aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/vital2000
diff options
context:
space:
mode:
authorgingold <gingold@b72b5c32-5f01-0410-b925-b5c7b92870f7>2005-09-24 05:10:24 +0000
committergingold <gingold@b72b5c32-5f01-0410-b925-b5c7b92870f7>2005-09-24 05:10:24 +0000
commit977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849 (patch)
tree7bcf8e7aff40a8b54d4af83e90cccd73568e77bb /libraries/vital2000
downloadghdl-977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849.tar.gz
ghdl-977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849.tar.bz2
ghdl-977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849.zip
First import from sources
Diffstat (limited to 'libraries/vital2000')
-rw-r--r--libraries/vital2000/memory_b.vhdl7151
-rw-r--r--libraries/vital2000/memory_p.vhdl1729
-rw-r--r--libraries/vital2000/prmtvs_b.vhdl5622
-rw-r--r--libraries/vital2000/prmtvs_p.vhdl1413
-rw-r--r--libraries/vital2000/timing_b.vhdl2187
-rw-r--r--libraries/vital2000/timing_p.vhdl1202
6 files changed, 19304 insertions, 0 deletions
diff --git a/libraries/vital2000/memory_b.vhdl b/libraries/vital2000/memory_b.vhdl
new file mode 100644
index 000000000..0376ee4d3
--- /dev/null
+++ b/libraries/vital2000/memory_b.vhdl
@@ -0,0 +1,7151 @@
+-- ----------------------------------------------------------------------------
+-- Title : Standard VITAL Memory Package
+-- :
+-- Library : Vital_Memory
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- : Ekambaram Balaji, LSI Logic Corporation
+-- : Jose De Castro, Consultant
+-- : Prakash Bare, GDA Technologies
+-- : William Yam, LSI Logic Corporation
+-- : Dennis Brophy, Model Technology
+-- :
+-- Purpose : This packages defines standard types, constants, functions
+-- : and procedures for use in developing ASIC memory models.
+-- :
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Ver:|Auth:| Date:| Changes Made:
+-- 0.1 | eb |071796| First prototye as part of VITAL memory proposal
+-- 0.2 | jdc |012897| Initial prototyping with proposed MTM scheme
+-- 0.3 | jdc |090297| Extensive updates for TAG review (functional)
+-- 0.4 | eb |091597| Changed naming conventions for VitalMemoryTable
+-- | | | Added interface of VitalMemoryCrossPorts() &
+-- | | | VitalMemoryViolation().
+-- 0.5 | jdc |092997| Completed naming changes thoughout package body.
+-- | | | Testing with simgle port test model looks ok.
+-- 0.6 | jdc |121797| Major updates to the packages:
+-- | | | - Implement VitalMemoryCrossPorts()
+-- | | | - Use new VitalAddressValueType
+-- | | | - Use new VitalCrossPortModeType enum
+-- | | | - Overloading without SamePort args
+-- | | | - Honor erroneous address values
+-- | | | - Honor ports disabled with 'Z'
+-- | | | - Implement implicit read 'M' table symbol
+-- | | | - Cleanup buses to use (H DOWNTO L)
+-- | | | - Message control via MsgOn,HeaderMsg,PortName
+-- | | | - Tested with 1P1RW,2P2RW,4P2R2W,4P4RW cases
+-- 0.7 | jdc |052698| Bug fixes to the packages:
+-- | | | - Fix failure with negative Address values
+-- | | | - Added debug messages for VMT table search
+-- | | | - Remove 'S' for action column (only 's')
+-- | | | - Remove 's' for response column (only 'S')
+-- | | | - Remove 'X' for action and response columns
+-- 0.8 | jdc |061298| Implemented VitalMemoryViolation()
+-- | | | - Minimal functionality violation tables
+-- | | | - Missing:
+-- | | | - Cannot handle wide violation variables
+-- | | | - Cannot handle sub-word cases
+-- | | | Fixed IIC version of MemoryMatch
+-- | | | Fixed 'M' vs 'm' switched on debug output
+-- | | | TO BE DONE:
+-- | | | - Implement 'd' corrupting a single bit
+-- | | | - Implement 'D' corrupting a single bit
+-- 0.9 |eb/sc|080498| Added UNDEF value for VitalPortFlagType
+-- 0.10|eb/sc|080798| Added CORRUPT value for VitalPortFlagType
+-- 0.11|eb/sc|081798| Added overloaded function interface for
+-- | | | VitalDeclareMemory
+-- 0.14| jdc |113198| Merging of memory functionality and version
+-- | | | 1.4 9/17/98 of timing package from Prakash
+-- 0.15| jdc |120198| Major development of VMV functionality
+-- 0.16| jdc |120298| Complete VMV functionlality for initial testing
+-- | | | - New ViolationTableCorruptMask() procedure
+-- | | | - New MemoryTableCorruptMask() procedure
+-- | | | - HandleMemoryAction():
+-- | | | - Removed DataOutBus bogus output
+-- | | | - Replaced DataOutTmp with DataInTmp
+-- | | | - Added CorruptMask input handling
+-- | | | - Implemented 'd','D' using CorruptMask
+-- | | | - CorruptMask on 'd','C','L','D','E'
+-- | | | - CorruptMask ignored on 'c','l','e'
+-- | | | - Changed 'l','d','e' to set PortFlag to CORRUPT
+-- | | | - Changed 'L','D','E' to set PortFlag to CORRUPT
+-- | | | - Changed 'c','l','d','e' to ignore HighBit, LowBit
+-- | | | - Changed 'C','L','D','E' to use HighBit, LowBit
+-- | | | - HandleDataAction():
+-- | | | - Added CorruptMask input handling
+-- | | | - Implemented 'd','D' using CorruptMask
+-- | | | - CorruptMask on 'd','C','L','D','E'
+-- | | | - CorruptMask ignored on 'l','e'
+-- | | | - Changed 'l','d','e' to set PortFlag to CORRUPT
+-- | | | - Changed 'L','D','E' to set PortFlag to CORRUPT
+-- | | | - Changed 'l','d','e' to ignore HighBit, LowBit
+-- | | | - Changed 'L','D','E' to use HighBit, LowBit
+-- | | | - MemoryTableLookUp():
+-- | | | - Added MsgOn table debug output
+-- | | | - Uses new MemoryTableCorruptMask()
+-- | | | - ViolationTableLookUp():
+-- | | | - Uses new ViolationTableCorruptMask()
+-- 0.17| jdc |120898| - Added VitalMemoryViolationSymbolType,
+-- | | | VitalMemoryViolationTableType data
+-- | | | types but not used yet (need to discuss)
+-- | | | - Added overload for VitalMemoryViolation()
+-- | | | which does not have array flags
+-- | | | - Bug fixes for VMV functionality:
+-- | | | - ViolationTableLookUp() not handling '-' in
+-- | | | scalar violation matching
+-- | | | - VitalMemoryViolation() now normalizes
+-- | | | VFlagArrayTmp'LEFT as LSB before calling
+-- | | | ViolationTableLookUp() for proper scanning
+-- | | | - ViolationTableCorruptMask() had to remove
+-- | | | normalization of CorruptMaskTmp and
+-- | | | ViolMaskTmp for proper MSB:LSB corruption
+-- | | | - HandleMemoryAction(), HandleDataAction()
+-- | | | - Removed 'D','E' since not being used
+-- | | | - Use XOR instead of OR for corrupt masks
+-- | | | - Now 'd' is sensitive to HighBit, LowBit
+-- | | | - Fixed LowBit overflow in bit writeable case
+-- | | | - MemoryTableCorruptMask()
+-- | | | - ViolationTableCorruptMask()
+-- | | | - VitalMemoryTable()
+-- | | | - VitalMemoryCrossPorts()
+-- | | | - Fixed VitalMemoryViolation() failing on
+-- | | | error AddressValue from earlier VMT()
+-- | | | - Minor cleanup of code formatting
+-- 0.18| jdc |032599| - In VitalDeclareMemory()
+-- | | | - Added BinaryLoadFile formal arg and
+-- | | | modified LoadMemory() to handle bin
+-- | | | - Added NOCHANGE to VitalPortFlagType
+-- | | | - For VitalCrossPortModeType
+-- | | | - Added CpContention enum
+-- | | | - In HandleDataAction()
+-- | | | - Set PortFlag := NOCHANGE for 'S'
+-- | | | - In HandleMemoryAction()
+-- | | | - Set PortFlag := NOCHANGE for 's'
+-- | | | - In VitalMemoryTable() and
+-- | | | VitalMemoryViolation()
+-- | | | - Honor PortFlag = NOCHANGE returned
+-- | | | from HandleMemoryAction()
+-- | | | - In VitalMemoryCrossPorts()
+-- | | | - Fixed Address = AddressJ for all
+-- | | | conditions of DoWrCont & DoCpRead
+-- | | | - Handle CpContention like WrContOnly
+-- | | | under CpReadOnly conditions, with
+-- | | | associated memory message changes
+-- | | | - Handle PortFlag = NOCHANGE like
+-- | | | PortFlag = READ for actions
+-- | | | - Modeling change:
+-- | | | - Need to init PortFlag every delta
+-- | | | PortFlag_A := (OTHES => UNDEF);
+-- | | | - Updated InternalTimingCheck code
+-- 0.19| jdc |042599| - Fixes for bit-writeable cases
+-- | | | - Check PortFlag after HandleDataAction
+-- | | | in VitalMemoryViolation()
+-- 0.20| jdc |042599| - Merge PortFlag changes from Prakash
+-- | | | and Willian:
+-- | | | VitalMemorySchedulePathDelay()
+-- | | | VitalMemoryExpandPortFlag()
+-- 0.21| jdc |072199| - Changed VitalCrossPortModeType enums,
+-- | | | added new CpReadAndReadContention.
+-- | | | - Fixed VitalMemoryCrossPorts() parameter
+-- | | | SamePortFlag to INOUT so that it can
+-- | | | set CORRUPT or READ value.
+-- | | | - Fixed VitalMemoryTable() where PortFlag
+-- | | | setting by HandleDataAction() is being
+-- | | | ignored when HandleMemoryAction() sets
+-- | | | PortFlagTmp to NOCHANGE.
+-- | | | - Fixed VitalMemoryViolation() to set
+-- | | | all bits of PortFlag when violating.
+-- 0.22| jdc |072399| - Added HIGHZ to PortFlagType. HandleData
+-- | | | checks whether the previous state is HIGHZ.
+-- | | | If yes then portFlag should be NOCHANGE
+-- | | | for VMPD to ignore IORetain corruption.
+-- | | | The idea is that the first Z should be
+-- | | | propagated but later ones should be ignored.
+-- | | |
+-- 0.23| jdc |100499| - Took code checked in by Dennis 09/28/99
+-- | | | - Changed VitalPortFlagType to record of
+-- | | | new VitalPortStateType to hold current,
+-- | | | previous values and separate disable.
+-- | | | Also created VitalDefaultPortFlag const.
+-- | | | Removed usage of PortFlag NOCHANGE
+-- | | | - VitalMemoryTable() changes:
+-- | | | Optimized return when all curr = prev
+-- | | | AddressValue is now INOUT to optimize
+-- | | | Transfer PF.MemoryCurrent to MemoryPrevious
+-- | | | Transfer PF.DataCurrent to DataPrevious
+-- | | | Reset PF.OutputDisable to FALSE
+-- | | | Expects PortFlag init in declaration
+-- | | | No need to init PortFlag every delta
+-- | | | - VitalMemorySchedulePathDelay() changes:
+-- | | | Initialize with VitalDefaultPortFlag
+-- | | | Check PortFlag.OutputDisable
+-- | | | - HandleMemoryAction() changes:
+-- | | | Set value of PortFlag.MemoryCurrent
+-- | | | Never set PortFlag.OutputDisable
+-- | | | - HandleDataAction() changes:
+-- | | | Set value of PortFlag.DataCurrent
+-- | | | Set PortFlag.DataCurrent for HIGHZ
+-- | | | - VitalMemoryCrossPorts() changes:
+-- | | | Check/set value of PF.MemoryCurrent
+-- | | | Check value of PF.OutputDisable
+-- | | | - VitalMemoryViolation() changes:
+-- | | | Fixed bug - not reading inout PF value
+-- | | | Clean up setting of PortFlag
+-- 0.24| jdc |100899| - Modified update of PF.OutputDisable
+-- | | | to correctly accomodate 2P1W1R case:
+-- | | | the read port should not exhibit
+-- | | | IO retain corrupt when reading
+-- | | | addr unrelated to addr being written.
+-- 0.25| jdc |100999| - VitalMemoryViolation() change:
+-- | | | Fixed bug with RDNWR mode incorrectly
+-- | | | updating the PF.OutputDisable
+-- 0.26| jdc |100999| - VitalMemoryCrossPorts() change:
+-- | | | Fixed bugs with update of PF
+-- 0.27| jdc |101499| - VitalMemoryCrossPorts() change:
+-- | | | Added DoRdWrCont message (ErrMcpRdWrCo,
+-- | | | Memory cross port read/write data only
+-- | | | contention)
+-- | | | - VitalMemoryTable() change:
+-- | | | Set PF.OutputDisable := TRUE for the
+-- | | | optimized cases.
+-- 0.28| pb |112399| - Added 8 VMPD procedures for vector
+-- | | | PathCondition support. Now the total
+-- | | | number of overloadings for VMPD is 24.
+-- | | | - Number of overloadings for SetupHold
+-- | | | procedures increased to 5. Scalar violations
+-- | | | are not supported anymore. Vector checkEnabled
+-- | | | support is provided through the new overloading
+-- 0.29| jdc |120999| - HandleMemoryAction() HandleDataAction()
+-- | | | Reinstated 'D' and 'E' actions but
+-- | | | with new PortFlagType
+-- | | | - Updated file handling syntax, must compile
+-- | | | with -93 syntax now.
+-- 0.30| jdc |022300| - Formated for 80 column max width
+-- ----------------------------------------------------------------------------
+
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.Vital_Timing.all;
+USE IEEE.Vital_Primitives.all;
+
+LIBRARY STD;
+USE STD.TEXTIO.ALL;
+
+-- ----------------------------------------------------------------------------
+PACKAGE BODY Vital_Memory IS
+
+-- ----------------------------------------------------------------------------
+-- Timing Section
+-- ----------------------------------------------------------------------------
+
+FILE LogFile : TEXT OPEN write_mode IS "delayLog";
+FILE Output : TEXT OPEN write_mode IS "STD_OUTPUT";
+
+-- Added for turning off the debug msg..
+CONSTANT PrintDebugMsg : STD_ULOGIC := '0';
+ -- '0' - don't print in STD OUTPUT
+ -- '1' - print in STD OUTPUT
+
+-- Type and constant definitions for type conversion.
+TYPE MVL9_TO_CHAR_TBL IS ARRAY (STD_ULOGIC) OF character;
+
+--constant MVL9_to_char: MVL9_TO_CHAR_TBL := "UX01ZWLH-";
+CONSTANT MVL9_to_char: MVL9_TO_CHAR_TBL := "XX01ZX010";
+
+-- ----------------------------------------------------------------------------
+-- STD_LOGIC WRITE UTILITIES
+-- ----------------------------------------------------------------------------
+PROCEDURE WRITE(
+ l : INOUT line;
+ val : IN std_logic_vector;
+ justify : IN side := right;
+ field : IN width := 0
+) IS
+ VARIABLE invect : std_logic_vector(val'LENGTH DOWNTO 1);
+ VARIABLE ins : STRING(val'LENGTH DOWNTO 1);
+BEGIN
+ invect := val;
+ FOR I IN invect'length DOWNTO 1 LOOP
+ ins(I) := MVL9_to_char(invect(I));
+ END LOOP;
+ WRITE(L, ins, justify, field);
+END;
+
+PROCEDURE WRITE(
+ l : INOUT line;
+ val : IN std_ulogic;
+ justify : IN side := right;
+ field : in width := 0
+) IS
+ VARIABLE ins : CHARACTER;
+BEGIN
+ ins := MVL9_to_char(val);
+ WRITE(L, ins, justify, field);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE DelayValue(
+ InputTime : IN TIME ;
+ outline : INOUT LINE
+) IS
+ CONSTANT header : STRING := "TIME'HIGH";
+BEGIN
+ IF(InputTime = TIME'HIGH) THEN
+ WRITE(outline, header);
+ ELSE
+ WRITE(outline, InputTime);
+ END IF;
+END DelayValue;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintScheduleDataArray (
+ ScheduleDataArray : IN VitalMemoryScheduleDataVectorType
+) IS
+ VARIABLE outline1 : LINE;
+ VARIABLE outline2 : LINE;
+ VARIABLE value : TIME;
+ CONSTANT empty : STRING := " ";
+ CONSTANT header1 : STRING := "i Age PropDly RetainDly";
+ CONSTANT header2 : STRING := "i Sc.Value Output Lastvalue Sc.Time";
+BEGIN
+ WRITE (outline1, empty);
+ WRITE (outline1, NOW);
+ outline2 := outline1;
+ WRITELINE (LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITE (outline1, header1);
+ outline2 := outline1;
+ WRITELINE (LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ FOR i IN ScheduleDataArray'RANGE LOOP
+ WRITE (outline1, i );
+ WRITE (outline1, empty);
+ DelayValue(ScheduleDataArray(i).InputAge, outline1);
+ WRITE (outline1, empty);
+ DelayValue(ScheduleDataArray(i).PropDelay, outline1);
+ WRITE (outline1, empty);
+ DelayValue(ScheduleDataArray(i).OutputRetainDelay, outline1);
+ outline2 := outline1;
+ WRITELINE (LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ END LOOP;
+ WRITE (outline1, header2);
+ outline2 := outline1;
+ WRITELINE (LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ FOR i IN ScheduleDataArray'RANGE LOOP
+ WRITE (outline1, i );
+ WRITE (outline1, empty);
+ WRITE (outline1, ScheduleDataArray(i).ScheduleValue);
+ WRITE (outline1, empty);
+ WRITE (outline1, ScheduleDataArray(i).OutputData);
+ WRITE (outline1, empty);
+ WRITE (outline1, ScheduleDataArray(i).LastOutputValue );
+ WRITE (outline1, empty);
+ DelayValue(ScheduleDataArray(i).ScheduleTime, outline1);
+ outline2 := outline1;
+ WRITELINE (LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ END LOOP;
+ WRITE (outline1, empty);
+ WRITE (outline2, empty);
+ WRITELINE (LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (Output, outline2);
+ END IF;
+END PrintScheduleDataArray;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintArcType (
+ ArcType : IN VitalMemoryArcType
+) IS
+ VARIABLE outline1, outline2 : LINE;
+ CONSTANT empty : STRING := " ";
+ CONSTANT cross : STRING := "CrossArc";
+ CONSTANT para : STRING := "ParallelArc";
+ CONSTANT sub : STRING := "SubWordArc";
+ CONSTANT Header1 : STRING := "Path considered @ ";
+ CONSTANT Header2 : STRING := " is ";
+BEGIN
+ WRITELINE (LogFile, outline1);
+ WRITE (outline1, header1);
+ WRITE (outline1, NOW);
+ WRITE (outline1, empty);
+ WRITE (outline1, header2);
+ WRITE (outline1, empty);
+ case ArcType is
+ WHEN CrossArc =>
+ WRITE (outline1, cross);
+ WHEN ParallelArc =>
+ WRITE (outline1, para);
+ WHEN SubwordArc =>
+ WRITE (outline1, sub);
+ END CASE;
+ outline2 := outline1 ;
+ -- Appears on STD OUT
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (Output, outline1);
+ END IF;
+ WRITELINE (LogFile, outline2);
+END PrintArcType;
+
+-- ----------------------------------------------------------------------------
+-- This returns the value picked from the delay array
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintDelay (
+ outbitpos : IN INTEGER;
+ InputArrayLow : IN INTEGER;
+ InputArrayHigh : IN INTEGER;
+ debugprop : IN VitalTimeArrayT;
+ debugretain : IN VitalTimeArrayT
+) IS
+ VARIABLE outline1 : LINE;
+ VARIABLE outline2 : LINE;
+ VARIABLE outline3 : LINE;
+ VARIABLE outline4 : LINE;
+ VARIABLE outline5 : LINE;
+ VARIABLE outline6 : LINE;
+ CONSTANT empty : STRING := " ";
+ CONSTANT empty5 : STRING := " ";
+ CONSTANT header1 : STRING := "Prop. delays : ";
+ CONSTANT header2 : STRING := "Retain delays : ";
+ CONSTANT header3 : STRING := "output bit : ";
+BEGIN
+ WRITE(outline1, header3);
+ WRITE(outline1, outbitpos);
+ outline2 := outline1;
+ WRITELINE(LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE(output, outline2);
+ END IF;
+ WRITE(outline1, header1);
+ WRITE (outline1, empty5);
+ FOR i IN InputArrayHigh DOWNTO InputArrayLow LOOP
+ DelayValue(debugprop(i), outline1);
+ WRITE(outline1, empty);
+ END LOOP;
+ outline2 := outline1;
+ WRITELINE(LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE(output, outline2);
+ END IF;
+ WRITE(outline1, header2);
+ WRITE (outline1, empty5);
+ FOR i in InputArrayHigh DOWNTO InputArrayLow LOOP
+ DelayValue(debugretain(i), outline1);
+ WRITE(outline1, empty);
+ END LOOP;
+ outline2 := outline1;
+ WRITELINE(LogFile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE(output, outline2);
+ END IF;
+END PrintDelay;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE DebugMsg1 IS
+ CONSTANT header1:STRING:= "******************************************";
+ CONSTANT header2 :STRING:="Entering the process because of an i/p change";
+ variable outline1, outline2 : LINE;
+BEGIN
+ WRITE(outline1, header1);
+ outline2 := outline1;
+ WRITELINE (Logfile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITE(outline1, header2);
+ outline2 := outline1;
+ WRITELINE (Logfile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITE(outline1, header1);
+ outline2 := outline1;
+ WRITELINE (Logfile, outline1);
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+END DebugMsg1;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE ScheduleDebugMsg IS
+ CONSTANT header1 : STRING := "******************************************";
+ CONSTANT header2 : STRING := "Finished executing all the procedures";
+ VARIABLE outline1 : LINE;
+ VARIABLE outline2 : LINE;
+BEGIN
+ WRITE(outline1, header1);
+ outline2 := outline1;
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITELINE (Logfile, outline1);
+ WRITE(outline1, header2);
+ outline2 := outline1;
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITELINE (Logfile, outline1);
+ WRITE(outline1, header1);
+ outline2 := outline1;
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITELINE (Logfile, outline1);
+END ScheduleDebugMsg;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintInputName(
+ InputSignalName : IN STRING
+) IS
+ VARIABLE outline1 : LINE;
+ VARIABLE outline2 : LINE;
+ CONSTANT header1 : STRING := "***Changing input is ";
+ CONSTANT header2 : STRING := "(";
+ CONSTANT header3 : STRING := ")";
+ CONSTANT header4 : STRING := "****";
+ CONSTANT header5 : STRING := "******************************************";
+ CONSTANT header6 : STRING:="Entering the process because of an i/p change";
+ CONSTANT empty : STRING := " ";
+BEGIN
+ WRITE(outline1, header5);
+ outline2 := outline1;
+ WRITELINE (output, outline1);
+ WRITELINE (Logfile, outline2);
+ WRITE(outline1, header6);
+ outline2 := outline1;
+ WRITELINE (output, outline1);
+ WRITELINE (Logfile, outline2);
+ WRITE(outline1, header5);
+ outline2 := outline1;
+ WRITELINE (output, outline1);
+ WRITELINE (Logfile, outline2);
+ WRITE(outline1, header1);
+ WRITE(outline1, InputSignalName);
+ WRITE(outline1, empty);
+ WRITE(outline1, now);
+ WRITE(outline1, empty);
+ WRITE(outline1, header4);
+ WRITELINE (output, outline1);
+ WRITELINE (Logfile, outline2);
+END PrintInputName;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintInputChangeTime(
+ ChangeTimeArray : IN VitalTimeArrayT
+) IS
+ VARIABLE outline1 : LINE;
+ VARIABLE outline2 : LINE;
+ CONSTANT header5 : STRING := "*************************************";
+ CONSTANT header6 : STRING:="ChangeTime Array : ";
+ CONSTANT empty : STRING := " ";
+BEGIN
+ WRITE(outline1, header5);
+ outline2 := outline1;
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITELINE (Logfile, outline1);
+ WRITE(outline1, header6);
+ FOR i in ChangeTimeArray'range LOOP
+ WRITE(outline1, ChangeTimeArray(i));
+ WRITE(outline1, empty);
+ END LOOP;
+ outline2 := outline1;
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITELINE (Logfile, outline1);
+ WRITE(outline1, header5);
+ outline2 := outline1;
+ IF (PrintDebugMsg = '1') THEN
+ WRITELINE (output, outline2);
+ END IF;
+ WRITELINE (Logfile, outline1);
+END PrintInputChangeTime;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintInputChangeTime(
+ ChangeTime : IN Time
+) IS
+ VARIABLE ChangeTimeArray : VitalTimeArrayT(0 DOWNTO 0);
+BEGIN
+ ChangeTimeArray(0) := ChangeTime;
+ PrintInputChangeTime(ChangeTimeArray);
+END PrintInputChangeTime;
+
+-- ----------------------------------------------------------------------------
+-- for debug purpose
+CONSTANT MaxNoInputBits : INTEGER := 1000;
+
+TYPE VitalMemoryDelayType IS RECORD
+ PropDelay : TIME;
+ OutputRetainDelay : TIME;
+END RECORD;
+
+-- ----------------------------------------------------------------------------
+-- PROCEDURE: IntToStr
+--
+-- PARAMETERS: InputInt - Integer to be converted to String.
+-- ResultStr - String buffer for converted Integer
+-- AppendPos - Position in buffer to place result
+--
+-- DESCRIPTION: This procedure is used to convert an input integer
+-- into a string representation. The converted string
+-- may be placed at a specific position in the result
+-- buffer.
+--
+-- ----------------------------------------------------------------------------
+
+PROCEDURE IntToStr (
+ InputInt : IN INTEGER ;
+ ResultStr : INOUT STRING ( 1 TO 256) ;
+ AppendPos : INOUT NATURAL
+) IS
+ -- Look-up table. Given an int, we can get the character.
+ TYPE integer_table_type IS ARRAY (0 TO 9) OF CHARACTER ;
+ CONSTANT integer_table : integer_table_type :=
+ ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ;
+ -- Local variables used in this function.
+ VARIABLE inpVal : INTEGER := inputInt ;
+ VARIABLE divisor : INTEGER := 10 ;
+ VARIABLE tmpStrIndex : INTEGER := 1 ;
+ VARIABLE tmpStr : STRING ( 1 TO 256 ) ;
+BEGIN
+ IF ( inpVal = 0 ) THEN
+ tmpStr(tmpStrIndex) := integer_table ( 0 ) ;
+ tmpStrIndex := tmpStrIndex + 1 ;
+ ELSE
+ WHILE ( inpVal > 0 ) LOOP
+ tmpStr(tmpStrIndex) := integer_table (inpVal mod divisor);
+ tmpStrIndex := tmpStrIndex + 1 ;
+ inpVal := inpVal / divisor ;
+ END LOOP ;
+ END IF ;
+ IF (appendPos /= 1 ) THEN
+ resultStr(appendPos) := ',' ;
+ appendPos := appendPos + 1 ;
+ END IF ;
+
+ FOR i IN tmpStrIndex-1 DOWNTO 1 LOOP
+ resultStr(appendPos) := tmpStr(i) ;
+ appendPos := appendPos + 1 ;
+ END LOOP ;
+END IntToStr ;
+
+-- ----------------------------------------------------------------------------
+TYPE CheckType IS (
+ SetupCheck,
+ HoldCheck,
+ RecoveryCheck,
+ RemovalCheck,
+ PulseWidCheck,
+ PeriodCheck
+);
+
+TYPE CheckInfoType IS RECORD
+ Violation : BOOLEAN;
+ CheckKind : CheckType;
+ ObsTime : TIME;
+ ExpTime : TIME;
+ DetTime : TIME;
+ State : X01;
+END RECORD;
+
+TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER;
+TYPE HiLoStrType IS ARRAY (std_ulogic RANGE 'X' TO '1') OF STRING(1 TO 4);
+
+CONSTANT LogicCvtTable : LogicCvtTableType
+ := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
+CONSTANT HiLoStr : HiLoStrType := (" X ", " Low", "High" );
+
+TYPE EdgeSymbolMatchType IS ARRAY (X01,X01,VitalEdgeSymbolType) OF BOOLEAN;
+
+-- last value, present value, edge symbol
+CONSTANT EdgeSymbolMatch : EdgeSymbolMatchType :=
+ (
+ 'X' =>
+ ( 'X'=>( OTHERS => FALSE),
+ '0'=>('N'|'F'|'v'|'E'|'D'|'*' => TRUE, OTHERS => FALSE ),
+ '1'=>('P'|'R'|'^'|'E'|'A'|'*' => TRUE, OTHERS => FALSE )
+ ),
+ '0' =>
+ ( 'X'=>( 'r'|'p'|'R'|'A'|'*' => TRUE, OTHERS => FALSE ),
+ '0'=>( OTHERS => FALSE ),
+ '1'=>( '/'|'P'|'p'|'R'|'*' => TRUE, OTHERS => FALSE )
+ ),
+ '1' =>
+ ( 'X'=>( 'f'|'n'|'F'|'D'|'*' => TRUE, OTHERS => FALSE ),
+ '0'=>( '\'|'N'|'n'|'F'|'*' => TRUE, OTHERS => FALSE ),
+ '1'=>( OTHERS => FALSE )
+ )
+ );
+
+-- ----------------------------------------------------------------------------
+FUNCTION Minimum (
+ CONSTANT t1, t2 : IN TIME
+) RETURN TIME IS
+BEGIN
+ IF (t1 < t2) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+END Minimum;
+
+-- ----------------------------------------------------------------------------
+FUNCTION Maximum (
+ CONSTANT t1, t2 : IN TIME
+) RETURN TIME IS
+BEGIN
+ IF (t1 < t2) THEN RETURN (t2); ELSE RETURN (t1); END IF;
+END Maximum;
+
+-- ----------------------------------------------------------------------------
+-- FUNCTION: VitalMemoryCalcDelay
+-- Description: Select Transition dependent Delay.
+-- Used internally by VitalMemorySelectDelay.
+-- ----------------------------------------------------------------------------
+FUNCTION VitalMemoryCalcDelay (
+ CONSTANT NewVal : IN STD_ULOGIC := 'X';
+ CONSTANT OldVal : IN STD_ULOGIC := 'X';
+ CONSTANT Delay : IN VitalDelayType01ZX
+) RETURN VitalMemoryDelayType IS
+ VARIABLE Result : VitalMemoryDelayType;
+BEGIN
+ CASE Oldval IS
+ WHEN '0' | 'L' =>
+ CASE Newval IS
+ WHEN '0' | 'L' =>
+ Result.PropDelay := Delay(tr10);
+ WHEN '1' | 'H' =>
+ Result.PropDelay := Delay(tr01);
+ WHEN 'Z' =>
+ Result.PropDelay := Delay(tr0Z);
+ WHEN OTHERS =>
+ Result.PropDelay := Minimum(Delay(tr01), Delay(tr0Z));
+ END CASE;
+ Result.OutputRetainDelay := Delay(tr0X);
+ WHEN '1' | 'H' =>
+ CASE Newval IS
+ WHEN '0' | 'L' =>
+ Result.PropDelay := Delay(tr10);
+ WHEN '1' | 'H' =>
+ Result.PropDelay := Delay(tr01);
+ WHEN 'Z' =>
+ Result.PropDelay := Delay(tr1Z);
+ WHEN OTHERS =>
+ Result.PropDelay := Minimum(Delay(tr10), Delay(tr1Z));
+ END CASE;
+ Result.OutputRetainDelay := Delay(tr1X);
+ WHEN 'Z' =>
+ CASE Newval IS
+ WHEN '0' | 'L' =>
+ Result.PropDelay := Delay(trZ0);
+ WHEN '1' | 'H' =>
+ Result.PropDelay := Delay(trZ1);
+ WHEN 'Z' =>
+ Result.PropDelay := Maximum(Delay(tr1Z), Delay(tr0Z));
+ WHEN OTHERS =>
+ Result.PropDelay := Minimum(Delay(trZ1), Delay(trZ0));
+ END CASE;
+ Result.OutputRetainDelay := Delay(trZX);
+ WHEN OTHERS =>
+ CASE Newval IS
+ WHEN '0' | 'L' =>
+ Result.PropDelay := Maximum(Delay(tr10), Delay(trZ0));
+ WHEN '1' | 'H' =>
+ Result.PropDelay := Maximum(Delay(tr01), Delay(trZ1));
+ WHEN 'Z' =>
+ Result.PropDelay := Maximum(Delay(tr1Z), Delay(tr0Z));
+ WHEN OTHERS =>
+ Result.PropDelay := Maximum(Delay(tr10), Delay(tr01));
+ END CASE;
+ Result.OutputRetainDelay := Minimum(Delay(tr1X), Delay(tr0X));
+ END CASE;
+ RETURN Result;
+END VitalMemoryCalcDelay;
+
+-- ----------------------------------------------------------------------------
+FUNCTION VitalMemoryCalcDelay (
+ CONSTANT NewVal : IN STD_ULOGIC := 'X';
+ CONSTANT OldVal : IN STD_ULOGIC := 'X';
+ CONSTANT Delay : IN VitalDelayType01Z
+) RETURN VitalMemoryDelayType IS
+ VARIABLE Result : VitalMemoryDelayType;
+BEGIN
+CASE Oldval IS
+ WHEN '0' | 'L' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result.PropDelay := Delay(tr10);
+ WHEN '1' | 'H' => Result.PropDelay := Delay(tr01);
+ WHEN OTHERS =>
+ Result.PropDelay := Minimum(Delay(tr01), Delay(tr10));
+ END CASE;
+ Result.OutputRetainDelay := Delay(tr0Z);
+ WHEN '1' | 'H' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result.PropDelay := Delay(tr10);
+ WHEN '1' | 'H' => Result.PropDelay := Delay(tr01);
+ WHEN OTHERS =>
+ Result.PropDelay := Minimum(Delay(tr10), Delay(tr01));
+ END CASE;
+ Result.OutputRetainDelay := Delay(tr1Z);
+ WHEN OTHERS =>
+ Result.PropDelay := Maximum(Delay(tr10),Delay(tr01));
+ Result.OutputRetainDelay := Minimum(Delay(tr1Z),Delay(tr0Z));
+ END CASE;
+ RETURN Result;
+END VitalMemoryCalcDelay;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryUpdateInputChangeTime (
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ VARIABLE NumBitsPerSubword : INTEGER
+) IS
+ VARIABLE LastInputValue : STD_LOGIC_VECTOR(InputSignal'LENGTH-1 downto 0);
+ VARIABLE InSignalNorm : STD_LOGIC_VECTOR(InputSignal'LENGTH-1 downto 0);
+ VARIABLE ChangeTimeNorm : VitalTimeArrayT(InputSignal'LENGTH-1 downto 0);
+ VARIABLE BitsPerWord : INTEGER;
+BEGIN
+ LastInputValue := InputSignal'LAST_VALUE;
+ IF NumBitsPerSubword = DefaultNumBitsPerSubword THEN
+ BitsPerWord := InputSignal'LENGTH;
+ ELSE
+ BitsPerWord := NumBitsPerSubword;
+ END IF;
+
+ FOR i IN InSignalNorm'RANGE LOOP
+ IF (InSignalNorm(i) /= LastInputValue(i)) THEN
+ ChangeTimeNorm(i/BitsPerWord) := NOW - InputSignal'LAST_EVENT;
+ ELSE
+ ChangeTimeNorm(i/BitsPerWord) := InputChangeTimeArray(i);
+ END IF;
+ END LOOP;
+
+ FOR i IN ChangeTimeNorm'RANGE LOOP
+ ChangeTimeNorm(i) := ChangeTimeNorm(i/BitsPerword);
+ END LOOP;
+
+ InputChangeTimeArray := ChangeTimeNorm;
+
+ -- for debug purpose only
+ PrintInputChangeTime(InputChangeTimeArray);
+END VitalMemoryUpdateInputChangeTime;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryUpdateInputChangeTime
+-- Description: Time since previous event for each bit of the input
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryUpdateInputChangeTime (
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR
+) IS
+ VARIABLE LastInputValue : STD_LOGIC_VECTOR(InputSignal'RANGE) ;
+BEGIN
+ LastInputValue := InputSignal'LAST_VALUE;
+ FOR i IN InputSignal'RANGE LOOP
+ IF (InputSignal(i) /= LastInputValue(i)) THEN
+ InputChangeTimeArray(i) := NOW - InputSignal'LAST_EVENT;
+ END IF;
+ END LOOP;
+ -- for debug purpose only
+ PrintInputChangeTime(InputChangeTimeArray);
+END VitalMemoryUpdateInputChangeTime;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryUpdateInputChangeTime (
+ VARIABLE InputChangeTime : INOUT TIME;
+ SIGNAL InputSignal : IN STD_ULOGIC
+) IS
+BEGIN
+ InputChangeTime := NOW - InputSignal'LAST_EVENT;
+ -- for debug purpose only
+ PrintInputChangeTime(InputChangeTime);
+END VitalMemoryUpdateInputChangeTime;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryExpandPortFlag (
+ CONSTANT PortFlag : IN VitalPortFlagVectorType;
+ CONSTANT NumBitsPerSubword : IN INTEGER;
+ VARIABLE ExpandedPortFlag : OUT VitalPortFlagVectorType
+) IS
+ VARIABLE PortFlagNorm : VitalPortFlagVectorType(
+ PortFlag'LENGTH-1 downto 0) := PortFlag;
+ VARIABLE ExpandedPortFlagNorm : VitalPortFlagVectorType(
+ ExpandedPortFlag'LENGTH-1 downto 0);
+ VARIABLE SubwordIndex : INTEGER;
+BEGIN
+ FOR Index IN INTEGER RANGE 0 to ExpandedPortFlag'LENGTH-1 LOOP
+ IF NumBitsPerSubword = DefaultNumBitsPerSubword THEN
+ SubwordIndex := 0;
+ ELSE
+ SubwordIndex := Index / NumBitsPerSubword;
+ END IF;
+ ExpandedPortFlagNorm(Index) := PortFlagNorm(SubWordIndex);
+ END LOOP;
+ ExpandedPortFlag := ExpandedPortFlagNorm;
+END VitalMemoryExpandPortFlag;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemorySelectDelay
+-- Description : Select Propagation Delay. Used internally by
+-- VitalMemoryAddPathDelay.
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- VitalDelayArrayType01ZX
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySelectDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ VARIABLE InputChangeTimeArray : IN VitalTimeArrayT;
+ CONSTANT OutputSignalName : IN STRING :="";
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN
+) IS
+ VARIABLE InputArrayLow : INTEGER := 0;
+ VARIABLE InputArrayHigh : INTEGER := 0;
+ VARIABLE DelayArrayIndex : INTEGER := 0;
+ VARIABLE NumBitsPerSubWord : INTEGER := DefaultNumBitsPerSubword;
+ VARIABLE NewValue : STD_ULOGIC;
+ VARIABLE OldValue : STD_ULOGIC;
+ VARIABLE OutputLength : INTEGER := 0;
+ VARIABLE OutArrayIndex : INTEGER;
+ VARIABLE PropDelay : TIME;
+ VARIABLE RetainDelay : TIME;
+ VARIABLE CurPropDelay : TIME;
+ VARIABLE CurRetainDelay : TIME;
+ VARIABLE InputAge : TIME;
+ VARIABLE CurInputAge : TIME;
+ VARIABLE InputChangeTimeNorm : VitalTimeArrayT(
+ InputChangeTimeArray'LENGTH-1 downto 0):=InputChangeTimeArray;
+ VARIABLE DelayArrayNorm : VitalDelayArrayType01ZX(
+ PathDelayArray'LENGTH-1 downto 0):= PathDelayArray;
+ VARIABLE ScheduleDataArrayNorm : VitalMemoryScheduleDatavectorType
+ (ScheduleDataArray'LENGTH-1 downto 0):= ScheduleDataArray;
+
+ -- for debug purpose
+ VARIABLE debugprop : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+ VARIABLE debugretain : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+
+BEGIN
+
+ -- for debug purpose
+ PrintArcType(ArcType);
+
+ OutputLength := ScheduleDataArray'LENGTH;
+ FOR OutBitPos IN 0 to (OutputLength -1) LOOP
+ NEXT WHEN PathConditionArray(OutBitPos) = FALSE;
+
+ NEXT WHEN ((ScheduleDataArrayNorm(OutBitPos).ScheduleValue
+ = ScheduleDataArrayNorm(OutBitPos).OutputData) AND
+ (ScheduleDataArrayNorm(OutBitPos).ScheduleTime <= NOW) AND
+ (OutputRetainFlag = FALSE ));
+
+ NewValue := ScheduleDataArrayNorm(OutBitPos).OutputData;
+ OldValue := ScheduleDataArrayNorm(OutBitPos).LastOutputValue;
+ PropDelay :=ScheduleDataArrayNorm(OutBitPos).PropDelay;
+ InputAge := ScheduleDataArrayNorm(OutBitPos).InputAge;
+ RetainDelay:=ScheduleDataArrayNorm(OutBitPos).OutputRetainDelay;
+ NumBitsPerSubWord:=ScheduleDataArrayNorm(OutBitPos).NumBitsPerSubWord;
+
+ CASE ArcType IS
+ WHEN ParallelArc =>
+ InputArrayLow := OutBitPos;
+ InputArrayHigh := OutBitPos;
+ DelayArrayIndex := OutBitPos;
+ WHEN CrossArc =>
+ InputArrayLow := 0;
+ InputArrayHigh := InputChangeTimeArray'LENGTH - 1 ;
+ DelayArrayIndex := OutBitPos;
+ WHEN SubwordArc =>
+ InputArrayLow := OutBitPos / NumBitsPerSubWord;
+ InputArrayHigh := OutBitPos / NumBitsPerSubWord;
+ DelayArrayIndex := OutBitPos +
+ (OutputLength * (OutBitPos / NumBitsPerSubWord));
+ END CASE;
+
+ FOR i IN InputArrayLow TO InputArrayHigh LOOP
+ (CurPropDelay,CurRetainDelay) :=
+ VitalMemoryCalcDelay (
+ NewValue, OldValue, DelayArrayNorm(DelayArrayIndex)
+ );
+ IF (OutputRetainFlag = FALSE) THEN
+ CurRetainDelay := TIME'HIGH;
+ END IF;
+
+ -- for debug purpose
+ debugprop(i) := CurPropDelay;
+ debugretain(i) := CurRetainDelay;
+
+ IF ArcType = CrossArc THEN
+ DelayArrayIndex := DelayArrayIndex + OutputLength;
+ END IF;
+
+ -- If there is one input change at a time, then choose the
+ -- delay from that input. If there is simultaneous input
+ -- change, then choose the minimum of propagation delays
+
+ IF (InputChangeTimeNorm(i) < 0 ns)THEN
+ CurInputAge := TIME'HIGH;
+ ELSE
+ CurInputAge := NOW - InputChangeTimeNorm(i);
+ END IF;
+
+ IF (CurInputAge < InputAge)THEN
+ PropDelay := CurPropDelay;
+ RetainDelay := CurRetainDelay;
+ InputAge := CurInputAge;
+ ELSIF (CurInputAge = InputAge)THEN
+ IF (CurPropDelay < PropDelay) THEN
+ PropDelay := CurPropDelay;
+ END IF;
+ IF (OutputRetainFlag = TRUE) THEN
+ IF (CurRetainDelay < RetainDelay) THEN
+ RetainDelay := CurRetainDelay;
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+
+ -- Store it back to data strucutre
+ ScheduleDataArrayNorm(OutBitPos).PropDelay := PropDelay;
+ ScheduleDataArrayNorm(OutBitPos).OutputRetainDelay:= RetainDelay;
+ ScheduleDataArrayNorm(OutBitPos).InputAge := InputAge;
+
+ -- for debug purpose
+ PrintDelay(outbitPos,InputArrayLow, InputArrayHigh,
+ debugprop, debugretain);
+ END LOOP;
+
+ ScheduleDataArray := ScheduleDataArrayNorm;
+
+END VitalMemorySelectDelay;
+
+-- ----------------------------------------------------------------------------
+-- VitalDelayArrayType01Z
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySelectDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ VARIABLE InputChangeTimeArray : IN VitalTimeArrayT;
+ CONSTANT OutputSignalName : IN STRING :="";
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN
+) IS
+ VARIABLE InputArrayLow : INTEGER := 0;
+ VARIABLE InputArrayHigh : INTEGER := 0;
+ VARIABLE DelayArrayIndex : INTEGER := 0;
+ VARIABLE NumBitsPerSubWord : INTEGER := DefaultNumBitsPerSubword;
+ VARIABLE NewValue : STD_ULOGIC;
+ VARIABLE OldValue : STD_ULOGIC;
+ VARIABLE OutputLength : INTEGER := 0;
+ VARIABLE OutArrayIndex : INTEGER;
+ VARIABLE PropDelay : TIME;
+ VARIABLE RetainDelay : TIME;
+ VARIABLE CurPropDelay : TIME;
+ VARIABLE CurRetainDelay : TIME;
+ VARIABLE InputAge : TIME;
+ VARIABLE CurInputAge : TIME;
+ VARIABLE InputChangeTimeNorm : VitalTimeArrayT(
+ InputChangeTimeArray'LENGTH-1 downto 0):=InputChangeTimeArray;
+ VARIABLE DelayArrayNorm : VitalDelayArrayType01Z(
+ PathDelayArray'LENGTH-1 downto 0):= PathDelayArray;
+ VARIABLE ScheduleDataArrayNorm : VitalMemoryScheduleDatavectorType
+ (ScheduleDataArray'LENGTH-1 downto 0):=ScheduleDataArray;
+
+ -- for debug purpose
+ VARIABLE debugprop : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+ VARIABLE debugretain : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+BEGIN
+
+ -- for debug purpose
+ PrintArcType(ArcType);
+
+ OutputLength := ScheduleDataArray'LENGTH;
+ FOR OutBitPos IN 0 to (OutputLength -1) LOOP
+ NEXT WHEN PathConditionArray(OutBitPos) = FALSE;
+
+ NEXT WHEN ((ScheduleDataArrayNorm(OutBitPos).ScheduleValue
+ = ScheduleDataArrayNorm(OutBitPos).OutputData) AND
+ (ScheduleDataArrayNorm(OutBitPos).ScheduleTime <= NOW) AND
+ (OutputRetainFlag = FALSE));
+
+ NewValue := ScheduleDataArrayNorm(OutBitPos).OutputData;
+ OldValue := ScheduleDataArrayNorm(OutBitPos).LastOutputValue;
+ PropDelay :=ScheduleDataArrayNorm(OutBitPos).PropDelay;
+ InputAge := ScheduleDataArrayNorm(OutBitPos).InputAge;
+ RetainDelay:=ScheduleDataArrayNorm(OutBitPos).OutputRetainDelay;
+ NumBitsPerSubWord:=ScheduleDataArrayNorm(OutBitPos).NumBitsPerSubWord;
+
+ CASE ArcType IS
+ WHEN ParallelArc =>
+ InputArrayLow := OutBitPos;
+ InputArrayHigh := OutBitPos;
+ DelayArrayIndex := OutBitPos;
+ WHEN CrossArc =>
+ InputArrayLow := 0;
+ InputArrayHigh := InputChangeTimeArray'LENGTH-1;
+ DelayArrayIndex := OutBitPos;
+ WHEN SubwordArc =>
+ InputArrayLow := OutBitPos / NumBitsPerSubWord;
+ InputArrayHigh := OutBitPos / NumBitsPerSubWord;
+ DelayArrayIndex := OutBitPos +
+ (OutputLength * (OutBitPos / NumBitsPerSubWord));
+ END CASE;
+
+ FOR i IN InputArrayLow TO InputArrayHigh LOOP
+ (CurPropDelay, CurRetainDelay) :=
+ VitalMemoryCalcDelay (
+ NewValue, OldValue, DelayArrayNorm(DelayArrayIndex)
+ );
+ IF (OutputRetainFlag = FALSE) THEN
+ CurRetainDelay := TIME'HIGH;
+ END IF;
+
+ -- for debug purpose
+ debugprop(i) := CurPropDelay;
+ debugretain(i) := CurRetainDelay;
+
+ IF (ArcType = CrossArc) THEN
+ DelayArrayIndex := DelayArrayIndex + OutputLength;
+ END IF;
+
+ -- If there is one input change at a time, then choose the
+ -- delay from that input. If there is simultaneous input
+ -- change, then choose the minimum of propagation delays
+
+ IF (InputChangeTimeNorm(i) < 0 ns) THEN
+ CurInputAge := TIME'HIGH;
+ ELSE
+ CurInputAge := NOW - InputChangeTimeNorm(i);
+ END IF;
+
+ IF (CurInputAge < InputAge) THEN
+ PropDelay := CurPropDelay;
+ RetainDelay := CurRetainDelay;
+ InputAge := CurInputAge;
+ ELSIF (CurInputAge = InputAge) THEN
+ IF (CurPropDelay < PropDelay) THEN
+ PropDelay := CurPropDelay;
+ END IF;
+ IF (OutputRetainFlag = TRUE) THEN
+ IF (CurRetainDelay < RetainDelay) THEN
+ RetainDelay := CurRetainDelay;
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+
+ -- Store it back to data strucutre
+ ScheduleDataArrayNorm(OutBitPos).PropDelay := PropDelay;
+ ScheduleDataArrayNorm(OutBitPos).OutputRetainDelay:= RetainDelay;
+ ScheduleDataArrayNorm(OutBitPos).InputAge := InputAge;
+
+ -- for debug purpose
+ PrintDelay(outbitPos, InputArrayLow, InputArrayHigh,
+ debugprop, debugretain);
+ END LOOP;
+
+ ScheduleDataArray := ScheduleDataArrayNorm;
+
+END VitalMemorySelectDelay;
+
+-- ----------------------------------------------------------------------------
+-- VitalDelayArrayType01
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySelectDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ VARIABLE InputChangeTimeArray : IN VitalTimeArrayT;
+ CONSTANT OutputSignalName : IN STRING :="";
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+) IS
+ VARIABLE CurPathDelay : VitalMemoryDelayType;
+ VARIABLE InputArrayLow : INTEGER := 0;
+ VARIABLE InputArrayHigh : INTEGER := 0;
+ VARIABLE DelayArrayIndex : INTEGER := 0;
+ VARIABLE NumBitsPerSubWord : INTEGER := DefaultNumBitsPerSubword;
+ VARIABLE NewValue : STD_ULOGIC;
+ VARIABLE OldValue : STD_ULOGIC;
+ VARIABLE OutputLength : INTEGER := 0;
+ VARIABLE OutArrayIndex : INTEGER;
+ VARIABLE PropDelay : TIME;
+ VARIABLE CurPropDelay : TIME;
+ VARIABLE InputAge : TIME;
+ VARIABLE CurInputAge : TIME;
+ VARIABLE InputChangeTimeNorm : VitalTimeArrayT(
+ InputChangeTimeArray'LENGTH-1 downto 0):= InputChangeTimeArray;
+ VARIABLE DelayArrayNorm : VitalDelayArrayType01(
+ PathDelayArray'LENGTH-1 downto 0):= PathDelayArray;
+ VARIABLE ScheduleDataArrayNorm : VitalMemoryScheduleDatavectorType
+ (ScheduleDataArray'LENGTH-1 downto 0):=ScheduleDataArray;
+
+ -- for debug purpose
+ VARIABLE debugprop : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+ VARIABLE debugretain : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+BEGIN
+
+ -- for debug purpose
+ PrintArcType(ArcType);
+
+ OutputLength := ScheduleDataArray'LENGTH;
+ FOR OutBitPos IN 0 to (OutputLength -1) LOOP
+ NEXT WHEN PathConditionArray(OutBitPos) = FALSE;
+
+ NEXT WHEN ((ScheduleDataArrayNorm(OutBitPos).ScheduleValue
+ = ScheduleDataArrayNorm(OutBitPos).OutputData) AND
+ (ScheduleDataArrayNorm(OutBitPos).ScheduleTime <= NOW));
+
+ NewValue := ScheduleDataArrayNorm(OutBitPos).OutputData;
+ OldValue := ScheduleDataArrayNorm(OutBitPos).LastOutputValue;
+ PropDelay :=ScheduleDataArrayNorm(OutBitPos).PropDelay;
+ InputAge := ScheduleDataArrayNorm(OutBitPos).InputAge;
+ NumBitsPerSubWord:=ScheduleDataArrayNorm(OutBitPos).NumBitsPerSubWord;
+
+ CASE ArcType IS
+ WHEN ParallelArc =>
+ InputArrayLow := OutBitPos;
+ InputArrayHigh := OutBitPos;
+ DelayArrayIndex := OutBitPos;
+ WHEN CrossArc =>
+ InputArrayLow := 0;
+ InputArrayHigh := InputChangeTimeArray'LENGTH-1;
+ DelayArrayIndex := OutBitPos;
+ WHEN SubwordArc =>
+ InputArrayLow := OutBitPos / NumBitsPerSubWord;
+ InputArrayHigh := OutBitPos / NumBitsPerSubWord;
+ DelayArrayIndex := OutBitPos +
+ (OutputLength * (OutBitPos / NumBitsPerSubWord));
+ END CASE;
+
+ FOR i IN InputArrayLow TO InputArrayHigh LOOP
+ CurPropDelay:= VitalCalcDelay (NewValue,
+ OldValue, DelayArrayNorm(DelayArrayIndex));
+
+ -- for debug purpose
+ debugprop(i) := CurPropDelay;
+ debugretain(i) := TIME'HIGH;
+
+ IF (ArcType = CrossArc) THEN
+ DelayArrayIndex := DelayArrayIndex + OutputLength;
+ END IF;
+
+ -- If there is one input change at a time, then choose the
+ -- delay from that input. If there is simultaneous input
+ -- change, then choose the minimum of propagation delays
+
+ IF (InputChangeTimeNorm(i) < 0 ns) THEN
+ CurInputAge := TIME'HIGH;
+ ELSE
+ CurInputAge := NOW - InputChangeTimeNorm(i);
+ END IF;
+ IF (CurInputAge < InputAge) THEN
+ PropDelay := CurPropDelay;
+ InputAge := CurInputAge;
+ ELSIF (CurInputAge = InputAge) THEN
+ IF (CurPropDelay < PropDelay) THEN
+ PropDelay := CurPropDelay;
+ END IF;
+ END IF;
+ END LOOP;
+
+ -- Store it back to data strucutre
+ ScheduleDataArrayNorm(OutBitPos).PropDelay := PropDelay;
+ ScheduleDataArrayNorm(OutBitPos).InputAge := InputAge;
+
+ -- for debug purpose
+ PrintDelay(outbitPos, InputArrayLow, InputArrayHigh,
+ debugprop, debugretain);
+ END LOOP;
+
+ ScheduleDataArray := ScheduleDataArrayNorm;
+
+END VitalMemorySelectDelay;
+
+-- ----------------------------------------------------------------------------
+-- VitalDelayArrayType
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySelectDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ VARIABLE InputChangeTimeArray : IN VitalTimeArrayT;
+ CONSTANT OutputSignalName : IN STRING :="";
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+) IS
+ VARIABLE InputArrayLow : INTEGER := 0;
+ VARIABLE InputArrayHigh : INTEGER := 0;
+ VARIABLE DelayArrayIndex : INTEGER := 0;
+ VARIABLE NumBitsPerSubWord : INTEGER := DefaultNumBitsPerSubword;
+ VARIABLE NewValue : STD_ULOGIC;
+ VARIABLE OldValue : STD_ULOGIC;
+ VARIABLE OutputLength : INTEGER := 0;
+ VARIABLE OutArrayIndex : INTEGER;
+ VARIABLE PropDelay : TIME;
+ VARIABLE CurPropDelay : TIME;
+ VARIABLE InputAge : TIME;
+ VARIABLE CurInputAge : TIME;
+ VARIABLE InputChangeTimeNorm : VitalTimeArrayT(
+ InputChangeTimeArray'LENGTH-1 downto 0) := InputChangeTimeArray;
+ VARIABLE DelayArrayNorm : VitalDelayArrayType(
+ PathDelayArray'LENGTH-1 downto 0) := PathDelayArray;
+ VARIABLE ScheduleDataArrayNorm : VitalMemoryScheduleDatavectorType
+ (ScheduleDataArray'LENGTH-1 downto 0) := ScheduleDataArray;
+
+ -- for debug purpose
+ VARIABLE debugprop : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+ VARIABLE debugretain : VitalTimeArrayT(MaxNoInputBits-1 downto 0);
+BEGIN
+
+ -- for debug purpose
+ PrintArcType(ArcType);
+
+ OutputLength := ScheduleDataArray'LENGTH;
+ FOR OutBitPos IN 0 to (OutputLength -1) LOOP
+ NEXT WHEN PathConditionArray(OutBitPos) = FALSE;
+
+ NEXT WHEN ((ScheduleDataArrayNorm(OutBitPos).ScheduleValue
+ = ScheduleDataArrayNorm(OutBitPos).OutputData) AND
+ (ScheduleDataArrayNorm(OutBitPos).ScheduleTime <= NOW));
+
+ NewValue := ScheduleDataArrayNorm(OutBitPos).OutputData;
+ OldValue := ScheduleDataArrayNorm(OutBitPos).LastOutputValue;
+ PropDelay :=ScheduleDataArrayNorm(OutBitPos).PropDelay;
+ InputAge := ScheduleDataArrayNorm(OutBitPos).InputAge;
+ NumBitsPerSubWord:=ScheduleDataArrayNorm(OutBitPos).NumBitsPerSubWord;
+
+ CASE ArcType IS
+ WHEN ParallelArc =>
+ InputArrayLow := OutBitPos;
+ InputArrayHigh := OutBitPos;
+ DelayArrayIndex := OutBitPos;
+ WHEN CrossArc =>
+ InputArrayLow := 0;
+ InputArrayHigh := InputChangeTimeArray'LENGTH-1;
+ DelayArrayIndex := OutBitPos;
+ WHEN SubwordArc =>
+ InputArrayLow := OutBitPos / NumBitsPerSubWord;
+ InputArrayHigh := OutBitPos / NumBitsPerSubWord;
+ DelayArrayIndex := OutBitPos +
+ (OutputLength * (OutBitPos / NumBitsPerSubWord));
+ END CASE;
+
+ FOR i IN InputArrayLow TO InputArrayHigh LOOP
+ CurPropDelay := VitalCalcDelay (NewValue,
+ OldValue, DelayArrayNorm(DelayArrayIndex));
+
+ -- for debug purpose
+ debugprop(i) := CurPropDelay;
+ debugretain(i) := TIME'HIGH;
+
+ IF (ArcType = CrossArc) THEN
+ DelayArrayIndex := DelayArrayIndex + OutputLength;
+ END IF;
+
+ -- If there is one input change at a time, then choose the
+ -- delay from that input. If there is simultaneous input
+ -- change, then choose the minimum of propagation delays
+
+ IF (InputChangeTimeNorm(i) < 0 ns) THEN
+ CurInputAge := TIME'HIGH;
+ ELSE
+ CurInputAge := NOW - InputChangeTimeNorm(i);
+ END IF;
+
+ IF (CurInputAge < InputAge) THEN
+ PropDelay := CurPropDelay;
+ InputAge := CurInputAge;
+ ELSIF (CurInputAge = InputAge) THEN
+ IF (CurPropDelay < PropDelay) THEN
+ PropDelay := CurPropDelay;
+ END IF;
+ END IF;
+ END LOOP;
+
+ -- Store it back to data strucutre
+ ScheduleDataArrayNorm(OutBitPos).PropDelay := PropDelay;
+ ScheduleDataArrayNorm(OutBitPos).InputAge := InputAge;
+
+ -- for debug purpose
+ PrintDelay(outbitPos, InputArrayLow, InputArrayHigh,
+ debugprop, debugretain);
+ END LOOP;
+
+ ScheduleDataArray := ScheduleDataArrayNorm;
+
+END VitalMemorySelectDelay;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryInitPathDelay
+-- Description: To initialize Schedule Data structure for an
+-- output.
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryInitPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ VARIABLE OutputDataArray : IN STD_LOGIC_VECTOR;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := DefaultNumBitsPerSubword
+) IS
+BEGIN
+ -- Initialize the ScheduleData Structure.
+ FOR i IN OutputDataArray'RANGE LOOP
+ ScheduleDataArray(i).OutputData := OutputDataArray(i);
+ ScheduleDataArray(i).PropDelay := TIME'HIGH;
+ ScheduleDataArray(i).OutputRetainDelay := TIME'HIGH;
+ ScheduleDataArray(i).InputAge := TIME'HIGH;
+ ScheduleDataArray(i).NumBitsPerSubWord := NumBitsPerSubWord;
+
+ -- Update LastOutputValue of Output if the Output has
+ -- already been scheduled.
+ IF ((ScheduleDataArray(i).ScheduleValue /= OutputDataArray(i)) AND
+ (ScheduleDataArray(i).ScheduleTime <= NOW)) THEN
+ ScheduleDataArray(i).LastOutputValue
+ := ScheduleDataArray(i).ScheduleValue;
+ END IF;
+ END LOOP;
+
+ -- for debug purpose
+ DebugMsg1;
+ PrintScheduleDataArray(ScheduleDataArray);
+
+END VitalMemoryInitPathDelay;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryInitPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ VARIABLE OutputData : IN STD_ULOGIC
+) IS
+ VARIABLE ScheduledataArray: VitalMemoryScheduleDataVectorType
+ (0 downto 0);
+ VARIABLE OutputDataArray : STD_LOGIC_VECTOR(0 downto 0);
+BEGIN
+ ScheduledataArray(0) := ScheduleData;
+ OutputDataArray(0) := OutputData;
+ VitalMemoryInitPathDelay (
+ ScheduleDataArray => ScheduleDataArray,
+ OutputDataArray => OutputDataArray,
+ NumBitsPerSubWord => DefaultNumBitsPerSubword
+ );
+
+ -- for debug purpose
+ DebugMsg1;
+ PrintScheduleDataArray( ScheduleDataArray);
+
+END VitalMemoryInitPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryAddPathDelay
+-- Description: Declare a path for one scalar/vector input to
+-- the output for which Schedule Data has been
+-- initialized previously.
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- #1
+-- DelayType - VitalMemoryDelayType
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelay : IN VitalDelayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE PathDelayArray : VitalDelayArrayType(0 downto 0);
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ PathDelayArray(0) := PathDelay;
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #2
+-- DelayType - VitalMemoryDelayType
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray
+ );
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #3
+-- DelayType - VitalMemoryDelayType
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR Mem400
+ VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #4
+-- DelayType - VitalMemoryDelayType
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE ScheduleDataArray : VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+
+ ScheduleDataArray(0) := ScheduleData;
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #5
+-- DelayType - VitalMemoryDelayType
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #6
+-- DelayType - VitalMemoryDelayType
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+) IS
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400;
+ VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #7
+-- DelayType - VitalMemoryDelayType01
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelay : IN VitalDelayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE PathDelayArray : VitalDelayArrayType01(0 downto 0);
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ PathDelayArray(0) := PathDelay;
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #8
+-- DelayType - VitalMemoryDelayType01
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #9
+-- DelayType - VitalMemoryDelayType01
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400;
+ VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #10
+-- DelayType - VitalMemoryDelayType01
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray: INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+)IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #11
+-- DelayType - VitalMemoryDelayType01
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+) IS
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #12
+-- DelayType - VitalMemoryDelayType01
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+) IS
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400;
+ VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #13
+-- DelayType - VitalMemoryDelayType01Z
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelay : IN VitalDelayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+) IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE PathDelayArray : VitalDelayArrayType01Z(0 downto 0);
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ PathDelayArray(0) := PathDelay;
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #14
+-- DelayType - VitalMemoryDelayType01Z
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #15
+-- DelayType - VitalMemoryDelayType01Z
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm : VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0);
+ VARIABLE PathConditionArrayExp : VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword := ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #16
+-- DelayType - VitalMemoryDelayType01Z
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+) IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ NumBitsPerSubword := ScheduleDataArray(0).NumBitsPerSubword;
+ IF (OutputRetainBehavior = WordCorrupt AND
+ ArcType = ParallelArc AND
+ OutputRetainFlag = TRUE) THEN
+ VitalMemoryUpdateInputChangeTime(
+ InputChangeTimeArray,
+ InputSignal,
+ NumBitsPerSubword
+ );
+ ELSE
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+ END IF;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #17
+-- DelayType - VitalMemoryDelayType01Z
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+) IS
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'LEFT).NumBitsPerSubword;
+ IF (OutputRetainBehavior = WordCorrupt AND
+ ArcType = ParallelArc AND
+ OutputRetainFlag = TRUE) THEN
+ VitalMemoryUpdateInputChangeTime(
+ InputChangeTimeArray,
+ InputSignal,
+ NumBitsPerSubword
+ );
+ ELSE
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+ END IF;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #18
+-- DelayType - VitalMemoryDelayType01Z
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+) IS
+VARIABLE NumBitsPerSubword : INTEGER;
+VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0);
+VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword := ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ IF (OutputRetainBehavior = WordCorrupt AND
+ ArcType = ParallelArc AND
+ OutputRetainFlag = TRUE) THEN
+ VitalMemoryUpdateInputChangeTime(
+ InputChangeTimeArray, InputSignal,
+ NumBitsPerSubword);
+ ELSE
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+ END IF;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #19
+-- DelayType - VitalMemoryDelayType01XZ
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelay : IN VitalDelayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+) IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE PathDelayArray : VitalDelayArrayType01ZX(0 downto 0);
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ PathDelayArray(0) := PathDelay;
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #20
+-- DelayType - VitalMemoryDelayType01XZ
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray :INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #21
+-- DelayType - VitalMemoryDelayType01XZ
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray :INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTime : INOUT TIME;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+) IS
+ VARIABLE InputChangeTimeArray : VitalTimeArrayT(0 downto 0);
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400;
+ VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ VitalMemoryUpdateInputChangeTime(InputChangeTime, InputSignal);
+ InputChangeTimeArray(0) := InputChangeTime;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #22
+-- DelayType - VitalMemoryDelayType01XZ
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+) IS
+ VARIABLE ScheduleDataArray :
+ VitalMemoryScheduleDataVectorType(0 downto 0);
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArray : VitalBoolArrayT(0 downto 0);
+BEGIN
+ PathConditionArray(0) := PathCondition;
+ ScheduleDataArray(0) := ScheduleData;
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'LEFT).NumBitsPerSubword;
+ IF (OutputRetainBehavior = WordCorrupt AND
+ ArcType = ParallelArc AND
+ OutputRetainFlag = TRUE) THEN
+ VitalMemoryUpdateInputChangeTime(
+ InputChangeTimeArray, InputSignal,
+ NumBitsPerSubword);
+ ELSE
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+ END IF;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #23
+-- DelayType - VitalMemoryDelayType01XZ
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+) IS
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArray :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ FOR i IN PathConditionArray'RANGE LOOP
+ PathConditionArray(i) := PathCondition;
+ END LOOP;
+
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'LEFT).NumBitsPerSubword;
+ IF (OutputRetainBehavior = WordCorrupt AND
+ ArcType = ParallelArc AND
+ OutputRetainFlag = TRUE) THEN
+ VitalMemoryUpdateInputChangeTime(
+ InputChangeTimeArray, InputSignal,
+ NumBitsPerSubword);
+ ELSE
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+ END IF;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArray, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- #24
+-- DelayType - VitalMemoryDelayType01XZ
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+) IS
+ VARIABLE NumBitsPerSubword : INTEGER;
+ VARIABLE PathConditionArrayNorm :
+ VitalBoolArrayT(PathConditionArray'LENGTH-1 downto 0) := PathConditionArray; -- IR MEM400;
+ VARIABLE PathConditionArrayExp :
+ VitalBoolArrayT(ScheduleDataArray'LENGTH-1 downto 0);
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'RIGHT).NumBitsPerSubword;
+ FOR i IN PathConditionArrayExp'RANGE LOOP
+ PathConditionArrayExp(i) := PathConditionArrayNorm(i/NumBitsPerSubword);
+ END LOOP;
+
+ IF (OutputRetainBehavior = WordCorrupt AND
+ ArcType = ParallelArc AND
+ OutputRetainFlag = TRUE) THEN
+ VitalMemoryUpdateInputChangeTime(
+ InputChangeTimeArray, InputSignal,
+ NumBitsPerSubword);
+ ELSE
+ VitalMemoryUpdateInputChangeTime(InputChangeTimeArray, InputSignal);
+ END IF;
+
+ VitalMemorySelectDelay(
+ ScheduleDataArray, InputChangeTimeArray,
+ OutputSignalName, PathDelayArray,
+ ArcType, PathConditionArrayExp, OutputRetainFlag);
+END VitalMemoryAddPathDelay;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemorySchedulePathDelay
+-- Description: Schedule Output after Propagation Delay selected
+-- by checking all the paths added thru'
+-- VitalMemoryAddPathDelay.
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySchedulePathDelay (
+ SIGNAL OutSignal : OUT STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ CONSTANT PortFlag : IN VitalPortFlagType := VitalDefaultPortFlag;
+ CONSTANT OutputMap : IN VitalOutputMapType:= VitalDefaultOutputMap;
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType
+) IS
+ VARIABLE Age : TIME;
+ VARIABLE PropDelay : TIME;
+ VARIABLE RetainDelay : TIME;
+ VARIABLE Data : STD_ULOGIC;
+BEGIN
+ IF (PortFlag.OutputDisable /= TRUE) THEN
+ FOR i IN ScheduleDataArray'RANGE LOOP
+ PropDelay := ScheduleDataArray(i).PropDelay;
+ RetainDelay := ScheduleDataArray(i).OutputRetainDelay;
+
+ NEXT WHEN PropDelay = TIME'HIGH;
+
+ Age := ScheduleDataArray(i).InputAge;
+ Data := ScheduleDataArray(i).OutputData;
+
+ IF (Age < RetainDelay and RetainDelay < PropDelay) THEN
+ OutSignal(i) <= TRANSPORT 'X' AFTER (RetainDelay - Age);
+ END IF;
+
+ IF (Age <= PropDelay) THEN
+ OutSignal(i)<= TRANSPORT OutputMap(Data)AFTER (PropDelay-Age);
+ ScheduleDataArray(i).ScheduleValue := Data;
+ ScheduleDataArray(i).ScheduleTime := NOW + PropDelay - Age;
+ END IF;
+ END LOOP;
+ END IF;
+
+ -- for debug purpose
+ PrintScheduleDataArray(ScheduleDataArray);
+
+ -- for debug purpose
+ ScheduleDebugMsg;
+END VitalMemorySchedulePathDelay;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemorySchedulePathDelay
+-- Description: Schedule Output after Propagation Delay selected
+-- by checking all the paths added thru'
+-- VitalMemoryAddPathDelay.
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySchedulePathDelay (
+ SIGNAL OutSignal : OUT STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING :="";
+ CONSTANT PortFlag : IN VitalPortFlagVectorType;
+ CONSTANT OutputMap : IN VitalOutputMapType:= VitalDefaultOutputMap;
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType
+) IS
+ VARIABLE Age : TIME;
+ VARIABLE PropDelay : TIME;
+ VARIABLE RetainDelay : TIME;
+ VARIABLE Data : STD_ULOGIC;
+ VARIABLE ExpandedPortFlag :
+ VitalPortFlagVectorType(ScheduleDataArray'RANGE);
+ VARIABLE NumBitsPerSubword : INTEGER;
+BEGIN
+ NumBitsPerSubword :=
+ ScheduleDataArray(ScheduleDataArray'LEFT).NumBitsPerSubword;
+ VitalMemoryExpandPortFlag( PortFlag, NumBitsPerSubword, ExpandedPortFlag );
+ FOR i IN ScheduleDataArray'RANGE LOOP
+ NEXT WHEN ExpandedPortFlag(i).OutputDisable = TRUE;
+
+ PropDelay := ScheduleDataArray(i).PropDelay;
+ RetainDelay := ScheduleDataArray(i).OutputRetainDelay;
+
+ NEXT WHEN PropDelay = TIME'HIGH;
+
+ Age := ScheduleDataArray(i).InputAge;
+ Data := ScheduleDataArray(i).OutputData;
+
+ IF (Age < RetainDelay and RetainDelay < PropDelay) THEN
+ OutSignal(i) <= TRANSPORT 'X' AFTER (RetainDelay - Age);
+ END IF;
+
+ IF (Age <= PropDelay) THEN
+ OutSignal(i)<= TRANSPORT OutputMap(Data)AFTER (PropDelay-Age);
+ ScheduleDataArray(i).ScheduleValue := Data;
+ ScheduleDataArray(i).ScheduleTime := NOW + PropDelay - Age;
+ END IF;
+ END LOOP;
+
+ -- for debug purpose
+ PrintScheduleDataArray(ScheduleDataArray);
+
+ -- for debug purpose
+ ScheduleDebugMsg;
+END VitalMemorySchedulePathDelay;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySchedulePathDelay (
+ SIGNAL OutSignal : OUT STD_ULOGIC;
+ CONSTANT OutputSignalName: IN STRING :="";
+ CONSTANT PortFlag : IN VitalPortFlagType := VitalDefaultPortFlag;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType
+) IS
+ VARIABLE Age : TIME;
+ VARIABLE PropDelay : TIME;
+ VARIABLE RetainDelay : TIME;
+ VARIABLE Data : STD_ULOGIC;
+ VARIABLE ScheduleDataArray : VitalMemoryScheduleDataVectorType (0 downto 0);
+BEGIN
+ IF (PortFlag.OutputDisable /= TRUE) THEN
+ ScheduledataArray(0) := ScheduleData;
+ PropDelay := ScheduleDataArray(0).PropDelay;
+ RetainDelay := ScheduleDataArray(0).OutputRetainDelay;
+ Age := ScheduleDataArray(0).InputAge;
+ Data := ScheduleDataArray(0).OutputData;
+
+ IF (Age < RetainDelay and RetainDelay < PropDelay) THEN
+ OutSignal <= TRANSPORT 'X' AFTER (RetainDelay - Age);
+ END IF;
+
+ IF (Age <= PropDelay and PropDelay /= TIME'HIGH) THEN
+ OutSignal <= TRANSPORT OutputMap(Data) AFTER (PropDelay - Age);
+ ScheduleDataArray(0).ScheduleValue := Data;
+ ScheduleDataArray(0).ScheduleTime := NOW + PropDelay - Age;
+ END IF;
+ END IF;
+
+ -- for debug purpose
+ PrintScheduleDataArray(ScheduleDataArray);
+
+ -- for debug purpose
+ ScheduleDebugMsg;
+
+END VitalMemorySchedulePathDelay;
+
+-- ----------------------------------------------------------------------------
+-- Procedure : InternalTimingCheck
+-- ----------------------------------------------------------------------------
+PROCEDURE InternalTimingCheck (
+ CONSTANT TestSignal : IN std_ulogic;
+ CONSTANT RefSignal : IN std_ulogic;
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ VARIABLE RefTime : IN TIME;
+ VARIABLE RefEdge : IN BOOLEAN;
+ VARIABLE TestTime : IN TIME;
+ VARIABLE TestEvent : IN BOOLEAN;
+ VARIABLE SetupEn : INOUT BOOLEAN;
+ VARIABLE HoldEn : INOUT BOOLEAN;
+ VARIABLE CheckInfo : INOUT CheckInfoType;
+ CONSTANT MsgOn : IN BOOLEAN
+) IS
+ VARIABLE bias : TIME;
+ VARIABLE actualObsTime : TIME;
+ VARIABLE BC : TIME;
+ VARIABLE Message :LINE;
+BEGIN
+ -- Check SETUP constraint
+ IF (RefEdge) THEN
+ IF (SetupEn) THEN
+ CheckInfo.ObsTime := RefTime - TestTime;
+ CheckInfo.State := To_X01(TestSignal);
+ CASE CheckInfo.State IS
+ WHEN '0' =>
+ CheckInfo.ExpTime := SetupLow;
+ -- start of new code IR245-246
+ BC := HoldHigh;
+ -- end of new code IR245-246
+ WHEN '1' =>
+ CheckInfo.ExpTime := SetupHigh;
+ -- start of new code IR245-246
+ BC := HoldLow;
+ -- end of new code IR245-246
+ WHEN 'X' =>
+ CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow);
+ -- start of new code IR245-246
+ BC := Maximum(HoldHigh,HoldLow);
+ -- end of new code IR245-246
+ END CASE;
+ -- added the second condition for IR 245-246
+ CheckInfo.Violation :=
+ ((CheckInfo.ObsTime < CheckInfo.ExpTime)
+ AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns))));
+ -- start of new code IR245-246
+ IF (CheckInfo.ExpTime = 0 ns) THEN
+ CheckInfo.CheckKind := HoldCheck;
+ ELSE
+ CheckInfo.CheckKind := SetupCheck;
+ END IF;
+ -- end of new code IR245-246
+ SetupEn := FALSE;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+
+ -- Check HOLD constraint
+ ELSIF (TestEvent) THEN
+ IF HoldEn THEN
+ CheckInfo.ObsTime := TestTime - RefTime;
+ CheckInfo.State := To_X01(TestSignal);
+ CASE CheckInfo.State IS
+ WHEN '0' =>
+ CheckInfo.ExpTime := HoldHigh;
+ -- new code for unnamed IR
+ CheckInfo.State := '1';
+ -- start of new code IR245-246
+ BC := SetupLow;
+ -- end of new code IR245-246
+ WHEN '1' =>
+ CheckInfo.ExpTime := HoldLow;
+ -- new code for unnamed IR
+ CheckInfo.State := '0';
+ -- start of new code IR245-246
+ BC := SetupHigh;
+ -- end of new code IR245-246
+ WHEN 'X' =>
+ CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow);
+ -- start of new code IR245-246
+ BC := Maximum(SetupHigh,SetupLow);
+ -- end of new code IR245-246
+ END CASE;
+ -- added the second condition for IR 245-246
+ CheckInfo.Violation :=
+ ((CheckInfo.ObsTime < CheckInfo.ExpTime)
+ AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns))));
+ -- start of new code IR245-246
+ IF (CheckInfo.ExpTime = 0 ns) THEN
+ CheckInfo.CheckKind := SetupCheck;
+ ELSE
+ CheckInfo.CheckKind := HoldCheck;
+ END IF;
+ -- end of new code IR245-246
+ HoldEn := NOT CheckInfo.Violation;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+
+ -- Adjust report values to account for internal model delays
+ -- Note: TestDelay, RefDelay, TestTime, RefTime are non-negative
+ -- Note: bias may be negative or positive
+ IF MsgOn AND CheckInfo.Violation THEN
+ -- modified the code for correct reporting of violation in case of
+ -- order of signals being reversed because of internal delays
+ -- new variable
+ actualObsTime := (TestTime-TestDelay)-(RefTime-RefDelay);
+ bias := TestDelay - RefDelay;
+ IF (actualObsTime < 0 ns) THEN -- It should be a setup check
+ IF ( CheckInfo.CheckKind = HoldCheck) THEN
+ CheckInfo.CheckKind := SetupCheck;
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := SetupLow;
+ WHEN '1' => CheckInfo.ExpTime := SetupHigh;
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow);
+ END CASE;
+ END IF;
+ CheckInfo.ObsTime := -actualObsTime;
+ CheckInfo.ExpTime := CheckInfo.ExpTime + bias;
+ CheckInfo.DetTime := RefTime - RefDelay;
+ ELSE -- It should be a hold check
+ IF (CheckInfo.CheckKind = SetupCheck) THEN
+ CheckInfo.CheckKind := HoldCheck;
+ CASE CheckInfo.State IS
+ WHEN '0' =>
+ CheckInfo.ExpTime := HoldHigh;
+ CheckInfo.State := '1';
+ WHEN '1' =>
+ CheckInfo.ExpTime := HoldLow;
+ CheckInfo.State := '0';
+ WHEN 'X' =>
+ CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow);
+ END CASE;
+ END IF;
+ CheckInfo.ObsTime := actualObsTime;
+ CheckInfo.ExpTime := CheckInfo.ExpTime - bias;
+ CheckInfo.DetTime := TestTime - TestDelay;
+ END IF;
+ END IF;
+END InternalTimingCheck;
+
+
+-- ----------------------------------------------------------------------------
+-- Setup and Hold Time Check Routine
+-- ----------------------------------------------------------------------------
+PROCEDURE TimingArrayIndex (
+ SIGNAL InputSignal : IN Std_logic_vector;
+ CONSTANT ArrayIndexNorm : IN INTEGER;
+ VARIABLE Index : OUT INTEGER
+) IS
+BEGIN
+ IF (InputSignal'LEFT > InputSignal'RIGHT) THEN
+ Index := ArrayIndexNorm + InputSignal'RIGHT;
+ ELSE
+ Index := InputSignal'RIGHT - ArrayIndexNorm;
+ END IF;
+END TimingArrayIndex;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryReportViolation (
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT CheckInfo : IN CheckInfoType;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+ VARIABLE Message : LINE;
+BEGIN
+ IF (NOT CheckInfo.Violation) THEN
+ RETURN;
+ END IF;
+ Write ( Message, HeaderMsg );
+ CASE CheckInfo.CheckKind IS
+ WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") );
+ WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") );
+ WHEN RecoveryCheck => Write ( Message, STRING'(" RECOVERY ") );
+ WHEN RemovalCheck => Write ( Message, STRING'(" REMOVAL ") );
+ WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH "));
+ WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") );
+ END CASE;
+ Write ( Message, HiLoStr(CheckInfo.State) );
+ Write ( Message, STRING'(" VIOLATION ON ") );
+ Write ( Message, TestSignalName );
+ IF (RefSignalName'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, RefSignalName );
+ END IF;
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" Expected := ") );
+ Write ( Message, CheckInfo.ExpTime);
+ Write ( Message, STRING'("; Observed := ") );
+ Write ( Message, CheckInfo.ObsTime);
+ Write ( Message, STRING'("; At : ") );
+ Write ( Message, CheckInfo.DetTime);
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+ DEALLOCATE (Message);
+END VitalMemoryReportViolation;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryReportViolation (
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT TestArrayIndex : IN INTEGER;
+ CONSTANT RefArrayIndex : IN INTEGER;
+ SIGNAL TestSignal : IN std_logic_vector;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT CheckInfo : IN CheckInfoType;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+ VARIABLE Message : LINE;
+ VARIABLE i, j : INTEGER;
+BEGIN
+ IF (NOT CheckInfo.Violation) THEN
+ RETURN;
+ END IF;
+
+ Write ( Message, HeaderMsg );
+ CASE CheckInfo.CheckKind IS
+ WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") );
+ WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") );
+ WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH "));
+ WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") );
+ WHEN OTHERS => Write ( Message, STRING'(" UNKNOWN ") );
+ END CASE;
+ Write ( Message, HiLoStr(CheckInfo.State) );
+ Write ( Message, STRING'(" VIOLATION ON ") );
+ Write ( Message, TestSignalName );
+ TimingArrayIndex(TestSignal, TestArrayIndex, i);
+ CASE MsgFormat IS
+ WHEN Scalar =>
+ NULL;
+ WHEN VectorEnum =>
+ Write ( Message, '_');
+ Write ( Message, i);
+ WHEN Vector =>
+ Write ( Message, '(');
+ Write ( Message, i);
+ Write ( Message, ')');
+ END CASE;
+
+ IF (RefSignalName'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, RefSignalName );
+ END IF;
+
+ IF(RefSignal'LENGTH > 0) THEN
+ TimingArrayIndex(RefSignal, RefArrayIndex, j);
+ CASE MsgFormat IS
+ WHEN Scalar =>
+ NULL;
+ WHEN VectorEnum =>
+ Write ( Message, '_');
+ Write ( Message, j);
+ WHEN Vector =>
+ Write ( Message, '(');
+ Write ( Message, j);
+ Write ( Message, ')');
+ END CASE;
+ END IF;
+
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" Expected := ") );
+ Write ( Message, CheckInfo.ExpTime);
+ Write ( Message, STRING'("; Observed := ") );
+ Write ( Message, CheckInfo.ObsTime);
+ Write ( Message, STRING'("; At : ") );
+ Write ( Message, CheckInfo.DetTime);
+
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+
+ DEALLOCATE (Message);
+END VitalMemoryReportViolation;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryReportViolation (
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT TestArrayIndex : IN INTEGER;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT CheckInfo : IN CheckInfoType;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+ VARIABLE Message : LINE;
+BEGIN
+ IF (NOT CheckInfo.Violation) THEN
+ RETURN;
+ END IF;
+
+ Write ( Message, HeaderMsg );
+ CASE CheckInfo.CheckKind IS
+ WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") );
+ WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") );
+ WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH "));
+ WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") );
+ WHEN OTHERS => Write ( Message, STRING'(" UNKNOWN ") );
+ END CASE;
+
+ Write ( Message, HiLoStr(CheckInfo.State) );
+ Write ( Message, STRING'(" VIOLATION ON ") );
+ Write ( Message, TestSignalName );
+
+ CASE MsgFormat IS
+ WHEN Scalar =>
+ NULL;
+ WHEN VectorEnum =>
+ Write ( Message, '_');
+ Write ( Message, TestArrayIndex);
+ WHEN Vector =>
+ Write ( Message, '(');
+ Write ( Message, TestArrayIndex);
+ Write ( Message, ')');
+ END CASE;
+
+ IF (RefSignalName'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, RefSignalName );
+ END IF;
+
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" Expected := ") );
+ Write ( Message, CheckInfo.ExpTime);
+ Write ( Message, STRING'("; Observed := ") );
+ Write ( Message, CheckInfo.ObsTime);
+ Write ( Message, STRING'("; At : ") );
+ Write ( Message, CheckInfo.DetTime);
+
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+
+ DEALLOCATE (Message);
+END VitalMemoryReportViolation;
+
+-- ----------------------------------------------------------------------------
+FUNCTION VitalMemoryTimingDataInit
+RETURN VitalMemoryTimingDataType IS
+BEGIN
+ RETURN (FALSE, 'X', 0 ns, FALSE, 'X', 0 ns, FALSE,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalSetupHoldCheck
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayType;
+ CONSTANT SetupLow : IN VitalDelayType;
+ CONSTANT HoldHigh : IN VitalDelayType;
+ CONSTANT HoldLow : IN VitalDelayType;
+ CONSTANT CheckEnabled : IN VitalBoolArrayT;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE CheckEnScalar : BOOLEAN := FALSE;
+ VARIABLE ViolationInt : X01ArrayT(CheckEnabled'RANGE);
+ VARIABLE RefEdge : BOOLEAN;
+ VARIABLE TestEvent : BOOLEAN;
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLast := To_X01(TestSignal);
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF (RefEdge) THEN
+ TimingData.RefTime := NOW;
+ --TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE);
+ --IR252 3/23/98
+ TimingData.SetupEn := TimingData.SetupEn AND EnableSetupOnRef;
+ TimingData.HoldEn := EnableHoldOnRef;
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ TestEvent := TimingData.TestLast /= To_X01Z(TestSignal);
+ TimingData.TestLast := To_X01Z(TestSignal);
+ IF TestEvent THEN
+ TimingData.SetupEn := EnableSetupOnTest ; --IR252 3/23/98
+ TimingData.HoldEn := TimingData.HoldEn AND EnableHoldOnTest ;
+ --IR252 3/23/98
+ TimingData.TestTime := NOW;
+ END IF;
+
+ FOR i IN CheckEnabled'RANGE LOOP
+ IF CheckEnabled(i) = TRUE THEN
+ CheckEnScalar := TRUE;
+ END IF;
+ ViolationInt(i) := '0';
+ END LOOP;
+
+ IF (CheckEnScalar) THEN
+ InternalTimingCheck (
+ TestSignal => TestSignal,
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh,
+ SetupLow => SetupLow,
+ HoldHigh => HoldHigh,
+ HoldLow => HoldLow,
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTime,
+ TestEvent => TestEvent,
+ SetupEn => TimingData.SetupEn,
+ HoldEn => TimingData.HoldEn,
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF;
+ IF (XOn) THEN
+ FOR i IN CheckEnabled'RANGE LOOP
+ IF CheckEnabled(i) = TRUE THEN
+ ViolationInt(i) := 'X';
+ END IF;
+ END LOOP;
+ END IF;
+ END IF;
+ END IF;
+ Violation := ViolationInt;
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayArraytype;
+ CONSTANT SetupLow : IN VitalDelayArraytype;
+ CONSTANT HoldHigh : IN VitalDelayArraytype;
+ CONSTANT HoldLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : BOOLEAN;
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE);
+ VARIABLE TestDly : TIME;
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE);
+ TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignal(i));
+ END LOOP;
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF (RefEdge) THEN
+ TimingData.RefTime := NOW;
+ --TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE);
+ --IR252 3/23/98
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.SetupEnA(i)
+ := TimingData.SetupEnA(i) AND EnableSetupOnRef;
+ TimingData.HoldEnA(i) := EnableHoldOnRef;
+ END LOOP;
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignal'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignal(i));
+ IF TestEvent(i) THEN
+ TimingData.SetupEnA(i) := EnableSetupOnTest ; --IR252 3/23/98
+ TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest ;
+ --IR252 3/23/98
+ TimingData.TestTimeA(i) := NOW;
+ --TimingData.SetupEnA(i) := TRUE;
+ TimingData.TestTime := NOW;
+ END IF;
+ END LOOP;
+
+ FOR i IN TestSignal'RANGE LOOP
+ Violation(i) := '0';
+
+ IF (CheckEnabled) THEN
+ TestDly := Maximum(0 ns, TestDelay(i));
+ InternalTimingCheck (
+ TestSignal => TestSignal(i),
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh(i),
+ SetupLow => SetupLow(i),
+ HoldHigh => HoldHigh(i),
+ HoldLow => HoldLow(i),
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(i),
+ HoldEn => TimingData.HoldEnA(i),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName, i ,
+ HeaderMsg, CheckInfo, MsgFormat, MsgSeverity );
+ END IF;
+ IF (XOn) THEN
+ Violation(i) := 'X';
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayArraytype;
+ CONSTANT SetupLow : IN VitalDelayArraytype;
+ CONSTANT HoldHigh : IN VitalDelayArraytype;
+ CONSTANT HoldLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN VitalBoolArrayT;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE ViolationInt : X01ArrayT(TestSignal'RANGE);
+ VARIABLE ViolationIntNorm: X01ArrayT(TestSignal'LENGTH-1 downto 0);
+ VARIABLE ViolationNorm : X01ArrayT(Violation'LENGTH-1 downto 0);
+ VARIABLE CheckEnInt : VitalBoolArrayT(TestSignal'RANGE);
+ VARIABLE CheckEnIntNorm : VitalBoolArrayT(TestSignal'LENGTH-1 downto 0);
+ VARIABLE CheckEnScalar : BOOLEAN := FALSE; --Mem IR 401
+ VARIABLE CheckEnabledNorm: VitalBoolArrayT(CheckEnabled'LENGTH-1 downto 0);
+ VARIABLE RefEdge : BOOLEAN;
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE);
+ VARIABLE TestDly : TIME;
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE);
+ TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignal(i));
+ END LOOP;
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ --TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE);
+ --IR252 3/23/98
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.SetupEnA(i)
+ := TimingData.SetupEnA(i) AND EnableSetupOnRef;
+ TimingData.HoldEnA(i) := EnableHoldOnRef;
+ END LOOP;
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignal'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignal(i));
+ IF TestEvent(i) THEN
+ TimingData.SetupEnA(i) := EnableSetupOnTest ; --IR252 3/23/98
+ TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest ;
+ --IR252 3/23/98
+ TimingData.TestTimeA(i) := NOW;
+ --TimingData.SetupEnA(i) := TRUE;
+ TimingData.TestTime := NOW;
+ END IF;
+ END LOOP;
+
+ IF ArcType = CrossArc THEN
+ CheckEnScalar := FALSE;
+ FOR i IN CheckEnabled'RANGE LOOP
+ IF CheckEnabled(i) = TRUE THEN
+ CheckEnScalar := TRUE;
+ END IF;
+ END LOOP;
+ FOR i IN CheckEnInt'RANGE LOOP
+ CheckEnInt(i) := CheckEnScalar;
+ END LOOP;
+ ELSE
+ FOR i IN CheckEnIntNorm'RANGE LOOP
+ CheckEnIntNorm(i) := CheckEnabledNorm(i / NumBitsPerSubWord );
+ END LOOP;
+ CheckEnInt := CheckEnIntNorm;
+ END IF;
+
+ FOR i IN TestSignal'RANGE LOOP
+ ViolationInt(i) := '0';
+
+ IF (CheckEnInt(i)) THEN
+ TestDly := Maximum(0 ns, TestDelay(i));
+ InternalTimingCheck (
+ TestSignal => TestSignal(i),
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh(i),
+ SetupLow => SetupLow(i),
+ HoldHigh => HoldHigh(i),
+ HoldLow => HoldLow(i),
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(i),
+ HoldEn => TimingData.HoldEnA(i),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName, i ,
+ HeaderMsg, CheckInfo, MsgFormat, MsgSeverity );
+ END IF;
+ IF (XOn) THEN
+ ViolationInt(i) := 'X';
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+
+ IF (ViolationInt'LENGTH = Violation'LENGTH) THEN
+ Violation := ViolationInt;
+ ELSE
+ ViolationIntNorm := ViolationInt;
+ FOR i IN ViolationNorm'RANGE LOOP
+ ViolationNorm(i) := '0';
+ END LOOP;
+ FOR i IN ViolationIntNorm'RANGE LOOP
+ IF (ViolationIntNorm(i) = 'X') THEN
+ ViolationNorm(i / NumBitsPerSubWord) := 'X';
+ END IF;
+ END LOOP;
+ Violation := ViolationNorm;
+ END IF;
+
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN VitalDelayArraytype;
+ CONSTANT SetupHigh : IN VitalDelayArraytype;
+ CONSTANT SetupLow : IN VitalDelayArraytype;
+ CONSTANT HoldHigh : IN VitalDelayArraytype;
+ CONSTANT HoldLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : VitalBoolArrayT(RefSignal'LENGTH-1 downto 0);
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'LENGTH-1 downto 0);
+ VARIABLE TestDly : TIME;
+ VARIABLE RefDly : TIME;
+ VARIABLE bias : TIME;
+ VARIABLE NumTestBits : NATURAL := TestSignal'LENGTH;
+ VARIABLE NumRefBits : NATURAL := RefSignal'LENGTH;
+ VARIABLE NumChecks : NATURAL;
+
+ VARIABLE ViolationTest : X01ArrayT(NumTestBits-1 downto 0);
+ VARIABLE ViolationRef : X01ArrayT(NumRefBits-1 downto 0);
+
+ VARIABLE TestSignalNorm : std_logic_vector(NumTestBits-1 downto 0)
+ := TestSignal;
+ VARIABLE TestDelayNorm : VitalDelayArraytype(NumTestBits-1 downto 0)
+ := TestDelay;
+ VARIABLE RefSignalNorm : std_logic_vector(NumRefBits-1 downto 0)
+ := RefSignal;
+ VARIABLE RefDelayNorm : VitalDelayArraytype(NumRefBits-1 downto 0)
+ := RefDelay;
+ VARIABLE SetupHighNorm : VitalDelayArraytype(SetupHigh'LENGTH-1 downto 0)
+ := SetupHigh;
+ VARIABLE SetupLowNorm : VitalDelayArraytype(SetupLow'LENGTH-1 downto 0)
+ := SetupLow;
+ VARIABLE HoldHighNorm : VitalDelayArraytype(HoldHigh'LENGTH-1 downto 0)
+ := HoldHigh;
+ VARIABLE HoldLowNorm : VitalDelayArraytype(HoldLow'LENGTH-1 downto 0)
+ := HoldLow;
+
+ VARIABLE RefBitLow : NATURAL;
+ VARIABLE RefBitHigh : NATURAL;
+ VARIABLE EnArrayIndex : NATURAL;
+ VARIABLE TimingArrayIndex: NATURAL;
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(NumTestBits-1 downto 0);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(NumTestBits-1 downto 0);
+ TimingData.RefTimeA := NEW VitalTimeArrayT(NumRefBits-1 downto 0);
+ TimingData.RefLastA := NEW X01ArrayT(NumRefBits-1 downto 0);
+ IF (ArcType = CrossArc) THEN
+ NumChecks := RefSignal'LENGTH * TestSignal'LENGTH;
+ ELSE
+ NumChecks := TestSignal'LENGTH;
+ END IF;
+ TimingData.HoldEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0);
+
+ FOR i IN TestSignalNorm'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignalNorm(i));
+ END LOOP;
+
+ FOR i IN RefSignalNorm'RANGE LOOP
+ TimingData.RefLastA(i) := To_X01(RefSignalNorm(i));
+ END LOOP;
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ FOR i IN RefSignalNorm'RANGE LOOP
+ RefEdge(i) := EdgeSymbolMatch(TimingData.RefLastA(i),
+ To_X01(RefSignalNorm(i)), RefTransition);
+ TimingData.RefLastA(i) := To_X01(RefSignalNorm(i));
+ IF (RefEdge(i)) THEN
+ TimingData.RefTimeA(i) := NOW;
+ END IF;
+ END LOOP;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignalNorm'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignalNorm(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignalNorm(i));
+ IF (TestEvent(i)) THEN
+ TimingData.TestTimeA(i) := NOW;
+ END IF;
+ END LOOP;
+
+ FOR i IN ViolationTest'RANGE LOOP
+ ViolationTest(i) := '0';
+ END LOOP;
+ FOR i IN ViolationRef'RANGE LOOP
+ ViolationRef(i) := '0';
+ END LOOP;
+
+ FOR i IN TestSignalNorm'RANGE LOOP
+ IF (ArcType = CrossArc) THEN
+ FOR j IN RefSignalNorm'RANGE LOOP
+ IF (TestEvent(i)) THEN
+ --TimingData.SetupEnA(i*NumRefBits+j) := TRUE;
+ --IR252
+ TimingData.SetupEnA(i*NumRefBits+j) := EnableSetupOnTest;
+ TimingData.HoldEnA(i*NumRefBits+j)
+ := TimingData.HoldEnA(i*NumRefBits+j) AND EnableHoldOnTest;
+ END IF;
+ IF (RefEdge(j)) THEN
+ --TimingData.HoldEnA(i*NumRefBits+j) := TRUE;
+ --IR252
+ TimingData.HoldEnA(i*NumRefBits+j) := EnableHoldOnRef;
+ TimingData.SetupEnA(i*NumRefBits+j)
+ := TimingData.SetupEnA(i*NumRefBits+j) AND EnableSetupOnRef;
+ END IF;
+ END LOOP;
+ RefBitLow := 0;
+ RefBitHigh := NumRefBits-1;
+ TimingArrayIndex := i;
+ ELSE
+ IF ArcType = SubwordArc THEN
+ RefBitLow := i / NumBitsPerSubWord;
+ TimingArrayIndex := i + NumTestBits * RefBitLow;
+ ELSE
+ RefBitLow := i;
+ TimingArrayIndex := i;
+ END IF;
+ RefBitHigh := RefBitLow;
+ IF TestEvent(i) THEN
+ --TimingData.SetupEnA(i) := TRUE;
+ --IR252
+ TimingData.SetupEnA(i) := EnableSetupOnTest;
+ TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest;
+ END IF;
+ IF RefEdge(RefBitLow) THEN
+ --TimingData.HoldEnA(i) := TRUE;
+ --IR252
+ TimingData.HoldEnA(i) := EnableHoldOnRef;
+ TimingData.SetupEnA(i) := TimingData.SetupEnA(i) AND EnableSetupOnRef;
+ END IF;
+ END IF;
+
+ EnArrayIndex := i;
+ FOR j IN RefBitLow to RefBitHigh LOOP
+
+ IF (CheckEnabled) THEN
+ TestDly := Maximum(0 ns, TestDelayNorm(i));
+ RefDly := Maximum(0 ns, RefDelayNorm(j));
+
+ InternalTimingCheck (
+ TestSignal => TestSignalNorm(i),
+ RefSignal => RefSignalNorm(j),
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHighNorm(TimingArrayIndex),
+ SetupLow => SetupLowNorm(TimingArrayIndex),
+ HoldHigh => HoldHighNorm(TimingArrayIndex),
+ HoldLow => HoldLowNorm(TimingArrayIndex),
+ RefTime => TimingData.RefTimeA(j),
+ RefEdge => RefEdge(j),
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(EnArrayIndex),
+ HoldEn => TimingData.HoldEnA(EnArrayIndex),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF (CheckInfo.Violation) THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName, i, j,
+ TestSignal, RefSignal, HeaderMsg, CheckInfo,
+ MsgFormat, MsgSeverity );
+ END IF;
+ IF (XOn) THEN
+ ViolationTest(i) := 'X';
+ ViolationRef(j) := 'X';
+ END IF;
+ END IF;
+ END IF;
+
+ TimingArrayIndex := TimingArrayIndex + NumRefBits;
+ EnArrayIndex := EnArrayIndex + NumRefBits;
+
+ END LOOP;
+ END LOOP;
+
+ IF (ArcType = CrossArc) THEN
+ Violation := ViolationRef;
+ ELSE
+ IF (Violation'LENGTH = ViolationRef'LENGTH) THEN
+ Violation := ViolationRef;
+ ELSE
+ Violation := ViolationTest;
+ END IF;
+ END IF;
+
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN VitalDelayArraytype;
+ CONSTANT SetupHigh : IN VitalDelayArraytype;
+ CONSTANT SetupLow : IN VitalDelayArraytype;
+ CONSTANT HoldHigh : IN VitalDelayArraytype;
+ CONSTANT HoldLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN VitalBoolArrayT;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : VitalBoolArrayT(RefSignal'LENGTH-1 downto 0);
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'LENGTH-1 downto 0);
+ VARIABLE TestDly : TIME;
+ VARIABLE RefDly : TIME;
+ VARIABLE bias : TIME;
+ VARIABLE NumTestBits : NATURAL := TestSignal'LENGTH;
+ VARIABLE NumRefBits : NATURAL := RefSignal'LENGTH;
+ VARIABLE NumChecks : NATURAL;
+
+ VARIABLE ViolationTest : X01ArrayT(NumTestBits-1 downto 0);
+ VARIABLE ViolationRef : X01ArrayT(NumRefBits-1 downto 0);
+
+ VARIABLE TestSignalNorm : std_logic_vector(NumTestBits-1 downto 0)
+ := TestSignal;
+ VARIABLE TestDelayNorm : VitalDelayArraytype(NumTestBits-1 downto 0)
+ := TestDelay;
+ VARIABLE RefSignalNorm : std_logic_vector(NumRefBits-1 downto 0)
+ := RefSignal;
+ VARIABLE RefDelayNorm : VitalDelayArraytype(NumRefBits-1 downto 0)
+ := RefDelay;
+ VARIABLE CheckEnNorm : VitalBoolArrayT(NumRefBits-1 downto 0)
+ := CheckEnabled;
+ VARIABLE SetupHighNorm : VitalDelayArraytype(SetupHigh'LENGTH-1 downto 0)
+ := SetupHigh;
+ VARIABLE SetupLowNorm : VitalDelayArraytype(SetupLow'LENGTH-1 downto 0)
+ := SetupLow;
+ VARIABLE HoldHighNorm : VitalDelayArraytype(HoldHigh'LENGTH-1 downto 0)
+ := HoldHigh;
+ VARIABLE HoldLowNorm : VitalDelayArraytype(HoldLow'LENGTH-1 downto 0)
+ := HoldLow;
+
+ VARIABLE RefBitLow : NATURAL;
+ VARIABLE RefBitHigh : NATURAL;
+ VARIABLE EnArrayIndex : NATURAL;
+ VARIABLE TimingArrayIndex: NATURAL;
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(NumTestBits-1 downto 0);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(NumTestBits-1 downto 0);
+ TimingData.RefTimeA := NEW VitalTimeArrayT(NumRefBits-1 downto 0);
+ TimingData.RefLastA := NEW X01ArrayT(NumRefBits-1 downto 0);
+ IF ArcType = CrossArc THEN
+ NumChecks := RefSignal'LENGTH * TestSignal'LENGTH;
+ ELSE
+ NumChecks := TestSignal'LENGTH;
+ END IF;
+ TimingData.HoldEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0);
+
+ FOR i IN TestSignalNorm'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignalNorm(i));
+ END LOOP;
+
+ FOR i IN RefSignalNorm'RANGE LOOP
+ TimingData.RefLastA(i) := To_X01(RefSignalNorm(i));
+ END LOOP;
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ FOR i IN RefSignalNorm'RANGE LOOP
+ RefEdge(i) := EdgeSymbolMatch(TimingData.RefLastA(i),
+ To_X01(RefSignalNorm(i)), RefTransition);
+ TimingData.RefLastA(i) := To_X01(RefSignalNorm(i));
+ IF RefEdge(i) THEN
+ TimingData.RefTimeA(i) := NOW;
+ END IF;
+ END LOOP;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignalNorm'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignalNorm(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignalNorm(i));
+ IF TestEvent(i) THEN
+ TimingData.TestTimeA(i) := NOW;
+ END IF;
+ END LOOP;
+
+ FOR i IN ViolationTest'RANGE LOOP
+ ViolationTest(i) := '0';
+ END LOOP;
+ FOR i IN ViolationRef'RANGE LOOP
+ ViolationRef(i) := '0';
+ END LOOP;
+
+ FOR i IN TestSignalNorm'RANGE LOOP
+ IF (ArcType = CrossArc) THEN
+ FOR j IN RefSignalNorm'RANGE LOOP
+ IF (TestEvent(i)) THEN
+ --TimingData.SetupEnA(i*NumRefBits+j) := TRUE;
+ --IR252
+ TimingData.SetupEnA(i*NumRefBits+j) := EnableSetupOnTest;
+ TimingData.HoldEnA(i*NumRefBits+j)
+ := TimingData.HoldEnA(i*NumRefBits+j) AND EnableHoldOnTest;
+ END IF;
+ IF (RefEdge(j)) THEN
+ --TimingData.HoldEnA(i*NumRefBits+j) := TRUE;
+ --IR252
+ TimingData.HoldEnA(i*NumRefBits+j) := EnableHoldOnRef;
+ TimingData.SetupEnA(i*NumRefBits+j)
+ := TimingData.SetupEnA(i*NumRefBits+j) AND EnableSetupOnRef;
+ END IF;
+ END LOOP;
+ RefBitLow := 0;
+ RefBitHigh := NumRefBits-1;
+ TimingArrayIndex := i;
+ ELSE
+ IF (ArcType = SubwordArc) THEN
+ RefBitLow := i / NumBitsPerSubWord;
+ TimingArrayIndex := i + NumTestBits * RefBitLow;
+ ELSE
+ RefBitLow := i;
+ TimingArrayIndex := i;
+ END IF;
+ RefBitHigh := RefBitLow;
+ IF (TestEvent(i)) THEN
+ --TimingData.SetupEnA(i) := TRUE;
+ --IR252
+ TimingData.SetupEnA(i) := EnableSetupOnTest;
+ TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest;
+ END IF;
+ IF (RefEdge(RefBitLow)) THEN
+ --TimingData.HoldEnA(i) := TRUE;
+ --IR252
+ TimingData.HoldEnA(i) := EnableHoldOnRef;
+ TimingData.SetupEnA(i) := TimingData.SetupEnA(i) AND EnableSetupOnRef;
+ END IF;
+ END IF;
+
+ EnArrayIndex := i;
+ FOR j IN RefBitLow to RefBitHigh LOOP
+ IF (CheckEnNorm(j)) THEN
+ TestDly := Maximum(0 ns, TestDelayNorm(i));
+ RefDly := Maximum(0 ns, RefDelayNorm(j));
+
+ InternalTimingCheck (
+ TestSignal => TestSignalNorm(i),
+ RefSignal => RefSignalNorm(j),
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHighNorm(TimingArrayIndex),
+ SetupLow => SetupLowNorm(TimingArrayIndex),
+ HoldHigh => HoldHighNorm(TimingArrayIndex),
+ HoldLow => HoldLowNorm(TimingArrayIndex),
+ RefTime => TimingData.RefTimeA(j),
+ RefEdge => RefEdge(j),
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(EnArrayIndex),
+ HoldEn => TimingData.HoldEnA(EnArrayIndex),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF (CheckInfo.Violation) THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName, i, j,
+ TestSignal, RefSignal, HeaderMsg, CheckInfo,
+ MsgFormat, MsgSeverity );
+ END IF;
+
+ IF (XOn) THEN
+ ViolationTest(i) := 'X';
+ ViolationRef(j) := 'X';
+ END IF;
+ END IF;
+ END IF;
+
+ TimingArrayIndex := TimingArrayIndex + NumRefBits;
+ EnArrayIndex := EnArrayIndex + NumRefBits;
+ END LOOP;
+ END LOOP;
+
+ IF (ArcType = CrossArc) THEN
+ Violation := ViolationRef;
+ ELSE
+ IF (Violation'LENGTH = ViolationRef'LENGTH) THEN
+ Violation := ViolationRef;
+ ELSE
+ Violation := ViolationTest;
+ END IF;
+ END IF;
+
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+-- scalar violations not needed
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayArraytype;
+ CONSTANT SetupLow : IN VitalDelayArraytype;
+ CONSTANT HoldHigh : IN VitalDelayArraytype;
+ CONSTANT HoldLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : BOOLEAN;
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE);
+ VARIABLE TestDly : TIME;
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE);
+ TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignal(i));
+ END LOOP;
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF (RefEdge) THEN
+ TimingData.RefTime := NOW;
+ --TimingData.HoldEnA.all := (TestSignal'RANGE=>TRUE);
+ --IR252 3/23/98
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.SetupEnA(i)
+ := TimingData.SetupEnA(i) AND EnableSetupOnRef;
+ TimingData.HoldEnA(i) := EnableHoldOnRef;
+ END LOOP;
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignal'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignal(i));
+ IF TestEvent(i) THEN
+ TimingData.SetupEnA(i) := EnableSetupOnTest ; --IR252 3/23/98
+ TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest ;
+ --IR252 3/23/98
+ TimingData.TestTimeA(i) := NOW;
+ --TimingData.SetupEnA(i) := TRUE;
+ TimingData.TestTime := NOW;
+ END IF;
+ END LOOP;
+
+ Violation := '0';
+ FOR i IN TestSignal'RANGE LOOP
+ IF (CheckEnabled) THEN
+ TestDly := Maximum(0 ns, TestDelay(i));
+ InternalTimingCheck (
+ TestSignal => TestSignal(i),
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh(i),
+ SetupLow => SetupLow(i),
+ HoldHigh => HoldHigh(i),
+ HoldLow => HoldLow(i),
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(i),
+ HoldEn => TimingData.HoldEnA(i),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName, i ,
+ HeaderMsg, CheckInfo, MsgFormat, MsgSeverity );
+ END IF;
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN VitalDelayArraytype;
+ CONSTANT SetupHigh : IN VitalDelayArraytype;
+ CONSTANT SetupLow : IN VitalDelayArraytype;
+ CONSTANT HoldHigh : IN VitalDelayArraytype;
+ CONSTANT HoldLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ --IR252 3/23/98
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : VitalBoolArrayT(RefSignal'LENGTH-1 downto 0);
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'LENGTH-1 downto 0);
+ VARIABLE TestDly : TIME;
+ VARIABLE RefDly : TIME;
+ VARIABLE bias : TIME;
+ VARIABLE NumTestBits : NATURAL := TestSignal'LENGTH;
+ VARIABLE NumRefBits : NATURAL := RefSignal'LENGTH;
+ VARIABLE NumChecks : NATURAL;
+
+ VARIABLE TestSignalNorm : std_logic_vector(NumTestBits-1 downto 0)
+ := TestSignal;
+ VARIABLE TestDelayNorm : VitalDelayArraytype(NumTestBits-1 downto 0)
+ := TestDelay;
+ VARIABLE RefSignalNorm : std_logic_vector(NumRefBits-1 downto 0)
+ := RefSignal;
+ VARIABLE RefDelayNorm : VitalDelayArraytype(NumRefBits-1 downto 0)
+ := RefDelay;
+ VARIABLE SetupHighNorm : VitalDelayArraytype(SetupHigh'LENGTH-1 downto 0)
+ := SetupHigh;
+ VARIABLE SetupLowNorm : VitalDelayArraytype(SetupLow'LENGTH-1 downto 0)
+ := SetupLow;
+ VARIABLE HoldHighNorm : VitalDelayArraytype(HoldHigh'LENGTH-1 downto 0)
+ := HoldHigh;
+ VARIABLE HoldLowNorm : VitalDelayArraytype(HoldLow'LENGTH-1 downto 0)
+ := HoldLow;
+
+ VARIABLE RefBitLow : NATURAL;
+ VARIABLE RefBitHigh : NATURAL;
+ VARIABLE EnArrayIndex : NATURAL;
+ VARIABLE TimingArrayIndex: NATURAL;
+BEGIN
+
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(NumTestBits-1 downto 0);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(NumTestBits-1 downto 0);
+ TimingData.RefTimeA := NEW VitalTimeArrayT(NumRefBits-1 downto 0);
+ TimingData.RefLastA := NEW X01ArrayT(NumRefBits-1 downto 0);
+ IF (ArcType = CrossArc) THEN
+ NumChecks := RefSignal'LENGTH * TestSignal'LENGTH;
+ ELSE
+ NumChecks := TestSignal'LENGTH;
+ END IF;
+ TimingData.HoldEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(NumChecks-1 downto 0);
+
+ FOR i IN TestSignalNorm'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignalNorm(i));
+ END LOOP;
+
+ FOR i IN RefSignalNorm'RANGE LOOP
+ TimingData.RefLastA(i) := To_X01(RefSignalNorm(i));
+ END LOOP;
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ FOR i IN RefSignalNorm'RANGE LOOP
+ RefEdge(i) := EdgeSymbolMatch(TimingData.RefLastA(i),
+ To_X01(RefSignalNorm(i)), RefTransition);
+ TimingData.RefLastA(i) := To_X01(RefSignalNorm(i));
+ IF (RefEdge(i)) THEN
+ TimingData.RefTimeA(i) := NOW;
+ END IF;
+ END LOOP;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignalNorm'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignalNorm(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignalNorm(i));
+ IF (TestEvent(i)) THEN
+ TimingData.TestTimeA(i) := NOW;
+ END IF;
+ END LOOP;
+
+ FOR i IN TestSignalNorm'RANGE LOOP
+ IF (ArcType = CrossArc) THEN
+ FOR j IN RefSignalNorm'RANGE LOOP
+ IF (TestEvent(i)) THEN
+ --TimingData.SetupEnA(i*NumRefBits+j) := TRUE;
+ --IR252
+ TimingData.SetupEnA(i*NumRefBits+j) := EnableSetupOnTest;
+ TimingData.HoldEnA(i*NumRefBits+j)
+ := TimingData.HoldEnA(i*NumRefBits+j) AND EnableHoldOnTest;
+ END IF;
+ IF (RefEdge(j)) THEN
+ --TimingData.HoldEnA(i*NumRefBits+j) := TRUE;
+ --IR252
+ TimingData.HoldEnA(i*NumRefBits+j) := EnableHoldOnRef;
+ TimingData.SetupEnA(i*NumRefBits+j)
+ := TimingData.SetupEnA(i*NumRefBits+j) AND EnableSetupOnRef;
+ END IF;
+ END LOOP;
+ RefBitLow := 0;
+ RefBitHigh := NumRefBits-1;
+ TimingArrayIndex := i;
+ ELSE
+ IF (ArcType = SubwordArc) THEN
+ RefBitLow := i / NumBitsPerSubWord;
+ TimingArrayIndex := i + NumTestBits * RefBitLow;
+ ELSE
+ RefBitLow := i;
+ TimingArrayIndex := i;
+ END IF;
+ RefBitHigh := RefBitLow;
+ IF (TestEvent(i)) THEN
+ --TimingData.SetupEnA(i) := TRUE;
+ --IR252
+ TimingData.SetupEnA(i) := EnableSetupOnTest;
+ TimingData.HoldEnA(i) := TimingData.HoldEnA(i) AND EnableHoldOnTest;
+ END IF;
+ IF (RefEdge(RefBitLow)) THEN
+ --TimingData.HoldEnA(i) := TRUE;
+ --IR252
+ TimingData.HoldEnA(i) := EnableHoldOnRef;
+ TimingData.SetupEnA(i) := TimingData.SetupEnA(i) AND EnableSetupOnRef;
+ END IF;
+ END IF;
+
+ EnArrayIndex := i;
+ Violation := '0';
+ FOR j IN RefBitLow to RefBitHigh LOOP
+
+ IF (CheckEnabled) THEN
+ TestDly := Maximum(0 ns, TestDelayNorm(i));
+ RefDly := Maximum(0 ns, RefDelayNorm(j));
+
+ InternalTimingCheck (
+ TestSignal => TestSignalNorm(i),
+ RefSignal => RefSignalNorm(j),
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHighNorm(TimingArrayIndex),
+ SetupLow => SetupLowNorm(TimingArrayIndex),
+ HoldHigh => HoldHighNorm(TimingArrayIndex),
+ HoldLow => HoldLowNorm(TimingArrayIndex),
+ RefTime => TimingData.RefTimeA(j),
+ RefEdge => RefEdge(j),
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(EnArrayIndex),
+ HoldEn => TimingData.HoldEnA(EnArrayIndex),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn
+ );
+
+ -- Report any detected violations and set return violation flag
+ IF (CheckInfo.Violation) THEN
+ IF (MsgOn) THEN
+ VitalMemoryReportViolation (TestSignalName, RefSignalName, i, j,
+ TestSignal, RefSignal, HeaderMsg, CheckInfo,
+ MsgFormat, MsgSeverity );
+ END IF;
+
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ END IF;
+ END IF;
+
+ TimingArrayIndex := TimingArrayIndex + NumRefBits;
+ EnArrayIndex := EnArrayIndex + NumRefBits;
+
+ END LOOP;
+ END LOOP;
+
+END VitalMemorySetupHoldCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryPeriodPulseCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE PeriodData : INOUT VitalPeriodDataArrayType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ CONSTANT Period : IN VitalDelayArraytype;
+ CONSTANT PulseWidthHigh : IN VitalDelayArraytype;
+ CONSTANT PulseWidthLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType
+) IS
+ VARIABLE TestDly : VitalDelayType;
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE PeriodObs : VitalDelayType;
+ VARIABLE PulseTest : BOOLEAN;
+ VARIABLE PeriodTest: BOOLEAN;
+ VARIABLE TestValue : X01;
+BEGIN
+
+ -- Initialize for no violation
+ Violation := '0'; --MEM IR 402
+
+ FOR i IN TestSignal'RANGE LOOP
+ TestDly := Maximum(0 ns, TestDelay(i));
+ TestValue := To_X01(TestSignal(i));
+
+ IF (PeriodData(i).NotFirstFlag = FALSE) THEN
+ PeriodData(i).Rise := -Maximum(Period(i),
+ Maximum(PulseWidthHigh(i),PulseWidthLow(i)));
+ PeriodData(i).Fall := -Maximum(Period(i),
+ Maximum(PulseWidthHigh(i),PulseWidthLow(i)));
+ PeriodData(i).Last := TestValue;
+ PeriodData(i).NotFirstFlag := TRUE;
+ END IF;
+
+ -- Initialize for no violation
+ -- Violation := '0'; --Mem IR 402
+
+ -- No violation possible if no test signal change
+ NEXT WHEN (PeriodData(i).Last = TestValue);
+
+ -- record starting pulse times
+ IF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'P')) THEN
+ -- Compute period times, then record the High Rise Time
+ PeriodObs := NOW - PeriodData(i).Rise;
+ PeriodData(i).Rise := NOW;
+ PeriodTest := TRUE;
+ ELSIF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'N')) THEN
+ -- Compute period times, then record the Low Fall Time
+ PeriodObs := NOW - PeriodData(i).Fall;
+ PeriodData(i).Fall := NOW;
+ PeriodTest := TRUE;
+ ELSE
+ PeriodTest := FALSE;
+ END IF;
+
+ -- do checks on pulse ends
+ IF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'p')) THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData(i).Fall;
+ CheckInfo.ExpTime := PulseWidthLow(i);
+ PulseTest := TRUE;
+ ELSIF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'n')) THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData(i).Rise;
+ CheckInfo.ExpTime := PulseWidthHigh(i);
+ PulseTest := TRUE;
+ ELSE
+ PulseTest := FALSE;
+ END IF;
+
+ IF (PulseTest AND CheckEnabled) THEN
+ -- Verify Pulse Width [ignore 1st edge]
+ IF (CheckInfo.ObsTime < CheckInfo.ExpTime) THEN
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PulseWidCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := PeriodData(i).Last;
+ VitalMemoryReportViolation (TestSignalName, "", i,
+ HeaderMsg, CheckInfo, MsgFormat, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ IF (PeriodTest AND CheckEnabled) THEN
+ -- Verify the Period [ignore 1st edge]
+ CheckInfo.ObsTime := PeriodObs;
+ CheckInfo.ExpTime := Period(i);
+ IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PeriodCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := TestValue;
+ VitalMemoryReportViolation (TestSignalName, "", i,
+ HeaderMsg, CheckInfo, MsgFormat, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ PeriodData(i).Last := TestValue;
+ END LOOP;
+
+END VitalMemoryPeriodPulseCheck;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryPeriodPulseCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE PeriodData : INOUT VitalPeriodDataArrayType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArraytype;
+ CONSTANT Period : IN VitalDelayArraytype;
+ CONSTANT PulseWidthHigh : IN VitalDelayArraytype;
+ CONSTANT PulseWidthLow : IN VitalDelayArraytype;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType
+)IS
+ VARIABLE TestDly : VitalDelayType;
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE PeriodObs : VitalDelayType;
+ VARIABLE PulseTest : BOOLEAN;
+ VARIABLE PeriodTest: BOOLEAN;
+ VARIABLE TestValue : X01;
+BEGIN
+
+ FOR i IN TestSignal'RANGE LOOP
+ TestDly := Maximum(0 ns, TestDelay(i));
+ TestValue := To_X01(TestSignal(i));
+
+ IF (PeriodData(i).NotFirstFlag = FALSE) THEN
+ PeriodData(i).Rise := -Maximum(Period(i),
+ Maximum(PulseWidthHigh(i),PulseWidthLow(i)));
+ PeriodData(i).Fall := -Maximum(Period(i),
+ Maximum(PulseWidthHigh(i),PulseWidthLow(i)));
+ PeriodData(i).Last := TestValue;
+ PeriodData(i).NotFirstFlag := TRUE;
+ END IF;
+
+ -- Initialize for no violation
+ Violation(i) := '0';
+
+ -- No violation possible if no test signal change
+ NEXT WHEN (PeriodData(i).Last = TestValue);
+
+ -- record starting pulse times
+ IF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'P')) THEN
+ -- Compute period times, then record the High Rise Time
+ PeriodObs := NOW - PeriodData(i).Rise;
+ PeriodData(i).Rise := NOW;
+ PeriodTest := TRUE;
+ ELSIF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'N')) THEN
+ -- Compute period times, then record the Low Fall Time
+ PeriodObs := NOW - PeriodData(i).Fall;
+ PeriodData(i).Fall := NOW;
+ PeriodTest := TRUE;
+ ELSE
+ PeriodTest := FALSE;
+ END IF;
+
+ -- do checks on pulse ends
+ IF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'p')) THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData(i).Fall;
+ CheckInfo.ExpTime := PulseWidthLow(i);
+ PulseTest := TRUE;
+ ELSIF (EdgeSymbolMatch(PeriodData(i).Last, TestValue, 'n')) THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData(i).Rise;
+ CheckInfo.ExpTime := PulseWidthHigh(i);
+ PulseTest := TRUE;
+ ELSE
+ PulseTest := FALSE;
+ END IF;
+
+ IF (PulseTest AND CheckEnabled) THEN
+ -- Verify Pulse Width [ignore 1st edge]
+ IF (CheckInfo.ObsTime < CheckInfo.ExpTime) THEN
+ IF (XOn) THEN
+ Violation(i) := 'X';
+ END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PulseWidCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := PeriodData(i).Last;
+ VitalMemoryReportViolation (TestSignalName, "", i,
+ HeaderMsg, CheckInfo, MsgFormat, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ IF (PeriodTest AND CheckEnabled) THEN
+ -- Verify the Period [ignore 1st edge]
+ CheckInfo.ObsTime := PeriodObs;
+ CheckInfo.ExpTime := Period(i);
+ IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN
+ IF (XOn) THEN
+ Violation(i) := 'X';
+ END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PeriodCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := TestValue;
+ VitalMemoryReportViolation (TestSignalName, "", i,
+ HeaderMsg, CheckInfo, MsgFOrmat, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ PeriodData(i).Last := TestValue;
+ END LOOP;
+
+END VitalMemoryPeriodPulseCheck;
+
+-- ----------------------------------------------------------------------------
+-- Functionality Section
+-- ----------------------------------------------------------------------------
+
+-- Look-up table. Given an int, we can get the 4-bit bit_vector.
+TYPE HexToBitvTableType IS ARRAY (NATURAL RANGE <>) OF
+ std_logic_vector(3 DOWNTO 0) ;
+
+CONSTANT HexToBitvTable : HexToBitvTableType (0 TO 15) :=
+ (
+ "0000", "0001", "0010", "0011",
+ "0100", "0101", "0110", "0111",
+ "1000", "1001", "1010", "1011",
+ "1100", "1101", "1110", "1111"
+ ) ;
+
+-- ----------------------------------------------------------------------------
+-- Misc Utilities Local Utilities
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- Procedure: IsSpace
+-- Parameters: ch -- input character
+-- Description: Returns TRUE or FALSE depending on the input character
+-- being white space or not.
+-- ----------------------------------------------------------------------------
+FUNCTION IsSpace (ch : character)
+RETURN boolean IS
+BEGIN
+ RETURN ((ch = ' ') OR (ch = CR) OR (ch = HT) OR (ch = NUL));
+END IsSpace;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: LenOfString
+-- Parameters: Str -- input string
+-- Description: Returns the NATURAL length of the input string.
+-- as terminated by the first NUL character.
+-- ----------------------------------------------------------------------------
+FUNCTION LenOfString (Str : STRING)
+RETURN NATURAL IS
+ VARIABLE StrRight : NATURAL;
+BEGIN
+ StrRight := Str'RIGHT;
+ FOR i IN Str'RANGE LOOP
+ IF (Str(i) = NUL) THEN
+ StrRight := i - 1;
+ EXIT;
+ END IF;
+ END LOOP;
+ RETURN (StrRight);
+END LenOfString;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: HexToInt
+-- Parameters: Hex -- input character or string
+-- Description: Converts input character or string interpreted as a
+-- hexadecimal representation to integer value.
+-- ----------------------------------------------------------------------------
+FUNCTION HexToInt(Hex : CHARACTER) RETURN INTEGER IS
+ CONSTANT HexChars : STRING := "0123456789ABCDEFabcdef";
+ CONSTANT XHiChar : CHARACTER := 'X';
+ CONSTANT XLoChar : CHARACTER := 'x';
+BEGIN
+ IF (Hex = XLoChar OR Hex = XHiChar) THEN
+ RETURN (23);
+ END IF;
+ FOR i IN 1 TO 16 LOOP
+ IF(Hex = HexChars(i)) THEN
+ RETURN (i-1);
+ END IF;
+ END LOOP;
+ FOR i IN 17 TO 22 LOOP
+ IF (Hex = HexChars(i)) THEN
+ RETURN (i-7);
+ END IF;
+ END LOOP;
+ ASSERT FALSE REPORT
+ "Invalid character received by HexToInt function"
+ SEVERITY WARNING;
+ RETURN (0);
+END HexToInt;
+
+-- ----------------------------------------------------------------------------
+FUNCTION HexToInt (Hex : STRING) RETURN INTEGER IS
+ VARIABLE Value : INTEGER := 0;
+ VARIABLE Length : INTEGER;
+BEGIN
+ Length := LenOfString(hex);
+ IF (Length > 8) THEN
+ ASSERT FALSE REPORT
+ "Invalid string length received by HexToInt function"
+ SEVERITY WARNING;
+ ELSE
+ FOR i IN 1 TO Length LOOP
+ Value := Value + HexToInt(Hex(i)) * 16 ** (Length - i);
+ END LOOP;
+ END IF;
+ RETURN (Value);
+END HexToInt;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: HexToBitv
+-- Parameters: Hex -- Input hex string
+-- Description: Converts input hex string to a std_logic_vector
+-- ----------------------------------------------------------------------------
+FUNCTION HexToBitv(
+ Hex : STRING
+) RETURN std_logic_vector is
+ VARIABLE Index : INTEGER := 0 ;
+ VARIABLE ValHexToInt : INTEGER ;
+ VARIABLE BitsPerHex : INTEGER := 4 ; -- Denotes no. of bits per hex char.
+ VARIABLE HexLen : NATURAL := (BitsPerHex * LenOfString(Hex)) ;
+ VARIABLE TableVal : std_logic_vector(3 DOWNTO 0) ;
+ VARIABLE Result : std_logic_vector(HexLen-1 DOWNTO 0) ;
+BEGIN
+ -- Assign 4-bit wide bit vector to result directly from a look-up table.
+ Index := 0 ;
+ WHILE ( Index < HexLen ) LOOP
+ ValHexToInt := HexToInt( Hex((HexLen - Index)/BitsPerHex ) );
+ IF ( ValHexToInt = 23 ) THEN
+ TableVal := "XXXX";
+ ELSE
+ -- Look up from the table.
+ TableVal := HexToBitvTable( ValHexToInt ) ;
+ END IF;
+ -- Assign now.
+ Result(Index+3 DOWNTO Index) := TableVal ;
+ -- Get ready for next block of 4-bits.
+ Index := Index + 4 ;
+ END LOOP ;
+ RETURN Result ;
+END HexToBitv ;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: BinToBitv
+-- Parameters: Bin -- Input bin string
+-- Description: Converts input bin string to a std_logic_vector
+-- ----------------------------------------------------------------------------
+FUNCTION BinToBitv(
+ Bin : STRING
+) RETURN std_logic_vector is
+ VARIABLE Index : INTEGER := 0 ;
+ VARIABLE Length : NATURAL := LenOfString(Bin);
+ VARIABLE BitVal : std_ulogic;
+ VARIABLE Result : std_logic_vector(Length-1 DOWNTO 0) ;
+BEGIN
+ Index := 0 ;
+ WHILE ( Index < Length ) LOOP
+ IF (Bin(Length-Index) = '0') THEN
+ BitVal := '0';
+ ELSIF (Bin(Length-Index) = '1') THEN
+ BitVal := '1';
+ ELSE
+ BitVal := 'X';
+ END IF ;
+ -- Assign now.
+ Result(Index) := BitVal ;
+ Index := Index + 1 ;
+ END LOOP ;
+ RETURN Result ;
+END BinToBitv ;
+
+-- ----------------------------------------------------------------------------
+-- For Memory Table Modeling
+-- ----------------------------------------------------------------------------
+
+TYPE To_MemoryCharType IS ARRAY (VitalMemorySymbolType) OF CHARACTER;
+CONSTANT To_MemoryChar : To_MemoryCharType :=
+ ( '/', '\', 'P', 'N', 'r', 'f', 'p', 'n', 'R', 'F', '^', 'v',
+ 'E', 'A', 'D', '*', 'X', '0', '1', '-', 'B', 'Z', 'S',
+ 'g', 'u', 'i', 'G', 'U', 'I',
+ 'w', 's',
+ 'c', 'l', 'd', 'e', 'C', 'L',
+ 'M', 'm', 't' );
+
+TYPE ValidMemoryTableInputType IS ARRAY (VitalMemorySymbolType) OF BOOLEAN;
+CONSTANT ValidMemoryTableInput : ValidMemoryTableInputType :=
+ -- '/', '\', 'P', 'N', 'r', 'f',
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
+ -- 'p', 'n', 'R', 'F', '^', 'v',
+ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
+ -- 'E', 'A', 'D', '*',
+ TRUE, TRUE, TRUE, TRUE,
+ -- 'X', '0', '1', '-', 'B', 'Z',
+ TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,
+ -- 'S',
+ TRUE,
+ -- 'g', 'u', 'i', 'G', 'U', 'I',
+ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+ -- 'w', 's',
+ FALSE, FALSE,
+ -- 'c', 'l', 'd', 'e', 'C', 'L',
+ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+ -- 'M', 'm', 't'
+ FALSE, FALSE, FALSE);
+
+TYPE MemoryTableMatchType IS ARRAY (X01,X01,VitalMemorySymbolType) OF BOOLEAN;
+-- last value, present value, table symbol
+CONSTANT MemoryTableMatch : MemoryTableMatchType := (
+ ( -- X (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ -- g u i G U I
+ -- w s
+ -- c l d e, C L
+ -- m t
+ ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE),
+ ( FALSE,FALSE,FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE, FALSE,TRUE,
+ TRUE, FALSE,TRUE, TRUE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE),
+ ( FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,TRUE, FALSE,TRUE, FALSE,
+ TRUE, TRUE, FALSE,TRUE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE)
+ ),
+
+ (-- 0 (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ -- g u i G U I
+ -- w s
+ -- c l d e, C L
+ -- m t
+ ( FALSE,FALSE,FALSE,FALSE,TRUE, FALSE,
+ TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE),
+ ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,TRUE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE),
+ ( TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE)
+ ),
+
+ (-- 1 (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ -- g u i G U I
+ -- w s
+ -- c l d e, C L
+ -- m t
+ ( FALSE,FALSE,FALSE,FALSE,FALSE,TRUE ,
+ FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,TRUE, TRUE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE),
+ ( FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE),
+ ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,TRUE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE)
+ )
+ );
+
+
+-- ----------------------------------------------------------------------------
+-- Error Message Types and Tables
+-- ----------------------------------------------------------------------------
+
+TYPE VitalMemoryErrorType IS (
+ ErrGoodAddr, -- 'g' Good address (no transition)
+ ErrUnknAddr, -- 'u' 'X' levels in address (no transition)
+ ErrInvaAddr, -- 'i' Invalid address (no transition)
+ ErrGoodTrAddr, -- 'G' Good address (with transition)
+ ErrUnknTrAddr, -- 'U' 'X' levels in address (with transition)
+ ErrInvaTrAddr, -- 'I' Invalid address (with transition)
+ ErrWrDatMem, -- 'w' Writing data to memory
+ ErrNoChgMem, -- 's' Retaining previous memory contents
+ ErrCrAllMem, -- 'c' Corrupting entire memory with 'X'
+ ErrCrWrdMem, -- 'l' Corrupting a word in memory with 'X'
+ ErrCrBitMem, -- 'd' Corrupting a single bit in memory with 'X'
+ ErrCrDatMem, -- 'e' Corrupting a word with 'X' based on data in
+ ErrCrAllSubMem,-- 'C' Corrupting a sub-word entire memory with 'X'
+ ErrCrWrdSubMem,-- 'L' Corrupting a sub-word in memory with 'X'
+ ErrCrBitSubMem,-- 'D' Corrupting a single bit of a memory sub-word with 'X'
+ ErrCrDatSubMem,-- 'E' Corrupting a sub-word with 'X' based on data in
+ ErrCrWrdOut, -- 'l' Corrupting data out with 'X'
+ ErrCrBitOut, -- 'd' Corrupting a single bit of data out with 'X'
+ ErrCrDatOut, -- 'e' Corrupting data out with 'X' based on data in
+ ErrCrWrdSubOut,-- 'L' Corrupting data out sub-word with 'X'
+ ErrCrBitSubOut,-- 'D' Corrupting a single bit of data out sub-word with 'X'
+ ErrCrDatSubOut,-- 'E' Corrupting data out sub-word with 'X' based on data in
+ ErrImplOut, -- 'M' Implicit read from memory to data out
+ ErrReadOut, -- 'm' Reading data from memory to data out
+ ErrAssgOut, -- 't' Transfering from data in to data out
+ ErrAsgXOut, -- 'X' Assigning unknown level to data out
+ ErrAsg0Out, -- '0' Assigning low level to data out
+ ErrAsg1Out, -- '1' Assigning high level to data out
+ ErrAsgZOut, -- 'Z' Assigning high impedence to data out
+ ErrAsgSOut, -- 'S' Keeping data out at steady value
+ ErrAsgXMem, -- 'X' Assigning unknown level to memory location
+ ErrAsg0Mem, -- '0' Assigning low level to memory location
+ ErrAsg1Mem, -- '1' Assigning high level to memory location
+ ErrAsgZMem, -- 'Z' Assigning high impedence to memory location
+ ErrDefMemAct, -- No memory table match, using default action
+ ErrInitMem, -- Initialize memory contents
+ ErrMcpWrCont, -- Memory cross port to same port write contention
+ ErrMcpCpCont, -- Memory cross port read/write data/memory contention
+ ErrMcpCpRead, -- Memory cross port read to same port
+ ErrMcpRdWrCo, -- Memory cross port read/write data only contention
+ ErrMcpCpWrCont,-- Memory cross port to cross port write contention
+ ErrUnknMemDo, -- Unknown memory action
+ ErrUnknDatDo, -- Unknown data action
+ ErrUnknSymbol, -- Illegal memory symbol
+ ErrLdIlgArg,
+ ErrLdAddrRng,
+ ErrLdMemInfo,
+ ErrLdFileEmpty,
+ ErrPrintString
+);
+
+TYPE VitalMemoryErrorSeverityType IS
+ARRAY (VitalMemoryErrorType) OF SEVERITY_LEVEL;
+CONSTANT VitalMemoryErrorSeverity :
+ VitalMemoryErrorSeverityType := (
+ ErrGoodAddr => NOTE,
+ ErrUnknAddr => WARNING,
+ ErrInvaAddr => WARNING,
+ ErrGoodTrAddr => NOTE,
+ ErrUnknTrAddr => WARNING,
+ ErrInvaTrAddr => WARNING,
+ ErrWrDatMem => NOTE,
+ ErrNoChgMem => NOTE,
+ ErrCrAllMem => WARNING,
+ ErrCrWrdMem => WARNING,
+ ErrCrBitMem => WARNING,
+ ErrCrDatMem => WARNING,
+ ErrCrAllSubMem => WARNING,
+ ErrCrWrdSubMem => WARNING,
+ ErrCrBitSubMem => WARNING,
+ ErrCrDatSubMem => WARNING,
+ ErrCrWrdOut => WARNING,
+ ErrCrBitOut => WARNING,
+ ErrCrDatOut => WARNING,
+ ErrCrWrdSubOut => WARNING,
+ ErrCrBitSubOut => WARNING,
+ ErrCrDatSubOut => WARNING,
+ ErrImplOut => NOTE,
+ ErrReadOut => NOTE,
+ ErrAssgOut => NOTE,
+ ErrAsgXOut => NOTE,
+ ErrAsg0Out => NOTE,
+ ErrAsg1Out => NOTE,
+ ErrAsgZOut => NOTE,
+ ErrAsgSOut => NOTE,
+ ErrAsgXMem => NOTE,
+ ErrAsg0Mem => NOTE,
+ ErrAsg1Mem => NOTE,
+ ErrAsgZMem => NOTE,
+ ErrDefMemAct => NOTE,
+ ErrInitMem => NOTE,
+ ErrMcpWrCont => WARNING,
+ ErrMcpCpCont => WARNING,
+ ErrMcpCpRead => WARNING,
+ ErrMcpRdWrCo => WARNING,
+ ErrMcpCpWrCont => WARNING,
+ ErrUnknMemDo => ERROR,
+ ErrUnknDatDo => ERROR,
+ ErrUnknSymbol => ERROR,
+ ErrLdIlgArg => ERROR,
+ ErrLdAddrRng => WARNING,
+ ErrLdMemInfo => NOTE,
+ ErrLdFileEmpty => ERROR,
+ ErrPrintString => WARNING
+ );
+
+-- ----------------------------------------------------------------------------
+CONSTANT MsgGoodAddr : STRING
+ := "Good address (no transition)";
+CONSTANT MsgUnknAddr : STRING
+ := "Unknown address (no transition)";
+CONSTANT MsgInvaAddr : STRING
+ := "Invalid address (no transition)";
+CONSTANT MsgGoodTrAddr : STRING
+ := "Good address (with transition)";
+CONSTANT MsgUnknTrAddr : STRING
+ := "Unknown address (with transition)";
+CONSTANT MsgInvaTrAddr : STRING
+ := "Invalid address (with transition)";
+CONSTANT MsgNoChgMem : STRING
+ := "Retaining previous memory contents";
+CONSTANT MsgWrDatMem : STRING
+ := "Writing data to memory";
+CONSTANT MsgCrAllMem : STRING
+ := "Corrupting entire memory with 'X'";
+CONSTANT MsgCrWrdMem : STRING
+ := "Corrupting a word in memory with 'X'";
+CONSTANT MsgCrBitMem : STRING
+ := "Corrupting a single bit in memory with 'X'";
+CONSTANT MsgCrDatMem : STRING
+ := "Corrupting a word with 'X' based on data in";
+CONSTANT MsgCrAllSubMem : STRING
+ := "Corrupting a sub-word entire memory with 'X'";
+CONSTANT MsgCrWrdSubMem : STRING
+ := "Corrupting a sub-word in memory with 'X'";
+CONSTANT MsgCrBitSubMem : STRING
+ := "Corrupting a single bit of a sub-word with 'X'";
+CONSTANT MsgCrDatSubMem : STRING
+ := "Corrupting a sub-word with 'X' based on data in";
+CONSTANT MsgCrWrdOut : STRING
+ := "Corrupting data out with 'X'";
+CONSTANT MsgCrBitOut : STRING
+ := "Corrupting a single bit of data out with 'X'";
+CONSTANT MsgCrDatOut : STRING
+ := "Corrupting data out with 'X' based on data in";
+CONSTANT MsgCrWrdSubOut : STRING
+ := "Corrupting data out sub-word with 'X'";
+CONSTANT MsgCrBitSubOut : STRING
+ := "Corrupting a single bit of data out sub-word with 'X'";
+CONSTANT MsgCrDatSubOut : STRING
+ := "Corrupting data out sub-word with 'X' based on data in";
+CONSTANT MsgImplOut : STRING
+ := "Implicit read from memory to data out";
+CONSTANT MsgReadOut : STRING
+ := "Reading data from memory to data out";
+CONSTANT MsgAssgOut : STRING
+ := "Transfering from data in to data out";
+CONSTANT MsgAsgXOut : STRING
+ := "Assigning unknown level to data out";
+CONSTANT MsgAsg0Out : STRING
+ := "Assigning low level to data out";
+CONSTANT MsgAsg1Out : STRING
+ := "Assigning high level to data out";
+CONSTANT MsgAsgZOut : STRING
+ := "Assigning high impedance to data out";
+CONSTANT MsgAsgSOut : STRING
+ := "Keeping data out at steady value";
+CONSTANT MsgAsgXMem : STRING
+ := "Assigning unknown level to memory location";
+CONSTANT MsgAsg0Mem : STRING
+ := "Assigning low level to memory location";
+CONSTANT MsgAsg1Mem : STRING
+ := "Assigning high level to memory location";
+CONSTANT MsgAsgZMem : STRING
+ := "Assigning high impedance to memory location";
+CONSTANT MsgDefMemAct : STRING
+ := "No memory table match, using default action";
+CONSTANT MsgInitMem : STRING
+ := "Initializing memory contents";
+CONSTANT MsgMcpWrCont : STRING
+ := "Same port write contention";
+CONSTANT MsgMcpCpCont : STRING
+ := "Cross port read/write data/memory contention";
+CONSTANT MsgMcpCpRead : STRING
+ := "Cross port read to same port";
+CONSTANT MsgMcpRdWrCo : STRING
+ := "Cross port read/write data only contention";
+CONSTANT MsgMcpCpWrCont : STRING
+ := "Cross port write contention";
+CONSTANT MsgUnknMemDo : STRING
+ := "Unknown memory action";
+CONSTANT MsgUnknDatDo : STRING
+ := "Unknown data action";
+CONSTANT MsgUnknSymbol : STRING
+ := "Illegal memory symbol";
+
+CONSTANT MsgLdIlgArg : STRING
+ := "Illegal bit arguments while loading memory.";
+CONSTANT MsgLdMemInfo : STRING
+ := "Loading data from the file into memory.";
+CONSTANT MsgLdAddrRng : STRING
+ := "Address out of range while loading memory.";
+CONSTANT MsgLdFileEmpty : STRING
+ := "Memory load file is empty.";
+CONSTANT MsgPrintString : STRING
+ := "";
+
+CONSTANT MsgUnknown : STRING
+ := "Unknown error message.";
+
+CONSTANT MsgVMT : STRING
+ := "VitalMemoryTable";
+CONSTANT MsgVMV : STRING
+ := "VitalMemoryViolation";
+CONSTANT MsgVDM : STRING
+ := "VitalDeclareMemory";
+CONSTANT MsgVMCP : STRING
+ := "VitalMemoryCrossPorts";
+
+-- ----------------------------------------------------------------------------
+-- LOCAL Utilities
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- Procedure: MemoryMessage
+-- Parameters: ErrorId -- Input error code
+-- Description: This function looks up the input error code and returns
+-- the string value of the associated message.
+-- ----------------------------------------------------------------------------
+
+FUNCTION MemoryMessage (
+ CONSTANT ErrorId : IN VitalMemoryErrorType
+) RETURN STRING IS
+BEGIN
+ CASE ErrorId IS
+ WHEN ErrGoodAddr => RETURN MsgGoodAddr ;
+ WHEN ErrUnknAddr => RETURN MsgUnknAddr ;
+ WHEN ErrInvaAddr => RETURN MsgInvaAddr ;
+ WHEN ErrGoodTrAddr => RETURN MsgGoodTrAddr ;
+ WHEN ErrUnknTrAddr => RETURN MsgUnknTrAddr ;
+ WHEN ErrInvaTrAddr => RETURN MsgInvaTrAddr ;
+ WHEN ErrWrDatMem => RETURN MsgWrDatMem ;
+ WHEN ErrNoChgMem => RETURN MsgNoChgMem ;
+ WHEN ErrCrAllMem => RETURN MsgCrAllMem ;
+ WHEN ErrCrWrdMem => RETURN MsgCrWrdMem ;
+ WHEN ErrCrBitMem => RETURN MsgCrBitMem ;
+ WHEN ErrCrDatMem => RETURN MsgCrDatMem ;
+ WHEN ErrCrAllSubMem => RETURN MsgCrAllSubMem;
+ WHEN ErrCrWrdSubMem => RETURN MsgCrWrdSubMem;
+ WHEN ErrCrBitSubMem => RETURN MsgCrBitSubMem;
+ WHEN ErrCrDatSubMem => RETURN MsgCrDatSubMem;
+ WHEN ErrCrWrdOut => RETURN MsgCrWrdOut ;
+ WHEN ErrCrBitOut => RETURN MsgCrBitOut ;
+ WHEN ErrCrDatOut => RETURN MsgCrDatOut ;
+ WHEN ErrCrWrdSubOut => RETURN MsgCrWrdSubOut;
+ WHEN ErrCrBitSubOut => RETURN MsgCrBitSubOut;
+ WHEN ErrCrDatSubOut => RETURN MsgCrDatSubOut;
+ WHEN ErrImplOut => RETURN MsgImplOut ;
+ WHEN ErrReadOut => RETURN MsgReadOut ;
+ WHEN ErrAssgOut => RETURN MsgAssgOut ;
+ WHEN ErrAsgXOut => RETURN MsgAsgXOut ;
+ WHEN ErrAsg0Out => RETURN MsgAsg0Out ;
+ WHEN ErrAsg1Out => RETURN MsgAsg1Out ;
+ WHEN ErrAsgZOut => RETURN MsgAsgZOut ;
+ WHEN ErrAsgSOut => RETURN MsgAsgSOut ;
+ WHEN ErrAsgXMem => RETURN MsgAsgXMem ;
+ WHEN ErrAsg0Mem => RETURN MsgAsg0Mem ;
+ WHEN ErrAsg1Mem => RETURN MsgAsg1Mem ;
+ WHEN ErrAsgZMem => RETURN MsgAsgZMem ;
+ WHEN ErrDefMemAct => RETURN MsgDefMemAct ;
+ WHEN ErrInitMem => RETURN MsgInitMem ;
+ WHEN ErrMcpWrCont => RETURN MsgMcpWrCont ;
+ WHEN ErrMcpCpCont => RETURN MsgMcpCpCont ;
+ WHEN ErrMcpCpRead => RETURN MsgMcpCpRead ;
+ WHEN ErrMcpRdWrCo => RETURN MsgMcpRdWrCo ;
+ WHEN ErrMcpCpWrCont => RETURN MsgMcpCpWrCont;
+ WHEN ErrUnknMemDo => RETURN MsgUnknMemDo ;
+ WHEN ErrUnknDatDo => RETURN MsgUnknDatDo ;
+ WHEN ErrUnknSymbol => RETURN MsgUnknSymbol ;
+ WHEN ErrLdIlgArg => RETURN MsgLdIlgArg ;
+ WHEN ErrLdAddrRng => RETURN MsgLdAddrRng ;
+ WHEN ErrLdMemInfo => RETURN MsgLdMemInfo ;
+ WHEN ErrLdFileEmpty => RETURN MsgLdFileEmpty;
+ WHEN ErrPrintString => RETURN MsgPrintString;
+ WHEN OTHERS => RETURN MsgUnknown ;
+ END CASE;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: PrintMemoryMessage
+-- Parameters: Routine -- String identifying the calling routine
+-- ErrorId -- Input error code for message lookup
+-- Info -- Output string or character
+-- InfoStr -- Additional output string
+-- Info1 -- Additional output integer
+-- Info2 -- Additional output integer
+-- Info3 -- Additional output integer
+-- Description: This procedure prints out a memory status message
+-- given the input error id and other status information.
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType
+) IS
+BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId)
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType;
+ CONSTANT Info : IN STRING
+) IS
+BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & Info
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType;
+ CONSTANT Info1 : IN STRING;
+ CONSTANT Info2 : IN STRING
+) IS
+BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & Info1 & " " & Info2
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType;
+ CONSTANT Info : IN CHARACTER
+) IS
+BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & Info
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType;
+ CONSTANT InfoStr : IN STRING;
+ CONSTANT Info1 : IN NATURAL
+) IS
+ VARIABLE TmpStr : STRING ( 1 TO 256 ) ;
+ VARIABLE TmpInt : INTEGER := 1;
+BEGIN
+ IntToStr(Info1,TmpStr,TmpInt);
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & InfoStr & " " & TmpStr
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType;
+ CONSTANT InfoStr : IN STRING;
+ CONSTANT Info1 : IN NATURAL;
+ CONSTANT Info2 : IN NATURAL
+) IS
+ VARIABLE TmpStr : STRING ( 1 TO 256 ) ;
+ VARIABLE TmpInt : INTEGER := 1;
+BEGIN
+ IntToStr(Info1,TmpStr,TmpInt);
+ IntToStr(Info2,TmpStr,TmpInt);
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & InfoStr & " " & TmpStr
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalMemoryErrorType;
+ CONSTANT InfoStr : IN STRING;
+ CONSTANT Info1 : IN NATURAL;
+ CONSTANT Info2 : IN NATURAL;
+ CONSTANT Info3 : IN NATURAL
+) IS
+ VARIABLE TmpStr : STRING ( 1 TO 256 ) ;
+ VARIABLE TmpInt : INTEGER := 1;
+BEGIN
+ IntToStr(Info1,TmpStr,TmpInt);
+ IntToStr(Info2,TmpStr,TmpInt);
+ IntToStr(Info3,TmpStr,TmpInt);
+ ASSERT FALSE
+ REPORT Routine & ": " & MemoryMessage(ErrorId) & " " & InfoStr & " " & TmpStr
+ SEVERITY VitalMemoryErrorSeverity(ErrorId);
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE PrintMemoryMessage (
+ CONSTANT Routine : IN STRING;
+ CONSTANT Table : IN VitalMemoryTableType;
+ CONSTANT Index : IN INTEGER;
+ CONSTANT InfoStr : IN STRING
+) IS
+ CONSTANT TableEntries : INTEGER := Table'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := Table'LENGTH(2);
+ VARIABLE TmpStr : STRING ( 1 TO 256 ) ;
+ VARIABLE TmpInt : INTEGER := 1;
+BEGIN
+ IF (Index < 0 AND Index > TableEntries-1) THEN
+ ASSERT FALSE
+ REPORT Routine & ": Memory table search failure"
+ SEVERITY ERROR;
+ END IF;
+ ColLoop:
+ FOR i IN 0 TO TableWidth-1 LOOP
+ IF (i >= 64) THEN
+ TmpStr(TmpInt) := '.';
+ TmpInt := TmpInt + 1;
+ TmpStr(TmpInt) := '.';
+ TmpInt := TmpInt + 1;
+ TmpStr(TmpInt) := '.';
+ TmpInt := TmpInt + 1;
+ EXIT ColLoop;
+ END IF;
+ TmpStr(TmpInt) := ''';
+ TmpInt := TmpInt + 1;
+ TmpStr(TmpInt) := To_MemoryChar(Table(Index,i));
+ TmpInt := TmpInt + 1;
+ TmpStr(TmpInt) := ''';
+ TmpInt := TmpInt + 1;
+ IF (i < TableWidth-1) THEN
+ TmpStr(TmpInt) := ',';
+ TmpInt := TmpInt + 1;
+ END IF;
+ END LOOP;
+ ASSERT FALSE
+ REPORT Routine & ": Port=" & InfoStr & " TableRow=" & TmpStr
+ SEVERITY NOTE;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: DecodeAddress
+-- Parameters: Address - Converted address.
+-- AddrFlag - Flag to indicte address match
+-- MemoryData - Information about memory characteristics
+-- PrevAddressBus - Previous input address value
+-- AddressBus - Input address value.
+-- Description: This procedure is used for transforming a valid
+-- address value to an integer in order to access memory.
+-- It performs address bound checking as well.
+-- Sets Address to -1 for unknowns
+-- Sets Address to -2 for out of range
+-- ----------------------------------------------------------------------------
+
+PROCEDURE DecodeAddress (
+ VARIABLE Address : INOUT INTEGER;
+ VARIABLE AddrFlag : INOUT VitalMemorySymbolType;
+ VARIABLE MemoryData : IN VitalMemoryDataType;
+ CONSTANT PrevAddressBus : IN std_logic_vector;
+ CONSTANT AddressBus : IN std_logic_vector
+) IS
+ VARIABLE Power : NATURAL;
+ VARIABLE AddrUnkn : BOOLEAN;
+BEGIN
+ Power := 0;
+ AddrUnkn := FALSE;
+ -- It is assumed that always Address'LEFT represents the Most significant bit.
+ FOR i IN AddressBus'RANGE LOOP
+ Power := Power * 2;
+ IF (AddressBus(i) /= '1' AND AddressBus(i) /= '0') THEN
+ AddrUnkn := TRUE;
+ Power := 0;
+ EXIT;
+ ELSIF (AddressBus(i) = '1') THEN
+ Power := Power + 1;
+ END IF;
+ END LOOP;
+ Address := Power;
+ AddrFlag := 'g';
+ IF (AddrUnkn) THEN
+ AddrFlag := 'u'; -- unknown addr
+ Address := -1;
+ END IF;
+ IF ( Power > (MemoryData.NoOfWords - 1)) THEN
+ AddrFlag := 'i'; -- invalid addr
+ Address := -2;
+ END IF;
+ IF (PrevAddressBus /= AddressBus) THEN
+ CASE AddrFlag IS
+ WHEN 'g' => AddrFlag := 'G';
+ WHEN 'u' => AddrFlag := 'U';
+ WHEN 'i' => AddrFlag := 'I';
+ WHEN OTHERS =>
+ ASSERT FALSE REPORT
+ "DecodeAddress: Internal error. [AddrFlag]="
+ & To_MemoryChar(AddrFlag)
+ SEVERITY ERROR;
+ END CASE;
+ END IF;
+END DecodeAddress;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: DecodeData
+-- Parameters: DataFlag - Flag to indicte data match
+-- PrevDataInBus - Previous input data value
+-- DataInBus - Input data value.
+-- HighBit - High bit offset value.
+-- LowBit - Low bit offset value.
+-- Description: This procedure is used for interpreting the input data
+-- as a data flag for subsequent table matching.
+-- ----------------------------------------------------------------------------
+PROCEDURE DecodeData (
+ VARIABLE DataFlag : INOUT VitalMemorySymbolType;
+ CONSTANT PrevDataInBus : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT HighBit : IN NATURAL;
+ CONSTANT LowBit : IN NATURAL
+) IS
+ VARIABLE DataUnkn : BOOLEAN := FALSE;
+BEGIN
+ FOR i IN LowBit TO HighBit LOOP
+ IF DataInBus(i) /= '1' AND DataInBus(i) /= '0' THEN
+ DataUnkn := TRUE;
+ EXIT;
+ END IF;
+ END LOOP;
+ DataFlag := 'g';
+ IF (DataUnkn) THEN
+ DataFlag := 'u'; -- unknown addr
+ END IF;
+ IF (PrevDataInBus(HighBit DOWNTO LowBit) /=
+ DataInBus(HighBit DOWNTO LowBit)) THEN
+ CASE DataFlag IS
+ WHEN 'g' => DataFlag := 'G';
+ WHEN 'u' => DataFlag := 'U';
+ WHEN OTHERS =>
+ ASSERT FALSE REPORT
+ "DecodeData: Internal error. [DataFlag]="
+ & To_MemoryChar(DataFlag)
+ SEVERITY ERROR;
+ END CASE;
+ END IF;
+END DecodeData;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: WriteMemory
+-- Parameters: MemoryPtr - Pointer to the memory array.
+-- DataInBus - Input Data to be written.
+-- Address - Address of the memory location.
+-- BitPosition - Position of bit in memory location.
+-- HighBit - High bit offset value.
+-- LowBit - Low bit offset value.
+-- Description: This procedure is used to write to a memory location
+-- on a bit/byte/word basis.
+-- The high bit and low bit offset are used for byte write
+-- operations.These parameters specify the data byte for write.
+-- In the case of word write the complete memory word is used.
+-- This procedure is overloaded for bit,byte and word write
+-- memory operations.The number of parameters may vary.
+-- ----------------------------------------------------------------------------
+PROCEDURE WriteMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT Address : IN INTEGER;
+ CONSTANT HighBit : IN NATURAL;
+ CONSTANT LowBit : IN NATURAL
+) IS
+ VARIABLE TmpData : std_logic_vector(DataInBus'LENGTH - 1 DOWNTO 0);
+BEGIN
+ -- Address bound checking.
+ IF ( Address < 0 OR Address > (MemoryPtr.NoOfWords - 1)) THEN
+ PrintMemoryMessage ( "WriteMemory", ErrPrintString,
+ "Aborting write operation as address is out of range.") ;
+ RETURN;
+ END IF;
+ TmpData := To_UX01(DataInBus);
+ FOR i in LowBit to HighBit LOOP
+ MemoryPtr.MemoryArrayPtr(Address).all(i) := TmpData(i);
+ END LOOP;
+END WriteMemory;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE WriteMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT Address : IN INTEGER;
+ CONSTANT BitPosition : IN NATURAL
+) IS
+ VARIABLE HighBit : NATURAL;
+ VARIABLE LowBit : NATURAL;
+BEGIN
+ HighBit := BitPosition;
+ LowBit := BitPosition;
+ WriteMemory (MemoryPtr, DataInBus, Address, HighBit, LowBit);
+END WriteMemory;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE WriteMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT Address : IN INTEGER
+) IS
+ VARIABLE HighBit : NATURAL;
+ VARIABLE LowBit : NATURAL;
+BEGIN
+ HighBit := MemoryPtr.NoOfBitsPerWord - 1;
+ LowBit := 0;
+ WriteMemory (MemoryPtr, DataInBus, Address, HighBit, LowBit);
+END WriteMemory;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: ReadMemory
+-- Parameters: MemoryPtr - Pointer to the memory array.
+-- DataOut - Output Data to be read in this.
+-- Address - Address of the memory location.
+-- BitPosition - Position of bit in memory location.
+-- HighBit - High bit offset value.
+-- LowBit - Low bit offset value.
+-- Description: This procedure is used to read from a memory location
+-- on a bit/byte/word basis.
+-- The high bit and low bit offset are used for byte write
+-- operations.These parameters specify the data byte for
+-- read.In the case of word write the complete memory word
+-- is used.This procedure is overloaded for bit,byte and
+-- word write memory operations.The number of parameters
+-- may vary.
+-- ----------------------------------------------------------------------------
+PROCEDURE ReadMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ VARIABLE DataOut : OUT std_logic_vector;
+ CONSTANT Address : IN INTEGER;
+ CONSTANT HighBit : IN NATURAL;
+ CONSTANT LowBit : IN NATURAL
+) IS
+ VARIABLE DataOutTmp : std_logic_vector(MemoryPtr.NoOfBitsPerWord-1 DOWNTO 0);
+ VARIABLE length : NATURAL := (HighBit - LowBit + 1);
+BEGIN
+ -- Address bound checking.
+ IF ( Address > (MemoryPtr.NoOfWords - 1)) THEN
+ PrintMemoryMessage (
+ "ReadMemory",ErrInvaAddr,
+ "[Address,NoOfWords]=",Address,MemoryPtr.NoOfWords
+ );
+ FOR i in LowBit to HighBit LOOP
+ DataOutTmp(i) := 'X';
+ END LOOP;
+ ELSE
+ FOR i in LowBit to HighBit LOOP
+ DataOutTmp(i) := MemoryPtr.MemoryArrayPtr (Address).all(i);
+ END LOOP;
+ END IF;
+ DataOut := DataOutTmp;
+END ReadMemory;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE ReadMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ VARIABLE DataOut : OUT std_logic_vector;
+ CONSTANT Address : IN INTEGER;
+ CONSTANT BitPosition : IN NATURAL
+) IS
+ VARIABLE HighBit : NATURAL;
+ VARIABLE LowBit : NATURAL;
+BEGIN
+ HighBit := BitPosition;
+ LowBit := BitPosition;
+ ReadMemory (MemoryPtr, DataOut, Address, HighBit, LowBit);
+END ReadMemory;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE ReadMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ VARIABLE DataOut : OUT std_logic_vector;
+ CONSTANT Address : IN INTEGER
+) IS
+ VARIABLE HighBit : NATURAL;
+ VARIABLE LowBit : NATURAL;
+BEGIN
+ HighBit := MemoryPtr.NoOfBitsPerWord - 1;
+ LowBit := 0;
+ ReadMemory (MemoryPtr, DataOut, Address, HighBit, LowBit);
+END ReadMemory;
+
+
+-- ----------------------------------------------------------------------------
+-- Procedure: LoadMemory
+-- Parameters: MemoryPtr - Pointer to the memory array.
+-- FileName - Name of the output file.
+-- HighBit - High bit offset value.
+-- LowBit - Low bit offset value.
+-- Description: This procedure is used to load the contents of the memory
+-- from a specified input file.
+-- The high bit and low bit offset are used so that same task
+-- can be used for all bit/byte/word write operations.
+-- In the case of a bit write RAM the HighBit and LowBit have
+-- the same value.
+-- This procedure is overloaded for word write operations.
+-- ----------------------------------------------------------------------------
+PROCEDURE LoadMemory (
+ VARIABLE MemoryPtr : INOUT VitalMemoryDataType;
+ CONSTANT FileName : IN STRING;
+ CONSTANT BinaryFile : IN BOOLEAN := FALSE
+) IS
+ FILE Fptr : TEXT OPEN read_mode IS FileName;
+ VARIABLE OneLine : LINE;
+ VARIABLE Ignore : CHARACTER;
+ VARIABLE Index : NATURAL := 1;
+ VARIABLE LineNo : NATURAL := 0;
+ VARIABLE Address : INTEGER := 0;
+ VARIABLE DataInBus : std_logic_vector(MemoryPtr.NoOfBitsPerWord-1 DOWNTO 0);
+ VARIABLE AddrStr : STRING(1 TO 80) ;
+ VARIABLE DataInStr : STRING(1 TO 255) ;
+BEGIN
+ IF (ENDFILE(fptr)) THEN
+ PrintMemoryMessage (MsgVDM, ErrLdFileEmpty,
+ "[FileName]="&FileName);
+ RETURN;
+ END IF ;
+ PrintMemoryMessage (
+ MsgVDM,ErrLdMemInfo, "[FileName]="&FileName
+ );
+ WHILE (NOT ENDFILE(fptr)) LOOP
+ ReadLine(Fptr, OneLine);
+ LineNo := LineNo + 1 ;
+ -- First ignoring leading spaces.
+ WHILE (OneLine'LENGTH /= 0 and IsSpace(OneLine(1))) LOOP
+ READ (OneLine, Ignore) ; -- Ignoring the space character.
+ END LOOP ;
+ -- Note that, by now oneline has been "stripped" of its leading spaces.
+ IF ( OneLine(1) = '@' ) THEN
+ READ (OneLine, Ignore); -- Ignore the '@' character and read the string.
+ -- Now strip off spaces, if any, between '@' and Address string.
+ WHILE (OneLine'LENGTH /= 0 and IsSpace(OneLine(1))) LOOP
+ READ (OneLine, Ignore) ; -- Ignoring the space character.
+ END LOOP ;
+ -- Now get the string which represents the address into string variable.
+ Index := 1;
+ WHILE (OneLine'LENGTH /= 0 AND (NOT(IsSpace(OneLine(1))))) LOOP
+ READ(OneLine, AddrStr(Index));
+ Index := Index + 1;
+ END LOOP ;
+ AddrStr(Index) := NUL;
+ -- Now convert the hex string into a hex integer
+ Address := HexToInt(AddrStr) ;
+ ELSE
+ IF ( LineNo /= 1 ) THEN
+ Address := Address + 1;
+ END IF;
+ END IF ;
+ IF ( Address > (MemoryPtr.NoOfWords - 1) ) THEN
+ PrintMemoryMessage (MsgVDM, ErrLdAddrRng,
+ "[Address,lineno]=", Address, LineNo) ;
+ EXIT ;
+ END IF;
+ -- Now strip off spaces, between Address string and DataInBus string.
+ WHILE (OneLine'LENGTH /= 0 AND IsSpace(OneLine(1))) LOOP
+ READ (OneLine, Ignore) ; -- Ignoring the space character.
+ END LOOP ;
+ Index := 1;
+ WHILE (OneLine'LENGTH /= 0 AND (NOT(IsSpace(OneLine(1))))) LOOP
+ READ(OneLine, DataInStr(Index));
+ Index := Index + 1;
+ END LOOP ;
+ DataInStr(Index) := NUL;
+ IF (BinaryFile) THEN
+ DataInBus := BinToBitv (DataInStr);
+ ELSE
+ DataInBus := HexToBitv (DataInStr);
+ END IF ;
+ WriteMemory (MemoryPtr, DataInBus, Address);
+ END LOOP ;
+END LoadMemory;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: MemoryMatch
+-- Parameters: Symbol - Symbol from memory table
+-- TestFlag - Interpreted data or address symbol
+-- In2 - input from VitalMemoryTable procedure
+-- to memory table
+-- In2LastValue - Previous value of input
+-- Err - TRUE if symbol is not a valid input symbol
+-- ReturnValue - TRUE if match occurred
+-- Description: This procedure sets ReturnValue to true if in2 matches
+-- symbol (from the memory table). If symbol is an edge
+-- value edge is set to true and in2 and in2LastValue are
+-- checked against symbol. Err is set to true if symbol
+-- is an invalid value for the input portion of the memory
+-- table.
+-- ----------------------------------------------------------------------------
+PROCEDURE MemoryMatch (
+ CONSTANT Symbol : IN VitalMemorySymbolType;
+ CONSTANT In2 : IN std_ulogic;
+ CONSTANT In2LastValue : IN std_ulogic;
+ VARIABLE Err : OUT BOOLEAN;
+ VARIABLE ReturnValue : OUT BOOLEAN
+) IS
+BEGIN
+ IF (NOT ValidMemoryTableInput(Symbol) ) THEN
+ PrintMemoryMessage(MsgVMT,ErrUnknSymbol,To_MemoryChar(Symbol));
+ Err := TRUE;
+ ReturnValue := FALSE;
+ ELSE
+ ReturnValue := MemoryTableMatch(To_X01(In2LastValue), To_X01(In2), Symbol);
+ Err := FALSE;
+ END IF;
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE MemoryMatch (
+ CONSTANT Symbol : IN VitalMemorySymbolType;
+ CONSTANT TestFlag : IN VitalMemorySymbolType;
+ VARIABLE Err : OUT BOOLEAN;
+ VARIABLE ReturnValue : OUT BOOLEAN
+) IS
+BEGIN
+ Err := FALSE;
+ ReturnValue := FALSE;
+ CASE Symbol IS
+ WHEN 'g'|'u'|'i'|'G'|'U'|'I'|'-'|'*'|'S' =>
+ IF (Symbol = TestFlag) THEN
+ ReturnValue := TRUE;
+ ELSE
+ CASE Symbol IS
+ WHEN '-' =>
+ ReturnValue := TRUE;
+ Err := FALSE;
+ WHEN '*' =>
+ IF (TestFlag = 'G' OR
+ TestFlag = 'U' OR
+ TestFlag = 'I') THEN
+ ReturnValue := TRUE;
+ Err := FALSE;
+ END IF;
+ WHEN 'S' =>
+ IF (TestFlag = 'g' OR
+ TestFlag = 'u' OR
+ TestFlag = 'i') THEN
+ ReturnValue := TRUE;
+ Err := FALSE;
+ END IF;
+ WHEN OTHERS =>
+ ReturnValue := FALSE;
+ END CASE;
+ END IF;
+ WHEN OTHERS =>
+ Err := TRUE;
+ RETURN;
+ END CASE;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: MemoryTableCorruptMask
+-- Description: Compute memory and data corruption masks for memory table
+-- ----------------------------------------------------------------------------
+PROCEDURE MemoryTableCorruptMask (
+ VARIABLE CorruptMask : OUT std_logic_vector;
+ CONSTANT Action : IN VitalMemorySymbolType;
+ CONSTANT EnableIndex : IN INTEGER;
+ CONSTANT BitsPerWord : IN INTEGER;
+ CONSTANT BitsPerSubWord : IN INTEGER;
+ CONSTANT BitsPerEnable : IN INTEGER
+) IS
+ VARIABLE CorruptMaskTmp : std_logic_vector (CorruptMask'RANGE)
+ := (OTHERS => '0');
+ VARIABLE ViolFlAryPosn : INTEGER;
+ VARIABLE HighBit : INTEGER;
+ VARIABLE LowBit : INTEGER;
+BEGIN
+ CASE (Action) IS
+ WHEN 'c'|'l'|'e' =>
+ -- Corrupt whole word
+ CorruptMaskTmp := (OTHERS => 'X');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ WHEN 'd'|'C'|'L'|'D'|'E' =>
+ -- Process corruption below
+ WHEN OTHERS =>
+ -- No data or memory corruption
+ CorruptMaskTmp := (OTHERS => '0');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ END CASE;
+ IF (Action = 'd') THEN
+ CorruptMaskTmp := (OTHERS => 'X');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ END IF;
+ -- Remaining are subword cases 'C', 'L', 'D', 'E'
+ CorruptMaskTmp := (OTHERS => '0');
+ LowBit := 0;
+ HighBit := BitsPerSubWord-1;
+ SubWordLoop:
+ FOR i IN 0 TO BitsPerEnable-1 LOOP
+ IF (i = EnableIndex) THEN
+ FOR j IN HighBit TO LowBit LOOP
+ CorruptMaskTmp(j) := 'X';
+ END LOOP;
+ END IF;
+ -- Calculate HighBit and LowBit
+ LowBit := LowBit + BitsPerSubWord;
+ IF (LowBit > BitsPerWord) THEN
+ LowBit := BitsPerWord;
+ END IF;
+ HighBit := LowBit + BitsPerSubWord;
+ IF (HighBit > BitsPerWord) THEN
+ HighBit := BitsPerWord;
+ ELSE
+ HighBit := HighBit - 1;
+ END IF;
+ END LOOP;
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE MemoryTableCorruptMask (
+ VARIABLE CorruptMask : OUT std_logic_vector;
+ CONSTANT Action : IN VitalMemorySymbolType
+) IS
+ VARIABLE CorruptMaskTmp : std_logic_vector (0 TO CorruptMask'LENGTH-1)
+ := (OTHERS => '0');
+ VARIABLE ViolFlAryPosn : INTEGER;
+ VARIABLE HighBit : INTEGER;
+ VARIABLE LowBit : INTEGER;
+BEGIN
+ CASE (Action) IS
+ WHEN 'c'|'l'|'d'|'e'|'C'|'L'|'D'|'E' =>
+ -- Corrupt whole word
+ CorruptMaskTmp := (OTHERS => 'X');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ WHEN OTHERS =>
+ -- No data or memory corruption
+ CorruptMaskTmp := (OTHERS => '0');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ END CASE;
+ RETURN;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: MemoryTableCorruptMask
+-- Description: Compute memory and data corruption masks for violation table
+-- ----------------------------------------------------------------------------
+PROCEDURE ViolationTableCorruptMask (
+ VARIABLE CorruptMask : OUT std_logic_vector;
+ CONSTANT Action : IN VitalMemorySymbolType;
+ CONSTANT ViolationFlags : IN std_logic_vector;
+ CONSTANT ViolationFlagsArray : IN std_logic_vector;
+ CONSTANT ViolationSizesArray : IN VitalMemoryViolFlagSizeType;
+ CONSTANT ViolationTable : IN VitalMemoryTableType;
+ CONSTANT TableIndex : IN INTEGER;
+ CONSTANT BitsPerWord : IN INTEGER;
+ CONSTANT BitsPerSubWord : IN INTEGER;
+ CONSTANT BitsPerEnable : IN INTEGER
+) IS
+ VARIABLE CorruptMaskTmp : std_logic_vector (CorruptMask'RANGE)
+ := (OTHERS => '0');
+ VARIABLE ViolMaskTmp : std_logic_vector (CorruptMask'RANGE)
+ := (OTHERS => '0');
+ VARIABLE ViolFlAryPosn : INTEGER;
+ VARIABLE HighBit : INTEGER;
+ VARIABLE LowBit : INTEGER;
+ CONSTANT ViolFlagsSize : INTEGER := ViolationFlags'LENGTH;
+ CONSTANT ViolFlArySize : INTEGER := ViolationFlagsArray'LENGTH;
+ CONSTANT TableEntries : INTEGER := ViolationTable'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := ViolationTable'LENGTH(2);
+ CONSTANT DatActionNdx : INTEGER := TableWidth - 1;
+ CONSTANT MemActionNdx : INTEGER := TableWidth - 2;
+BEGIN
+ CASE (Action) IS
+ WHEN 'c'|'l'|'e' =>
+ -- Corrupt whole word
+ CorruptMaskTmp := (OTHERS => 'X');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ WHEN 'd'|'C'|'L'|'D'|'E' =>
+ -- Process corruption below
+ WHEN OTHERS =>
+ -- No data or memory corruption
+ CorruptMaskTmp := (OTHERS => '0');
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+ END CASE;
+ RowLoop: -- Check each element of the ViolationFlags
+ FOR j IN 0 TO ViolFlagsSize LOOP
+ IF (j = ViolFlagsSize) THEN
+ ViolFlAryPosn := 0;
+ RowLoop2: -- Check relevant elements of the ViolationFlagsArray
+ FOR k IN 0 TO MemActionNdx - ViolFlagsSize - 1 LOOP
+ IF (ViolationTable(TableIndex, k + ViolFlagsSize) = 'X') THEN
+ MaskLoop: -- Set the 'X' bits in the violation mask
+ FOR m IN INTEGER RANGE 0 TO CorruptMask'LENGTH-1 LOOP
+ IF (m <= ViolationSizesArray(k)-1) THEN
+ ViolMaskTmp(m) := ViolMaskTmp(m) XOR
+ ViolationFlagsArray(ViolFlAryPosn+m);
+ ELSE
+ EXIT MaskLoop;
+ END IF;
+ END LOOP;
+ END IF;
+ ViolFlAryPosn := ViolFlAryPosn + ViolationSizesArray(k);
+ END LOOP;
+ ELSE
+ IF (ViolationTable(TableIndex, j) = 'X') THEN
+ ViolMaskTmp(0) := ViolMaskTmp(0) XOR ViolationFlags(j);
+ END IF;
+ END IF;
+ END LOOP;
+ IF (Action = 'd') THEN
+ CorruptMask := ViolMaskTmp;
+ RETURN;
+ END IF;
+ -- Remaining are subword cases 'C', 'L', 'D', 'E'
+ CorruptMaskTmp := (OTHERS => '0');
+ LowBit := 0;
+ HighBit := BitsPerSubWord-1;
+ SubWordLoop:
+ FOR i IN 0 TO BitsPerEnable-1 LOOP
+ IF (ViolMaskTmp(i) = 'X') THEN
+ FOR j IN HighBit TO LowBit LOOP
+ CorruptMaskTmp(j) := 'X';
+ END LOOP;
+ END IF;
+ -- Calculate HighBit and LowBit
+ LowBit := LowBit + BitsPerSubWord;
+ IF (LowBit > BitsPerWord) THEN
+ LowBit := BitsPerWord;
+ END IF;
+ HighBit := LowBit + BitsPerSubWord;
+ IF (HighBit > BitsPerWord) THEN
+ HighBit := BitsPerWord;
+ ELSE
+ HighBit := HighBit - 1;
+ END IF;
+ END LOOP;
+ CorruptMask := CorruptMaskTmp;
+ RETURN;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: MemoryTableLookUp
+-- Parameters: MemoryAction - Output memory action to be performed
+-- DataAction - Output data action to be performed
+-- PrevControls - Previous data in for edge detection
+-- PrevEnableBus - Previous enables for edge detection
+-- Controls - Agregate of scalar control lines
+-- EnableBus - Concatenation of vector control lines
+-- EnableIndex - Current slice of vector control lines
+-- AddrFlag - Matching symbol from address decoding
+-- DataFlag - Matching symbol from data decoding
+-- MemoryTable - Input memory action table
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control message output
+--
+-- Description: This function is used to find the output of the
+-- MemoryTable corresponding to a given set of inputs.
+--
+-- ----------------------------------------------------------------------------
+PROCEDURE MemoryTableLookUp (
+ VARIABLE MemoryAction : OUT VitalMemorySymbolType;
+ VARIABLE DataAction : OUT VitalMemorySymbolType;
+ VARIABLE MemoryCorruptMask : OUT std_logic_vector;
+ VARIABLE DataCorruptMask : OUT std_logic_vector;
+ CONSTANT PrevControls : IN std_logic_vector;
+ CONSTANT Controls : IN std_logic_vector;
+ CONSTANT AddrFlag : IN VitalMemorySymbolType;
+ CONSTANT DataFlag : IN VitalMemorySymbolType;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+ CONSTANT ControlsSize : INTEGER := Controls'LENGTH;
+ CONSTANT TableEntries : INTEGER := MemoryTable'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := MemoryTable'LENGTH(2);
+ CONSTANT DatActionNdx : INTEGER := TableWidth - 1;
+ CONSTANT MemActionNdx : INTEGER := TableWidth - 2;
+ CONSTANT DataInBusNdx : INTEGER := TableWidth - 3;
+ CONSTANT AddressBusNdx : INTEGER := TableWidth - 4;
+ VARIABLE AddrFlagTable : VitalMemorySymbolType;
+ VARIABLE Match : BOOLEAN;
+ VARIABLE Err : BOOLEAN := FALSE;
+ VARIABLE TableAlias : VitalMemoryTableType(
+ 0 TO TableEntries - 1,
+ 0 TO TableWidth - 1)
+ := MemoryTable;
+BEGIN
+ ColLoop: -- Compare each entry in the table
+ FOR i IN TableAlias'RANGE(1) LOOP
+ RowLoop: -- Check each element of the Controls
+ FOR j IN 0 TO ControlsSize LOOP
+ IF (j = ControlsSize) THEN
+ -- a match occurred, now check AddrFlag, DataFlag
+ MemoryMatch(TableAlias(i,AddressBusNdx),AddrFlag,Err,Match);
+ IF (Match) THEN
+ MemoryMatch(TableAlias(i,DataInBusNdx),DataFlag,Err,Match);
+ IF (Match) THEN
+ MemoryTableCorruptMask (
+ CorruptMask => MemoryCorruptMask ,
+ Action => TableAlias(i, MemActionNdx)
+ );
+ MemoryTableCorruptMask (
+ CorruptMask => DataCorruptMask ,
+ Action => TableAlias(i, DatActionNdx)
+ );
+ -- get the return memory and data actions
+ MemoryAction := TableAlias(i, MemActionNdx);
+ DataAction := TableAlias(i, DatActionNdx);
+ -- DEBUG: The lines below report table search
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMT,TableAlias,i,PortName);
+ END IF;
+ -- DEBUG: The lines above report table search
+ RETURN;
+ END IF;
+ END IF;
+ ELSE
+ -- Match memory table inputs
+ MemoryMatch ( TableAlias(i,j),
+ Controls(j), PrevControls(j),
+ Err, Match);
+ END IF;
+ EXIT RowLoop WHEN NOT(Match);
+ EXIT ColLoop WHEN Err;
+ END LOOP RowLoop;
+ END LOOP ColLoop;
+ -- no match found, return default action
+ MemoryAction := 's'; -- no change to memory
+ DataAction := 'S'; -- no change to dataout
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMT,ErrDefMemAct,HeaderMsg,PortName);
+ END IF;
+ RETURN;
+END;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE MemoryTableLookUp (
+ VARIABLE MemoryAction : OUT VitalMemorySymbolType;
+ VARIABLE DataAction : OUT VitalMemorySymbolType;
+ VARIABLE MemoryCorruptMask : OUT std_logic_vector;
+ VARIABLE DataCorruptMask : OUT std_logic_vector;
+ CONSTANT PrevControls : IN std_logic_vector;
+ CONSTANT PrevEnableBus : IN std_logic_vector;
+ CONSTANT Controls : IN std_logic_vector;
+ CONSTANT EnableBus : IN std_logic_vector;
+ CONSTANT EnableIndex : IN INTEGER;
+ CONSTANT BitsPerWord : IN INTEGER;
+ CONSTANT BitsPerSubWord : IN INTEGER;
+ CONSTANT BitsPerEnable : IN INTEGER;
+ CONSTANT AddrFlag : IN VitalMemorySymbolType;
+ CONSTANT DataFlag : IN VitalMemorySymbolType;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+ CONSTANT ControlsSize : INTEGER := Controls'LENGTH;
+ CONSTANT TableEntries : INTEGER := MemoryTable'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := MemoryTable'LENGTH(2);
+ CONSTANT DatActionNdx : INTEGER := TableWidth - 1;
+ CONSTANT MemActionNdx : INTEGER := TableWidth - 2;
+ CONSTANT DataInBusNdx : INTEGER := TableWidth - 3;
+ CONSTANT AddressBusNdx : INTEGER := TableWidth - 4;
+ VARIABLE AddrFlagTable : VitalMemorySymbolType;
+ VARIABLE Match : BOOLEAN;
+ VARIABLE Err : BOOLEAN := FALSE;
+ VARIABLE TableAlias : VitalMemoryTableType(
+ 0 TO TableEntries - 1,
+ 0 TO TableWidth - 1)
+ := MemoryTable;
+BEGIN
+ ColLoop: -- Compare each entry in the table
+ FOR i IN TableAlias'RANGE(1) LOOP
+ RowLoop: -- Check each element of the Controls
+ FOR j IN 0 TO ControlsSize LOOP
+ IF (j = ControlsSize) THEN
+ -- a match occurred, now check EnableBus, AddrFlag, DataFlag
+ IF (EnableIndex >= 0) THEN
+ RowLoop2: -- Check relevant elements of the EnableBus
+ FOR k IN 0 TO AddressBusNdx - ControlsSize - 1 LOOP
+ MemoryMatch ( TableAlias(i,k + ControlsSize),
+ EnableBus(k * BitsPerEnable + EnableIndex),
+ PrevEnableBus(k * BitsPerEnable + EnableIndex),
+ Err, Match);
+ EXIT RowLoop2 WHEN NOT(Match);
+ END LOOP;
+ END IF;
+ IF (Match) THEN
+ MemoryMatch(TableAlias(i,AddressBusNdx),AddrFlag,Err,Match);
+ IF (Match) THEN
+ MemoryMatch(TableAlias(i,DataInBusNdx),DataFlag,Err,Match);
+ IF (Match) THEN
+ MemoryTableCorruptMask (
+ CorruptMask => MemoryCorruptMask ,
+ Action => TableAlias(i, MemActionNdx),
+ EnableIndex => EnableIndex ,
+ BitsPerWord => BitsPerWord ,
+ BitsPerSubWord => BitsPerSubWord ,
+ BitsPerEnable => BitsPerEnable
+ );
+ MemoryTableCorruptMask (
+ CorruptMask => DataCorruptMask ,
+ Action => TableAlias(i, DatActionNdx),
+ EnableIndex => EnableIndex ,
+ BitsPerWord => BitsPerWord ,
+ BitsPerSubWord => BitsPerSubWord ,
+ BitsPerEnable => BitsPerEnable
+ );
+ -- get the return memory and data actions
+ MemoryAction := TableAlias(i, MemActionNdx);
+ DataAction := TableAlias(i, DatActionNdx);
+ -- DEBUG: The lines below report table search
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMT,TableAlias,i,PortName);
+ END IF;
+ -- DEBUG: The lines above report table search
+ RETURN;
+ END IF;
+ END IF;
+ END IF;
+ ELSE
+ -- Match memory table inputs
+ MemoryMatch ( TableAlias(i,j),
+ Controls(j), PrevControls(j),
+ Err, Match);
+ END IF;
+ EXIT RowLoop WHEN NOT(Match);
+ EXIT ColLoop WHEN Err;
+ END LOOP RowLoop;
+ END LOOP ColLoop;
+ -- no match found, return default action
+ MemoryAction := 's'; -- no change to memory
+ DataAction := 'S'; -- no change to dataout
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMT,ErrDefMemAct,HeaderMsg,PortName);
+ END IF;
+ RETURN;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: ViolationTableLookUp
+-- Parameters: MemoryAction - Output memory action to be performed
+-- DataAction - Output data action to be performed
+-- TimingDataArray - This is currently not used (comment out)
+-- ViolationArray - Aggregation of violation variables
+-- ViolationTable - Input memory violation table
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control message output
+-- Description: This function is used to find the output of the
+-- ViolationTable corresponding to a given set of inputs.
+-- ----------------------------------------------------------------------------
+PROCEDURE ViolationTableLookUp (
+ VARIABLE MemoryAction : OUT VitalMemorySymbolType;
+ VARIABLE DataAction : OUT VitalMemorySymbolType;
+ VARIABLE MemoryCorruptMask : OUT std_logic_vector;
+ VARIABLE DataCorruptMask : OUT std_logic_vector;
+ CONSTANT ViolationFlags : IN std_logic_vector;
+ CONSTANT ViolationFlagsArray : IN std_logic_vector;
+ CONSTANT ViolationSizesArray : IN VitalMemoryViolFlagSizeType;
+ CONSTANT ViolationTable : IN VitalMemoryTableType;
+ CONSTANT BitsPerWord : IN INTEGER;
+ CONSTANT BitsPerSubWord : IN INTEGER;
+ CONSTANT BitsPerEnable : IN INTEGER;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+ CONSTANT ViolFlagsSize : INTEGER := ViolationFlags'LENGTH;
+ CONSTANT ViolFlArySize : INTEGER := ViolationFlagsArray'LENGTH;
+ VARIABLE ViolFlAryPosn : INTEGER;
+ VARIABLE ViolFlAryItem : std_ulogic;
+ CONSTANT ViolSzArySize : INTEGER := ViolationSizesArray'LENGTH;
+ CONSTANT TableEntries : INTEGER := ViolationTable'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := ViolationTable'LENGTH(2);
+ CONSTANT DatActionNdx : INTEGER := TableWidth - 1;
+ CONSTANT MemActionNdx : INTEGER := TableWidth - 2;
+ VARIABLE HighBit : NATURAL := 0;
+ VARIABLE LowBit : NATURAL := 0;
+ VARIABLE Match : BOOLEAN;
+ VARIABLE Err : BOOLEAN := FALSE;
+ VARIABLE TableAlias : VitalMemoryTableType(
+ 0 TO TableEntries - 1,
+ 0 TO TableWidth - 1)
+ := ViolationTable;
+BEGIN
+ ColLoop: -- Compare each entry in the table
+ FOR i IN TableAlias'RANGE(1) LOOP
+ RowLoop: -- Check each element of the ViolationFlags
+ FOR j IN 0 TO ViolFlagsSize LOOP
+ IF (j = ViolFlagsSize) THEN
+ ViolFlAryPosn := 0;
+ RowLoop2: -- Check relevant elements of the ViolationFlagsArray
+ FOR k IN 0 TO MemActionNdx - ViolFlagsSize - 1 LOOP
+ ViolFlAryItem := '0';
+ SubwordLoop: -- Check for 'X' in ViolationFlagsArray chunk
+ FOR s IN ViolFlAryPosn TO ViolFlAryPosn+ViolationSizesArray(k)-1 LOOP
+ IF (ViolationFlagsArray(s) = 'X') THEN
+ ViolFlAryItem := 'X';
+ EXIT SubwordLoop;
+ END IF;
+ END LOOP;
+ MemoryMatch ( TableAlias(i,k + ViolFlagsSize),
+ ViolFlAryItem,ViolFlAryItem,
+ Err, Match);
+ ViolFlAryPosn := ViolFlAryPosn + ViolationSizesArray(k);
+ EXIT RowLoop2 WHEN NOT(Match);
+ END LOOP;
+ IF (Match) THEN
+ -- Compute memory and data corruption masks
+ ViolationTableCorruptMask(
+ CorruptMask => MemoryCorruptMask ,
+ Action => TableAlias(i, MemActionNdx),
+ ViolationFlags => ViolationFlags ,
+ ViolationFlagsArray => ViolationFlagsArray ,
+ ViolationSizesArray => ViolationSizesArray ,
+ ViolationTable => ViolationTable ,
+ TableIndex => i ,
+ BitsPerWord => BitsPerWord ,
+ BitsPerSubWord => BitsPerSubWord ,
+ BitsPerEnable => BitsPerEnable
+ );
+ ViolationTableCorruptMask(
+ CorruptMask => DataCorruptMask ,
+ Action => TableAlias(i, DatActionNdx),
+ ViolationFlags => ViolationFlags ,
+ ViolationFlagsArray => ViolationFlagsArray ,
+ ViolationSizesArray => ViolationSizesArray ,
+ ViolationTable => ViolationTable ,
+ TableIndex => i ,
+ BitsPerWord => BitsPerWord ,
+ BitsPerSubWord => BitsPerSubWord ,
+ BitsPerEnable => BitsPerEnable
+ );
+ -- get the return memory and data actions
+ MemoryAction := TableAlias(i, MemActionNdx);
+ DataAction := TableAlias(i, DatActionNdx);
+ -- DEBUG: The lines below report table search
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMV,TableAlias,i,PortName);
+ END IF;
+ -- DEBUG: The lines above report table search
+ RETURN;
+ END IF;
+ ELSE
+ -- Match violation table inputs
+ Err := FALSE;
+ Match := FALSE;
+ IF (TableAlias(i,j) /= 'X' AND
+ TableAlias(i,j) /= '0' AND
+ TableAlias(i,j) /= '-') THEN
+ Err := TRUE;
+ ELSIF (TableAlias(i,j) = '-' OR
+ (TableAlias(i,j) = 'X' AND ViolationFlags(j) = 'X') OR
+ (TableAlias(i,j) = '0' AND ViolationFlags(j) = '0')) THEN
+ Match := TRUE;
+ END IF;
+ END IF;
+ EXIT RowLoop WHEN NOT(Match);
+ EXIT ColLoop WHEN Err;
+ END LOOP RowLoop;
+ END LOOP ColLoop;
+ -- no match found, return default action
+ MemoryAction := 's'; -- no change to memory
+ DataAction := 'S'; -- no change to dataout
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMV,ErrDefMemAct,HeaderMsg,PortName);
+ END IF;
+ RETURN;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: HandleMemoryAction
+-- Parameters: MemoryData - Pointer to memory data structure
+-- PortFlag - Indicates read/write mode of port
+-- CorruptMask - XOR'ed with DataInBus when corrupting
+-- DataInBus - Current data bus in
+-- Address - Current address integer
+-- HighBit - Current address high bit
+-- LowBit - Current address low bit
+-- MemoryTable - Input memory action table
+-- MemoryAction - Memory action to be performed
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control message output
+-- Description: This procedure performs the specified memory action on
+-- the input memory data structure.
+-- ----------------------------------------------------------------------------
+PROCEDURE HandleMemoryAction (
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PortFlag : INOUT VitalPortFlagType;
+ CONSTANT CorruptMask : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT Address : IN INTEGER;
+ CONSTANT HighBit : IN NATURAL;
+ CONSTANT LowBit : IN NATURAL;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT MemoryAction : IN VitalMemorySymbolType;
+ CONSTANT CallerName : IN STRING;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+ VARIABLE DataInTmp : std_logic_vector(DataInBus'RANGE)
+ := DataInBus;
+ BEGIN
+
+ -- Handle the memory action
+ CASE MemoryAction IS
+
+ WHEN 'w' =>
+ -- Writing data to memory
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrWrDatMem,HeaderMsg,PortName);
+ END IF;
+ WriteMemory(MemoryData,DataInBus,Address,HighBit,LowBit);
+ PortFlag.MemoryCurrent := WRITE;
+
+ WHEN 's' =>
+ -- Retaining previous memory contents
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrNoChgMem,HeaderMsg,PortName);
+ END IF;
+ -- Set memory current to quiet state
+ PortFlag.MemoryCurrent := READ;
+
+ WHEN 'c' =>
+ -- Corrupting entire memory with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrAllMem,HeaderMsg,PortName);
+ END IF;
+ DataInTmp := (OTHERS => 'X');
+ -- No need to CorruptMask
+ FOR i IN 0 TO MemoryData.NoOfWords-1 LOOP
+ WriteMemory(MemoryData,DataInTmp,i);
+ END LOOP;
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'l' =>
+ -- Corrupting a word in memory with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrWrdMem,HeaderMsg,PortName);
+ END IF;
+ DataInTmp := (OTHERS => 'X');
+ -- No need to CorruptMask
+ WriteMemory(MemoryData,DataInTmp,Address);
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'd' =>
+ -- Corrupting a single bit in memory with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrBitMem,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataInTmp,Address);
+ DataInTmp := DataInTmp XOR CorruptMask;
+ WriteMemory(MemoryData,DataInTmp,Address,HighBit,LowBit);
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'e' =>
+ -- Corrupting a word with 'X' based on data in
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrDatMem,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataInTmp,Address);
+ IF (DataInTmp /= DataInBus) THEN
+ DataInTmp := (OTHERS => 'X');
+ -- No need to CorruptMask
+ WriteMemory(MemoryData,DataInTmp,Address);
+ END IF;
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'C' =>
+ -- Corrupting a sub-word entire memory with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrAllSubMem,HeaderMsg,PortName);
+ END IF;
+ FOR i IN 0 TO MemoryData.NoOfWords-1 LOOP
+ ReadMemory(MemoryData,DataInTmp,i);
+ DataInTmp := DataInTmp XOR CorruptMask;
+ WriteMemory(MemoryData,DataInTmp,i,HighBit,LowBit);
+ END LOOP;
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'L' =>
+ -- Corrupting a sub-word in memory with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrWrdSubMem,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataInTmp,Address);
+ DataInTmp := DataInTmp XOR CorruptMask;
+ WriteMemory(MemoryData,DataInTmp,Address,HighBit,LowBit);
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'D' =>
+ -- Corrupting a single bit of a memory sub-word with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrBitSubMem,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataInTmp,Address);
+ DataInTmp := DataInTmp XOR CorruptMask;
+ WriteMemory(MemoryData,DataInTmp,Address,HighBit,LowBit);
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN 'E' =>
+ -- Corrupting a sub-word with 'X' based on data in
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrDatSubMem,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataInTmp,Address);
+ IF (DataInBus(HighBit DOWNTO LowBit) /=
+ DataInTmp(HighBit DOWNTO LowBit)) THEN
+ DataInTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X');
+ WriteMemory(MemoryData,DataInTmp,Address,HighBit,LowBit);
+ END IF;
+ --PortFlag := WRITE;
+ PortFlag.MemoryCurrent := CORRUPT;
+
+ WHEN '0' =>
+ -- Assigning low level to memory location
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsg0Mem,HeaderMsg,PortName);
+ END IF;
+ DataInTmp := (OTHERS => '0');
+ WriteMemory(MemoryData,DataInTmp,Address, HighBit, LowBit);
+ PortFlag.MemoryCurrent := WRITE;
+
+ WHEN '1' =>
+ -- Assigning high level to memory location
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsg1Mem,HeaderMsg,PortName);
+ END IF;
+ DataInTmp := (OTHERS => '1');
+ WriteMemory(MemoryData,DataInTmp,Address, HighBit, LowBit);
+ PortFlag.MemoryCurrent := WRITE;
+
+ WHEN 'Z' =>
+ -- Assigning high impedence to memory location
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsgZMem,HeaderMsg,PortName);
+ END IF;
+ DataInTmp := (OTHERS => 'Z');
+ WriteMemory(MemoryData,DataInTmp,Address, HighBit, LowBit);
+ PortFlag.MemoryCurrent := WRITE;
+
+ WHEN OTHERS =>
+ -- Unknown memory action
+ PortFlag.MemoryCurrent := UNDEF;
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrUnknMemDo,HeaderMsg,PortName);
+ END IF;
+
+ END CASE;
+
+ -- Note: HandleMemoryAction does not change the PortFlag.OutputDisable
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: HandleDataAction
+-- Parameters: DataOutBus - Output result of the data action
+-- MemoryData - Input pointer to memory data structure
+-- PortFlag - Indicates read/write mode of port
+-- CorruptMask - XOR'ed with DataInBus when corrupting
+-- DataInBus - Current data bus in
+-- Address - Current address integer
+-- HighBit - Current address high bit
+-- LowBit - Current address low bit
+-- MemoryTable - Input memory action table
+-- DataAction - Data action to be performed
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control message output
+-- Description: This procedure performs the specified data action based
+-- on the input memory data structure. Checks whether
+-- the previous state is HighZ. If yes then portFlag
+-- should be NOCHANGE for VMPD to ignore IORetain
+-- corruption. The idea is that the first Z should be
+-- propagated but later ones should be ignored.
+-- ----------------------------------------------------------------------------
+PROCEDURE HandleDataAction (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PortFlag : INOUT VitalPortFlagType;
+ CONSTANT CorruptMask : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT Address : IN INTEGER;
+ CONSTANT HighBit : IN NATURAL;
+ CONSTANT LowBit : IN NATURAL;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT DataAction : IN VitalMemorySymbolType;
+ CONSTANT CallerName : IN STRING;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+
+ VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE)
+ := DataOutBus;
+
+BEGIN
+
+ -- Handle the data action
+ CASE DataAction IS
+
+ WHEN 'l' =>
+ -- Corrupting data out with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrWrdOut,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp := (OTHERS => 'X');
+ -- No need to CorruptMask
+ PortFlag.DataCurrent := CORRUPT;
+
+ WHEN 'd' =>
+ -- Corrupting a single bit of data out with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrBitOut,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp(HighBit DOWNTO LowBit) :=
+ DataOutTmp(HighBit DOWNTO LowBit) XOR
+ CorruptMask(HighBit DOWNTO LowBit);
+ PortFlag.DataCurrent := CORRUPT;
+
+ WHEN 'e' =>
+ -- Corrupting data out with 'X' based on data in
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrDatOut,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataOutTmp,Address);
+ IF (DataOutTmp /= DataInBus) THEN
+ DataOutTmp := (OTHERS => 'X');
+ -- No need to CorruptMask
+ END IF;
+ PortFlag.DataCurrent := CORRUPT;
+
+ WHEN 'L' =>
+ -- Corrupting data out sub-word with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrWrdSubOut,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataOutTmp,Address);
+ DataOutTmp(HighBit DOWNTO LowBit) :=
+ DataOutTmp(HighBit DOWNTO LowBit) XOR
+ CorruptMask(HighBit DOWNTO LowBit);
+ PortFlag.DataCurrent := CORRUPT;
+
+ WHEN 'D' =>
+ -- Corrupting a single bit of data out sub-word with 'X'
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrBitSubOut,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp(HighBit DOWNTO LowBit) :=
+ DataOutTmp(HighBit DOWNTO LowBit) XOR
+ CorruptMask(HighBit DOWNTO LowBit);
+ PortFlag.DataCurrent := CORRUPT;
+
+ WHEN 'E' =>
+ -- Corrupting data out sub-word with 'X' based on data in
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrCrDatSubOut,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataOutTmp,Address);
+ IF (DataInBus(HighBit DOWNTO LowBit) /=
+ DataOutTmp(HighBit DOWNTO LowBit)) THEN
+ DataOutTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X');
+ -- No need to CorruptMask
+ END IF;
+ PortFlag.DataCurrent := CORRUPT;
+
+ WHEN 'M' =>
+ -- Implicit read from memory to data out
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrImplOut,HeaderMsg,PortName);
+ END IF;
+ PortFlag.DataCurrent := READ;
+
+ WHEN 'm' =>
+ -- Reading data from memory to data out
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrReadOut,HeaderMsg,PortName);
+ END IF;
+ ReadMemory(MemoryData,DataOutTmp,Address);
+ PortFlag.DataCurrent := READ;
+
+ WHEN 't' =>
+ -- Transfering from data in to data out
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAssgOut,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp := DataInBus;
+ PortFlag.DataCurrent := READ;
+
+ WHEN '0' =>
+ -- Assigning low level to data out
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsg0Out,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp := (OTHERS => '0');
+ PortFlag.DataCurrent := READ;
+
+ WHEN '1' =>
+ -- Assigning high level to data out
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsg1Out,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp := (OTHERS => '1');
+ PortFlag.DataCurrent := READ;
+
+ WHEN 'Z' =>
+ -- Assigning high impedence to data out
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsgZOut,HeaderMsg,PortName);
+ END IF;
+ DataOutTmp := (OTHERS => 'Z');
+ PortFlag.DataCurrent := HIGHZ;
+
+ WHEN 'S' =>
+ -- Keeping data out at steady value
+ PortFlag.OutputDisable := TRUE;
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrAsgSOut,HeaderMsg,PortName);
+ END IF;
+
+ WHEN OTHERS =>
+ -- Unknown data action
+ PortFlag.DataCurrent := UNDEF;
+ IF (MsgOn) THEN
+ PrintMemoryMessage(CallerName,ErrUnknDatDo,HeaderMsg,PortName);
+ END IF;
+
+ END CASE;
+
+ DataOutBus(HighBit DOWNTO LowBit) := DataOutTmp(HighBit DOWNTO LowBit);
+
+END;
+
+
+-- ----------------------------------------------------------------------------
+-- Memory Table Modeling Primitives
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalDeclareMemory
+-- Parameters: NoOfWords - Number of words in the memory
+-- NoOfBitsPerWord - Number of bits per word in memory
+-- NoOfBitsPerSubWord - Number of bits per sub word
+-- MemoryLoadFile - Name of data file to load
+-- Description: This function is intended to be used to initialize
+-- memory data declarations, i.e. to be executed duing
+-- simulation elaboration time. Handles the allocation
+-- and initialization of memory for the memory data.
+-- Default NoOfBitsPerSubWord is NoOfBitsPerWord.
+-- ----------------------------------------------------------------------------
+IMPURE FUNCTION VitalDeclareMemory (
+ CONSTANT NoOfWords : IN POSITIVE;
+ CONSTANT NoOfBitsPerWord : IN POSITIVE;
+ CONSTANT MemoryLoadFile : IN string := "";
+ CONSTANT BinaryLoadFile : IN BOOLEAN := FALSE
+) RETURN VitalMemoryDataType IS
+ VARIABLE MemoryPtr : VitalMemoryDataType;
+BEGIN
+ MemoryPtr := VitalDeclareMemory(
+ NoOfWords => NoOfWords,
+ NoOfBitsPerWord => NoOfBitsPerWord,
+ NoOfBitsPerSubWord => NoOfBitsPerWord,
+ MemoryLoadFile => MemoryLoadFile,
+ BinaryLoadFile => BinaryLoadFile
+ );
+ RETURN MemoryPtr;
+END;
+
+-- ----------------------------------------------------------------------------
+IMPURE FUNCTION VitalDeclareMemory (
+ CONSTANT NoOfWords : IN POSITIVE;
+ CONSTANT NoOfBitsPerWord : IN POSITIVE;
+ CONSTANT NoOfBitsPerSubWord : IN POSITIVE;
+ CONSTANT MemoryLoadFile : IN string := "";
+ CONSTANT BinaryLoadFile : IN BOOLEAN := FALSE
+) RETURN VitalMemoryDataType IS
+ VARIABLE MemoryPtr : VitalMemoryDataType;
+ VARIABLE BitsPerEnable : NATURAL
+ := ((NoOfBitsPerWord-1)
+ /NoOfBitsPerSubWord)+1;
+BEGIN
+ PrintMemoryMessage(MsgVDM,ErrInitMem);
+ MemoryPtr := new VitalMemoryArrayRecType '(
+ NoOfWords => NoOfWords,
+ NoOfBitsPerWord => NoOfBitsPerWord,
+ NoOfBitsPerSubWord => NoOfBitsPerSubWord,
+ NoOfBitsPerEnable => BitsPerEnable,
+ MemoryArrayPtr => NULL
+ );
+ MemoryPtr.MemoryArrayPtr
+ := new MemoryArrayType (0 to MemoryPtr.NoOfWords - 1);
+ FOR i IN 0 TO MemoryPtr.NoOfWords - 1 LOOP
+ MemoryPtr.MemoryArrayPtr(i)
+ := new MemoryWordType (MemoryPtr.NoOfBitsPerWord - 1 DOWNTO 0);
+ END LOOP;
+ IF (MemoryLoadFile /= "") THEN
+ LoadMemory (MemoryPtr, MemoryLoadFile, BinaryLoadFile);
+ END IF;
+ RETURN MemoryPtr;
+END;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryTable
+-- Parameters: DataOutBus - Output candidate zero delay data bus out
+-- MemoryData - Pointer to memory data structure
+-- PrevControls - Previous data in for edge detection
+-- PrevEnableBus - Previous enables for edge detection
+-- PrevDataInBus - Previous data bus for edge detection
+-- PrevAddressBus - Previous address bus for edge detection
+-- PortFlag - Indicates port operating mode
+-- PortFlagArray - Vector form of PortFlag for sub-word
+-- Controls - Agregate of scalar control lines
+-- EnableBus - Concatenation of vector control lines
+-- DataInBus - Input value of data bus in
+-- AddressBus - Input value of address bus in
+-- AddressValue - Decoded value of the AddressBus
+-- MemoryTable - Input memory action table
+-- PortType - The type of port (currently not used)
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control the generation of messages
+-- MsgSeverity - Control level of message generation
+-- Description: This procedure implements the majority of the memory
+-- modeling functionality via lookup of the memory action
+-- tables and performing the specified actions if matches
+-- are found, or the default actions otherwise. The
+-- overloadings are provided for the word and sub-word
+-- (using the EnableBus and PortFlagArray arguments) addressing
+-- cases.
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryTable (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PrevControls : INOUT std_logic_vector;
+ VARIABLE PrevDataInBus : INOUT std_logic_vector;
+ VARIABLE PrevAddressBus : INOUT std_logic_vector;
+ VARIABLE PortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT Controls : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressBus : IN std_logic_vector;
+ VARIABLE AddressValue : INOUT VitalAddressValueType;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType := UNDEF;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+
+ VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE)
+ := DataOutBus;
+ VARIABLE MemoryAction : VitalMemorySymbolType;
+ VARIABLE DataAction : VitalMemorySymbolType;
+ VARIABLE HighBit : NATURAL := MemoryData.NoOfBitsPerWord-1;
+ VARIABLE LowBit : NATURAL := 0;
+ VARIABLE Address : INTEGER := 0;
+ VARIABLE PortFlagTmp : VitalPortFlagType;
+ VARIABLE AddrFlag : VitalMemorySymbolType := 'g'; -- good addr
+ VARIABLE DataFlag : VitalMemorySymbolType := 'g'; -- good data
+ VARIABLE MemCorruptMask : std_logic_vector (DataOutBus'RANGE);
+ VARIABLE DatCorruptMask : std_logic_vector (DataOutBus'RANGE);
+
+BEGIN
+
+ -- Optimize for case when all current inputs are same as previous
+ IF (PrevDataInBus = DataInBus
+ AND PrevAddressBus = AddressBus
+ AND PrevControls = Controls
+ AND PortFlag(0).MemoryCurrent = PortFlag(0).MemoryPrevious
+ AND PortFlag(0).DataCurrent = PortFlag(0).DataPrevious) THEN
+ PortFlag(0).OutputDisable := TRUE;
+ RETURN;
+ END IF;
+
+ PortFlag(0).DataPrevious := PortFlag(0).DataCurrent;
+ PortFlag(0).MemoryPrevious := PortFlag(0).MemoryCurrent;
+ PortFlag(0).OutputDisable := FALSE;
+ PortFlagTmp := PortFlag(0);
+
+ -- Convert address bus to integer value and table lookup flag
+ DecodeAddress(
+ Address => Address ,
+ AddrFlag => AddrFlag ,
+ MemoryData => MemoryData ,
+ PrevAddressBus => PrevAddressBus ,
+ AddressBus => AddressBus
+ );
+
+ -- Interpret data bus as a table lookup flag
+ DecodeData (
+ DataFlag => DataFlag ,
+ PrevDataInBus => PrevDataInBus ,
+ DataInBus => DataInBus ,
+ HighBit => HighBit ,
+ LowBit => LowBit
+ );
+
+ -- Lookup memory and data actions
+ MemoryTableLookUp(
+ MemoryAction => MemoryAction ,
+ DataAction => DataAction ,
+ MemoryCorruptMask => MemCorruptMask ,
+ DataCorruptMask => DatCorruptMask ,
+ PrevControls => PrevControls ,
+ Controls => Controls ,
+ AddrFlag => AddrFlag ,
+ DataFlag => DataFlag ,
+ MemoryTable => MemoryTable ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ -- Handle data action before memory action
+ -- This allows reading previous memory contents
+ HandleDataAction(
+ DataOutBus => DataOutTmp ,
+ MemoryData => MemoryData ,
+ PortFlag => PortFlagTmp ,
+ CorruptMask => DatCorruptMask ,
+ DataInBus => DataInBus ,
+ Address => Address ,
+ HighBit => HighBit ,
+ LowBit => LowBit ,
+ MemoryTable => MemoryTable ,
+ DataAction => DataAction ,
+ CallerName => MsgVMT ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ HandleMemoryAction(
+ MemoryData => MemoryData ,
+ PortFlag => PortFlagTmp ,
+ CorruptMask => MemCorruptMask ,
+ DataInBus => DataInBus ,
+ Address => Address ,
+ HighBit => HighBit ,
+ LowBit => LowBit ,
+ MemoryTable => MemoryTable ,
+ MemoryAction => MemoryAction ,
+ CallerName => MsgVMT ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ -- Set the output PortFlag(0) value
+ IF (DataAction = 'S') THEN
+ PortFlagTmp.OutputDisable := TRUE;
+ END IF;
+ IF (PortFlagTmp.DataCurrent = PortFlagTmp.DataPrevious
+ AND PortFlagTmp.DataCurrent = HIGHZ) THEN
+ PortFlagTmp.OutputDisable := TRUE;
+ END IF;
+ PortFlag(0) := PortFlagTmp;
+
+ -- Set previous values for subsequent edge detection
+ PrevControls := Controls;
+ PrevDataInBus := DataInBus;
+ PrevAddressBus := AddressBus;
+
+ -- Set the candidate zero delay return value
+ DataOutBus := DataOutTmp;
+
+ -- Set the output AddressValue for VitalMemoryCrossPorts
+ AddressValue := Address;
+
+END VitalMemoryTable;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryTable (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PrevControls : INOUT std_logic_vector;
+ VARIABLE PrevEnableBus : INOUT std_logic_vector;
+ VARIABLE PrevDataInBus : INOUT std_logic_vector;
+ VARIABLE PrevAddressBus : INOUT std_logic_vector;
+ VARIABLE PortFlagArray : INOUT VitalPortFlagVectorType;
+ CONSTANT Controls : IN std_logic_vector;
+ CONSTANT EnableBus : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressBus : IN std_logic_vector;
+ VARIABLE AddressValue : INOUT VitalAddressValueType;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType := UNDEF;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+
+ VARIABLE BitsPerWord : NATURAL := MemoryData.NoOfBitsPerWord;
+ VARIABLE BitsPerSubWord : NATURAL := MemoryData.NoOfBitsPerSubWord;
+ VARIABLE BitsPerEnable : NATURAL := MemoryData.NoOfBitsPerEnable;
+ VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE)
+ := DataOutBus;
+ VARIABLE MemoryAction : VitalMemorySymbolType;
+ VARIABLE DataAction : VitalMemorySymbolType;
+ VARIABLE HighBit : NATURAL := BitsPerSubWord-1;
+ VARIABLE LowBit : NATURAL := 0;
+ VARIABLE Address : INTEGER := 0;
+ VARIABLE PortFlagTmp : VitalPortFlagType;
+ VARIABLE AddrFlag : VitalMemorySymbolType := 'g'; -- good addr
+ VARIABLE DataFlag : VitalMemorySymbolType := 'g'; -- good data
+ VARIABLE MemCorruptMask : std_logic_vector (DataOutBus'RANGE);
+ VARIABLE DatCorruptMask : std_logic_vector (DataOutBus'RANGE);
+
+BEGIN
+
+ -- Optimize for case when all current inputs are same as previous
+ IF (PrevDataInBus = DataInBus
+ AND PrevAddressBus = AddressBus
+ AND PrevControls = Controls) THEN
+ CheckFlags:
+ FOR i IN 0 TO BitsPerEnable-1 LOOP
+ IF (PortFlagArray(i).MemoryCurrent /= PortFlagArray(i).MemoryPrevious
+ OR PortFlagArray(i).DataCurrent /= PortFlagArray(i).DataPrevious) THEN
+ EXIT CheckFlags;
+ END IF;
+ IF (i = BitsPerEnable-1) THEN
+ FOR j IN 0 TO BitsPerEnable-1 LOOP
+ PortFlagArray(j).OutputDisable := TRUE;
+ END LOOP;
+ RETURN;
+ END IF;
+ END LOOP;
+ END IF;
+
+ -- Convert address bus to integer value and table lookup flag
+ DecodeAddress(
+ Address => Address,
+ AddrFlag => AddrFlag,
+ MemoryData => MemoryData,
+ PrevAddressBus => PrevAddressBus,
+ AddressBus => AddressBus
+ );
+
+ -- Perform independent operations for each sub-word
+ FOR i IN 0 TO BitsPerEnable-1 LOOP
+
+ -- Set the output PortFlag(i) value
+ PortFlagArray(i).DataPrevious := PortFlagArray(i).DataCurrent;
+ PortFlagArray(i).MemoryPrevious := PortFlagArray(i).MemoryCurrent;
+ PortFlagArray(i).OutputDisable := FALSE;
+ PortFlagTmp := PortFlagArray(i);
+
+ -- Interpret data bus as a table lookup flag
+ DecodeData (
+ DataFlag => DataFlag ,
+ PrevDataInBus => PrevDataInBus ,
+ DataInBus => DataInBus ,
+ HighBit => HighBit ,
+ LowBit => LowBit
+ );
+
+ -- Lookup memory and data actions
+ MemoryTableLookUp(
+ MemoryAction => MemoryAction ,
+ DataAction => DataAction ,
+ MemoryCorruptMask => MemCorruptMask ,
+ DataCorruptMask => DatCorruptMask ,
+ PrevControls => PrevControls ,
+ PrevEnableBus => PrevEnableBus ,
+ Controls => Controls ,
+ EnableBus => EnableBus ,
+ EnableIndex => i ,
+ BitsPerWord => BitsPerWord ,
+ BitsPerSubWord => BitsPerSubWord ,
+ BitsPerEnable => BitsPerEnable ,
+ AddrFlag => AddrFlag ,
+ DataFlag => DataFlag ,
+ MemoryTable => MemoryTable ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ -- Handle data action before memory action
+ -- This allows reading previous memory contents
+ HandleDataAction(
+ DataOutBus => DataOutTmp ,
+ MemoryData => MemoryData ,
+ PortFlag => PortFlagTmp ,
+ CorruptMask => DatCorruptMask ,
+ DataInBus => DataInBus ,
+ Address => Address ,
+ HighBit => HighBit ,
+ LowBit => LowBit ,
+ MemoryTable => MemoryTable ,
+ DataAction => DataAction ,
+ CallerName => MsgVMT ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ HandleMemoryAction(
+ MemoryData => MemoryData ,
+ PortFlag => PortFlagTmp ,
+ CorruptMask => MemCorruptMask ,
+ DataInBus => DataInBus ,
+ Address => Address ,
+ HighBit => HighBit ,
+ LowBit => LowBit ,
+ MemoryTable => MemoryTable ,
+ MemoryAction => MemoryAction ,
+ CallerName => MsgVMT ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ -- Set the output PortFlag(i) value
+ IF (DataAction = 'S') THEN
+ PortFlagTmp.OutputDisable := TRUE;
+ END IF;
+ IF (PortFlagTmp.DataCurrent = PortFlagTmp.DataPrevious
+ AND PortFlagTmp.DataCurrent = HIGHZ) THEN
+ PortFlagTmp.OutputDisable := TRUE;
+ END IF;
+ PortFlagArray(i) := PortFlagTmp;
+
+ IF (i < BitsPerEnable-1) THEN
+ -- Calculate HighBit and LowBit
+ LowBit := LowBit + BitsPerSubWord;
+ IF (LowBit > BitsPerWord) THEN
+ LowBit := BitsPerWord;
+ END IF;
+ HighBit := LowBit + BitsPerSubWord;
+ IF (HighBit > BitsPerWord) THEN
+ HighBit := BitsPerWord;
+ ELSE
+ HighBit := HighBit - 1;
+ END IF;
+ END IF;
+
+ END LOOP;
+
+ -- Set previous values for subsequent edge detection
+ PrevControls := Controls;
+ PrevEnableBus := EnableBus;
+ PrevDataInBus := DataInBus;
+ PrevAddressBus := AddressBus;
+
+ -- Set the candidate zero delay return value
+ DataOutBus := DataOutTmp;
+
+ -- Set the output AddressValue for VitalMemoryCrossPorts
+ AddressValue := Address;
+
+END VitalMemoryTable;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryCrossPorts
+-- Parameters: DataOutBus - Output candidate zero delay data bus out
+-- MemoryData - Pointer to memory data structure
+-- SamePortFlag - Operating mode for same port
+-- SamePortAddressValue - Operating modes for cross ports
+-- CrossPortAddressArray - Decoded AddressBus for cross ports
+-- CrossPortMode - Write contention and crossport read control
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control the generation of messages
+-- Description: These procedures control the effect of memory operations
+-- on a given port due to operations on other ports in a
+-- multi-port memory.
+-- This includes data write through when reading and writing
+-- to the same address, as well as write contention when
+-- there are multiple write to the same address.
+-- If addresses do not match then data bus is unchanged.
+-- The DataOutBus can be diabled with 'Z' value.
+-- If the WritePortFlag is 'CORRUPT', that would mean
+-- that the whole memory is corrupted. So, for corrupting
+-- the Read port, the Addresses need not be compared.
+--
+-- CrossPortMode Enum Description
+-- 1. CpRead Allows Cross Port Read Only
+-- No contention checking.
+-- 2. WriteContention Allows for write contention checks
+-- only between multiple write ports
+-- 3. ReadWriteContention Allows contention between read and
+-- write ports. The action is to corrupt
+-- the memory and the output bus.
+-- 4. CpReadAndWriteContention Is a combination of 1 & 2
+-- 5. CpReadAndReadContention Allows contention between read and
+-- write ports. The action is to corrupt
+-- the dataout bus only. The cp read is
+-- performed if not contending.
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryCrossPorts (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE SamePortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT SamePortAddressValue : IN VitalAddressValueType;
+ CONSTANT CrossPortFlagArray : IN VitalPortFlagVectorType;
+ CONSTANT CrossPortAddressArray : IN VitalAddressValueVectorType;
+ CONSTANT CrossPortMode : IN VitalCrossPortModeType
+ := CpReadAndWriteContention;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+
+ VARIABLE BitsPerWord : NATURAL := MemoryData.NoOfBitsPerWord;
+ VARIABLE BitsPerSubWord : NATURAL := MemoryData.NoOfBitsPerSubWord;
+ VARIABLE BitsPerEnable : NATURAL := MemoryData.NoOfBitsPerEnable;
+ VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE) := (OTHERS => 'Z');
+ VARIABLE MemoryTmp : std_logic_vector(DataOutBus'RANGE);
+ VARIABLE CrossPorts : NATURAL := CrossPortAddressArray'LENGTH;
+ VARIABLE LowBit : NATURAL := 0;
+ VARIABLE HighBit : NATURAL := BitsPerSubWord-1;
+ VARIABLE Address : VitalAddressValueType := SamePortAddressValue;
+ VARIABLE AddressJ : VitalAddressValueType;
+ VARIABLE AddressK : VitalAddressValueType;
+ VARIABLE PortFlagI : VitalPortFlagType;
+ VARIABLE PortFlagIJ : VitalPortFlagType;
+ VARIABLE PortFlagIK : VitalPortFlagType;
+ VARIABLE DoCpRead : BOOLEAN := FALSE;
+ VARIABLE DoWrCont : BOOLEAN := FALSE;
+ VARIABLE DoCpCont : BOOLEAN := FALSE;
+ VARIABLE DoRdWrCont : BOOLEAN := FALSE;
+ VARIABLE CpWrCont : BOOLEAN := FALSE;
+ VARIABLE ModeWrCont : BOOLEAN :=
+ (CrossPortMode=WriteContention) OR
+ (CrossPortMode=CpReadAndWriteContention);
+ VARIABLE ModeCpRead : BOOLEAN :=
+ (CrossPortMode=CpRead) OR
+ (CrossPortMode=CpReadAndWriteContention);
+ VARIABLE ModeCpCont : BOOLEAN := (CrossPortMode=ReadWriteContention);
+ VARIABLE ModeRdWrCont : BOOLEAN := (CrossPortMode=CpReadAndReadContention);
+
+BEGIN
+
+ -- Check for disabled port (i.e. OTHERS => 'Z')
+ IF (DataOutBus = DataOutTmp) THEN
+ RETURN;
+ ELSE
+ DataOutTmp := DataOutBus;
+ END IF;
+
+ -- Check for error in address
+ IF (Address < 0) THEN
+ RETURN;
+ END IF;
+
+ ReadMemory(MemoryData,MemoryTmp,Address);
+
+ SubWordLoop: -- For each slice of the sub-word I
+ FOR i IN 0 TO BitsPerEnable-1 LOOP
+ PortFlagI := SamePortFlag(i);
+
+ -- For each cross port J: check with same port address
+ FOR j IN 0 TO CrossPorts-1 LOOP
+ PortFlagIJ := CrossPortFlagArray(i+j*BitsPerEnable);
+ AddressJ := CrossPortAddressArray(j);
+ IF (AddressJ < 0) THEN
+ NEXT;
+ END IF;
+ DoWrCont := (Address = AddressJ) AND
+ (ModeWrCont = TRUE) AND
+ ((PortFlagI.MemoryCurrent = WRITE) OR
+ (PortFlagI.MemoryCurrent = CORRUPT)) AND
+ ((PortFlagIJ.MemoryCurrent = WRITE) OR
+ (PortFlagIJ.MemoryCurrent = CORRUPT)) ;
+ DoCpRead := (Address = AddressJ) AND
+ (ModeCpRead = TRUE) AND
+ ((PortFlagI.MemoryCurrent = READ) OR
+ (PortFlagI.OutputDisable = TRUE)) AND
+ ((PortFlagIJ.MemoryCurrent = WRITE) OR
+ (PortFlagIJ.MemoryCurrent = CORRUPT)) ;
+ DoCpCont := (Address = AddressJ) AND
+ (ModeCpCont = TRUE) AND
+ ((PortFlagI.MemoryCurrent = READ) OR
+ (PortFlagI.OutputDisable = TRUE)) AND
+ ((PortFlagIJ.MemoryCurrent = WRITE) OR
+ (PortFlagIJ.MemoryCurrent = CORRUPT)) ;
+ DoRdWrCont:= (Address = AddressJ) AND
+ (ModeRdWrCont = TRUE) AND
+ ((PortFlagI.MemoryCurrent = READ) OR
+ (PortFlagI.OutputDisable = TRUE)) AND
+ ((PortFlagIJ.MemoryCurrent = WRITE) OR
+ (PortFlagIJ.MemoryCurrent = CORRUPT)) ;
+ IF (DoWrCont OR DoCpCont) THEN
+ -- Corrupt dataout and memory
+ MemoryTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X');
+ DataOutTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X');
+ SamePortFlag(i).MemoryCurrent := CORRUPT;
+ SamePortFlag(i).DataCurrent := CORRUPT;
+ SamePortFlag(i).OutputDisable := FALSE;
+ EXIT;
+ END IF;
+ IF (DoCpRead) THEN
+ -- Update dataout with memory
+ DataOutTmp(HighBit DOWNTO LowBit) :=
+ MemoryTmp(HighBit DOWNTO LowBit);
+ SamePortFlag(i).MemoryCurrent := READ;
+ SamePortFlag(i).DataCurrent := READ;
+ SamePortFlag(i).OutputDisable := FALSE;
+ EXIT;
+ END IF;
+ IF (DoRdWrCont) THEN
+ -- Corrupt dataout only
+ DataOutTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X');
+ SamePortFlag(i).DataCurrent := CORRUPT;
+ SamePortFlag(i).OutputDisable := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ IF (i < BitsPerEnable-1) THEN
+ -- Calculate HighBit and LowBit
+ LowBit := LowBit + BitsPerSubWord;
+ IF (LowBit > BitsPerWord) THEN
+ LowBit := BitsPerWord;
+ END IF;
+ HighBit := LowBit + BitsPerSubWord;
+ IF (HighBit > BitsPerWord) THEN
+ HighBit := BitsPerWord;
+ ELSE
+ HighBit := HighBit - 1;
+ END IF;
+ END IF;
+
+ END LOOP; -- SubWordLoop
+
+ DataOutBus := DataOutTmp;
+
+ IF (DoWrCont) THEN
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMCP,ErrMcpWrCont,HeaderMsg,PortName);
+ END IF;
+ WriteMemory(MemoryData,MemoryTmp,Address);
+ END IF;
+
+ IF (DoCpCont) THEN
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMCP,ErrMcpCpCont,HeaderMsg,PortName);
+ END IF;
+ WriteMemory(MemoryData,MemoryTmp,Address);
+ END IF;
+
+ IF (DoCpRead) THEN
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMCP,ErrMcpCpRead,HeaderMsg,PortName);
+ END IF;
+ END IF;
+
+ IF (DoRdWrCont) THEN
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMCP,ErrMcpRdWrCo,HeaderMsg,PortName);
+ END IF;
+ END IF;
+
+END VitalMemoryCrossPorts;
+
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryCrossPorts (
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ CONSTANT CrossPortFlagArray : IN VitalPortFlagVectorType;
+ CONSTANT CrossPortAddressArray : IN VitalAddressValueVectorType;
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) IS
+
+ VARIABLE BitsPerWord : NATURAL := MemoryData.NoOfBitsPerWord;
+ VARIABLE BitsPerSubWord : NATURAL := MemoryData.NoOfBitsPerSubWord;
+ VARIABLE BitsPerEnable : NATURAL := MemoryData.NoOfBitsPerEnable;
+ VARIABLE MemoryTmp : std_logic_vector(BitsPerWord-1 DOWNTO 0);
+ VARIABLE CrossPorts : NATURAL := CrossPortAddressArray'LENGTH;
+ VARIABLE LowBit : NATURAL := 0;
+ VARIABLE HighBit : NATURAL := BitsPerSubWord-1;
+ VARIABLE AddressJ : VitalAddressValueType;
+ VARIABLE AddressK : VitalAddressValueType;
+ VARIABLE PortFlagIJ : VitalPortFlagType;
+ VARIABLE PortFlagIK : VitalPortFlagType;
+ VARIABLE CpWrCont : BOOLEAN := FALSE;
+
+BEGIN
+
+ SubWordLoop: -- For each slice of the sub-word I
+ FOR i IN 0 TO BitsPerEnable-1 LOOP
+
+ -- For each cross port J: check with each cross port K
+ FOR j IN 0 TO CrossPorts-1 LOOP
+ PortFlagIJ := CrossPortFlagArray(i+j*BitsPerEnable);
+ AddressJ := CrossPortAddressArray(j);
+ -- Check for error in address
+ IF (AddressJ < 0) THEN
+ NEXT;
+ END IF;
+ ReadMemory(MemoryData,MemoryTmp,AddressJ);
+ -- For each cross port K
+ FOR k IN 0 TO CrossPorts-1 LOOP
+ IF (k <= j) THEN
+ NEXT;
+ END IF;
+ PortFlagIK := CrossPortFlagArray(i+k*BitsPerEnable);
+ AddressK := CrossPortAddressArray(k);
+ -- Check for error in address
+ IF (AddressK < 0) THEN
+ NEXT;
+ END IF;
+ CpWrCont := ( (AddressJ = AddressK) AND
+ (PortFlagIJ.MemoryCurrent = WRITE) AND
+ (PortFlagIK.MemoryCurrent = WRITE) ) OR
+ ( (PortFlagIJ.MemoryCurrent = WRITE) AND
+ (PortFlagIK.MemoryCurrent = CORRUPT) ) OR
+ ( (PortFlagIJ.MemoryCurrent = CORRUPT) AND
+ (PortFlagIK.MemoryCurrent = WRITE) ) OR
+ ( (PortFlagIJ.MemoryCurrent = CORRUPT) AND
+ (PortFlagIK.MemoryCurrent = CORRUPT) ) ;
+ IF (CpWrCont) THEN
+ -- Corrupt memory only
+ MemoryTmp(HighBit DOWNTO LowBit) := (OTHERS => 'X');
+ EXIT;
+ END IF;
+ END LOOP; -- FOR k IN 0 TO CrossPorts-1 LOOP
+ IF (CpWrCont = TRUE) THEN
+ IF (MsgOn) THEN
+ PrintMemoryMessage(MsgVMCP,ErrMcpCpWrCont,HeaderMsg);
+ END IF;
+ WriteMemory(MemoryData,MemoryTmp,AddressJ);
+ END IF;
+ END LOOP; -- FOR j IN 0 TO CrossPorts-1 LOOP
+
+ IF (i < BitsPerEnable-1) THEN
+ -- Calculate HighBit and LowBit
+ LowBit := LowBit + BitsPerSubWord;
+ IF (LowBit > BitsPerWord) THEN
+ LowBit := BitsPerWord;
+ END IF;
+ HighBit := LowBit + BitsPerSubWord;
+ IF (HighBit > BitsPerWord) THEN
+ HighBit := BitsPerWord;
+ ELSE
+ HighBit := HighBit - 1;
+ END IF;
+ END IF;
+ END LOOP; -- SubWordLoop
+
+END VitalMemoryCrossPorts;
+
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryViolation
+-- Parameters: DataOutBus - Output zero delay data bus out
+-- MemoryData - Pointer to memory data structure
+-- PortFlag - Indicates port operating mode
+-- TimingDataArray - This is currently not used (comment out)
+-- ViolationArray - Aggregation of violation variables
+-- DataInBus - Input value of data bus in
+-- AddressBus - Input value of address bus in
+-- AddressValue - Decoded value of the AddressBus
+-- ViolationTable - Input memory violation table
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control the generation of messages
+-- MsgSeverity - Control level of message generation
+-- Description: This procedure is intended to implement all actions on the
+-- memory contents and data out bus as a result of timing viols.
+-- It uses the memory action table to perform various corruption
+-- policies specified by the user.
+-- ----------------------------------------------------------------------------
+
+PROCEDURE VitalMemoryViolation (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressValue : IN VitalAddressValueType;
+ CONSTANT ViolationFlags : IN std_logic_vector;
+ CONSTANT ViolationFlagsArray : IN X01ArrayT;
+ CONSTANT ViolationSizesArray : IN VitalMemoryViolFlagSizeType;
+ CONSTANT ViolationTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+
+ VARIABLE BitsPerWord : NATURAL := MemoryData.NoOfBitsPerWord;
+ VARIABLE BitsPerSubWord : NATURAL := MemoryData.NoOfBitsPerSubWord;
+ VARIABLE BitsPerEnable : NATURAL := MemoryData.NoOfBitsPerEnable;
+ VARIABLE DataOutTmp : std_logic_vector(DataOutBus'RANGE)
+ := DataOutBus;
+ VARIABLE MemoryAction : VitalMemorySymbolType;
+ VARIABLE DataAction : VitalMemorySymbolType;
+ -- VMT relies on the corrupt masks so HighBit/LowBit are full word
+ VARIABLE HighBit : NATURAL := BitsPerWord-1;
+ VARIABLE LowBit : NATURAL := 0;
+ VARIABLE PortFlagTmp : VitalPortFlagType;
+ VARIABLE VFlagArrayTmp : std_logic_vector
+ (0 TO ViolationFlagsArray'LENGTH-1);
+ VARIABLE MemCorruptMask : std_logic_vector (DataOutBus'RANGE);
+ VARIABLE DatCorruptMask : std_logic_vector (DataOutBus'RANGE);
+
+BEGIN
+
+ -- Don't do anything if given an error address
+ IF (AddressValue < 0) THEN
+ RETURN;
+ END IF;
+
+ FOR i IN ViolationFlagsArray'RANGE LOOP
+ VFlagArrayTmp(i) := ViolationFlagsArray(i);
+ END LOOP;
+
+ -- Lookup memory and data actions
+ ViolationTableLookUp(
+ MemoryAction => MemoryAction ,
+ DataAction => DataAction ,
+ MemoryCorruptMask => MemCorruptMask ,
+ DataCorruptMask => DatCorruptMask ,
+ ViolationFlags => ViolationFlags ,
+ ViolationFlagsArray => VFlagArrayTmp ,
+ ViolationSizesArray => ViolationSizesArray ,
+ ViolationTable => ViolationTable ,
+ BitsPerWord => BitsPerWord ,
+ BitsPerSubWord => BitsPerSubWord ,
+ BitsPerEnable => BitsPerEnable ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+
+ -- Need to read incoming PF value (was not before)
+ PortFlagTmp := PortFlag(0);
+
+ IF (PortType = READ OR PortType = RDNWR) THEN
+ -- Handle data action before memory action
+ -- This allows reading previous memory contents
+ HandleDataAction(
+ DataOutBus => DataOutTmp ,
+ MemoryData => MemoryData ,
+ PortFlag => PortFlagTmp ,
+ CorruptMask => DatCorruptMask ,
+ DataInBus => DataInBus ,
+ Address => AddressValue ,
+ HighBit => HighBit ,
+ LowBit => LowBit ,
+ MemoryTable => ViolationTable ,
+ DataAction => DataAction ,
+ CallerName => MsgVMV ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+ END IF;
+
+ IF (PortType = WRITE OR PortType = RDNWR) THEN
+ HandleMemoryAction(
+ MemoryData => MemoryData ,
+ PortFlag => PortFlagTmp ,
+ CorruptMask => MemCorruptMask ,
+ DataInBus => DataInBus ,
+ Address => AddressValue ,
+ HighBit => HighBit ,
+ LowBit => LowBit ,
+ MemoryTable => ViolationTable ,
+ MemoryAction => MemoryAction ,
+ CallerName => MsgVMV ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn
+ );
+ END IF;
+
+ -- Check if we need to turn off PF.OutputDisable
+ IF (DataAction /= 'S') THEN
+ PortFlagTmp.OutputDisable := FALSE;
+ -- Set the output PortFlag(0) value
+ -- Note that all bits of PortFlag get PortFlagTmp
+ FOR i IN PortFlag'RANGE LOOP
+ PortFlag(i) := PortFlagTmp;
+ END LOOP;
+ END IF;
+
+ -- Set the candidate zero delay return value
+ DataOutBus := DataOutTmp;
+
+END;
+
+PROCEDURE VitalMemoryViolation (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressValue : IN VitalAddressValueType;
+ CONSTANT ViolationFlags : IN std_logic_vector;
+ CONSTANT ViolationTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) IS
+
+ VARIABLE VFlagArrayTmp : X01ArrayT (0 TO 0);
+
+BEGIN
+
+ VitalMemoryViolation (
+ DataOutBus => DataOutBus ,
+ MemoryData => MemoryData ,
+ PortFlag => PortFlag ,
+ DataInBus => DataInBus ,
+ AddressValue => AddressValue ,
+ ViolationFlags => ViolationFlags ,
+ ViolationFlagsArray => VFlagArrayTmp ,
+ ViolationSizesArray => ( 0 => 0 ) ,
+ ViolationTable => ViolationTable ,
+ PortType => PortType ,
+ PortName => PortName ,
+ HeaderMsg => HeaderMsg ,
+ MsgOn => MsgOn ,
+ MsgSeverity => MsgSeverity
+ );
+
+END;
+
+END Vital_Memory ;
diff --git a/libraries/vital2000/memory_p.vhdl b/libraries/vital2000/memory_p.vhdl
new file mode 100644
index 000000000..83874f45e
--- /dev/null
+++ b/libraries/vital2000/memory_p.vhdl
@@ -0,0 +1,1729 @@
+-- ----------------------------------------------------------------------------
+-- Title : Standard VITAL Memory Package
+-- :
+-- Library : Vital_Memory
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- : Ekambaram Balaji, LSI Logic Corporation
+-- : Jose De Castro, Consultant
+-- : Prakash Bare, GDA Technologies
+-- : William Yam, LSI Logic Corporation
+-- : Dennis Brophy, Model Technology
+-- :
+-- Purpose : This packages defines standard types, constants, functions
+-- : and procedures for use in developing ASIC memory models.
+-- :
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Ver:|Auth:| Date:| Changes Made:
+-- 0.1 | eb |071796| First prototye as part of VITAL memory proposal
+-- 0.2 | jdc |012897| Initial prototyping with proposed MTM scheme
+-- 0.3 | jdc |090297| Extensive updates for TAG review (functional)
+-- 0.4 | eb |091597| Changed naming conventions for VitalMemoryTable
+-- | | | Added interface of VitalMemoryCrossPorts() &
+-- | | | VitalMemoryViolation().
+-- 0.5 | jdc |092997| Completed naming changes thoughout package body.
+-- | | | Testing with simgle port test model looks ok.
+-- 0.6 | jdc |121797| Major updates to the packages:
+-- | | | - Implement VitalMemoryCrossPorts()
+-- | | | - Use new VitalAddressValueType
+-- | | | - Use new VitalCrossPortModeType enum
+-- | | | - Overloading without SamePort args
+-- | | | - Honor erroneous address values
+-- | | | - Honor ports disabled with 'Z'
+-- | | | - Implement implicit read 'M' table symbol
+-- | | | - Cleanup buses to use (H DOWNTO L)
+-- | | | - Message control via MsgOn,HeaderMsg,PortName
+-- | | | - Tested with 1P1RW,2P2RW,4P2R2W,4P4RW cases
+-- 0.7 | jdc |052698| Bug fixes to the packages:
+-- | | | - Fix failure with negative Address values
+-- | | | - Added debug messages for VMT table search
+-- | | | - Remove 'S' for action column (only 's')
+-- | | | - Remove 's' for response column (only 'S')
+-- | | | - Remove 'X' for action and response columns
+-- 0.8 | jdc |061298| Implemented VitalMemoryViolation()
+-- | | | - Minimal functionality violation tables
+-- | | | - Missing:
+-- | | | - Cannot handle wide violation variables
+-- | | | - Cannot handle sub-word cases
+-- | | | Fixed IIC version of MemoryMatch
+-- | | | Fixed 'M' vs 'm' switched on debug output
+-- | | | TO BE DONE:
+-- | | | - Implement 'd' corrupting a single bit
+-- | | | - Implement 'D' corrupting a single bit
+-- 0.9 |eb/sc|080498| Added UNDEF value for VitalPortFlagType
+-- 0.10|eb/sc|080798| Added CORRUPT value for VitalPortFlagType
+-- 0.11|eb/sc|081798| Added overloaded function interface for
+-- | | | VitalDeclareMemory
+-- 0.14| jdc |113198| Merging of memory functionality and version
+-- | | | 1.4 9/17/98 of timing package from Prakash
+-- 0.15| jdc |120198| Major development of VMV functionality
+-- 0.16| jdc |120298| Complete VMV functionlality for initial testing
+-- | | | - New ViolationTableCorruptMask() procedure
+-- | | | - New MemoryTableCorruptMask() procedure
+-- | | | - HandleMemoryAction():
+-- | | | - Removed DataOutBus bogus output
+-- | | | - Replaced DataOutTmp with DataInTmp
+-- | | | - Added CorruptMask input handling
+-- | | | - Implemented 'd','D' using CorruptMask
+-- | | | - CorruptMask on 'd','C','L','D','E'
+-- | | | - CorruptMask ignored on 'c','l','e'
+-- | | | - Changed 'l','d','e' to set PortFlag to CORRUPT
+-- | | | - Changed 'L','D','E' to set PortFlag to CORRUPT
+-- | | | - Changed 'c','l','d','e' to ignore HighBit, LowBit
+-- | | | - Changed 'C','L','D','E' to use HighBit, LowBit
+-- | | | - HandleDataAction():
+-- | | | - Added CorruptMask input handling
+-- | | | - Implemented 'd','D' using CorruptMask
+-- | | | - CorruptMask on 'd','C','L','D','E'
+-- | | | - CorruptMask ignored on 'l','e'
+-- | | | - Changed 'l','d','e' to set PortFlag to CORRUPT
+-- | | | - Changed 'L','D','E' to set PortFlag to CORRUPT
+-- | | | - Changed 'l','d','e' to ignore HighBit, LowBit
+-- | | | - Changed 'L','D','E' to use HighBit, LowBit
+-- | | | - MemoryTableLookUp():
+-- | | | - Added MsgOn table debug output
+-- | | | - Uses new MemoryTableCorruptMask()
+-- | | | - ViolationTableLookUp():
+-- | | | - Uses new ViolationTableCorruptMask()
+-- 0.17| jdc |120898| - Added VitalMemoryViolationSymbolType,
+-- | | | VitalMemoryViolationTableType data
+-- | | | types but not used yet (need to discuss)
+-- | | | - Added overload for VitalMemoryViolation()
+-- | | | which does not have array flags
+-- | | | - Bug fixes for VMV functionality:
+-- | | | - ViolationTableLookUp() not handling '-' in
+-- | | | scalar violation matching
+-- | | | - VitalMemoryViolation() now normalizes
+-- | | | VFlagArrayTmp'LEFT as LSB before calling
+-- | | | ViolationTableLookUp() for proper scanning
+-- | | | - ViolationTableCorruptMask() had to remove
+-- | | | normalization of CorruptMaskTmp and
+-- | | | ViolMaskTmp for proper MSB:LSB corruption
+-- | | | - HandleMemoryAction(), HandleDataAction()
+-- | | | - Removed 'D','E' since not being used
+-- | | | - Use XOR instead of OR for corrupt masks
+-- | | | - Now 'd' is sensitive to HighBit, LowBit
+-- | | | - Fixed LowBit overflow in bit writeable case
+-- | | | - MemoryTableCorruptMask()
+-- | | | - ViolationTableCorruptMask()
+-- | | | - VitalMemoryTable()
+-- | | | - VitalMemoryCrossPorts()
+-- | | | - Fixed VitalMemoryViolation() failing on
+-- | | | error AddressValue from earlier VMT()
+-- | | | - Minor cleanup of code formatting
+-- 0.18| jdc |032599| - In VitalDeclareMemory()
+-- | | | - Added BinaryLoadFile formal arg and
+-- | | | modified LoadMemory() to handle bin
+-- | | | - Added NOCHANGE to VitalPortFlagType
+-- | | | - For VitalCrossPortModeType
+-- | | | - Added CpContention enum
+-- | | | - In HandleDataAction()
+-- | | | - Set PortFlag := NOCHANGE for 'S'
+-- | | | - In HandleMemoryAction()
+-- | | | - Set PortFlag := NOCHANGE for 's'
+-- | | | - In VitalMemoryTable() and
+-- | | | VitalMemoryViolation()
+-- | | | - Honor PortFlag = NOCHANGE returned
+-- | | | from HandleMemoryAction()
+-- | | | - In VitalMemoryCrossPorts()
+-- | | | - Fixed Address = AddressJ for all
+-- | | | conditions of DoWrCont & DoCpRead
+-- | | | - Handle CpContention like WrContOnly
+-- | | | under CpReadOnly conditions, with
+-- | | | associated memory message changes
+-- | | | - Handle PortFlag = NOCHANGE like
+-- | | | PortFlag = READ for actions
+-- | | | - Modeling change:
+-- | | | - Need to init PortFlag every delta
+-- | | | PortFlag_A := (OTHES => UNDEF);
+-- | | | - Updated InternalTimingCheck code
+-- 0.19| jdc |042599| - Fixes for bit-writeable cases
+-- | | | - Check PortFlag after HandleDataAction
+-- | | | in VitalMemoryViolation()
+-- 0.20| jdc |042599| - Merge PortFlag changes from Prakash
+-- | | | and Willian:
+-- | | | VitalMemorySchedulePathDelay()
+-- | | | VitalMemoryExpandPortFlag()
+-- 0.21| jdc |072199| - Changed VitalCrossPortModeType enums,
+-- | | | added new CpReadAndReadContention.
+-- | | | - Fixed VitalMemoryCrossPorts() parameter
+-- | | | SamePortFlag to INOUT so that it can
+-- | | | set CORRUPT or READ value.
+-- | | | - Fixed VitalMemoryTable() where PortFlag
+-- | | | setting by HandleDataAction() is being
+-- | | | ignored when HandleMemoryAction() sets
+-- | | | PortFlagTmp to NOCHANGE.
+-- | | | - Fixed VitalMemoryViolation() to set
+-- | | | all bits of PortFlag when violating.
+-- 0.22| jdc |072399| - Added HIGHZ to PortFlagType. HandleData
+-- | | | checks whether the previous state is HIGHZ.
+-- | | | If yes then portFlag should be NOCHANGE
+-- | | | for VMPD to ignore IORetain corruption.
+-- | | | The idea is that the first Z should be
+-- | | | propagated but later ones should be ignored.
+-- | | |
+-- 0.23| jdc |100499| - Took code checked in by Dennis 09/28/99
+-- | | | - Changed VitalPortFlagType to record of
+-- | | | new VitalPortStateType to hold current,
+-- | | | previous values and separate disable.
+-- | | | Also created VitalDefaultPortFlag const.
+-- | | | Removed usage of PortFlag NOCHANGE
+-- | | | - VitalMemoryTable() changes:
+-- | | | Optimized return when all curr = prev
+-- | | | AddressValue is now INOUT to optimize
+-- | | | Transfer PF.MemoryCurrent to MemoryPrevious
+-- | | | Transfer PF.DataCurrent to DataPrevious
+-- | | | Reset PF.OutputDisable to FALSE
+-- | | | Expects PortFlag init in declaration
+-- | | | No need to init PortFlag every delta
+-- | | | - VitalMemorySchedulePathDelay() changes:
+-- | | | Initialize with VitalDefaultPortFlag
+-- | | | Check PortFlag.OutputDisable
+-- | | | - HandleMemoryAction() changes:
+-- | | | Set value of PortFlag.MemoryCurrent
+-- | | | Never set PortFlag.OutputDisable
+-- | | | - HandleDataAction() changes:
+-- | | | Set value of PortFlag.DataCurrent
+-- | | | Set PortFlag.DataCurrent for HIGHZ
+-- | | | - VitalMemoryCrossPorts() changes:
+-- | | | Check/set value of PF.MemoryCurrent
+-- | | | Check value of PF.OutputDisable
+-- | | | - VitalMemoryViolation() changes:
+-- | | | Fixed bug - not reading inout PF value
+-- | | | Clean up setting of PortFlag
+-- 0.24| jdc |100899| - Modified update of PF.OutputDisable
+-- | | | to correctly accomodate 2P1W1R case:
+-- | | | the read port should not exhibit
+-- | | | IO retain corrupt when reading
+-- | | | addr unrelated to addr being written.
+-- 0.25| jdc |100999| - VitalMemoryViolation() change:
+-- | | | Fixed bug with RDNWR mode incorrectly
+-- | | | updating the PF.OutputDisable
+-- 0.26| jdc |100999| - VitalMemoryCrossPorts() change:
+-- | | | Fixed bugs with update of PF
+-- 0.27| jdc |101499| - VitalMemoryCrossPorts() change:
+-- | | | Added DoRdWrCont message (ErrMcpRdWrCo,
+-- | | | Memory cross port read/write data only
+-- | | | contention)
+-- | | | - VitalMemoryTable() change:
+-- | | | Set PF.OutputDisable := TRUE for the
+-- | | | optimized cases.
+-- 0.28| pb |112399| - Added 8 VMPD procedures for vector
+-- | | | PathCondition support. Now the total
+-- | | | number of overloadings for VMPD is 24.
+-- | | | - Number of overloadings for SetupHold
+-- | | | procedures increased to 5. Scalar violations
+-- | | | are not supported anymore. Vector checkEnabled
+-- | | | support is provided through the new overloading
+-- 0.29| jdc |120999| - HandleMemoryAction() HandleDataAction()
+-- | | | Reinstated 'D' and 'E' actions but
+-- | | | with new PortFlagType
+-- | | | - Updated file handling syntax, must compile
+-- | | | with -93 syntax now.
+-- 0.30| jdc |022300| - Formated for 80 column max width
+-- ----------------------------------------------------------------------------
+
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.Vital_Timing.ALL;
+USE IEEE.Vital_Primitives.ALL;
+
+LIBRARY STD;
+USE STD.TEXTIO.ALL;
+
+PACKAGE Vital_Memory IS
+
+-- ----------------------------------------------------------------------------
+-- Timing Section
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- Types and constants for Memory timing procedures
+-- ----------------------------------------------------------------------------
+TYPE VitalMemoryArcType IS (ParallelArc, CrossArc, SubwordArc);
+TYPE OutputRetainBehaviorType IS (BitCorrupt, WordCorrupt);
+TYPE VitalMemoryMsgFormatType IS (Vector, Scalar, VectorEnum);
+TYPE X01ArrayT IS ARRAY (NATURAL RANGE <> ) OF X01;
+TYPE X01ArrayPT IS ACCESS X01ArrayT;
+TYPE VitalMemoryViolationType IS ACCESS X01ArrayT;
+CONSTANT DefaultNumBitsPerSubword : INTEGER := -1;
+
+
+-- Data type storing path delay and schedule information for output bits
+TYPE VitalMemoryScheduleDataType IS RECORD
+ OutputData : std_ulogic;
+ NumBitsPerSubWord : INTEGER;
+ ScheduleTime : TIME;
+ ScheduleValue : std_ulogic;
+ LastOutputValue : std_ulogic;
+ PropDelay : TIME;
+ OutputRetainDelay : TIME;
+ InputAge : TIME;
+END RECORD;
+
+TYPE VitalMemoryTimingDataType IS RECORD
+ NotFirstFlag : BOOLEAN;
+ RefLast : X01;
+ RefTime : TIME;
+ HoldEn : BOOLEAN;
+ TestLast : std_ulogic;
+ TestTime : TIME;
+ SetupEn : BOOLEAN;
+ TestLastA : VitalLogicArrayPT;
+ TestTimeA : VitalTimeArrayPT;
+ RefLastA : X01ArrayPT;
+ RefTimeA : VitalTimeArrayPT;
+ HoldEnA : VitalBoolArrayPT;
+ SetupEnA : VitalBoolArrayPT;
+END RECORD;
+
+TYPE VitalPeriodDataArrayType IS ARRAY (NATURAL RANGE <>) OF
+ VitalPeriodDataType;
+
+-- Data type storing path delay and schedule information for output
+-- vectors
+TYPE VitalMemoryScheduleDataVectorType IS ARRAY (NATURAL RANGE <> ) OF
+ VitalMemoryScheduleDataType;
+
+-- VitalPortFlagType records runtime mode of port sub-word slices
+-- TYPE VitalPortFlagType IS (
+-- UNDEF,
+-- READ,
+-- WRITE,
+-- CORRUPT,
+-- HIGHZ,
+-- NOCHANGE
+-- );
+
+-- VitalPortFlagType records runtime mode of port sub-word slices
+TYPE VitalPortStateType IS (
+ UNDEF,
+ READ,
+ WRITE,
+ CORRUPT,
+ HIGHZ
+);
+
+TYPE VitalPortFlagType IS RECORD
+ MemoryCurrent : VitalPortStateType;
+ MemoryPrevious : VitalPortStateType;
+ DataCurrent : VitalPortStateType;
+ DataPrevious : VitalPortStateType;
+ OutputDisable : BOOLEAN;
+END RECORD;
+
+CONSTANT VitalDefaultPortFlag : VitalPortFlagType := (
+ MemoryCurrent => READ,
+ MemoryPrevious => UNDEF,
+ DataCurrent => READ,
+ DataPrevious => UNDEF,
+ OutputDisable => FALSE
+);
+
+-- VitalPortFlagVectorType to be same width i as enables of a port
+-- or j multiples thereof, where j is the number of cross ports
+TYPE VitalPortFlagVectorType IS
+ ARRAY (NATURAL RANGE <>) OF VitalPortFlagType;
+
+-- ----------------------------------------------------------------------------
+-- Functions : VitalMemory path delay procedures
+-- - VitalMemoryInitPathDelay
+-- - VitalMemoryAddPathDelay
+-- - VitalMemorySchedulePathDelay
+--
+-- Description: VitalMemoryInitPathDelay, VitalMemoryAddPathDelay and
+-- VitalMemorySchedulePathDelay are Level 1 routines used
+-- for selecting the propagation delay paths based on
+-- path condition, transition type and delay values and
+-- schedule a new output value.
+--
+-- Following features are implemented in these procedures:
+-- o condition dependent path selection
+-- o Transition dependent delay selection
+-- o shortest delay path selection from multiple
+-- candidate paths
+-- o Scheduling of the computed values on the specified
+-- signal.
+-- o output retain behavior if outputRetain flag is set
+-- o output mapping to alternate strengths to model
+-- pull-up, pull-down etc.
+--
+-- <More details to be added here>
+--
+-- Following is information on overloading of the procedures.
+--
+-- VitalMemoryInitPathDelay is overloaded for ScheduleDataArray and
+-- OutputDataArray
+--
+-- ----------------------------------------------------------------------------
+-- ScheduleDataArray OutputDataArray
+-- ----------------------------------------------------------------------------
+-- Scalar Scalar
+-- Vector Vector
+-- ----------------------------------------------------------------------------
+--
+--
+-- VitalMemoryAddPathDelay is overloaded for ScheduleDataArray,
+-- PathDelayArray, InputSignal and delaytype.
+--
+-- ----------------------------------------------------------------------------
+-- DelayType InputSignal ScheduleData PathDelay
+-- Array Array
+-- ----------------------------------------------------------------------------
+-- VitalDelayType Scalar Scalar Scalar
+-- VitalDelayType Scalar Vector Vector
+-- VitalDelayType Vector Scalar Vector
+-- VitalDelayType Vector Vector Vector
+-- VitalDelayType01 Scalar Scalar Scalar
+-- VitalDelayType01 Scalar Vector Vector
+-- VitalDelayType01 Vector Scalar Vector
+-- VitalDelayType01 Vector Vector Vector
+-- VitalDelayType01Z Scalar Scalar Scalar
+-- VitalDelayType01Z Scalar Vector Vector
+-- VitalDelayType01Z Vector Scalar Vector
+-- VitalDelayType01Z Vector Vector Vector
+-- VitalDelayType01XZ Scalar Scalar Scalar
+-- VitalDelayType01XZ Scalar Vector Vector
+-- VitalDelayType01XZ Vector Scalar Vector
+-- VitalDelayType01XZ Vector Vector Vector
+-- ----------------------------------------------------------------------------
+--
+--
+-- VitalMemorySchedulePathDelay is overloaded for ScheduleDataArray,
+-- and OutSignal
+--
+-- ----------------------------------------------------------------------------
+-- OutSignal ScheduleDataArray
+-- ----------------------------------------------------------------------------
+-- Scalar Scalar
+-- Vector Vector
+-- ----------------------------------------------------------------------------
+--
+-- Procedure Declarations:
+--
+--
+-- Function : VitalMemoryInitPathDelay
+--
+-- Arguments:
+--
+-- INOUT Type Description
+--
+-- ScheduleDataArray/ VitalMemoryScheduleDataVectorType/
+-- ScheduleData VitalMemoryScheduleDataType
+-- Internal data variable for
+-- storing delay and schedule
+-- information for each output bit
+--
+--
+-- IN
+--
+-- OutputDataArray/ STD_LOGIC_VECTOR/Array containing current output
+-- OutputData STD_ULOGIC value
+--
+--
+-- NumBitsPerSubWord INTEGER Number of bits per subword.
+-- Default value of this argument
+-- is DefaultNumBitsPerSubword
+-- which is interpreted as no
+-- subwords
+--
+-- ----------------------------------------------------------------------------
+--
+--
+-- ScheduleDataArray - Vector
+-- OutputDataArray - Vector
+--
+PROCEDURE VitalMemoryInitPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ VARIABLE OutputDataArray : IN STD_LOGIC_VECTOR;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := DefaultNumBitsPerSubword
+);
+--
+-- ScheduleDataArray - Scalar
+-- OutputDataArray - Scalar
+--
+PROCEDURE VitalMemoryInitPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ VARIABLE OutputData : IN STD_ULOGIC
+);
+
+-- ----------------------------------------------------------------------------
+--
+-- Function : VitalMemoryAddPathDelay
+--
+-- Arguments
+--
+-- INOUT Type Description
+--
+-- ScheduleDataArray/ VitalMemoryScheduleDataVectorType/
+-- ScheduleData VitalMemoryScheduleDataType
+-- Internal data variable for
+-- storing delay and schedule
+-- information for each output bit
+--
+-- InputChangeTimeArray/ VitaltimeArrayT/Time
+-- InputChangeTime Holds the time since the last
+-- input change
+--
+-- IN
+--
+-- InputSignal STD_LOGIC_VECTOR
+-- STD_ULOGIC/ Array holding the input value
+--
+-- OutputSignalName STRING The output signal name
+--
+-- PathDelayArray/ VitalDelayArrayType01ZX,
+-- PathDelay VitalDelayArrayType01Z,
+-- VitalDelayArrayType01,
+-- VitalDelayArrayType/
+-- VitalDelayType01ZX,
+-- VitalDelayType01Z,
+-- VitalDelayType01,
+-- VitalDelayType Array of delay values
+--
+-- ArcType VitalMemoryArcType
+-- Indicates the Path type. This
+-- can be SubwordArc, CrossArc or
+-- ParallelArc
+--
+-- PathCondition BOOLEAN If True, the transition in
+-- the corresponding input signal
+-- is considered while
+-- caluculating the prop. delay
+-- else the transition is ignored.
+--
+-- OutputRetainFlag BOOLEAN If specified TRUE,output retain
+-- (hold) behavior is implemented.
+--
+-- ----------------------------------------------------------------------------
+--
+-- #1
+-- DelayType - VitalDelayType
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelay : IN VitalDelayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #2
+-- DelayType - VitalDelayType
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #3
+-- DelayType - VitalDelayType
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT
+);
+
+-- #4
+-- DelayType - VitalDelayType
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #5
+-- DelayType - VitalDelayType
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #6
+-- DelayType - VitalDelayType
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+);
+
+-- #7
+-- DelayType - VitalDelayType01
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelay : IN VitalDelayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #8
+-- DelayType - VitalDelayType01
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #9
+-- DelayType - VitalDelayType01
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT
+);
+
+-- #10
+-- DelayType - VitalDelayType01
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #11
+-- DelayType - VitalDelayType01
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE
+);
+
+-- #12
+-- DelayType - VitalDelayType01
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT
+);
+
+-- #13
+-- DelayType - VitalDelayType01Z
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelay : IN VitalDelayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+);
+
+-- #14
+-- DelayType - VitalDelayType01Z
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+);
+
+-- #15
+-- DelayType - VitalDelayType01Z
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+);
+
+-- #16
+-- DelayType - VitalDelayType01Z
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+);
+
+-- #17
+-- DelayType - VitalDelayType01Z
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+);
+
+-- #18
+-- DelayType - VitalDelayType01Z
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01Z;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+);
+
+-- #19
+-- DelayType - VitalDelayType01ZX
+-- Input - Scalar
+-- Output - Scalar
+-- Delay - Scalar
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelay : IN VitalDelayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+);
+
+-- #20
+-- DelayType - VitalDelayType01ZX
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+);
+
+-- #21
+-- DelayType - VitalDelayType01ZX
+-- Input - Scalar
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_ULOGIC;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTime : INOUT Time;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray: IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE
+);
+
+-- #22
+-- DelayType - VitalDelayType01ZX
+-- Input - Vector
+-- Output - Scalar
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+);
+
+-- #23
+-- DelayType - VitalDelayType01ZX
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Scalar
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathCondition : IN BOOLEAN := TRUE;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+);
+
+-- #24
+-- DelayType - VitalDelayType01ZX
+-- Input - Vector
+-- Output - Vector
+-- Delay - Vector
+-- Condition - Vector
+
+PROCEDURE VitalMemoryAddPathDelay (
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType;
+ SIGNAL InputSignal : IN STD_LOGIC_VECTOR;
+ CONSTANT OutputSignalName : IN STRING := "";
+ VARIABLE InputChangeTimeArray : INOUT VitalTimeArrayT;
+ CONSTANT PathDelayArray : IN VitalDelayArrayType01ZX;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT PathConditionArray : IN VitalBoolArrayT;
+ CONSTANT OutputRetainFlag : IN BOOLEAN := FALSE;
+ CONSTANT OutputRetainBehavior : IN OutputRetainBehaviorType := BitCorrupt
+);
+
+-- ----------------------------------------------------------------------------
+--
+-- Function : VitalMemorySchedulePathDelay
+--
+-- Arguments:
+--
+-- OUT Type Description
+-- OutSignal STD_LOGIC_VECTOR/ The output signal for
+-- STD_ULOGIC scheduling
+--
+-- IN
+-- OutputSignalName STRING The name of the output signal
+--
+-- IN
+-- PortFlag VitalPortFlagType Port flag variable from
+-- functional procedures
+--
+-- IN
+-- OutputMap VitalOutputMapType For VitalPathDelay01Z, the
+-- output can be mapped to
+-- alternate strengths to model
+-- tri-state devices, pull-ups
+-- and pull-downs.
+--
+-- INOUT
+-- ScheduleDataArray/ VitalMemoryScheduleDataVectorType/
+-- ScheduleData VitalMemoryScheduleDataType
+-- Internal data variable for
+-- storing delay and schedule
+-- information for each
+-- output bit
+--
+-- ----------------------------------------------------------------------------
+--
+-- ScheduleDataArray - Vector
+-- OutputSignal - Vector
+--
+PROCEDURE VitalMemorySchedulePathDelay (
+ SIGNAL OutSignal : OUT std_logic_vector;
+ CONSTANT OutputSignalName : IN STRING := "";
+ CONSTANT PortFlag : IN VitalPortFlagType := VitalDefaultPortFlag;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType
+);
+--
+-- ScheduleDataArray - Vector
+-- OutputSignal - Vector
+--
+PROCEDURE VitalMemorySchedulePathDelay (
+ SIGNAL OutSignal : OUT std_logic_vector;
+ CONSTANT OutputSignalName : IN STRING := "";
+ CONSTANT PortFlag : IN VitalPortFlagVectorType;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ VARIABLE ScheduleDataArray : INOUT VitalMemoryScheduleDataVectorType
+);
+--
+-- ScheduleDataArray - Scalar
+-- OutputSignal - Scalar
+--
+PROCEDURE VitalMemorySchedulePathDelay (
+ SIGNAL OutSignal : OUT std_ulogic;
+ CONSTANT OutputSignalName : IN STRING := "";
+ CONSTANT PortFlag : IN VitalPortFlagType := VitalDefaultPortFlag;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ VARIABLE ScheduleData : INOUT VitalMemoryScheduleDataType
+);
+
+-- ----------------------------------------------------------------------------
+FUNCTION VitalMemoryTimingDataInit RETURN VitalMemoryTimingDataType;
+
+-- ----------------------------------------------------------------------------
+--
+-- Function Name: VitalMemorySetupHoldCheck
+--
+-- Description: The VitalMemorySetupHoldCheck procedure detects a setup or a
+-- hold violation on the input test signal with respect
+-- to the corresponding input reference signal. The timing
+-- constraints are specified through parameters
+-- representing the high and low values for the setup and
+-- hold values for the setup and hold times. This
+-- procedure assumes non-negative values for setup and hold
+-- timing constraints.
+--
+-- It is assumed that negative timing constraints
+-- are handled by internally delaying the test or
+-- reference signals. Negative setup times result in
+-- a delayed reference signal. Negative hold times
+-- result in a delayed test signal. Furthermore, the
+-- delays and constraints associated with these and
+-- other signals may need to be appropriately
+-- adjusted so that all constraint intervals overlap
+-- the delayed reference signals and all constraint
+-- values (with respect to the delayed signals) are
+-- non-negative.
+--
+-- This function is overloaded based on the input
+-- TestSignal and reference signals. Parallel, Subword and
+-- Cross Arc relationships between test and reference
+-- signals are supported.
+--
+-- TestSignal XXXXXXXXXXXX____________________________XXXXXXXXXXXXXXXXXXXXXX
+-- :
+-- : -->| error region |<--
+-- :
+-- _______________________________
+-- RefSignal \______________________________
+-- : | | |
+-- : | -->| |<-- thold
+-- : -->| tsetup |<--
+--
+-- Arguments:
+--
+-- IN Type Description
+-- TestSignal std_logic_vector Value of test signal
+-- TestSignalName STRING Name of test signal
+-- TestDelay VitalDelayArrayType Model's internal delay associated
+-- with TestSignal
+-- RefSignal std_ulogic Value of reference signal
+-- std_logic_vector
+-- RefSignalName STRING Name of reference signal
+-- RefDelay TIME Model's internal delay associated
+-- VitalDelayArrayType with RefSignal
+-- SetupHigh VitalDelayArrayType Absolute minimum time duration
+-- before the transition of RefSignal
+-- for which transitions of
+-- TestSignal are allowed to proceed
+-- to the "1" state without causing
+-- a setup violation.
+-- SetupLow VitalDelayArrayType Absolute minimum time duration
+-- before the transition of RefSignal
+-- for which transitions of
+-- TestSignal are allowed to proceed
+-- to the "0" state without causing
+-- a setup violation.
+-- HoldHigh VitalDelayArrayType Absolute minimum time duration
+-- after the transition of RefSignal
+-- for which transitions of
+-- TestSignal are allowed to
+-- proceed to the "1" state without
+-- causing a hold violation.
+-- HoldLow VitalDelayArrayType Absolute minimum time duration
+-- after the transition of RefSignal
+-- for which transitions of
+-- TestSignal are allowed to
+-- proceed to the "0" state without
+-- causing a hold violation.
+-- CheckEnabled BOOLEAN Check performed if TRUE.
+-- RefTransition VitalEdgeSymbolType
+-- Reference edge specified. Events
+-- on the RefSignal which match the
+-- edge spec. are used as reference
+-- edges.
+-- ArcType VitalMemoryArcType
+-- NumBitsPerSubWord INTEGER
+-- HeaderMsg STRING String that will accompany any
+-- assertion messages produced.
+-- XOn BOOLEAN If TRUE, Violation output
+-- parameter is set to "X".
+-- Otherwise, Violation is always
+-- set to "0."
+-- MsgOn BOOLEAN If TRUE, set and hold violation
+-- message will be generated.
+-- Otherwise, no messages are
+-- generated, even upon violations.
+-- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+-- MsgFormat VitalMemoryMsgFormatType
+-- Format of the Test/Reference
+-- signals in violation messages.
+--
+-- INOUT
+-- TimingData VitalMemoryTimingDataType
+-- VitalMemorySetupHoldCheck information
+-- storage area. This is used
+-- internally to detect reference
+-- edges and record the time of the
+-- last edge.
+--
+-- OUT
+-- Violation X01 This is the violation flag returned.
+-- X01ArrayT Overloaded for array type.
+--
+--
+-- ----------------------------------------------------------------------------
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayType;
+ CONSTANT SetupLow : IN VitalDelayType;
+ CONSTANT HoldHigh : IN VitalDelayType;
+ CONSTANT HoldLow : IN VitalDelayType;
+ CONSTANT CheckEnabled : IN VitalBoolArrayT;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayArrayType;
+ CONSTANT SetupLow : IN VitalDelayArrayType;
+ CONSTANT HoldHigh : IN VitalDelayArrayType;
+ CONSTANT HoldLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayArrayType;
+ CONSTANT SetupLow : IN VitalDelayArrayType;
+ CONSTANT HoldHigh : IN VitalDelayArrayType;
+ CONSTANT HoldLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN VitalBoolArrayT;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN VitalDelayArrayType;
+ CONSTANT SetupHigh : IN VitalDelayArrayType;
+ CONSTANT SetupLow : IN VitalDelayArrayType;
+ CONSTANT HoldHigh : IN VitalDelayArrayType;
+ CONSTANT HoldLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN VitalDelayArrayType;
+ CONSTANT SetupHigh : IN VitalDelayArrayType;
+ CONSTANT SetupLow : IN VitalDelayArrayType;
+ CONSTANT HoldHigh : IN VitalDelayArrayType;
+ CONSTANT HoldLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN VitalBoolArrayT;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+--------------- following are not needed --------------------------
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN VitalDelayArrayType;
+ CONSTANT SetupLow : IN VitalDelayArrayType;
+ CONSTANT HoldHigh : IN VitalDelayArrayType;
+ CONSTANT HoldLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+PROCEDURE VitalMemorySetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalMemoryTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ SIGNAL RefSignal : IN std_logic_vector;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN VitalDelayArrayType;
+ CONSTANT SetupHigh : IN VitalDelayArrayType;
+ CONSTANT SetupLow : IN VitalDelayArrayType;
+ CONSTANT HoldHigh : IN VitalDelayArrayType;
+ CONSTANT HoldLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT ArcType : IN VitalMemoryArcType := CrossArc;
+ CONSTANT NumBitsPerSubWord : IN INTEGER := 1;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE;
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE;
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE
+);
+
+
+-- ----------------------------------------------------------------------------
+--
+-- Function Name: VitalPeriodPulseCheck
+--
+-- Description: VitalPeriodPulseCheck checks for minimum and maximum
+-- periodicity and pulse width for "1" and "0" values of
+-- the input test signal. The timing constraint is
+-- specified through parameters representing the minimal
+-- period between successive rising and falling edges of
+-- the input test signal and the minimum pulse widths
+-- associated with high and low values.
+--
+-- VitalPeriodCheck's accepts rising and falling edges
+-- from 1 and 0 as well as transitions to and from 'X.'
+--
+-- _______________ __________
+-- ____________| |_______|
+--
+-- |<--- pw_hi --->|
+-- |<-------- period ----->|
+-- -->| pw_lo |<--
+--
+-- Arguments:
+-- IN Type Description
+-- TestSignal std_logic_vector Value of test signal
+-- TestSignalName STRING Name of the test signal
+-- TestDelay VitalDelayArrayType
+-- Model's internal delay associated
+-- with TestSignal
+-- Period VitalDelayArrayType
+-- Minimum period allowed between
+-- consecutive rising ('P') or
+-- falling ('F') transitions.
+-- PulseWidthHigh VitalDelayArrayType
+-- Minimum time allowed for a high
+-- pulse ('1' or 'H')
+-- PulseWidthLow VitalDelayArrayType
+-- Minimum time allowed for a low
+-- pulse ('0' or 'L')
+-- CheckEnabled BOOLEAN Check performed if TRUE.
+-- HeaderMsg STRING String that will accompany any
+-- assertion messages produced.
+-- XOn BOOLEAN If TRUE, Violation output parameter
+-- is set to "X". Otherwise, Violation
+-- is always set to "0."
+-- MsgOn BOOLEAN If TRUE, period/pulse violation
+-- message will be generated.
+-- Otherwise, no messages are generated,
+-- even though a violation is detected.
+-- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+-- MsgFormat VitalMemoryMsgFormatType
+-- Format of the Test/Reference signals
+-- in violation messages.
+--
+-- INOUT
+-- PeriodData VitalPeriodDataArrayType
+-- VitalPeriodPulseCheck information
+-- storage area. This is used
+-- internally to detect reference edges
+-- and record the pulse and period
+-- times.
+-- OUT
+-- Violation X01 This is the violation flag returned.
+-- X01ArrayT Overloaded for array type.
+--
+-- ----------------------------------------------------------------------------
+PROCEDURE VitalMemoryPeriodPulseCheck (
+ VARIABLE Violation : OUT X01ArrayT;
+ VARIABLE PeriodData : INOUT VitalPeriodDataArrayType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ CONSTANT Period : IN VitalDelayArrayType;
+ CONSTANT PulseWidthHigh : IN VitalDelayArrayType;
+ CONSTANT PulseWidthLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType
+);
+
+PROCEDURE VitalMemoryPeriodPulseCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE PeriodData : INOUT VitalPeriodDataArrayType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN VitalDelayArrayType;
+ CONSTANT Period : IN VitalDelayArrayType;
+ CONSTANT PulseWidthHigh : IN VitalDelayArrayType;
+ CONSTANT PulseWidthLow : IN VitalDelayArrayType;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT MsgFormat : IN VitalMemoryMsgFormatType
+);
+
+-- ----------------------------------------------------------------------------
+-- Functionality Section
+-- ----------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------
+-- All Memory Types and Record definitions.
+-- ----------------------------------------------------------------------------
+TYPE MemoryWordType IS ARRAY (NATURAL RANGE <>) OF UX01;
+TYPE MemoryWordPtr IS ACCESS MemoryWordType;
+
+TYPE MemoryArrayType IS ARRAY (NATURAL RANGE <>) OF MemoryWordPtr;
+TYPE MemoryArrayPtrType IS ACCESS MemoryArrayType;
+
+TYPE VitalMemoryArrayRecType IS
+RECORD
+NoOfWords : POSITIVE;
+NoOfBitsPerWord : POSITIVE;
+NoOfBitsPerSubWord : POSITIVE;
+NoOfBitsPerEnable : POSITIVE;
+MemoryArrayPtr : MemoryArrayPtrType;
+END RECORD;
+
+TYPE VitalMemoryDataType IS ACCESS VitalMemoryArrayRecType;
+
+TYPE VitalTimingDataVectorType IS
+ARRAY (NATURAL RANGE <>) OF VitalTimingDataType;
+
+TYPE VitalMemoryViolFlagSizeType IS ARRAY (NATURAL RANGE <>) OF INTEGER;
+
+-- ----------------------------------------------------------------------------
+-- Symbol Literals used for Memory Table Modeling
+-- ----------------------------------------------------------------------------
+
+-- Symbol literals from '/' to 'S' are closely related to MemoryTableMatch
+-- lookup matching and the order cannot be arbitrarily changed.
+-- The remaining symbol literals are interpreted directly and matchting is
+-- handled in the MemoryMatch procedure itself.
+
+TYPE VitalMemorySymbolType IS (
+ '/', -- 0 -> 1
+ '\', -- 1 -> 0
+ 'P', -- Union of '/' and '^' (any edge to 1)
+ 'N', -- Union of '\' and 'v' (any edge to 0)
+ 'r', -- 0 -> X
+ 'f', -- 1 -> X
+ 'p', -- Union of '/' and 'r' (any edge from 0)
+ 'n', -- Union of '\' and 'f' (any edge from 1)
+ 'R', -- Union of '^' and 'p' (any possible rising edge)
+ 'F', -- Union of 'v' and 'n' (any possible falling edge)
+ '^', -- X -> 1
+ 'v', -- X -> 0
+ 'E', -- Union of 'v' and '^' (any edge from X)
+ 'A', -- Union of 'r' and '^' (rising edge to or from 'X')
+
+ 'D', -- Union of 'f' and 'v' (falling edge to or from 'X')
+
+ '*', -- Union of 'R' and 'F' (any edge)
+ 'X', -- Unknown level
+ '0', -- low level
+ '1', -- high level
+ '-', -- don't care
+ 'B', -- 0 or 1
+ 'Z', -- High Impedance
+ 'S', -- steady value
+
+ 'g', -- Good address (no transition)
+ 'u', -- Unknown address (no transition)
+ 'i', -- Invalid address (no transition)
+ 'G', -- Good address (with transition)
+ 'U', -- Unknown address (with transition)
+ 'I', -- Invalid address (with transition)
+
+ 'w', -- Write data to memory
+ 's', -- Retain previous memory contents
+
+ 'c', -- Corrupt entire memory with 'X'
+ 'l', -- Corrupt a word in memory with 'X'
+ 'd', -- Corrupt a single bit in memory with 'X'
+ 'e', -- Corrupt a word with 'X' based on data in
+ 'C', -- Corrupt a sub-word entire memory with 'X'
+ 'L', -- Corrupt a sub-word in memory with 'X'
+
+ -- The following entries are commented since their
+ -- interpretation overlap with existing definitions.
+
+ -- 'D', -- Corrupt a single bit of a sub-word with 'X'
+ -- 'E', -- Corrupt a sub-word with 'X' based on datain
+
+ 'M', -- Implicit read data from memory
+ 'm', -- Read data from memory
+ 't' -- Immediate assign/transfer data in
+
+);
+
+TYPE VitalMemoryTableType IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> )
+ OF VitalMemorySymbolType;
+
+TYPE VitalMemoryViolationSymbolType IS (
+ 'X', -- Unknown level
+ '0', -- low level
+ '-' -- don't care
+);
+
+TYPE VitalMemoryViolationTableType IS
+ ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> )
+ OF VitalMemoryViolationSymbolType;
+
+TYPE VitalPortType IS (
+ UNDEF,
+ READ,
+ WRITE,
+ RDNWR
+);
+
+TYPE VitalCrossPortModeType IS (
+ CpRead, -- CpReadOnly,
+ WriteContention, -- WrContOnly,
+ ReadWriteContention, -- CpContention
+ CpReadAndWriteContention, -- WrContAndCpRead,
+ CpReadAndReadContention
+);
+
+SUBTYPE VitalAddressValueType IS INTEGER;
+TYPE VitalAddressValueVectorType IS
+ ARRAY (NATURAL RANGE <>) OF VitalAddressValueType;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalDeclareMemory
+-- Parameters: NoOfWords - Number of words in the memory
+-- NoOfBitsPerWord - Number of bits per word in memory
+-- NoOfBitsPerSubWord - Number of bits per sub word
+-- MemoryLoadFile - Name of data file to load
+-- Description: This function is intended to be used to initialize
+-- memory data declarations, i.e. to be executed duing
+-- simulation elaboration time. Handles the allocation
+-- and initialization of memory for the memory data.
+-- Default NoOfBitsPerSubWord is NoOfBits.
+-- ----------------------------------------------------------------------------
+
+IMPURE FUNCTION VitalDeclareMemory (
+ CONSTANT NoOfWords : IN POSITIVE;
+ CONSTANT NoOfBitsPerWord : IN POSITIVE;
+ CONSTANT NoOfBitsPerSubWord : IN POSITIVE;
+ CONSTANT MemoryLoadFile : IN string := "";
+ CONSTANT BinaryLoadFile : IN BOOLEAN := FALSE
+) RETURN VitalMemoryDataType;
+
+IMPURE FUNCTION VitalDeclareMemory (
+ CONSTANT NoOfWords : IN POSITIVE;
+ CONSTANT NoOfBitsPerWord : IN POSITIVE;
+ CONSTANT MemoryLoadFile : IN string := "";
+ CONSTANT BinaryLoadFile : IN BOOLEAN := FALSE
+) RETURN VitalMemoryDataType;
+
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryTable
+-- Parameters: DataOutBus - Output candidate zero delay data bus out
+-- MemoryData - Pointer to memory data structure
+-- PrevControls - Previous data in for edge detection
+-- PrevEnableBus - Previous enables for edge detection
+-- PrevDataInBus - Previous data bus for edge detection
+-- PrevAddressBus - Previous address bus for edge detection
+-- PortFlag - Indicates port operating mode
+-- PortFlagArray - Vector form of PortFlag for sub-word
+-- Controls - Agregate of scalar control lines
+-- EnableBus - Concatenation of vector control lines
+-- DataInBus - Input value of data bus in
+-- AddressBus - Input value of address bus in
+-- AddressValue - Decoded value of the AddressBus
+-- MemoryTable - Input memory action table
+-- PortType - The type of port (currently not used)
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control the generation of messages
+-- MsgSeverity - Control level of message generation
+-- Description: This procedure implements the majority of the memory
+-- modeling functionality via lookup of the memory action
+-- tables and performing the specified actions if matches
+-- are found, or the default actions otherwise. The
+-- overloadings are provided for the word and sub-word
+-- (using the EnableBus and PortFlagArray arguments) addressing
+-- cases.
+-- ----------------------------------------------------------------------------
+
+PROCEDURE VitalMemoryTable (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PrevControls : INOUT std_logic_vector;
+ VARIABLE PrevDataInBus : INOUT std_logic_vector;
+ VARIABLE PrevAddressBus : INOUT std_logic_vector;
+ VARIABLE PortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT Controls : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressBus : IN std_logic_vector;
+ VARIABLE AddressValue : INOUT VitalAddressValueType;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType := UNDEF;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+);
+
+PROCEDURE VitalMemoryTable (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PrevControls : INOUT std_logic_vector;
+ VARIABLE PrevEnableBus : INOUT std_logic_vector;
+ VARIABLE PrevDataInBus : INOUT std_logic_vector;
+ VARIABLE PrevAddressBus : INOUT std_logic_vector;
+ VARIABLE PortFlagArray : INOUT VitalPortFlagVectorType;
+ CONSTANT Controls : IN std_logic_vector;
+ CONSTANT EnableBus : IN std_logic_vector;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressBus : IN std_logic_vector;
+ VARIABLE AddressValue : INOUT VitalAddressValueType;
+ CONSTANT MemoryTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType := UNDEF;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+);
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryCrossPorts
+-- Parameters: DataOutBus - Output candidate zero delay data bus out
+-- MemoryData - Pointer to memory data structure
+-- SamePortFlag - Operating mode for same port
+-- SamePortAddressValue - Decoded AddressBus for same port
+-- CrossPortFlagArray - Operating modes for cross ports
+-- CrossPortAddressArray - Decoded AddressBus for cross ports
+-- CrossPortMode - Write contention and crossport read control
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control the generation of messages
+--
+-- Description: These procedures control the effect of memory operations
+-- on a given port due to operations on other ports in a
+-- multi-port memory.
+-- This includes data write through when reading and writing
+-- to the same address, as well as write contention when
+-- there are multiple write to the same address.
+-- If addresses do not match then data bus is unchanged.
+-- The DataOutBus can be diabled with 'Z' value.
+-- ----------------------------------------------------------------------------
+
+PROCEDURE VitalMemoryCrossPorts (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE SamePortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT SamePortAddressValue : IN VitalAddressValueType;
+ CONSTANT CrossPortFlagArray : IN VitalPortFlagVectorType;
+ CONSTANT CrossPortAddressArray : IN VitalAddressValueVectorType;
+ CONSTANT CrossPortMode : IN VitalCrossPortModeType
+ := CpReadAndWriteContention;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) ;
+
+PROCEDURE VitalMemoryCrossPorts (
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ CONSTANT CrossPortFlagArray : IN VitalPortFlagVectorType;
+ CONSTANT CrossPortAddressArray : IN VitalAddressValueVectorType;
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE
+) ;
+
+-- ----------------------------------------------------------------------------
+-- Procedure: VitalMemoryViolation
+-- Parameters: DataOutBus - Output zero delay data bus out
+-- MemoryData - Pointer to memory data structure
+-- PortFlag - Indicates port operating mode
+-- DataInBus - Input value of data bus in
+-- AddressValue - Decoded value of the AddressBus
+-- ViolationFlags - Aggregate of scalar violation vars
+-- ViolationFlagsArray - Concatenation of vector violation vars
+-- ViolationTable - Input memory violation table
+-- PortType - The type of port (currently not used)
+-- PortName - Port name string for messages
+-- HeaderMsg - Header string for messages
+-- MsgOn - Control the generation of messages
+-- MsgSeverity - Control level of message generation
+-- Description: This procedure is intended to implement all actions on the
+-- memory contents and data out bus as a result of timing viols.
+-- It uses the memory action table to perform various corruption
+-- policies specified by the user.
+-- ----------------------------------------------------------------------------
+
+PROCEDURE VitalMemoryViolation (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressValue : IN VitalAddressValueType;
+ CONSTANT ViolationFlags : IN std_logic_vector;
+ CONSTANT ViolationFlagsArray : IN X01ArrayT;
+ CONSTANT ViolationSizesArray : IN VitalMemoryViolFlagSizeType;
+ CONSTANT ViolationTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) ;
+
+PROCEDURE VitalMemoryViolation (
+ VARIABLE DataOutBus : INOUT std_logic_vector;
+ VARIABLE MemoryData : INOUT VitalMemoryDataType;
+ VARIABLE PortFlag : INOUT VitalPortFlagVectorType;
+ CONSTANT DataInBus : IN std_logic_vector;
+ CONSTANT AddressValue : IN VitalAddressValueType;
+ CONSTANT ViolationFlags : IN std_logic_vector;
+ CONSTANT ViolationTable : IN VitalMemoryTableType;
+ CONSTANT PortType : IN VitalPortType;
+ CONSTANT PortName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := "";
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+) ;
+
+END Vital_Memory;
diff --git a/libraries/vital2000/prmtvs_b.vhdl b/libraries/vital2000/prmtvs_b.vhdl
new file mode 100644
index 000000000..c015e62d5
--- /dev/null
+++ b/libraries/vital2000/prmtvs_b.vhdl
@@ -0,0 +1,5622 @@
+-------------------------------------------------------------------------------
+-- Title : Standard VITAL_Primitives Package
+-- : $Revision: 600 $
+-- :
+-- Library : VITAL
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, constants, functions
+-- : and procedures for use in developing ASIC models.
+-- : Specifically a set of logic primitives are defined.
+-- :
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/02/95 | Initial ballot draft 1995
+-- v95.1 | | 08/31/95 | #204 - glitch detection prior to OutputMap
+-- ----------------------------------------------------------------------------
+-- v95.2 | ddl | 09/14/96 | #223 - single input prmtvs use on-detect
+-- | | | instead of glitch-on-event behavior
+-- v95.3 | ddl | 09/24/96 | #236 - VitalTruthTable DataIn should be of
+-- | | | of class SIGNAL
+-- v95.4 | ddl | 01/16/97 | #243 - index constraint error in nbit xor/xnor
+-- v99.1 | dbb | 03/31/99 | Updated for VHDL 93
+-- ----------------------------------------------------------------------------
+
+LIBRARY STD;
+USE STD.TEXTIO.ALL;
+
+PACKAGE BODY VITAL_Primitives IS
+ -- ------------------------------------------------------------------------
+ -- Default values for Primitives
+ -- ------------------------------------------------------------------------
+ -- default values for delay parameters
+ CONSTANT VitalDefDelay01 : VitalDelayType01 := VitalZeroDelay01;
+ CONSTANT VitalDefDelay01Z : VitalDelayType01Z := VitalZeroDelay01Z;
+
+ TYPE VitalTimeArray IS ARRAY (NATURAL RANGE <>) OF TIME;
+
+ -- default primitive model operation parameters
+ -- Glitch detection/reporting
+ TYPE VitalGlitchModeType IS ( MessagePlusX, MessageOnly, XOnly, NoGlitch);
+ CONSTANT PrimGlitchMode : VitalGlitchModeType := XOnly;
+
+ -- ------------------------------------------------------------------------
+ -- Local Type and Subtype Declarations
+ -- ------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- enumeration value representing the transition or level of the signal.
+ -- See function 'GetEdge'
+ ---------------------------------------------------------------------------
+ TYPE EdgeType IS ( 'U', -- Uninitialized level
+ 'X', -- Unknown level
+ '0', -- low level
+ '1', -- high level
+ '\', -- 1 to 0 falling edge
+ '/', -- 0 to 1 rising edge
+ 'F', -- * to 0 falling edge
+ 'R', -- * to 1 rising edge
+ 'f', -- rising to X edge
+ 'r', -- falling to X edge
+ 'x', -- Unknown edge (ie U->X)
+ 'V' -- Timing violation edge
+ );
+ TYPE EdgeArray IS ARRAY ( NATURAL RANGE <> ) OF EdgeType;
+
+ TYPE EdgeX1Table IS ARRAY ( EdgeType ) OF EdgeType;
+ TYPE EdgeX2Table IS ARRAY ( EdgeType, EdgeType ) OF EdgeType;
+ TYPE EdgeX3Table IS ARRAY ( EdgeType, EdgeType, EdgeType ) OF EdgeType;
+ TYPE EdgeX4Table IS ARRAY (EdgeType,EdgeType,EdgeType,EdgeType) OF EdgeType;
+
+ TYPE LogicToEdgeT IS ARRAY(std_ulogic, std_ulogic) OF EdgeType;
+ TYPE LogicToLevelT IS ARRAY(std_ulogic ) OF EdgeType;
+
+ TYPE GlitchDataType IS
+ RECORD
+ SchedTime : TIME;
+ GlitchTime : TIME;
+ SchedValue : std_ulogic;
+ CurrentValue : std_ulogic;
+ END RECORD;
+ TYPE GlitchDataArrayType IS ARRAY (NATURAL RANGE <>)
+ OF GlitchDataType;
+
+ -- Enumerated type used in selection of output path delays
+ TYPE SchedType IS
+ RECORD
+ inp0 : TIME; -- time (abs) of output change due to input change to 0
+ inp1 : TIME; -- time (abs) of output change due to input change to 1
+ InpX : TIME; -- time (abs) of output change due to input change to X
+ Glch0 : TIME; -- time (abs) of output glitch due to input change to 0
+ Glch1 : TIME; -- time (abs) of output glitch due to input change to 0
+ END RECORD;
+
+ TYPE SchedArray IS ARRAY ( NATURAL RANGE <> ) OF SchedType;
+ CONSTANT DefSchedType : SchedType := (TIME'HIGH, TIME'HIGH, 0 ns,0 ns,0 ns);
+ CONSTANT DefSchedAnd : SchedType := (TIME'HIGH, 0 ns,0 ns, TIME'HIGH,0 ns);
+
+ -- Constrained array declarations (common sizes used by primitives)
+ SUBTYPE SchedArray2 IS SchedArray(1 DOWNTO 0);
+ SUBTYPE SchedArray3 IS SchedArray(2 DOWNTO 0);
+ SUBTYPE SchedArray4 IS SchedArray(3 DOWNTO 0);
+ SUBTYPE SchedArray8 IS SchedArray(7 DOWNTO 0);
+
+ SUBTYPE TimeArray2 IS VitalTimeArray(1 DOWNTO 0);
+ SUBTYPE TimeArray3 IS VitalTimeArray(2 DOWNTO 0);
+ SUBTYPE TimeArray4 IS VitalTimeArray(3 DOWNTO 0);
+ SUBTYPE TimeArray8 IS VitalTimeArray(7 DOWNTO 0);
+
+ SUBTYPE GlitchArray2 IS GlitchDataArrayType(1 DOWNTO 0);
+ SUBTYPE GlitchArray3 IS GlitchDataArrayType(2 DOWNTO 0);
+ SUBTYPE GlitchArray4 IS GlitchDataArrayType(3 DOWNTO 0);
+ SUBTYPE GlitchArray8 IS GlitchDataArrayType(7 DOWNTO 0);
+
+ SUBTYPE EdgeArray2 IS EdgeArray(1 DOWNTO 0);
+ SUBTYPE EdgeArray3 IS EdgeArray(2 DOWNTO 0);
+ SUBTYPE EdgeArray4 IS EdgeArray(3 DOWNTO 0);
+ SUBTYPE EdgeArray8 IS EdgeArray(7 DOWNTO 0);
+
+ CONSTANT DefSchedArray2 : SchedArray2 :=
+ (OTHERS=> (0 ns, 0 ns, 0 ns, 0 ns, 0 ns));
+
+ TYPE stdlogic_table IS ARRAY(std_ulogic, std_ulogic) OF std_ulogic;
+
+ CONSTANT InitialEdge : LogicToLevelT := (
+ '1'|'H' => 'R',
+ '0'|'L' => 'F',
+ OTHERS => 'x'
+ );
+
+ CONSTANT LogicToEdge : LogicToEdgeT := ( -- previous, current
+ -- old \ new: U X 0 1 Z W L H -
+ 'U' => ( 'U', 'x', 'F', 'R', 'x', 'x', 'F', 'R', 'x' ),
+ 'X' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ),
+ '0' => ( 'r', 'r', '0', '/', 'r', 'r', '0', '/', 'r' ),
+ '1' => ( 'f', 'f', '\', '1', 'f', 'f', '\', '1', 'f' ),
+ 'Z' => ( 'x', 'X', 'F', 'R', 'X', 'x', 'F', 'R', 'x' ),
+ 'W' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' ),
+ 'L' => ( 'r', 'r', '0', '/', 'r', 'r', '0', '/', 'r' ),
+ 'H' => ( 'f', 'f', '\', '1', 'f', 'f', '\', '1', 'f' ),
+ '-' => ( 'x', 'X', 'F', 'R', 'x', 'X', 'F', 'R', 'X' )
+ );
+ CONSTANT LogicToLevel : LogicToLevelT := (
+ '1'|'H' => '1',
+ '0'|'L' => '0',
+ 'U' => 'U',
+ OTHERS => 'X'
+ );
+
+ -- -----------------------------------
+ -- 3-state logic tables
+ -- -----------------------------------
+ CONSTANT BufIf0_Table : stdlogic_table :=
+ -- enable data value
+ ( '1'|'H' => ( OTHERS => 'Z' ),
+ '0'|'L' => ( '1'|'H' => '1',
+ '0'|'L' => '0',
+ 'U' => 'U',
+ OTHERS => 'X' ),
+ 'U' => ( OTHERS => 'U' ),
+ OTHERS => ( OTHERS => 'X' ) );
+ CONSTANT BufIf1_Table : stdlogic_table :=
+ -- enable data value
+ ( '0'|'L' => ( OTHERS => 'Z' ),
+ '1'|'H' => ( '1'|'H' => '1',
+ '0'|'L' => '0',
+ 'U' => 'U',
+ OTHERS => 'X' ),
+ 'U' => ( OTHERS => 'U' ),
+ OTHERS => ( OTHERS => 'X' ) );
+ CONSTANT InvIf0_Table : stdlogic_table :=
+ -- enable data value
+ ( '1'|'H' => ( OTHERS => 'Z' ),
+ '0'|'L' => ( '1'|'H' => '0',
+ '0'|'L' => '1',
+ 'U' => 'U',
+ OTHERS => 'X' ),
+ 'U' => ( OTHERS => 'U' ),
+ OTHERS => ( OTHERS => 'X' ) );
+ CONSTANT InvIf1_Table : stdlogic_table :=
+ -- enable data value
+ ( '0'|'L' => ( OTHERS => 'Z' ),
+ '1'|'H' => ( '1'|'H' => '0',
+ '0'|'L' => '1',
+ 'U' => 'U',
+ OTHERS => 'X' ),
+ 'U' => ( OTHERS => 'U' ),
+ OTHERS => ( OTHERS => 'X' ) );
+
+
+ TYPE To_StateCharType IS ARRAY (VitalStateSymbolType) OF CHARACTER;
+ CONSTANT To_StateChar : To_StateCharType :=
+ ( '/', '\', 'P', 'N', 'r', 'f', 'p', 'n', 'R', 'F', '^', 'v',
+ 'E', 'A', 'D', '*', 'X', '0', '1', '-', 'B', 'Z', 'S' );
+ TYPE To_TruthCharType IS ARRAY (VitalTruthSymbolType) OF CHARACTER;
+ CONSTANT To_TruthChar : To_TruthCharType :=
+ ( 'X', '0', '1', '-', 'B', 'Z' );
+
+ TYPE TruthTableOutMapType IS ARRAY (VitalTruthSymbolType) OF std_ulogic;
+ CONSTANT TruthTableOutMap : TruthTableOutMapType :=
+ -- 'X', '0', '1', '-', 'B', 'Z'
+ ( 'X', '0', '1', 'X', '-', 'Z' );
+
+ TYPE StateTableOutMapType IS ARRAY (VitalStateSymbolType) OF std_ulogic;
+ -- does conversion to X01Z or '-' if invalid
+ CONSTANT StateTableOutMap : StateTableOutMapType :=
+ -- '/' '\' 'P' 'N' 'r' 'f' 'p' 'n' 'R' 'F' '^' 'v'
+ -- 'E' 'A' 'D' '*' 'X' '0' '1' '-' 'B' 'Z' 'S'
+ ( '-','-','-','-','-','-','-','-','-','-','-','-',
+ '-','-','-','-','X','0','1','X','-','Z','W');
+
+ -- ------------------------------------------------------------------------
+ TYPE ValidTruthTableInputType IS ARRAY (VitalTruthSymbolType) OF BOOLEAN;
+ -- checks if a symbol IS valid for the stimulus portion of a truth table
+ CONSTANT ValidTruthTableInput : ValidTruthTableInputType :=
+ -- 'X' '0' '1' '-' 'B' 'Z'
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, FALSE );
+
+ TYPE TruthTableMatchType IS ARRAY (X01, VitalTruthSymbolType) OF BOOLEAN;
+ -- checks if an input matches th corresponding truth table symbol
+ -- use: TruthTableMatch(input_converted_to_X01, truth_table_stimulus_symbol)
+ CONSTANT TruthTableMatch : TruthTableMatchType := (
+ -- X, 0, 1, - B Z
+ ( TRUE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- X
+ ( FALSE, TRUE, FALSE, TRUE, TRUE, FALSE ), -- 0
+ ( FALSE, FALSE, TRUE, TRUE, TRUE, FALSE ) -- 1
+ );
+
+ -- ------------------------------------------------------------------------
+ TYPE ValidStateTableInputType IS ARRAY (VitalStateSymbolType) OF BOOLEAN;
+ CONSTANT ValidStateTableInput : ValidStateTableInputType :=
+ -- '/', '\', 'P', 'N', 'r', 'f',
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
+ -- 'p', 'n', 'R', 'F', '^', 'v',
+ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
+ -- 'E', 'A', 'D', '*',
+ TRUE, TRUE, TRUE, TRUE,
+ -- 'X', '0', '1', '-', 'B', 'Z',
+ TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,
+ -- 'S'
+ TRUE );
+
+ CONSTANT ValidStateTableState : ValidStateTableInputType :=
+ -- '/', '\', 'P', 'N', 'r', 'f',
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+ -- 'p', 'n', 'R', 'F', '^', 'v',
+ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+ -- 'E', 'A', 'D', '*',
+ FALSE, FALSE, FALSE, FALSE,
+ -- 'X', '0', '1', '-', 'B', 'Z',
+ TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,
+ -- 'S'
+ FALSE );
+
+ TYPE StateTableMatchType IS ARRAY (X01,X01,VitalStateSymbolType) OF BOOLEAN;
+ -- last value, present value, table symbol
+ CONSTANT StateTableMatch : StateTableMatchType := (
+ ( -- X (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE),
+ (FALSE,FALSE,FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE, FALSE,TRUE,
+ TRUE, FALSE,TRUE, TRUE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE),
+ (FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,TRUE, FALSE,TRUE, FALSE,
+ TRUE, TRUE, FALSE,TRUE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE)
+ ),
+
+ (-- 0 (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ (FALSE,FALSE,FALSE,FALSE,TRUE, FALSE,
+ TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE),
+ (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,TRUE ),
+ (TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ TRUE, FALSE,TRUE, FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,FALSE)
+ ),
+
+ (-- 1 (lastvalue)
+ -- / \ P N r f
+ -- p n R F ^ v
+ -- E A D *
+ -- X 0 1 - B Z S
+ (FALSE,FALSE,FALSE,FALSE,FALSE,TRUE ,
+ FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,TRUE, TRUE,
+ TRUE, FALSE,FALSE,TRUE, FALSE,FALSE,FALSE),
+ (FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,TRUE, FALSE,TRUE, FALSE,FALSE,
+ FALSE,FALSE,FALSE,TRUE,
+ FALSE,TRUE, FALSE,TRUE, TRUE, FALSE,FALSE),
+ (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,FALSE,FALSE,
+ FALSE,FALSE,TRUE, TRUE, TRUE, FALSE,TRUE )
+ )
+ );
+
+ TYPE Logic_UX01Z_Table IS ARRAY (std_ulogic) OF UX01Z;
+ ----------------------------------------------------------
+ -- table name : cvt_to_x01z
+ -- parameters : std_ulogic -- some logic value
+ -- returns : UX01Z -- state value of logic value
+ -- purpose : to convert state-strength to state only
+ ----------------------------------------------------------
+ CONSTANT cvt_to_ux01z : Logic_UX01Z_Table :=
+ ('U','X','0','1','Z','X','0','1','X' );
+
+ TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER;
+ CONSTANT LogicCvtTable : LogicCvtTableType
+ := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
+
+ --------------------------------------------------------------------
+ -- LOCAL Utilities
+ --------------------------------------------------------------------
+ -- ------------------------------------------------------------------------
+ -- FUNCTION NAME : MINIMUM
+ --
+ -- PARAMETERS : in1, in2 - integer, time
+ --
+ -- DESCRIPTION : return smaller of in1 and in2
+ -- ------------------------------------------------------------------------
+ FUNCTION Minimum (
+ CONSTANT in1, in2 : INTEGER
+ ) RETURN INTEGER IS
+ BEGIN
+ IF (in1 < in2) THEN
+ RETURN in1;
+ END IF;
+ RETURN in2;
+ END;
+ -- ------------------------------------------------------------------------
+ FUNCTION Minimum (
+ CONSTANT t1,t2 : IN TIME
+ ) RETURN TIME IS
+ BEGIN
+ IF ( t1 < t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Minimum;
+
+ -- ------------------------------------------------------------------------
+ -- FUNCTION NAME : MAXIMUM
+ --
+ -- PARAMETERS : in1, in2 - integer, time
+ --
+ -- DESCRIPTION : return larger of in1 and in2
+ -- ------------------------------------------------------------------------
+ FUNCTION Maximum (
+ CONSTANT in1, in2 : INTEGER
+ ) RETURN INTEGER IS
+ BEGIN
+ IF (in1 > in2) THEN
+ RETURN in1;
+ END IF;
+ RETURN in2;
+ END;
+ -----------------------------------------------------------------------
+ FUNCTION Maximum (
+ CONSTANT t1,t2 : IN TIME
+ ) RETURN TIME IS
+ BEGIN
+ IF ( t1 > t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Maximum;
+
+ -----------------------------------------------------------------------
+ FUNCTION GlitchMinTime (
+ CONSTANT Time1, Time2 : IN TIME
+ ) RETURN TIME IS
+ BEGIN
+ IF ( Time1 >= NOW ) THEN
+ IF ( Time2 >= NOW ) THEN
+ RETURN Minimum ( Time1, Time2);
+ ELSE
+ RETURN Time1;
+ END IF;
+ ELSE
+ IF ( Time2 >= NOW ) THEN
+ RETURN Time2;
+ ELSE
+ RETURN 0 ns;
+ END IF;
+ END IF;
+ END;
+
+ --------------------------------------------------------------------
+ -- Error Message Types and Tables
+ --------------------------------------------------------------------
+ TYPE VitalErrorType IS (
+ ErrNegDel,
+ ErrInpSym,
+ ErrOutSym,
+ ErrStaSym,
+ ErrVctLng,
+ ErrTabWidSml,
+ ErrTabWidLrg,
+ ErrTabResSml,
+ ErrTabResLrg
+ );
+
+ TYPE VitalErrorSeverityType IS ARRAY (VitalErrorType) OF SEVERITY_LEVEL;
+ CONSTANT VitalErrorSeverity : VitalErrorSeverityType := (
+ ErrNegDel => WARNING,
+ ErrInpSym => ERROR,
+ ErrOutSym => ERROR,
+ ErrStaSym => ERROR,
+ ErrVctLng => ERROR,
+ ErrTabWidSml => ERROR,
+ ErrTabWidLrg => WARNING,
+ ErrTabResSml => WARNING,
+ ErrTabResLrg => WARNING
+ );
+
+ CONSTANT MsgNegDel : STRING :=
+ "Negative delay. New output value not scheduled. Output signal is: ";
+ CONSTANT MsgInpSym : STRING :=
+ "Illegal symbol in the input portion of a Truth/State table.";
+ CONSTANT MsgOutSym : STRING :=
+ "Illegal symbol in the output portion of a Truth/State table.";
+ CONSTANT MsgStaSym : STRING :=
+ "Illegal symbol in the state portion of a State table.";
+ CONSTANT MsgVctLng : STRING :=
+ "Vector (array) lengths not equal. ";
+ CONSTANT MsgTabWidSml : STRING :=
+ "Width of the Truth/State table is too small.";
+ CONSTANT MsgTabWidLrg : STRING :=
+ "Width of Truth/State table is too large. Extra elements are ignored.";
+ CONSTANT MsgTabResSml : STRING :=
+ "Result of Truth/State table has too many elements.";
+ CONSTANT MsgTabResLrg : STRING :=
+ "Result of Truth/State table has too few elements.";
+
+ CONSTANT MsgUnknown : STRING :=
+ "Unknown error message.";
+
+ --------------------------------------------------------------------
+ -- LOCAL Utilities
+ --------------------------------------------------------------------
+ FUNCTION VitalMessage (
+ CONSTANT ErrorId : IN VitalErrorType
+ ) RETURN STRING IS
+ BEGIN
+ CASE ErrorId IS
+ WHEN ErrNegDel => RETURN MsgNegDel;
+ WHEN ErrInpSym => RETURN MsgInpSym;
+ WHEN ErrOutSym => RETURN MsgOutSym;
+ WHEN ErrStaSym => RETURN MsgStaSym;
+ WHEN ErrVctLng => RETURN MsgVctLng;
+ WHEN ErrTabWidSml => RETURN MsgTabWidSml;
+ WHEN ErrTabWidLrg => RETURN MsgTabWidLrg;
+ WHEN ErrTabResSml => RETURN MsgTabResSml;
+ WHEN ErrTabResLrg => RETURN MsgTabResLrg;
+ WHEN OTHERS => RETURN MsgUnknown;
+ END CASE;
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId)
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN STRING
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN CHARACTER
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE ReportGlitch (
+ CONSTANT GlitchRoutine : IN STRING;
+ CONSTANT OutSignalName : IN STRING;
+ CONSTANT PreemptedTime : IN TIME;
+ CONSTANT PreemptedValue : IN std_ulogic;
+ CONSTANT NewTime : IN TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT Index : IN INTEGER := 0;
+ CONSTANT IsArraySignal : IN BOOLEAN := FALSE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE StrPtr1, StrPtr2, StrPtr3, StrPtr4, StrPtr5 : LINE;
+ BEGIN
+
+ Write (StrPtr1, PreemptedTime );
+ Write (StrPtr2, NewTime);
+ Write (StrPtr3, LogicCvtTable(PreemptedValue));
+ Write (StrPtr4, LogicCvtTable(NewValue));
+ IF IsArraySignal THEN
+ Write (StrPtr5, STRING'( "(" ) );
+ Write (StrPtr5, Index);
+ Write (StrPtr5, STRING'( ")" ) );
+ ELSE
+ Write (StrPtr5, STRING'( " " ) );
+ END IF;
+
+ -- Issue Report only if Preemted value has not been
+ -- removed from event queue
+ ASSERT PreemptedTime > NewTime
+ REPORT GlitchRoutine & ": GLITCH Detected on port " &
+ OutSignalName & StrPtr5.ALL &
+ "; Preempted Future Value := " & StrPtr3.ALL &
+ " @ " & StrPtr1.ALL &
+ "; Newly Scheduled Value := " & StrPtr4.ALL &
+ " @ " & StrPtr2.ALL &
+ ";"
+ SEVERITY MsgSeverity;
+
+ DEALLOCATE(StrPtr1);
+ DEALLOCATE(StrPtr2);
+ DEALLOCATE(StrPtr3);
+ DEALLOCATE(StrPtr4);
+ DEALLOCATE(StrPtr5);
+ RETURN;
+ END ReportGlitch;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : VitalGlitchOnEvent
+ -- :
+ -- Parameters : OutSignal ........ signal being driven
+ -- : OutSignalName..... name of the driven signal
+ -- : GlitchData........ internal data required by the procedure
+ -- : NewValue.......... new value being assigned
+ -- : NewDelay.......... Delay accompanying the assignment
+ -- : (Note: for vectors, this is an array)
+ -- : GlitchMode........ Glitch generation mode
+ -- : MessagePlusX, MessageOnly,
+ -- : XOnly, NoGlitch )
+ -- : GlitchDelay....... if <= 0 ns , then there will be no Glitch
+ -- : if > NewDelay, then there is no Glitch,
+ -- : otherwise, this is the time when a FORCED
+ -- : generation of a glitch will occur.
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalGlitchOnEvent (
+ SIGNAL OutSignal : OUT std_logic;
+ CONSTANT OutSignalName : IN STRING;
+ VARIABLE GlitchData : INOUT GlitchDataType;
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT NewDelay : IN TIME := 0 ns;
+ CONSTANT GlitchMode : IN VitalGlitchModeType := MessagePlusX;
+ CONSTANT GlitchDelay : IN TIME := -1 ns; -- IR#223
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+ -- ------------------------------------------------------------------------
+ VARIABLE NoGlitchDet : BOOLEAN := FALSE;
+ VARIABLE OldGlitch : BOOLEAN := FALSE;
+ VARIABLE Dly : TIME := NewDelay;
+
+ BEGIN
+ -- If nothing to schedule, just return
+ IF NewDelay < 0 ns THEN
+ IF (NewValue /= GlitchData.SchedValue) THEN
+ VitalError ( "VitalGlitchOnEvent", ErrNegDel, OutSignalName );
+ END IF;
+
+ ELSE
+ -- If nothing currently scheduled
+ IF GlitchData.SchedTime <= NOW THEN
+ GlitchData.CurrentValue := GlitchData.SchedValue;
+ IF (GlitchDelay <= 0 ns) THEN
+ IF (NewValue = GlitchData.SchedValue) THEN RETURN; END IF;
+ NoGlitchDet := TRUE;
+ END IF;
+
+ -- Transaction currently scheduled - if glitch already happened
+ ELSIF GlitchData.GlitchTime <= NOW THEN
+ GlitchData.CurrentValue := 'X';
+ OldGlitch := TRUE;
+ IF (GlitchData.SchedValue = NewValue) THEN
+ dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+ END IF;
+
+ -- Transaction currently scheduled (no glitch if same value)
+ ELSIF (GlitchData.SchedValue = NewValue) AND
+ (GlitchData.SchedTime = GlitchData.GlitchTime) AND
+ (GlitchDelay <= 0 ns) THEN
+ NoGlitchDet := TRUE;
+ Dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+
+ END IF;
+
+ GlitchData.SchedTime := NOW+Dly;
+ IF OldGlitch THEN
+ OutSignal <= NewValue AFTER Dly;
+
+ ELSIF NoGlitchDet THEN
+ GlitchData.GlitchTime := NOW+Dly;
+ OutSignal <= NewValue AFTER Dly;
+
+ ELSE -- new glitch
+ GlitchData.GlitchTime := GlitchMinTime ( GlitchData.GlitchTime,
+ NOW+GlitchDelay );
+
+ IF (GlitchMode = MessagePlusX) OR
+ (GlitchMode = MessageOnly) THEN
+ ReportGlitch ( "VitalGlitchOnEvent", OutSignalName,
+ GlitchData.GlitchTime, GlitchData.SchedValue,
+ (Dly + NOW), NewValue,
+ MsgSeverity=>MsgSeverity );
+ END IF;
+
+ IF (GlitchMode = MessagePlusX) OR (GlitchMode = XOnly) THEN
+ OutSignal <= 'X' AFTER GlitchData.GlitchTime-NOW;
+ OutSignal <= TRANSPORT NewValue AFTER Dly;
+ ELSE
+ OutSignal <= NewValue AFTER Dly;
+ END IF;
+ END IF;
+
+ GlitchData.SchedValue := NewValue;
+ END IF;
+
+ RETURN;
+ END;
+
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalGlitchOnEvent (
+ SIGNAL OutSignal : OUT std_logic_vector;
+ CONSTANT OutSignalName : IN STRING;
+ VARIABLE GlitchData : INOUT GlitchDataArrayType;
+ CONSTANT NewValue : IN std_logic_vector;
+ CONSTANT NewDelay : IN VitalTimeArray;
+ CONSTANT GlitchMode : IN VitalGlitchModeType := MessagePlusX;
+ CONSTANT GlitchDelay : IN VitalTimeArray;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ ALIAS GlDataAlias : GlitchDataArrayType(1 TO GlitchData'LENGTH)
+ IS GlitchData;
+ ALIAS NewValAlias : std_logic_vector(1 TO NewValue'LENGTH) IS NewValue;
+ ALIAS GlDelayAlias : VitalTimeArray(1 TO GlitchDelay'LENGTH)
+ IS GlitchDelay;
+ ALIAS NewDelAlias : VitalTimeArray(1 TO NewDelay'LENGTH) IS NewDelay;
+
+ VARIABLE Index : INTEGER := OutSignal'LEFT;
+ VARIABLE Direction : INTEGER;
+ VARIABLE NoGlitchDet : BOOLEAN;
+ VARIABLE OldGlitch : BOOLEAN;
+ VARIABLE Dly, GlDly : TIME;
+
+ BEGIN
+ IF (OutSignal'LEFT > OutSignal'RIGHT) THEN
+ Direction := -1;
+ ELSE
+ Direction := 1;
+ END IF;
+
+ IF ( (OutSignal'LENGTH /= GlitchData'LENGTH) OR
+ (OutSignal'LENGTH /= NewValue'LENGTH) OR
+ (OutSignal'LENGTH /= NewDelay'LENGTH) OR
+ (OutSignal'LENGTH /= GlitchDelay'LENGTH) ) THEN
+ VitalError ( "VitalGlitchOnEvent", ErrVctLng, OutSignalName );
+ RETURN;
+ END IF;
+
+ -- a call to the scalar function cannot be made since the actual
+ -- name associated with a signal parameter must be locally static
+ FOR n IN 1 TO OutSignal'LENGTH LOOP
+
+ NoGlitchDet := FALSE;
+ OldGlitch := FALSE;
+ Dly := NewDelAlias(n);
+
+ -- If nothing to schedule, just skip to next loop iteration
+ IF NewDelAlias(n) < 0 ns THEN
+ IF (NewValAlias(n) /= GlDataAlias(n).SchedValue) THEN
+ VitalError ( "VitalGlitchOnEvent", ErrNegDel, OutSignalName );
+ END IF;
+ ELSE
+ -- If nothing currently scheduled (i.e. last scheduled
+ -- transaction already occurred)
+ IF GlDataAlias(n).SchedTime <= NOW THEN
+ GlDataAlias(n).CurrentValue := GlDataAlias(n).SchedValue;
+ IF (GlDelayAlias(n) <= 0 ns) THEN
+ -- Next iteration if no change in value
+ IF (NewValAlias(n) = GlDataAlias(n).SchedValue) THEN
+ Index := Index + Direction;
+ NEXT;
+ END IF;
+ -- since last transaction already occurred there is no glitch
+ NoGlitchDet := TRUE;
+ END IF;
+
+ -- Transaction currently scheduled - if glitch already happened
+ ELSIF GlDataAlias(n).GlitchTime <= NOW THEN
+ GlDataAlias(n).CurrentValue := 'X';
+ OldGlitch := TRUE;
+ IF (GlDataAlias(n).SchedValue = NewValAlias(n)) THEN
+ dly := Minimum( GlDataAlias(n).SchedTime-NOW,
+ NewDelAlias(n) );
+ END IF;
+
+ -- Transaction currently scheduled
+ ELSIF (GlDataAlias(n).SchedValue = NewValAlias(n)) AND
+ (GlDataAlias(n).SchedTime = GlDataAlias(n).GlitchTime) AND
+ (GlDelayAlias(n) <= 0 ns) THEN
+ NoGlitchDet := TRUE;
+ Dly := Minimum( GlDataAlias(n).SchedTime-NOW,
+ NewDelAlias(n) );
+ END IF;
+
+ -- update last scheduled transaction
+ GlDataAlias(n).SchedTime := NOW+Dly;
+
+ IF OldGlitch THEN
+ OutSignal(Index) <= NewValAlias(n) AFTER Dly;
+ ELSIF NoGlitchDet THEN
+ -- if no glitch then update last glitch time
+ -- and OutSignal(actual_index)
+ GlDataAlias(n).GlitchTime := NOW+Dly;
+ OutSignal(Index) <= NewValAlias(n) AFTER Dly;
+ ELSE -- new glitch
+ GlDataAlias(n).GlitchTime := GlitchMinTime (
+ GlDataAlias(n).GlitchTime,
+ NOW+GlDelayAlias(n) );
+
+ IF (GlitchMode = MessagePlusX) OR
+ (GlitchMode = MessageOnly) THEN
+ ReportGlitch ( "VitalGlitchOnEvent", OutSignalName,
+ GlDataAlias(n).GlitchTime,
+ GlDataAlias(n).SchedValue,
+ (Dly + NOW), NewValAlias(n),
+ Index, TRUE, MsgSeverity );
+ END IF;
+
+ IF (GlitchMode = MessagePlusX) OR (GlitchMode = XOnly) THEN
+ GlDly := GlDataAlias(n).GlitchTime - NOW;
+ OutSignal(Index) <= 'X' AFTER GlDly;
+ OutSignal(Index) <= TRANSPORT NewValAlias(n) AFTER Dly;
+ ELSE
+ OutSignal(Index) <= NewValAlias(n) AFTER Dly;
+ END IF;
+
+ END IF; -- glitch / no-glitch
+ GlDataAlias(n).SchedValue := NewValAlias(n);
+
+ END IF; -- NewDelAlias(n) < 0 ns
+ Index := Index + Direction;
+ END LOOP;
+
+ RETURN;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- ------------------------------------------------------------------------
+ -- PROCEDURE NAME : TruthOutputX01Z
+ --
+ -- PARAMETERS : table_out - output of table
+ -- X01Zout - output converted to X01Z
+ -- err - true if illegal character is encountered
+ --
+ --
+ -- DESCRIPTION : converts the output of a truth table to a valid
+ -- std_ulogic
+ -- ------------------------------------------------------------------------
+ PROCEDURE TruthOutputX01Z (
+ CONSTANT TableOut : IN VitalTruthSymbolType;
+ VARIABLE X01Zout : OUT std_ulogic;
+ VARIABLE Err : OUT BOOLEAN
+ ) IS
+ VARIABLE TempOut : std_ulogic;
+ BEGIN
+ Err := FALSE;
+ TempOut := TruthTableOutMap(TableOut);
+ IF (TempOut = '-') THEN
+ Err := TRUE;
+ TempOut := 'X';
+ VitalError ( "VitalTruthTable", ErrOutSym, To_TruthChar(TableOut));
+ END IF;
+ X01Zout := TempOut;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- PROCEDURE NAME : StateOutputX01Z
+ --
+ -- PARAMETERS : table_out - output of table
+ -- prev_out - previous output value
+ -- X01Zout - output cojnverted to X01Z
+ -- err - true if illegal character is encountered
+ --
+ -- DESCRIPTION : converts the output of a state table to a
+ -- valid std_ulogic
+ -- ------------------------------------------------------------------------
+ PROCEDURE StateOutputX01Z (
+ CONSTANT TableOut : IN VitalStateSymbolType;
+ CONSTANT PrevOut : IN std_ulogic;
+ VARIABLE X01Zout : OUT std_ulogic;
+ VARIABLE Err : OUT BOOLEAN
+ ) IS
+ VARIABLE TempOut : std_ulogic;
+ BEGIN
+ Err := FALSE;
+ TempOut := StateTableOutMap(TableOut);
+ IF (TempOut = '-') THEN
+ Err := TRUE;
+ TempOut := 'X';
+ VitalError ( "VitalStateTable", ErrOutSym, To_StateChar(TableOut));
+ ELSIF (TempOut = 'W') THEN
+ TempOut := To_X01Z(PrevOut);
+ END IF;
+ X01Zout := TempOut;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- PROCEDURE NAME: StateMatch
+ --
+ -- PARAMETERS : symbol - symbol from state table
+ -- in2 - input from VitalStateTble procedure
+ -- to state table
+ -- in2LastValue - previous value of input
+ -- state - false if the symbol is from the input
+ -- portion of the table,
+ -- true if the symbol is from the state
+ -- portion of the table
+ -- Err - true if symbol is not a valid input symbol
+ -- ReturnValue - true if match occurred
+ --
+ -- DESCRIPTION : This procedure sets ReturnValue to true if in2 matches
+ -- symbol (from the state table). If symbol is an edge
+ -- value edge is set to true and in2 and in2LastValue are
+ -- checked against symbol. Err is set to true if symbol
+ -- is an invalid value for the input portion of the state
+ -- table.
+ --
+ -- ------------------------------------------------------------------------
+ PROCEDURE StateMatch (
+ CONSTANT Symbol : IN VitalStateSymbolType;
+ CONSTANT in2 : IN std_ulogic;
+ CONSTANT in2LastValue : IN std_ulogic;
+ CONSTANT State : IN BOOLEAN;
+ VARIABLE Err : OUT BOOLEAN;
+ VARIABLE ReturnValue : OUT BOOLEAN
+ ) IS
+ BEGIN
+ IF (State) THEN
+ IF (NOT ValidStateTableState(Symbol)) THEN
+ VitalError ( "VitalStateTable", ErrStaSym, To_StateChar(Symbol));
+ Err := TRUE;
+ ReturnValue := FALSE;
+ ELSE
+ Err := FALSE;
+ ReturnValue := StateTableMatch(in2LastValue, in2, Symbol);
+ END IF;
+ ELSE
+ IF (NOT ValidStateTableInput(Symbol) ) THEN
+ VitalError ( "VitalStateTable", ErrInpSym, To_StateChar(Symbol));
+ Err := TRUE;
+ ReturnValue := FALSE;
+ ELSE
+ ReturnValue := StateTableMatch(in2LastValue, in2, Symbol);
+ Err := FALSE;
+ END IF;
+ END IF;
+ END;
+
+ -- -----------------------------------------------------------------------
+ -- FUNCTION NAME: StateTableLookUp
+ --
+ -- PARAMETERS : StateTable - state table
+ -- PresentDataIn - current inputs
+ -- PreviousDataIn - previous inputs and states
+ -- NumStates - number of state variables
+ -- PresentOutputs - current state and current outputs
+ --
+ -- DESCRIPTION : This function is used to find the output of the
+ -- StateTable corresponding to a given set of inputs.
+ --
+ -- ------------------------------------------------------------------------
+ FUNCTION StateTableLookUp (
+ CONSTANT StateTable : VitalStateTableType;
+ CONSTANT PresentDataIn : std_logic_vector;
+ CONSTANT PreviousDataIn : std_logic_vector;
+ CONSTANT NumStates : NATURAL;
+ CONSTANT PresentOutputs : std_logic_vector
+ ) RETURN std_logic_vector IS
+
+ CONSTANT InputSize : INTEGER := PresentDataIn'LENGTH;
+ CONSTANT NumInputs : INTEGER := InputSize + NumStates - 1;
+ CONSTANT TableEntries : INTEGER := StateTable'LENGTH(1);
+ CONSTANT TableWidth : INTEGER := StateTable'LENGTH(2);
+ CONSTANT OutSize : INTEGER := TableWidth - InputSize - NumStates;
+ VARIABLE Inputs : std_logic_vector(0 TO NumInputs);
+ VARIABLE PrevInputs : std_logic_vector(0 TO NumInputs)
+ := (OTHERS => 'X');
+ VARIABLE ReturnValue : std_logic_vector(0 TO (OutSize-1))
+ := (OTHERS => 'X');
+ VARIABLE Temp : std_ulogic;
+ VARIABLE Match : BOOLEAN;
+ VARIABLE Err : BOOLEAN := FALSE;
+
+ -- This needs to be done since the TableLookup arrays must be
+ -- ascending starting with 0
+ VARIABLE TableAlias : VitalStateTableType(0 TO TableEntries - 1,
+ 0 TO TableWidth - 1)
+ := StateTable;
+
+ BEGIN
+ Inputs(0 TO InputSize-1) := PresentDataIn;
+ Inputs(InputSize TO NumInputs) := PresentOutputs(0 TO NumStates - 1);
+ PrevInputs(0 TO InputSize - 1) := PreviousDataIn(0 TO InputSize - 1);
+
+ ColLoop: -- Compare each entry in the table
+ FOR i IN TableAlias'RANGE(1) LOOP
+
+ RowLoop: -- Check each element of the entry
+ FOR j IN 0 TO InputSize + NumStates LOOP
+
+ IF (j = InputSize + NumStates) THEN -- a match occurred
+ FOR k IN 0 TO Minimum(OutSize, PresentOutputs'LENGTH)-1 LOOP
+ StateOutputX01Z (
+ TableAlias(i, TableWidth - k - 1),
+ PresentOutputs(PresentOutputs'LENGTH - k - 1),
+ Temp, Err);
+ ReturnValue(OutSize - k - 1) := Temp;
+ IF (Err) THEN
+ ReturnValue := (OTHERS => 'X');
+ RETURN ReturnValue;
+ END IF;
+ END LOOP;
+ RETURN ReturnValue;
+ END IF;
+
+ StateMatch ( TableAlias(i,j),
+ Inputs(j), PrevInputs(j),
+ j >= InputSize, Err, Match);
+ EXIT RowLoop WHEN NOT(Match);
+ EXIT ColLoop WHEN Err;
+ END LOOP RowLoop;
+ END LOOP ColLoop;
+
+ ReturnValue := (OTHERS => 'X');
+ RETURN ReturnValue;
+ END;
+
+ --------------------------------------------------------------------
+ -- to_ux01z
+ -------------------------------------------------------------------
+ FUNCTION To_UX01Z ( s : std_ulogic
+ ) RETURN UX01Z IS
+ BEGIN
+ RETURN cvt_to_ux01z (s);
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Function : GetEdge
+ -- Purpose : Converts transitions on a given input signal into a
+ -- enumeration value representing the transition or level
+ -- of the signal.
+ --
+ -- previous "value" current "value" := "edge"
+ -- ---------------------------------------------------------
+ -- '1' | 'H' '1' | 'H' '1' level, no edge
+ -- '0' | 'L' '1' | 'H' '/' rising edge
+ -- others '1' | 'H' 'R' rising from X
+ --
+ -- '1' | 'H' '0' | 'L' '\' falling egde
+ -- '0' | 'L' '0' | 'L' '0' level, no edge
+ -- others '0' | 'L' 'F' falling from X
+ --
+ -- 'X' | 'W' | '-' 'X' | 'W' | '-' 'X' unknown (X) level
+ -- 'Z' 'Z' 'X' unknown (X) level
+ -- 'U' 'U' 'U' 'U' level
+ --
+ -- '1' | 'H' others 'f' falling to X
+ -- '0' | 'L' others 'r' rising to X
+ -- 'X' | 'W' | '-' 'U' | 'Z' 'x' unknown (X) edge
+ -- 'Z' 'X' | 'W' | '-' | 'U' 'x' unknown (X) edge
+ -- 'U' 'X' | 'W' | '-' | 'Z' 'x' unknown (X) edge
+ --
+ ---------------------------------------------------------------------------
+ FUNCTION GetEdge (
+ SIGNAL s : IN std_logic
+ ) RETURN EdgeType IS
+ BEGIN
+ IF (s'EVENT)
+ THEN RETURN LogicToEdge ( s'LAST_VALUE, s );
+ ELSE RETURN LogicToLevel ( s );
+ END IF;
+ END;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE GetEdge (
+ SIGNAL s : IN std_logic_vector;
+ VARIABLE LastS : INOUT std_logic_vector;
+ VARIABLE Edge : OUT EdgeArray ) IS
+
+ ALIAS sAlias : std_logic_vector ( 1 TO s'LENGTH ) IS s;
+ ALIAS LastSAlias : std_logic_vector ( 1 TO LastS'LENGTH ) IS LastS;
+ ALIAS EdgeAlias : EdgeArray ( 1 TO Edge'LENGTH ) IS Edge;
+ BEGIN
+ IF s'LENGTH /= LastS'LENGTH OR
+ s'LENGTH /= Edge'LENGTH THEN
+ VitalError ( "GetEdge", ErrVctLng, "s, LastS, Edge" );
+ END IF;
+
+ FOR n IN 1 TO s'LENGTH LOOP
+ EdgeAlias(n) := LogicToEdge( LastSAlias(n), sAlias(n) );
+ LastSAlias(n) := sAlias(n);
+ END LOOP;
+ END;
+
+ ---------------------------------------------------------------------------
+ FUNCTION ToEdge ( Value : IN std_logic
+ ) RETURN EdgeType IS
+ BEGIN
+ RETURN LogicToLevel( Value );
+ END;
+
+ -- Note: This function will likely be replaced by S'DRIVING_VALUE in VHDL'92
+ ----------------------------------------------------------------------------
+ IMPURE FUNCTION CurValue (
+ CONSTANT GlitchData : IN GlitchDataType
+ ) RETURN std_logic IS
+ BEGIN
+ IF NOW >= GlitchData.SchedTime THEN
+ RETURN GlitchData.SchedValue;
+ ELSIF NOW >= GlitchData.GlitchTime THEN
+ RETURN 'X';
+ ELSE
+ RETURN GlitchData.CurrentValue;
+ END IF;
+ END;
+ ---------------------------------------------------------------------------
+ IMPURE FUNCTION CurValue (
+ CONSTANT GlitchData : IN GlitchDataArrayType
+ ) RETURN std_logic_vector IS
+ VARIABLE Result : std_logic_vector(GlitchData'RANGE);
+ BEGIN
+ FOR n IN GlitchData'RANGE LOOP
+ IF NOW >= GlitchData(n).SchedTime THEN
+ Result(n) := GlitchData(n).SchedValue;
+ ELSIF NOW >= GlitchData(n).GlitchTime THEN
+ Result(n) := 'X';
+ ELSE
+ Result(n) := GlitchData(n).CurrentValue;
+ END IF;
+ END LOOP;
+ RETURN Result;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- function calculation utilities
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- Function : VitalSame
+ -- Returns : VitalSame compares the state (UX01) of two logic value. A
+ -- value of 'X' is returned if the values are different. The
+ -- common value is returned if the values are equal.
+ -- Purpose : When the result of a logic model may be either of two
+ -- separate input values (eg. when the select on a MUX is 'X'),
+ -- VitalSame may be used to determine if the result needs to
+ -- be 'X'.
+ -- Arguments : See the declarations below...
+ ---------------------------------------------------------------------------
+ FUNCTION VitalSame (
+ CONSTANT a, b : IN std_ulogic
+ ) RETURN std_ulogic IS
+ BEGIN
+ IF To_UX01(a) = To_UX01(b)
+ THEN RETURN To_UX01(a);
+ ELSE RETURN 'X';
+ END IF;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- delay selection utilities
+ ---------------------------------------------------------------------------
+
+ ---------------------------------------------------------------------------
+ -- Procedure : BufPath, InvPath
+ --
+ -- Purpose : BufPath and InvPath compute output change times, based on
+ -- a change on an input port. The computed output change times
+ -- returned in the composite parameter 'schd'.
+ --
+ -- BufPath and InpPath are used together with the delay path
+ -- selection functions (GetSchedDelay, VitalAND, VitalOR... )
+ -- The 'schd' value from each of the input ports of a model are
+ -- combined by the delay selection functions (VitalAND,
+ -- VitalOR, ...). The GetSchedDelay procedure converts the
+ -- combined output changes times to the single delay (delta
+ -- time) value for scheduling the output change (passed to
+ -- VitalGlitchOnEvent).
+ --
+ -- The values in 'schd' are: (absolute times)
+ -- inp0 : time of output change due to input change to 0
+ -- inp1 : time of output change due to input change to 1
+ -- inpX : time of output change due to input change to X
+ -- glch0 : time of output glitch due to input change to 0
+ -- glch1 : time of output glitch due to input change to 1
+ --
+ -- The output times are computed from the model INPUT value
+ -- and not the final value. For this reason, 'BufPath' should
+ -- be used to compute the output times for a non-inverting
+ -- delay paths and 'InvPath' should be used to compute the
+ -- ouput times for inverting delay paths. Delay paths which
+ -- include both non-inverting and paths require usage of both
+ -- 'BufPath' and 'InvPath'. (IE this is needed for the
+ -- select->output path of a MUX -- See the VitalMUX model).
+ --
+ --
+ -- Parameters : schd....... Computed output result times. (INOUT parameter
+ -- modified only on input edges)
+ -- Iedg....... Input port edge/level value.
+ -- tpd....... Propagation delays from this input
+ --
+ ---------------------------------------------------------------------------
+
+ PROCEDURE BufPath (
+ VARIABLE Schd : INOUT SchedType;
+ CONSTANT Iedg : IN EdgeType;
+ CONSTANT tpd : IN VitalDelayType01
+ ) IS
+ BEGIN
+ CASE Iedg IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd.inp0 := TIME'HIGH;
+ Schd.inp1 := NOW + tpd(tr01); Schd.Glch1 := Schd.inp1;
+ Schd.InpX := Schd.inp1;
+ WHEN '\'|'F' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := NOW + tpd(tr10); Schd.Glch0 := Schd.inp0;
+ Schd.InpX := Schd.inp0;
+ WHEN 'r' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := TIME'HIGH;
+ Schd.InpX := NOW + tpd(tr01);
+ WHEN 'f' => Schd.inp0 := TIME'HIGH;
+ Schd.inp1 := TIME'HIGH;
+ Schd.InpX := NOW + tpd(tr10);
+ WHEN 'x' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := TIME'HIGH;
+ -- update for X->X change
+ Schd.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END;
+
+ PROCEDURE BufPath (
+ VARIABLE Schd : INOUT SchedArray;
+ CONSTANT Iedg : IN EdgeArray;
+ CONSTANT tpd : IN VitalDelayArrayType01
+ ) IS
+ BEGIN
+ FOR n IN Schd'RANGE LOOP
+ CASE Iedg(n) IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd(n).inp0 := TIME'HIGH;
+ Schd(n).inp1 := NOW + tpd(n)(tr01);
+ Schd(n).Glch1 := Schd(n).inp1;
+ Schd(n).InpX := Schd(n).inp1;
+ WHEN '\'|'F' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := NOW + tpd(n)(tr10);
+ Schd(n).Glch0 := Schd(n).inp0;
+ Schd(n).InpX := Schd(n).inp0;
+ WHEN 'r' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := TIME'HIGH;
+ Schd(n).InpX := NOW + tpd(n)(tr01);
+ WHEN 'f' => Schd(n).inp0 := TIME'HIGH;
+ Schd(n).inp1 := TIME'HIGH;
+ Schd(n).InpX := NOW + tpd(n)(tr10);
+ WHEN 'x' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := TIME'HIGH;
+ -- update for X->X change
+ Schd(n).InpX := NOW + Minimum ( tpd(n)(tr10),
+ tpd(n)(tr01) );
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END LOOP;
+ END;
+
+ PROCEDURE InvPath (
+ VARIABLE Schd : INOUT SchedType;
+ CONSTANT Iedg : IN EdgeType;
+ CONSTANT tpd : IN VitalDelayType01
+ ) IS
+ BEGIN
+ CASE Iedg IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd.inp0 := TIME'HIGH;
+ Schd.inp1 := NOW + tpd(tr10); Schd.Glch1 := Schd.inp1;
+ Schd.InpX := Schd.inp1;
+ WHEN '\'|'F' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := NOW + tpd(tr01); Schd.Glch0 := Schd.inp0;
+ Schd.InpX := Schd.inp0;
+ WHEN 'r' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := TIME'HIGH;
+ Schd.InpX := NOW + tpd(tr10);
+ WHEN 'f' => Schd.inp0 := TIME'HIGH;
+ Schd.inp1 := TIME'HIGH;
+ Schd.InpX := NOW + tpd(tr01);
+ WHEN 'x' => Schd.inp1 := TIME'HIGH;
+ Schd.inp0 := TIME'HIGH;
+ -- update for X->X change
+ Schd.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END;
+
+ PROCEDURE InvPath (
+ VARIABLE Schd : INOUT SchedArray;
+ CONSTANT Iedg : IN EdgeArray;
+ CONSTANT tpd : IN VitalDelayArrayType01
+ ) IS
+ BEGIN
+ FOR n IN Schd'RANGE LOOP
+ CASE Iedg(n) IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd(n).inp0 := TIME'HIGH;
+ Schd(n).inp1 := NOW + tpd(n)(tr10);
+ Schd(n).Glch1 := Schd(n).inp1;
+ Schd(n).InpX := Schd(n).inp1;
+ WHEN '\'|'F' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := NOW + tpd(n)(tr01);
+ Schd(n).Glch0 := Schd(n).inp0;
+ Schd(n).InpX := Schd(n).inp0;
+ WHEN 'r' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := TIME'HIGH;
+ Schd(n).InpX := NOW + tpd(n)(tr10);
+ WHEN 'f' => Schd(n).inp0 := TIME'HIGH;
+ Schd(n).inp1 := TIME'HIGH;
+ Schd(n).InpX := NOW + tpd(n)(tr01);
+ WHEN 'x' => Schd(n).inp1 := TIME'HIGH;
+ Schd(n).inp0 := TIME'HIGH;
+ -- update for X->X change
+ Schd(n).InpX := NOW + Minimum ( tpd(n)(tr10),
+ tpd(n)(tr01) );
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END LOOP;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : BufEnab, InvEnab
+ --
+ -- Purpose : BufEnab and InvEnab compute output change times, from a
+ -- change on an input enable port for a 3-state driver. The
+ -- computed output change times are returned in the composite
+ -- parameters 'schd1', 'schd0'.
+ --
+ -- BufEnab and InpEnab are used together with the delay path
+ -- selection functions (GetSchedDelay, VitalAND, VitalOR... )
+ -- The 'schd' value from each of the non-enable input ports of
+ -- a model (See BufPath, InvPath) are combined using the delay
+ -- selection functions (VitalAND, VitalOR, ...). The
+ -- GetSchedDelay procedure combines the output times on the
+ -- enable path with the output times from the data path(s) and
+ -- computes the single delay (delta time) value for scheduling
+ -- the output change (passed to VitalGlitchOnEvent)
+ --
+ -- The values in 'schd*' are: (absolute times)
+ -- inp0 : time of output change due to input change to 0
+ -- inp1 : time of output change due to input change to 1
+ -- inpX : time of output change due to input change to X
+ -- glch0 : time of output glitch due to input change to 0
+ -- glch1 : time of output glitch due to input change to 1
+ --
+ -- 'schd1' contains output times for 1->Z, Z->1 transitions.
+ -- 'schd0' contains output times for 0->Z, Z->0 transitions.
+ --
+ -- 'BufEnab' is used for computing the output times for an
+ -- high asserted enable (output 'Z' for enable='0').
+ -- 'InvEnab' is used for computing the output times for an
+ -- low asserted enable (output 'Z' for enable='1').
+ --
+ -- Note: separate 'schd1', 'schd0' parameters are generated
+ -- so that the combination of the delay paths from
+ -- multiple enable signals may be combined using the
+ -- same functions/operators used in combining separate
+ -- data paths. (See exampe 2 below)
+ --
+ --
+ -- Parameters : schd1...... Computed output result times for 1->Z, Z->1
+ -- transitions. This parameter is modified only on
+ -- input edge values (events).
+ -- schd0...... Computed output result times for 0->Z, 0->1
+ -- transitions. This parameter is modified only on
+ -- input edge values (events).
+ -- Iedg....... Input port edge/level value.
+ -- tpd....... Propagation delays for the enable -> output path.
+ --
+ ---------------------------------------------------------------------------
+ PROCEDURE BufEnab (
+ VARIABLE Schd1 : INOUT SchedType;
+ VARIABLE Schd0 : INOUT SchedType;
+ CONSTANT Iedg : IN EdgeType;
+ CONSTANT tpd : IN VitalDelayType01Z
+ ) IS
+ BEGIN
+ CASE Iedg IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := NOW + tpd(trz1);
+ Schd1.Glch1 := Schd1.inp1;
+ Schd1.InpX := Schd1.inp1;
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := NOW + tpd(trz0);
+ Schd0.Glch1 := Schd0.inp1;
+ Schd0.InpX := Schd0.inp1;
+ WHEN '\'|'F' => Schd1.inp1 := TIME'HIGH;
+ Schd1.inp0 := NOW + tpd(tr1z);
+ Schd1.Glch0 := Schd1.inp0;
+ Schd1.InpX := Schd1.inp0;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.inp0 := NOW + tpd(tr0z);
+ Schd0.Glch0 := Schd0.inp0;
+ Schd0.InpX := Schd0.inp0;
+ WHEN 'r' => Schd1.inp1 := TIME'HIGH;
+ Schd1.inp0 := TIME'HIGH;
+ Schd1.InpX := NOW + tpd(trz1);
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.InpX := NOW + tpd(trz0);
+ WHEN 'f' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := TIME'HIGH;
+ Schd1.InpX := NOW + tpd(tr1z);
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.InpX := NOW + tpd(tr0z);
+ WHEN 'x' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := TIME'HIGH;
+ Schd1.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END;
+
+ PROCEDURE InvEnab (
+ VARIABLE Schd1 : INOUT SchedType;
+ VARIABLE Schd0 : INOUT SchedType;
+ CONSTANT Iedg : IN EdgeType;
+ CONSTANT tpd : IN VitalDelayType01Z
+ ) IS
+ BEGIN
+ CASE Iedg IS
+ WHEN '0'|'1' => NULL; -- no edge: no timing update
+ WHEN '/'|'R' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := NOW + tpd(tr1z);
+ Schd1.Glch1 := Schd1.inp1;
+ Schd1.InpX := Schd1.inp1;
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := NOW + tpd(tr0z);
+ Schd0.Glch1 := Schd0.inp1;
+ Schd0.InpX := Schd0.inp1;
+ WHEN '\'|'F' => Schd1.inp1 := TIME'HIGH;
+ Schd1.inp0 := NOW + tpd(trz1);
+ Schd1.Glch0 := Schd1.inp0;
+ Schd1.InpX := Schd1.inp0;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.inp0 := NOW + tpd(trz0);
+ Schd0.Glch0 := Schd0.inp0;
+ Schd0.InpX := Schd0.inp0;
+ WHEN 'r' => Schd1.inp1 := TIME'HIGH;
+ Schd1.inp0 := TIME'HIGH;
+ Schd1.InpX := NOW + tpd(tr1z);
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.InpX := NOW + tpd(tr0z);
+ WHEN 'f' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := TIME'HIGH;
+ Schd1.InpX := NOW + tpd(trz1);
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.InpX := NOW + tpd(trz0);
+ WHEN 'x' => Schd1.inp0 := TIME'HIGH;
+ Schd1.inp1 := TIME'HIGH;
+ Schd1.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ Schd0.inp0 := TIME'HIGH;
+ Schd0.inp1 := TIME'HIGH;
+ Schd0.InpX := NOW + Minimum(tpd(tr10),tpd(tr01));
+ WHEN OTHERS => NULL; -- no timing change
+ END CASE;
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : GetSchedDelay
+ --
+ -- Purpose : GetSchedDelay computes the final delay (incremental) for
+ -- for scheduling an output signal. The delay is computed
+ -- from the absolute output times in the 'NewSched' parameter.
+ -- (See BufPath, InvPath).
+ --
+ -- Computation of the output delay for non-3_state outputs
+ -- consists of selection the appropriate output time based
+ -- on the new output value 'NewValue' and subtracting 'NOW'
+ -- to convert to an incremental delay value.
+ --
+ -- The Computation of the output delay for 3_state output
+ -- also includes combination of the enable path delay with
+ -- the date path delay.
+ --
+ -- Parameters : NewDelay... Returned output delay value.
+ -- GlchDelay.. Returned output delay for the start of a glitch.
+ -- NewValue... New output value.
+ -- CurValue... Current value of the output.
+ -- NewSched... Composite containing the combined absolute
+ -- output times from the data inputs.
+ -- EnSched1... Composite containing the combined absolute
+ -- output times from the enable input(s).
+ -- (for a 3_state output transitions 1->Z, Z->1)
+ -- EnSched0... Composite containing the combined absolute
+ -- output times from the enable input(s).
+ -- (for a 3_state output transitions 0->Z, Z->0)
+ --
+ ---------------------------------------------------------------------------
+ PROCEDURE GetSchedDelay (
+ VARIABLE NewDelay : OUT TIME;
+ VARIABLE GlchDelay : OUT TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT CurValue : IN std_ulogic;
+ CONSTANT NewSched : IN SchedType
+ ) IS
+ VARIABLE Tim, Glch : TIME;
+ BEGIN
+
+ CASE To_UX01(NewValue) IS
+ WHEN '0' => Tim := NewSched.inp0;
+ Glch := NewSched.Glch1;
+ WHEN '1' => Tim := NewSched.inp1;
+ Glch := NewSched.Glch0;
+ WHEN OTHERS => Tim := NewSched.InpX;
+ Glch := -1 ns;
+ END CASE;
+ IF (CurValue /= NewValue)
+ THEN Glch := -1 ns;
+ END IF;
+
+ NewDelay := Tim - NOW;
+ IF Glch < 0 ns
+ THEN GlchDelay := Glch;
+ ELSE GlchDelay := Glch - NOW;
+ END IF; -- glch < 0 ns
+ END;
+
+ PROCEDURE GetSchedDelay (
+ VARIABLE NewDelay : OUT VitalTimeArray;
+ VARIABLE GlchDelay : OUT VitalTimeArray;
+ CONSTANT NewValue : IN std_logic_vector;
+ CONSTANT CurValue : IN std_logic_vector;
+ CONSTANT NewSched : IN SchedArray
+ ) IS
+ VARIABLE Tim, Glch : TIME;
+ ALIAS NewDelayAlias : VitalTimeArray( NewDelay'LENGTH DOWNTO 1)
+ IS NewDelay;
+ ALIAS GlchDelayAlias : VitalTimeArray(GlchDelay'LENGTH DOWNTO 1)
+ IS GlchDelay;
+ ALIAS NewSchedAlias : SchedArray( NewSched'LENGTH DOWNTO 1)
+ IS NewSched;
+ ALIAS NewValueAlias : std_logic_vector ( NewValue'LENGTH DOWNTO 1 )
+ IS NewValue;
+ ALIAS CurValueAlias : std_logic_vector ( CurValue'LENGTH DOWNTO 1 )
+ IS CurValue;
+ BEGIN
+ FOR n IN NewDelay'LENGTH DOWNTO 1 LOOP
+ CASE To_UX01(NewValueAlias(n)) IS
+ WHEN '0' => Tim := NewSchedAlias(n).inp0;
+ Glch := NewSchedAlias(n).Glch1;
+ WHEN '1' => Tim := NewSchedAlias(n).inp1;
+ Glch := NewSchedAlias(n).Glch0;
+ WHEN OTHERS => Tim := NewSchedAlias(n).InpX;
+ Glch := -1 ns;
+ END CASE;
+ IF (CurValueAlias(n) /= NewValueAlias(n))
+ THEN Glch := -1 ns;
+ END IF;
+
+ NewDelayAlias(n) := Tim - NOW;
+ IF Glch < 0 ns
+ THEN GlchDelayAlias(n) := Glch;
+ ELSE GlchDelayAlias(n) := Glch - NOW;
+ END IF; -- glch < 0 ns
+ END LOOP;
+ RETURN;
+ END;
+
+ PROCEDURE GetSchedDelay (
+ VARIABLE NewDelay : OUT TIME;
+ VARIABLE GlchDelay : OUT TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT CurValue : IN std_ulogic;
+ CONSTANT NewSched : IN SchedType;
+ CONSTANT EnSched1 : IN SchedType;
+ CONSTANT EnSched0 : IN SchedType
+ ) IS
+ SUBTYPE v2 IS std_logic_vector(0 TO 1);
+ VARIABLE Tim, Glch : TIME;
+ BEGIN
+
+ CASE v2'(To_X01Z(CurValue) & To_X01Z(NewValue)) IS
+ WHEN "00" => Tim := Maximum (NewSched.inp0, EnSched0.inp1);
+ Glch := GlitchMinTime(NewSched.Glch1,EnSched0.Glch0);
+ WHEN "01" => Tim := Maximum (NewSched.inp1, EnSched1.inp1);
+ Glch := EnSched1.Glch0;
+ WHEN "0Z" => Tim := EnSched0.inp0;
+ Glch := NewSched.Glch1;
+ WHEN "0X" => Tim := Maximum (NewSched.InpX, EnSched1.InpX);
+ Glch := 0 ns;
+ WHEN "10" => Tim := Maximum (NewSched.inp0, EnSched0.inp1);
+ Glch := EnSched0.Glch0;
+ WHEN "11" => Tim := Maximum (NewSched.inp1, EnSched1.inp1);
+ Glch := GlitchMinTime(NewSched.Glch0,EnSched1.Glch0);
+ WHEN "1Z" => Tim := EnSched1.inp0;
+ Glch := NewSched.Glch0;
+ WHEN "1X" => Tim := Maximum (NewSched.InpX, EnSched0.InpX);
+ Glch := 0 ns;
+ WHEN "Z0" => Tim := Maximum (NewSched.inp0, EnSched0.inp1);
+ IF NewSched.Glch0 > NOW
+ THEN Glch := Maximum(NewSched.Glch1,EnSched1.inp1);
+ ELSE Glch := 0 ns;
+ END IF;
+ WHEN "Z1" => Tim := Maximum (NewSched.inp1, EnSched1.inp1);
+ IF NewSched.Glch1 > NOW
+ THEN Glch := Maximum(NewSched.Glch0,EnSched0.inp1);
+ ELSE Glch := 0 ns;
+ END IF;
+ WHEN "ZX" => Tim := Maximum (NewSched.InpX, EnSched1.InpX);
+ Glch := 0 ns;
+ WHEN "ZZ" => Tim := Maximum (EnSched1.InpX, EnSched0.InpX);
+ Glch := 0 ns;
+ WHEN "X0" => Tim := Maximum (NewSched.inp0, EnSched0.inp1);
+ Glch := 0 ns;
+ WHEN "X1" => Tim := Maximum (NewSched.inp1, EnSched1.inp1);
+ Glch := 0 ns;
+ WHEN "XZ" => Tim := Maximum (EnSched1.InpX, EnSched0.InpX);
+ Glch := 0 ns;
+ WHEN OTHERS => Tim := Maximum (NewSched.InpX, EnSched1.InpX);
+ Glch := 0 ns;
+
+ END CASE;
+ NewDelay := Tim - NOW;
+ IF Glch < 0 ns
+ THEN GlchDelay := Glch;
+ ELSE GlchDelay := Glch - NOW;
+ END IF; -- glch < 0 ns
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Operators and Functions for combination (selection) of path delays
+ -- > These functions support selection of the "appripriate" path delay
+ -- dependent on the logic function.
+ -- > These functions only "select" from the possable output times. No
+ -- calculation (addition) of delays is performed.
+ -- > See description of 'BufPath', 'InvPath' and 'GetSchedDelay'
+ -- > See primitive PROCEDURE models for examples.
+ ---------------------------------------------------------------------------
+
+ FUNCTION "not" (
+ CONSTANT a : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp1 := a.inp0 ;
+ z.inp0 := a.inp1 ;
+ z.InpX := a.InpX ;
+ z.Glch1 := a.Glch0;
+ z.Glch0 := a.Glch1;
+ RETURN (z);
+ END;
+
+ FUNCTION "and" (
+ CONSTANT a, b : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp1 := Maximum ( a.inp1 , b.inp1 );
+ z.inp0 := Minimum ( a.inp0 , b.inp0 );
+ z.InpX := GlitchMinTime ( a.InpX , b.InpX );
+ z.Glch1 := Maximum ( a.Glch1, b.Glch1 );
+ z.Glch0 := GlitchMinTime ( a.Glch0, b.Glch0 );
+ RETURN (z);
+ END;
+
+ FUNCTION "or" (
+ CONSTANT a, b : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp0 := Maximum ( a.inp0 , b.inp0 );
+ z.inp1 := Minimum ( a.inp1 , b.inp1 );
+ z.InpX := GlitchMinTime ( a.InpX , b.InpX );
+ z.Glch0 := Maximum ( a.Glch0, b.Glch0 );
+ z.Glch1 := GlitchMinTime ( a.Glch1, b.Glch1 );
+ RETURN (z);
+ END;
+
+ IMPURE FUNCTION "nand" (
+ CONSTANT a, b : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp0 := Maximum ( a.inp1 , b.inp1 );
+ z.inp1 := Minimum ( a.inp0 , b.inp0 );
+ z.InpX := GlitchMinTime ( a.InpX , b.InpX );
+ z.Glch0 := Maximum ( a.Glch1, b.Glch1 );
+ z.Glch1 := GlitchMinTime ( a.Glch0, b.Glch0 );
+ RETURN (z);
+ END;
+
+ IMPURE FUNCTION "nor" (
+ CONSTANT a, b : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ z.inp1 := Maximum ( a.inp0 , b.inp0 );
+ z.inp0 := Minimum ( a.inp1 , b.inp1 );
+ z.InpX := GlitchMinTime ( a.InpX , b.InpX );
+ z.Glch1 := Maximum ( a.Glch0, b.Glch0 );
+ z.Glch0 := GlitchMinTime ( a.Glch1, b.Glch1 );
+ RETURN (z);
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Delay Calculation for 2-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ IMPURE FUNCTION VitalXOR2 (
+ CONSTANT ab,ai, bb,bi : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ -- z = (a AND b) NOR (a NOR b)
+ z.inp1 := Maximum ( Minimum (ai.inp0 , bi.inp0 ),
+ Minimum (ab.inp1 , bb.inp1 ) );
+ z.inp0 := Minimum ( Maximum (ai.inp1 , bi.inp1 ),
+ Maximum (ab.inp0 , bb.inp0 ) );
+ z.InpX := Maximum ( Maximum (ai.InpX , bi.InpX ),
+ Maximum (ab.InpX , bb.InpX ) );
+ z.Glch1 := Maximum (GlitchMinTime (ai.Glch0, bi.Glch0),
+ GlitchMinTime (ab.Glch1, bb.Glch1) );
+ z.Glch0 := GlitchMinTime ( Maximum (ai.Glch1, bi.Glch1),
+ Maximum (ab.Glch0, bb.Glch0) );
+ RETURN (z);
+ END;
+
+ IMPURE FUNCTION VitalXNOR2 (
+ CONSTANT ab,ai, bb,bi : IN SchedType
+ ) RETURN SchedType IS
+ VARIABLE z : SchedType;
+ BEGIN
+ -- z = (a AND b) OR (a NOR b)
+ z.inp0 := Maximum ( Minimum (ab.inp0 , bb.inp0 ),
+ Minimum (ai.inp1 , bi.inp1 ) );
+ z.inp1 := Minimum ( Maximum (ab.inp1 , bb.inp1 ),
+ Maximum (ai.inp0 , bi.inp0 ) );
+ z.InpX := Maximum ( Maximum (ab.InpX , bb.InpX ),
+ Maximum (ai.InpX , bi.InpX ) );
+ z.Glch0 := Maximum (GlitchMinTime (ab.Glch0, bb.Glch0),
+ GlitchMinTime (ai.Glch1, bi.Glch1) );
+ z.Glch1 := GlitchMinTime ( Maximum (ab.Glch1, bb.Glch1),
+ Maximum (ai.Glch0, bi.Glch0) );
+ RETURN (z);
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Delay Calculation for 3-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ IMPURE FUNCTION VitalXOR3 (
+ CONSTANT ab,ai, bb,bi, cb,ci : IN SchedType )
+ RETURN SchedType IS
+ BEGIN
+ RETURN VitalXOR2 ( VitalXOR2 (ab,ai, bb,bi),
+ VitalXOR2 (ai,ab, bi,bb),
+ cb, ci );
+ END;
+
+ IMPURE FUNCTION VitalXNOR3 (
+ CONSTANT ab,ai, bb,bi, cb,ci : IN SchedType )
+ RETURN SchedType IS
+ BEGIN
+ RETURN VitalXNOR2 ( VitalXOR2 ( ab,ai, bb,bi ),
+ VitalXOR2 ( ai,ab, bi,bb ),
+ cb, ci );
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Delay Calculation for 4-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ IMPURE FUNCTION VitalXOR4 (
+ CONSTANT ab,ai, bb,bi, cb,ci, db,di : IN SchedType )
+ RETURN SchedType IS
+ BEGIN
+ RETURN VitalXOR2 ( VitalXOR2 ( ab,ai, bb,bi ),
+ VitalXOR2 ( ai,ab, bi,bb ),
+ VitalXOR2 ( cb,ci, db,di ),
+ VitalXOR2 ( ci,cb, di,db ) );
+ END;
+
+ IMPURE FUNCTION VitalXNOR4 (
+ CONSTANT ab,ai, bb,bi, cb,ci, db,di : IN SchedType )
+ RETURN SchedType IS
+ BEGIN
+ RETURN VitalXNOR2 ( VitalXOR2 ( ab,ai, bb,bi ),
+ VitalXOR2 ( ai,ab, bi,bb ),
+ VitalXOR2 ( cb,ci, db,di ),
+ VitalXOR2 ( ci,cb, di,db ) );
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Delay Calculation for N-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ -- Note: index range on datab,datai assumed to be 1 TO length.
+ -- This is enforced by internal only usage of this Function
+ IMPURE FUNCTION VitalXOR (
+ CONSTANT DataB, DataI : IN SchedArray
+ ) RETURN SchedType IS
+ CONSTANT Leng : INTEGER := DataB'LENGTH;
+ BEGIN
+ IF Leng = 2 THEN
+ RETURN VitalXOR2 ( DataB(1),DataI(1), DataB(2),DataI(2) );
+ ELSE
+ RETURN VitalXOR2 ( VitalXOR ( DataB(1 TO Leng-1),
+ DataI(1 TO Leng-1) ),
+ VitalXOR ( DataI(1 TO Leng-1),
+ DataB(1 TO Leng-1) ),
+ DataB(Leng),DataI(Leng) );
+ END IF;
+ END;
+
+ -- Note: index range on datab,datai assumed to be 1 TO length.
+ -- This is enforced by internal only usage of this Function
+ IMPURE FUNCTION VitalXNOR (
+ CONSTANT DataB, DataI : IN SchedArray
+ ) RETURN SchedType IS
+ CONSTANT Leng : INTEGER := DataB'LENGTH;
+ BEGIN
+ IF Leng = 2 THEN
+ RETURN VitalXNOR2 ( DataB(1),DataI(1), DataB(2),DataI(2) );
+ ELSE
+ RETURN VitalXNOR2 ( VitalXOR ( DataB(1 TO Leng-1),
+ DataI(1 TO Leng-1) ),
+ VitalXOR ( DataI(1 TO Leng-1),
+ DataB(1 TO Leng-1) ),
+ DataB(Leng),DataI(Leng) );
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Multiplexor
+ -- MUX .......... result := data(dselect)
+ -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'),
+ -- data1 when (dselect = '1'),
+ -- 'X' when (dselect = 'X') and (data0 /= data1)
+ -- MUX4 .......... 4-input mux; result := data(dselect)
+ -- MUX8 .......... 8-input mux; result := data(dselect)
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalMUX2 (
+ CONSTANT d1, d0 : IN SchedType;
+ CONSTANT sb, SI : IN SchedType
+ ) RETURN SchedType IS
+ BEGIN
+ RETURN (d1 AND sb) OR (d0 AND (NOT SI) );
+ END;
+--
+ FUNCTION VitalMUX4 (
+ CONSTANT Data : IN SchedArray4;
+ CONSTANT sb : IN SchedArray2;
+ CONSTANT SI : IN SchedArray2
+ ) RETURN SchedType IS
+ BEGIN
+ RETURN ( sb(1) AND VitalMUX2(Data(3),Data(2), sb(0), SI(0)) )
+ OR ( (NOT SI(1)) AND VitalMUX2(Data(1),Data(0), sb(0), SI(0)) );
+ END;
+
+ FUNCTION VitalMUX8 (
+ CONSTANT Data : IN SchedArray8;
+ CONSTANT sb : IN SchedArray3;
+ CONSTANT SI : IN SchedArray3
+ ) RETURN SchedType IS
+ BEGIN
+ RETURN ( ( sb(2)) AND VitalMUX4 (Data(7 DOWNTO 4),
+ sb(1 DOWNTO 0), SI(1 DOWNTO 0) ) )
+ OR ( (NOT SI(2)) AND VitalMUX4 (Data(3 DOWNTO 0),
+ sb(1 DOWNTO 0), SI(1 DOWNTO 0) ) );
+ END;
+--
+ FUNCTION VInterMux (
+ CONSTANT Data : IN SchedArray;
+ CONSTANT sb : IN SchedArray;
+ CONSTANT SI : IN SchedArray
+ ) RETURN SchedType IS
+ CONSTANT sMsb : INTEGER := sb'LENGTH;
+ CONSTANT dMsbHigh : INTEGER := Data'LENGTH;
+ CONSTANT dMsbLow : INTEGER := Data'LENGTH/2;
+ BEGIN
+ IF sb'LENGTH = 1 THEN
+ RETURN VitalMUX2( Data(2), Data(1), sb(1), SI(1) );
+ ELSIF sb'LENGTH = 2 THEN
+ RETURN VitalMUX4( Data, sb, SI );
+ ELSIF sb'LENGTH = 3 THEN
+ RETURN VitalMUX8( Data, sb, SI );
+ ELSIF sb'LENGTH > 3 THEN
+ RETURN (( sb(sMsb)) AND VInterMux( Data(dMsbLow DOWNTO 1),
+ sb(sMsb-1 DOWNTO 1),
+ SI(sMsb-1 DOWNTO 1) ))
+ OR ((NOT SI(sMsb)) AND VInterMux( Data(dMsbHigh DOWNTO dMsbLow+1),
+ sb(sMsb-1 DOWNTO 1),
+ SI(sMsb-1 DOWNTO 1) ));
+ ELSE
+ RETURN (0 ns, 0 ns, 0 ns, 0 ns, 0 ns); -- dselect'LENGTH < 1
+ END IF;
+ END;
+--
+ FUNCTION VitalMUX (
+ CONSTANT Data : IN SchedArray;
+ CONSTANT sb : IN SchedArray;
+ CONSTANT SI : IN SchedArray
+ ) RETURN SchedType IS
+ CONSTANT msb : INTEGER := 2**sb'LENGTH;
+ VARIABLE lDat : SchedArray(msb DOWNTO 1);
+ ALIAS DataAlias : SchedArray ( Data'LENGTH DOWNTO 1 ) IS Data;
+ ALIAS sbAlias : SchedArray ( sb'LENGTH DOWNTO 1 ) IS sb;
+ ALIAS siAlias : SchedArray ( SI'LENGTH DOWNTO 1 ) IS SI;
+ BEGIN
+ IF Data'LENGTH <= msb THEN
+ FOR i IN Data'LENGTH DOWNTO 1 LOOP
+ lDat(i) := DataAlias(i);
+ END LOOP;
+ FOR i IN msb DOWNTO Data'LENGTH+1 LOOP
+ lDat(i) := DefSchedAnd;
+ END LOOP;
+ ELSE
+ FOR i IN msb DOWNTO 1 LOOP
+ lDat(i) := DataAlias(i);
+ END LOOP;
+ END IF;
+ RETURN VInterMux( lDat, sbAlias, siAlias );
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Decoder
+ -- General Algorithm :
+ -- (a) Result(...) := '0' when (enable = '0')
+ -- (b) Result(data) := '1'; all other subelements = '0'
+ -- ... Result array is decending (n-1 downto 0)
+ --
+ -- DECODERn .......... n:2**n decoder
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalDECODER2 (
+ CONSTANT DataB : IN SchedType;
+ CONSTANT DataI : IN SchedType;
+ CONSTANT Enable : IN SchedType
+ ) RETURN SchedArray IS
+ VARIABLE Result : SchedArray2;
+ BEGIN
+ Result(1) := Enable AND ( DataB);
+ Result(0) := Enable AND (NOT DataI);
+ RETURN Result;
+ END;
+
+ FUNCTION VitalDECODER4 (
+ CONSTANT DataB : IN SchedArray2;
+ CONSTANT DataI : IN SchedArray2;
+ CONSTANT Enable : IN SchedType
+ ) RETURN SchedArray IS
+ VARIABLE Result : SchedArray4;
+ BEGIN
+ Result(3) := Enable AND ( DataB(1)) AND ( DataB(0));
+ Result(2) := Enable AND ( DataB(1)) AND (NOT DataI(0));
+ Result(1) := Enable AND (NOT DataI(1)) AND ( DataB(0));
+ Result(0) := Enable AND (NOT DataI(1)) AND (NOT DataI(0));
+ RETURN Result;
+ END;
+
+ FUNCTION VitalDECODER8 (
+ CONSTANT DataB : IN SchedArray3;
+ CONSTANT DataI : IN SchedArray3;
+ CONSTANT Enable : IN SchedType
+ ) RETURN SchedArray IS
+ VARIABLE Result : SchedArray8;
+ BEGIN
+ Result(7):= Enable AND ( DataB(2))AND( DataB(1))AND( DataB(0));
+ Result(6):= Enable AND ( DataB(2))AND( DataB(1))AND(NOT DataI(0));
+ Result(5):= Enable AND ( DataB(2))AND(NOT DataI(1))AND( DataB(0));
+ Result(4):= Enable AND ( DataB(2))AND(NOT DataI(1))AND(NOT DataI(0));
+ Result(3):= Enable AND (NOT DataI(2))AND( DataB(1))AND( DataB(0));
+ Result(2):= Enable AND (NOT DataI(2))AND( DataB(1))AND(NOT DataI(0));
+ Result(1):= Enable AND (NOT DataI(2))AND(NOT DataI(1))AND( DataB(0));
+ Result(0):= Enable AND (NOT DataI(2))AND(NOT DataI(1))AND(NOT DataI(0));
+ RETURN Result;
+ END;
+
+
+ FUNCTION VitalDECODER (
+ CONSTANT DataB : IN SchedArray;
+ CONSTANT DataI : IN SchedArray;
+ CONSTANT Enable : IN SchedType
+ ) RETURN SchedArray IS
+ CONSTANT DMsb : INTEGER := DataB'LENGTH - 1;
+ ALIAS DataBAlias : SchedArray ( DMsb DOWNTO 0 ) IS DataB;
+ ALIAS DataIAlias : SchedArray ( DMsb DOWNTO 0 ) IS DataI;
+ BEGIN
+ IF DataB'LENGTH = 1 THEN
+ RETURN VitalDECODER2 ( DataBAlias( 0 ),
+ DataIAlias( 0 ), Enable );
+ ELSIF DataB'LENGTH = 2 THEN
+ RETURN VitalDECODER4 ( DataBAlias(1 DOWNTO 0),
+ DataIAlias(1 DOWNTO 0), Enable );
+ ELSIF DataB'LENGTH = 3 THEN
+ RETURN VitalDECODER8 ( DataBAlias(2 DOWNTO 0),
+ DataIAlias(2 DOWNTO 0), Enable );
+ ELSIF DataB'LENGTH > 3 THEN
+ RETURN VitalDECODER ( DataBAlias(DMsb-1 DOWNTO 0),
+ DataIAlias(DMsb-1 DOWNTO 0),
+ Enable AND ( DataBAlias(DMsb)) )
+ & VitalDECODER ( DataBAlias(DMsb-1 DOWNTO 0),
+ DataIAlias(DMsb-1 DOWNTO 0),
+ Enable AND (NOT DataIAlias(DMsb)) );
+ ELSE
+ RETURN DefSchedArray2;
+ END IF;
+ END;
+
+
+-------------------------------------------------------------------------------
+-- PRIMITIVES
+-------------------------------------------------------------------------------
+ -- ------------------------------------------------------------------------
+ -- N-bit wide Logical gates.
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalAND (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '1';
+ FOR i IN Data'RANGE LOOP
+ Result := Result AND Data(i);
+ END LOOP;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '0';
+ FOR i IN Data'RANGE LOOP
+ Result := Result OR Data(i);
+ END LOOP;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalXOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '0';
+ FOR i IN Data'RANGE LOOP
+ Result := Result XOR Data(i);
+ END LOOP;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalNAND (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '1';
+ FOR i IN Data'RANGE LOOP
+ Result := Result AND Data(i);
+ END LOOP;
+ RETURN ResultMap(NOT Result);
+ END;
+--
+ FUNCTION VitalNOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '0';
+ FOR i IN Data'RANGE LOOP
+ Result := Result OR Data(i);
+ END LOOP;
+ RETURN ResultMap(NOT Result);
+ END;
+--
+ FUNCTION VitalXNOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ Result := '0';
+ FOR i IN Data'RANGE LOOP
+ Result := Result XOR Data(i);
+ END LOOP;
+ RETURN ResultMap(NOT Result);
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Commonly used 2-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalAND2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a AND b);
+ END;
+--
+ FUNCTION VitalOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a OR b);
+ END;
+--
+ FUNCTION VitalXOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a XOR b);
+ END;
+--
+ FUNCTION VitalNAND2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a NAND b);
+ END;
+--
+ FUNCTION VitalNOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a NOR b);
+ END;
+--
+ FUNCTION VitalXNOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a XOR b));
+ END;
+--
+ -- ------------------------------------------------------------------------
+ -- Commonly used 3-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalAND3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a AND b AND c);
+ END;
+--
+ FUNCTION VitalOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a OR b OR c);
+ END;
+--
+ FUNCTION VitalXOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a XOR b XOR c);
+ END;
+--
+ FUNCTION VitalNAND3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a AND b AND c));
+ END;
+--
+ FUNCTION VitalNOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a OR b OR c));
+ END;
+--
+ FUNCTION VitalXNOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a XOR b XOR c));
+ END;
+
+ -- ---------------------------------------------------------------------------
+ -- Commonly used 4-bit Logical gates.
+ -- ---------------------------------------------------------------------------
+ FUNCTION VitalAND4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a AND b AND c AND d);
+ END;
+--
+ FUNCTION VitalOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a OR b OR c OR d);
+ END;
+--
+ FUNCTION VitalXOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(a XOR b XOR c XOR d);
+ END;
+--
+ FUNCTION VitalNAND4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a AND b AND c AND d));
+ END;
+--
+ FUNCTION VitalNOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a OR b OR c OR d));
+ END;
+--
+ FUNCTION VitalXNOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT (a XOR b XOR c XOR d));
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Buffers
+ -- BUF ....... standard non-inverting buffer
+ -- BUFIF0 ....... non-inverting buffer Data passes thru if (Enable = '0')
+ -- BUFIF1 ....... non-inverting buffer Data passes thru if (Enable = '1')
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalBUF (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(To_UX01(Data));
+ END;
+--
+ FUNCTION VitalBUFIF0 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(BufIf0_Table(Enable,Data));
+ END;
+--
+ FUNCTION VitalBUFIF1 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(BufIf1_Table(Enable,Data));
+ END;
+ FUNCTION VitalIDENT (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(To_UX01Z(Data));
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Invertors
+ -- INV ......... standard inverting buffer
+ -- INVIF0 ......... inverting buffer Data passes thru if (Enable = '0')
+ -- INVIF1 ......... inverting buffer Data passes thru if (Enable = '1')
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalINV (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(NOT Data);
+ END;
+--
+ FUNCTION VitalINVIF0 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(InvIf0_Table(Enable,Data));
+ END;
+--
+ FUNCTION VitalINVIF1 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic IS
+ BEGIN
+ RETURN ResultMap(InvIf1_Table(Enable,Data));
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Multiplexor
+ -- MUX .......... result := data(dselect)
+ -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'),
+ -- data1 when (dselect = '1'),
+ -- 'X' when (dselect = 'X') and (data0 /= data1)
+ -- MUX4 .......... 4-input mux; result := data(dselect)
+ -- MUX8 .......... 8-input mux; result := data(dselect)
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalMUX2 (
+ CONSTANT Data1, Data0 : IN std_ulogic;
+ CONSTANT dSelect : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ CASE To_X01(dSelect) IS
+ WHEN '0' => Result := To_UX01(Data0);
+ WHEN '1' => Result := To_UX01(Data1);
+ WHEN OTHERS => Result := VitalSame( Data1, Data0 );
+ END CASE;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalMUX4 (
+ CONSTANT Data : IN std_logic_vector4;
+ CONSTANT dSelect : IN std_logic_vector2;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Slct : std_logic_vector2;
+ VARIABLE Result : UX01;
+ BEGIN
+ Slct := To_X01(dSelect);
+ CASE Slct IS
+ WHEN "00" => Result := To_UX01(Data(0));
+ WHEN "01" => Result := To_UX01(Data(1));
+ WHEN "10" => Result := To_UX01(Data(2));
+ WHEN "11" => Result := To_UX01(Data(3));
+ WHEN "0X" => Result := VitalSame( Data(1), Data(0) );
+ WHEN "1X" => Result := VitalSame( Data(2), Data(3) );
+ WHEN "X0" => Result := VitalSame( Data(2), Data(0) );
+ WHEN "X1" => Result := VitalSame( Data(3), Data(1) );
+ WHEN OTHERS => Result := VitalSame( VitalSame(Data(3),Data(2)),
+ VitalSame(Data(1),Data(0)));
+ END CASE;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VitalMUX8 (
+ CONSTANT Data : IN std_logic_vector8;
+ CONSTANT dSelect : IN std_logic_vector3;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ VARIABLE Result : UX01;
+ BEGIN
+ CASE To_X01(dSelect(2)) IS
+ WHEN '0' => Result := VitalMUX4( Data(3 DOWNTO 0),
+ dSelect(1 DOWNTO 0));
+ WHEN '1' => Result := VitalMUX4( Data(7 DOWNTO 4),
+ dSelect(1 DOWNTO 0));
+ WHEN OTHERS => Result := VitalSame( VitalMUX4( Data(3 DOWNTO 0),
+ dSelect(1 DOWNTO 0)),
+ VitalMUX4( Data(7 DOWNTO 4),
+ dSelect(1 DOWNTO 0)));
+ END CASE;
+ RETURN ResultMap(Result);
+ END;
+--
+ FUNCTION VInterMux (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT dSelect : IN std_logic_vector
+ ) RETURN std_ulogic IS
+
+ CONSTANT sMsb : INTEGER := dSelect'LENGTH;
+ CONSTANT dMsbHigh : INTEGER := Data'LENGTH;
+ CONSTANT dMsbLow : INTEGER := Data'LENGTH/2;
+ ALIAS DataAlias : std_logic_vector ( Data'LENGTH DOWNTO 1) IS Data;
+ ALIAS dSelAlias : std_logic_vector (dSelect'LENGTH DOWNTO 1) IS dSelect;
+
+ VARIABLE Result : UX01;
+ BEGIN
+ IF dSelect'LENGTH = 1 THEN
+ Result := VitalMUX2( DataAlias(2), DataAlias(1), dSelAlias(1) );
+ ELSIF dSelect'LENGTH = 2 THEN
+ Result := VitalMUX4( DataAlias, dSelAlias );
+ ELSIF dSelect'LENGTH > 2 THEN
+ CASE To_X01(dSelect(sMsb)) IS
+ WHEN '0' =>
+ Result := VInterMux( DataAlias(dMsbLow DOWNTO 1),
+ dSelAlias(sMsb-1 DOWNTO 1) );
+ WHEN '1' =>
+ Result := VInterMux( DataAlias(dMsbHigh DOWNTO dMsbLow+1),
+ dSelAlias(sMsb-1 DOWNTO 1) );
+ WHEN OTHERS =>
+ Result := VitalSame(
+ VInterMux( DataAlias(dMsbLow DOWNTO 1),
+ dSelAlias(sMsb-1 DOWNTO 1) ),
+ VInterMux( DataAlias(dMsbHigh DOWNTO dMsbLow+1),
+ dSelAlias(sMsb-1 DOWNTO 1) )
+ );
+ END CASE;
+ ELSE
+ Result := 'X'; -- dselect'LENGTH < 1
+ END IF;
+ RETURN Result;
+ END;
+--
+ FUNCTION VitalMUX (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT dSelect : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic IS
+ CONSTANT msb : INTEGER := 2**dSelect'LENGTH;
+ ALIAS DataAlias : std_logic_vector ( Data'LENGTH DOWNTO 1) IS Data;
+ ALIAS dSelAlias : std_logic_vector (dSelect'LENGTH DOWNTO 1) IS dSelect;
+ VARIABLE lDat : std_logic_vector(msb DOWNTO 1) := (OTHERS=>'X');
+ VARIABLE Result : UX01;
+ BEGIN
+ IF Data'LENGTH <= msb THEN
+ FOR i IN Data'LENGTH DOWNTO 1 LOOP
+ lDat(i) := DataAlias(i);
+ END LOOP;
+ ELSE
+ FOR i IN msb DOWNTO 1 LOOP
+ lDat(i) := DataAlias(i);
+ END LOOP;
+ END IF;
+ Result := VInterMux( lDat, dSelAlias );
+ RETURN ResultMap(Result);
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Decoder
+ -- General Algorithm :
+ -- (a) Result(...) := '0' when (enable = '0')
+ -- (b) Result(data) := '1'; all other subelements = '0'
+ -- ... Result array is decending (n-1 downto 0)
+ --
+ -- DECODERn .......... n:2**n decoder
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalDECODER2 (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector2 IS
+ VARIABLE Result : std_logic_vector2;
+ BEGIN
+ Result(1) := ResultMap(Enable AND ( Data));
+ Result(0) := ResultMap(Enable AND (NOT Data));
+ RETURN Result;
+ END;
+--
+ FUNCTION VitalDECODER4 (
+ CONSTANT Data : IN std_logic_vector2;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector4 IS
+ VARIABLE Result : std_logic_vector4;
+ BEGIN
+ Result(3) := ResultMap(Enable AND ( Data(1)) AND ( Data(0)));
+ Result(2) := ResultMap(Enable AND ( Data(1)) AND (NOT Data(0)));
+ Result(1) := ResultMap(Enable AND (NOT Data(1)) AND ( Data(0)));
+ Result(0) := ResultMap(Enable AND (NOT Data(1)) AND (NOT Data(0)));
+ RETURN Result;
+ END;
+--
+ FUNCTION VitalDECODER8 (
+ CONSTANT Data : IN std_logic_vector3;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector8 IS
+ VARIABLE Result : std_logic_vector8;
+ BEGIN
+ Result(7) := ( Data(2)) AND ( Data(1)) AND ( Data(0));
+ Result(6) := ( Data(2)) AND ( Data(1)) AND (NOT Data(0));
+ Result(5) := ( Data(2)) AND (NOT Data(1)) AND ( Data(0));
+ Result(4) := ( Data(2)) AND (NOT Data(1)) AND (NOT Data(0));
+ Result(3) := (NOT Data(2)) AND ( Data(1)) AND ( Data(0));
+ Result(2) := (NOT Data(2)) AND ( Data(1)) AND (NOT Data(0));
+ Result(1) := (NOT Data(2)) AND (NOT Data(1)) AND ( Data(0));
+ Result(0) := (NOT Data(2)) AND (NOT Data(1)) AND (NOT Data(0));
+
+ Result(0) := ResultMap ( Enable AND Result(0) );
+ Result(1) := ResultMap ( Enable AND Result(1) );
+ Result(2) := ResultMap ( Enable AND Result(2) );
+ Result(3) := ResultMap ( Enable AND Result(3) );
+ Result(4) := ResultMap ( Enable AND Result(4) );
+ Result(5) := ResultMap ( Enable AND Result(5) );
+ Result(6) := ResultMap ( Enable AND Result(6) );
+ Result(7) := ResultMap ( Enable AND Result(7) );
+
+ RETURN Result;
+ END;
+--
+ FUNCTION VitalDECODER (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector IS
+
+ CONSTANT DMsb : INTEGER := Data'LENGTH - 1;
+ ALIAS DataAlias : std_logic_vector ( DMsb DOWNTO 0 ) IS Data;
+ BEGIN
+ IF Data'LENGTH = 1 THEN
+ RETURN VitalDECODER2 (DataAlias( 0 ), Enable, ResultMap );
+ ELSIF Data'LENGTH = 2 THEN
+ RETURN VitalDECODER4 (DataAlias(1 DOWNTO 0), Enable, ResultMap );
+ ELSIF Data'LENGTH = 3 THEN
+ RETURN VitalDECODER8 (DataAlias(2 DOWNTO 0), Enable, ResultMap );
+ ELSIF Data'LENGTH > 3 THEN
+ RETURN VitalDECODER (DataAlias(DMsb-1 DOWNTO 0),
+ Enable AND ( DataAlias(DMsb)), ResultMap )
+ & VitalDECODER (DataAlias(DMsb-1 DOWNTO 0),
+ Enable AND (NOT DataAlias(DMsb)), ResultMap );
+ ELSE RETURN "X";
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- N-bit wide Logical gates.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalAND (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalAND(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := '1';
+ new_schd := Data_Schd(Data_Schd'LEFT);
+ FOR i IN Data'RANGE LOOP
+ NewValue := NewValue AND Data(i);
+ new_schd := new_schd AND Data_Schd(i);
+ END LOOP;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalOR(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := '0';
+ new_schd := Data_Schd(Data_Schd'LEFT);
+ FOR i IN Data'RANGE LOOP
+ NewValue := NewValue OR Data(i);
+ new_schd := new_schd OR Data_Schd(i);
+ END LOOP;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalXOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE DataB_Schd : SchedArray(1 TO Data'LENGTH);
+ VARIABLE DataI_Schd : SchedArray(1 TO Data'LENGTH);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS ADataB_Schd : SchedArray(Data'RANGE) IS DataB_Schd;
+ ALIAS ADataI_Schd : SchedArray(Data'RANGE) IS DataI_Schd;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalXOR(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( ADataB_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( ADataI_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( ADataB_Schd, Data_Edge, Atpd_data_q );
+ InvPath ( ADataI_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalXOR ( Data );
+ new_schd := VitalXOR ( DataB_Schd, DataI_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalNAND (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalNAND(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ InvPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ InvPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := '1';
+ new_schd := Data_Schd(Data_Schd'LEFT);
+ FOR i IN Data'RANGE LOOP
+ NewValue := NewValue AND Data(i);
+ new_schd := new_schd AND Data_Schd(i);
+ END LOOP;
+ NewValue := NOT NewValue;
+ new_schd := NOT new_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalNOR(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ InvPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ InvPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := '0';
+ new_schd := Data_Schd(Data_Schd'LEFT);
+ FOR i IN Data'RANGE LOOP
+ NewValue := NewValue OR Data(i);
+ new_schd := new_schd OR Data_Schd(i);
+ END LOOP;
+ NewValue := NOT NewValue;
+ new_schd := NOT new_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalXNOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE DataB_Schd : SchedArray(1 TO Data'LENGTH);
+ VARIABLE DataI_Schd : SchedArray(1 TO Data'LENGTH);
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS ADataB_Schd : SchedArray(Data'RANGE) IS DataB_Schd;
+ ALIAS ADataI_Schd : SchedArray(Data'RANGE) IS DataI_Schd;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalXNOR(Data, ResultMap);
+ WAIT ON Data;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( ADataB_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( ADataI_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( ADataB_Schd, Data_Edge, Atpd_data_q );
+ InvPath ( ADataI_Schd, Data_Edge, Atpd_data_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalXNOR ( Data );
+ new_schd := VitalXNOR ( DataB_Schd, DataI_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+
+ -- ------------------------------------------------------------------------
+ -- Commonly used 2-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalAND2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalAND2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a AND b;
+ new_schd := a_schd AND b_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalOR2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a OR b;
+ new_schd := a_schd OR b_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNAND2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNAND2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a NAND b;
+ new_schd := a_schd NAND b_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNOR2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a NOR b;
+ new_schd := a_schd NOR b_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd : SchedType;
+ VARIABLE ai_schd, bi_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXOR2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a XOR b;
+ new_schd := VitalXOR2 ( ab_schd,ai_schd, bb_schd,bi_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXNOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd : SchedType;
+ VARIABLE ai_schd, bi_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ((tpd_a_q = VitalZeroDelay01) AND (tpd_b_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXNOR2 ( a, b, ResultMap );
+ WAIT ON a, b;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := NOT (a XOR b);
+ new_schd := VitalXNOR2 ( ab_schd,ai_schd, bb_schd,bi_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Commonly used 3-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalAND3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+--
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalAND3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( c_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+ BufPath ( c_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a AND b AND c;
+ new_schd := a_schd AND b_schd AND c_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalOR3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( c_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+ BufPath ( c_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a OR b OR c;
+ new_schd := a_schd OR b_schd OR c_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNAND3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNAND3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( c_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+ InvPath ( c_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := (a AND b) NAND c;
+ new_schd := (a_schd AND b_schd) NAND c_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNOR3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( c_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+ InvPath ( c_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := (a OR b) NOR c;
+ new_schd := (a_schd OR b_schd) NOR c_schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd, cb_schd : SchedType;
+ VARIABLE ai_schd, bi_schd, ci_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXOR3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, GetEdge(c), tpd_c_q );
+ InvPath ( ci_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a XOR b XOR c;
+ new_schd := VitalXOR3 ( ab_schd,ai_schd,
+ bb_schd,bi_schd,
+ cb_schd,ci_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXNOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd, cb_schd : SchedType;
+ VARIABLE ai_schd, bi_schd, ci_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXNOR3 ( a, b, c, ResultMap );
+ WAIT ON a, b, c;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, GetEdge(c), tpd_c_q );
+ InvPath ( ci_schd, GetEdge(c), tpd_c_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := NOT (a XOR b XOR c);
+ new_schd := VitalXNOR3 ( ab_schd, ai_schd,
+ bb_schd, bi_schd,
+ cb_schd, ci_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Commonly used 4-bit Logical gates.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalAND4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalAND4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( c_schd, InitialEdge(c), tpd_c_q );
+ BufPath ( d_Schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+ BufPath ( c_schd, GetEdge(c), tpd_c_q );
+ BufPath ( d_Schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a AND b AND c AND d;
+ new_schd := a_schd AND b_schd AND c_schd AND d_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalOR4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( a_schd, InitialEdge(a), tpd_a_q );
+ BufPath ( b_schd, InitialEdge(b), tpd_b_q );
+ BufPath ( c_schd, InitialEdge(c), tpd_c_q );
+ BufPath ( d_Schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( a_schd, GetEdge(a), tpd_a_q );
+ BufPath ( b_schd, GetEdge(b), tpd_b_q );
+ BufPath ( c_schd, GetEdge(c), tpd_c_q );
+ BufPath ( d_Schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a OR b OR c OR d;
+ new_schd := a_schd OR b_schd OR c_schd OR d_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNAND4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNAND4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( c_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( d_Schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+ InvPath ( c_schd, GetEdge(c), tpd_c_q );
+ InvPath ( d_Schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := (a AND b) NAND (c AND d);
+ new_schd := (a_schd AND b_schd) NAND (c_schd AND d_Schd);
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalNOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE a_schd, b_schd, c_schd, d_Schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalNOR4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( a_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( b_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( c_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( d_Schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( a_schd, GetEdge(a), tpd_a_q );
+ InvPath ( b_schd, GetEdge(b), tpd_b_q );
+ InvPath ( c_schd, GetEdge(c), tpd_c_q );
+ InvPath ( d_Schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := (a OR b) NOR (c OR d);
+ new_schd := (a_schd OR b_schd) NOR (c_schd OR d_Schd);
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd, cb_schd, DB_Schd : SchedType;
+ VARIABLE ai_schd, bi_schd, ci_schd, di_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXOR4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
+
+ BufPath ( DB_Schd, InitialEdge(d), tpd_d_q );
+ InvPath ( di_schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, GetEdge(c), tpd_c_q );
+ InvPath ( ci_schd, GetEdge(c), tpd_c_q );
+
+ BufPath ( DB_Schd, GetEdge(d), tpd_d_q );
+ InvPath ( di_schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := a XOR b XOR c XOR d;
+ new_schd := VitalXOR4 ( ab_schd,ai_schd, bb_schd,bi_schd,
+ cb_schd,ci_schd, DB_Schd,di_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalXNOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE ab_schd, bb_schd, cb_schd, DB_Schd : SchedType;
+ VARIABLE ai_schd, bi_schd, ci_schd, di_schd : SchedType;
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_a_q = VitalZeroDelay01)
+ AND (tpd_b_q = VitalZeroDelay01)
+ AND (tpd_c_q = VitalZeroDelay01)
+ AND (tpd_d_q = VitalZeroDelay01)) THEN
+ LOOP
+ q <= VitalXNOR4 ( a, b, c, d, ResultMap );
+ WAIT ON a, b, c, d;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, InitialEdge(a), tpd_a_q );
+ InvPath ( ai_schd, InitialEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, InitialEdge(b), tpd_b_q );
+ InvPath ( bi_schd, InitialEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, InitialEdge(c), tpd_c_q );
+ InvPath ( ci_schd, InitialEdge(c), tpd_c_q );
+
+ BufPath ( DB_Schd, InitialEdge(d), tpd_d_q );
+ InvPath ( di_schd, InitialEdge(d), tpd_d_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( ab_schd, GetEdge(a), tpd_a_q );
+ InvPath ( ai_schd, GetEdge(a), tpd_a_q );
+
+ BufPath ( bb_schd, GetEdge(b), tpd_b_q );
+ InvPath ( bi_schd, GetEdge(b), tpd_b_q );
+
+ BufPath ( cb_schd, GetEdge(c), tpd_c_q );
+ InvPath ( ci_schd, GetEdge(c), tpd_c_q );
+
+ BufPath ( DB_Schd, GetEdge(d), tpd_d_q );
+ InvPath ( di_schd, GetEdge(d), tpd_d_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := NOT (a XOR b XOR c XOR d);
+ new_schd := VitalXNOR4 ( ab_schd,ai_schd, bb_schd,bi_schd,
+ cb_schd,ci_schd, DB_Schd,di_schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON a, b, c, d;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Buffers
+ -- BUF ....... standard non-inverting buffer
+ -- BUFIF0 ....... non-inverting buffer Data passes thru if (Enable = '0')
+ -- BUFIF1 ....... non-inverting buffer Data passes thru if (Enable = '1')
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalBUF (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_a_q = VitalZeroDelay01) THEN
+ LOOP
+ q <= ResultMap(To_UX01(a));
+ WAIT ON a;
+ END LOOP;
+
+ ELSE
+ LOOP
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := To_UX01(a); -- convert to forcing strengths
+ CASE EdgeType'(GetEdge(a)) IS
+ WHEN '1'|'/'|'R'|'r' => Dly := tpd_a_q(tr01);
+ WHEN '0'|'\'|'F'|'f' => Dly := tpd_a_q(tr10);
+ WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10));
+ END CASE;
+
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode );
+
+ WAIT ON a;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalBUFIF1 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ VARIABLE NewValue : UX01Z;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_data_q = VitalZeroDelay01 )
+ AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
+ LOOP
+ q <= VitalBUFIF1( Data, Enable, ResultMap );
+ WAIT ON Data, Enable;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( d_Schd, InitialEdge(Data), tpd_data_q );
+ BufEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( d_Schd, GetEdge(Data), tpd_data_q );
+ BufEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalBUFIF1( Data, Enable );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
+ d_Schd, e1_Schd, e0_Schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalBUFIF0 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ VARIABLE NewValue : UX01Z;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
+ VARIABLE ne1_schd, ne0_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_data_q = VitalZeroDelay01 )
+ AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
+ LOOP
+ q <= VitalBUFIF0( Data, Enable, ResultMap );
+ WAIT ON Data, Enable;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( d_Schd, InitialEdge(Data), tpd_data_q );
+ InvEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( d_Schd, GetEdge(Data), tpd_data_q );
+ InvEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalBUFIF0( Data, Enable );
+ ne1_schd := NOT e1_Schd;
+ ne0_schd := NOT e0_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
+ d_Schd, ne1_schd, ne0_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+
+ PROCEDURE VitalIDENT (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ SUBTYPE v2 IS std_logic_vector(0 TO 1);
+ VARIABLE NewValue : UX01Z;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_a_q = VitalZeroDelay01Z) THEN
+ LOOP
+ q <= ResultMap(To_UX01Z(a));
+ WAIT ON a;
+ END LOOP;
+
+ ELSE
+ LOOP
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ CASE v2'(To_X01Z(NewValue) & To_X01Z(a)) IS
+ WHEN "00" => Dly := tpd_a_q(tr10);
+ WHEN "01" => Dly := tpd_a_q(tr01);
+ WHEN "0Z" => Dly := tpd_a_q(tr0z);
+ WHEN "0X" => Dly := tpd_a_q(tr01);
+ WHEN "10" => Dly := tpd_a_q(tr10);
+ WHEN "11" => Dly := tpd_a_q(tr01);
+ WHEN "1Z" => Dly := tpd_a_q(tr1z);
+ WHEN "1X" => Dly := tpd_a_q(tr10);
+ WHEN "Z0" => Dly := tpd_a_q(trz0);
+ WHEN "Z1" => Dly := tpd_a_q(trz1);
+ WHEN "ZZ" => Dly := 0 ns;
+ WHEN "ZX" => Dly := Minimum (tpd_a_q(trz1), tpd_a_q(trz0));
+ WHEN "X0" => Dly := tpd_a_q(tr10);
+ WHEN "X1" => Dly := tpd_a_q(tr01);
+ WHEN "XZ" => Dly := Minimum (tpd_a_q(tr0z), tpd_a_q(tr1z));
+ WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10));
+ END CASE;
+ NewValue := To_UX01Z(a);
+
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode );
+
+ WAIT ON a;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Invertors
+ -- INV ......... standard inverting buffer
+ -- INVIF0 ......... inverting buffer Data passes thru if (Enable = '0')
+ -- INVIF1 ......... inverting buffer Data passes thru if (Enable = '1')
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalINV (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic ;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+ IF (tpd_a_q = VitalZeroDelay01) THEN
+ LOOP
+ q <= ResultMap(NOT a);
+ WAIT ON a;
+ END LOOP;
+
+ ELSE
+ LOOP
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := NOT a;
+ CASE EdgeType'(GetEdge(a)) IS
+ WHEN '1'|'/'|'R'|'r' => Dly := tpd_a_q(tr10);
+ WHEN '0'|'\'|'F'|'f' => Dly := tpd_a_q(tr01);
+ WHEN OTHERS => Dly := Minimum (tpd_a_q(tr01), tpd_a_q(tr10));
+ END CASE;
+
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode );
+
+ WAIT ON a;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalINVIF1 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ VARIABLE NewValue : UX01Z;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_data_q = VitalZeroDelay01 )
+ AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
+ LOOP
+ q <= VitalINVIF1( Data, Enable, ResultMap );
+ WAIT ON Data, Enable;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( d_Schd, InitialEdge(Data), tpd_data_q );
+ BufEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( d_Schd, GetEdge(Data), tpd_data_q );
+ BufEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalINVIF1( Data, Enable );
+ new_schd := NOT d_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
+ new_schd, e1_Schd, e0_Schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalINVIF0 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) IS
+ VARIABLE NewValue : UX01Z;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE d_Schd, e1_Schd, e0_Schd : SchedType;
+ VARIABLE ne1_schd, ne0_schd : SchedType := DefSchedType;
+ VARIABLE Dly, Glch : TIME;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_data_q = VitalZeroDelay01 )
+ AND (tpd_enable_q = VitalZeroDelay01Z)) THEN
+ LOOP
+ q <= VitalINVIF0( Data, Enable, ResultMap );
+ WAIT ON Data, Enable;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ InvPath ( d_Schd, InitialEdge(Data), tpd_data_q );
+ InvEnab ( e1_Schd, e0_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ InvPath ( d_Schd, GetEdge(Data), tpd_data_q );
+ InvEnab ( e1_Schd, e0_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delay
+ -- ------------------------------------
+ NewValue := VitalINVIF0( Data, Enable );
+ ne1_schd := NOT e1_Schd;
+ ne0_schd := NOT e0_Schd;
+ new_schd := NOT d_Schd;
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data),
+ new_schd, ne1_schd, ne0_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Multiplexor
+ -- MUX .......... result := data(dselect)
+ -- MUX2 .......... 2-input mux; result := data0 when (dselect = '0'),
+ -- data1 when (dselect = '1'),
+ -- 'X' when (dselect = 'X') and (data0 /= data1)
+ -- MUX4 .......... 4-input mux; result := data(dselect)
+ -- MUX8 .......... 8-input mux; result := data(dselect)
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalMUX2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL d1, d0 : IN std_ulogic;
+ SIGNAL dSel : IN std_ulogic;
+ CONSTANT tpd_d1_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d0_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_dsel_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ VARIABLE d1_Schd, d0_Schd : SchedType;
+ VARIABLE dSel_bSchd, dSel_iSchd : SchedType;
+ VARIABLE d1_Edge, d0_Edge, dSel_Edge : EdgeType;
+ BEGIN
+
+ -- ------------------------------------------------------------------------
+ -- For ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF ( (tpd_d1_q = VitalZeroDelay01)
+ AND (tpd_d0_q = VitalZeroDelay01)
+ AND (tpd_dsel_q = VitalZeroDelay01) ) THEN
+ LOOP
+ q <= VitalMUX2 ( d1, d0, dSel, ResultMap );
+ WAIT ON d1, d0, dSel;
+ END LOOP;
+
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( d1_Schd, InitialEdge(d1), tpd_d1_q );
+ BufPath ( d0_Schd, InitialEdge(d0), tpd_d0_q );
+ BufPath ( dSel_bSchd, InitialEdge(dSel), tpd_dsel_q );
+ InvPath ( dSel_iSchd, InitialEdge(dSel), tpd_dsel_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( d1_Schd, GetEdge(d1), tpd_d1_q );
+ BufPath ( d0_Schd, GetEdge(d0), tpd_d0_q );
+ BufPath ( dSel_bSchd, GetEdge(dSel), tpd_dsel_q );
+ InvPath ( dSel_iSchd, GetEdge(dSel), tpd_dsel_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalMUX2 ( d1, d0, dSel );
+ new_schd := VitalMUX2 ( d1_Schd, d0_Schd, dSel_bSchd, dSel_iSchd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON d1, d0, dSel;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalMUX4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector4;
+ SIGNAL dSel : IN std_logic_vector2;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ VARIABLE Data_Schd : SchedArray4;
+ VARIABLE Data_Edge : EdgeArray4;
+ VARIABLE dSel_Edge : EdgeArray2;
+ VARIABLE dSel_bSchd : SchedArray2;
+ VARIABLE dSel_iSchd : SchedArray2;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN dSel'RANGE LOOP
+ IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalMUX(Data, dSel, ResultMap);
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ FOR n IN dSel'RANGE LOOP
+ BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ GetEdge ( dSel, LastdSel, dSel_Edge );
+ BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q );
+ InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalMUX4 ( Data, dSel );
+ new_schd := VitalMUX4 ( Data_Schd, dSel_bSchd, dSel_iSchd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF; --SN
+ END;
+
+ PROCEDURE VitalMUX8 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector8;
+ SIGNAL dSel : IN std_logic_vector3;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ VARIABLE Data_Schd : SchedArray8;
+ VARIABLE Data_Edge : EdgeArray8;
+ VARIABLE dSel_Edge : EdgeArray3;
+ VARIABLE dSel_bSchd : SchedArray3;
+ VARIABLE dSel_iSchd : SchedArray3;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN dSel'RANGE LOOP
+ IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalMUX(Data, dSel, ResultMap);
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ FOR n IN dSel'RANGE LOOP
+ BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ GetEdge ( dSel, LastdSel, dSel_Edge );
+ BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q );
+ InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalMUX8 ( Data, dSel );
+ new_schd := VitalMUX8 ( Data_Schd, dSel_bSchd, dSel_iSchd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalMUX (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ SIGNAL dSel : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE LastdSel : std_logic_vector(dSel'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : UX01;
+ VARIABLE Glitch_Data : GlitchDataType;
+ VARIABLE new_schd : SchedType;
+ VARIABLE Dly, Glch : TIME;
+ VARIABLE Data_Schd : SchedArray(Data'RANGE);
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE dSel_Edge : EdgeArray(dSel'RANGE);
+ VARIABLE dSel_bSchd : SchedArray(dSel'RANGE);
+ VARIABLE dSel_iSchd : SchedArray(dSel'RANGE);
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ ALIAS Atpd_dsel_q : VitalDelayArrayType01(dSel'RANGE) IS tpd_dsel_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ FOR i IN dSel'RANGE LOOP
+ IF (Atpd_dsel_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ IF (AllZeroDelay) THEN
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalMUX(Data, dSel, ResultMap);
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_Schd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ FOR n IN dSel'RANGE LOOP
+ BufPath ( dSel_bSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ InvPath ( dSel_iSchd(n), InitialEdge(dSel(n)), Atpd_dsel_q(n) );
+ END LOOP;
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_Schd, Data_Edge, Atpd_data_q );
+
+ GetEdge ( dSel, LastdSel, dSel_Edge );
+ BufPath ( dSel_bSchd, dSel_Edge, Atpd_dsel_q );
+ InvPath ( dSel_iSchd, dSel_Edge, Atpd_dsel_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalMUX ( Data, dSel );
+ new_schd := VitalMUX ( Data_Schd, dSel_bSchd, dSel_iSchd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, ResultMap(NewValue), Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, dSel;
+ END LOOP;
+ END IF; --SN
+ END;
+
+ -- ------------------------------------------------------------------------
+ -- Decoder
+ -- General Algorithm :
+ -- (a) Result(...) := '0' when (enable = '0')
+ -- (b) Result(data) := '1'; all other subelements = '0'
+ -- ... Result array is decending (n-1 downto 0)
+ --
+ -- DECODERn .......... n:2**n decoder
+ -- Caution: If 'ResultMap' defines other than strength mapping, the
+ -- delay selection is not defined.
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalDECODER2 (
+ SIGNAL q : OUT std_logic_vector2;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE NewValue : std_logic_vector2;
+ VARIABLE Glitch_Data : GlitchArray2;
+ VARIABLE new_schd : SchedArray2;
+ VARIABLE Dly, Glch : TimeArray2;
+ VARIABLE Enable_Schd : SchedType := DefSchedType;
+ VARIABLE Data_BSchd, Data_ISchd : SchedType;
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_enable_q = VitalZeroDelay01) AND (tpd_data_q = VitalZeroDelay01) THEN
+ LOOP
+ q <= VitalDECODER2(Data, Enable, ResultMap);
+ WAIT ON Data, Enable;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ BufPath ( Data_BSchd, InitialEdge(Data), tpd_data_q );
+ InvPath ( Data_ISchd, InitialEdge(Data), tpd_data_q );
+ BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ BufPath ( Data_BSchd, GetEdge(Data), tpd_data_q );
+ InvPath ( Data_ISchd, GetEdge(Data), tpd_data_q );
+
+ BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalDECODER2 ( Data, Enable, ResultMap );
+ new_schd := VitalDECODER2 ( Data_BSchd, Data_ISchd, Enable_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF; -- SN
+ END;
+--
+ PROCEDURE VitalDECODER4 (
+ SIGNAL q : OUT std_logic_vector4;
+ SIGNAL Data : IN std_logic_vector2;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : std_logic_vector4;
+ VARIABLE Glitch_Data : GlitchArray4;
+ VARIABLE new_schd : SchedArray4;
+ VARIABLE Dly, Glch : TimeArray4;
+ VARIABLE Enable_Schd : SchedType;
+ VARIABLE Enable_Edge : EdgeType;
+ VARIABLE Data_Edge : EdgeArray2;
+ VARIABLE Data_BSchd, Data_ISchd : SchedArray2;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_enable_q /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ ELSE
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ END IF;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalDECODER4(Data, Enable, ResultMap);
+ WAIT ON Data, Enable;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_BSchd, Data_Edge, Atpd_data_q );
+ InvPath ( Data_ISchd, Data_Edge, Atpd_data_q );
+
+ BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalDECODER4 ( Data, Enable, ResultMap );
+ new_schd := VitalDECODER4 ( Data_BSchd, Data_ISchd, Enable_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+--
+ PROCEDURE VitalDECODER8 (
+ SIGNAL q : OUT std_logic_vector8;
+ SIGNAL Data : IN std_logic_vector3;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : std_logic_vector8;
+ VARIABLE Glitch_Data : GlitchArray8;
+ VARIABLE new_schd : SchedArray8;
+ VARIABLE Dly, Glch : TimeArray8;
+ VARIABLE Enable_Schd : SchedType;
+ VARIABLE Enable_Edge : EdgeType;
+ VARIABLE Data_Edge : EdgeArray3;
+ VARIABLE Data_BSchd, Data_ISchd : SchedArray3;
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE; --SN
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_enable_q /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ ELSE
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ END IF;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalDECODER(Data, Enable, ResultMap);
+ WAIT ON Data, Enable;
+ END LOOP;
+ ELSE
+
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_BSchd, Data_Edge, Atpd_data_q );
+ InvPath ( Data_ISchd, Data_Edge, Atpd_data_q );
+
+ BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalDECODER8 ( Data, Enable, ResultMap );
+ new_schd := VitalDECODER8 ( Data_BSchd, Data_ISchd, Enable_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF; --SN
+ END;
+--
+ PROCEDURE VitalDECODER (
+ SIGNAL q : OUT std_logic_vector;
+ SIGNAL Data : IN std_logic_vector;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) IS
+ VARIABLE LastData : std_logic_vector(Data'RANGE) := (OTHERS=>'U');
+ VARIABLE NewValue : std_logic_vector(q'RANGE);
+ VARIABLE Glitch_Data : GlitchDataArrayType(q'RANGE);
+ VARIABLE new_schd : SchedArray(q'RANGE);
+ VARIABLE Dly, Glch : VitalTimeArray(q'RANGE);
+ VARIABLE Enable_Schd : SchedType;
+ VARIABLE Enable_Edge : EdgeType;
+ VARIABLE Data_Edge : EdgeArray(Data'RANGE);
+ VARIABLE Data_BSchd, Data_ISchd : SchedArray(Data'RANGE);
+ ALIAS Atpd_data_q : VitalDelayArrayType01(Data'RANGE) IS tpd_data_q;
+ VARIABLE AllZeroDelay : BOOLEAN := TRUE;
+ BEGIN
+ -- ------------------------------------------------------------------------
+ -- Check if ALL zero delay paths, use simple model
+ -- ( No delay selection, glitch detection required )
+ -- ------------------------------------------------------------------------
+ IF (tpd_enable_q /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ ELSE
+ FOR i IN Data'RANGE LOOP
+ IF (Atpd_data_q(i) /= VitalZeroDelay01) THEN
+ AllZeroDelay := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+ END IF;
+ IF (AllZeroDelay) THEN LOOP
+ q <= VitalDECODER(Data, Enable, ResultMap);
+ WAIT ON Data, Enable;
+ END LOOP;
+ ELSE
+ -- --------------------------------------
+ -- Initialize delay schedules
+ -- --------------------------------------
+ FOR n IN Data'RANGE LOOP
+ BufPath ( Data_BSchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ InvPath ( Data_ISchd(n), InitialEdge(Data(n)), Atpd_data_q(n) );
+ END LOOP;
+ BufPath ( Enable_Schd, InitialEdge(Enable), tpd_enable_q );
+
+ LOOP
+ -- --------------------------------------
+ -- Process input signals
+ -- get edge values
+ -- re-evaluate output schedules
+ -- --------------------------------------
+ GetEdge ( Data, LastData, Data_Edge );
+ BufPath ( Data_BSchd, Data_Edge, Atpd_data_q );
+ InvPath ( Data_ISchd, Data_Edge, Atpd_data_q );
+
+ BufPath ( Enable_Schd, GetEdge(Enable), tpd_enable_q );
+
+ -- ------------------------------------
+ -- Compute function and propation delaq
+ -- ------------------------------------
+ NewValue := VitalDECODER ( Data, Enable, ResultMap );
+ new_schd := VitalDECODER ( Data_BSchd, Data_ISchd, Enable_Schd );
+
+ -- ------------------------------------------------------
+ -- Assign Outputs
+ -- get delays to new value and possable glitch
+ -- schedule output change with On Event glitch detection
+ -- ------------------------------------------------------
+ GetSchedDelay ( Dly, Glch, NewValue, CurValue(Glitch_Data), new_schd );
+ VitalGlitchOnEvent ( q, "q", Glitch_Data, NewValue, Dly,
+ PrimGlitchMode, GlitchDelay=>Glch );
+
+ WAIT ON Data, Enable;
+ END LOOP;
+ END IF;
+ END;
+
+ -- ------------------------------------------------------------------------
+ FUNCTION VitalTruthTable (
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) RETURN std_logic_vector IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER := TruthTable'LENGTH(2) - InputSize;
+ VARIABLE ReturnValue : std_logic_vector(OutSize - 1 DOWNTO 0)
+ := (OTHERS => 'X');
+ VARIABLE DataInAlias : std_logic_vector(0 TO InputSize - 1)
+ := To_X01(DataIn);
+ VARIABLE Index : INTEGER;
+ VARIABLE Err : BOOLEAN := FALSE;
+
+ -- This needs to be done since the TableLookup arrays must be
+ -- ascending starting with 0
+ VARIABLE TableAlias : VitalTruthTableType(0 TO (TruthTable'LENGTH(1)-1),
+ 0 TO (TruthTable'LENGTH(2)-1))
+ := TruthTable;
+
+ BEGIN
+ -- search through each row of the truth table
+ IF OutSize > 0 THEN
+ ColLoop:
+ FOR i IN TableAlias'RANGE(1) LOOP
+
+ RowLoop: -- Check each input element of the entry
+ FOR j IN 0 TO InputSize LOOP
+
+ IF (j = InputSize) THEN -- This entry matches
+ -- Return the Result
+ Index := 0;
+ FOR k IN TruthTable'LENGTH(2) - 1 DOWNTO InputSize LOOP
+ TruthOutputX01Z ( TableAlias(i,k),
+ ReturnValue(Index), Err);
+ EXIT WHEN Err;
+ Index := Index + 1;
+ END LOOP;
+
+ IF Err THEN
+ ReturnValue := (OTHERS => 'X');
+ END IF;
+ RETURN ReturnValue;
+ END IF;
+ IF NOT ValidTruthTableInput(TableAlias(i,j)) THEN
+ VitalError ( "VitalTruthTable", ErrInpSym,
+ To_TruthChar(TableAlias(i,j)) );
+ EXIT ColLoop;
+ END IF;
+ EXIT RowLoop WHEN NOT ( TruthTableMatch( DataInAlias(j),
+ TableAlias(i, j)));
+ END LOOP RowLoop;
+ END LOOP ColLoop;
+
+ ELSE
+ VitalError ( "VitalTruthTable", ErrTabWidSml );
+ END IF;
+ RETURN ReturnValue;
+ END VitalTruthTable;
+
+ FUNCTION VitalTruthTable (
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) RETURN std_logic IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER := TruthTable'LENGTH(2) - InputSize;
+ VARIABLE TempResult : std_logic_vector(OutSize - 1 DOWNTO 0)
+ := (OTHERS => 'X');
+ BEGIN
+ IF (OutSize > 0) THEN
+ TempResult := VitalTruthTable(TruthTable, DataIn);
+ IF ( 1 > OutSize) THEN
+ VitalError ( "VitalTruthTable", ErrTabResSml );
+ ELSIF ( 1 < OutSize) THEN
+ VitalError ( "VitalTruthTable", ErrTabResLrg );
+ END IF;
+ RETURN (TempResult(0));
+ ELSE
+ VitalError ( "VitalTruthTable", ErrTabWidSml );
+ RETURN 'X';
+ END IF;
+ END VitalTruthTable;
+
+ PROCEDURE VitalTruthTable (
+ SIGNAL Result : OUT std_logic_vector;
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ SIGNAL DataIn : IN std_logic_vector -- IR#236
+ ) IS
+ CONSTANT ResLeng : INTEGER := Result'LENGTH;
+ CONSTANT ActResLen : INTEGER := TruthTable'LENGTH(2) - DataIn'LENGTH;
+ CONSTANT FinalResLen : INTEGER := Minimum(ActResLen, ResLeng);
+ VARIABLE TempResult : std_logic_vector(ActResLen - 1 DOWNTO 0)
+ := (OTHERS => 'X');
+
+ BEGIN
+ TempResult := VitalTruthTable(TruthTable, DataIn);
+
+ IF (ResLeng > ActResLen) THEN
+ VitalError ( "VitalTruthTable", ErrTabResSml );
+ ELSIF (ResLeng < ActResLen) THEN
+ VitalError ( "VitalTruthTable", ErrTabResLrg );
+ END IF;
+ TempResult(FinalResLen-1 DOWNTO 0) := TempResult(FinalResLen-1 DOWNTO 0);
+ Result <= TempResult;
+
+ END VitalTruthTable;
+
+ PROCEDURE VitalTruthTable (
+ SIGNAL Result : OUT std_logic;
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ SIGNAL DataIn : IN std_logic_vector -- IR#236
+ ) IS
+
+ CONSTANT ActResLen : INTEGER := TruthTable'LENGTH(2) - DataIn'LENGTH;
+ VARIABLE TempResult : std_logic_vector(ActResLen - 1 DOWNTO 0)
+ := (OTHERS => 'X');
+
+ BEGIN
+ TempResult := VitalTruthTable(TruthTable, DataIn);
+
+ IF ( 1 > ActResLen) THEN
+ VitalError ( "VitalTruthTable", ErrTabResSml );
+ ELSIF ( 1 < ActResLen) THEN
+ VitalError ( "VitalTruthTable", ErrTabResLrg );
+ END IF;
+ IF (ActResLen > 0) THEN
+ Result <= TempResult(0);
+ END IF;
+
+ END VitalTruthTable;
+
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalStateTable (
+ VARIABLE Result : INOUT std_logic_vector;
+ VARIABLE PreviousDataIn : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ CONSTANT DataIn : IN std_logic_vector;
+ CONSTANT NumStates : IN NATURAL
+ ) IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER
+ := StateTable'LENGTH(2) - InputSize - NumStates;
+ CONSTANT ResLeng : INTEGER := Result'LENGTH;
+ VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1)
+ := To_X01(DataIn);
+ VARIABLE PrevDataAlias : std_logic_vector(0 TO PreviousDataIn'LENGTH-1)
+ := To_X01(PreviousDataIn);
+ VARIABLE ResultAlias : std_logic_vector(0 TO ResLeng-1)
+ := To_X01(Result);
+ VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1);
+
+ BEGIN
+ IF (PreviousDataIn'LENGTH < DataIn'LENGTH) THEN
+ VitalError ( "VitalStateTable", ErrVctLng, "PreviousDataIn<DataIn");
+
+ ResultAlias := (OTHERS => 'X');
+ Result := ResultAlias;
+
+ ELSIF (OutSize <= 0) THEN
+ VitalError ( "VitalStateTable", ErrTabWidSml );
+
+ ResultAlias := (OTHERS => 'X');
+ Result := ResultAlias;
+
+ ELSE
+ IF (ResLeng > OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResSml );
+ ELSIF (ResLeng < OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResLrg );
+ END IF;
+
+ ExpResult := StateTableLookUp ( StateTable, DataInAlias,
+ PrevDataAlias, NumStates,
+ ResultAlias);
+ ResultAlias := (OTHERS => 'X');
+ ResultAlias ( Maximum(0, ResLeng - OutSize) TO ResLeng - 1)
+ := ExpResult(Maximum(0, OutSize - ResLeng) TO OutSize-1);
+
+ Result := ResultAlias;
+ PrevDataAlias(0 TO InputSize - 1) := DataInAlias;
+ PreviousDataIn := PrevDataAlias;
+
+ END IF;
+ END VitalStateTable;
+
+
+ PROCEDURE VitalStateTable (
+ VARIABLE Result : INOUT std_logic; -- states
+ VARIABLE PreviousDataIn : INOUT std_logic_vector; -- previous inputs and states
+ CONSTANT StateTable : IN VitalStateTableType; -- User's StateTable data
+ CONSTANT DataIn : IN std_logic_vector -- Inputs
+ ) IS
+
+ VARIABLE ResultAlias : std_logic_vector(0 TO 0);
+ BEGIN
+ ResultAlias(0) := Result;
+ VitalStateTable ( StateTable => StateTable,
+ DataIn => DataIn,
+ NumStates => 1,
+ Result => ResultAlias,
+ PreviousDataIn => PreviousDataIn
+ );
+ Result := ResultAlias(0);
+
+ END VitalStateTable;
+
+ PROCEDURE VitalStateTable (
+ SIGNAL Result : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ SIGNAL DataIn : IN std_logic_vector;
+ CONSTANT NumStates : IN NATURAL
+ ) IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER
+ := StateTable'LENGTH(2) - InputSize - NumStates;
+ CONSTANT ResLeng : INTEGER := Result'LENGTH;
+
+ VARIABLE PrevData : std_logic_vector(0 TO DataIn'LENGTH-1)
+ := (OTHERS => 'X');
+ VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1);
+ VARIABLE ResultAlias : std_logic_vector(0 TO ResLeng-1);
+ VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1);
+
+ BEGIN
+ IF (OutSize <= 0) THEN
+ VitalError ( "VitalStateTable", ErrTabWidSml );
+
+ ResultAlias := (OTHERS => 'X');
+ Result <= ResultAlias;
+
+ ELSE
+ IF (ResLeng > OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResSml );
+ ELSIF (ResLeng < OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResLrg );
+ END IF;
+
+ LOOP
+ DataInAlias := To_X01(DataIn);
+ ResultAlias := To_X01(Result);
+ ExpResult := StateTableLookUp ( StateTable, DataInAlias,
+ PrevData, NumStates,
+ ResultAlias);
+ ResultAlias := (OTHERS => 'X');
+ ResultAlias(Maximum(0, ResLeng - OutSize) TO ResLeng-1)
+ := ExpResult(Maximum(0, OutSize - ResLeng) TO OutSize-1);
+
+ Result <= ResultAlias;
+ PrevData := DataInAlias;
+
+ WAIT ON DataIn;
+ END LOOP;
+
+ END IF;
+
+ END VitalStateTable;
+
+ PROCEDURE VitalStateTable (
+ SIGNAL Result : INOUT std_logic;
+ CONSTANT StateTable : IN VitalStateTableType;
+ SIGNAL DataIn : IN std_logic_vector
+ ) IS
+
+ CONSTANT InputSize : INTEGER := DataIn'LENGTH;
+ CONSTANT OutSize : INTEGER := StateTable'LENGTH(2) - InputSize-1;
+
+ VARIABLE PrevData : std_logic_vector(0 TO DataIn'LENGTH-1)
+ := (OTHERS => 'X');
+ VARIABLE DataInAlias : std_logic_vector(0 TO DataIn'LENGTH-1);
+ VARIABLE ResultAlias : std_logic_vector(0 TO 0);
+ VARIABLE ExpResult : std_logic_vector(0 TO OutSize-1);
+
+ BEGIN
+ IF (OutSize <= 0) THEN
+ VitalError ( "VitalStateTable", ErrTabWidSml );
+
+ Result <= 'X';
+
+ ELSE
+ IF ( 1 > OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResSml );
+ ELSIF ( 1 < OutSize) THEN
+ VitalError ( "VitalStateTable", ErrTabResLrg );
+ END IF;
+
+ LOOP
+ ResultAlias(0) := To_X01(Result);
+ DataInAlias := To_X01(DataIn);
+ ExpResult := StateTableLookUp ( StateTable, DataInAlias,
+ PrevData, 1, ResultAlias);
+
+ Result <= ExpResult(OutSize-1);
+ PrevData := DataInAlias;
+
+ WAIT ON DataIn;
+ END LOOP;
+ END IF;
+
+ END VitalStateTable;
+
+ -- ------------------------------------------------------------------------
+ -- std_logic resolution primitive
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalResolve (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector --IR236 4/2/98
+ ) IS
+ VARIABLE uData : std_ulogic_vector(Data'RANGE);
+ BEGIN
+ FOR i IN Data'RANGE LOOP
+ uData(i) := Data(i);
+ END LOOP;
+ q <= resolved(uData);
+ END;
+
+END VITAL_Primitives;
+
diff --git a/libraries/vital2000/prmtvs_p.vhdl b/libraries/vital2000/prmtvs_p.vhdl
new file mode 100644
index 000000000..764ac449a
--- /dev/null
+++ b/libraries/vital2000/prmtvs_p.vhdl
@@ -0,0 +1,1413 @@
+-- -----------------------------------------------------------------------------
+-- Title : Standard VITAL_Primitives Package
+-- : $Revision: 598 $
+-- :
+-- Library : This package shall be compiled into a library
+-- : symbolically named IEEE.
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, constants, functions
+-- : and procedures for use in developing ASIC models.
+-- : Specifically a set of logic primitives are defined.
+-- :
+-- Known Errors :
+-- :
+-- Note : No declarations or definitions shall be included in,
+-- : or excluded from this package. The "package declaration"
+-- : defines the objects (types, subtypes, constants, functions,
+-- : procedures ... etc.) that can be used by a user. The package
+-- : body shall be considered the formal definition of the
+-- : semantics of this package. Tool developers may choose to
+-- : implement the package body in the most efficient manner
+-- : available to them.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Acknowledgments:
+-- This code was originally developed under the "VHDL Initiative Toward ASIC
+-- Libraries" (VITAL), an industry sponsored initiative. Technical
+-- Director: William Billowitch, VHDL Technology Group; U.S. Coordinator:
+-- Steve Schultz; Steering Committee Members: Victor Berman, Cadence Design
+-- Systems; Oz Levia, Synopsys Inc.; Ray Ryan, Ryan & Ryan; Herman van Beek,
+-- Texas Instruments; Victor Martin, Hewlett-Packard Company.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/02/95 | Initial ballot draft 1995
+-- ----------------------------------------------------------------------------
+-- v95.3 | ddl | 09/24/96 | #236 - VitalTruthTable DataIn should be of
+-- | | | of class SIGNAL (PROPOSED)
+-- ----------------------------------------------------------------------------
+
+LIBRARY IEEE;
+USE IEEE.Std_Logic_1164.ALL;
+USE IEEE.VITAL_Timing.ALL;
+
+PACKAGE VITAL_Primitives IS
+ -- ------------------------------------------------------------------------
+ -- Type and Subtype Declarations
+ -- ------------------------------------------------------------------------
+
+ -- For Truth and State Tables
+ SUBTYPE VitalTruthSymbolType IS VitalTableSymbolType RANGE 'X' TO 'Z';
+ SUBTYPE VitalStateSymbolType IS VitalTableSymbolType RANGE '/' TO 'S';
+
+ TYPE VitalTruthTableType IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> )
+ OF VitalTruthSymbolType;
+ TYPE VitalStateTableType IS ARRAY ( NATURAL RANGE <>, NATURAL RANGE <> )
+ OF VitalStateSymbolType;
+
+ -- ---------------------------------
+ -- Default values used by primitives
+ -- ---------------------------------
+ CONSTANT VitalDefDelay01 : VitalDelayType01; -- Propagation delays
+ CONSTANT VitalDefDelay01Z : VitalDelayType01Z;
+
+ -- ------------------------------------------------------------------------
+ -- VITAL Primitives
+ --
+ -- The primitives packages contains a collections of common gates,
+ -- including AND, OR, XOR, NAND, NOR, XNOR, BUF, INV, MUX and DECODER
+ -- functions. In addition, for sequential devices, a STATE TABLE construct
+ -- is provided. For complex functions a modeler may wish to use either
+ -- a collection of connected VITAL primitives, or a TRUTH TABLE construct.
+ --
+ -- For each primitive a Function and Procedure is provided. The primitive
+ -- functions are provided to support behavioral modeling styles. The
+ -- primitive procedures are provided to support structural modeling styles.
+ --
+ -- The procedures wait internally for an event on an input signal, compute
+ -- the new result, perform glitch handling, schedule transaction on the
+ -- output signals, and wait for future input events. All of the functional
+ -- (logic) input or output parameters of the primitive procedures are
+ -- signals. All the other parameters are constants.
+ --
+ -- The procedure primitives are parameterized for separate path delays
+ -- from each input signal. All path delays default to 0 ns.
+ --
+ -- The sequential primitive functions compute the defined function and
+ -- return a value of type std_ulogic or std_logic_vector. All parameters
+ -- of the primitive functions are constants of mode IN.
+ --
+ -- The primitives are based on 1164 operators. The user may also elect to
+ -- express functions using the 1164 operators as well. These styles are
+ -- all equally acceptable methods for device modeling.
+ --
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: N-input logic device function calls:
+ -- VitalAND VitalOR VitalXOR
+ -- VitalNAND VitalNOR VitalXNOR
+ --
+ -- Description: The function calls return the evaluated logic function
+ -- corresponding to the function name.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_logic_vector The input signals for the n-bit
+ -- wide logic functions.
+ -- ResultMap VitalResultMapType The output signal strength
+ -- result map to modify default
+ -- result mapping.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic The evaluated logic function of
+ -- the n-bit wide primitives.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalAND (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNAND (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXNOR (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: N-input logic device concurrent procedure calls.
+ -- VitalAND VitalOR VitalXOR
+ -- VitalNAND VitalNOR VitalXNOR
+ --
+ -- Description: The procedure calls return the evaluated logic function
+ -- corresponding to the function name as a parameter to the
+ -- procedure. Propagation delay form data to q is a
+ -- a parameter to the procedure. A vector of delay values
+ -- for inputs to output are provided. It is noted that
+ -- limitations in SDF make the back annotation of the delay
+ -- array difficult.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_logic_vector The input signals for the n-
+ -- bit wide logic functions.
+ -- tpd_data_q VitalDelayArrayType01 The propagation delay from
+ -- the data inputs to the output
+ -- q.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic The output signal of the
+ -- evaluated logic function.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalAND (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNAND (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXNOR (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: 2,3 and 4 input logic device function calls.
+ --
+ -- VitalAND2 VitalOR2 VitalXOR2
+ -- VitalAND3 VitalOR3 VitalXOR3
+ -- VitalAND4 VitalOR4 VitalXOR4
+ --
+ -- VitalNAND2 VitalNOR2 VitalXNOR2
+ -- VitalNAND3 VitalNOR3 VitalXNOR3
+ -- VitalNAND4 VitalNOR4 VitalXNOR4
+ --
+ -- Description: The function calls return the evaluated 2, 3 or 4 input
+ -- logic function corresponding to the function name.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- a, b, c, d std_ulogic 2 input devices have a and b as
+ -- inputs. 3 input devices have a, b
+ -- and c as inputs. 4 input devices
+ -- have a, b, c and d as inputs.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic The result of the evaluated logic
+ -- function.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalAND2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNAND2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXNOR2 (
+ CONSTANT a, b : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalAND3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNAND3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXNOR3 (
+ CONSTANT a, b, c : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalAND4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNAND4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalNOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalXNOR4 (
+ CONSTANT a, b, c, d : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: 2, 3 and 4 input logic device concurrent procedure
+ -- calls.
+ --
+ -- VitalAND2 VitalOR2 VitalXOR2
+ -- VitalAND3 VitalOR3 VitalXOR3
+ -- VitalAND4 VitalOR4 VitalXOR4
+ --
+ -- VitalNAND2 VitalNOR2 VitalXNOR2
+ -- VitalNAND3 VitalNOR3 VitalXNOR3
+ -- VitalNAND4 VitalNOR4 VitalXNOR4
+ --
+ -- Description: The procedure calls return the evaluated logic function
+ -- corresponding to the function name as a parameter to the
+ -- procedure. Propagation delays from a and b to q are
+ -- a parameter to the procedure. The default propagation
+ -- delay is 0 ns.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- a, b, c, d std_ulogic 2 input devices have a and b as
+ -- inputs. 3 input devices have a, b
+ -- and c as inputs. 4 input devices
+ -- have a, b, c and d as inputs.
+ -- tpd_a_q VitalDelayType01 The propagation delay from the a
+ -- input to output q for 2, 3 and 4
+ -- input devices.
+ -- tpd_b_q VitalDelayType01 The propagation delay from the b
+ -- input to output q for 2, 3 and 4
+ -- input devices.
+ -- tpd_c_q VitalDelayType01 The propagation delay from the c
+ -- input to output q for 3 and 4 input
+ -- devices.
+ -- tpd_d_q VitalDelayType01 The propagation delay from the d
+ -- input to output q for 4 input
+ -- devices.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic The output signal of the evaluated
+ -- logic function.
+ --
+ -- Returns
+ -- none
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalAND2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNAND2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXNOR2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalAND3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNAND3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXNOR3 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalAND4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNAND4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalNOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalXNOR4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a, b, c, d : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_b_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_c_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: Buffer logic device concurrent procedure calls.
+ --
+ -- Description: Four buffer sequential primitive function calls are
+ -- provided. One is a simple buffer and the others
+ -- offer high and low enables and the four permits
+ -- propagation of Z as shown below:
+ --
+ -- VitalBUF Standard non-inverting buffer
+ -- VitalBUFIF0 Non-inverting buffer with Enable low
+ -- VitalBUFIF1 Non-inverting buffer with Enable high
+ -- VitalIDENT Pass buffer capable of propagating Z
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_ulogic Input to the buffers
+ -- Enable std_ulogic Enable for the enable high and low
+ -- buffers.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- simple buffer.
+ -- VitalResultZMapType The output signal strength result map
+ -- to modify default result mapping
+ -- which has high impedance capability
+ -- for the enable high, enable low and
+ -- identity buffers.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic The output signal of the evaluated
+ -- buffer function.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalBUF (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+ FUNCTION VitalBUFIF0 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+ FUNCTION VitalBUFIF1 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+ FUNCTION VitalIDENT (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: Buffer device procedure calls.
+ --
+ -- Description: Four buffer concurrent primitive procedure calls are
+ -- provided. One is a simple buffer and the others
+ -- offer high and low enables and the fourth permits
+ -- propagation of Z as shown below:
+ --
+ -- VitalBUF Standard non-inverting buffer
+ -- VitalBUFIF0 Non-inverting buffer with Enable low
+ -- VitalBUFIF1 Non-inverting buffer with Enable high
+ -- VitalIDENT Pass buffer capable of propagating Z
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- a std_ulogic Input signal to the buffers
+ -- Enable std_ulogic Enable signal for the enable high and
+ -- low buffers.
+ -- tpd_a_q VitalDelayType01 Propagation delay from input to
+ -- output for the simple buffer.
+ -- VitalDelayType01Z Propagation delay from input to
+ -- to output for the enable high and low
+ -- and identity buffers.
+ -- tpd_enable_q VitalDelayType01Z Propagation delay from enable to
+ -- output for the enable high and low
+ -- buffers.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- simple buffer.
+ -- VitalResultZMapType The output signal strength result map
+ -- to modify default result mapping
+ -- which has high impedance capability
+ -- for the enable high, enable low and
+ -- identity buffers.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic Output of the buffers.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalBUF (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalBUFIF0 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap);
+
+
+ PROCEDURE VitalBUFIF1 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap);
+
+ PROCEDURE VitalIDENT (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: VitalINV, VitalINVIF0, VitalINVIF1
+ --
+ -- Description: Inverter functions which return the inverted signal
+ -- value. Inverters with enable low and high are provided
+ -- which can drive high impedance when inactive.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_ulogic Input to the inverter
+ -- Enable std_ulogic Enable to the enable high and low
+ -- inverters.
+ -- ResultMap VitalResultMap The output signal strength result map
+ -- to modify default result mapping for
+ -- simple inverter.
+ -- VitalResultZMapType The output signal strength result map
+ -- to modify default result mapping
+ -- which has high impedance capability
+ -- for the enable high, enable low
+ -- inverters.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic Output of the inverter
+ --
+ -- -------------------------------------------------------------------------
+
+ FUNCTION VitalINV (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalINVIF0 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalINVIF1 (
+ CONSTANT Data, Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: VitalINV, VitalINVIF0, VitalINVIF1
+ --
+ -- Description: The concurrent primitive procedure calls implement a
+ -- signal inversion function. The output is a parameter to
+ -- the procedure. The path delay information is passed as
+ -- a parameter to the call.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- a std_ulogic Input signal for the simple inverter
+ -- Data std_ulogic Input signal for the enable high and
+ -- low inverters.
+ -- Enable std_ulogic Enable signal for the enable high and
+ -- low inverters.
+ -- tpd_a_q VitalDelayType01 Propagation delay from input a to
+ -- output q for the simple inverter.
+ -- tpd_data_q VitalDelayType01 Propagation delay from input data to
+ -- output q for the enable high and low
+ -- inverters.
+ -- tpd_enable_q VitalDelayType01Z Propagation delay from input enable
+ -- to output q for the enable high and
+ -- low inverters.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- simple inverter.
+ -- VitalResultZMapType The output signal strength result map
+ -- to modify default result mapping
+ -- which has high impedance capability
+ -- for the enable high, enable low
+ -- inverters.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic Output signal of the inverter.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalINV (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL a : IN std_ulogic;
+ CONSTANT tpd_a_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+ PROCEDURE VitalINVIF0 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap);
+
+ PROCEDURE VitalINVIF1 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01Z := VitalDefDelay01Z;
+ CONSTANT ResultMap : IN VitalResultZMapType
+ := VitalDefaultResultZMap);
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: VitalMUX, VitalMUX2, VitalMUX4, VitalMUX8
+ --
+ -- Description: The VitalMUX functions return the selected data bit
+ -- based on the value of dSelect. For MUX2, the function
+ -- returns data0 when dselect is 0 and returns data1 when
+ -- dselect is 1. When dselect is X, result is X for MUX2
+ -- when data0 /= data1. X propagation is reduced when the
+ -- dselect signal is X and both data signals are identical.
+ -- When this is the case, the result returned is the value
+ -- of the data signals.
+ --
+ -- For the N input device:
+ --
+ -- N must equal 2**(bits of dSelect)
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_logic_vector Input signal for the N-bit, 4-bit and
+ -- 8-bit mux.
+ -- Data1,Data0 std_ulogic Input signals for the 2-bit mux.
+ -- dSelect std_ulogic Select signal for 2-bit mux
+ -- std_logic_vector2 Select signal for 4-bit mux
+ -- std_logic_vector3 Select signal for 8-bit mux
+ -- std_logic_vector Select signal for N-Bit mux
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- all muxes.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_ulogic The value of the selected bit is
+ -- returned.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalMUX (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT dSelect : IN std_logic_vector;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalMUX2 (
+ CONSTANT Data1, Data0 : IN std_ulogic;
+ CONSTANT dSelect : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalMUX4 (
+ CONSTANT Data : IN std_logic_vector4;
+ CONSTANT dSelect : IN std_logic_vector2;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ FUNCTION VitalMUX8 (
+ CONSTANT Data : IN std_logic_vector8;
+ CONSTANT dSelect : IN std_logic_vector3;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_ulogic;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: VitalMUX, VitalMUX2, VitalMUX4, VitalMUX8
+ --
+ -- Description: The VitalMUX concurrent primitive procedures calls
+ -- return in the output q the value of the selected data
+ -- bit based on the value of dsel. For the two bit mux,
+ -- the data returned is either d0 or d1, the data input.
+ -- For 4, 8 and N-bit functions, data is the input and is
+ -- of type std_logic_vector. For the 2-bit mux, if d0 or
+ -- d1 are X, the output is X only when d0 do not equal d1.
+ -- When d0 and d1 are equal, the return value is this value
+ -- to reduce X propagation.
+ --
+ -- Propagation delay information is passed as a parameter
+ -- to the procedure call for delays from data to output and
+ -- select to output. For 2-bit muxes, the propagation
+ -- delays from data are provided for d0 and d1 to output.
+ --
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- d1,d0 std_ulogic Input signals for the 2-bit mux.
+ -- Data std_logic_vector4 Input signals for the 4-bit mux.
+ -- std_logic_vector8 Input signals for the 8-bit mux.
+ -- std_logic_vector Input signals for the N-bit mux.
+ -- dsel std_ulogic Select signal for the 2-bit mux.
+ -- std_logic_vector2 Select signals for the 4-bit mux.
+ -- std_logic_vector3 Select signals for the 8-bit mux.
+ -- std_logic_vector Select signals for the N-bit mux.
+ -- tpd_d1_q VitalDelayType01 Propagation delay from input d1 to
+ -- output q for 2-bit mux.
+ -- tpd_d0_q VitalDelayType01 Propagation delay from input d0 to
+ -- output q for 2-bit mux.
+ -- tpd_data_q VitalDelayArrayType01 Propagation delay from input data
+ -- to output q for 4-bit, 8-bit and
+ -- N-bit muxes.
+ -- tpd_dsel_q VitalDelayType01 Propagation delay from input dsel
+ -- to output q for 2-bit mux.
+ -- VitalDelayArrayType01 Propagation delay from input dsel
+ -- to output q for 4-bit, 8-bit and
+ -- N-bit muxes.
+ -- ResultMap VitalResultMapType The output signal strength result
+ -- map to modify default result
+ -- mapping for all muxes.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic The value of the selected signal.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalMUX (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector;
+ SIGNAL dSel : IN std_logic_vector;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalMUX2 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL d1, d0 : IN std_ulogic;
+ SIGNAL dSel : IN std_ulogic;
+ CONSTANT tpd_d1_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_d0_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_dsel_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalMUX4 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector4;
+ SIGNAL dSel : IN std_logic_vector2;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalMUX8 (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector8;
+ SIGNAL dSel : IN std_logic_vector3;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_dsel_q : IN VitalDelayArrayType01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Sequential
+ -- Primitive
+ -- Function Name: VitalDECODER, VitalDECODER2, VitalDECODER4,
+ -- VitalDECODER8
+ --
+ -- Description: The VitalDECODER functions are the sequential primitive
+ -- calls for decoder logic. The functions are provided
+ -- for N, 2, 4 and 8-bit outputs.
+ --
+ -- The N-bit decoder is (2**(bits of data)) wide.
+ --
+ -- The VitalDECODER returns 0 if enable is 0.
+ -- The VitalDECODER returns the result bit set to 1 if
+ -- enable is 1. All other bits of returned result are
+ -- set to 0.
+ --
+ -- The returned array is in descending order:
+ -- (n-1 downto 0).
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_ulogic Input signal for 2-bit decoder.
+ -- std_logic_vector2 Input signals for 4-bit decoder.
+ -- std_logic_vector3 Input signals for 8-bit decoder.
+ -- std_logic_vector Input signals for N-bit decoder.
+ -- Enable std_ulogic Enable input signal. The result is
+ -- output when enable is high.
+ -- ResultMap VitalResultMapType The output signal strength result map
+ -- to modify default result mapping for
+ -- all output signals of the decoders.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- std_logic_vector2 The output of the 2-bit decoder.
+ -- std_logic_vector4 The output of the 4-bit decoder.
+ -- std_logic_vector8 The output of the 8-bit decoder.
+ -- std_logic_vector The output of the n-bit decoder.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalDECODER (
+ CONSTANT Data : IN std_logic_vector;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector;
+
+ FUNCTION VitalDECODER2 (
+ CONSTANT Data : IN std_ulogic;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector2;
+
+ FUNCTION VitalDECODER4 (
+ CONSTANT Data : IN std_logic_vector2;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector4;
+
+ FUNCTION VitalDECODER8 (
+ CONSTANT Data : IN std_logic_vector3;
+ CONSTANT Enable : IN std_ulogic;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap
+ ) RETURN std_logic_vector8;
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Concurrent
+ -- Primitive
+ -- Procedure Name: VitalDECODER, VitalDECODER2, VitalDECODER4,
+ -- VitalDECODER8
+ --
+ -- Description: The VitalDECODER procedures are the concurrent primitive
+ -- procedure calls for decoder functions. The procedures
+ -- are provided for N, 2, 4 and 8 outputs.
+ --
+ -- The N-bit decoder is (2**(bits of data)) wide.
+ --
+ -- The procedural form of the decoder is used for
+ -- distributed delay modeling. The delay information for
+ -- each path is passed as an argument to the procedure.
+ --
+ -- Result is set to 0 if enable is 0.
+ -- The result bit represented by data is set to 1 if
+ -- enable is 1. All other bits of result are set to 0.
+ --
+ -- The result array is in descending order: (n-1 downto 0).
+ --
+ -- For the N-bit decoder, the delay path is a vector of
+ -- delays from inputs to outputs.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_ulogic Input signal for 2-bit decoder.
+ -- std_logic_vector2 Input signals for 4-bit decoder.
+ -- std_logic_vector3 Input signals for 8-bit decoder.
+ -- std_logic_vector Input signals for N-bit decoder.
+ -- enable std_ulogic Enable input signal. The result is
+ -- output when enable is high.
+ -- tpd_data_q VitalDelayType01 Propagation delay from input data
+ -- to output q for 2-bit decoder.
+ -- VitalDelayArrayType01 Propagation delay from input data
+ -- to output q for 4, 8 and n-bit
+ -- decoders.
+ -- tpd_enable_q VitalDelayType01 Propagation delay from input enable
+ -- to output q for 2, 4, 8 and n-bit
+ -- decoders.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_logic_vector2 Output signals for 2-bit decoder.
+ -- std_logic_vector4 Output signals for 4-bit decoder.
+ -- std_logic_vector8 Output signals for 8-bit decoder.
+ -- std_logic_vector Output signals for n-bit decoder.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalDECODER (
+ SIGNAL q : OUT std_logic_vector;
+ SIGNAL Data : IN std_logic_vector;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+ PROCEDURE VitalDECODER2 (
+ SIGNAL q : OUT std_logic_vector2;
+ SIGNAL Data : IN std_ulogic;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ PROCEDURE VitalDECODER4 (
+ SIGNAL q : OUT std_logic_vector4;
+ SIGNAL Data : IN std_logic_vector2;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+ PROCEDURE VitalDECODER8 (
+ SIGNAL q : OUT std_logic_vector8;
+ SIGNAL Data : IN std_logic_vector3;
+ SIGNAL Enable : IN std_ulogic;
+ CONSTANT tpd_data_q : IN VitalDelayArrayType01;
+ CONSTANT tpd_enable_q : IN VitalDelayType01 := VitalDefDelay01;
+ CONSTANT ResultMap : IN VitalResultMapType
+ := VitalDefaultResultMap );
+
+ -- -------------------------------------------------------------------------
+ -- Function Name: VitalTruthTable
+ --
+ -- Description: VitalTruthTable implements a truth table. Given
+ -- a set of inputs, a sequential search is performed
+ -- to match the input. If a match is found, the output
+ -- is set based on the contents of the CONSTANT TruthTable.
+ -- If there is no match, all X's are returned. There is
+ -- no limit to the size of the table.
+ --
+ -- There is a procedure and function for VitalTruthTable.
+ -- For each of these, a single value output (std_logic) and
+ -- a multi-value output (std_logic_vector) are provided.
+ --
+ -- The first dimension of the table is for number of
+ -- entries in the truth table and second dimension is for
+ -- the number of elements in a row. The number of inputs
+ -- in the row should be Data'LENGTH plus result'LENGTH.
+ --
+ -- Elements is a row will be interpreted as
+ -- Input(NumInputs - 1),.., Input(0),
+ -- Result(NumOutputs - 1),.., Result(0)
+ --
+ -- All inputs will be mapped to the X01 subtype
+ --
+ -- If the value of Result is not in the range 'X' to 'Z'
+ -- then an error will be reported. Also, the Result is
+ -- always given either as a 0, 1, X or Z value.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- TruthTable The input constant which defines the
+ -- behavior in truth table form.
+ -- DataIn The inputs to the truth table used to
+ -- perform input match to select
+ -- output(s) to value(s) to drive.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- Result std_logic Concurrent procedure version scalar
+ -- output.
+ -- std_logic_vector Concurrent procedure version vector
+ -- output.
+ --
+ -- Returns
+ -- Result std_logic Function version scalar output.
+ -- std_logic_vector Function version vector output.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalTruthTable (
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) RETURN std_logic_vector;
+
+ FUNCTION VitalTruthTable (
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ ) RETURN std_logic;
+
+ PROCEDURE VitalTruthTable (
+ SIGNAL Result : OUT std_logic_vector;
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ SIGNAL DataIn : IN std_logic_vector -- IR#236
+ );
+ PROCEDURE VitalTruthTable (
+ SIGNAL Result : OUT std_logic;
+ CONSTANT TruthTable : IN VitalTruthTableType;
+ SIGNAL DataIn : IN std_logic_vector -- IR#236
+ );
+ -- -------------------------------------------------------------------------
+ --
+ -- Function Name: VitalStateTable
+ --
+ -- Description: VitalStateTable is a non-concurrent implementation of a
+ -- state machine (Moore Machine). It is used to model
+ -- sequential devices and devices with internal states.
+ --
+ -- The procedure takes the value of the state table
+ -- data set and performs a sequential search of the
+ -- CONSTANT StateTable until a match is found. Once a
+ -- match is found, the result of that match is applied
+ -- to Result. If there is no match, all X's are returned.
+ -- The resultant output becomes the input for the next
+ -- state.
+ --
+ -- The first dimension of the table is the number of
+ -- entries in the state table and second dimension is the
+ -- number of elements in a row of the table. The number of
+ -- inputs in the row should be DataIn'LENGTH. Result should
+ -- contain the current state (which will become the next
+ -- state) as well as the outputs
+ --
+ -- Elements is a row of the table will be interpreted as
+ -- Input(NumInputs-1),.., Input(0), State(NumStates-1),
+ -- ..., State(0),Output(NumOutputs-1),.., Output(0)
+ --
+ -- where State(numStates-1) DOWNTO State(0) represent the
+ -- present state and Output(NumOutputs - 1) DOWNTO
+ -- Outputs(NumOutputs - NumStates) represent the new
+ -- values of the state variables (i.e. the next state).
+ -- Also, Output(NumOutputs - NumStates - 1)
+ --
+ -- This procedure returns the next state and the new
+ -- outputs when a match is made between the present state
+ -- and present inputs and the state table. A search is
+ -- made starting at the top of the state table and
+ -- terminates with the first match. If no match is found
+ -- then the next state and new outputs are set to all 'X's.
+ --
+ -- (Asynchronous inputs (i.e. resets and clears) must be
+ -- handled by placing the corresponding entries at the top
+ -- of the table. )
+ --
+ -- All inputs will be mapped to the X01 subtype.
+ --
+ -- NOTE: Edge transitions should not be used as values
+ -- for the state variables in the present state
+ -- portion of the state table. The only valid
+ -- values that can be used for the present state
+ -- portion of the state table are:
+ -- 'X', '0', '1', 'B', '-'
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- StateTable VitalStateTableType The input constant which defines
+ -- the behavior in state table form.
+ -- DataIn std_logic_vector The current state inputs to the
+ -- state table used to perform input
+ -- matches and transition
+ -- calculations.
+ -- NumStates NATURAL Number of state variables
+ --
+ -- INOUT
+ -- Result std_logic Output signal for scalar version of
+ -- the concurrent procedure call.
+ -- std_logic_vector Output signals for vector version
+ -- of the concurrent procedure call.
+ -- PreviousDataIn std_logic_vector The previous inputs and states used
+ -- in transition calculations and to
+ -- set outputs for steady state cases.
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalStateTable (
+ VARIABLE Result : INOUT std_logic_vector;
+ VARIABLE PreviousDataIn : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ CONSTANT DataIn : IN std_logic_vector;
+ CONSTANT NumStates : IN NATURAL
+ );
+
+ PROCEDURE VitalStateTable (
+ VARIABLE Result : INOUT std_logic;
+ VARIABLE PreviousDataIn : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ CONSTANT DataIn : IN std_logic_vector
+ );
+
+ PROCEDURE VitalStateTable (
+ SIGNAL Result : INOUT std_logic_vector;
+ CONSTANT StateTable : IN VitalStateTableType;
+ SIGNAL DataIn : IN std_logic_vector;
+ CONSTANT NumStates : IN NATURAL
+ );
+
+ PROCEDURE VitalStateTable (
+ SIGNAL Result : INOUT std_logic;
+ CONSTANT StateTable : IN VitalStateTableType;
+ SIGNAL DataIn : IN std_logic_vector
+ );
+
+ -- -------------------------------------------------------------------------
+ --
+ -- Function Name: VitalResolve
+ --
+ -- Description: VitalResolve takes a vector of signals and resolves
+ -- them to a std_ulogic value. This procedure can be used
+ -- to resolve multiple drivers in a single model.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Data std_logic_vector Set of input signals which drive a
+ -- common signal.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- q std_ulogic Output signal which is the resolved
+ -- value being driven by the collection of
+ -- input signals.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalResolve (
+ SIGNAL q : OUT std_ulogic;
+ SIGNAL Data : IN std_logic_vector); --IR236 4/2/98
+
+END VITAL_Primitives;
diff --git a/libraries/vital2000/timing_b.vhdl b/libraries/vital2000/timing_b.vhdl
new file mode 100644
index 000000000..28bf52095
--- /dev/null
+++ b/libraries/vital2000/timing_b.vhdl
@@ -0,0 +1,2187 @@
+-------------------------------------------------------------------------------
+-- Title : Standard VITAL TIMING Package
+-- : $Revision: 598 $
+-- Library : VITAL
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, attributes, constants,
+-- : functions and procedures for use in developing ASIC models.
+-- : This file contains the Package Body.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/08/95 | Initial ballot draft 1995
+-- v95.1 | | 08/31/95 | #IR203 - Timing violations at time 0
+-- #IR204 - Output mapping prior to glitch detection
+-- v98.0 |TAG | 03/27/98 | Initial ballot draft 1998
+-- | #IR225 - Negative Premptive Glitch
+-- **Code_effected=ReportGlitch,VitalGlitch,
+-- VitalPathDelay,VitalPathDelay01,
+-- VitalPathDelay01z.
+-- #IR105 - Skew timing check needed
+-- **Code_effected=NONE, New code added!!
+-- #IR245,IR246,IR251 ITC code to fix false boundry cases
+-- **Code_effected=InternalTimingCheck.
+-- #IR248 - Allows VPD to use a default timing delay
+-- **Code_effected=VitalPathDelay,
+-- VitalPathDelay01,VitalPathDelay01z,
+-- VitalSelectPathDelay,VitalSelectPathDelay01,
+-- VitalSelectPathDelay01z.
+-- #IR250 - Corrects fastpath condition in VPD
+-- **Code_effected=VitalPathDelay01,
+-- VitalPathDelay01z,
+-- #IR252 - Corrects cancelled timing check call if
+-- condition expires.
+-- **Code_effected=VitalSetupHoldCheck,
+-- VitalRecoveryRemovalCheck.
+-- v98.1 | jdc | 03/25/99 | Changed UseDefaultDelay to IgnoreDefaultDelay
+-- and set default to FALSE in VitalPathDelay()
+--
+-- ----------------------------------------------------------------------------
+
+LIBRARY STD;
+USE STD.TEXTIO.ALL;
+
+PACKAGE BODY VITAL_Timing IS
+
+ -- --------------------------------------------------------------------
+ -- Package Local Declarations
+ -- --------------------------------------------------------------------
+
+ TYPE CheckType IS ( SetupCheck, HoldCheck, RecoveryCheck, RemovalCheck,
+ PulseWidCheck, PeriodCheck );
+
+ TYPE CheckInfoType IS RECORD
+ Violation : BOOLEAN;
+ CheckKind : CheckType;
+ ObsTime : TIME;
+ ExpTime : TIME;
+ DetTime : TIME;
+ State : X01;
+ END RECORD;
+
+ TYPE LogicCvtTableType IS ARRAY (std_ulogic) OF CHARACTER;
+ TYPE HiLoStrType IS ARRAY (std_ulogic RANGE 'X' TO '1') OF STRING(1 TO 4);
+
+ CONSTANT LogicCvtTable : LogicCvtTableType
+ := ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
+ CONSTANT HiLoStr : HiLoStrType := (" X ", " Low", "High" );
+
+ TYPE EdgeSymbolMatchType IS ARRAY (X01,X01,VitalEdgeSymbolType) OF BOOLEAN;
+ -- last value, present value, edge symbol
+ CONSTANT EdgeSymbolMatch : EdgeSymbolMatchType := (
+ 'X'=>('X'=>( OTHERS => FALSE),
+ '0'=>('N'|'F'|'v'|'E'|'D'|'*' => TRUE, OTHERS => FALSE ),
+ '1'=>('P'|'R'|'^'|'E'|'A'|'*' => TRUE, OTHERS => FALSE ) ),
+ '0'=>('X'=>( 'r'|'p'|'R'|'A'|'*' => TRUE, OTHERS => FALSE ),
+ '0'=>( OTHERS => FALSE ),
+ '1'=>( '/'|'P'|'p'|'R'|'*' => TRUE, OTHERS => FALSE ) ),
+ '1'=>('X'=>( 'f'|'n'|'F'|'D'|'*' => TRUE, OTHERS => FALSE ),
+ '0'=>( '\'|'N'|'n'|'F'|'*' => TRUE, OTHERS => FALSE ),
+ '1'=>( OTHERS => FALSE ) ) );
+
+
+
+
+ ---------------------------------------------------------------------------
+ -- Tables used to implement 'posedge' and 'negedge' in path delays
+ -- These are new tables for Skewcheck routines. IR105
+ ---------------------------------------------------------------------------
+
+ TYPE EdgeRable IS ARRAY(std_ulogic, std_ulogic) OF boolean;
+
+ CONSTANT Posedge : EdgeRable := (
+ -- ------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H -
+ -- ------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- U
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- X
+ ( TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE ), -- 0
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- 1
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- Z
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ), -- W
+ ( TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE , TRUE ), -- L
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- H
+ ( FALSE, FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE ) -- -
+
+ ); --IR105
+
+
+ CONSTANT Negedge : EdgeRable := (
+ -- -----------------------------------------------------------------------
+ -- | U X 0 1 Z W L H -
+ -- -----------------------------------------------------------------------
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- U
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- X
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- 0
+ ( TRUE , TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE ), -- 1
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- Z
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ), -- W
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- L
+ ( TRUE , TRUE , TRUE , FALSE, TRUE , TRUE , TRUE , FALSE, TRUE ), -- H
+ ( FALSE, FALSE, TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, FALSE ) -- -
+
+ ); --IR105
+
+ TYPE SkewType IS (Inphase, Outphase); --IR105
+
+ CONSTANT noTrigger : TIME := -1 ns; --IR105
+ ---------------------------------------------------------------------------
+ -- End of Skew (IR105 additions)
+ ---------------------------------------------------------------------------
+
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- Misc Utilities Local Utilities
+ ---------------------------------------------------------------------------
+ -----------------------------------------------------------------------
+ FUNCTION Minimum ( CONSTANT t1,t2 : IN TIME ) RETURN TIME IS
+ BEGIN
+ IF ( t1 < t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Minimum;
+ -----------------------------------------------------------------------
+ FUNCTION Maximum ( CONSTANT t1,t2 : IN TIME ) RETURN TIME IS
+ BEGIN
+ IF ( t1 > t2 ) THEN RETURN (t1); ELSE RETURN (t2); END IF;
+ END Maximum;
+
+ --------------------------------------------------------------------
+ -- Error Message Types and Tables
+ --------------------------------------------------------------------
+ TYPE VitalErrorType IS (
+ ErrVctLng ,
+ ErrNoPath ,
+ ErrNegPath ,
+ ErrNegDel
+ );
+
+ TYPE VitalErrorSeverityType IS ARRAY (VitalErrorType) OF SEVERITY_LEVEL;
+ CONSTANT VitalErrorSeverity : VitalErrorSeverityType := (
+ ErrVctLng => ERROR,
+ ErrNoPath => WARNING,
+ ErrNegPath => WARNING,
+ ErrNegDel => WARNING
+ );
+
+ CONSTANT MsgNoPath : STRING :=
+ "No Delay Path Condition TRUE. 0-delay used. Output signal is: ";
+ CONSTANT MsgNegPath : STRING :=
+ "Path Delay less than time since input. 0 delay used. Output signal is: ";
+ CONSTANT MsgNegDel : STRING :=
+ "Negative delay. New output value not scheduled. Output signal is: ";
+ CONSTANT MsgVctLng : STRING :=
+ "Vector (array) lengths not equal. ";
+
+ CONSTANT MsgUnknown : STRING :=
+ "Unknown error message.";
+
+ FUNCTION VitalMessage (
+ CONSTANT ErrorId : IN VitalErrorType
+ ) RETURN STRING IS
+ BEGIN
+ CASE ErrorId IS
+ WHEN ErrVctLng => RETURN MsgVctLng;
+ WHEN ErrNoPath => RETURN MsgNoPath;
+ WHEN ErrNegPath => RETURN MsgNegPath;
+ WHEN ErrNegDel => RETURN MsgNegDel;
+ WHEN OTHERS => RETURN MsgUnknown;
+ END CASE;
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId)
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN STRING
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ PROCEDURE VitalError (
+ CONSTANT Routine : IN STRING;
+ CONSTANT ErrorId : IN VitalErrorType;
+ CONSTANT Info : IN CHARACTER
+ ) IS
+ BEGIN
+ ASSERT FALSE
+ REPORT Routine & ": " & VitalMessage(ErrorId) & Info
+ SEVERITY VitalErrorSeverity(ErrorId);
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Time Delay Assignment Subprograms
+ ---------------------------------------------------------------------------
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN VitalDelayType01Z IS
+ BEGIN
+ RETURN (OTHERS => Delay);
+ END VitalExtendToFillDelay;
+
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN VitalDelayType01Z IS
+ VARIABLE Delay01Z : VitalDelayType01Z;
+ BEGIN
+ Delay01Z(tr01) := Delay(tr01);
+ Delay01Z(tr0z) := Delay(tr01);
+ Delay01Z(trz1) := Delay(tr01);
+ Delay01Z(tr10) := Delay(tr10);
+ Delay01Z(tr1z) := Delay(tr10);
+ Delay01Z(trz0) := Delay(tr10);
+ RETURN (Delay01Z);
+ END VitalExtendToFillDelay;
+
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN VitalDelayType01Z IS
+ BEGIN
+ RETURN Delay;
+ END VitalExtendToFillDelay;
+
+ ---------------------------------------------------------------------------
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN TIME IS
+ BEGIN
+ RETURN delay;
+ END VitalCalcDelay;
+
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN TIME IS
+ VARIABLE Result : TIME;
+ BEGIN
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(tr10);
+ WHEN '1' | 'H' => Result := Delay(tr01);
+ WHEN 'Z' =>
+ CASE Oldval IS
+ WHEN '0' | 'L' => Result := Delay(tr01);
+ WHEN '1' | 'H' => Result := Delay(tr10);
+ WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01));
+ END CASE;
+ WHEN OTHERS =>
+ CASE Oldval IS
+ WHEN '0' | 'L' => Result := Delay(tr01);
+ WHEN '1' | 'H' => Result := Delay(tr10);
+ WHEN 'Z' => Result := MINIMUM(Delay(tr10), Delay(tr01));
+ WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01));
+ END CASE;
+ END CASE;
+ RETURN Result;
+ END VitalCalcDelay;
+
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN TIME IS
+ VARIABLE Result : TIME;
+ BEGIN
+ CASE Oldval IS
+ WHEN '0' | 'L' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(tr10);
+ WHEN '1' | 'H' => Result := Delay(tr01);
+ WHEN 'Z' => Result := Delay(tr0z);
+ WHEN OTHERS => Result := MINIMUM(Delay(tr01), Delay(tr0z));
+ END CASE;
+ WHEN '1' | 'H' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(tr10);
+ WHEN '1' | 'H' => Result := Delay(tr01);
+ WHEN 'Z' => Result := Delay(tr1z);
+ WHEN OTHERS => Result := MINIMUM(Delay(tr10), Delay(tr1z));
+ END CASE;
+ WHEN 'Z' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := Delay(trz0);
+ WHEN '1' | 'H' => Result := Delay(trz1);
+ WHEN 'Z' => Result := MAXIMUM (Delay(tr0z), Delay(tr1z));
+ WHEN OTHERS => Result := MINIMUM (Delay(trz1), Delay(trz0));
+ END CASE;
+ WHEN 'U' | 'X' | 'W' | '-' =>
+ CASE Newval IS
+ WHEN '0' | 'L' => Result := MAXIMUM(Delay(tr10), Delay(trz0));
+ WHEN '1' | 'H' => Result := MAXIMUM(Delay(tr01), Delay(trz1));
+ WHEN 'Z' => Result := MAXIMUM(Delay(tr1z), Delay(tr0z));
+ WHEN OTHERS => Result := MAXIMUM(Delay(tr10), Delay(tr01));
+ END CASE;
+ END CASE;
+ RETURN Result;
+ END VitalCalcDelay;
+
+ ---------------------------------------------------------------------------
+ --
+ -- VitalSelectPathDelay returns the path delay selected by the Paths array.
+ -- If no paths are selected, it returns either the appropriate default
+ -- delay or TIME'HIGH, depending upon the value of IgnoreDefaultDelay.
+ --
+
+ FUNCTION VitalSelectPathDelay (
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT OldValue : IN std_logic;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT Paths : IN VitalPathArrayType;
+ CONSTANT DefaultDelay : IN VitalDelayType;
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN
+ ) RETURN TIME IS
+
+ VARIABLE TmpDelay : TIME;
+ VARIABLE InputAge : TIME := TIME'HIGH;
+ VARIABLE PropDelay : TIME := TIME'HIGH;
+ BEGIN
+ -- for each delay path
+ FOR i IN Paths'RANGE LOOP
+ -- ignore the delay path if it is not enabled
+ NEXT WHEN NOT Paths(i).PathCondition;
+ -- ignore the delay path if a more recent input event has been seen
+ NEXT WHEN Paths(i).InputChangeTime > InputAge;
+
+ -- This is the most recent input change (so far)
+ -- Get the transition dependent delay
+ TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay);
+
+ -- If other inputs changed at the same time,
+ -- then use the minimum of their propagation delays,
+ -- else use the propagation delay from this input.
+ IF Paths(i).InputChangeTime < InputAge THEN
+ PropDelay := TmpDelay;
+ ELSE -- Simultaneous inputs change
+ IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF;
+ end if;
+
+ InputAge := Paths(i).InputChangeTime;
+ END LOOP;
+
+ -- If there were no paths (with an enabled condition),
+ -- use the default delay, if so indicated, otherwise return TIME'HIGH
+ IF (PropDelay = TIME'HIGH) THEN
+ IF (IgnoreDefaultDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+ END IF;
+
+ -- If the time since the most recent selected input event is
+ -- greater than the propagation delay from that input,
+ -- then use the default delay (won't happen if no paths are selected)
+ ELSIF (InputAge > PropDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- Adjust the propagation delay by the time since the
+ -- the input event occurred (Usually 0 ns).
+ ELSE
+ PropDelay := PropDelay - InputAge;
+ END IF;
+
+ RETURN PropDelay;
+ END;
+
+ FUNCTION VitalSelectPathDelay (
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT OldValue : IN std_logic;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT Paths : IN VitalPathArray01Type;
+ CONSTANT DefaultDelay : IN VitalDelayType01;
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN
+ ) RETURN TIME IS
+
+ VARIABLE TmpDelay : TIME;
+ VARIABLE InputAge : TIME := TIME'HIGH;
+ VARIABLE PropDelay : TIME := TIME'HIGH;
+ BEGIN
+ -- for each delay path
+ FOR i IN Paths'RANGE LOOP
+ -- ignore the delay path if it is not enabled
+ NEXT WHEN NOT Paths(i).PathCondition;
+ -- ignore the delay path if a more recent input event has been seen
+ NEXT WHEN Paths(i).InputChangeTime > InputAge;
+
+ -- This is the most recent input change (so far)
+ -- Get the transition dependent delay
+ TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay);
+
+ -- If other inputs changed at the same time,
+ -- then use the minimum of their propagation delays,
+ -- else use the propagation delay from this input.
+ IF Paths(i).InputChangeTime < InputAge THEN
+ PropDelay := TmpDelay;
+ ELSE -- Simultaneous inputs change
+ IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF;
+ end if;
+
+ InputAge := Paths(i).InputChangeTime;
+ END LOOP;
+
+ -- If there were no paths (with an enabled condition),
+ -- use the default delay, if so indicated, otherwise return TIME'HIGH
+ IF (PropDelay = TIME'HIGH) THEN
+ IF (IgnoreDefaultDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+ END IF;
+
+ -- If the time since the most recent selected input event is
+ -- greater than the propagation delay from that input,
+ -- then use the default delay (won't happen if no paths are selected)
+ ELSIF (InputAge > PropDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- Adjust the propagation delay by the time since the
+ -- the input event occurred (Usually 0 ns).
+ ELSE
+ PropDelay := PropDelay - InputAge;
+ END IF;
+
+ RETURN PropDelay;
+ END;
+
+ FUNCTION VitalSelectPathDelay (
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT OldValue : IN std_logic;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT Paths : IN VitalPathArray01ZType;
+ CONSTANT DefaultDelay : IN VitalDelayType01Z;
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN
+ ) RETURN TIME IS
+
+ VARIABLE TmpDelay : TIME;
+ VARIABLE InputAge : TIME := TIME'HIGH;
+ VARIABLE PropDelay : TIME := TIME'HIGH;
+ BEGIN
+ -- for each delay path
+ FOR i IN Paths'RANGE LOOP
+ -- ignore the delay path if it is not enabled
+ NEXT WHEN NOT Paths(i).PathCondition;
+ -- ignore the delay path if a more recent input event has been seen
+ NEXT WHEN Paths(i).InputChangeTime > InputAge;
+
+ -- This is the most recent input change (so far)
+ -- Get the transition dependent delay
+ TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay);
+
+ -- If other inputs changed at the same time,
+ -- then use the minimum of their propagation delays,
+ -- else use the propagation delay from this input.
+ IF Paths(i).InputChangeTime < InputAge THEN
+ PropDelay := TmpDelay;
+ ELSE -- Simultaneous inputs change
+ IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF;
+ end if;
+
+ InputAge := Paths(i).InputChangeTime;
+ END LOOP;
+
+ -- If there were no paths (with an enabled condition),
+ -- use the default delay, if so indicated, otherwise return TIME'HIGH
+ IF (PropDelay = TIME'HIGH) THEN
+ IF (IgnoreDefaultDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+ END IF;
+
+ -- If the time since the most recent selected input event is
+ -- greater than the propagation delay from that input,
+ -- then use the default delay (won't happen if no paths are selected)
+ ELSIF (InputAge > PropDelay) THEN
+ PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay);
+
+ -- Adjust the propagation delay by the time since the
+ -- the input event occurred (Usually 0 ns).
+ ELSE
+ PropDelay := PropDelay - InputAge;
+ END IF;
+
+ RETURN PropDelay;
+ END;
+
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- Glitch Handlers
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ PROCEDURE ReportGlitch (
+ CONSTANT GlitchRoutine : IN STRING;
+ CONSTANT OutSignalName : IN STRING;
+ CONSTANT PreemptedTime : IN TIME;
+ CONSTANT PreemptedValue : IN std_ulogic;
+ CONSTANT NewTime : IN TIME;
+ CONSTANT NewValue : IN std_ulogic;
+ CONSTANT Index : IN INTEGER := 0;
+ CONSTANT IsArraySignal : IN BOOLEAN := FALSE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE StrPtr1, StrPtr2, StrPtr3, StrPtr4, StrPtr5 : LINE;
+ BEGIN
+
+ Write (StrPtr1, PreemptedTime );
+ Write (StrPtr2, NewTime);
+ Write (StrPtr3, LogicCvtTable(PreemptedValue));
+ Write (StrPtr4, LogicCvtTable(NewValue));
+ IF IsArraySignal THEN
+ Write (StrPtr5, STRING'( "(" ) );
+ Write (StrPtr5, Index);
+ Write (StrPtr5, STRING'( ")" ) );
+ ELSE
+ Write (StrPtr5, STRING'( " " ) );
+ END IF;
+
+ -- Issue Report only if Preempted value has not been
+ -- removed from event queue
+ ASSERT PreemptedTime > NewTime
+ REPORT GlitchRoutine & ": GLITCH Detected on port " &
+ OutSignalName & StrPtr5.ALL &
+ "; Preempted Future Value := " & StrPtr3.ALL &
+ " @ " & StrPtr1.ALL &
+ "; Newly Scheduled Value := " & StrPtr4.ALL &
+ " @ " & StrPtr2.ALL &
+ ";"
+ SEVERITY MsgSeverity;
+
+
+ ASSERT PreemptedTime <= NewTime
+ REPORT GlitchRoutine & ": GLITCH Detected on port " &
+ OutSignalName & StrPtr5.ALL &
+ "; Negative Preempted Value := " & StrPtr3.ALL &
+ " @ " & StrPtr1.ALL &
+ "; Newly Scheduled Value := " & StrPtr4.ALL &
+ " @ " & StrPtr2.ALL &
+ ";"
+ SEVERITY MsgSeverity;
+
+
+ DEALLOCATE(StrPtr1);
+ DEALLOCATE(StrPtr2);
+ DEALLOCATE(StrPtr3);
+ DEALLOCATE(StrPtr4);
+ DEALLOCATE(StrPtr5);
+ RETURN;
+ END ReportGlitch;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalGlitch (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT NewValue : IN std_logic;
+ CONSTANT NewDelay : IN TIME := 0 ns;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225
+ CONSTANT MsgOn : IN BOOLEAN := FALSE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+ ---------------------------------------------------------------------------
+ VARIABLE NewGlitch : BOOLEAN := TRUE;
+ VARIABLE dly : TIME := NewDelay;
+ VARIABLE NOW_TIME : TIME := NOW;
+ VARIABLE NegPreemptGlitch : BOOLEAN := FALSE;
+
+ BEGIN
+ NegPreemptGlitch:=FALSE;--reset Preempt-Glitch
+
+ -- If nothing to schedule, just return
+ IF NewDelay < 0 ns THEN
+ IF (NewValue /= GlitchData.SchedValue) THEN
+ VitalError ( "VitalGlitch", ErrNegDel, OutSignalName );
+ END IF;
+ RETURN;
+ END IF;
+
+ -- If simple signal assignment
+ -- perform the signal assignment
+ IF ( Mode = VitalInertial) THEN
+ OutSignal <= NewValue AFTER dly;
+ ELSIF ( Mode = VitalTransport ) THEN
+ OutSignal <= TRANSPORT NewValue AFTER dly;
+ ELSE
+ -- Glitch Processing ---
+ -- If nothing currently scheduled
+ IF GlitchData.SchedTime <= NOW THEN -- NOW >= last event
+ -- Note: NewValue is always /= OldValue when called from VPPD
+ IF (NewValue = GlitchData.SchedValue) THEN RETURN; END IF;
+ NewGlitch := FALSE;
+ GlitchData.GlitchTime := NOW+dly;
+
+ -- New value earlier than the earliest previous value scheduled
+ -- (negative preemptive)
+ ELSIF (NOW+dly <= GlitchData.GlitchTime)
+ AND (NOW+dly <= GlitchData.SchedTime) THEN
+
+ -- Glitch is negative preemptive - check if same value and
+ -- NegPreempt is on IR225
+ IF (GlitchData.SchedValue /= NewValue) AND (NegPreemptOn) AND
+ (NOW > 0 NS) THEN
+ NewGlitch := TRUE;
+ NegPreemptGlitch :=TRUE; -- Set preempt Glitch condition
+ ELSE
+ NewGlitch := FALSE; -- No new glitch, save time for
+ -- possible future glitch
+ END IF;
+ GlitchData.GlitchTime := NOW+dly;
+
+ -- Transaction currently scheduled - if glitch already happened
+ ELSIF GlitchData.GlitchTime <= NOW THEN
+ IF (GlitchData.SchedValue = NewValue) THEN
+ dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+ END IF;
+ NewGlitch := FALSE;
+
+ -- Transaction currently scheduled (no glitch if same value)
+ ELSIF (GlitchData.SchedValue = NewValue)
+ AND (GlitchData.SchedTime = GlitchData.GlitchTime) THEN
+ -- revise scheduled output time if new delay is sooner
+ dly := Minimum( GlitchData.SchedTime-NOW, NewDelay );
+ -- No new glitch, save time for possable future glitch
+ NewGlitch := FALSE;
+ GlitchData.GlitchTime := NOW+dly;
+
+ -- Transaction currently scheduled represents a glitch
+ ELSE
+ NewGlitch := TRUE; -- A new glitch has been detected
+ END IF;
+
+ IF NewGlitch THEN
+ -- If messages requested, report the glitch
+ IF MsgOn THEN
+ IF NegPreemptGlitch THEN --IR225
+ ReportGlitch ("VitalGlitch-Neg", OutSignalName,
+ GlitchData.GlitchTime, GlitchData.SchedValue,
+ (dly + NOW), NewValue,
+ MsgSeverity=>MsgSeverity );
+ ELSE
+ ReportGlitch ("VitalGlitch", OutSignalName,
+ GlitchData.GlitchTime, GlitchData.SchedValue,
+ (dly + NOW), NewValue,
+ MsgSeverity=>MsgSeverity );
+ END IF;
+ END IF;
+
+ -- If 'X' generation is requested, schedule the new value
+ -- preceeded by a glitch pulse.
+ -- Otherwise just schedule the new value (inertial mode).
+ IF XOn THEN
+ IF (Mode = OnDetect) THEN
+ OutSignal <= 'X';
+ ELSE
+ OutSignal <= 'X' AFTER GlitchData.GlitchTime-NOW;
+ END IF;
+
+ IF NegPreemptGlitch THEN -- IR225
+ OutSignal <= TRANSPORT NewValue AFTER GlitchData.SchedTime-NOW;
+ ELSE
+ OutSignal <= TRANSPORT NewValue AFTER dly;
+ END IF;
+ ELSE
+ OutSignal <= NewValue AFTER dly; -- no glitch regular prop delay
+ END IF;
+
+ -- If there no new glitch was detected, just schedule the new value.
+ ELSE
+ OutSignal <= NewValue AFTER dly;
+ END IF;
+ END IF;
+
+ -- Record the new value and time depending on glitch type just scheduled.
+ IF NOT NegPreemptGlitch THEN -- 5/2/96 for "x-pulse" IR225
+ GlitchData.SchedValue := NewValue;
+ GlitchData.SchedTime := NOW+dly; -- pulse timing.
+ ELSE
+ GlitchData.SchedValue := 'X';
+ -- leave GlitchData.SchedTime to old value since glitch is negative
+ END IF;
+ RETURN;
+ END;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalPathDelay (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArrayType;
+ CONSTANT DefaultDelay : IN VitalDelayType := VitalZeroDelay;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE --IR248 3/14/98
+ ) IS
+
+ VARIABLE PropDelay : TIME;
+
+ BEGIN
+ -- Check if the new value to be scheduled is different than the
+ -- previously scheduled value
+ IF (GlitchData.SchedTime <= NOW) AND
+ (GlitchData.SchedValue = OutTemp)
+ THEN RETURN;
+ END IF;
+
+ -- Evaluate propagation delay paths
+ PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue,
+ OutSignalName, Paths, DefaultDelay,
+ IgnoreDefaultDelay);
+
+ GlitchData.LastValue := OutTemp;
+
+ -- Schedule the output transactions - including glitch handling
+ VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp,
+ PropDelay, Mode, XOn, NegPreemptOn, MsgOn, MsgSeverity );
+
+ END VitalPathDelay;
+
+ ---------------------------------------------------------------------------
+
+ PROCEDURE VitalPathDelay01 (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01Type;
+ CONSTANT DefaultDelay : IN VitalDelayType01 := VitalZeroDelay01;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98
+ CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250
+
+
+ ) IS
+
+ VARIABLE PropDelay : TIME;
+ BEGIN
+
+ -- Check if the new value to be scheduled is different than the
+ -- previously scheduled value
+ IF (GlitchData.SchedTime <= NOW) AND
+ (GlitchData.SchedValue = OutTemp)
+ THEN RETURN;
+ -- Check if the new value to be Scheduled is the same as the
+ -- previously scheduled output transactions. If this condition
+ -- exists and the new scheduled time is < the current GlitchData.
+ -- schedTime then a fast path condition exists (IR250). If the
+ -- modeler wants this condition rejected by setting the
+ -- RejectFastPath actual to true then exit out.
+ ELSIF (GlitchData.SchedValue=OutTemp) AND (RejectFastPath)
+ THEN RETURN;
+ END IF;
+
+ -- Evaluate propagation delay paths
+ PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue,
+ OutSignalName, Paths, DefaultDelay,
+ IgnoreDefaultDelay);
+
+ GlitchData.LastValue := OutTemp;
+
+
+ VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp,
+ PropDelay, Mode, XOn, NegPreemptOn, MsgOn, MsgSeverity );
+ END VitalPathDelay01;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalPathDelay01Z (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01ZType;
+ CONSTANT DefaultDelay : IN VitalDelayType01Z := VitalZeroDelay01Z;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98
+ CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250
+ ) IS
+
+ VARIABLE PropDelay : TIME;
+
+ BEGIN
+ -- Check if the new value to be scheduled is different than the
+ -- previously scheduled value
+ IF (GlitchData.SchedTime <= NOW) AND
+ (GlitchData.SchedValue = OutTemp)
+ THEN RETURN;
+ -- Check if the new value to be Scheduled is the same as the
+ -- previously scheduled output transactions. If this condition
+ -- exists and the new scheduled time is < the current GlitchData.
+ -- schedTime then a fast path condition exists (IR250). If the
+ -- modeler wants this condition rejected by setting the
+ -- RejectFastPath actual to true then exit out.
+ ELSIF (GlitchData.SchedValue=OutTemp) AND (RejectFastPath)
+ THEN RETURN;
+ END IF;
+
+ -- Evaluate propagation delay paths
+ PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue,
+ OutSignalName, Paths, DefaultDelay,
+ IgnoreDefaultDelay);
+
+ GlitchData.LastValue := OutTemp;
+
+
+ -- Schedule the output transactions - including glitch handling
+ VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp,
+ PropDelay, Mode, XOn, NegPreemptOn, MsgOn, MsgSeverity );
+ END VitalPathDelay01Z;
+
+
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType
+ ) IS
+ BEGIN
+ OutSig <= TRANSPORT InSig AFTER twire;
+ END VitalWireDelay;
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01
+ ) IS
+ VARIABLE Delay : TIME;
+ BEGIN
+ Delay := VitalCalcDelay( InSig, InSig'LAST_VALUE, twire );
+ OutSig <= TRANSPORT InSig AFTER Delay;
+ END VitalWireDelay;
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01Z
+ ) IS
+ VARIABLE Delay : TIME;
+ BEGIN
+ Delay := VitalCalcDelay( InSig, InSig'LAST_VALUE, twire );
+ OutSig <= TRANSPORT InSig AFTER Delay;
+ END VitalWireDelay;
+
+ ----------------------------------------------------------------------------
+ PROCEDURE VitalSignalDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT dly : IN TIME
+ ) IS
+ BEGIN
+ OutSig <= TRANSPORT InSig AFTER dly;
+ END;
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ -- Setup and Hold Time Check Routine
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ PROCEDURE ReportViolation (
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT CheckInfo : IN CheckInfoType;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+ VARIABLE Message : LINE;
+ BEGIN
+ IF NOT CheckInfo.Violation THEN RETURN; END IF;
+
+ Write ( Message, HeaderMsg );
+ Case CheckInfo.CheckKind IS
+ WHEN SetupCheck => Write ( Message, STRING'(" SETUP ") );
+ WHEN HoldCheck => Write ( Message, STRING'(" HOLD ") );
+ WHEN RecoveryCheck => Write ( Message, STRING'(" RECOVERY ") );
+ WHEN RemovalCheck => Write ( Message, STRING'(" REMOVAL ") );
+ WHEN PulseWidCheck => Write ( Message, STRING'(" PULSE WIDTH "));
+ WHEN PeriodCheck => Write ( Message, STRING'(" PERIOD ") );
+ END CASE;
+ Write ( Message, HiLoStr(CheckInfo.State) );
+ Write ( Message, STRING'(" VIOLATION ON ") );
+ Write ( Message, TestSignalName );
+ IF (RefSignalName'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, RefSignalName );
+ END IF;
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" Expected := ") );
+ Write ( Message, CheckInfo.ExpTime);
+ Write ( Message, STRING'("; Observed := ") );
+ Write ( Message, CheckInfo.ObsTime);
+ Write ( Message, STRING'("; At : ") );
+ Write ( Message, CheckInfo.DetTime);
+
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+
+ DEALLOCATE (Message);
+ END ReportViolation;
+
+
+ ---------------------------------------------------------------------------
+ -- Procedure : InternalTimingCheck
+ ---------------------------------------------------------------------------
+ PROCEDURE InternalTimingCheck (
+ CONSTANT TestSignal : IN std_ulogic;
+ CONSTANT RefSignal : IN std_ulogic;
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ VARIABLE RefTime : IN TIME;
+ VARIABLE RefEdge : IN BOOLEAN;
+ VARIABLE TestTime : IN TIME;
+ VARIABLE TestEvent : IN BOOLEAN;
+ VARIABLE SetupEn : INOUT BOOLEAN;
+ VARIABLE HoldEn : INOUT BOOLEAN;
+ VARIABLE CheckInfo : INOUT CheckInfoType;
+ CONSTANT MsgOn : IN BOOLEAN
+ ) IS
+ VARIABLE bias : TIME;
+ VARIABLE actualObsTime : TIME;
+ VARIABLE BC : TIME;
+ VARIABLE Message:LINE;
+ BEGIN
+ -- Check SETUP constraint
+ IF RefEdge THEN
+ IF SetupEn THEN
+ CheckInfo.ObsTime := RefTime - TestTime;
+ CheckInfo.State := To_X01(TestSignal);
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := SetupLow;
+ -- start of new code IR245-246
+ BC := HoldHigh;
+ -- end of new code IR245-246
+ WHEN '1' => CheckInfo.ExpTime := SetupHigh;
+ -- start of new code IR245-246
+ BC := HoldLow;
+ -- end of new code IR245-246
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow);
+ -- start of new code IR245-246
+ BC := Maximum(HoldHigh,HoldLow);
+ -- end of new code IR245-246
+ END CASE;
+ -- added the second condition for IR 245-246
+ CheckInfo.Violation := ( (CheckInfo.ObsTime < CheckInfo.ExpTime)
+ AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns))) );
+ -- start of new code IR245-246
+ IF(CheckInfo.ExpTime = 0 ns) THEN
+ CheckInfo.CheckKind := HoldCheck;
+ ELSE
+ CheckInfo.CheckKind := SetupCheck;
+ END IF;
+ -- end of new code IR245-246
+ SetupEn := FALSE;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+
+ -- Check HOLD constraint
+ ELSIF TestEvent THEN
+ IF HoldEn THEN
+ CheckInfo.ObsTime := TestTime - RefTime;
+ CheckInfo.State := To_X01(TestSignal);
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := HoldHigh;
+
+ -- new code for unnamed IR
+ CheckInfo.State := '1';
+
+ -- start of new code IR245-246
+ BC := SetupLow;
+ -- end of new code IR245-246
+ WHEN '1' => CheckInfo.ExpTime := HoldLow;
+
+ -- new code for unnamed IR
+ CheckInfo.State := '0';
+
+ -- start of new code IR245-246
+ BC := SetupHigh;
+ -- end of new code IR245-246
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow);
+ -- start of new code IR245-246
+ BC := Maximum(SetupHigh,SetupLow);
+ -- end of new code IR245-246
+ END CASE;
+ -- added the second condition for IR 245-246
+ CheckInfo.Violation := ( (CheckInfo.ObsTime < CheckInfo.ExpTime)
+ AND ( NOT ((CheckInfo.ObsTime = BC) and (BC = 0 ns))) );
+
+ -- start of new code IR245-246
+ IF(CheckInfo.ExpTime = 0 ns) THEN
+ CheckInfo.CheckKind := SetupCheck;
+ ELSE
+ CheckInfo.CheckKind := HoldCheck;
+ END IF;
+ -- end of new code IR245-246
+ HoldEn := NOT CheckInfo.Violation;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+ ELSE
+ CheckInfo.Violation := FALSE;
+ END IF;
+
+ -- Adjust report values to account for internal model delays
+ -- Note: TestDelay, RefDelay, TestTime, RefTime are non-negative
+ -- Note: bias may be negative or positive
+ IF MsgOn AND CheckInfo.Violation THEN
+ -- modified the code for correct reporting of violation in case of
+ -- order of signals being reversed because of internal delays
+ -- new variable
+ actualObsTime := (TestTime-TestDelay)-(RefTime-RefDelay);
+ bias := TestDelay - RefDelay;
+ IF (actualObsTime < 0 ns) THEN -- It should be a setup check
+ IF ( CheckInfo.CheckKind = HoldCheck) then
+ CheckInfo.CheckKind := SetupCheck;
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := SetupLow;
+ WHEN '1' => CheckInfo.ExpTime := SetupHigh;
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(SetupHigh,SetupLow);
+ END CASE;
+ END IF;
+
+ CheckInfo.ObsTime := -actualObsTime;
+ CheckInfo.ExpTime := CheckInfo.ExpTime + bias;
+ CheckInfo.DetTime := RefTime - RefDelay;
+ ELSE -- It should be a hold check
+ IF ( CheckInfo.CheckKind = SetupCheck) then
+ CheckInfo.CheckKind := HoldCheck;
+ CASE CheckInfo.State IS
+ WHEN '0' => CheckInfo.ExpTime := HoldHigh;
+ CheckInfo.State := '1';
+ WHEN '1' => CheckInfo.ExpTime := HoldLow;
+ CheckInfo.State := '0';
+ WHEN 'X' => CheckInfo.ExpTime := Maximum(HoldHigh,HoldLow);
+ END CASE;
+ END IF;
+
+ CheckInfo.ObsTime := actualObsTime;
+ CheckInfo.ExpTime := CheckInfo.ExpTime - bias;
+ CheckInfo.DetTime := TestTime - TestDelay;
+ END IF;
+
+ END IF;
+ END InternalTimingCheck;
+
+ ---------------------------------------------------------------------------
+ ---------------------------------------------------------------------------
+ FUNCTION VitalTimingDataInit
+ RETURN VitalTimingDataType IS
+ BEGIN
+ RETURN (FALSE,'X', 0 ns, FALSE, 'X', 0 ns, FALSE, NULL, NULL, NULL, NULL);
+ END;
+
+ ---------------------------------------------------------------------------
+ -- Procedure : VitalSetupHoldCheck
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+ ) IS
+
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge, TestEvent : BOOLEAN;
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+ BEGIN
+
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLast := To_X01(TestSignal);
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ TimingData.SetupEn := TimingData.SetupEn AND EnableSetupOnRef; --IR252 3/23/98
+ TimingData.HoldEn := EnableHoldOnRef; --IR252 3/23/98
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ TestEvent := TimingData.TestLast /= To_X01Z(TestSignal);
+ TimingData.TestLast := To_X01Z(TestSignal);
+ IF TestEvent THEN
+ TimingData.TestTime := NOW;
+ TimingData.SetupEn := EnableSetupOnTest; --IR252 3/23/98
+ TimingData.HoldEn := TimingData.HoldEn AND EnableHoldOnTest; --IR252 3/23/98
+ END IF;
+
+ -- Perform timing checks (if enabled)
+ Violation := '0';
+ IF (CheckEnabled) THEN
+ InternalTimingCheck (
+ TestSignal => TestSignal,
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh,
+ SetupLow => SetupLow,
+ HoldHigh => HoldHigh,
+ HoldLow => HoldLow,
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTime,
+ TestEvent => TestEvent,
+ SetupEn => TimingData.SetupEn,
+ HoldEn => TimingData.HoldEn,
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ ReportViolation (TestSignalName, RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF;
+ IF (XOn) THEN Violation := 'X'; END IF;
+ END IF;
+ END IF;
+
+ END VitalSetupHoldCheck;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+
+ ) IS
+
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge : BOOLEAN;
+ VARIABLE TestEvent : VitalBoolArrayT(TestSignal'RANGE);
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+ VARIABLE ChangedAllAtOnce : BOOLEAN := TRUE;
+ VARIABLE StrPtr1 : LINE;
+
+ BEGIN
+ -- Initialization of working area.
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE);
+ TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE);
+ TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE);
+ FOR i IN TestSignal'RANGE LOOP
+ TimingData.TestLastA(i) := To_X01(TestSignal(i));
+ END LOOP;
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ TimingData.SetupEn := TimingData.SetupEn AND EnableSetupOnRef; --IR252 3/23/98
+ TimingData.HoldEnA.all := (TestSignal'RANGE => EnableHoldOnRef); --IR252 3/23/98
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ FOR i IN TestSignal'RANGE LOOP
+ TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i));
+ TimingData.TestLastA(i) := To_X01Z(TestSignal(i));
+ IF TestEvent(i) THEN
+ TimingData.TestTimeA(i) := NOW;
+ TimingData.SetupEnA(i) := EnableSetupOnTest; --IR252 3/23/98
+ TimingData.HoldEnA(i) := TimingData.HoldEn AND EnableHoldOnTest; --IR252 3/23/98
+ TimingData.TestTime := NOW; --IR252 3/23/98
+ END IF;
+ END LOOP;
+
+ -- Check to see if the Bus subelements changed all at the same time.
+ -- If so, then we can reduce the volume of error messages since we no
+ -- longer have to report every subelement individually
+ FOR i IN TestSignal'RANGE LOOP
+ IF TimingData.TestTimeA(i) /= TimingData.TestTime THEN
+ ChangedAllAtOnce := FALSE;
+ EXIT;
+ END IF;
+ END LOOP;
+
+ -- Perform timing checks (if enabled)
+ Violation := '0';
+ IF (CheckEnabled) THEN
+ FOR i IN TestSignal'RANGE LOOP
+ InternalTimingCheck (
+ TestSignal => TestSignal(i),
+ RefSignal => RefSignal,
+ TestDelay => TestDly,
+ RefDelay => RefDly,
+ SetupHigh => SetupHigh,
+ SetupLow => SetupLow,
+ HoldHigh => HoldHigh,
+ HoldLow => HoldLow,
+ RefTime => TimingData.RefTime,
+ RefEdge => RefEdge,
+ TestTime => TimingData.TestTimeA(i),
+ TestEvent => TestEvent(i),
+ SetupEn => TimingData.SetupEnA(i),
+ HoldEn => TimingData.HoldEnA(i),
+ CheckInfo => CheckInfo,
+ MsgOn => MsgOn );
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF (MsgOn) THEN
+ IF ( ChangedAllAtOnce AND (i = TestSignal'LEFT) ) THEN
+ ReportViolation (TestSignalName&"(...)", RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ ELSIF (NOT ChangedAllAtOnce) THEN
+ Write (StrPtr1, i);
+ ReportViolation (TestSignalName & "(" & StrPtr1.ALL & ")",
+ RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ DEALLOCATE (StrPtr1);
+ END IF;
+ END IF;
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ END IF;
+ END LOOP;
+ END IF;
+
+ DEALLOCATE (StrPtr1);
+
+ END VitalSetupHoldCheck;
+
+ ---------------------------------------------------------------------------
+ -- Function : VitalRecoveryRemovalCheck
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalRecoveryRemovalCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT Recovery : IN TIME := 0 ns;
+ CONSTANT Removal : IN TIME := 0 ns;
+ CONSTANT ActiveLow : IN BOOLEAN := TRUE;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableRecOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRecOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRemOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRemOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+ ) IS
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE RefEdge, TestEvent : BOOLEAN;
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay);
+ VARIABLE bias : TIME;
+ BEGIN
+
+ IF (TimingData.NotFirstFlag = FALSE) THEN
+ TimingData.TestLast := To_X01(TestSignal);
+ TimingData.RefLast := To_X01(RefSignal);
+ TimingData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Detect reference edges and record the time of the last edge
+ RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal),
+ RefTransition);
+ TimingData.RefLast := To_X01(RefSignal);
+ IF RefEdge THEN
+ TimingData.RefTime := NOW;
+ TimingData.SetupEn := TimingData.SetupEn AND EnableRecOnRef; --IR252 3/23/98
+ TimingData.HoldEn := EnableRemOnRef; --IR252 3/23/98
+ END IF;
+
+ -- Detect test (data) changes and record the time of the last change
+ TestEvent := TimingData.TestLast /= To_X01Z(TestSignal);
+ TimingData.TestLast := To_X01Z(TestSignal);
+ IF TestEvent THEN
+ TimingData.TestTime := NOW;
+ TimingData.SetupEn := EnableRecOnTest; --IR252 3/23/98
+ TimingData.HoldEn := TimingData.HoldEn AND EnableRemOnTest; --IR252 3/23/98
+ END IF;
+
+ -- Perform timing checks (if enabled)
+ Violation := '0';
+ IF (CheckEnabled) THEN
+
+ IF ActiveLow THEN
+ InternalTimingCheck (
+ TestSignal, RefSignal, TestDly, RefDly,
+ Recovery, 0 ns, 0 ns, Removal,
+ TimingData.RefTime, RefEdge,
+ TimingData.TestTime, TestEvent,
+ TimingData.SetupEn, TimingData.HoldEn,
+ CheckInfo, MsgOn );
+ ELSE
+ InternalTimingCheck (
+ TestSignal, RefSignal, TestDly, RefDly,
+ 0 ns, Recovery, Removal, 0 ns,
+ TimingData.RefTime, RefEdge,
+ TimingData.TestTime, TestEvent,
+ TimingData.SetupEn, TimingData.HoldEn,
+ CheckInfo, MsgOn );
+ END IF;
+
+
+ -- Report any detected violations and set return violation flag
+ IF CheckInfo.Violation THEN
+ IF CheckInfo.CheckKind = SetupCheck THEN
+ CheckInfo.CheckKind := RecoveryCheck;
+ ELSE
+ CheckInfo.CheckKind := RemovalCheck;
+ END IF;
+ IF (MsgOn) THEN
+ ReportViolation (TestSignalName, RefSignalName,
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF;
+ IF (XOn) THEN Violation := 'X'; END IF;
+ END IF;
+ END IF;
+
+ END VitalRecoveryRemovalCheck;
+
+ ---------------------------------------------------------------------------
+ PROCEDURE VitalPeriodPulseCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE PeriodData : INOUT VitalPeriodDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT Period : IN TIME := 0 ns;
+ CONSTANT PulseWidthHigh : IN TIME := 0 ns;
+ CONSTANT PulseWidthLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ ) IS
+
+ VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay);
+ VARIABLE CheckInfo : CheckInfoType;
+ VARIABLE PeriodObs : TIME;
+ VARIABLE PulseTest, PeriodTest : BOOLEAN;
+ VARIABLE TestValue : X01 := To_X01(TestSignal);
+ BEGIN
+
+ IF (PeriodData.NotFirstFlag = FALSE) THEN
+ PeriodData.Rise :=
+ -maximum(Period, maximum(PulseWidthHigh, PulseWidthLow));
+ PeriodData.Fall :=
+ -maximum(Period, maximum(PulseWidthHigh, PulseWidthLow));
+ PeriodData.Last := To_X01(TestSignal);
+ PeriodData.NotFirstFlag := TRUE;
+ END IF;
+
+ -- Initialize for no violation
+ -- No violation possible if no test signal change
+ Violation := '0';
+ IF (PeriodData.Last = TestValue) THEN
+ RETURN;
+ END IF;
+
+ -- record starting pulse times
+ IF EdgeSymbolMatch(PeriodData.Last, TestValue, 'P') THEN
+ -- Compute period times, then record the High Rise Time
+ PeriodObs := NOW - PeriodData.Rise;
+ PeriodData.Rise := NOW;
+ PeriodTest := TRUE;
+ ELSIF EdgeSymbolMatch(PeriodData.Last, TestValue, 'N') THEN
+ -- Compute period times, then record the Low Fall Time
+ PeriodObs := NOW - PeriodData.Fall;
+ PeriodData.Fall := NOW;
+ PeriodTest := TRUE;
+ ELSE
+ PeriodTest := FALSE;
+ END IF;
+
+ -- do checks on pulse ends
+ IF EdgeSymbolMatch(PeriodData.Last, TestValue, 'p') THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData.Fall;
+ CheckInfo.ExpTime := PulseWidthLow;
+ PulseTest := TRUE;
+ ELSIF EdgeSymbolMatch(PeriodData.Last, TestValue, 'n') THEN
+ -- Compute pulse times
+ CheckInfo.ObsTime := NOW - PeriodData.Rise;
+ CheckInfo.ExpTime := PulseWidthHigh;
+ PulseTest := TRUE;
+ ELSE
+ PulseTest := FALSE;
+ END IF;
+
+ IF PulseTest AND CheckEnabled THEN
+ -- Verify Pulse Width [ignore 1st edge]
+ IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN
+ IF (XOn) THEN Violation := 'X'; END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PulseWidCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := PeriodData.Last;
+ ReportViolation (TestSignalName, "",
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ IF PeriodTest AND CheckEnabled THEN
+ -- Verify the Period [ignore 1st edge]
+ CheckInfo.ObsTime := PeriodObs;
+ CheckInfo.ExpTime := Period;
+ IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN
+ IF (XOn) THEN Violation := 'X'; END IF;
+ IF (MsgOn) THEN
+ CheckInfo.Violation := TRUE;
+ CheckInfo.CheckKind := PeriodCheck;
+ CheckInfo.DetTime := NOW - TestDly;
+ CheckInfo.State := TestValue;
+ ReportViolation (TestSignalName, "",
+ HeaderMsg, CheckInfo, MsgSeverity );
+ END IF; -- MsgOn
+ END IF;
+ END IF;
+
+ PeriodData.Last := TestValue;
+
+ END VitalPeriodPulseCheck;
+
+
+
+ PROCEDURE ReportSkewViolation (
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT ExpectedTime : IN TIME;
+ CONSTANT OccuranceTime : IN TIME;
+ CONSTANT HeaderMsg : IN STRING;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT SkewPhase : IN SkewType;
+ CONSTANT ViolationFlag : IN BOOLEAN := TRUE
+ ) IS
+ VARIABLE Message : LINE;
+ BEGIN
+ Write ( Message, HeaderMsg );
+ IF (ViolationFlag /= TRUE) THEN
+ Write ( Message, STRING'(" POSSIBLE") );
+ END IF;
+ IF (SkewPhase = Inphase) THEN
+ Write ( Message, STRING'(" IN PHASE ") );
+ ELSE
+ Write ( Message, STRING'(" OUT OF PHASE ") );
+ END IF;
+ Write ( Message, STRING'("SKEW VIOLATION ON ") );
+ Write ( Message, Signal2Name );
+ IF (Signal1Name'LENGTH > 0) THEN
+ Write ( Message, STRING'(" WITH RESPECT TO ") );
+ Write ( Message, Signal1Name );
+ END IF;
+ Write ( Message, ';' & LF );
+ Write ( Message, STRING'(" At : ") );
+ Write ( Message, OccuranceTime);
+ Write ( Message, STRING'("; Skew Limit : ") );
+ Write ( Message, ExpectedTime);
+
+ ASSERT FALSE REPORT Message.ALL SEVERITY MsgSeverity;
+
+ DEALLOCATE (Message);
+ END ReportSkewViolation;
+
+
+ PROCEDURE VitalInPhaseSkewCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE SkewData : INOUT VitalSkewDataType;
+ SIGNAL Signal1 : IN std_ulogic;
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal1Delay : IN TIME := 0 ns;
+ SIGNAL Signal2 : IN std_ulogic;
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT Signal2Delay : IN TIME := 0 ns;
+ CONSTANT SkewS1S2RiseRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1RiseRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS1S2FallFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1FallFall : IN TIME := TIME'HIGH;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT HeaderMsg : IN STRING := "";
+ SIGNAL Trigger : INOUT std_ulogic
+ ) IS
+ VARIABLE ReportType : VitalSkewExpectedType := none;
+ VARIABLE ExpectedType : VitalSkewExpectedType := none;
+ VARIABLE ReportTime : TIME;
+ VARIABLE TriggerDelay : TIME;
+ VARIABLE ViolationCertain : Boolean := TRUE;
+ BEGIN
+ Violation := '0';
+ ReportType := none;
+ TriggerDelay := noTrigger;
+
+ IF (CheckEnabled) THEN
+ IF (SkewData.ExpectedType /= none) THEN
+ IF (trigger'Event) THEN
+ CASE SkewData.ExpectedType IS
+ WHEN s1r => ReportType := s1r;
+ ReportTime := NOW - Signal1Delay;
+ WHEN s1f => ReportType := s1f;
+ ReportTime := NOW - Signal1Delay;
+ WHEN s2r => ReportType := s2r;
+ ReportTime := NOW - Signal2Delay;
+ WHEN s2f => ReportType := s2f;
+ ReportTime := NOW - Signal2Delay;
+ WHEN OTHERS =>
+ END CASE;
+ SkewData.ExpectedType := none;
+ ELSIF ( Signal1'Event OR Signal2'Event ) THEN
+ IF ( Signal1 /= 'X' AND Signal2 /= 'X' ) THEN
+ TriggerDelay := 0 ns;
+ ExpectedType := none;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (Signal1'EVENT and Signal2'EVENT) THEN
+ IF (Signal1 = Signal2) THEN
+ IF (Posedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - Signal2Delay) >=
+ SkewS1S2RiseRise) THEN
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseRise;
+ ELSIF ((Signal2Delay -Signal1Delay) >=
+ SkewS2S1RiseRise) THEN
+ ReportType := s1r;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1RiseRise;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - Signal2Delay) >=
+ SkewS1S2FallFall) THEN
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallFall;
+ ELSIF ((Signal2Delay - Signal1Delay) >=
+ SkewS2S1FallFall) THEN
+ ReportType := s1f;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1FallFall;
+ END IF;
+ END IF;
+ ELSIF (Posedge(Signal1'LAST_VALUE , Signal1)) THEN
+ IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay >
+ SkewS2S1FallFall)) THEN
+ ReportType := s1f;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1FallFall;
+ ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay >
+ SkewS1S2RiseRise)) THEN
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseRise;
+ ELSIF (Signal2Delay > Signal1Delay) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2RiseRise +
+ Signal2Delay - Signal1Delay;
+ ELSIF (Signal1Delay > Signal2Delay) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1RiseRise +
+ Signal1Delay - Signal2Delay;
+ ELSIF (SkewS1S2RiseRise < SkewS2S1RiseRise) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2RiseRise;
+ ELSE
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1RiseRise;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE , Signal1)) THEN
+ IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay >
+ SkewS2S1RiseRise)) THEN
+ ReportType := s1r;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1RiseRise;
+ ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay >
+ SkewS1S2FallFall)) THEN
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallFall;
+ ELSIF (Signal2Delay > Signal1Delay) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2FallFall +
+ Signal2Delay - Signal1Delay;
+ ELSIF (Signal1Delay > Signal2Delay) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1FallFall +
+ Signal1Delay - Signal2Delay;
+ ELSIF (SkewS1S2FallFall < SkewS2S1FallFall) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2FallFall;
+ ELSE
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1FallFall;
+ END IF;
+ END IF;
+ ELSIF (Signal1'EVENT) THEN
+ IF ( Signal1 /= Signal2) THEN
+ IF ( Posedge( Signal1'LAST_VALUE, Signal1)) THEN
+ IF (SkewS1S2RiseRise > (Signal1Delay -
+ Signal2Delay)) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2RiseRise +
+ Signal2Delay -
+ Signal1Delay;
+ ELSE
+ ReportType := s2r;
+ ReportTime := NOW + SkewS1S2RiseRise -
+ Signal1Delay;
+ END IF;
+ ELSIF ( Negedge( Signal1'LAST_VALUE, Signal1)) THEN
+ IF (SkewS1S2FallFall > (Signal1Delay -
+ Signal2Delay)) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2FallFall +
+ Signal2Delay -
+ Signal1Delay;
+ ELSE
+ ReportType := s2f;
+ ReportTime := NOW + SkewS1S2FallFall -
+ Signal1Delay;
+ END IF;
+ END IF;
+ ELSE
+ IF ( Posedge( Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - SkewS1S2RiseRise) >
+ (Signal2'LAST_EVENT + Signal2Delay)) THEN
+ IF ((SkewData.Signal2Old2 - Signal2Delay) >
+ (NOW - Signal1Delay +
+ SkewS1S2RiseRise)) THEN
+ ViolationCertain := FALSE;
+ ReportType := s2r;
+ ReportTime := NOW + SkewS1S2RiseRise -
+ Signal1Delay;
+ END IF;
+ END IF;
+ ELSIF ( Negedge( Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - SkewS1S2FallFall) >
+ (Signal2'LAST_EVENT + Signal2Delay)) THEN
+ IF (( SkewData.Signal2Old2 - Signal2Delay) >
+ (NOW - Signal1Delay +
+ SkewS1S2FallFall )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s2f;
+ ReportTime := NOW + SkewS1S2FallFall -
+ Signal1Delay;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ ELSIF (Signal2'EVENT) THEN
+ IF (Signal1 /= Signal2) THEN
+ IF (Posedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF ( SkewS2S1RiseRise > (Signal2Delay -
+ Signal1Delay)) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1RiseRise +
+ Signal1Delay -
+ Signal2Delay;
+ ELSE
+ ReportType := s2r;
+ ReportTime := NOW + SkewS2S1RiseRise -
+ Signal2Delay;
+ END IF;
+ ELSIF (Negedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF ( SkewS2S1FallFall > (Signal2Delay -
+ Signal1Delay)) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1FallFall +
+ Signal1Delay -
+ Signal2Delay;
+ ELSE
+ ReportType := s1f;
+ ReportTime := NOW + SkewS2S1FallFall -
+ Signal2Delay;
+ END IF;
+ END IF;
+ ELSE
+ IF (Posedge(Signal2'LAST_VALUE, Signal2)) THEN
+ IF ((Signal2Delay - SkewS2S1RiseRise) >
+ (Signal1'LAST_EVENT + Signal1Delay)) THEN
+ IF (( SkewData.Signal1Old2 - Signal1Delay) >
+ (NOW - Signal2Delay +
+ SkewS2S1RiseRise )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s1r;
+ ReportTime := NOW + SkewS2S1RiseRise -
+ Signal2Delay;
+ END IF;
+ END IF;
+ ELSIF (Negedge(Signal2'LAST_VALUE, Signal2)) THEN
+ IF ((Signal2Delay - SkewS2S1FallFall) >
+ (Signal1'LAST_EVENT + Signal1Delay)) THEN
+ IF (( SkewData.Signal1Old2 - Signal1Delay) >
+ (NOW - Signal2Delay +
+ SkewS2S1FallFall )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s1f;
+ ReportTime := NOW + SkewS2S1FallFall -
+ Signal2Delay;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (ReportType /= none) THEN
+ IF (MsgOn) THEN
+ CASE ReportType IS
+ WHEN s1r =>
+ ReportSkewViolation(
+ Signal2Name,
+ Signal1Name,
+ SkewS2S1RiseRise,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Inphase,
+ ViolationCertain);
+ WHEN s1f =>
+ ReportSkewViolation(
+ Signal2Name,
+ Signal1Name,
+ SkewS2S1FallFall,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Inphase,
+ ViolationCertain);
+ WHEN s2r =>
+ ReportSkewViolation(
+ Signal1Name,
+ Signal2Name,
+ SkewS1S2RiseRise,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Inphase,
+ ViolationCertain);
+ WHEN s2f =>
+ ReportSkewViolation(
+ Signal1Name,
+ Signal2Name,
+ SkewS1S2FallFall,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Inphase,
+ ViolationCertain);
+ WHEN OTHERS =>
+ END CASE;
+ END IF;
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ SkewData.ExpectedType := none;
+ END IF;
+ IF (TriggerDelay /= noTrigger) THEN
+ IF (TriggerDelay = 0 ns) THEN
+ trigger <= TRANSPORT trigger AFTER 0 ns;
+ ELSE
+ trigger <= TRANSPORT not (trigger) AFTER
+ TriggerDelay;
+ END IF;
+ END IF;
+ END IF;
+ IF (Signal1'EVENT and SkewData.Signal1Old1 /= NOW) THEN
+ SkewData.Signal1Old2 := SkewData.Signal1Old1;
+ SkewData.Signal1Old1 := NOW;
+ END IF;
+ IF (Signal2'EVENT and SkewData.Signal2Old1 /= NOW) THEN
+ SkewData.Signal2Old2 := SkewData.Signal2Old1;
+ SkewData.Signal2Old1 := NOW;
+ END IF;
+ END VitalInPhaseSkewCheck;
+
+ PROCEDURE VitalOutPhaseSkewCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE SkewData : INOUT VitalSkewDataType;
+ SIGNAL Signal1 : IN std_ulogic;
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal1Delay : IN TIME := 0 ns;
+ SIGNAL Signal2 : IN std_ulogic;
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT Signal2Delay : IN TIME := 0 ns;
+ CONSTANT SkewS1S2RiseFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1RiseFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS1S2FallRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1FallRise : IN TIME := TIME'HIGH;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT HeaderMsg : IN STRING := "";
+ SIGNAL Trigger : INOUT std_ulogic
+ ) IS
+ VARIABLE ReportType : VitalSkewExpectedType := none;
+ VARIABLE ExpectedType : VitalSkewExpectedType := none;
+ VARIABLE ReportTime : TIME;
+ VARIABLE TriggerDelay : TIME;
+ VARIABLE ViolationCertain : Boolean := TRUE;
+ BEGIN
+ Violation := '0';
+ TriggerDelay := noTrigger;
+ IF (CheckEnabled) THEN
+ IF (SkewData.ExpectedType /= none) THEN
+ IF (trigger'Event) THEN
+ CASE SkewData.ExpectedType IS
+ WHEN s1r => ReportType := s1r;
+ ReportTime := NOW - Signal1Delay;
+ WHEN s1f => ReportType := s1f;
+ ReportTime := NOW - Signal1Delay;
+ WHEN s2r => ReportType := s2r;
+ ReportTime := NOW - Signal2Delay;
+ WHEN s2f => ReportType := s2f;
+ ReportTime := NOW - Signal2Delay;
+ WHEN OTHERS =>
+ END CASE;
+ SkewData.ExpectedType := none;
+ ELSIF (Signal1'Event OR Signal2'Event ) THEN
+ IF (Signal1 /= 'X' AND Signal2 /= 'X' ) THEN
+ TriggerDelay := 0 ns;
+ SkewData.ExpectedType := none;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (Signal1'EVENT and Signal2'EVENT) THEN
+ IF (Signal1 /= Signal2) THEN
+ IF (Posedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - Signal2Delay) >=
+ SkewS1S2RiseFall) THEN
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseFall;
+ ELSIF ((Signal2Delay - Signal1Delay) >=
+ SkewS2S1FallRise) THEN
+ ReportType := s1r;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1FallRise;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - Signal2Delay) >=
+ SkewS1S2FallRise) THEN
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallRise;
+ ELSIF ((Signal2Delay - Signal1Delay) >=
+ SkewS2S1RiseFall) THEN
+ ReportType := s1f;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1RiseFall;
+ END IF;
+ END IF;
+ ELSIF (Posedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay >
+ SkewS2S1RiseFall)) THEN
+ ReportType := s1f;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1RiseFall;
+ ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay >
+ SkewS1S2RiseFall)) THEN
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseFall;
+ ELSIF (Signal1Delay > Signal2Delay) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1RiseFall +
+ Signal1Delay - Signal2Delay;
+ ELSIF (Signal2Delay > Signal1Delay) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2RiseFall +
+ Signal2Delay - Signal1Delay;
+ ELSIF (SkewS2S1RiseFall < SkewS1S2RiseFall) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1RiseFall;
+ ELSE
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2RiseFall;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay >= Signal2Delay) and (Signal2Delay >
+ SkewS2S1FallRise)) THEN
+ ReportType := s1r;
+ ReportTime := NOW - Signal2Delay +
+ SkewS2S1FallRise;
+ ELSIF ((Signal2Delay >= Signal1Delay) and (Signal1Delay >
+ SkewS1S2FallRise)) THEN
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallRise;
+ ELSIF (Signal1Delay > Signal2Delay) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1FallRise +
+ Signal1Delay - Signal2Delay;
+ ELSIF (Signal2Delay > Signal1Delay) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2FallRise +
+ Signal2Delay - Signal1Delay;
+ ELSIF (SkewS2S1FallRise < SkewS1S2FallRise) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1FallRise;
+ ELSE
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2FallRise;
+ END IF;
+ END IF;
+ ELSIF (Signal1'EVENT) THEN
+ IF (Signal1 = Signal2) THEN
+ IF (Posedge(Signal1'LAST_VALUE,Signal1)) THEN
+ IF (SkewS1S2RiseFall > (Signal1Delay -
+ Signal2Delay)) THEN
+ SkewData.ExpectedType := s2f;
+ TriggerDelay := SkewS1S2RiseFall +
+ Signal2Delay - Signal1Delay;
+ ELSE
+ ReportType := s2f;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2RiseFall;
+ END IF;
+ ELSIF ( Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ( SkewS1S2FallRise > (Signal1Delay -
+ Signal2Delay)) THEN
+ SkewData.ExpectedType := s2r;
+ TriggerDelay := SkewS1S2FallRise +
+ Signal2Delay - Signal1Delay;
+ ELSE
+ ReportType := s2r;
+ ReportTime := NOW - Signal1Delay +
+ SkewS1S2FallRise;
+ END IF;
+ END IF;
+ ELSE
+ IF (Posedge( Signal1'LAST_VALUE, Signal1 )) THEN
+ IF ((Signal1Delay - SkewS1S2RiseFall) >
+ (Signal2'LAST_EVENT + Signal2Delay)) THEN
+ IF (( SkewData.Signal2Old2 - Signal2Delay) >
+ (NOW - Signal1Delay +
+ SkewS1S2RiseFall )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s2f;
+ ReportTime := NOW + SkewS1S2RiseFall -
+ Signal1Delay;
+ END IF;
+ END IF;
+ ELSIF (Negedge(Signal1'LAST_VALUE, Signal1)) THEN
+ IF ((Signal1Delay - SkewS1S2FallRise) >
+ (Signal2'LAST_EVENT + Signal2Delay)) THEN
+ IF (( SkewData.Signal2Old2 - Signal2Delay) >
+ (NOW - Signal1Delay +
+ SkewS1S2FallRise )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s2r;
+ ReportTime := NOW + SkewS1S2FallRise -
+ Signal1Delay;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ ELSIF (Signal2'EVENT) THEN
+ IF (Signal1 = Signal2) THEN
+ IF (Posedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF (SkewS2S1RiseFall > (Signal2Delay -
+ Signal1Delay)) THEN
+ SkewData.ExpectedType := s1f;
+ TriggerDelay := SkewS2S1RiseFall + Signal1Delay -
+ Signal2Delay ;
+ ELSE
+ ReportType := s1f;
+ ReportTime := NOW + SkewS2S1RiseFall -
+ Signal2Delay;
+ END IF;
+ ELSIF (Negedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF (SkewS2S1FallRise > (Signal2Delay -
+ Signal1Delay)) THEN
+ SkewData.ExpectedType := s1r;
+ TriggerDelay := SkewS2S1FallRise + Signal1Delay -
+ Signal2Delay;
+ ELSE
+ ReportType := s1r;
+ ReportTime := NOW + SkewS2S1FallRise -
+ Signal2Delay;
+ END IF;
+ END IF;
+ ELSE
+ IF (Posedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF ((Signal2Delay - SkewS2S1RiseFall) >
+ (Signal1'LAST_EVENT + Signal1Delay)) THEN
+ IF (( SkewData.Signal1Old2 - Signal1Delay) >
+ (NOW - Signal2Delay +
+ SkewS2S1RiseFall )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s1f;
+ ReportTime := NOW + SkewS2S1RiseFall -
+ Signal2Delay;
+ END IF;
+ END IF;
+ ELSIF (Negedge(Signal2'LAST_VALUE,Signal2)) THEN
+ IF ((Signal2Delay - SkewS2S1FallRise) >
+ (Signal1'LAST_EVENT + Signal1Delay)) THEN
+ IF (( SkewData.Signal1Old2 - Signal1Delay) >
+ (NOW - Signal2Delay +
+ SkewS2S1FallRise )) THEN
+ ViolationCertain := FALSE;
+ ReportType := s1r;
+ ReportTime := NOW + SkewS2S1FallRise -
+ Signal2Delay;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+ END IF;
+
+ IF (ReportType /= none) THEN
+ IF (MsgOn) THEN
+ CASE ReportType IS
+ WHEN s1r =>
+ ReportSkewViolation(
+ Signal2Name,
+ Signal1Name,
+ SkewS2S1FallRise,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Outphase,
+ ViolationCertain);
+ WHEN s1f =>
+ ReportSkewViolation(
+ Signal2Name,
+ Signal1Name,
+ SkewS2S1RiseFall,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Outphase,
+ ViolationCertain);
+ WHEN s2r =>
+ ReportSkewViolation(
+ Signal1Name,
+ Signal2Name,
+ SkewS1S2FallRise,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Outphase,
+ ViolationCertain);
+ WHEN s2f =>
+ ReportSkewViolation(
+ Signal1Name,
+ Signal2Name,
+ SkewS1S2RiseFall,
+ ReportTime,
+ HeaderMsg,
+ MsgSeverity,
+ Outphase,
+ ViolationCertain);
+ WHEN OTHERS =>
+ END CASE;
+ END IF;
+ IF (XOn) THEN
+ Violation := 'X';
+ END IF;
+ ReportType := none;
+ END IF;
+ IF (TriggerDelay /= noTrigger) THEN
+ IF (TriggerDelay = 0 ns) THEN
+ trigger <= TRANSPORT trigger AFTER 0 ns;
+ ELSE
+ trigger <= TRANSPORT not (trigger) AFTER
+ TriggerDelay;
+ END IF;
+ END IF;
+ END IF;
+ IF (Signal1'EVENT and SkewData.Signal1Old1 /= NOW) THEN
+ SkewData.Signal1Old2 := SkewData.Signal1Old1;
+ SkewData.Signal1Old1 := NOW;
+ END IF;
+ IF (Signal2'EVENT and SkewData.Signal2Old1 /= NOW) THEN
+ SkewData.Signal2Old2 := SkewData.Signal2Old1;
+ SkewData.Signal2Old1 := NOW;
+ END IF;
+ END VitalOutPhaseSkewCheck;
+
+END VITAL_Timing;
diff --git a/libraries/vital2000/timing_p.vhdl b/libraries/vital2000/timing_p.vhdl
new file mode 100644
index 000000000..e18c8c24a
--- /dev/null
+++ b/libraries/vital2000/timing_p.vhdl
@@ -0,0 +1,1202 @@
+-------------------------------------------------------------------------------
+-- Title : Standard VITAL TIMING Package
+-- : $Revision: 598 $
+-- :
+-- Library : This package shall be compiled into a library
+-- : symbolically named IEEE.
+-- :
+-- Developers : IEEE DASC Timing Working Group (TWG), PAR 1076.4
+-- :
+-- Purpose : This packages defines standard types, attributes, constants,
+-- : functions and procedures for use in developing ASIC models.
+-- :
+-- Known Errors :
+-- :
+-- Note : No declarations or definitions shall be included in,
+-- : or excluded from this package. The "package declaration"
+-- : defines the objects (types, subtypes, constants, functions,
+-- : procedures ... etc.) that can be used by a user. The package
+-- : body shall be considered the formal definition of the
+-- : semantics of this package. Tool developers may choose to
+-- : implement the package body in the most efficient manner
+-- : available to them.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Acknowledgments:
+-- This code was originally developed under the "VHDL Initiative Toward ASIC
+-- Libraries" (VITAL), an industry sponsored initiative. Technical
+-- Director: William Billowitch, VHDL Technology Group; U.S. Coordinator:
+-- Steve Schultz; Steering Committee Members: Victor Berman, Cadence Design
+-- Systems; Oz Levia, Synopsys Inc.; Ray Ryan, Ryan & Ryan; Herman van Beek,
+-- Texas Instruments; Victor Martin, Hewlett-Packard Company.
+-- ----------------------------------------------------------------------------
+--
+-- ----------------------------------------------------------------------------
+-- Modification History :
+-- ----------------------------------------------------------------------------
+-- Version No:|Auth:| Mod.Date:| Changes Made:
+-- v95.0 A | | 06/02/95 | Initial ballot draft 1995
+-- v95.1 | | 08/31/95 | #203 - Timing violations at time 0
+-- #204 - Output mapping prior to glitch detection
+-- v98.0 |TAG | 03/27/98 | Initial ballot draft 1998
+-- | #IR225 - Negative Premptive Glitch
+-- **Pkg_effected=VitalPathDelay,
+-- VitalPathDelay01,VitalPathDelay01z.
+-- #IR105 - Skew timing check needed
+-- **Pkg_effected=NONE, New code added!!
+-- #IR248 - Allows VPD to use a default timing
+-- delay
+-- **Pkg_effected=VitalPathDelay,
+-- VitalPathDelay01,VitalPathDelay01z,
+-- #IR250 - Corrects fastpath condition in VPD
+-- **Pkg_effected=VitalPathDelay01,
+-- VitalPathDelay01z,
+-- #IR252 - Corrects cancelled timing check call if
+-- condition expires.
+-- **Pkg_effected=VitalSetupHoldCheck,
+-- VitalRecoveryRemovalCheck.
+-- #IR105 - Skew timing check
+-- **Pkg_effected=NONE, New code added
+-- v98.1 | jdc | 03/25/99 | Changed UseDefaultDelay to IgnoreDefaultDelay
+-- and set default to FALSE in VitalPathDelay()
+-- v00.7 | dbb | 07/18/00 | Removed "maximum" from VitalPeriodPulse()
+-- comments
+
+
+LIBRARY IEEE;
+USE IEEE.Std_Logic_1164.ALL;
+
+PACKAGE VITAL_Timing IS
+ TYPE VitalTransitionType IS ( tr01, tr10, tr0z, trz1, tr1z, trz0,
+ tr0X, trx1, tr1x, trx0, trxz, trzx);
+
+ SUBTYPE VitalDelayType IS TIME;
+ TYPE VitalDelayType01 IS ARRAY (VitalTransitionType RANGE tr01 to tr10)
+ OF TIME;
+ TYPE VitalDelayType01Z IS ARRAY (VitalTransitionType RANGE tr01 to trz0)
+ OF TIME;
+ TYPE VitalDelayType01ZX IS ARRAY (VitalTransitionType RANGE tr01 to trzx)
+ OF TIME;
+
+ TYPE VitalDelayArrayType IS ARRAY (NATURAL RANGE <>) OF VitalDelayType;
+ TYPE VitalDelayArrayType01 IS ARRAY (NATURAL RANGE <>) OF VitalDelayType01;
+ TYPE VitalDelayArrayType01Z IS ARRAY (NATURAL RANGE <>) OF VitalDelayType01Z;
+ TYPE VitalDelayArrayType01ZX IS ARRAY (NATURAL RANGE <>) OF VitalDelayType01ZX;
+ -- ----------------------------------------------------------------------
+ -- **********************************************************************
+ -- ----------------------------------------------------------------------
+
+ CONSTANT VitalZeroDelay : VitalDelayType := 0 ns;
+ CONSTANT VitalZeroDelay01 : VitalDelayType01 := ( 0 ns, 0 ns );
+ CONSTANT VitalZeroDelay01Z : VitalDelayType01Z := ( OTHERS => 0 ns );
+ CONSTANT VitalZeroDelay01ZX : VitalDelayType01ZX := ( OTHERS => 0 ns );
+
+ ---------------------------------------------------------------------------
+ -- examples of usage:
+ ---------------------------------------------------------------------------
+ -- tpd_CLK_Q : VitalDelayType := 5 ns;
+ -- tpd_CLK_Q : VitalDelayType01 := (tr01 => 2 ns, tr10 => 3 ns);
+ -- tpd_CLK_Q : VitalDelayType01Z := ( 1 ns, 2 ns, 3 ns, 4 ns, 5 ns, 6 ns );
+ -- tpd_CLK_Q : VitalDelayArrayType(0 to 1)
+ -- := (0 => 5 ns, 1 => 6 ns);
+ -- tpd_CLK_Q : VitalDelayArrayType01(0 to 1)
+ -- := (0 => (tr01 => 2 ns, tr10 => 3 ns),
+ -- 1 => (tr01 => 2 ns, tr10 => 3 ns));
+ -- tpd_CLK_Q : VitalDelayArrayType01Z(0 to 1)
+ -- := (0 => ( 1 ns, 2 ns, 3 ns, 4 ns, 5 ns, 6 ns ),
+ -- 1 => ( 1 ns, 2 ns, 3 ns, 4 ns, 5 ns, 6 ns ));
+ ---------------------------------------------------------------------------
+
+ -- TRUE if the model is LEVEL0 | LEVEL1 compliant
+ ATTRIBUTE VITAL_Level0 : BOOLEAN;
+ ATTRIBUTE VITAL_Level1 : BOOLEAN;
+
+ SUBTYPE std_logic_vector2 IS std_logic_vector(1 DOWNTO 0);
+ SUBTYPE std_logic_vector3 IS std_logic_vector(2 DOWNTO 0);
+ SUBTYPE std_logic_vector4 IS std_logic_vector(3 DOWNTO 0);
+ SUBTYPE std_logic_vector8 IS std_logic_vector(7 DOWNTO 0);
+
+ -- Types for strength mapping of outputs
+ TYPE VitalOutputMapType IS ARRAY ( std_ulogic ) OF std_ulogic;
+ TYPE VitalResultMapType IS ARRAY ( UX01 ) OF std_ulogic;
+ TYPE VitalResultZMapType IS ARRAY ( UX01Z ) OF std_ulogic;
+ CONSTANT VitalDefaultOutputMap : VitalOutputMapType
+ := "UX01ZWLH-";
+ CONSTANT VitalDefaultResultMap : VitalResultMapType
+ := ( 'U', 'X', '0', '1' );
+ CONSTANT VitalDefaultResultZMap : VitalResultZMapType
+ := ( 'U', 'X', '0', '1', 'Z' );
+
+ -- Types for fields of VitalTimingDataType
+ TYPE VitalTimeArrayT IS ARRAY (INTEGER RANGE <>) OF TIME;
+ TYPE VitalTimeArrayPT IS ACCESS VitalTimeArrayT;
+ TYPE VitalBoolArrayT IS ARRAY (INTEGER RANGE <>) OF BOOLEAN;
+ TYPE VitalBoolArrayPT IS ACCESS VitalBoolArrayT;
+ TYPE VitalLogicArrayPT IS ACCESS std_logic_vector;
+
+ TYPE VitalTimingDataType IS RECORD
+ NotFirstFlag : BOOLEAN;
+ RefLast : X01;
+ RefTime : TIME;
+ HoldEn : BOOLEAN;
+ TestLast : std_ulogic;
+ TestTime : TIME;
+ SetupEn : BOOLEAN;
+ TestLastA : VitalLogicArrayPT;
+ TestTimeA : VitalTimeArrayPT;
+ HoldEnA : VitalBoolArrayPT;
+ SetupEnA : VitalBoolArrayPT;
+ END RECORD;
+
+ FUNCTION VitalTimingDataInit RETURN VitalTimingDataType;
+
+ -- type for internal data of VitalPeriodPulseCheck
+ TYPE VitalPeriodDataType IS RECORD
+ Last : X01;
+ Rise : TIME;
+ Fall : TIME;
+ NotFirstFlag : BOOLEAN;
+ END RECORD;
+ CONSTANT VitalPeriodDataInit : VitalPeriodDataType
+ := ('X', 0 ns, 0 ns, FALSE );
+
+ -- Type for specifying the kind of Glitch handling to use
+ TYPE VitalGlitchKindType IS (OnEvent,
+ OnDetect,
+ VitalInertial,
+ VitalTransport);
+
+ TYPE VitalGlitchDataType IS
+ RECORD
+ SchedTime : TIME;
+ GlitchTime : TIME;
+ SchedValue : std_ulogic;
+ LastValue : std_ulogic;
+ END RECORD;
+ TYPE VitalGlitchDataArrayType IS ARRAY (NATURAL RANGE <>)
+ OF VitalGlitchDataType;
+
+ -- PathTypes: for handling simple PathDelay info
+ TYPE VitalPathType IS RECORD
+ InputChangeTime : TIME; -- timestamp for path input signal
+ PathDelay : VitalDelayType; -- delay for this path
+ PathCondition : BOOLEAN; -- path sensitize condition
+ END RECORD;
+ TYPE VitalPath01Type IS RECORD
+ InputChangeTime : TIME; -- timestamp for path input signal
+ PathDelay : VitalDelayType01; -- delay for this path
+ PathCondition : BOOLEAN; -- path sensitize condition
+ END RECORD;
+ TYPE VitalPath01ZType IS RECORD
+ InputChangeTime : TIME; -- timestamp for path input signal
+ PathDelay : VitalDelayType01Z;-- delay for this path
+ PathCondition : BOOLEAN; -- path sensitize condition
+ END RECORD;
+
+ -- For representing multiple paths to an output
+ TYPE VitalPathArrayType IS ARRAY (NATURAL RANGE <> ) OF VitalPathType;
+ TYPE VitalPathArray01Type IS ARRAY (NATURAL RANGE <> ) OF VitalPath01Type;
+ TYPE VitalPathArray01ZType IS ARRAY (NATURAL RANGE <> ) OF VitalPath01ZType;
+
+ TYPE VitalTableSymbolType IS (
+ '/', -- 0 -> 1
+ '\', -- 1 -> 0
+ 'P', -- Union of '/' and '^' (any edge to 1)
+ 'N', -- Union of '\' and 'v' (any edge to 0)
+ 'r', -- 0 -> X
+ 'f', -- 1 -> X
+ 'p', -- Union of '/' and 'r' (any edge from 0)
+ 'n', -- Union of '\' and 'f' (any edge from 1)
+ 'R', -- Union of '^' and 'p' (any possible rising edge)
+ 'F', -- Union of 'v' and 'n' (any possible falling edge)
+ '^', -- X -> 1
+ 'v', -- X -> 0
+ 'E', -- Union of 'v' and '^' (any edge from X)
+ 'A', -- Union of 'r' and '^' (rising edge to or from 'X')
+ 'D', -- Union of 'f' and 'v' (falling edge to or from 'X')
+ '*', -- Union of 'R' and 'F' (any edge)
+ 'X', -- Unknown level
+ '0', -- low level
+ '1', -- high level
+ '-', -- don't care
+ 'B', -- 0 or 1
+ 'Z', -- High Impedance
+ 'S' -- steady value
+ );
+
+ SUBTYPE VitalEdgeSymbolType IS VitalTableSymbolType RANGE '/' TO '*';
+
+
+
+
+ -- Addition of Vital Skew Type Information
+ -- March 14, 1998
+
+ ---------------------------------------------------------------------------
+ -- Procedures and Type Definitions for Defining Skews
+ ---------------------------------------------------------------------------
+
+ TYPE VitalSkewExpectedType IS (none, s1r, s1f, s2r, s2f);
+
+ TYPE VitalSkewDataType IS RECORD
+ ExpectedType : VitalSkewExpectedType;
+ Signal1Old1 : TIME;
+ Signal2Old1 : TIME;
+ Signal1Old2 : TIME;
+ Signal2Old2 : TIME;
+ END RECORD;
+
+ CONSTANT VitalSkewDataInit : VitalSkewDataType := ( none, 0 ns, 0 ns, 0 ns, 0 ns );
+
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalExtendToFillDelay
+ --
+ -- Description: A six element array of delay values of type
+ -- VitalDelayType01Z is returned when a 1, 2 or 6
+ -- element array is given. This function will convert
+ -- VitalDelayType and VitalDelayType01 delay values into
+ -- a VitalDelayType01Z type following these rules:
+ --
+ -- When a VitalDelayType is passed, all six transition
+ -- values are assigned the input value. When a
+ -- VitalDelayType01 is passed, the 01 transitions are
+ -- assigned to the 01, 0Z and Z1 transitions and the 10
+ -- transitions are assigned to 10, 1Z and Z0 transition
+ -- values. When a VitalDelayType01Z is passed, the values
+ -- are kept as is.
+ --
+ -- The function is overloaded based on input type.
+ --
+ -- There is no function to fill a 12 value delay
+ -- type.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Delay A one, two or six delay value Vital-
+ -- DelayType is passed and a six delay,
+ -- VitalDelayType01Z, item is returned.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- VitalDelayType01Z
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN VitalDelayType01Z;
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN VitalDelayType01Z;
+ FUNCTION VitalExtendToFillDelay (
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN VitalDelayType01Z;
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalCalcDelay
+ --
+ -- Description: This function accepts a 1, 2 or 6 value delay and
+ -- chooses the correct delay time to delay the NewVal
+ -- signal. This function is overloaded based on the
+ -- delay type passed. The function returns a single value
+ -- of time.
+ --
+ -- This function is provided for Level 0 models in order
+ -- to calculate the delay which should be applied
+ -- for the passed signal. The delay selection is performed
+ -- using the OldVal and the NewVal to determine the
+ -- transition to select. The default value of OldVal is X.
+ --
+ -- This function cannot be used in a Level 1 model since
+ -- the VitalPathDelay routines perform the delay path
+ -- selection and output driving function.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- NewVal New value of the signal to be
+ -- assigned
+ -- OldVal Previous value of the signal.
+ -- Default value is 'X'
+ -- Delay The delay structure from which to
+ -- select the appropriate delay. The
+ -- function overload is based on the
+ -- type of delay passed. In the case of
+ -- the single delay, VitalDelayType, no
+ -- selection is performed, since there
+ -- is only one value to choose from.
+ -- For the other cases, the transition
+ -- from the old value to the new value
+ -- decide the value returned.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- none
+ --
+ -- Returns
+ -- Time The time value selected from the
+ -- Delay INPUT is returned.
+ --
+ -- -------------------------------------------------------------------------
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType
+ ) RETURN TIME;
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01
+ ) RETURN TIME;
+ FUNCTION VitalCalcDelay (
+ CONSTANT NewVal : IN std_ulogic := 'X';
+ CONSTANT OldVal : IN std_ulogic := 'X';
+ CONSTANT Delay : IN VitalDelayType01Z
+ ) RETURN TIME;
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalPathDelay
+ --
+ -- Description: VitalPathDelay is the Level 1 routine used to select
+ -- the propagation delay path and schedule a new output
+ -- value.
+ --
+ -- For single and dual delay values, VitalDelayType and
+ -- VitalDelayType01 are used. The output value is
+ -- scheduled with a calculated delay without strength
+ -- modification.
+ --
+ -- For the six delay value, VitalDelayType01Z, the output
+ -- value is scheduled with a calculated delay. The drive
+ -- strength can be modified to handle weak signal strengths
+ -- to model tri-state devices, pull-ups and pull-downs as
+ -- an example.
+ --
+ -- The correspondence between the delay type and the
+ -- path delay function is as follows:
+ --
+ -- Delay Type Path Type
+ --
+ -- VitalDelayType VitalPathDelay
+ -- VitalDelayType01 VitalPathDelay01
+ -- VitalDelayType01Z VitalPathDelay01Z
+ --
+ -- For each of these routines, the following capabilities
+ -- is provided:
+ --
+ -- o Transition dependent path delay selection
+ -- o User controlled glitch detection with the ability
+ -- to generate "X" on output and report the violation
+ -- o Control of the severity level for message generation
+ -- o Scheduling of the computed values on the specified
+ -- signal.
+ --
+ -- Selection of the appropriate path delay begins with the
+ -- candidate paths. The candidate paths are selected by
+ -- identifying the paths for which the PathCondition is
+ -- true. If there is a single candidate path, then that
+ -- delay is selected. If there is more than one candidate
+ -- path, then the shortest delay is selected using
+ -- transition dependent delay selection. If there is no
+ -- candidate paths, then the delay specified by the
+ -- DefaultDelay parameter to the path delay is used.
+ --
+ -- Once the delay is known, the output signal is then
+ -- scheduled with that delay. In the case of
+ -- VitalPathDelay01Z, an additional result mapping of
+ -- the output value is performed before scheduling. The
+ -- result mapping is performed after transition dependent
+ -- delay selection but before scheduling the final output.
+ --
+ -- In order to perform glitch detection, the user is
+ -- obligated to provide a variable of VitalGlitchDataType
+ -- for the propagation delay functions to use. The user
+ -- cannot modify or use this information.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- OutSignalName string The name of the output signal
+ -- OutTemp std_logic The new output value to be driven
+ -- Paths VitalPathArrayType A list of paths of VitalPathArray
+ -- VitalPathArrayType01 type. The VitalPathDelay routine
+ -- VitalPathArrayType01Z is overloaded based on the type
+ -- of constant passed in. With
+ -- VitalPathArrayType01Z, the
+ -- resulting output strengths can be
+ -- mapped.
+ -- DefaultDelay VitalDelayType The default delay can be changed
+ -- VitalDelayType01 from zero-delay to another set
+ -- VitalDelayType01Z of values.
+ --
+ -- IgnoreDefaultDelay BOOLEAN If TRUE, the default delay will
+ -- be used when no paths are
+ -- selected. If false, no event
+ -- will be scheduled if no paths are
+ -- selected.
+ --
+ -- Mode VitalGlitchKindType The value of this constant
+ -- selects the type of glitch
+ -- detection.
+ -- OnEvent Glitch on transition event
+ -- | OnDetect Glitch immediate on detection
+ -- | VitalInertial No glitch, use INERTIAL
+ -- assignment
+ -- | VitalTransport No glitch, use TRANSPORT
+ -- assignment
+ -- XOn BOOLEAN Control for generation of 'X' on
+ -- glitch. When TRUE, 'X's are
+ -- scheduled for glitches, otherwise
+ -- no are generated.
+ -- MsgOn BOOLEAN Control for message generation on
+ -- glitch detect. When TRUE,
+ -- glitches are reported, otherwise
+ -- they are not reported.
+ -- MsgSeverity SEVERITY_LEVEL The level at which the message,
+ -- or assertion, will be reported.
+ -- IgnoreDefaultDelay BOOLEAN Tells the VPD whether to use the
+ -- default delay value in the absense
+ -- of a valid delay for input conditions 3/14/98 MG
+ --
+ -- OutputMap VitalOutputMapType For VitalPathDelay01Z, the output
+ -- can be mapped to alternate
+ -- strengths to model tri-state
+ -- devices, pull-ups and pull-downs.
+ --
+ -- INOUT
+ -- GlitchData VitalGlitchDataType The internal data storage
+ -- variable required to detect
+ -- glitches.
+ --
+ -- OUT
+ -- OutSignal std_logic The output signal to be driven
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalPathDelay (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArrayType;
+ CONSTANT DefaultDelay : IN VitalDelayType := VitalZeroDelay;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE --IR248 3/14/98
+ );
+ PROCEDURE VitalPathDelay01 (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01Type;
+ CONSTANT DefaultDelay : IN VitalDelayType01 := VitalZeroDelay01;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98
+ CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250
+ );
+ PROCEDURE VitalPathDelay01Z (
+ SIGNAL OutSignal : OUT std_logic;
+ VARIABLE GlitchData : INOUT VitalGlitchDataType;
+ CONSTANT OutSignalName : IN string;
+ CONSTANT OutTemp : IN std_logic;
+ CONSTANT Paths : IN VitalPathArray01ZType;
+ CONSTANT DefaultDelay : IN VitalDelayType01Z := VitalZeroDelay01Z;
+ CONSTANT Mode : IN VitalGlitchKindType := OnEvent;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT OutputMap : IN VitalOutputMapType := VitalDefaultOutputMap;
+ CONSTANT NegPreemptOn : IN BOOLEAN := FALSE; --IR225 3/14/98
+ CONSTANT IgnoreDefaultDelay : IN BOOLEAN := FALSE; --IR248 3/14/98
+ CONSTANT RejectFastPath : IN BOOLEAN := FALSE --IR250
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalWireDelay
+ --
+ -- Description: VitalWireDelay is used to delay an input signal.
+ -- The delay is selected from the input parameter passed.
+ -- The function is useful for back annotation of actual
+ -- net delays.
+ --
+ -- The function is overloaded to permit passing a delay
+ -- value for twire for VitalDelayType, VitalDelayType01
+ -- and VitalDelayType01Z. twire is a generic which can
+ -- be back annotated and must be constructed to follow
+ -- the SDF to generic mapping rules.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- InSig std_ulogic The input signal (port) to be
+ -- delayed.
+ -- twire VitalDelayType The delay value for which the input
+ -- VitalDelayType01 signal should be delayed. For Vital-
+ -- VitalDelayType01Z DelayType, the value is single value
+ -- passed. For VitalDelayType01 and
+ -- VitalDelayType01Z, the appropriate
+ -- delay value is selected by VitalCalc-
+ -- Delay.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- OutSig std_ulogic The internal delayed signal
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType
+ );
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01
+ );
+
+ PROCEDURE VitalWireDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT twire : IN VitalDelayType01Z
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalSignalDelay
+ --
+ -- Description: The VitalSignalDelay procedure is called in a signal
+ -- delay block in the architecture to delay the
+ -- appropriate test or reference signal in order to
+ -- accommodate negative constraint checks.
+ --
+ -- The amount of delay is of type TIME and is a constant.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- InSig std_ulogic The signal to be delayed.
+ -- dly TIME The amount of time the signal is
+ -- delayed.
+ --
+ -- INOUT
+ -- none
+ --
+ -- OUT
+ -- OutSig std_ulogic The delayed signal
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalSignalDelay (
+ SIGNAL OutSig : OUT std_ulogic;
+ SIGNAL InSig : IN std_ulogic;
+ CONSTANT dly : IN TIME
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalSetupHoldCheck
+ --
+ -- Description: The VitalSetupHoldCheck procedure detects a setup or a
+ -- hold violation on the input test signal with respect
+ -- to the corresponding input reference signal. The timing
+ -- constraints are specified through parameters
+ -- representing the high and low values for the setup and
+ -- hold values for the setup and hold times. This
+ -- procedure assumes non-negative values for setup and hold
+ -- timing constraints.
+ --
+ -- It is assumed that negative timing constraints
+ -- are handled by internally delaying the test or
+ -- reference signals. Negative setup times result in
+ -- a delayed reference signal. Negative hold times
+ -- result in a delayed test signal. Furthermore, the
+ -- delays and constraints associated with these and
+ -- other signals may need to be appropriately
+ -- adjusted so that all constraint intervals overlap
+ -- the delayed reference signals and all constraint
+ -- values (with respect to the delayed signals) are
+ -- non-negative.
+ --
+ -- This function is overloaded based on the input
+ -- TestSignal. A vector and scalar form are provided.
+ --
+ -- TestSignal XXXXXXXXXXXX____________________________XXXXXXXXXXXXXXXXXXXXXX
+ -- :
+ -- : -->| error region |<--
+ -- :
+ -- _______________________________
+ -- RefSignal \______________________________
+ -- : | | |
+ -- : | -->| |<-- thold
+ -- : -->| tsetup |<--
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- TestSignal std_ulogic Value of test signal
+ -- std_logic_vector
+ -- TestSignalName STRING Name of test signal
+ -- TestDelay TIME Model's internal delay associated
+ -- with TestSignal
+ -- RefSignal std_ulogic Value of reference signal
+ -- RefSignalName STRING Name of reference signal
+ -- RefDelay TIME Model's internal delay associated
+ -- with RefSignal
+ -- SetupHigh TIME Absolute minimum time duration before
+ -- the transition of RefSignal for which
+ -- transitions of TestSignal are allowed
+ -- to proceed to the "1" state without
+ -- causing a setup violation.
+ -- SetupLow TIME Absolute minimum time duration before
+ -- the transition of RefSignal for which
+ -- transitions of TestSignal are allowed
+ -- to proceed to the "0" state without
+ -- causing a setup violation.
+ -- HoldHigh TIME Absolute minimum time duration after
+ -- the transition of RefSignal for which
+ -- transitions of TestSignal are allowed
+ -- to proceed to the "1" state without
+ -- causing a hold violation.
+ -- HoldLow TIME Absolute minimum time duration after
+ -- the transition of RefSignal for which
+ -- transitions of TestSignal are allowed
+ -- to proceed to the "0" state without
+ -- causing a hold violation.
+ -- CheckEnabled BOOLEAN Check performed if TRUE.
+ -- RefTransition VitalEdgeSymbolType
+ -- Reference edge specified. Events on
+ -- the RefSignal which match the edge
+ -- spec. are used as reference edges.
+ -- HeaderMsg STRING String that will accompany any
+ -- assertion messages produced.
+ -- XOn BOOLEAN If TRUE, Violation output parameter
+ -- is set to "X". Otherwise, Violation
+ -- is always set to "0".
+ -- MsgOn BOOLEAN If TRUE, set and hold violation
+ -- message will be generated.
+ -- Otherwise, no messages are generated,
+ -- even upon violations.
+ -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+ -- EnableSetupOnTest BOOLEAN If FALSE at the time that the
+ -- TestSignal signal changes,
+ -- no setup check will be performed.
+ -- EnableSetupOnRef BOOLEAN If FALSE at the time that the
+ -- RefSignal signal changes,
+ -- no setup check will be performed.
+ -- EnableHoldOnRef BOOLEAN If FALSE at the time that the
+ -- RefSignal signal changes,
+ -- no hold check will be performed.
+ -- EnableHoldOnTest BOOLEAN If FALSE at the time that the
+ -- TestSignal signal changes,
+ -- no hold check will be performed.
+ --
+ -- INOUT
+ -- TimingData VitalTimingDataType
+ -- VitalSetupHoldCheck information
+ -- storage area. This is used
+ -- internally to detect reference edges
+ -- and record the time of the last edge.
+ --
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+ );
+
+ PROCEDURE VitalSetupHoldCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_logic_vector;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT SetupHigh : IN TIME := 0 ns;
+ CONSTANT SetupLow : IN TIME := 0 ns;
+ CONSTANT HoldHigh : IN TIME := 0 ns;
+ CONSTANT HoldLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableSetupOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableSetupOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableHoldOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+ );
+
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalRecoveryRemovalCheck
+ --
+ -- Description: The VitalRecoveryRemovalCheck detects the presence of
+ -- a recovery or removal violation on the input test
+ -- signal with respect to the corresponding input reference
+ -- signal. It assumes non-negative values of setup and
+ -- hold timing constraints. The timing constraint is
+ -- specified through parameters representing the recovery
+ -- and removal times associated with a reference edge of
+ -- the reference signal. A flag indicates whether a test
+ -- signal is asserted when it is high or when it is low.
+ --
+ -- It is assumed that negative timing constraints
+ -- are handled by internally delaying the test or
+ -- reference signals. Negative recovery times result in
+ -- a delayed reference signal. Negative removal times
+ -- result in a delayed test signal. Furthermore, the
+ -- delays and constraints associated with these and
+ -- other signals may need to be appropriately
+ -- adjusted so that all constraint intervals overlap
+ -- the delayed reference signals and all constraint
+ -- values (with respect to the delayed signals) are
+ -- non-negative.
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- TestSignal std_ulogic Value of TestSignal. The routine is
+ -- TestSignalName STRING Name of TestSignal
+ -- TestDelay TIME Model internal delay associated with
+ -- the TestSignal
+ -- RefSignal std_ulogic Value of RefSignal
+ -- RefSignalName STRING Name of RefSignal
+ -- RefDelay TIME Model internal delay associated with
+ -- the RefSignal
+ -- Recovery TIME A change to an unasserted value on
+ -- the asynchronous TestSignal must
+ -- precede reference edge (on RefSignal)
+ -- by at least this time.
+ -- Removal TIME An asserted condition must be present
+ -- on the asynchronous TestSignal for at
+ -- least the removal time following a
+ -- reference edge on RefSignal.
+ -- ActiveLow BOOLEAN A flag which indicates if TestSignal
+ -- is asserted when it is low - "0."
+ -- FALSE indicate that TestSignal is
+ -- asserted when it has a value "1."
+ -- CheckEnabled BOOLEAN The check in enabled when the value
+ -- is TRUE, otherwise the constraints
+ -- are not checked.
+ -- RefTransition VitalEdgeSymbolType
+ -- Reference edge specifier. Events on
+ -- RefSignal will match the edge
+ -- specified.
+ -- HeaderMsg STRING A header message that will accompany
+ -- any assertion message.
+ -- XOn BOOLEAN When TRUE, the output Violation is
+ -- set to "X." When FALSE, it is always
+ -- "0."
+ -- MsgOn BOOLEAN When TRUE, violation messages are
+ -- output. When FALSE, no messages are
+ -- generated.
+ -- MsgSeverity SEVERITY_LEVEL Severity level of the asserted
+ -- message.
+ -- EnableRecOnTest BOOLEAN If FALSE at the time that the
+ -- TestSignal signal changes,
+ -- no recovery check will be performed.
+ -- EnableRecOnRef BOOLEAN If FALSE at the time that the
+ -- RefSignal signal changes,
+ -- no recovery check will be performed.
+ -- EnableRemOnRef BOOLEAN If FALSE at the time that the
+ -- RefSignal signal changes,
+ -- no removal check will be performed.
+ -- EnableRemOnTest BOOLEAN If FALSE at the time that the
+ -- TestSignal signal changes,
+ -- no removal check will be performed.
+ --
+ -- INOUT
+ -- TimingData VitalTimingDataType
+ -- VitalRecoveryRemovalCheck information
+ -- storage area. This is used
+ -- internally to detect reference edges
+ -- and record the time of the last edge.
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalRecoveryRemovalCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE TimingData : INOUT VitalTimingDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName: IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ SIGNAL RefSignal : IN std_ulogic;
+ CONSTANT RefSignalName : IN STRING := "";
+ CONSTANT RefDelay : IN TIME := 0 ns;
+ CONSTANT Recovery : IN TIME := 0 ns;
+ CONSTANT Removal : IN TIME := 0 ns;
+ CONSTANT ActiveLow : IN BOOLEAN := TRUE;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT RefTransition : IN VitalEdgeSymbolType;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT EnableRecOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRecOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRemOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98
+ CONSTANT EnableRemOnTest : IN BOOLEAN := TRUE --IR252 3/23/98
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalPeriodPulseCheck
+ --
+ -- Description: VitalPeriodPulseCheck checks for minimum
+ -- periodicity and pulse width for "1" and "0" values of
+ -- the input test signal. The timing constraint is
+ -- specified through parameters representing the minimal
+ -- period between successive rising and falling edges of
+ -- the input test signal and the minimum pulse widths
+ -- associated with high and low values.
+ --
+ -- VitalPeriodCheck's accepts rising and falling edges
+ -- from 1 and 0 as well as transitions to and from 'X.'
+ --
+ -- _______________ __________
+ -- ____________| |_______|
+ --
+ -- |<--- pw_hi --->|
+ -- |<-------- period ----->|
+ -- -->| pw_lo |<--
+ --
+ -- Arguments:
+ -- IN Type Description
+ -- TestSignal std_ulogic Value of test signal
+ -- TestSignalName STRING Name of the test signal
+ -- TestDelay TIME Model's internal delay associated
+ -- with TestSignal
+ -- Period TIME Minimum period allowed between
+ -- consecutive rising ('P') or
+ -- falling ('F') transitions.
+ -- PulseWidthHigh TIME Minimum time allowed for a high
+ -- pulse ('1' or 'H')
+ -- PulseWidthLow TIME Minimum time allowed for a low
+ -- pulse ('0' or 'L')
+ -- CheckEnabled BOOLEAN Check performed if TRUE.
+ -- HeaderMsg STRING String that will accompany any
+ -- assertion messages produced.
+ -- XOn BOOLEAN If TRUE, Violation output parameter
+ -- is set to "X". Otherwise, Violation
+ -- is always set to "0".
+ -- XOnChecks is a global that allows for
+ -- only timing checks to be turned on.
+ -- MsgOn BOOLEAN If TRUE, period/pulse violation
+ -- message will be generated.
+ -- Otherwise, no messages are generated,
+ -- even though a violation is detected.
+ -- MsgOnChecks allows for only timing
+ -- check messages to be turned on.
+ -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+ --
+ -- INOUT
+ -- PeriodData VitalPeriodDataType
+ -- VitalPeriodPulseCheck information
+ -- storage area. This is used
+ -- internally to detect reference edges
+ -- and record the pulse and period
+ -- times.
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- ------------------------------------------------------------------------
+ PROCEDURE VitalPeriodPulseCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE PeriodData : INOUT VitalPeriodDataType;
+ SIGNAL TestSignal : IN std_ulogic;
+ CONSTANT TestSignalName : IN STRING := "";
+ CONSTANT TestDelay : IN TIME := 0 ns;
+ CONSTANT Period : IN TIME := 0 ns;
+ CONSTANT PulseWidthHigh : IN TIME := 0 ns;
+ CONSTANT PulseWidthLow : IN TIME := 0 ns;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT HeaderMsg : IN STRING := " ";
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING
+ );
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalInPhaseSkewCheck
+ --
+ -- Description: The VitalInPhaseSkewCheck procedure detects an in-phase
+ -- skew violation between input signals Signal1 and Signal2.
+ -- This is a timer based skew check in which a
+ -- violation is detected if Signal1 and Signal2 are in
+ -- different logic states longer than the specified skew
+ -- interval.
+ --
+ -- The timing constraints are specified through parameters
+ -- representing the skew values for the different states
+ -- of Signal1 and Signal2.
+ --
+ --
+ -- Signal2 XXXXXXXXXXXX___________________________XXXXXXXXXXXXXXXXXXXXXX
+ -- :
+ -- : -->| |<--
+ -- : Signal2 should go low in this region
+ -- :
+ --
+ -- ____________
+ -- Signal1 \_________________________________________________
+ -- : | |
+ -- : |<-------- tskew -------->|
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Signal1 std_ulogic Value of first signal
+ -- Signal1Name STRING Name of first signal
+ -- Signal1Delay TIME Model's internal delay associated
+ -- with Signal1
+ -- Signal2 std_ulogic Value of second signal
+ -- Signal2Name STRING Name of second signal
+ -- Signal2Delay TIME Model's internal delay associated
+ -- with Signal2
+ -- SkewS1S2RiseRise TIME Absolute maximum time duration for
+ -- which Signal2 can remain at "0"
+ -- after Signal1 goes to the "1" state,
+ -- without causing a skew violation.
+ -- SkewS2S1RiseRise TIME Absolute maximum time duration for
+ -- which Signal1 can remain at "0"
+ -- after Signal2 goes to the "1" state,
+ -- without causing a skew violation.
+ -- SkewS1S2FallFall TIME Absolute maximum time duration for
+ -- which Signal2 can remain at "1"
+ -- after Signal1 goes to the "0" state,
+ -- without causing a skew violation.
+ -- SkewS2S1FallFall TIME Absolute maximum time duration for
+ -- which Signal1 can remain at "1"
+ -- after Signal2 goes to the "0" state,
+ -- without causing a skew violation.
+ -- CheckEnabled BOOLEAN Check performed if TRUE.
+ -- HeaderMsg STRING String that will accompany any
+ -- assertion messages produced.
+ -- XOn BOOLEAN If TRUE, Violation output parameter
+ -- is set to "X". Otherwise, Violation
+ -- is always set to "0."
+ -- MsgOn BOOLEAN If TRUE, skew timing violation
+ -- messages will be generated.
+ -- Otherwise, no messages are generated,
+ -- even upon violations.
+ -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+ --
+ -- INOUT
+ -- SkewData VitalSkewDataType
+ -- VitalInPhaseSkewCheck information
+ -- storage area. This is used
+ -- internally to detect signal edges
+ -- and record the time of the last edge.
+ --
+ --
+ -- Trigger std_ulogic This signal is used to trigger the
+ -- process in which the timing check
+ -- occurs upon expiry of the skew
+ -- interval.
+ --
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+
+ PROCEDURE VitalInPhaseSkewCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE SkewData : INOUT VitalSkewDataType;
+ SIGNAL Signal1 : IN std_ulogic;
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal1Delay : IN TIME := 0 ns;
+ SIGNAL Signal2 : IN std_ulogic;
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT Signal2Delay : IN TIME := 0 ns;
+ CONSTANT SkewS1S2RiseRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1RiseRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS1S2FallFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1FallFall : IN TIME := TIME'HIGH;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT HeaderMsg : IN STRING := "";
+ SIGNAL Trigger : INOUT std_ulogic
+ );
+
+
+ -- ------------------------------------------------------------------------
+ --
+ -- Function Name: VitalOutPhaseSkewCheck
+ --
+ -- Description: The VitalOutPhaseSkewCheck procedure detects an
+ -- out-of-phase skew violation between input signals Signal1
+ -- and Signal2. This is a timer based skew check in
+ -- which a violation is detected if Signal1 and Signal2 are
+ -- in the same logic state longer than the specified skew
+ -- interval.
+ --
+ -- The timing constraints are specified through parameters
+ -- representing the skew values for the different states
+ -- of Signal1 and Signal2.
+ --
+ --
+ -- Signal2 XXXXXXXXXXXX___________________________XXXXXXXXXXXXXXXXXXXXXX
+ -- :
+ -- : -->| |<--
+ -- : Signal2 should go high in this region
+ -- :
+ --
+ -- ____________
+ -- Signal1 \_________________________________________________
+ -- : | |
+ -- : |<-------- tskew -------->|
+ --
+ -- Arguments:
+ --
+ -- IN Type Description
+ -- Signal1 std_ulogic Value of first signal
+ -- Signal1Name STRING Name of first signal
+ -- Signal1Delay TIME Model's internal delay associated
+ -- with Signal1
+ -- Signal2 std_ulogic Value of second signal
+ -- Signal2Name STRING Name of second signal
+ -- Signal2Delay TIME Model's internal delay associated
+ -- with Signal2
+ -- SkewS1S2RiseFall TIME Absolute maximum time duration for
+ -- which Signal2 can remain at "1"
+ -- after Signal1 goes to the "1" state,
+ -- without causing a skew violation.
+ -- SkewS2S1RiseFall TIME Absolute maximum time duration for
+ -- which Signal1 can remain at "1"
+ -- after Signal2 goes to the "1" state,
+ -- without causing a skew violation.
+ -- SkewS1S2FallRise TIME Absolute maximum time duration for
+ -- which Signal2 can remain at "0"
+ -- after Signal1 goes to the "0" state,
+ -- without causing a skew violation.
+ -- SkewS2S1FallRise TIME Absolute maximum time duration for
+ -- which Signal1 can remain at "0"
+ -- after Signal2 goes to the "0" state,
+ -- without causing a skew violation.
+ -- CheckEnabled BOOLEAN Check performed if TRUE.
+ -- HeaderMsg STRING String that will accompany any
+ -- assertion messages produced.
+ -- XOn BOOLEAN If TRUE, Violation output parameter
+ -- is set to "X". Otherwise, Violation
+ -- is always set to "0."
+ -- MsgOn BOOLEAN If TRUE, skew timing violation
+ -- messages will be generated.
+ -- Otherwise, no messages are generated,
+ -- even upon violations.
+ -- MsgSeverity SEVERITY_LEVEL Severity level for the assertion.
+ --
+ -- INOUT
+ -- SkewData VitalSkewDataType
+ -- VitalInPhaseSkewCheck information
+ -- storage area. This is used
+ -- internally to detect signal edges
+ -- and record the time of the last edge.
+ --
+ -- Trigger std_ulogic This signal is used to trigger the
+ -- process in which the timing check
+ -- occurs upon expiry of the skew
+ -- interval.
+ --
+ -- OUT
+ -- Violation X01 This is the violation flag returned.
+ --
+ -- Returns
+ -- none
+ --
+ -- -------------------------------------------------------------------------
+ PROCEDURE VitalOutPhaseSkewCheck (
+ VARIABLE Violation : OUT X01;
+ VARIABLE SkewData : INOUT VitalSkewDataType;
+ SIGNAL Signal1 : IN std_ulogic;
+ CONSTANT Signal1Name : IN STRING := "";
+ CONSTANT Signal1Delay : IN TIME := 0 ns;
+ SIGNAL Signal2 : IN std_ulogic;
+ CONSTANT Signal2Name : IN STRING := "";
+ CONSTANT Signal2Delay : IN TIME := 0 ns;
+ CONSTANT SkewS1S2RiseFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1RiseFall : IN TIME := TIME'HIGH;
+ CONSTANT SkewS1S2FallRise : IN TIME := TIME'HIGH;
+ CONSTANT SkewS2S1FallRise : IN TIME := TIME'HIGH;
+ CONSTANT CheckEnabled : IN BOOLEAN := TRUE;
+ CONSTANT XOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgOn : IN BOOLEAN := TRUE;
+ CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING;
+ CONSTANT HeaderMsg : IN STRING := "";
+ SIGNAL Trigger : INOUT std_ulogic
+ );
+
+
+END VITAL_Timing;