Jump to content

uvm_vreg increment issues

Recommended Posts

I am working an a block that requires two different type of buffer descriptors, let call them bd_base, bd_ext.

bd_base is size 8 bytes and bd_ext is size 32 bytes.  These are implemented on a 64 bit (8 byte) bus/memory.

For now I set the memory size to be 'd100000 with datasize 64bits.


I have ran a simulation with bd_base which vreg size is equal to the bus width and the increment to the next vreg[i+1] is correct.


However, when running with bd_ext with vreg size=32 bytes (4x the size of the bus), the increment to the next vreg[i+1] is off.  The offset for a particular example for each vreg is computed as:



BD[0] address=0x1118e0
BD[1] address=0x111960
BD[2] address=0x1119e0
BD[3] address=0x111a60
BD[4] address=0x111ae0
BD[5] address=0x111b60
BD[6] address=0x111be0

128-byte offset


I would expect


BD[0] address=0x1118e0
BD[1] address=0x111900
BD[2] address=0x111920
BD[3] address=0x111940
BD[4] address=0x111960
BD[5] address=0x111980
BD[6] address=0x1119a0

32-byte offset


Perhaps I am on the wrong trail, but I have narrowed down the issue to the following lines of code:


uvm_mem.svh (line 1328 - get_addresses function)


     addr = addr + map_info.mem_range.stride * offset;


uvm_reg_map.svh (line 890 - m_set_mem_offset function)


     stride = (max2 - max)/(mem.get_size()-1);


uvm_vreg.svh (lines 995-996 - allocate)


      int min_incr = (this.get_n_bytes()-1) / mem.get_n_bytes() + 1;
      if (incr == 0) incr = min_incr;


uvm_vreg.svh (lines 1073 - get_offset_in_memory function)


      return this.offset + idx * this.incr;


uvm_vreg.svh (lines 1353 - read task)


   addr = this.offset + (idx * this.incr);


From what I can see the uvm_mem stride variable already determines the correct offset and the incr variable is not needed to compute the next address/offset in the read or get_offset_in_memory function.  As a hack, I removed the (* this.incr - in red) in both and the simulation behaves as I expect.





Just some more info if needed:


1. I am currently using UVM package 1.1d


2. I am using define UVM_REG_DATA_WIDTH=64 for bd_base and UVM_REG_DATA_WIDTH=256 for bd_ext


3. Register bd_ext class:


class ral_vreg_enet_bd extends uvm_vreg;
    rand uvm_vreg_field READY;


   function new(string name = "ral_vreg_enet_bd", int unsigned n_bits = 256);
     super.new(name, n_bits);
      this.READY = uvm_vreg_field::type_id::create("READY",,get_full_name());


   endfunction: new


endclass : ral_vreg_enet_bd


class ral_block_bd extends uvm_reg_block;

  rand ral_vreg_bd bd;

  rand ral_mem_bd_sys_mem sys_mem;


   virtual function void build();
      this.default_map = create_map("", 0, 32, UVM_BIG_ENDIAN, 1);
      this.bd = ral_vreg_enet_bd::type_id::create("bd",,get_full_name());
      this.bd.configure(this, , 0, 'h0, 0);


      this.sys_mem = ral_mem_enet_bd_sys_mem::type_id::create("sys_mem",,get_full_name());
      this.sys_mem.configure(this, "");
      this.default_map.add_mem(this.sys_mem, `UVM_REG_ADDR_WIDTH'h0, "RW", 0);


   endfunction : build


endclass : ral_block_enet_bd


Thanks in advance.

Link to comment
Share on other sites

  • 1 year later...

I am having similar issues. I am using version 1.1c (not 1.1d) as in the previous post.


I am unable to get the uvm_reg to generate the correct address for accessing my uvm_mem "MEM_winhashmem". Details below.

Here is my code. 
1. I have defined '+define+UVM_REG_DATA_WIDTH=512' since some register X is 512b wide. 
2. I have a memory "MEM_winhashmem" that is 16K * 512b starting at offset 0x80000 I use a vreg to access it.

My Model
rand my_uvm_mem MEM_winhashmem;
rand my_uvm_vreg winhashmem;

virtual function void build();
this.MEM_winhashmem = new("MEM_winhashmem", 16384, 64); // Create a memory 16K * 8B
this.winhashmem = new;                                                            // Create a vreg
this.winhashmem.configure(this, MEM_winhashmem, 16384);        // Configure it for 16K RAM
this.default_map.add_mem(this.MEM_winhashmem, `UVM_REG_ADDR_WIDTH'h80000); // Set Memory base at 0x80000

My Sequence: Write to the first and the last location in the mem.
task body();
regmodel.winhashmem.write(0, status,512'hF000DCAFE); // Generates address 0x80000
regmodel.winhashmem.write(16383, status, 512'hAA55BBCC); // Generated address 0x17ffc0

since the memory is only 64b wide, I expected the address of index 16383 = 0x80000 + 0x1fff8 = 0x9FF8

However I am getting 0x80000 + 0x40 *16383 = 0x17FFC0. This is not correct.


Link to comment
Share on other sites

  • 5 years later...

I'm in the same boat as previous posts and those posts were in 2014 and 2015.

I'm using version 1.2 and the code in uvm_reg_map.svh in the method Xinit_address_mapX(), that calculates the stride is still the same.  Currently the database, m_mems_inf[], is defined as local, so it's difficult to override the stride value with derived classes.  Could there be support to have the user override the stride value prior to calling lock_model()?  If there's suggestions as how to go about doing this that would be great.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...