------------------------------------------------------------------------------- -- Title : Standard VITAL_Primitives Package -- : $Revision: 597 $ -- : -- Library : VITAL -- : -- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4 -- : -- Purpose : This packages defines standard types, constants, functions -- : and procedures for use in developing ASIC models. -- : Specifically a set of logic primitives are defined. -- : -- ---------------------------------------------------------------------------- -- -- ---------------------------------------------------------------------------- -- Modification History : -- ---------------------------------------------------------------------------- -- Version No:|Auth:| Mod.Date:| Changes Made: -- v95.0 A | | 06/02/95 | Initial ballot draft 1995 -- v95.1 | | 08/31/95 | #204 - glitch detection prior to OutputMap -- ---------------------------------------------------------------------------- LIBRARY STD; USE STD.TEXTIO.ALL; PACKAGE BODY VITAL_Primitives IS -- ------------------------------------------------------------------------ -- Default values for Primitives -- ------------------------------------------------------------------------ -- default values for delay parameters CONSTANT VitalDefDelay01 : VitalDelayType01 := VitalZeroDelay01; CONSTANT VitalDefDelay01Z : VitalDelayType01Z := VitalZeroDelay01Z; TYPE VitalTimeArray IS ARRAY (NATURAL RANGE <>) OF TIME; -- default primitive model operation parameters -- Glitch detection/reporting TYPE VitalGlitchModeType IS ( MessagePlusX, MessageOnly, XOnly, NoGlitch); CONSTANT PrimGlitchMode : VitalGlitchModeType := XOnly; -- ------------------------------------------------------------------------ -- Local Type and Subtype Declarations -- ------------------------------------------------------------------------ --------------------------------------------------------------------------- -- enumeration value representing the transition or level of the signal. -- See function 'GetEdge' --------------------------------------------------------------------------- TYPE EdgeType IS ( 'U', -- Uninitialized level 'X', -- Unknown level '0', -- low level '1', -- high level '\', -- 1 to 0 falling edge '/', -- 0 to 1 rising edge 'F', -- * to 0 falling edge 'R', -- * to 1 rising edge 'f', -- rising to X edge 'r', -- falling to X edge 'x', -- Unknown edge (ie U->X) 'V' -- Timing violation edge ); TYPE EdgeArray IS ARRAY ( NATURAL RANGE <> ) OF EdgeType; TYPE EdgeX1Table IS ARRAY ( EdgeType ) OF EdgeType; TYPE EdgeX2Table IS ARRAY ( EdgeType, EdgeType ) OF EdgeType; TYPE EdgeX3Table IS ARRAY ( EdgeType, EdgeType, EdgeType ) OF EdgeType; TYPE EdgeX4Table IS ARRAY (EdgeType,EdgeType,EdgeType,EdgeType) OF EdgeType; TYPE LogicToEdgeT IS ARRAY(std_ulogic, std_ulogic) OF EdgeType; TYPE LogicToLevelT IS ARRAY(std_ulogic ) OF EdgeType; TYPE GlitchDataType IS RECORD SchedTime : TIME; GlitchTime : TIME; SchedValue : std_ulogic; CurrentValue : std_ulogic; END RECORD; TYPE GlitchDataArrayType IS ARRAY (NATURAL RANGE <>) OF GlitchDataType; -- Enumerated type used in selection of output path delays TYPE SchedType IS RECORD inp0 : TIME; -- time (abs) of output change due to input change to 0 inp1 : TIME; -- time (abs) of output change due to input change to 1 InpX : TIME; -- time (abs) of output change due to input change to X Glch0 : TIME; -- time (abs) of output glitch due to input change to 0 Glch1 : TIME; -- time (abs) of output glitch due to input change to 0 END RECORD; TYPE SchedArray IS ARRAY ( NATURAL RANGE <> ) OF SchedType; CONSTANT DefSchedType : SchedType := (TIME'HIGH, TIME'HIGH, 0 ns,0 ns,0 ns); CONSTANT DefSchedAnd : SchedType := (TIME'HIGH, 0 ns,0 ns, TIME'HIGH,0 ns); -- Constrained array declarations (common sizes used by primitives) SUBTYPE SchedArray2 IS SchedArray(1 DOWNTO 0); SUBTYPE SchedArray3 IS SchedArray(2 DOWNTO 0); SUBTYPE SchedArray4 IS SchedArray(3 DOWNTO 0); SUBTYPE SchedArray8 IS SchedArray(7 DOWNTO 0); SUBTYPE TimeArray2 IS VitalTimeArray(1 DOWNTO 0); SUBTYPE TimeArray3 IS VitalTimeArray(2 DOWNTO 0); SUBTYPE TimeArray4 IS VitalTimeArray(3 DOWNTO 0); SUBTYPE TimeArray8 IS VitalTimeArray(7 DOWNTO 0); SUBTYPE GlitchArray2 IS GlitchDataArrayType(1 DOWNTO 0); SUBTYPE GlitchArray3 IS GlitchDataArrayType(2 DOWNTO 0); SUBTYPE GlitchArray4 IS GlitchDataArrayType(3 DOWNTO 0); SUBTYPE GlitchArray8 IS GlitchDataArrayType(7 DOWNTO 0); SUBTYPE EdgeArray2 IS EdgeArray(1 DOWNTO 0); SUBTYPE EdgeArray3 IS EdgeArray(2 DOWNTO 0); SUBTYPE EdgeArray4 IS EdgeArray(3 DOWNTO 0); SUBTYPE EdgeArray8 IS EdgeArray(7 DOWNTO 0); CONSTANT DefSchedArray2 : SchedArray2 := (OTHERS=> (0 ns, 0 ns, 0 ns, 0 ns, 0 ns)); TYPE stdlogic_table IS ARRAY(std_ulogic, std_ulogic) OF std_ulogic; CONSTANT InitialEdge : LogicToLevelT := ( '1'|'H' => 'R', '0'|'L' => 'F', OTHERS => 'x' ); CONSTANT LogicToEdge : LogicToEdgeT := ( -- previous, current -- old \ new: U X 0 1 Z W L H - 'U' => ( 'U', 'x', 'F', 'R', 'x', 'x', 'F', 'R', 'x' ), 'X' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ), '0' => ( 'r', 'r', '0', '/', 'r', 'r', '0', '/', 'r' ), '1' => ( 'f', 'f', '\', '1', 'f', 'f', '\', '1', 'f' ), 'Z' => ( 'x', 'X', 'F', 'R', 'X', 'x', 'F', 'R', 'x' ), 'W' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ), 'L' => ( 'r', 'r', '0', '/', 'r', 'r', '0', '/', 'r' ), 'H' => ( 'f', 'f', '\', '1', 'f', 'f', '\', '1', 'f' ), '-' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ) ); CONSTANT LogicToLevel : LogicToLevelT := ( '1'|'H' => '1', '0'|'L' => '0', 'U' => 'U', OTHERS => 'X' ); -- ----------------------------------- -- 3-state logic tables -- ----------------------------------- CONSTANT BufIf0_Table : stdlogic_table := -- enable data value ( '1'|'H' => ( OTHERS => 'Z' ), '0'|'L' => ( '1'|'H' => '1', '0'|'L' => '0', 'U' => 'U', OTHERS => 'X' ), 'U' => ( OTHERS => 'U' ), OTHERS => ( OTHERS => 'X' ) ); CONSTANT BufIf1_Table : stdlogic_table := -- enable data value ( '0'|'L' => ( OTHERS => 'Z' ), '1'|'H' => ( '1'|'H' => '1', '0'|'L' => '0', 'U' => 'U', OTHERS => 'X' ), 'U' => ( OTHERS => 'U' ), OTHERS => ( OTHERS => 'X' ) ); CONSTANT InvIf0_Table : stdlogic_table := -- enable data value ( '1'|'H' => ( OTHERS => 'Z' ), '0'|'L' => ( '1'|'H' => '0', '0'|'L' => '1', 'U' => 'U', OTHERS => 'X' ), 'U' => ( OTHERS => 'U' ), OTHERS => ( OTHERS => 'X' ) ); CONSTANT InvIf1_Table : stdlogic_table := -- enable data value ( '0'|'L' => ( OTHERS => 'Z' ), '1'|'H' => ( '1'|'H' => '0', '0'|'L' => '1', 'U' => 'U', OTHERS => 'X' ), 'U' => ( OTHERS => 'U' ), OTHERS => ( OTHERS => 'X' ) ); TYPE To_StateCharType IS ARRAY (VitalStateSymbolType) OF CHARACTER; CONSTANT To_StateChar : To_StateCharType := ( '/', '\', 'P', 'N', 'r', 'f', 'p', 'n', 'R', 'F', '^', 'v', 'E', 'A', 'D', '*', 'X', '0', '1', '-', 'B', 'Z', 'S' ); TYPE To_TruthCharType IS ARRAY (VitalTruthSymbolType) OF CHARACTER; CONSTANT To_TruthChar : To_TruthCharType := ( 'X', '0', '1', '-', 'B', 'Z' ); TYPE TruthTableOutMapType IS ARRAY (VitalTruthSymbolType) OF std_ulogic; CONSTANT TruthTableOutMap : TruthTableOutMapType := -- 'X', '0', '1', '-', 'B', 'Z' ( 'X', '0', '1', 'X', '-', 'Z' ); TYPE StateTableOutMapType IS ARRAY (VitalStateSymbolType) OF std_ulogic; -- does conversion to X01Z or '-' if invalid CONSTANT StateTableOutMap : StateTableOutMapType := -- '/' '\' 'P' 'N' 'r' 'f' 'p' 'n' 'R' 'F' '^' 'v' -- 'E' 'A' 'D' '*' 'X' '0' '1' '-' 'B' 'Z' 'S' ( '-','-','-','-','-','-','-','-','-','-','-','-', '-','-','-','-','X','0','1','X','-','Z','W'); -- ------------------------------------------------------------------------ TYPE ValidTruthTableInputType IS ARRAY (VitalTruthSymbolType) OF BOOLEAN; -- checks if a symbol IS valid for the stimulus portion of a truth table CONSTANT ValidTruthTableInput : ValidTruthTableInputType := -- 'X' '0' '1' '-' 'B' 'Z' ( TRUE, TRUE, TRUE, TRUE, TRUE, FALSE ); TYPE TruthTableMatchType IS ARRAY (X01, VitalTruthSymbolType) OF BOOLEAN; -- checks if an input matches th corresponding truth table symbol -- use: TruthTableMatch(input_converted_to_X01, truth_table_stimulus_symbol) CONSTANT TruthTableMatch : TruthTableMatchType := ( -- X, 0, 1, - B Z ( TRUE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- X ( FALSE, TRUE, FALSE, TRUE, TRUE, FALSE ), -- 0 ( FALSE, FALSE, TRUE, TRUE, TRUE, FALSE ) -- 1 ); -- ------------------------------------------------------------------------ TYPE ValidStateTableInputType IS ARRAY (VitalStateSymbolType) OF BOOLEAN; CONSTANT ValidStateTableInput : ValidStateTableInputType := -- '/', '\', 'P', 'N', 'r', 'f', ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, -- 'p', 'n', 'R', 'F', '^', 'v', TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, -- 'E', 'A', 'D', '*', TRUE, TRUE, TRUE, TRUE, -- 'X', '0', '1', '-', 'B', 'Z', TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, -- 'S' TRUE ); CONSTANT ValidStateTableState : ValidStateTableInputType := -- '/', '\', 'P', 'N', 'r', 'f', ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, -- 'p', 'n', 'R', 'F', '^', 'v', FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, -- 'E', 'A', 'D', '*', FALSE, FALSE, FALSE, FALSE, -- 'X', '0', '1', '-', 'B', 'Z', TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, -- 'S' FALSE ); TYPE StateTableMatchType IS ARRAY (X01,X01,VitalStateSymbolType) OF BOOLEAN; -- last value, present value, table symbol CONSTANT StateTableMatch : StateTableMatchType := ( ( -- X (lastvalue) -- / \ P N r f -- p n R F ^ v -- E A D * -- X 0 1 - B Z S (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE, TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE), (FALSE,FALSE,FALSE,TRUE, FALSE,FALSE, FALSE,FALSE,FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,TRUE, TRUE, FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE), (FALSE,FALSE,TRUE, FALSE,FALSE,FALSE, FALSE,FALSE,TRUE, FALSE,TRUE, FALSE, TRUE, TRUE, FALSE,TRUE, FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE) ), (-- 0 (lastvalue) -- / \ P N r f -- p n R F ^ v -- E A D * -- X 0 1 - B Z S (FALSE,FALSE,FALSE,FALSE,TRUE, FALSE, TRUE, FALSE,TRUE, FALSE,FALSE,FALSE, FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE), (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE, FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,TRUE ), (TRUE, FALSE,TRUE, FALSE,FALSE,FALSE, TRUE, FALSE,TRUE, FALSE,FALSE,FALSE, FALSE,FALSE,FALSE,TRUE, FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE) ), (-- 1 (lastvalue) -- / \ P N r f -- p n R F ^ v -- E A D * -- X 0 1 - B Z S (FALSE,FALSE,FALSE,FALSE,FALSE,TRUE , FALSE,TRUE, FALSE,TRUE, FALSE,FALSE, FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE), (FALSE,TRUE, FALSE,TRUE, FALSE,FALSE, FALSE,TRUE, FALSE,TRUE, FALSE,FALSE, FALSE,FALSE,FALSE,TRUE, FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE), (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE, FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,TRUE ) ) ); TYPE Logic_UX01Z_Table IS ARRAY (std_ulogic) OF UX01Z; ---------------------------------------------------------- -- table name : cvt_to_x01z -- parameters : std_ulogic -- some logic value -- returns : UX01Z -- state value of logic value -- purpose : to convert state-strength to state only ---------------------------------------------------------- CONSTANT cvt_to_ux01z : Logic_UX01Z_Table := ('U','X','0','1','Z','X','0','1','X' ); TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER; CONSTANT LogicCvtTable : LogicCvtTableType := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'); -------------------------------------------------------------------- -- LOCAL Utilities -------------------------------------------------------------------- -- ------------------------------------------------------------------------ -- FUNCTION NAME : MINIMUM -- -- PARAMETERS : in1, in2 - integer, time -- -- DESCRIPTION : return smaller of in1 and in2 -- ------------------------------------------------------------------------ FUNCTION Minimum ( CONSTANT in1, in2 : INTEGER ) RETURN INTEGER IS BEGIN IF (in1 < in2) THEN RETURN in1; END IF; RETURN in2; END; -- ------------------------------------------------------------------------ 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 NAME : MAXIMUM -- -- PARAMETERS : in1, in2 - integer, time -- -- DESCRIPTION : return larger of in1 and in2 -- ------------------------------------------------------------------------ FUNCTION Maximum ( CONSTANT in1, in2 : INTEGER ) RETURN INTEGER IS BEGIN IF (in1 > in2) THEN RETURN in1; END IF; RETURN in2; END; ----------------------------------------------------------------------- FUNCTION Maximum ( CONSTANT t1,t2 : IN TIME ) RETURN TIME IS BEGIN IF ( t1 > t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF; END Maximum; ----------------------------------------------------------------------- FUNCTION GlitchMinTime ( CONSTANT Time1, Time2 : IN TIME ) RETURN TIME IS BEGIN IF ( Time1 >= NOW ) THEN IF ( Time2 >= NOW ) THEN RETURN Minimum ( Time1, Time2); ELSE RETURN Time1; END IF; ELSE IF ( Time2 >= NOW ) THEN RETURN Time2; ELSE RETURN 0 ns; END IF; END IF; END; -------------------------------------------------------------------- -- Error Message Types and Tables -------------------------------------------------------------------- TYPE VitalErrorType IS ( ErrNegDel, ErrInpSym, ErrOutSym, ErrStaSym, ErrVctLng, ErrTabWidSml, ErrTabWidLrg, ErrTabResSml, ErrTabResLrg ); TYPE VitalErrorSeverityType IS ARRAY (VitalErrorType) OF SEVERITY_LEVEL; CONSTANT VitalErrorSeverity : VitalErrorSeverityType := ( ErrNegDel => WARNING, ErrInpSym => ERROR, ErrOutSym => ERROR, ErrStaSym => ERROR, ErrVctLng => ERROR, ErrTabWidSml => ERROR, ErrTabWidLrg => WARNING, ErrTabResSml => WARNING, ErrTabResLrg => WARNING ); CONSTANT MsgNegDel : STRING := "Negative delay. New output value not scheduled. Output signal is: "; CONSTANT MsgInpSym : STRING := "Illegal symbol in the input portion of a Truth/State table."; CONSTANT MsgOutSym : STRING := "Illegal symbol in the output portion of a Truth/State table."; CONSTANT MsgStaSym : STRING := "Illegal symbol in the state portion of a State table."; CONSTANT MsgVctLng : STRING := "Vector (array) lengths not equal. "; CONSTANT MsgTabWidSml : STRING := "Width of the Truth/State table is too small."; CONSTANT MsgTabWidLrg : STRING := "Width of Truth/State table is too large. Extra elements are ignored."; CONSTANT MsgTabResSml : STRING := "Result of Truth/State table has too many elements."; CONSTANT MsgTabResLrg : STRING := "Result of Truth/State table has too few elements."; CONSTANT MsgUnknown : STRING := "Unknown error message."; -------------------------------------------------------------------- -- LOCAL Utilities -------------------------------------------------------------------- FUNCTION VitalMessage ( CONSTANT ErrorId : IN VitalErrorType ) RETURN STRING IS BEGIN CASE ErrorId IS WHEN ErrNegDel => RETURN MsgNegDel; WHEN ErrInpSym => RETURN MsgInpSym; WHEN ErrOutSym => RETURN MsgOutSym; WHEN ErrStaSym => RETURN MsgStaSym; WHEN ErrVctLng => RETURN MsgVctLng; WHEN ErrTabWidSml => RETURN MsgTabWidSml; WHEN ErrTabWidLrg => RETURN MsgTabWidLrg; WHEN ErrTabResSml => RETURN MsgTabResSml; WHEN ErrTabResLrg => RETURN MsgTabResLrg; 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; --------------------------------------------------------------------------- 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 Preemted 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; DEALLOCATE(StrPtr1); DEALLOCATE(StrPtr2); DEALLOCATE(StrPtr3); DEALLOCATE(StrPtr4); DEALLOCATE(StrPtr5); RETURN; END ReportGlitch; --------------------------------------------------------------------------- -- Procedure : VitalGlitchOnEvent -- : -- Parameters : OutSignal ........ signal being driven -- : OutSignalName..... name of the driven signal -- : GlitchData........ internal data required by the procedure -- : NewValue.......... new value being assigned -- : NewDelay.......... Delay accompanying the assignment -- : (Note: for vectors, this is an array) -- : GlitchMode........ Glitch generation mode -- : MessagePlusX, MessageOnly, -- : XOnly, NoGlitch ) -- : GlitchDelay....... if <= 0 ns , then there will be no Glitch -- : if > NewDelay, then there is no Glitch, -- : otherwise, this is the time when a FORCED -- : generation of a glitch will occur. ---------------------------------------------------------------------------- PROCEDURE VitalGlitchOnEvent ( SIGNAL OutSignal : OUT std_logic; CONSTANT OutSignalName : IN STRING; VARIABLE GlitchData : INOUT GlitchDataType; CONSTANT NewValue : IN std_logic; CONSTANT NewDelay : IN TIME := 0 ns; CONSTANT GlitchMode : IN VitalGlitchModeType := MessagePlusX; CONSTANT GlitchDelay : IN TIME := 0 ns; CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING ) IS -- ------------------------------------------------------------------------ VARIABLE NoGlitchDet : BOOLEAN := FALSE; VARIABLE OldGlitch : BOOLEAN := FALSE; VARIABLE Dly : TIME := NewDelay; BEGIN -- If nothing to schedule, just return IF NewDelay < 0 ns THEN IF (NewValue /= GlitchData.SchedValue) THEN VitalError ( "VitalGlitchOnEvent", ErrNegDel, OutSignalName ); END IF; ELSE -- If nothing currently scheduled IF GlitchData.SchedTime <= NOW THEN GlitchData.CurrentValue := GlitchData.SchedValue; IF (GlitchDelay <= 0 ns) THEN IF (NewValue = GlitchData.SchedValue) THEN RETURN; END IF; NoGlitchDet := TRUE; END IF; -- Transaction currently scheduled - if glitch already happened ELSIF GlitchData.GlitchTime <= NOW THEN GlitchData.CurrentValue := 'X'; OldGlitch := TRUE; IF (GlitchData.SchedValue = NewValue) THEN dly := Minimum( GlitchData.SchedTime-NOW, NewDelay ); END IF; -- Transaction currently scheduled (no glitch if same value) ELSIF (GlitchData.SchedValue = NewValue) AND (GlitchData.SchedTime = GlitchData.GlitchTime) AND (GlitchDelay <= 0 ns) THEN NoGlitchDet := TRUE; Dly := Minimum( GlitchData.SchedTime-NOW, NewDelay ); END IF; GlitchData.SchedTime := NOW+Dly; IF OldGlitch THEN OutSignal <= NewValue AFTER Dly; ELSIF NoGlitchDet THEN GlitchData.GlitchTime := NOW+Dly; OutSignal <= NewValue AFTER Dly; ELSE -- new glitch GlitchData.GlitchTime := GlitchMinTime ( GlitchData.GlitchTime, NOW+GlitchDelay ); IF (GlitchMode = MessagePlusX) OR (GlitchMode = MessageOnly) THEN ReportGlitch ( "VitalGlitchOnEvent", OutSignalName, GlitchData.GlitchTime, GlitchData.SchedValue, (Dly + NOW), NewValue, MsgSeverity=>MsgSeverity ); END IF; IF (GlitchMode = MessagePlusX) OR (GlitchMode = XOnly) THEN OutSignal <= 'X' AFTER GlitchData.GlitchTime-NOW; OutSignal <= TRANSPORT NewValue AFTER Dly; ELSE OutSignal <= NewValue AFTER Dly; END IF; END IF; GlitchData.SchedValue := NewValue; END IF; RETURN; END; ---------------------------------------------------------------------------- PROCEDURE VitalGlitchOnEvent ( SIGNAL OutSignal : OUT std_logic_vector; CONSTANT OutSignalName : IN STRING; VARIABLE GlitchData : INOUT GlitchDataArrayType; CONSTANT NewValue : IN std_logic_vector; CONSTANT NewDelay : IN VitalTimeArray; CONSTANT GlitchMode : IN VitalGlitchModeType := MessagePlusX; CONSTANT GlitchDelay : IN VitalTimeArray; CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING ) IS ALIAS GlDataAlias : GlitchDataArrayType(1 TO GlitchData'LENGTH) IS GlitchData; ALIAS NewValAlias : std_logic_vector(1 TO NewValue'LENGTH) IS NewValue; ALIAS GlDelayAlias : VitalTimeArray(1 TO GlitchDelay'LENGTH) IS GlitchDelay; ALIAS NewDelAlias : VitalTimeArray(1 TO NewDelay'LENGTH) IS NewDelay; VARIABLE Index : INTEGER := OutSignal'LEFT; VARIABLE Direction : INTEGER; VARIABLE NoGlitchDet : BOOLEAN; VARIABLE OldGlitch : BOOLEAN; VARIABLE Dly, GlDly : TIME; BEGIN IF (OutSignal'LEFT > OutSignal'RIGHT) THEN Direction := -1; ELSE Direction := 1; END IF; IF ( (OutSignal'LENGTH /= GlitchData'LENGTH) OR (OutSignal'LENGTH /= NewValue'LENGTH) OR (OutSignal'LENGTH /= NewDelay'LENGTH) OR (OutSignal'LENGTH /= GlitchDelay'LENGTH) ) THEN VitalError ( "VitalGlitchOnEvent", ErrVctLng, OutSignalName ); RETURN; END IF; -- a call to the scalar function cannot be made since the actual -- name associated with a signal parameter must be locally static FOR n IN 1 TO OutSignal'LENGTH LOOP NoGlitchDet := FALSE; OldGlitch := FALSE; Dly := NewDelAlias(n); -- If nothing to schedule, just skip to next loop iteration IF NewDelAlias(n) < 0 ns THEN IF (NewValAlias(n) /= GlDataAlias(n).SchedValue) THEN VitalError ( "VitalGlitchOnEvent", ErrNegDel, OutSignalName ); END IF; ELSE -- If nothing currently scheduled (i.e. last scheduled -- transaction already occurred) IF GlDataAlias(n).SchedTime <= NOW THEN GlDataAlias(n).CurrentValue := GlDataAlias(n).SchedValue; IF (GlDelayAlias(n) <= 0 ns) THEN -- Next iteration if no change in value IF (NewValAlias(n) = GlDataAlias(n).SchedValue) THEN Index := Index + Direction; NEXT; END IF; -- since last transaction already occurred there is no glitch NoGlitchDet := TRUE; END IF; -- Transaction currently scheduled - if glitch already happened ELSIF GlDataAlias(n).GlitchTime <= NOW THEN GlDataAlias(n).CurrentValue := 'X'; OldGlitch := TRUE; IF (GlDataAlias(n).SchedValue = NewValAlias(n)) THEN dly := Minimum( GlDataAlias(n).SchedTime-NOW, NewDelAlias(n) ); END IF; -- Transaction currently scheduled ELSIF (GlDataAlias(n).SchedValue = NewValAlias(n)) AND (GlDataAlias(n).SchedTime = GlDataAlias(n).GlitchTime) AND (GlDelayAlias(n) <= 0 ns) THEN NoGlitchDet := TRUE; Dly := Minimum( GlDataAlias(n).SchedTime-NOW, NewDelAlias(n) ); END IF; -- update last scheduled transaction GlDataAlias(n).SchedTime := NOW+Dly; IF OldGlitch THEN OutSignal(Index) <= NewValAlias(n) AFTER Dly; ELSIF NoGlitchDet THEN -- if no glitch then update last glitch time -- and OutSignal(actual_index) GlDataAlias(n).GlitchTime := NOW+Dly; OutSignal(Index) <= NewValAlias(n) AFTER Dly; ELSE -- new glitch GlDataAlias(n).GlitchTime := GlitchMinTime ( GlDataAlias(n).GlitchTime, NOW+GlDelayAlias(n) ); IF (GlitchMode = MessagePlusX) OR (GlitchMode = MessageOnly) THEN ReportGlitch ( "VitalGlitchOnEvent", OutSignalName, GlDataAlias(n).GlitchTime, GlDataAlias(n).SchedValue, (Dly + NOW), NewValAlias(n), Index, TRUE, MsgSeverity ); END IF; IF (GlitchMode = MessagePlusX) OR (GlitchMode = XOnly) THEN GlDly := GlDataAlias(n).GlitchTime - NOW; OutSignal(Index) <= 'X' AFTER GlDly; OutSignal(Index) <= TRANSPORT NewValAlias(n) AFTER Dly; ELSE OutSignal(Index) <= NewValAlias(n) AFTER Dly; END IF; END IF; -- glitch / no-glitch GlDataAlias(n).SchedValue := NewValAlias(n); END IF; -- NewDelAlias(n) < 0 ns Index := Index + Direction; END LOOP; RETURN; END; --------------------------------------------------------------------------- -- ------------------------------------------------------------------------ -- PROCEDURE NAME : TruthOutputX01Z -- -- PARAMETERS : table_out - output of table -- X01Zout - output converted to X01Z -- err - true if illegal character is encountered -- -- -- DESCRIPTION : converts the output of a truth table to a valid -- std_ulogic -- ------------------------------------------------------------------------ PROCEDURE TruthOutputX01Z ( CONSTANT TableOut : IN VitalTruthSymbolType; VARIABLE X01Zout : OUT std_ulogic; VARIABLE Err : OUT BOOLEAN ) IS VARIABLE TempOut : std_ulogic; BEGIN Err := FALSE; TempOut := TruthTableOutMap(TableOut); IF (TempOut = '-') THEN Err := TRUE; TempOut := 'X'; VitalError ( "VitalTruthTable", ErrOutSym, To_TruthChar(TableOut)); END IF; X01Zout := TempOut; END; -- ------------------------------------------------------------------------ -- PROCEDURE NAME : StateOutputX01Z -- -- PARAMETERS : table_out - output of table -- prev_out - previous output value -- X01Zout - output cojnverted to X01Z -- err - true if illegal character is encountered -- -- DESCRIPTION : converts the output of a state table to a -- valid std_ulogic -- ------------------------------------------------------------------------ PROCEDURE StateOutputX01Z ( CONSTANT TableOut : IN VitalStateSymbolType; CONSTANT PrevOut : IN std_ulogic; VARIABLE X01Zout : OUT std_ulogic; VARIABLE Err : OUT BOOLEAN ) IS VARIABLE TempOut : std_ulogic; BEGIN Err := FALSE; TempOut := StateTableOutMap(TableOut); IF (TempOut = '-') THEN Err := TRUE; TempOut := 'X'; VitalError ( "VitalStateTable", ErrOutSym, To_StateChar(TableOut)); ELSIF (TempOut = 'W') THEN TempOut := To_X01Z(PrevOut); END IF; X01Zout := TempOut; END; -- ------------------------------------------------------------------------ -- PROCEDURE NAME: StateMatch -- -- PARAMETERS : symbol - symbol from state table -- in2 - input from VitalStateTble procedure -- to state table -- in2LastValue - previous value of input -- state - false if the symbol is from the input -- portion of the table, -- true if the symbol is from the state -- portion of the table -- Err - true if symbol is not a valid input symbol -- ReturnValue - true if match occurred -- -- DESCRIPTION : This procedure sets ReturnValue to true if in2 matches -- symbol (from the state table). If symbol is an edge -- value edge is set to true and in2 and in2LastValue are -- checked against symbol. Err is set to true if symbol -- is an invalid value for the input portion of the state -- table. -- -- ------------------------------------------------------------------------ PROCEDURE StateMatch ( CONSTANT Symbol : IN VitalStateSymbolType; CONSTANT in2 : IN std_ulogic; CONSTANT in2LastValue : IN std_ulogic; CONSTANT State : IN BOOLEAN; VARIABLE Err : OUT BOOLEAN; VARIABLE ReturnValue : OUT BOOLEAN ) IS BEGIN IF (State) THEN IF (NOT ValidStateTableState(Symbol)) THEN VitalError ( "VitalStateTable", ErrStaSym, To_StateChar(Symbol)); Err := TRUE; ReturnValue := FALSE; ELSE Err := FALSE; ReturnValue := StateTableMatch(in2LastValue, in2, Symbol); END IF; ELSE IF (NOT ValidStateTableInput(Symbol) ) THEN VitalError ( "VitalStateTable", ErrInpSym, To_StateChar(Symbol)); Err := TRUE; ReturnValue := FALSE; ELSE ReturnValue := StateTableMatch(in2LastValue, in2, Symbol); Err := FALSE; END IF; END IF; END; -- ----------------------------------------------------------------------- -- FUNCTION NAME: StateTableLookUp -- -- PARAMETERS : StateTable - state table -- PresentDataIn - current inputs -- PreviousDataIn - previous inputs and states -- NumStates - number of state variables -- PresentOutputs - current state and current outputs -- -- DESCRIPTION : This function is used to find the output of the -- StateTable corresponding to a given set of inputs. -- -- ------------------------------------------------------------------------ FUNCTION StateTableLookUp ( CONSTANT StateTable : VitalStateTableType; CONSTANT PresentDataIn : std_logic_vector; CONSTANT PreviousDataIn : std_logic_vector; CONSTANT NumStates : NATURAL; CONSTANT PresentOutputs : std_logic_vector ) RETURN std_logic_vector IS CONSTANT InputSize : INTEGER := PresentDataIn'LENGTH; CONSTANT NumInputs : INTEGER := InputSize + NumStates - 1; CONSTANT TableEntries : INTEGER := StateTable'LENGTH(1); CONSTANT TableWidth : INTEGER := StateTable'LENGTH(2); CONSTANT OutSize : INTEGER := TableWidth - InputSize - NumStates; VARIABLE Inputs : std_logic_vector(0 TO NumInputs); VARIABLE PrevInputs : std_logic_vector(0 TO NumInputs) := (OTHERS => 'X'); VARIABLE ReturnValue : std_logic_vector(0 TO (OutSize-1)) := (OTHERS => 'X'); VARIABLE Temp : std_ulogic; VARIABLE Match : BOOLEAN; VARIABLE Err : BOOLEAN := FALSE; -- This needs to be done since the TableLookup arrays must be -- ascending starting with 0 VARIABLE TableAlias : VitalStateTableType(0 TO TableEntries - 1, 0 TO TableWidth - 1) := StateTable; BEGIN Inputs(0 TO InputSize-1) := PresentDataIn; Inputs(InputSize TO NumInputs) := PresentOutputs(0 TO NumStates - 1); PrevInputs(0 TO InputSize - 1) := PreviousDataIn(0 TO InputSize - 1); ColLoop: -- Compare each entry in the table FOR i IN TableAlias'RANGE(1) LOOP RowLoop: -- Check each element of the entry FOR j IN 0 TO InputSize + NumStates LOOP IF (j = InputSize + NumStates) THEN -- a match occurred FOR k IN 0 TO Minimum(OutSize, PresentOutputs'LENGTH)-1 LOOP StateOutputX01Z ( TableAlias(i, TableWidth - k - 1), PresentOutputs(PresentOutputs'LENGTH - k - 1), Temp, Err); ReturnValue(OutSize - k - 1) := Temp; IF (Err) THEN ReturnValue := (OTHERS => 'X'); RETURN ReturnValue; END IF; END LOOP; RETURN ReturnValue; END IF; StateMatch ( TableAlias(i,j), Inputs(j), PrevInputs(j), j >= InputSize, Err, Match); EXIT RowLoop WHEN NOT(Match); EXIT ColLoop WHEN Err; END LOOP RowLoop; END LOOP ColLoop; ReturnValue := (OTHERS => 'X'); RETURN ReturnValue; END; -------------------------------------------------------------------- -- to_ux01z ------------------------------------------------------------------- FUNCTION To_UX01Z ( s : std_ulogic ) RETURN UX01Z IS BEGIN RETURN cvt_to_ux01z (s); END; --------------------------------------------------------------------------- -- Function : GetEdge -- Purpose : Converts transitions on a given input signal into a -- enumeration value representing the transition or level -- of the signal. -- -- previous "value" current "value" := "edge" -- --------------------------------------------------------- -- '1' | 'H' '1' | 'H' '1' level, no edge -- '0' | 'L' '1' | 'H' '/' rising edge -- others '1' | 'H' 'R' rising from X -- -- '1' | 'H' '0' | 'L' '\' falling egde -- '0' | 'L' '0' | 'L' '0' level, no edge -- others '0' | 'L' 'F' falling from X -- -- 'X' | 'W' | '-' 'X' | 'W' | '-' 'X' unknown (X) level -- 'Z' 'Z' 'X' unknown (X) level -- 'U' 'U' 'U' 'U' level -- -- '1' | 'H' others 'f' falling to X -- '0' | 'L' others 'r' rising to X -- 'X' | 'W' | '-' 'U' | 'Z' 'x' unknown (X) edge -- 'Z' 'X' | 'W' | '-' | 'U' 'x' unknown (X) edge -- 'U' 'X' | 'W' | '-' | 'Z' 'x' unknown (X) edge -- --------------------------------------------------------------------------- FUNCTION GetEdge ( SIGNAL s : IN std_logic ) RETURN EdgeType IS BEGIN IF (s'EVENT) THEN RETURN LogicToEdge ( s'LAST_VALUE, s ); ELSE RETURN LogicToLevel ( s ); END IF; END; --------------------------------------------------------------------------- PROCEDURE GetEdge ( SIGNAL s : IN std_logic_vector; VARIABLE LastS : INOUT std_logic_vector; VARIABLE Edge : OUT EdgeArray ) IS ALIAS sAlias : std_logic_vector ( 1 TO s'LENGTH ) IS s; ALIAS LastSAlias : std_logic_vector ( 1 TO LastS'LENGTH ) IS LastS; ALIAS EdgeAlias : EdgeArray ( 1 TO Edge'LENGTH ) IS Edge; BEGIN IF s'LENGTH /= LastS'LENGTH OR s'LENGTH /= Edge'LENGTH THEN VitalError ( "GetEdge", ErrVctLng, "s, LastS, Edge" ); END IF; FOR n IN 1 TO s'LENGTH LOOP EdgeAlias(n) := LogicToEdge( LastSAlias(n), sAlias(n) ); LastSAlias(n) := sAlias(n); END LOOP; END; --------------------------------------------------------------------------- FUNCTION ToEdge ( Value : IN std_logic ) RETURN EdgeType IS BEGIN RETURN LogicToLevel( Value ); END; -- Note: This function will likely be replaced by S'DRIVING_VALUE in VHDL'92 ---------------------------------------------------------------------------- FUNCTION CurValue ( CONSTANT GlitchData : IN GlitchDataType ) RETURN std_logic IS BEGIN IF NOW >= GlitchData.SchedTime THEN RETURN GlitchData.SchedValue; ELSIF NOW >= GlitchData.GlitchTime THEN RETURN 'X'; ELSE RETURN GlitchData.CurrentValue; END IF; END; --------------------------------------------------------------------------- FUNCTION CurValue ( CONSTANT GlitchData : IN GlitchDataArrayType ) RETURN std_logic_vector IS VARIABLE Result : std_logic_vector(GlitchData'RANGE); BEGIN FOR n IN GlitchData'RANGE LOOP IF NOW >= GlitchData(n).SchedTime THEN Result(n) := GlitchData(n).SchedValue; ELSIF NOW >= GlitchData(n).GlitchTime THEN Result(n) := 'X'; ELSE Result(n) := GlitchData(n).CurrentValue; END IF; END LOOP; RETURN Result; END; --------------------------------------------------------------------------- -- function calculation utilities --------------------------------------------------------------------------- --------------------------------------------------------------------------- -- Function : VitalSame -- Returns : VitalSame compares the state (UX01) of two logic value. A -- value of 'X' is returned if the values are different. The -- common value is returned if the values are equal. -- Purpose : When the result of a logic model may be either of two -- separate input values (eg. when the select on a MUX is 'X'), -- VitalSame may be used to determine if the result needs to -- be 'X'. -- Arguments : See the declarations below... --------------------------------------------------------------------------- FUNCTION VitalSame ( CONSTANT a, b : IN std_ulogic ) RETURN std_ulogic IS BEGIN IF To_UX01(a) = To_UX01(b) THEN RETURN To_UX01(a); ELSE RETURN 'X'; END IF; END; --------------------------------------------------------------------------- -- delay selection utilities --------------------------------------------------------------------------- --------------------------------------------------------------------------- -- Procedure : BufPath, InvPath -- -- Purpose : BufPath and InvPath compute output change times, based on -- a change on an input port. The computed output change times -- returned in the composite parameter 'schd'. -- -- BufPath and InpPath are used together with the delay path -- selection functions (GetSchedDelay, VitalAND, VitalOR... ) -- The 'schd' value from each of the input ports of a model are -- combined by the delay selection functions (VitalAND, -- VitalOR, ...). The GetSchedDelay procedure converts the -- combined output changes times to the single delay (delta -- time) value for scheduling the output change (passed to -- VitalGlitchOnEvent). -- -- The values in 'schd' are: (absolute times) -- inp0 : time of output change due to input change to 0 -- inp1 : time of output change due to input change to 1 -- inpX : time of output change due to input change to X -- glch0 : time of output glitch due to input change to 0 -- glch1 : time of output glitch due to input change to 1 -- -- The output times are computed from the model INPUT value -- and not the final value. For this reason, 'BufPath' should -- be used to compute the output times for a non-inverting -- delay paths and 'InvPath' should be used to compute the -- ouput times for inverting delay paths. Delay paths which -- include both non-inverting and paths require usage of both -- 'BufPath' and 'InvPath'. (IE this is needed for the -- select->output path of a MUX -- See the VitalMUX model). -- -- -- Parameters : schd....... Computed output result times. (INOUT parameter -- modified only on input edges) -- Iedg....... Input port edge/level value. -- tpd....... Propagation delays from this input -- --------------------------------------------------------------------------- PROCEDURE BufPath ( VARIABLE Schd : INOUT SchedType; CONSTANT Iedg : IN EdgeType; CONSTANT tpd : IN VitalDelayType01 ) IS BEGIN CASE Iedg IS WHEN '0'|'1' => NULL; -- no edge: no timing update WHEN '/'|'R' => Schd.inp0 := TIME'HIGH; Schd.inp1 := NOW + tpd(tr01); Schd.Glch1 := Schd.inp1; Schd.InpX := Schd.inp1; WHEN '\'|'F' => Schd.inp1 := TIME'HIGH; Schd.inp0 := NOW + tpd(tr10); Schd.Glch0 := Schd.inp0; Schd.InpX := Schd.inp0; WHEN 'r' => Schd.inp1 := TIME'HIGH; Schd.inp0 := TIME'HIGH; Schd.InpX := NOW + tpd(tr01); WHEN 'f' => Schd.inp0 := TIME'HIGH; Schd.inp1 := TIME'HIGH; Schd.InpX := NOW + tpd(tr10); WHEN 'x' => Schd.inp1 := TIME'HIGH; Schd.inp0 := TIME'HIGH; -- update for X->X change Schd.InpX := NOW + Minimum(tpd(tr10),tpd(tr01)); WHEN OTHERS => NULL; -- no timing change END CASE; END; PROCEDURE BufPath ( VARIABLE Schd : INOUT SchedArray; CONSTANT Iedg : IN EdgeArray; CONSTANT tpd : IN VitalDelayArrayType01 ) IS BEGIN FOR n IN Schd'RANGE LOOP CASE Iedg(n) IS WHEN '0'|'1' => NULL; -- no edge: no timing update WHEN '/'|'R' => Schd(n).inp0 := TIME'HIGH; Schd(n).inp1 := NOW + tpd(n)(tr01); Schd(n).Glch1 := Schd(n).inp1; Schd(n).InpX := Schd(n).inp1; WHEN '\'|'F' => Schd(n).inp1 := TIME'HIGH; Schd(n).inp0 := NOW + tpd(n)(tr10); Schd(n).Glch0 := Schd(n).inp0; Schd(n).InpX := Schd(n).inp0; WHEN 'r' => Schd(n).inp1 := TIME'HIGH; Schd(n).inp0 := TIME'HIGH; Schd(n).InpX := NOW + tpd(n)(tr01); WHEN 'f' => Schd(n).inp0 := TIME'HIGH; Schd(n).inp1 := TIME'HIGH; Schd(n).InpX := NOW + tpd(n)(tr10); WHEN 'x' => Schd(n).inp1 := TIME'HIGH; Schd(n).inp0 := TIME'HIGH; -- update for X->X change Schd(n).InpX := NOW + Minimum ( tpd(n)(tr10), tpd(n)(tr01) ); WHEN OTHERS => NULL; -- no timing change END CASE; END LOOP; END; PROCEDURE InvPath ( VARIABLE Schd : INOUT SchedType; CONSTANT Iedg : IN EdgeType; CONSTANT tpd : IN VitalDelayType01 ) IS BEGIN CASE Iedg IS WHEN '0'|'1' => NULL; -- no edge: no timing update WHEN '/'|'R' => Schd.inp0 := TIME'HIGH; Schd.inp1 := NOW + tpd(tr10); Schd.Glch1 := Schd.inp1; Schd.InpX := Schd.inp1; WHEN '\'|'F' => Schd.inp1 := TIME'HIGH; Schd.inp0 := NOW + tpd(tr01); Schd.Glch0 := Schd.inp0; Schd.InpX := Schd.inp0; WHEN 'r' => Schd.inp1 := TIME'HIGH; Schd.inp0 := TIME'HIGH; Schd.InpX := NOW + tpd(tr10); WHEN 'f' => Schd.inp0 := TIME'HIGH; Schd.inp1 := TIME'HIGH; Schd.InpX := NOW + tpd(tr01); WHEN 'x' => Schd.inp1 := TIME'HIGH; Schd.inp0 := TIME'HIGH; -- update for X->X change Schd.InpX := NOW + Minimum(tpd(tr10),tpd(tr01)); WHEN OTHERS => NULL; -- no timing change END CASE; END; PROCEDURE InvPath ( VARIABLE Schd : INOUT SchedArray; CONSTANT Iedg : IN EdgeArray; CONSTANT tpd : IN VitalDelayArrayType01 ) IS BEGIN FOR n IN Schd'RANGE LOOP CASE Iedg(n) IS WHEN '0'|'1' => NULL; -- no edge: no timing update WHEN '/'|'R' => Schd(n).inp0 := TIME'HIGH; Schd(n).inp1 := NOW + tpd(n)(tr10); Schd(n).Glch1 := Schd(n).inp1; Schd(n).InpX := Schd(n).inp1; WHEN '\'|'F' => Schd(n).inp1 := TIME'HIGH; Schd(n).inp0 := NOW + tpd(n)(tr01); Schd(n).Glch0 := Schd(n).inp0; Schd(n).InpX := Schd(n).inp0; WHEN 'r' => Schd(n).inp1 := TIME'HIGH; Schd(n).inp0 := TIME'HIGH; Schd(n).InpX := NOW + tpd(n)(tr10); WHEN 'f' => Schd(n).inp0 := TIME'HIGH; Schd(n).inp1 := TIME'HIGH; Schd(n).InpX := NOW + tpd(n)(tr01); WHEN 'x' => Schd(n).inp1 := TIME'HIGH; Schd(n).inp0 := TIME'HIGH; -- update for X->X change Schd(n).InpX := NOW + Minimum ( tpd(n)(tr10), tpd(n)(tr01) ); WHEN OTHERS => NULL; -- no timing change END CASE; END LOOP; END; --------------------------------------------------------------------------- -- Procedure : BufEnab, InvEnab -- -- Purpose : BufEnab and InvEnab compute output change times, from a -- change on an input enable port for a 3-state driver. The -- computed output change times are returned in the composite -- parameters 'schd1', 'schd0'. -- -- BufEnab and InpEnab are used together with the delay path -- selection functions (GetSchedDelay, VitalAND, VitalOR... ) -- The 'schd' value from each of the non-enable input ports of -- a model (See BufPath, InvPath) are combined using the delay -- selection functions (VitalAND, VitalOR, ...). The -- GetSchedDelay procedure combines the output times on the -- enable path with the output times from the data path(s) and -- computes the single delay (delta time) value for scheduling -- the output change (passed to VitalGlitchOnEvent) -- -- The values in 'schd*' are: (absolute times) -- inp0 : time of output change due to input change to 0 -- inp1 : time of output change due to input change to 1 -- inpX : time of output change due to input change to X -- glch0 : time of output glitch due to input change to 0 -- glch1 : time of output glitch due to input change to 1 -- -- 'schd1' contains output times for 1->Z, Z->1 transitions. -- 'schd0' contains output times for 0->Z, Z->0 transitions. -- -- 'BufEnab' is used for computing the output times for an -- high asserted enable (output 'Z' for enable='0'). -- 'InvEnab' is used for computing the output times for an -- low asserted enable (output 'Z' for enable='1'). -- -- Note: separate 'schd1', 'schd0' parameters are generated -- so that the combination of the delay paths from -- multiple enable signals may be combined using the -- same functions/operators used in combining separate -- data paths. (See exampe 2 below) -- -- -- Parameters : schd1...... Computed output result times for 1->Z, Z->1 -- transitions. This parameter is modified only on -- input edge values (events). -- schd0...... Computed output result times for 0->Z, 0->1 -- transitions. This parameter is modified only on -- input edge values (events). -- Iedg....... Input port edge/level value. -- tpd....... Propagation delays for the enable -> output path. -- --------------------------------------------------------------------------- PROCEDURE BufEnab ( VARIABLE Schd1 : INOUT SchedType; VARIABLE Schd0 : INOUT SchedType; CONSTANT Iedg : IN EdgeType; CONSTANT tpd : IN VitalDelayType01Z ) IS BEGIN CASE Iedg IS WHEN '0'|'1' => NULL; -- no edge: no timing update WHEN '/'|'R' => Schd1.inp0 := TIME'HIGH; Schd1.inp1 := NOW + tpd(trz1); Schd1.Glch1 := Schd1.inp1; Schd1.InpX := Schd1.inp1; Schd0.inp0 := TIME'HIGH; Schd0.inp1 := NOW + tpd(trz0); Schd0.Glch1 := Schd0.inp1; Schd0.InpX := Schd0.inp1; WHEN '\'|'F' => Schd1.inp1 := TIME'HIGH; Schd1.inp0 := NOW + tpd(tr1z); Schd1.Glch0 := Schd1.inp0; Schd1.InpX := Schd1.inp0; Schd0.inp1 := TIME'HIGH; Schd0.inp0 := NOW + tpd(tr0z); Schd0.Glch0 := Schd0.inp0; Schd0.InpX := Schd0.inp0; WHEN 'r' => Schd1.inp1 := TIME'HIGH; Schd1.inp0 := TIME'HIGH; Schd1.InpX := NOW + tpd(trz1); Schd0.inp1 := TIME'HIGH; Schd0.inp0 := TIME'HIGH; Schd0.InpX := NOW + tpd(trz0); WHEN 'f' => Schd1.inp0 := TIME'HIGH; Schd1.inp1 := TIME'HIGH; Schd1.InpX := NOW + tpd(tr1z); Schd0.inp0 := TIME'HIGH; Schd0.inp1 := TIME'HIGH; Schd0.InpX := NOW + tpd(tr0z); WHEN 'x' => Schd1.inp0 := TIME'HIGH; Schd1.inp1 := TIME'HIGH; Schd1.InpX := NOW + Minimum(tpd(tr10),tpd(tr01)); Schd0.inp0 := TIME'HIGH; Schd0.inp1 := TIME'HIGH; Schd0.InpX := NOW + Minimum(tpd(tr10),tpd(tr01)); WHEN OTHERS => NULL; -- no timing change END CASE; END; PROCEDURE InvEnab ( VARIABLE Schd1 : INOUT SchedType; VARIABLE Schd0 : INOUT SchedType; CONSTANT Iedg : IN EdgeType; CONSTANT tpd : IN VitalDelayType01Z ) IS BEGIN CASE Iedg IS WHEN '0'|'1' => NULL; -- no edge: no timing update WHEN '/'|'R' => Schd1.inp0 := TIME'HIGH; Schd1.inp1 := NOW + tpd(tr1z); Schd1.Glch1 := Schd1.inp1; Schd1.InpX := Schd1.inp1; Schd0.inp0 := TIME'HIGH; Schd0.inp1 := NOW + tpd(tr0z); Schd0.Glch1 := Schd0.inp1; Schd0.InpX := Schd0.inp1; WHEN '\'|'F' => Schd1.inp1 := TIME'HIGH; Schd1.inp0 := NOW + tpd(trz1); Schd1.Glch0 := Schd1.inp0; Schd1.InpX := Schd1.inp0; Schd0.inp1 := TIME'HIGH; Schd0.inp0 := NOW + tpd(trz0); Schd0.Glch0 := Schd0.inp0; Schd0.InpX := Schd0.inp0; WHEN 'r' => Schd1.inp1 := TIME'HIGH; Schd1.inp0 := TIME'HIGH; Schd1.InpX := NOW + tpd(tr1z); Schd0.inp1 := TIME'HIGH; Schd0.inp0 := TIME'HIGH; Schd0.InpX := NOW + tpd(tr0z); WHEN 'f' => Schd1.inp0 := TIME'HIGH; Schd1.inp1 := TIME'HIGH; Schd1.InpX := NOW + tpd(trz1); Schd0.inp0 := TIME'HIGH; Schd0.inp1 := TIME'HIGH; Schd0.InpX := NOW + tpd(trz0); WHEN 'x' => Schd1.inp0 := TIME'HIGH; Schd1.inp1 := TIME'HIGH; Schd1.InpX := NOW + Minimum(tpd(tr10),tpd(tr01)); Schd0.inp0 := TIME'HIGH; Schd0.inp1 := TIME'HIGH; Schd0.InpX := NOW + Minimum(tpd(tr10),tpd(tr01)); WHEN OTHERS => NULL; -- no timing change END CASE; END; --------------------------------------------------------------------------- -- Procedure : GetSchedDelay -- -- Purpose : GetSchedDelay computes the final delay (incremental) for -- for scheduling an output signal. The delay is computed -- from the absolute output times in the 'NewSched' parameter. -- (See BufPath, InvPath). -- -- Computation of the output delay for non-3_state outputs -- consists of selection the appropriate output time based -- on the new output value 'NewValue' and subtracting 'NOW' -- to convert to an incremental delay value. -- -- The Computation of the output delay for 3_state output -- also includes combination of the enable path delay with -- the date path delay. -- -- Parameters : NewDelay... Returned output delay value. -- GlchDelay.. Returned output delay for the start of a glitch. -- NewValue... New output value. -- CurValue... Current value of the output. -- NewSched... Composite containing the combined absolute -- output times from the data inputs. -- EnSched1... Composite containing the combined absolute -- output times from the enable input(s). -- (for a 3_state output transitions 1->Z, Z->1) -- EnSched0... Composite containing the combined absolute -- output times from the enable input(s). -- (for a 3_state output transitions 0->Z, Z->0) -- --------------------------------------------------------------------------- PROCEDURE GetSchedDelay ( VARIABLE NewDelay : OUT TIME; VARIABLE GlchDelay : OUT TIME; CONSTANT NewValue : IN std_ulogic; CONSTANT CurValue : IN std_ulogic; CONSTANT NewSched : IN SchedType ) IS VARIABLE Tim, Glch : TIME; BEGIN CASE To_UX01(NewValue) IS WHEN '0' => Tim := NewSched.inp0; Glch := NewSched.Glch1; WHEN '1' => Tim := NewSched.inp1; Glch := NewSched.Glch0; WHEN OTHERS => Tim := NewSched.InpX; Glch := -1 ns; END CASE; IF (CurValue /= NewValue) THEN Glch := -1 ns; END IF; NewDelay := Tim - NOW; IF Glch < 0 ns THEN GlchDelay := Glch; ELSE GlchDelay := Glch - NOW; END IF; -- glch < 0 ns END; PROCEDURE GetSchedDelay ( VARIABLE NewDelay : OUT VitalTimeArray; VARIABLE GlchDelay : OUT VitalTimeArray; CONSTANT NewValue : IN std_logic_vector; CONSTANT CurValue : IN std_logic_vector; CONSTANT NewSched : IN SchedArray ) IS VARIABLE Tim, Glch : TIME; ALIAS NewDelayAlias : VitalTimeArray( NewDelay'LENGTH DOWNTO 1) IS NewDelay; ALIAS GlchDelayAlias : VitalTimeArray(GlchDelay'LENGTH DOWNTO 1) IS GlchDelay; ALIAS NewSchedAlias : SchedArray( NewSched'LENGTH DOWNTO 1) IS NewSched; ALIAS NewValueAlias : std_logic_vector ( NewValue'LENGTH DOWNTO 1 ) IS NewValue; ALIAS CurValueAlias : std_logic_vector ( CurValue'LENGTH DOWNTO 1 ) IS CurValue; BEGIN FOR n IN NewDelay'LENGTH DOWNTO 1 LOOP CASE To_UX01(NewValueAlias(n)) IS WHEN '0' => Tim := NewSchedAlias(n).inp0; Glch := NewSchedAlias(n).Glch1; WHEN '1' => Tim := NewSchedAlias(n).inp1; Glch := NewSchedAlias(n).Glch0; WHEN OTHERS => Tim := NewSchedAlias(n).InpX; Glch := -1 ns; END CASE; IF (CurValueAlias(n) /= NewValueAlias(n)) THEN Glch := -1 ns; END IF; NewDelayAlias(n) := Tim - NOW; IF Glch < 0 ns THEN GlchDelayAlias(n) := Glch; ELSE GlchDelayAlias(n) := Glch - NOW; END IF; -- glch < 0 ns END LOOP; RETURN; END; PROCEDURE GetSchedDelay ( VARIABLE NewDelay : OUT TIME; VARIABLE GlchDelay : OUT TIME; CONSTANT NewValue : IN std_ulogic; CONSTANT CurValue : IN std_ulogic; CONSTANT NewSched : IN SchedType; CONSTANT EnSched1 : IN SchedType; CONSTANT EnSched0 : IN SchedType ) IS SUBTYPE v2 IS std_logic_vector(0 TO 1); VARIABLE Tim, Glch : TIME; BEGIN CASE v2'(To_X01Z(CurValue) & To_X01Z(NewValue)) IS WHEN "00" => Tim := Maximum (NewSched.inp0, EnSched0.inp1); Glch := GlitchMinTime(NewSched.Glch1,EnSched0.Glch0); WHEN "01" => Tim := Maximum (NewSched.inp1, EnSched1.inp1); Glch := EnSched1.Glch0; WHEN "0Z" => Tim := EnSched0.inp0; Glch := NewSched.Glch1; WHEN "0X" => Tim := Maximum (NewSched.InpX, EnSched1.InpX); Glch := 0 ns; WHEN "10" => Tim := Maximum (NewSched.inp0, EnSched0.inp1); Glch := EnSched0.Glch0; WHEN "11" => Tim := Maximum (NewSched.inp1, EnSched1.inp1); Glch := GlitchMinTime(NewSched.Glch0,EnSched1.Glch0); WHEN "1Z" => Tim := EnSched1.inp0; Glch := NewSched.Glch0; WHEN "1X" => Tim := Maximum (NewSched.InpX, EnSched0.InpX); Glch := 0 ns; WHEN "Z0" => Tim := Maximum (NewSched.inp0, EnSched0.inp1); IF NewSched.Glch0 > NOW THEN Glch := Maximum(NewSched.Glch1,EnSched1.inp1); ELSE Glch := 0 ns; END IF; WHEN "Z1" => Tim := Maximum (NewSched.inp1, EnSched1.inp1); IF NewSched.Glch1 > NOW THEN Glch := Maximum(NewSched.Glch0,EnSched0.inp1); ELSE Glch := 0 ns; END IF; WHEN "ZX" => Tim := Maximum (NewSched.InpX, EnSched1.InpX); Glch := 0 ns; WHEN "ZZ" => Tim := Maximum (EnSched1.InpX, EnSched0.InpX); Glch := 0 ns; WHEN "X0" => Tim := Maximum (NewSched.inp0, EnSched0.inp1); Glch := 0 ns; WHEN "X1" => Tim := Maximum (NewSched.inp1, EnSched1.inp1); Glch := 0 ns; WHEN "XZ" => Tim := Maximum (EnSched1.InpX, EnSched0.InpX); Glch := 0 ns; WHEN OTHERS => Tim := Maximum (NewSched.InpX, EnSched1.InpX); Glch := 0 ns; END CASE; NewDelay := Tim - NOW; IF Glch < 0 ns THEN GlchDelay := Glch; ELSE GlchDelay := Glch - NOW; END IF; -- glch < 0 ns END; --------------------------------------------------------------------------- -- Operators and Functions for combination (selection) of path delays -- > These functions support selection of the "appripriate" path delay -- dependent on the logic function. -- > These functions only "select" from the possable output times. No -- calculation (addition) of delays is performed. -- > See description of 'BufPath', 'InvPath' and 'GetSchedDelay' -- > See primitive PROCEDURE models for examples. --------------------------------------------------------------------------- FUNCTION "not" ( CONSTANT a : IN SchedType ) RETURN SchedType IS VARIABLE z : SchedType; BEGIN z.inp1 := a.inp0 ; z.inp0 := a.inp1 ; z.InpX := a.InpX ; z.Glch1 := a.Glch0; z.Glch0 := a.Glch1; RETURN (z); END; FUNCTION "and" ( CONSTANT a, b : IN SchedType ) RETURN SchedType IS VARIABLE z : SchedType; BEGIN z.inp1 := Maximum ( a.inp1 , b.inp1 ); z.inp0 := Minimum ( a.inp0 , b.inp0 ); z.InpX := GlitchMinTime ( a.InpX , b.InpX ); z.Glch1 := Maximum ( a.Glch1, b.Glch1 ); z.Glch0 := GlitchMinTime ( a.Glch0, b.Glch0 ); RETURN (z); END; FUNCTION "or" ( CONSTANT a, b : IN SchedType ) RETURN SchedType IS VARIABLE z : SchedType; BEGIN z.inp0 := Maximum ( a.inp0 , b.inp0 ); z.inp1 := Minimum ( a.inp1 , b.inp1 ); z.InpX := GlitchMinTime ( a.InpX , b.InpX ); z.Glch0 := Maximum ( a.Glch0, b.Glch0 ); z.Glch1 := GlitchMinTime ( a.Glch1, b.Glch1 ); RETURN (z); END; FUNCTION "nand" ( CONSTANT a, b : IN SchedType ) RETURN SchedType IS VARIABLE z : SchedType; BEGIN z.inp0 := Maximum ( a.inp1 , b.inp1 ); z.inp1 := Minimum ( a.inp0 , b.inp0 ); z.InpX := GlitchMinTime ( a.InpX , b.InpX ); z.Glch0 := Maximum ( a.Glch1, b.Glch1 ); z.Glch1 := GlitchMinTime ( a.Glch0, b.Glch0 ); RETURN (z); END; FUNCTION "nor" ( CONSTANT a, b : IN SchedType ) RETURN SchedType IS VARIABLE z : SchedType; BEGIN z.inp1 := Maximum ( a.inp0 , b.inp0 ); z.inp0 := Minimum ( a.inp1 , b.inp1 ); z.InpX := GlitchMinTime ( a.InpX , b.InpX ); z.Glch1 := Maximum ( a.Glch0, b.Glch0 ); z.Glch0 := GlitchMinTime ( a.Glch1, b.Glch1 ); RETURN (z); END; -- ------------------------------------------------------------------------ -- Delay Calculation for 2-bit Logical gates. -- ------------------------------------------------------------------------ FUNCTION VitalXOR2 ( CONSTANT ab,ai, bb,bi : IN SchedType ) RETURN SchedType IS VARIABLE z : SchedType; BEGIN -- z = (a AND b) NOR (a NOR b) z.inp1 := Maximum ( Minimum (ai.inp0 , bi.inp0 ), Minimum (ab.inp1 , bb.inp1 ) ); z.inp0 := Minimum ( Maximum (ai.inp1 , bi.inp1 ), Maximum (ab.inp0 , bb.inp0 ) ); z.InpX := Maximum ( Maximum (ai.InpX , bi.InpX ), Maximum (ab.InpX , bb.InpX ) ); z.Glch1 := Maximum (GlitchMinTime (ai.Glch0, bi.Glch0), GlitchMinTime (ab.Glch1, bb.Glch1) ); z.Glch0 := GlitchMinTime ( Maximum (ai.Glch1, bi.Glch1), Maximum (ab.Glch0, bb.Glch0) ); RETURN (z); END; FUNCTION VitalXNOR2 ( CONSTANT ab,ai, bb,bi : IN SchedType ) RETURN SchedType IS VARIABLE z : SchedType; BEGIN -- z = (a AND b) OR (a NOR b) z.inp0 := Maximum ( Minimum (ab.inp0 , bb.inp0 ), Minimum (ai.inp1 , bi.inp1 ) ); z.inp1 := Minimum ( Maximum (ab.inp1 , bb.inp1 ), Maximum (ai.inp0 , bi.inp0 ) ); z.InpX := Maximum ( Maximum (ab.InpX , bb.InpX ), Maximum (ai.InpX , bi.InpX ) ); z.Glch0 := Maximum (GlitchMinTime (ab.Glch0, bb.Glch0), GlitchMinTime (ai.Glch1, bi.Glch1) ); z.Glch1 := GlitchMinTime ( Maximum (ab.Glch1, bb.Glch1), Maximum (ai.Glch0, bi.Glch0) ); RETURN (z); END; -- ------------------------------------------------------------------------ -- Delay Calculation for 3-bit Logical gates. -- ------------------------------------------------------------------------ FUNCTION VitalXOR3 ( CONSTANT ab,ai, bb,bi, cb,ci : IN SchedType ) RETURN SchedType IS BEGIN RETURN VitalXOR2 ( VitalXOR2 (ab,ai, bb,bi), VitalXOR2 (ai,ab, bi,bb), cb, ci ); END; FUNCTION VitalXNOR3 ( CONSTANT ab,ai, bb,bi, cb,ci : IN SchedType ) RETURN SchedType IS BEGIN RETURN VitalXNOR2 ( VitalXOR2 ( ab,ai, bb,bi ), VitalXOR2 ( ai,ab, bi,bb ), cb, ci ); END; -- ------------------------------------------------------------------------ -- Delay Calculation for 4-bit Logical gates. -- ------------------------------------------------------------------------ FUNCTION VitalXOR4 ( CONSTANT ab,ai, bb,bi, cb,ci, db,di : IN SchedType ) RETURN SchedType IS BEGIN RETURN VitalXOR2 ( VitalXOR2 ( ab,ai, bb,bi ), VitalXOR2 ( ai,ab, bi,bb ), VitalXOR2 ( cb,ci, db,di ), VitalXOR2 ( ci,cb, di,db ) ); END; FUNCTION VitalXNOR4 ( CONSTANT ab,ai, bb,bi, cb,ci, db,di : IN SchedType ) RETURN SchedType IS BEGIN RETURN VitalXNOR2 ( VitalXOR2 ( ab,ai, bb,bi ), VitalXOR2 ( ai,ab, bi,bb ), VitalXOR2 ( cb,ci, db,di ), VitalXOR2 ( ci,cb, di,db ) ); END; -- ------------------------------------------------------------------------ -- Delay Calculation for N-bit Logical gates. -- ------------------------------------------------------------------------ -- Note: index range on datab,datai assumed to be 1 TO length. -- This is enforced by internal only usage of this Function FUNCTION VitalXOR ( CONSTANT DataB, DataI : IN SchedArray ) RETURN SchedType IS CONSTANT Leng : INTEGER := DataB'LENGTH; BEGIN IF Leng = 2 THEN RETURN VitalXOR2 ( DataB(1),DataI(1), DataB(2),DataI(2) ); ELSE RETURN VitalXOR2 ( VitalXOR ( DataB(1 TO Leng-1), DataI(1 TO Leng-1) ), VitalXOR ( DataI(1 TO Leng-1), DataB(1 TO Leng-1) ), DataB(Leng),DataI(Leng) ); END IF; END; -- Note: index range on datab,datai assumed to be 1 TO length. -- This is enforced by internal only usage of this Function FUNCTION VitalXNOR ( CONSTANT DataB, DataI : IN SchedArray ) RETURN SchedType IS CONSTANT Leng : INTEGER := DataB'LENGTH; BEGIN IF Leng = 2 THEN RETURN VitalXNOR2 ( DataB(1),DataI(1), DataB(2),DataI(2) ); ELSE RETURN VitalXNOR2 ( VitalXOR ( DataB(1 TO Leng-1), DataI(1 TO Leng-1) ), VitalXOR ( DataI(1 TO Leng-1), DataB(1 TO Leng-1) ), DataB(Leng),DataI(Leng) ); END IF; END; -- ------------------------------------------------------------------------ -- Multiplexor -- MUX .......... result := data(dselect) -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'), -- data1 when (dselect = '1'), -- 'X' when (dselect = 'X') and (data0 /= data1) -- MUX4 .......... 4-input mux; result := data(dselect) -- MUX8 .......... 8-input mux; result := data(dselect) -- ------------------------------------------------------------------------ FUNCTION VitalMUX2 ( CONSTANT d1, d0 : IN SchedType; CONSTANT sb, SI : IN SchedType ) RETURN SchedType IS BEGIN RETURN (d1 AND sb) OR (d0 AND (NOT SI) ); END; -- FUNCTION VitalMUX4 ( CONSTANT Data : IN SchedArray4; CONSTANT sb : IN SchedArray2; CONSTANT SI : IN SchedArray2 ) RETURN SchedType IS BEGIN RETURN ( sb(1) AND VitalMUX2(Data(3),Data(2), sb(0), SI(0)) ) OR ( (NOT SI(1)) AND VitalMUX2(Data(1),Data(0), sb(0), SI(0)) ); END; FUNCTION VitalMUX8 ( CONSTANT Data : IN SchedArray8; CONSTANT sb : IN SchedArray3; CONSTANT SI : IN SchedArray3 ) RETURN SchedType IS BEGIN RETURN ( ( sb(2)) AND VitalMUX4 (Data(7 DOWNTO 4), sb(1 DOWNTO 0), SI(1 DOWNTO 0) ) ) OR ( (NOT SI(2)) AND VitalMUX4 (Data(3 DOWNTO 0), sb(1 DOWNTO 0), SI(1 DOWNTO 0) ) ); END; -- FUNCTION VInterMux ( CONSTANT Data : IN SchedArray; CONSTANT sb : IN SchedArray; CONSTANT SI : IN SchedArray ) RETURN SchedType IS CONSTANT sMsb : INTEGER := sb'LENGTH; CONSTANT dMsbHigh : INTEGER := Data'LENGTH; CONSTANT dMsbLow : INTEGER := Data'LENGTH/2; BEGIN IF sb'LENGTH = 1 THEN RETURN VitalMUX2( Data(2), Data(1), sb(1), SI(1) ); ELSIF sb'LENGTH = 2 THEN RETURN VitalMUX4( Data, sb, SI ); ELSIF sb'LENGTH = 3 THEN RETURN VitalMUX8( Data, sb, SI ); ELSIF sb'LENGTH > 3 THEN RETURN (( sb(sMsb)) AND VInterMux( Data(dMsbLow DOWNTO 1), sb(sMsb-1 DOWNTO 1), SI(sMsb-1 DOWNTO 1) )) OR ((NOT SI(sMsb)) AND VInterMux( Data(dMsbHigh DOWNTO dMsbLow+1), sb(sMsb-1 DOWNTO 1), SI(sMsb-1 DOWNTO 1) )); ELSE RETURN (0 ns, 0 ns, 0 ns, 0 ns, 0 ns); -- dselect'LENGTH < 1 END IF; END; -- FUNCTION VitalMUX ( CONSTANT Data : IN SchedArray; CONSTANT sb : IN SchedArray; CONSTANT SI : IN SchedArray ) RETURN SchedType IS CONSTANT msb : INTEGER := 2**sb'LENGTH; VARIABLE lDat : SchedArray(msb DOWNTO 1); ALIAS DataAlias : SchedArray ( Data'LENGTH DOWNTO 1 ) IS Data; ALIAS sbAlias : SchedArray ( sb'LENGTH DOWNTO 1 ) IS sb; ALIAS siAlias : SchedArray ( SI'LENGTH DOWNTO 1 ) IS SI; BEGIN IF Data'LENGTH <= msb THEN FOR i IN Data'LENGTH DOWNTO 1 LOOP lDat(i) := DataAlias(i); END LOOP; FOR i IN msb DOWNTO Data'LENGTH+1 LOOP lDat(i) := DefSchedAnd; END LOOP; ELSE FOR i IN msb DOWNTO 1 LOOP lDat(i) := DataAlias(i); END LOOP; END IF; RETURN VInterMux( lDat, sbAlias, siAlias ); END; -- ------------------------------------------------------------------------ -- Decoder -- General Algorithm : -- (a) Result(...) := '0' when (enable = '0') -- (b) Result(data) := '1'; all other subelements = '0' -- ... Result array is decending (n-1 downto 0) -- -- DECODERn .......... n:2**n decoder -- ------------------------------------------------------------------------ FUNCTION VitalDECODER2 ( CONSTANT DataB : IN SchedType; CONSTANT DataI : IN SchedType; CONSTANT Enable : IN SchedType ) RETURN SchedArray IS VARIABLE Result : SchedArray2; BEGIN Result(1) := Enable AND ( DataB); Result(0) := Enable AND (NOT DataI); RETURN Result; END; FUNCTION VitalDECODER4 ( CONSTANT DataB : IN SchedArray2; CONSTANT DataI : IN SchedArray2; CONSTANT Enable : IN SchedType ) RETURN SchedArray IS VARIABLE Result : SchedArray4; BEGIN Result(3) := Enable AND ( DataB(1)) AND ( DataB(0)); Result(2) := Enable AND ( DataB(1)) AND (NOT DataI(0)); Result(1) := Enable AND (NOT DataI(1)) AND ( DataB(0)); Result(0) := Enable AND (NOT DataI(1)) AND (NOT DataI(0)); RETURN Result; END; FUNCTION VitalDECODER8 ( CONSTANT DataB : IN SchedArray3; CONSTANT DataI : IN SchedArray3; CONSTANT Enable : IN SchedType ) RETURN SchedArray IS VARIABLE Result : SchedArray8; BEGIN Result(7):= Enable AND ( DataB(2))AND( DataB(1))AND( DataB(0)); Result(6):= Enable AND ( DataB(2))AND( DataB(1))AND(NOT DataI(0)); Result(5):= Enable AND ( DataB(2))AND(NOT DataI(1))AND( DataB(0)); Result(4):= Enable AND ( DataB(2))AND(NOT DataI(1))AND(NOT DataI(0)); Result(3):= Enable AND (NOT DataI(2))AND( DataB(1))AND( DataB(0)); Result(2):= Enable AND (NOT DataI(2))AND( DataB(1))AND(NOT DataI(0)); Result(1):= Enable AND (NOT DataI(2))AND(NOT DataI(1))AND( DataB(0)); Result(0):= Enable AND (NOT DataI(2))AND(NOT DataI(1))AND(NOT DataI(0)); RETURN Result; END; FUNCTION VitalDECODER ( CONSTANT DataB : IN SchedArray; CONSTANT DataI : IN SchedArray; CONSTANT Enable : IN SchedType ) RETURN SchedArray IS CONSTANT DMsb : INTEGER := DataB'LENGTH - 1; ALIAS DataBAlias : SchedArray ( DMsb DOWNTO 0 ) IS DataB; ALIAS DataIAlias : SchedArray ( DMsb DOWNTO 0 ) IS DataI; BEGIN IF DataB'LENGTH = 1 THEN RETURN VitalDECODER2 ( DataBAlias( 0 ), DataIAlias( 0 ), Enable ); ELSIF DataB'LENGTH = 2 THEN RETURN VitalDECODER4 ( DataBAlias(1 DOWNTO 0), DataIAlias(1 DOWNTO 0), Enable ); ELSIF DataB'LENGTH = 3 THEN RETURN VitalDECODER8 ( DataBAlias(2 DOWNTO 0), DataIAlias(2 DOWNTO 0), Enable ); ELSIF DataB'LENGTH > 3 THEN RETURN VitalDECODER ( DataBAlias(DMsb-1 DOWNTO 0), DataIAlias(DMsb-1 DOWNTO 0), Enable AND ( DataBAlias(DMsb)) ) & VitalDECODER ( DataBAlias(DMsb-1 DOWNTO 0), DataIAlias(DMsb-1 DOWNTO 0), Enable AND (NOT DataIAlias(DMsb)) ); ELSE RETURN DefSchedArray2; END IF; END; ------------------------------------------------------------------------------- -- PRIMITIVES ------------------------------------------------------------------------------- -- ------------------------------------------------------------------------ -- N-bit wide Logical gates. -- ------------------------------------------------------------------------ FUNCTION VitalAND ( CONSTANT Data : IN std_logic_vector; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS VARIABLE Result : UX01; BEGIN Result := '1'; FOR i IN Data'RANGE LOOP Result := Result AND Data(i); END LOOP; RETURN ResultMap(Result); END; -- FUNCTION VitalOR ( CONSTANT Data : IN std_logic_vector; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS VARIABLE Result : UX01; BEGIN Result := '0'; FOR i IN Data'RANGE LOOP Result := Result OR Data(i); END LOOP; RETURN ResultMap(Result); END; -- FUNCTION VitalXOR ( CONSTANT Data : IN std_logic_vector; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS VARIABLE Result : UX01; BEGIN Result := '0'; FOR i IN Data'RANGE LOOP Result := Result XOR Data(i); END LOOP; RETURN ResultMap(Result); END; -- FUNCTION VitalNAND ( CONSTANT Data : IN std_logic_vector; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS VARIABLE Result : UX01; BEGIN Result := '1'; FOR i IN Data'RANGE LOOP Result := Result AND Data(i); END LOOP; RETURN ResultMap(NOT Result); END; -- FUNCTION VitalNOR ( CONSTANT Data : IN std_logic_vector; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS VARIABLE Result : UX01; BEGIN Result := '0'; FOR i IN Data'RANGE LOOP Result := Result OR Data(i); END LOOP; RETURN ResultMap(NOT Result); END; -- FUNCTION VitalXNOR ( CONSTANT Data : IN std_logic_vector; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS VARIABLE Result : UX01; BEGIN Result := '0'; FOR i IN Data'RANGE LOOP Result := Result XOR Data(i); END LOOP; RETURN ResultMap(NOT Result); END; -- ------------------------------------------------------------------------ -- Commonly used 2-bit Logical gates. -- ------------------------------------------------------------------------ FUNCTION VitalAND2 ( CONSTANT a, b : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(a AND b); END; -- FUNCTION VitalOR2 ( CONSTANT a, b : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(a OR b); END; -- FUNCTION VitalXOR2 ( CONSTANT a, b : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(a XOR b); END; -- FUNCTION VitalNAND2 ( CONSTANT a, b : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(a NAND b); END; -- FUNCTION VitalNOR2 ( CONSTANT a, b : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(a NOR b); END; -- FUNCTION VitalXNOR2 ( CONSTANT a, b : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(NOT (a XOR b)); END; -- -- ------------------------------------------------------------------------ -- Commonly used 3-bit Logical gates. -- ------------------------------------------------------------------------ FUNCTION VitalAND3 ( CONSTANT a, b, c : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(a AND b AND c); END; -- FUNCTION VitalOR3 ( CONSTANT a, b, c : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(a OR b OR c); END; -- FUNCTION VitalXOR3 ( CONSTANT a, b, c : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(a XOR b XOR c); END; -- FUNCTION VitalNAND3 ( CONSTANT a, b, c : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(NOT (a AND b AND c)); END; -- FUNCTION VitalNOR3 ( CONSTANT a, b, c : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(NOT (a OR b OR c)); END; -- FUNCTION VitalXNOR3 ( CONSTANT a, b, c : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(NOT (a XOR b XOR c)); END; -- --------------------------------------------------------------------------- -- Commonly used 4-bit Logical gates. -- --------------------------------------------------------------------------- FUNCTION VitalAND4 ( CONSTANT a, b, c, d : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(a AND b AND c AND d); END; -- FUNCTION VitalOR4 ( CONSTANT a, b, c, d : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(a OR b OR c OR d); END; -- FUNCTION VitalXOR4 ( CONSTANT a, b, c, d : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(a XOR b XOR c XOR d); END; -- FUNCTION VitalNAND4 ( CONSTANT a, b, c, d : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(NOT (a AND b AND c AND d)); END; -- FUNCTION VitalNOR4 ( CONSTANT a, b, c, d : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(NOT (a OR b OR c OR d)); END; -- FUNCTION VitalXNOR4 ( CONSTANT a, b, c, d : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(NOT (a XOR b XOR c XOR d)); END; -- ------------------------------------------------------------------------ -- Buffers -- BUF ....... standard non-inverting buffer -- BUFIF0 ....... non-inverting buffer Data passes thru if (Enable = '0') -- BUFIF1 ....... non-inverting buffer Data passes thru if (Enable = '1') -- ------------------------------------------------------------------------ FUNCTION VitalBUF ( CONSTANT Data : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(To_UX01(Data)); END; -- FUNCTION VitalBUFIF0 ( CONSTANT Data, Enable : IN std_ulogic; CONSTANT ResultMap : IN VitalResultZMapType := VitalDefaultResultZMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(BufIf0_Table(Enable,Data)); END; -- FUNCTION VitalBUFIF1 ( CONSTANT Data, Enable : IN std_ulogic; CONSTANT ResultMap : IN VitalResultZMapType := VitalDefaultResultZMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(BufIf1_Table(Enable,Data)); END; FUNCTION VitalIDENT ( CONSTANT Data : IN std_ulogic; CONSTANT ResultMap : IN VitalResultZMapType := VitalDefaultResultZMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(To_UX01Z(Data)); END; -- ------------------------------------------------------------------------ -- Invertors -- INV ......... standard inverting buffer -- INVIF0 ......... inverting buffer Data passes thru if (Enable = '0') -- INVIF1 ......... inverting buffer Data passes thru if (Enable = '1') -- ------------------------------------------------------------------------ FUNCTION VitalINV ( CONSTANT Data : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(NOT Data); END; -- FUNCTION VitalINVIF0 ( CONSTANT Data, Enable : IN std_ulogic; CONSTANT ResultMap : IN VitalResultZMapType := VitalDefaultResultZMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(InvIf0_Table(Enable,Data)); END; -- FUNCTION VitalINVIF1 ( CONSTANT Data, Enable : IN std_ulogic; CONSTANT ResultMap : IN VitalResultZMapType := VitalDefaultResultZMap ) RETURN std_ulogic IS BEGIN RETURN ResultMap(InvIf1_Table(Enable,Data)); END; -- ------------------------------------------------------------------------ -- Multiplexor -- MUX .......... result := data(dselect) -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'), -- data1 when (dselect = '1'), -- 'X' when (dselect = 'X') and (data0 /= data1) -- MUX4 .......... 4-input mux; result := data(dselect) -- MUX8 .......... 8-input mux; result := data(dselect) -- ------------------------------------------------------------------------ FUNCTION VitalMUX2 ( CONSTANT Data1, Data0 : IN std_ulogic; CONSTANT dSelect : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS VARIABLE Result : UX01; BEGIN CASE To_X01(dSelect) IS WHEN '0' => Result := To_UX01(Data0); WHEN '1' => Result := To_UX01(Data1); WHEN OTHERS => Result := VitalSame( Data1, Data0 ); END CASE; RETURN ResultMap(Result); END; -- FUNCTION VitalMUX4 ( CONSTANT Data : IN std_logic_vector4; CONSTANT dSelect : IN std_logic_vector2; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS VARIABLE Slct : std_logic_vector2; VARIABLE Result : UX01; BEGIN Slct := To_X01(dSelect); CASE Slct IS WHEN "00" => Result := To_UX01(Data(0)); WHEN "01" => Result := To_UX01(Data(1)); WHEN "10" => Result := To_UX01(Data(2)); WHEN "11" => Result := To_UX01(Data(3)); WHEN "0X" => Result := VitalSame( Data(1), Data(0) ); WHEN "1X" => Result := VitalSame( Data(2), Data(3) ); WHEN "X0" => Result := VitalSame( Data(2), Data(0) ); WHEN "X1" => Result := VitalSame( Data(3), Data(1) ); WHEN OTHERS => Result := VitalSame( VitalSame(Data(3),Data(2)), VitalSame(Data(1),Data(0))); END CASE; RETURN ResultMap(Result); END; -- FUNCTION VitalMUX8 ( CONSTANT Data : IN std_logic_vector8; CONSTANT dSelect : IN std_logic_vector3; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS VARIABLE Result : UX01; BEGIN CASE To_X01(dSelect(2)) IS WHEN '0' => Result := VitalMUX4( Data(3 DOWNTO 0), dSelect(1 DOWNTO 0)); WHEN '1' => Result := VitalMUX4( Data(7 DOWNTO 4), dSelect(1 DOWNTO 0)); WHEN OTHERS => Result := VitalSame( VitalMUX4( Data(3 DOWNTO 0), dSelect(1 DOWNTO 0)), VitalMUX4( Data(7 DOWNTO 4), dSelect(1 DOWNTO 0))); END CASE; RETURN ResultMap(Result); END; -- FUNCTION VInterMux ( CONSTANT Data : IN std_logic_vector; CONSTANT dSelect : IN std_logic_vector ) RETURN std_ulogic IS CONSTANT sMsb : INTEGER := dSelect'LENGTH; CONSTANT dMsbHigh : INTEGER := Data'LENGTH; CONSTANT dMsbLow : INTEGER := Data'LENGTH/2; ALIAS DataAlias : std_logic_vector ( Data'LENGTH DOWNTO 1) IS Data; ALIAS dSelAlias : std_logic_vector (dSelect'LENGTH DOWNTO 1) IS dSelect; VARIABLE Result : UX01; BEGIN IF dSelect'LENGTH = 1 THEN Result := VitalMUX2( DataAlias(2), DataAlias(1), dSelAlias(1) ); ELSIF dSelect'LENGTH = 2 THEN Result := VitalMUX4( DataAlias, dSelAlias ); ELSIF dSelect'LENGTH > 2 THEN CASE To_X01(dSelect(sMsb)) IS WHEN '0' => Result := VInterMux( DataAlias(dMsbLow DOWNTO 1), dSelAlias(sMsb-1 DOWNTO 1) ); WHEN '1' => Result := VInterMux( DataAlias(dMsbHigh DOWNTO dMsbLow+1), dSelAlias(sMsb-1 DOWNTO 1) ); WHEN OTHERS => Result := VitalSame( VInterMux( DataAlias(dMsbLow DOWNTO 1), dSelAlias(sMsb-1 DOWNTO 1) ), VInterMux( DataAlias(dMsbHigh DOWNTO dMsbLow+1), dSelAlias(sMsb-1 DOWNTO 1) ) ); END CASE; ELSE Result := 'X'; -- dselect'LENGTH < 1 END IF; RETURN Result; END; -- FUNCTION VitalMUX ( CONSTANT Data : IN std_logic_vector; CONSTANT dSelect : IN std_logic_vector; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_ulogic IS CONSTANT msb : INTEGER := 2**dSelect'LENGTH; ALIAS DataAlias : std_logic_vector ( Data'LENGTH DOWNTO 1) IS Data; ALIAS dSelAlias : std_logic_vector (dSelect'LENGTH DOWNTO 1) IS dSelect; VARIABLE lDat : std_logic_vector(msb DOWNTO 1) := (OTHERS=>'X'); VARIABLE Result : UX01; BEGIN IF Data'LENGTH <= msb THEN FOR i IN Data'LENGTH DOWNTO 1 LOOP lDat(i) := DataAlias(i); END LOOP; ELSE FOR i IN msb DOWNTO 1 LOOP lDat(i) := DataAlias(i); END LOOP; END IF; Result := VInterMux( lDat, dSelAlias ); RETURN ResultMap(Result); END; -- ------------------------------------------------------------------------ -- Decoder -- General Algorithm : -- (a) Result(...) := '0' when (enable = '0') -- (b) Result(data) := '1'; all other subelements = '0' -- ... Result array is decending (n-1 downto 0) -- -- DECODERn .......... n:2**n decoder -- ------------------------------------------------------------------------ FUNCTION VitalDECODER2 ( CONSTANT Data : IN std_ulogic; CONSTANT Enable : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_logic_vector2 IS VARIABLE Result : std_logic_vector2; BEGIN Result(1) := ResultMap(Enable AND ( Data)); Result(0) := ResultMap(Enable AND (NOT Data)); RETURN Result; END; -- FUNCTION VitalDECODER4 ( CONSTANT Data : IN std_logic_vector2; CONSTANT Enable : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_logic_vector4 IS VARIABLE Result : std_logic_vector4; BEGIN Result(3) := ResultMap(Enable AND ( Data(1)) AND ( Data(0))); Result(2) := ResultMap(Enable AND ( Data(1)) AND (NOT Data(0))); Result(1) := ResultMap(Enable AND (NOT Data(1)) AND ( Data(0))); Result(0) := ResultMap(Enable AND (NOT Data(1)) AND (NOT Data(0))); RETURN Result; END; -- FUNCTION VitalDECODER8 ( CONSTANT Data : IN std_logic_vector3; CONSTANT Enable : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_logic_vector8 IS VARIABLE Result : std_logic_vector8; BEGIN Result(7) := ( Data(2)) AND ( Data(1)) AND ( Data(0)); Result(6) := ( Data(2)) AND ( Data(1)) AND (NOT Data(0)); Result(5) := ( Data(2)) AND (NOT Data(1)) AND ( Data(0)); Result(4) := ( Data(2)) AND (NOT Data(1)) AND (NOT Data(0)); Result(3) := (NOT Data(2)) AND ( Data(1)) AND ( Data(0)); Result(2) := (NOT Data(2)) AND ( Data(1)) AND (NOT Data(0)); Result(1) := (NOT Data(2)) AND (NOT Data(1)) AND ( Data(0)); Result(0) := (NOT Data(2)) AND (NOT Data(1)) AND (NOT Data(0)); Result(0) := ResultMap ( Enable AND Result(0) ); Result(1) := ResultMap ( Enable AND Result(1) ); Result(2) := ResultMap ( Enable AND Result(2) ); Result(3) := ResultMap ( Enable AND Result(3) ); Result(4) := ResultMap ( Enable AND Result(4) ); Result(5) := ResultMap ( Enable AND Result(5) ); Result(6) := ResultMap ( Enable AND Result(6) ); Result(7) := ResultMap ( Enable AND Result(7) ); RETURN Result; END; -- FUNCTION VitalDECODER ( CONSTANT Data : IN std_logic_vector; CONSTANT Enable : IN std_ulogic; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) RETURN std_logic_vector IS CONSTANT DMsb : INTEGER := Data'LENGTH - 1; ALIAS DataAlias : std_logic_vector ( DMsb DOWNTO 0 ) IS Data; BEGIN IF Data'LENGTH = 1 THEN RETURN VitalDECODER2 (DataAlias( 0 ), Enable, ResultMap ); ELSIF Data'LENGTH = 2 THEN RETURN VitalDECODER4 (DataAlias(1 DOWNTO 0), Enable, ResultMap ); ELSIF Data'LENGTH = 3 THEN RETURN VitalDECODER8 (DataAlias(2 DOWNTO 0), Enable, ResultMap ); ELSIF Data'LENGTH > 3 THEN RETURN VitalDECODER (DataAlias(DMsb-1 DOWNTO 0), Enable AND ( DataAlias(DMsb)), ResultMap ) & VitalDECODER (DataAlias(DMsb-1 DOWNTO 0), Enable AND (NOT DataAlias(DMsb)), ResultMap ); ELSE RETURN "X"; END IF; END; -- ------------------------------------------------------------------------ -- N-bit wide Logical gates. -- ------------------------------------------------------------------------ PROCEDURE VitalAND ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_logic_vector; CONSTANT tpd_data_q : IN VitalDelayArrayType01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); VARIABLE Data_Edge : EdgeArray(Data'RANGE); VARIABLE Data_Schd : SchedArray(Data'RANGE); VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ FOR i IN Data'RANGE LOOP IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; IF (AllZeroDelay) THEN LOOP q <= VitalAND(Data, ResultMap); WAIT ON Data; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- FOR n IN Data'RANGE LOOP BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); END LOOP; LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- GetEdge ( Data, LastData, Data_Edge ); BufPath ( Data_Schd, Data_Edge, Atpd_data_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := '1'; new_schd := Data_Schd(Data_Schd'LEFT); FOR i IN Data'RANGE LOOP NewValue := NewValue AND Data(i); new_schd := new_schd AND Data_Schd(i); END LOOP; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data; END LOOP; END IF; --SN END; -- PROCEDURE VitalOR ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_logic_vector; CONSTANT tpd_data_q : IN VitalDelayArrayType01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); VARIABLE Data_Edge : EdgeArray(Data'RANGE); VARIABLE Data_Schd : SchedArray(Data'RANGE); VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ FOR i IN Data'RANGE LOOP IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; IF (AllZeroDelay) THEN LOOP q <= VitalOR(Data, ResultMap); WAIT ON Data; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- FOR n IN Data'RANGE LOOP BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); END LOOP; LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- GetEdge ( Data, LastData, Data_Edge ); BufPath ( Data_Schd, Data_Edge, Atpd_data_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := '0'; new_schd := Data_Schd(Data_Schd'LEFT); FOR i IN Data'RANGE LOOP NewValue := NewValue OR Data(i); new_schd := new_schd OR Data_Schd(i); END LOOP; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data; END LOOP; END IF; --SN END; -- PROCEDURE VitalXOR ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_logic_vector; CONSTANT tpd_data_q : IN VitalDelayArrayType01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); VARIABLE Data_Edge : EdgeArray(Data'RANGE); VARIABLE DataB_Schd : SchedArray(1 TO Data'LENGTH); VARIABLE DataI_Schd : SchedArray(1 TO Data'LENGTH); VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; ALIAS ADataB_Schd : SchedArray(Data'RANGE) IS DataB_Schd; ALIAS ADataI_Schd : SchedArray(Data'RANGE) IS DataI_Schd; VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ FOR i IN Data'RANGE LOOP IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; IF (AllZeroDelay) THEN LOOP q <= VitalXOR(Data, ResultMap); WAIT ON Data; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- FOR n IN Data'RANGE LOOP BufPath ( ADataB_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); InvPath ( ADataI_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); END LOOP; LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- GetEdge ( Data, LastData, Data_Edge ); BufPath ( DataB_Schd, Data_Edge, Atpd_data_q ); InvPath ( DataI_Schd, Data_Edge, Atpd_data_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := VitalXOR ( Data ); new_schd := VitalXOR ( DataB_Schd, DataI_Schd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data; END LOOP; END IF; --SN END; -- PROCEDURE VitalNAND ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_logic_vector; CONSTANT tpd_data_q : IN VitalDelayArrayType01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); VARIABLE Data_Edge : EdgeArray(Data'RANGE); VARIABLE Data_Schd : SchedArray(Data'RANGE); VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ FOR i IN Data'RANGE LOOP IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; IF (AllZeroDelay) THEN LOOP q <= VitalNAND(Data, ResultMap); WAIT ON Data; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- FOR n IN Data'RANGE LOOP InvPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); END LOOP; LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- GetEdge ( Data, LastData, Data_Edge ); InvPath ( Data_Schd, Data_Edge, Atpd_data_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := '1'; new_schd := Data_Schd(Data_Schd'LEFT); FOR i IN Data'RANGE LOOP NewValue := NewValue AND Data(i); new_schd := new_schd AND Data_Schd(i); END LOOP; NewValue := NOT NewValue; new_schd := NOT new_schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data; END LOOP; END IF; END; -- PROCEDURE VitalNOR ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_logic_vector; CONSTANT tpd_data_q : IN VitalDelayArrayType01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); VARIABLE Data_Edge : EdgeArray(Data'RANGE); VARIABLE Data_Schd : SchedArray(Data'RANGE); VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ FOR i IN Data'RANGE LOOP IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; IF (AllZeroDelay) THEN LOOP q <= VitalNOR(Data, ResultMap); WAIT ON Data; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- FOR n IN Data'RANGE LOOP InvPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); END LOOP; LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- GetEdge ( Data, LastData, Data_Edge ); InvPath ( Data_Schd, Data_Edge, Atpd_data_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := '0'; new_schd := Data_Schd(Data_Schd'LEFT); FOR i IN Data'RANGE LOOP NewValue := NewValue OR Data(i); new_schd := new_schd OR Data_Schd(i); END LOOP; NewValue := NOT NewValue; new_schd := NOT new_schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data; END LOOP; END IF; --SN END; -- PROCEDURE VitalXNOR ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_logic_vector; CONSTANT tpd_data_q : IN VitalDelayArrayType01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); VARIABLE Data_Edge : EdgeArray(Data'RANGE); VARIABLE DataB_Schd : SchedArray(1 TO Data'LENGTH); VARIABLE DataI_Schd : SchedArray(1 TO Data'LENGTH); VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; ALIAS ADataB_Schd : SchedArray(Data'RANGE) IS DataB_Schd; ALIAS ADataI_Schd : SchedArray(Data'RANGE) IS DataI_Schd; VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ FOR i IN Data'RANGE LOOP IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; IF (AllZeroDelay) THEN LOOP q <= VitalXNOR(Data, ResultMap); WAIT ON Data; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- FOR n IN Data'RANGE LOOP BufPath ( ADataB_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); InvPath ( ADataI_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); END LOOP; LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- GetEdge ( Data, LastData, Data_Edge ); BufPath ( DataB_Schd, Data_Edge, Atpd_data_q ); InvPath ( DataI_Schd, Data_Edge, Atpd_data_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := VitalXNOR ( Data ); new_schd := VitalXNOR ( DataB_Schd, DataI_Schd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data; END LOOP; END IF; --SN END; -- -- ------------------------------------------------------------------------ -- Commonly used 2-bit Logical gates. -- ------------------------------------------------------------------------ PROCEDURE VitalAND2 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE a_schd, b_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN LOOP q <= VitalAND2 ( a, b, ResultMap ); WAIT ON a, b; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( a_schd, InitialEdge(a), tpd_a_q ); BufPath ( b_schd, InitialEdge(b), tpd_b_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( a_schd, GetEdge(a), tpd_a_q ); BufPath ( b_schd, GetEdge(b), tpd_b_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := a AND b; new_schd := a_schd AND b_schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b; END LOOP; END IF; END; -- PROCEDURE VitalOR2 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE a_schd, b_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN LOOP q <= VitalOR2 ( a, b, ResultMap ); WAIT ON a, b; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( a_schd, InitialEdge(a), tpd_a_q ); BufPath ( b_schd, InitialEdge(b), tpd_b_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( a_schd, GetEdge(a), tpd_a_q ); BufPath ( b_schd, GetEdge(b), tpd_b_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := a OR b; new_schd := a_schd OR b_schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b; END LOOP; END IF; END; -- PROCEDURE VitalNAND2 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE a_schd, b_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN LOOP q <= VitalNAND2 ( a, b, ResultMap ); WAIT ON a, b; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- InvPath ( a_schd, InitialEdge(a), tpd_a_q ); InvPath ( b_schd, InitialEdge(b), tpd_b_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- InvPath ( a_schd, GetEdge(a), tpd_a_q ); InvPath ( b_schd, GetEdge(b), tpd_b_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := a NAND b; new_schd := a_schd NAND b_schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b; END LOOP; END IF; END; -- PROCEDURE VitalNOR2 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE a_schd, b_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN LOOP q <= VitalNOR2 ( a, b, ResultMap ); WAIT ON a, b; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- InvPath ( a_schd, InitialEdge(a), tpd_a_q ); InvPath ( b_schd, InitialEdge(b), tpd_b_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- InvPath ( a_schd, GetEdge(a), tpd_a_q ); InvPath ( b_schd, GetEdge(b), tpd_b_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := a NOR b; new_schd := a_schd NOR b_schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b; END LOOP; END IF; END; -- PROCEDURE VitalXOR2 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE ab_schd, bb_schd : SchedType; VARIABLE ai_schd, bi_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN LOOP q <= VitalXOR2 ( a, b, ResultMap ); WAIT ON a, b; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( ab_schd, InitialEdge(a), tpd_a_q ); InvPath ( ai_schd, InitialEdge(a), tpd_a_q ); BufPath ( bb_schd, InitialEdge(b), tpd_b_q ); InvPath ( bi_schd, InitialEdge(b), tpd_b_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( ab_schd, GetEdge(a), tpd_a_q ); InvPath ( ai_schd, GetEdge(a), tpd_a_q ); BufPath ( bb_schd, GetEdge(b), tpd_b_q ); InvPath ( bi_schd, GetEdge(b), tpd_b_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := a XOR b; new_schd := VitalXOR2 ( ab_schd,ai_schd, bb_schd,bi_schd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b; END LOOP; END IF; END; -- PROCEDURE VitalXNOR2 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE ab_schd, bb_schd : SchedType; VARIABLE ai_schd, bi_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN LOOP q <= VitalXNOR2 ( a, b, ResultMap ); WAIT ON a, b; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( ab_schd, InitialEdge(a), tpd_a_q ); InvPath ( ai_schd, InitialEdge(a), tpd_a_q ); BufPath ( bb_schd, InitialEdge(b), tpd_b_q ); InvPath ( bi_schd, InitialEdge(b), tpd_b_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( ab_schd, GetEdge(a), tpd_a_q ); InvPath ( ai_schd, GetEdge(a), tpd_a_q ); BufPath ( bb_schd, GetEdge(b), tpd_b_q ); InvPath ( bi_schd, GetEdge(b), tpd_b_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := NOT (a XOR b); new_schd := VitalXNOR2 ( ab_schd,ai_schd, bb_schd,bi_schd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b; END LOOP; END IF; END; -- ------------------------------------------------------------------------ -- Commonly used 3-bit Logical gates. -- ------------------------------------------------------------------------ PROCEDURE VitalAND3 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b, c : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE a_schd, b_schd, c_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01) AND (tpd_c_q = VitalZeroDelay01)) THEN LOOP q <= VitalAND3 ( a, b, c, ResultMap ); WAIT ON a, b, c; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( a_schd, InitialEdge(a), tpd_a_q ); BufPath ( b_schd, InitialEdge(b), tpd_b_q ); BufPath ( c_schd, InitialEdge(c), tpd_c_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( a_schd, GetEdge(a), tpd_a_q ); BufPath ( b_schd, GetEdge(b), tpd_b_q ); BufPath ( c_schd, GetEdge(c), tpd_c_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := a AND b AND c; new_schd := a_schd AND b_schd AND c_schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b, c; END LOOP; END IF; END; -- PROCEDURE VitalOR3 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b, c : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE a_schd, b_schd, c_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01) AND (tpd_c_q = VitalZeroDelay01)) THEN LOOP q <= VitalOR3 ( a, b, c, ResultMap ); WAIT ON a, b, c; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( a_schd, InitialEdge(a), tpd_a_q ); BufPath ( b_schd, InitialEdge(b), tpd_b_q ); BufPath ( c_schd, InitialEdge(c), tpd_c_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( a_schd, GetEdge(a), tpd_a_q ); BufPath ( b_schd, GetEdge(b), tpd_b_q ); BufPath ( c_schd, GetEdge(c), tpd_c_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := a OR b OR c; new_schd := a_schd OR b_schd OR c_schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b, c; END LOOP; END IF; END; -- PROCEDURE VitalNAND3 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b, c : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE a_schd, b_schd, c_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01) AND (tpd_c_q = VitalZeroDelay01)) THEN LOOP q <= VitalNAND3 ( a, b, c, ResultMap ); WAIT ON a, b, c; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- InvPath ( a_schd, InitialEdge(a), tpd_a_q ); InvPath ( b_schd, InitialEdge(b), tpd_b_q ); InvPath ( c_schd, InitialEdge(c), tpd_c_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- InvPath ( a_schd, GetEdge(a), tpd_a_q ); InvPath ( b_schd, GetEdge(b), tpd_b_q ); InvPath ( c_schd, GetEdge(c), tpd_c_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := (a AND b) NAND c; new_schd := (a_schd AND b_schd) NAND c_schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b, c; END LOOP; END IF; END; -- PROCEDURE VitalNOR3 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b, c : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE a_schd, b_schd, c_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01) AND (tpd_c_q = VitalZeroDelay01)) THEN LOOP q <= VitalNOR3 ( a, b, c, ResultMap ); WAIT ON a, b, c; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- InvPath ( a_schd, InitialEdge(a), tpd_a_q ); InvPath ( b_schd, InitialEdge(b), tpd_b_q ); InvPath ( c_schd, InitialEdge(c), tpd_c_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- InvPath ( a_schd, GetEdge(a), tpd_a_q ); InvPath ( b_schd, GetEdge(b), tpd_b_q ); InvPath ( c_schd, GetEdge(c), tpd_c_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := (a OR b) NOR c; new_schd := (a_schd OR b_schd) NOR c_schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b, c; END LOOP; END IF; END; -- PROCEDURE VitalXOR3 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b, c : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE ab_schd, bb_schd, cb_schd : SchedType; VARIABLE ai_schd, bi_schd, ci_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01) AND (tpd_c_q = VitalZeroDelay01)) THEN LOOP q <= VitalXOR3 ( a, b, c, ResultMap ); WAIT ON a, b, c; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( ab_schd, InitialEdge(a), tpd_a_q ); InvPath ( ai_schd, InitialEdge(a), tpd_a_q ); BufPath ( bb_schd, InitialEdge(b), tpd_b_q ); InvPath ( bi_schd, InitialEdge(b), tpd_b_q ); BufPath ( cb_schd, InitialEdge(c), tpd_c_q ); InvPath ( ci_schd, InitialEdge(c), tpd_c_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( ab_schd, GetEdge(a), tpd_a_q ); InvPath ( ai_schd, GetEdge(a), tpd_a_q ); BufPath ( bb_schd, GetEdge(b), tpd_b_q ); InvPath ( bi_schd, GetEdge(b), tpd_b_q ); BufPath ( cb_schd, GetEdge(c), tpd_c_q ); InvPath ( ci_schd, GetEdge(c), tpd_c_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := a XOR b XOR c; new_schd := VitalXOR3 ( ab_schd,ai_schd, bb_schd,bi_schd, cb_schd,ci_schd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b, c; END LOOP; END IF; END; -- PROCEDURE VitalXNOR3 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b, c : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE ab_schd, bb_schd, cb_schd : SchedType; VARIABLE ai_schd, bi_schd, ci_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01) AND (tpd_c_q = VitalZeroDelay01)) THEN LOOP q <= VitalXNOR3 ( a, b, c, ResultMap ); WAIT ON a, b, c; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( ab_schd, InitialEdge(a), tpd_a_q ); InvPath ( ai_schd, InitialEdge(a), tpd_a_q ); BufPath ( bb_schd, InitialEdge(b), tpd_b_q ); InvPath ( bi_schd, InitialEdge(b), tpd_b_q ); BufPath ( cb_schd, InitialEdge(c), tpd_c_q ); InvPath ( ci_schd, InitialEdge(c), tpd_c_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( ab_schd, GetEdge(a), tpd_a_q ); InvPath ( ai_schd, GetEdge(a), tpd_a_q ); BufPath ( bb_schd, GetEdge(b), tpd_b_q ); InvPath ( bi_schd, GetEdge(b), tpd_b_q ); BufPath ( cb_schd, GetEdge(c), tpd_c_q ); InvPath ( ci_schd, GetEdge(c), tpd_c_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := NOT (a XOR b XOR c); new_schd := VitalXNOR3 ( ab_schd, ai_schd, bb_schd, bi_schd, cb_schd, ci_schd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b, c; END LOOP; END IF; END; -- ------------------------------------------------------------------------ -- Commonly used 4-bit Logical gates. -- ------------------------------------------------------------------------ PROCEDURE VitalAND4 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b, c, d : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01) AND (tpd_c_q = VitalZeroDelay01) AND (tpd_d_q = VitalZeroDelay01)) THEN LOOP q <= VitalAND4 ( a, b, c, d, ResultMap ); WAIT ON a, b, c, d; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( a_schd, InitialEdge(a), tpd_a_q ); BufPath ( b_schd, InitialEdge(b), tpd_b_q ); BufPath ( c_schd, InitialEdge(c), tpd_c_q ); BufPath ( d_Schd, InitialEdge(d), tpd_d_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( a_schd, GetEdge(a), tpd_a_q ); BufPath ( b_schd, GetEdge(b), tpd_b_q ); BufPath ( c_schd, GetEdge(c), tpd_c_q ); BufPath ( d_Schd, GetEdge(d), tpd_d_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := a AND b AND c AND d; new_schd := a_schd AND b_schd AND c_schd AND d_Schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b, c, d; END LOOP; END IF; END; -- PROCEDURE VitalOR4 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b, c, d : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01) AND (tpd_c_q = VitalZeroDelay01) AND (tpd_d_q = VitalZeroDelay01)) THEN LOOP q <= VitalOR4 ( a, b, c, d, ResultMap ); WAIT ON a, b, c, d; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( a_schd, InitialEdge(a), tpd_a_q ); BufPath ( b_schd, InitialEdge(b), tpd_b_q ); BufPath ( c_schd, InitialEdge(c), tpd_c_q ); BufPath ( d_Schd, InitialEdge(d), tpd_d_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( a_schd, GetEdge(a), tpd_a_q ); BufPath ( b_schd, GetEdge(b), tpd_b_q ); BufPath ( c_schd, GetEdge(c), tpd_c_q ); BufPath ( d_Schd, GetEdge(d), tpd_d_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := a OR b OR c OR d; new_schd := a_schd OR b_schd OR c_schd OR d_Schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b, c, d; END LOOP; END IF; END; -- PROCEDURE VitalNAND4 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b, c, d : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01) AND (tpd_c_q = VitalZeroDelay01) AND (tpd_d_q = VitalZeroDelay01)) THEN LOOP q <= VitalNAND4 ( a, b, c, d, ResultMap ); WAIT ON a, b, c, d; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- InvPath ( a_schd, InitialEdge(a), tpd_a_q ); InvPath ( b_schd, InitialEdge(b), tpd_b_q ); InvPath ( c_schd, InitialEdge(c), tpd_c_q ); InvPath ( d_Schd, InitialEdge(d), tpd_d_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- InvPath ( a_schd, GetEdge(a), tpd_a_q ); InvPath ( b_schd, GetEdge(b), tpd_b_q ); InvPath ( c_schd, GetEdge(c), tpd_c_q ); InvPath ( d_Schd, GetEdge(d), tpd_d_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := (a AND b) NAND (c AND d); new_schd := (a_schd AND b_schd) NAND (c_schd AND d_Schd); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b, c, d; END LOOP; END IF; END; -- PROCEDURE VitalNOR4 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b, c, d : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01) AND (tpd_c_q = VitalZeroDelay01) AND (tpd_d_q = VitalZeroDelay01)) THEN LOOP q <= VitalNOR4 ( a, b, c, d, ResultMap ); WAIT ON a, b, c, d; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- InvPath ( a_schd, InitialEdge(a), tpd_a_q ); InvPath ( b_schd, InitialEdge(b), tpd_b_q ); InvPath ( c_schd, InitialEdge(c), tpd_c_q ); InvPath ( d_Schd, InitialEdge(d), tpd_d_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- InvPath ( a_schd, GetEdge(a), tpd_a_q ); InvPath ( b_schd, GetEdge(b), tpd_b_q ); InvPath ( c_schd, GetEdge(c), tpd_c_q ); InvPath ( d_Schd, GetEdge(d), tpd_d_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := (a OR b) NOR (c OR d); new_schd := (a_schd OR b_schd) NOR (c_schd OR d_Schd); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b, c, d; END LOOP; END IF; END; -- PROCEDURE VitalXOR4 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b, c, d : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE ab_schd, bb_schd, cb_schd, DB_Schd : SchedType; VARIABLE ai_schd, bi_schd, ci_schd, di_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01) AND (tpd_c_q = VitalZeroDelay01) AND (tpd_d_q = VitalZeroDelay01)) THEN LOOP q <= VitalXOR4 ( a, b, c, d, ResultMap ); WAIT ON a, b, c, d; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( ab_schd, InitialEdge(a), tpd_a_q ); InvPath ( ai_schd, InitialEdge(a), tpd_a_q ); BufPath ( bb_schd, InitialEdge(b), tpd_b_q ); InvPath ( bi_schd, InitialEdge(b), tpd_b_q ); BufPath ( cb_schd, InitialEdge(c), tpd_c_q ); InvPath ( ci_schd, InitialEdge(c), tpd_c_q ); BufPath ( DB_Schd, InitialEdge(d), tpd_d_q ); InvPath ( di_schd, InitialEdge(d), tpd_d_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( ab_schd, GetEdge(a), tpd_a_q ); InvPath ( ai_schd, GetEdge(a), tpd_a_q ); BufPath ( bb_schd, GetEdge(b), tpd_b_q ); InvPath ( bi_schd, GetEdge(b), tpd_b_q ); BufPath ( cb_schd, GetEdge(c), tpd_c_q ); InvPath ( ci_schd, GetEdge(c), tpd_c_q ); BufPath ( DB_Schd, GetEdge(d), tpd_d_q ); InvPath ( di_schd, GetEdge(d), tpd_d_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := a XOR b XOR c XOR d; new_schd := VitalXOR4 ( ab_schd,ai_schd, bb_schd,bi_schd, cb_schd,ci_schd, DB_Schd,di_schd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b, c, d; END LOOP; END IF; END; -- PROCEDURE VitalXNOR4 ( SIGNAL q : OUT std_ulogic; SIGNAL a, b, c, d : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE ab_schd, bb_schd, cb_schd, DB_Schd : SchedType; VARIABLE ai_schd, bi_schd, ci_schd, di_schd : SchedType; VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01) AND (tpd_c_q = VitalZeroDelay01) AND (tpd_d_q = VitalZeroDelay01)) THEN LOOP q <= VitalXNOR4 ( a, b, c, d, ResultMap ); WAIT ON a, b, c, d; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( ab_schd, InitialEdge(a), tpd_a_q ); InvPath ( ai_schd, InitialEdge(a), tpd_a_q ); BufPath ( bb_schd, InitialEdge(b), tpd_b_q ); InvPath ( bi_schd, InitialEdge(b), tpd_b_q ); BufPath ( cb_schd, InitialEdge(c), tpd_c_q ); InvPath ( ci_schd, InitialEdge(c), tpd_c_q ); BufPath ( DB_Schd, InitialEdge(d), tpd_d_q ); InvPath ( di_schd, InitialEdge(d), tpd_d_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( ab_schd, GetEdge(a), tpd_a_q ); InvPath ( ai_schd, GetEdge(a), tpd_a_q ); BufPath ( bb_schd, GetEdge(b), tpd_b_q ); InvPath ( bi_schd, GetEdge(b), tpd_b_q ); BufPath ( cb_schd, GetEdge(c), tpd_c_q ); InvPath ( ci_schd, GetEdge(c), tpd_c_q ); BufPath ( DB_Schd, GetEdge(d), tpd_d_q ); InvPath ( di_schd, GetEdge(d), tpd_d_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := NOT (a XOR b XOR c XOR d); new_schd := VitalXNOR4 ( ab_schd,ai_schd, bb_schd,bi_schd, cb_schd,ci_schd, DB_Schd,di_schd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON a, b, c, d; END LOOP; END IF; END; -- ------------------------------------------------------------------------ -- Buffers -- BUF ....... standard non-inverting buffer -- BUFIF0 ....... non-inverting buffer Data passes thru if (Enable = '0') -- BUFIF1 ....... non-inverting buffer Data passes thru if (Enable = '1') -- ------------------------------------------------------------------------ PROCEDURE VitalBUF ( SIGNAL q : OUT std_ulogic; SIGNAL a : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF (tpd_a_q = VitalZeroDelay01) THEN LOOP q <= ResultMap(To_UX01(a)); WAIT ON a; END LOOP; ELSE LOOP -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := To_UX01(a); -- convert to forcing strengths CASE EdgeType'(GetEdge(a)) IS WHEN '1'|'/'|'R'|'r' => Dly := tpd_a_q(tr01); WHEN '0'|'\'|'F'|'f' => Dly := tpd_a_q(tr10); WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10)); END CASE; VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode ); WAIT ON a; END LOOP; END IF; END; -- PROCEDURE VitalBUFIF1 ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_ulogic; SIGNAL Enable : IN std_ulogic; CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z; CONSTANT ResultMap : IN VitalResultZMapType := VitalDefaultResultZMap ) IS VARIABLE NewValue : UX01Z; VARIABLE Glitch_Data : GlitchDataType; VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_data_q = VitalZeroDelay01 ) AND (tpd_enable_q = VitalZeroDelay01Z)) THEN LOOP q <= VitalBUFIF1( Data, Enable, ResultMap ); WAIT ON Data, Enable; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( d_Schd, InitialEdge(Data), tpd_data_q ); BufEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( d_Schd, GetEdge(Data), tpd_data_q ); BufEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := VitalBUFIF1( Data, Enable ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), d_Schd, e1_Schd, e0_Schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data, Enable; END LOOP; END IF; END; -- PROCEDURE VitalBUFIF0 ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_ulogic; SIGNAL Enable : IN std_ulogic; CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z; CONSTANT ResultMap : IN VitalResultZMapType := VitalDefaultResultZMap ) IS VARIABLE NewValue : UX01Z; VARIABLE Glitch_Data : GlitchDataType; VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType; VARIABLE ne1_schd, ne0_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_data_q = VitalZeroDelay01 ) AND (tpd_enable_q = VitalZeroDelay01Z)) THEN LOOP q <= VitalBUFIF0( Data, Enable, ResultMap ); WAIT ON Data, Enable; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( d_Schd, InitialEdge(Data), tpd_data_q ); InvEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( d_Schd, GetEdge(Data), tpd_data_q ); InvEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := VitalBUFIF0( Data, Enable ); ne1_schd := NOT e1_Schd; ne0_schd := NOT e0_Schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), d_Schd, ne1_schd, ne0_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data, Enable; END LOOP; END IF; END; PROCEDURE VitalIDENT ( SIGNAL q : OUT std_ulogic; SIGNAL a : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01Z := VitalDefDelay01Z; CONSTANT ResultMap : IN VitalResultZMapType := VitalDefaultResultZMap ) IS SUBTYPE v2 IS std_logic_vector(0 TO 1); VARIABLE NewValue : UX01Z; VARIABLE Glitch_Data : GlitchDataType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF (tpd_a_q = VitalZeroDelay01Z) THEN LOOP q <= ResultMap(To_UX01Z(a)); WAIT ON a; END LOOP; ELSE LOOP -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ CASE v2'(To_X01Z(NewValue) & To_X01Z(a)) IS WHEN "00" => Dly := tpd_a_q(tr10); WHEN "01" => Dly := tpd_a_q(tr01); WHEN "0Z" => Dly := tpd_a_q(tr0z); WHEN "0X" => Dly := tpd_a_q(tr01); WHEN "10" => Dly := tpd_a_q(tr10); WHEN "11" => Dly := tpd_a_q(tr01); WHEN "1Z" => Dly := tpd_a_q(tr1z); WHEN "1X" => Dly := tpd_a_q(tr10); WHEN "Z0" => Dly := tpd_a_q(trz0); WHEN "Z1" => Dly := tpd_a_q(trz1); WHEN "ZZ" => Dly := 0 ns; WHEN "ZX" => Dly := Minimum (tpd_a_q(trz1), tpd_a_q(trz0)); WHEN "X0" => Dly := tpd_a_q(tr10); WHEN "X1" => Dly := tpd_a_q(tr01); WHEN "XZ" => Dly := Minimum (tpd_a_q(tr0z), tpd_a_q(tr1z)); WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10)); END CASE; NewValue := To_UX01Z(a); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode ); WAIT ON a; END LOOP; END IF; END; -- ------------------------------------------------------------------------ -- Invertors -- INV ......... standard inverting buffer -- INVIF0 ......... inverting buffer Data passes thru if (Enable = '0') -- INVIF1 ......... inverting buffer Data passes thru if (Enable = '1') -- ------------------------------------------------------------------------ PROCEDURE VitalINV ( SIGNAL q : OUT std_ulogic; SIGNAL a : IN std_ulogic ; CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN IF (tpd_a_q = VitalZeroDelay01) THEN LOOP q <= ResultMap(NOT a); WAIT ON a; END LOOP; ELSE LOOP -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := NOT a; CASE EdgeType'(GetEdge(a)) IS WHEN '1'|'/'|'R'|'r' => Dly := tpd_a_q(tr10); WHEN '0'|'\'|'F'|'f' => Dly := tpd_a_q(tr01); WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10)); END CASE; VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode ); WAIT ON a; END LOOP; END IF; END; -- PROCEDURE VitalINVIF1 ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_ulogic; SIGNAL Enable : IN std_ulogic; CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z; CONSTANT ResultMap : IN VitalResultZMapType := VitalDefaultResultZMap ) IS VARIABLE NewValue : UX01Z; VARIABLE new_schd : SchedType; VARIABLE Glitch_Data : GlitchDataType; VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_data_q = VitalZeroDelay01 ) AND (tpd_enable_q = VitalZeroDelay01Z)) THEN LOOP q <= VitalINVIF1( Data, Enable, ResultMap ); WAIT ON Data, Enable; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- InvPath ( d_Schd, InitialEdge(Data), tpd_data_q ); BufEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- InvPath ( d_Schd, GetEdge(Data), tpd_data_q ); BufEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := VitalINVIF1( Data, Enable ); new_schd := NOT d_Schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd, e1_Schd, e0_Schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data, Enable; END LOOP; END IF; END; -- PROCEDURE VitalINVIF0 ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_ulogic; SIGNAL Enable : IN std_ulogic; CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z; CONSTANT ResultMap : IN VitalResultZMapType := VitalDefaultResultZMap ) IS VARIABLE NewValue : UX01Z; VARIABLE new_schd : SchedType; VARIABLE Glitch_Data : GlitchDataType; VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType; VARIABLE ne1_schd, ne0_schd : SchedType := DefSchedType; VARIABLE Dly, Glch : TIME; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_data_q = VitalZeroDelay01 ) AND (tpd_enable_q = VitalZeroDelay01Z)) THEN LOOP q <= VitalINVIF0( Data, Enable, ResultMap ); WAIT ON Data, Enable; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- InvPath ( d_Schd, InitialEdge(Data), tpd_data_q ); InvEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- InvPath ( d_Schd, GetEdge(Data), tpd_data_q ); InvEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q ); -- ------------------------------------ -- Compute function and propation delay -- ------------------------------------ NewValue := VitalINVIF0( Data, Enable ); ne1_schd := NOT e1_Schd; ne0_schd := NOT e0_Schd; new_schd := NOT d_Schd; -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd, ne1_schd, ne0_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data, Enable; END LOOP; END IF; END; -- ------------------------------------------------------------------------ -- Multiplexor -- MUX .......... result := data(dselect) -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'), -- data1 when (dselect = '1'), -- 'X' when (dselect = 'X') and (data0 /= data1) -- MUX4 .......... 4-input mux; result := data(dselect) -- MUX8 .......... 8-input mux; result := data(dselect) -- ------------------------------------------------------------------------ PROCEDURE VitalMUX2 ( SIGNAL q : OUT std_ulogic; SIGNAL d1, d0 : IN std_ulogic; SIGNAL dSel : IN std_ulogic; CONSTANT tpd_d1_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_d0_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_dsel_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; VARIABLE d1_Schd, d0_Schd : SchedType; VARIABLE dSel_bSchd, dSel_iSchd : SchedType; VARIABLE d1_Edge, d0_Edge, dSel_Edge : EdgeType; BEGIN -- ------------------------------------------------------------------------ -- For ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF ( (tpd_d1_q = VitalZeroDelay01) AND (tpd_d0_q = VitalZeroDelay01) AND (tpd_dsel_q = VitalZeroDelay01) ) THEN LOOP q <= VitalMUX2 ( d1, d0, dSel, ResultMap ); WAIT ON d1, d0, dSel; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( d1_Schd, InitialEdge(d1), tpd_d1_q ); BufPath ( d0_Schd, InitialEdge(d0), tpd_d0_q ); BufPath ( dSel_bSchd, InitialEdge(dSel), tpd_dsel_q ); InvPath ( dSel_iSchd, InitialEdge(dSel), tpd_dsel_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( d1_Schd, GetEdge(d1), tpd_d1_q ); BufPath ( d0_Schd, GetEdge(d0), tpd_d0_q ); BufPath ( dSel_bSchd, GetEdge(dSel), tpd_dsel_q ); InvPath ( dSel_iSchd, GetEdge(dSel), tpd_dsel_q ); -- ------------------------------------ -- Compute function and propation delaq -- ------------------------------------ NewValue := VitalMUX2 ( d1, d0, dSel ); new_schd := VitalMUX2 ( d1_Schd, d0_Schd, dSel_bSchd, dSel_iSchd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON d1, d0, dSel; END LOOP; END IF; END; -- PROCEDURE VitalMUX4 ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_logic_vector4; SIGNAL dSel : IN std_logic_vector2; CONSTANT tpd_data_q : IN VitalDelayArrayType01; CONSTANT tpd_dsel_q : IN VitalDelayArrayType01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U'); VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; VARIABLE Data_Schd : SchedArray4; VARIABLE Data_Edge : EdgeArray4; VARIABLE dSel_Edge : EdgeArray2; VARIABLE dSel_bSchd : SchedArray2; VARIABLE dSel_iSchd : SchedArray2; ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q; VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ FOR i IN dSel'RANGE LOOP IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; IF (AllZeroDelay) THEN FOR i IN Data'RANGE LOOP IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; IF (AllZeroDelay) THEN LOOP q <= VitalMUX(Data, dSel, ResultMap); WAIT ON Data, dSel; END LOOP; END IF; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- FOR n IN Data'RANGE LOOP BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); END LOOP; FOR n IN dSel'RANGE LOOP BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) ); InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) ); END LOOP; LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- GetEdge ( Data, LastData, Data_Edge ); BufPath ( Data_Schd, Data_Edge, Atpd_data_q ); GetEdge ( dSel, LastdSel, dSel_Edge ); BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q ); InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q ); -- ------------------------------------ -- Compute function and propation delaq -- ------------------------------------ NewValue := VitalMUX4 ( Data, dSel ); new_schd := VitalMUX4 ( Data_Schd, dSel_bSchd, dSel_iSchd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data, dSel; END LOOP; END IF; --SN END; PROCEDURE VitalMUX8 ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_logic_vector8; SIGNAL dSel : IN std_logic_vector3; CONSTANT tpd_data_q : IN VitalDelayArrayType01; CONSTANT tpd_dsel_q : IN VitalDelayArrayType01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U'); VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; VARIABLE Data_Schd : SchedArray8; VARIABLE Data_Edge : EdgeArray8; VARIABLE dSel_Edge : EdgeArray3; VARIABLE dSel_bSchd : SchedArray3; VARIABLE dSel_iSchd : SchedArray3; ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q; VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ FOR i IN dSel'RANGE LOOP IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; IF (AllZeroDelay) THEN FOR i IN Data'RANGE LOOP IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; IF (AllZeroDelay) THEN LOOP q <= VitalMUX(Data, dSel, ResultMap); WAIT ON Data, dSel; END LOOP; END IF; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- FOR n IN Data'RANGE LOOP BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); END LOOP; FOR n IN dSel'RANGE LOOP BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) ); InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) ); END LOOP; LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- GetEdge ( Data, LastData, Data_Edge ); BufPath ( Data_Schd, Data_Edge, Atpd_data_q ); GetEdge ( dSel, LastdSel, dSel_Edge ); BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q ); InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q ); -- ------------------------------------ -- Compute function and propation delaq -- ------------------------------------ NewValue := VitalMUX8 ( Data, dSel ); new_schd := VitalMUX8 ( Data_Schd, dSel_bSchd, dSel_iSchd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data, dSel; END LOOP; END IF; END; -- PROCEDURE VitalMUX ( SIGNAL q : OUT std_ulogic; SIGNAL Data : IN std_logic_vector; SIGNAL dSel : IN std_logic_vector; CONSTANT tpd_data_q : IN VitalDelayArrayType01; CONSTANT tpd_dsel_q : IN VitalDelayArrayType01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U'); VARIABLE NewValue : UX01; VARIABLE Glitch_Data : GlitchDataType; VARIABLE new_schd : SchedType; VARIABLE Dly, Glch : TIME; VARIABLE Data_Schd : SchedArray(Data'RANGE); VARIABLE Data_Edge : EdgeArray(Data'RANGE); VARIABLE dSel_Edge : EdgeArray(dSel'RANGE); VARIABLE dSel_bSchd : SchedArray(dSel'RANGE); VARIABLE dSel_iSchd : SchedArray(dSel'RANGE); ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q; VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ FOR i IN dSel'RANGE LOOP IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; IF (AllZeroDelay) THEN FOR i IN Data'RANGE LOOP IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; IF (AllZeroDelay) THEN LOOP q <= VitalMUX(Data, dSel, ResultMap); WAIT ON Data, dSel; END LOOP; END IF; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- FOR n IN Data'RANGE LOOP BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); END LOOP; FOR n IN dSel'RANGE LOOP BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) ); InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) ); END LOOP; LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- GetEdge ( Data, LastData, Data_Edge ); BufPath ( Data_Schd, Data_Edge, Atpd_data_q ); GetEdge ( dSel, LastdSel, dSel_Edge ); BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q ); InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q ); -- ------------------------------------ -- Compute function and propation delaq -- ------------------------------------ NewValue := VitalMUX ( Data, dSel ); new_schd := VitalMUX ( Data_Schd, dSel_bSchd, dSel_iSchd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data, dSel; END LOOP; END IF; --SN END; -- ------------------------------------------------------------------------ -- Decoder -- General Algorithm : -- (a) Result(...) := '0' when (enable = '0') -- (b) Result(data) := '1'; all other subelements = '0' -- ... Result array is decending (n-1 downto 0) -- -- DECODERn .......... n:2**n decoder -- Caution: If 'ResultMap' defines other than strength mapping, the -- delay selection is not defined. -- ------------------------------------------------------------------------ PROCEDURE VitalDECODER2 ( SIGNAL q : OUT std_logic_vector2; SIGNAL Data : IN std_ulogic; SIGNAL Enable : IN std_ulogic; CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE NewValue : std_logic_vector2; VARIABLE Glitch_Data : GlitchArray2; VARIABLE new_schd : SchedArray2; VARIABLE Dly, Glch : TimeArray2; VARIABLE Enable_Schd : SchedType := DefSchedType; VARIABLE Data_BSchd, Data_ISchd : SchedType; BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF (tpd_enable_q = VitalZeroDelay01) AND (tpd_data_q = VitalZeroDelay01) THEN LOOP q <= VitalDECODER2(Data, Enable, ResultMap); WAIT ON Data, Enable; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- BufPath ( Data_BSchd, InitialEdge(Data), tpd_data_q ); InvPath ( Data_ISchd, InitialEdge(Data), tpd_data_q ); BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- BufPath ( Data_BSchd, GetEdge(Data), tpd_data_q ); InvPath ( Data_ISchd, GetEdge(Data), tpd_data_q ); BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q ); -- ------------------------------------ -- Compute function and propation delaq -- ------------------------------------ NewValue := VitalDECODER2 ( Data, Enable, ResultMap ); new_schd := VitalDECODER2 ( Data_BSchd, Data_ISchd, Enable_Schd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data, Enable; END LOOP; END IF; -- SN END; -- PROCEDURE VitalDECODER4 ( SIGNAL q : OUT std_logic_vector4; SIGNAL Data : IN std_logic_vector2; SIGNAL Enable : IN std_ulogic; CONSTANT tpd_data_q : IN VitalDelayArrayType01; CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); VARIABLE NewValue : std_logic_vector4; VARIABLE Glitch_Data : GlitchArray4; VARIABLE new_schd : SchedArray4; VARIABLE Dly, Glch : TimeArray4; VARIABLE Enable_Schd : SchedType; VARIABLE Enable_Edge : EdgeType; VARIABLE Data_Edge : EdgeArray2; VARIABLE Data_BSchd, Data_ISchd : SchedArray2; ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF (tpd_enable_q /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; ELSE FOR i IN Data'RANGE LOOP IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; END IF; IF (AllZeroDelay) THEN LOOP q <= VitalDECODER4(Data, Enable, ResultMap); WAIT ON Data, Enable; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- FOR n IN Data'RANGE LOOP BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); END LOOP; BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- GetEdge ( Data, LastData, Data_Edge ); BufPath ( Data_BSchd, Data_Edge, Atpd_data_q ); InvPath ( Data_ISchd, Data_Edge, Atpd_data_q ); BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q ); -- ------------------------------------ -- Compute function and propation delaq -- ------------------------------------ NewValue := VitalDECODER4 ( Data, Enable, ResultMap ); new_schd := VitalDECODER4 ( Data_BSchd, Data_ISchd, Enable_Schd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data, Enable; END LOOP; END IF; END; -- PROCEDURE VitalDECODER8 ( SIGNAL q : OUT std_logic_vector8; SIGNAL Data : IN std_logic_vector3; SIGNAL Enable : IN std_ulogic; CONSTANT tpd_data_q : IN VitalDelayArrayType01; CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); VARIABLE NewValue : std_logic_vector8; VARIABLE Glitch_Data : GlitchArray8; VARIABLE new_schd : SchedArray8; VARIABLE Dly, Glch : TimeArray8; VARIABLE Enable_Schd : SchedType; VARIABLE Enable_Edge : EdgeType; VARIABLE Data_Edge : EdgeArray3; VARIABLE Data_BSchd, Data_ISchd : SchedArray3; ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF (tpd_enable_q /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; ELSE FOR i IN Data'RANGE LOOP IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; END IF; IF (AllZeroDelay) THEN LOOP q <= VitalDECODER(Data, Enable, ResultMap); WAIT ON Data, Enable; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- FOR n IN Data'RANGE LOOP BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); END LOOP; BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- GetEdge ( Data, LastData, Data_Edge ); BufPath ( Data_BSchd, Data_Edge, Atpd_data_q ); InvPath ( Data_ISchd, Data_Edge, Atpd_data_q ); BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q ); -- ------------------------------------ -- Compute function and propation delaq -- ------------------------------------ NewValue := VitalDECODER8 ( Data, Enable, ResultMap ); new_schd := VitalDECODER8 ( Data_BSchd, Data_ISchd, Enable_Schd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data, Enable; END LOOP; END IF; --SN END; -- PROCEDURE VitalDECODER ( SIGNAL q : OUT std_logic_vector; SIGNAL Data : IN std_logic_vector; SIGNAL Enable : IN std_ulogic; CONSTANT tpd_data_q : IN VitalDelayArrayType01; CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01; CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap ) IS VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U'); VARIABLE NewValue : std_logic_vector(q'RANGE); VARIABLE Glitch_Data : GlitchDataArrayType(q'RANGE); VARIABLE new_schd : SchedArray(q'RANGE); VARIABLE Dly, Glch : VitalTimeArray(q'RANGE); VARIABLE Enable_Schd : SchedType; VARIABLE Enable_Edge : EdgeType; VARIABLE Data_Edge : EdgeArray(Data'RANGE); VARIABLE Data_BSchd, Data_ISchd : SchedArray(Data'RANGE); ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q; VARIABLE AllZeroDelay : BOOLEAN := TRUE; BEGIN -- ------------------------------------------------------------------------ -- Check if ALL zero delay paths, use simple model -- ( No delay selection, glitch detection required ) -- ------------------------------------------------------------------------ IF (tpd_enable_q /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; ELSE FOR i IN Data'RANGE LOOP IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN AllZeroDelay := FALSE; EXIT; END IF; END LOOP; END IF; IF (AllZeroDelay) THEN LOOP q <= VitalDECODER(Data, Enable, ResultMap); WAIT ON Data, Enable; END LOOP; ELSE -- -------------------------------------- -- Initialize delay schedules -- -------------------------------------- FOR n IN Data'RANGE LOOP BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) ); END LOOP; BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q ); LOOP -- -------------------------------------- -- Process input signals -- get edge values -- re-evaluate output schedules -- -------------------------------------- GetEdge ( Data, LastData, Data_Edge ); BufPath ( Data_BSchd, Data_Edge, Atpd_data_q ); InvPath ( Data_ISchd, Data_Edge, Atpd_data_q ); BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q ); -- ------------------------------------ -- Compute function and propation delaq -- ------------------------------------ NewValue := VitalDECODER ( Data, Enable, ResultMap ); new_schd := VitalDECODER ( Data_BSchd, Data_ISchd, Enable_Schd ); -- ------------------------------------------------------ -- Assign Outputs -- get delays to new value and possable glitch -- schedule output change with On Event glitch detection -- ------------------------------------------------------ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd ); VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly, PrimGlitchMode, GlitchDelay=>Glch ); WAIT ON Data, Enable; END LOOP; END IF; END; -- ------------------------------------------------------------------------ FUNCTION VitalTruthTable ( CONSTANT TruthTable : IN VitalTruthTableType; CONSTANT DataIn : IN std_logic_vector ) RETURN std_logic_vector IS CONSTANT InputSize : INTEGER := DataIn'LENGTH; CONSTANT OutSize : INTEGER := TruthTable'LENGTH(2) - InputSize; VARIABLE ReturnValue : std_logic_vector(OutSize - 1 DOWNTO 0) := (OTHERS => 'X'); VARIABLE DataInAlias : std_logic_vector(0 TO InputSize - 1) := To_X01(DataIn); VARIABLE Index : INTEGER; VARIABLE Err : BOOLEAN := FALSE; -- This needs to be done since the TableLookup arrays must be -- ascending starting with 0 VARIABLE TableAlias : VitalTruthTableType(0 TO (TruthTable'LENGTH(1)-1), 0 TO (TruthTable'LENGTH(2)-1)) := TruthTable; BEGIN -- search through each row of the truth table IF OutSize > 0 THEN ColLoop: FOR i IN TableAlias'RANGE(1) LOOP RowLoop: -- Check each input element of the entry FOR j IN 0 TO InputSize LOOP IF (j = InputSize) THEN -- This entry matches -- Return the Result Index := 0; FOR k IN TruthTable'LENGTH(2) - 1 DOWNTO InputSize LOOP TruthOutputX01Z ( TableAlias(i,k), ReturnValue(Index), Err); EXIT WHEN Err; Index := Index + 1; END LOOP; IF Err THEN ReturnValue := (OTHERS => 'X'); END IF; RETURN ReturnValue; END IF; IF NOT ValidTruthTableInput(TableAlias(i,j)) THEN VitalError ( "VitalTruthTable", ErrInpSym, To_TruthChar(TableAlias(i,j)) ); EXIT ColLoop; END IF; EXIT RowLoop WHEN NOT ( TruthTableMatch( DataInAlias(j), TableAlias(i, j))); END LOOP RowLoop; END LOOP ColLoop; ELSE VitalError ( "VitalTruthTable", ErrTabWidSml ); END IF; RETURN ReturnValue; END VitalTruthTable; FUNCTION VitalTruthTable ( CONSTANT TruthTable : IN VitalTruthTableType; CONSTANT DataIn : IN std_logic_vector ) RETURN std_logic IS CONSTANT InputSize : INTEGER := DataIn'LENGTH; CONSTANT OutSize : INTEGER := TruthTable'LENGTH(2) - InputSize; VARIABLE TempResult : std_logic_vector(OutSize - 1 DOWNTO 0) := (OTHERS => 'X'); BEGIN IF (OutSize > 0) THEN TempResult := VitalTruthTable(TruthTable, DataIn); IF ( 1 > OutSize) THEN VitalError ( "VitalTruthTable", ErrTabResSml ); ELSIF ( 1 < OutSize) THEN VitalError ( "VitalTruthTable", ErrTabResLrg ); END IF; RETURN (TempResult(0)); ELSE VitalError ( "VitalTruthTable", ErrTabWidSml ); RETURN 'X'; END IF; END VitalTruthTable; PROCEDURE VitalTruthTable ( SIGNAL Result : OUT std_logic_vector; CONSTANT TruthTable : IN VitalTruthTableType; CONSTANT DataIn : IN std_logic_vector ) IS CONSTANT ResLeng : INTEGER := Result'LENGTH; CONSTANT ActResLen : INTEGER := TruthTable'LENGTH(2) - DataIn'LENGTH; CONSTANT FinalResLen : INTEGER := Minimum(ActResLen, ResLeng); VARIABLE TempResult : std_logic_vector(ActResLen - 1 DOWNTO 0) := (OTHERS => 'X'); BEGIN TempResult := VitalTruthTable(TruthTable, DataIn); IF (ResLeng > ActResLen) THEN VitalError ( "VitalTruthTable", ErrTabResSml ); ELSIF (ResLeng < ActResLen) THEN VitalError ( "VitalTruthTable", ErrTabResLrg ); END IF; TempResult(FinalResLen-1 DOWNTO 0) := TempResult(FinalResLen-1 DOWNTO 0); Result <= TempResult; END VitalTruthTable; PROCEDURE VitalTruthTable ( SIGNAL Result : OUT std_logic; CONSTANT TruthTable : IN VitalTruthTableType; CONSTANT DataIn : IN std_logic_vector ) IS CONSTANT ActResLen : INTEGER := TruthTable'LENGTH(2) - DataIn'LENGTH; VARIABLE TempResult : std_logic_vector(ActResLen - 1 DOWNTO 0) := (OTHERS => 'X'); BEGIN TempResult := VitalTruthTable(TruthTable, DataIn); IF ( 1 > ActResLen) THEN VitalError ( "VitalTruthTable", ErrTabResSml ); ELSIF ( 1 < ActResLen) THEN VitalError ( "VitalTruthTable", ErrTabResLrg ); END IF; IF (ActResLen > 0) THEN Result <= TempResult(0); END IF; END VitalTruthTable; -- ------------------------------------------------------------------------ PROCEDURE VitalStateTable ( VARIABLE Result : INOUT std_logic_vector; VARIABLE PreviousDataIn : INOUT std_logic_vector; CONSTANT StateTable : IN VitalStateTableType; CONSTANT DataIn : IN std_logic_vector; CONSTANT NumStates : IN NATURAL ) IS CONSTANT InputSize : INTEGER := DataIn'LENGTH; CONSTANT OutSize : INTEGER := StateTable'LENGTH(2) - InputSize - NumStates; CONSTANT ResLeng : INTEGER := Result'LENGTH; VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1) := To_X01(DataIn); VARIABLE PrevDataAlias : std_logic_vector(0 TO PreviousDataIn'LENGTH-1) := To_X01(PreviousDataIn); VARIABLE ResultAlias : std_logic_vector(0 TO ResLeng-1) := To_X01(Result); VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1); BEGIN IF (PreviousDataIn'LENGTH < DataIn'LENGTH) THEN VitalError ( "VitalStateTable", ErrVctLng, "PreviousDataIn 'X'); Result := ResultAlias; ELSIF (OutSize <= 0) THEN VitalError ( "VitalStateTable", ErrTabWidSml ); ResultAlias := (OTHERS => 'X'); Result := ResultAlias; ELSE IF (ResLeng > OutSize) THEN VitalError ( "VitalStateTable", ErrTabResSml ); ELSIF (ResLeng < OutSize) THEN VitalError ( "VitalStateTable", ErrTabResLrg ); END IF; ExpResult := StateTableLookUp ( StateTable, DataInAlias, PrevDataAlias, NumStates, ResultAlias); ResultAlias := (OTHERS => 'X'); ResultAlias ( Maximum(0, ResLeng - OutSize) TO ResLeng - 1) := ExpResult(Maximum(0, OutSize - ResLeng) TO OutSize-1); Result := ResultAlias; PrevDataAlias(0 TO InputSize - 1) := DataInAlias; PreviousDataIn := PrevDataAlias; END IF; END VitalStateTable; PROCEDURE VitalStateTable ( VARIABLE Result : INOUT std_logic; -- states VARIABLE PreviousDataIn : INOUT std_logic_vector; -- previous inputs and states CONSTANT StateTable : IN VitalStateTableType; -- User's StateTable data CONSTANT DataIn : IN std_logic_vector -- Inputs ) IS VARIABLE ResultAlias : std_logic_vector(0 TO 0); BEGIN ResultAlias(0) := Result; VitalStateTable ( StateTable => StateTable, DataIn => DataIn, NumStates => 1, Result => ResultAlias, PreviousDataIn => PreviousDataIn ); Result := ResultAlias(0); END VitalStateTable; PROCEDURE VitalStateTable ( SIGNAL Result : INOUT std_logic_vector; CONSTANT StateTable : IN VitalStateTableType; SIGNAL DataIn : IN std_logic_vector; CONSTANT NumStates : IN NATURAL ) IS CONSTANT InputSize : INTEGER := DataIn'LENGTH; CONSTANT OutSize : INTEGER := StateTable'LENGTH(2) - InputSize - NumStates; CONSTANT ResLeng : INTEGER := Result'LENGTH; VARIABLE PrevData : std_logic_vector(0 TO DataIn'LENGTH-1) := (OTHERS => 'X'); VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1); VARIABLE ResultAlias : std_logic_vector(0 TO ResLeng-1); VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1); BEGIN IF (OutSize <= 0) THEN VitalError ( "VitalStateTable", ErrTabWidSml ); ResultAlias := (OTHERS => 'X'); Result <= ResultAlias; ELSE IF (ResLeng > OutSize) THEN VitalError ( "VitalStateTable", ErrTabResSml ); ELSIF (ResLeng < OutSize) THEN VitalError ( "VitalStateTable", ErrTabResLrg ); END IF; LOOP DataInAlias := To_X01(DataIn); ResultAlias := To_X01(Result); ExpResult := StateTableLookUp ( StateTable, DataInAlias, PrevData, NumStates, ResultAlias); ResultAlias := (OTHERS => 'X'); ResultAlias(Maximum(0, ResLeng - OutSize) TO ResLeng-1) := ExpResult(Maximum(0, OutSize - ResLeng) TO OutSize-1); Result <= ResultAlias; PrevData := DataInAlias; WAIT ON DataIn; END LOOP; END IF; END VitalStateTable; PROCEDURE VitalStateTable ( SIGNAL Result : INOUT std_logic; CONSTANT StateTable : IN VitalStateTableType; SIGNAL DataIn : IN std_logic_vector ) IS CONSTANT InputSize : INTEGER := DataIn'LENGTH; CONSTANT OutSize : INTEGER := StateTable'LENGTH(2) - InputSize-1; VARIABLE PrevData : std_logic_vector(0 TO DataIn'LENGTH-1) := (OTHERS => 'X'); VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1); VARIABLE ResultAlias : std_logic_vector(0 TO 0); VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1); BEGIN IF (OutSize <= 0) THEN VitalError ( "VitalStateTable", ErrTabWidSml ); Result <= 'X'; ELSE IF ( 1 > OutSize) THEN VitalError ( "VitalStateTable", ErrTabResSml ); ELSIF ( 1 < OutSize) THEN VitalError ( "VitalStateTable", ErrTabResLrg ); END IF; LOOP ResultAlias(0) := To_X01(Result); DataInAlias := To_X01(DataIn); ExpResult := StateTableLookUp ( StateTable, DataInAlias, PrevData, 1, ResultAlias); Result <= ExpResult(OutSize-1); PrevData := DataInAlias; WAIT ON DataIn; END LOOP; END IF; END VitalStateTable; -- ------------------------------------------------------------------------ -- std_logic resolution primitive -- ------------------------------------------------------------------------ PROCEDURE VitalResolve ( SIGNAL q : OUT std_ulogic; CONSTANT Data : IN std_logic_vector ) IS VARIABLE uData : std_ulogic_vector(Data'RANGE); BEGIN FOR i IN Data'RANGE LOOP uData(i) := Data(i); END LOOP; q <= resolved(uData); END; END VITAL_Primitives;