我想使用以下 SystemVerilog 概念:
现在在 UVM 中,我们实例化一个虚拟接口并通过配置数据库使其可用,因此我不知道驱动程序如何仅获取对 modport 而不是虚拟接口的引用。避免在没有 modport 的情况下意外访问信号的标准解决方案是什么?
我只能想出以下(未经测试的)代码示例,但是我不确定是否有更好的方法:
interface my_interface(input clk);
logic I;
logic O;
clocking cb_drv @(posedge clk);
output I;
input O;
endclocking
clocking cb_mon @(posedge clk);
input I;
output O;
endclocking
modport drv(clocking cb_drv, output clk);
modport mon(clocking cb_mon, input clk);
endinterface
class my_driver extends uvm_driver #(my_transaction);
`uvm_component_utils(my_driver);
virtual my_interface.drv vif;
...
virtual function void build_phase(uvm_phase phase);
virtual my_interface temp;
super.build_phase(phase);
if(!uvm_config_db#(virtual my_interface)::get(this, "", "my_interface", temp))
`uvm_fatal(...);
vif = temp.drv;
endfunction
virtual task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(transaction);
@(vif.cb_drv);
vif.cb_drv.I = transaction.I;
seq_item_port.item_done();
end
endtask
endclass
此解决方案的问题是,我有在接口中实现的功能/任务(例如读/写功能),通过这种方式无法访问。
时钟块只是防止测试台和 DUT 之间出现竞争状况的多种方法之一。您可以使用非阻塞分配,就像设计人员使用非阻塞分配来防止 RTL 代码之间的竞争一样。您可以使用负时钟沿或偏移时钟沿来驱动和监控 DUT。请参阅我的 DVCon 论文:缺失的环节:测试平台与 DUT 连接。
关于在界面
modport
中使用任务和功能,您当然可以使用 import
来访问它们。但大多数人已经放弃使用 modports 进行验证,因为即使在您展示的情况下,访问整个界面也很容易。您必须为每个 modport 分离配置数据库。
uvm_config_db#(virtual my_interface.drv)::set(this, "*", "my_interface", itf_instance.drv)
uvm_config_db#(virtual my_interface.mon)::set(this, "*", "my_interface", itf_instance.mon)
驱动程序和监视器需要从 uvm_config_db 获取各自的虚拟接口实例。