[CU]reg model使用篇-uvm_reg常用操作part2(peek(读操作)/poke(写操作))

参考资料:

(1) 《UVM1.1应用指南及源代码分析》

1. peek/poke (path=BACKDOOR)

(1) peek/poke同属于后门访问register/register field方式, 与backdoor read/write类似,但是peek/poke不会模拟寄存器的行为;

(2)如果对一个只读寄存器进行write操作,无论是BACKDOOR还是FRONTDOOR,都不能写进去,而对其进行poke操作(即写操作),能写进去; 

(3) 如果对一个读清零的寄存器来说,进行read操作,无论是BACKDOOR还是FRONTDOOR, DUT中此寄存器的值在read操作之后都会变为0,而peek则会得到寄存器的值,但是DUT中寄存器的值依然保持不变;

1 regmodel.register.poke(status,value,.parent(this));
2 regmodel.register.peek(status,value,.parent(this));

(4) peek/poke操作完成后,寄存器模型会根据操作的结果更新期望值和镜像值(二者相等);

2. peek源码

(1) peek task内部会判断寄存器是否能进行BACKDOOR操作,比如是否设置该寄存器的hdl path;

(2) 主要是调用backdoor_rd task与do_predict(UVM_PREDICT_READ); do_predict用于更新register model中寄存器的相关值;

复制代码
 1 task uvm_reg::peek(output uvm_status_e      status,
 2                    output uvm_reg_data_t    value,
 3                    input  string            kind = "",
 4                    input  uvm_sequence_base parent = null,
 5                    input  uvm_object        extension = null,
 6                    input  string            fname = "",
 7                    input  int               lineno = 0);
 8 
 9    uvm_reg_backdoor bkdr = get_backdoor();
10    uvm_reg_item rw;
11 
12    m_fname = fname;
13    m_lineno = lineno;
14 
15    if (bkdr == null && !has_hdl_path(kind)) begin
16       `uvm_error("RegModel",
17         $sformatf("No backdoor access available to peek register \"%s\"",
18                   get_full_name()));
19       status = UVM_NOT_OK;
20       return;
21    end
22 
23    if(!m_is_locked_by_field)
24       XatomicX(1);
25 
26    // create an abstract transaction for this operation
27    rw = uvm_reg_item::type_id::create("mem_peek_item",,get_full_name());
28    rw.element      = this;
29    rw.path         = UVM_BACKDOOR;
30    rw.element_kind = UVM_REG;
31    rw.kind         = UVM_READ;
32    rw.bd_kind      = kind;
33    rw.parent       = parent;
34    rw.extension    = extension;
35    rw.fname        = fname;
36    rw.lineno       = lineno;
37 
38    if (bkdr != null)
39      bkdr.read(rw);
40    else
41      backdoor_read(rw);
42 
43    status = rw.status;
44    value = rw.value[0];
45    `uvm_info("RegModel", $sformatf("Peeked register \"%s\": 'h%h",
46                           get_full_name(), value),UVM_HIGH);
47 
48    do_predict(rw, UVM_PREDICT_READ);
49 
50    if (!m_is_locked_by_field)
51       XatomicX(0);
52 endtask: peek
复制代码

 3. poke源码

(1) 主要是调用backdoor_wr task与do_predict(UVM_PREDICT_WRITE);

(2) 本质上采用的是deposit函数;

(3) poke与backdoor write的区别在于后者在调用backdoor_write操作前,先使用backdoor的read读出原来寄存器的值,把读出来的值以及要写入的数值通过调用uvm_reg_field的XpredictX,得到一个新的值,这个值其实就完全模拟了FRONTDOOR行为的一个值,之后再把这个值写入,而前者则是直接写入;

复制代码
 1 task uvm_reg::poke(output uvm_status_e      status,
 2                    input  uvm_reg_data_t    value,
 3                    input  string            kind = "",
 4                    input  uvm_sequence_base parent = null,
 5                    input  uvm_object        extension = null,
 6                    input  string            fname = "",
 7                    input  int               lineno = 0);
 8 
 9    uvm_reg_backdoor bkdr = get_backdoor();
10    uvm_reg_item rw;
11 
12    m_fname = fname;
13    m_lineno = lineno;
14 
15 
16    if (bkdr == null && !has_hdl_path(kind)) begin
17       `uvm_error("RegModel",
18         {"No backdoor access available to poke register '",get_full_name(),"'"})
19       status = UVM_NOT_OK;
20       return;
21    end
22 
23    if (!m_is_locked_by_field)
24      XatomicX(1);
25 
26    // create an abstract transaction for this operation
27    rw = uvm_reg_item::type_id::create("reg_poke_item",,get_full_name());
28    rw.element      = this;
29    rw.path         = UVM_BACKDOOR;
30    rw.element_kind = UVM_REG;
31    rw.kind         = UVM_WRITE;
32    rw.bd_kind      = kind;
33    rw.value[0]     = value & ((1 << m_n_bits)-1);
34    rw.parent       = parent;
35    rw.extension    = extension;
36    rw.fname        = fname;
37    rw.lineno       = lineno;
38 
39    if (bkdr != null)
40      bkdr.write(rw);
41    else
42      backdoor_write(rw);
43 
44    status = rw.status;
45    `uvm_info("RegModel", $sformatf("Poked register \"%s\": 'h%h",
46                               get_full_name(), value),UVM_HIGH);
47 
48    do_predict(rw, UVM_PREDICT_WRITE);
49 
50    if (!m_is_locked_by_field)
51      XatomicX(0);
52 endtask: poke
复制代码

 

 

posted on   知北游。。  阅读(2426)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示