Verilog 32位加法器代码输出不匹配,请求技术协助
Verilog 32位加法器输出不匹配问题排查与修正

这是一道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模块,但没有效果,也调整过代码结构。
问题根源
你的代码存在两个致命错误:
- 信号多重驱动:同时用
generate循环实现bit0~bit15的单bit加法器级联,又调用add16模块对sum[15:0]赋值,同一个信号被两个逻辑驱动,属于Verilog非法行为,必然导致输出混乱。 - 进位逻辑混乱:
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
相关产品推荐
相关产品推荐

