基于FullAdder的参数化n位减法器编译异常(代码255)求助
n位减法器编译异常排查
问题描述
我用FullAdder搭建的4位加法器实现了一个带参数N的n位减法器,本想通过修改N值切换为32、36或40位减法器,但仿真时出现compilation exited abnormally with code 255错误,调整过b和m的异或方式、for循环范围后还是没解决,求帮忙排查代码问题。
原代码模块
FullAdder模块
module FullAdder (a, b, ci, r, co); input a, b, ci; output r, co; assign r = a ^ b ^ ci; assign co = (a&b) | ((a^b)&ci); endmodule // FullAdder
4位加法器模块
module adder_4bit (A, B, ci, R, co); input [3:0] A, B; // [MSB:LSB] input ci; output [3:0] R; output co; wire [2:0] c; // FullAdder i0 (.a(A[0]), .b(B[0]), .ci(ci), .r(R[0]), .co(c[0])); // FullAdder i1 (.a(A[1]), .b(B[1]), .ci(c[0]), .r(R[1]), .co(c[1])); // FullAdder i2 (.a(A[2]), .b(B[2]), .ci(c[1]), .r(R[2]), .co(c[2])); // FullAdder i3 (.a(A[3]), .b(B[3]), .ci(c[2]), .r(R[3]), .co(co)); FullAdder i[3:0] (.a(A[3:0]), .b(B[3:0]), .ci({c[2:0],ci}), .r(R[3:0]), .co({co,c[2:0]})); endmodule // adder_4bit
n位加减法器模块
module adder_nbit (a, b, m, s, co, v); parameter N = 32; // 32 bit subtractor input [N-1:0] a, b; input m; output [N-1:0] s; output co, v; wire [N/4-1:0] c; wire [N-1:0] bi; genvar i; assign bi[0] = b[0] ^ m; assign bi[1] = b[1] ^ m; assign bi[2] = b[2] ^ m; assign bi[3] = b[3] ^ m; adder_4bit add0(.A(a[3:0]), .B(bi[3:0]), .ci(m), .R(s[3:0]), .co(c[0])); generate for (i=1; i<=N/4-1; i=i+1) begin:bit assign bi[i*4] = b[i*4] ^ m; assign bi[i*4+1] = b[i*4+1] ^ m; assign bi[i*4+2] = b[i*4+2] ^ m; assign bi[i*4+3] = b[i*4+3] ^ m; adder_4bit add(.A(a[i*4+3:i*4]), .B(bi[i*4+3:i*4]), .ci(c[i-1]), .R(s[i*4+3:i*4]), .co(c[i])); end endgenerate assign co = c[N/4-1]; // carry assign v = c[N/4-2] ^ co; // overflow endmodule // adder_nbit
测试模块
`timescale 1ns/1ns `include "FullAdder.v" `include "adder_4bit.v" `include "adder_nbit.v" module subtractor_nbit_tb; parameter N = 32; reg [N-1:0] A, B; reg M; wire [N-1:0] S; wire CO, V; adder_nbit i0 (.a(A), .b(B), .m(M), .s(S), .co(CO), .v(V)); initial begin $dumpfile ("subtractor_nbit_tb.vcd"); $dumpvars(0, subtractor_nbit_tb); M=1; // subtractor A=0; B=0; #10 A=302; #10 B=100; #10 A=400; #10 B=203; #10 $finish; end // initial begin endmodule // adder_4bit_tb
问题排查与修复
核心问题1:参数未传递导致位宽不匹配
测试模块中实例化adder_nbit时,未将自身的N参数传递给该模块,导致当修改测试模块的N为36或40时,adder_nbit仍使用默认的32位参数,造成输入输出端口位宽不匹配,触发编译错误。
修复方式:在实例化adder_nbit时显式传递参数:
adder_nbit #(.N(N)) i0 (.a(A), .b(B), .m(M), .s(S), .co(CO), .v(V));
问题2:bi赋值冗余易出错
原代码中手动逐位赋值bi,写法冗余且当N变化时需要调整代码,存在出错风险。可通过整体位运算简化:
// 替换原有的逐位assign语句 assign bi = b ^ {N{m}};
该语句会将m扩展为N位后与b逐位异或,当m=1时实现对b的取反,符合减法器的补码运算逻辑。
问题3:测试模块注释错误
测试模块末尾的注释endmodule // adder_4bit_tb与模块名不符,修正为:
endmodule // subtractor_nbit_tb
修复后的完整代码
修正后的adder_nbit模块
module adder_nbit (a, b, m, s, co, v); parameter N = 32; input [N-1:0] a, b; input m; output [N-1:0] s; output co, v; wire [N/4-1:0] c; wire [N-1:0] bi; genvar i; // 整体生成补码输入 assign bi = b ^ {N{m}}; adder_4bit add0(.A(a[3:0]), .B(bi[3:0]), .ci(m), .R(s[3:0]), .co(c[0])); generate for (i=1; i<=N/4-1; i=i+1) begin:adder_group adder_4bit add(.A(a[i*4+3:i*4]), .B(bi[i*4+3:i*4]), .ci(c[i-1]), .R(s[i*4+3:i*4]), .co(c[i])); end endgenerate assign co = c[N/4-1]; assign v = c[N/4-2] ^ co; endmodule // adder_nbit
修正后的测试模块
`timescale 1ns/1ns `include "FullAdder.v" `include "adder_4bit.v" `include "adder_nbit.v" module subtractor_nbit_tb; parameter N = 32; reg [N-1:0] A, B; reg M; wire [N-1:0] S; wire CO, V; // 传递参数N保证位宽匹配 adder_nbit #(.N(N)) i0 (.a(A), .b(B), .m(M), .s(S), .co(CO), .v(V)); initial begin $dumpfile ("subtractor_nbit_tb.vcd"); $dumpvars(0, subtractor_nbit_tb); M=1; // 启用减法模式 A=0; B=0; #10 A=302; #10 B=100; #10 A=400; #10 B=203; #10 $finish; end endmodule // subtractor_nbit_tb
内容的提问来源于stack exchange,提问作者Hyeonsu Shin
相关产品推荐
相关产品推荐

