Search code examples
verilogfpgaquartusintel-fpga

What am I doing wrong? Testbench not updating correctly


I am trying to implement the testbench so that after 3 ticks, each input gets the new specified valued. For example, first 3 seconds (or ticks) A = 10, B = 0, and then the next 3 seconds (3 seconds to 6 seconds) A = 10, B = 16 and etc. However, on my actual testbench, the values aren't updating the way I want. Am I getting the syntax wrong?

Here's a screenshot of the current values I am getting. I drew the red lines at the top to represent every 3 ticks.

https://gyazo.com/f2c0cddc192d0d6734c98334cd377f12

module ALU_tb();

reg [63:0] A, B;
reg [4:0] FS;
reg cin;

wire cout;
wire [63:0] result;
wire [3:0] status;


     
     Final_ALU dut (
     .A(A),
     .B(B),
     .FS(FS),
     .cin(cin),
     .cout(cout),
     .result(result),
     .status(status)
                    );

initial begin //A+1 //A=10 B=0
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000000000;
FS <= 5'b01000;
cin <= 1'b1;
end

always begin //A+B //A=10 B=16
#3
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000010000;
FS <= 5'b01000;
cin <= 1'd0;
#3;
end

always begin //A-B //A=10 B=16
#6
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000010000;
FS <= 5'b01001;
cin <= 1'd1;
#6; 
end

always begin //A-1 //A=10 , B=1
#9
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000000001;
FS <= 5'b01001;
cin <= 1'd1;
#9; 
end

always begin //-A //A=10 , B=0 (just twos complement of A)
#12
A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
B <= 64'b0000000000000000000000000000000000000000000000000000000000000000;
FS <= 5'b01010;
cin <= 1'd1;
#12; 
end


initial begin
#30 $finish;
end
endmodule

Solution

  • You should not make assignments to the same signal from multiple always blocks.

    One way to fix the problem is to use a fork/join inside an initial block, and get rid of the always keywords. This makes minimal changes to your code:

    initial begin
        fork
            begin //A+1 //A=10 B=0
            A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
            B <= 64'b0000000000000000000000000000000000000000000000000000000000000000;
            FS <= 5'b01000;
            cin <= 1'b1;
            end
    
            begin //A+B //A=10 B=16
            #3
            A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
            B <= 64'b0000000000000000000000000000000000000000000000000000000000010000;
            FS <= 5'b01000;
            cin <= 1'd0;
            #3;
            end
    
            begin //A-B //A=10 B=16
            #6
            A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
            B <= 64'b0000000000000000000000000000000000000000000000000000000000010000;
            FS <= 5'b01001;
            cin <= 1'd1;
            #6; 
            end
    
            begin //A-1 //A=10 , B=1
            #9
            A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
            B <= 64'b0000000000000000000000000000000000000000000000000000000000000001;
            FS <= 5'b01001;
            cin <= 1'd1;
            #9; 
            end
    
            begin //-A //A=10 , B=0 (just twos complement of A)
            #12
            A <= 64'b0000000000000000000000000000000000000000000000000000000000001010;
            B <= 64'b0000000000000000000000000000000000000000000000000000000000000000;
            FS <= 5'b01010;
            cin <= 1'd1;
            #12; 
            end
        join
    end
    

    A more traditional approach would be to get rid of the fork, and just drive all the groups of signals in sequence inside the initial block. Then you would have to adjust all your # delays accordingly.