UVM register model conflict

Hi Everyone,

I’m having an issue while using a UVM register model with an APB register adapter. I can post some code if required, but I think in this case it’ll be clearer if I just explain the problem:

If a sequence issues a frontdoor register read on the same clock edge as the DUT updates the register internally, then the read value returned over apb is the ‘old’ value as expected, while the register now holds the new value. This is fine, and the scoreboard anticipates this update and does a backdoor predict of kind UVM_PREDICT_WRITE.

However, the register model read function also performs a predict one cycle later, using the value which was just read. This reverts the newly updated mirrored value back to the old value, so now the register model is out of sync with the DUT.

I’ve had a look through the UVM code and can’t find a way to issue a frontdoor read access without it being followed by a prediction.

Does anyone here have any suggestions to get round this? I’d rather not avoid this occurrence altogether, as these sort of accesses are a genuine use case for the component.

Thanks,
Adam

In reply to bennetta1000:

Your question is a general question of modelling and function. You should always take care that 2 register operations do not happen at the same time. Consider you do a write in your case at the same time the register is updated internally by the DUT, you cannot be sure what value will be in the register after the operations. The consequence is to block one of these operation and execute them after the first one has been completed.

As far as I know, the register model will update itself once the transaction is over. You’ll see the effect (at least) one clock cycle later.

I’m assuming you’re using explicit prediction. If not, you should implement it. You’re seeing issues because you’re not synchronizing the modeling for DUT updates with the modeling for bus accesses.

You have a couple of options here:

  1. You can use a callback where you override post_predict(…). Inside post_predict(…) you can implement the logic you currently have in your scoreboard for the DUT update.

  2. You can chain your scoreboard to start work after the register model has settled from the bus read. The reg_predictor has a ‘reg_ap’ analysis port which sends out register items once it’s finished processing them. If you connect your scoreboard to this port, it will be notified when a register access finishes and you can implement your logic for modeling the DUT updates.

Thanks very much for both your responses.

I was unable to use the analysis port option you described as the access I have to wait for is a backdoor access, although that’s useful info I’m sure I’ll be using.

I ended up adding an associative array inside the config database along with a couple of functions to add, remove and check entries in this to track which registers have outstanding predictions. I add a register to the array before I call the predict method (in my scoreboard), and clear it in the post_predict call back. I can then delay the reads in any sequences until there are no outstanding predictions for the particular register.

I’ve tried to do this sort of check before by waiting for the parent registers “.is_busy()” to be zero, but it doesn’t seem to remain set throughout predictions.

This still doesn’t allow me to simulate reads at the same time as DUT internal updates, but it is a way around the problem.

I also started predicting with UVM_PREDICT_DIRECT as it warns me about potential conflicts when I do this sort of thing.

Hello bennetta1000,

I am actually new to uvm reg model recently.
As what I know uvm_reg_map has built in function set_auto_predict().
Which you can configure if you want to use do_predict method when you execute reg::write or reg::read. The do_predict method will update m_mirrored value in the reg_field. You can disable it as well. But in this way you need to update m_mirrored value in other ways.

Jeremy