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.
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 :
Flip-flop data setupA 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.
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 holdThe 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 widthChecking 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. |