You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

问题根源

  1. 寄存器变量被多驱动:时序逻辑块(always @(posedge clk, posedge reset))负责将next_*同步到*_reg寄存器,但组合逻辑块(always @*)中错误地对state、cociente_reg等寄存器变量赋值,导致这些变量同时被时序逻辑和组合逻辑驱动,触发多冲突警告。
  2. 未赋默认值导致锁存器:组合逻辑中部分next_*变量未在所有分支赋值,综合器会推断出不必要的锁存器,进一步加剧逻辑冲突。
  3. 仿真与综合差异:仿真器对这种代码错误的容忍度较高,未触发异常,但综合时会严格检查驱动冲突,烧录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

验证方法

  1. 重新执行apio build,确认多驱动冲突警告消失。
  2. 烧录到FPGA后测试功能,验证除法运算、状态切换(listo、terminado信号)是否正常。

内容的提问来源于stack exchange,提问作者Segundo Saccani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 11:45:00