Delay Modeling: Timing Checks.

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.

IMAGE

Syntax:

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 );