摘要:SV添加了一个时钟块,用于识别时钟信号,实现计时和同步需求 。
- 输入采样
- 同步事件
- 同步驱动
1. input and output skew
- 通常在基于周期的代码设计和验证中,输入在时钟边沿采样,输出在时钟边沿驱动;
- 如果指定了skew,则输入在时钟skew时间之前采样,输出在时钟skew之后驱动。
- skew必须是一个常量表达式,并且可以指定为参数。如果skew没有指定时间单位,则使用当前时间单位,如果使用数字,则使用当前时间作用域的时间刻度解释倾斜。
![](https://img-blog.csdnimg.cn/img_convert/f485407e68d59234512051165e2d51de.png)
input output skews
1 `timescale 1ns/1ns
2 // program declaration with ports.
3 program clocking_skew_prg (
4 input wire clk,
5 output logic [7:0] din,
6 input wire [7:0] dout,
7 output logic [7:0] addr,
8 output logic ce,
9 output logic we
10 );
11
12 // Clocking block
13 clocking ram @(posedge clk);
14 input #1 dout;
15 output #1 din,addr,ce,we;
16 endclocking
17
18 initial begin
19 // Init the outputs
20 ram.addr <= 0;
21 ram.din <= 0;
22 ram.ce <= 0;
23 ram.we <= 0;
24 // Write Operation to Ram
25 for (int i = 0; i < 2; i++) begin
26 @ (posedge clk);
27 ram.addr <= i;
28 ram.din <= $random;
29 ram.ce <= 1;
30 ram.we <= 1;
31 @ (posedge clk);
32 ram.ce <= 0;
33 end
34 // Read Operation to Ram
35 for (int i = 0; i < 2; i++) begin
36 @ (posedge clk);
37 ram.addr <= i;
38 ram.ce <= 1;
39 ram.we <= 0;
40 // Below line is same as @ (posedge clk);
41 @ (ram);
42 ram.ce <= 0;
43 end
44 #40 $finish;
45 end
46
47 endprogram
48
49 // Simple top level file
50 module clocking_skew();
51
52 logic clk = 0;
53 wire [7:0] din;
54 logic [7:0] dout;
55 wire [7:0] addr;
56 wire ce;
57 wire we;
58 reg [7:0] memory [0:255];
59
60 // Clock generator
61 always #10 clk++;
62
63 // Simple ram model
64 always @ (posedge clk)
65 if (ce)
66 if (we)
67 memory[addr] <= din;
68 else
69 dout <= memory[addr];
70
71 // Monitor all the signals
72 initial begin
73 $monitor("@%0dns addr :%0x din %0x dout %0x we %0x ce %0x",
74 $time, addr, din,dout,we,ce);
75 end
76 // Connect the program
77 clocking_skew_prg U_program(
78 .clk (clk),
79 .din (din),
80 .dout (dout),
81 .addr (addr),
82 .ce (ce),
83 .we (we)
84 );
85
86 endmodule
87
88 //compile skew
89
90 @0ns addr :xx din xx dout xx we x ce x
91 @11ns addr :0 din 24 dout xx we 1 ce 1
92 @31ns addr :0 din 24 dout xx we 1 ce 0
93 @51ns addr :1 din 81 dout xx we 1 ce 1
94 @71ns addr :1 din 81 dout xx we 1 ce 0
95 @91ns addr :0 din 81 dout xx we 0 ce 1
96 @110ns addr :0 din 81 dout 24 we 0 ce 1
97 @111ns addr :0 din 81 dout 24 we 0 ce 0
98 @131ns addr :1 din 81 dout 24 we 0 ce 1
99 @150ns addr :1 din 81 dout 81 we 0 ce 1
100 @151ns addr :1 din 81 dout 81 we 0 ce 0
2. hierarchical names
- 时钟块可以访问(输入)任意 的层次性好,这意味着不仅可以访问本地信号,而且可以访问层次内部的信号
1 `timescale 1ns/1ns
2 // program declaration with ports.
3 program clocking_hier_prg (
4 input wire clk,
5 output logic [7:0] din,
6 input wire [7:0] dout,
7 output logic [7:0] addr,
8 output logic ce,
9 output logic we
10 );
11
12 // Clocking block
13 clocking ram @(posedge clk);
14 input #1 dout = clocking_skew.dout;
15 output #1 din,addr,ce,we;
16 endclocking
17
18 initial begin
19 $monitor("@%0dns addr :%0x din %0x dout %0x we %0x ce %0x",
20 $time, addr, din,ram.dout,we,ce);
21 // Init the outputs
22 ram.addr <= 0;
23 ram.din <= 0;
24 ram.ce <= 0;
25 ram.we <= 0;
26 // Write Operation to Ram
27 for (int i = 0; i < 2; i++) begin
28 @ (posedge clk);
29 ram.addr <= i;
30 ram.din <= $random;
31 ram.ce <= 1;
32 ram.we <= 1;
33 @ (posedge clk);
34 ram.ce <= 0;
35 end
36 // Read Operation to Ram
37 for (int i = 0; i < 2; i++) begin
38 @ (posedge clk);
39 ram.addr <= i;
40 ram.ce <= 1;
41 ram.we <= 0;
42 // Below line is same as @ (posedge clk);
43 @ (ram);
44 ram.ce <= 0;
45 end
46 #40;
47 end
48
49 endprogram
50
51 // Simple top level file
52 module clocking_skew();
53
54 logic clk = 0;
55 wire [7:0] din;
56 logic [7:0] dout;
57 wire [7:0] addr;
58 wire ce;
59 wire we;
60 reg [7:0] memory [0:255];
61
62 // Clock generator
63 always #10 clk++;
64
65 // Simple ram model
66 always @ (posedge clk)
67 if (ce)
68 if (we)
69 memory[addr] <= din;
70 else
71 dout <= memory[addr];
72
73 // Connect the program
74 clocking_hier_prg U_program(
75 .clk (clk),
76 .din (din),
77 .dout (),
78 .addr (addr),
79 .ce (ce),
80 .we (we)
81 );
82
83 endmodule
84
85 //compile result
86
87 @0ns addr :xx din xx dout xx we x ce x
88 @11ns addr :0 din 24 dout xx we 1 ce 1
89 @31ns addr :0 din 24 dout xx we 1 ce 0
90 @51ns addr :1 din 81 dout xx we 1 ce 1
91 @71ns addr :1 din 81 dout xx we 1 ce 0
92 @91ns addr :0 din 81 dout xx we 0 ce 1
93 @111ns addr :0 din 81 dout xx we 0 ce 0
94 @130ns addr :0 din 81 dout 24 we 0 ce 0
95 @131ns addr :1 din 81 dout 24 we 0 ce 1
96 @151ns addr :1 din 81 dout 24 we 0 ce 0
97 @170ns addr :1 din 81 dout 81 we 0 ce 0
3. cycle delay
##操作符
1 `timescale 1ns/1ns
2 // program declaration with ports.
3 program clocking_skew_prg (
4 input wire clk,
5 output logic [7:0] din,
6 input wire [7:0] dout,
7 output logic [7:0] addr,
8 output logic ce,
9 output logic we
10 );
11
12 // Clocking block
13 default clocking ram @(posedge clk);
14 input #1 dout;
15 output #1 din,addr,ce,we;
16 endclocking
17
18 initial begin
19 // Init the outputs
20 ram.addr <= 0;
21 ram.din <= 0;
22 ram.ce <= 0;
23 ram.we <= 0;
24 // Write Operation to Ram
25 for (int i = 0; i < 2; i++) begin
26 // Below line is same as repeat (2) @ (posedge clk);
27 ## 2 ;
28 ram.addr <= i;
29 ram.din <= $random;
30 ram.ce <= 1;
31 ram.we <= 1;
32 ## 2;
33 ram.ce <= 0;
34 end
35 // Read Operation to Ram
36 for (int i = 0; i < 2; i++) begin
37 // Below line is same as @ (posedge clk);
38 ## 1 ;
39 ram.addr <= i;
40 ram.ce <= 1;
41 ram.we <= 0;
42 // Below line is same as repeat (3) @ (posedge clk);
43 ## 3;
44 ram.ce <= 0;
45 end
46 #40 $finish;
47 end
48
49 endprogram
50
51 // Simple top level file
52 module clocking_skew();
53
54 logic clk = 0;
55 wire [7:0] din;
56 logic [7:0] dout;
57 wire [7:0] addr;
58 wire ce;
59 wire we;
60 reg [7:0] memory [0:255];
61
62 // Clock generator
63 always #10 clk++;
64
65 // Simple ram model
66 always @ (posedge clk)
67 if (ce)
68 if (we)
69 memory[addr] <= din;
70 else
71 dout <= memory[addr];
72
73 // Monitor all the signals
74 initial begin
75 $monitor("@%0dns addr :%0x din %0x dout %0x we %0x ce %0x",
76 $time, addr, din,dout,we,ce);
77 end
78 // Connect the program
79 clocking_skew_prg U_program(
80 .clk (clk),
81 .din (din),
82 .dout (dout),
83 .addr (addr),
84 .ce (ce),
85 .we (we)
86 );
87
88 endmodule
89
90 //compile result
91
92 @0ns addr :x din x dout x we x ce x
93 @11ns addr :0 din 0 dout x we 0 ce 0
94 @51ns addr :0 din 24 dout x we 1 ce 1
95 @91ns addr :0 din 24 dout x we 1 ce 0
96 @131ns addr :1 din 81 dout x we 1 ce 1
97 @171ns addr :1 din 81 dout x we 1 ce 0
98 @191ns addr :0 din 81 dout x we 0 ce 1
99 @210ns addr :0 din 81 dout 24 we 0 ce 1
100 @251ns addr :0 din 81 dout 24 we 0 ce 0
101 @271ns addr :1 din 81 dout 24 we 0 ce 1
102 @290ns addr :1 din 81 dout 81 we 0 ce 1
103 @331ns addr :1 din 81 dout 81 we 0 ce 0
4. default clocking
- 在给定的模块、接口或程序中,可以指定一个时钟作为所有周期延迟操作的默认值;
- 在程序、模块。接口中只能指定一个 default时钟;
- 任何##语句都将按照指定的default时钟进行。
1 module clocking_default();
2
3 logic clk = 0;
4 always #10 clk++;
5
6 // Specify the default clocking
7 default clocking test @ (posedge clk);
8
9 endclocking
10
11 initial begin
12 $display("%0dns is current time",$time);
13 // Any ## is evaluated with respect to default clock
14 ##100;
15 $display("%0dns is current time",$time);
16 $finish;
17 end
18
19 endmodule
20 //compile result
21
22 0ns is current time
23 1990ns is current time