Keywords: $setup, $hold, $width
This section, the final part of the delay modeling chapter, discusses some of the various system tasks that exist for the purposes of timing checks. Verilog contains many timing-check system tasks, but only the three most common tasks are discussed here: $setup, $hold and $width. Timing checks are used to verify that timing constraints are upheld, and are especially important in the simulation of high-speed sequential circuits such as microprocessors. All timing checks must be contained within specify blocks as shown in the example below.
The $setup and $hold tasks are used to monitor the setup and hold constraints during the simulation of a sequential circuit element. In the example, the setup time is the minimum allowed time between a change in the input d and a positive clock edge. Similarly, the hold time is the minimum allowed time between a positive clock edge and a change in the input d.
The $width task is used to check the minimum width of a positive or negative-going pulse. In the example, this is the time between a negative transition and the transition back to 1.
NB: data_change, reference and reference1 must be declared wires.
$setup(data_change, reference, time_limit);
data_change: signal that is checked against the reference
reference: signal used as reference
time_limit: minimum time required between the two events.
Violation if: Treference - Tdata_change < time_limit.
$hold(reference, data_change, time_limit);
reference: signal used as reference
data_change: signal that is checked against the reference
time_limit: minimum time required between the two events.
Violation if: Tdata_change - Treference < time_limit
$width(reference1, time_limit);
reference1: first transition of signal
time_limit: minimum time required between transition1 and transition2.
Violation if: Treference2 - Treference1 < time_limit
Example:
module d_type(q, clk, d); output q; input clk, d; reg q; always @(posedge clk) q = d; endmodule // d_type module stimulus; reg clk, d; wire q, clk2, d2; d_type dt_test(q, clk, d); assign d2=d; assign clk2=clk; initial begin $display ("\t\t clock d q"); $display ($time," %b %b %b", clk, d, q); clk=0; d=1; #7 d=0; #7 d=1; // causes setup violation #3 d=0; #5 d=1; // causes hold violation #2 d=0; #1 d=1; // causes width violation end // initial begin initial #26 $finish; always #3 clk = ~clk; always #1 $display ($time," %b %b %b", clk, d, q); specify $setup(d2, posedge clk2, 2); $hold(posedge clk2, d2, 2); $width(negedge d2, 2); endspecify
endmodule // stimulus
Output:
clock d q 0 x x x 1 0 1 x 2 0 1 x 3 1 1 x 4 1 1 1 5 1 1 1 6 0 1 1 7 0 0 1 8 0 0 1 9 1 0 1 10 1 0 0 11 1 0 0 12 0 0 0 13 0 0 0 14 0 1 0 15 1 1 0 "timechecks.v", 46: Timing violation in stimulus $setup( d2:14, posedge clk2:15, 2 ); 16 1 1 1 17 1 0 1 18 0 0 1 19 0 0 1 20 0 0 1 21 1 0 1 22 1 1 0 "timechecks.v", 47: Timing violation in stimulus $hold( posedge clk2:21, d2:22, 2 ); 23 1 1 0 24 0 0 0 25 0 1 0 "timechecks.v", 48: Timing violation in stimulus $width( negedge d2:24, : 25, 2 );