I have observed a register access synchronization issue in one of my simulations and want to raise this in this forum in order to get feedback if this is a bug or a misusage in some way.
In the verification environment there are two register sequences running in parallel. One sequence is doing the DUT configuration and the other one is a noise sequence which switches between the different programming agents and produces some read traffic on all the programming interfaces.
The issue I have observed is that the programming sequence is doing a write to a register (AHB SEQ in the image below). During this access the noise sequence randomly selects the same register to do a read access (SPI SEQ in the image).
What is happening now is that the mirror(map:SPI) is waiting in the XatomicX task (uvm_reg.svh, line 2400 [Accellera-1800.2-2017-1.0 reference implementation]) for the semaphore (m_atomic). When the field write(map:AHB) finishes after some it calls the put() function of the semaphores two times. Once in the called do_write() of the parent uvm_reg (line 1775) and once in the do_write() of the uvm_reg_field itself (line 1182). This is done in "zero" time but the first put(1) already triggers the get(1) from the other thread (SPI) and the second put(1) increments the m_atomic semaphore to 1. This allows the next writes on the AHB thread to start while the read of the slower SPI thread is still ongoing.
In the image I tried to visualize the parallel sequences. The issue was causing the fourth write on the AHB interface to write wrong values to the internal register because it was based on older captured data. The timing is not accurate but chosen for better visualization (all arrows would otherwise be vertical arrows). The simulation was running with a recent version of the purple EDA vendor but the semaphore handling looks ok for me (first come, first serve).
I did some local modifications to uvm_reg.svh and with these changes the simulation was passing but I don't know if there are other side effect in scenarios which are not happening in our simulations.
These are the modifications I did:
Removed all XatomicX() calls from uvm_reg::do_write task (line: 1591, 1633, 1775 [Accellera-1800.2-2017-1.0 reference implementation])
Changed XatomicX task () (line 2435ff)
task uvm_reg::XatomicX(bit on);
if (on) begin // if (m_reg_process == m_process)
m_process = m_reg_process;
// Maybe a key was put back in by a spurious call to reset()
m_process = null;
I hope this topic is helpful.