interface 封装了模块的端口(ports),以及它们的方向(modports),同步关系( clocking block),function和task。
interface 简化了模块之间的连接,但是无法很好地适用于基于OOP的测试平台,无法在program ,class中进行实例化。
为了解决这个问题, System Verilog引入了virtual interface的概念。virtual interface是实际interface的指针。即virtual interface是一种可以在class中实例化的数据类型,使用virtual interface可与被测设计(DUT)进行间接地通信,而无需使用层次结构引用。
interface将测试平台与DUT分开。virtual interface在测试平台的不同位置操纵一组虚拟信号,而不是直接操纵实际的信号。
interface SBus; // A Simple bus interface
logic [7:0] addr, data;
endinterface
class SBusTransctor; // SBus transactor class
virtual SBus bus; // virtual interface of type Sbus
function new( virtual SBus s );
bus= s; // initialize the virtual interface
endfunction
endclass
module dev ( Sbus s ) ... endmodule //devices that use SBus
module top
SBus s ; // instantiate interface
dev a ( s ); // instantiate device
initial begin
SbusTransactor t; // create bus-transactors
t = new( s );
end
endmodule
在前面的示例中,SbusTransctor是一个简单的可重用事务类,其在编写时不需要知道测试平台的层次结构,也不知道与之交互的特定设计。该事务类可以与符合接口协议的任何数量的设计进行交互。
在测试平台中是virtual interface时,需要满足以下3个要求
1、实例化的接口必须正确连接到DUT。
SBus s ; // instantiate interface
dev a ( s ); // instantiate device
2、必须在类中声明virtual interface句柄。
virtual SBus bus; // virtual interface oftype Sbus
function new( virtual SBus s );
bus = s; // initialize the virtual interface
endfunction
3、必须将指定模块的interface赋值给virtual interface
SbusTransactor t; // create bus-transactors
t = new( s );
UVM是基于类的验证方法,其需要在driver和monitor两个不同的位置访问DUT,因此在UVM中需要两个virtual interface。
在UVM中设置虚拟接口如下所示
module top;
…
dut_if dif;
…
initial begin
uvm_config_db#(virtual dut_if)::set(null, "*", "vif", dif);
run_test();
end
endmodule
class tb_driver extends uvm_driver #(trans1);
…
virtual dut_if vif;
…
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// Get the virtual interface handle that was stored in the
// uvm_config_db and assign it to the local vif field.
if (!uvm_config_db#(virtual dut_if)::get(this, "", "vif",vif))
`uvm_fatal("NOVIF", {"virtual interface must be set for: ",
get_full_name(), ".vif"});
endfunction
…
endclass
实际的interface dif在顶层模块中的run\_test()之前使用命令
uvm_config_db#(virtualdut_if)::set(null, "*", "vif", dif);
存储在(set)字符串“ vif”中。
然后使用命令
uvm_config_db#(virtual dut_if)::get(this, "", "vif", vif)
从同一“ vif”位置,并将其赋值给tb\_driver类中的virtual interface vif。
本文转载自公众号:芯片数字实验室
原文链接:
https://mp.weixin.qq.com/s/fOcKnJyvOoALeqVAa8Qpsw
未经作者同意,请勿转载!
推荐阅读
想了解更多内容,欢迎关注芯片数字实验室专栏