summaryrefslogtreecommitdiff
path: root/libraries/vital2000/timing_b.vhdl
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/vital2000/timing_b.vhdl')
-rw-r--r--libraries/vital2000/timing_b.vhdl2187
1 files changed, 2187 insertions, 0 deletions
diff --git a/libraries/vital2000/timing_b.vhdl b/libraries/vital2000/timing_b.vhdl
new file mode 100644
index 0000000..28bf520
--- /dev/null
+++ b/libraries/vital2000/timing_b.vhdl
@@ -0,0 +1,2187 @@
+-------------------------------------------------------------------------------
+-- Title : Standard VITAL TIMING Package
+-- : $Revision: 598 $
+-- Library : VITAL
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, attributes, constants,
+-- : functions and procedures for use in developing ASIC models.
+-- : This file contains the Package Body.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/08/95 | Initial ballot draft 1995
+-- v95.1 | | 08/31/95 | #IR203 - Timing violations at time 0
+-- #IR204 - Output mapping prior to glitch detection
+-- v98.0 |TAG | 03/27/98 | Initial ballot draft 1998
+-- | #IR225 - Negative Premptive Glitch
+-- **Code_effected=ReportGlitch,VitalGlitch,
+-- VitalPathDelay,VitalPathDelay01,
+-- VitalPathDelay01z.
+-- #IR105 - Skew timing check needed
+-- **Code_effected=NONE, New code added!!
+-- #IR245,IR246,IR251 ITC code to fix false boundry cases
+-- **Code_effected=InternalTimingCheck.
+-- #IR248 - Allows VPD to use a default timing delay
+-- **Code_effected=VitalPathDelay,
+-- VitalPathDelay01,VitalPathDelay01z,
+-- VitalSelectPathDelay,VitalSelectPathDelay01,
+-- VitalSelectPathDelay01z.
+-- #IR250 - Corrects fastpath condition in VPD
+-- **Code_effected=VitalPathDelay01,
+-- VitalPathDelay01z,
+-- #IR252 - Corrects cancelled timing check call if
+-- condition expires.
+-- **Code_effected=VitalSetupHoldCheck,
+-- VitalRecoveryRemovalCheck.
+-- v98.1 | jdc | 03/25/99 | Changed UseDefaultDelay to IgnoreDefaultDelay
+-- and set default to FALSE in VitalPathDelay()
+--
+-- ----------------------------------------------------------------------------
+
+LIBRARY STD;
+USE STD.TEXTIO.ALL;
+
+PACKAGE BODY VITAL_Timing IS
+
+ -- --------------------------------------------------------------------
+ -- Package Local Declarations
+ -- --------------------------------------------------------------------
+
+ TYPE CheckType IS ( SetupCheck, HoldCheck, RecoveryCheck, RemovalCheck,
+ PulseWidCheck, PeriodCheck );
+
+ TYPE CheckInfoType IS RECORD
+ Violation : BOOLEAN;
+ CheckKind : CheckType;
+ ObsTime : TIME;
+ ExpTime : TIME;
+ DetTime : TIME;
+ State : X01;
+ END RECORD;
+
+ TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER;
+ TYPE HiLoStrType IS ARRAY (std_ulogic RANGE 'X' TO '1') OF STRING(1 TO 4);
+
+ CONSTANT LogicCvtTable : LogicCvtTableType
+ := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
+ CONSTANT HiLoStr : HiLoStrType := (" X ", " Low", "High" );
+
+ TYPE EdgeSymbolMatchType IS ARRAY (X01,X01,VitalEdgeSymbolType) OF BOOLEAN;
+ -- last value, present value, edge symbol
+ CONSTANT EdgeSymbolMatch : EdgeSymbolMatchType := (
+ 'X'=>('X'=>( OTHERS => FALSE),
+ '0'=>('N'|'F'|'v'|'E'|'D'|'*' => TRUE, OTHERS => FALSE ),
+ '1'=>('P'|'R'|'^'|'E'|'A'|'*' => TRUE, OTHERS => FALSE ) ),
+ '0'=>('X'=>( 'r'|'p'|'R'|'A'|'*' => TRUE, OTHERS => FALSE ),
+ '0'=>( OTHERS => FALSE ),
+ '1'=>( '/'|'P'|'p'|'R'|'*' => TRUE, OTHERS => FALSE ) ),
+ '1'=>('X'=>( 'f'|'n'|'F'|'D'|'*' => TRUE, OTHERS => FALSE ),
+ '0'=>( '\'|'N'|'n'|'F'|'*' => TRUE, OTHERS => FALSE ),
+ '1'=>( OTHERS => FALSE ) ) );
+
+
+
+
+ ---------------------------------------------------------------------------
+ -- Tables used to implement 'posedge' and 'negedge' in path delays
+ -- These are new tables for Skewcheck routines. IR105
+ ---------------------------------------------------------------------------
+
+ TYPE EdgeRable IS ARRAY(std_ulogic, std_ulogic) OF boolean;
+
+ CONSTANT Posedge : EdgeRable := (
+ -- ------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H -
+ -- ------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- U
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- X
+ ( TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE ), -- 0
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- 1
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- Z
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- W
+ ( TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE ), -- L
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- H
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ) -- -
+
+ ); --IR105
+
+
+ CONSTANT Negedge : EdgeRable := (
+ -- -----------------------------------------------------------------------
+ -- | U X 0 1 Z W L H -
+ -- -----------------------------------------------------------------------
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- U
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- X
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- 0
+ ( TRUE , TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE ), -- 1
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- Z
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- W
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- L
+ ( TRUE , TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE ), -- H
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ) -- -
+
+ ); --IR105
+
+ TYPE SkewType IS (Inphase, Outphase); --IR105
+
+ CONSTANT noTrigger : TIME := -1 ns; --IR105
+ ---------------------------------------------------------------------------
+ -- End of Skew (IR105 additions)
+ ---------------------------------------------------------------------------
+
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- Misc Utilities Local Utilities
+ ---------------------------------------------------------------------------
+ -----------------------------------------------------------------------
+ FUNCTION Minimum ( CONSTANT t1,t2 : IN TIME ) RETURN TIME IS
+ BEGIN
+ IF ( t1 < t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Minimum;
+ -----------------------------------------------------------------------
+ FUNCTION Maximum ( CONSTANT t1,t2 : IN TIME ) RETURN TIME IS
+ BEGIN
+ IF ( t1 > t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Maximum;
+
+ --------------------------------------------------------------------
+ -- Error Message Types and Tables
+ --------------------------------------------------------------------
+ TYPE VitalErrorType IS (
+ ErrVctLng ,
+ ErrNoPath ,
+ ErrNegPath ,
+ ErrNegDel
+ );
+
+ TYPE VitalErrorSeverityType IS ARRAY (VitalErrorType) OF SEVERITY_LEVEL;
+ CONSTANT VitalErrorSeverity : VitalErrorSeverityType := (
+ ErrVctLng => ERROR,
+ ErrNoPath => WARNING,
+ ErrNegPath => WARNING,
+ ErrNegDel => WARNING
+ );
+
+ CONSTANT MsgNoPath : STRING :=
+ "No Delay Path Condition TRUE. 0-delay used. Output signal is: ";
+ CONSTANT MsgNegPath : STRING :=
+ "Path Delay less than time since input. 0 delay used. Output signal is: ";
+ CONSTANT MsgNegDel : STRING :=
+ "Negative delay. New output value not scheduled. Output signal is: ";
+ CONSTANT MsgVctLng : STRING :=
+ "Vector (array) lengths not equal. ";
+
+ CONSTANT MsgUnknown : STRING :=
+ "Unknown error message.";
+
+ FUNCTION VitalMessage (
+ CONSTANT ErrorId : IN VitalErrorType
+ ) RETURN STRING IS
+ BEGIN
+ CASE ErrorId IS
+ WHEN ErrVctLng => RETURN MsgVctLng;
+ WHEN ErrNoPath => RETURN MsgNoPath;
+ WHEN ErrNegPath => RETURN MsgNegPath;
+ WHEN ErrNegDel => RETURN MsgNegDel;
+ WHEN OTHERS => RETURN MsgUnknown;
+ END CASE;
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId)
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN STRING
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN CHARACTER
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Time Delay Assignment Subprograms
+ ---------------------------------------------------------------------------
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN VitalDelayType01Z IS
+ BEGIN
+ RETURN (OTHERS => Delay);
+ END VitalExtendToFillDelay;
+
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN VitalDelayType01Z IS
+ VARIABLE Delay01Z : VitalDelayType01Z;
+ BEGIN
+ Delay01Z(tr01) := Delay(tr01);
+ Delay01Z(tr0z) := Delay(tr01);
+ Delay01Z(trz1) := Delay(tr01);
+ Delay01Z(tr10) := Delay(tr10);
+ Delay01Z(tr1z) := Delay(tr10);
+ Delay01Z(trz0) := Delay(tr10);
+ RETURN (Delay01Z);
+ END VitalExtendToFillDelay;
+
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN VitalDelayType01Z IS
+ BEGIN
+ RETURN Delay;
+ END VitalExtendToFillDelay;
+
+ ---------------------------------------------------------------------------
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN TIME IS
+ BEGIN
+ RETURN delay;
+ END VitalCalcDelay;
+
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN TIME IS
+ VARIABLE Result : TIME;
+ BEGIN
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(tr10);
+ WHEN '1' | 'H' => Result := Delay(tr01);
+ WHEN 'Z' =>
+ CASE Oldval IS
+ WHEN '0' | 'L' => Result := Delay(tr01);
+ WHEN '1' | 'H' => Result := Delay(tr10);
+ WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01));
+ END CASE;
+ WHEN OTHERS =>
+ CASE Oldval IS
+ WHEN '0' | 'L' => Result := Delay(tr01);
+ WHEN '1' | 'H' => Result := Delay(tr10);
+ WHEN 'Z' => Result := MINIMUM(Delay(tr10), Delay(tr01));
+ WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01));
+ END CASE;
+ END CASE;
+ RETURN Result;
+ END VitalCalcDelay;
+
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN TIME IS
+ VARIABLE Result : TIME;
+ BEGIN
+ CASE Oldval IS
+ WHEN '0' | 'L' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(tr10);
+ WHEN '1' | 'H' => Result := Delay(tr01);
+ WHEN 'Z' => Result := Delay(tr0z);
+ WHEN OTHERS => Result := MINIMUM(Delay(tr01), Delay(tr0z));
+ END CASE;
+ WHEN '1' | 'H' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(tr10);
+ WHEN '1' | 'H' => Result := Delay(tr01);
+ WHEN 'Z' => Result := Delay(tr1z);
+ WHEN OTHERS => Result := MINIMUM(Delay(tr10), Delay(tr1z));
+ END CASE;
+ WHEN 'Z' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(trz0);
+ WHEN '1' | 'H' => Result := Delay(trz1);
+ WHEN 'Z' => Result := MAXIMUM (Delay(tr0z), Delay(tr1z));
+ WHEN OTHERS => Result := MINIMUM (Delay(trz1), Delay(trz0));
+ END CASE;
+ WHEN 'U' | 'X' | 'W' | '-' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := MAXIMUM(Delay(tr10), Delay(trz0));
+ WHEN '1' | 'H' => Result := MAXIMUM(Delay(tr01), Delay(trz1));
+ WHEN 'Z' => Result := MAXIMUM(Delay(tr1z), Delay(tr0z));
+ WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01));
+ END CASE;
+ END CASE;
+ RETURN Result;
+ END VitalCalcDelay;
+
+ ---------------------------------------------------------------------------
+ --
+ -- VitalSelectPathDelay returns the path delay selected by the Paths array.
+ -- If no paths are selected, it returns either the appropriate default
+ -- delay or TIME'HIGH, depending upon the value of IgnoreDefaultDelay.
+ --
+
+ FUNCTION VitalSelectPathDelay (
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT OldValue : IN std_logic;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT Paths : IN VitalPathArrayType;
+ CONSTANT DefaultDelay : IN VitalDelayType;
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN
+ ) RETURN TIME IS
+
+ VARIABLE TmpDelay : TIME;
+ VARIABLE InputAge : TIME := TIME'HIGH;
+ VARIABLE PropDelay : TIME := TIME'HIGH;
+ BEGIN
+ -- for each delay path
+ FOR i IN Paths'RANGE LOOP
+ -- ignore the delay path if it is not enabled
+ NEXT WHEN NOT Paths(i).PathCondition;
+ -- ignore the delay path if a more recent input event has been seen
+ NEXT WHEN Paths(i).InputChangeTime > InputAge;
+
+ -- This is the most recent input change (so far)
+ -- Get the transition dependent delay
+ TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay);
+
+ -- If other inputs changed at the same time,
+ -- then use the minimum of their propagation delays,
+ -- else use the propagation delay from this input.
+ IF Paths(i).InputChangeTime < InputAge THEN
+ PropDelay := TmpDelay;
+ ELSE -- Simultaneous inputs change
+ IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF;
+ end if;
+
+ InputAge := Paths(i).InputChangeTime;
+ END LOOP;
+
+ -- If there were no paths (with an enabled condition),
+ -- use the default delay, if so indicated, otherwise return TIME'HIGH
+ IF (PropDelay = TIME'HIGH) THEN
+ IF (IgnoreDefaultDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+ END IF;
+
+ -- If the time since the most recent selected input event is
+ -- greater than the propagation delay from that input,
+ -- then use the default delay (won't happen if no paths are selected)
+ ELSIF (InputAge > PropDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- Adjust the propagation delay by the time since the
+ -- the input event occurred (Usually 0 ns).
+ ELSE
+ PropDelay := PropDelay - InputAge;
+ END IF;
+
+ RETURN PropDelay;
+ END;
+
+ FUNCTION VitalSelectPathDelay (
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT OldValue : IN std_logic;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT Paths : IN VitalPathArray01Type;
+ CONSTANT DefaultDelay : IN VitalDelayType01;
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN
+ ) RETURN TIME IS
+
+ VARIABLE TmpDelay : TIME;
+ VARIABLE InputAge : TIME := TIME'HIGH;
+ VARIABLE PropDelay : TIME := TIME'HIGH;
+ BEGIN
+ -- for each delay path
+ FOR i IN Paths'RANGE LOOP
+ -- ignore the delay path if it is not enabled
+ NEXT WHEN NOT Paths(i).PathCondition;
+ -- ignore the delay path if a more recent input event has been seen
+ NEXT WHEN Paths(i).InputChangeTime > InputAge;
+
+ -- This is the most recent input change (so far)
+ -- Get the transition dependent delay
+ TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay);
+
+ -- If other inputs changed at the same time,
+ -- then use the minimum of their propagation delays,
+ -- else use the propagation delay from this input.
+ IF Paths(i).InputChangeTime < InputAge THEN
+ PropDelay := TmpDelay;
+ ELSE -- Simultaneous inputs change
+ IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF;
+ end if;
+
+ InputAge := Paths(i).InputChangeTime;
+ END LOOP;
+
+ -- If there were no paths (with an enabled condition),
+ -- use the default delay, if so indicated, otherwise return TIME'HIGH
+ IF (PropDelay = TIME'HIGH) THEN
+ IF (IgnoreDefaultDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+ END IF;
+
+ -- If the time since the most recent selected input event is
+ -- greater than the propagation delay from that input,
+ -- then use the default delay (won't happen if no paths are selected)
+ ELSIF (InputAge > PropDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- Adjust the propagation delay by the time since the
+ -- the input event occurred (Usually 0 ns).
+ ELSE
+ PropDelay := PropDelay - InputAge;
+ END IF;
+
+ RETURN PropDelay;
+ END;
+
+ FUNCTION VitalSelectPathDelay (
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT OldValue : IN std_logic;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT Paths : IN VitalPathArray01ZType;
+ CONSTANT DefaultDelay : IN VitalDelayType01Z;
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN
+ ) RETURN TIME IS
+
+ VARIABLE TmpDelay : TIME;
+ VARIABLE InputAge : TIME := TIME'HIGH;
+ VARIABLE PropDelay : TIME := TIME'HIGH;
+ BEGIN
+ -- for each delay path
+ FOR i IN Paths'RANGE LOOP
+ -- ignore the delay path if it is not enabled
+ NEXT WHEN NOT Paths(i).PathCondition;
+ -- ignore the delay path if a more recent input event has been seen
+ NEXT WHEN Paths(i).InputChangeTime > InputAge;
+
+ -- This is the most recent input change (so far)
+ -- Get the transition dependent delay
+ TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay);
+
+ -- If other inputs changed at the same time,
+ -- then use the minimum of their propagation delays,
+ -- else use the propagation delay from this input.
+ IF Paths(i).InputChangeTime < InputAge THEN
+ PropDelay := TmpDelay;
+ ELSE -- Simultaneous inputs change
+ IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF;
+ end if;
+
+ InputAge := Paths(i).InputChangeTime;
+ END LOOP;
+
+ -- If there were no paths (with an enabled condition),
+ -- use the default delay, if so indicated, otherwise return TIME'HIGH
+ IF (PropDelay = TIME'HIGH) THEN
+ IF (IgnoreDefaultDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+ END IF;
+
+ -- If the time since the most recent selected input event is
+ -- greater than the propagation delay from that input,
+ -- then use the default delay (won't happen if no paths are selected)
+ ELSIF (InputAge > PropDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- Adjust the propagation delay by the time since the
+ -- the input event occurred (Usually 0 ns).
+ ELSE
+ PropDelay := PropDelay - InputAge;
+ END IF;
+
+ RETURN PropDelay;
+ END;
+
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- Glitch Handlers
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ PROCEDURE ReportGlitch (
+ CONSTANT GlitchRoutine : IN STRING;
+ CONSTANT OutSignalName : IN STRING;
+ CONSTANT PreemptedTime : IN TIME;
+ CONSTANT PreemptedValue : IN std_ulogic;
+ CONSTANT NewTime : IN TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT Index : IN INTEGER := 0;
+ CONSTANT IsArraySignal : IN BOOLEAN := FALSE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE StrPtr1, StrPtr2, StrPtr3, StrPtr4, StrPtr5 : LINE;
+ BEGIN
+
+ Write (StrPtr1, PreemptedTime );
+ Write (StrPtr2, NewTime);
+ Write (StrPtr3, LogicCvtTable(PreemptedValue));
+ Write (StrPtr4, LogicCvtTable(NewValue));
+ IF IsArraySignal THEN
+ Write (StrPtr5, STRING'( "(" ) );
+ Write (StrPtr5, Index);
+ Write (StrPtr5, STRING'( ")" ) );
+ ELSE
+ Write (StrPtr5, STRING'( " " ) );
+ END IF;
+
+ -- Issue Report only if Preempted value has not been
+ -- removed from event queue
+ ASSERT PreemptedTime > NewTime
+ REPORT GlitchRoutine & ": GLITCH Detected on port " &
+ OutSignalName & StrPtr5.ALL &
+ "; Preempted Future Value := " & StrPtr3.ALL &
+ " @ " & StrPtr1.ALL &
+ "; Newly Scheduled Value := " & StrPtr4.ALL &
+ " @ " & StrPtr2.ALL &
+ ";"
+ SEVERITY MsgSeverity;
+
+
+ ASSERT PreemptedTime <= NewTime
+ REPORT GlitchRoutine & ": GLITCH Detected on port " &
+ OutSignalName & StrPtr5.ALL &
+ "; Negative Preempted Value := " & StrPtr3.ALL &
+ " @ " & StrPtr1.ALL &
+ "; Newly Scheduled Value := " & StrPtr4.ALL &
+ " @ " & StrPtr2.ALL &
+ ";"
+ SEVERITY MsgSeverity;
+
+
+ DEALLOCATE(StrPtr1);
+ DEALLOCATE(StrPtr2);
+ DEALLOCATE(StrPtr3);
+ DEALLOCATE(StrPtr4);
+ DEALLOCATE(StrPtr5);
+ RETURN;
+ END ReportGlitch;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalGlitch (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT NewDelay : IN TIME := 0 ns;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225
+ CONSTANT MsgOn : IN BOOLEAN := FALSE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+ ---------------------------------------------------------------------------
+ VARIABLE NewGlitch : BOOLEAN := TRUE;
+ VARIABLE dly : TIME := NewDelay;
+ VARIABLE NOW_TIME : TIME := NOW;
+ VARIABLE NegPreemptGlitch : BOOLEAN := FALSE;
+
+ BEGIN
+ NegPreemptGlitch:=FALSE;--reset Preempt-Glitch
+
+ -- If nothing to schedule, just return
+ IF NewDelay < 0 ns THEN
+ IF (NewValue /= GlitchData.SchedValue) THEN
+ VitalError ( "VitalGlitch", ErrNegDel, OutSignalName );
+ END IF;
+ RETURN;
+ END IF;
+
+ -- If simple signal assignment
+ -- perform the signal assignment
+ IF ( Mode = VitalInertial) THEN
+ OutSignal <= NewValue AFTER dly;
+ ELSIF ( Mode = VitalTransport ) THEN
+ OutSignal <= TRANSPORT NewValue AFTER dly;
+ ELSE
+ -- Glitch Processing ---
+ -- If nothing currently scheduled
+ IF GlitchData.SchedTime <= NOW THEN -- NOW >= last event
+ -- Note: NewValue is always /= OldValue when called from VPPD
+ IF (NewValue = GlitchData.SchedValue) THEN RETURN; END IF;
+ NewGlitch := FALSE;
+ GlitchData.GlitchTime := NOW+dly;
+
+ -- New value earlier than the earliest previous value scheduled
+ -- (negative preemptive)
+ ELSIF (NOW+dly <= GlitchData.GlitchTime)
+ AND (NOW+dly <= GlitchData.SchedTime) THEN
+
+ -- Glitch is negative preemptive - check if same value and
+ -- NegPreempt is on IR225
+ IF (GlitchData.SchedValue /= NewValue) AND (NegPreemptOn) AND
+ (NOW > 0 NS) THEN
+ NewGlitch := TRUE;
+ NegPreemptGlitch :=TRUE; -- Set preempt Glitch condition
+ ELSE
+ NewGlitch := FALSE; -- No new glitch, save time for
+ -- possible future glitch
+ END IF;
+ GlitchData.GlitchTime := NOW+dly;
+
+ -- Transaction currently scheduled - if glitch already happened
+ ELSIF GlitchData.GlitchTime <= NOW THEN
+ IF (GlitchData.SchedValue = NewValue) THEN
+ dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+ END IF;
+ NewGlitch := FALSE;
+
+ -- Transaction currently scheduled (no glitch if same value)
+ ELSIF (GlitchData.SchedValue = NewValue)
+ AND (GlitchData.SchedTime = GlitchData.GlitchTime) THEN
+ -- revise scheduled output time if new delay is sooner
+ dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+ -- No new glitch, save time for possable future glitch
+ NewGlitch := FALSE;
+ GlitchData.GlitchTime := NOW+dly;
+
+ -- Transaction currently scheduled represents a glitch
+ ELSE
+ NewGlitch := TRUE; -- A new glitch has been detected
+ END IF;
+
+ IF NewGlitch THEN
+ -- If messages requested, report the glitch
+ IF MsgOn THEN
+ IF NegPreemptGlitch THEN --IR225
+ ReportGlitch ("VitalGlitch-Neg", OutSignalName,
+ GlitchData.GlitchTime, GlitchData.SchedValue,
+ (dly + NOW), NewValue,
+ MsgSeverity=>MsgSeverity );
+ ELSE
+ ReportGlitch ("VitalGlitch", OutSignalName,
+ GlitchData.GlitchTime, GlitchData.SchedValue,
+ (dly + NOW), NewValue,
+ MsgSeverity=>MsgSeverity );
+ END IF;
+ END IF;
+
+ -- If 'X' generation is requested, schedule the new value
+ -- preceeded by a glitch pulse.
+ -- Otherwise just schedule the new value (inertial mode).
+ IF XOn THEN
+ IF (Mode = OnDetect) THEN
+ OutSignal <= 'X';
+ ELSE
+ OutSignal <= 'X' AFTER GlitchData.GlitchTime-NOW;
+ END IF;
+
+ IF NegPreemptGlitch THEN -- IR225
+ OutSignal <= TRANSPORT NewValue AFTER GlitchData.SchedTime-NOW;
+ ELSE
+ OutSignal <= TRANSPORT NewValue AFTER dly;
+ END IF;
+ ELSE
+ OutSignal <= NewValue AFTER dly; -- no glitch regular prop delay
+ END IF;
+
+ -- If there no new glitch was detected, just schedule the new value.
+ ELSE
+ OutSignal <= NewValue AFTER dly;
+ END IF;
+ END IF;
+
+ -- Record the new value and time depending on glitch type just scheduled.
+ IF NOT NegPreemptGlitch THEN -- 5/2/96 for "x-pulse" IR225
+ GlitchData.SchedValue := NewValue;
+ GlitchData.SchedTime := NOW+dly; -- pulse timing.
+ ELSE
+ GlitchData.SchedValue := 'X';
+ -- leave GlitchData.SchedTime to old value since glitch is negative
+ END IF;
+ RETURN;
+ END;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalPathDelay (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArrayType;
+ CONSTANT DefaultDelay : IN VitalDelayType := VitalZeroDelay;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE --IR248 3/14/98
+ ) IS
+
+ VARIABLE PropDelay : TIME;
+
+ BEGIN
+ -- Check if the new value to be scheduled is different than the
+ -- previously scheduled value
+ IF (GlitchData.SchedTime <= NOW) AND
+ (GlitchData.SchedValue = OutTemp)
+ THEN RETURN;
+ END IF;
+
+ -- Evaluate propagation delay paths
+ PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue,
+ OutSignalName, Paths, DefaultDelay,
+ IgnoreDefaultDelay);
+
+ GlitchData.LastValue := OutTemp;
+
+ -- Schedule the output transactions - including glitch handling
+ VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp,
+ PropDelay, Mode, XOn, NegPreemptOn, MsgOn, MsgSeverity );
+
+ END VitalPathDelay;
+
+ ---------------------------------------------------------------------------
+
+ PROCEDURE VitalPathDelay01 (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01Type;
+ CONSTANT DefaultDelay : IN VitalDelayType01 := VitalZeroDelay01;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98
+ CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250
+
+
+ ) IS
+
+ VARIABLE PropDelay : TIME;
+ BEGIN
+
+ -- Check if the new value to be scheduled is different than the
+ -- previously scheduled value
+ IF (GlitchData.SchedTime <= NOW) AND
+ (GlitchData.SchedValue = OutTemp)
+ THEN RETURN;
+ -- Check if the new value to be Scheduled is the same as the
+ -- previously scheduled output transactions. If this condition
+ -- exists and the new scheduled time is < the current GlitchData.
+ -- schedTime then a fast path condition exists (IR250). If the
+ -- modeler wants this condition rejected by setting the
+ -- RejectFastPath actual to true then exit out.
+ ELSIF (GlitchData.SchedValue=OutTemp) AND (RejectFastPath)
+ THEN RETURN;
+ END IF;
+
+ -- Evaluate propagation delay paths
+ PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue,
+ OutSignalName, Paths, DefaultDelay,
+ IgnoreDefaultDelay);
+
+ GlitchData.LastValue := OutTemp;
+
+
+ VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp,
+ PropDelay, Mode, XOn, NegPreemptOn, MsgOn, MsgSeverity );
+ END VitalPathDelay01;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalPathDelay01Z (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01ZType;
+ CONSTANT DefaultDelay : IN VitalDelayType01Z := VitalZeroDelay01Z;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98
+ CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250
+ ) IS
+
+ VARIABLE PropDelay : TIME;
+
+ BEGIN
+ -- Check if the new value to be scheduled is different than the
+ -- previously scheduled value
+ IF (GlitchData.SchedTime <= NOW) AND
+ (GlitchData.SchedValue = OutTemp)
+ THEN RETURN;
+ -- Check if the new value to be Scheduled is the same as the
+ -- previously scheduled output transactions. If this condition
+ -- exists and the new scheduled time is < the current GlitchData.
+ -- schedTime then a fast path condition exists (IR250). If the
+ -- modeler wants this condition rejected by setting the
+ -- RejectFastPath actual to true then exit out.
+ ELSIF (GlitchData.SchedValue=OutTemp) AND (RejectFastPath)
+ THEN RETURN;
+ END IF;
+
+ -- Evaluate propagation delay paths
+ PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue,
+ OutSignalName, Paths, DefaultDelay,
+ IgnoreDefaultDelay);
+
+ GlitchData.LastValue := OutTemp;
+
+
+ -- Schedule the output transactions - including glitch handling
+ VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp,
+ PropDelay, Mode, XOn, NegPreemptOn, MsgOn, MsgSeverity );
+ END VitalPathDelay01Z;
+
+
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType
+ ) IS
+ BEGIN
+ OutSig <= TRANSPORT InSig AFTER twire;
+ END VitalWireDelay;
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01
+ ) IS
+ VARIABLE Delay : TIME;
+ BEGIN
+ Delay := VitalCalcDelay( InSig, InSig'LAST_VALUE, twire );
+ OutSig <= TRANSPORT InSig AFTER Delay;
+ END VitalWireDelay;
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01Z
+ ) IS
+ VARIABLE Delay : TIME;
+ BEGIN
+ Delay := VitalCalcDelay( InSig, InSig'LAST_VALUE, twire );
+ OutSig <= TRANSPORT InSig AFTER Delay;
+ END VitalWireDelay;
+
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalSignalDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT dly : IN TIME
+ ) IS
+ BEGIN
+ OutSig <= TRANSPORT InSig AFTER dly;
+ END;
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- Setup and Hold Time Check Routine
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ PROCEDURE ReportViolation (
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT CheckInfo : IN CheckInfoType;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+ VARIABLE Message : LINE;
+ BEGIN
+ IF NOT CheckInfo.Violation THEN RETURN; END IF;
+
+ Write ( Message, HeaderMsg );
+ Case CheckInfo.CheckKind IS
+ WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") );
+ WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") );
+ WHEN RecoveryCheck => Write ( Message, STRING'(" RECOVERY ") );
+ WHEN RemovalCheck => Write ( Message, STRING'(" REMOVAL ") );
+ WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH "));
+ WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") );
+ END CASE;
+ Write ( Message, HiLoStr(CheckInfo.State) );
+ Write ( Message, STRING'(" VIOLATION ON ") );
+ Write ( Message, TestSignalName );
+ IF (RefSignalName'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, RefSignalName );
+ END IF;
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" Expected := ") );
+ Write ( Message, CheckInfo.ExpTime);
+ Write ( Message, STRING'("; Observed := ") );
+ Write ( Message, CheckInfo.ObsTime);
+ Write ( Message, STRING'("; At : ") );
+ Write ( Message, CheckInfo.DetTime);
+
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+
+ DEALLOCATE (Message);
+ END ReportViolation;
+
+
+ ---------------------------------------------------------------------------
+ -- Procedure : InternalTimingCheck
+ ---------------------------------------------------------------------------
+ PROCEDURE InternalTimingCheck (
+ CONSTANT TestSignal : IN std_ulogic;
+ CONSTANT RefSignal : IN std_ulogic;
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ VARIABLE RefTime : IN TIME;
+ VARIABLE RefEdge : IN BOOLEAN;
+ VARIABLE TestTime : IN TIME;
+ VARIABLE TestEvent : IN BOOLEAN;
+ VARIABLE SetupEn : INOUT BOOLEAN;
+ VARIABLE HoldEn : INOUT BOOLEAN;
+ VARIABLE CheckInfo : INOUT CheckInfoType;
+ CONSTANT MsgOn : IN BOOLEAN
+ ) IS
+ VARIABLE bias : TIME;
+ VARIABLE actualObsTime : TIME;
+ VARIABLE BC : TIME;
+ VARIABLE Message:LINE;
+ BEGIN
+ -- Check SETUP constraint
+ IF RefEdge THEN
+ IF SetupEn THEN
+ CheckInfo.ObsTime := RefTime - TestTime;
+ CheckInfo.State := To_X01(TestSignal);
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := SetupLow;
+ -- start of new code IR245-246
+ BC := HoldHigh;
+ -- end of new code IR245-246
+ WHEN '1' => CheckInfo.ExpTime := SetupHigh;
+ -- start of new code IR245-246
+ BC := HoldLow;
+ -- end of new code IR245-246
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow);
+ -- start of new code IR245-246
+ BC := Maximum(HoldHigh,HoldLow);
+ -- end of new code IR245-246
+ END CASE;
+ -- added the second condition for IR 245-246
+ CheckInfo.Violation := ( (CheckInfo.ObsTime < CheckInfo.ExpTime)
+ AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns))) );
+ -- start of new code IR245-246
+ IF(CheckInfo.ExpTime = 0 ns) THEN
+ CheckInfo.CheckKind := HoldCheck;
+ ELSE
+ CheckInfo.CheckKind := SetupCheck;
+ END IF;
+ -- end of new code IR245-246
+ SetupEn := FALSE;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+
+ -- Check HOLD constraint
+ ELSIF TestEvent THEN
+ IF HoldEn THEN
+ CheckInfo.ObsTime := TestTime - RefTime;
+ CheckInfo.State := To_X01(TestSignal);
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := HoldHigh;
+
+ -- new code for unnamed IR
+ CheckInfo.State := '1';
+
+ -- start of new code IR245-246
+ BC := SetupLow;
+ -- end of new code IR245-246
+ WHEN '1' => CheckInfo.ExpTime := HoldLow;
+
+ -- new code for unnamed IR
+ CheckInfo.State := '0';
+
+ -- start of new code IR245-246
+ BC := SetupHigh;
+ -- end of new code IR245-246
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow);
+ -- start of new code IR245-246
+ BC := Maximum(SetupHigh,SetupLow);
+ -- end of new code IR245-246
+ END CASE;
+ -- added the second condition for IR 245-246
+ CheckInfo.Violation := ( (CheckInfo.ObsTime < CheckInfo.ExpTime)
+ AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns))) );
+
+ -- start of new code IR245-246
+ IF(CheckInfo.ExpTime = 0 ns) THEN
+ CheckInfo.CheckKind := SetupCheck;
+ ELSE
+ CheckInfo.CheckKind := HoldCheck;
+ END IF;
+ -- end of new code IR245-246
+ HoldEn := NOT CheckInfo.Violation;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+
+ -- Adjust report values to account for internal model delays
+ -- Note: TestDelay, RefDelay, TestTime, RefTime are non-negative
+ -- Note: bias may be negative or positive
+ IF MsgOn AND CheckInfo.Violation THEN
+ -- modified the code for correct reporting of violation in case of
+ -- order of signals being reversed because of internal delays
+ -- new variable
+ actualObsTime := (TestTime-TestDelay)-(RefTime-RefDelay);
+ bias := TestDelay - RefDelay;
+ IF (actualObsTime < 0 ns) THEN -- It should be a setup check
+ IF ( CheckInfo.CheckKind = HoldCheck) then
+ CheckInfo.CheckKind := SetupCheck;
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := SetupLow;
+ WHEN '1' => CheckInfo.ExpTime := SetupHigh;
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow);
+ END CASE;
+ END IF;
+
+ CheckInfo.ObsTime := -actualObsTime;
+ CheckInfo.ExpTime := CheckInfo.ExpTime + bias;
+ CheckInfo.DetTime := RefTime - RefDelay;
+ ELSE -- It should be a hold check
+ IF ( CheckInfo.CheckKind = SetupCheck) then
+ CheckInfo.CheckKind := HoldCheck;
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := HoldHigh;
+ CheckInfo.State := '1';
+ WHEN '1' => CheckInfo.ExpTime := HoldLow;
+ CheckInfo.State := '0';
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow);
+ END CASE;
+ END IF;
+
+ CheckInfo.ObsTime := actualObsTime;
+ CheckInfo.ExpTime := CheckInfo.ExpTime - bias;
+ CheckInfo.DetTime := TestTime - TestDelay;
+ END IF;
+
+ END IF;
+ END InternalTimingCheck;
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ FUNCTION VitalTimingDataInit
+ RETURN VitalTimingDataType IS
+ BEGIN
+ RETURN (FALSE,'X', 0 ns, FALSE, 'X', 0 ns, FALSE, NULL, NULL, NULL, NULL);
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : VitalSetupHoldCheck
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+ ) IS
+
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge, TestEvent : BOOLEAN;
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+ BEGIN
+
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLast := To_X01(TestSignal);
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ TimingData.SetupEn := TimingData.SetupEn AND EnableSetupOnRef; --IR252 3/23/98
+ TimingData.HoldEn := EnableHoldOnRef; --IR252 3/23/98
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ TestEvent := TimingData.TestLast /= To_X01Z(TestSignal);
+ TimingData.TestLast := To_X01Z(TestSignal);
+ IF TestEvent THEN
+ TimingData.TestTime := NOW;
+ TimingData.SetupEn := EnableSetupOnTest; --IR252 3/23/98
+ TimingData.HoldEn := TimingData.HoldEn AND EnableHoldOnTest; --IR252 3/23/98
+ END IF;
+
+ -- Perform timing checks (if enabled)
+ Violation := '0';
+ IF (CheckEnabled) THEN
+ InternalTimingCheck (
+ TestSignal => TestSignal,
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh,
+ SetupLow => SetupLow,
+ HoldHigh => HoldHigh,
+ HoldLow => HoldLow,
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTime,
+ TestEvent => TestEvent,
+ SetupEn => TimingData.SetupEn,
+ HoldEn => TimingData.HoldEn,
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ ReportViolation (TestSignalName, RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF;
+ IF (XOn) THEN Violation := 'X'; END IF;
+ END IF;
+ END IF;
+
+ END VitalSetupHoldCheck;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+
+ ) IS
+
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : BOOLEAN;
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE);
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+ VARIABLE ChangedAllAtOnce : BOOLEAN := TRUE;
+ VARIABLE StrPtr1 : LINE;
+
+ BEGIN
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE);
+ TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignal(i));
+ END LOOP;
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ TimingData.SetupEn := TimingData.SetupEn AND EnableSetupOnRef; --IR252 3/23/98
+ TimingData.HoldEnA.all := (TestSignal'RANGE => EnableHoldOnRef); --IR252 3/23/98
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignal'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignal(i));
+ IF TestEvent(i) THEN
+ TimingData.TestTimeA(i) := NOW;
+ TimingData.SetupEnA(i) := EnableSetupOnTest; --IR252 3/23/98
+ TimingData.HoldEnA(i) := TimingData.HoldEn AND EnableHoldOnTest; --IR252 3/23/98
+ TimingData.TestTime := NOW; --IR252 3/23/98
+ END IF;
+ END LOOP;
+
+ -- Check to see if the Bus subelements changed all at the same time.
+ -- If so, then we can reduce the volume of error messages since we no
+ -- longer have to report every subelement individually
+ FOR i IN TestSignal'RANGE LOOP
+ IF TimingData.TestTimeA(i) /= TimingData.TestTime THEN
+ ChangedAllAtOnce := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ -- Perform timing checks (if enabled)
+ Violation := '0';
+ IF (CheckEnabled) THEN
+ FOR i IN TestSignal'RANGE LOOP
+ InternalTimingCheck (
+ TestSignal => TestSignal(i),
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh,
+ SetupLow => SetupLow,
+ HoldHigh => HoldHigh,
+ HoldLow => HoldLow,
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(i),
+ HoldEn => TimingData.HoldEnA(i),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ IF ( ChangedAllAtOnce AND (i = TestSignal'LEFT) ) THEN
+ ReportViolation (TestSignalName&"(...)", RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ ELSIF (NOT ChangedAllAtOnce) THEN
+ Write (StrPtr1, i);
+ ReportViolation (TestSignalName & "(" & StrPtr1.ALL & ")",
+ RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ DEALLOCATE (StrPtr1);
+ END IF;
+ END IF;
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ END IF;
+ END LOOP;
+ END IF;
+
+ DEALLOCATE (StrPtr1);
+
+ END VitalSetupHoldCheck;
+
+ ---------------------------------------------------------------------------
+ -- Function : VitalRecoveryRemovalCheck
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalRecoveryRemovalCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT Recovery : IN TIME := 0 ns;
+ CONSTANT Removal : IN TIME := 0 ns;
+ CONSTANT ActiveLow : IN BOOLEAN := TRUE;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableRecOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRecOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRemOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRemOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+ ) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge, TestEvent : BOOLEAN;
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+ BEGIN
+
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLast := To_X01(TestSignal);
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ TimingData.SetupEn := TimingData.SetupEn AND EnableRecOnRef; --IR252 3/23/98
+ TimingData.HoldEn := EnableRemOnRef; --IR252 3/23/98
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ TestEvent := TimingData.TestLast /= To_X01Z(TestSignal);
+ TimingData.TestLast := To_X01Z(TestSignal);
+ IF TestEvent THEN
+ TimingData.TestTime := NOW;
+ TimingData.SetupEn := EnableRecOnTest; --IR252 3/23/98
+ TimingData.HoldEn := TimingData.HoldEn AND EnableRemOnTest; --IR252 3/23/98
+ END IF;
+
+ -- Perform timing checks (if enabled)
+ Violation := '0';
+ IF (CheckEnabled) THEN
+
+ IF ActiveLow THEN
+ InternalTimingCheck (
+ TestSignal, RefSignal, TestDly, RefDly,
+ Recovery, 0 ns, 0 ns, Removal,
+ TimingData.RefTime, RefEdge,
+ TimingData.TestTime, TestEvent,
+ TimingData.SetupEn, TimingData.HoldEn,
+ CheckInfo, MsgOn );
+ ELSE
+ InternalTimingCheck (
+ TestSignal, RefSignal, TestDly, RefDly,
+ 0 ns, Recovery, Removal, 0 ns,
+ TimingData.RefTime, RefEdge,
+ TimingData.TestTime, TestEvent,
+ TimingData.SetupEn, TimingData.HoldEn,
+ CheckInfo, MsgOn );
+ END IF;
+
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF CheckInfo.CheckKind = SetupCheck THEN
+ CheckInfo.CheckKind := RecoveryCheck;
+ ELSE
+ CheckInfo.CheckKind := RemovalCheck;
+ END IF;
+ IF (MsgOn) THEN
+ ReportViolation (TestSignalName, RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF;
+ IF (XOn) THEN Violation := 'X'; END IF;
+ END IF;
+ END IF;
+
+ END VitalRecoveryRemovalCheck;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalPeriodPulseCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE PeriodData : INOUT VitalPeriodDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT Period : IN TIME := 0 ns;
+ CONSTANT PulseWidthHigh : IN TIME := 0 ns;
+ CONSTANT PulseWidthLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE PeriodObs : TIME;
+ VARIABLE PulseTest, PeriodTest : BOOLEAN;
+ VARIABLE TestValue : X01 := To_X01(TestSignal);
+ BEGIN
+
+ IF (PeriodData.NotFirstFlag = FALSE) THEN
+ PeriodData.Rise :=
+ -maximum(Period, maximum(PulseWidthHigh, PulseWidthLow));
+ PeriodData.Fall :=
+ -maximum(Period, maximum(PulseWidthHigh, PulseWidthLow));
+ PeriodData.Last := To_X01(TestSignal);
+ PeriodData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Initialize for no violation
+ -- No violation possible if no test signal change
+ Violation := '0';
+ IF (PeriodData.Last = TestValue) THEN
+ RETURN;
+ END IF;
+
+ -- record starting pulse times
+ IF EdgeSymbolMatch(PeriodData.Last, TestValue, 'P') THEN
+ -- Compute period times, then record the High Rise Time
+ PeriodObs := NOW - PeriodData.Rise;
+ PeriodData.Rise := NOW;
+ PeriodTest := TRUE;
+ ELSIF EdgeSymbolMatch(PeriodData.Last, TestValue, 'N') THEN
+ -- Compute period times, then record the Low Fall Time
+ PeriodObs := NOW - PeriodData.Fall;
+ PeriodData.Fall := NOW;
+ PeriodTest := TRUE;
+ ELSE
+ PeriodTest := FALSE;
+ END IF;
+
+ -- do checks on pulse ends
+ IF EdgeSymbolMatch(PeriodData.Last, TestValue, 'p') THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData.Fall;
+ CheckInfo.ExpTime := PulseWidthLow;
+ PulseTest := TRUE;
+ ELSIF EdgeSymbolMatch(PeriodData.Last, TestValue, 'n') THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData.Rise;
+ CheckInfo.ExpTime := PulseWidthHigh;
+ PulseTest := TRUE;
+ ELSE
+ PulseTest := FALSE;
+ END IF;
+
+ IF PulseTest AND CheckEnabled THEN
+ -- Verify Pulse Width [ignore 1st edge]
+ IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN
+ IF (XOn) THEN Violation := 'X'; END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PulseWidCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := PeriodData.Last;
+ ReportViolation (TestSignalName, "",
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ IF PeriodTest AND CheckEnabled THEN
+ -- Verify the Period [ignore 1st edge]
+ CheckInfo.ObsTime := PeriodObs;
+ CheckInfo.ExpTime := Period;
+ IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN
+ IF (XOn) THEN Violation := 'X'; END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PeriodCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := TestValue;
+ ReportViolation (TestSignalName, "",
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ PeriodData.Last := TestValue;
+
+ END VitalPeriodPulseCheck;
+
+
+
+ PROCEDURE ReportSkewViolation (
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT ExpectedTime : IN TIME;
+ CONSTANT OccuranceTime : IN TIME;
+ CONSTANT HeaderMsg : IN STRING;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT SkewPhase : IN SkewType;
+ CONSTANT ViolationFlag : IN BOOLEAN := TRUE
+ ) IS
+ VARIABLE Message : LINE;
+ BEGIN
+ Write ( Message, HeaderMsg );
+ IF (ViolationFlag /= TRUE) THEN
+ Write ( Message, STRING'(" POSSIBLE") );
+ END IF;
+ IF (SkewPhase = Inphase) THEN
+ Write ( Message, STRING'(" IN PHASE ") );
+ ELSE
+ Write ( Message, STRING'(" OUT OF PHASE ") );
+ END IF;
+ Write ( Message, STRING'("SKEW VIOLATION ON ") );
+ Write ( Message, Signal2Name );
+ IF (Signal1Name'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, Signal1Name );
+ END IF;
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" At : ") );
+ Write ( Message, OccuranceTime);
+ Write ( Message, STRING'("; Skew Limit : ") );
+ Write ( Message, ExpectedTime);
+
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+
+ DEALLOCATE (Message);
+ END ReportSkewViolation;
+
+
+ PROCEDURE VitalInPhaseSkewCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE SkewData : INOUT VitalSkewDataType;
+ SIGNAL Signal1 : IN std_ulogic;
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal1Delay : IN TIME := 0 ns;
+ SIGNAL Signal2 : IN std_ulogic;
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT Signal2Delay : IN TIME := 0 ns;
+ CONSTANT SkewS1S2RiseRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1RiseRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS1S2FallFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1FallFall : IN TIME := TIME'HIGH;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT HeaderMsg : IN STRING := "";
+ SIGNAL Trigger : INOUT std_ulogic
+ ) IS
+ VARIABLE ReportType : VitalSkewExpectedType := none;
+ VARIABLE ExpectedType : VitalSkewExpectedType := none;
+ VARIABLE ReportTime : TIME;
+ VARIABLE TriggerDelay : TIME;
+ VARIABLE ViolationCertain : Boolean := TRUE;
+ BEGIN
+ Violation := '0';
+ ReportType := none;
+ TriggerDelay := noTrigger;
+
+ IF (CheckEnabled) THEN
+ IF (SkewData.ExpectedType /= none) THEN
+ IF (trigger'Event) THEN
+ CASE SkewData.ExpectedType IS
+ WHEN s1r => ReportType := s1r;
+ ReportTime := NOW - Signal1Delay;
+ WHEN s1f => ReportType := s1f;
+ ReportTime := NOW - Signal1Delay;
+ WHEN s2r => ReportType := s2r;
+ ReportTime := NOW - Signal2Delay;
+ WHEN s2f => ReportType := s2f;
+ ReportTime := NOW - Signal2Delay;
+ WHEN OTHERS =>
+ END CASE;
+ SkewData.ExpectedType := none;
+ ELSIF ( Signal1'Event OR Signal2'Event ) THEN
+ IF ( Signal1 /= 'X' AND Signal2 /= 'X' ) THEN
+ TriggerDelay := 0 ns;
+ ExpectedType := none;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (Signal1'EVENT and Signal2'EVENT) THEN
+ IF (Signal1 = Signal2) THEN
+ IF (Posedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - Signal2Delay) >=
+ SkewS1S2RiseRise) THEN
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseRise;
+ ELSIF ((Signal2Delay -Signal1Delay) >=
+ SkewS2S1RiseRise) THEN
+ ReportType := s1r;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1RiseRise;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - Signal2Delay) >=
+ SkewS1S2FallFall) THEN
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallFall;
+ ELSIF ((Signal2Delay - Signal1Delay) >=
+ SkewS2S1FallFall) THEN
+ ReportType := s1f;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1FallFall;
+ END IF;
+ END IF;
+ ELSIF (Posedge(Signal1'LAST_VALUE , Signal1)) THEN
+ IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay >
+ SkewS2S1FallFall)) THEN
+ ReportType := s1f;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1FallFall;
+ ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay >
+ SkewS1S2RiseRise)) THEN
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseRise;
+ ELSIF (Signal2Delay > Signal1Delay) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2RiseRise +
+ Signal2Delay - Signal1Delay;
+ ELSIF (Signal1Delay > Signal2Delay) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1RiseRise +
+ Signal1Delay - Signal2Delay;
+ ELSIF (SkewS1S2RiseRise < SkewS2S1RiseRise) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2RiseRise;
+ ELSE
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1RiseRise;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE , Signal1)) THEN
+ IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay >
+ SkewS2S1RiseRise)) THEN
+ ReportType := s1r;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1RiseRise;
+ ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay >
+ SkewS1S2FallFall)) THEN
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallFall;
+ ELSIF (Signal2Delay > Signal1Delay) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2FallFall +
+ Signal2Delay - Signal1Delay;
+ ELSIF (Signal1Delay > Signal2Delay) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1FallFall +
+ Signal1Delay - Signal2Delay;
+ ELSIF (SkewS1S2FallFall < SkewS2S1FallFall) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2FallFall;
+ ELSE
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1FallFall;
+ END IF;
+ END IF;
+ ELSIF (Signal1'EVENT) THEN
+ IF ( Signal1 /= Signal2) THEN
+ IF ( Posedge( Signal1'LAST_VALUE, Signal1)) THEN
+ IF (SkewS1S2RiseRise > (Signal1Delay -
+ Signal2Delay)) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2RiseRise +
+ Signal2Delay -
+ Signal1Delay;
+ ELSE
+ ReportType := s2r;
+ ReportTime := NOW + SkewS1S2RiseRise -
+ Signal1Delay;
+ END IF;
+ ELSIF ( Negedge( Signal1'LAST_VALUE, Signal1)) THEN
+ IF (SkewS1S2FallFall > (Signal1Delay -
+ Signal2Delay)) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2FallFall +
+ Signal2Delay -
+ Signal1Delay;
+ ELSE
+ ReportType := s2f;
+ ReportTime := NOW + SkewS1S2FallFall -
+ Signal1Delay;
+ END IF;
+ END IF;
+ ELSE
+ IF ( Posedge( Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - SkewS1S2RiseRise) >
+ (Signal2'LAST_EVENT + Signal2Delay)) THEN
+ IF ((SkewData.Signal2Old2 - Signal2Delay) >
+ (NOW - Signal1Delay +
+ SkewS1S2RiseRise)) THEN
+ ViolationCertain := FALSE;
+ ReportType := s2r;
+ ReportTime := NOW + SkewS1S2RiseRise -
+ Signal1Delay;
+ END IF;
+ END IF;
+ ELSIF ( Negedge( Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - SkewS1S2FallFall) >
+ (Signal2'LAST_EVENT + Signal2Delay)) THEN
+ IF (( SkewData.Signal2Old2 - Signal2Delay) >
+ (NOW - Signal1Delay +
+ SkewS1S2FallFall )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s2f;
+ ReportTime := NOW + SkewS1S2FallFall -
+ Signal1Delay;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ ELSIF (Signal2'EVENT) THEN
+ IF (Signal1 /= Signal2) THEN
+ IF (Posedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF ( SkewS2S1RiseRise > (Signal2Delay -
+ Signal1Delay)) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1RiseRise +
+ Signal1Delay -
+ Signal2Delay;
+ ELSE
+ ReportType := s2r;
+ ReportTime := NOW + SkewS2S1RiseRise -
+ Signal2Delay;
+ END IF;
+ ELSIF (Negedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF ( SkewS2S1FallFall > (Signal2Delay -
+ Signal1Delay)) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1FallFall +
+ Signal1Delay -
+ Signal2Delay;
+ ELSE
+ ReportType := s1f;
+ ReportTime := NOW + SkewS2S1FallFall -
+ Signal2Delay;
+ END IF;
+ END IF;
+ ELSE
+ IF (Posedge(Signal2'LAST_VALUE, Signal2)) THEN
+ IF ((Signal2Delay - SkewS2S1RiseRise) >
+ (Signal1'LAST_EVENT + Signal1Delay)) THEN
+ IF (( SkewData.Signal1Old2 - Signal1Delay) >
+ (NOW - Signal2Delay +
+ SkewS2S1RiseRise )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s1r;
+ ReportTime := NOW + SkewS2S1RiseRise -
+ Signal2Delay;
+ END IF;
+ END IF;
+ ELSIF (Negedge(Signal2'LAST_VALUE, Signal2)) THEN
+ IF ((Signal2Delay - SkewS2S1FallFall) >
+ (Signal1'LAST_EVENT + Signal1Delay)) THEN
+ IF (( SkewData.Signal1Old2 - Signal1Delay) >
+ (NOW - Signal2Delay +
+ SkewS2S1FallFall )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s1f;
+ ReportTime := NOW + SkewS2S1FallFall -
+ Signal2Delay;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (ReportType /= none) THEN
+ IF (MsgOn) THEN
+ CASE ReportType IS
+ WHEN s1r =>
+ ReportSkewViolation(
+ Signal2Name,
+ Signal1Name,
+ SkewS2S1RiseRise,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Inphase,
+ ViolationCertain);
+ WHEN s1f =>
+ ReportSkewViolation(
+ Signal2Name,
+ Signal1Name,
+ SkewS2S1FallFall,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Inphase,
+ ViolationCertain);
+ WHEN s2r =>
+ ReportSkewViolation(
+ Signal1Name,
+ Signal2Name,
+ SkewS1S2RiseRise,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Inphase,
+ ViolationCertain);
+ WHEN s2f =>
+ ReportSkewViolation(
+ Signal1Name,
+ Signal2Name,
+ SkewS1S2FallFall,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Inphase,
+ ViolationCertain);
+ WHEN OTHERS =>
+ END CASE;
+ END IF;
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ SkewData.ExpectedType := none;
+ END IF;
+ IF (TriggerDelay /= noTrigger) THEN
+ IF (TriggerDelay = 0 ns) THEN
+ trigger <= TRANSPORT trigger AFTER 0 ns;
+ ELSE
+ trigger <= TRANSPORT not (trigger) AFTER
+ TriggerDelay;
+ END IF;
+ END IF;
+ END IF;
+ IF (Signal1'EVENT and SkewData.Signal1Old1 /= NOW) THEN
+ SkewData.Signal1Old2 := SkewData.Signal1Old1;
+ SkewData.Signal1Old1 := NOW;
+ END IF;
+ IF (Signal2'EVENT and SkewData.Signal2Old1 /= NOW) THEN
+ SkewData.Signal2Old2 := SkewData.Signal2Old1;
+ SkewData.Signal2Old1 := NOW;
+ END IF;
+ END VitalInPhaseSkewCheck;
+
+ PROCEDURE VitalOutPhaseSkewCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE SkewData : INOUT VitalSkewDataType;
+ SIGNAL Signal1 : IN std_ulogic;
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal1Delay : IN TIME := 0 ns;
+ SIGNAL Signal2 : IN std_ulogic;
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT Signal2Delay : IN TIME := 0 ns;
+ CONSTANT SkewS1S2RiseFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1RiseFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS1S2FallRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1FallRise : IN TIME := TIME'HIGH;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT HeaderMsg : IN STRING := "";
+ SIGNAL Trigger : INOUT std_ulogic
+ ) IS
+ VARIABLE ReportType : VitalSkewExpectedType := none;
+ VARIABLE ExpectedType : VitalSkewExpectedType := none;
+ VARIABLE ReportTime : TIME;
+ VARIABLE TriggerDelay : TIME;
+ VARIABLE ViolationCertain : Boolean := TRUE;
+ BEGIN
+ Violation := '0';
+ TriggerDelay := noTrigger;
+ IF (CheckEnabled) THEN
+ IF (SkewData.ExpectedType /= none) THEN
+ IF (trigger'Event) THEN
+ CASE SkewData.ExpectedType IS
+ WHEN s1r => ReportType := s1r;
+ ReportTime := NOW - Signal1Delay;
+ WHEN s1f => ReportType := s1f;
+ ReportTime := NOW - Signal1Delay;
+ WHEN s2r => ReportType := s2r;
+ ReportTime := NOW - Signal2Delay;
+ WHEN s2f => ReportType := s2f;
+ ReportTime := NOW - Signal2Delay;
+ WHEN OTHERS =>
+ END CASE;
+ SkewData.ExpectedType := none;
+ ELSIF (Signal1'Event OR Signal2'Event ) THEN
+ IF (Signal1 /= 'X' AND Signal2 /= 'X' ) THEN
+ TriggerDelay := 0 ns;
+ SkewData.ExpectedType := none;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (Signal1'EVENT and Signal2'EVENT) THEN
+ IF (Signal1 /= Signal2) THEN
+ IF (Posedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - Signal2Delay) >=
+ SkewS1S2RiseFall) THEN
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseFall;
+ ELSIF ((Signal2Delay - Signal1Delay) >=
+ SkewS2S1FallRise) THEN
+ ReportType := s1r;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1FallRise;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - Signal2Delay) >=
+ SkewS1S2FallRise) THEN
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallRise;
+ ELSIF ((Signal2Delay - Signal1Delay) >=
+ SkewS2S1RiseFall) THEN
+ ReportType := s1f;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1RiseFall;
+ END IF;
+ END IF;
+ ELSIF (Posedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay >
+ SkewS2S1RiseFall)) THEN
+ ReportType := s1f;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1RiseFall;
+ ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay >
+ SkewS1S2RiseFall)) THEN
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseFall;
+ ELSIF (Signal1Delay > Signal2Delay) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1RiseFall +
+ Signal1Delay - Signal2Delay;
+ ELSIF (Signal2Delay > Signal1Delay) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2RiseFall +
+ Signal2Delay - Signal1Delay;
+ ELSIF (SkewS2S1RiseFall < SkewS1S2RiseFall) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1RiseFall;
+ ELSE
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2RiseFall;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay >
+ SkewS2S1FallRise)) THEN
+ ReportType := s1r;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1FallRise;
+ ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay >
+ SkewS1S2FallRise)) THEN
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallRise;
+ ELSIF (Signal1Delay > Signal2Delay) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1FallRise +
+ Signal1Delay - Signal2Delay;
+ ELSIF (Signal2Delay > Signal1Delay) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2FallRise +
+ Signal2Delay - Signal1Delay;
+ ELSIF (SkewS2S1FallRise < SkewS1S2FallRise) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1FallRise;
+ ELSE
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2FallRise;
+ END IF;
+ END IF;
+ ELSIF (Signal1'EVENT) THEN
+ IF (Signal1 = Signal2) THEN
+ IF (Posedge(Signal1'LAST_VALUE,Signal1)) THEN
+ IF (SkewS1S2RiseFall > (Signal1Delay -
+ Signal2Delay)) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2RiseFall +
+ Signal2Delay - Signal1Delay;
+ ELSE
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseFall;
+ END IF;
+ ELSIF ( Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ( SkewS1S2FallRise > (Signal1Delay -
+ Signal2Delay)) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2FallRise +
+ Signal2Delay - Signal1Delay;
+ ELSE
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallRise;
+ END IF;
+ END IF;
+ ELSE
+ IF (Posedge( Signal1'LAST_VALUE, Signal1 )) THEN
+ IF ((Signal1Delay - SkewS1S2RiseFall) >
+ (Signal2'LAST_EVENT + Signal2Delay)) THEN
+ IF (( SkewData.Signal2Old2 - Signal2Delay) >
+ (NOW - Signal1Delay +
+ SkewS1S2RiseFall )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s2f;
+ ReportTime := NOW + SkewS1S2RiseFall -
+ Signal1Delay;
+ END IF;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - SkewS1S2FallRise) >
+ (Signal2'LAST_EVENT + Signal2Delay)) THEN
+ IF (( SkewData.Signal2Old2 - Signal2Delay) >
+ (NOW - Signal1Delay +
+ SkewS1S2FallRise )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s2r;
+ ReportTime := NOW + SkewS1S2FallRise -
+ Signal1Delay;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ ELSIF (Signal2'EVENT) THEN
+ IF (Signal1 = Signal2) THEN
+ IF (Posedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF (SkewS2S1RiseFall > (Signal2Delay -
+ Signal1Delay)) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1RiseFall + Signal1Delay -
+ Signal2Delay ;
+ ELSE
+ ReportType := s1f;
+ ReportTime := NOW + SkewS2S1RiseFall -
+ Signal2Delay;
+ END IF;
+ ELSIF (Negedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF (SkewS2S1FallRise > (Signal2Delay -
+ Signal1Delay)) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1FallRise + Signal1Delay -
+ Signal2Delay;
+ ELSE
+ ReportType := s1r;
+ ReportTime := NOW + SkewS2S1FallRise -
+ Signal2Delay;
+ END IF;
+ END IF;
+ ELSE
+ IF (Posedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF ((Signal2Delay - SkewS2S1RiseFall) >
+ (Signal1'LAST_EVENT + Signal1Delay)) THEN
+ IF (( SkewData.Signal1Old2 - Signal1Delay) >
+ (NOW - Signal2Delay +
+ SkewS2S1RiseFall )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s1f;
+ ReportTime := NOW + SkewS2S1RiseFall -
+ Signal2Delay;
+ END IF;
+ END IF;
+ ELSIF (Negedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF ((Signal2Delay - SkewS2S1FallRise) >
+ (Signal1'LAST_EVENT + Signal1Delay)) THEN
+ IF (( SkewData.Signal1Old2 - Signal1Delay) >
+ (NOW - Signal2Delay +
+ SkewS2S1FallRise )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s1r;
+ ReportTime := NOW + SkewS2S1FallRise -
+ Signal2Delay;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (ReportType /= none) THEN
+ IF (MsgOn) THEN
+ CASE ReportType IS
+ WHEN s1r =>
+ ReportSkewViolation(
+ Signal2Name,
+ Signal1Name,
+ SkewS2S1FallRise,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Outphase,
+ ViolationCertain);
+ WHEN s1f =>
+ ReportSkewViolation(
+ Signal2Name,
+ Signal1Name,
+ SkewS2S1RiseFall,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Outphase,
+ ViolationCertain);
+ WHEN s2r =>
+ ReportSkewViolation(
+ Signal1Name,
+ Signal2Name,
+ SkewS1S2FallRise,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Outphase,
+ ViolationCertain);
+ WHEN s2f =>
+ ReportSkewViolation(
+ Signal1Name,
+ Signal2Name,
+ SkewS1S2RiseFall,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Outphase,
+ ViolationCertain);
+ WHEN OTHERS =>
+ END CASE;
+ END IF;
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ ReportType := none;
+ END IF;
+ IF (TriggerDelay /= noTrigger) THEN
+ IF (TriggerDelay = 0 ns) THEN
+ trigger <= TRANSPORT trigger AFTER 0 ns;
+ ELSE
+ trigger <= TRANSPORT not (trigger) AFTER
+ TriggerDelay;
+ END IF;
+ END IF;
+ END IF;
+ IF (Signal1'EVENT and SkewData.Signal1Old1 /= NOW) THEN
+ SkewData.Signal1Old2 := SkewData.Signal1Old1;
+ SkewData.Signal1Old1 := NOW;
+ END IF;
+ IF (Signal2'EVENT and SkewData.Signal2Old1 /= NOW) THEN
+ SkewData.Signal2Old2 := SkewData.Signal2Old1;
+ SkewData.Signal2Old1 := NOW;
+ END IF;
+ END VitalOutPhaseSkewCheck;
+
+END VITAL_Timing;