Mirroring in Register Abstraction Layer

Hi,

I have a DUT and a Register Model integrated to it.
I went through the Register Layer lectures available for Advanced UVM and obtained the following understanding.
“When I write a register via frontdoor, both the desired and mirrorred values inside the register model gets updated after the transaction.So a mirror() after either a read or a write on a register that does not have any live bits should always PASS.”

In my case, I did a write operation to a register and then a mirror() on the same register.I get the following error.
UVM_ERROR /eda/questa_10.1d/questasim/verilog_src/uvm-1.1c/src/reg/uvm_reg.svh(2884) @ 225: reporter [RegModel] Register “reg_model.clock_addend” value read from DUT (0x0000000000000000) does not match mirrored value (0x0000000012341234)

UVM_INFO /eda/questa_10.1d/questasim/verilog_src/uvm-1.1c/src/reg/uvm_reg.svh(2903) @ 225: reporter [RegModel] Field clock_addend (reg_model.clock_addend[31:0]) mismatch read=32’h0 mirrored=32’h12341234

But the DUT register is updated correctly.
On the otherhand when I do the operations in the following order ie write(), read() and mirror() respectively I dont get the error.
Does mirror() compare the desired value and mirrored value? If that is the case, in the first scenario that I mentioned, I guess my desired value in the register model is not updated. What could be the reason for this? Kindly correct me if my understanding is wrong.

Thanks

Hi Dhivya,

Calling mirror() function actually lunch a read() on the register and compare the read data to the mirrored value which was set at the end of the previous write call.

In your case it seems that the write command works correctly because your mirrored value is 32’h12341234.
Your problem seems to reside during the read call. The value read is 32’h0!
Have you check the read value from the bus (APB or other) in a wave?
If you see the correct value (32’h12341234) it means that you have an issue with you reg2bus_adapter or the way to update your mirrored values!

Check also that you haven’t done some mistakes with the register access type (for instance write_only instead of read_write).

Regards,
Xavier

In reply to xavier.correcher:

I was telling about write->mirror scenario in the previous thread.
I would like to tell about write->read scenario so that debugging could be easier.
The register that I work upon has “RW” as the access mode.
The following is the body task of my sequence.

task body();

uvm_reg_data_t value;
uvm_reg_status_e status;

reg_model.clock_addend.write(status,'h12341234,.parent(this));
#100;
reg_model.clock_addend.read(status,value,.parent(this));
$display("RAL read value = %x",value);

endtask

Upon execution I got the following output:
RAL read value = 0000000000000000

The following are my observations from the waveform.
1.The DUT register has been written correctly via a write cycle.
2.A read operation has been initiated and the correct data is available on the read_bus.
3.Also I gave some print statements in the adapter to ensure if the read transaction has been captured and I get the correct read value being printed.

On the otherhand, when I do a read again (ie two reads after a write) the correct value is getting printed. ie RAL read value = 0000000012341234
In such a case, what could be the possible reason for the read data for not going inside the variable “value” of read task during the first call even though the read data is available in the read bus of the DUT soon afte its first call.

// The post was updated as :
I would also like to add that subsequent writes and reads give the correct value.
That is, this problem occurs only for the first read. If I write a different value to the register and read it, the correct value is updated.

In reply to Dhivya:

I would like to add the following:

  1. write->read
  2. write->mirror
    Both of these work for different write values(ie they dont throw any UVM_ERROR and they return the correct read value) except for the first time.

Only during the first time,

  1. write->read doesnt return the correct read value
  2. write->mirror throws out error saying “read value and mirrorred value doesnt match”
    In both these cases I have ensured that the test starts after the release of reset.

Also,
During the first time,

  1. write-> read → #delay mirror works without throwing uvm_error but returns wrong read value
  2. write-> read → read ->mirror works without throwing uvm_error but first read returns wrong value whereas second read returns correct value

In reply to Dhivya:

Very strange…
Difficult to help you without knowing the environment you put in place.
Get another look to the “register layer course” to compare with your env or try to print your bus and reg transaction. I seems that the reg transaction is sending or receiving too late!?
I implemented the register layer some times ago and I did not get into such difficulties…

I know this question has been answered. but i have a few questions about mirroring. I hope you will be able to clear those.

  1. Why do we require a mirror variable and a mirror option in RAL? Basically all it does is just keep a track of the DUT register variables. What exactly is the function of mirror and why do we need it

Thanks in advance.

In reply to Katri:

However, with mirror we can replicate the register value that should be there in the rtl in our testbench.
Now, the next question that will rise is why do we need to mirror the value if we can get the register value by performing the read?

  • Yes, that is true but if we have a mirrored value we don’t require to perform a read transaction every time we want get the register value.
    Hopefully, this answered your question to some extent

In reply to shrestha_verif:

Thanks Shrestha… it is a little clear now.

I have another question. How does the mirror work?? I mean how does it get the value from the RTL? If it also performs the read, then the whole process would be same as directly performing a read action isnt it.

thanks in advance.

In reply to Katri:

RAL does not mirror the value of RTL on its own. A change in RTL register doesn’t ensure that the RAL model register will replicate the change. Vice verse, if you have called ralmodel.randomize(), it doesn’t mean the RAL values are updated on the RTL registers. We will have to update these values
Suppose you called a reset function to reset DUT. In this case all the registers in RTL will shift to their default value ,however, this won’t be updated in the RAL model. To update RAL model we will have to call ralmodel.reset() function.
Typically, RAL model gets updated if either on a register is read or write. There is one more fuction , ralmodel.update() replicates the RAL value on the rtl.

In reply to shrestha_verif:

Thanks Shrestha. I got it now

And one more thing, how are the desired values and mirror values automatically updated in back door access?? In back door access, we access the values through the hierarchical path. But how does that update the mirrored and desired values automatically?

Thanks

In reply to Katri:

Can you please tell me the meaning of Desired values and mirrored values?

hello all,

I am getting both mirrored and desired values. But for mirrored values am getting with some delay and am unable to figure it out. Can some one please help me in this issue.

Thanks in advance.

In reply to naveen-y:

set changes the desired value.
update writes the desired value to the DUT if desired value != mirrored value.

In reply to Katri:

In reply to shrestha_verif:
Thanks Shrestha. I got it now
And one more thing, how are the desired values and mirror values automatically updated in back door access?? In back door access, we access the values through the hierarchical path. But how does that update the mirrored and desired values automatically?
Thanks

With backdoor access using mirror (for both read/write), poke (for backdoor read), peek (for backdoor write) function, the do_predict function will be called after reading/writing successfully. Thus, mirror and desired value will be updated automatically.

In reply to chr_sue:

In reply to naveen-y:
set changes the desired value.
update writes the desired value to the DUT if desired value != mirrored value.

hi,
Thank you for replying. I have connected monitor(with analysis port) to the predictor(bus-in, implementation port in predictor) and I have done the set_auto_predict(1), in the ‘env’, which updates the mirrored_values automatically. And I have not used any ‘set’ and ‘update’ methods any where.
And one more doubt I have is that, I am getting the desired and mirrored values of different registers at different times. For example, if am getting the
desired value of ‘ctrl’ reg at time t, i get
mirrored value of ‘ctrl’ reg at time t+20 and
desired value of ‘div’ reg at time t+20, i get
mirrored value of ‘div’ reg at time t+40 and so on for the other registers(in the order in which I have written in sequence by using ‘write’ and ‘read’ register access methods).
Is it correct if we get the values of all the registers at different times?
And is it correct if we get the desired and mirrored values at different times?
Is it compulsory that we should get all the values at the same time?

In reply to naveen-y:

If you connected bus monitor to predictor then you don’t need to set_auto_predict(1).
Basically,

  • Write operation will update desired/mirrored value as follow:
  1. Update desired mirror with written value using set(value) function
  2. Perform write operation
  3. Update both desired and mirrored value using do_predict function (if auto_predict is enable, and write operation is successfull)
  4. Write transaction on the monitor bus will be captured to predictor (in your case), then desired and mirrored value will be updated one more time using do_predict function in predictor.
  • Read operation will update desired/mirrored value as follow:
  1. Perform read operation
  2. Read transaction on the monitor bus will be captured to predictor, then desired and mirrored value will be updated using do_predict function in predictor.
  3. Update both desired and mirrored value using do_predict function (if auto_predict is enable, and read operation is successful)

Please follow the flow above to apply your case. From my experience, maybe you get mirrored/desired value too fast then you see the mismatched. To avoid a conflict when updating desired/mirrored value in predictor and in get/set function, you should add some waited times after write/read function to make sure the operation in predictor is successful first before you can get these values.

In reply to cuonghl:

Thank you,
I will try that and get back to you.

Thanks,
Naveen.