Introduction to SystemVerilog Clocking Blocks
How do I use SystemVerilog clocking blocks in VCS?
What are the delays between the Design Under Test and the testbench?
Answer:
Clocking blocks are used to ensure that a Testbench (TB), in a program block, communicates synchronously with the Design Under Test (DUT). The TB and DUT should be connected with an interface, and the clocking block should be put into the interface.
Start with a simple D-flip flop with a d input and q output (both synchronous). It uses the following interface:
interface dff_if (input bit clk);
logic q, d;
clocking cb @(posedge clk);
input q; // TB input
output d; // TB output
endclocking
modport DUT (input clk, // Design under test
input d,
output q);
modport TB (clocking cb); // Synch signals
endinterface: dff_if
This has two modports, one for the DUT (the dff) and one for the TB. The clocking block is only used by the TB.How does the testbench drive a signal in the design?
When a TB changes a signal, the result is not seen immediately in the DUT. In the TB, you can drive the d line with:
dff_if.cb.d <= 0;This is a non-blocking assignment (NBA). This is because the program block executes in a different timing region than the design, so the value of d will not propagate immediately to the DUT, with or without a delay. This is a synchronous assignment (note the .cb. in the name) so d will not be updated until all TB statements in the program have completed for this time slot, and then not until the next posedge of the clock. Even if the statement is executed at the same time as the clock goes high, the DUT will not latch this new value as the clock has already gone high. This helps reduce race conditions.
Even if you use a hierarchical reference to drive a DUT signal directly, bypassing the interface, you still need to use an NBA.
You can advance time by adding a cycle delay to the assignment:
##1 dff_if.cb.d <= 0;Now the d signal will change one clock cycle from now. But since the NBA is in the TB, it will happen after the DUT executes, and after the clock has already changed. So the new value of d will not be seen for another cycle.
What happens when a TB tries to sample a signal from the DUT?
If you read a signal using a clocking block, SystemVerilog acts as if there is a synchronizer inserted into the line. The following statement:
gnt_out = dff_if.cb.q;will get the value of q from the previous clock cycle. For example, if the above line executes in the same time slot when the clock goes high, you will get the value from the previous clock edge.
How long is the minimum delay from the testbench, through the design, back to the testbench?
It takes one cycle for the output of the TB to be clocked into the DFF, and then one cycle for the output to propagate back into the TB.
Here is the code used in the above example. You can compile it with:
vcs -sverilog -R example.svExample code
// example.sv `timescale 1ns/1ns interface dff_ifc(input bit clock); logic q, d; clocking cb @(posedge clock); output d; input q; endclocking modport DUT (input d, output q); modport TB (clocking cb); endinterface module dff (dff_ifc.DUT dff_if, input bit clock); always @(posedge clock) begin dff_if.q = dff_if.d; $display("@%0d: DUT: q=%b", $time, dff_if.q); end endmodule program automatic test (dff_ifc.TB dff_if); initial #10 repeat (100) #1 $display("@%0d: TB: q=%b", $time, dff_if.cb.q); initial begin ##2 dff_if.cb.d <= 0; $display("@%0d: TB: drive d=0", $time); ##2 dff_if.cb.d <= 1; $display("@%0d: TB: drive d=0", $time); ##2 dff_if.cb.d <= 0; $display("@%0d: TB: drive d=0", $time); ##2 dff_if.cb.d <= 0; $display("@%0d: TB: drive d=0", $time); ##2 dff_if.cb.d <= 0; $display("@%0d: TB: drive d=0", $time); $finish; end endprogram module top; bit clock = 1; always #5 clock = !clock; dff_ifc dff_if(clock); dff a1 (dff_if, clock); test t1(dff_if); initial $monitor("@%0d: Top: d=%b, q=%b, clock=%b", $time, dff_if.d, dff_if.q, clock); endmoduleThe program block has the "automatic" modifier so that all blocks and routines inside will use automatic storage. This is not needed for this example, but is a recommended coding style.
Comments