问题描述
我更喜欢将测试平台和测试编写为顶级模块,这样我就可以编译所有这些模块并详细说明/优化我需要运行的测试平台和测试。但是,我不确定如何将测试平台中的接口实例传递给测试。在下面的示例中,dut_tb 是顶级 testbech,dut_tb_intf 是在 testbench 中实例化的接口。测试 dut_tb_test 使用接口中的函数,我可以使用完整路径引用这些函数,但想知道是否可以将 dut_tb 中的接口实例传递给测试或更好的方法。
请看下面的例子。
module dut(input data,input clk,input rst_n,output logic inv_data);
logic inv_data_d;
assign inv_data_d = ~data;
always_ff @(posedge clk or negedge rst_n)
if (~rst_n)
inv_data <= '0;
else
inv_data <= inv_data_d;
endmodule
package dut_tb_pkg;
logic clk;
logic rst_n;
logic data;
logic inv_data;
endpackage
module dut_tb();
import dut_tb_pkg::*;
dut_tb_intf dut_tb_intf();
//logic data;
//logic inv_data;
assign data = dut_tb_intf.data_i;
assign dut_tb_intf.data_inv = inv_data;
assign clk = dut_tb_intf.aclk;
initial
begin
rst_n = '0;
@(posedge clk);
rst_n = '1;
end
dut dut (.clk (clk),.rst_n(rst_n),.data (data),.inv_data(inv_data));
endmodule
//module dut_tb_test( dut_tb.dut_tb_intf intf_inst); // DOES NOT WORK**
module dut_tb_test();
import dut_tb_pkg::*;
logic in,out;
initial
begin
@(posedge clk);
#30;
@(posedge clk);
in = 1'b0;
dut_tb.dut_tb_intf.inv_data (in,out);
//intf_inst.inv_data (in,out); // DOES NOT WORK**
end
initial
begin
@(posedge clk);
@(posedge clk);
$display ("INFO_0: in is %b and out is %b\n",in,out);
#300;
$display ("INFO_1: in is %b and out is %b\n",out);
#100;
$finish;
end
endmodule
interface dut_tb_intf;
logic aclk;
logic data_i;
logic data_inv;
initial
begin
aclk = '0;
forever #5 aclk = ~aclk;
end
task inv_data(input i,output logic d);
data_i = i;;
@(posedge aclk);
@(posedge aclk);
d = data_inv;
endtask
modport utils (import inv_data);
endinterface
解决方法
在您的方法中,您可以不在两个模块之间传递接口。接口通过实例化端口传递给模块。在经典的 verilog 方法中,您还需要另一个 top
模块来实例化所有模块:
module tb(MyInterface i);
...
endmodule
module test(MyInteface i);
...
endmodule
interface MyInterface;
...
endinterface
module top();
MyInterface myIntf;
tb tb(myIntf);
test test(myIntf);
endmodule
可能会有点难看,并在 tb 中实例化您的界面并将其传递给测试,如下所示
module top();
tb tb();
test test (tb.myIntf);
endmodule
另一种方法是在测试平台中实例化您的测试。这样就省去了你上面所有的麻烦,你自然可以把接口传给它:
module test...
module tb();
MyInterface myIf;
test test(myIf);
...
endmodule
或者更好的是,在系统 verilog 中,您可以将测试设计为一个类并传递虚拟接口。