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;endclockingmodport master(clocking cb);modport slave(input write, data_in, address, output data_out);endinterfacemodule 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;endmoduleclass BB;virtual my_if master_inst;function new(virtual interface my_if a);master_inst=a;
endfunctiontask 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; endtaskendclassmodule slaver(my_if.slave sif);initial beginsif.data_out <= 16'h0;#275 sif.data_out <= 16'h1;end
endmodulemodule 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();endendmodule
注意:
(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