aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/vital2000/memory_b.vhdl
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/vital2000/memory_b.vhdl')
-rw-r--r--libraries/vital2000/memory_b.vhdl7151
1 files changed, 7151 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 ;