1、interface中端口方向的理解
(1)从testbench的角度看,tb中信号的输入输出方向与interface中信号输入输出方向一致:
(2)从DUT角度看,DUT中信号输入输出方向与interface中信号输入输出方向相反。简单图示如下:
代码示例如下:
interface my_if(input bit clk);
bit write;
bit [15:0] data_in;
bit [7:0] address;
logic [15:0] data_out;
clocking cb @ (negedge clk);
default input #1ns output #2ns;
output write;
output data_in;
output address;
input data_out;
endclocking
modport master(clocking cb);
modport slave(input write, data_in, address, output data_out);
endinterface
module master( clk,data_out , write ,data_in,address );
input logic clk,write;
output logic [7:0] data_out;
input logic [7:0] data_in ,address;
always @(negedge clk)
if(write==0)
data_out<=0;
else if (write==1)
data_out<=data_in;
endmodule
class BB;
virtual my_if master_inst;
function new(virtual interface my_if a);
master_inst=a;
endfunction
task ass();
master_inst.master.cb.write<=0;
repeat(10) @(negedge master_inst.clk);
master_inst.master.cb.data_in<='h12;
$display("data_in ==12 is %d\n",$time);
repeat(10) @(negedge master_inst.clk);
master_inst.master.cb.data_in<='h34;
$display("data_in ==34 is %d\n",$time);
repeat(10) @(negedge master_inst.clk);
master_inst.master.cb.data_in<='h45;
$display("data_in ==45 is %d\n",$time);
master_inst.master.cb.write<=1;
repeat(10) @(negedge master_inst.clk);
master_inst.master.cb.data_in<='h56;
$display("data_in ==56 is %d\n",$time);
repeat(10) @(negedge master_inst.clk);
master_inst.master.cb.data_in<='h67;
$display("data_in ==67 is %d\n",$time);
repeat(10) @(negedge master_inst.clk);
master_inst.master.cb.data_in<='h52;
$display("data_in ==52 is %d\n",$time);
repeat(10) @(negedge master_inst.clk);
master_inst.master.cb.data_in<='h81;
repeat(10) @(negedge master_inst.clk);
master_inst.master.cb.data_in<='h05;
endtask
endclass
module slaver(my_if.slave sif);
initial begin
sif.data_out <= 16'h0;
#275 sif.data_out <= 16'h1;
end
endmodule
module test;
bit clk = 0;
always #50 clk = ~clk;
my_if regbus(clk);
master m0(.clk(regbus.clk ), .address(regbus.address), .data_out(regbus.data_out), .data_in(regbus.data_in),.write(regbus.write));
//slaver s0(regbus.slave);
BB b_inst=new(regbus);
initial begin
#100 b_inst.ass();
end
endmodule
注意:
(1)当interface中有modport或者clocking块时,在testbench中可以直接定义interface的实例,可以将其直接传递到class中,然后在class中的task中可以通过点运算法逐层次的访问modport或者clocking中的信号。也可以通过点运算符直接在tb中实例化interface中的modport对象,然后传递到class中。
(2)在class中的task中对clocking块中的信号赋值时,必须使用非阻塞赋值语句<=;
2、interface中clocking block的理解
在上面的代码中,clocking cb块中default input #1ns output #2ns;表示output类型的信号在negedge clk延时2ns才赋值,仿真波形如下所示:
clocking cb @ (negedge clk);
default input #1ns output #2ns;
output write;
output data_in;
output address;
input data_out;
endclocking