1

I am using Quartus Prime Lite 19.1.0.

module memory_address_register1 #(
    parameter                       ADDR_WIDTH = 4
)(
    input                           clk, rst, load,
    input       [ADDR_WIDTH-1:0]    add_in,
    output reg     [ADDR_WIDTH-1:0]    add_out
);


    always @(posedge clk) begin
        if (rst) begin
            add_out <= 4'b0000;
        end else if (load) begin
            add_out <= add_in;
        end else begin
            add_out <= add_out;
        end
    end
    
endmodule

module mmr_tb();
    reg clk, rst, load;
    reg [3:0] add_in;
    wire [3:0] add_out;
    
    initial begin
        clk <= 1'b0;
        rst <= 1'b0;
        load <= 1'b0;
    end
    
    memory_address_register1 mmr (.clk(clk), .rst(rst), .load(load), .add_in(add_in), .add_out(add_out));
    
    always #10 clk = ~clk;
    
    initial begin
        #20 add_in <= 4'd2;
        #10 add_in <= 4'd3;
        load <= 1'b1;
        #30 add_in <= 4'd6;
        #10 load <= 1'b1;
        
    end

endmodule

It the output (add_out) accurate? Should the output (add_out) at t=70.0ns be "6" or "7"?

  1. If the expected output is "6", can anyone explain why is that?

img1: posedge clk output value from previous clk cycle

img2: posedge clk output value from previous clk cycle

I ran the testbench using modelsim, and I am able to get the expected output I wanted (output on the exact clock edge), but is it expected? https://i.stack.imgur.com/GVmKO.jpg

toolic
  • 57,801
  • 17
  • 75
  • 117
Blaco
  • 109
  • 8

1 Answers1

2

You have potential race conditions in your testbench code. You should drive all your inputs in the testbench the same way you drive them in the design:

  1. Use nonblocking assignments (<=) instead of blocking assignments (=)
  2. Use @(posedge clk) instead of # delays

This will guarantee that your inputs will be synchronous to the clock. This also assures that pulsewidths of your inputs are a multiple of the clock period. Some of your signals are half a period wide or 1.5 periods wide.

module mmr_tb();
    reg clk, rst, load;
    reg [3:0] add_in;
    wire [3:0] add_out;
    
    initial begin
        clk    <= 0;
        rst    <= 1;
        load   <= 0;
        add_in <= 0;
        repeat (2) @(posedge clk);
        rst <= 0;
        forever @(posedge clk) begin
            add_in <= add_in + 1;
        end
    end
    
    memory_address_register1 mmr (.clk(clk), .rst(rst), .load(load), .add_in(add_in), .add_out(add_out));
    
    always #10 clk = ~clk;
    
    initial begin
        repeat (4) @(posedge clk); load <= ~load;
        repeat (1) @(posedge clk); load <= ~load;
        repeat (4) @(posedge clk); load <= ~load;
        repeat (1) @(posedge clk); load <= ~load;
        repeat (3) @(posedge clk); $finish;
    end
endmodule

waves

toolic
  • 57,801
  • 17
  • 75
  • 117