Search the Community
Showing results for tags 'uvm_vreg'.
Found 2 results
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 address=0x1118e0 BD address=0x111960 BD address=0x1119e0 BD address=0x111a60 BD address=0x111ae0 BD address=0x111b60 BD address=0x111be0 128-byte offset I would expect BD address=0x1118e0 BD address=0x111900 BD address=0x111920 BD address=0x111940 BD address=0x111960 BD address=0x111980 BD 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 `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.
Are there any good examples/post out there for UVM Virtual Registers (UVM_VREG) implementation? I am currently evaluating and having issues with read/write to some the uvm_vreg_field's. Thanks in advance.