UVM寄存器模型和存储器模型同时作用于一个接口

在为RTL添加UVM存储器模型时,如果模块的存储器和寄存器共用同一接口,通常通过bus_agent和bus_adapter进行处理。但当涉及显式预测时,问题出现,因为一个predictor不能关联两个model。解决方法是创建两个predictor,各自关联一个model,并共享同一个adapter,从而避免资源浪费。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家在为RTL添加UVM存储器模型的时候是否会遇到这样一种情况:这个模块的存储器配置和寄存器配置用的是同一个接口。那么我们对这个模块的寄存器模型和存储器模型该如何实现?

一般情况下因为是只有一个总线接口,所以我们只对它使用一套bus_agent即可。在对这个bus_agent配置一个可以用于寄存器模型和总线协议传输转换的转换器bus_adapter即可。如下图所示:

 这么设计是可以的。因为reg_model和mem_model提供给bus_adapter的数据类型没有差异,并且书写语法上不存在冲突。

reg_model_inst.default_map.set_sequencer(my_env.my_agent.my_seqr,bus_adapter_inst);

mem_model_inst.default_map.set_sequencer(my_env.my_agent.my_seqr,bus_adapter_inst);

 相当于对reg_model和mem_model同时设置了同一个agent下的同一个sequencer,并且关联了同一个bus_adapter。

可是一旦需要加入显式预测的代码进来就会出现问题。通常情况下我们的UVM环境中进行显式预测时候是这样设计的:

monitor接收到事务之后会把事务转发给predictor。再由predictor通过adapter把信息更新到reg_model的map中去,具体详见刘斌老师的红皮书。

如果要在我们这种一个接口同时对应寄存器模型和存储器模型的设计中使用显示预测,应该如何实现呢?

首先,一个predictor不能关联两个model。因为一个predictor只有一个map变量用于关联model中的map变量。

my_predictor = uvm_predictor #(bus_transaction)::type_id::create("my_predictor",this);

my_predictor.map = reg_model.default_map;

my_predictor.adapter = bus_adapter_inst;

 可以发现在一个您的my_predictor实例当中,它的map只能对应一个model的default_map。如果对应了reg_model则不能对应mem_model。如果在上面标红的语句下面再写一句:

my_predictor.map = mem_model.default_map;

 那么就会出现下面一句的map句柄覆盖了上面设置的map句柄。

所以加入显式预测的设计就应当设计成这样:

 这么设计的问题在于bus_adapter1和bus_adapter2在做的是同一件事情,他们的输入和输出都是处理的同一种格式的事务。为了减少不必要的资源占用,是否能够把两个adaper合并呢?

答案是可以。因为两个predictor能够关联同一个adapter。对两个predictor进行adapter句柄传递的时候可以传递同一个adapter的句柄。

my_predictor1.adapter = bus_adapter_inst;

my_predictor2.adapter = bus_adapter_inst;

所以,可以设计为以下这个结构:

 这样就可以对一个模块的同一个接口使用同时寄存器模型和存储器模型。

### SystemVerilog 中的后门(Backdoor)实现及用法 在 SystemVerilog 验证环境中,后门访问是一种绕过正常的数据路径直接访问寄存器或内存的技术。这种技术通常用于加速验证过程,尤其是在需要频繁更新或读取寄存器值的情况下。以下是关于后门实现及其用法的具体说明: #### 1. **后门访问的基本概念** 后门访问允许验证工程师通过特殊的机制直接修改或读取 DUT(Design Under Test)内部的状态变量,而不依赖于正常的前门接口逻辑。这种方式对于调试测试非常有用,因为它可以显著减少仿真时间[^5]。 #### 2. **后门访问的主要用途** - 当需要快速设置或获取特定寄存器或存储单元的值时。 - 在某些情况下,DUT 的寄存器模型可能过于复杂,或者其操作频率较低,不适合构建完整的 UVM RAL 流程。 - 提供一种替代方案,在不改变 RTL 设计的前提下完成必要的状态调整。 #### 3. **后门访问的实现方式** ##### a) 使用 `$readmemb` `$writememb` 这是两种常用的命令,分别用来从文件加载数据到存储器或将存储器的内容保存到文件中。例如: ```systemverilog initial begin $readmemb("mem_content.txt", dut.memory); // 将 mem_content.txt 文件内容写入 memory end ``` ##### b) 使用 `force` `release` 虽然传统的 `force`/`release` 方法可以直接作用于信号,但它存在一定的局限性——无法在 package 内部使用。因此推荐更灵活的方法如 uvm_hdl_force/uvm_hdl_release 来代替[^4]。 ##### c) 利用 `uvm_hdl_*` API 家族 UVM 提供了一组专门处理 HDL 层次结构的操作函数,其中包括但不限于以下几个重要成员: - `uvm_hdl_deposit(string path, bit value)`:将指定值赋给目标位置; - `uvm_hdl_force(string path, bit value)`:强制设定某条路径上的节点为固定数值直到调用 release; - `uvm_hdl_release(string path)` :解除之前施加在此处的所有 forces; 示例代码如下所示: ```systemverilog class my_test extends uvm_test; function void build_phase(uvm_phase phase); super.build_phase(phase); // Force the register to specific values via backdoor. uvm_hdl_force("dut.reg_a", 'hFF); // Release after some delay if necessary. #10ns; uvm_hdl_release("dut.reg_a"); endfunction : build_phase endclass : my_test ``` 这里需要注意的是,为了使上述代码生效,必须确保编译工具支持 `-debug_access+f` 参数以便正确解析包内的信号引用关系[^4]。 #### 4. **注意事项** 尽管后门访问带来了诸多便利之处,但也伴随着潜在风险: - 可能破坏原有设计意图,特别是在未充分理解整个系统工作原理前提下随意更改内部状态可能导致意外行为发生。 - 如果滥用可能会掩盖实际存在的 bug ,因为真实运行环境下不可能具备类似的特权级别来进行任意干预。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

常大胖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值