Backdoor Read consumes simulation time

Hi Forum,

I have a single CSR interface through which we read/write registers.The reg_block is accessible to different sequences & components through which we initiate register access.

In my simulation I observe that ISR sequence accesses TAIL_PTR register through UVM_FRONTDOOR at T: 5683.000ns. The read task unblocks at T: 5711.000ns.

My env initiates a backdoor read to the same TAIL_PTR register at T:5686.000ns ( i.e after the frontdoor read has been initiated )

This results in backdoor read completing at T:5711.000ns ( same time that frontdoor read completes )

Curious to know why the backdoor read consumes time, I decided to check code for class uvm_reg

I notice that each uvm_reg class has these 2 properties

local semaphore  m_atomic;

local bit        m_read_in_progress;

(1) During call to uvm_reg::read internally calls m_atomic.get(1)( via XatomicX(1)) and just before read completes, it calls m_atomic.put(1) ( via XatomicX(0) )

(2) uvm_reg::read calls uvm_reg::do_read which initially assigns m_read_in_progress = 1’b1 and just before uvm_reg::do_read completes it assigns m_read_in_progress = 1’b0

Due to these properties my backdoor read remains blocked till frontdoor read completes.

My intention is that the backdoor read should complete in 0 time so I have one possible solution to this

// Within top_tb
   wire [31:0] tail_ptr;
   assign tail_ptr = tb_top.rtl_top.<RTL_Hierarchy>.tail_ptr;

   assign my_intf.tail_ptr = tail_ptr;// my_intf is accessible via virtual intf

My env would directly read my_vintf.tail_ptr instead of reg_block.TAIL_PTR.read(status,rd_data,UVM_BACKDOOR);

[Q] I am curious if there is any RAL API based solution to this issue ?

Please note that ISR sequence would perform only frontdoor reads (to mimic a real FW) while the env is performing a backdoor read for some checker.

The order of the 2 reads ( env & ISR ) in a simulation is non-deterministic and depends on IO command flow i.e env could perform read before the ISR’s

Although the assign based solution would have worked, I would have needed to add the same assign based logic in SS_top_tb & Complex_top_tb as well

I went ahead with replacing reg_block.TAIL_PTR.read(status,rd_data,UVM_BACKDOOR); with if( !uvm_hdl_read(“tb_top.<RTL_hierarchy>.tail_ptr“,rd_data) ) `uvm_error(..)

Since the RTL hierarchy would vary based on SS / complex based simulations I have 3 calls to uvm_hdl_read based on respective compiler directives.

I do not see your code, but wrt your description I guess your problem arises due to differnt access of your registers. I’d recommend to clean-up your register access strategy and then it will work.

BTW, I do not understand why you are accessing your registers from the env. The register content should be modifiedd or read only from your test, i.e. register access only from the sequences. Then you’ll see your problem disappears.