[UVM源代码研究] 谈谈寄存器模型中predict

本文详细探讨了在UVM环境中寄存器模型中predict函数的使用,包括自动预测的开启与关闭策略,以及手动使用predictor时的组件连接和数据流通过程。重点介绍了如何在connect_phase中配置自动预测,以及关闭自动预测时predictor的实例化与监控器的配合工作。

[UVM源代码研究] 谈谈寄存器模型中predict

我们在前面的文章 聊聊寄存器模型中的期望值(desired value)、镜像值(mirrored value)以及DUT中的实际值(actual value)的相关概念及方法 已经简单介绍了predict()函数以及auto_predict相关的概念,本文我们来详细介绍一下寄存器模型中如何正确引入predictor。

首先我们看下当我们环境中使用自动预测时,UVM源代码是如何工作的,我们需要在寄存器模型创建的组件的connect_phase()执行如下代码,将我们寄存器模型中的uvm_reg_map设置为自动预测。
在这里插入图片描述

我们来看看源代码中该函数的定义
在这里插入图片描述

这里的set_auto_predict()参数是可以为1和0的,参数值会直接赋给m_auto_predict,m_auto_predict为1会打开自动预测的功能。

如果打开自动预测的功能,那么通过uvm_reg_map来进行总线的的读写(包括UVM_FRONTDOOR和UVM_BACKDOOR)时,在读写task调用结束前,该寄存器的predict()函数会被自动调用以更新镜像值和期望值。

如果关闭自动预测功能,那么我们需要将uvm_reg_predictor实例化(或者继承一个我们自己的predictor),将predictor实例与我们monitor相连接(这里还需要我们monitor能够正确抓去总线数据),这样predictor就会实时的获取m

<think>我们面对的问题是如何在UVM验证平台中,在refm组件中监测寄存器模型的配置变化,并在检测到特定配置(如配置A)时发送携带控制信息的item到scb。 解决思路: 1. 理解需求:refm(reference model)需要监测寄存器模型(register model)的配置变化,特别是当配置变成特定的值(配置A)时,需要发送一个包含控制信息的transaction(item)到scoreboard(scb)。 2. UVM寄存器模型提供了回调机制(callbacks)和内置的预测器(predictor)来跟踪寄存器的读写操作。我们可以利用这些机制来监测寄存器变化。 3. 具体实现步骤: a. 在refm中创建并注册一个回调类(callback),该回调类可以附加到寄存器模型上。 b. 在回调类中,覆盖特定的回调方法(如post_predict),以便在寄存器值发生变化时得到通知。 c. 在回调方法中,检查变化的寄存器值是否为配置A。如果是,则触发一个事件(event)或者直接调用refm的方法来发送item。 d. 在refm中,当检测到配置A时,创建并发送一个包含控制信息的item到scb。通常,refm和scb之间通过TLM端口(如analysis port)连接。 详细步骤: 步骤1:创建一个回调类,继承自`uvm_reg_cb`。 步骤2:在回调类中覆盖`post_predict`方法。这个方法会在寄存器值被预测(更新)后调用。 步骤3:在`post_predict`方法中,检查寄存器的值是否为配置A。注意:配置A可能对应一个特定的寄存器字段值。 步骤4:如果检测到配置A,则触发一个事件(该事件在refm中定义)或者直接调用refm的一个方法(通过传递refm的句柄)。 步骤5:在refm中,定义该事件的处理方法(或者直接定义被回调调用的方法),在该方法中创建并发送item到scb。 另外,我们需要将回调注册到特定的寄存器(或寄存器字段)上。 注意:寄存器模型更新可能发生在两个地方:前门访问(通过总线)和后门访问(直接写入)。回调机制可以捕获这两种更新。 实现代码框架: 1. 定义回调类: ```systemverilog class reg_callback extends uvm_reg_cb; // 注册到工厂 `uvm_object_utils(reg_callback) // 需要有一个refm的句柄,以便在回调中通知refm refm refm_inst; function new(string name = "reg_callback"); super.new(name); endfunction // 覆盖post_predict函数 virtual function void post_predict(input uvm_reg_field fld, input uvm_reg_data_t previous, inout uvm_reg_data_t value, input uvm_predict_e kind, input uvm_path_e path, input uvm_reg_map map); // 检查是否是特定的寄存器字段,并且值是否变为配置A // 假设我们关注的寄存器字段名为"config_field",配置A的值为8'hA5 if (fld.get_name() == "config_field") begin if (value == 8'hA5) begin // 配置A的值 // 通知refm_inst refm_inst.config_a_triggered(); end end endfunction endclass ``` 2. 在refm中: ```systemverilog class refm extends uvm_component; `uvm_component_utils(refm) // 分析端口,用于发送item到scb uvm_analysis_port #(ctrl_item) ap; // 回调实例 reg_callback cb; function new(string name, uvm_component parent); super.new(name, parent); ap = new("ap", this); endfunction // 在build_phase中创建回调并注册 function void build_phase(uvm_phase phase); super.build_phase(phase); cb = reg_callback::type_id::create("cb"); cb.refm_inst = this; // 设置回调中的refm句柄 endfunction // 连接阶段:将回调添加到特定的寄存器字段上 function void connect_phase(uvm_phase phase); super.connect_phase(phase); // 假设寄存器模型中有一个名为reg_block的block,其中有一个寄存器config_reg,该寄存器中有一个字段config_field uvm_reg_field fld = reg_block.config_reg.config_field; // 将回调注册到该字段 uvm_reg_cb::add(fld, cb); endfunction // 当配置A被检测到时调用的函数 function void config_a_triggered(); ctrl_item item = ctrl_item::type_id::create("item"); // 设置控制信息 item.ctrl_info = ...; // 根据需求设置 ap.write(item); // 发送到scb endfunction endclass ``` 3. 在scb中,我们需要有一个analysis imp端口来接收这个item,并做相应的检查。 注意事项: - 确保寄存器模型(reg_block)在refm中是可访问的(通常通过config_db获取)。 - 回调函数中,我们只检查了字段名,实际应用中可能还需要检查寄存器名或者映射的地址,以避免不同寄存器块中有同名字段。 - 配置A的值需要根据具体设计定义。 替代方法:使用观察者模式(observer pattern)在寄存器模型中注册观察者(observer),但UVM寄存器模型本身没有内置观察者模式,所以回调是标准做法。 另一种方法是使用UVM寄存器模型的`uvm_reg_predictor`,但predictor主要用于更新寄存器模型的值,而不是用于这种监测。因此,回调更合适。 总结:通过寄存器回调,我们可以在寄存器值变化时得到通知,然后根据变化的值触发相应的动作。 §§相关问题§§ 1. UVM回调机制在寄存器模型中的应用还有哪些常见场景? 2. 如何避免在回调函数中产生竞争条件? 3. 如果寄存器模型通过后门访问更新,回调函数是否同样有效?</think>在UVM验证平台中,实现`refm`监测寄存器模型配置变化并在检测到特定配置时发送`item`到`scb`,可通过以下步骤完成: --- ### **1. 创建回调类监测寄存器变化** 利用UVM寄存器模型的**回调机制**监测字段变化: ```systemverilog class reg_field_callback extends uvm_reg_cb; `uvm_object_utils(reg_field_callback) refm refm_inst; // 指向refm的句柄 function new(string name = "reg_field_callback"); super.new(name); endfunction // 覆盖post_predict回调 virtual function void post_predict( input uvm_reg_field fld, input uvm_reg_data_t previous, inout uvm_reg_data_t value, input uvm_predict_e kind, input uvm_path_e path, input uvm_reg_map map ); if (fld.get_name() == "CONFIG_A") begin // 监测特定字段 if (value != previous) begin // 值发生变化 refm_inst.handle_config_change(value); // 通知refm end end endfunction endclass ``` --- ### **2. 在refm中实现配置处理** 在`refm`中绑定回调并定义处理逻辑: ```systemverilog class refm extends uvm_component; `uvm_component_utils(refm) uvm_analysis_port #(ctrl_item) ap_port; // 连接scb的分析端口 reg_block regmodel; // 寄存器模型句柄 reg_field_callback cb; function void build_phase(uvm_phase phase); super.build_phase(phase); ap_port = new("ap_port", this); cb = reg_field_callback::type_id::create("cb"); cb.refm_inst = this; // 传递refm句柄 endfunction function void connect_phase(uvm_phase phase); // 获取寄存器模型(通过config_db) if (!uvm_config_db#(reg_block)::get(this, "", "regmodel", regmodel)) `uvm_fatal("REG_ERR", "Register model not found") // 注册回调到特定字段 uvm_reg_cb::add(regmodel.CONFIG_A_FIELD, cb); // CONFIG_A_FIELD为目标字段 endfunction // 配置变化处理函数 function void handle_config_change(uvm_reg_data_t new_val); if (new_val == `CONFIG_A_VALUE) begin // 检测到配置A ctrl_item item = ctrl_item::type_id::create("item"); item.control_info = new_val; // 携带控制信息 ap_port.write(item); // 发送到scb end endfunction endclass ``` --- ### **3. Scoreboard(scb)接收item** 在`scb`中通过分析端口接收并处理`item`: ```systemverilog class scb extends uvm_component; `uvm_component_utils(scb) uvm_analysis_imp #(ctrl_item, scb) item_imp; function void build_phase(uvm_phase phase); item_imp = new("item_imp", this); endfunction // 处理接收到的item function void write(ctrl_item item); `uvm_info("CFG_CHANGE", $sformatf("Received config: 0x%0h", item.control_info), UVM_MEDIUM) // 在此添加验证逻辑(如比对预期值) endfunction endclass ``` --- ### **4. 环境连接** 在`env`中连接`refm`和`scb`: ```systemverilog class env extends uvm_env; refm refm_inst; scb scb_inst; function void connect_phase(uvm_phase phase); refm_inst.ap_port.connect(scb_inst.item_imp); // 端口连接 endfunction endclass ``` --- ### **关键机制说明** 1. **回调触发条件** - `post_predict`在寄存器值**预测更新**时触发(前门/后门访问均有效)[^1]。 - 通过`previous`和`value`比对确保仅处理**实际变化**。 2. **控制信息传递** - `ctrl_item`需自定义,包含配置值和相关控制信号。 - 通过`uvm_analysis_port`实现**非阻塞传输**,避免时序问题。 3. **同步处理** 若配置变化需响应时序逻辑,可在`refm`中使用`uvm_event`触发后续任务。 --- ### **注意事项** - **寄存器模型访问**:确保通过`config_db`正确传递寄存器模型句柄。 - **字段命名**:实际字段名(如`CONFIG_A_FIELD`)需与RTL设计一致。 - **配置值匹配**:`CONFIG_A_VALUE`需定义为宏或参数,避免硬编码。 --- ### **应用场景** 此方法适用于: - 动态配置驱动的验证场景(如电源管理、工作模式切换)。 - 寄存器依赖项验证(如字段A变化时需检查字段B)。 - 实时错误注入控制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值