What is the problem with below code?

module r_w_mem();
reg [7:0] addr;
reg [31:0] data_i;
reg [31:0] data_o;
reg[31:0] mem [7:0];
initial begin
fork
write();
read();
join
#100
$finish;
end
task write();
begin
addr=$random;
data_i=$random;
for(int i=0;i<2;i++)begin
mem[addr]<=data_i;
$display("Write data[%0d]=%0d",addr,data_i);
end
endtask


task read();
begin
for(int i=0;i<2;i++)begin
data_o<=mem[addr];
$display("Read data[%0d]=%0d",addr,data_i);
end
endtask

Read data is always x and the address location is also not as per write address.

In reply to rustyguru:

You’ve forked off two threads in parallel with no timing. There’s nothing to synchronize execution of the two loops, so the simulator is free to execute the read loop first before the wright loop ever executes.

To get this to work you need to introduce a clock or some sort of delay so that the write happens before the read.

In reply to rustyguru:

Try:

initial begin
//fork
write();
read();
//join
#100
$finish;
end

It should work

In reply to kangrh007:

*In reply to rustyguru:*It should work

That will not work. The read() task would only read the last addr.

In reply to dave_59:

In reply to kangrh007:
That will not work. The read() task would only read the last addr.

Yes it wont work, but even if I am providing some sort of delay in between write and read task , then also it is reading last address only and read value is x.

In reply to rustyguru:

module r_w_mem();
  logic [7:0] addr;
  logic [31:0] data_i;
  logic [31:0] data_o;
  logic [31:0] mem [255:0]; // not [7:0]
  bit clk;
always #1 clk= !clk;
initial begin
  fork
    write();
    read();
  join
  #100 $finish;  
end
task write(); 
  for(int i=0;i<2;i++) @(posedge clk) begin
    addr=$urandom;  
    data_i=$urandom;
    mem[addr]<=data_i;
    $display("Write data[%0d]=%0d",addr,data_i);
  end
endtask
 
task read();
  for(int i=0;i<2;i++) @(negedge clk) begin
    data_o<=mem[addr];
    $strobe("Read data[%0d]=%0d",addr,data_o);
  end
endtask
endmodule