Verilog 将2位模块(乘法器)转换为更多位

Verilog 将2位模块(乘法器)转换为更多位,verilog,iverilog,Verilog,Iverilog,对于2位乘法器,我有以下代码: module Multiplier (a0, a1, b0, b1, c[3:0]); output [3:0]c; input a0, a1, b0, b1; wire a0b1, a1b0, ha0c, a1b1; and (c[0], a0, b0); and (a0b1, a0, b1); and (a1b0, a1, b0); HalfAdder ha0 (a1b0, a0b1, c[1], ha0c); a

对于2位乘法器,我有以下代码:

module Multiplier (a0, a1, b0, b1, c[3:0]);
output      [3:0]c; 
input       a0, a1, b0, b1;
wire        a0b1, a1b0, ha0c, a1b1;  

and (c[0], a0, b0);
and (a0b1, a0, b1);
and (a1b0, a1, b0);
HalfAdder ha0 (a1b0, a0b1, c[1], ha0c);

and (a1b1, a1, b1);
HalfAdder ha1 (ha0c, a1b1, c[2], c[3]);
endmodule

我希望能够将其扩展到2位以上(32位)。不过,我的代码结构对此提出了挑战。首先,我必须有68个模块参数。此外,我还必须手动创建64条导线(导线a0b1、a1b0、ha0c、a1b1的副本)。最后,我需要手动写出一组逻辑门和半加法器模块来连接所有逻辑。因此,我想知道是否有一种方法可以重构我的代码,以便能够实例化一个大小为n(传递的参数)的二进制乘法器

您需要参数化并使用生成块。(使用同步电路比使用异步电路要好得多)

这是一个不完整的示例,您可以填写必要的逻辑:

module Multiplier (a, b, c, clk);
parameter WIDTH = 64;
output      [2*WIDTH:0]c; 
input       [WIDTH-1:0]a; 
input       [WIDTH-1:0]b; 
input       clk;


genvar i;
generate  for (i = 0; i < WIDTH; i <= i + 1)
begin : shifts
    // shift a 1-bit for each i and 'logical and' it with b
    reg  [WIDTH + i :0]carry;
    wire [WIDTH + i -1:0]shifted = {a,i{0}} & b[i]; 


    // sum the result of shift and 'logical and'
    always @ (posedge clk)
    begin
        carry <= shifted + shifts[i-1].carry ;
    end
end

assign c = shifts[WIDTH].carry;

endgenerate

endmodule
模块乘法器(a、b、c、clk);
参数宽度=64;
输出[2*宽度:0]c;
输入[WIDTH-1:0]a;
输入[WIDTH-1:0]b;
输入时钟;
genvar i;

为(i=0;i
循环组合
生成
/
,但我更喜欢编写脚本(例如,用Perl或TCL)相反。是的,我的意思是使用赋值、运算符、始终块、循环、“如果”语句、函数、数组、结构……和非门。门级表示在某些探索和合成过程、一些spice模拟中是有意义的。根据我的经验,所有这些都是由RTL中的其他工具生成的,或者从原理图中抽象出来的。它很少有人用手创建它们。可能是在低级的库单元中。人们有时会使用某些类型的门,比如三态缓冲器来驱动总线。所以,一般来说,你应该避免使用它们。