SystemVerilog - Clocking Block

2023-07-13

interfacemodport把訊號由不同module之間串起來,但是沒有時序性也沒有同步機制,clocking block可以用來滿足module之間的timing requirement的需求。

clocking blocking可以指定trigger時間點的input skew和output skew,這裡的input/output不是資料的方向性
例如時間單位是ns的話
input #1的話,就是sample觸發事件前1ns的signal的值。
output #1的話,就是在觸發事件後1ns才做驅動。

語法

1
2
3
4
clocking [name] @ [event_or_identifier]
default input #[delay_or_edge] output #[delay_or_edge]
[list of signals]
endclocking

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
interface _if(input bit clk);
bit [7:0] sig1_input;
bit [7:0] sig2_output;

clocking cb @(posedge clk);
input #1 sig1_input;
output #2 sig2_output;
endclocking
endinterface

module tb;

bit clk;
always #3 clk = ~clk;

_if if0(clk);

initial begin
clk <=0;
if0.sig1_input = 8'h12;
if0.cb.sig2_output <= 8'h34;
$display("sig1_input:%0h", if0.cb.sig1_input);
@if0.cb;
if0.sig1_input = 8'h56;
if0.cb.sig2_output <= 8'h78;
#1
if0.cb.sig2_output <= 8'hAA;
$display("sig1_input:%0h", if0.cb.sig1_input);
@if0.cb;
if0.sig1_input = 8'h9A;
if0.cb.sig2_output <= 8'hBC;
#1
if0.cb.sig2_output <= 8'hDD;
$display("sig1_input:%0h", if0.cb.sig1_input);
#100 $finish();
end
endmodule

Output

Alt text

這個例子在一開始tb先把
if0.sig1_input設為0x12,if0.cb.sig2_output設定為0x34,

3ns的clk由0->1觸發事件,
if0.sig1_input設為0x56,這時候if0.cb.sig1_input因為clocking裡面設定input #1,所以是sample 1ns前的資料,所以if0.sig1_input值是0x12
if0.cb.sig2_output設定為0x78,再過1ns之後再設為0xAA,因為clocking裡面設定output #2,所以是2ns之後driven,所以if0.sig2_output值在第5ns的值是0x78。