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[i] = addr[i] + 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
`uvm_object_utils(ral_vreg_enet_bd)
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.sys_mem.build();
this.default_map.add_mem(this.sys_mem, `UVM_REG_ADDR_WIDTH'h0, "RW", 0);
endfunction : build
`uvm_object_utils(ral_block_enet_bd)
endclass : ral_block_enet_bd
Thanks in advance.