Hello,
I have a question regarding sampling in memory in register abstraction layer.
Lets say I have implemented sample() method in my uvm_mem memory and I want to read/write something from/to the memory at offset 5:
my_memory.read(status, 5, rdata, UVM_FRONTDOOR);
or
my_memory.write(status, 5, wdata, UVM_FRONTDOOR);
Method read()/write() then calls method do_read() or do_write() (all code snippets are taken from uvm_mem.svh):
task uvm_mem::read(output uvm_status_e status,
input uvm_reg_addr_t offset,
output uvm_reg_data_t value,
input uvm_path_e path = UVM_DEFAULT_PATH,
input uvm_reg_map map = null,
input uvm_sequence_base parent = null,
input int prior = -1,
input uvm_object extension = null,
input string fname = "",
input int lineno = 0);
uvm_reg_item rw;
rw = uvm_reg_item::type_id::create("mem_read",,get_full_name());
rw.element = this;
rw.element_kind = UVM_MEM;
rw.kind = UVM_READ;
rw.value[0] = 0;
rw.offset = offset;
rw.path = path;
rw.map = map;
rw.parent = parent;
rw.prior = prior;
rw.extension = extension;
rw.fname = fname;
rw.lineno = lineno;
do_read(rw);
status = rw.status;
value = rw.value[0];
endtask: read
Methods do_read() and do_write() then call method XsampleX():
task uvm_mem::do_read(uvm_reg_item rw);
// ...
// FRONTDOOR
if (rw.path == UVM_FRONTDOOR) begin
// ...
if (rw.status != UVM_NOT_OK)
for (int idx = rw.offset;
idx <= rw.offset + rw.value.size();
idx++) begin
XsampleX(map_info.mem_range.stride * idx, 1, rw.map);
m_parent.XsampleX(map_info.offset +
(map_info.mem_range.stride * idx),
1, rw.map);
end
end
// ...
endtask: do_read
And XsampleX() in turn calls my implemeted sample() method:
/*local*/ function void XsampleX(uvm_reg_addr_t addr,
bit is_read,
uvm_reg_map map);
sample(addr, is_read, map);
endfunction
My question is - wouldn’t memory invoke XsampleX() method one more time than it should? In case of reading/writing from/to offset 5, rw.offset is set to 5, rw.value.size() is 1 and methods in loop:
for (int idx = rw.offset;
idx <= rw.offset + rw.value.size();
idx++) begin
XsampleX(map_info.mem_range.stride * idx, 1, rw.map);
m_parent.XsampleX(map_info.offset +
(map_info.mem_range.stride * idx),
1, rw.map);
end
are executed twice? I.e. XsampleX() would be called with offset map_info.mem_range.stride * 5 and map_info.mem_range.stride * 6?
Thank you.