Search code examples
verilogmultiplicationsequential

Verilog sequential multiplier


I am trying to implement a 4 bit signed sequential multiplier. I have a for loop in my TB, but only the multiplicand changes, not the multiplier. When I manually change the multiplier, I notice that my product outputs all 0s then it changes to the actual product. What am I doing wrong?

module seq4bit(a,b,sign,clk,out,ready);
input [3:0]a,b;
output [7:0]out;
input ready,sign,clk;

reg [7:0] out,out_t;
reg[3:0]b0,msb,lsb;
reg[7:0]a0;
reg neg;
reg[2:0]bit;

wire ready = !bit;

initial bit = 0;
initial neg = 0;

always @(posedge clk)

if(ready)begin
    bit = 3'b100;
    out = 0;
    out_t = 0;
    a0 = (!sign || !a[3])?{4'd0,a}:{4'd0,!a + 1'b1};
    b0 = (!sign || !b[3])? b : !b + 1'b1;
    neg = sign && ((b[3] && !a[3])||(b[3]&&a[3]));
end
else if(bit > 0)begin
    if(b0 == 1'b1)
    out_t = out_t + a0;
    out = (!neg)?out_t:(~out_t + 1'b1);
    b0 = b0 >> 1;
    a0 = a0 << 1;
    bit = bit - 1'b1;
    
end
endmodule

module seq4tb;
reg[3:0]a,b;
wire [7:0]out;
reg clk,sign,ready;
integer i;
seq4bit uut(.a,.b,.out,.ready,.clk,.sign);

initial begin

a = 0;
b = 0;
clk = 0;
sign = 0;
ready = 1;

end

always #10 clk = ~clk;

initial

$monitor("time = %2d, a=%4b, b=%4b, sign=%1b, out=%8b, clk = %1b,ready = %1b", $time,a,b,sign,out,clk,ready);

    
always @(*)
        begin
        for ( i=0; i< 16*16 ; i = i + 1 ) 
            #20 a = a + 1;b = b +1;
                
            
            
        #1000 $stop;

        end
      
endmodule

Solution

  • I think the main problem was that b = b + 1; was not inside the for loop.

    Replace the always block in the testbench with this initial block:

    initial begin
        for ( i=0; i< 16*16 ; i = i + 1 ) begin
            #20 a = a + 1;
            b = b + 1;
        end
        #1000 $finish;
    end
    

    The always block simulated like an infinite loop for me. In this case, b also changes.