write与read的实现具体参见uvm源码中uvm_reg_map.svh,下文代码均来自该文件。
write的发送与返回:
rw_access.kind = rw.kind;
rw_access.addr = addrs[i];
rw_access.data = data;
rw_access.n_bits = (n_bits > bus_width*8) ? bus_width*8 : n_bits;
rw_access.byte_en = byte_en;
adapter.m_set_item(rw);
bus_req = adapter.reg2bus(rw_access);
adapter.m_set_item(null);
if (bus_req == null)
`uvm_fatal("RegMem",{"adapter [",adapter.get_name(),"] didnt return a bus transaction"});
bus_req.set_sequencer(sequencer);
rw.parent.start_item(bus_req,rw.prior);
if (rw.parent != null && i == 0)
rw.parent.mid_do(rw);
rw.parent.finish_item(bus_req);
bus_req.end_event.wait_on();
该部分为do_bus_write任务的内容。首先将读写类型、地址、数据等类型从rw加载到rw_access,通过adapter的reg2bus转换成transaction并发送。
if (adapter.provides_responses) begin
uvm_sequence_item bus_rsp;
uvm_access_e op;
// TODO: need to test for right trans type, if not put back in q
rw.parent.get_base_response(bus_rsp);
adapter.bus2reg(bus_rsp,rw_access);
end
else begin
adapter.bus2reg(bus_req,rw_access);
end
if (rw.parent != null && i == addrs.size()-1)
rw.parent.post_do(rw);
rw.status = rw_access.status;
然后是返回。这里的adapter的provides_responses代表是否支持rsp返回(需要在driver里实现put_response才能支持)。该变量为bit类型,为1就返回rsp,为0就不返回rsp,而是直接返回req。
个人理解:如果实现了put_response功能,则可以在rsp中返回改变的值,如果没有实现rsp但是想返回改变后的值就在req中直接修改。(write大多数情况应该不会管写入值吧?所以不在意即可。)
read的发送与返回:
rw_access.kind = rw.kind;
rw_access.addr = addrs[i];
rw_access.data = 'h0;
rw_access.byte_en = byte_en;
rw_access.n_bits = (n_bits > bus_width*8) ? bus_width*8 : n_bits;
adapter.m_set_item(rw);
bus_req = adapter.reg2bus(rw_access);
adapter.m_set_item(null);
if (bus_req == null)
`uvm_fatal("RegMem",{"adapter [",adapter.get_name(),"] didnt return a bus transaction"});
bus_req.set_sequencer(sequencer);
rw.parent.start_item(bus_req,rw.prior);
if (rw.parent != null && i == 0) begin
rw.parent.mid_do(rw);
end
rw.parent.finish_item(bus_req);
bus_req.end_event.wait_on();
发送与write类似,函数为do_bus_read,此处data默认0(还没开始读)。
if (adapter.provides_responses) begin
uvm_sequence_item bus_rsp;
uvm_access_e op;
// TODO: need to test for right trans type, if not put back in q
rw.parent.get_base_response(bus_rsp);
adapter.bus2reg(bus_rsp,rw_access);
end
else begin
adapter.bus2reg(bus_req,rw_access);
end
data = rw_access.data & ((1<<bus_width*8)-1);
rw.status = rw_access.status;
返回也与写类似,但读功能的话,需要把读取到的值返回,有rsp则从rsp里载入返回的读数据,没有rsp则需要在req中载入返回的读数据!!!
萌新粗鄙的理解,如果有错还请指出,如果是问更深层次的东西那我也不会orz。