'Retrieving Data from Register File (Unpacked Array)

I try to write a register file for updating and retrieving data from it. Here is my code

module RegisterFile(input logic         clk
                   ,input logic         M_we // M_we is write enabled
                   ,input logic         M_re // M_re is read enabled
                   ,input logic [2:0]   M_add // Memory Adress
                   ,input logic [3:0]   M_wd // Memory write data
                   ,output logic [3:0]  M_rd  // Memory read data
                   ,output logic [3:0] rfOut [15:0]);
    
    logic [3:0] rf [7:0]; // There will be seven slot on the register file
    logic [3:0] readData;
    
    always_ff@(posedge clk) begin
        if(M_we) begin
            rf[M_add] <= M_wd;
        end
        
        else if(M_re) begin
            readData <= rf[M_add];
        end                                             
    end
    
    assign M_rd = readData;
    
                           
endmodule

There are seven slots on the register file to hold 4-bit data on each slot. I thought that there must be two signals to whether the register file operate for reading or writing. For writing, I used M_we, and for reading, I used M_re. Then I wrote this testbench.

module RegisterFile_Simulation();

    logic clk;
    logic M_we;
    logic M_re;
    logic [2:0] M_add;
    logic [3:0] M_wd;
    logic [3:0] M_rd;
    logic [3:0] rfOut [15:0];
    
    RegisterFile DUT(clk, M_we, M_re, M_add, M_wd, M_rd, rfOut);
    
    always begin
        clk = 0;
        #10;
        clk = 1;
        #10;
    end
    
    initial begin
        M_we = 1;
        M_re = 1;
        
        M_add = 0;
        M_wd = 1;
        #10;
        M_we = 0;
        
        for(int b = 0; b < 8; b++) begin
            M_add = b;
            #10;
        end
    end

endmodule

In this testbench, I expected to see 1 at the rf[0] as the M_add will be 0 with the first iteration of the 0. On the other hand, I only get xxxx for the result which means it is undefined. I thought that my testbench is wrong, but it is not working with the other testbenches as well. Why cannot this code block set rf[0] = 1 ?



Solution 1:[1]

You have a race condition in the testbench. The design (RegisterFile) does not sample the M_we signal as 1.

You should drive your synchronous inputs in the testbench the same way you drive your signals in the design: using @(posedge clk) and using nonblocking assignments (<=):

initial begin
    M_we = 1;
    M_re = 1;        
    M_add = 0;
    M_wd = 1;

    @(posedge clk);
    M_we <= 0;
    
    for(int b = 0; b < 8; b++) begin
        @(posedge clk);
        M_add <= b;
    end
end

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1