SV_12_Clocking Block
摘要:SV添加了一个时钟块,用于识别时钟信号,实现计时和同步需求 。
- 输入采样
- 同步事件
- 同步驱动
1. input and output skew
- 通常在基于周期的代码设计和验证中,输入在时钟边沿采样,输出在时钟边沿驱动;
- 如果指定了skew,则输入在时钟skew时间之前采样,输出在时钟skew之后驱动。
- skew必须是一个常量表达式,并且可以指定为参数。如果skew没有指定时间单位,则使用当前时间单位,如果使用数字,则使用当前时间作用域的时间刻度解释倾斜。

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
浙公网安备 33010602011771号