Getting previous read data instead of current one

The below piece of code is trying to write incrementing data into incrementing locations… also trying to read back the data… so In the display statement I expect the read data to match the write data but I see that it is actually showing previous read data not the current one, what could be the reason ? and possibly how to fix it… Thanks


``` verilog

class write_read_sequence extends uvm_sequence#(mem_seq_item);
         `uvm_object_utils(write_read_sequence)
         //Constructor
         function new(string name = "write_read_sequence");
                 super.new(name);
         endfunction

         virtual task body();
         for (int adr = 0; adr<16;adr++) begin
             `uvm_do_with(req,{req.wr_en==1;req.addr == adr; req.wdata == adr;})
             `uvm_do_with(req,{req.rd_en==1;req.addr == adr;})
             $display("====== RDATA [%h] in sequence is %h ===== ",req.addr,req.rdata);
         end
         endtask
endclass

In reply to Subrahmanyam:
Here is the output I see

====== RDATA [0] in sequence is 00 ===== 
====== RDATA [1] in sequence is 00 ===== 
====== RDATA [2] in sequence is 01 ===== 
====== RDATA [3] in sequence is 02 ===== 
====== RDATA [4] in sequence is 03 ===== 
====== RDATA [5] in sequence is 04 ===== 
====== RDATA [6] in sequence is 05 ===== 
====== RDATA [7] in sequence is 06 ===== 
====== RDATA [8] in sequence is 07 ===== 
====== RDATA [9] in sequence is 08 =====

In reply to Subrahmanyam:

The problem would be in your driver code. Does it wait for a response?

In reply to dave_59:

Here is the driver code …


``` verilog

       virtual task run_phase(uvm_phase phase);
             forever begin
                     seq_item_port.get_next_item(req);
                     drive();
                     seq_item_port.item_done();
             end
         endtask

         virtual task drive();
         $display("----- driving the transacation ---------");
         req.print();
         `DRIV_IF.wr_en<=0;
         `DRIV_IF.rd_en<=0;
         @(posedge vif.DRIVER.clk);
         `DRIV_IF.addr <= req.addr;
         if(req.wr_en) begin
                 `DRIV_IF.wr_en <= req.wr_en;
                 `DRIV_IF.wdata <= req.wdata;
                 @(posedge vif.DRIVER.clk);
         end
         if(req.rd_en) begin
                 `DRIV_IF.rd_en <= req.rd_en;
                 @(posedge vif.DRIVER.clk);
                 `DRIV_IF.rd_en <= 0;
                 @(posedge vif.DRIVER.clk);
                 req.rdata = `DRIV_IF.rdata;
         end
         $display("-----------------");
         endtask

In reply to Subrahmanyam:

Hi Dave,
Any idea ??

Siva

In reply to Subrahmanyam:

It depends on your interface protocol. You are assuming the read data is available after 1 clock cycle. Because you do not specify which interface you have this might be wrong.

In reply to chr_sue:

Yes my DUT returns the data in cycle … basically I am using this playground exaample UTB C - verificationguide.com - EDA Playground and playing around the code to get back the data into sequence from sequencer…

In reply to Subrahmanyam:

It works percfectly. It’s doing what you are instructing. It writes to addr = 0 and it reads from addr = 3, which has still the reset value.
Where is your problem.

In reply to Subrahmanyam:

In reply to chr_sue:
Yes my DUT returns the data in cycle … basically I am using this playground exaample https://www.edaplayground.com/x/5r89 and playing around the code to get back the data into sequence from sequencer…

See here my example

BTW only components will be created in the build_phase,but not objects like sequences.

In reply to chr_sue:

sir, Iam working with system verilog. even I am facing same problem, when am reading addr at particular clock cycle but it is retrieving in other clock cycle. so there is a one clock cycle delay when am retrieving my read data. please let me know how to synchronize read data with read address. thanks

Your text to link here…

In reply to subbarao:

That’s correct what you are seeing. In 1 clock cycle you are passing the address and in the following clock cycle you see the read data, because it is sampled by 1 clock cycle. I do not understand your problem.

In reply to chr_sue:

Thanks sir… i understood now…

In reply to chr_sue:

In reply to Subrahmanyam:
It works percfectly. It’s doing what you are instructing. It writes to addr = 0 and it reads from addr = 3, which has still the reset value.
Where is your problem.

Hi ,
Here is my problem…
Here are the values I write into the addresses
Addr = 0, data = 0
Addr = 1, data = 1
Addr = 2, data = 2
so on … bit when I read back I get
Addr = 0, data = 0
Addr = 1, data = 0
Addr = 2, data = 1
Addr = 3, data = 2
so on …
inspite of driver waiting for one cycle to get the read data, the sequence is getting back the previous data… Is my problem clear?

In reply to Subrahmanyam:

Which sequence are you running?

In reply to Subrahmanyam:

I made a few useful modifications.
See he write_read_sequence.

In reply to chr_sue:

I am running the same sequence you mentioned “write_read_sequence” … Thanks for the modifications where you are shuffling the order of the addresses which are being read … I would like to print the value that is read from the memory in the write_read_sequence itself …

In reply to Subrahmanyam:

Then you have to create a response in the driver and pass it back to the sequence. It is not really helpful to do this. You could directly print he response in the driver.

In reply to Subrahmanyam:

In reply to chr_sue:
I am running the same sequence you mentioned “write_read_sequence” … Thanks for the modifications where you are shuffling the order of the addresses which are being read … I would like to print the value that is read from the memory in the write_read_sequence itself …

Please find here a solution passing back the response to the sequence.

BTW I fixed a few things in your driver/monitor. You are using clocking blocks. Then you have to synchronize on theme and not on the clock signal.