首页 > 解决方案 > 我是否需要避免在 UVM 中使用 OOMR(模块外引用)代码?

问题描述

我正在设置一个新的 UVM 代码,并且想在我的 uvm 代码中制作 OOMR 代​​码,我是否需要避免 UVM 中的 OOMR(模块外引用)代码概念?如果不需要它,我应该在 OOMR 代​​码之前和之后检查什么?

例子

tb.top.env.dut.a = 1;
a = tb.top.env.dut.b    

如果您在运行后看到链接,则会出现一些错误消息。

    a=u_sub.b; 
            |
ncvlog: *E,ILLHIN (add.sv,6|12): illegal location for a hierarchical name (in a package).

为了防止这个问题,我想我必须避免喜欢这种代码风格。但我不确定我对这个问题的理解是什么。

不确定,但据我所知,一些 EDA 工具支持该问题。例如,cadence($xm_mirror)、Mentor、VCS...

所以我想知道我是否需要避免这些OOMR代码风格?或者我应该只使用 EDA 工具的帮助。当我在庞大的复杂 uvm 代码中遇到类似错误时,如何解决此问题?

标签: system-veriloguvm

解决方案


在 SystemVerilog 包中使用 Verilog 分层引用或 OOMR 是非法的。这是因为首先编译 SystemVerilog 包,其编译方式与 SystemVerilog 代码的其余部分不同。

通常,您会将类放在一个包中。因此,您将避免在类中使用 Verilog 分层引用或 OOMR。

显然,您需要将类中的代码连接到 DUT 端口(例如驱动程序和监视器),并且您可能还想探测 DUT 内部信号。每种情况的解决方案都不同。

对于连接到 DUT 端口,大多数人会使用 SystemVerilog接口。您在与 DUT 相同的层次结构级别实例化接口,并以某种方式将接口成员连接到 DUT,例如使用 Verilog Hierarchical References 或 OOMR),例如:

interface TB_hook (input bit clk);
  logic Stim, Resp;
  ...
endinterface

module harness;
  bit clk;
  TB_hook DUT_intf (.clk);
  Sys_Top DUT (
    .clk  (clk), 
    .Stim (DUT_intf.Stim),
    .Resp (DUT_intf.Resp), 
    ...

然后在某个类(驱动程序、监视器或代理)中,您可以使用 SystemVerilog虚拟接口连接到接口实例。虚拟接口是一种特殊的 SystemVerilog 变量,可以将 Verilog 分层引用或 OOMR 存储到接口实例或 modport。因为您必须在运行时分配该值,所以可以在包中编译虚拟接口(但分配值的代码不能在包中),例如:

class driver;
  virtual TB_hook V;
  task drive (input bit data);
    V.Stim <= data;

然后,在某些 Verilog module(可能是顶级模块)中,您将为虚拟接口变量分配一个值。您可以直接执行此操作,例如:

module TB_top;
  top_env env;
  ...
  initial begin
    ...
    env.agent.driver.V = harness.DUT_intf;

但大多数人会使用 UVM 配置数据库:

module TB_top;
  top_env env;
  ...
  initial begin
    ...
    uvm_config_db #(virtual TB_hook)::set(null, "*", "DUT_intf", harness.DUT_intf);

class driver;
  virtual TB_hook V;
  ...
  function void connect_phase(uvm_phase phase);
    ...
    ok = uvm_config_db#(virtual TB_hook)::get(this, "", "DUT_intf", V);

您可以使用 modport 和/或时钟模块来增强此技术。

为了探测内部 DUT 信号,UVM 寄存器层提供了一些工具。为此有一组功能/任务:

  • uvm_hdl_check_path– 检查 HDL 路径是否存在
  • uvm_hdl_deposit– 将值存入 RTL
  • uvm_hdl_force– 强制一个值进入 RTL
  • uvm_hdl_force_time– 在指定的持续时间内强制一个值
  • uvm_hdl_release– 释放一个强制值
  • uvm_hdl_release_and_read– 释放一个强制值并读取新值
  • uvm_hdl_read– 读取 RTL 值

推荐阅读