UVM 测试平台中的断言模块
Assertion module in an UVM testbench
我已经编写了一个包含 3 个代理的 UVM 测试台,现在正在编写一个 scoreboard/checker。我的 SystemVerilog 断言需要一个检查器模块,但是这个检查器模块需要了解测试完成的寄存器配置(并且可以是随机的,在测试的 run_phase 期间决定)。
我不知道这是怎么回事?如果我要为我的断言创建一个检查器模块,并将其在顶层 (tb_top) 绑定到 dut,这个检查器模块如何知道我的寄存器配置?
看了一些论文后,我想我可以把我的检查器模块写成一个接口,把它设置在tb_top。但这将允许访问我的 UVC 界面中的变量。接口如何访问UVC中的变量?
感谢任何帮助。我觉得我在这里遗漏了一些关键的东西,因为这可能已经做过很多次了。
编辑:请不要告诉我我必须实施某种 API 来设置我的 UVC 中的每个单独的寄存器设置?我只想获取我的 reg_block 的句柄(或我的代理中的任何其他配置变量)
您似乎想将信息从 tb_top
传递给您的 UVC
,反之亦然。此信息将由您在 tb_top
中的断言使用,并由您的 UVC 共享。我的建议是,您可以使用 uvm_resource_db
或 uvm_config_db
.
我可以想到两种实现这种交流的方法。
第一种方法是set
你tb_top
中的配置,然后你的UVC抓住这个句柄。从这里开始,您可以传达您的注册信息或您的声明所需的任何信息。
class my_tb_config extends uvm_object;
// ...
endclass
module tb_top;
my_tb_config tcfg;
initial begin
tcfg = new("tcfg");
uvm_config_db#(my_tb_config)::set(uvm_root::get(), "*", "my_tb_config", tcfg);
end
endmodule
// somewhere in your UVC
class my_uvc extends uvm_component;
my_tb_config tcfg;
function void build_phase(uvm_phase phase);
// now both tb_top and your UVC point to the same config object
void'(uvm_config_db#(my_tb_config)::get(this,"","my_tb_config", tcfg));
endfunction
endclass
另一种方法是反过来。将您的 UVC 配置传递给您的 tb_top
.
class my_other_uvc extends uvm_component;
my_tb_config tcfg;
function void build_phase(uvm_phase);
tcfg = new("tcfg");
uvm_resource_db#(my_tb_config)::set("*", "my_tb_config", tcfg);
endfunction
endclass
// somewhere in your tb_top
module tb_top;
my_tb_config tcfg;
initial begin
#1ps; // small delay, making sure resource is submitted
void'(uvm_resource_db#(my_tb_config)::read_by_name("*","my_tb_config",tcfg);
// Now both your tb_top and UVC share same object, so you can freely define your whatever communication between them
end
endmodule
我想出了一个办法来做到这一点。首先,我意识到我问了两个不同的问题:
1) 我的检查器模块需要知道测试完成的寄存器配置
我在我的设计中使用跨模块引用来访问我的寄存器,这为我提供了在 运行 阶段测试设置的最新寄存器配置。
tb.sv
module tb;
dut my_dut( ... )
interface my_checker (
.input_registerA (tb.my_dut.my_sub_module.regA),
.input_registerB (tb.my_dut.my_sub_module.regB),
.input_registerC (tb.my_dut.my_other_sub_module.regC),
....
)
endmodule
my_checker.sv
interface my_checker (
input input_registerA,
input input_registerB,
input input_registerC,
....
);
// Here I can write properties/assertions that are register-aware
endinterface
2) 接口如何访问UVC中的变量?
这有点棘手。我想从 uvm_sequence 或 uvm_monitor 等
动态更新我的检查器变量
我读了 Verilab 的这篇论文,它清楚地描述了执行此操作的方法:
http://www.verilab.com/files/litterick_sva_encapsulation.pdf
在我的检查器模块中,我创建了一个 uvm_component。从这个组件,我现在可以访问 uvm_resource_db,通过它我可以与我的 UVM 测试台交换信息。
要记住的一件事是检查器模块中实例化的 uvm_component 位于顶层 (uvm_root)。
我已经编写了一个包含 3 个代理的 UVM 测试台,现在正在编写一个 scoreboard/checker。我的 SystemVerilog 断言需要一个检查器模块,但是这个检查器模块需要了解测试完成的寄存器配置(并且可以是随机的,在测试的 run_phase 期间决定)。
我不知道这是怎么回事?如果我要为我的断言创建一个检查器模块,并将其在顶层 (tb_top) 绑定到 dut,这个检查器模块如何知道我的寄存器配置?
看了一些论文后,我想我可以把我的检查器模块写成一个接口,把它设置在tb_top。但这将允许访问我的 UVC 界面中的变量。接口如何访问UVC中的变量?
感谢任何帮助。我觉得我在这里遗漏了一些关键的东西,因为这可能已经做过很多次了。
编辑:请不要告诉我我必须实施某种 API 来设置我的 UVC 中的每个单独的寄存器设置?我只想获取我的 reg_block 的句柄(或我的代理中的任何其他配置变量)
您似乎想将信息从 tb_top
传递给您的 UVC
,反之亦然。此信息将由您在 tb_top
中的断言使用,并由您的 UVC 共享。我的建议是,您可以使用 uvm_resource_db
或 uvm_config_db
.
我可以想到两种实现这种交流的方法。
第一种方法是set
你tb_top
中的配置,然后你的UVC抓住这个句柄。从这里开始,您可以传达您的注册信息或您的声明所需的任何信息。
class my_tb_config extends uvm_object;
// ...
endclass
module tb_top;
my_tb_config tcfg;
initial begin
tcfg = new("tcfg");
uvm_config_db#(my_tb_config)::set(uvm_root::get(), "*", "my_tb_config", tcfg);
end
endmodule
// somewhere in your UVC
class my_uvc extends uvm_component;
my_tb_config tcfg;
function void build_phase(uvm_phase phase);
// now both tb_top and your UVC point to the same config object
void'(uvm_config_db#(my_tb_config)::get(this,"","my_tb_config", tcfg));
endfunction
endclass
另一种方法是反过来。将您的 UVC 配置传递给您的 tb_top
.
class my_other_uvc extends uvm_component;
my_tb_config tcfg;
function void build_phase(uvm_phase);
tcfg = new("tcfg");
uvm_resource_db#(my_tb_config)::set("*", "my_tb_config", tcfg);
endfunction
endclass
// somewhere in your tb_top
module tb_top;
my_tb_config tcfg;
initial begin
#1ps; // small delay, making sure resource is submitted
void'(uvm_resource_db#(my_tb_config)::read_by_name("*","my_tb_config",tcfg);
// Now both your tb_top and UVC share same object, so you can freely define your whatever communication between them
end
endmodule
我想出了一个办法来做到这一点。首先,我意识到我问了两个不同的问题:
1) 我的检查器模块需要知道测试完成的寄存器配置
我在我的设计中使用跨模块引用来访问我的寄存器,这为我提供了在 运行 阶段测试设置的最新寄存器配置。
tb.sv
module tb;
dut my_dut( ... )
interface my_checker (
.input_registerA (tb.my_dut.my_sub_module.regA),
.input_registerB (tb.my_dut.my_sub_module.regB),
.input_registerC (tb.my_dut.my_other_sub_module.regC),
....
)
endmodule
my_checker.sv
interface my_checker (
input input_registerA,
input input_registerB,
input input_registerC,
....
);
// Here I can write properties/assertions that are register-aware
endinterface
2) 接口如何访问UVC中的变量?
这有点棘手。我想从 uvm_sequence 或 uvm_monitor 等
动态更新我的检查器变量我读了 Verilab 的这篇论文,它清楚地描述了执行此操作的方法: http://www.verilab.com/files/litterick_sva_encapsulation.pdf
在我的检查器模块中,我创建了一个 uvm_component。从这个组件,我现在可以访问 uvm_resource_db,通过它我可以与我的 UVM 测试台交换信息。
要记住的一件事是检查器模块中实例化的 uvm_component 位于顶层 (uvm_root)。