Can anyone help me debug this code to verify single port ram?

I’m trying to verify the functionality of single port ram and not getting the data_out as expected , im only getting the value of data_in on data_out at the clock cycle when write_en goes low and all previous values are missed.

ram module -

module single_port_ram (
  
  input logic clk ,
  
 // input logic reset ,
  
  input logic write_en ,
  
  input logic [7:0] data_in ,
  
  input logic [4:0] addr ,
  
  output logic [7:0] data_out 
  
);
  
  
  logic [7:0] ram [32];
  logic [4:0] temp;
  
  
  always_ff @(posedge clk ) begin
    
    if (write_en)
      
      ram[addr] <=data_in;
    
    else 
      
      temp<=ram[addr];
      
      end
      
      
      assign data_out = temp;
    
    
    endmodule

testbench code -

module tb;
  
    logic clk ;
  
 //  logic reset ;
  
   logic write_en ;
  
  logic [7:0] data_in ;
  
  logic [4:0] addr ;
  
  logic [7:0] data_out  ;
  
  
  logic [7:0] data_q[$] ;
  logic [7:0] data;
  
  
  
  
  single_port_ram dut (.clk(clk),  .write_en(write_en) , .data_in(data_in) , .addr(addr) , .data_out(data_out));
  
 always #10 clk= ~clk;
  
  initial begin
    
    clk =0;
   /* 
    reset = 1'b1 ;
    
    #20;
    
    reset = 1'b0;
   */ 
  end
  
  initial begin
    
    repeat(5)  begin
      
     
    @(posedge clk ) write_en = 1;
      
    addr=$urandom();
    data_in = $urandom();
    data_q.push_back(data_in); 
      
    end
    
    repeat(5)  begin
    
   @(posedge clk) write_en = 1'b0;
      data = data_q.pop_front();
      
      if(data_out!=data) $display ("comparison failed");
      else
        $display ("pass");
      
      
    end
    
    repeat(5) begin
      
      @(posedge clk) write_en = 1'b1;
      
    addr=$urandom();
    data_in = $urandom();
    data_q.push_back(data_in);     
      
      
       end
    
    repeat(5)  begin
    
      @(posedge clk) write_en = 1'b0;
     data = data_q.pop_front();
      
      if(data_out!=data) $display("comparison failed") ;
      
      else
        
        $display("pass");
    
    end
    
  end

  
  
 
    initial begin
      
      $dumpfile("dump.vcd");
      $dumpvars();
      
    end
    
    initial begin
      #500 ;
      $finish();
    end
    
    
    endmodule

eda playground link - EDA Playground

Issues in the RAM Module:

  • Incorrect Temporary Register Size:
    The temporary register temp is declared as logic [4:0] temp, but it should match the width of data_out, which is 8 bits.
    Fix: Change temp to logic [7:0] temp.

Issues in the Testbench:

  • Random Address Generation Issue:
    The use of $urandom() without range constraints may generate out-of-bounds addresses (greater than 31).
    Fix: Use addr = $urandom_range(0, 31) to ensure valid addresses.

  • Read Address Not Set in Testbench:
    Both data and addresses are stored in a queue, and the read address is not explicitly set before reading.
    Fix: Ensure addr is properly assigned before initiating a read operation.

  • Comparison Logic Timing Issue:
    The expected value (data_q.pop_front()) is being compared immediately after write_en is deasserted. However, data_out updates on the next clock cycle.
    Fix: Introduce a delay before checking data_out using @(posedge clk).

Thanks man , i don’t know how i missed that temp[4:0] but with your suggestions of testbench changes i am able to get the results