0
votes

I have a code written for multiplying two 53 bit numbers (written below). I am using shift-add strategy using two other 106 bit registers. This code is working fine. Now I have another 53 bit highly optimized hans carlson adder module written in form:

module hans_carlson_adder(input [52:0] a, b, input c_in, output [52:0] sum, output c_out);

I want to use this adder to do the summation line in for loop (mentioned in code). I am having problem instantiating the adder inside an always block. Plus I dont want to have 106 instances (due to for loop) of this adder. Can you please help with this code

  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
You have two choices: 1) 52 adders that do the multiplication in one cycle 2) one adder that does the multiplication in 52 cycles. Which do you want to do. Note: Your original code didn't need to loop 106 times since there aren't that many bits in y. You can't instantiate a module in an always block, so either create the instances outside the always, or get a function implementation instead.Brad Budlong
@Brad Budlong I want one adder implementation in 52 cycles. (Since the operands would be 106 bit so I would have to use two). I dont understand how I can instantiate the module outside and still use the function like I am doing the addition in for loop.Rizwan Ali

1 Answers

0
votes

First you need to instantiate your adder outside of the always block and connect it to signals:

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);

Now because this is a pipelined adder you are going to need something to kick off the multiplication (I'll call that input start) and something that indicates that the result is available (I'll call that output reg done). You'll want to add them to your mul1 module definition. You can choose a slightly different protocol depending on your needs. It appears that you have something that you've been implementing with the input state. I'm also going to use start to initialize during each calculation so that I don't need a separate reset signal.

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

If you want to make an optimization you could end once the shift signal is equal to 0. In this case the done signal would become high as soon as there were no more bits to add into the result, so multiplying by small values of y would take less cycles.