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

Verilog 32位加法器代码输出不匹配,请求技术协助

Verilog 32位加法器输出不匹配问题排查与修正

HDLBits.01xz.net 代码片段

这是一道Verilog题目,我根据图片编写了代码,但出现输出不匹配的问题,能否获得技术协助?

我的代码:

module add1 ( input a, input b, input cin,   output sum, output cout );
    assign sum = a ^ b ^ cin;
    assign cout = (a & b)|(a & cin)|(b & cin);
endmodule
 
module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire carry [31:0]; 
    wire cout1,cout2;
add1 fa1(a[0],b[0],1'b0,sum[0],carry[0]);
genvar i;
    generate
        for(i = 1; i < 16; i = i + 1) begin:adders
            add1 fa2(a[i],b[i],carry[i-1],sum[i],carry[i]);
        end
    endgenerate
    add16 fa2(a[15:0],b[15:0],carry[14],sum[15:0],cout1);
    add16 fa3(a[31:16],b[31:16],carry[15],sum[31:16],cout2);
endmodule

我尝试过单独编写add16模块,但没有效果,也调整过代码结构。


问题根源

你的代码存在两个致命错误:

  1. 信号多重驱动:同时用generate循环实现bit0~bit15的单bit加法器级联,又调用add16模块对sum[15:0]赋值,同一个信号被两个逻辑驱动,属于Verilog非法行为,必然导致输出混乱。
  2. 进位逻辑混乱:generate循环已生成到bit15的加法器,却用carry[14]作为add16的输入进位,同时用carry[15]给高16位加法器做输入,完全违背了进位级联的逻辑。

修正方案

推荐两种清晰的实现方式,选其一即可:

方案1:纯单bit加法器级联实现32位加法

module add1 ( input a, input b, input cin,   output sum, output cout );
    assign sum = a ^ b ^ cin;
    assign cout = (a & b)|(a & cin)|(b & cin);
endmodule
 
module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire [31:0] carry; // carry[i]表示第i位加法器的进位输出
    
    // 最低位加法器,进位输入为0
    add1 fa0(a[0], b[0], 1'b0, sum[0], carry[0]);
    
    // 循环生成1~31位的加法器,级联进位
    genvar i;
    generate
        for(i = 1; i < 32; i = i + 1) begin: adders
            add1 fa(a[i], b[i], carry[i-1], sum[i], carry[i]);
        end
    endgenerate
endmodule

方案2:先实现16位加法器,再级联两个16位加法器

module add1 ( input a, input b, input cin,   output sum, output cout );
    assign sum = a ^ b ^ cin;
    assign cout = (a & b)|(a & cin)|(b & cin);
endmodule

// 实现16位加法器模块
module add16 (
    input [15:0] a,
    input [15:0] b,
    input cin,
    output [15:0] sum,
    output cout
);
    wire [15:0] carry;
    
    add1 fa0(a[0], b[0], cin, sum[0], carry[0]);
    
    genvar i;
    generate
        for(i = 1; i < 16; i = i + 1) begin: adders
            add1 fa(a[i], b[i], carry[i-1], sum[i], carry[i]);
        end
    endgenerate
    
    assign cout = carry[15]; // 16位加法器的最终进位
endmodule
 
module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire mid_carry; // 低16位的进位输出,作为高16位的进位输入
    
    // 低16位加法,初始进位为0
    add16 fa_low(a[15:0], b[15:0], 1'b0, sum[15:0], mid_carry);
    // 高16位加法,接收低16位的进位
    add16 fa_high(a[31:16], b[31:16], mid_carry, sum[31:16], );
endmodule

说明

两种方案都严格遵循加法器进位级联逻辑,不会出现信号冲突,可解决输出不匹配问题。若选择方案2,需确保add16模块实现正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 09:48:12