module multiplier(mult_if.RTL inf);
always@(posedge inf.clk or posedge inf.reset) begin
if(inf.reset) begin
inf.out <= 0;
inf.ack <= 0;
end
else begin
if(inf.en) begin
inf.out <= inf.a * inf.b;
inf.ack <= 1;
end
else begin
inf.out <= inf.out;
inf.ack <= 0;
end
end
end
endmodule
interface mult_if (input logic clk, reset);
logic [7:0] a, b;
logic [15:0] out;
logic en;
logic ack;
clocking cb @(posedge clk);
default input #7 output #6;
input out, ack; // 这里数据宽度不是必要的
output a,b, en;
endclocking
// 这里的default input #7 output #6指的是对于@(posedge clk)的偏移,而非对于信号的延迟
modport TB (clocking cb, input clk, reset);
modport RTL (input clk, reset, a,b, en, output out, ack);
endinterface
module tb_top;
bit clk;
bit reset;
always #2 clk = ~clk;
initial begin
clk = 0;
reset = 1;
#2;
reset = 0;
end
mult_if inf(clk, reset);
multiplier DUT(inf);
`define TB_IF inf.cb
initial begin
$monitor("postponed time = %0t:\ta=%d\tb=%d\tout=%d\ten=%d\tack=%d\tTB_IF.out=%d\tTB_IF.ack=%d", \
$time, inf.a,inf.b,inf.out,inf.en,inf.ack,`TB_IF.out,`TB_IF.ack);
#1;
`TB_IF.a <= 'd20;
`TB_IF.b <= 'd7;
#5;
`TB_IF.en <= 1;
wait(`TB_IF.ack);
$display("time = %0t: finish", $time);
#10;
$finish;
end
initial begin
$dumpfile("dump.vcd"); $dumpvars;
end
endmodule
Output:
time = 0: a= x b= x out= 0 en=x ack=0 TB_IF.out= x TB_IF.ack=x
time = 8: a= 20 b= 7 out= 0 en=x ack=0 TB_IF.out= x TB_IF.ack=x
time = 10: a= 20 b= 7 out= 0 en=x ack=0 TB_IF.out= 0 TB_IF.ack=0
time = 12: a= 20 b= 7 out= 0 en=1 ack=0 TB_IF.out= 0 TB_IF.ack=0
time = 14: a= 20 b= 7 out= 140 en=1 ack=1 TB_IF.out= 0 TB_IF.ack=0
time = 22: finish
time = 22: a= 20 b= 7 out= 140 en=1 ack=1 TB_IF.out= 140 TB_IF.ack=1
这段代码中的 clocking block (cb) 在接口 mult_if 中定义,主要作用有:
default input #7 output #6 表示:input)在时钟沿前7个时间单位采样output)在时钟沿后6个时间单位驱动time=0:
time=1:
time=2:
time=6:
time=8:
time=12:
time=14:
time=22:
wait(TB_IF.ack)` 等待的是clocking block采样到的ack信号,而不是实时信号这种机制确保了测试平台与设计之间的同步,避免了竞争条件,是SystemVerilog中验证环境常用的同步技术。
default input #7 output #8;
下面是结果:
time = 0: a= x b= x out= 0 en=x ack=0 TB_IF.out= x TB_IF.ack=x
time = 10: a= 20 b= 7 out= 0 en=x ack=0 TB_IF.out= 0 TB_IF.ack=0
time = 14: a= 20 b= 7 out= 0 en=1 ack=0 TB_IF.out= 0 TB_IF.ack=0
time = 18: a= 20 b= 7 out= 140 en=1 ack=1 TB_IF.out= 0 TB_IF.ack=0
time = 26: finish
time = 26: a= 20 b= 7 out= 140 en=1 ack=1 TB_IF.out= 140 TB_IF.ack=1