Shift and add binary multiplier getting don't-cares for reg2

51 views Asked by At
module bin_mult(
    output reg [7:0]mult,reg1,reg2,
    output reg [2:0]count,
    input [3:0]a,b,
    input load,clk);

    //reg [7:0]reg1,reg2;
    //reg [2:0]count;
    reg [3:0]m[3:0];
    integer i,j;
    
    // Partial product generation
    always@(*) begin
        for(i=0;i<4;i=i+1) begin
            for(j=0;j<4;j=j+1) begin
                m[i][j]=b[i]&a[j];
            end
        end
    end

    always@(posedge clk) begin
        if(load) begin
            reg1<=0;
            count<=0;
            reg2<={4'd0,m[0]};
        end
        else if(count==4'd3) count<=0;
        else begin
                count<=count+1;
                if(b[count+1]==1'b1) begin
                    reg1<={4'd0,m[count+1]}<<(count+1);
                    mult<=reg1+reg2;
                    reg2<=mult;
                end
                else if(b[count+1]==1'b0) reg2<=reg2;
        end
    end
endmodule

module tb;
wire [7:0]mult,reg1,reg2;
wire [2:0]count;
reg [3:0]a,b;
reg load,clk;
bin_mult DUT(mult,reg1,reg2,count,a,b,load,clk);
always #5 clk=~clk;
initial begin
    $dumpfile("tb.vcd");
    $dumpvars(0,tb);
    $monitor("clk=%b load=%b a=%d b=%d count=%d reg1=%b reg2=%b mult=%d",clk,load,a,b,count,reg1,reg2,mult);
    {clk,load}=0;
    @(negedge clk) a=4'd15;b=4'd15;
    @(negedge clk) load=1'b1;
    @(negedge clk) load=1'b0;
    #100 $finish;
end
endmodule

This was the simulation result:

VCD info: dumpfile tb.vcd opened for output.
clk=0 load=0 a= x b= x count=x reg1=xxxxxxxx reg2=xxxxxxxx mult=  x
clk=1 load=0 a= x b= x count=x reg1=xxxxxxxx reg2=xxxxxxxx mult=  x
clk=0 load=0 a=15 b=15 count=x reg1=xxxxxxxx reg2=xxxxxxxx mult=  x
clk=1 load=0 a=15 b=15 count=x reg1=xxxxxxxx reg2=xxxxxxxx mult=  x
clk=0 load=1 a=15 b=15 count=x reg1=xxxxxxxx reg2=xxxxxxxx mult=  x
clk=1 load=1 a=15 b=15 count=0 reg1=00000000 reg2=00001111 mult=  x
clk=0 load=0 a=15 b=15 count=0 reg1=00000000 reg2=00001111 mult=  x
clk=1 load=0 a=15 b=15 count=1 reg1=00011110 reg2=xxxxxxxx mult= 15
clk=0 load=0 a=15 b=15 count=1 reg1=00011110 reg2=xxxxxxxx mult= 15
clk=1 load=0 a=15 b=15 count=2 reg1=00111100 reg2=00001111 mult=  x
clk=0 load=0 a=15 b=15 count=2 reg1=00111100 reg2=00001111 mult=  x
clk=1 load=0 a=15 b=15 count=3 reg1=01111000 reg2=xxxxxxxx mult= 75
clk=0 load=0 a=15 b=15 count=3 reg1=01111000 reg2=xxxxxxxx mult= 75
clk=1 load=0 a=15 b=15 count=0 reg1=01111000 reg2=xxxxxxxx mult= 75
clk=0 load=0 a=15 b=15 count=0 reg1=01111000 reg2=xxxxxxxx mult= 75
clk=1 load=0 a=15 b=15 count=1 reg1=00011110 reg2=01001011 mult=  x
clk=0 load=0 a=15 b=15 count=1 reg1=00011110 reg2=01001011 mult=  x
clk=1 load=0 a=15 b=15 count=2 reg1=00111100 reg2=xxxxxxxx mult=105
clk=0 load=0 a=15 b=15 count=2 reg1=00111100 reg2=xxxxxxxx mult=105
clk=1 load=0 a=15 b=15 count=3 reg1=01111000 reg2=01101001 mult=  x
clk=0 load=0 a=15 b=15 count=3 reg1=01111000 reg2=01101001 mult=  x
clk=1 load=0 a=15 b=15 count=0 reg1=01111000 reg2=01101001 mult=  x
clk=0 load=0 a=15 b=15 count=0 reg1=01111000 reg2=01101001 mult=  x
clk=1 load=0 a=15 b=15 count=1 reg1=00011110 reg2=xxxxxxxx mult=225
clk=0 load=0 a=15 b=15 count=1 reg1=00011110 reg2=xxxxxxxx mult=225
clk=1 load=0 a=15 b=15 count=2 reg1=00111100 reg2=11100001 mult=  x
test.v:56: $finish called at 130 (1s)
clk=0 load=0 a=15 b=15 count=2 reg1=00111100 reg2=11100001 mult=  x

I have taken two registers reg1 to store partial product terms and reg2 to store intermediate result (initialized it with first partial product terms array m[0]), but I'm getting unknown state for reg2.

When count becomes 1, the reg2 has to hold its previous value, i.e., 00001111, but instead it is getting x. After that at many places reg2 is getting x. I'm unable to find the reason.

1

There are 1 answers

0
toolic On

reg2 is unknown because mult is unknown.

One way to resolve the unknowns is to set mult to 0 when load is 1, just like your other signals:

always@(posedge clk) begin
    if(load) begin
        reg1<=0;
        count<=0;
        reg2<={4'd0,m[0]};
        mult <= 0;
    end