module dut(
input clk,
input rst_n,
input [1:0] trans_in,
output [1:0] trans_out);
reg [1:0] trans_r;
always @ (posedge clk or negedge rst_n)begin
if(!rst_n)begin
trans_r <= 'b0 ;
end
else begin
trans_r <= trans_in;
end
end
assign trans_out = trans_r;
endmodule
interface intf;
logic clk ;
logic rst_n ;
logic [1:0] trans_in ;
logic [1:0] trans_out ;
clocking cb_mst @(posedge clk);
default input #1ns output #1ns;
output trans_in;
input trans_out;
endclocking
clocking cb_mon @(posedge clk);
default input #1ns output #1ns;
input trans_in , trans_out;
endclocking
endinterface
module tb();
logic clk ;
logic rst_n ;
//logic [1:0] trans_in ;
//logic [1:0] trans_out ;
logic [1:0] variable1 ;
logic [1:0] variable2 ;
logic [1:0] variable3 ;
logic [1:0] variable4 ;
logic [1:0] variable5 ;
logic [1:0] variable6 ;
intf itf();
assign itf.clk = clk;
assign itf.rst_n = rst_n;
assign variable1 = itf.cb_mon.trans_in;
assign variable2 = itf.cb_mon.trans_out;
assign variable3 = itf.trans_in;
assign variable4 = itf.trans_out;
assign variable5 = itf.cb_mst.trans_in;
assign variable6 = itf.cb_mst.trans_out;
dut dt(
.clk(itf.clk),
.rst_n(itf.rst_n),
.trans_in(itf.trans_in),
.trans_out(itf.trans_out));
initial begin
clk = 'b0;
forever begin
#5;
clk = !clk;
end
end
initial begin
rst_n = 'b0;
#32;
rst_n = 'b1;
begin
@(posedge itf.cb_mst);
itf.cb_mst.trans_in <= 'b00;
@(posedge itf.cb_mst);
itf.cb_mst.trans_in <= 'b01;
@(posedge itf.cb_mst);
itf.cb_mst.trans_in <= 'b10;
@(posedge itf.cb_mst);
itf.cb_mst.trans_in <= 'b11;
end
#32;
$finish();
end
endmodule
关于monitor的时钟块:
两种情况:第一种是输入给dut的数据通过monitor采样,由于时钟块的存在,实际上输入给dut的信号在第二拍才能采集到;第二种是由dut输出的信号经过monitor采样,同样是在信号由dut驱动出来后的下一拍可以采集到。参考dut信号和这里的variable1和variable2.
关于driver的时钟块:
对于输入的信号,由于dut的信号实际是由driver时钟块驱动的,因此这里的输入信号两者会在同一拍,只会差1ns的时间(参考dut信号和variable5);对于输出信号,由于输出的信号对于driver的时钟块是输入,其采集的时候会在dut输入的信号时钟沿之前采集,因此这两个信号差一拍(参考dut信号和variable6)。