我是否需要避免 UVM 中的 OOMR(模块外参考)代码?
Do I need to avoid OOMR (Out of Module reference) code in UVM?
我正在设置一个新的 UVM 代码,并想在我的 uvm 代码中生成 OOMR 代码,我是否需要避免 UVM 中的 OOMR(模块外引用)代码概念?
如果不需要,OOMR代码之前和之后我应该检查什么?
tb.top.env.dut.a = 1;
a = tb.top.env.dut.b
如果您在 运行 之后看到 link 有一些错误消息。
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代码中遇到类似错误时如何解决这个问题?
在 SystemVerilog 包中使用 Verilog 层次引用或 OOMR 是非法的。这是因为 SystemVerilog 包首先被编译,其方式与其余 SystemVerilog 代码不同。
通常,您会将 classes 放在一个包中。因此,您将避免在 classes 中使用 Verilog 分层引用或 OOMR。
显然,您需要将 class 中的代码连接到 DUT 端口(例如驱动器和监视器),并且您可能还想探测 DUT 内部信号。这些问题的解决方案因情况而异。
为了连接到 DUT 端口,大多数人会使用 SystemVerilog 接口。您在与 DUT 相同的层次结构级别实例化接口,并以某种方式将接口成员连接到 DUT,例如使用 Verilog 层次结构引用或 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),
...
然后在某些class(驱动程序、监视器或代理)中,您可以使用SystemVerilog 虚拟接口 连接到接口实例。虚拟接口是一种特殊的 SystemVerilog 变量,它可以将 Verilog 层次参考或 OOMR 存储到接口实例或 modport。因为你必须在运行时赋值,所以一个虚拟接口可以编译成一个包(但是赋值的代码不能在一个包中),例如:
class driver;
virtual TB_hook V;
task drive (input bit data);
V.Stim <= data;
然后,在某些 Verilog module
(可能是 top-level 模块)中,您将为虚拟接口变量赋值。您可以直接执行此操作,例如:
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);
您可以使用 modports and/or 时钟块增强此技术。
为了探测内部 DUT 信号,UVM 寄存器层提供了一些工具。为此有一组functions/tasks:
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 值
我正在设置一个新的 UVM 代码,并想在我的 uvm 代码中生成 OOMR 代码,我是否需要避免 UVM 中的 OOMR(模块外引用)代码概念? 如果不需要,OOMR代码之前和之后我应该检查什么?
tb.top.env.dut.a = 1;
a = tb.top.env.dut.b
如果您在 运行 之后看到 link 有一些错误消息。
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代码中遇到类似错误时如何解决这个问题?
在 SystemVerilog 包中使用 Verilog 层次引用或 OOMR 是非法的。这是因为 SystemVerilog 包首先被编译,其方式与其余 SystemVerilog 代码不同。
通常,您会将 classes 放在一个包中。因此,您将避免在 classes 中使用 Verilog 分层引用或 OOMR。
显然,您需要将 class 中的代码连接到 DUT 端口(例如驱动器和监视器),并且您可能还想探测 DUT 内部信号。这些问题的解决方案因情况而异。
为了连接到 DUT 端口,大多数人会使用 SystemVerilog 接口。您在与 DUT 相同的层次结构级别实例化接口,并以某种方式将接口成员连接到 DUT,例如使用 Verilog 层次结构引用或 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),
...
然后在某些class(驱动程序、监视器或代理)中,您可以使用SystemVerilog 虚拟接口 连接到接口实例。虚拟接口是一种特殊的 SystemVerilog 变量,它可以将 Verilog 层次参考或 OOMR 存储到接口实例或 modport。因为你必须在运行时赋值,所以一个虚拟接口可以编译成一个包(但是赋值的代码不能在一个包中),例如:
class driver;
virtual TB_hook V;
task drive (input bit data);
V.Stim <= data;
然后,在某些 Verilog module
(可能是 top-level 模块)中,您将为虚拟接口变量赋值。您可以直接执行此操作,例如:
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);
您可以使用 modports and/or 时钟块增强此技术。
为了探测内部 DUT 信号,UVM 寄存器层提供了一些工具。为此有一组functions/tasks:
uvm_hdl_check_path
– 检查 HDL 路径是否存在uvm_hdl_deposit
– 将值存入 RTLuvm_hdl_force
– 强制一个值进入 RTLuvm_hdl_force_time
– 强制指定持续时间的值uvm_hdl_release
– 释放一个强制值uvm_hdl_release_and_read
– 释放强制值并读取新值uvm_hdl_read
– 读取一个 RTL 值