Sign in to follow this  
Followers 0
joniale

UVM register model: Field access and bus2reg

3 posts in this topic

Dear Accellera developers,

 

I have been working with the register model since some weeks. I have tried to understand how the adapters were supposed to be used for all the possible combinations of accesses and register definitions.

After those weeks I still have some questions.

Lets assume we have a register of 32bits  with 3 fields. The databytes per address granularity is 1 databyte per increment of address. In other words, each address increment corresponds to one data byte written . That means that a 32bit register comprises 4 address per register.

We have a protocol like AXI that supports byte enable masking.

The first field covers only the first data byte of the register.

When writing the first field of the register, then our AXI monitor sends one xfer that writes only one byte to the reg_predictor.

On the other side, the register predictor that uses the bus2reg  function of the adapter, will see that bus access and will try to update the register.

I have seen that the UVM library calls bus2reg only once per bus TLM channel transfer.

I have seen that the register that outputs bus2reg starts a bus collection process. 

I have seen that the register update will be done if:

              1) the address is inside a register address:  if (rw.addr == map_info.addr) begin

              2) the bus collector reached the number of bytes needed to complete a register:  if (predict_info.addr.num() == map_info.addr.size()) begin

I have seen that in case the bus collector doesn´t have all the needed xfers to complete a register (if (predict_info.addr.num() == map_info.addr.size()) begin), a break will stop the loop over the addresses.

From the previous information, I guess that the intention with the "write" function of the predictor was, that the monitor provides as many xfers that the collector will always complete all the bytes inside a register. Is that correct? 

Now come the question with the summary.

The write function of the register predictor will be called only once. 

The bus2reg of the register predictor will be called only once.

The collector of the write function in the register predictor will collect only once.

The  condition: "if (predict_info.addr.num() == map_info.addr.size()" will never be true because the register collected field has a size of 1 byte and the total register has a size of 4 bytes.

At least it will not be true until the 4 predict_info addresses are received in the write function.

How it is supposed to update fields within the UVM register model?

We think we can come around to this problem if we call the write() function for each byte with 3 byte_enables set to zero and one set to 1. Is the monitor supposed to split the 32bit AXI data on the bus into bytes to send those to the register predictor?

Could you explain me the concept behind field write and field update of the register model in this context. Are my assumptions and understanding wrong? 

Any help would be appreciated. Do you have an example for this situation?

Looking forward your answer

Joachim and Jonathan

 

Share this post


Link to post
Share on other sites
  1. In case you are using a direct VC burst

    I guess the way to do this is by expanding/padding the original partial access to a register and make it access the whole register. The padding can make use of byte_en to flag those extra bytes as dummy. This can be done, either in the monitor or by overwritting the uvm_reg_predictor class (creating a split/padding adapter function).
     
  2. In case you use the UVM register write function to write a field of a register:
    With the configuration 1byte per address and a register of 4 bytes. First field in the first byte.

    The reason why the monitor sends only one byte to the reg_predictor is because the reg2bus function is not forced to do a complete register access. There is a configuration parameter for the fields called " individually_accessible "

    If two fields share their  address they should have both "individually_accessible"=0  (set to zero/non individual accessible). Once this is done, UVM will read previous complete register value and make an OR with the new field value. This is in order to keep previous values in a complete register access.

 

The documentation says:// individually_accessible shows if this field can be written individually, i.e. without affecting other fields in the containing register.

"individually_accessible" is  the last parameter in the configure function of the field: .

e.g. this.BLK_PKG_TEST3_F.configure(this, 10, 20, "RW", 0, 10'h3F, 1, 1, 0);

When you do that you will receive the following warning:  UVM_WARNING verilog_src/uvm-1.1d/src/reg/uvm_reg_field.svh(1716) @ 900000 ps: reporter [RegModel] Individual field access not available for field 'ral_sys_airqc_rm_top0.info_registers.BLK_PKG_TEST.BLK_PKG_TEST0_F'. Accessing complete register instead.

With this, UVM will force the adapter reg2bus to generate a bus that write the whole register. Other fields will have previous values merged with your new field value so that the complete register access doesn't modify other fields.  (forcing reg2bus full register will solve the bus2reg collecting part)

 

Something important to remark is that the definition of "individually_accessible" is in fact not applicable to our example.

In our example, each field is "individually accessible"  because we have a "bytes per address" of 1 byte and each field is in a different byte address. That means this is somehow a hack or a trick and not really a good solution. Besidesyou will have a nasty WARNING.

Next questions are,

 why UVM has not different warning/error codes inside register model to be able to mask those warnings individually?

why UVM has not implemented a general solution that takes in mind direct VC register updates (e.g. other VHDL block) and not limiting its usage to their UVM register access functions?

 

Share this post


Link to post
Share on other sites

You can avoid the display of the warning coming from the regmodel using the UVM component function

uvm_top.set_report_severity_id_action(UVM_WARNING, "RegModel", UVM_NO_ACTION);

However, this will disable all warnings coming from RegModel ID.

Best regards,

Jonathan

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0