Jump to content
Sign in to follow this  
joniale

Maybe an error on UVM 1.1d for uvm_reg_map.svh class

Recommended Posts

Hi ,

To whom may correspond

I think there is some kind of error in the UVM 1.1d register model.

I have been experimenting with the UVM register model and i have seen the following code in uvm_reg_map.svh

 

task uvm_reg_map::do_bus_write (uvm_reg_item rw,
                                uvm_sequencer_base sequencer,
                                uvm_reg_adapter adapter);

  uvm_reg_addr_t     addrs[$];
  uvm_reg_map        system_map = get_root_map();
  int unsigned       bus_width  = get_n_bytes();
  uvm_reg_byte_en_t  byte_en    = -1;
  uvm_reg_map_info   map_info;
  int                n_bits;
  int                lsb;
  int                skip;
  int unsigned       curr_byte;
  int                n_access_extra, n_access;
  int               n_bits_init;

  Xget_bus_infoX(rw, map_info, n_bits_init, lsb, skip);
  addrs=map_info.addr;

  // if a memory, adjust addresses based on offset
  if (rw.element_kind == UVM_MEM)
    foreach (addrs[i])
      addrs[i] = addrs[i] + map_info.mem_range.stride * rw.offset;

  foreach (rw.value[val_idx]) begin: foreach_value

     uvm_reg_data_t value = rw.value[val_idx];

    /* calculate byte_enables */
    if (rw.element_kind == UVM_FIELD) begin
      int temp_be;
      int idx;
      n_access_extra = lsb%(bus_width*8);                
      n_access = n_access_extra + n_bits_init;
      temp_be = n_access_extra;
      value = value << n_access_extra;
      while(temp_be >= 8) begin
         byte_en[idx++] = 0;
         temp_be -= 8;
      end                        
      temp_be += n_bits_init;
      while(temp_be > 0) begin
         byte_en[idx++] = 1;
         temp_be -= 8;
      end
      byte_en &= (1<<idx)-1;
      for (int i=0; i<skip; i++)
        void'(addrs.pop_front());
      while (addrs.size() > (n_bits_init/(bus_width*8) + 1))
        void'(addrs.pop_back());
    end
    curr_byte=0;
    n_bits= n_bits_init;     

 

The code continues but the interesting part is already there.

Lets assume we have a register with 4 bytes and 1byte per address granularity (byte_addressing).

Now, we do a FIELD access of 8bits length (the first byte of a register). The field is configured "individual_accessible, so UVM should only access that FIELD. The reg2bus should generate that byte request to be written.

In other words, the vector "addrs" should have only one byte address.

Going to the code, i see that initially the addrs has the 4 address ( the whole register) and when it comes to the "if (rw.element_kind == UVM_FIELD) begin" and it will pop_back()/remove all the exceeding bytes that doesn't need to complete "n_bits_init" of the field access.

The problem is here:

UVM has
//while (addrs.size() > (n_bits_init/(bus_width*8) + 1))
and i think it should be
 while (addrs.size() > ((n_bits_init-1)/(bus_width*8) + 1))  //ejonalv possible error in UVM? check

That is because in case we want to write 8 bits, it will calculate 8/8+1=2 address in the UVM version, but in fact it should require only 1 address.

This is of course applicable for the READ variation.

Did i misunderstand something? It is very hard to go through the register model without proper documentation in the code.

I am looking forward your answer

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  

×