Verilog在一个始终块内实例化模块。使用Adder进行乘法

时间:2017-05-10 03:49:43

标签: module verilog instantiation modelsim

我有一个代码,用于将两个53位数相乘(如下所示)。我正在使用另外两个106位寄存器的移位添加策略。这段代码工作正常。现在我有另外53位高度优化的汉斯卡尔森加法器模块,其形式为:

模块hans_carlson_adder(输入[52:0] a,b,输入c_in,输出[52:0]总和,输出c_out);

我想使用这个加法器来执行for循环中的求和行(在代码中提到)。我遇到问题,在一个始终块内实例化加法器。另外,我不希望这个加法器有106个实例(由于for循环)。你能帮忙解决这个代码吗?

  module mul1(
                output reg [105:0]  c,
                input [52:0]   x,
                input [52:0]   y,
            input clk,
            input state
            ); 

        reg [105:0] p;
        reg [105:0]a;
        integer i;

        always @(posedge clk) begin
        if (state==1) begin

          a={53'b0,x[52:0]};
          p=106'b0; // needs to zeroed
          for(i=0;i<106;i=i+1) begin
            if(y[i]) begin
              p=p+a; //THIS LINE NEEDS TO BE REPLACED WITH HANS CARLSONADDER
            end
            a=a<<1;
          end

        c<=p;

        end else begin
         c=0;

        end
        end
        endmodule

1 个答案:

答案 0 :(得分:0)

首先,您需要在always块之外实例化您的加法器并将其连接到信号:

wire [52:0] b;
reg [5:0] count;
assign b = c[count+7'd52:count];
wire [52:0] sum;
wire c_out;
// Add in x depending on the bits in y
// b has the running result bits that still apply at this point
hans_carlson_adder u0(x, b, 1'b0, sum, c_out);

现在因为这是一个流水线加法器,你需要一些东西来启动乘法(我会称之为input start)以及表明结果可用的东西(我会称之为{{ 1}})。您需要将它们添加到output reg done模块定义中。您可以根据需要选择略有不同的协议。您似乎已经使用mul1实现了一些功能。我还将在每次计算期间使用input state进行初始化,这样我就不需要单独的重置信号。

start

如果你想进行优化,你可以在reg [52:0] shift; always @(posedge clk) begin if (start) begin done <= 0; count <= 0; c <= 106'b0; shift <= y; end else if (count < 53) begin if (shift[0]) begin c[count+7'd52:count] <= sum; c[count+7'd53] <= c_out; end count <= count + 1; shift = shift >> 1; end else begin done <= 1; end end 信号等于0时结束。在这种情况下,只要没有更多位要加入,shift信号就会变高。结果,因此乘以较小的done值会减少周期。