4位减法器除法器多驱动冲突问题排查求助
4位除法器多驱动冲突问题排查与解决
问题背景
用减法器实现4位除法器,模块在测试平台运行正常,但集成到项目执行apio build时出现多驱动冲突警告,烧录到FPGA后无法正常工作。
编译警告信息
Warning: multiple conflicting drivers for top.\div.auxNumerador_next [3]: port Q[3] of cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$866 ($dlatch) port Q[3] of cell $flatten\div.$procdff$895 ($adff) Warning: multiple conflicting drivers for top.\div.auxNumerador_next [2]: port Q[2] of cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$866 ($dlatch) port Q[2] of cell $flatten\div.$procdff$895 ($adff) Warning: multiple conflicting drivers for top.\div.auxNumerador_next [1]: port Q[1] of cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$866 ($dlatch) port Q[1] of cell $flatten\div.$procdff$895 ($adff) Warning: multiple conflicting drivers for top.\div.auxNumerador_next [0]: port Q[0] of cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$866 ($dlatch) port Q[0] of cell $flatten\div.$procdff$895 ($adff) Warning: multiple conflicting drivers for top.\div.cociente_next [3]: port Q[3] of cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$822 ($dlatch) port Q[3] of cell $flatten\div.$procdff$893 ($adff) Warning: multiple conflicting drivers for top.\div.cociente_next [2]: port Q[2] of cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$822 ($dlatch) port Q[2] of cell $flatten\div.$procdff$893 ($adff) Warning: multiple conflicting drivers for top.\div.cociente_next [1]: port Q[1] of cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$822 ($dlatch) port Q[1] of cell $flatten\div.$procdff$893 ($adff) Warning: multiple conflicting drivers for top.\div.cociente_next [0]: port Q[0] of cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$822 ($dlatch) port Q[0] of cell $flatten\div.$procdff$893 ($adff) Warning: multiple conflicting drivers for top.\div.next_state [2]: port Q[2] of cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$795 ($dlatch) port Q[2] of cell $flatten\div.$procdff$892 ($adff) Warning: multiple conflicting drivers for top.\div.next_state [1]: port Q[1] of cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$795 ($dlatch) port Q[1] of cell $flatten\div.$procdff$892 ($adff) Warning: multiple conflicting drivers for top.\div.next_state [0]: port Q[0] of cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$795 ($dlatch) port Q[0] of cell $flatten\div.$procdff$892 ($adff) Warning: Driver-driver conflict for \div.cociente_next [3] between cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$822.Q and constant 1'0 in top: Resolved using constant. Warning: Driver-driver conflict for \div.cociente_next [2] between cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$822.Q and constant 1'0 in top: Resolved using constant. Warning: Driver-driver conflict for \div.cociente_next [1] between cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$822.Q and constant 1'0 in top: Resolved using constant. Warning: Driver-driver conflict for \div.cociente_next [0] between cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$822.Q and constant 1'0 in top: Resolved using constant. Warning: Driver-driver conflict for \div.next_state [2] between cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$795.Q and constant 1'0 in top: Resolved using constant. Warning: Driver-driver conflict for \div.next_state [1] between cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$795.Q and constant 1'0 in top: Resolved using constant. Warning: Driver-driver conflict for \div.next_state [0] between cell $flatten\div.$auto$proc_dlatch.cc:427:proc_dlatch$795.Q and constant 1'0 in top: Resolved using constant.
问题代码
module divisor( input wire clk, reset, input wire iniciar, input wire [3:0] numerador, denominador, output wire [3:0] cociente, resto, output reg terminado, listo ); localparam [2:0] s0 = 3'b000, s1 = 3'b001, s2 = 3'b010, s3 = 3'b011, s4 = 3'b100; reg [2:0] state, next_state; reg [3:0] cociente_reg, cociente_next, resto_reg, resto_next; reg [3:0] auxNumerador_reg, auxNumerador_next; always @(posedge clk, posedge reset) begin if (reset) begin state <= s0; cociente_reg <= 4'b0000; resto_reg <= 4'b0000; auxNumerador_reg <= 4'b0000; end else begin state <= next_state; cociente_reg <= cociente_next; resto_reg <= resto_next; auxNumerador_reg <= auxNumerador_next; end end always @* begin state = next_state; listo = 1'b0; terminado = 1'b0; cociente_reg = cociente_next; resto_reg = resto_next; auxNumerador_reg = auxNumerador_next; case (state) s0: begin listo = 1'b1; if(iniciar)begin auxNumerador_next = numerador; cociente_next = 4'b0000; if (denominador == 4'b0000 || numerador == 4'b0000 ) next_state = s3; else next_state = s1; end end s1: begin auxNumerador_next = auxNumerador_reg - denominador; cociente_next = cociente_reg + 1; if(auxNumerador_next < denominador) next_state = s2; end s2: begin resto_next = auxNumerador_reg; next_state = s4; end s3: begin resto_next = numerador; next_state = s4; end s4: begin terminado = 1'b1; next_state = s0; end default: next_state = s0; endcase end assign cociente = cociente_reg; assign resto = resto_reg; endmodule
问题根源
- 寄存器变量被多驱动:时序逻辑块(
always @(posedge clk, posedge reset))负责将next_*同步到*_reg寄存器,但组合逻辑块(always @*)中错误地对state、cociente_reg等寄存器变量赋值,导致这些变量同时被时序逻辑和组合逻辑驱动,触发多冲突警告。 - 未赋默认值导致锁存器:组合逻辑中部分
next_*变量未在所有分支赋值,综合器会推断出不必要的锁存器,进一步加剧逻辑冲突。 - 仿真与综合差异:仿真器对这种代码错误的容忍度较高,未触发异常,但综合时会严格检查驱动冲突,烧录FPGA后逻辑完全混乱。
修复方案
1. 删除组合逻辑中对寄存器变量的错误赋值
组合逻辑仅负责计算next_*变量、listo和terminado,不能修改*_reg和state这类寄存器变量。
2. 给所有next_*变量添加默认值
在always @*开头为next_state、cociente_next、auxNumerador_next、resto_next赋默认值,避免综合器推断锁存器。
3. 修正后的代码
module divisor( input wire clk, reset, input wire iniciar, input wire [3:0] numerador, denominador, output wire [3:0] cociente, resto, output reg terminado, listo ); localparam [2:0] s0 = 3'b000, s1 = 3'b001, s2 = 3'b010, s3 = 3'b011, s4 = 3'b100; reg [2:0] state, next_state; reg [3:0] cociente_reg, cociente_next, resto_reg, resto_next; reg [3:0] auxNumerador_reg, auxNumerador_next; always @(posedge clk, posedge reset) begin if (reset) begin state <= s0; cociente_reg <= 4'b0000; resto_reg <= 4'b0000; auxNumerador_reg <= 4'b0000; end else begin state <= next_state; cociente_reg <= cociente_next; resto_reg <= resto_next; auxNumerador_reg <= auxNumerador_next; end end always @* begin // 给所有next_*变量赋默认值,避免锁存器 next_state = state; cociente_next = cociente_reg; auxNumerador_next = auxNumerador_reg; resto_next = resto_reg; listo = 1'b0; terminado = 1'b0; case (state) s0: begin listo = 1'b1; if(iniciar)begin auxNumerador_next = numerador; cociente_next = 4'b0000; if (denominador == 4'b0000 || numerador == 4'b0000 ) next_state = s3; else next_state = s1; end end s1: begin auxNumerador_next = auxNumerador_reg - denominador; cociente_next = cociente_reg + 1; if(auxNumerador_next < denominador) next_state = s2; end s2: begin resto_next = auxNumerador_reg; next_state = s4; end s3: begin resto_next = numerador; next_state = s4; end s4: begin terminado = 1'b1; next_state = s0; end default: next_state = s0; endcase end assign cociente = cociente_reg; assign resto = resto_reg; endmodule
验证方法
- 重新执行
apio build,确认多驱动冲突警告消失。 - 烧录到FPGA后测试功能,验证除法运算、状态切换(
listo、terminado信号)是否正常。
内容的提问来源于stack exchange,提问作者Segundo Saccani
相关产品推荐
相关产品推荐

