Jump to content

UVM-REG Built-in Frontdoor and Bus byte enables computation issue?

Recommended Posts




While debugging a prediction error returned by "Bit Bashing Test Sequence", I came to read the uvm_reg_map::do_bus_read/do_bus_write methods which seems incorrect when it comes to computing the "byte enable" for the bus accesses (ie data member "byte_en" of the object of type uvm_bus_reg_op created by those functions)



I'm explain the issue that I think I found here-below, can you please give me your feedback (Am i wrong or not?)



My understanding about "uvm_reg_map::do_bus_read/do_bus_write" methods about is that

  • these methods are called when I request a frontdoor read/write access and  I don't supply a user frontdoor sequence.

  • these methods aimed at splitting the high level object uvm_reg_item into as many uvm_bus_reg_op as need on the real bus.

  • part of their role is to compute bus lane "byte enable" based on length and base address for a UVM_REG and length, base address and field offset in the reg for a UVM_FIELD


The "uvm_reg_map::do_bus_read/do_bus_write" code extract I'm interested in here given here below with focus on bus byte enable (rw_access.byte_en) computation:

task uvm_reg_map::do_bus_write (uvm_reg_item rw,
                                uvm_sequencer_base sequencer,
                                uvm_reg_adapter adapter);
  uvm_reg_byte_en_t  byte_en    = -1; // <= here the default value of byte_en is set to 'all ones'
  foreach (rw.value[val_idx]) begin: foreach_value
    /* calculate byte_enables */
    if (rw.element_kind == UVM_FIELD) begin // <= here byte_en is re-computed for UVM_FIELD only, not for UVM_REG
    foreach(addrs[i]) begin: foreach_addr
      uvm_reg_bus_op rw_access;
      if (rw.element_kind == UVM_FIELD) begin // <= here the slice of the computed byte_en corresponding to
                                              //    the current bus address is applied to the bus (rw_access.byte_en)
                                              //     for UVM_FIELD only, not for UVM_REG
        for (int z=0;z<bus_width;z++)
          rw_access.byte_en[z] = byte_en[curr_byte+z];
      rw_access.byte_en = byte_en; // <= here for UVM_REG, the default 'all ones' byte_en value is applied
                                   //    and  for UVM_REG, the correct value of rw_access.byte_en assigned above is
                                   //     erroneously overwritten
    end: foreach_addr
  end: foreach_value
endtask: do_bus_write

But the extract of code here-below shows two issues:

  • for a read/write to a UVM_REG, the byte_en is hard coded to "all ones" which seems incorrect to me in at least 2 cases:
    • if the bus is 4-Byte wide, a register R1 to write is 1-Byte wide and at address 1 and another register R0 is also 1-Byte wide and located at address 0, then trying to write R1, will also write R0.

    • if the bus is 4-Byte wide, a register R0 to write is 6-Byte wide and at address 0 and another register R1 is 1-Byte wide and located at address 6, then trying to write R0, will also write R1.

  • for a read/write to a UVM_FIELD, there's a complex computation of byte_en for the whole field , then another computation to extract the correct bus byte enable from the whole field byte_enable. Those 2 computations seems correct to me but the last assignemnt "rw_access.byte_en = byte_en;" breaks everything by systematically setting the same bus byte enables value. For a field spanning several bus addresses this is correct/acceptable for the first bus access but this incorrect for the other bus accesses.


Any feedback welcome, thank you


Share this post

Link to post
Share on other sites
We also have a similar issue here.
We have some register which are updated through byte_enables.
I have used the option: supports_byte_enable =1 for the register adapter.
And my scoreboarding logics updates the register values with approriate write value and the corresponding byte_en.
During read operation, I supply the appropriate byte_en; and expected no data checks for the byte having corresponding byte_en :0.

I can see in the corresponding register, the byte_en being set appropriately. But, the check is also happening.

Any body tried working with byte_en and had it succesful in implementation.

Rgards, Rajesh


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