The UVM memory API can be used where an uvm_register can be used, and has the same API. A memory can be read or written. The memory is implemented using a sparse area, and so will be space efficient even for large address spaces, if the access to the memory is sparse.
The UVM Memory support big or little endian memory, and has available access routines either on the memory or on a containing address map
Sample usage: (See 09_memory_simple for the complete example)
task test1();
bytearray_t ba = '{1, 2, 3, 4, 5, 6, 7};
rm.poke_bytes(address, ba);
m_little.bus_read(ba, address);
rm.bus_read(ba, address);
read_ba = rm.peek_bytes(address, ba.size());
endtaskclass my_memory_little extends uvm_memory#(bit[31:0]);
function new(string name, uvm_component p,
bit [31:0] l_resetValue = 0);
super.new(name, p, l_resetValue);
endfunction
endclass
class my_memory_big extends uvm_memory#(bit[0:31]);
function new(string name, uvm_component p,
bit [0:31] l_resetValue = 0);
super.new(name, p, l_resetValue);
endfunction
endclass
class device2_rf extends my_device;
rand my_memory_little mem_little;
rand my_memory_big mem_big;
function new(string name, uvm_component p);
super.new(name, p);
mem_little = new("mem_little", this, 'h12345678);
mem_big = new("mem_big", this, 'h12345678);
// --------------------------------------
// Add the registers to the register file
// --------------------------------------
add_memory(mem_little.get_fullname(),
'h10000, 'h80000, mem_little);
add_memory(mem_big.get_fullname(),
'h90000, 'ha0000, mem_big);
endfunction
endclass