微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 微电子和IC设计 > IC验证交流 > 求助:UVM中peek与poke的问题

求助:UVM中peek与poke的问题

时间:10-02 整理:3721RD 点击:
各位:
正在学习UVM中对register model的backdoor访问。使用peek的时候有点问题,想不出到底为什么,于是上来请教大家。
我在my_test中的run_phase中这样写:

  1. phase.raise_objection(this);
  2. begin
  3. uvm_status_estatus;
  4. addr=32'h0;
  5. data=32'h0;
  6. repeat(1024) begin
  7. reg_tb0.apb_slave.n_ram.write(status.addr,data);
  8. addr++;
  9. data +=2'b10;
  10. end
  11. addr=32'h0;
  12. repeat(1024) begin
  13. reg_tb0.apb_slave.n_ram.peek(status,addr,data);
  14. reg_tb0.apb_slave.n_ram.read(status,addr,data1);
  15. $display("peek @%0h=%0h\t\tread @%0h=%0h",addr,data1,addr,data);
  16. addr++;
  17. end
  18. end
  19. phase.drop_objection(this);

复制代码

可是,结果跑出的结果如下:
peek @0=d712read @0=1
peek @1=1read @1=11
peek @2=1read @2=21
peek @3=1read @3=31
peek @4=1read @4=41
peek @5=1read @5=51
peek @6=1read @6=61
peek @7=1read @7=71
. . .. . .
peek @3ff=1read @3ff=3ff1
我有点不大明白,为什么peek出来的所有的数都不对呀?

没人知道么?
自己顶上去。

这个算是backdoor访问么?怎么看着像一般的寄存器访问操作呢?

后来如何解决的,问题出在哪里?

peek使用的hierarchy写错了。就是写register model的时候

也在做memory的backdoor访问操作,不是很清楚uvm_mem.svh源文件中的函数peak/poke和write/read的区别,write/read不支持backdoor访问 ? 另外hdl_path和地址之间是如何绑定的,hdl_path的作用是什么,在函数中视乎不需要指定这个路径?
求小编再给解释一下……
另外是否有backdoor的访问方式的example,能不能给个参考。谢谢

也在做memory的backdoor访问操作,不是很清楚uvm_mem.svh源文件中的函数peak/poke和write/read的区别,write/read不支持backdoor访问 ? 另外hdl_path和地址之间是如何绑定的,hdl_path的作用是什么,在函数中视乎不需要指定这个路径?
求小编再给解释一下……
另外是否有backdoor的访问方式的example,能不能给个参考。谢谢

也在做memory的backdoor访问操作,不是很清楚uvm_mem.svh源文件中的函数peak/poke和write/read的区别,write/read不支持backdoor访问 ? 另外hdl_path和地址之间是如何绑定的,hdl_path的作用是什么,在函数中视乎不需要指定这个路径?
求小编再给解释一下……
另外是否有backdoor的访问方式的example,能不能给个参考。谢谢

backdoor是直接通过hdl_path访问寄存器或者ram,就像平时写的“u_dut.apb_slave.regA=16‘h45"一样。这样访问是不消耗仿真时间的,而read/write是通过总线访问需要消耗仿真时间。hdl_path那个我忘了,应该是没有什么关系吧,如果需要backdoor访问,则需要指定正确的hdl_path,不然就会像我这个问题一样了。我出现这个问题是地址对了,但是hdl_path错了,因此前后门的数值对不上。

在uvm1.1c的库文件中,uvm_mem.svh的1434行起 有下面的这段代码,想请问,这里面的rw.path就是所谓的hdl_path了,是如何传递进来,以及和offset进行绑定的呢?
谢谢
task uvm_mem::write(output uvm_status_estatus,
inputuvm_reg_addr_toffset,
inputuvm_reg_data_tvalue,
inputuvm_path_epath = UVM_DEFAULT_PATH,
inputuvm_reg_mapmap = null,
inputuvm_sequence_base parent = null,
inputintprior = -1,
inputuvm_objectextension = null,
inputstringfname = "",
inputintlineno = 0);
// create an abstract transaction for this operation
uvm_reg_item rw = uvm_reg_item::type_id::create("mem_write",,get_full_name());
rw.element= this;
rw.element_kind = UVM_MEM;
rw.kind= UVM_WRITE;
rw.offset= offset;
rw.value[0]= value;
rw.path= path;
rw.map= map;
rw.parent= parent;
rw.prior= prior;
rw.extension= extension;
rw.fname= fname;
rw.lineno= lineno;
do_write(rw);
status = rw.status;
endtask: write



在uvm1.1c的库文件中,uvm_mem.svh的1434行起 有下面的这段代码,想请问,这里面的rw.path就是所谓的hdl_path了,是如何传递进来,以及和offset进行绑定的呢?
谢谢
task uvm_mem::write(output uvm_status_estatus,
inputuvm_reg_addr_toffset,
inputuvm_reg_data_tvalue,
inputuvm_path_epath = UVM_DEFAULT_PATH,
inputuvm_reg_mapmap = null,
inputuvm_sequence_base parent = null,
inputintprior = -1,
inputuvm_objectextension = null,
inputstringfname = "",
inputintlineno = 0);
// create an abstract transaction for this operation
uvm_reg_item rw = uvm_reg_item::type_id::create("mem_write",,get_full_name());
rw.element= this;
rw.element_kind = UVM_MEM;
rw.kind= UVM_WRITE;
rw.offset= offset;
rw.value[0]= value;
rw.path= path;
rw.map= map;
rw.parent= parent;
rw.prior= prior;
rw.extension= extension;
rw.fname= fname;
rw.lineno= lineno;
do_write(rw);
status = rw.status;
endtask: write

应该就是的。不大明白你说的跟offset进行绑定是什么意思,反正当时我使用register model的时候,需要用configure函数对其指定hdl_path

  1. virtual function void build_phase(uvm_phase phase);
  2. super.build_phase(phase);
  3. demo_cfg = demo_config::type_id::create("demo_cfg");
  4. vdo_cfg= config1::type_id::create("vdo_cfg");
  5. uvm_config_object::set(this,"apb0*","cfg",demo_cfg);
  6. uvm_config_object::set(this,"apb0.slave[0]*","cfg",demo_cfg.slave_configs[0]);
  7. uvm_config_object::set(this,"vdo0*","cfg",vdo_cfg);
  8. uvm_config_object::set(this,"vdo0.slave[0]","cfg",vdo_cfg.slave_configs[0]);
  9. apb0=apb_env::type_id::create("apb0",this);
  10. vdo0=vdo_env::type_id::create("vdo0",this);

  11. regmodel=ral_block_apb_basic_block::type_id::create("regmodel",,get_full_name());
  12. regmodel.configure(null,"top.u_dut.apb_slave");
  13. regmodel.build();
  14. regmodel.lock_model();
  15. regmodel.reset();
  16. reg_sqr_adapter=reg_to_apb_adapter::type_id::create("reg_sqr_adapter",,get_full_name());
  17. mon_sqr_adapter=reg_to_apb_adapter::type_id::create("mon_sqr_adapter",,get_full_name());
  18. reg_predictor=new("reg_predictor",this);

  19. endfunction : build_phase

复制代码

好像我用的configure中省掉了一些参数,我记得这个东西很长的参数列表。
这个regmodel是个ram,而它的地址的指定,是在为其建立模型的时候:

  1. class ral_mem_MY_RAM extends uvm_mem;
  2. //function new(string name = "MY_RAM");
  3. function new(string name = "n_ram");
  4. super.new(name, `UVM_REG_ADDR_WIDTH'h400, 32, "RW", build_coverage(UVM_NO_COVERAGE));
  5. endfunction
  6. virtual function void build();
  7. endfunction: build

  8. `uvm_object_utils(ral_mem_MY_RAM)

  9. endclass : ral_mem_MY_RAM

复制代码

好像是new函数中需要指定(好像是大小),然后将其映射到default_map上去的时候要指定起始地址?时间太久我不大记得了。

  1. class ral_block_apb_basic_block extends uvm_reg_block;
  2. //rand ral_mem_MY_RAM MY_RAM;
  3. rand ral_mem_MY_RAM n_ram;

  4. function new(string name = "apb_slave");
  5. super.new(name, build_coverage(UVM_NO_COVERAGE));
  6. endfunction: new

  7. virtual function void build();
  8. this.default_map = create_map("", 0, 4, UVM_LITTLE_ENDIAN);
  9. //this.MY_RAM = ral_mem_MY_RAM::type_id::create("MY_RAM");
  10. //this.MY_RAM.build();
  11. //this.MY_RAM.configure(this, "");
  12. //this.default_map.add_mem(this.MY_RAM, `UVM_REG_ADDR_WIDTH'h0, "RW", 0);
  13. this.n_ram = ral_mem_MY_RAM::type_id::create("n_ram");
  14. this.n_ram.build();
  15. this.n_ram.configure(this,"n_ram.mem");
  16. this.default_map.add_mem(this.n_ram,`UVM_REG_ADDR_WIDTH'h0,"RW",0);
  17. //add_hdl_path("dut","apb_slave");
  18. endfunction : build
  19. function display();
  20. $display({"***************now is ",get_full_name()});
  21. endfunction : display

  22. `uvm_object_utils(ral_block_apb_basic_block)

  23. endclass : ral_block_apb_basic_block

复制代码

小编看了你上面的代码还有一个问题,你在config里指明了 HDL 路径
但是在peek/poke 中有一个地方是判断是否使用backdoor访问的,uvm_mem.svh中的源码 如下
task uvm_mem::peek(output uvm_status_estatus,
inputuvm_reg_addr_toffset,
output uvm_reg_data_tvalue,
inputstringkind = "",
inputuvm_sequence_base parent = null,
inputuvm_objectextension = null,
inputstringfname = "",
inputintlineno = 0);
uvm_reg_backdoor bkdr = get_backdoor();
uvm_reg_item rw;
m_fname = fname;
m_lineno = lineno;
if (bkdr == null && !has_hdl_path(kind)) begin
`uvm_error("RegModel", {"No backdoor access available in memory '",
get_full_name(),"'"})
status = UVM_NOT_OK;
return;
end
这里面的bkdr = get_backdoor 该怎样保证不为 null ?谢谢

小编,看了你的这段代码,有个问题不理解,调用uvm_peek函数时, 下面的这个如何设置get_backdoor
task uvm_mem::peek(output uvm_status_estatus,
inputuvm_reg_addr_toffset,
output uvm_reg_data_tvalue,
inputstringkind = "",
inputuvm_sequence_base parent = null,
inputuvm_objectextension = null,
inputstringfname = "",
inputintlineno = 0);
uvm_reg_backdoor bkdr = get_backdoor();
uvm_reg_item rw;
m_fname = fname;
m_lineno = lineno;
if (bkdr == null && !has_hdl_path(kind)) begin
`uvm_error("RegModel", {"No backdoor access available in memory '",
get_full_name(),"'"})
status = UVM_NOT_OK;
return;
end
怎么设置get_backdoor才能够让bkdr != null ?
谢谢

小编,看了你的这段代码,有个问题不理解,调用uvm_peek函数时, 下面的这个如何设置get_backdoor
task uvm_mem::peek(output uvm_status_estatus,
inputuvm_reg_addr_toffset,
output uvm_reg_data_tvalue,
inputstringkind = "",
inputuvm_sequence_base parent = null,
inputuvm_objectextension = null,
inputstringfname = "",
inputintlineno = 0);
uvm_reg_backdoor bkdr = get_backdoor();
uvm_reg_item rw;
m_fname = fname;
m_lineno = lineno;
if (bkdr == null && !has_hdl_path(kind)) begin
`uvm_error("RegModel", {"No backdoor access available in memory '",
get_full_name(),"'"})
status = UVM_NOT_OK;
return;
end
怎么设置get_backdoor才能够让bkdr != null ?
谢谢

小编,看了你的这段代码,有个问题不理解,调用uvm_peek函数时, 下面的这个如何设置get_backdoor
task uvm_mem::peek(output uvm_status_estatus,
inputuvm_reg_addr_toffset,
output uvm_reg_data_tvalue,
inputstringkind = "",
inputuvm_sequence_base parent = null,
inputuvm_objectextension = null,
inputstringfname = "",
inputintlineno = 0);
uvm_reg_backdoor bkdr = get_backdoor();
uvm_reg_item rw;
m_fname = fname;
m_lineno = lineno;
if (bkdr == null && !has_hdl_path(kind)) begin
`uvm_error("RegModel", {"No backdoor access available in memory '",
get_full_name(),"'"})
status = UVM_NOT_OK;
return;
end
怎么设置get_backdoor才能够让bkdr != null ?
谢谢

我觉得应该是确保你设定的hdl_path是正确的,畅通的。
因为get_backdoor是'get the user-defined backdoor for all registers in this block'
如果你定义的backdoor路径是错误的,或者没有指定backdoor路径,那么,肯定返回的是null值。
我是这样理解的,不知道你有什么想法呢?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top