Search code examples
verilogquartus

Verilog Module not updating as expected


I'm currently in the process of designing a processor in Verilog, and part of the process is creating multiplication functionality using the booth algorithm, using the code below:

//Booths Algorithm

module boothNumber(in, out, bits);
    input signed [31:0] in;
    input [2:0] bits;
    output reg [63:0] out;

    always @(in or out or bits)
     begin
        case (bits)
            3'b001,
            3'b010: out <= $signed(in);
            3'b011: 
                    begin
                    out <= $signed(in) + $signed(in);
                    end
            3'b100: 
                    begin
                    out <= - $signed(in) - $signed(in);
                    end
            3'b101,
            3'b110: 
                    begin
                    out <= - $signed(in);
                    end
            default: out <= $signed(64'b0);
            //3'b000: output = $signed(64'b0);
            //3'b111: output = $signed(64'b0);
            //both of these are in default instead
          endcase
     end
endmodule 


module booth(mc, mp, prod);
    input signed[31:0] mc, mp;
    output reg signed[63:0] prod;
    wire signed[63:0] temp [15:0];

     boothNumber num0(.in(mc), .out(temp[0]), .bits({mp[1:0], 1'b0}));
     boothNumber num1(.in(mc), .out(temp[1]), .bits({mp[3:1]}));
     boothNumber num2(.in(mc), .out(temp[2]), .bits({mp[5:3]}));
     boothNumber num3(.in(mc), .out(temp[3]), .bits({mp[7:5]}));
     boothNumber num4(.in(mc), .out(temp[4]), .bits({mp[9:7]}));
     boothNumber num5(.in(mc), .out(temp[5]), .bits({mp[11:9]}));
     boothNumber num6(.in(mc), .out(temp[6]), .bits({mp[13:11]}));
     boothNumber num7(.in(mc), .out(temp[7]), .bits({mp[15:13]}));
     boothNumber num8(.in(mc), .out(temp[8]), .bits({mp[17:15]}));
     boothNumber num9(.in(mc), .out(temp[9]), .bits({mp[19:17]}));
     boothNumber num10(.in(mc), .out(temp[10]), .bits({mp[21:19]}));
     boothNumber num11(.in(mc), .out(temp[11]), .bits({mp[23:21]}));
     boothNumber num12(.in(mc), .out(temp[12]), .bits({mp[25:23]}));
     boothNumber num13(.in(mc), .out(temp[13]), .bits({mp[27:25]}));
     boothNumber num14(.in(mc), .out(temp[14]), .bits({mp[29:27]}));
     boothNumber num15(.in(mc), .out(temp[15]), .bits({mp[31:29]}));

     always @(temp)
     begin
     prod <= $signed({{32{temp[0][31]}}, temp[0]} << 0) + $signed({{30{temp[1][31]}}, temp[1]} << 2) + $signed({{28{temp[2][31]}}, temp[2]} << 4) + $signed({{26{temp[3][31]}}, temp[3]} << 6) + $signed({{24{temp[4][31]}}, temp[4]} << 8) + $signed({{22{temp[5][31]}}, temp[5]} << 10) + $signed({{20{temp[6][31]}}, temp[6]} << 12) + $signed({{18{temp[7][31]}}, temp[7]} << 14) + $signed({{16{temp[8][31]}}, temp[8]} << 16) + $signed({{14{temp[9][31]}}, temp[9]} << 18) + $signed({{12{temp[10][31]}}, temp[10]} << 20) + $signed({{10{temp[11][31]}}, temp[11]} << 22) + $signed({{8{temp[12][31]}}, temp[12]} << 24) + $signed({{6{temp[13][31]}}, temp[13]} << 26) + $signed({{4{temp[14][31]}}, temp[14]} << 28) + $signed({{2{temp[15][31]}}, temp[15]} << 30);

     end
endmodule

which I then test with the following testbench using the Modelsim-altera simulation software in Quartus:

`timescale 1ns/10ps
module test_test;

   reg [31:0] A, B;
    reg [4:0] control;
    wire [63:0] Z;

    reg cout;
    reg c_in;
    reg Clock;


initial
    begin
        Clock <= 0;
    forever #10 Clock <= ~Clock;
    end
ALU the_ALU(A, B, Z, control);
 initial
    begin
    A = 32'b0; //Q
    B = 32'b0;
    control = 5'b01011;
     c_in = 1'b0;
    cout = 1'b0;

        #50     A <= 32'sd5;
            B <= 32'sd3;

        #50 A <= 32'sd55;
        #50 A <= 32'sd55;
        #50 A <= 32'sd55;
        #50 A <= 32'sd4;
        #50 A <= 32'sd4;
        #50 A <= 32'sd5;
        #50 A <= 32'sd6;
        #50 A <= 32'sd7;
    end

endmodule

while using this code for the ALU (slightly abridged, removed other control outputs)

module ALU (A, B, Z, control);

input signed [31:0] A, B;
input [4:0] control;
output reg signed [63:0] Z;
wire cout;

reg c_in;
wire signed [63:0] adder_out;
wire signed [63:0] booth_out;

always@(A or B or control)
begin
    c_in = 1'b0;

    case(control) //Would be more cases

        5'b01011 : 
            begin //MUL
            Z = booth_outt;
            end


    endcase
end

RC_ADDER ALU_adder(.sout(adder_out), .cout(cout), .a(A), .b(B), .cin(c_in));
booth ALU_booth(.mc(A), .mp(B), .prod(booth_out));

endmodule

After all of this, an odd simulation occurs. After the first change of A or B in the testbench, the output Z updates appropriately, but during the next change it doesn't, and then it "lags behind" for the continuation of the simulation, updating to the previous answer only when A or B are changed. (Like this)

Modelsim Output

I've spent many a hour resimulating, and would appreciate any advice possible


Solution

  • Your sensitivity list is A or B or control, so it will only update when one of those changes. If you're not trying to create a latch, it's easier to use always @* to update when any of the inputs change.