1-------------------------------------------------------------------------------
2-- Title        : Standard VITAL_Primitives Package
3--              : $Revision$
4--              :
5-- Library      : VITAL
6--              :
7-- Developers   : IEEE DASC Timing Working Group (TWG), PAR 1076.4
8--              :
9-- Purpose      : This packages defines standard types, constants, functions
10--              : and procedures for use in developing ASIC models.
11--              : Specifically a set of logic primitives are defined.
12--              :
13-- ----------------------------------------------------------------------------
14--
15-- ----------------------------------------------------------------------------
16-- Modification History :
17-- ----------------------------------------------------------------------------
18-- Version No:|Auth:| Mod.Date:| Changes Made:
19--   v95.0 A  |     | 06/02/95 | Initial ballot draft 1995
20--   v95.1    |     | 08/31/95 | #204 - glitch detection prior to OutputMap
21-- ----------------------------------------------------------------------------
22--   v95.2    | ddl | 09/14/96 | #223 - single input prmtvs use on-detect
23--            |     |          |        instead of glitch-on-event behavior
24--   v95.3    | ddl | 09/24/96 | #236 - VitalTruthTable DataIn should be of
25--            |     |          |        of class SIGNAL
26--   v95.4    | ddl | 01/16/97 | #243 - index constraint error in nbit xor/xnor
27--   v99.1    | dbb | 03/31/99 | Updated for VHDL 93
28-- ----------------------------------------------------------------------------
29
30LIBRARY STD;
31USE STD.TEXTIO.ALL;
32
33PACKAGE BODY VITAL_Primitives IS
34    -- ------------------------------------------------------------------------
35    --  Default values for Primitives
36    -- ------------------------------------------------------------------------
37    --  default values for delay parameters
38    CONSTANT VitalDefDelay01  : VitalDelayType01  := VitalZeroDelay01;
39    CONSTANT VitalDefDelay01Z : VitalDelayType01Z := VitalZeroDelay01Z;
40
41    TYPE VitalTimeArray IS ARRAY (NATURAL RANGE <>) OF TIME;
42
43    --  default primitive model operation parameters
44    --  Glitch detection/reporting
45    TYPE VitalGlitchModeType IS ( MessagePlusX, MessageOnly, XOnly, NoGlitch);
46    CONSTANT PrimGlitchMode : VitalGlitchModeType   := XOnly;
47
48    -- ------------------------------------------------------------------------
49    -- Local Type and Subtype Declarations
50    -- ------------------------------------------------------------------------
51    ---------------------------------------------------------------------------
52    -- enumeration value representing the transition or level of the signal.
53    --  See function 'GetEdge'
54    ---------------------------------------------------------------------------
55    TYPE EdgeType IS ( 'U',   -- Uninitialized level
56                       'X',   -- Unknown level
57                       '0',   -- low level
58                       '1',   -- high level
59                       '\',   -- 1 to 0 falling edge
60                       '/',   -- 0 to 1 rising  edge
61                       'F',   -- * to 0 falling edge
62                       'R',   -- * to 1 rising  edge
63                       'f',   -- rising  to X edge
64                       'r',   -- falling to X edge
65                       'x',   -- Unknown edge (ie U->X)
66                       'V'    -- Timing violation edge
67                     );
68    TYPE EdgeArray  IS ARRAY ( NATURAL RANGE <> ) OF EdgeType;
69
70    TYPE EdgeX1Table IS ARRAY ( EdgeType                          ) OF EdgeType;
71    TYPE EdgeX2Table IS ARRAY ( EdgeType, EdgeType                ) OF EdgeType;
72    TYPE EdgeX3Table IS ARRAY ( EdgeType, EdgeType, EdgeType      ) OF EdgeType;
73    TYPE EdgeX4Table IS ARRAY (EdgeType,EdgeType,EdgeType,EdgeType) OF EdgeType;
74
75    TYPE LogicToEdgeT  IS ARRAY(std_ulogic, std_ulogic) OF EdgeType;
76    TYPE LogicToLevelT IS ARRAY(std_ulogic ) OF EdgeType;
77
78    TYPE GlitchDataType IS
79      RECORD
80        SchedTime    : TIME;
81        GlitchTime   : TIME;
82        SchedValue   : std_ulogic;
83        CurrentValue    : std_ulogic;
84      END RECORD;
85    TYPE GlitchDataArrayType IS ARRAY (NATURAL RANGE <>)
86         OF GlitchDataType;
87
88    -- Enumerated type used in selection of output path delays
89    TYPE SchedType  IS
90      RECORD
91        inp0  : TIME;   -- time (abs) of output change due to input change to 0
92        inp1  : TIME;   -- time (abs) of output change due to input change to 1
93        InpX  : TIME;   -- time (abs) of output change due to input change to X
94        Glch0 : TIME;   -- time (abs) of output glitch due to input change to 0
95        Glch1 : TIME;   -- time (abs) of output glitch due to input change to 0
96      END RECORD;
97
98    TYPE SchedArray  IS ARRAY ( NATURAL RANGE <> ) OF SchedType;
99    CONSTANT DefSchedType : SchedType := (TIME'HIGH, TIME'HIGH, 0 ns,0 ns,0 ns);
100    CONSTANT DefSchedAnd  : SchedType := (TIME'HIGH, 0 ns,0 ns, TIME'HIGH,0 ns);
101
102    -- Constrained array declarations (common sizes used by primitives)
103    SUBTYPE SchedArray2 IS SchedArray(1 DOWNTO 0);
104    SUBTYPE SchedArray3 IS SchedArray(2 DOWNTO 0);
105    SUBTYPE SchedArray4 IS SchedArray(3 DOWNTO 0);
106    SUBTYPE SchedArray8 IS SchedArray(7 DOWNTO 0);
107
108    SUBTYPE TimeArray2 IS VitalTimeArray(1 DOWNTO 0);
109    SUBTYPE TimeArray3 IS VitalTimeArray(2 DOWNTO 0);
110    SUBTYPE TimeArray4 IS VitalTimeArray(3 DOWNTO 0);
111    SUBTYPE TimeArray8 IS VitalTimeArray(7 DOWNTO 0);
112
113    SUBTYPE GlitchArray2 IS GlitchDataArrayType(1 DOWNTO 0);
114    SUBTYPE GlitchArray3 IS GlitchDataArrayType(2 DOWNTO 0);
115    SUBTYPE GlitchArray4 IS GlitchDataArrayType(3 DOWNTO 0);
116    SUBTYPE GlitchArray8 IS GlitchDataArrayType(7 DOWNTO 0);
117
118    SUBTYPE EdgeArray2 IS EdgeArray(1 DOWNTO 0);
119    SUBTYPE EdgeArray3 IS EdgeArray(2 DOWNTO 0);
120    SUBTYPE EdgeArray4 IS EdgeArray(3 DOWNTO 0);
121    SUBTYPE EdgeArray8 IS EdgeArray(7 DOWNTO 0);
122
123    CONSTANT DefSchedArray2 : SchedArray2 :=
124                             (OTHERS=> (0 ns, 0 ns, 0 ns, 0 ns, 0 ns));
125
126    TYPE stdlogic_table IS ARRAY(std_ulogic, std_ulogic) OF std_ulogic;
127
128    CONSTANT InitialEdge : LogicToLevelT := (
129            '1'|'H' => 'R',
130            '0'|'L' => 'F',
131            OTHERS  => 'x'
132     );
133
134    CONSTANT LogicToEdge  : LogicToEdgeT  := (  -- previous, current
135    --  old \ new: U    X    0    1    Z    W    L    H    -
136        'U' =>  ( 'U', 'x', 'F', 'R', 'x', 'x', 'F', 'R', 'x' ),
137        'X' =>  ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ),
138        '0' =>  ( 'r', 'r', '0', '/', 'r', 'r', '0', '/', 'r' ),
139        '1' =>  ( 'f', 'f', '\', '1', 'f', 'f', '\', '1', 'f' ),
140        'Z' =>  ( 'x', 'X', 'F', 'R', 'X', 'x', 'F', 'R', 'x' ),
141        'W' =>  ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ),
142        'L' =>  ( 'r', 'r', '0', '/', 'r', 'r', '0', '/', 'r' ),
143        'H' =>  ( 'f', 'f', '\', '1', 'f', 'f', '\', '1', 'f' ),
144        '-' =>  ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' )
145    );
146    CONSTANT LogicToLevel : LogicToLevelT := (
147            '1'|'H' => '1',
148            '0'|'L' => '0',
149            'U'     => 'U',
150            OTHERS  => 'X'
151     );
152
153    -- -----------------------------------
154    -- 3-state logic tables
155    -- -----------------------------------
156    CONSTANT BufIf0_Table : stdlogic_table :=
157        -- enable        data       value
158        ( '1'|'H'   => ( OTHERS  => 'Z' ),
159          '0'|'L'   => ( '1'|'H' => '1',
160                         '0'|'L' => '0',
161                         'U'     => 'U',
162                         OTHERS  => 'X' ),
163          'U'       => ( OTHERS  => 'U' ),
164          OTHERS    => ( OTHERS  => 'X' ) );
165    CONSTANT BufIf1_Table : stdlogic_table :=
166        -- enable        data       value
167        ( '0'|'L'   => ( OTHERS  => 'Z' ),
168          '1'|'H'   => ( '1'|'H' => '1',
169                         '0'|'L' => '0',
170                         'U'     => 'U',
171                         OTHERS  => 'X' ),
172          'U'       => ( OTHERS  => 'U' ),
173          OTHERS    => ( OTHERS  => 'X' ) );
174    CONSTANT InvIf0_Table : stdlogic_table :=
175        -- enable        data       value
176        ( '1'|'H'   => ( OTHERS  => 'Z' ),
177          '0'|'L'   => ( '1'|'H' => '0',
178                         '0'|'L' => '1',
179                         'U'     => 'U',
180                         OTHERS  => 'X' ),
181          'U'       => ( OTHERS  => 'U' ),
182          OTHERS    => ( OTHERS  => 'X' ) );
183    CONSTANT InvIf1_Table : stdlogic_table :=
184        -- enable        data       value
185        ( '0'|'L'   => ( OTHERS  => 'Z' ),
186          '1'|'H'   => ( '1'|'H' => '0',
187                         '0'|'L' => '1',
188                         'U'     => 'U',
189                         OTHERS  => 'X' ),
190          'U'       => ( OTHERS  => 'U' ),
191          OTHERS    => ( OTHERS  => 'X' ) );
192
193
194    TYPE To_StateCharType IS ARRAY (VitalStateSymbolType) OF CHARACTER;
195    CONSTANT To_StateChar : To_StateCharType :=
196     ( '/', '\', 'P', 'N', 'r', 'f', 'p', 'n', 'R', 'F', '^', 'v',
197       'E', 'A', 'D', '*', 'X', '0', '1', '-', 'B', 'Z', 'S' );
198    TYPE To_TruthCharType IS ARRAY (VitalTruthSymbolType) OF CHARACTER;
199    CONSTANT To_TruthChar : To_TruthCharType :=
200     ( 'X', '0', '1', '-', 'B', 'Z' );
201
202    TYPE TruthTableOutMapType IS ARRAY (VitalTruthSymbolType) OF std_ulogic;
203    CONSTANT TruthTableOutMap : TruthTableOutMapType :=
204       --  'X', '0', '1', '-', 'B', 'Z'
205         ( 'X', '0', '1', 'X', '-', 'Z' );
206
207    TYPE StateTableOutMapType IS ARRAY (VitalStateSymbolType) OF std_ulogic;
208    -- does conversion to X01Z or '-' if invalid
209    CONSTANT StateTableOutMap : StateTableOutMapType :=
210     -- '/' '\' 'P' 'N' 'r' 'f' 'p' 'n' 'R' 'F' '^' 'v'
211     -- 'E' 'A' 'D' '*' 'X' '0' '1' '-' 'B' 'Z' 'S'
212      ( '-','-','-','-','-','-','-','-','-','-','-','-',
213        '-','-','-','-','X','0','1','X','-','Z','W');
214
215    -- ------------------------------------------------------------------------
216    TYPE ValidTruthTableInputType IS ARRAY (VitalTruthSymbolType) OF BOOLEAN;
217    -- checks if a symbol IS valid for the stimulus portion of a truth table
218    CONSTANT ValidTruthTableInput : ValidTruthTableInputType :=
219       -- 'X'    '0'    '1'    '-'    'B'    'Z'
220       (  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  FALSE );
221
222    TYPE TruthTableMatchType IS ARRAY (X01, VitalTruthSymbolType) OF BOOLEAN;
223    -- checks if an input matches th corresponding truth table symbol
224    -- use: TruthTableMatch(input_converted_to_X01, truth_table_stimulus_symbol)
225    CONSTANT TruthTableMatch : TruthTableMatchType  :=  (
226       -- X,     0,     1,     -      B      Z
227       (  TRUE,  FALSE, FALSE, TRUE,  FALSE, FALSE  ),  -- X
228       (  FALSE, TRUE,  FALSE, TRUE,  TRUE,  FALSE  ),  -- 0
229       (  FALSE, FALSE, TRUE,  TRUE,  TRUE,  FALSE  )   -- 1
230    );
231
232    -- ------------------------------------------------------------------------
233    TYPE ValidStateTableInputType IS ARRAY (VitalStateSymbolType) OF BOOLEAN;
234    CONSTANT ValidStateTableInput : ValidStateTableInputType :=
235       -- '/',   '\',   'P',   'N',   'r',   'f',
236      (   TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,
237       -- 'p',   'n',   'R',   'F',   '^',   'v',
238          TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,
239       -- 'E',   'A',    'D',  '*',
240          TRUE,  TRUE,  TRUE,  TRUE,
241       -- 'X',   '0',   '1',   '-',   'B',   'Z',
242          TRUE,  TRUE,  TRUE,  TRUE,  TRUE, FALSE,
243       -- 'S'
244          TRUE );
245
246    CONSTANT ValidStateTableState : ValidStateTableInputType :=
247       -- '/',   '\',   'P',   'N',   'r',   'f',
248      (   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
249       -- 'p',   'n',   'R',   'F',   '^',   'v',
250          FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
251       -- 'E',   'A',    'D',  '*',
252          FALSE, FALSE, FALSE, FALSE,
253       -- 'X',   '0',   '1',   '-',   'B',   'Z',
254          TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  FALSE,
255       -- 'S'
256          FALSE );
257
258    TYPE StateTableMatchType IS ARRAY (X01,X01,VitalStateSymbolType) OF BOOLEAN;
259    -- last value, present value, table symbol
260    CONSTANT StateTableMatch : StateTableMatchType :=  (
261      ( -- X (lastvalue)
262     -- /     \     P     N     r     f
263     -- p     n     R     F     ^     v
264     -- E     A     D     *
265     -- X     0     1     -     B     Z     S
266      (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
267       FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
268       FALSE,FALSE,FALSE,FALSE,
269       TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE),
270      (FALSE,FALSE,FALSE,TRUE, FALSE,FALSE,
271       FALSE,FALSE,FALSE,TRUE, FALSE,TRUE,
272       TRUE, FALSE,TRUE, TRUE,
273       FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE),
274      (FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,
275       FALSE,FALSE,TRUE, FALSE,TRUE, FALSE,
276       TRUE, TRUE, FALSE,TRUE,
277       FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE)
278      ),
279
280      (-- 0 (lastvalue)
281     -- /     \     P     N     r     f
282     -- p     n     R     F     ^     v
283     -- E     A     D     *
284     -- X     0     1     -     B     Z     S
285      (FALSE,FALSE,FALSE,FALSE,TRUE, FALSE,
286       TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
287       FALSE,TRUE, FALSE,TRUE,
288       TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE),
289      (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
290       FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
291       FALSE,FALSE,FALSE,FALSE,
292       FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,TRUE ),
293      (TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
294       TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
295       FALSE,FALSE,FALSE,TRUE,
296       FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE)
297      ),
298
299      (-- 1 (lastvalue)
300     -- /     \     P     N     r     f
301     -- p     n     R     F     ^     v
302     -- E     A     D     *
303     -- X     0     1     -     B     Z     S
304      (FALSE,FALSE,FALSE,FALSE,FALSE,TRUE ,
305       FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
306       FALSE,FALSE,TRUE, TRUE,
307       TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE),
308      (FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
309       FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
310       FALSE,FALSE,FALSE,TRUE,
311       FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE),
312      (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
313       FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
314       FALSE,FALSE,FALSE,FALSE,
315       FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,TRUE )
316      )
317      );
318
319    TYPE Logic_UX01Z_Table IS ARRAY (std_ulogic) OF UX01Z;
320    ----------------------------------------------------------
321    -- table name : cvt_to_x01z
322    -- parameters :  std_ulogic  -- some logic value
323    -- returns    :  UX01Z       -- state value of logic value
324    -- purpose    :  to convert state-strength to state only
325    ----------------------------------------------------------
326    CONSTANT cvt_to_ux01z : Logic_UX01Z_Table :=
327                                ('U','X','0','1','Z','X','0','1','X' );
328
329    TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER;
330    CONSTANT LogicCvtTable : LogicCvtTableType
331                     := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
332
333    --------------------------------------------------------------------
334    -- LOCAL Utilities
335    --------------------------------------------------------------------
336    -- ------------------------------------------------------------------------
337    --  FUNCTION  NAME  :  MINIMUM
338    --
339    --  PARAMETERS      :  in1, in2  - integer, time
340    --
341    --  DESCRIPTION     :  return smaller of in1 and in2
342    -- ------------------------------------------------------------------------
343    FUNCTION Minimum (
344            CONSTANT in1, in2 : INTEGER
345          ) RETURN INTEGER IS
346    BEGIN
347       IF (in1 < in2) THEN
348          RETURN in1;
349       END IF;
350       RETURN in2;
351    END;
352    -- ------------------------------------------------------------------------
353    FUNCTION Minimum (
354            CONSTANT t1,t2 : IN TIME
355          ) RETURN TIME IS
356    BEGIN
357        IF ( t1 < t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
358    END Minimum;
359
360    -- ------------------------------------------------------------------------
361    --  FUNCTION  NAME  :  MAXIMUM
362    --
363    --  PARAMETERS      :  in1, in2  - integer, time
364    --
365    --  DESCRIPTION     :  return larger of in1 and in2
366    -- ------------------------------------------------------------------------
367    FUNCTION Maximum (
368            CONSTANT in1, in2 : INTEGER
369          ) RETURN INTEGER IS
370    BEGIN
371       IF (in1 > in2) THEN
372          RETURN in1;
373       END IF;
374       RETURN in2;
375    END;
376    -----------------------------------------------------------------------
377    FUNCTION Maximum (
378            CONSTANT t1,t2 : IN TIME
379          ) RETURN TIME IS
380    BEGIN
381        IF ( t1 > t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
382    END Maximum;
383
384    -----------------------------------------------------------------------
385    FUNCTION GlitchMinTime (
386            CONSTANT Time1, Time2 : IN TIME
387          ) RETURN TIME IS
388    BEGIN
389        IF ( Time1 >= NOW ) THEN
390                IF ( Time2 >= NOW ) THEN
391                  RETURN Minimum ( Time1, Time2);
392                ELSE
393                  RETURN Time1;
394                END IF;
395        ELSE
396                IF ( Time2 >= NOW ) THEN
397                   RETURN Time2;
398                ELSE
399                   RETURN 0 ns;
400                END IF;
401        END IF;
402    END;
403
404    --------------------------------------------------------------------
405    -- Error Message Types and Tables
406    --------------------------------------------------------------------
407    TYPE VitalErrorType IS (
408        ErrNegDel,
409        ErrInpSym,
410        ErrOutSym,
411        ErrStaSym,
412        ErrVctLng,
413        ErrTabWidSml,
414        ErrTabWidLrg,
415        ErrTabResSml,
416        ErrTabResLrg
417    );
418
419    TYPE VitalErrorSeverityType IS ARRAY (VitalErrorType) OF SEVERITY_LEVEL;
420    CONSTANT VitalErrorSeverity : VitalErrorSeverityType := (
421        ErrNegDel    => WARNING,
422        ErrInpSym    => ERROR,
423        ErrOutSym    => ERROR,
424        ErrStaSym    => ERROR,
425        ErrVctLng    => ERROR,
426        ErrTabWidSml => ERROR,
427        ErrTabWidLrg => WARNING,
428        ErrTabResSml => WARNING,
429        ErrTabResLrg => WARNING
430    );
431
432    CONSTANT MsgNegDel : STRING :=
433      "Negative delay. New output value not scheduled. Output signal is: ";
434    CONSTANT MsgInpSym : STRING :=
435      "Illegal symbol in the input portion of a Truth/State table.";
436    CONSTANT MsgOutSym : STRING :=
437      "Illegal symbol in the output portion of a Truth/State table.";
438    CONSTANT MsgStaSym : STRING :=
439      "Illegal symbol in the state portion of a State table.";
440    CONSTANT MsgVctLng : STRING :=
441      "Vector (array) lengths not equal. ";
442    CONSTANT MsgTabWidSml : STRING :=
443      "Width of the Truth/State table is too small.";
444    CONSTANT MsgTabWidLrg : STRING :=
445      "Width of Truth/State table is too large. Extra elements are ignored.";
446    CONSTANT MsgTabResSml : STRING :=
447      "Result of Truth/State table has too many elements.";
448    CONSTANT MsgTabResLrg : STRING :=
449      "Result of Truth/State table has too few elements.";
450
451    CONSTANT MsgUnknown : STRING :=
452      "Unknown error message.";
453
454    --------------------------------------------------------------------
455    -- LOCAL Utilities
456    --------------------------------------------------------------------
457    FUNCTION VitalMessage (
458            CONSTANT ErrorId : IN VitalErrorType
459          ) RETURN STRING IS
460    BEGIN
461        CASE ErrorId IS
462            WHEN ErrNegDel    => RETURN MsgNegDel;
463            WHEN ErrInpSym    => RETURN MsgInpSym;
464            WHEN ErrOutSym    => RETURN MsgOutSym;
465            WHEN ErrStaSym    => RETURN MsgStaSym;
466            WHEN ErrVctLng    => RETURN MsgVctLng;
467            WHEN ErrTabWidSml => RETURN MsgTabWidSml;
468            WHEN ErrTabWidLrg => RETURN MsgTabWidLrg;
469            WHEN ErrTabResSml => RETURN MsgTabResSml;
470            WHEN ErrTabResLrg => RETURN MsgTabResLrg;
471            WHEN OTHERS       => RETURN MsgUnknown;
472        END CASE;
473    END;
474
475    PROCEDURE VitalError (
476            CONSTANT Routine : IN STRING;
477            CONSTANT ErrorId : IN VitalErrorType
478    ) IS
479    BEGIN
480        ASSERT FALSE
481          REPORT Routine & ": " & VitalMessage(ErrorId)
482          SEVERITY VitalErrorSeverity(ErrorId);
483    END;
484
485    PROCEDURE VitalError (
486            CONSTANT Routine : IN STRING;
487            CONSTANT ErrorId : IN VitalErrorType;
488            CONSTANT Info    : IN STRING
489    ) IS
490    BEGIN
491        ASSERT FALSE
492          REPORT Routine & ": " & VitalMessage(ErrorId) & Info
493          SEVERITY VitalErrorSeverity(ErrorId);
494    END;
495
496    PROCEDURE VitalError (
497            CONSTANT Routine : IN STRING;
498            CONSTANT ErrorId : IN VitalErrorType;
499            CONSTANT Info    : IN CHARACTER
500    ) IS
501    BEGIN
502        ASSERT FALSE
503          REPORT Routine & ": " & VitalMessage(ErrorId) & Info
504          SEVERITY VitalErrorSeverity(ErrorId);
505    END;
506
507    ---------------------------------------------------------------------------
508    PROCEDURE ReportGlitch (
509            CONSTANT GlitchRoutine  : IN  STRING;
510            CONSTANT OutSignalName  : IN  STRING;
511            CONSTANT PreemptedTime  : IN  TIME;
512            CONSTANT PreemptedValue : IN  std_ulogic;
513            CONSTANT NewTime        : IN  TIME;
514            CONSTANT NewValue       : IN  std_ulogic;
515            CONSTANT Index          : IN  INTEGER := 0;
516            CONSTANT IsArraySignal  : IN  BOOLEAN := FALSE;
517            CONSTANT MsgSeverity    : IN  SEVERITY_LEVEL := WARNING
518    ) IS
519
520        VARIABLE StrPtr1, StrPtr2, StrPtr3, StrPtr4, StrPtr5 : LINE;
521    BEGIN
522
523        Write (StrPtr1, PreemptedTime );
524        Write (StrPtr2, NewTime);
525        Write (StrPtr3, LogicCvtTable(PreemptedValue));
526        Write (StrPtr4, LogicCvtTable(NewValue));
527        IF IsArraySignal THEN
528            Write (StrPtr5, STRING'( "(" ) );
529            Write (StrPtr5, Index);
530            Write (StrPtr5, STRING'( ")" ) );
531        ELSE
532            Write (StrPtr5, STRING'( " " ) );
533        END IF;
534
535        -- Issue Report only if Preemted value has not been
536        --  removed from event queue
537        ASSERT PreemptedTime >  NewTime
538          REPORT GlitchRoutine & ": GLITCH Detected on port " &
539                 OutSignalName & StrPtr5.ALL &
540                 "; Preempted Future Value := " & StrPtr3.ALL &
541                 " @ " & StrPtr1.ALL &
542                 "; Newly Scheduled Value := " & StrPtr4.ALL &
543                 " @ " & StrPtr2.ALL &
544                 ";"
545          SEVERITY MsgSeverity;
546
547        DEALLOCATE(StrPtr1);
548        DEALLOCATE(StrPtr2);
549        DEALLOCATE(StrPtr3);
550        DEALLOCATE(StrPtr4);
551        DEALLOCATE(StrPtr5);
552        RETURN;
553    END ReportGlitch;
554
555    ---------------------------------------------------------------------------
556    -- Procedure  : VitalGlitchOnEvent
557    --            :
558    -- Parameters : OutSignal ........ signal being driven
559    --            : OutSignalName..... name of the driven signal
560    --            : GlitchData........ internal data required by the procedure
561    --            : NewValue.......... new value being assigned
562    --            : NewDelay.......... Delay accompanying the assignment
563    --            :                    (Note: for vectors, this is an array)
564    --            : GlitchMode........ Glitch generation mode
565    --            :                     MessagePlusX, MessageOnly,
566    --            :                     XOnly, NoGlitch )
567    --            : GlitchDelay....... if <= 0 ns , then there will be no Glitch
568    --            :                    if >  NewDelay, then there is no Glitch,
569    --            :                    otherwise, this is the time when a FORCED
570    --            :                    generation of a glitch will occur.
571    ----------------------------------------------------------------------------
572    PROCEDURE VitalGlitchOnEvent (
573            SIGNAL   OutSignal        : OUT   std_logic;
574            CONSTANT OutSignalName    : IN    STRING;
575            VARIABLE GlitchData       : INOUT GlitchDataType;
576            CONSTANT NewValue         : IN    std_logic;
577            CONSTANT NewDelay         : IN    TIME := 0 ns;
578            CONSTANT GlitchMode       : IN    VitalGlitchModeType := MessagePlusX;
579            CONSTANT GlitchDelay      : IN    TIME := -1 ns;  -- IR#223
580            CONSTANT MsgSeverity      : IN    SEVERITY_LEVEL := WARNING
581    ) IS
582    -- ------------------------------------------------------------------------
583        VARIABLE NoGlitchDet  : BOOLEAN := FALSE;
584        VARIABLE OldGlitch    : BOOLEAN := FALSE;
585        VARIABLE Dly          : TIME    := NewDelay;
586
587    BEGIN
588        -- If nothing to schedule, just return
589        IF NewDelay < 0 ns THEN
590            IF (NewValue /= GlitchData.SchedValue) THEN
591                VitalError ( "VitalGlitchOnEvent", ErrNegDel, OutSignalName );
592            END IF;
593
594        ELSE
595            -- If nothing currently scheduled
596            IF GlitchData.SchedTime <= NOW THEN
597                GlitchData.CurrentValue := GlitchData.SchedValue;
598                IF (GlitchDelay <= 0 ns) THEN
599                    IF (NewValue = GlitchData.SchedValue) THEN RETURN; END IF;
600                    NoGlitchDet := TRUE;
601                END IF;
602
603            -- Transaction currently scheduled - if glitch already happened
604            ELSIF GlitchData.GlitchTime <= NOW THEN
605                GlitchData.CurrentValue := 'X';
606                OldGlitch := TRUE;
607                IF (GlitchData.SchedValue = NewValue) THEN
608                    dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
609                END IF;
610
611            -- Transaction currently scheduled (no glitch if same value)
612            ELSIF (GlitchData.SchedValue = NewValue) AND
613                  (GlitchData.SchedTime = GlitchData.GlitchTime) AND
614                  (GlitchDelay <= 0 ns) THEN
615                NoGlitchDet := TRUE;
616                Dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
617
618            END IF;
619
620            GlitchData.SchedTime := NOW+Dly;
621            IF OldGlitch THEN
622                OutSignal <= NewValue AFTER Dly;
623
624            ELSIF NoGlitchDet THEN
625                GlitchData.GlitchTime := NOW+Dly;
626                OutSignal <= NewValue AFTER Dly;
627
628            ELSE -- new glitch
629                GlitchData.GlitchTime := GlitchMinTime ( GlitchData.GlitchTime,
630                                                         NOW+GlitchDelay );
631
632                IF (GlitchMode = MessagePlusX) OR
633                   (GlitchMode = MessageOnly) THEN
634                    ReportGlitch ( "VitalGlitchOnEvent", OutSignalName,
635                                   GlitchData.GlitchTime, GlitchData.SchedValue,
636                                   (Dly + NOW), NewValue,
637                                   MsgSeverity=>MsgSeverity );
638                END IF;
639
640                IF (GlitchMode = MessagePlusX) OR (GlitchMode = XOnly) THEN
641                    OutSignal <= 'X' AFTER GlitchData.GlitchTime-NOW;
642                    OutSignal <=  TRANSPORT NewValue AFTER Dly;
643                ELSE
644                    OutSignal <= NewValue AFTER Dly;
645                END IF;
646            END IF;
647
648            GlitchData.SchedValue := NewValue;
649        END IF;
650
651        RETURN;
652    END;
653
654    ----------------------------------------------------------------------------
655    PROCEDURE VitalGlitchOnEvent (
656            SIGNAL   OutSignal        : OUT   std_logic_vector;
657            CONSTANT OutSignalName    : IN    STRING;
658            VARIABLE GlitchData       : INOUT GlitchDataArrayType;
659            CONSTANT NewValue         : IN    std_logic_vector;
660            CONSTANT NewDelay         : IN    VitalTimeArray;
661            CONSTANT GlitchMode       : IN    VitalGlitchModeType := MessagePlusX;
662            CONSTANT GlitchDelay      : IN    VitalTimeArray;
663            CONSTANT MsgSeverity      : IN    SEVERITY_LEVEL := WARNING
664    ) IS
665
666        ALIAS GlDataAlias  : GlitchDataArrayType(1 TO GlitchData'LENGTH)
667                                 IS GlitchData;
668        ALIAS NewValAlias  : std_logic_vector(1 TO NewValue'LENGTH) IS NewValue;
669        ALIAS GlDelayAlias : VitalTimeArray(1 TO GlitchDelay'LENGTH)
670              IS GlitchDelay;
671        ALIAS NewDelAlias  : VitalTimeArray(1 TO NewDelay'LENGTH) IS NewDelay;
672
673        VARIABLE Index       : INTEGER := OutSignal'LEFT;
674        VARIABLE Direction   : INTEGER;
675        VARIABLE NoGlitchDet : BOOLEAN;
676        VARIABLE OldGlitch   : BOOLEAN;
677        VARIABLE Dly, GlDly  : TIME;
678
679    BEGIN
680        IF (OutSignal'LEFT > OutSignal'RIGHT) THEN
681            Direction := -1;
682        ELSE
683            Direction := 1;
684        END IF;
685
686        IF ( (OutSignal'LENGTH /=  GlitchData'LENGTH) OR
687             (OutSignal'LENGTH /=    NewValue'LENGTH) OR
688             (OutSignal'LENGTH /=    NewDelay'LENGTH) OR
689             (OutSignal'LENGTH /= GlitchDelay'LENGTH) ) THEN
690          VitalError ( "VitalGlitchOnEvent", ErrVctLng, OutSignalName );
691          RETURN;
692        END IF;
693
694        -- a call to the scalar function cannot be made since the actual
695        -- name associated with a signal parameter must be locally static
696      FOR n IN 1 TO OutSignal'LENGTH LOOP
697
698        NoGlitchDet := FALSE;
699        OldGlitch   := FALSE;
700        Dly := NewDelAlias(n);
701
702        -- If nothing to schedule, just skip to next loop iteration
703        IF NewDelAlias(n) < 0 ns THEN
704            IF (NewValAlias(n) /=  GlDataAlias(n).SchedValue) THEN
705                VitalError ( "VitalGlitchOnEvent", ErrNegDel, OutSignalName );
706            END IF;
707        ELSE
708            -- If nothing currently scheduled (i.e. last scheduled
709            -- transaction already occurred)
710            IF GlDataAlias(n).SchedTime <= NOW THEN
711                GlDataAlias(n).CurrentValue := GlDataAlias(n).SchedValue;
712                IF (GlDelayAlias(n) <= 0 ns) THEN
713                    -- Next iteration if no change in value
714                    IF (NewValAlias(n) = GlDataAlias(n).SchedValue) THEN
715                        Index := Index + Direction;
716                        NEXT;
717                    END IF;
718                    -- since last transaction already occurred there is no glitch
719                    NoGlitchDet := TRUE;
720                END IF;
721
722            -- Transaction currently scheduled - if glitch already happened
723            ELSIF GlDataAlias(n).GlitchTime <= NOW THEN
724                GlDataAlias(n).CurrentValue := 'X';
725                OldGlitch := TRUE;
726                IF (GlDataAlias(n).SchedValue = NewValAlias(n)) THEN
727                    dly := Minimum( GlDataAlias(n).SchedTime-NOW,
728                                    NewDelAlias(n) );
729                END IF;
730
731            -- Transaction currently scheduled
732            ELSIF (GlDataAlias(n).SchedValue = NewValAlias(n)) AND
733                  (GlDataAlias(n).SchedTime = GlDataAlias(n).GlitchTime) AND
734                  (GlDelayAlias(n) <= 0 ns) THEN
735                  NoGlitchDet := TRUE;
736                  Dly := Minimum( GlDataAlias(n).SchedTime-NOW,
737                                  NewDelAlias(n) );
738            END IF;
739
740            -- update last scheduled transaction
741            GlDataAlias(n).SchedTime := NOW+Dly;
742
743            IF OldGlitch THEN
744                OutSignal(Index) <= NewValAlias(n) AFTER Dly;
745            ELSIF NoGlitchDet THEN
746                -- if no glitch then update last glitch time
747                -- and OutSignal(actual_index)
748                GlDataAlias(n).GlitchTime := NOW+Dly;
749                OutSignal(Index) <= NewValAlias(n) AFTER Dly;
750            ELSE   -- new glitch
751                GlDataAlias(n).GlitchTime := GlitchMinTime (
752                                                  GlDataAlias(n).GlitchTime,
753                                                  NOW+GlDelayAlias(n) );
754
755                IF (GlitchMode = MessagePlusX) OR
756                   (GlitchMode = MessageOnly) THEN
757                    ReportGlitch ( "VitalGlitchOnEvent", OutSignalName,
758                                   GlDataAlias(n).GlitchTime,
759                                   GlDataAlias(n).SchedValue,
760                                   (Dly + NOW), NewValAlias(n),
761                                   Index, TRUE, MsgSeverity );
762                END IF;
763
764                IF (GlitchMode = MessagePlusX) OR (GlitchMode = XOnly) THEN
765                    GlDly := GlDataAlias(n).GlitchTime - NOW;
766                    OutSignal(Index) <= 'X' AFTER GlDly;
767                    OutSignal(Index) <= TRANSPORT NewValAlias(n) AFTER Dly;
768                ELSE
769                    OutSignal(Index) <= NewValAlias(n) AFTER Dly;
770                END IF;
771
772            END IF; -- glitch / no-glitch
773            GlDataAlias(n).SchedValue := NewValAlias(n);
774
775        END IF; -- NewDelAlias(n) < 0 ns
776        Index := Index + Direction;
777      END LOOP;
778
779        RETURN;
780    END;
781
782    ---------------------------------------------------------------------------
783    -- ------------------------------------------------------------------------
784    --  PROCEDURE NAME  :  TruthOutputX01Z
785    --
786    --  PARAMETERS      :  table_out - output of table
787    --                     X01Zout   - output converted to X01Z
788    --                     err       - true if illegal character is encountered
789    --
790    --
791    --  DESCRIPTION     :  converts the output of a truth table to a valid
792    --                     std_ulogic
793    -- ------------------------------------------------------------------------
794    PROCEDURE TruthOutputX01Z (
795            CONSTANT TableOut : IN VitalTruthSymbolType;
796            VARIABLE X01Zout   : OUT std_ulogic;
797            VARIABLE Err       : OUT BOOLEAN
798    ) IS
799        VARIABLE TempOut : std_ulogic;
800    BEGIN
801        Err := FALSE;
802        TempOut := TruthTableOutMap(TableOut);
803        IF (TempOut = '-') THEN
804            Err := TRUE;
805            TempOut := 'X';
806            VitalError ( "VitalTruthTable", ErrOutSym, To_TruthChar(TableOut));
807        END IF;
808        X01Zout := TempOut;
809    END;
810
811    -- ------------------------------------------------------------------------
812    --  PROCEDURE NAME  :  StateOutputX01Z
813    --
814    --  PARAMETERS      :  table_out - output of table
815    --                     prev_out  - previous output value
816    --                     X01Zout   - output cojnverted to X01Z
817    --                     err       - true if illegal character is encountered
818    --
819    --  DESCRIPTION     :  converts the output of a state table to a
820    --                     valid std_ulogic
821    -- ------------------------------------------------------------------------
822    PROCEDURE StateOutputX01Z (
823            CONSTANT TableOut : IN VitalStateSymbolType;
824            CONSTANT PrevOut  : IN std_ulogic;
825            VARIABLE X01Zout   : OUT std_ulogic;
826            VARIABLE Err       : OUT BOOLEAN
827    ) IS
828        VARIABLE TempOut : std_ulogic;
829    BEGIN
830        Err := FALSE;
831        TempOut := StateTableOutMap(TableOut);
832        IF (TempOut = '-') THEN
833            Err := TRUE;
834            TempOut := 'X';
835            VitalError ( "VitalStateTable", ErrOutSym, To_StateChar(TableOut));
836        ELSIF (TempOut = 'W') THEN
837            TempOut := To_X01Z(PrevOut);
838        END IF;
839        X01Zout := TempOut;
840    END;
841
842    -- ------------------------------------------------------------------------
843    -- PROCEDURE NAME:  StateMatch
844    --
845    -- PARAMETERS    :  symbol       - symbol from state table
846    --                  in2          - input from VitalStateTble procedure
847    --                                 to state table
848    --                  in2LastValue - previous value of input
849    --                  state        - false if the symbol is from the input
850    --                                  portion of the table,
851    --                                 true if the symbol is from the state
852    --                                  portion of the table
853    --                  Err          - true if symbol is not a valid input symbol
854    --                  ReturnValue  - true if match occurred
855    --
856    -- DESCRIPTION   :  This procedure sets ReturnValue to true if in2 matches
857    --                  symbol (from the state table).  If symbol is an edge
858    --                  value edge is set to true and in2 and in2LastValue are
859    --                  checked against symbol.  Err is set to true if symbol
860    --                  is an invalid value for the input portion of the state
861    --                  table.
862    --
863    -- ------------------------------------------------------------------------
864    PROCEDURE StateMatch (
865            CONSTANT Symbol       : IN VitalStateSymbolType;
866            CONSTANT in2          : IN std_ulogic;
867            CONSTANT in2LastValue : IN std_ulogic;
868            CONSTANT State        : IN BOOLEAN;
869            VARIABLE Err          : OUT BOOLEAN;
870            VARIABLE ReturnValue  : OUT BOOLEAN
871    ) IS
872    BEGIN
873        IF (State) THEN
874            IF (NOT ValidStateTableState(Symbol)) THEN
875                VitalError ( "VitalStateTable", ErrStaSym, To_StateChar(Symbol));
876                Err := TRUE;
877                ReturnValue := FALSE;
878            ELSE
879                Err := FALSE;
880                ReturnValue := StateTableMatch(in2LastValue, in2, Symbol);
881            END IF;
882        ELSE
883            IF (NOT ValidStateTableInput(Symbol) ) THEN
884                VitalError ( "VitalStateTable", ErrInpSym, To_StateChar(Symbol));
885                Err := TRUE;
886                ReturnValue := FALSE;
887            ELSE
888                ReturnValue := StateTableMatch(in2LastValue, in2, Symbol);
889                Err := FALSE;
890            END IF;
891        END IF;
892    END;
893
894    -- -----------------------------------------------------------------------
895    -- FUNCTION NAME:  StateTableLookUp
896    --
897    -- PARAMETERS   :  StateTable     - state table
898    --                 PresentDataIn  - current inputs
899    --                 PreviousDataIn - previous inputs and states
900    --                 NumStates      - number of state variables
901    --                 PresentOutputs - current state and current outputs
902    --
903    -- DESCRIPTION  :  This function is used to find the output of the
904    --                 StateTable corresponding to a given set of inputs.
905    --
906    -- ------------------------------------------------------------------------
907    FUNCTION StateTableLookUp (
908            CONSTANT StateTable     : VitalStateTableType;
909            CONSTANT PresentDataIn  : std_logic_vector;
910            CONSTANT PreviousDataIn : std_logic_vector;
911            CONSTANT NumStates      : NATURAL;
912            CONSTANT PresentOutputs : std_logic_vector
913          ) RETURN std_logic_vector IS
914
915        CONSTANT InputSize    : INTEGER := PresentDataIn'LENGTH;
916        CONSTANT NumInputs    : INTEGER := InputSize + NumStates - 1;
917        CONSTANT TableEntries : INTEGER := StateTable'LENGTH(1);
918        CONSTANT TableWidth   : INTEGER := StateTable'LENGTH(2);
919        CONSTANT OutSize      : INTEGER := TableWidth - InputSize - NumStates;
920        VARIABLE Inputs       : std_logic_vector(0 TO NumInputs);
921        VARIABLE PrevInputs   : std_logic_vector(0 TO NumInputs)
922                                := (OTHERS => 'X');
923        VARIABLE ReturnValue  : std_logic_vector(0 TO (OutSize-1))
924                                := (OTHERS => 'X');
925        VARIABLE Temp   : std_ulogic;
926        VARIABLE Match  : BOOLEAN;
927        VARIABLE Err    : BOOLEAN := FALSE;
928
929        -- This needs to be done since the TableLookup arrays must be
930        -- ascending starting with 0
931        VARIABLE TableAlias   : VitalStateTableType(0 TO TableEntries - 1,
932                                                    0 TO TableWidth - 1)
933                                := StateTable;
934
935    BEGIN
936        Inputs(0 TO InputSize-1) := PresentDataIn;
937        Inputs(InputSize TO NumInputs) := PresentOutputs(0 TO NumStates - 1);
938        PrevInputs(0 TO InputSize - 1) := PreviousDataIn(0 TO InputSize - 1);
939
940      ColLoop: -- Compare each entry in the table
941        FOR i IN TableAlias'RANGE(1) LOOP
942
943        RowLoop: -- Check each element of the entry
944          FOR j IN 0 TO InputSize + NumStates  LOOP
945
946            IF (j = InputSize + NumStates) THEN        -- a match occurred
947                FOR k IN 0 TO Minimum(OutSize, PresentOutputs'LENGTH)-1  LOOP
948                    StateOutputX01Z (
949                            TableAlias(i, TableWidth - k - 1),
950                            PresentOutputs(PresentOutputs'LENGTH - k - 1),
951                            Temp, Err);
952                    ReturnValue(OutSize - k - 1) := Temp;
953                    IF (Err) THEN
954                        ReturnValue := (OTHERS => 'X');
955                        RETURN ReturnValue;
956                    END IF;
957                END LOOP;
958                RETURN ReturnValue;
959            END IF;
960
961            StateMatch ( TableAlias(i,j),
962                         Inputs(j), PrevInputs(j),
963                         j >= InputSize, Err, Match);
964            EXIT RowLoop WHEN NOT(Match);
965            EXIT ColLoop WHEN Err;
966          END LOOP RowLoop;
967        END LOOP ColLoop;
968
969        ReturnValue := (OTHERS => 'X');
970        RETURN ReturnValue;
971    END;
972
973    --------------------------------------------------------------------
974    -- to_ux01z
975    -------------------------------------------------------------------
976    FUNCTION To_UX01Z  ( s : std_ulogic
977          ) RETURN  UX01Z IS
978    BEGIN
979        RETURN cvt_to_ux01z (s);
980    END;
981
982    ---------------------------------------------------------------------------
983    -- Function  : GetEdge
984    -- Purpose   : Converts transitions on a given input signal into a
985    --             enumeration value representing the transition or level
986    --             of the signal.
987    --
988    --    previous "value"   current "value"     :=   "edge"
989    --   ---------------------------------------------------------
990    --     '1' | 'H'          '1' | 'H'                 '1'    level, no edge
991    --     '0' | 'L'          '1' | 'H'                 '/'    rising edge
992    --      others            '1' | 'H'                 'R'    rising from X
993    --
994    --     '1' | 'H'          '0' | 'L'                 '\'    falling egde
995    --     '0' | 'L'          '0' | 'L'                 '0'    level, no edge
996    --      others            '0' | 'L'                 'F'    falling from X
997    --
998    --     'X' | 'W' | '-'    'X' | 'W' | '-'           'X'    unknown (X) level
999    --     'Z'                'Z'                       'X'    unknown (X) level
1000    --     'U'                'U'                       'U'    'U' level
1001    --
1002    --     '1' | 'H'           others                   'f'    falling to X
1003    --     '0' | 'L'           others                   'r'    rising to X
1004    --     'X' | 'W' | '-'    'U' | 'Z'                 'x'    unknown (X) edge
1005    --     'Z'                'X' | 'W' | '-' | 'U'     'x'    unknown (X) edge
1006    --     'U'                'X' | 'W' | '-' | 'Z'     'x'    unknown (X) edge
1007    --
1008    ---------------------------------------------------------------------------
1009    FUNCTION GetEdge (
1010            SIGNAL      s : IN    std_logic
1011          ) RETURN EdgeType IS
1012    BEGIN
1013        IF (s'EVENT)
1014            THEN RETURN LogicToEdge  ( s'LAST_VALUE, s );
1015            ELSE RETURN LogicToLevel ( s );
1016        END IF;
1017    END;
1018
1019    ---------------------------------------------------------------------------
1020    PROCEDURE GetEdge (
1021            SIGNAL       s : IN    std_logic_vector;
1022            VARIABLE LastS : INOUT std_logic_vector;
1023            VARIABLE  Edge :   OUT EdgeArray ) IS
1024
1025        ALIAS     sAlias : std_logic_vector ( 1 TO     s'LENGTH ) IS s;
1026        ALIAS LastSAlias : std_logic_vector ( 1 TO LastS'LENGTH ) IS LastS;
1027        ALIAS  EdgeAlias : EdgeArray ( 1 TO  Edge'LENGTH ) IS Edge;
1028    BEGIN
1029        IF s'LENGTH /= LastS'LENGTH OR
1030           s'LENGTH /=  Edge'LENGTH THEN
1031            VitalError ( "GetEdge", ErrVctLng, "s, LastS, Edge" );
1032        END IF;
1033
1034        FOR n IN 1 TO s'LENGTH LOOP
1035            EdgeAlias(n)  := LogicToEdge( LastSAlias(n), sAlias(n) );
1036            LastSAlias(n) := sAlias(n);
1037        END LOOP;
1038    END;
1039
1040    ---------------------------------------------------------------------------
1041    FUNCTION  ToEdge     ( Value         : IN std_logic
1042          ) RETURN EdgeType IS
1043    BEGIN
1044        RETURN LogicToLevel( Value );
1045    END;
1046
1047    -- Note: This function will likely be replaced by S'DRIVING_VALUE in VHDL'92
1048    ----------------------------------------------------------------------------
1049    IMPURE FUNCTION CurValue (
1050            CONSTANT GlitchData : IN  GlitchDataType
1051          ) RETURN std_logic IS
1052    BEGIN
1053        IF NOW >= GlitchData.SchedTime THEN
1054            RETURN GlitchData.SchedValue;
1055        ELSIF NOW >= GlitchData.GlitchTime THEN
1056            RETURN 'X';
1057        ELSE
1058            RETURN GlitchData.CurrentValue;
1059        END IF;
1060    END;
1061    ---------------------------------------------------------------------------
1062    IMPURE FUNCTION CurValue (
1063            CONSTANT GlitchData : IN  GlitchDataArrayType
1064          ) RETURN std_logic_vector IS
1065        VARIABLE Result : std_logic_vector(GlitchData'RANGE);
1066    BEGIN
1067        FOR n IN GlitchData'RANGE LOOP
1068            IF NOW >= GlitchData(n).SchedTime THEN
1069                Result(n) := GlitchData(n).SchedValue;
1070            ELSIF NOW >= GlitchData(n).GlitchTime THEN
1071                Result(n) := 'X';
1072            ELSE
1073                Result(n) := GlitchData(n).CurrentValue;
1074            END IF;
1075        END LOOP;
1076        RETURN Result;
1077    END;
1078
1079    ---------------------------------------------------------------------------
1080    -- function calculation utilities
1081    ---------------------------------------------------------------------------
1082
1083    ---------------------------------------------------------------------------
1084    -- Function   : VitalSame
1085    -- Returns    : VitalSame compares the state (UX01) of two logic value. A
1086    --              value of 'X' is returned if the values are different.  The
1087    --              common value is returned if the values are equal.
1088    -- Purpose    : When the result of a logic model may be either of two
1089    --              separate input values (eg. when the select on a MUX is 'X'),
1090    --              VitalSame may be used to determine if the result needs to
1091    --              be 'X'.
1092    -- Arguments  : See the declarations below...
1093    ---------------------------------------------------------------------------
1094    FUNCTION VitalSame (
1095            CONSTANT a, b : IN std_ulogic
1096          ) RETURN std_ulogic IS
1097    BEGIN
1098        IF To_UX01(a) = To_UX01(b)
1099            THEN RETURN To_UX01(a);
1100            ELSE RETURN 'X';
1101        END IF;
1102    END;
1103
1104    ---------------------------------------------------------------------------
1105    -- delay selection utilities
1106    ---------------------------------------------------------------------------
1107
1108    ---------------------------------------------------------------------------
1109    -- Procedure  : BufPath, InvPath
1110    --
1111    -- Purpose    : BufPath and InvPath compute output change times, based on
1112    --              a change on an input port. The computed output change times
1113    --              returned in the composite parameter 'schd'.
1114    --
1115    --              BufPath and InpPath are used together with the delay path
1116    --              selection functions (GetSchedDelay, VitalAND, VitalOR... )
1117    --              The 'schd' value from each of the input ports of a model are
1118    --              combined by the delay selection functions (VitalAND,
1119    --              VitalOR, ...). The GetSchedDelay procedure converts the
1120    --              combined output changes times to the single delay (delta
1121    --              time) value for scheduling the output change (passed to
1122    --              VitalGlitchOnEvent).
1123    --
1124    --              The values in 'schd' are: (absolute times)
1125    --                inp0  :  time of output change due to input change to 0
1126    --                inp1  :  time of output change due to input change to 1
1127    --                inpX  :  time of output change due to input change to X
1128    --                glch0 :  time of output glitch due to input change to 0
1129    --                glch1 :  time of output glitch due to input change to 1
1130    --
1131    --              The output times are computed from the model INPUT value
1132    --              and not the final value.  For this reason, 'BufPath' should
1133    --              be used to compute the output times for a non-inverting
1134    --              delay paths and 'InvPath' should be used to compute the
1135    --              ouput times for inverting delay paths. Delay paths which
1136    --              include both non-inverting and paths require usage of both
1137    --              'BufPath' and 'InvPath'. (IE this is needed for the
1138    --              select->output path of a MUX -- See the VitalMUX model).
1139    --
1140    --
1141    -- Parameters : schd....... Computed output result times. (INOUT parameter
1142    --                          modified only on input edges)
1143    --              Iedg....... Input port edge/level value.
1144    --               tpd....... Propagation delays from this input
1145    --
1146    ---------------------------------------------------------------------------
1147
1148    PROCEDURE BufPath (
1149            VARIABLE Schd : INOUT SchedType;
1150            CONSTANT Iedg : IN    EdgeType;
1151            CONSTANT  tpd : IN    VitalDelayType01
1152    ) IS
1153    BEGIN
1154      CASE Iedg IS
1155        WHEN '0'|'1' => NULL;                   -- no edge: no timing update
1156        WHEN '/'|'R' => Schd.inp0 := TIME'HIGH;
1157                        Schd.inp1 := NOW + tpd(tr01);  Schd.Glch1 := Schd.inp1;
1158                        Schd.InpX := Schd.inp1;
1159        WHEN '\'|'F' => Schd.inp1 := TIME'HIGH;
1160                        Schd.inp0 := NOW + tpd(tr10);  Schd.Glch0 := Schd.inp0;
1161                        Schd.InpX := Schd.inp0;
1162        WHEN 'r'     => Schd.inp1 := TIME'HIGH;
1163                        Schd.inp0 := TIME'HIGH;
1164                        Schd.InpX := NOW + tpd(tr01);
1165        WHEN 'f'     => Schd.inp0 := TIME'HIGH;
1166                        Schd.inp1 := TIME'HIGH;
1167                        Schd.InpX := NOW + tpd(tr10);
1168        WHEN 'x'     => Schd.inp1 := TIME'HIGH;
1169                        Schd.inp0 := TIME'HIGH;
1170                        -- update for X->X change
1171                        Schd.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
1172        WHEN OTHERS  => NULL;                   -- no timing change
1173      END CASE;
1174    END;
1175
1176    PROCEDURE BufPath (
1177            VARIABLE Schd : INOUT SchedArray;
1178            CONSTANT Iedg : IN    EdgeArray;
1179            CONSTANT  tpd : IN    VitalDelayArrayType01
1180    ) IS
1181    BEGIN
1182      FOR n IN Schd'RANGE LOOP
1183        CASE Iedg(n) IS
1184          WHEN '0'|'1' => NULL;                   -- no edge: no timing update
1185          WHEN '/'|'R' => Schd(n).inp0 := TIME'HIGH;
1186                          Schd(n).inp1 := NOW + tpd(n)(tr01);
1187                          Schd(n).Glch1 := Schd(n).inp1;
1188                          Schd(n).InpX := Schd(n).inp1;
1189          WHEN '\'|'F' => Schd(n).inp1 := TIME'HIGH;
1190                          Schd(n).inp0 := NOW + tpd(n)(tr10);
1191                          Schd(n).Glch0 := Schd(n).inp0;
1192                          Schd(n).InpX := Schd(n).inp0;
1193          WHEN 'r'     => Schd(n).inp1 := TIME'HIGH;
1194                          Schd(n).inp0 := TIME'HIGH;
1195                          Schd(n).InpX := NOW + tpd(n)(tr01);
1196          WHEN 'f'     => Schd(n).inp0 := TIME'HIGH;
1197                          Schd(n).inp1 := TIME'HIGH;
1198                          Schd(n).InpX := NOW + tpd(n)(tr10);
1199          WHEN 'x'     => Schd(n).inp1 := TIME'HIGH;
1200                          Schd(n).inp0 := TIME'HIGH;
1201                          -- update for X->X change
1202                          Schd(n).InpX := NOW + Minimum ( tpd(n)(tr10),
1203                                                          tpd(n)(tr01) );
1204          WHEN OTHERS  => NULL;                   -- no timing change
1205        END CASE;
1206      END LOOP;
1207    END;
1208
1209    PROCEDURE InvPath (
1210            VARIABLE Schd : INOUT SchedType;
1211            CONSTANT Iedg : IN    EdgeType;
1212            CONSTANT  tpd : IN    VitalDelayType01
1213    ) IS
1214    BEGIN
1215      CASE Iedg IS
1216        WHEN '0'|'1' => NULL;                   -- no edge: no timing update
1217        WHEN '/'|'R' => Schd.inp0 := TIME'HIGH;
1218                        Schd.inp1 := NOW + tpd(tr10);  Schd.Glch1 := Schd.inp1;
1219                        Schd.InpX := Schd.inp1;
1220        WHEN '\'|'F' => Schd.inp1 := TIME'HIGH;
1221                        Schd.inp0 := NOW + tpd(tr01);  Schd.Glch0 := Schd.inp0;
1222                        Schd.InpX := Schd.inp0;
1223        WHEN 'r'     => Schd.inp1 := TIME'HIGH;
1224                        Schd.inp0 := TIME'HIGH;
1225                        Schd.InpX := NOW + tpd(tr10);
1226        WHEN 'f'     => Schd.inp0 := TIME'HIGH;
1227                        Schd.inp1 := TIME'HIGH;
1228                        Schd.InpX := NOW + tpd(tr01);
1229        WHEN 'x'     => Schd.inp1 := TIME'HIGH;
1230                        Schd.inp0 := TIME'HIGH;
1231                        -- update for X->X change
1232                        Schd.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
1233        WHEN OTHERS  => NULL;                   -- no timing change
1234      END CASE;
1235    END;
1236
1237    PROCEDURE InvPath (
1238            VARIABLE Schd : INOUT SchedArray;
1239            CONSTANT Iedg : IN    EdgeArray;
1240            CONSTANT  tpd : IN    VitalDelayArrayType01
1241    ) IS
1242    BEGIN
1243      FOR n IN Schd'RANGE LOOP
1244        CASE Iedg(n) IS
1245          WHEN '0'|'1' => NULL;                   -- no edge: no timing update
1246          WHEN '/'|'R' => Schd(n).inp0 := TIME'HIGH;
1247                          Schd(n).inp1 := NOW + tpd(n)(tr10);
1248                          Schd(n).Glch1 := Schd(n).inp1;
1249                          Schd(n).InpX := Schd(n).inp1;
1250          WHEN '\'|'F' => Schd(n).inp1 := TIME'HIGH;
1251                          Schd(n).inp0 := NOW + tpd(n)(tr01);
1252                          Schd(n).Glch0 := Schd(n).inp0;
1253                          Schd(n).InpX := Schd(n).inp0;
1254          WHEN 'r'     => Schd(n).inp1 := TIME'HIGH;
1255                          Schd(n).inp0 := TIME'HIGH;
1256                          Schd(n).InpX := NOW + tpd(n)(tr10);
1257          WHEN 'f'     => Schd(n).inp0 := TIME'HIGH;
1258                          Schd(n).inp1 := TIME'HIGH;
1259                          Schd(n).InpX := NOW + tpd(n)(tr01);
1260          WHEN 'x'     => Schd(n).inp1 := TIME'HIGH;
1261                          Schd(n).inp0 := TIME'HIGH;
1262                          -- update for X->X change
1263                          Schd(n).InpX := NOW + Minimum ( tpd(n)(tr10),
1264                                                          tpd(n)(tr01) );
1265          WHEN OTHERS  => NULL;                   -- no timing change
1266        END CASE;
1267      END LOOP;
1268    END;
1269
1270    ---------------------------------------------------------------------------
1271    -- Procedure  : BufEnab, InvEnab
1272    --
1273    -- Purpose    : BufEnab and InvEnab compute output change times, from a
1274    --              change on an input enable port for a 3-state driver. The
1275    --              computed output change times are returned in the composite
1276    --              parameters 'schd1', 'schd0'.
1277    --
1278    --              BufEnab and InpEnab are used together with the delay path
1279    --              selection functions (GetSchedDelay, VitalAND, VitalOR... )
1280    --              The 'schd' value from each of the non-enable input ports of
1281    --              a model (See BufPath, InvPath) are combined using the delay
1282    --              selection functions (VitalAND,  VitalOR, ...). The
1283    --              GetSchedDelay procedure combines the output times on the
1284    --              enable path with the output times from the data path(s) and
1285    --              computes the single delay (delta time) value for scheduling
1286    --              the output change (passed to VitalGlitchOnEvent)
1287    --
1288    --              The values in 'schd*' are: (absolute times)
1289    --                inp0  :  time of output change due to input change to 0
1290    --                inp1  :  time of output change due to input change to 1
1291    --                inpX  :  time of output change due to input change to X
1292    --                glch0 :  time of output glitch due to input change to 0
1293    --                glch1 :  time of output glitch due to input change to 1
1294    --
1295    --              'schd1' contains output times for 1->Z, Z->1 transitions.
1296    --              'schd0' contains output times for 0->Z, Z->0 transitions.
1297    --
1298    --              'BufEnab' is used for computing the output times for an
1299    --              high asserted enable (output 'Z' for enable='0').
1300    --              'InvEnab' is used for computing the output times for an
1301    --              low asserted enable (output 'Z' for enable='1').
1302    --
1303    --              Note: separate 'schd1', 'schd0' parameters are generated
1304    --                    so that the combination of the delay paths from
1305    --                    multiple enable signals may be combined using the
1306    --                    same functions/operators used in combining separate
1307    --                    data paths. (See exampe 2 below)
1308    --
1309    --
1310    -- Parameters : schd1...... Computed output result times for 1->Z, Z->1
1311    --                          transitions. This parameter is modified only on
1312    --                          input edge values (events).
1313    --              schd0...... Computed output result times for 0->Z, 0->1
1314    --                          transitions. This parameter is modified only on
1315    --                          input edge values (events).
1316    --              Iedg....... Input port edge/level value.
1317    --               tpd....... Propagation delays for the enable -> output path.
1318    --
1319    ---------------------------------------------------------------------------
1320    PROCEDURE BufEnab (
1321            VARIABLE Schd1 : INOUT SchedType;
1322            VARIABLE Schd0 : INOUT SchedType;
1323            CONSTANT  Iedg : IN    EdgeType;
1324            CONSTANT   tpd : IN    VitalDelayType01Z
1325    ) IS
1326    BEGIN
1327      CASE Iedg IS
1328        WHEN '0'|'1' => NULL;                   -- no edge: no timing update
1329        WHEN '/'|'R' => Schd1.inp0 := TIME'HIGH;
1330                        Schd1.inp1 := NOW + tpd(trz1);
1331                        Schd1.Glch1 := Schd1.inp1;
1332                        Schd1.InpX := Schd1.inp1;
1333                        Schd0.inp0 := TIME'HIGH;
1334                        Schd0.inp1 := NOW + tpd(trz0);
1335                        Schd0.Glch1 := Schd0.inp1;
1336                        Schd0.InpX := Schd0.inp1;
1337        WHEN '\'|'F' => Schd1.inp1 := TIME'HIGH;
1338                        Schd1.inp0 := NOW + tpd(tr1z);
1339                        Schd1.Glch0 := Schd1.inp0;
1340                        Schd1.InpX := Schd1.inp0;
1341                        Schd0.inp1 := TIME'HIGH;
1342                        Schd0.inp0 := NOW + tpd(tr0z);
1343                        Schd0.Glch0 := Schd0.inp0;
1344                        Schd0.InpX := Schd0.inp0;
1345        WHEN 'r'     => Schd1.inp1 := TIME'HIGH;
1346                        Schd1.inp0 := TIME'HIGH;
1347                        Schd1.InpX := NOW + tpd(trz1);
1348                        Schd0.inp1 := TIME'HIGH;
1349                        Schd0.inp0 := TIME'HIGH;
1350                        Schd0.InpX := NOW + tpd(trz0);
1351        WHEN 'f'     => Schd1.inp0 := TIME'HIGH;
1352                        Schd1.inp1 := TIME'HIGH;
1353                        Schd1.InpX := NOW + tpd(tr1z);
1354                        Schd0.inp0 := TIME'HIGH;
1355                        Schd0.inp1 := TIME'HIGH;
1356                        Schd0.InpX := NOW + tpd(tr0z);
1357        WHEN 'x'     => Schd1.inp0 := TIME'HIGH;
1358                        Schd1.inp1 := TIME'HIGH;
1359                        Schd1.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
1360                        Schd0.inp0 := TIME'HIGH;
1361                        Schd0.inp1 := TIME'HIGH;
1362                        Schd0.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
1363        WHEN OTHERS  => NULL;                   -- no timing change
1364      END CASE;
1365    END;
1366
1367    PROCEDURE InvEnab (
1368            VARIABLE Schd1 : INOUT SchedType;
1369            VARIABLE Schd0 : INOUT SchedType;
1370            CONSTANT  Iedg : IN    EdgeType;
1371            CONSTANT   tpd : IN    VitalDelayType01Z
1372    ) IS
1373    BEGIN
1374      CASE Iedg IS
1375        WHEN '0'|'1' => NULL;                   -- no edge: no timing update
1376        WHEN '/'|'R' => Schd1.inp0 := TIME'HIGH;
1377                        Schd1.inp1 := NOW + tpd(tr1z);
1378                        Schd1.Glch1 := Schd1.inp1;
1379                        Schd1.InpX := Schd1.inp1;
1380                        Schd0.inp0 := TIME'HIGH;
1381                        Schd0.inp1 := NOW + tpd(tr0z);
1382                        Schd0.Glch1 := Schd0.inp1;
1383                        Schd0.InpX := Schd0.inp1;
1384        WHEN '\'|'F' => Schd1.inp1 := TIME'HIGH;
1385                        Schd1.inp0 := NOW + tpd(trz1);
1386                        Schd1.Glch0 := Schd1.inp0;
1387                        Schd1.InpX := Schd1.inp0;
1388                        Schd0.inp1 := TIME'HIGH;
1389                        Schd0.inp0 := NOW + tpd(trz0);
1390                        Schd0.Glch0 := Schd0.inp0;
1391                        Schd0.InpX := Schd0.inp0;
1392        WHEN 'r'     => Schd1.inp1 := TIME'HIGH;
1393                        Schd1.inp0 := TIME'HIGH;
1394                        Schd1.InpX := NOW + tpd(tr1z);
1395                        Schd0.inp1 := TIME'HIGH;
1396                        Schd0.inp0 := TIME'HIGH;
1397                        Schd0.InpX := NOW + tpd(tr0z);
1398        WHEN 'f'     => Schd1.inp0 := TIME'HIGH;
1399                        Schd1.inp1 := TIME'HIGH;
1400                        Schd1.InpX := NOW + tpd(trz1);
1401                        Schd0.inp0 := TIME'HIGH;
1402                        Schd0.inp1 := TIME'HIGH;
1403                        Schd0.InpX := NOW + tpd(trz0);
1404        WHEN 'x'     => Schd1.inp0 := TIME'HIGH;
1405                        Schd1.inp1 := TIME'HIGH;
1406                        Schd1.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
1407                        Schd0.inp0 := TIME'HIGH;
1408                        Schd0.inp1 := TIME'HIGH;
1409                        Schd0.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
1410        WHEN OTHERS  => NULL;                   -- no timing change
1411      END CASE;
1412    END;
1413
1414    ---------------------------------------------------------------------------
1415    -- Procedure  : GetSchedDelay
1416    --
1417    -- Purpose    : GetSchedDelay computes the final delay (incremental) for
1418    --              for scheduling an output signal.  The delay is computed
1419    --              from the absolute output times in the 'NewSched' parameter.
1420    --              (See BufPath, InvPath).
1421    --
1422    --              Computation of the output delay for non-3_state outputs
1423    --              consists of selection the appropriate output time based
1424    --              on the new output value 'NewValue' and subtracting 'NOW'
1425    --              to convert to an incremental delay value.
1426    --
1427    --              The Computation of the output delay for 3_state output
1428    --              also includes combination of the enable path delay with
1429    --              the date path delay.
1430    --
1431    -- Parameters : NewDelay... Returned output delay value.
1432    --              GlchDelay.. Returned output delay for the start of a glitch.
1433    --              NewValue... New output value.
1434    --              CurValue... Current value of the output.
1435    --              NewSched... Composite containing the combined absolute
1436    --                          output times from the data inputs.
1437    --              EnSched1... Composite containing the combined absolute
1438    --                          output times from the enable input(s).
1439    --                          (for a 3_state output transitions 1->Z, Z->1)
1440    --              EnSched0... Composite containing the combined absolute
1441    --                          output times from the enable input(s).
1442    --                          (for a 3_state output transitions 0->Z, Z->0)
1443    --
1444    ---------------------------------------------------------------------------
1445    PROCEDURE GetSchedDelay (
1446            VARIABLE   NewDelay : OUT TIME;
1447            VARIABLE  GlchDelay : OUT TIME;
1448            CONSTANT   NewValue : IN  std_ulogic;
1449            CONSTANT   CurValue : IN  std_ulogic;
1450            CONSTANT   NewSched : IN  SchedType
1451    ) IS
1452        VARIABLE Tim, Glch : TIME;
1453    BEGIN
1454
1455        CASE To_UX01(NewValue) IS
1456          WHEN '0'    => Tim  := NewSched.inp0;
1457                         Glch := NewSched.Glch1;
1458          WHEN '1'    => Tim  := NewSched.inp1;
1459                         Glch := NewSched.Glch0;
1460          WHEN OTHERS => Tim  := NewSched.InpX;
1461                         Glch := -1 ns;
1462        END CASE;
1463        IF (CurValue /= NewValue)
1464          THEN Glch := -1 ns;
1465        END IF;
1466
1467        NewDelay  := Tim  - NOW;
1468        IF Glch < 0 ns
1469            THEN GlchDelay := Glch;
1470            ELSE GlchDelay := Glch - NOW;
1471        END IF; -- glch < 0 ns
1472    END;
1473
1474    PROCEDURE GetSchedDelay (
1475            VARIABLE   NewDelay : OUT VitalTimeArray;
1476            VARIABLE  GlchDelay : OUT VitalTimeArray;
1477            CONSTANT   NewValue : IN  std_logic_vector;
1478            CONSTANT   CurValue : IN  std_logic_vector;
1479            CONSTANT   NewSched : IN  SchedArray
1480    ) IS
1481        VARIABLE Tim, Glch : TIME;
1482        ALIAS  NewDelayAlias : VitalTimeArray( NewDelay'LENGTH DOWNTO 1)
1483               IS NewDelay;
1484        ALIAS GlchDelayAlias : VitalTimeArray(GlchDelay'LENGTH DOWNTO 1)
1485               IS GlchDelay;
1486        ALIAS  NewSchedAlias : SchedArray( NewSched'LENGTH DOWNTO 1)
1487               IS NewSched;
1488        ALIAS  NewValueAlias : std_logic_vector (  NewValue'LENGTH DOWNTO 1 )
1489                                IS  NewValue;
1490        ALIAS  CurValueAlias : std_logic_vector (  CurValue'LENGTH DOWNTO 1 )
1491                                IS  CurValue;
1492    BEGIN
1493      FOR n IN NewDelay'LENGTH DOWNTO 1 LOOP
1494        CASE To_UX01(NewValueAlias(n)) IS
1495          WHEN '0'    => Tim  := NewSchedAlias(n).inp0;
1496                         Glch := NewSchedAlias(n).Glch1;
1497          WHEN '1'    => Tim  := NewSchedAlias(n).inp1;
1498                         Glch := NewSchedAlias(n).Glch0;
1499          WHEN OTHERS => Tim  := NewSchedAlias(n).InpX;
1500                         Glch := -1 ns;
1501        END CASE;
1502        IF (CurValueAlias(n) /= NewValueAlias(n))
1503          THEN Glch := -1 ns;
1504        END IF;
1505
1506        NewDelayAlias(n) := Tim  - NOW;
1507        IF Glch < 0 ns
1508            THEN GlchDelayAlias(n) := Glch;
1509            ELSE GlchDelayAlias(n) := Glch - NOW;
1510        END IF; -- glch < 0 ns
1511      END LOOP;
1512      RETURN;
1513    END;
1514
1515    PROCEDURE GetSchedDelay (
1516            VARIABLE   NewDelay : OUT TIME;
1517            VARIABLE  GlchDelay : OUT TIME;
1518            CONSTANT   NewValue : IN  std_ulogic;
1519            CONSTANT   CurValue : IN  std_ulogic;
1520            CONSTANT   NewSched : IN  SchedType;
1521            CONSTANT   EnSched1 : IN  SchedType;
1522            CONSTANT   EnSched0 : IN  SchedType
1523    ) IS
1524        SUBTYPE v2 IS std_logic_vector(0 TO 1);
1525        VARIABLE Tim, Glch : TIME;
1526    BEGIN
1527
1528        CASE v2'(To_X01Z(CurValue) & To_X01Z(NewValue)) IS
1529          WHEN "00"    => Tim  := Maximum (NewSched.inp0, EnSched0.inp1);
1530                          Glch := GlitchMinTime(NewSched.Glch1,EnSched0.Glch0);
1531          WHEN "01"    => Tim  := Maximum (NewSched.inp1, EnSched1.inp1);
1532                          Glch := EnSched1.Glch0;
1533          WHEN "0Z"    => Tim  := EnSched0.inp0;
1534                          Glch := NewSched.Glch1;
1535          WHEN "0X"    => Tim  := Maximum (NewSched.InpX, EnSched1.InpX);
1536                          Glch := 0 ns;
1537          WHEN "10"    => Tim  := Maximum (NewSched.inp0, EnSched0.inp1);
1538                          Glch := EnSched0.Glch0;
1539          WHEN "11"    => Tim  := Maximum (NewSched.inp1, EnSched1.inp1);
1540                          Glch := GlitchMinTime(NewSched.Glch0,EnSched1.Glch0);
1541          WHEN "1Z"    => Tim  := EnSched1.inp0;
1542                          Glch := NewSched.Glch0;
1543          WHEN "1X"    => Tim  := Maximum (NewSched.InpX, EnSched0.InpX);
1544                          Glch := 0 ns;
1545          WHEN "Z0"    => Tim  := Maximum (NewSched.inp0, EnSched0.inp1);
1546                          IF NewSched.Glch0 > NOW
1547                            THEN Glch := Maximum(NewSched.Glch1,EnSched1.inp1);
1548                            ELSE Glch := 0 ns;
1549                          END IF;
1550          WHEN "Z1"    => Tim  := Maximum (NewSched.inp1, EnSched1.inp1);
1551                          IF NewSched.Glch1 > NOW
1552                            THEN Glch := Maximum(NewSched.Glch0,EnSched0.inp1);
1553                            ELSE Glch := 0 ns;
1554                          END IF;
1555          WHEN "ZX"    => Tim  := Maximum (NewSched.InpX, EnSched1.InpX);
1556                          Glch := 0 ns;
1557          WHEN "ZZ"    => Tim  := Maximum (EnSched1.InpX, EnSched0.InpX);
1558                          Glch := 0 ns;
1559          WHEN "X0"    => Tim  := Maximum (NewSched.inp0, EnSched0.inp1);
1560                          Glch := 0 ns;
1561          WHEN "X1"    => Tim  := Maximum (NewSched.inp1, EnSched1.inp1);
1562                          Glch := 0 ns;
1563          WHEN "XZ"    => Tim  := Maximum (EnSched1.InpX, EnSched0.InpX);
1564                          Glch := 0 ns;
1565          WHEN OTHERS  => Tim  := Maximum (NewSched.InpX, EnSched1.InpX);
1566                          Glch := 0 ns;
1567
1568        END CASE;
1569        NewDelay  := Tim  - NOW;
1570        IF Glch < 0 ns
1571            THEN GlchDelay := Glch;
1572            ELSE GlchDelay := Glch - NOW;
1573        END IF; -- glch < 0 ns
1574    END;
1575
1576    ---------------------------------------------------------------------------
1577    -- Operators and Functions for combination (selection) of path delays
1578    -- > These functions support selection of the "appripriate" path delay
1579    --   dependent on the logic function.
1580    -- > These functions only "select" from the possable output times. No
1581    --   calculation (addition) of delays is performed.
1582    -- > See description of 'BufPath', 'InvPath' and 'GetSchedDelay'
1583    -- > See primitive PROCEDURE models for examples.
1584    ---------------------------------------------------------------------------
1585
1586    FUNCTION "not"  (
1587            CONSTANT a : IN SchedType
1588          ) RETURN SchedType IS
1589        VARIABLE z : SchedType;
1590    BEGIN
1591        z.inp1  := a.inp0 ;
1592        z.inp0  := a.inp1 ;
1593        z.InpX  := a.InpX ;
1594        z.Glch1 := a.Glch0;
1595        z.Glch0 := a.Glch1;
1596        RETURN (z);
1597    END;
1598
1599    FUNCTION "and"  (
1600            CONSTANT a, b : IN SchedType
1601          ) RETURN SchedType IS
1602        VARIABLE z : SchedType;
1603    BEGIN
1604        z.inp1  := Maximum   ( a.inp1 , b.inp1  );
1605        z.inp0  := Minimum   ( a.inp0 , b.inp0  );
1606        z.InpX  := GlitchMinTime ( a.InpX , b.InpX  );
1607        z.Glch1 := Maximum   ( a.Glch1, b.Glch1 );
1608        z.Glch0 := GlitchMinTime ( a.Glch0, b.Glch0 );
1609        RETURN (z);
1610    END;
1611
1612    FUNCTION "or"   (
1613            CONSTANT a, b : IN SchedType
1614          ) RETURN SchedType IS
1615        VARIABLE z : SchedType;
1616    BEGIN
1617        z.inp0  := Maximum   ( a.inp0 , b.inp0  );
1618        z.inp1  := Minimum   ( a.inp1 , b.inp1  );
1619        z.InpX  := GlitchMinTime ( a.InpX , b.InpX  );
1620        z.Glch0 := Maximum   ( a.Glch0, b.Glch0 );
1621        z.Glch1 := GlitchMinTime ( a.Glch1, b.Glch1 );
1622        RETURN (z);
1623    END;
1624
1625    IMPURE FUNCTION "nand" (
1626            CONSTANT a, b : IN SchedType
1627          ) RETURN SchedType IS
1628        VARIABLE z : SchedType;
1629    BEGIN
1630        z.inp0  := Maximum   ( a.inp1 , b.inp1  );
1631        z.inp1  := Minimum   ( a.inp0 , b.inp0  );
1632        z.InpX  := GlitchMinTime ( a.InpX , b.InpX  );
1633        z.Glch0 := Maximum   ( a.Glch1, b.Glch1 );
1634        z.Glch1 := GlitchMinTime ( a.Glch0, b.Glch0 );
1635        RETURN (z);
1636    END;
1637
1638    IMPURE FUNCTION "nor"  (
1639            CONSTANT a, b : IN SchedType
1640          ) RETURN SchedType IS
1641        VARIABLE z : SchedType;
1642    BEGIN
1643        z.inp1  := Maximum   ( a.inp0 , b.inp0  );
1644        z.inp0  := Minimum   ( a.inp1 , b.inp1  );
1645        z.InpX  := GlitchMinTime ( a.InpX , b.InpX  );
1646        z.Glch1 := Maximum   ( a.Glch0, b.Glch0 );
1647        z.Glch0 := GlitchMinTime ( a.Glch1, b.Glch1 );
1648        RETURN (z);
1649    END;
1650
1651    -- ------------------------------------------------------------------------
1652    -- Delay Calculation for 2-bit Logical gates.
1653    -- ------------------------------------------------------------------------
1654    IMPURE FUNCTION VitalXOR2   (
1655            CONSTANT ab,ai, bb,bi : IN SchedType
1656          ) RETURN SchedType IS
1657        VARIABLE z : SchedType;
1658    BEGIN
1659        -- z = (a AND b) NOR (a NOR b)
1660        z.inp1  :=   Maximum (  Minimum (ai.inp0 , bi.inp0 ),
1661                                Minimum (ab.inp1 , bb.inp1 ) );
1662        z.inp0  :=   Minimum (  Maximum (ai.inp1 , bi.inp1 ),
1663                                Maximum (ab.inp0 , bb.inp0 ) );
1664        z.InpX  :=   Maximum (  Maximum (ai.InpX , bi.InpX ),
1665                                Maximum (ab.InpX , bb.InpX ) );
1666        z.Glch1 :=   Maximum (GlitchMinTime (ai.Glch0, bi.Glch0),
1667                              GlitchMinTime (ab.Glch1, bb.Glch1) );
1668        z.Glch0 := GlitchMinTime (  Maximum (ai.Glch1, bi.Glch1),
1669                                Maximum (ab.Glch0, bb.Glch0) );
1670        RETURN (z);
1671    END;
1672
1673    IMPURE FUNCTION VitalXNOR2  (
1674            CONSTANT ab,ai, bb,bi : IN SchedType
1675          ) RETURN SchedType IS
1676        VARIABLE z : SchedType;
1677    BEGIN
1678        -- z = (a AND b) OR (a NOR b)
1679        z.inp0  :=   Maximum (  Minimum (ab.inp0 , bb.inp0 ),
1680                                Minimum (ai.inp1 , bi.inp1 ) );
1681        z.inp1  :=   Minimum (  Maximum (ab.inp1 , bb.inp1 ),
1682                                Maximum (ai.inp0 , bi.inp0 ) );
1683        z.InpX  :=   Maximum (  Maximum (ab.InpX , bb.InpX ),
1684                                Maximum (ai.InpX , bi.InpX ) );
1685        z.Glch0 :=   Maximum (GlitchMinTime (ab.Glch0, bb.Glch0),
1686                              GlitchMinTime (ai.Glch1, bi.Glch1) );
1687        z.Glch1 := GlitchMinTime (  Maximum (ab.Glch1, bb.Glch1),
1688                                Maximum (ai.Glch0, bi.Glch0) );
1689        RETURN (z);
1690    END;
1691
1692    -- ------------------------------------------------------------------------
1693    -- Delay Calculation for 3-bit Logical gates.
1694    -- ------------------------------------------------------------------------
1695    IMPURE FUNCTION VitalXOR3   (
1696            CONSTANT ab,ai, bb,bi, cb,ci : IN SchedType )
1697      RETURN SchedType IS
1698    BEGIN
1699        RETURN VitalXOR2 ( VitalXOR2 (ab,ai, bb,bi),
1700                           VitalXOR2 (ai,ab, bi,bb),
1701                           cb, ci );
1702    END;
1703
1704    IMPURE FUNCTION VitalXNOR3  (
1705            CONSTANT ab,ai, bb,bi, cb,ci : IN SchedType )
1706      RETURN SchedType IS
1707    BEGIN
1708        RETURN VitalXNOR2 ( VitalXOR2 ( ab,ai, bb,bi ),
1709                            VitalXOR2 ( ai,ab, bi,bb ),
1710                            cb, ci );
1711    END;
1712
1713    -- ------------------------------------------------------------------------
1714    -- Delay Calculation for 4-bit Logical gates.
1715    -- ------------------------------------------------------------------------
1716    IMPURE FUNCTION VitalXOR4   (
1717            CONSTANT ab,ai, bb,bi, cb,ci, db,di : IN SchedType )
1718      RETURN SchedType IS
1719    BEGIN
1720        RETURN VitalXOR2 ( VitalXOR2 ( ab,ai, bb,bi ),
1721                           VitalXOR2 ( ai,ab, bi,bb ),
1722                           VitalXOR2 ( cb,ci, db,di ),
1723                           VitalXOR2 ( ci,cb, di,db ) );
1724    END;
1725
1726    IMPURE FUNCTION VitalXNOR4  (
1727            CONSTANT ab,ai, bb,bi, cb,ci, db,di : IN SchedType )
1728      RETURN SchedType IS
1729    BEGIN
1730        RETURN VitalXNOR2 ( VitalXOR2 ( ab,ai, bb,bi ),
1731                            VitalXOR2 ( ai,ab, bi,bb ),
1732                            VitalXOR2 ( cb,ci, db,di ),
1733                            VitalXOR2 ( ci,cb, di,db ) );
1734    END;
1735
1736    -- ------------------------------------------------------------------------
1737    -- Delay Calculation for N-bit Logical gates.
1738    -- ------------------------------------------------------------------------
1739    -- Note: index range on datab,datai assumed to be 1 TO length.
1740    --       This is enforced by internal only usage of this Function
1741    IMPURE FUNCTION VitalXOR   (
1742            CONSTANT DataB, DataI : IN SchedArray
1743          ) RETURN SchedType IS
1744            CONSTANT Leng : INTEGER := DataB'LENGTH;
1745    BEGIN
1746        IF Leng = 2 THEN
1747            RETURN VitalXOR2 ( DataB(1),DataI(1), DataB(2),DataI(2) );
1748        ELSE
1749            RETURN VitalXOR2 ( VitalXOR ( DataB(1 TO Leng-1),
1750                                          DataI(1 TO Leng-1) ),
1751                               VitalXOR ( DataI(1 TO Leng-1),
1752                                          DataB(1 TO Leng-1) ),
1753                               DataB(Leng),DataI(Leng) );
1754        END IF;
1755    END;
1756
1757    -- Note: index range on datab,datai assumed to be 1 TO length.
1758    --       This is enforced by internal only usage of this Function
1759    IMPURE FUNCTION VitalXNOR  (
1760            CONSTANT DataB, DataI : IN SchedArray
1761          ) RETURN SchedType IS
1762            CONSTANT Leng : INTEGER := DataB'LENGTH;
1763    BEGIN
1764        IF Leng = 2 THEN
1765            RETURN VitalXNOR2 ( DataB(1),DataI(1), DataB(2),DataI(2) );
1766        ELSE
1767            RETURN VitalXNOR2 ( VitalXOR ( DataB(1 TO Leng-1),
1768                                           DataI(1 TO Leng-1) ),
1769                                VitalXOR ( DataI(1 TO Leng-1),
1770                                           DataB(1 TO Leng-1) ),
1771                                DataB(Leng),DataI(Leng) );
1772        END IF;
1773    END;
1774
1775    -- ------------------------------------------------------------------------
1776    -- Multiplexor
1777    --   MUX   .......... result := data(dselect)
1778    --   MUX2  .......... 2-input mux; result := data0 when (dselect = '0'),
1779    --                                           data1 when (dselect = '1'),
1780    --                        'X' when (dselect = 'X') and (data0 /= data1)
1781    --   MUX4  .......... 4-input mux; result := data(dselect)
1782    --   MUX8  .......... 8-input mux; result := data(dselect)
1783    -- ------------------------------------------------------------------------
1784    FUNCTION VitalMUX2  (
1785            CONSTANT d1, d0 : IN SchedType;
1786            CONSTANT sb, SI : IN SchedType
1787          ) RETURN SchedType IS
1788    BEGIN
1789        RETURN (d1 AND sb) OR (d0 AND (NOT SI) );
1790    END;
1791--
1792    FUNCTION VitalMUX4  (
1793            CONSTANT Data : IN SchedArray4;
1794            CONSTANT sb   : IN SchedArray2;
1795            CONSTANT SI   : IN SchedArray2
1796          ) RETURN SchedType IS
1797    BEGIN
1798        RETURN    (      sb(1)  AND VitalMUX2(Data(3),Data(2), sb(0), SI(0)) )
1799               OR ( (NOT SI(1)) AND VitalMUX2(Data(1),Data(0), sb(0), SI(0)) );
1800    END;
1801
1802    FUNCTION VitalMUX8  (
1803            CONSTANT Data : IN SchedArray8;
1804            CONSTANT sb   : IN SchedArray3;
1805            CONSTANT SI   : IN SchedArray3
1806          ) RETURN SchedType IS
1807    BEGIN
1808        RETURN    ( (    sb(2)) AND VitalMUX4 (Data(7 DOWNTO 4),
1809                                           sb(1 DOWNTO 0), SI(1 DOWNTO 0) ) )
1810               OR ( (NOT SI(2)) AND VitalMUX4 (Data(3 DOWNTO 0),
1811                                           sb(1 DOWNTO 0), SI(1 DOWNTO 0) ) );
1812    END;
1813--
1814    FUNCTION VInterMux   (
1815            CONSTANT Data : IN SchedArray;
1816            CONSTANT sb   : IN SchedArray;
1817            CONSTANT SI   : IN SchedArray
1818          ) RETURN SchedType IS
1819        CONSTANT sMsb : INTEGER := sb'LENGTH;
1820        CONSTANT dMsbHigh : INTEGER := Data'LENGTH;
1821        CONSTANT dMsbLow  : INTEGER := Data'LENGTH/2;
1822    BEGIN
1823        IF sb'LENGTH = 1 THEN
1824          RETURN VitalMUX2( Data(2), Data(1), sb(1), SI(1) );
1825        ELSIF sb'LENGTH = 2 THEN
1826          RETURN VitalMUX4( Data, sb, SI );
1827        ELSIF sb'LENGTH = 3 THEN
1828          RETURN VitalMUX8( Data, sb, SI );
1829        ELSIF sb'LENGTH > 3 THEN
1830          RETURN ((    sb(sMsb)) AND VInterMux( Data(dMsbLow  DOWNTO  1),
1831                                                  sb(sMsb-1 DOWNTO 1),
1832                                                  SI(sMsb-1 DOWNTO 1) ))
1833              OR ((NOT SI(sMsb)) AND VInterMux( Data(dMsbHigh DOWNTO dMsbLow+1),
1834                                                  sb(sMsb-1 DOWNTO 1),
1835                                                  SI(sMsb-1 DOWNTO 1) ));
1836        ELSE
1837          RETURN (0 ns, 0 ns, 0 ns, 0 ns, 0 ns); -- dselect'LENGTH < 1
1838        END IF;
1839    END;
1840--
1841    FUNCTION VitalMUX   (
1842            CONSTANT Data : IN SchedArray;
1843            CONSTANT sb   : IN SchedArray;
1844            CONSTANT SI   : IN SchedArray
1845          ) RETURN SchedType IS
1846        CONSTANT msb : INTEGER := 2**sb'LENGTH;
1847        VARIABLE    lDat : SchedArray(msb DOWNTO 1);
1848        ALIAS DataAlias : SchedArray ( Data'LENGTH DOWNTO 1 ) IS Data;
1849        ALIAS   sbAlias : SchedArray (   sb'LENGTH DOWNTO 1 ) IS sb;
1850        ALIAS   siAlias : SchedArray (   SI'LENGTH DOWNTO 1 ) IS SI;
1851    BEGIN
1852        IF Data'LENGTH <= msb THEN
1853            FOR i IN Data'LENGTH DOWNTO 1 LOOP
1854                lDat(i) := DataAlias(i);
1855            END LOOP;
1856            FOR i IN msb DOWNTO Data'LENGTH+1 LOOP
1857                lDat(i) := DefSchedAnd;
1858            END LOOP;
1859        ELSE
1860            FOR i IN msb DOWNTO 1 LOOP
1861                lDat(i) := DataAlias(i);
1862            END LOOP;
1863        END IF;
1864        RETURN VInterMux( lDat, sbAlias, siAlias );
1865    END;
1866
1867    -- ------------------------------------------------------------------------
1868    -- Decoder
1869    --          General Algorithm :
1870    --              (a) Result(...) := '0' when (enable = '0')
1871    --              (b) Result(data) := '1'; all other subelements = '0'
1872    --              ... Result array is decending (n-1 downto 0)
1873    --
1874    --          DECODERn  .......... n:2**n decoder
1875    -- ------------------------------------------------------------------------
1876    FUNCTION VitalDECODER2  (
1877            CONSTANT DataB  : IN SchedType;
1878            CONSTANT DataI  : IN SchedType;
1879            CONSTANT Enable : IN SchedType
1880          ) RETURN SchedArray IS
1881        VARIABLE Result : SchedArray2;
1882    BEGIN
1883        Result(1) := Enable AND (    DataB);
1884        Result(0) := Enable AND (NOT DataI);
1885        RETURN Result;
1886    END;
1887
1888    FUNCTION VitalDECODER4  (
1889            CONSTANT DataB  : IN SchedArray2;
1890            CONSTANT DataI  : IN SchedArray2;
1891            CONSTANT Enable : IN SchedType
1892          ) RETURN SchedArray IS
1893        VARIABLE Result : SchedArray4;
1894    BEGIN
1895        Result(3) := Enable AND (    DataB(1)) AND (    DataB(0));
1896        Result(2) := Enable AND (    DataB(1)) AND (NOT DataI(0));
1897        Result(1) := Enable AND (NOT DataI(1)) AND (    DataB(0));
1898        Result(0) := Enable AND (NOT DataI(1)) AND (NOT DataI(0));
1899        RETURN Result;
1900    END;
1901
1902    FUNCTION VitalDECODER8  (
1903            CONSTANT DataB  : IN SchedArray3;
1904            CONSTANT DataI  : IN SchedArray3;
1905            CONSTANT Enable : IN SchedType
1906          ) RETURN SchedArray IS
1907        VARIABLE Result : SchedArray8;
1908    BEGIN
1909        Result(7):= Enable AND (    DataB(2))AND(    DataB(1))AND(    DataB(0));
1910        Result(6):= Enable AND (    DataB(2))AND(    DataB(1))AND(NOT DataI(0));
1911        Result(5):= Enable AND (    DataB(2))AND(NOT DataI(1))AND(    DataB(0));
1912        Result(4):= Enable AND (    DataB(2))AND(NOT DataI(1))AND(NOT DataI(0));
1913        Result(3):= Enable AND (NOT DataI(2))AND(    DataB(1))AND(    DataB(0));
1914        Result(2):= Enable AND (NOT DataI(2))AND(    DataB(1))AND(NOT DataI(0));
1915        Result(1):= Enable AND (NOT DataI(2))AND(NOT DataI(1))AND(    DataB(0));
1916        Result(0):= Enable AND (NOT DataI(2))AND(NOT DataI(1))AND(NOT DataI(0));
1917        RETURN Result;
1918    END;
1919
1920
1921    FUNCTION VitalDECODER   (
1922            CONSTANT DataB  : IN SchedArray;
1923            CONSTANT DataI  : IN SchedArray;
1924            CONSTANT Enable : IN SchedType
1925          ) RETURN SchedArray IS
1926        CONSTANT DMsb : INTEGER := DataB'LENGTH - 1;
1927        ALIAS DataBAlias : SchedArray ( DMsb DOWNTO 0 ) IS DataB;
1928        ALIAS DataIAlias : SchedArray ( DMsb DOWNTO 0 ) IS DataI;
1929    BEGIN
1930        IF DataB'LENGTH = 1 THEN
1931            RETURN  VitalDECODER2 ( DataBAlias(    0     ),
1932                                    DataIAlias(    0     ), Enable );
1933        ELSIF DataB'LENGTH = 2 THEN
1934            RETURN  VitalDECODER4 ( DataBAlias(1 DOWNTO 0),
1935                                    DataIAlias(1 DOWNTO 0), Enable );
1936        ELSIF DataB'LENGTH = 3 THEN
1937            RETURN  VitalDECODER8 ( DataBAlias(2 DOWNTO 0),
1938                                    DataIAlias(2 DOWNTO 0), Enable );
1939        ELSIF DataB'LENGTH > 3 THEN
1940            RETURN  VitalDECODER  ( DataBAlias(DMsb-1 DOWNTO 0),
1941                                    DataIAlias(DMsb-1 DOWNTO 0),
1942                                    Enable AND (    DataBAlias(DMsb)) )
1943                  & VitalDECODER  ( DataBAlias(DMsb-1 DOWNTO 0),
1944                                    DataIAlias(DMsb-1 DOWNTO 0),
1945                                    Enable AND (NOT DataIAlias(DMsb)) );
1946        ELSE
1947            RETURN DefSchedArray2;
1948        END IF;
1949    END;
1950
1951
1952-------------------------------------------------------------------------------
1953-- PRIMITIVES
1954-------------------------------------------------------------------------------
1955    -- ------------------------------------------------------------------------
1956    -- N-bit wide Logical gates.
1957    -- ------------------------------------------------------------------------
1958    FUNCTION VitalAND    (
1959            CONSTANT       Data :  IN std_logic_vector;
1960            CONSTANT  ResultMap :  IN VitalResultMapType
1961                                      := VitalDefaultResultMap
1962          ) RETURN std_ulogic IS
1963        VARIABLE Result : UX01;
1964    BEGIN
1965        Result := '1';
1966        FOR i IN Data'RANGE LOOP
1967            Result := Result AND Data(i);
1968        END LOOP;
1969        RETURN ResultMap(Result);
1970    END;
1971--
1972    FUNCTION VitalOR     (
1973            CONSTANT       Data :  IN std_logic_vector;
1974            CONSTANT  ResultMap :  IN VitalResultMapType
1975                                      := VitalDefaultResultMap
1976          ) RETURN std_ulogic IS
1977        VARIABLE Result : UX01;
1978    BEGIN
1979        Result := '0';
1980        FOR i IN Data'RANGE LOOP
1981            Result := Result OR Data(i);
1982        END LOOP;
1983        RETURN ResultMap(Result);
1984    END;
1985--
1986    FUNCTION VitalXOR    (
1987            CONSTANT       Data :  IN std_logic_vector;
1988            CONSTANT  ResultMap :  IN VitalResultMapType
1989                                      := VitalDefaultResultMap
1990          ) RETURN std_ulogic IS
1991        VARIABLE Result : UX01;
1992    BEGIN
1993        Result := '0';
1994        FOR i IN Data'RANGE LOOP
1995            Result := Result XOR Data(i);
1996        END LOOP;
1997        RETURN ResultMap(Result);
1998    END;
1999--
2000    FUNCTION VitalNAND   (
2001            CONSTANT       Data :  IN std_logic_vector;
2002            CONSTANT  ResultMap :  IN VitalResultMapType
2003                                      := VitalDefaultResultMap
2004          ) RETURN std_ulogic IS
2005        VARIABLE Result : UX01;
2006    BEGIN
2007        Result := '1';
2008        FOR i IN Data'RANGE LOOP
2009            Result := Result AND Data(i);
2010        END LOOP;
2011        RETURN ResultMap(NOT Result);
2012    END;
2013--
2014    FUNCTION VitalNOR    (
2015            CONSTANT       Data :  IN std_logic_vector;
2016            CONSTANT  ResultMap :  IN VitalResultMapType
2017                                      := VitalDefaultResultMap
2018          ) RETURN std_ulogic IS
2019        VARIABLE Result : UX01;
2020    BEGIN
2021        Result := '0';
2022        FOR i IN Data'RANGE LOOP
2023            Result := Result OR Data(i);
2024        END LOOP;
2025        RETURN ResultMap(NOT Result);
2026    END;
2027--
2028    FUNCTION VitalXNOR   (
2029            CONSTANT       Data :  IN std_logic_vector;
2030            CONSTANT  ResultMap :  IN VitalResultMapType
2031                                      := VitalDefaultResultMap
2032          ) RETURN std_ulogic IS
2033        VARIABLE Result : UX01;
2034    BEGIN
2035        Result := '0';
2036        FOR i IN Data'RANGE LOOP
2037            Result := Result XOR Data(i);
2038        END LOOP;
2039        RETURN ResultMap(NOT Result);
2040    END;
2041
2042    -- ------------------------------------------------------------------------
2043    -- Commonly used 2-bit Logical gates.
2044    -- ------------------------------------------------------------------------
2045    FUNCTION VitalAND2   (
2046            CONSTANT       a, b :  IN std_ulogic;
2047            CONSTANT  ResultMap :  IN VitalResultMapType
2048                                      := VitalDefaultResultMap
2049          ) RETURN std_ulogic IS
2050    BEGIN
2051        RETURN ResultMap(a AND b);
2052    END;
2053--
2054    FUNCTION VitalOR2    (
2055            CONSTANT       a, b :  IN std_ulogic;
2056            CONSTANT  ResultMap :  IN VitalResultMapType
2057                                      := VitalDefaultResultMap
2058          ) RETURN std_ulogic IS
2059    BEGIN
2060        RETURN ResultMap(a OR b);
2061    END;
2062--
2063    FUNCTION VitalXOR2   (
2064            CONSTANT       a, b :  IN std_ulogic;
2065            CONSTANT  ResultMap :  IN VitalResultMapType
2066                                      := VitalDefaultResultMap
2067          ) RETURN std_ulogic IS
2068    BEGIN
2069        RETURN ResultMap(a XOR b);
2070    END;
2071--
2072    FUNCTION VitalNAND2  (
2073            CONSTANT       a, b :  IN std_ulogic;
2074            CONSTANT  ResultMap :  IN VitalResultMapType
2075                                      := VitalDefaultResultMap
2076          ) RETURN std_ulogic IS
2077    BEGIN
2078        RETURN ResultMap(a NAND b);
2079    END;
2080--
2081    FUNCTION VitalNOR2   (
2082            CONSTANT       a, b :  IN std_ulogic;
2083            CONSTANT  ResultMap :  IN VitalResultMapType
2084                                      := VitalDefaultResultMap
2085          ) RETURN std_ulogic IS
2086    BEGIN
2087        RETURN ResultMap(a NOR b);
2088    END;
2089--
2090    FUNCTION VitalXNOR2  (
2091            CONSTANT       a, b :  IN std_ulogic;
2092            CONSTANT  ResultMap :  IN VitalResultMapType
2093                                      := VitalDefaultResultMap
2094          ) RETURN std_ulogic IS
2095    BEGIN
2096        RETURN ResultMap(NOT (a XOR b));
2097    END;
2098--
2099    -- ------------------------------------------------------------------------
2100    -- Commonly used 3-bit Logical gates.
2101    -- ------------------------------------------------------------------------
2102    FUNCTION VitalAND3   (
2103            CONSTANT    a, b, c :  IN std_ulogic;
2104            CONSTANT  ResultMap :  IN VitalResultMapType
2105                                      := VitalDefaultResultMap
2106          ) RETURN std_ulogic IS
2107    BEGIN
2108        RETURN ResultMap(a AND b AND c);
2109    END;
2110--
2111    FUNCTION VitalOR3    (
2112            CONSTANT    a, b, c :  IN std_ulogic;
2113            CONSTANT  ResultMap :  IN VitalResultMapType
2114                                      := VitalDefaultResultMap
2115          ) RETURN std_ulogic IS
2116    BEGIN
2117        RETURN ResultMap(a OR b OR c);
2118    END;
2119--
2120    FUNCTION VitalXOR3   (
2121            CONSTANT    a, b, c :  IN std_ulogic;
2122            CONSTANT  ResultMap :  IN VitalResultMapType
2123                                      := VitalDefaultResultMap
2124          ) RETURN std_ulogic IS
2125    BEGIN
2126        RETURN ResultMap(a XOR b XOR c);
2127    END;
2128--
2129    FUNCTION VitalNAND3  (
2130            CONSTANT    a, b, c :  IN std_ulogic;
2131            CONSTANT  ResultMap :  IN VitalResultMapType
2132                                      := VitalDefaultResultMap
2133          ) RETURN std_ulogic IS
2134    BEGIN
2135        RETURN ResultMap(NOT (a AND b AND c));
2136    END;
2137--
2138    FUNCTION VitalNOR3   (
2139            CONSTANT    a, b, c :  IN std_ulogic;
2140            CONSTANT  ResultMap :  IN VitalResultMapType
2141                                      := VitalDefaultResultMap
2142          ) RETURN std_ulogic IS
2143    BEGIN
2144        RETURN ResultMap(NOT (a OR b OR c));
2145    END;
2146--
2147    FUNCTION VitalXNOR3  (
2148            CONSTANT    a, b, c :  IN std_ulogic;
2149            CONSTANT  ResultMap :  IN VitalResultMapType
2150                                      := VitalDefaultResultMap
2151          ) RETURN std_ulogic IS
2152    BEGIN
2153        RETURN ResultMap(NOT (a XOR b XOR c));
2154    END;
2155
2156    -- ---------------------------------------------------------------------------
2157    -- Commonly used 4-bit Logical gates.
2158    -- ---------------------------------------------------------------------------
2159    FUNCTION VitalAND4   (
2160            CONSTANT a, b, c, d :  IN std_ulogic;
2161            CONSTANT  ResultMap :  IN VitalResultMapType
2162                                      := VitalDefaultResultMap
2163          ) RETURN std_ulogic IS
2164    BEGIN
2165        RETURN ResultMap(a AND b AND c AND d);
2166    END;
2167--
2168    FUNCTION VitalOR4    (
2169            CONSTANT a, b, c, d :  IN std_ulogic;
2170            CONSTANT  ResultMap :  IN VitalResultMapType
2171                                      := VitalDefaultResultMap
2172          ) RETURN std_ulogic IS
2173    BEGIN
2174        RETURN ResultMap(a OR b OR c OR d);
2175    END;
2176--
2177    FUNCTION VitalXOR4   (
2178            CONSTANT a, b, c, d :  IN std_ulogic;
2179            CONSTANT  ResultMap :  IN VitalResultMapType
2180                                      := VitalDefaultResultMap
2181          ) RETURN std_ulogic IS
2182    BEGIN
2183        RETURN ResultMap(a XOR b XOR c XOR d);
2184    END;
2185--
2186    FUNCTION VitalNAND4  (
2187            CONSTANT a, b, c, d :  IN std_ulogic;
2188            CONSTANT  ResultMap :  IN VitalResultMapType
2189                                      := VitalDefaultResultMap
2190          ) RETURN std_ulogic IS
2191    BEGIN
2192        RETURN ResultMap(NOT (a AND b AND c AND d));
2193    END;
2194--
2195    FUNCTION VitalNOR4   (
2196            CONSTANT a, b, c, d :  IN std_ulogic;
2197            CONSTANT  ResultMap :  IN VitalResultMapType
2198                                      := VitalDefaultResultMap
2199          ) RETURN std_ulogic IS
2200    BEGIN
2201        RETURN ResultMap(NOT (a OR b OR c OR d));
2202    END;
2203--
2204    FUNCTION VitalXNOR4  (
2205            CONSTANT a, b, c, d :  IN std_ulogic;
2206            CONSTANT  ResultMap :  IN VitalResultMapType
2207                                      := VitalDefaultResultMap
2208          ) RETURN std_ulogic IS
2209    BEGIN
2210        RETURN ResultMap(NOT (a XOR b XOR c XOR d));
2211    END;
2212
2213    -- ------------------------------------------------------------------------
2214    -- Buffers
2215    --   BUF    ....... standard non-inverting buffer
2216    --   BUFIF0 ....... non-inverting buffer Data passes thru if (Enable = '0')
2217    --   BUFIF1 ....... non-inverting buffer Data passes thru if (Enable = '1')
2218    -- ------------------------------------------------------------------------
2219    FUNCTION VitalBUF    (
2220            CONSTANT         Data :  IN std_ulogic;
2221            CONSTANT    ResultMap :  IN VitalResultMapType
2222                                        := VitalDefaultResultMap
2223          ) RETURN std_ulogic IS
2224    BEGIN
2225        RETURN ResultMap(To_UX01(Data));
2226    END;
2227--
2228    FUNCTION VitalBUFIF0 (
2229            CONSTANT Data, Enable :  IN std_ulogic;
2230            CONSTANT    ResultMap :  IN VitalResultZMapType
2231                                        := VitalDefaultResultZMap
2232          ) RETURN std_ulogic IS
2233    BEGIN
2234        RETURN ResultMap(BufIf0_Table(Enable,Data));
2235    END;
2236--
2237    FUNCTION VitalBUFIF1 (
2238            CONSTANT Data, Enable :  IN std_ulogic;
2239            CONSTANT    ResultMap :  IN VitalResultZMapType
2240                                        := VitalDefaultResultZMap
2241          ) RETURN std_ulogic IS
2242    BEGIN
2243        RETURN ResultMap(BufIf1_Table(Enable,Data));
2244    END;
2245    FUNCTION VitalIDENT  (
2246            CONSTANT         Data :  IN std_ulogic;
2247            CONSTANT    ResultMap :  IN VitalResultZMapType
2248                                        := VitalDefaultResultZMap
2249          ) RETURN std_ulogic IS
2250    BEGIN
2251        RETURN ResultMap(To_UX01Z(Data));
2252    END;
2253
2254    -- ------------------------------------------------------------------------
2255    -- Invertors
2256    --   INV    ......... standard inverting buffer
2257    --   INVIF0 ......... inverting buffer Data passes thru if (Enable = '0')
2258    --   INVIF1 ......... inverting buffer Data passes thru if (Enable = '1')
2259    -- ------------------------------------------------------------------------
2260    FUNCTION VitalINV    (
2261            CONSTANT         Data :  IN std_ulogic;
2262            CONSTANT    ResultMap :  IN VitalResultMapType
2263                                        := VitalDefaultResultMap
2264          ) RETURN std_ulogic IS
2265    BEGIN
2266        RETURN ResultMap(NOT Data);
2267    END;
2268--
2269    FUNCTION VitalINVIF0 (
2270            CONSTANT Data, Enable :  IN std_ulogic;
2271            CONSTANT    ResultMap :  IN VitalResultZMapType
2272                                        := VitalDefaultResultZMap
2273          ) RETURN std_ulogic IS
2274    BEGIN
2275        RETURN ResultMap(InvIf0_Table(Enable,Data));
2276    END;
2277--
2278    FUNCTION VitalINVIF1 (
2279            CONSTANT Data, Enable :  IN std_ulogic;
2280            CONSTANT    ResultMap :  IN VitalResultZMapType
2281                                        := VitalDefaultResultZMap
2282          ) RETURN std_ulogic IS
2283    BEGIN
2284        RETURN ResultMap(InvIf1_Table(Enable,Data));
2285    END;
2286
2287    -- ------------------------------------------------------------------------
2288    -- Multiplexor
2289    --   MUX   .......... result := data(dselect)
2290    --   MUX2  .......... 2-input mux; result := data0 when (dselect = '0'),
2291    --                                           data1 when (dselect = '1'),
2292    --                        'X' when (dselect = 'X') and (data0 /= data1)
2293    --   MUX4  .......... 4-input mux; result := data(dselect)
2294    --   MUX8  .......... 8-input mux; result := data(dselect)
2295    -- ------------------------------------------------------------------------
2296    FUNCTION VitalMUX2  (
2297            CONSTANT Data1, Data0 :  IN std_ulogic;
2298            CONSTANT      dSelect :  IN std_ulogic;
2299            CONSTANT    ResultMap :  IN VitalResultMapType
2300                                        := VitalDefaultResultMap
2301          ) RETURN std_ulogic IS
2302        VARIABLE Result : UX01;
2303    BEGIN
2304        CASE To_X01(dSelect) IS
2305          WHEN '0'    => Result := To_UX01(Data0);
2306          WHEN '1'    => Result := To_UX01(Data1);
2307          WHEN OTHERS => Result := VitalSame( Data1, Data0 );
2308        END CASE;
2309        RETURN ResultMap(Result);
2310    END;
2311--
2312    FUNCTION VitalMUX4  (
2313            CONSTANT       Data :  IN std_logic_vector4;
2314            CONSTANT    dSelect :  IN std_logic_vector2;
2315            CONSTANT  ResultMap :  IN VitalResultMapType
2316                                        := VitalDefaultResultMap
2317          ) RETURN std_ulogic IS
2318        VARIABLE Slct : std_logic_vector2;
2319        VARIABLE Result : UX01;
2320    BEGIN
2321        Slct := To_X01(dSelect);
2322        CASE Slct IS
2323          WHEN "00"   => Result := To_UX01(Data(0));
2324          WHEN "01"   => Result := To_UX01(Data(1));
2325          WHEN "10"   => Result := To_UX01(Data(2));
2326          WHEN "11"   => Result := To_UX01(Data(3));
2327          WHEN "0X"   => Result := VitalSame( Data(1), Data(0) );
2328          WHEN "1X"   => Result := VitalSame( Data(2), Data(3) );
2329          WHEN "X0"   => Result := VitalSame( Data(2), Data(0) );
2330          WHEN "X1"   => Result := VitalSame( Data(3), Data(1) );
2331          WHEN OTHERS => Result := VitalSame( VitalSame(Data(3),Data(2)),
2332                                              VitalSame(Data(1),Data(0)));
2333        END CASE;
2334        RETURN ResultMap(Result);
2335    END;
2336--
2337    FUNCTION VitalMUX8  (
2338            CONSTANT       Data :  IN std_logic_vector8;
2339            CONSTANT    dSelect :  IN std_logic_vector3;
2340            CONSTANT  ResultMap :  IN VitalResultMapType
2341                                        := VitalDefaultResultMap
2342          ) RETURN std_ulogic IS
2343        VARIABLE Result : UX01;
2344    BEGIN
2345        CASE To_X01(dSelect(2)) IS
2346          WHEN '0'    => Result := VitalMUX4( Data(3 DOWNTO 0),
2347                                              dSelect(1 DOWNTO 0));
2348          WHEN '1'    => Result := VitalMUX4( Data(7 DOWNTO 4),
2349                                              dSelect(1 DOWNTO 0));
2350          WHEN OTHERS => Result := VitalSame( VitalMUX4( Data(3 DOWNTO 0),
2351                                                         dSelect(1 DOWNTO 0)),
2352                                              VitalMUX4( Data(7 DOWNTO 4),
2353                                                         dSelect(1 DOWNTO 0)));
2354        END CASE;
2355        RETURN ResultMap(Result);
2356    END;
2357--
2358    FUNCTION VInterMux    (
2359            CONSTANT Data    : IN std_logic_vector;
2360            CONSTANT dSelect : IN std_logic_vector
2361          ) RETURN std_ulogic IS
2362
2363        CONSTANT sMsb     : INTEGER := dSelect'LENGTH;
2364        CONSTANT dMsbHigh : INTEGER := Data'LENGTH;
2365        CONSTANT dMsbLow  : INTEGER := Data'LENGTH/2;
2366        ALIAS DataAlias : std_logic_vector (   Data'LENGTH DOWNTO 1) IS Data;
2367        ALIAS dSelAlias : std_logic_vector (dSelect'LENGTH DOWNTO 1) IS dSelect;
2368
2369        VARIABLE Result : UX01;
2370    BEGIN
2371        IF dSelect'LENGTH = 1 THEN
2372            Result := VitalMUX2( DataAlias(2), DataAlias(1), dSelAlias(1) );
2373        ELSIF dSelect'LENGTH = 2 THEN
2374            Result := VitalMUX4( DataAlias, dSelAlias );
2375        ELSIF dSelect'LENGTH > 2 THEN
2376          CASE To_X01(dSelect(sMsb)) IS
2377            WHEN '0'    =>
2378              Result := VInterMux( DataAlias(dMsbLow  DOWNTO          1),
2379                                   dSelAlias(sMsb-1 DOWNTO 1) );
2380            WHEN '1'    =>
2381              Result := VInterMux( DataAlias(dMsbHigh DOWNTO dMsbLow+1),
2382                                   dSelAlias(sMsb-1 DOWNTO 1) );
2383            WHEN OTHERS =>
2384              Result := VitalSame(
2385                              VInterMux( DataAlias(dMsbLow  DOWNTO          1),
2386                                         dSelAlias(sMsb-1 DOWNTO 1) ),
2387                              VInterMux( DataAlias(dMsbHigh DOWNTO dMsbLow+1),
2388                                         dSelAlias(sMsb-1 DOWNTO 1) )
2389                              );
2390          END CASE;
2391        ELSE
2392          Result := 'X'; -- dselect'LENGTH < 1
2393        END IF;
2394        RETURN Result;
2395    END;
2396--
2397    FUNCTION VitalMUX   (
2398            CONSTANT       Data :  IN std_logic_vector;
2399            CONSTANT    dSelect :  IN std_logic_vector;
2400            CONSTANT  ResultMap :  IN VitalResultMapType
2401                                        := VitalDefaultResultMap
2402          ) RETURN std_ulogic IS
2403        CONSTANT msb    : INTEGER := 2**dSelect'LENGTH;
2404        ALIAS DataAlias : std_logic_vector (   Data'LENGTH DOWNTO 1) IS Data;
2405        ALIAS dSelAlias : std_logic_vector (dSelect'LENGTH DOWNTO 1) IS dSelect;
2406        VARIABLE lDat   : std_logic_vector(msb DOWNTO 1) := (OTHERS=>'X');
2407        VARIABLE Result : UX01;
2408    BEGIN
2409        IF Data'LENGTH <= msb THEN
2410            FOR i IN Data'LENGTH DOWNTO 1 LOOP
2411                lDat(i) := DataAlias(i);
2412            END LOOP;
2413        ELSE
2414            FOR i IN msb DOWNTO 1 LOOP
2415                lDat(i) := DataAlias(i);
2416            END LOOP;
2417        END IF;
2418        Result := VInterMux( lDat, dSelAlias );
2419        RETURN ResultMap(Result);
2420    END;
2421
2422    -- ------------------------------------------------------------------------
2423    -- Decoder
2424    --          General Algorithm :
2425    --              (a) Result(...) := '0' when (enable = '0')
2426    --              (b) Result(data) := '1'; all other subelements = '0'
2427    --              ... Result array is decending (n-1 downto 0)
2428    --
2429    --          DECODERn  .......... n:2**n decoder
2430    -- ------------------------------------------------------------------------
2431    FUNCTION VitalDECODER2  (
2432            CONSTANT       Data :  IN std_ulogic;
2433            CONSTANT     Enable :  IN std_ulogic;
2434            CONSTANT  ResultMap :  IN VitalResultMapType
2435                                        := VitalDefaultResultMap
2436          ) RETURN std_logic_vector2 IS
2437        VARIABLE Result : std_logic_vector2;
2438    BEGIN
2439        Result(1) := ResultMap(Enable AND (    Data));
2440        Result(0) := ResultMap(Enable AND (NOT Data));
2441        RETURN Result;
2442    END;
2443--
2444    FUNCTION VitalDECODER4  (
2445            CONSTANT       Data :  IN std_logic_vector2;
2446            CONSTANT     Enable :  IN std_ulogic;
2447            CONSTANT  ResultMap :  IN VitalResultMapType
2448                                        := VitalDefaultResultMap
2449          ) RETURN std_logic_vector4 IS
2450        VARIABLE Result : std_logic_vector4;
2451    BEGIN
2452        Result(3) := ResultMap(Enable AND (    Data(1)) AND (    Data(0)));
2453        Result(2) := ResultMap(Enable AND (    Data(1)) AND (NOT Data(0)));
2454        Result(1) := ResultMap(Enable AND (NOT Data(1)) AND (    Data(0)));
2455        Result(0) := ResultMap(Enable AND (NOT Data(1)) AND (NOT Data(0)));
2456        RETURN Result;
2457    END;
2458--
2459    FUNCTION VitalDECODER8  (
2460            CONSTANT       Data :  IN std_logic_vector3;
2461            CONSTANT     Enable :  IN std_ulogic;
2462            CONSTANT  ResultMap :  IN VitalResultMapType
2463                                        := VitalDefaultResultMap
2464          ) RETURN std_logic_vector8 IS
2465        VARIABLE Result : std_logic_vector8;
2466    BEGIN
2467        Result(7) := (    Data(2)) AND (    Data(1)) AND (    Data(0));
2468        Result(6) := (    Data(2)) AND (    Data(1)) AND (NOT Data(0));
2469        Result(5) := (    Data(2)) AND (NOT Data(1)) AND (    Data(0));
2470        Result(4) := (    Data(2)) AND (NOT Data(1)) AND (NOT Data(0));
2471        Result(3) := (NOT Data(2)) AND (    Data(1)) AND (    Data(0));
2472        Result(2) := (NOT Data(2)) AND (    Data(1)) AND (NOT Data(0));
2473        Result(1) := (NOT Data(2)) AND (NOT Data(1)) AND (    Data(0));
2474        Result(0) := (NOT Data(2)) AND (NOT Data(1)) AND (NOT Data(0));
2475
2476        Result(0) := ResultMap ( Enable AND Result(0) );
2477        Result(1) := ResultMap ( Enable AND Result(1) );
2478        Result(2) := ResultMap ( Enable AND Result(2) );
2479        Result(3) := ResultMap ( Enable AND Result(3) );
2480        Result(4) := ResultMap ( Enable AND Result(4) );
2481        Result(5) := ResultMap ( Enable AND Result(5) );
2482        Result(6) := ResultMap ( Enable AND Result(6) );
2483        Result(7) := ResultMap ( Enable AND Result(7) );
2484
2485        RETURN Result;
2486    END;
2487--
2488    FUNCTION VitalDECODER   (
2489            CONSTANT       Data :  IN std_logic_vector;
2490            CONSTANT     Enable :  IN std_ulogic;
2491            CONSTANT  ResultMap :  IN VitalResultMapType
2492                                        := VitalDefaultResultMap
2493          ) RETURN std_logic_vector IS
2494
2495        CONSTANT DMsb : INTEGER := Data'LENGTH - 1;
2496        ALIAS DataAlias : std_logic_vector ( DMsb DOWNTO 0 ) IS Data;
2497    BEGIN
2498        IF    Data'LENGTH = 1 THEN
2499            RETURN VitalDECODER2 (DataAlias(    0     ), Enable, ResultMap );
2500        ELSIF Data'LENGTH = 2 THEN
2501            RETURN VitalDECODER4 (DataAlias(1 DOWNTO 0), Enable, ResultMap );
2502        ELSIF Data'LENGTH = 3 THEN
2503            RETURN VitalDECODER8 (DataAlias(2 DOWNTO 0), Enable, ResultMap );
2504        ELSIF Data'LENGTH > 3 THEN
2505            RETURN VitalDECODER  (DataAlias(DMsb-1 DOWNTO 0),
2506                                  Enable AND (    DataAlias(DMsb)), ResultMap )
2507                 & VitalDECODER  (DataAlias(DMsb-1 DOWNTO 0),
2508                                  Enable AND (NOT DataAlias(DMsb)), ResultMap );
2509        ELSE RETURN "X";
2510        END IF;
2511    END;
2512
2513    -- ------------------------------------------------------------------------
2514    -- N-bit wide Logical gates.
2515    -- ------------------------------------------------------------------------
2516    PROCEDURE VitalAND   (
2517            SIGNAL            q : OUT std_ulogic;
2518            SIGNAL         Data :  IN std_logic_vector;
2519            CONSTANT tpd_data_q :  IN VitalDelayArrayType01;
2520            CONSTANT  ResultMap :  IN VitalResultMapType
2521                                        := VitalDefaultResultMap
2522    ) IS
2523        VARIABLE LastData  : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
2524        VARIABLE Data_Edge :  EdgeArray(Data'RANGE);
2525        VARIABLE Data_Schd : SchedArray(Data'RANGE);
2526        VARIABLE NewValue     : UX01;
2527        VARIABLE Glitch_Data : GlitchDataType;
2528        VARIABLE new_schd    : SchedType;
2529        VARIABLE Dly, Glch   : TIME;
2530        ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
2531        VARIABLE AllZeroDelay  : BOOLEAN := TRUE; --SN
2532    BEGIN
2533      -- ------------------------------------------------------------------------
2534      --  Check if ALL zero delay paths, use simple model
2535      --   ( No delay selection, glitch detection required )
2536      -- ------------------------------------------------------------------------
2537      FOR i IN Data'RANGE LOOP
2538          IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
2539              AllZeroDelay := FALSE;
2540              EXIT;
2541          END IF;
2542      END LOOP;
2543      IF (AllZeroDelay) THEN LOOP
2544          q <= VitalAND(Data, ResultMap);
2545          WAIT ON Data;
2546      END LOOP;
2547      ELSE
2548
2549        -- --------------------------------------
2550        -- Initialize delay schedules
2551        -- --------------------------------------
2552        FOR n IN Data'RANGE LOOP
2553            BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
2554        END LOOP;
2555
2556      LOOP
2557        -- --------------------------------------
2558        -- Process input signals
2559        --   get edge values
2560        --   re-evaluate output schedules
2561        -- --------------------------------------
2562        GetEdge ( Data, LastData, Data_Edge );
2563        BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
2564
2565        -- ------------------------------------
2566        -- Compute function and propation delay
2567        -- ------------------------------------
2568        NewValue := '1';
2569        new_schd := Data_Schd(Data_Schd'LEFT);
2570        FOR i IN Data'RANGE LOOP
2571            NewValue  := NewValue  AND Data(i);
2572            new_schd := new_schd AND Data_Schd(i);
2573        END LOOP;
2574
2575        -- ------------------------------------------------------
2576        -- Assign Outputs
2577        --  get delays to new value and possable glitch
2578        --  schedule output change with On Event glitch detection
2579        -- ------------------------------------------------------
2580        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
2581        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
2582                             PrimGlitchMode, GlitchDelay=>Glch );
2583
2584        WAIT ON Data;
2585      END LOOP;
2586      END IF; --SN
2587    END;
2588--
2589    PROCEDURE VitalOR    (
2590            SIGNAL            q : OUT std_ulogic;
2591            SIGNAL         Data :  IN std_logic_vector;
2592            CONSTANT tpd_data_q :  IN VitalDelayArrayType01;
2593            CONSTANT  ResultMap :  IN VitalResultMapType
2594                                        := VitalDefaultResultMap
2595    ) IS
2596        VARIABLE LastData  : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
2597        VARIABLE Data_Edge :  EdgeArray(Data'RANGE);
2598        VARIABLE Data_Schd : SchedArray(Data'RANGE);
2599        VARIABLE NewValue     : UX01;
2600        VARIABLE Glitch_Data : GlitchDataType;
2601        VARIABLE new_schd    : SchedType;
2602        VARIABLE Dly, Glch   : TIME;
2603        ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
2604        VARIABLE AllZeroDelay  : BOOLEAN := TRUE; --SN
2605    BEGIN
2606      -- ------------------------------------------------------------------------
2607      --  Check if ALL zero delay paths, use simple model
2608      --   ( No delay selection, glitch detection required )
2609      -- ------------------------------------------------------------------------
2610      FOR i IN Data'RANGE LOOP
2611          IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
2612              AllZeroDelay := FALSE;
2613              EXIT;
2614          END IF;
2615      END LOOP;
2616      IF (AllZeroDelay) THEN LOOP
2617          q <= VitalOR(Data, ResultMap);
2618          WAIT ON Data;
2619      END LOOP;
2620      ELSE
2621
2622        -- --------------------------------------
2623        -- Initialize delay schedules
2624        -- --------------------------------------
2625        FOR n IN Data'RANGE LOOP
2626            BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
2627        END LOOP;
2628
2629      LOOP
2630        -- --------------------------------------
2631        -- Process input signals
2632        --   get edge values
2633        --   re-evaluate output schedules
2634        -- --------------------------------------
2635        GetEdge ( Data, LastData, Data_Edge );
2636        BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
2637
2638        -- ------------------------------------
2639        -- Compute function and propation delay
2640        -- ------------------------------------
2641        NewValue := '0';
2642        new_schd := Data_Schd(Data_Schd'LEFT);
2643        FOR i IN Data'RANGE LOOP
2644            NewValue  := NewValue  OR Data(i);
2645            new_schd := new_schd OR Data_Schd(i);
2646        END LOOP;
2647
2648        -- ------------------------------------------------------
2649        -- Assign Outputs
2650        --  get delays to new value and possable glitch
2651        --  schedule output change with On Event glitch detection
2652        -- ------------------------------------------------------
2653        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
2654        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
2655                             PrimGlitchMode, GlitchDelay=>Glch );
2656
2657        WAIT ON Data;
2658      END LOOP;
2659      END IF; --SN
2660    END;
2661--
2662    PROCEDURE VitalXOR   (
2663            SIGNAL            q : OUT std_ulogic;
2664            SIGNAL         Data :  IN std_logic_vector;
2665            CONSTANT tpd_data_q :  IN VitalDelayArrayType01;
2666            CONSTANT  ResultMap :  IN VitalResultMapType
2667                                        := VitalDefaultResultMap
2668    ) IS
2669        VARIABLE LastData  : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
2670        VARIABLE Data_Edge   :  EdgeArray(Data'RANGE);
2671        VARIABLE DataB_Schd  : SchedArray(1 TO Data'LENGTH);
2672        VARIABLE DataI_Schd  : SchedArray(1 TO Data'LENGTH);
2673        VARIABLE NewValue     : UX01;
2674        VARIABLE Glitch_Data : GlitchDataType;
2675        VARIABLE new_schd    : SchedType;
2676        VARIABLE Dly, Glch   : TIME;
2677        ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
2678        ALIAS ADataB_Schd : SchedArray(Data'RANGE) IS DataB_Schd;
2679        ALIAS ADataI_Schd : SchedArray(Data'RANGE) IS DataI_Schd;
2680        VARIABLE AllZeroDelay  : BOOLEAN := TRUE; --SN
2681    BEGIN
2682      -- ------------------------------------------------------------------------
2683      --  Check if ALL zero delay paths, use simple model
2684      --   ( No delay selection, glitch detection required )
2685      -- ------------------------------------------------------------------------
2686      FOR i IN Data'RANGE LOOP
2687          IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
2688              AllZeroDelay := FALSE;
2689              EXIT;
2690          END IF;
2691      END LOOP;
2692      IF (AllZeroDelay) THEN LOOP
2693          q <= VitalXOR(Data, ResultMap);
2694          WAIT ON Data;
2695      END LOOP;
2696      ELSE
2697
2698        -- --------------------------------------
2699        -- Initialize delay schedules
2700        -- --------------------------------------
2701        FOR n IN Data'RANGE LOOP
2702            BufPath ( ADataB_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
2703            InvPath ( ADataI_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
2704        END LOOP;
2705
2706      LOOP
2707        -- --------------------------------------
2708        -- Process input signals
2709        --   get edge values
2710        --   re-evaluate output schedules
2711        -- --------------------------------------
2712        GetEdge ( Data, LastData, Data_Edge );
2713        BufPath ( ADataB_Schd, Data_Edge, Atpd_data_q );
2714        InvPath ( ADataI_Schd, Data_Edge, Atpd_data_q );
2715
2716        -- ------------------------------------
2717        -- Compute function and propation delay
2718        -- ------------------------------------
2719        NewValue  := VitalXOR ( Data );
2720        new_schd := VitalXOR ( DataB_Schd, DataI_Schd );
2721
2722        -- ------------------------------------------------------
2723        -- Assign Outputs
2724        --  get delays to new value and possable glitch
2725        --  schedule output change with On Event glitch detection
2726        -- ------------------------------------------------------
2727        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
2728        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
2729                             PrimGlitchMode, GlitchDelay=>Glch );
2730
2731        WAIT ON Data;
2732      END LOOP;
2733      END IF; --SN
2734    END;
2735--
2736    PROCEDURE VitalNAND  (
2737            SIGNAL            q : OUT std_ulogic;
2738            SIGNAL         Data :  IN std_logic_vector;
2739            CONSTANT tpd_data_q :  IN VitalDelayArrayType01;
2740            CONSTANT  ResultMap :  IN VitalResultMapType
2741                                        := VitalDefaultResultMap
2742    ) IS
2743        VARIABLE LastData  : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
2744        VARIABLE Data_Edge :  EdgeArray(Data'RANGE);
2745        VARIABLE Data_Schd : SchedArray(Data'RANGE);
2746        VARIABLE NewValue     : UX01;
2747        VARIABLE Glitch_Data : GlitchDataType;
2748        VARIABLE new_schd    : SchedType;
2749        VARIABLE Dly, Glch   : TIME;
2750        ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
2751        VARIABLE AllZeroDelay  : BOOLEAN := TRUE; --SN
2752    BEGIN
2753      -- ------------------------------------------------------------------------
2754      --  Check if ALL zero delay paths, use simple model
2755      --   ( No delay selection, glitch detection required )
2756      -- ------------------------------------------------------------------------
2757      FOR i IN Data'RANGE LOOP
2758          IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
2759              AllZeroDelay := FALSE;
2760              EXIT;
2761          END IF;
2762      END LOOP;
2763      IF (AllZeroDelay) THEN LOOP
2764          q <= VitalNAND(Data, ResultMap);
2765          WAIT ON Data;
2766      END LOOP;
2767      ELSE
2768
2769        -- --------------------------------------
2770        -- Initialize delay schedules
2771        -- --------------------------------------
2772        FOR n IN Data'RANGE LOOP
2773            InvPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
2774        END LOOP;
2775
2776      LOOP
2777        -- --------------------------------------
2778        -- Process input signals
2779        --   get edge values
2780        --   re-evaluate output schedules
2781        -- --------------------------------------
2782        GetEdge ( Data, LastData, Data_Edge );
2783        InvPath ( Data_Schd, Data_Edge, Atpd_data_q );
2784
2785        -- ------------------------------------
2786        -- Compute function and propation delay
2787        -- ------------------------------------
2788        NewValue := '1';
2789        new_schd := Data_Schd(Data_Schd'LEFT);
2790        FOR i IN Data'RANGE LOOP
2791            NewValue  := NewValue  AND Data(i);
2792            new_schd := new_schd AND Data_Schd(i);
2793        END LOOP;
2794        NewValue  := NOT NewValue;
2795        new_schd := NOT new_schd;
2796
2797        -- ------------------------------------------------------
2798        -- Assign Outputs
2799        --  get delays to new value and possable glitch
2800        --  schedule output change with On Event glitch detection
2801        -- ------------------------------------------------------
2802        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
2803        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
2804                             PrimGlitchMode, GlitchDelay=>Glch );
2805
2806        WAIT ON Data;
2807      END LOOP;
2808      END IF;
2809    END;
2810--
2811    PROCEDURE VitalNOR   (
2812            SIGNAL            q : OUT std_ulogic;
2813            SIGNAL         Data :  IN std_logic_vector;
2814            CONSTANT tpd_data_q :  IN VitalDelayArrayType01;
2815            CONSTANT  ResultMap :  IN VitalResultMapType
2816                                        := VitalDefaultResultMap
2817    ) IS
2818        VARIABLE LastData  : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
2819        VARIABLE Data_Edge :  EdgeArray(Data'RANGE);
2820        VARIABLE Data_Schd : SchedArray(Data'RANGE);
2821        VARIABLE NewValue     : UX01;
2822        VARIABLE Glitch_Data : GlitchDataType;
2823        VARIABLE new_schd    : SchedType;
2824        VARIABLE Dly, Glch   : TIME;
2825        ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
2826        VARIABLE AllZeroDelay  : BOOLEAN := TRUE; --SN
2827    BEGIN
2828      -- ------------------------------------------------------------------------
2829      --  Check if ALL zero delay paths, use simple model
2830      --   ( No delay selection, glitch detection required )
2831      -- ------------------------------------------------------------------------
2832      FOR i IN Data'RANGE LOOP
2833          IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
2834              AllZeroDelay := FALSE;
2835              EXIT;
2836          END IF;
2837      END LOOP;
2838      IF (AllZeroDelay) THEN LOOP
2839          q <= VitalNOR(Data, ResultMap);
2840          WAIT ON Data;
2841      END LOOP;
2842      ELSE
2843
2844        -- --------------------------------------
2845        -- Initialize delay schedules
2846        -- --------------------------------------
2847        FOR n IN Data'RANGE LOOP
2848            InvPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
2849        END LOOP;
2850
2851      LOOP
2852        -- --------------------------------------
2853        -- Process input signals
2854        --   get edge values
2855        --   re-evaluate output schedules
2856        -- --------------------------------------
2857        GetEdge ( Data, LastData, Data_Edge );
2858        InvPath ( Data_Schd, Data_Edge, Atpd_data_q );
2859
2860        -- ------------------------------------
2861        -- Compute function and propation delay
2862        -- ------------------------------------
2863        NewValue := '0';
2864        new_schd := Data_Schd(Data_Schd'LEFT);
2865        FOR i IN Data'RANGE LOOP
2866            NewValue  := NewValue  OR Data(i);
2867            new_schd := new_schd OR Data_Schd(i);
2868        END LOOP;
2869        NewValue  := NOT NewValue;
2870        new_schd := NOT new_schd;
2871
2872        -- ------------------------------------------------------
2873        -- Assign Outputs
2874        --  get delays to new value and possable glitch
2875        --  schedule output change with On Event glitch detection
2876        -- ------------------------------------------------------
2877        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
2878        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
2879                             PrimGlitchMode, GlitchDelay=>Glch );
2880
2881        WAIT ON Data;
2882      END LOOP;
2883      END IF; --SN
2884    END;
2885--
2886    PROCEDURE VitalXNOR  (
2887            SIGNAL            q : OUT std_ulogic;
2888            SIGNAL         Data :  IN std_logic_vector;
2889            CONSTANT tpd_data_q :  IN VitalDelayArrayType01;
2890            CONSTANT  ResultMap :  IN VitalResultMapType
2891                                        := VitalDefaultResultMap
2892    ) IS
2893        VARIABLE LastData    : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
2894        VARIABLE Data_Edge   :  EdgeArray(Data'RANGE);
2895        VARIABLE DataB_Schd  : SchedArray(1 TO Data'LENGTH);
2896        VARIABLE DataI_Schd  : SchedArray(1 TO Data'LENGTH);
2897        VARIABLE NewValue     : UX01;
2898        VARIABLE Glitch_Data : GlitchDataType;
2899        VARIABLE new_schd    : SchedType;
2900        VARIABLE Dly, Glch   : TIME;
2901        ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
2902        ALIAS ADataB_Schd : SchedArray(Data'RANGE) IS DataB_Schd;
2903        ALIAS ADataI_Schd : SchedArray(Data'RANGE) IS DataI_Schd;
2904        VARIABLE AllZeroDelay  : BOOLEAN := TRUE; --SN
2905    BEGIN
2906      -- ------------------------------------------------------------------------
2907      --  Check if ALL zero delay paths, use simple model
2908      --   ( No delay selection, glitch detection required )
2909      -- ------------------------------------------------------------------------
2910      FOR i IN Data'RANGE LOOP
2911          IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
2912              AllZeroDelay := FALSE;
2913              EXIT;
2914          END IF;
2915      END LOOP;
2916      IF (AllZeroDelay) THEN LOOP
2917          q <= VitalXNOR(Data, ResultMap);
2918          WAIT ON Data;
2919      END LOOP;
2920      ELSE
2921
2922        -- --------------------------------------
2923        -- Initialize delay schedules
2924        -- --------------------------------------
2925        FOR n IN Data'RANGE LOOP
2926            BufPath ( ADataB_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
2927            InvPath ( ADataI_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
2928        END LOOP;
2929
2930      LOOP
2931        -- --------------------------------------
2932        -- Process input signals
2933        --   get edge values
2934        --   re-evaluate output schedules
2935        -- --------------------------------------
2936        GetEdge ( Data, LastData, Data_Edge );
2937        BufPath ( ADataB_Schd, Data_Edge, Atpd_data_q );
2938        InvPath ( ADataI_Schd, Data_Edge, Atpd_data_q );
2939
2940        -- ------------------------------------
2941        -- Compute function and propation delay
2942        -- ------------------------------------
2943        NewValue  := VitalXNOR ( Data );
2944        new_schd := VitalXNOR ( DataB_Schd, DataI_Schd );
2945
2946        -- ------------------------------------------------------
2947        -- Assign Outputs
2948        --  get delays to new value and possable glitch
2949        --  schedule output change with On Event glitch detection
2950        -- ------------------------------------------------------
2951        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
2952        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
2953                             PrimGlitchMode, GlitchDelay=>Glch );
2954
2955        WAIT ON Data;
2956      END LOOP;
2957      END IF; --SN
2958    END;
2959--
2960
2961    -- ------------------------------------------------------------------------
2962    -- Commonly used 2-bit Logical gates.
2963    -- ------------------------------------------------------------------------
2964    PROCEDURE VitalAND2  (
2965            SIGNAL            q : OUT std_ulogic;
2966            SIGNAL         a, b :  IN std_ulogic   ;
2967            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
2968            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
2969            CONSTANT  ResultMap :  IN VitalResultMapType
2970                                        := VitalDefaultResultMap
2971    ) IS
2972        VARIABLE a_schd, b_schd : SchedType;
2973        VARIABLE NewValue        : UX01;
2974        VARIABLE Glitch_Data    : GlitchDataType;
2975        VARIABLE new_schd       : SchedType;
2976        VARIABLE Dly, Glch      : TIME;
2977    BEGIN
2978
2979    -- ------------------------------------------------------------------------
2980    --  For ALL zero delay paths, use simple model
2981    --   ( No delay selection, glitch detection required )
2982    -- ------------------------------------------------------------------------
2983    IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
2984      LOOP
2985        q <= VitalAND2 ( a, b, ResultMap );
2986        WAIT ON a, b;
2987      END LOOP;
2988
2989    ELSE
2990        -- --------------------------------------
2991        -- Initialize delay schedules
2992        -- --------------------------------------
2993        BufPath ( a_schd, InitialEdge(a), tpd_a_q );
2994        BufPath ( b_schd, InitialEdge(b), tpd_b_q );
2995
2996      LOOP
2997        -- --------------------------------------
2998        -- Process input signals
2999        --   get edge values
3000        --   re-evaluate output schedules
3001        -- --------------------------------------
3002        BufPath ( a_schd, GetEdge(a), tpd_a_q );
3003        BufPath ( b_schd, GetEdge(b), tpd_b_q );
3004
3005        -- ------------------------------------
3006        -- Compute function and propation delay
3007        -- ------------------------------------
3008        NewValue := a AND b;
3009        new_schd := a_schd AND b_schd;
3010
3011        -- ------------------------------------------------------
3012        -- Assign Outputs
3013        --  get delays to new value and possable glitch
3014        --  schedule output change with On Event glitch detection
3015        -- ------------------------------------------------------
3016        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3017        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3018                             PrimGlitchMode, GlitchDelay=>Glch );
3019
3020        WAIT ON a, b;
3021      END LOOP;
3022    END IF;
3023    END;
3024--
3025    PROCEDURE VitalOR2   (
3026            SIGNAL            q : OUT std_ulogic;
3027            SIGNAL         a, b :  IN std_ulogic   ;
3028            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3029            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3030            CONSTANT  ResultMap :  IN VitalResultMapType
3031                                        := VitalDefaultResultMap
3032    ) IS
3033        VARIABLE a_schd, b_schd : SchedType;
3034        VARIABLE NewValue        : UX01;
3035        VARIABLE Glitch_Data    : GlitchDataType;
3036        VARIABLE new_schd       : SchedType;
3037        VARIABLE Dly, Glch      : TIME;
3038    BEGIN
3039
3040    -- ------------------------------------------------------------------------
3041    --  For ALL zero delay paths, use simple model
3042    --   ( No delay selection, glitch detection required )
3043    -- ------------------------------------------------------------------------
3044    IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
3045      LOOP
3046        q <= VitalOR2 ( a, b, ResultMap );
3047        WAIT ON a, b;
3048      END LOOP;
3049
3050    ELSE
3051        -- --------------------------------------
3052        -- Initialize delay schedules
3053        -- --------------------------------------
3054        BufPath ( a_schd, InitialEdge(a), tpd_a_q );
3055        BufPath ( b_schd, InitialEdge(b), tpd_b_q );
3056
3057      LOOP
3058        -- --------------------------------------
3059        -- Process input signals
3060        --   get edge values
3061        --   re-evaluate output schedules
3062        -- --------------------------------------
3063        BufPath ( a_schd, GetEdge(a), tpd_a_q );
3064        BufPath ( b_schd, GetEdge(b), tpd_b_q );
3065
3066        -- ------------------------------------
3067        -- Compute function and propation delay
3068        -- ------------------------------------
3069        NewValue := a OR b;
3070        new_schd := a_schd OR b_schd;
3071
3072        -- ------------------------------------------------------
3073        -- Assign Outputs
3074        --  get delays to new value and possable glitch
3075        --  schedule output change with On Event glitch detection
3076        -- ------------------------------------------------------
3077        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3078        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3079                             PrimGlitchMode, GlitchDelay=>Glch );
3080
3081        WAIT ON a, b;
3082      END LOOP;
3083    END IF;
3084    END;
3085--
3086    PROCEDURE VitalNAND2 (
3087            SIGNAL            q : OUT std_ulogic;
3088            SIGNAL         a, b :  IN std_ulogic   ;
3089            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3090            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3091            CONSTANT  ResultMap :  IN VitalResultMapType
3092                                        := VitalDefaultResultMap
3093    ) IS
3094        VARIABLE a_schd, b_schd : SchedType;
3095        VARIABLE NewValue        : UX01;
3096        VARIABLE Glitch_Data    : GlitchDataType;
3097        VARIABLE new_schd       : SchedType;
3098        VARIABLE Dly, Glch      : TIME;
3099    BEGIN
3100
3101    -- ------------------------------------------------------------------------
3102    --  For ALL zero delay paths, use simple model
3103    --   ( No delay selection, glitch detection required )
3104    -- ------------------------------------------------------------------------
3105    IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
3106      LOOP
3107        q <= VitalNAND2 ( a, b, ResultMap );
3108        WAIT ON a, b;
3109      END LOOP;
3110
3111    ELSE
3112        -- --------------------------------------
3113        -- Initialize delay schedules
3114        -- --------------------------------------
3115        InvPath ( a_schd, InitialEdge(a), tpd_a_q );
3116        InvPath ( b_schd, InitialEdge(b), tpd_b_q );
3117
3118      LOOP
3119        -- --------------------------------------
3120        -- Process input signals
3121        --   get edge values
3122        --   re-evaluate output schedules
3123        -- --------------------------------------
3124        InvPath ( a_schd, GetEdge(a), tpd_a_q );
3125        InvPath ( b_schd, GetEdge(b), tpd_b_q );
3126
3127        -- ------------------------------------
3128        -- Compute function and propation delay
3129        -- ------------------------------------
3130        NewValue := a NAND b;
3131        new_schd := a_schd NAND b_schd;
3132
3133        -- ------------------------------------------------------
3134        -- Assign Outputs
3135        --  get delays to new value and possable glitch
3136        --  schedule output change with On Event glitch detection
3137        -- ------------------------------------------------------
3138        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3139        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3140                             PrimGlitchMode, GlitchDelay=>Glch );
3141
3142        WAIT ON a, b;
3143      END LOOP;
3144    END IF;
3145    END;
3146--
3147    PROCEDURE VitalNOR2  (
3148            SIGNAL            q : OUT std_ulogic;
3149            SIGNAL         a, b :  IN std_ulogic   ;
3150            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3151            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3152            CONSTANT  ResultMap :  IN VitalResultMapType
3153                                        := VitalDefaultResultMap
3154    ) IS
3155        VARIABLE a_schd, b_schd : SchedType;
3156        VARIABLE NewValue        : UX01;
3157        VARIABLE Glitch_Data    : GlitchDataType;
3158        VARIABLE new_schd       : SchedType;
3159        VARIABLE Dly, Glch      : TIME;
3160    BEGIN
3161
3162    -- ------------------------------------------------------------------------
3163    --  For ALL zero delay paths, use simple model
3164    --   ( No delay selection, glitch detection required )
3165    -- ------------------------------------------------------------------------
3166    IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
3167      LOOP
3168        q <= VitalNOR2 ( a, b, ResultMap );
3169        WAIT ON a, b;
3170      END LOOP;
3171
3172    ELSE
3173        -- --------------------------------------
3174        -- Initialize delay schedules
3175        -- --------------------------------------
3176        InvPath ( a_schd, InitialEdge(a), tpd_a_q );
3177        InvPath ( b_schd, InitialEdge(b), tpd_b_q );
3178
3179      LOOP
3180        -- --------------------------------------
3181        -- Process input signals
3182        --   get edge values
3183        --   re-evaluate output schedules
3184        -- --------------------------------------
3185        InvPath ( a_schd, GetEdge(a), tpd_a_q );
3186        InvPath ( b_schd, GetEdge(b), tpd_b_q );
3187
3188        -- ------------------------------------
3189        -- Compute function and propation delay
3190        -- ------------------------------------
3191        NewValue := a NOR b;
3192        new_schd := a_schd NOR b_schd;
3193
3194        -- ------------------------------------------------------
3195        -- Assign Outputs
3196        --  get delays to new value and possable glitch
3197        --  schedule output change with On Event glitch detection
3198        -- ------------------------------------------------------
3199        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3200        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3201                             PrimGlitchMode, GlitchDelay=>Glch );
3202
3203        WAIT ON a, b;
3204      END LOOP;
3205    END IF;
3206    END;
3207--
3208    PROCEDURE VitalXOR2  (
3209            SIGNAL            q : OUT std_ulogic;
3210            SIGNAL         a, b :  IN std_ulogic   ;
3211            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3212            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3213            CONSTANT  ResultMap :  IN VitalResultMapType
3214                                        := VitalDefaultResultMap
3215    ) IS
3216        VARIABLE ab_schd, bb_schd : SchedType;
3217        VARIABLE ai_schd, bi_schd : SchedType;
3218        VARIABLE NewValue        : UX01;
3219        VARIABLE Glitch_Data    : GlitchDataType;
3220        VARIABLE new_schd       : SchedType;
3221        VARIABLE Dly, Glch      : TIME;
3222    BEGIN
3223
3224    -- ------------------------------------------------------------------------
3225    --  For ALL zero delay paths, use simple model
3226    --   ( No delay selection, glitch detection required )
3227    -- ------------------------------------------------------------------------
3228    IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
3229      LOOP
3230        q <= VitalXOR2 ( a, b, ResultMap );
3231        WAIT ON a, b;
3232      END LOOP;
3233
3234    ELSE
3235        -- --------------------------------------
3236        -- Initialize delay schedules
3237        -- --------------------------------------
3238        BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
3239        InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
3240        BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
3241        InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
3242
3243      LOOP
3244        -- --------------------------------------
3245        -- Process input signals
3246        --   get edge values
3247        --   re-evaluate output schedules
3248        -- --------------------------------------
3249        BufPath ( ab_schd, GetEdge(a), tpd_a_q );
3250        InvPath ( ai_schd, GetEdge(a), tpd_a_q );
3251
3252        BufPath ( bb_schd, GetEdge(b), tpd_b_q );
3253        InvPath ( bi_schd, GetEdge(b), tpd_b_q );
3254
3255        -- ------------------------------------
3256        -- Compute function and propation delay
3257        -- ------------------------------------
3258        NewValue  := a XOR b;
3259        new_schd := VitalXOR2 ( ab_schd,ai_schd, bb_schd,bi_schd );
3260
3261        -- ------------------------------------------------------
3262        -- Assign Outputs
3263        --  get delays to new value and possable glitch
3264        --  schedule output change with On Event glitch detection
3265        -- ------------------------------------------------------
3266        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3267        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3268                             PrimGlitchMode, GlitchDelay=>Glch );
3269
3270        WAIT ON a, b;
3271      END LOOP;
3272    END IF;
3273    END;
3274--
3275    PROCEDURE VitalXNOR2 (
3276            SIGNAL            q : OUT std_ulogic;
3277            SIGNAL         a, b :  IN std_ulogic   ;
3278            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3279            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3280            CONSTANT  ResultMap :  IN VitalResultMapType
3281                                        := VitalDefaultResultMap
3282    ) IS
3283        VARIABLE ab_schd, bb_schd : SchedType;
3284        VARIABLE ai_schd, bi_schd : SchedType;
3285        VARIABLE NewValue        : UX01;
3286        VARIABLE Glitch_Data    : GlitchDataType;
3287        VARIABLE new_schd       : SchedType;
3288        VARIABLE Dly, Glch      : TIME;
3289    BEGIN
3290
3291    -- ------------------------------------------------------------------------
3292    --  For ALL zero delay paths, use simple model
3293    --   ( No delay selection, glitch detection required )
3294    -- ------------------------------------------------------------------------
3295    IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
3296      LOOP
3297        q <= VitalXNOR2 ( a, b, ResultMap );
3298        WAIT ON a, b;
3299      END LOOP;
3300
3301    ELSE
3302        -- --------------------------------------
3303        -- Initialize delay schedules
3304        -- --------------------------------------
3305        BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
3306        InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
3307        BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
3308        InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
3309
3310      LOOP
3311        -- --------------------------------------
3312        -- Process input signals
3313        --   get edge values
3314        --   re-evaluate output schedules
3315        -- --------------------------------------
3316        BufPath ( ab_schd, GetEdge(a), tpd_a_q );
3317        InvPath ( ai_schd, GetEdge(a), tpd_a_q );
3318
3319        BufPath ( bb_schd, GetEdge(b), tpd_b_q );
3320        InvPath ( bi_schd, GetEdge(b), tpd_b_q );
3321
3322        -- ------------------------------------
3323        -- Compute function and propation delay
3324        -- ------------------------------------
3325        NewValue  := NOT (a XOR b);
3326        new_schd := VitalXNOR2 ( ab_schd,ai_schd, bb_schd,bi_schd );
3327
3328        -- ------------------------------------------------------
3329        -- Assign Outputs
3330        --  get delays to new value and possable glitch
3331        --  schedule output change with On Event glitch detection
3332        -- ------------------------------------------------------
3333        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3334        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3335                             PrimGlitchMode, GlitchDelay=>Glch );
3336
3337        WAIT ON a, b;
3338      END LOOP;
3339    END IF;
3340    END;
3341
3342    -- ------------------------------------------------------------------------
3343    -- Commonly used 3-bit Logical gates.
3344    -- ------------------------------------------------------------------------
3345    PROCEDURE VitalAND3  (
3346            SIGNAL            q : OUT std_ulogic;
3347            SIGNAL      a, b, c :  IN std_ulogic   ;
3348            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3349            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3350            CONSTANT    tpd_c_q :  IN VitalDelayType01    := VitalDefDelay01;
3351            CONSTANT  ResultMap :  IN VitalResultMapType
3352                                        := VitalDefaultResultMap
3353    ) IS
3354        VARIABLE a_schd, b_schd, c_schd : SchedType;
3355        VARIABLE NewValue        : UX01;
3356        VARIABLE Glitch_Data    : GlitchDataType;
3357        VARIABLE new_schd       : SchedType;
3358        VARIABLE Dly, Glch      : TIME;
3359    BEGIN
3360--
3361    -- ------------------------------------------------------------------------
3362    --  For ALL zero delay paths, use simple model
3363    --   ( No delay selection, glitch detection required )
3364    -- ------------------------------------------------------------------------
3365    IF (     (tpd_a_q = VitalZeroDelay01)
3366         AND (tpd_b_q = VitalZeroDelay01)
3367         AND (tpd_c_q = VitalZeroDelay01)) THEN
3368      LOOP
3369        q <= VitalAND3 ( a, b, c, ResultMap );
3370        WAIT ON a, b, c;
3371      END LOOP;
3372
3373    ELSE
3374        -- --------------------------------------
3375        -- Initialize delay schedules
3376        -- --------------------------------------
3377        BufPath ( a_schd, InitialEdge(a), tpd_a_q );
3378        BufPath ( b_schd, InitialEdge(b), tpd_b_q );
3379        BufPath ( c_schd, InitialEdge(c), tpd_c_q );
3380
3381      LOOP
3382        -- --------------------------------------
3383        -- Process input signals
3384        --   get edge values
3385        --   re-evaluate output schedules
3386        -- --------------------------------------
3387        BufPath ( a_schd, GetEdge(a), tpd_a_q );
3388        BufPath ( b_schd, GetEdge(b), tpd_b_q );
3389        BufPath ( c_schd, GetEdge(c), tpd_c_q );
3390
3391        -- ------------------------------------
3392        -- Compute function and propation delay
3393        -- ------------------------------------
3394        NewValue  := a AND b AND c;
3395        new_schd := a_schd AND b_schd AND c_schd;
3396
3397        -- ------------------------------------------------------
3398        -- Assign Outputs
3399        --  get delays to new value and possable glitch
3400        --  schedule output change with On Event glitch detection
3401        -- ------------------------------------------------------
3402        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3403        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3404                             PrimGlitchMode, GlitchDelay=>Glch );
3405
3406        WAIT ON a, b, c;
3407      END LOOP;
3408    END IF;
3409    END;
3410--
3411    PROCEDURE VitalOR3   (
3412            SIGNAL            q : OUT std_ulogic;
3413            SIGNAL      a, b, c :  IN std_ulogic   ;
3414            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3415            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3416            CONSTANT    tpd_c_q :  IN VitalDelayType01    := VitalDefDelay01;
3417            CONSTANT  ResultMap :  IN VitalResultMapType
3418                                        := VitalDefaultResultMap
3419    ) IS
3420        VARIABLE a_schd, b_schd, c_schd : SchedType;
3421        VARIABLE NewValue        : UX01;
3422        VARIABLE Glitch_Data    : GlitchDataType;
3423        VARIABLE new_schd       : SchedType;
3424        VARIABLE Dly, Glch      : TIME;
3425    BEGIN
3426
3427    -- ------------------------------------------------------------------------
3428    --  For ALL zero delay paths, use simple model
3429    --   ( No delay selection, glitch detection required )
3430    -- ------------------------------------------------------------------------
3431    IF (     (tpd_a_q = VitalZeroDelay01)
3432         AND (tpd_b_q = VitalZeroDelay01)
3433         AND (tpd_c_q = VitalZeroDelay01)) THEN
3434      LOOP
3435        q <= VitalOR3 ( a, b, c, ResultMap );
3436        WAIT ON a, b, c;
3437      END LOOP;
3438
3439    ELSE
3440        -- --------------------------------------
3441        -- Initialize delay schedules
3442        -- --------------------------------------
3443        BufPath ( a_schd, InitialEdge(a), tpd_a_q );
3444        BufPath ( b_schd, InitialEdge(b), tpd_b_q );
3445        BufPath ( c_schd, InitialEdge(c), tpd_c_q );
3446
3447      LOOP
3448        -- --------------------------------------
3449        -- Process input signals
3450        --   get edge values
3451        --   re-evaluate output schedules
3452        -- --------------------------------------
3453        BufPath ( a_schd, GetEdge(a), tpd_a_q );
3454        BufPath ( b_schd, GetEdge(b), tpd_b_q );
3455        BufPath ( c_schd, GetEdge(c), tpd_c_q );
3456
3457        -- ------------------------------------
3458        -- Compute function and propation delay
3459        -- ------------------------------------
3460        NewValue  := a OR b OR c;
3461        new_schd := a_schd OR b_schd OR c_schd;
3462
3463        -- ------------------------------------------------------
3464        -- Assign Outputs
3465        --  get delays to new value and possable glitch
3466        --  schedule output change with On Event glitch detection
3467        -- ------------------------------------------------------
3468        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3469        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3470                             PrimGlitchMode, GlitchDelay=>Glch );
3471
3472        WAIT ON a, b, c;
3473      END LOOP;
3474    END IF;
3475    END;
3476--
3477    PROCEDURE VitalNAND3 (
3478            SIGNAL            q : OUT std_ulogic;
3479            SIGNAL      a, b, c :  IN std_ulogic   ;
3480            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3481            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3482            CONSTANT    tpd_c_q :  IN VitalDelayType01    := VitalDefDelay01;
3483            CONSTANT  ResultMap :  IN VitalResultMapType
3484                                        := VitalDefaultResultMap
3485    ) IS
3486        VARIABLE a_schd, b_schd, c_schd : SchedType;
3487        VARIABLE NewValue        : UX01;
3488        VARIABLE Glitch_Data    : GlitchDataType;
3489        VARIABLE new_schd       : SchedType;
3490        VARIABLE Dly, Glch      : TIME;
3491    BEGIN
3492
3493    -- ------------------------------------------------------------------------
3494    --  For ALL zero delay paths, use simple model
3495    --   ( No delay selection, glitch detection required )
3496    -- ------------------------------------------------------------------------
3497    IF (     (tpd_a_q = VitalZeroDelay01)
3498         AND (tpd_b_q = VitalZeroDelay01)
3499         AND (tpd_c_q = VitalZeroDelay01)) THEN
3500      LOOP
3501        q <= VitalNAND3 ( a, b, c, ResultMap );
3502        WAIT ON a, b, c;
3503      END LOOP;
3504
3505    ELSE
3506        -- --------------------------------------
3507        -- Initialize delay schedules
3508        -- --------------------------------------
3509        InvPath ( a_schd, InitialEdge(a), tpd_a_q );
3510        InvPath ( b_schd, InitialEdge(b), tpd_b_q );
3511        InvPath ( c_schd, InitialEdge(c), tpd_c_q );
3512
3513      LOOP
3514        -- --------------------------------------
3515        -- Process input signals
3516        --   get edge values
3517        --   re-evaluate output schedules
3518        -- --------------------------------------
3519        InvPath ( a_schd, GetEdge(a), tpd_a_q );
3520        InvPath ( b_schd, GetEdge(b), tpd_b_q );
3521        InvPath ( c_schd, GetEdge(c), tpd_c_q );
3522
3523        -- ------------------------------------
3524        -- Compute function and propation delay
3525        -- ------------------------------------
3526        NewValue  := (a AND b) NAND c;
3527        new_schd := (a_schd AND b_schd) NAND c_schd;
3528
3529        -- ------------------------------------------------------
3530        -- Assign Outputs
3531        --  get delays to new value and possable glitch
3532        --  schedule output change with On Event glitch detection
3533        -- ------------------------------------------------------
3534        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3535        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3536                             PrimGlitchMode, GlitchDelay=>Glch );
3537
3538        WAIT ON a, b, c;
3539      END LOOP;
3540    END IF;
3541    END;
3542--
3543    PROCEDURE VitalNOR3  (
3544            SIGNAL            q : OUT std_ulogic;
3545            SIGNAL      a, b, c :  IN std_ulogic   ;
3546            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3547            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3548            CONSTANT    tpd_c_q :  IN VitalDelayType01    := VitalDefDelay01;
3549            CONSTANT  ResultMap :  IN VitalResultMapType
3550                                        := VitalDefaultResultMap
3551    ) IS
3552        VARIABLE a_schd, b_schd, c_schd : SchedType;
3553        VARIABLE NewValue        : UX01;
3554        VARIABLE Glitch_Data    : GlitchDataType;
3555        VARIABLE new_schd       : SchedType;
3556        VARIABLE Dly, Glch      : TIME;
3557    BEGIN
3558
3559    -- ------------------------------------------------------------------------
3560    --  For ALL zero delay paths, use simple model
3561    --   ( No delay selection, glitch detection required )
3562    -- ------------------------------------------------------------------------
3563    IF (     (tpd_a_q = VitalZeroDelay01)
3564         AND (tpd_b_q = VitalZeroDelay01)
3565         AND (tpd_c_q = VitalZeroDelay01)) THEN
3566      LOOP
3567        q <= VitalNOR3 ( a, b, c, ResultMap );
3568        WAIT ON a, b, c;
3569      END LOOP;
3570
3571    ELSE
3572        -- --------------------------------------
3573        -- Initialize delay schedules
3574        -- --------------------------------------
3575        InvPath ( a_schd, InitialEdge(a), tpd_a_q );
3576        InvPath ( b_schd, InitialEdge(b), tpd_b_q );
3577        InvPath ( c_schd, InitialEdge(c), tpd_c_q );
3578
3579      LOOP
3580        -- --------------------------------------
3581        -- Process input signals
3582        --   get edge values
3583        --   re-evaluate output schedules
3584        -- --------------------------------------
3585        InvPath ( a_schd, GetEdge(a), tpd_a_q );
3586        InvPath ( b_schd, GetEdge(b), tpd_b_q );
3587        InvPath ( c_schd, GetEdge(c), tpd_c_q );
3588
3589        -- ------------------------------------
3590        -- Compute function and propation delay
3591        -- ------------------------------------
3592        NewValue  := (a OR b) NOR c;
3593        new_schd := (a_schd OR b_schd) NOR c_schd;
3594
3595        -- ------------------------------------------------------
3596        -- Assign Outputs
3597        --  get delays to new value and possable glitch
3598        --  schedule output change with On Event glitch detection
3599        -- ------------------------------------------------------
3600        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3601        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3602                             PrimGlitchMode, GlitchDelay=>Glch );
3603
3604        WAIT ON a, b, c;
3605      END LOOP;
3606    END IF;
3607    END;
3608--
3609    PROCEDURE VitalXOR3  (
3610            SIGNAL            q : OUT std_ulogic;
3611            SIGNAL      a, b, c :  IN std_ulogic   ;
3612            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3613            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3614            CONSTANT    tpd_c_q :  IN VitalDelayType01    := VitalDefDelay01;
3615            CONSTANT  ResultMap :  IN VitalResultMapType
3616                                        := VitalDefaultResultMap
3617    ) IS
3618        VARIABLE ab_schd, bb_schd, cb_schd : SchedType;
3619        VARIABLE ai_schd, bi_schd, ci_schd : SchedType;
3620        VARIABLE NewValue        : UX01;
3621        VARIABLE Glitch_Data    : GlitchDataType;
3622        VARIABLE new_schd       : SchedType;
3623        VARIABLE Dly, Glch      : TIME;
3624    BEGIN
3625
3626    -- ------------------------------------------------------------------------
3627    --  For ALL zero delay paths, use simple model
3628    --   ( No delay selection, glitch detection required )
3629    -- ------------------------------------------------------------------------
3630    IF (     (tpd_a_q = VitalZeroDelay01)
3631         AND (tpd_b_q = VitalZeroDelay01)
3632         AND (tpd_c_q = VitalZeroDelay01)) THEN
3633      LOOP
3634        q <= VitalXOR3 ( a, b, c, ResultMap );
3635        WAIT ON a, b, c;
3636      END LOOP;
3637
3638    ELSE
3639        -- --------------------------------------
3640        -- Initialize delay schedules
3641        -- --------------------------------------
3642        BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
3643        InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
3644        BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
3645        InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
3646        BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
3647        InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
3648
3649      LOOP
3650        -- --------------------------------------
3651        -- Process input signals
3652        --   get edge values
3653        --   re-evaluate output schedules
3654        -- --------------------------------------
3655        BufPath ( ab_schd, GetEdge(a), tpd_a_q );
3656        InvPath ( ai_schd, GetEdge(a), tpd_a_q );
3657
3658        BufPath ( bb_schd, GetEdge(b), tpd_b_q );
3659        InvPath ( bi_schd, GetEdge(b), tpd_b_q );
3660
3661        BufPath ( cb_schd, GetEdge(c), tpd_c_q );
3662        InvPath ( ci_schd, GetEdge(c), tpd_c_q );
3663
3664        -- ------------------------------------
3665        -- Compute function and propation delay
3666        -- ------------------------------------
3667        NewValue  := a XOR b XOR c;
3668        new_schd := VitalXOR3 ( ab_schd,ai_schd,
3669                                bb_schd,bi_schd,
3670                                cb_schd,ci_schd );
3671
3672        -- ------------------------------------------------------
3673        -- Assign Outputs
3674        --  get delays to new value and possable glitch
3675        --  schedule output change with On Event glitch detection
3676        -- ------------------------------------------------------
3677        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3678        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3679                             PrimGlitchMode, GlitchDelay=>Glch );
3680
3681        WAIT ON a, b, c;
3682      END LOOP;
3683    END IF;
3684    END;
3685--
3686    PROCEDURE VitalXNOR3 (
3687            SIGNAL            q : OUT std_ulogic;
3688            SIGNAL      a, b, c :  IN std_ulogic   ;
3689            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3690            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3691            CONSTANT    tpd_c_q :  IN VitalDelayType01    := VitalDefDelay01;
3692            CONSTANT  ResultMap :  IN VitalResultMapType
3693                                        := VitalDefaultResultMap
3694    ) IS
3695        VARIABLE ab_schd, bb_schd, cb_schd : SchedType;
3696        VARIABLE ai_schd, bi_schd, ci_schd : SchedType;
3697        VARIABLE NewValue        : UX01;
3698        VARIABLE Glitch_Data    : GlitchDataType;
3699        VARIABLE new_schd       : SchedType;
3700        VARIABLE Dly, Glch      : TIME;
3701    BEGIN
3702
3703    -- ------------------------------------------------------------------------
3704    --  For ALL zero delay paths, use simple model
3705    --   ( No delay selection, glitch detection required )
3706    -- ------------------------------------------------------------------------
3707    IF (     (tpd_a_q = VitalZeroDelay01)
3708         AND (tpd_b_q = VitalZeroDelay01)
3709         AND (tpd_c_q = VitalZeroDelay01)) THEN
3710      LOOP
3711        q <= VitalXNOR3 ( a, b, c, ResultMap );
3712        WAIT ON a, b, c;
3713      END LOOP;
3714
3715    ELSE
3716        -- --------------------------------------
3717        -- Initialize delay schedules
3718        -- --------------------------------------
3719        BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
3720        InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
3721        BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
3722        InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
3723        BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
3724        InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
3725
3726      LOOP
3727        -- --------------------------------------
3728        -- Process input signals
3729        --   get edge values
3730        --   re-evaluate output schedules
3731        -- --------------------------------------
3732        BufPath ( ab_schd, GetEdge(a), tpd_a_q );
3733        InvPath ( ai_schd, GetEdge(a), tpd_a_q );
3734
3735        BufPath ( bb_schd, GetEdge(b), tpd_b_q );
3736        InvPath ( bi_schd, GetEdge(b), tpd_b_q );
3737
3738        BufPath ( cb_schd, GetEdge(c), tpd_c_q );
3739        InvPath ( ci_schd, GetEdge(c), tpd_c_q );
3740
3741        -- ------------------------------------
3742        -- Compute function and propation delay
3743        -- ------------------------------------
3744        NewValue  := NOT (a XOR b XOR c);
3745        new_schd := VitalXNOR3 ( ab_schd, ai_schd,
3746                                 bb_schd, bi_schd,
3747                                 cb_schd, ci_schd );
3748
3749        -- ------------------------------------------------------
3750        -- Assign Outputs
3751        --  get delays to new value and possable glitch
3752        --  schedule output change with On Event glitch detection
3753        -- ------------------------------------------------------
3754        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3755        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3756                             PrimGlitchMode, GlitchDelay=>Glch );
3757
3758        WAIT ON a, b, c;
3759      END LOOP;
3760    END IF;
3761    END;
3762
3763    -- ------------------------------------------------------------------------
3764    -- Commonly used 4-bit Logical gates.
3765    -- ------------------------------------------------------------------------
3766    PROCEDURE VitalAND4  (
3767            SIGNAL            q : OUT std_ulogic;
3768            SIGNAL   a, b, c, d :  IN std_ulogic   ;
3769            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3770            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3771            CONSTANT    tpd_c_q :  IN VitalDelayType01    := VitalDefDelay01;
3772            CONSTANT    tpd_d_q :  IN VitalDelayType01    := VitalDefDelay01;
3773            CONSTANT  ResultMap :  IN VitalResultMapType
3774                                        := VitalDefaultResultMap
3775    ) IS
3776        VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
3777        VARIABLE NewValue        : UX01;
3778        VARIABLE Glitch_Data    : GlitchDataType;
3779        VARIABLE new_schd       : SchedType;
3780        VARIABLE Dly, Glch      : TIME;
3781    BEGIN
3782
3783    -- ------------------------------------------------------------------------
3784    --  For ALL zero delay paths, use simple model
3785    --   ( No delay selection, glitch detection required )
3786    -- ------------------------------------------------------------------------
3787    IF (     (tpd_a_q = VitalZeroDelay01)
3788         AND (tpd_b_q = VitalZeroDelay01)
3789         AND (tpd_c_q = VitalZeroDelay01)
3790         AND (tpd_d_q = VitalZeroDelay01)) THEN
3791      LOOP
3792        q <= VitalAND4 ( a, b, c, d, ResultMap );
3793        WAIT ON a, b, c, d;
3794      END LOOP;
3795
3796    ELSE
3797        -- --------------------------------------
3798        -- Initialize delay schedules
3799        -- --------------------------------------
3800        BufPath ( a_schd, InitialEdge(a), tpd_a_q );
3801        BufPath ( b_schd, InitialEdge(b), tpd_b_q );
3802        BufPath ( c_schd, InitialEdge(c), tpd_c_q );
3803        BufPath ( d_Schd, InitialEdge(d), tpd_d_q );
3804
3805      LOOP
3806        -- --------------------------------------
3807        -- Process input signals
3808        --   get edge values
3809        --   re-evaluate output schedules
3810        -- --------------------------------------
3811        BufPath ( a_schd, GetEdge(a), tpd_a_q );
3812        BufPath ( b_schd, GetEdge(b), tpd_b_q );
3813        BufPath ( c_schd, GetEdge(c), tpd_c_q );
3814        BufPath ( d_Schd, GetEdge(d), tpd_d_q );
3815
3816        -- ------------------------------------
3817        -- Compute function and propation delay
3818        -- ------------------------------------
3819        NewValue  := a AND b AND c AND d;
3820        new_schd := a_schd AND b_schd AND c_schd AND d_Schd;
3821
3822        -- ------------------------------------------------------
3823        -- Assign Outputs
3824        --  get delays to new value and possable glitch
3825        --  schedule output change with On Event glitch detection
3826        -- ------------------------------------------------------
3827        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3828        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3829                             PrimGlitchMode, GlitchDelay=>Glch );
3830
3831        WAIT ON a, b, c, d;
3832      END LOOP;
3833    END IF;
3834    END;
3835--
3836    PROCEDURE VitalOR4   (
3837            SIGNAL            q : OUT std_ulogic;
3838            SIGNAL   a, b, c, d :  IN std_ulogic   ;
3839            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3840            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3841            CONSTANT    tpd_c_q :  IN VitalDelayType01    := VitalDefDelay01;
3842            CONSTANT    tpd_d_q :  IN VitalDelayType01    := VitalDefDelay01;
3843            CONSTANT  ResultMap :  IN VitalResultMapType
3844                                        := VitalDefaultResultMap
3845    ) IS
3846        VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
3847        VARIABLE NewValue        : UX01;
3848        VARIABLE Glitch_Data    : GlitchDataType;
3849        VARIABLE new_schd       : SchedType;
3850        VARIABLE Dly, Glch      : TIME;
3851    BEGIN
3852
3853    -- ------------------------------------------------------------------------
3854    --  For ALL zero delay paths, use simple model
3855    --   ( No delay selection, glitch detection required )
3856    -- ------------------------------------------------------------------------
3857    IF (     (tpd_a_q = VitalZeroDelay01)
3858         AND (tpd_b_q = VitalZeroDelay01)
3859         AND (tpd_c_q = VitalZeroDelay01)
3860         AND (tpd_d_q = VitalZeroDelay01)) THEN
3861      LOOP
3862        q <= VitalOR4 ( a, b, c, d, ResultMap );
3863        WAIT ON a, b, c, d;
3864      END LOOP;
3865
3866    ELSE
3867        -- --------------------------------------
3868        -- Initialize delay schedules
3869        -- --------------------------------------
3870        BufPath ( a_schd, InitialEdge(a), tpd_a_q );
3871        BufPath ( b_schd, InitialEdge(b), tpd_b_q );
3872        BufPath ( c_schd, InitialEdge(c), tpd_c_q );
3873        BufPath ( d_Schd, InitialEdge(d), tpd_d_q );
3874
3875      LOOP
3876        -- --------------------------------------
3877        -- Process input signals
3878        --   get edge values
3879        --   re-evaluate output schedules
3880        -- --------------------------------------
3881        BufPath ( a_schd, GetEdge(a), tpd_a_q );
3882        BufPath ( b_schd, GetEdge(b), tpd_b_q );
3883        BufPath ( c_schd, GetEdge(c), tpd_c_q );
3884        BufPath ( d_Schd, GetEdge(d), tpd_d_q );
3885
3886        -- ------------------------------------
3887        -- Compute function and propation delay
3888        -- ------------------------------------
3889        NewValue  := a OR b OR c OR d;
3890        new_schd := a_schd OR b_schd OR c_schd OR d_Schd;
3891
3892        -- ------------------------------------------------------
3893        -- Assign Outputs
3894        --  get delays to new value and possable glitch
3895        --  schedule output change with On Event glitch detection
3896        -- ------------------------------------------------------
3897        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3898        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3899                             PrimGlitchMode, GlitchDelay=>Glch );
3900
3901        WAIT ON a, b, c, d;
3902      END LOOP;
3903    END IF;
3904    END;
3905--
3906    PROCEDURE VitalNAND4 (
3907            SIGNAL            q : OUT std_ulogic;
3908            SIGNAL   a, b, c, d :  IN std_ulogic   ;
3909            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3910            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3911            CONSTANT    tpd_c_q :  IN VitalDelayType01    := VitalDefDelay01;
3912            CONSTANT    tpd_d_q :  IN VitalDelayType01    := VitalDefDelay01;
3913            CONSTANT  ResultMap :  IN VitalResultMapType
3914                                        := VitalDefaultResultMap
3915    ) IS
3916        VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
3917        VARIABLE NewValue        : UX01;
3918        VARIABLE Glitch_Data    : GlitchDataType;
3919        VARIABLE new_schd       : SchedType;
3920        VARIABLE Dly, Glch      : TIME;
3921    BEGIN
3922
3923    -- ------------------------------------------------------------------------
3924    --  For ALL zero delay paths, use simple model
3925    --   ( No delay selection, glitch detection required )
3926    -- ------------------------------------------------------------------------
3927    IF (     (tpd_a_q = VitalZeroDelay01)
3928         AND (tpd_b_q = VitalZeroDelay01)
3929         AND (tpd_c_q = VitalZeroDelay01)
3930         AND (tpd_d_q = VitalZeroDelay01)) THEN
3931      LOOP
3932        q <= VitalNAND4 ( a, b, c, d, ResultMap );
3933        WAIT ON a, b, c, d;
3934      END LOOP;
3935
3936    ELSE
3937        -- --------------------------------------
3938        -- Initialize delay schedules
3939        -- --------------------------------------
3940        InvPath ( a_schd, InitialEdge(a), tpd_a_q );
3941        InvPath ( b_schd, InitialEdge(b), tpd_b_q );
3942        InvPath ( c_schd, InitialEdge(c), tpd_c_q );
3943        InvPath ( d_Schd, InitialEdge(d), tpd_d_q );
3944
3945      LOOP
3946        -- --------------------------------------
3947        -- Process input signals
3948        --   get edge values
3949        --   re-evaluate output schedules
3950        -- --------------------------------------
3951        InvPath ( a_schd, GetEdge(a), tpd_a_q );
3952        InvPath ( b_schd, GetEdge(b), tpd_b_q );
3953        InvPath ( c_schd, GetEdge(c), tpd_c_q );
3954        InvPath ( d_Schd, GetEdge(d), tpd_d_q );
3955
3956        -- ------------------------------------
3957        -- Compute function and propation delay
3958        -- ------------------------------------
3959        NewValue  := (a AND b) NAND (c AND d);
3960        new_schd := (a_schd AND b_schd) NAND (c_schd AND d_Schd);
3961
3962        -- ------------------------------------------------------
3963        -- Assign Outputs
3964        --  get delays to new value and possable glitch
3965        --  schedule output change with On Event glitch detection
3966        -- ------------------------------------------------------
3967        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
3968        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
3969                             PrimGlitchMode, GlitchDelay=>Glch );
3970
3971        WAIT ON a, b, c, d;
3972      END LOOP;
3973    END IF;
3974    END;
3975--
3976    PROCEDURE VitalNOR4  (
3977            SIGNAL            q : OUT std_ulogic;
3978            SIGNAL   a, b, c, d :  IN std_ulogic   ;
3979            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
3980            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
3981            CONSTANT    tpd_c_q :  IN VitalDelayType01    := VitalDefDelay01;
3982            CONSTANT    tpd_d_q :  IN VitalDelayType01    := VitalDefDelay01;
3983            CONSTANT  ResultMap :  IN VitalResultMapType
3984                                        := VitalDefaultResultMap
3985    ) IS
3986        VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
3987        VARIABLE NewValue        : UX01;
3988        VARIABLE Glitch_Data    : GlitchDataType;
3989        VARIABLE new_schd       : SchedType;
3990        VARIABLE Dly, Glch      : TIME;
3991    BEGIN
3992
3993    -- ------------------------------------------------------------------------
3994    --  For ALL zero delay paths, use simple model
3995    --   ( No delay selection, glitch detection required )
3996    -- ------------------------------------------------------------------------
3997    IF (     (tpd_a_q = VitalZeroDelay01)
3998         AND (tpd_b_q = VitalZeroDelay01)
3999         AND (tpd_c_q = VitalZeroDelay01)
4000         AND (tpd_d_q = VitalZeroDelay01)) THEN
4001      LOOP
4002        q <= VitalNOR4 ( a, b, c, d, ResultMap );
4003        WAIT ON a, b, c, d;
4004      END LOOP;
4005
4006    ELSE
4007        -- --------------------------------------
4008        -- Initialize delay schedules
4009        -- --------------------------------------
4010        InvPath ( a_schd, InitialEdge(a), tpd_a_q );
4011        InvPath ( b_schd, InitialEdge(b), tpd_b_q );
4012        InvPath ( c_schd, InitialEdge(c), tpd_c_q );
4013        InvPath ( d_Schd, InitialEdge(d), tpd_d_q );
4014
4015      LOOP
4016        -- --------------------------------------
4017        -- Process input signals
4018        --   get edge values
4019        --   re-evaluate output schedules
4020        -- --------------------------------------
4021        InvPath ( a_schd, GetEdge(a), tpd_a_q );
4022        InvPath ( b_schd, GetEdge(b), tpd_b_q );
4023        InvPath ( c_schd, GetEdge(c), tpd_c_q );
4024        InvPath ( d_Schd, GetEdge(d), tpd_d_q );
4025
4026        -- ------------------------------------
4027        -- Compute function and propation delay
4028        -- ------------------------------------
4029        NewValue  := (a OR b) NOR (c OR d);
4030        new_schd := (a_schd OR b_schd) NOR (c_schd OR d_Schd);
4031
4032        -- ------------------------------------------------------
4033        -- Assign Outputs
4034        --  get delays to new value and possable glitch
4035        --  schedule output change with On Event glitch detection
4036        -- ------------------------------------------------------
4037        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
4038        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4039                             PrimGlitchMode, GlitchDelay=>Glch );
4040
4041        WAIT ON a, b, c, d;
4042      END LOOP;
4043    END IF;
4044    END;
4045--
4046    PROCEDURE VitalXOR4  (
4047            SIGNAL            q : OUT std_ulogic;
4048            SIGNAL   a, b, c, d :  IN std_ulogic   ;
4049            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
4050            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
4051            CONSTANT    tpd_c_q :  IN VitalDelayType01    := VitalDefDelay01;
4052            CONSTANT    tpd_d_q :  IN VitalDelayType01    := VitalDefDelay01;
4053            CONSTANT  ResultMap :  IN VitalResultMapType
4054                                        := VitalDefaultResultMap
4055    ) IS
4056        VARIABLE ab_schd, bb_schd, cb_schd, DB_Schd : SchedType;
4057        VARIABLE ai_schd, bi_schd, ci_schd, di_schd : SchedType;
4058        VARIABLE NewValue        : UX01;
4059        VARIABLE Glitch_Data    : GlitchDataType;
4060        VARIABLE new_schd       : SchedType;
4061        VARIABLE Dly, Glch      : TIME;
4062    BEGIN
4063
4064    -- ------------------------------------------------------------------------
4065    --  For ALL zero delay paths, use simple model
4066    --   ( No delay selection, glitch detection required )
4067    -- ------------------------------------------------------------------------
4068    IF (     (tpd_a_q = VitalZeroDelay01)
4069         AND (tpd_b_q = VitalZeroDelay01)
4070         AND (tpd_c_q = VitalZeroDelay01)
4071         AND (tpd_d_q = VitalZeroDelay01)) THEN
4072      LOOP
4073        q <= VitalXOR4 ( a, b, c, d, ResultMap );
4074        WAIT ON a, b, c, d;
4075      END LOOP;
4076
4077    ELSE
4078        -- --------------------------------------
4079        -- Initialize delay schedules
4080        -- --------------------------------------
4081        BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
4082        InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
4083
4084        BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
4085        InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
4086
4087        BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
4088        InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
4089
4090        BufPath ( DB_Schd, InitialEdge(d), tpd_d_q );
4091        InvPath ( di_schd, InitialEdge(d), tpd_d_q );
4092
4093      LOOP
4094        -- --------------------------------------
4095        -- Process input signals
4096        --   get edge values
4097        --   re-evaluate output schedules
4098        -- --------------------------------------
4099        BufPath ( ab_schd, GetEdge(a), tpd_a_q );
4100        InvPath ( ai_schd, GetEdge(a), tpd_a_q );
4101
4102        BufPath ( bb_schd, GetEdge(b), tpd_b_q );
4103        InvPath ( bi_schd, GetEdge(b), tpd_b_q );
4104
4105        BufPath ( cb_schd, GetEdge(c), tpd_c_q );
4106        InvPath ( ci_schd, GetEdge(c), tpd_c_q );
4107
4108        BufPath ( DB_Schd, GetEdge(d), tpd_d_q );
4109        InvPath ( di_schd, GetEdge(d), tpd_d_q );
4110
4111        -- ------------------------------------
4112        -- Compute function and propation delay
4113        -- ------------------------------------
4114        NewValue  := a XOR b XOR c XOR d;
4115        new_schd := VitalXOR4 ( ab_schd,ai_schd, bb_schd,bi_schd,
4116                                cb_schd,ci_schd, DB_Schd,di_schd );
4117
4118        -- ------------------------------------------------------
4119        -- Assign Outputs
4120        --  get delays to new value and possable glitch
4121        --  schedule output change with On Event glitch detection
4122        -- ------------------------------------------------------
4123        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
4124        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4125                             PrimGlitchMode, GlitchDelay=>Glch );
4126
4127        WAIT ON a, b, c, d;
4128      END LOOP;
4129    END IF;
4130    END;
4131--
4132    PROCEDURE VitalXNOR4 (
4133            SIGNAL            q : OUT std_ulogic;
4134            SIGNAL   a, b, c, d :  IN std_ulogic   ;
4135            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
4136            CONSTANT    tpd_b_q :  IN VitalDelayType01    := VitalDefDelay01;
4137            CONSTANT    tpd_c_q :  IN VitalDelayType01    := VitalDefDelay01;
4138            CONSTANT    tpd_d_q :  IN VitalDelayType01    := VitalDefDelay01;
4139            CONSTANT  ResultMap :  IN VitalResultMapType
4140                                        := VitalDefaultResultMap
4141    ) IS
4142        VARIABLE ab_schd, bb_schd, cb_schd, DB_Schd : SchedType;
4143        VARIABLE ai_schd, bi_schd, ci_schd, di_schd : SchedType;
4144        VARIABLE NewValue        : UX01;
4145        VARIABLE Glitch_Data    : GlitchDataType;
4146        VARIABLE new_schd       : SchedType;
4147        VARIABLE Dly, Glch      : TIME;
4148    BEGIN
4149
4150    -- ------------------------------------------------------------------------
4151    --  For ALL zero delay paths, use simple model
4152    --   ( No delay selection, glitch detection required )
4153    -- ------------------------------------------------------------------------
4154    IF (     (tpd_a_q = VitalZeroDelay01)
4155         AND (tpd_b_q = VitalZeroDelay01)
4156         AND (tpd_c_q = VitalZeroDelay01)
4157         AND (tpd_d_q = VitalZeroDelay01)) THEN
4158      LOOP
4159        q <= VitalXNOR4 ( a, b, c, d, ResultMap );
4160        WAIT ON a, b, c, d;
4161      END LOOP;
4162
4163    ELSE
4164        -- --------------------------------------
4165        -- Initialize delay schedules
4166        -- --------------------------------------
4167        BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
4168        InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
4169
4170        BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
4171        InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
4172
4173        BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
4174        InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
4175
4176        BufPath ( DB_Schd, InitialEdge(d), tpd_d_q );
4177        InvPath ( di_schd, InitialEdge(d), tpd_d_q );
4178
4179      LOOP
4180        -- --------------------------------------
4181        -- Process input signals
4182        --   get edge values
4183        --   re-evaluate output schedules
4184        -- --------------------------------------
4185        BufPath ( ab_schd, GetEdge(a), tpd_a_q );
4186        InvPath ( ai_schd, GetEdge(a), tpd_a_q );
4187
4188        BufPath ( bb_schd, GetEdge(b), tpd_b_q );
4189        InvPath ( bi_schd, GetEdge(b), tpd_b_q );
4190
4191        BufPath ( cb_schd, GetEdge(c), tpd_c_q );
4192        InvPath ( ci_schd, GetEdge(c), tpd_c_q );
4193
4194        BufPath ( DB_Schd, GetEdge(d), tpd_d_q );
4195        InvPath ( di_schd, GetEdge(d), tpd_d_q );
4196
4197        -- ------------------------------------
4198        -- Compute function and propation delay
4199        -- ------------------------------------
4200        NewValue  := NOT (a XOR b XOR c XOR d);
4201        new_schd := VitalXNOR4 ( ab_schd,ai_schd, bb_schd,bi_schd,
4202                                 cb_schd,ci_schd, DB_Schd,di_schd );
4203
4204        -- ------------------------------------------------------
4205        -- Assign Outputs
4206        --  get delays to new value and possable glitch
4207        --  schedule output change with On Event glitch detection
4208        -- ------------------------------------------------------
4209        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
4210        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4211                             PrimGlitchMode, GlitchDelay=>Glch );
4212
4213        WAIT ON a, b, c, d;
4214      END LOOP;
4215    END IF;
4216    END;
4217
4218    -- ------------------------------------------------------------------------
4219    -- Buffers
4220    --   BUF    ....... standard non-inverting buffer
4221    --   BUFIF0 ....... non-inverting buffer Data passes thru if (Enable = '0')
4222    --   BUFIF1 ....... non-inverting buffer Data passes thru if (Enable = '1')
4223    -- ------------------------------------------------------------------------
4224    PROCEDURE VitalBUF   (
4225            SIGNAL            q : OUT std_ulogic;
4226            SIGNAL            a :  IN std_ulogic   ;
4227            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
4228            CONSTANT  ResultMap :  IN VitalResultMapType
4229                                        := VitalDefaultResultMap
4230    ) IS
4231        VARIABLE NewValue      : UX01;
4232        VARIABLE Glitch_Data  : GlitchDataType;
4233        VARIABLE Dly, Glch    : TIME;
4234    BEGIN
4235
4236    -- ------------------------------------------------------------------------
4237    --  For ALL zero delay paths, use simple model
4238    --   ( No delay selection, glitch detection required )
4239    -- ------------------------------------------------------------------------
4240    IF (tpd_a_q = VitalZeroDelay01) THEN
4241      LOOP
4242        q <= ResultMap(To_UX01(a));
4243        WAIT ON a;
4244      END LOOP;
4245
4246    ELSE
4247      LOOP
4248        -- ------------------------------------
4249        -- Compute function and propation delay
4250        -- ------------------------------------
4251        NewValue  := To_UX01(a);     -- convert to forcing strengths
4252        CASE EdgeType'(GetEdge(a)) IS
4253          WHEN '1'|'/'|'R'|'r' => Dly := tpd_a_q(tr01);
4254          WHEN '0'|'\'|'F'|'f' => Dly := tpd_a_q(tr10);
4255          WHEN OTHERS          => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10));
4256        END CASE;
4257
4258        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4259                             PrimGlitchMode );
4260
4261        WAIT ON a;
4262      END LOOP;
4263    END IF;
4264    END;
4265--
4266    PROCEDURE VitalBUFIF1 (
4267            SIGNAL              q : OUT std_ulogic;
4268            SIGNAL           Data :  IN std_ulogic;
4269            SIGNAL         Enable :  IN std_ulogic;
4270            CONSTANT   tpd_data_q :  IN VitalDelayType01    := VitalDefDelay01;
4271            CONSTANT tpd_enable_q :  IN VitalDelayType01Z   := VitalDefDelay01Z;
4272            CONSTANT    ResultMap :  IN VitalResultZMapType
4273                                        := VitalDefaultResultZMap
4274    ) IS
4275        VARIABLE NewValue        : UX01Z;
4276        VARIABLE Glitch_Data    : GlitchDataType;
4277        VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
4278        VARIABLE Dly, Glch      : TIME;
4279    BEGIN
4280
4281    -- ------------------------------------------------------------------------
4282    --  For ALL zero delay paths, use simple model
4283    --   ( No delay selection, glitch detection required )
4284    -- ------------------------------------------------------------------------
4285    IF (     (tpd_data_q   = VitalZeroDelay01 )
4286         AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
4287      LOOP
4288        q <= VitalBUFIF1( Data, Enable, ResultMap );
4289        WAIT ON Data, Enable;
4290      END LOOP;
4291
4292    ELSE
4293        -- --------------------------------------
4294        -- Initialize delay schedules
4295        -- --------------------------------------
4296        BufPath ( d_Schd, InitialEdge(Data), tpd_data_q );
4297        BufEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
4298
4299      LOOP
4300        -- --------------------------------------
4301        -- Process input signals
4302        --   get edge values
4303        --   re-evaluate output schedules
4304        -- --------------------------------------
4305        BufPath ( d_Schd, GetEdge(Data), tpd_data_q );
4306        BufEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
4307
4308        -- ------------------------------------
4309        -- Compute function and propation delay
4310        -- ------------------------------------
4311        NewValue := VitalBUFIF1( Data, Enable );
4312
4313        -- ------------------------------------------------------
4314        -- Assign Outputs
4315        --  get delays to new value and possable glitch
4316        --  schedule output change with On Event glitch detection
4317        -- ------------------------------------------------------
4318        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
4319                        d_Schd, e1_Schd, e0_Schd );
4320        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4321                             PrimGlitchMode, GlitchDelay=>Glch );
4322
4323        WAIT ON Data, Enable;
4324      END LOOP;
4325    END IF;
4326    END;
4327--
4328    PROCEDURE VitalBUFIF0 (
4329            SIGNAL              q : OUT std_ulogic;
4330            SIGNAL           Data :  IN std_ulogic;
4331            SIGNAL         Enable :  IN std_ulogic;
4332            CONSTANT   tpd_data_q :  IN VitalDelayType01    := VitalDefDelay01;
4333            CONSTANT tpd_enable_q :  IN VitalDelayType01Z   := VitalDefDelay01Z;
4334            CONSTANT    ResultMap :  IN VitalResultZMapType
4335                                        := VitalDefaultResultZMap
4336    ) IS
4337        VARIABLE NewValue        : UX01Z;
4338        VARIABLE Glitch_Data    : GlitchDataType;
4339        VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
4340        VARIABLE ne1_schd, ne0_schd : SchedType;
4341        VARIABLE Dly, Glch      : TIME;
4342  BEGIN
4343
4344    -- ------------------------------------------------------------------------
4345    --  For ALL zero delay paths, use simple model
4346    --   ( No delay selection, glitch detection required )
4347    -- ------------------------------------------------------------------------
4348    IF (     (tpd_data_q   = VitalZeroDelay01 )
4349         AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
4350      LOOP
4351        q <= VitalBUFIF0( Data, Enable, ResultMap );
4352        WAIT ON Data, Enable;
4353      END LOOP;
4354
4355    ELSE
4356        -- --------------------------------------
4357        -- Initialize delay schedules
4358        -- --------------------------------------
4359        BufPath ( d_Schd, InitialEdge(Data), tpd_data_q );
4360        InvEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
4361
4362      LOOP
4363        -- --------------------------------------
4364        -- Process input signals
4365        --   get edge values
4366        --   re-evaluate output schedules
4367        -- --------------------------------------
4368        BufPath ( d_Schd, GetEdge(Data), tpd_data_q );
4369        InvEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
4370
4371        -- ------------------------------------
4372        -- Compute function and propation delay
4373        -- ------------------------------------
4374        NewValue := VitalBUFIF0( Data, Enable );
4375        ne1_schd := NOT e1_Schd;
4376        ne0_schd := NOT e0_Schd;
4377
4378        -- ------------------------------------------------------
4379        -- Assign Outputs
4380        --  get delays to new value and possable glitch
4381        --  schedule output change with On Event glitch detection
4382        -- ------------------------------------------------------
4383        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
4384                        d_Schd, ne1_schd, ne0_schd );
4385        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4386                             PrimGlitchMode, GlitchDelay=>Glch );
4387
4388        WAIT ON Data, Enable;
4389      END LOOP;
4390    END IF;
4391    END;
4392
4393    PROCEDURE VitalIDENT (
4394            SIGNAL            q : OUT std_ulogic;
4395            SIGNAL            a :  IN std_ulogic   ;
4396            CONSTANT    tpd_a_q :  IN VitalDelayType01Z   := VitalDefDelay01Z;
4397            CONSTANT  ResultMap :  IN VitalResultZMapType
4398                                        := VitalDefaultResultZMap
4399    ) IS
4400        SUBTYPE v2 IS std_logic_vector(0 TO 1);
4401        VARIABLE NewValue      : UX01Z;
4402        VARIABLE Glitch_Data  : GlitchDataType;
4403        VARIABLE Dly, Glch    : TIME;
4404    BEGIN
4405
4406    -- ------------------------------------------------------------------------
4407    --  For ALL zero delay paths, use simple model
4408    --   ( No delay selection, glitch detection required )
4409    -- ------------------------------------------------------------------------
4410    IF (tpd_a_q = VitalZeroDelay01Z) THEN
4411      LOOP
4412        q <= ResultMap(To_UX01Z(a));
4413        WAIT ON a;
4414      END LOOP;
4415
4416    ELSE
4417      LOOP
4418        -- ------------------------------------
4419        -- Compute function and propation delay
4420        -- ------------------------------------
4421        CASE v2'(To_X01Z(NewValue) & To_X01Z(a)) IS
4422          WHEN "00"   => Dly := tpd_a_q(tr10);
4423          WHEN "01"   => Dly := tpd_a_q(tr01);
4424          WHEN "0Z"   => Dly := tpd_a_q(tr0z);
4425          WHEN "0X"   => Dly := tpd_a_q(tr01);
4426          WHEN "10"   => Dly := tpd_a_q(tr10);
4427          WHEN "11"   => Dly := tpd_a_q(tr01);
4428          WHEN "1Z"   => Dly := tpd_a_q(tr1z);
4429          WHEN "1X"   => Dly := tpd_a_q(tr10);
4430          WHEN "Z0"   => Dly := tpd_a_q(trz0);
4431          WHEN "Z1"   => Dly := tpd_a_q(trz1);
4432          WHEN "ZZ"   => Dly := 0 ns;
4433          WHEN "ZX"   => Dly := Minimum (tpd_a_q(trz1), tpd_a_q(trz0));
4434          WHEN "X0"   => Dly := tpd_a_q(tr10);
4435          WHEN "X1"   => Dly := tpd_a_q(tr01);
4436          WHEN "XZ"   => Dly := Minimum (tpd_a_q(tr0z), tpd_a_q(tr1z));
4437          WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10));
4438        END CASE;
4439        NewValue  := To_UX01Z(a);
4440
4441        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4442                             PrimGlitchMode );
4443
4444        WAIT ON a;
4445      END LOOP;
4446    END IF;
4447    END;
4448
4449    -- ------------------------------------------------------------------------
4450    -- Invertors
4451    --   INV    ......... standard inverting buffer
4452    --   INVIF0 ......... inverting buffer Data passes thru if (Enable = '0')
4453    --   INVIF1 ......... inverting buffer Data passes thru if (Enable = '1')
4454    -- ------------------------------------------------------------------------
4455    PROCEDURE VitalINV   (
4456            SIGNAL            q : OUT std_ulogic;
4457            SIGNAL            a :  IN std_ulogic   ;
4458            CONSTANT    tpd_a_q :  IN VitalDelayType01    := VitalDefDelay01;
4459            CONSTANT  ResultMap :  IN VitalResultMapType
4460                                        := VitalDefaultResultMap
4461    ) IS
4462        VARIABLE NewValue      : UX01;
4463        VARIABLE Glitch_Data  : GlitchDataType;
4464        VARIABLE new_schd     : SchedType;
4465        VARIABLE Dly, Glch    : TIME;
4466    BEGIN
4467    IF (tpd_a_q = VitalZeroDelay01) THEN
4468      LOOP
4469        q <= ResultMap(NOT a);
4470        WAIT ON a;
4471      END LOOP;
4472
4473    ELSE
4474      LOOP
4475        -- ------------------------------------
4476        -- Compute function and propation delay
4477        -- ------------------------------------
4478        NewValue  := NOT a;
4479        CASE EdgeType'(GetEdge(a)) IS
4480          WHEN '1'|'/'|'R'|'r' => Dly := tpd_a_q(tr10);
4481          WHEN '0'|'\'|'F'|'f' => Dly := tpd_a_q(tr01);
4482          WHEN OTHERS          => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10));
4483        END CASE;
4484
4485        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4486                             PrimGlitchMode );
4487
4488        WAIT ON a;
4489      END LOOP;
4490    END IF;
4491    END;
4492--
4493    PROCEDURE VitalINVIF1 (
4494            SIGNAL              q : OUT std_ulogic;
4495            SIGNAL           Data :  IN std_ulogic;
4496            SIGNAL         Enable :  IN std_ulogic;
4497            CONSTANT   tpd_data_q :  IN VitalDelayType01    := VitalDefDelay01;
4498            CONSTANT tpd_enable_q :  IN VitalDelayType01Z   := VitalDefDelay01Z;
4499            CONSTANT    ResultMap :  IN VitalResultZMapType
4500                                        := VitalDefaultResultZMap
4501    ) IS
4502        VARIABLE NewValue        : UX01Z;
4503        VARIABLE new_schd       : SchedType;
4504        VARIABLE Glitch_Data    : GlitchDataType;
4505        VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
4506        VARIABLE Dly, Glch      : TIME;
4507  BEGIN
4508
4509    -- ------------------------------------------------------------------------
4510    --  For ALL zero delay paths, use simple model
4511    --   ( No delay selection, glitch detection required )
4512    -- ------------------------------------------------------------------------
4513    IF (     (tpd_data_q   = VitalZeroDelay01 )
4514         AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
4515      LOOP
4516        q <= VitalINVIF1( Data, Enable, ResultMap );
4517        WAIT ON Data, Enable;
4518      END LOOP;
4519
4520    ELSE
4521        -- --------------------------------------
4522        -- Initialize delay schedules
4523        -- --------------------------------------
4524        InvPath ( d_Schd, InitialEdge(Data), tpd_data_q );
4525        BufEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
4526
4527      LOOP
4528        -- --------------------------------------
4529        -- Process input signals
4530        --   get edge values
4531        --   re-evaluate output schedules
4532        -- --------------------------------------
4533        InvPath ( d_Schd, GetEdge(Data), tpd_data_q );
4534        BufEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
4535
4536        -- ------------------------------------
4537        -- Compute function and propation delay
4538        -- ------------------------------------
4539        NewValue := VitalINVIF1( Data, Enable );
4540        new_schd := NOT d_Schd;
4541
4542        -- ------------------------------------------------------
4543        -- Assign Outputs
4544        --  get delays to new value and possable glitch
4545        --  schedule output change with On Event glitch detection
4546        -- ------------------------------------------------------
4547        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
4548                        new_schd, e1_Schd, e0_Schd );
4549        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4550                             PrimGlitchMode, GlitchDelay=>Glch );
4551
4552        WAIT ON Data, Enable;
4553      END LOOP;
4554    END IF;
4555    END;
4556--
4557    PROCEDURE VitalINVIF0 (
4558            SIGNAL              q : OUT std_ulogic;
4559            SIGNAL           Data :  IN std_ulogic;
4560            SIGNAL         Enable :  IN std_ulogic;
4561            CONSTANT   tpd_data_q :  IN VitalDelayType01    := VitalDefDelay01;
4562            CONSTANT tpd_enable_q :  IN VitalDelayType01Z   := VitalDefDelay01Z;
4563            CONSTANT    ResultMap :  IN VitalResultZMapType
4564                                        := VitalDefaultResultZMap
4565    ) IS
4566        VARIABLE NewValue        : UX01Z;
4567        VARIABLE new_schd       : SchedType;
4568        VARIABLE Glitch_Data    : GlitchDataType;
4569        VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
4570        VARIABLE ne1_schd, ne0_schd : SchedType := DefSchedType;
4571        VARIABLE Dly, Glch      : TIME;
4572  BEGIN
4573
4574    -- ------------------------------------------------------------------------
4575    --  For ALL zero delay paths, use simple model
4576    --   ( No delay selection, glitch detection required )
4577    -- ------------------------------------------------------------------------
4578    IF (     (tpd_data_q   = VitalZeroDelay01 )
4579         AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
4580      LOOP
4581        q <= VitalINVIF0( Data, Enable, ResultMap );
4582        WAIT ON Data, Enable;
4583      END LOOP;
4584
4585    ELSE
4586        -- --------------------------------------
4587        -- Initialize delay schedules
4588        -- --------------------------------------
4589        InvPath ( d_Schd, InitialEdge(Data), tpd_data_q );
4590        InvEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
4591
4592      LOOP
4593        -- --------------------------------------
4594        -- Process input signals
4595        --   get edge values
4596        --   re-evaluate output schedules
4597        -- --------------------------------------
4598        InvPath ( d_Schd, GetEdge(Data), tpd_data_q );
4599        InvEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
4600
4601        -- ------------------------------------
4602        -- Compute function and propation delay
4603        -- ------------------------------------
4604        NewValue := VitalINVIF0( Data, Enable );
4605        ne1_schd := NOT e1_Schd;
4606        ne0_schd := NOT e0_Schd;
4607        new_schd := NOT d_Schd;
4608
4609        -- ------------------------------------------------------
4610        -- Assign Outputs
4611        --  get delays to new value and possable glitch
4612        --  schedule output change with On Event glitch detection
4613        -- ------------------------------------------------------
4614        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
4615                        new_schd, ne1_schd, ne0_schd );
4616        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4617                             PrimGlitchMode, GlitchDelay=>Glch );
4618
4619        WAIT ON Data, Enable;
4620      END LOOP;
4621    END IF;
4622    END;
4623
4624    -- ------------------------------------------------------------------------
4625    -- Multiplexor
4626    --   MUX   .......... result := data(dselect)
4627    --   MUX2  .......... 2-input mux; result := data0 when (dselect = '0'),
4628    --                                           data1 when (dselect = '1'),
4629    --                        'X' when (dselect = 'X') and (data0 /= data1)
4630    --   MUX4  .......... 4-input mux; result := data(dselect)
4631    --   MUX8  .......... 8-input mux; result := data(dselect)
4632    -- ------------------------------------------------------------------------
4633    PROCEDURE VitalMUX2  (
4634            SIGNAL            q : OUT std_ulogic;
4635            SIGNAL       d1, d0 :  IN std_ulogic;
4636            SIGNAL         dSel :  IN std_ulogic;
4637            CONSTANT   tpd_d1_q :  IN VitalDelayType01    := VitalDefDelay01;
4638            CONSTANT   tpd_d0_q :  IN VitalDelayType01    := VitalDefDelay01;
4639            CONSTANT tpd_dsel_q :  IN VitalDelayType01    := VitalDefDelay01;
4640            CONSTANT  ResultMap :  IN VitalResultMapType
4641                                        := VitalDefaultResultMap
4642    ) IS
4643        VARIABLE NewValue        : UX01;
4644        VARIABLE Glitch_Data    : GlitchDataType;
4645        VARIABLE new_schd       : SchedType;
4646        VARIABLE Dly, Glch      : TIME;
4647        VARIABLE d1_Schd,  d0_Schd  : SchedType;
4648        VARIABLE dSel_bSchd, dSel_iSchd : SchedType;
4649        VARIABLE d1_Edge, d0_Edge, dSel_Edge : EdgeType;
4650    BEGIN
4651
4652    -- ------------------------------------------------------------------------
4653    --  For ALL zero delay paths, use simple model
4654    --   ( No delay selection, glitch detection required )
4655    -- ------------------------------------------------------------------------
4656    IF (     (tpd_d1_q   = VitalZeroDelay01)
4657         AND (tpd_d0_q   = VitalZeroDelay01)
4658         AND (tpd_dsel_q = VitalZeroDelay01) ) THEN
4659      LOOP
4660        q <= VitalMUX2 ( d1, d0, dSel, ResultMap );
4661        WAIT ON d1, d0, dSel;
4662      END LOOP;
4663
4664    ELSE
4665        -- --------------------------------------
4666        -- Initialize delay schedules
4667        -- --------------------------------------
4668        BufPath ( d1_Schd, InitialEdge(d1), tpd_d1_q );
4669        BufPath ( d0_Schd, InitialEdge(d0), tpd_d0_q );
4670        BufPath ( dSel_bSchd, InitialEdge(dSel), tpd_dsel_q );
4671        InvPath ( dSel_iSchd, InitialEdge(dSel), tpd_dsel_q );
4672
4673      LOOP
4674        -- --------------------------------------
4675        -- Process input signals
4676        --   get edge values
4677        --   re-evaluate output schedules
4678        -- --------------------------------------
4679        BufPath ( d1_Schd, GetEdge(d1), tpd_d1_q );
4680        BufPath ( d0_Schd, GetEdge(d0), tpd_d0_q );
4681        BufPath ( dSel_bSchd, GetEdge(dSel), tpd_dsel_q );
4682        InvPath ( dSel_iSchd, GetEdge(dSel), tpd_dsel_q );
4683
4684        -- ------------------------------------
4685        -- Compute function and propation delaq
4686        -- ------------------------------------
4687        NewValue  := VitalMUX2 ( d1, d0, dSel );
4688        new_schd := VitalMUX2 ( d1_Schd, d0_Schd, dSel_bSchd, dSel_iSchd );
4689
4690        -- ------------------------------------------------------
4691        -- Assign Outputs
4692        --  get delays to new value and possable glitch
4693        --  schedule output change with On Event glitch detection
4694        -- ------------------------------------------------------
4695        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
4696        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4697                             PrimGlitchMode, GlitchDelay=>Glch );
4698
4699        WAIT ON d1, d0, dSel;
4700      END LOOP;
4701    END IF;
4702    END;
4703--
4704    PROCEDURE VitalMUX4  (
4705            SIGNAL            q : OUT std_ulogic;
4706            SIGNAL         Data :  IN std_logic_vector4;
4707            SIGNAL         dSel :  IN std_logic_vector2;
4708            CONSTANT tpd_data_q :  IN VitalDelayArrayType01;
4709            CONSTANT tpd_dsel_q :  IN VitalDelayArrayType01;
4710            CONSTANT  ResultMap :  IN VitalResultMapType
4711                                        := VitalDefaultResultMap
4712    ) IS
4713        VARIABLE LastData  : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
4714        VARIABLE LastdSel  : std_logic_vector(dSel'RANGE) := (OTHERS=>'U');
4715        VARIABLE NewValue        : UX01;
4716        VARIABLE Glitch_Data    : GlitchDataType;
4717        VARIABLE new_schd       : SchedType;
4718        VARIABLE Dly, Glch      : TIME;
4719        VARIABLE Data_Schd      : SchedArray4;
4720        VARIABLE Data_Edge      : EdgeArray4;
4721        VARIABLE dSel_Edge      : EdgeArray2;
4722        VARIABLE dSel_bSchd     : SchedArray2;
4723        VARIABLE dSel_iSchd     : SchedArray2;
4724        ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
4725        ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q;
4726        VARIABLE AllZeroDelay  : BOOLEAN := TRUE; --SN
4727    BEGIN
4728      -- ------------------------------------------------------------------------
4729      --  Check if ALL zero delay paths, use simple model
4730      --   ( No delay selection, glitch detection required )
4731      -- ------------------------------------------------------------------------
4732      FOR i IN dSel'RANGE LOOP
4733          IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN
4734              AllZeroDelay := FALSE;
4735              EXIT;
4736          END IF;
4737      END LOOP;
4738      IF (AllZeroDelay) THEN
4739          FOR i IN Data'RANGE LOOP
4740              IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
4741                  AllZeroDelay := FALSE;
4742                  EXIT;
4743              END IF;
4744          END LOOP;
4745
4746          IF (AllZeroDelay) THEN LOOP
4747              q <= VitalMUX(Data, dSel, ResultMap);
4748              WAIT ON Data, dSel;
4749          END LOOP;
4750          END IF;
4751      ELSE
4752
4753        -- --------------------------------------
4754        -- Initialize delay schedules
4755        -- --------------------------------------
4756        FOR n IN Data'RANGE LOOP
4757            BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
4758        END LOOP;
4759        FOR n IN dSel'RANGE LOOP
4760            BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
4761            InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
4762        END LOOP;
4763
4764      LOOP
4765        -- --------------------------------------
4766        -- Process input signals
4767        --   get edge values
4768        --   re-evaluate output schedules
4769        -- --------------------------------------
4770        GetEdge ( Data, LastData, Data_Edge );
4771        BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
4772
4773        GetEdge ( dSel, LastdSel, dSel_Edge );
4774        BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q );
4775        InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q );
4776
4777        -- ------------------------------------
4778        -- Compute function and propation delaq
4779        -- ------------------------------------
4780        NewValue  := VitalMUX4 ( Data, dSel );
4781        new_schd := VitalMUX4 ( Data_Schd, dSel_bSchd, dSel_iSchd );
4782
4783        -- ------------------------------------------------------
4784        -- Assign Outputs
4785        --  get delays to new value and possable glitch
4786        --  schedule output change with On Event glitch detection
4787        -- ------------------------------------------------------
4788        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
4789        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4790                             PrimGlitchMode, GlitchDelay=>Glch );
4791
4792        WAIT ON Data, dSel;
4793      END LOOP;
4794      END IF; --SN
4795    END;
4796
4797    PROCEDURE VitalMUX8  (
4798            SIGNAL            q : OUT std_ulogic;
4799            SIGNAL         Data :  IN std_logic_vector8;
4800            SIGNAL         dSel :  IN std_logic_vector3;
4801            CONSTANT tpd_data_q :  IN VitalDelayArrayType01;
4802            CONSTANT tpd_dsel_q :  IN VitalDelayArrayType01;
4803            CONSTANT  ResultMap :  IN VitalResultMapType  := VitalDefaultResultMap
4804    ) IS
4805        VARIABLE LastData  : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
4806        VARIABLE LastdSel  : std_logic_vector(dSel'RANGE) := (OTHERS=>'U');
4807        VARIABLE NewValue        : UX01;
4808        VARIABLE Glitch_Data    : GlitchDataType;
4809        VARIABLE new_schd       : SchedType;
4810        VARIABLE Dly, Glch      : TIME;
4811        VARIABLE Data_Schd      : SchedArray8;
4812        VARIABLE Data_Edge      : EdgeArray8;
4813        VARIABLE dSel_Edge      : EdgeArray3;
4814        VARIABLE dSel_bSchd     : SchedArray3;
4815        VARIABLE dSel_iSchd     : SchedArray3;
4816        ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
4817        ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q;
4818        VARIABLE AllZeroDelay  : BOOLEAN := TRUE; --SN
4819    BEGIN
4820      -- ------------------------------------------------------------------------
4821      --  Check if ALL zero delay paths, use simple model
4822      --   ( No delay selection, glitch detection required )
4823      -- ------------------------------------------------------------------------
4824      FOR i IN dSel'RANGE LOOP
4825          IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN
4826              AllZeroDelay := FALSE;
4827              EXIT;
4828          END IF;
4829      END LOOP;
4830      IF (AllZeroDelay) THEN
4831          FOR i IN Data'RANGE LOOP
4832              IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
4833                  AllZeroDelay := FALSE;
4834                  EXIT;
4835              END IF;
4836          END LOOP;
4837
4838          IF (AllZeroDelay) THEN LOOP
4839              q <= VitalMUX(Data, dSel, ResultMap);
4840              WAIT ON Data, dSel;
4841          END LOOP;
4842          END IF;
4843       ELSE
4844
4845        -- --------------------------------------
4846        -- Initialize delay schedules
4847        -- --------------------------------------
4848        FOR n IN Data'RANGE LOOP
4849            BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
4850        END LOOP;
4851        FOR n IN dSel'RANGE LOOP
4852            BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
4853            InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
4854        END LOOP;
4855
4856      LOOP
4857        -- --------------------------------------
4858        -- Process input signals
4859        --   get edge values
4860        --   re-evaluate output schedules
4861        -- --------------------------------------
4862        GetEdge ( Data, LastData, Data_Edge );
4863        BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
4864
4865        GetEdge ( dSel, LastdSel, dSel_Edge );
4866        BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q );
4867        InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q );
4868
4869        -- ------------------------------------
4870        -- Compute function and propation delaq
4871        -- ------------------------------------
4872        NewValue  := VitalMUX8 ( Data, dSel );
4873        new_schd := VitalMUX8 ( Data_Schd, dSel_bSchd, dSel_iSchd );
4874
4875        -- ------------------------------------------------------
4876        -- Assign Outputs
4877        --  get delays to new value and possable glitch
4878        --  schedule output change with On Event glitch detection
4879        -- ------------------------------------------------------
4880        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
4881        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4882                             PrimGlitchMode, GlitchDelay=>Glch );
4883
4884        WAIT ON Data, dSel;
4885      END LOOP;
4886      END IF;
4887    END;
4888--
4889    PROCEDURE VitalMUX   (
4890            SIGNAL            q : OUT std_ulogic;
4891            SIGNAL         Data :  IN std_logic_vector;
4892            SIGNAL         dSel :  IN std_logic_vector;
4893            CONSTANT tpd_data_q :  IN VitalDelayArrayType01;
4894            CONSTANT tpd_dsel_q :  IN VitalDelayArrayType01;
4895            CONSTANT  ResultMap :  IN VitalResultMapType
4896                                        := VitalDefaultResultMap
4897    ) IS
4898        VARIABLE LastData  : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
4899        VARIABLE LastdSel  : std_logic_vector(dSel'RANGE) := (OTHERS=>'U');
4900        VARIABLE NewValue        : UX01;
4901        VARIABLE Glitch_Data    : GlitchDataType;
4902        VARIABLE new_schd       : SchedType;
4903        VARIABLE Dly, Glch      : TIME;
4904        VARIABLE Data_Schd      : SchedArray(Data'RANGE);
4905        VARIABLE Data_Edge      : EdgeArray(Data'RANGE);
4906        VARIABLE dSel_Edge      : EdgeArray(dSel'RANGE);
4907        VARIABLE dSel_bSchd     : SchedArray(dSel'RANGE);
4908        VARIABLE dSel_iSchd     : SchedArray(dSel'RANGE);
4909        ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
4910        ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q;
4911        VARIABLE AllZeroDelay  : BOOLEAN := TRUE; --SN
4912    BEGIN
4913      -- ------------------------------------------------------------------------
4914      --  Check if ALL zero delay paths, use simple model
4915      --   ( No delay selection, glitch detection required )
4916      -- ------------------------------------------------------------------------
4917      FOR i IN dSel'RANGE LOOP
4918          IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN
4919              AllZeroDelay := FALSE;
4920              EXIT;
4921          END IF;
4922      END LOOP;
4923      IF (AllZeroDelay) THEN
4924          FOR i IN Data'RANGE LOOP
4925              IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
4926                  AllZeroDelay := FALSE;
4927                  EXIT;
4928              END IF;
4929          END LOOP;
4930
4931          IF (AllZeroDelay) THEN LOOP
4932              q <= VitalMUX(Data, dSel, ResultMap);
4933              WAIT ON Data, dSel;
4934          END LOOP;
4935          END IF;
4936      ELSE
4937
4938        -- --------------------------------------
4939        -- Initialize delay schedules
4940        -- --------------------------------------
4941        FOR n IN Data'RANGE LOOP
4942            BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
4943        END LOOP;
4944        FOR n IN dSel'RANGE LOOP
4945            BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
4946            InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
4947        END LOOP;
4948
4949      LOOP
4950        -- --------------------------------------
4951        -- Process input signals
4952        --   get edge values
4953        --   re-evaluate output schedules
4954        -- --------------------------------------
4955        GetEdge ( Data, LastData, Data_Edge );
4956        BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
4957
4958        GetEdge ( dSel, LastdSel, dSel_Edge );
4959        BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q );
4960        InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q );
4961
4962        -- ------------------------------------
4963        -- Compute function and propation delaq
4964        -- ------------------------------------
4965        NewValue  := VitalMUX ( Data, dSel );
4966        new_schd := VitalMUX ( Data_Schd, dSel_bSchd, dSel_iSchd );
4967
4968        -- ------------------------------------------------------
4969        -- Assign Outputs
4970        --  get delays to new value and possable glitch
4971        --  schedule output change with On Event glitch detection
4972        -- ------------------------------------------------------
4973        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
4974        VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
4975                             PrimGlitchMode, GlitchDelay=>Glch );
4976
4977        WAIT ON Data, dSel;
4978      END LOOP;
4979     END IF; --SN
4980    END;
4981
4982    -- ------------------------------------------------------------------------
4983    -- Decoder
4984    --          General Algorithm :
4985    --              (a) Result(...) := '0' when (enable = '0')
4986    --              (b) Result(data) := '1'; all other subelements = '0'
4987    --              ... Result array is decending (n-1 downto 0)
4988    --
4989    --          DECODERn  .......... n:2**n decoder
4990    -- Caution: If 'ResultMap' defines other than strength mapping, the
4991    --          delay selection is not defined.
4992    -- ------------------------------------------------------------------------
4993    PROCEDURE VitalDECODER2  (
4994            SIGNAL              q : OUT std_logic_vector2;
4995            SIGNAL           Data :  IN std_ulogic;
4996            SIGNAL         Enable :  IN std_ulogic;
4997            CONSTANT   tpd_data_q :  IN VitalDelayType01    := VitalDefDelay01;
4998            CONSTANT tpd_enable_q :  IN VitalDelayType01    := VitalDefDelay01;
4999            CONSTANT    ResultMap :  IN VitalResultMapType
5000                                        := VitalDefaultResultMap
5001    ) IS
5002        VARIABLE NewValue        : std_logic_vector2;
5003        VARIABLE Glitch_Data    : GlitchArray2;
5004        VARIABLE new_schd       : SchedArray2;
5005        VARIABLE Dly, Glch      : TimeArray2;
5006        VARIABLE Enable_Schd  : SchedType := DefSchedType;
5007        VARIABLE Data_BSchd, Data_ISchd : SchedType;
5008    BEGIN
5009      -- ------------------------------------------------------------------------
5010      --  Check if ALL zero delay paths, use simple model
5011      --   ( No delay selection, glitch detection required )
5012      -- ------------------------------------------------------------------------
5013      IF (tpd_enable_q = VitalZeroDelay01) AND (tpd_data_q = VitalZeroDelay01) THEN
5014      LOOP
5015          q <= VitalDECODER2(Data, Enable, ResultMap);
5016          WAIT ON Data, Enable;
5017      END LOOP;
5018      ELSE
5019
5020        -- --------------------------------------
5021        -- Initialize delay schedules
5022        -- --------------------------------------
5023        BufPath ( Data_BSchd, InitialEdge(Data), tpd_data_q );
5024        InvPath ( Data_ISchd, InitialEdge(Data), tpd_data_q );
5025        BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
5026
5027      LOOP
5028        -- --------------------------------------
5029        -- Process input signals
5030        --   get edge values
5031        --   re-evaluate output schedules
5032        -- --------------------------------------
5033        BufPath ( Data_BSchd, GetEdge(Data), tpd_data_q );
5034        InvPath ( Data_ISchd, GetEdge(Data), tpd_data_q );
5035
5036        BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
5037
5038        -- ------------------------------------
5039        -- Compute function and propation delaq
5040        -- ------------------------------------
5041        NewValue  := VitalDECODER2 ( Data, Enable, ResultMap );
5042        new_schd := VitalDECODER2 ( Data_BSchd, Data_ISchd, Enable_Schd );
5043
5044        -- ------------------------------------------------------
5045        -- Assign Outputs
5046        --  get delays to new value and possable glitch
5047        --  schedule output change with On Event glitch detection
5048        -- ------------------------------------------------------
5049        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
5050        VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
5051                             PrimGlitchMode, GlitchDelay=>Glch );
5052
5053        WAIT ON Data, Enable;
5054      END LOOP;
5055      END IF; -- SN
5056    END;
5057--
5058    PROCEDURE VitalDECODER4  (
5059            SIGNAL              q : OUT std_logic_vector4;
5060            SIGNAL           Data :  IN std_logic_vector2;
5061            SIGNAL         Enable :  IN std_ulogic;
5062            CONSTANT   tpd_data_q :  IN VitalDelayArrayType01;
5063            CONSTANT tpd_enable_q :  IN VitalDelayType01    := VitalDefDelay01;
5064            CONSTANT    ResultMap :  IN VitalResultMapType       := VitalDefaultResultMap
5065    ) IS
5066        VARIABLE LastData  : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
5067        VARIABLE NewValue        : std_logic_vector4;
5068        VARIABLE Glitch_Data    : GlitchArray4;
5069        VARIABLE new_schd       : SchedArray4;
5070        VARIABLE Dly, Glch      : TimeArray4;
5071        VARIABLE Enable_Schd    : SchedType;
5072        VARIABLE Enable_Edge    : EdgeType;
5073        VARIABLE Data_Edge      : EdgeArray2;
5074        VARIABLE Data_BSchd, Data_ISchd : SchedArray2;
5075        ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
5076        VARIABLE AllZeroDelay  : BOOLEAN := TRUE; --SN
5077    BEGIN
5078      -- ------------------------------------------------------------------------
5079      --  Check if ALL zero delay paths, use simple model
5080      --   ( No delay selection, glitch detection required )
5081      -- ------------------------------------------------------------------------
5082      IF (tpd_enable_q /= VitalZeroDelay01) THEN
5083          AllZeroDelay := FALSE;
5084      ELSE
5085          FOR i IN Data'RANGE LOOP
5086          IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
5087              AllZeroDelay := FALSE;
5088              EXIT;
5089          END IF;
5090          END LOOP;
5091      END IF;
5092      IF (AllZeroDelay) THEN LOOP
5093          q <= VitalDECODER4(Data, Enable, ResultMap);
5094          WAIT ON Data, Enable;
5095      END LOOP;
5096      ELSE
5097
5098        -- --------------------------------------
5099        -- Initialize delay schedules
5100        -- --------------------------------------
5101        FOR n IN Data'RANGE LOOP
5102            BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
5103            InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
5104        END LOOP;
5105        BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
5106
5107      LOOP
5108        -- --------------------------------------
5109        -- Process input signals
5110        --   get edge values
5111        --   re-evaluate output schedules
5112        -- --------------------------------------
5113        GetEdge ( Data, LastData, Data_Edge );
5114        BufPath ( Data_BSchd, Data_Edge, Atpd_data_q );
5115        InvPath ( Data_ISchd, Data_Edge, Atpd_data_q );
5116
5117        BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
5118
5119        -- ------------------------------------
5120        -- Compute function and propation delaq
5121        -- ------------------------------------
5122        NewValue  := VitalDECODER4 ( Data, Enable, ResultMap );
5123        new_schd := VitalDECODER4 ( Data_BSchd, Data_ISchd, Enable_Schd );
5124
5125        -- ------------------------------------------------------
5126        -- Assign Outputs
5127        --  get delays to new value and possable glitch
5128        --  schedule output change with On Event glitch detection
5129        -- ------------------------------------------------------
5130        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
5131        VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
5132                             PrimGlitchMode, GlitchDelay=>Glch );
5133
5134        WAIT ON Data, Enable;
5135      END LOOP;
5136      END IF;
5137    END;
5138--
5139    PROCEDURE VitalDECODER8  (
5140            SIGNAL              q : OUT std_logic_vector8;
5141            SIGNAL           Data :  IN std_logic_vector3;
5142            SIGNAL         Enable :  IN std_ulogic;
5143            CONSTANT   tpd_data_q :  IN VitalDelayArrayType01;
5144            CONSTANT tpd_enable_q :  IN VitalDelayType01    := VitalDefDelay01;
5145            CONSTANT    ResultMap :  IN VitalResultMapType
5146                                        := VitalDefaultResultMap
5147    ) IS
5148        VARIABLE LastData  : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
5149        VARIABLE NewValue        : std_logic_vector8;
5150        VARIABLE Glitch_Data    : GlitchArray8;
5151        VARIABLE new_schd       : SchedArray8;
5152        VARIABLE Dly, Glch      : TimeArray8;
5153        VARIABLE Enable_Schd    : SchedType;
5154        VARIABLE Enable_Edge    : EdgeType;
5155        VARIABLE Data_Edge      : EdgeArray3;
5156        VARIABLE Data_BSchd, Data_ISchd : SchedArray3;
5157        ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
5158        VARIABLE AllZeroDelay  : BOOLEAN := TRUE; --SN
5159    BEGIN
5160      -- ------------------------------------------------------------------------
5161      --  Check if ALL zero delay paths, use simple model
5162      --   ( No delay selection, glitch detection required )
5163      -- ------------------------------------------------------------------------
5164      IF (tpd_enable_q /= VitalZeroDelay01) THEN
5165          AllZeroDelay := FALSE;
5166      ELSE
5167          FOR i IN Data'RANGE LOOP
5168          IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
5169              AllZeroDelay := FALSE;
5170              EXIT;
5171          END IF;
5172          END LOOP;
5173      END IF;
5174      IF (AllZeroDelay) THEN LOOP
5175          q <= VitalDECODER(Data, Enable, ResultMap);
5176          WAIT ON Data, Enable;
5177      END LOOP;
5178      ELSE
5179
5180        -- --------------------------------------
5181        -- Initialize delay schedules
5182        -- --------------------------------------
5183        FOR n IN Data'RANGE LOOP
5184            BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
5185            InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
5186        END LOOP;
5187        BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
5188
5189      LOOP
5190        -- --------------------------------------
5191        -- Process input signals
5192        --   get edge values
5193        --   re-evaluate output schedules
5194        -- --------------------------------------
5195        GetEdge ( Data, LastData, Data_Edge );
5196        BufPath ( Data_BSchd, Data_Edge, Atpd_data_q );
5197        InvPath ( Data_ISchd, Data_Edge, Atpd_data_q );
5198
5199        BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
5200
5201        -- ------------------------------------
5202        -- Compute function and propation delaq
5203        -- ------------------------------------
5204        NewValue  := VitalDECODER8 ( Data, Enable, ResultMap );
5205        new_schd := VitalDECODER8 ( Data_BSchd, Data_ISchd, Enable_Schd );
5206
5207        -- ------------------------------------------------------
5208        -- Assign Outputs
5209        --  get delays to new value and possable glitch
5210        --  schedule output change with On Event glitch detection
5211        -- ------------------------------------------------------
5212        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
5213        VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
5214                             PrimGlitchMode, GlitchDelay=>Glch );
5215
5216        WAIT ON Data, Enable;
5217      END LOOP;
5218      END IF; --SN
5219    END;
5220--
5221    PROCEDURE VitalDECODER   (
5222            SIGNAL              q : OUT std_logic_vector;
5223            SIGNAL           Data :  IN std_logic_vector;
5224            SIGNAL         Enable :  IN std_ulogic;
5225            CONSTANT   tpd_data_q :  IN VitalDelayArrayType01;
5226            CONSTANT tpd_enable_q :  IN VitalDelayType01    := VitalDefDelay01;
5227            CONSTANT    ResultMap :  IN VitalResultMapType
5228                                        := VitalDefaultResultMap
5229    ) IS
5230        VARIABLE LastData  : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
5231        VARIABLE NewValue        : std_logic_vector(q'RANGE);
5232        VARIABLE Glitch_Data    : GlitchDataArrayType(q'RANGE);
5233        VARIABLE new_schd       : SchedArray(q'RANGE);
5234        VARIABLE Dly, Glch      : VitalTimeArray(q'RANGE);
5235        VARIABLE Enable_Schd    : SchedType;
5236        VARIABLE Enable_Edge    : EdgeType;
5237        VARIABLE Data_Edge      : EdgeArray(Data'RANGE);
5238        VARIABLE Data_BSchd, Data_ISchd : SchedArray(Data'RANGE);
5239        ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
5240        VARIABLE AllZeroDelay  : BOOLEAN := TRUE;
5241    BEGIN
5242      -- ------------------------------------------------------------------------
5243      --  Check if ALL zero delay paths, use simple model
5244      --   ( No delay selection, glitch detection required )
5245      -- ------------------------------------------------------------------------
5246      IF (tpd_enable_q /= VitalZeroDelay01) THEN
5247          AllZeroDelay := FALSE;
5248      ELSE
5249          FOR i IN Data'RANGE LOOP
5250          IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
5251              AllZeroDelay := FALSE;
5252              EXIT;
5253          END IF;
5254          END LOOP;
5255      END IF;
5256      IF (AllZeroDelay) THEN LOOP
5257          q <= VitalDECODER(Data, Enable, ResultMap);
5258          WAIT ON Data, Enable;
5259      END LOOP;
5260      ELSE
5261        -- --------------------------------------
5262        -- Initialize delay schedules
5263        -- --------------------------------------
5264        FOR n IN Data'RANGE LOOP
5265            BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
5266            InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
5267        END LOOP;
5268        BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
5269
5270      LOOP
5271        -- --------------------------------------
5272        -- Process input signals
5273        --   get edge values
5274        --   re-evaluate output schedules
5275        -- --------------------------------------
5276        GetEdge ( Data, LastData, Data_Edge );
5277        BufPath ( Data_BSchd, Data_Edge, Atpd_data_q );
5278        InvPath ( Data_ISchd, Data_Edge, Atpd_data_q );
5279
5280        BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
5281
5282        -- ------------------------------------
5283        -- Compute function and propation delaq
5284        -- ------------------------------------
5285        NewValue  := VitalDECODER ( Data, Enable, ResultMap );
5286        new_schd := VitalDECODER ( Data_BSchd, Data_ISchd, Enable_Schd );
5287
5288        -- ------------------------------------------------------
5289        -- Assign Outputs
5290        --  get delays to new value and possable glitch
5291        --  schedule output change with On Event glitch detection
5292        -- ------------------------------------------------------
5293        GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
5294        VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
5295                             PrimGlitchMode, GlitchDelay=>Glch );
5296
5297        WAIT ON Data, Enable;
5298      END LOOP;
5299      END IF;
5300    END;
5301
5302    -- ------------------------------------------------------------------------
5303    FUNCTION VitalTruthTable  (
5304            CONSTANT TruthTable   : IN VitalTruthTableType;
5305            CONSTANT DataIn       : IN std_logic_vector
5306          ) RETURN std_logic_vector IS
5307
5308        CONSTANT InputSize   : INTEGER := DataIn'LENGTH;
5309        CONSTANT OutSize     : INTEGER := TruthTable'LENGTH(2) - InputSize;
5310        VARIABLE ReturnValue : std_logic_vector(OutSize - 1 DOWNTO 0)
5311                               := (OTHERS => 'X');
5312        VARIABLE DataInAlias : std_logic_vector(0 TO InputSize - 1)
5313                               :=  To_X01(DataIn);
5314        VARIABLE Index       : INTEGER;
5315        VARIABLE Err         : BOOLEAN := FALSE;
5316
5317        -- This needs to be done since the TableLookup arrays must be
5318        -- ascending starting with 0
5319        VARIABLE TableAlias  : VitalTruthTableType(0 TO (TruthTable'LENGTH(1)-1),
5320                                                   0 TO (TruthTable'LENGTH(2)-1))
5321                                := TruthTable;
5322
5323    BEGIN
5324        -- search through each row of the truth table
5325        IF OutSize > 0 THEN
5326          ColLoop:
5327            FOR i IN TableAlias'RANGE(1) LOOP
5328
5329            RowLoop: -- Check each input element of the entry
5330              FOR j IN 0 TO InputSize LOOP
5331
5332                IF (j = InputSize) THEN -- This entry matches
5333                    -- Return the Result
5334                    Index := 0;
5335                    FOR k IN TruthTable'LENGTH(2) - 1 DOWNTO InputSize LOOP
5336                        TruthOutputX01Z ( TableAlias(i,k),
5337                                          ReturnValue(Index), Err);
5338                        EXIT WHEN Err;
5339                        Index := Index + 1;
5340                    END LOOP;
5341
5342                    IF Err THEN
5343                        ReturnValue := (OTHERS => 'X');
5344                    END IF;
5345                    RETURN ReturnValue;
5346                END IF;
5347                IF NOT ValidTruthTableInput(TableAlias(i,j)) THEN
5348                    VitalError ( "VitalTruthTable", ErrInpSym,
5349                                 To_TruthChar(TableAlias(i,j)) );
5350                    EXIT ColLoop;
5351                END IF;
5352                EXIT RowLoop WHEN NOT ( TruthTableMatch( DataInAlias(j),
5353                                                         TableAlias(i, j)));
5354              END LOOP RowLoop;
5355            END LOOP ColLoop;
5356
5357        ELSE
5358            VitalError ( "VitalTruthTable", ErrTabWidSml );
5359        END IF;
5360        RETURN ReturnValue;
5361    END VitalTruthTable;
5362
5363    FUNCTION VitalTruthTable  (
5364            CONSTANT TruthTable   : IN VitalTruthTableType;
5365            CONSTANT DataIn       : IN std_logic_vector
5366          ) RETURN std_logic IS
5367
5368        CONSTANT InputSize  : INTEGER := DataIn'LENGTH;
5369        CONSTANT OutSize    : INTEGER := TruthTable'LENGTH(2) - InputSize;
5370        VARIABLE TempResult : std_logic_vector(OutSize - 1 DOWNTO 0)
5371                              := (OTHERS => 'X');
5372    BEGIN
5373        IF (OutSize > 0) THEN
5374            TempResult := VitalTruthTable(TruthTable, DataIn);
5375            IF ( 1 > OutSize) THEN
5376                VitalError ( "VitalTruthTable", ErrTabResSml );
5377            ELSIF ( 1 < OutSize) THEN
5378                VitalError ( "VitalTruthTable", ErrTabResLrg );
5379            END IF;
5380            RETURN (TempResult(0));
5381        ELSE
5382            VitalError ( "VitalTruthTable", ErrTabWidSml );
5383            RETURN 'X';
5384        END IF;
5385    END VitalTruthTable;
5386
5387    PROCEDURE VitalTruthTable (
5388            SIGNAL   Result     : OUT std_logic_vector;
5389            CONSTANT TruthTable : IN  VitalTruthTableType;
5390            SIGNAL   DataIn     : IN  std_logic_vector        -- IR#236
5391    ) IS
5392        CONSTANT ResLeng     : INTEGER := Result'LENGTH;
5393        CONSTANT ActResLen   : INTEGER := TruthTable'LENGTH(2) - DataIn'LENGTH;
5394        CONSTANT FinalResLen : INTEGER := Minimum(ActResLen, ResLeng);
5395        VARIABLE TempResult  : std_logic_vector(ActResLen - 1 DOWNTO 0)
5396                                := (OTHERS => 'X');
5397
5398    BEGIN
5399        TempResult := VitalTruthTable(TruthTable, DataIn);
5400
5401        IF (ResLeng > ActResLen) THEN
5402            VitalError ( "VitalTruthTable", ErrTabResSml );
5403        ELSIF (ResLeng < ActResLen) THEN
5404            VitalError ( "VitalTruthTable", ErrTabResLrg );
5405        END IF;
5406        TempResult(FinalResLen-1 DOWNTO 0) := TempResult(FinalResLen-1 DOWNTO 0);
5407        Result <= TempResult;
5408
5409    END VitalTruthTable;
5410
5411    PROCEDURE VitalTruthTable (
5412            SIGNAL   Result     : OUT std_logic;
5413            CONSTANT TruthTable : IN VitalTruthTableType;
5414            SIGNAL DataIn       : IN std_logic_vector        -- IR#236
5415    ) IS
5416
5417        CONSTANT ActResLen  : INTEGER := TruthTable'LENGTH(2) - DataIn'LENGTH;
5418        VARIABLE TempResult : std_logic_vector(ActResLen - 1 DOWNTO 0)
5419                              := (OTHERS => 'X');
5420
5421    BEGIN
5422        TempResult := VitalTruthTable(TruthTable, DataIn);
5423
5424        IF ( 1 > ActResLen) THEN
5425            VitalError ( "VitalTruthTable", ErrTabResSml );
5426        ELSIF ( 1 < ActResLen) THEN
5427            VitalError ( "VitalTruthTable", ErrTabResLrg );
5428        END IF;
5429        IF (ActResLen >  0) THEN
5430            Result <= TempResult(0);
5431        END IF;
5432
5433    END VitalTruthTable;
5434
5435    -- ------------------------------------------------------------------------
5436    PROCEDURE VitalStateTable (
5437            VARIABLE Result         : INOUT std_logic_vector;
5438            VARIABLE PreviousDataIn : INOUT std_logic_vector;
5439            CONSTANT StateTable     : IN VitalStateTableType;
5440            CONSTANT DataIn         : IN std_logic_vector;
5441            CONSTANT NumStates      : IN NATURAL
5442    ) IS
5443
5444        CONSTANT InputSize     : INTEGER := DataIn'LENGTH;
5445        CONSTANT OutSize       : INTEGER
5446                                 := StateTable'LENGTH(2) - InputSize - NumStates;
5447        CONSTANT ResLeng       : INTEGER := Result'LENGTH;
5448        VARIABLE DataInAlias   : std_logic_vector(0 TO DataIn'LENGTH-1)
5449                                 := To_X01(DataIn);
5450        VARIABLE PrevDataAlias : std_logic_vector(0 TO PreviousDataIn'LENGTH-1)
5451                                 := To_X01(PreviousDataIn);
5452        VARIABLE ResultAlias   : std_logic_vector(0 TO ResLeng-1)
5453                                 := To_X01(Result);
5454        VARIABLE ExpResult     : std_logic_vector(0 TO OutSize-1);
5455
5456    BEGIN
5457        IF (PreviousDataIn'LENGTH < DataIn'LENGTH) THEN
5458            VitalError ( "VitalStateTable", ErrVctLng, "PreviousDataIn<DataIn");
5459
5460            ResultAlias := (OTHERS => 'X');
5461            Result := ResultAlias;
5462
5463        ELSIF (OutSize <= 0) THEN
5464            VitalError ( "VitalStateTable", ErrTabWidSml );
5465
5466            ResultAlias := (OTHERS => 'X');
5467            Result := ResultAlias;
5468
5469        ELSE
5470            IF (ResLeng > OutSize) THEN
5471                VitalError ( "VitalStateTable", ErrTabResSml );
5472            ELSIF (ResLeng < OutSize) THEN
5473                VitalError ( "VitalStateTable", ErrTabResLrg );
5474            END IF;
5475
5476            ExpResult := StateTableLookUp ( StateTable, DataInAlias,
5477                                            PrevDataAlias, NumStates,
5478                                            ResultAlias);
5479            ResultAlias := (OTHERS => 'X');
5480            ResultAlias ( Maximum(0, ResLeng - OutSize) TO ResLeng - 1)
5481                   := ExpResult(Maximum(0, OutSize - ResLeng) TO OutSize-1);
5482
5483            Result := ResultAlias;
5484            PrevDataAlias(0 TO InputSize - 1) := DataInAlias;
5485            PreviousDataIn := PrevDataAlias;
5486
5487        END IF;
5488    END VitalStateTable;
5489
5490
5491    PROCEDURE VitalStateTable (
5492            VARIABLE Result         : INOUT std_logic;        -- states
5493            VARIABLE PreviousDataIn : INOUT std_logic_vector; -- previous inputs and states
5494            CONSTANT StateTable     : IN VitalStateTableType; -- User's StateTable data
5495            CONSTANT DataIn         : IN std_logic_vector     -- Inputs
5496    ) IS
5497
5498        VARIABLE ResultAlias : std_logic_vector(0 TO 0);
5499    BEGIN
5500        ResultAlias(0) := Result;
5501        VitalStateTable ( StateTable     => StateTable,
5502                          DataIn         => DataIn,
5503                          NumStates      => 1,
5504                          Result         => ResultAlias,
5505                          PreviousDataIn => PreviousDataIn
5506                        );
5507        Result := ResultAlias(0);
5508
5509    END VitalStateTable;
5510
5511    PROCEDURE VitalStateTable (
5512            SIGNAL   Result     : INOUT std_logic_vector;
5513            CONSTANT StateTable : IN VitalStateTableType;
5514            SIGNAL   DataIn     : IN std_logic_vector;
5515            CONSTANT NumStates  : IN NATURAL
5516    ) IS
5517
5518        CONSTANT InputSize   : INTEGER := DataIn'LENGTH;
5519        CONSTANT OutSize     : INTEGER
5520                               := StateTable'LENGTH(2) - InputSize - NumStates;
5521        CONSTANT ResLeng     : INTEGER := Result'LENGTH;
5522
5523        VARIABLE PrevData    : std_logic_vector(0 TO DataIn'LENGTH-1)
5524                               := (OTHERS => 'X');
5525        VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1);
5526        VARIABLE ResultAlias : std_logic_vector(0 TO ResLeng-1);
5527        VARIABLE ExpResult   : std_logic_vector(0 TO OutSize-1);
5528
5529    BEGIN
5530        IF (OutSize <= 0) THEN
5531            VitalError ( "VitalStateTable", ErrTabWidSml );
5532
5533            ResultAlias  := (OTHERS => 'X');
5534            Result <= ResultAlias;
5535
5536        ELSE
5537            IF (ResLeng > OutSize) THEN
5538                VitalError ( "VitalStateTable", ErrTabResSml );
5539            ELSIF (ResLeng < OutSize) THEN
5540                VitalError ( "VitalStateTable", ErrTabResLrg );
5541            END IF;
5542
5543            LOOP
5544                DataInAlias := To_X01(DataIn);
5545                ResultAlias := To_X01(Result);
5546                ExpResult   := StateTableLookUp ( StateTable, DataInAlias,
5547                                                  PrevData, NumStates,
5548                                                  ResultAlias);
5549                ResultAlias := (OTHERS => 'X');
5550                ResultAlias(Maximum(0, ResLeng - OutSize) TO ResLeng-1)
5551                       := ExpResult(Maximum(0, OutSize - ResLeng) TO OutSize-1);
5552
5553                Result   <= ResultAlias;
5554                PrevData := DataInAlias;
5555
5556                WAIT ON DataIn;
5557            END LOOP;
5558
5559        END IF;
5560
5561    END VitalStateTable;
5562
5563    PROCEDURE VitalStateTable (
5564            SIGNAL   Result     : INOUT std_logic;
5565            CONSTANT StateTable : IN VitalStateTableType;
5566            SIGNAL   DataIn     : IN std_logic_vector
5567    ) IS
5568
5569        CONSTANT InputSize   : INTEGER := DataIn'LENGTH;
5570        CONSTANT OutSize     : INTEGER := StateTable'LENGTH(2) - InputSize-1;
5571
5572        VARIABLE PrevData    : std_logic_vector(0 TO DataIn'LENGTH-1)
5573                               := (OTHERS => 'X');
5574        VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1);
5575        VARIABLE ResultAlias : std_logic_vector(0 TO 0);
5576        VARIABLE ExpResult   : std_logic_vector(0 TO OutSize-1);
5577
5578    BEGIN
5579        IF (OutSize <= 0) THEN
5580            VitalError ( "VitalStateTable", ErrTabWidSml );
5581
5582            Result <= 'X';
5583
5584        ELSE
5585            IF ( 1 > OutSize) THEN
5586                VitalError ( "VitalStateTable", ErrTabResSml );
5587            ELSIF ( 1 < OutSize) THEN
5588                VitalError ( "VitalStateTable", ErrTabResLrg );
5589            END IF;
5590
5591            LOOP
5592                ResultAlias(0) := To_X01(Result);
5593                DataInAlias := To_X01(DataIn);
5594                ExpResult   := StateTableLookUp ( StateTable, DataInAlias,
5595                                                  PrevData, 1, ResultAlias);
5596
5597                Result   <= ExpResult(OutSize-1);
5598                PrevData := DataInAlias;
5599
5600                WAIT ON DataIn;
5601            END LOOP;
5602        END IF;
5603
5604    END VitalStateTable;
5605
5606    -- ------------------------------------------------------------------------
5607    -- std_logic resolution primitive
5608    -- ------------------------------------------------------------------------
5609    PROCEDURE VitalResolve (
5610            SIGNAL              q : OUT std_ulogic;
5611            SIGNAL         Data :  IN std_logic_vector  --IR236 4/2/98
5612    ) IS
5613        VARIABLE uData : std_ulogic_vector(Data'RANGE);
5614    BEGIN
5615        FOR i IN Data'RANGE LOOP
5616            uData(i) := Data(i);
5617        END LOOP;
5618        q <= resolved(uData);
5619    END;
5620
5621END VITAL_Primitives;
5622
5623