Home
VHDL info
VHDL links
VHDL models

Timing Checks Using Signal Attributes

An essential part of any VHDL model written for simulation is checking for timing violations, for example, a micropocessor model should check its acknowledge input for setup and hold violations or a memory model should check the active pulse width of its chip select, output enable and write enable inputs. VHDL has several predefined signal attributes which can be used during simulation to perform timing checks such as pulse width violations, setup or hold violations, etc.
The predefined signal attributes are :

Attribute Returns Description
signalname'EVENT Boolean value Returns the value TRUE if there is an event on signalname in the current delta period, else FALSE.
signalname'ACTIVE Boolean value Returns the value TRUE if there is a transaction on signalname in the current delta period, else FALSE.
signalname'QUIET(t) Boolean signal Returns a signal whose value is TRUE when an activity has not occurred on signalname within the last t time units, else FALSE. If t is not specified, then a signal whose value is TRUE when an activity has not occurred on signalname within the current delta period is returned.
signalname'STABLE(t) Boolean signal Returns a signal whose value is TRUE when an event has not occurred on signalname within the last t time units, else FALSE. If t is not specified, then a signal whose value is TRUE when an event has not occurred on signalname within the current delta period is returned.
signalname'TRANSACTION Bit signal Returns a signal of type BIT which toggles whenever an event occurs on signalname.
signalname'DELAYED(t) Signal Returns a signal whose value is that of signalname delayed by t time units. If t is not specified, then a signal whose value is that of signalname delayed by 1 delta period is returned.
signalname'LAST_ACTIVE Time Returns the amount of time since the last activity on signalname.
signalname'LAST_EVENT Time Returns the amount of time since the last event on signalname.
signalname'LAST_VALUE Signal Returns the value that signalname had before the the last event onsignalname.
  • Note that there is no need to type the attribute name in uppercase - VHDL is not case sensitive.
  • VHDL '93 introduced two other predefined signal attributes which are not described here: 'DRIVING and 'DRIVING_VALUE.
  • All the attributes operate on signals, but some return signals and some return values. This is important since it means we can use other attributes on the signals returned by attributes, for example:
IF (ramwe'DELAYED'STABLE(Twe)) THEN

Now that we have defined the attributes, let's see how to use them to perform timing checks. The common thread running through all these checks is this :

  1. Wait until an event (or activity) occurs.
  2. Look back in time to see if the timing requirement was met.

Flip-flop data setup

A clocked flip-flop can be described by the following code snippet :

flip_flop : PROCESS (clk)
 BEGIN
 IF (clk'EVENT AND clk='1') THEN  -- on clock rising edge..  
  q <= d;                         -- ..set q output..
 ELSE
  q <= q;                         -- ..otherwise, no change in q
 END IF;
END PROCESS flip_flop;

The first use of the predefined signal attributes is seen in the IF condition which detects the rising edge of the clk signal. Applying the 'EVENT attribute to clk will return the value TRUE if there has been an event on the clk signal in the current delta time period. If the value of clk is '1' and it has changed value (the definition of an event) then this is the rising edge.

Suppose we now wish to add a check for minimum data setup violation. The data input must not vary (i.e. change state) for a certain time before the clock rising edge - the minimum setup time.

flip_flop : PROCESS (clk)
 BEGIN
  IF (clk'EVENT AND clk='1') THEN   -- on clock rising edge..  

   -- check d has been stable for time Tsu
   IF (d'STABLE(Tsu)) THEN          
    q <= d;                         --..set q output to d..  
   ELSE
    q <= 'X';                       -- ..otherwise, set q unknown
    ASSERT false REPORT "FF: Data setup violation"
    SEVERITY error;
   END IF;

  ELSE
   q <= q;                          -- ..otherwise, no change in q
  END IF;
 END PROCESS flip_flop;

When a rising edge occurs, the second IF condition checks that the data input has been stable, i.e. no event has occurred for at least Tsu time units (Tsu would normally be defined as a constant of type TIME). If that condition is satisfied then q is assigned the value of d. If the condition is not satisfied, then q is assigned the value 'X' to indicate that its value is uncertain and an error message is generated.

Flip-flop data hold

The data input must not vary (i.e. change state) for a certain time after the clock rising edge - the minimum hold time. The technique for checking the hold time is slightly different from the check of the setup time as we have to wait until a rising edge on the clock, then wait for the minimum hold time and then check to see if d has been stable for that time. The easiest way to do this is with WAIT statements, which means that we can't have a sensitivity list.

flip_flop : PROCESS
 BEGIN
  -- wait until a clock rising edge
  WAIT UNTIL (clk'EVENT AND clk='1');
  WAIT FOR (Thld);                     -- wait hold time
  -- check d has been stable for time Thld
  
  IF (d'STABLE(Thld)) THEN    
   q <= d;                             -- ..set q output to d..  
  ELSE
   q <= 'X';                           -- ..otherwise, set q unknown
   ASSERT false REPORT "FF: Data hold violation"
   SEVERITY error;
  END IF;
  
END PROCESS flip_flop;

This process will wait until the rising edge on the clk signal, then wait for the minimum hold time Thld (again, this would normally be defined as a constant). If d has been stable for time Thld, then the output q is assigned the value of d, otherwise it is assigned the value 'X' (undefined) and an error message is asserted.

Basically, the above process waits a certain time (Thld) after the clk rising edge and then "looks back" to see if the data input has remained stable during that time. Another way to achieve that same thing is to delay the clk signal by time Thld and then "look back" to see if d has been stable during that time.

                                
flip_flop : PROCESS
 BEGIN
 WAIT UNTIL (clk'DELAYED(Thld)'EVENT AND clk'DELAYED(Thld)='1');
 
 -- check d has been stable for time Thld
 IF (d'STABLE(Thld)) THEN
  q <= d;                           -- ..set q output to d..
 ELSE
  q <= 'X';                         -- ..otherwise, set q unknown
  ASSERT false REPORT "FF: Data hold violation"
  SEVERITY error;
 END IF;
 
END PROCESS flip_flop;

The first WAIT statement will wait for a rising edge on a signal which is equivalent to the clk signal, but delayed by time Thld, the data is then checked to see if it has been stable for the required time. The 'DELAYED attribute returns a signal, so other attributes can be applied to it.

Pulse width

Checking the width of a pulse is quite simple - just wait until the falling edge for active high pulses or the rising edge for active low pulses and then "look back" at the pulse to check that it has been stable for the required time. The following code snippet checks that an active low static ram write strobe (ramwe) pulse meets the minimum width requirements and will report any violation:

ram_we_check : PROCESS
 BEGIN
 
 -- wait until end of write pulse
 WAIT UNTIL (ramwe'EVENT AND ramwe='1');
 
  -- check ramwe stable for time Twe
  IF (NOT(ramwe'DELAYED'STABLE(Twe))) THEN
   ASSERT false REPORT "RAM: Min write strobe width violation"
   SEVERITY error;
  END IF;
  
END PROCESS ram_we_check;
 

Note that the ramwe signal is not directly tested for stability, instead the 'DELAYED attribute is used to delay it by 1 delta period, otherwise the 'STABLE attribute always returns false since there is an event on ramwe in the current delta period.


Maintained by Mark Harvey. Please email me with any comments.