【发布时间】:2026-01-28 08:15:02
【问题描述】:
我正在尝试使用组合逻辑方法在 verilog 中创建一个乘法器模块,以便不涉及时钟。我希望模块有一个通用的定义,即我希望 Multiplier 分别接收大小为 M 和 N 位的两个因子,并返回大小为 M+N 位的乘积。
基本思想是计算部分乘积的总和,每个乘积根据其级别向左移动一定数量的位。要理解这个想法,请看以下示例:
A = A3 A2 A1 A0 和 B = B2 B1 B0
然后,A X B 会这样计算:
A3*B0 A2*B0 A1*B0 A0*B0
A3*B1 A2*B1 A1*B1 A0*B1
+ A3*B2 A2*B2 A1*B2 A0*B2
____________________________________________
要计算部分乘积的和,我需要计算前两个乘积的总和 (A 乘 B0) + ([A 乘 B1]
更一般地,要计算乘积 A[M-1:0] 乘以 B[N-1:0],我们需要使用 N-1 个 RippleCarryAdder(每个定义比前一个多一位)并以某种方式将每个的输出用作下一个的两个输入之一。
到目前为止,这是我不完整的verilog代码:
首先,RippleCarryAdder 参数化,这可以正常工作
module RippleCarryAdder#(parameter N = 4)(A,B,Cin,S,Cout);
input [N-1:0] A;
input [N-1:0] B;
input Cin;
output [N-1:0] S;
output Cout;
wire [N:0] CC;
assign CC[0] = Cin;
assign Cout = CC[N];
genvar i;
generate
for (i=0; i < N; i=i+1)
begin: addbit
FullAdder unit(A[i],B[i],CC[i],S[i],CC[i+1]);
end
endgenerate
endmodule
乘数的不完整代码
module Multiplier #(parameter M = 4, N = 4)(A,B,P);
input [M-1:0] A; //Input A, size M
input [N-1:0] B; //Input B, size N
output [M+N-1:0] P; //Output P (product), size M+N
wire [N-1:0] CC; //Bus for the carries of the RippleCarryAdders
assign CC[0] = 1'b0;
RippleCarryAdder#(M+1) adder0({1'b0,A&{M{B[0]}}},{A&{M{B[1]}},1'b0},CC[0], /*insert bus P0 here*/);
/*I want bus P0 = (0 A[N-1]&B[0] ... A[0]&B[0]) + (A[N-1]&B[1] ... A[0]&B[1] 0) + CC[0], with CC[0] = 0 because it is the first sum */
genvar i;
generate
for (i=2; i < N; i=i+1)
begin: addPartialProduct
RippleCarryAdder#(M+i) adder({A&{M{B[i]}},{(i{1'b0}}},/*{CC[i-1],P[i-2]}*/,CC[i-2],/*P[i-1]*/,CC[i-1]);
//When I do {CC[i-1],P[i-1]}, I mean the concatenation of the carry CC[i] (1 bit) with the product P[i-1] (several bits)
end
endgenerate
//Finally, I want P = P[N-1], the output of the last RippleCarryAdder
endmodule
所以我的问题是:如何定义这些参数化大小的 P[i] 总线,以便它们可以用于连接每对连续 RippleCarryAdder 的输入和输出?请注意,每条总线 P[i] 的大小为 (M+i+1),因为 i = 0, ..., N-1
如果不可能,还有哪些其他解决方案可以仅使用组合逻辑(不涉及时钟)制作参数化乘法器?
提前致谢。
PS:我知道有使用时钟的有效解决方案,但挑战是不使用它们。
【问题讨论】:
标签: verilog