aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/gna/issue317/OSVVM
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2017-05-18 08:01:02 +0200
committerTristan Gingold <tgingold@free.fr>2017-05-18 08:01:02 +0200
commitcff9d9a80bc14e81684fd5e02a361c171737022d (patch)
treecc40a1f680ae5a8ecd1db3e6f27c6a0cbfb30741 /testsuite/gna/issue317/OSVVM
parent2e3634206b04775398f712a4da735d70a32020f2 (diff)
downloadghdl-cff9d9a80bc14e81684fd5e02a361c171737022d.tar.gz
ghdl-cff9d9a80bc14e81684fd5e02a361c171737022d.tar.bz2
ghdl-cff9d9a80bc14e81684fd5e02a361c171737022d.zip
Add testcase for #317
Diffstat (limited to 'testsuite/gna/issue317/OSVVM')
-rw-r--r--testsuite/gna/issue317/OSVVM/AlertLogPkg.vhd2732
-rw-r--r--testsuite/gna/issue317/OSVVM/NamePkg.vhd129
-rw-r--r--testsuite/gna/issue317/OSVVM/OsvvmGlobalPkg.vhd350
-rw-r--r--testsuite/gna/issue317/OSVVM/RandomBasePkg.vhd234
-rw-r--r--testsuite/gna/issue317/OSVVM/RandomPkg.vhd1647
-rw-r--r--testsuite/gna/issue317/OSVVM/ScoreboardGenericPkg.vhd1573
-rw-r--r--testsuite/gna/issue317/OSVVM/SortListPkg_int.vhd417
-rw-r--r--testsuite/gna/issue317/OSVVM/TextUtilPkg.vhd407
-rw-r--r--testsuite/gna/issue317/OSVVM/TranscriptPkg.vhd200
9 files changed, 7689 insertions, 0 deletions
diff --git a/testsuite/gna/issue317/OSVVM/AlertLogPkg.vhd b/testsuite/gna/issue317/OSVVM/AlertLogPkg.vhd
new file mode 100644
index 000000000..0e3e15124
--- /dev/null
+++ b/testsuite/gna/issue317/OSVVM/AlertLogPkg.vhd
@@ -0,0 +1,2732 @@
+--
+-- File Name: AlertLogPkg.vhd
+-- Design Unit Name: AlertLogPkg
+-- Revision: STANDARD VERSION
+--
+-- Maintainer: Jim Lewis email: jim@synthworks.com
+-- Contributor(s):
+-- Jim Lewis jim@synthworks.com
+--
+--
+-- Description:
+-- Alert handling and log filtering (verbosity control)
+-- Alert handling provides a method to count failures, errors, and warnings
+-- To accumlate counts, a data structure is created in a shared variable
+-- It is of type AlertLogStructPType which is defined in AlertLogBasePkg
+-- Log filtering provides verbosity control for logs (display or do not display)
+-- AlertLogPkg provides a simplified interface to the shared variable
+--
+--
+-- Developed for:
+-- SynthWorks Design Inc.
+-- VHDL Training Classes
+-- 11898 SW 128th Ave. Tigard, Or 97223
+-- http://www.SynthWorks.com
+--
+-- Revision History:
+-- Date Version Description
+-- 01/2015: 2015.01 Initial revision
+-- 03/2015 2015.03 Added: AlertIfEqual, AlertIfNotEqual, AlertIfDiff, PathTail,
+-- ReportNonZeroAlerts, ReadLogEnables
+-- 05/2015 2015.06 Added IncAlertCount, AffirmIf
+-- 07/2015 2016.01 Fixed AlertLogID issue with > 32 IDs
+-- 02/2016 2016.02 Fixed IsLogEnableType (for PASSED), AffirmIf (to pass AlertLevel)
+-- Created LocalInitialize
+--
+-- Copyright (c) 2015 - 2016 by SynthWorks Design Inc. All rights reserved.
+--
+-- Verbatim copies of this source file may be used and
+-- distributed without restriction.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the ARTISTIC License
+-- as published by The Perl Foundation; either version 2.0 of
+-- the License, or (at your option) any later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the Artistic License for details.
+--
+-- You should have received a copy of the license with this source.
+-- If not download it from,
+-- http://www.perlfoundation.org/artistic_license_2_0
+--
+
+
+use std.textio.all ;
+use work.OsvvmGlobalPkg.all ;
+use work.TranscriptPkg.all ;
+use work.TextUtilPkg.all ;
+
+library IEEE ;
+use ieee.std_logic_1164.all ;
+use ieee.numeric_std.all ;
+
+package AlertLogPkg is
+
+ subtype AlertLogIDType is integer ;
+ type AlertType is (FAILURE, ERROR, WARNING) ; -- NEVER
+ subtype AlertIndexType is AlertType range FAILURE to WARNING ;
+ type AlertCountType is array (AlertIndexType) of integer ;
+ type AlertEnableType is array(AlertIndexType) of boolean ;
+ type LogType is (ALWAYS, DEBUG, FINAL, INFO, PASSED) ; -- NEVER -- See function IsLogEnableType
+ subtype LogIndexType is LogType range DEBUG to PASSED ;
+ type LogEnableType is array (LogIndexType) of boolean ;
+
+ constant ALERTLOG_BASE_ID : AlertLogIDType := 0 ; -- Careful as some code may assume this is 0.
+ constant ALERTLOG_DEFAULT_ID : AlertLogIDType := 1 ;
+ constant ALERT_DEFAULT_ID : AlertLogIDType := ALERTLOG_DEFAULT_ID ;
+ constant LOG_DEFAULT_ID : AlertLogIDType := ALERTLOG_DEFAULT_ID ;
+ constant OSVVM_ALERTLOG_ID : AlertLogIDType := 2 ;
+ constant OSVVM_SCOREBOARD_ALERTLOG_ID : AlertLogIDType := OSVVM_ALERTLOG_ID ;
+ -- NUM_PREDEFINED_AL_IDS intended to be local, but depends on others
+ -- constant NUM_PREDEFINED_AL_IDS : AlertLogIDType := OSVVM_SCOREBOARD_ALERTLOG_ID - ALERTLOG_BASE_ID ; -- Not including base
+ constant ALERTLOG_ID_NOT_FOUND : AlertLogIDType := -1 ; -- alternately integer'right
+ constant ALERTLOG_ID_NOT_ASSIGNED : AlertLogIDType := -1 ;
+ constant MIN_NUM_AL_IDS : AlertLogIDType := 32 ; -- Number IDs initially allocated
+
+ alias AlertLogOptionsType is work.OsvvmGlobalPkg.OsvvmOptionsType ;
+
+ ------------------------------------------------------------
+ -- Alert always goes to the transcript file
+ procedure Alert(
+ AlertLogID : AlertLogIDType ;
+ Message : string ;
+ Level : AlertType := ERROR
+ ) ;
+ procedure Alert( Message : string ; Level : AlertType := ERROR ) ;
+
+ ------------------------------------------------------------
+ procedure IncAlertCount( -- A silent form of alert
+ AlertLogID : AlertLogIDType ;
+ Level : AlertType := ERROR
+ ) ;
+ procedure IncAlertCount( Level : AlertType := ERROR ) ;
+
+ ------------------------------------------------------------
+ -- Similar to assert, except condition is positive
+ procedure AlertIf( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIf( condition : boolean ; Message : string ; Level : AlertType := ERROR ) ;
+ impure function AlertIf( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Level : AlertType := ERROR ) return boolean ;
+ impure function AlertIf( condition : boolean ; Message : string ; Level : AlertType := ERROR ) return boolean ;
+
+ -- deprecated
+ procedure AlertIf( condition : boolean ; AlertLogID : AlertLogIDType ; Message : string ; Level : AlertType := ERROR ) ;
+ impure function AlertIf( condition : boolean ; AlertLogID : AlertLogIDType ; Message : string ; Level : AlertType := ERROR ) return boolean ;
+
+ ------------------------------------------------------------
+ -- Direct replacement for assert
+ procedure AlertIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNot( condition : boolean ; Message : string ; Level : AlertType := ERROR ) ;
+ impure function AlertIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Level : AlertType := ERROR ) return boolean ;
+ impure function AlertIfNot( condition : boolean ; Message : string ; Level : AlertType := ERROR ) return boolean ;
+
+ -- deprecated
+ procedure AlertIfNot( condition : boolean ; AlertLogID : AlertLogIDType ; Message : string ; Level : AlertType := ERROR ) ;
+ impure function AlertIfNot( condition : boolean ; AlertLogID : AlertLogIDType ; Message : string ; Level : AlertType := ERROR ) return boolean ;
+
+ ------------------------------------------------------------
+ -- overloading for common functionality
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : std_logic ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : std_logic_vector ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : unsigned ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : signed ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : integer ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : real ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : character ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : string ; Message : string ; Level : AlertType := ERROR ) ;
+
+ procedure AlertIfEqual( L, R : std_logic ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( L, R : std_logic_vector ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( L, R : unsigned ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( L, R : signed ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( L, R : integer ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( L, R : real ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( L, R : character ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfEqual( L, R : string ; Message : string ; Level : AlertType := ERROR ) ;
+
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : std_logic ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : std_logic_vector ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : unsigned ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : signed ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : integer ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : real ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : character ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : string ; Message : string ; Level : AlertType := ERROR ) ;
+
+ procedure AlertIfNotEqual( L, R : std_logic ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( L, R : std_logic_vector ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( L, R : unsigned ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( L, R : signed ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( L, R : integer ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( L, R : real ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( L, R : character ; Message : string ; Level : AlertType := ERROR ) ;
+ procedure AlertIfNotEqual( L, R : string ; Message : string ; Level : AlertType := ERROR ) ;
+ ------------------------------------------------------------
+ -- Simple Diff for file comparisons
+ procedure AlertIfDiff (AlertLogID : AlertLogIDType ; Name1, Name2 : string; Message : string := "" ; Level : AlertType := ERROR ) ;
+ procedure AlertIfDiff (Name1, Name2 : string; Message : string := "" ; Level : AlertType := ERROR ) ;
+ procedure AlertIfDiff (AlertLogID : AlertLogIDType ; file File1, File2 : text; Message : string := "" ; Level : AlertType := ERROR ) ;
+ procedure AlertIfDiff (file File1, File2 : text; Message : string := "" ; Level : AlertType := ERROR ) ;
+ ------------------------------------------------------------
+ procedure AffirmIf(
+ AlertLogID : AlertLogIDType ;
+ condition : boolean ;
+ Message : string ;
+ LogLevel : LogType := PASSED ;
+ AlertLevel : AlertType := ERROR
+ ) ;
+ procedure AffirmIf(condition : boolean ; Message : string ; LogLevel : LogType := PASSED ; AlertLevel : AlertType := ERROR) ;
+
+ ------------------------------------------------------------
+ procedure SetAlertLogJustify ;
+ procedure ReportAlerts ( Name : String ; AlertCount : AlertCountType ) ;
+ procedure ReportAlerts ( Name : string := OSVVM_STRING_INIT_PARM_DETECT ; AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; ExternalErrors : AlertCountType := (others => 0) ) ;
+ procedure ReportNonZeroAlerts ( Name : string := OSVVM_STRING_INIT_PARM_DETECT ; AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; ExternalErrors : AlertCountType := (others => 0) ) ;
+ procedure ClearAlerts ;
+ function "ABS" (L : AlertCountType) return AlertCountType ;
+ function "+" (L, R : AlertCountType) return AlertCountType ;
+ function "-" (L, R : AlertCountType) return AlertCountType ;
+ function "-" (R : AlertCountType) return AlertCountType ;
+ impure function SumAlertCount(AlertCount: AlertCountType) return integer ;
+ impure function GetAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return AlertCountType ;
+ impure function GetAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return integer ;
+ impure function GetEnabledAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return AlertCountType ;
+ impure function GetEnabledAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return integer ;
+ impure function GetDisabledAlertCount return AlertCountType ;
+ impure function GetDisabledAlertCount return integer ;
+ impure function GetDisabledAlertCount(AlertLogID: AlertLogIDType) return AlertCountType ;
+ impure function GetDisabledAlertCount(AlertLogID: AlertLogIDType) return integer ;
+
+ ------------------------------------------------------------
+ -- log filtering for verbosity control, optionally has a separate file parameter
+ procedure Log(
+ AlertLogID : AlertLogIDType ;
+ Message : string ;
+ Level : LogType := ALWAYS ;
+ Enable : boolean := FALSE -- override internal enable
+ ) ;
+ procedure Log( Message : string ; Level : LogType := ALWAYS ; Enable : boolean := FALSE) ;
+
+
+ ------------------------------------------------------------
+ -- Accessor Methods
+ procedure SetAlertLogName(Name : string ) ;
+ impure function GetAlertLogName(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return string ;
+ procedure DeallocateAlertLogStruct ;
+ procedure InitializeAlertLogStruct ;
+ impure function FindAlertLogID(Name : string ) return AlertLogIDType ;
+ impure function FindAlertLogID(Name : string ; ParentID : AlertLogIDType) return AlertLogIDType ;
+ impure function GetAlertLogID(Name : string ; ParentID : AlertLogIDType := ALERTLOG_BASE_ID ; CreateHierarchy : Boolean := TRUE) return AlertLogIDType ;
+ impure function GetAlertLogParentID(AlertLogID : AlertLogIDType) return AlertLogIDType ;
+
+ ------------------------------------------------------------
+ -- Accessor Methods
+ procedure SetGlobalAlertEnable (A : boolean := TRUE) ;
+ impure function SetGlobalAlertEnable (A : boolean := TRUE) return boolean ;
+ impure function GetGlobalAlertEnable return boolean ;
+ procedure IncAffirmCheckCount ;
+ impure function GetAffirmCheckCount return natural ;
+--?? procedure IncAffirmPassCount ;
+--?? impure function GetAffirmPassCount return natural ;
+
+ procedure SetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType ; Count : integer) ;
+ procedure SetAlertStopCount(Level : AlertType ; Count : integer) ;
+ impure function GetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType) return integer ;
+ impure function GetAlertStopCount(Level : AlertType) return integer ;
+
+ procedure SetAlertEnable(Level : AlertType ; Enable : boolean) ;
+ procedure SetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) ;
+ impure function GetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType) return boolean ;
+ impure function GetAlertEnable(Level : AlertType) return boolean ;
+
+ procedure SetLogEnable(Level : LogType ; Enable : boolean) ;
+ procedure SetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) ;
+ impure function GetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType) return boolean ;
+ impure function GetLogEnable(Level : LogType) return boolean ;
+ impure function IsLoggingEnabled(AlertLogID : AlertLogIDType ; Level : LogType) return boolean ; -- same as GetLogEnable
+ impure function IsLoggingEnabled(Level : LogType) return boolean ;
+
+ procedure ReportLogEnables ;
+
+ ------------------------------------------------------------
+ procedure SetAlertLogOptions (
+ FailOnWarning : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ FailOnDisabledErrors : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ ReportHierarchy : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAlertLevel : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAlertName : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAlertTime : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteLogLevel : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteLogName : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteLogTime : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ AlertPrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ LogPrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ ReportPrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ DoneName : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ PassName : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ FailName : string := OSVVM_STRING_INIT_PARM_DETECT
+ ) ;
+
+ procedure ReportAlertLogOptions ;
+
+ impure function GetAlertLogFailOnWarning return AlertLogOptionsType ;
+ impure function GetAlertLogFailOnDisabledErrors return AlertLogOptionsType ;
+ impure function GetAlertLogReportHierarchy return AlertLogOptionsType ;
+ impure function GetAlertLogFoundReportHier return boolean ;
+ impure function GetAlertLogFoundAlertHier return boolean ;
+ impure function GetAlertLogWriteAlertLevel return AlertLogOptionsType ;
+ impure function GetAlertLogWriteAlertName return AlertLogOptionsType ;
+ impure function GetAlertLogWriteAlertTime return AlertLogOptionsType ;
+ impure function GetAlertLogWriteLogLevel return AlertLogOptionsType ;
+ impure function GetAlertLogWriteLogName return AlertLogOptionsType ;
+ impure function GetAlertLogWriteLogTime return AlertLogOptionsType ;
+
+ impure function GetAlertLogAlertPrefix return string ;
+ impure function GetAlertLogLogPrefix return string ;
+
+ impure function GetAlertLogReportPrefix return string ;
+ impure function GetAlertLogDoneName return string ;
+ impure function GetAlertLogPassName return string ;
+ impure function GetAlertLogFailName return string ;
+
+
+ -- File Reading Utilities
+ function IsLogEnableType (Name : String) return boolean ;
+ procedure ReadLogEnables (file AlertLogInitFile : text) ;
+ procedure ReadLogEnables (FileName : string) ;
+
+ -- String Helper Functions -- This should be in a more general string package
+ function PathTail (A : string) return string ;
+
+end AlertLogPkg ;
+
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+
+use work.NamePkg.all ;
+
+package body AlertLogPkg is
+
+ -- instead of justify(to_upper(to_string())), just look up the upper case, left justified values
+ type AlertNameType is array(AlertType) of string(1 to 7) ;
+ constant ALERT_NAME : AlertNameType := (WARNING => "WARNING", ERROR => "ERROR ", FAILURE => "FAILURE") ; -- , NEVER => "NEVER "
+ type LogNameType is array(LogType) of string(1 to 7) ;
+ constant LOG_NAME : LogNameType := (DEBUG => "DEBUG ", FINAL => "FINAL ", INFO => "INFO ", ALWAYS => "ALWAYS ", PASSED => "PASSED ") ; -- , NEVER => "NEVER "
+
+
+ type AlertLogStructPType is protected
+
+ ------------------------------------------------------------
+ procedure alert (
+ ------------------------------------------------------------
+ AlertLogID : AlertLogIDType ;
+ message : string ;
+ level : AlertType := ERROR
+ ) ;
+
+ ------------------------------------------------------------
+ procedure IncAlertCount ( AlertLogID : AlertLogIDType ; level : AlertType := ERROR ) ;
+ procedure SetJustify ;
+ procedure ReportAlerts ( Name : string ; AlertCount : AlertCountType ) ;
+ procedure ReportAlerts ( Name : string := OSVVM_STRING_INIT_PARM_DETECT ; AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; ExternalErrors : AlertCountType := (0,0,0) ; ReportAll : boolean := TRUE ) ;
+ procedure ClearAlerts ;
+ impure function GetAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return AlertCountType ;
+ impure function GetEnabledAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return AlertCountType ;
+ impure function GetDisabledAlertCount return AlertCountType ;
+ impure function GetDisabledAlertCount(AlertLogID: AlertLogIDType) return AlertCountType ;
+
+ ------------------------------------------------------------
+ procedure log (
+ ------------------------------------------------------------
+ AlertLogID : AlertLogIDType ;
+ Message : string ;
+ Level : LogType := ALWAYS ;
+ Enable : boolean := FALSE -- override internal enable
+ ) ;
+
+ ------------------------------------------------------------
+ -- FILE IO Controls
+-- procedure SetTranscriptEnable (A : boolean := TRUE) ;
+-- impure function IsTranscriptEnabled return boolean ;
+-- procedure MirrorTranscript (A : boolean := TRUE) ;
+-- impure function IsTranscriptMirrored return boolean ;
+
+ ------------------------------------------------------------
+ ------------------------------------------------------------
+ -- AlertLog Structure Creation and Interaction Methods
+
+ ------------------------------------------------------------
+ procedure SetAlertLogName(Name : string ) ;
+ procedure SetNumAlertLogIDs (NewNumAlertLogIDs : integer) ;
+ impure function FindAlertLogID(Name : string ) return AlertLogIDType ;
+ impure function FindAlertLogID(Name : string ; ParentID : AlertLogIDType) return AlertLogIDType ;
+ impure function GetAlertLogID(Name : string ; ParentID : AlertLogIDType ; CreateHierarchy : Boolean) return AlertLogIDType ;
+ impure function GetAlertLogParentID(AlertLogID : AlertLogIDType) return AlertLogIDType ;
+ procedure Initialize(NewNumAlertLogIDs : integer := MIN_NUM_AL_IDS) ;
+ procedure Deallocate ;
+
+ ------------------------------------------------------------
+ ------------------------------------------------------------
+ -- Accessor Methods
+ ------------------------------------------------------------
+ procedure SetGlobalAlertEnable (A : boolean := TRUE) ;
+ impure function GetAlertLogName(AlertLogID : AlertLogIDType) return string ;
+ impure function GetGlobalAlertEnable return boolean ;
+ procedure IncAffirmCheckCount ;
+ impure function GetAffirmCheckCount return natural ;
+--?? procedure IncAffirmPassCount ;
+--?? impure function GetAffirmPassCount return natural ;
+
+ procedure SetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType ; Count : integer) ;
+ impure function GetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType) return integer ;
+
+ procedure SetAlertEnable(Level : AlertType ; Enable : boolean) ;
+ procedure SetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) ;
+ impure function GetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType) return boolean ;
+
+ procedure SetLogEnable(Level : LogType ; Enable : boolean) ;
+ procedure SetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) ;
+ impure function GetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType) return boolean ;
+
+ procedure ReportLogEnables ;
+
+ ------------------------------------------------------------
+ -- Reporting Accessor
+ procedure SetAlertLogOptions (
+ FailOnWarning : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ FailOnDisabledErrors : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ ReportHierarchy : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAlertLevel : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAlertName : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAlertTime : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteLogLevel : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteLogName : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteLogTime : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ AlertPrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ LogPrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ ReportPrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ DoneName : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ PassName : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ FailName : string := OSVVM_STRING_INIT_PARM_DETECT
+ ) ;
+ procedure ReportAlertLogOptions ;
+
+ impure function GetAlertLogFailOnWarning return AlertLogOptionsType ;
+ impure function GetAlertLogFailOnDisabledErrors return AlertLogOptionsType ;
+ impure function GetAlertLogReportHierarchy return AlertLogOptionsType ;
+ impure function GetAlertLogFoundReportHier return boolean ;
+ impure function GetAlertLogFoundAlertHier return boolean ;
+ impure function GetAlertLogWriteAlertLevel return AlertLogOptionsType ;
+ impure function GetAlertLogWriteAlertName return AlertLogOptionsType ;
+ impure function GetAlertLogWriteAlertTime return AlertLogOptionsType ;
+ impure function GetAlertLogWriteLogLevel return AlertLogOptionsType ;
+ impure function GetAlertLogWriteLogName return AlertLogOptionsType ;
+ impure function GetAlertLogWriteLogTime return AlertLogOptionsType ;
+
+ impure function GetAlertLogAlertPrefix return string ;
+ impure function GetAlertLogLogPrefix return string ;
+
+ impure function GetAlertLogReportPrefix return string ;
+ impure function GetAlertLogDoneName return string ;
+ impure function GetAlertLogPassName return string ;
+ impure function GetAlertLogFailName return string ;
+
+ end protected AlertLogStructPType ;
+
+ --- ///////////////////////////////////////////////////////////////////////////
+
+ type AlertLogStructPType is protected body
+
+ variable GlobalAlertEnabledVar : boolean := TRUE ; -- Allows turn off and on
+
+ variable AffirmCheckCountVar : natural := 0 ;
+--?? variable AffirmPassedCountVar : natural := 0 ;
+
+ ------------------------------------------------------------
+ type AlertLogRecType is record
+ ------------------------------------------------------------
+ Name : Line ;
+ ParentID : AlertLogIDType ;
+ AlertCount : AlertCountType ;
+ AlertStopCount : AlertCountType ;
+ AlertEnabled : AlertEnableType ;
+ LogEnabled : LogEnableType ;
+ end record AlertLogRecType ;
+
+ ------------------------------------------------------------
+ -- Basis for AlertLog Data Structure
+ variable NumAlertLogIDsVar : AlertLogIDType := 0 ; -- defined by initialize
+ variable NumAllocatedAlertLogIDsVar : AlertLogIDType := 0 ;
+--xx variable NumPredefinedAlIDsVar : AlertLogIDType := 0 ; -- defined by initialize
+
+ type AlertLogRecPtrType is access AlertLogRecType ;
+ type AlertLogArrayType is array (AlertLogIDType range <>) of AlertLogRecPtrType ;
+ type AlertLogArrayPtrType is access AlertLogArrayType ;
+ variable AlertLogPtr : AlertLogArrayPtrType ;
+
+ ------------------------------------------------------------
+ -- Report formatting settings, with defaults
+ variable FailOnWarningVar : boolean := TRUE ;
+ variable FailOnDisabledErrorsVar : boolean := TRUE ;
+ variable ReportHierarchyVar : boolean := TRUE ;
+ variable FoundReportHierVar : boolean := FALSE ;
+ variable FoundAlertHierVar : boolean := FALSE ;
+
+ variable WriteAlertLevelVar : boolean := TRUE ;
+ variable WriteAlertNameVar : boolean := TRUE ;
+ variable WriteAlertTimeVar : boolean := TRUE ;
+ variable WriteLogLevelVar : boolean := TRUE ;
+ variable WriteLogNameVar : boolean := TRUE ;
+ variable WriteLogTimeVar : boolean := TRUE ;
+
+ variable AlertPrefixVar : NamePType ;
+ variable LogPrefixVar : NamePType ;
+ variable ReportPrefixVar : NamePType ;
+ variable DoneNameVar : NamePType ;
+ variable PassNameVar : NamePType ;
+ variable FailNameVar : NamePType ;
+
+ variable AlertLogJustifyAmountVar : integer := 0 ;
+ variable ReportJustifyAmountVar : integer := 0 ;
+
+ ------------------------------------------------------------
+ -- PT Local
+ impure function LeftJustify(A : String; Amount : integer) return string is
+ ------------------------------------------------------------
+ constant Spaces : string(1 to maximum(1, Amount)) := (others => ' ') ;
+ begin
+ if A'length >= Amount then
+ return A ;
+ else
+ return A & Spaces(1 to Amount - A'length) ;
+ end if ;
+ end function LeftJustify ;
+
+
+ ------------------------------------------------------------
+ -- PT Local
+ procedure IncrementAlertCount(
+ ------------------------------------------------------------
+ constant AlertLogID : in AlertLogIDType ;
+ constant Level : in AlertType ;
+ variable StopDueToCount : inout boolean
+ ) is
+ begin
+ -- Always Count at this level
+ AlertLogPtr(AlertLogID).AlertCount(Level) := AlertLogPtr(AlertLogID).AlertCount(Level) + 1 ;
+ -- Only do remaining actions if enabled
+ if AlertLogPtr(AlertLogID).AlertEnabled(Level) then
+ -- Exceeded Stop Count at this level?
+ if AlertLogPtr(AlertLogID).AlertCount(Level) >= AlertLogPtr(AlertLogID).AlertStopCount(Level) then
+ StopDueToCount := TRUE ;
+ end if ;
+ -- Propagate counts to parent(s) -- Ascend Hierarchy
+ if AlertLogID /= ALERTLOG_BASE_ID then
+ IncrementAlertCount(AlertLogPtr(AlertLogID).ParentID, Level, StopDueToCount) ;
+ end if ;
+ end if ;
+ end procedure IncrementAlertCount ;
+
+ ------------------------------------------------------------
+ procedure alert (
+ ------------------------------------------------------------
+ AlertLogID : AlertLogIDType ;
+ message : string ;
+ level : AlertType := ERROR
+ ) is
+ variable buf : Line ;
+ constant AlertPrefix : string := AlertPrefixVar.Get(OSVVM_DEFAULT_ALERT_PREFIX) ;
+ variable StopDueToCount : boolean := FALSE ;
+ begin
+ if GlobalAlertEnabledVar then
+ -- Do not write or count when GlobalAlertEnabledVar is disabled
+ if AlertLogPtr(AlertLogID).AlertEnabled(Level) then
+ -- do not write when disabled
+ write(buf, AlertPrefix) ;
+ if WriteAlertLevelVar then
+ -- write(buf, " " & to_string(Level) ) ;
+ write(buf, " " & ALERT_NAME(Level)) ; -- uses constant lookup
+ end if ;
+--xx if (NumAlertLogIDsVar > NumPredefinedAlIDsVar) and WriteAlertNameVar then -- print hierarchy names even when silent
+ if FoundAlertHierVar and WriteAlertNameVar then
+-- write(buf, " in " & justify(AlertLogPtr(AlertLogID).Name.all & ",", LEFT, AlertLogJustifyAmountVar) ) ;
+ write(buf, " in " & LeftJustify(AlertLogPtr(AlertLogID).Name.all & ",", AlertLogJustifyAmountVar) ) ;
+ end if ;
+ write(buf, " " & Message) ;
+ if WriteAlertTimeVar then
+ write(buf, " at " & to_string(NOW, 1 ns)) ;
+ end if ;
+ writeline(buf) ;
+ end if ;
+ -- Always Count
+ IncrementAlertCount(AlertLogID, Level, StopDueToCount) ;
+ if StopDueToCount then
+ write(buf, LF & AlertPrefix & " Stop Count on " & ALERT_NAME(Level) & " reached") ;
+--xx if NumAlertLogIDsVar > NumPredefinedAlIDsVar then -- print hierarchy names even when silent
+ if FoundAlertHierVar then
+ write(buf, " in " & AlertLogPtr(AlertLogID).Name.all) ;
+ end if ;
+ write(buf, " at " & to_string(NOW, 1 ns) & " ") ;
+ writeline(buf) ;
+ ReportAlerts(ReportAll => TRUE) ;
+ std.env.stop(1) ;
+ end if ;
+ end if ;
+ end procedure alert ;
+
+ ------------------------------------------------------------
+ procedure IncAlertCount (
+ ------------------------------------------------------------
+ AlertLogID : AlertLogIDType ;
+ level : AlertType := ERROR
+ ) is
+ variable buf : Line ;
+ constant AlertPrefix : string := AlertPrefixVar.Get(OSVVM_DEFAULT_ALERT_PREFIX) ;
+ variable StopDueToCount : boolean := FALSE ;
+ begin
+ if GlobalAlertEnabledVar then
+ IncrementAlertCount(AlertLogID, Level, StopDueToCount) ;
+ if StopDueToCount then
+ write(buf, LF & AlertPrefix & " Stop Count on " & ALERT_NAME(Level) & " reached") ;
+--xx if NumAlertLogIDsVar > NumPredefinedAlIDsVar then -- print hierarchy names even when silent
+ if FoundAlertHierVar then
+ write(buf, " in " & AlertLogPtr(AlertLogID).Name.all) ;
+ end if ;
+ write(buf, " at " & to_string(NOW, 1 ns) & " ") ;
+ writeline(buf) ;
+ ReportAlerts(ReportAll => TRUE) ;
+ std.env.stop ;
+ end if ;
+ end if ;
+ end procedure IncAlertCount ;
+
+ ------------------------------------------------------------
+ -- PT Local
+ impure function CalcJustify (AlertLogID : AlertLogIDType ; CurrentLength : integer ; IndentAmount : integer) return integer_vector is
+ ------------------------------------------------------------
+ variable ResultValues, LowerLevelValues : integer_vector(1 to 2) ; -- 1 = Max, 2 = Indented
+ begin
+ ResultValues(1) := CurrentLength + 1 ; -- AlertLogJustifyAmountVar
+ ResultValues(2) := CurrentLength + IndentAmount ; -- ReportJustifyAmountVar
+ for i in AlertLogID+1 to NumAlertLogIDsVar loop
+ if AlertLogID = AlertLogPtr(i).ParentID then
+ LowerLevelValues := CalcJustify(i, AlertLogPtr(i).Name'length, IndentAmount + 2) ;
+ ResultValues(1) := maximum(ResultValues(1), LowerLevelValues(1)) ;
+ ResultValues(2) := maximum(ResultValues(2), LowerLevelValues(2)) ;
+ end if ;
+ end loop ;
+ return ResultValues ;
+ end function CalcJustify ;
+
+ ------------------------------------------------------------
+ procedure SetJustify is
+ ------------------------------------------------------------
+ variable ResultValues : integer_vector(1 to 2) ; -- 1 = Max, 2 = Indented
+ begin
+ ResultValues := CalcJustify(ALERTLOG_BASE_ID, 0, 0) ;
+ AlertLogJustifyAmountVar := ResultValues(1) ;
+ ReportJustifyAmountVar := ResultValues(2) ;
+ end procedure SetJustify ;
+
+ ------------------------------------------------------------
+ -- PT Local
+ impure function GetEnabledAlertCount(AlertCount: AlertCountType; AlertEnabled : AlertEnableType) return AlertCountType is
+ ------------------------------------------------------------
+ variable Count : AlertCountType := (others => 0) ;
+ begin
+ if AlertEnabled(FAILURE) then
+ Count(FAILURE) := AlertCount(FAILURE) ;
+ end if ;
+ if AlertEnabled(ERROR) then
+ Count(ERROR) := AlertCount(ERROR) ;
+ end if ;
+ if FailOnWarningVar and AlertEnabled(WARNING) then
+ Count(WARNING) := AlertCount(WARNING) ;
+ end if ;
+ return Count ;
+ end function GetEnabledAlertCount ;
+
+ ------------------------------------------------------------
+ impure function GetAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return AlertCountType is
+ ------------------------------------------------------------
+ variable AlertCount : AlertCountType ;
+ begin
+ return AlertLogPtr(AlertLogID).AlertCount ;
+ end function GetAlertCount ;
+
+ ------------------------------------------------------------
+ impure function GetEnabledAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return AlertCountType is
+ ------------------------------------------------------------
+ variable AlertCount : AlertCountType ;
+ begin
+ return GetEnabledAlertCount(AlertLogPtr(AlertLogID).AlertCount, AlertLogPtr(AlertLogID).AlertEnabled) ;
+ end function GetEnabledAlertCount ;
+
+ ------------------------------------------------------------
+ -- PT Local
+ impure function GetDisabledAlertCount(AlertCount: AlertCountType; AlertEnabled : AlertEnableType) return AlertCountType is
+ ------------------------------------------------------------
+ variable Count : AlertCountType := (others => 0) ;
+ begin
+ if not AlertEnabled(FAILURE) then
+ Count(FAILURE) := AlertCount(FAILURE) ;
+ end if ;
+ if not AlertEnabled(ERROR) then
+ Count(ERROR) := AlertCount(ERROR) ;
+ end if ;
+ if FailOnWarningVar and not AlertEnabled(WARNING) then
+ Count(WARNING) := AlertCount(WARNING) ;
+ end if ;
+ return Count ;
+ end function GetDisabledAlertCount ;
+
+ ------------------------------------------------------------
+ impure function GetDisabledAlertCount return AlertCountType is
+ ------------------------------------------------------------
+ variable Count : AlertCountType := (others => 0) ;
+ begin
+ for i in ALERTLOG_BASE_ID to NumAlertLogIDsVar loop
+ Count := Count + GetDisabledAlertCount(AlertLogPtr(i).AlertCount, AlertLogPtr(i).AlertEnabled) ;
+ end loop ;
+ return Count ;
+ end function GetDisabledAlertCount ;
+
+ ------------------------------------------------------------
+ impure function GetDisabledAlertCount(AlertLogID: AlertLogIDType) return AlertCountType is
+ ------------------------------------------------------------
+ variable Count : AlertCountType := (others => 0) ;
+ begin
+ Count := GetDisabledAlertCount(AlertLogPtr(AlertLogID).AlertCount, AlertLogPtr(AlertLogID).AlertEnabled) ;
+ for i in AlertLogID+1 to NumAlertLogIDsVar loop
+ if AlertLogID = AlertLogPtr(i).ParentID then
+ Count := Count + GetDisabledAlertCount(i) ;
+ end if ;
+ end loop ;
+ return Count ;
+ end function GetDisabledAlertCount ;
+
+ ------------------------------------------------------------
+ -- PT Local
+ procedure PrintTopAlerts (
+ ------------------------------------------------------------
+ NumErrors : integer ;
+ AlertCount : AlertCountType ;
+ Name : string ;
+ NumDisabledErrors : integer
+ ) is
+ constant ReportPrefix : string := ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt ) ;
+ constant DoneName : string := ResolveOsvvmDoneName(DoneNameVar.GetOpt ) ;
+ constant PassName : string := ResolveOsvvmPassName(PassNameVar.GetOpt ) ;
+ constant FailName : string := ResolveOsvvmFailName(FailNameVar.GetOpt ) ;
+ variable buf : line ;
+ begin
+ if NumErrors = 0 then
+ if NumDisabledErrors = 0 then
+ -- Passed
+ write(buf, ReportPrefix & DoneName & " " & PassName & " " & Name) ;
+ if AffirmCheckCountVar > 0 then
+ write(buf, " Affirmations Checked: " & to_string(AffirmCheckCountVar)) ;
+ end if ;
+ write(buf, " at " & to_string(NOW, 1 ns)) ;
+ WriteLine(buf) ;
+ else
+ -- Failed Due to Disabled Errors
+ write(buf, ReportPrefix & DoneName & " " & FailName & " " & Name) ;
+ write(buf, " Failed Due to Disabled Error(s) = " & to_string(NumDisabledErrors)) ;
+ if AffirmCheckCountVar > 0 then
+ write(buf, " Affirmations Checked: " & to_string(AffirmCheckCountVar)) ;
+ end if ;
+ write(buf, " at " & to_string(NOW, 1 ns)) ;
+ WriteLine(buf) ;
+ end if ;
+ else
+ -- Failed
+ write(buf, ReportPrefix & DoneName & " " & FailName & " "& Name) ;
+ write(buf, " Total Error(s) = " & to_string(NumErrors) ) ;
+ write(buf, " Failures: " & to_string(AlertCount(FAILURE)) ) ;
+ write(buf, " Errors: " & to_string(AlertCount(ERROR) ) ) ;
+ write(buf, " Warnings: " & to_string(AlertCount(WARNING) ) ) ;
+ if AffirmCheckCountVar > 0 then
+--?? write(buf, " Affirmations Passed: " & to_string(AffirmPassedCountVar)) ;
+--?? write(buf, " Checked: " & to_string(AffirmCheckCountVar)) ;
+ write(buf, " Affirmations Checked: " & to_string(AffirmCheckCountVar)) ;
+ end if ;
+ Write(buf, " at " & to_string(NOW, 1 ns)) ;
+ WriteLine(buf) ;
+ end if ;
+ end procedure PrintTopAlerts ;
+
+ ------------------------------------------------------------
+ -- PT Local
+ procedure PrintChild(
+ ------------------------------------------------------------
+ AlertLogID : AlertLogIDType ;
+ Prefix : string ;
+ IndentAmount : integer ;
+ ReportAll : boolean
+ ) is
+ variable buf : line ;
+ begin
+ for i in AlertLogID+1 to NumAlertLogIDsVar loop
+ if AlertLogID = AlertLogPtr(i).ParentID then
+ if ReportAll or SumAlertCount(AlertLogPtr(i).AlertCount) > 0 then
+ Write(buf, Prefix & " " & LeftJustify(AlertLogPtr(i).Name.all, ReportJustifyAmountVar - IndentAmount)) ;
+ write(buf, " Failures: " & to_string(AlertLogPtr(i).AlertCount(FAILURE) ) ) ;
+ write(buf, " Errors: " & to_string(AlertLogPtr(i).AlertCount(ERROR) ) ) ;
+ write(buf, " Warnings: " & to_string(AlertLogPtr(i).AlertCount(WARNING) ) ) ;
+ WriteLine(buf) ;
+ end if ;
+ PrintChild(
+ AlertLogID => i,
+ Prefix => Prefix & " ",
+ IndentAmount => IndentAmount + 2,
+ ReportAll => ReportAll
+ ) ;
+ end if ;
+ end loop ;
+ end procedure PrintChild ;
+
+ ------------------------------------------------------------
+ procedure ReportAlerts ( Name : string := OSVVM_STRING_INIT_PARM_DETECT ; AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; ExternalErrors : AlertCountType := (0,0,0) ; ReportAll : boolean := TRUE) is
+ ------------------------------------------------------------
+ variable NumErrors : integer ;
+ variable NumDisabledErrors : integer ;
+ constant ReportPrefix : string := ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt) ;
+ begin
+ if ReportJustifyAmountVar <= 0 then
+ SetJustify ;
+ end if ;
+ NumErrors := SumAlertCount( ExternalErrors + GetEnabledAlertCount(AlertLogPtr(AlertLogID).AlertCount, AlertLogPtr(AlertLogID).AlertEnabled) ) ;
+ if FailOnDisabledErrorsVar then
+ NumDisabledErrors := SumAlertCount( GetDisabledAlertCount(AlertLogID) ) ;
+ else
+ NumDisabledErrors := 0 ;
+ end if ;
+ if IsOsvvmStringSet(Name) then
+ PrintTopAlerts (
+ NumErrors => NumErrors,
+ AlertCount => AlertLogPtr(AlertLogID).AlertCount + ExternalErrors,
+ Name => Name,
+ NumDisabledErrors => NumDisabledErrors
+ ) ;
+ else
+ PrintTopAlerts (
+ NumErrors => NumErrors,
+ AlertCount => AlertLogPtr(AlertLogID).AlertCount + ExternalErrors,
+ Name => AlertLogPtr(AlertLogID).Name.all,
+ NumDisabledErrors => NumDisabledErrors
+ ) ;
+ end if ;
+ --Print Hierarchy when enabled and error or disabled error
+ if (FoundReportHierVar and ReportHierarchyVar) and (NumErrors /= 0 or NumDisabledErrors /=0) then
+ PrintChild(
+ AlertLogID => AlertLogID,
+ Prefix => ReportPrefix & " ",
+ IndentAmount => 2,
+ ReportAll => ReportAll
+ ) ;
+ end if ;
+ end procedure ReportAlerts ;
+
+ ------------------------------------------------------------
+ procedure ReportAlerts ( Name : string ; AlertCount : AlertCountType ) is
+ ------------------------------------------------------------
+ begin
+ PrintTopAlerts (
+ NumErrors => SumAlertCount(AlertCount),
+ AlertCount => AlertCount,
+ Name => Name,
+ NumDisabledErrors => 0
+ ) ;
+ end procedure ReportAlerts ;
+
+ ------------------------------------------------------------
+ procedure ClearAlerts is
+ ------------------------------------------------------------
+ begin
+ AffirmCheckCountVar := 0 ;
+--?? AffirmPassedCountVar := 0 ;
+
+ AlertLogPtr(ALERTLOG_BASE_ID).AlertCount := (0, 0, 0) ;
+ AlertLogPtr(ALERTLOG_BASE_ID).AlertStopCount := (FAILURE => 0, ERROR => integer'right, WARNING => integer'right) ;
+
+ for i in ALERTLOG_BASE_ID + 1 to NumAlertLogIDsVar loop
+ AlertLogPtr(i).AlertCount := (0, 0, 0) ;
+ AlertLogPtr(i).AlertStopCount := (FAILURE => integer'right, ERROR => integer'right, WARNING => integer'right) ;
+ end loop ;
+ end procedure ClearAlerts ;
+
+ ------------------------------------------------------------
+ -- PT Local
+ procedure LocalLog (
+ ------------------------------------------------------------
+ AlertLogID : AlertLogIDType ;
+ Message : string ;
+ Level : LogType
+ ) is
+ variable buf : line ;
+ constant LogPrefix : string := LogPrefixVar.Get(OSVVM_DEFAULT_LOG_PREFIX) ;
+ begin
+ write(buf, LogPrefix) ;
+ if WriteLogLevelVar then
+ write(buf, " " & LOG_NAME(Level) ) ;
+ end if ;
+--xx if (NumAlertLogIDsVar > NumPredefinedAlIDsVar) and WriteLogNameVar then -- print hierarchy names even when silent
+ if FoundAlertHierVar and WriteLogNameVar then
+-- write(buf, " in " & justify(AlertLogPtr(AlertLogID).Name.all & ",", LEFT, AlertLogJustifyAmountVar) ) ;
+ write(buf, " in " & LeftJustify(AlertLogPtr(AlertLogID).Name.all & ",", AlertLogJustifyAmountVar) ) ;
+ end if ;
+ write(buf, " " & Message) ;
+ if WriteLogTimeVar then
+ write(buf, " at " & to_string(NOW, 1 ns)) ;
+ end if ;
+ writeline(buf) ;
+ end procedure LocalLog ;
+
+ ------------------------------------------------------------
+ procedure log (
+ ------------------------------------------------------------
+ AlertLogID : AlertLogIDType ;
+ Message : string ;
+ Level : LogType := ALWAYS ;
+ Enable : boolean := FALSE -- override internal enable
+ ) is
+ begin
+ if Level = ALWAYS or Enable then
+ LocalLog(AlertLogID, Message, Level) ;
+ elsif AlertLogPtr(AlertLogID).LogEnabled(Level) then
+ LocalLog(AlertLogID, Message, Level) ;
+ end if ;
+ end procedure log ;
+
+ ------------------------------------------------------------
+ ------------------------------------------------------------
+ -- AlertLog Structure Creation and Interaction Methods
+
+ ------------------------------------------------------------
+ procedure SetAlertLogName(Name : string ) is
+ ------------------------------------------------------------
+ begin
+ Deallocate(AlertLogPtr(ALERTLOG_BASE_ID).Name) ;
+ AlertLogPtr(ALERTLOG_BASE_ID).Name := new string'(Name) ;
+ end procedure SetAlertLogName ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogName(AlertLogID : AlertLogIDType) return string is
+ ------------------------------------------------------------
+ begin
+ return AlertLogPtr(AlertLogID).Name.all ;
+ end function GetAlertLogName ;
+
+ ------------------------------------------------------------
+ -- PT Local
+ procedure NewAlertLogRec(AlertLogID : AlertLogIDType ; Name : string ; ParentID : AlertLogIDType) is
+ ------------------------------------------------------------
+ variable AlertEnabled : AlertEnableType ;
+ variable AlertStopCount : AlertCountType ;
+ variable LogEnabled : LogEnableType ;
+ begin
+ if AlertLogID = ALERTLOG_BASE_ID then
+ AlertEnabled := (TRUE, TRUE, TRUE) ;
+ LogEnabled := (others => FALSE) ;
+ AlertStopCount := (FAILURE => 0, ERROR => integer'right, WARNING => integer'right) ;
+ else
+ if ParentID < ALERTLOG_BASE_ID then
+ AlertEnabled := AlertLogPtr(ALERTLOG_BASE_ID).AlertEnabled ;
+ LogEnabled := AlertLogPtr(ALERTLOG_BASE_ID).LogEnabled ;
+ else
+ AlertEnabled := AlertLogPtr(ParentID).AlertEnabled ;
+ LogEnabled := AlertLogPtr(ParentID).LogEnabled ;
+ end if ;
+ AlertStopCount := (FAILURE => integer'right, ERROR => integer'right, WARNING => integer'right) ;
+ end if ;
+ AlertLogPtr(AlertLogID) := new AlertLogRecType ;
+ AlertLogPtr(AlertLogID).Name := new string'(NAME) ;
+ AlertLogPtr(AlertLogID).ParentID := ParentID ;
+ AlertLogPtr(AlertLogID).AlertCount := (0, 0, 0) ;
+ AlertLogPtr(AlertLogID).AlertEnabled := AlertEnabled ;
+ AlertLogPtr(AlertLogID).AlertStopCount := AlertStopCount ;
+ AlertLogPtr(AlertLogID).LogEnabled := LogEnabled ;
+-- AlertLogPtr(AlertLogID) := new AlertLogRecType'(
+-- Name => new string'(NAME),
+-- ParentID => ParentID,
+-- AlertCount => (0, 0, 0),
+-- AlertEnabled => AlertEnabled,
+-- AlertStopCount => AlertStopCount,
+-- LogEnabled => LogEnabled
+-- ) ;
+ end procedure NewAlertLogRec ;
+
+ ------------------------------------------------------------
+ -- PT Local
+ -- Construct initial data structure
+ procedure LocalInitialize(NewNumAlertLogIDs : integer := MIN_NUM_AL_IDS) is
+ ------------------------------------------------------------
+ begin
+ if NumAllocatedAlertLogIDsVar /= 0 then
+ Alert(ALERT_DEFAULT_ID, "AlertLogPkg: Initialize, data structure already initialized", FAILURE) ;
+ return ;
+ end if ;
+ -- Initialize Pointer
+ AlertLogPtr := new AlertLogArrayType(ALERTLOG_BASE_ID to ALERTLOG_BASE_ID + NewNumAlertLogIDs) ;
+ NumAllocatedAlertLogIDsVar := NewNumAlertLogIDs ;
+ -- Create BASE AlertLogID (if it differs from DEFAULT
+ if ALERTLOG_BASE_ID /= ALERT_DEFAULT_ID then
+ NewAlertLogRec(ALERTLOG_BASE_ID, "AlertLogTop", ALERTLOG_BASE_ID) ;
+ end if ;
+ -- Create DEFAULT AlertLogID
+ NewAlertLogRec(ALERT_DEFAULT_ID, "Default", ALERTLOG_BASE_ID) ;
+ NumAlertLogIDsVar := ALERT_DEFAULT_ID ;
+ -- Create OSVVM AlertLogID (if it differs from DEFAULT
+ if OSVVM_ALERTLOG_ID /= ALERT_DEFAULT_ID then
+ NewAlertLogRec(OSVVM_ALERTLOG_ID, "OSVVM", ALERTLOG_BASE_ID) ;
+ NumAlertLogIDsVar := NumAlertLogIDsVar + 1 ;
+ end if ;
+ if OSVVM_SCOREBOARD_ALERTLOG_ID /= OSVVM_ALERTLOG_ID then
+ NewAlertLogRec(OSVVM_SCOREBOARD_ALERTLOG_ID, "OSVVM Scoreboard", ALERTLOG_BASE_ID) ;
+ NumAlertLogIDsVar := NumAlertLogIDsVar + 1 ;
+ end if ;
+ end procedure LocalInitialize ;
+
+ ------------------------------------------------------------
+ -- Construct initial data structure
+ procedure Initialize(NewNumAlertLogIDs : integer := MIN_NUM_AL_IDS) is
+ ------------------------------------------------------------
+ begin
+ LocalInitialize(NewNumAlertLogIDs) ;
+ end procedure Initialize ;
+
+ ------------------------------------------------------------
+ -- PT Local
+ -- Constructs initial data structure using constant below
+ impure function LocalInitialize return boolean is
+ ------------------------------------------------------------
+ begin
+ LocalInitialize(MIN_NUM_AL_IDS) ;
+ return TRUE ;
+ end function LocalInitialize ;
+
+ constant CONSTRUCT_ALERT_DATA_STRUCTURE : boolean := LocalInitialize ;
+
+ ------------------------------------------------------------
+ procedure Deallocate is
+ ------------------------------------------------------------
+ begin
+ for i in ALERTLOG_BASE_ID to NumAlertLogIDsVar loop
+ Deallocate(AlertLogPtr(i).Name) ;
+ Deallocate(AlertLogPtr(i)) ;
+ end loop ;
+ deallocate(AlertLogPtr) ;
+ -- Free up space used by protected types within AlertLogPkg
+ AlertPrefixVar.Deallocate ;
+ LogPrefixVar.Deallocate ;
+ ReportPrefixVar.Deallocate ;
+ DoneNameVar.Deallocate ;
+ PassNameVar.Deallocate ;
+ FailNameVar.Deallocate ;
+ -- Restore variables to their initial state
+ NumAlertLogIDsVar := 0 ;
+ NumAllocatedAlertLogIDsVar := 0 ;
+ GlobalAlertEnabledVar := TRUE ; -- Allows turn off and on
+ AffirmCheckCountVar := 0 ;
+--?? AffirmPassedCountVar := 0 ;
+ FailOnWarningVar := TRUE ;
+ FailOnDisabledErrorsVar := TRUE ;
+ ReportHierarchyVar := TRUE ;
+ FoundReportHierVar := FALSE ;
+ FoundAlertHierVar := FALSE ;
+ WriteAlertLevelVar := TRUE ;
+ WriteAlertNameVar := TRUE ;
+ WriteAlertTimeVar := TRUE ;
+ WriteLogLevelVar := TRUE ;
+ WriteLogNameVar := TRUE ;
+ WriteLogTimeVar := TRUE ;
+ end procedure Deallocate ;
+
+ ------------------------------------------------------------
+ -- PT Local.
+ procedure GrowAlertStructure (NewNumAlertLogIDs : integer) is
+ ------------------------------------------------------------
+ variable oldAlertLogPtr : AlertLogArrayPtrType ;
+ begin
+ if NumAllocatedAlertLogIDsVar = 0 then
+ Initialize (NewNumAlertLogIDs) ; -- Construct initial structure
+ else
+ oldAlertLogPtr := AlertLogPtr ;
+ AlertLogPtr := new AlertLogArrayType(ALERTLOG_BASE_ID to NewNumAlertLogIDs) ;
+ AlertLogPtr(ALERTLOG_BASE_ID to NumAlertLogIDsVar) := oldAlertLogPtr(ALERTLOG_BASE_ID to NumAlertLogIDsVar) ;
+ deallocate(oldAlertLogPtr) ;
+ end if ;
+ NumAllocatedAlertLogIDsVar := NewNumAlertLogIDs ;
+ end procedure GrowAlertStructure ;
+
+ ------------------------------------------------------------
+ -- Sets a AlertLogPtr to a particular size
+ -- Use for small bins to save space or large bins to
+ -- suppress the resize and copy as a CovBin autosizes.
+ procedure SetNumAlertLogIDs (NewNumAlertLogIDs : integer) is
+ ------------------------------------------------------------
+ variable oldAlertLogPtr : AlertLogArrayPtrType ;
+ begin
+ if NewNumAlertLogIDs > NumAllocatedAlertLogIDsVar then
+ GrowAlertStructure(NewNumAlertLogIDs) ;
+ end if;
+ end procedure SetNumAlertLogIDs ;
+
+ ------------------------------------------------------------
+ -- PT Local
+ impure function GetNextAlertLogID return AlertLogIDType is
+ ------------------------------------------------------------
+ variable NewNumAlertLogIDs : AlertLogIDType ;
+ begin
+ NewNumAlertLogIDs := NumAlertLogIDsVar + 1 ;
+ if NewNumAlertLogIDs > NumAllocatedAlertLogIDsVar then
+ GrowAlertStructure(NumAllocatedAlertLogIDsVar + MIN_NUM_AL_IDS) ;
+ end if ;
+ NumAlertLogIDsVar := NewNumAlertLogIDs ;
+ return NumAlertLogIDsVar ;
+ end function GetNextAlertLogID ;
+
+ ------------------------------------------------------------
+ impure function FindAlertLogID(Name : string ) return AlertLogIDType is
+ ------------------------------------------------------------
+ begin
+ for i in ALERTLOG_BASE_ID to NumAlertLogIDsVar loop
+ if Name = AlertLogPtr(i).Name.all then
+ return i ;
+ end if ;
+ end loop ;
+ return ALERTLOG_ID_NOT_FOUND ; -- not found
+ end function FindAlertLogID ;
+
+ ------------------------------------------------------------
+ impure function FindAlertLogID(Name : string ; ParentID : AlertLogIDType) return AlertLogIDType is
+ ------------------------------------------------------------
+ variable CurParentID : AlertLogIDType ;
+ begin
+ for i in ALERTLOG_BASE_ID to NumAlertLogIDsVar loop
+ CurParentID := AlertLogPtr(i).ParentID ;
+ if Name = AlertLogPtr(i).Name.all and
+ (CurParentID = ParentID or CurParentID = ALERTLOG_ID_NOT_ASSIGNED or ParentID = ALERTLOG_ID_NOT_ASSIGNED)
+ then
+ return i ;
+ end if ;
+ end loop ;
+ return ALERTLOG_ID_NOT_FOUND ; -- not found
+ end function FindAlertLogID ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogID(Name : string ; ParentID : AlertLogIDType ; CreateHierarchy : Boolean) return AlertLogIDType is
+ ------------------------------------------------------------
+ variable ResultID : AlertLogIDType ;
+ begin
+ ResultID := FindAlertLogID(Name, ParentID) ;
+ if ResultID /= ALERTLOG_ID_NOT_FOUND then
+ -- found it, set ParentID
+ if AlertLogPtr(ResultID).ParentID = ALERTLOG_ID_NOT_ASSIGNED then
+ AlertLogPtr(ResultID).ParentID := ParentID ;
+ -- else -- do not update as ParentIDs are either same or input ParentID = ALERTLOG_ID_NOT_ASSIGNED
+ end if ;
+ else
+ ResultID := GetNextAlertLogID ;
+ NewAlertLogRec(ResultID, Name, ParentID) ;
+ FoundAlertHierVar := TRUE ;
+ if CreateHierarchy then
+ FoundReportHierVar := TRUE ;
+ end if ;
+ end if ;
+ return ResultID ;
+ end function GetAlertLogID ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogParentID(AlertLogID : AlertLogIDType) return AlertLogIDType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogPtr(AlertLogID).ParentID ;
+ end function GetAlertLogParentID ;
+
+ ------------------------------------------------------------
+ ------------------------------------------------------------
+ -- Accessor Methods
+ ------------------------------------------------------------
+
+ ------------------------------------------------------------
+ procedure SetGlobalAlertEnable (A : boolean := TRUE) is
+ ------------------------------------------------------------
+ begin
+ GlobalAlertEnabledVar := A ;
+ end procedure SetGlobalAlertEnable ;
+
+ ------------------------------------------------------------
+ impure function GetGlobalAlertEnable return boolean is
+ ------------------------------------------------------------
+ begin
+ return GlobalAlertEnabledVar ;
+ end function GetGlobalAlertEnable ;
+
+ ------------------------------------------------------------
+ procedure IncAffirmCheckCount is
+ ------------------------------------------------------------
+ begin
+ if GlobalAlertEnabledVar then
+ AffirmCheckCountVar := AffirmCheckCountVar + 1 ;
+ end if ;
+ end procedure IncAffirmCheckCount ;
+
+ ------------------------------------------------------------
+ impure function GetAffirmCheckCount return natural is
+ ------------------------------------------------------------
+ begin
+ return AffirmCheckCountVar ;
+ end function GetAffirmCheckCount ;
+
+--?? ------------------------------------------------------------
+--?? procedure IncAffirmPassCount is
+--?? ------------------------------------------------------------
+--?? begin
+--?? if GlobalAlertEnabledVar then
+--?? AffirmCheckCountVar := AffirmCheckCountVar + 1 ;
+--?? AffirmPassedCountVar := AffirmPassedCountVar + 1 ;
+--?? end if ;
+--?? end procedure IncAffirmPassCount ;
+--??
+--?? ------------------------------------------------------------
+--?? impure function GetAffirmPassCount return natural is
+--?? ------------------------------------------------------------
+--?? begin
+--?? return AffirmPassedCountVar ;
+--?? end function GetAffirmPassCount ;
+
+ ------------------------------------------------------------
+ -- PT LOCAL
+ procedure SetOneStopCount(
+ ------------------------------------------------------------
+ AlertLogID : AlertLogIDType ;
+ Level : AlertType ;
+ Count : integer
+ ) is
+ begin
+ if AlertLogPtr(AlertLogID).AlertStopCount(Level) = integer'right then
+ AlertLogPtr(AlertLogID).AlertStopCount(Level) := Count ;
+ else
+ AlertLogPtr(AlertLogID).AlertStopCount(Level) :=
+ AlertLogPtr(AlertLogID).AlertStopCount(Level) + Count ;
+ end if ;
+ end procedure SetOneStopCount ;
+
+ ------------------------------------------------------------
+ procedure SetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType ; Count : integer) is
+ ------------------------------------------------------------
+ begin
+ SetOneStopCount(AlertLogID, Level, Count) ;
+ if AlertLogID /= ALERTLOG_BASE_ID then
+ SetAlertStopCount(AlertLogPtr(AlertLogID).ParentID, Level, Count) ;
+ end if ;
+ end procedure SetAlertStopCount ;
+
+ ------------------------------------------------------------
+ impure function GetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType) return integer is
+ ------------------------------------------------------------
+ begin
+ return AlertLogPtr(AlertLogID).AlertStopCount(Level) ;
+ end function GetAlertStopCount ;
+
+ ------------------------------------------------------------
+ procedure SetAlertEnable(Level : AlertType ; Enable : boolean) is
+ ------------------------------------------------------------
+ begin
+ for i in ALERTLOG_BASE_ID to NumAlertLogIDsVar loop
+ AlertLogPtr(i).AlertEnabled(Level) := Enable ;
+ end loop ;
+ end procedure SetAlertEnable ;
+
+ ------------------------------------------------------------
+ procedure SetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) is
+ ------------------------------------------------------------
+ begin
+ AlertLogPtr(AlertLogID).AlertEnabled(Level) := Enable ;
+ if DescendHierarchy then
+ for i in AlertLogID+1 to NumAlertLogIDsVar loop
+ if AlertLogID = AlertLogPtr(i).ParentID then
+ SetAlertEnable(i, Level, Enable, DescendHierarchy) ;
+ end if ;
+ end loop ;
+ end if ;
+ end procedure SetAlertEnable ;
+
+ ------------------------------------------------------------
+ impure function GetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType) return boolean is
+ ------------------------------------------------------------
+ begin
+ return AlertLogPtr(AlertLogID).AlertEnabled(Level) ;
+ end function GetAlertEnable ;
+
+ ------------------------------------------------------------
+ procedure SetLogEnable(Level : LogType ; Enable : boolean) is
+ ------------------------------------------------------------
+ begin
+ for i in ALERTLOG_BASE_ID to NumAlertLogIDsVar loop
+ AlertLogPtr(i).LogEnabled(Level) := Enable ;
+ end loop ;
+ end procedure SetLogEnable ;
+
+ ------------------------------------------------------------
+ procedure SetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) is
+ ------------------------------------------------------------
+ begin
+ AlertLogPtr(AlertLogID).LogEnabled(Level) := Enable ;
+ if DescendHierarchy then
+ for i in AlertLogID+1 to NumAlertLogIDsVar loop
+ if AlertLogID = AlertLogPtr(i).ParentID then
+ SetLogEnable(i, Level, Enable, DescendHierarchy) ;
+ end if ;
+ end loop ;
+ end if ;
+ end procedure SetLogEnable ;
+
+ ------------------------------------------------------------
+ impure function GetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType) return boolean is
+ ------------------------------------------------------------
+ begin
+ if Level = ALWAYS then
+ return TRUE ;
+ else
+ return AlertLogPtr(AlertLogID).LogEnabled(Level) ;
+ end if ;
+ end function GetLogEnable ;
+
+ ------------------------------------------------------------
+ -- PT Local
+ procedure PrintLogLevels(
+ ------------------------------------------------------------
+ AlertLogID : AlertLogIDType ;
+ Prefix : string ;
+ IndentAmount : integer
+ ) is
+ variable buf : line ;
+ begin
+ write(buf, Prefix & " " & LeftJustify(AlertLogPtr(AlertLogID).Name.all, ReportJustifyAmountVar - IndentAmount)) ;
+ for i in LogIndexType loop
+ if AlertLogPtr(AlertLogID).LogEnabled(i) then
+-- write(buf, " " & to_string(AlertLogPtr(AlertLogID).LogEnabled(i)) ) ;
+ write(buf, " " & to_string(i)) ;
+ end if ;
+ end loop ;
+ WriteLine(buf) ;
+ for i in AlertLogID+1 to NumAlertLogIDsVar loop
+ if AlertLogID = AlertLogPtr(i).ParentID then
+ PrintLogLevels(
+ AlertLogID => i,
+ Prefix => Prefix & " ",
+ IndentAmount => IndentAmount + 2
+ ) ;
+ end if ;
+ end loop ;
+ end procedure PrintLogLevels ;
+
+ ------------------------------------------------------------
+ procedure ReportLogEnables is
+ ------------------------------------------------------------
+ begin
+ if ReportJustifyAmountVar <= 0 then
+ SetJustify ;
+ end if ;
+ PrintLogLevels(ALERTLOG_BASE_ID, "", 0) ;
+ end procedure ReportLogEnables ;
+
+ ------------------------------------------------------------
+ procedure SetAlertLogOptions (
+ ------------------------------------------------------------
+ FailOnWarning : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ FailOnDisabledErrors : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ ReportHierarchy : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAlertLevel : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAlertName : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAlertTime : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteLogLevel : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteLogName : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteLogTime : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ AlertPrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ LogPrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ ReportPrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ DoneName : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ PassName : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ FailName : string := OSVVM_STRING_INIT_PARM_DETECT
+ ) is
+ begin
+ if FailOnWarning /= OPT_INIT_PARM_DETECT then
+ FailOnWarningVar := IsEnabled(FailOnWarning) ;
+ end if ;
+ if FailOnDisabledErrors /= OPT_INIT_PARM_DETECT then
+ FailOnDisabledErrorsVar := IsEnabled(FailOnDisabledErrors) ;
+ end if ;
+ if ReportHierarchy /= OPT_INIT_PARM_DETECT then
+ ReportHierarchyVar := IsEnabled(ReportHierarchy) ;
+ end if ;
+ if WriteAlertLevel /= OPT_INIT_PARM_DETECT then
+ WriteAlertLevelVar := IsEnabled(WriteAlertLevel) ;
+ end if ;
+ if WriteAlertName /= OPT_INIT_PARM_DETECT then
+ WriteAlertNameVar := IsEnabled(WriteAlertName) ;
+ end if ;
+ if WriteAlertTime /= OPT_INIT_PARM_DETECT then
+ WriteAlertTimeVar := IsEnabled(WriteAlertTime) ;
+ end if ;
+ if WriteLogLevel /= OPT_INIT_PARM_DETECT then
+ WriteLogLevelVar := IsEnabled(WriteLogLevel) ;
+ end if ;
+ if WriteLogName /= OPT_INIT_PARM_DETECT then
+ WriteLogNameVar := IsEnabled(WriteLogName) ;
+ end if ;
+ if WriteLogTime /= OPT_INIT_PARM_DETECT then
+ WriteLogTimeVar := IsEnabled(WriteLogTime) ;
+ end if ;
+ if AlertPrefix /= OSVVM_STRING_INIT_PARM_DETECT then
+ AlertPrefixVar.Set(AlertPrefix) ;
+ end if ;
+ if LogPrefix /= OSVVM_STRING_INIT_PARM_DETECT then
+ LogPrefixVar.Set(LogPrefix) ;
+ end if ;
+ if ReportPrefix /= OSVVM_STRING_INIT_PARM_DETECT then
+ ReportPrefixVar.Set(ReportPrefix) ;
+ end if ;
+ if DoneName /= OSVVM_STRING_INIT_PARM_DETECT then
+ DoneNameVar.Set(DoneName) ;
+ end if ;
+ if PassName /= OSVVM_STRING_INIT_PARM_DETECT then
+ PassNameVar.Set(PassName) ;
+ end if ;
+ if FailName /= OSVVM_STRING_INIT_PARM_DETECT then
+ FailNameVar.Set(FailName) ;
+ end if ;
+ end procedure SetAlertLogOptions ;
+
+ ------------------------------------------------------------
+ procedure ReportAlertLogOptions is
+ ------------------------------------------------------------
+ variable buf : line ;
+ begin
+ -- Boolean Values
+ swrite(buf, "ReportAlertLogOptions" & LF ) ;
+ swrite(buf, "---------------------" & LF ) ;
+ swrite(buf, "FailOnWarningVar: " & to_string(FailOnWarningVar ) & LF ) ;
+ swrite(buf, "FailOnDisabledErrorsVar: " & to_string(FailOnDisabledErrorsVar ) & LF ) ;
+ swrite(buf, "ReportHierarchyVar: " & to_string(ReportHierarchyVar ) & LF ) ;
+ swrite(buf, "FoundReportHierVar: " & to_string(FoundReportHierVar ) & LF ) ; -- Not set by user
+ swrite(buf, "FoundAlertHierVar: " & to_string(FoundAlertHierVar ) & LF ) ; -- Not set by user
+ swrite(buf, "WriteAlertLevelVar: " & to_string(WriteAlertLevelVar ) & LF ) ;
+ swrite(buf, "WriteAlertNameVar: " & to_string(WriteAlertNameVar ) & LF ) ;
+ swrite(buf, "WriteAlertTimeVar: " & to_string(WriteAlertTimeVar ) & LF ) ;
+ swrite(buf, "WriteLogLevelVar: " & to_string(WriteLogLevelVar ) & LF ) ;
+ swrite(buf, "WriteLogNameVar: " & to_string(WriteLogNameVar ) & LF ) ;
+ swrite(buf, "WriteLogTimeVar: " & to_string(WriteLogTimeVar ) & LF ) ;
+
+ -- String
+ swrite(buf, "AlertPrefixVar: " & string'(AlertPrefixVar.Get(OSVVM_DEFAULT_ALERT_PREFIX)) & LF ) ;
+ swrite(buf, "LogPrefixVar: " & string'(LogPrefixVar.Get(OSVVM_DEFAULT_LOG_PREFIX)) & LF ) ;
+ swrite(buf, "ReportPrefixVar: " & ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt) & LF ) ;
+ swrite(buf, "DoneNameVar: " & ResolveOsvvmDoneName(DoneNameVar.GetOpt) & LF ) ;
+ swrite(buf, "PassNameVar: " & ResolveOsvvmPassName(PassNameVar.GetOpt) & LF ) ;
+ swrite(buf, "FailNameVar: " & ResolveOsvvmFailName(FailNameVar.GetOpt) & LF ) ;
+ writeline(buf) ;
+ end procedure ReportAlertLogOptions ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogFailOnWarning return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return to_OsvvmOptionsType(FailOnWarningVar) ;
+ end function GetAlertLogFailOnWarning ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogFailOnDisabledErrors return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return to_OsvvmOptionsType(FailOnDisabledErrorsVar) ;
+ end function GetAlertLogFailOnDisabledErrors ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogReportHierarchy return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return to_OsvvmOptionsType(ReportHierarchyVar) ;
+ end function GetAlertLogReportHierarchy ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogFoundReportHier return boolean is
+ ------------------------------------------------------------
+ begin
+ return FoundReportHierVar ;
+ end function GetAlertLogFoundReportHier ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogFoundAlertHier return boolean is
+ ------------------------------------------------------------
+ begin
+ return FoundAlertHierVar ;
+ end function GetAlertLogFoundAlertHier ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogWriteAlertLevel return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return to_OsvvmOptionsType(WriteAlertLevelVar) ;
+ end function GetAlertLogWriteAlertLevel ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogWriteAlertName return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return to_OsvvmOptionsType(WriteAlertNameVar) ;
+ end function GetAlertLogWriteAlertName ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogWriteAlertTime return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return to_OsvvmOptionsType(WriteAlertTimeVar) ;
+ end function GetAlertLogWriteAlertTime ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogWriteLogLevel return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return to_OsvvmOptionsType(WriteLogLevelVar) ;
+ end function GetAlertLogWriteLogLevel ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogWriteLogName return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return to_OsvvmOptionsType(WriteLogNameVar) ;
+ end function GetAlertLogWriteLogName ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogWriteLogTime return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return to_OsvvmOptionsType(WriteLogTimeVar) ;
+ end function GetAlertLogWriteLogTime ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogAlertPrefix return string is
+ ------------------------------------------------------------
+ begin
+ return AlertPrefixVar.Get(OSVVM_DEFAULT_ALERT_PREFIX) ;
+ end function GetAlertLogAlertPrefix ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogLogPrefix return string is
+ ------------------------------------------------------------
+ begin
+ return LogPrefixVar.Get(OSVVM_DEFAULT_LOG_PREFIX) ;
+ end function GetAlertLogLogPrefix ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogReportPrefix return string is
+ ------------------------------------------------------------
+ begin
+ return ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt) ;
+ end function GetAlertLogReportPrefix ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogDoneName return string is
+ ------------------------------------------------------------
+ begin
+ return ResolveOsvvmDoneName(DoneNameVar.GetOpt) ;
+ end function GetAlertLogDoneName ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogPassName return string is
+ ------------------------------------------------------------
+ begin
+ return ResolveOsvvmPassName(PassNameVar.GetOpt) ;
+ end function GetAlertLogPassName ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogFailName return string is
+ ------------------------------------------------------------
+ begin
+ return ResolveOsvvmFailName(FailNameVar.GetOpt) ;
+ end function GetAlertLogFailName ;
+
+ end protected body AlertLogStructPType ;
+
+
+
+ shared variable AlertLogStruct : AlertLogStructPType ;
+
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+
+ ------------------------------------------------------------
+ procedure Alert(
+ ------------------------------------------------------------
+ AlertLogID : AlertLogIDType ;
+ Message : string ;
+ Level : AlertType := ERROR
+ ) is
+ begin
+ AlertLogStruct.Alert(AlertLogID, Message, Level) ;
+ end procedure alert ;
+
+ ------------------------------------------------------------
+ procedure Alert( Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message, Level) ;
+ end procedure alert ;
+
+ ------------------------------------------------------------
+ procedure IncAlertCount(
+ ------------------------------------------------------------
+ AlertLogID : AlertLogIDType ;
+ Level : AlertType := ERROR
+ ) is
+ begin
+ AlertLogStruct.IncAlertCount(AlertLogID, Level) ;
+ end procedure IncAlertCount ;
+
+ ------------------------------------------------------------
+ procedure IncAlertCount( Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.IncAlertCount(ALERT_DEFAULT_ID, Level) ;
+ end procedure IncAlertCount ;
+
+
+ ------------------------------------------------------------
+ procedure AlertIf( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if condition then
+ AlertLogStruct.Alert(AlertLogID , Message, Level) ;
+ end if ;
+ end procedure AlertIf ;
+
+ ------------------------------------------------------------
+ -- deprecated
+ procedure AlertIf( condition : boolean ; AlertLogID : AlertLogIDType ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ AlertIf( AlertLogID, condition, Message, Level) ;
+ end procedure AlertIf ;
+
+ ------------------------------------------------------------
+ procedure AlertIf( condition : boolean ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if condition then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID , Message, Level) ;
+ end if ;
+ end procedure AlertIf ;
+
+ ------------------------------------------------------------
+ -- useful with exit conditions in a loop: exit when alert( not ReadValid, failure, "Read Failed") ;
+ impure function AlertIf( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Level : AlertType := ERROR ) return boolean is
+ ------------------------------------------------------------
+ begin
+ if condition then
+ AlertLogStruct.Alert(AlertLogID , Message, Level) ;
+ end if ;
+ return condition ;
+ end function AlertIf ;
+
+ ------------------------------------------------------------
+ -- deprecated
+ impure function AlertIf( condition : boolean ; AlertLogID : AlertLogIDType ; Message : string ; Level : AlertType := ERROR ) return boolean is
+ ------------------------------------------------------------
+ begin
+ return AlertIf( AlertLogID, condition, Message, Level) ;
+ end function AlertIf ;
+
+ ------------------------------------------------------------
+ impure function AlertIf( condition : boolean ; Message : string ; Level : AlertType := ERROR ) return boolean is
+ ------------------------------------------------------------
+ begin
+ if condition then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message, Level) ;
+ end if ;
+ return condition ;
+ end function AlertIf ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if not condition then
+ AlertLogStruct.Alert(AlertLogID, Message, Level) ;
+ end if ;
+ end procedure AlertIfNot ;
+
+ ------------------------------------------------------------
+ -- deprecated
+ procedure AlertIfNot( condition : boolean ; AlertLogID : AlertLogIDType ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ AlertIfNot( AlertLogID, condition, Message, Level) ;
+ end procedure AlertIfNot ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNot( condition : boolean ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if not condition then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message, Level) ;
+ end if ;
+ end procedure AlertIfNot ;
+
+ ------------------------------------------------------------
+ -- useful with exit conditions in a loop: exit when alert( not ReadValid, failure, "Read Failed") ;
+ impure function AlertIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Level : AlertType := ERROR ) return boolean is
+ ------------------------------------------------------------
+ begin
+ if not condition then
+ AlertLogStruct.Alert(AlertLogID, Message, Level) ;
+ end if ;
+ return not condition ;
+ end function AlertIfNot ;
+
+ ------------------------------------------------------------
+ -- deprecated
+ impure function AlertIfNot( condition : boolean ; AlertLogID : AlertLogIDType ; Message : string ; Level : AlertType := ERROR ) return boolean is
+ ------------------------------------------------------------
+ begin
+ return AlertIfNot( AlertLogID, condition, Message, Level) ;
+ end function AlertIfNot ;
+
+ ------------------------------------------------------------
+ impure function AlertIfNot( condition : boolean ; Message : string ; Level : AlertType := ERROR ) return boolean is
+ ------------------------------------------------------------
+ begin
+ if not condition then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message, Level) ;
+ end if ;
+ return not condition ;
+ end function AlertIfNot ;
+
+ -- With AlertLogID
+ ------------------------------------------------------------
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : std_logic ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?= R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : std_logic_vector ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?= R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : unsigned ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?= R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : signed ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?= R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : integer ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L = R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : real ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L = R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L, 4) & " R = " & to_string(R, 4), Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : character ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L = R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & L & " R = " & R, Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : string ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L = R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & L & " R = " & R, Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ -- Without AlertLogID
+ ------------------------------------------------------------
+ procedure AlertIfEqual( L, R : std_logic ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?= R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( L, R : std_logic_vector ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?= R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( L, R : unsigned ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?= R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( L, R : signed ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?= R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( L, R : integer ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L = R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( L, R : real ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L = R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & to_string(L, 4) & " R = " & to_string(R, 4), Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( L, R : character ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L = R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & L & " R = " & R, Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfEqual( L, R : string ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L = R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & L & " R = " & R, Level) ;
+ end if ;
+ end procedure AlertIfEqual ;
+
+ -- With AlertLogID
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : std_logic ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?/= R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : std_logic_vector ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?/= R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : unsigned ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?/= R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : signed ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?/= R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : integer ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L /= R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : real ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L /= R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L, 4) & " R = " & to_string(R, 4), Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : character ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L /= R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & L & " R = " & R, Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : string ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L /= R then
+ AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & L & " R = " & R, Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ -- Without AlertLogID
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( L, R : std_logic ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?/= R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( L, R : std_logic_vector ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?/= R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( L, R : unsigned ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?/= R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( L, R : signed ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L ?/= R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( L, R : integer ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L /= R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( L, R : real ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L /= R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & to_string(L, 4) & " R = " & to_string(R, 4), Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( L, R : character ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L /= R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & L & " R = " & R, Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfNotEqual( L, R : string ; Message : string ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ if L /= R then
+ AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & L & " R = " & R, Level) ;
+ end if ;
+ end procedure AlertIfNotEqual ;
+
+ ------------------------------------------------------------
+ procedure AlertIfDiff (AlertLogID : AlertLogIDType ; Name1, Name2 : string; Message : string := "" ; Level : AlertType := ERROR ) is
+ -- Open files and call AlertIfDiff[text, ...]
+ ------------------------------------------------------------
+ file FileID1, FileID2 : text ;
+ variable status1, status2 : file_open_status ;
+ begin
+ file_open(status1, FileID1, Name1, READ_MODE) ;
+ file_open(status2, FileID2, Name2, READ_MODE) ;
+ if status1 = OPEN_OK and status2 = OPEN_OK then
+ AlertIfDiff (AlertLogID, FileID1, FileID2, Message & " " & Name1 & " /= " & Name2 & ", ", Level) ;
+ else
+ if status1 /= OPEN_OK then
+ AlertLogStruct.Alert(AlertLogID , Message & " File, " & Name1 & ", did not open", Level) ;
+ end if ;
+ if status2 /= OPEN_OK then
+ AlertLogStruct.Alert(AlertLogID , Message & " File, " & Name2 & ", did not open", Level) ;
+ end if ;
+ end if;
+ end procedure AlertIfDiff ;
+
+ ------------------------------------------------------------
+ procedure AlertIfDiff (Name1, Name2 : string; Message : string := "" ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ AlertIfDiff (ALERT_DEFAULT_ID, Name1, Name2, Message, Level) ;
+ end procedure AlertIfDiff ;
+
+ ------------------------------------------------------------
+ procedure AlertIfDiff (AlertLogID : AlertLogIDType ; file File1, File2 : text; Message : string := "" ; Level : AlertType := ERROR ) is
+ -- Simple diff.
+ ------------------------------------------------------------
+ variable Buf1, Buf2 : line ;
+ variable File1Done, File2Done : boolean ;
+ variable LineCount : integer := 0 ;
+ begin
+ ReadLoop : loop
+ File1Done := EndFile(File1) ;
+ File2Done := EndFile(File2) ;
+ exit ReadLoop when File1Done or File2Done ;
+
+ ReadLine(File1, Buf1) ;
+ ReadLine(File2, Buf2) ;
+ LineCount := LineCount + 1 ;
+
+ if Buf1.all /= Buf2.all then
+ AlertLogStruct.Alert(AlertLogID , Message & " File miscompare on line " & to_string(LineCount), Level) ;
+ exit ReadLoop ;
+ end if ;
+ end loop ReadLoop ;
+ if File1Done /= File2Done then
+ if not File1Done then
+ AlertLogStruct.Alert(AlertLogID , Message & " File1 longer than File2 " & to_string(LineCount), Level) ;
+ end if ;
+ if not File2Done then
+ AlertLogStruct.Alert(AlertLogID , Message & " File2 longer than File1 " & to_string(LineCount), Level) ;
+ end if ;
+ end if;
+ end procedure AlertIfDiff ;
+
+ ------------------------------------------------------------
+ procedure AlertIfDiff (file File1, File2 : text; Message : string := "" ; Level : AlertType := ERROR ) is
+ ------------------------------------------------------------
+ begin
+ AlertIfDiff (ALERT_DEFAULT_ID, File1, File2, Message, Level) ;
+ end procedure AlertIfDiff ;
+
+ ------------------------------------------------------------
+ procedure AffirmIf(
+ ------------------------------------------------------------
+ AlertLogID : AlertLogIDType ;
+ condition : boolean ;
+ Message : string ;
+ LogLevel : LogType := PASSED ;
+ AlertLevel : AlertType := ERROR
+ ) is
+ begin
+ AlertLogStruct.IncAffirmCheckCount ; -- increment check count
+ if condition then
+ -- passed
+ AlertLogStruct.Log(AlertLogID, Message, LogLevel) ; -- call log
+-- AlertLogStruct.IncAffirmPassCount ; -- increment pass & check count
+ else
+ AlertLogStruct.Alert(AlertLogID, Message, AlertLevel) ; -- signal failure
+ end if ;
+ end procedure AffirmIf ;
+
+ ------------------------------------------------------------
+ procedure AffirmIf(condition : boolean ; Message : string ; LogLevel : LogType := PASSED ; AlertLevel : AlertType := ERROR) is
+ ------------------------------------------------------------
+ begin
+ AffirmIf(ALERT_DEFAULT_ID, condition, Message, LogLevel, AlertLevel) ;
+ end procedure AffirmIf;
+
+ ------------------------------------------------------------
+ procedure SetAlertLogJustify is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.SetJustify ;
+ end procedure SetAlertLogJustify ;
+
+ ------------------------------------------------------------
+ procedure ReportAlerts ( Name : String ; AlertCount : AlertCountType ) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.ReportAlerts(Name, AlertCount) ;
+ end procedure ReportAlerts ;
+
+ ------------------------------------------------------------
+ procedure ReportAlerts ( Name : string := OSVVM_STRING_INIT_PARM_DETECT ; AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; ExternalErrors : AlertCountType := (others => 0) ) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.ReportAlerts(Name, AlertLogID, ExternalErrors, TRUE) ;
+ end procedure ReportAlerts ;
+
+ ------------------------------------------------------------
+ procedure ReportNonZeroAlerts ( Name : string := OSVVM_STRING_INIT_PARM_DETECT ; AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; ExternalErrors : AlertCountType := (others => 0) ) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.ReportAlerts(Name, AlertLogID, ExternalErrors, FALSE) ;
+ end procedure ReportNonZeroAlerts ;
+
+ ------------------------------------------------------------
+ procedure ClearAlerts is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.ClearAlerts ;
+ end procedure ClearAlerts ;
+
+ ------------------------------------------------------------
+ function "ABS" (L : AlertCountType) return AlertCountType is
+ ------------------------------------------------------------
+ variable Result : AlertCountType ;
+ begin
+ Result(FAILURE) := ABS( L(FAILURE) ) ;
+ Result(ERROR) := ABS( L(ERROR) ) ;
+ Result(WARNING) := ABS( L(WARNING) );
+ return Result ;
+ end function "ABS" ;
+
+ ------------------------------------------------------------
+ function "+" (L, R : AlertCountType) return AlertCountType is
+ ------------------------------------------------------------
+ variable Result : AlertCountType ;
+ begin
+ Result(FAILURE) := L(FAILURE) + R(FAILURE) ;
+ Result(ERROR) := L(ERROR) + R(ERROR) ;
+ Result(WARNING) := L(WARNING) + R(WARNING) ;
+ return Result ;
+ end function "+" ;
+
+ ------------------------------------------------------------
+ function "-" (L, R : AlertCountType) return AlertCountType is
+ ------------------------------------------------------------
+ variable Result : AlertCountType ;
+ begin
+ Result(FAILURE) := L(FAILURE) - R(FAILURE) ;
+ Result(ERROR) := L(ERROR) - R(ERROR) ;
+ Result(WARNING) := L(WARNING) - R(WARNING) ;
+ return Result ;
+ end function "-" ;
+
+ ------------------------------------------------------------
+ function "-" (R : AlertCountType) return AlertCountType is
+ ------------------------------------------------------------
+ variable Result : AlertCountType ;
+ begin
+ Result(FAILURE) := - R(FAILURE) ;
+ Result(ERROR) := - R(ERROR) ;
+ Result(WARNING) := - R(WARNING) ;
+ return Result ;
+ end function "-" ;
+
+ ------------------------------------------------------------
+ impure function SumAlertCount(AlertCount: AlertCountType) return integer is
+ ------------------------------------------------------------
+ begin
+ -- Using ABS ensures correct expected error handling.
+ return abs(AlertCount(FAILURE)) + abs(AlertCount(ERROR)) + abs(AlertCount(WARNING)) ;
+ end function SumAlertCount ;
+
+ ------------------------------------------------------------
+ impure function GetAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return AlertCountType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertCount(AlertLogID) ;
+ end function GetAlertCount ;
+
+ ------------------------------------------------------------
+ impure function GetAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return integer is
+ ------------------------------------------------------------
+ begin
+ return SumAlertCount(AlertLogStruct.GetAlertCount(AlertLogID)) ;
+ end function GetAlertCount ;
+
+ ------------------------------------------------------------
+ impure function GetEnabledAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return AlertCountType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetEnabledAlertCount(AlertLogID) ;
+ end function GetEnabledAlertCount ;
+
+ ------------------------------------------------------------
+ impure function GetEnabledAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return integer is
+ ------------------------------------------------------------
+ begin
+ return SumAlertCount(AlertLogStruct.GetEnabledAlertCount(AlertLogID)) ;
+ end function GetEnabledAlertCount ;
+
+ ------------------------------------------------------------
+ impure function GetDisabledAlertCount return AlertCountType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetDisabledAlertCount ;
+ end function GetDisabledAlertCount ;
+
+ ------------------------------------------------------------
+ impure function GetDisabledAlertCount return integer is
+ ------------------------------------------------------------
+ begin
+ return SumAlertCount(AlertLogStruct.GetDisabledAlertCount) ;
+ end function GetDisabledAlertCount ;
+
+ ------------------------------------------------------------
+ impure function GetDisabledAlertCount(AlertLogID: AlertLogIDType) return AlertCountType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetDisabledAlertCount(AlertLogID) ;
+ end function GetDisabledAlertCount ;
+
+ ------------------------------------------------------------
+ impure function GetDisabledAlertCount(AlertLogID: AlertLogIDType) return integer is
+ ------------------------------------------------------------
+ begin
+ return SumAlertCount(AlertLogStruct.GetDisabledAlertCount(AlertLogID)) ;
+ end function GetDisabledAlertCount ;
+
+ ------------------------------------------------------------
+ procedure Log(
+ AlertLogID : AlertLogIDType ;
+ Message : string ;
+ Level : LogType := ALWAYS ;
+ Enable : boolean := FALSE -- override internal enable
+ ) is
+ begin
+ AlertLogStruct.Log(AlertLogID, Message, Level, Enable) ;
+ end procedure log ;
+
+ ------------------------------------------------------------
+ procedure Log( Message : string ; Level : LogType := ALWAYS ; Enable : boolean := FALSE) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.Log(LOG_DEFAULT_ID, Message, Level, Enable) ;
+ end procedure log ;
+
+ ------------------------------------------------------------
+ procedure SetAlertLogName(Name : string ) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.SetAlertLogName(Name) ;
+ end procedure SetAlertLogName ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogName(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return string is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogName(AlertLogID) ;
+ end GetAlertLogName ;
+
+ ------------------------------------------------------------
+ procedure DeallocateAlertLogStruct is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.Deallocate ;
+ end procedure DeallocateAlertLogStruct ;
+
+ ------------------------------------------------------------
+ procedure InitializeAlertLogStruct is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.Initialize ;
+ end procedure InitializeAlertLogStruct ;
+
+ ------------------------------------------------------------
+ impure function FindAlertLogID(Name : string ) return AlertLogIDType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.FindAlertLogID(Name) ;
+ end function FindAlertLogID ;
+
+ ------------------------------------------------------------
+ impure function FindAlertLogID(Name : string ; ParentID : AlertLogIDType) return AlertLogIDType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.FindAlertLogID(Name, ParentID) ;
+ end function FindAlertLogID ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogID(Name : string ; ParentID : AlertLogIDType := ALERTLOG_BASE_ID ; CreateHierarchy : Boolean := TRUE) return AlertLogIDType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogID(Name, ParentID, CreateHierarchy ) ;
+ end function GetAlertLogID ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogParentID(AlertLogID : AlertLogIDType) return AlertLogIDType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogParentID(AlertLogID) ;
+ end function GetAlertLogParentID ;
+
+ ------------------------------------------------------------
+ procedure SetGlobalAlertEnable (A : boolean := TRUE) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.SetGlobalAlertEnable(A) ;
+ end procedure SetGlobalAlertEnable ;
+
+ ------------------------------------------------------------
+ -- Set using constant. Set before code runs.
+ impure function SetGlobalAlertEnable (A : boolean := TRUE) return boolean is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.SetGlobalAlertEnable(A) ;
+ return A ;
+ end function SetGlobalAlertEnable ;
+
+ ------------------------------------------------------------
+ impure function GetGlobalAlertEnable return boolean is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetGlobalAlertEnable ;
+ end function GetGlobalAlertEnable ;
+
+ ------------------------------------------------------------
+ procedure IncAffirmCheckCount is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.IncAffirmCheckCount ;
+ end procedure IncAffirmCheckCount ;
+
+ ------------------------------------------------------------
+ impure function GetAffirmCheckCount return natural is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAffirmCheckCount ;
+ end function GetAffirmCheckCount ;
+
+--?? ------------------------------------------------------------
+--?? procedure IncAffirmPassCount is
+--?? ------------------------------------------------------------
+--?? begin
+--?? AlertLogStruct.IncAffirmPassCount ;
+--?? end procedure IncAffirmPassCount ;
+--??
+--?? ------------------------------------------------------------
+--?? impure function GetAffirmPassCount return natural is
+--?? ------------------------------------------------------------
+--?? begin
+--?? return AlertLogStruct.GetAffirmPassCount ;
+--?? end function GetAffirmPassCount ;
+
+ ------------------------------------------------------------
+ procedure SetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType ; Count : integer) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.SetAlertStopCount(AlertLogID, Level, Count) ;
+ end procedure SetAlertStopCount ;
+
+ ------------------------------------------------------------
+ procedure SetAlertStopCount(Level : AlertType ; Count : integer) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.SetAlertStopCount(ALERTLOG_BASE_ID, Level, Count) ;
+ end procedure SetAlertStopCount ;
+
+ ------------------------------------------------------------
+ impure function GetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType) return integer is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertStopCount(AlertLogID, Level) ;
+ end function GetAlertStopCount ;
+
+ ------------------------------------------------------------
+ impure function GetAlertStopCount(Level : AlertType) return integer is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertStopCount(ALERTLOG_BASE_ID, Level) ;
+ end function GetAlertStopCount ;
+
+ ------------------------------------------------------------
+ procedure SetAlertEnable(Level : AlertType ; Enable : boolean) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.SetAlertEnable(Level, Enable) ;
+ end procedure SetAlertEnable ;
+
+ ------------------------------------------------------------
+ procedure SetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.SetAlertEnable(AlertLogID, Level, Enable, DescendHierarchy) ;
+ end procedure SetAlertEnable ;
+
+ ------------------------------------------------------------
+ impure function GetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType) return boolean is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertEnable(AlertLogID, Level) ;
+ end function GetAlertEnable ;
+
+ ------------------------------------------------------------
+ impure function GetAlertEnable(Level : AlertType) return boolean is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertEnable(ALERT_DEFAULT_ID, Level) ;
+ end function GetAlertEnable ;
+
+ ------------------------------------------------------------
+ procedure SetLogEnable(Level : LogType ; Enable : boolean) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.SetLogEnable(Level, Enable) ;
+ end procedure SetLogEnable ;
+
+ ------------------------------------------------------------
+ procedure SetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.SetLogEnable(AlertLogID, Level, Enable, DescendHierarchy) ;
+ end procedure SetLogEnable ;
+
+ ------------------------------------------------------------
+ impure function GetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType) return boolean is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetLogEnable(AlertLogID, Level) ;
+ end function GetLogEnable ;
+
+ ------------------------------------------------------------
+ impure function GetLogEnable(Level : LogType) return boolean is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetLogEnable(LOG_DEFAULT_ID, Level) ;
+ end function GetLogEnable ;
+
+ ------------------------------------------------------------
+ impure function IsLoggingEnabled(AlertLogID : AlertLogIDType ; Level : LogType) return boolean is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetLogEnable(AlertLogID, Level) ;
+ end function IsLoggingEnabled ;
+
+ ------------------------------------------------------------
+ impure function IsLoggingEnabled(Level : LogType) return boolean is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetLogEnable(LOG_DEFAULT_ID, Level) ;
+ end function IsLoggingEnabled ;
+
+ ------------------------------------------------------------
+ procedure ReportLogEnables is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.ReportLogEnables ;
+ end ReportLogEnables ;
+
+ ------------------------------------------------------------
+ procedure SetAlertLogOptions (
+ ------------------------------------------------------------
+ FailOnWarning : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ FailOnDisabledErrors : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ ReportHierarchy : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAlertLevel : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAlertName : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAlertTime : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteLogLevel : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteLogName : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteLogTime : AlertLogOptionsType := OPT_INIT_PARM_DETECT ;
+ AlertPrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ LogPrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ ReportPrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ DoneName : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ PassName : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ FailName : string := OSVVM_STRING_INIT_PARM_DETECT
+ ) is
+ begin
+ AlertLogStruct.SetAlertLogOptions (
+ FailOnWarning => FailOnWarning ,
+ FailOnDisabledErrors => FailOnDisabledErrors,
+ ReportHierarchy => ReportHierarchy ,
+ WriteAlertLevel => WriteAlertLevel ,
+ WriteAlertName => WriteAlertName ,
+ WriteAlertTime => WriteAlertTime ,
+ WriteLogLevel => WriteLogLevel ,
+ WriteLogName => WriteLogName ,
+ WriteLogTime => WriteLogTime ,
+ AlertPrefix => AlertPrefix ,
+ LogPrefix => LogPrefix ,
+ ReportPrefix => ReportPrefix ,
+ DoneName => DoneName ,
+ PassName => PassName ,
+ FailName => FailName
+ );
+ end procedure SetAlertLogOptions ;
+
+ ------------------------------------------------------------
+ procedure ReportAlertLogOptions is
+ ------------------------------------------------------------
+ begin
+ AlertLogStruct.ReportAlertLogOptions ;
+ end procedure ReportAlertLogOptions ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogFailOnWarning return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogFailOnWarning ;
+ end function GetAlertLogFailOnWarning ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogFailOnDisabledErrors return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogFailOnDisabledErrors ;
+ end function GetAlertLogFailOnDisabledErrors ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogReportHierarchy return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogReportHierarchy ;
+ end function GetAlertLogReportHierarchy ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogFoundReportHier return boolean is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogFoundReportHier ;
+ end function GetAlertLogFoundReportHier ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogFoundAlertHier return boolean is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogFoundAlertHier ;
+ end function GetAlertLogFoundAlertHier ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogWriteAlertLevel return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogWriteAlertLevel ;
+ end function GetAlertLogWriteAlertLevel ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogWriteAlertName return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogWriteAlertName ;
+ end function GetAlertLogWriteAlertName ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogWriteAlertTime return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogWriteAlertTime ;
+ end function GetAlertLogWriteAlertTime ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogWriteLogLevel return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogWriteLogLevel ;
+ end function GetAlertLogWriteLogLevel ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogWriteLogName return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogWriteLogName ;
+ end function GetAlertLogWriteLogName ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogWriteLogTime return AlertLogOptionsType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogWriteLogTime ;
+ end function GetAlertLogWriteLogTime ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogAlertPrefix return string is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogAlertPrefix ;
+ end function GetAlertLogAlertPrefix ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogLogPrefix return string is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogLogPrefix ;
+ end function GetAlertLogLogPrefix ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogReportPrefix return string is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogReportPrefix ;
+ end function GetAlertLogReportPrefix ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogDoneName return string is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogDoneName ;
+ end function GetAlertLogDoneName ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogPassName return string is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogPassName ;
+ end function GetAlertLogPassName ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogFailName return string is
+ ------------------------------------------------------------
+ begin
+ return AlertLogStruct.GetAlertLogFailName ;
+ end function GetAlertLogFailName ;
+
+ ------------------------------------------------------------
+ function IsLogEnableType (Name : String) return boolean is
+ ------------------------------------------------------------
+ -- type LogType is (ALWAYS, DEBUG, FINAL, INFO, PASSED) ; -- NEVER
+ begin
+ if Name = "PASSED" then return TRUE ;
+ elsif Name = "DEBUG" then return TRUE ;
+ elsif Name = "FINAL" then return TRUE ;
+ elsif Name = "INFO" then return TRUE ;
+ end if ;
+ return FALSE ;
+ end function IsLogEnableType ;
+
+ ------------------------------------------------------------
+ procedure ReadLogEnables (file AlertLogInitFile : text) is
+ -- Preferred Read format
+ -- Line 1: instance1_name log_enable log_enable log_enable
+ -- Line 2: instance2_name log_enable log_enable log_enable
+ -- when reading multiple log_enables on a line, they must be separated by a space
+ --
+ --- Also supports alternate format from Lyle/....
+ -- Line 1: instance1_name
+ -- Line 2: log enable
+ -- Line 3: instance2_name
+ -- Line 4: log enable
+ --
+ ------------------------------------------------------------
+ type ReadStateType is (GET_ID, GET_ENABLE) ;
+ variable ReadState : ReadStateType := GET_ID ;
+ variable buf : line ;
+ variable Empty : boolean ;
+ variable MultiLineComment : boolean := FALSE ;
+ variable Name : string(1 to 80) ;
+ variable NameLen : integer ;
+ variable AlertLogID : AlertLogIDType ;
+ variable ReadAnEnable : boolean ;
+ variable LogLevel : LogType ;
+ begin
+ ReadState := GET_ID ;
+ ReadLineLoop : while not EndFile(AlertLogInitFile) loop
+ ReadLine(AlertLogInitFile, buf) ;
+ if ReadAnEnable then
+ -- Read one or more enable values, next line read AlertLog name
+ -- Note that any newline with ReadAnEnable TRUE will result in
+ -- searching for another AlertLogID name - this includes multi-line comments.
+ ReadState := GET_ID ;
+ end if ;
+
+ ReadNameLoop : loop
+ EmptyOrCommentLine(buf, Empty, MultiLineComment) ;
+ next ReadLineLoop when Empty ;
+
+ case ReadState is
+ when GET_ID =>
+ sread(buf, Name, NameLen) ;
+ exit ReadNameLoop when NameLen = 0 ;
+ AlertLogID := GetAlertLogID(Name(1 to NameLen), ALERTLOG_ID_NOT_ASSIGNED) ;
+ ReadState := GET_ENABLE ;
+ ReadAnEnable := FALSE ;
+
+ when GET_ENABLE =>
+ sread(buf, Name, NameLen) ;
+ exit ReadNameLoop when NameLen = 0 ;
+ ReadAnEnable := TRUE ;
+ if not IsLogEnableType(Name(1 to NameLen)) then
+ Alert(OSVVM_ALERTLOG_ID, "AlertLogPkg.ReadLogEnables: Found Invalid LogEnable: " & Name(1 to NameLen)) ;
+ exit ReadNameLoop ;
+ end if ;
+ LogLevel := LogType'value(Name(1 to NameLen)) ;
+ SetLogEnable(AlertLogID, LogLevel, TRUE) ;
+ end case ;
+ end loop ReadNameLoop ;
+ end loop ReadLineLoop ;
+ end procedure ReadLogEnables ;
+
+ ------------------------------------------------------------
+ procedure ReadLogEnables (FileName : string) is
+ ------------------------------------------------------------
+ file AlertLogInitFile : text open READ_MODE is FileName ;
+ begin
+ ReadLogEnables(AlertLogInitFile) ;
+ end procedure ReadLogEnables ;
+
+ ------------------------------------------------------------
+ function PathTail (A : string) return string is
+ ------------------------------------------------------------
+ alias aA : string(1 to A'length) is A ;
+ begin
+ for i in aA'length - 1 downto 1 loop
+ if aA(i) = ':' then
+ return aA(i+1 to aA'length-1) ;
+ end if ;
+ end loop ;
+ return aA ;
+ end function PathTail ;
+
+end package body AlertLogPkg ; \ No newline at end of file
diff --git a/testsuite/gna/issue317/OSVVM/NamePkg.vhd b/testsuite/gna/issue317/OSVVM/NamePkg.vhd
new file mode 100644
index 000000000..44e4ec6cf
--- /dev/null
+++ b/testsuite/gna/issue317/OSVVM/NamePkg.vhd
@@ -0,0 +1,129 @@
+--
+-- File Name: NamePkg.vhd
+-- Design Unit Name: NamePkg
+-- Revision: STANDARD VERSION
+--
+-- Maintainer: Jim Lewis email: jim@synthworks.com
+-- Contributor(s):
+-- Jim Lewis SynthWorks
+--
+--
+-- Package Defines
+-- Data structure for name.
+--
+-- Developed for:
+-- SynthWorks Design Inc.
+-- VHDL Training Classes
+-- 11898 SW 128th Ave. Tigard, Or 97223
+-- http://www.SynthWorks.com
+--
+-- Latest standard version available at:
+-- http://www.SynthWorks.com/downloads
+--
+-- Revision History:
+-- Date Version Description
+-- 06/2010: 0.1 Initial revision
+-- 07/2014: 2014.07 Moved specialization required by CoveragePkg to CoveragePkg
+-- Separated name handling from message handling to simplify naming
+-- 12/2014: 2014.07a Removed initialized pointers which can lead to memory leaks.
+-- 05/2015 2015.06 Added input to Get to return when not initialized
+--
+--
+-- Copyright (c) 2010 - 2015 by SynthWorks Design Inc. All rights reserved.
+--
+-- Verbatim copies of this source file may be used and
+-- distributed without restriction.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the ARTISTIC License
+-- as published by The Perl Foundation; either version 2.0 of
+-- the License, or (at your option) any later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the Artistic License for details.
+--
+-- You should have received a copy of the license with this source.
+-- If not download it from,
+-- http://www.perlfoundation.org/artistic_license_2_0
+--
+
+use std.textio.all ;
+
+package NamePkg is
+
+ type NamePType is protected
+ procedure Set (NameIn : String) ;
+ impure function Get (DefaultName : string := "") return string ;
+ impure function GetOpt return string ;
+ impure function IsSet return boolean ;
+ procedure Clear ; -- clear name
+ procedure Deallocate ; -- effectively alias to clear name
+ end protected NamePType ;
+
+end package NamePkg ;
+
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+
+package body NamePkg is
+ type NamePType is protected body
+
+ variable NamePtr : line ;
+
+ ------------------------------------------------------------
+ procedure Set (NameIn : String) is
+ ------------------------------------------------------------
+ begin
+ deallocate(NamePtr) ;
+ NamePtr := new string'(NameIn) ;
+ end procedure Set ;
+
+ ------------------------------------------------------------
+ impure function Get (DefaultName : string := "") return string is
+ ------------------------------------------------------------
+ begin
+ if NamePtr = NULL then
+ return DefaultName ;
+ else
+ return NamePtr.all ;
+ end if ;
+ end function Get ;
+
+ ------------------------------------------------------------
+ impure function GetOpt return string is
+ ------------------------------------------------------------
+ begin
+ if NamePtr = NULL then
+ return NUL & "" ;
+ else
+ return NamePtr.all ;
+ end if ;
+ end function GetOpt ;
+
+ ------------------------------------------------------------
+ impure function IsSet return boolean is
+ ------------------------------------------------------------
+ begin
+ return NamePtr /= NULL ;
+ end function IsSet ;
+
+ ------------------------------------------------------------
+ procedure Clear is -- clear name
+ ------------------------------------------------------------
+ begin
+ deallocate(NamePtr) ;
+ end procedure Clear ;
+
+ ------------------------------------------------------------
+ procedure Deallocate is -- clear name
+ ------------------------------------------------------------
+ begin
+ Clear ;
+ end procedure Deallocate ;
+
+ end protected body NamePType ;
+
+end package body NamePkg ; \ No newline at end of file
diff --git a/testsuite/gna/issue317/OSVVM/OsvvmGlobalPkg.vhd b/testsuite/gna/issue317/OSVVM/OsvvmGlobalPkg.vhd
new file mode 100644
index 000000000..1d61e2bd3
--- /dev/null
+++ b/testsuite/gna/issue317/OSVVM/OsvvmGlobalPkg.vhd
@@ -0,0 +1,350 @@
+--
+-- File Name: OsvvmGlobalPkg.vhd
+-- Design Unit Name: OsvvmGlobalPkg
+-- Revision: STANDARD VERSION, revision 2015.01
+--
+-- Maintainer: Jim Lewis email: jim@synthworks.com
+-- Contributor(s):
+-- Jim Lewis jim@synthworks.com
+--
+--
+-- Description:
+-- Global Settings for OSVVM packages
+--
+--
+-- Developed for:
+-- SynthWorks Design Inc.
+-- VHDL Training Classes
+-- 11898 SW 128th Ave. Tigard, Or 97223
+-- http://www.SynthWorks.com
+--
+-- Revision History:
+-- Date Version Description
+-- 01/2014: 2015.01 Initial revision
+--
+--
+-- Copyright (c) 2015 by SynthWorks Design Inc. All rights reserved.
+--
+-- Verbatim copies of this source file may be used and
+-- distributed without restriction.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the ARTISTIC License
+-- as published by The Perl Foundation; either version 2.0 of
+-- the License, or (at your option) any later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the Artistic License for details.
+--
+-- You should have received a copy of the license with this source.
+-- If not download it from,
+-- http://www.perlfoundation.org/artistic_license_2_0
+--
+
+library ieee ;
+use std.textio.all ;
+
+use work.NamePkg.all ;
+
+package OsvvmGlobalPkg is
+ -- FILE IO Global File Identifier -- Open using AlertLogPkg.TranscriptOpen
+-- file TranscriptFile : text ;
+
+ -- Shared Options Type used in OSVVM
+ type OsvvmOptionsType is (OPT_INIT_PARM_DETECT, OPT_USE_DEFAULT, DISABLED, FALSE, ENABLED, TRUE) ;
+ function IsEnabled (A : OsvvmOptionsType) return boolean ; -- Requires that TRUE is last and ENABLED is 2nd to last
+ function to_OsvvmOptionsType (A : boolean) return OsvvmOptionsType ;
+
+ -- Defaults for String values
+ constant OSVVM_DEFAULT_ALERT_PREFIX : string := "%% Alert" ;
+ constant OSVVM_DEFAULT_LOG_PREFIX : string := "%% Log " ;
+ constant OSVVM_DEFAULT_WRITE_PREFIX : string := "%% " ;
+ constant OSVVM_DEFAULT_DONE_NAME : string := "DONE" ;
+ constant OSVVM_DEFAULT_PASS_NAME : string := "PASSED" ;
+ constant OSVVM_DEFAULT_FAIL_NAME : string := "FAILED" ;
+ constant OSVVM_STRING_INIT_PARM_DETECT : string := NUL & NUL & NUL ;
+ constant OSVVM_STRING_USE_DEFAULT : string := NUL & "" ;
+
+ -- Coverage Settings
+ constant OSVVM_DEFAULT_WRITE_PASS_FAIL : OsvvmOptionsType := FALSE ;
+ constant OSVVM_DEFAULT_WRITE_BIN_INFO : OsvvmOptionsType := TRUE ;
+ constant OSVVM_DEFAULT_WRITE_COUNT : OsvvmOptionsType := TRUE ;
+ constant OSVVM_DEFAULT_WRITE_ANY_ILLEGAL : OsvvmOptionsType := FALSE ;
+
+ ------------------------------------------------------------
+ procedure SetOsvvmGlobalOptions (
+ ------------------------------------------------------------
+ WritePassFail : OsvvmOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteBinInfo : OsvvmOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteCount : OsvvmOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAnyIllegal : OsvvmOptionsType := OPT_INIT_PARM_DETECT ;
+ WritePrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ DoneName : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ PassName : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ FailName : string := OSVVM_STRING_INIT_PARM_DETECT
+ ) ;
+
+ ------------------------------------------------------------
+ -- Accessor Functions
+ function ResolveOsvvmOption(A, B, C : OsvvmOptionsType) return OsvvmOptionsType ;
+ function ResolveOsvvmOption(A, B, C, D : OsvvmOptionsType) return OsvvmOptionsType ;
+ function IsOsvvmStringSet (A : string) return boolean ;
+ function ResolveOsvvmOption(A, B : string) return string ;
+ function ResolveOsvvmOption(A, B, C : string) return string ;
+ function ResolveOsvvmOption(A, B, C, D : string) return string ;
+
+ impure function ResolveOsvvmWritePrefix(A : String) return string ;
+ impure function ResolveOsvvmWritePrefix(A, B : String) return string ;
+ impure function ResolveOsvvmDoneName(A : String) return string ;
+ impure function ResolveOsvvmDoneName(A, B : String) return string ;
+ impure function ResolveOsvvmPassName(A : String) return string ;
+ impure function ResolveOsvvmPassName(A, B : String) return string ;
+ impure function ResolveOsvvmFailName(A : String) return string ;
+ impure function ResolveOsvvmFailName(A, B : String) return string ;
+
+ impure function ResolveCovWritePassFail(A, B : OsvvmOptionsType) return OsvvmOptionsType ; -- Cov
+ impure function ResolveCovWriteBinInfo(A, B : OsvvmOptionsType) return OsvvmOptionsType ; -- Cov
+ impure function ResolveCovWriteCount(A, B : OsvvmOptionsType) return OsvvmOptionsType ; -- Cov
+ impure function ResolveCovWriteAnyIllegal(A, B : OsvvmOptionsType) return OsvvmOptionsType ; -- Cov
+
+ procedure OsvvmDeallocate ;
+
+ type OptionsPType is protected
+ procedure Set (A: OsvvmOptionsType) ;
+ impure function get return OsvvmOptionsType ;
+ end protected OptionsPType ;
+end OsvvmGlobalPkg ;
+
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+
+package body OsvvmGlobalPkg is
+ type OptionsPType is protected body
+ variable GlobalVar : OsvvmOptionsType ;
+ procedure Set (A : OsvvmOptionsType) is
+ begin
+ GlobalVar := A ;
+ end procedure Set ;
+ impure function get return OsvvmOptionsType is
+ begin
+ return GlobalVar ;
+ end function get ;
+ end protected body OptionsPType ;
+
+ shared variable WritePrefixVar : NamePType ;
+ shared variable DoneNameVar : NamePType ;
+ shared variable PassNameVar : NamePType ;
+ shared variable FailNameVar : NamePType ;
+ shared variable WritePassFailVar : OptionsPType ; -- := FALSE ;
+ shared variable WriteBinInfoVar : OptionsPType ; -- := TRUE ;
+ shared variable WriteCountVar : OptionsPType ; -- := TRUE ;
+ shared variable WriteAnyIllegalVar : OptionsPType ; -- := FALSE ;
+
+ function IsEnabled (A : OsvvmOptionsType) return boolean is
+ begin
+ return A >= ENABLED ;
+ end function IsEnabled ;
+
+ function to_OsvvmOptionsType (A : boolean) return OsvvmOptionsType is
+ begin
+ if A then
+ return TRUE ;
+ else
+ return FALSE ;
+ end if ;
+ end function to_OsvvmOptionsType ;
+
+
+ ------------------------------------------------------------
+ procedure SetOsvvmGlobalOptions (
+ ------------------------------------------------------------
+ WritePassFail : OsvvmOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteBinInfo : OsvvmOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteCount : OsvvmOptionsType := OPT_INIT_PARM_DETECT ;
+ WriteAnyIllegal : OsvvmOptionsType := OPT_INIT_PARM_DETECT ;
+ WritePrefix : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ DoneName : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ PassName : string := OSVVM_STRING_INIT_PARM_DETECT ;
+ FailName : string := OSVVM_STRING_INIT_PARM_DETECT
+ ) is
+ begin
+ if WritePassFail /= OPT_INIT_PARM_DETECT then
+ WritePassFailVar.Set(WritePassFail) ;
+ end if ;
+ if WriteBinInfo /= OPT_INIT_PARM_DETECT then
+ WriteBinInfoVar.Set(WriteBinInfo) ;
+ end if ;
+ if WriteCount /= OPT_INIT_PARM_DETECT then
+ WriteCountVar.Set(WriteCount) ;
+ end if ;
+ if WriteAnyIllegal /= OPT_INIT_PARM_DETECT then
+ WriteAnyIllegalVar.Set(WriteAnyIllegal) ;
+ end if ;
+ if WritePrefix /= OSVVM_STRING_INIT_PARM_DETECT then
+ WritePrefixVar.Set(WritePrefix) ;
+ end if ;
+ if DoneName /= OSVVM_STRING_INIT_PARM_DETECT then
+ DoneNameVar.Set(DoneName) ;
+ end if ;
+ if PassName /= OSVVM_STRING_INIT_PARM_DETECT then
+ PassNameVar.Set(PassName) ;
+ end if ;
+ if FailName /= OSVVM_STRING_INIT_PARM_DETECT then
+ FailNameVar.Set(FailName) ;
+ end if ;
+ end procedure SetOsvvmGlobalOptions ;
+
+ ------------------------------------------------------------
+ -- Accessor Functions
+ -- Local Function
+ function IsOsvvmOptionSet (A : OsvvmOptionsType) return boolean is
+ begin
+ return A > OPT_USE_DEFAULT ;
+ end function IsOsvvmOptionSet ;
+
+ function ResolveOsvvmOption(A, B, C : OsvvmOptionsType) return OsvvmOptionsType is
+ begin
+ if IsOsvvmOptionSet(A) then
+ return A ;
+ elsif IsOsvvmOptionSet(B) then
+ return B ;
+ else
+ return C ;
+ end if ;
+ end function ResolveOsvvmOption ;
+
+ function ResolveOsvvmOption(A, B, C, D : OsvvmOptionsType) return OsvvmOptionsType is
+ begin
+ if IsOsvvmOptionSet(A) then
+ return A ;
+ elsif IsOsvvmOptionSet(B) then
+ return B ;
+ elsif IsOsvvmOptionSet(C) then
+ return C ;
+ else
+ return D ;
+ end if ;
+ end function ResolveOsvvmOption ;
+
+ -- Local Function
+ function IsOsvvmStringSet (A : string) return boolean is
+ begin
+ if A'length = 0 then -- Null strings permitted
+ return TRUE ;
+ else
+ return A(A'left) /= NUL ;
+ end if;
+ end function IsOsvvmStringSet ;
+
+ function ResolveOsvvmOption(A, B : string) return string is
+ begin
+ if IsOsvvmStringSet(A) then
+ return A ;
+ else
+ return B ;
+ end if ;
+ end function ResolveOsvvmOption ;
+
+ function ResolveOsvvmOption(A, B, C : string) return string is
+ begin
+ if IsOsvvmStringSet(A) then
+ return A ;
+ elsif IsOsvvmStringSet(B) then
+ return B ;
+ else
+ return C ;
+ end if ;
+ end function ResolveOsvvmOption ;
+
+ function ResolveOsvvmOption(A, B, C, D : string) return string is
+ begin
+ if IsOsvvmStringSet(A) then
+ return A ;
+ elsif IsOsvvmStringSet(B) then
+ return B ;
+ elsif IsOsvvmStringSet(C) then
+ return C ;
+ else
+ return D ;
+ end if ;
+ end function ResolveOsvvmOption ;
+
+
+ impure function ResolveOsvvmWritePrefix(A : String) return string is
+ begin
+ return ResolveOsvvmOption(A, WritePrefixVar.GetOpt, OSVVM_DEFAULT_WRITE_PREFIX) ;
+ end function ResolveOsvvmWritePrefix ;
+
+ impure function ResolveOsvvmWritePrefix(A, B : String) return string is
+ begin
+ return ResolveOsvvmOption(A, B, WritePrefixVar.GetOpt, OSVVM_DEFAULT_WRITE_PREFIX) ;
+ end function ResolveOsvvmWritePrefix ;
+
+ impure function ResolveOsvvmDoneName(A : String) return string is
+ begin
+ return ResolveOsvvmOption(A, DoneNameVar.GetOpt, OSVVM_DEFAULT_DONE_NAME) ;
+ end function ResolveOsvvmDoneName ;
+
+ impure function ResolveOsvvmDoneName(A, B : String) return string is
+ begin
+ return ResolveOsvvmOption(A, DoneNameVar.GetOpt, OSVVM_DEFAULT_DONE_NAME) ;
+ end function ResolveOsvvmDoneName ;
+
+ impure function ResolveOsvvmPassName(A : String) return string is
+ begin
+ return ResolveOsvvmOption(A, PassNameVar.GetOpt, OSVVM_DEFAULT_PASS_NAME) ;
+ end function ResolveOsvvmPassName ;
+
+ impure function ResolveOsvvmPassName(A, B : String) return string is
+ begin
+ return ResolveOsvvmOption(A, B, PassNameVar.GetOpt, OSVVM_DEFAULT_PASS_NAME) ;
+ end function ResolveOsvvmPassName ;
+
+ impure function ResolveOsvvmFailName(A : String) return string is
+ begin
+ return ResolveOsvvmOption(A, FailNameVar.GetOpt, OSVVM_DEFAULT_FAIL_NAME) ;
+ end function ResolveOsvvmFailName ;
+
+ impure function ResolveOsvvmFailName(A, B : String) return string is
+ begin
+ return ResolveOsvvmOption(A, B, FailNameVar.GetOpt, OSVVM_DEFAULT_FAIL_NAME) ;
+ end function ResolveOsvvmFailName ;
+
+ impure function ResolveCovWritePassFail(A, B : OsvvmOptionsType) return OsvvmOptionsType is
+ begin
+ return ResolveOsvvmOption(A, B, WritePassFailVar.Get, OSVVM_DEFAULT_WRITE_PASS_FAIL) ;
+ end function ResolveCovWritePassFail ; -- Cov
+
+ impure function ResolveCovWriteBinInfo(A, B : OsvvmOptionsType) return OsvvmOptionsType is
+ begin
+ return ResolveOsvvmOption(A, B, WriteBinInfoVar.Get, OSVVM_DEFAULT_WRITE_BIN_INFO) ;
+ end function ResolveCovWriteBinInfo ; -- Cov
+
+ impure function ResolveCovWriteCount(A, B : OsvvmOptionsType) return OsvvmOptionsType is
+ begin
+ return ResolveOsvvmOption(A, B, WriteCountVar.Get, OSVVM_DEFAULT_WRITE_COUNT) ;
+ end function ResolveCovWriteCount ; -- Cov
+
+ impure function ResolveCovWriteAnyIllegal(A, B : OsvvmOptionsType) return OsvvmOptionsType is
+ begin
+ return ResolveOsvvmOption(A, B, WriteAnyIllegalVar.Get, OSVVM_DEFAULT_WRITE_ANY_ILLEGAL) ;
+ end function ResolveCovWriteAnyIllegal ; -- Cov
+
+ procedure OsvvmDeallocate is
+ begin
+ -- Free up space used by NamePType within OsvvmGlobalPkg
+ WritePrefixVar.Deallocate ;
+ DoneNameVar.Deallocate ;
+ PassNameVar.Deallocate ;
+ FailNameVar.Deallocate ;
+ WritePassFailVar.Set(FALSE) ; -- := FALSE ;
+ WriteBinInfoVar.Set(TRUE ) ; -- := TRUE ;
+ WriteCountVar.Set(TRUE ) ; -- := TRUE ;
+ WriteAnyIllegalVar.Set(FALSE) ; -- := FALSE ;
+
+ end procedure OsvvmDeallocate ;
+
+end package body OsvvmGlobalPkg ; \ No newline at end of file
diff --git a/testsuite/gna/issue317/OSVVM/RandomBasePkg.vhd b/testsuite/gna/issue317/OSVVM/RandomBasePkg.vhd
new file mode 100644
index 000000000..9dc00d8e2
--- /dev/null
+++ b/testsuite/gna/issue317/OSVVM/RandomBasePkg.vhd
@@ -0,0 +1,234 @@
+--
+-- File Name: RandomBasePkg.vhd
+-- Design Unit Name: RandomBasePkg
+-- Revision: STANDARD VERSION
+--
+-- Maintainer: Jim Lewis email: jim@synthworks.com
+-- Contributor(s):
+-- Jim Lewis jim@synthworks.com
+--
+--
+-- Description:
+-- Defines Base randomization, seed definition, seed generation,
+-- and seed IO functionality for RandomPkg.vhd
+-- Defines:
+-- Procedure Uniform - baseline randomization
+-- Type RandomSeedType - the seed as a single object
+-- function GenRandSeed from integer_vector, integer, or string
+-- IO function to_string, & procedures write, read
+--
+-- In revision 2.0 these types and functions are included by package reference.
+-- Long term these will be passed as generics to RandomGenericPkg
+--
+--
+-- Developed for:
+-- SynthWorks Design Inc.
+-- VHDL Training Classes
+-- 11898 SW 128th Ave. Tigard, Or 97223
+-- http://www.SynthWorks.com
+--
+-- Revision History:
+-- Date Version Description
+-- 01/2008: 0.1 Initial revision
+-- Numerous revisions for VHDL Testbenches and Verification
+-- 02/2009: 1.0 First Public Released Version
+-- 02/25/2009 1.1 Replaced reference to std_2008 with a reference
+-- to ieee_proposed.standard_additions.all ;
+-- 03/01/2011 2.0 STANDARD VERSION
+-- Fixed abstraction by moving RandomParmType to RandomPkg.vhd
+-- 4/2013 2013.04 No Changes
+-- 5/2013 2013.05 No Changes
+-- 1/2015 2015.01 Changed Assert/Report to Alert
+-- 6/2015 2015.06 Changed GenRandSeed to impure
+--
+--
+-- Copyright (c) 2008 - 2015 by SynthWorks Design Inc. All rights reserved.
+--
+-- Verbatim copies of this source file may be used and
+-- distributed without restriction.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the ARTISTIC License
+-- as published by The Perl Foundation; either version 2.0 of
+-- the License, or (at your option) any later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the Artistic License for details.
+--
+-- You should have received a copy of the license with this source.
+-- If not download it from,
+-- http://www.perlfoundation.org/artistic_license_2_0
+--
+
+library ieee ;
+use ieee.math_real.all ;
+use std.textio.all ;
+
+use work.OsvvmGlobalPkg.all ;
+use work.AlertLogPkg.all ;
+
+-- comment out following 2 lines with VHDL-2008. Leave in for VHDL-2002
+-- library ieee_proposed ; -- remove with VHDL-2008
+-- use ieee_proposed.standard_additions.all ; -- remove with VHDL-2008
+
+
+package RandomBasePkg is
+
+ -- RandomSeedType and Uniform can be replaced by any procedure that
+ -- produces a uniform distribution with 0 <= Value < 1 or 0 < Value < 1
+ -- and maintains the same call interface
+ type RandomSeedType is array (1 to 2) of integer ;
+ procedure Uniform (Result : out real ; Seed : inout RandomSeedType) ;
+
+ -- Translate from integer_vector, integer, or string to RandomSeedType
+ -- Required by RandomPkg.InitSeed
+ -- GenRandSeed makes sure all values are in a valid range
+ impure function GenRandSeed(IV : integer_vector) return RandomSeedType ;
+ impure function GenRandSeed(I : integer) return RandomSeedType ;
+ impure function GenRandSeed(S : string) return RandomSeedType ;
+
+ -- IO for RandomSeedType. If use subtype, then create aliases here
+ -- in a similar fashion VHDL-2008 std_logic_textio.
+ -- Not required by RandomPkg
+ function to_string(A : RandomSeedType) return string ;
+ procedure write(variable L: inout line ; A : RandomSeedType ) ;
+ procedure read (variable L: inout line ; A : out RandomSeedType ; good : out boolean ) ;
+ procedure read (variable L: inout line ; A : out RandomSeedType ) ;
+
+end RandomBasePkg ;
+
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+
+package body RandomBasePkg is
+
+ -----------------------------------------------------------------
+ -- Uniform
+ -- Generate a random number with a Uniform distribution
+ -- Required by RandomPkg. All randomization is derived from here.
+ -- Value produced must be either:
+ -- 0 <= Value < 1 or 0 < Value < 1
+ --
+ -- Current version uses ieee.math_real.Uniform
+ -- This abstraction allows higher precision version
+ -- of a uniform distribution to be used provided
+ --
+ procedure Uniform (
+ Result : out real ;
+ Seed : inout RandomSeedType
+ ) is
+ begin
+ ieee.math_real.Uniform (Seed(Seed'left), Seed(Seed'right), Result) ;
+ end procedure Uniform ;
+
+
+ -----------------------------------------------------------------
+ -- GenRandSeed
+ -- Convert integer_vector to RandomSeedType
+ -- Uniform requires two seed values of the form:
+ -- 1 <= SEED1 <= 2147483562; 1 <= SEED2 <= 2147483398
+ --
+ -- if 2 seed values are passed to GenRandSeed and they are
+ -- in the above range, then they must remain unmodified.
+ --
+ impure function GenRandSeed(IV : integer_vector) return RandomSeedType is
+ alias iIV : integer_vector(1 to IV'length) is IV ;
+ variable Seed1 : integer ;
+ variable Seed2 : integer ;
+ constant SEED1_MAX : integer := 2147483562 ;
+ constant SEED2_MAX : integer := 2147483398 ;
+ begin
+ if iIV'Length <= 0 then -- no seed
+ Alert(OSVVM_ALERTLOG_ID, "RandomBasePkg.GenRandSeed received NULL integer_vector", FAILURE) ;
+ return (3, 17) ; -- if continue seed = (3, 17)
+
+ elsif iIV'Length = 1 then -- one seed value
+ -- inefficient handling, but condition is unlikely
+ return GenRandSeed(iIV(1)) ; -- generate a seed
+
+ else -- only use the left two values
+ -- 1 <= SEED1 <= 2147483562
+ -- mod returns 0 to MAX-1, the -1 adjusts legal values, +1 adjusts them back
+ Seed1 := ((iIV(1)-1) mod SEED1_MAX) + 1 ;
+ -- 1 <= SEED2 <= 2147483398
+ Seed2 := ((iIV(2)-1) mod SEED2_MAX) + 1 ;
+ return (Seed1, Seed2) ;
+ end if ;
+ end function GenRandSeed ;
+
+
+ -----------------------------------------------------------------
+ -- GenRandSeed
+ -- transform a single integer into the internal seed
+ --
+ impure function GenRandSeed(I : integer) return RandomSeedType is
+ variable result : integer_vector(1 to 2) ;
+ begin
+ result(1) := I ;
+ result(2) := I/3 + 1 ;
+ return GenRandSeed(result) ; -- make value ranges legal
+ end function GenRandSeed ;
+
+
+ -----------------------------------------------------------------
+ -- GenRandSeed
+ -- transform a string value into the internal seed
+ -- usage: RV.GenRandSeed(RV'instance_path));
+ --
+ impure function GenRandSeed(S : string) return RandomSeedType is
+ constant LEN : integer := S'length ;
+ constant HALF_LEN : integer := LEN/2 ;
+ alias revS : string(LEN downto 1) is S ;
+ variable result : integer_vector(1 to 2) ;
+ variable temp : integer := 0 ;
+ begin
+ for i in 1 to HALF_LEN loop
+ temp := (temp + character'pos(revS(i))) mod (integer'right - 2**8) ;
+ end loop ;
+ result(1) := temp ;
+ for i in HALF_LEN + 1 to LEN loop
+ temp := (temp + character'pos(revS(i))) mod (integer'right - 2**8) ;
+ end loop ;
+ result(2) := temp ;
+ return GenRandSeed(result) ; -- make value ranges legal
+ end function GenRandSeed ;
+
+
+ -----------------------------------------------------------------
+ function to_string(A : RandomSeedType) return string is
+ begin
+ return to_string(A(A'left)) & " " & to_string(A(A'right)) ;
+ end function to_string ;
+
+
+ -----------------------------------------------------------------
+ procedure write(variable L: inout line ; A : RandomSeedType ) is
+ begin
+ write(L, to_string(A)) ;
+ end procedure ;
+
+
+ -----------------------------------------------------------------
+ procedure read(variable L: inout line ; A : out RandomSeedType ; good : out boolean ) is
+ variable iReadValid : boolean ;
+ begin
+ for i in A'range loop
+ read(L, A(i), iReadValid) ;
+ exit when not iReadValid ;
+ end loop ;
+ good := iReadValid ;
+ end procedure read ;
+
+
+ -----------------------------------------------------------------
+ procedure read(variable L: inout line ; A : out RandomSeedType ) is
+ variable ReadValid : boolean ;
+ begin
+ read(L, A, ReadValid) ;
+ AlertIfNot(ReadValid, OSVVM_ALERTLOG_ID, "RandomBasePkg.read[line, RandomSeedType] failed", FAILURE) ;
+ end procedure read ;
+
+end RandomBasePkg ; \ No newline at end of file
diff --git a/testsuite/gna/issue317/OSVVM/RandomPkg.vhd b/testsuite/gna/issue317/OSVVM/RandomPkg.vhd
new file mode 100644
index 000000000..8c5065881
--- /dev/null
+++ b/testsuite/gna/issue317/OSVVM/RandomPkg.vhd
@@ -0,0 +1,1647 @@
+--
+-- File Name : RandomPkg.vhd
+-- Design Unit Name : RandomPkg
+-- Revision : STANDARD VERSION
+--
+-- Maintainer : Jim Lewis email : jim@synthworks.com
+-- Contributor(s) :
+-- Jim Lewis email : jim@synthworks.com
+-- *
+--
+-- * In writing procedures normal, poisson, the following sources were referenced :
+-- Wikipedia
+-- package rnd2 written by John Breen and Ken Christensen
+-- package RNG written by Gnanasekaran Swaminathan
+--
+--
+-- Description :
+-- RandomPType, a protected type, defined to hold randomization RandomSeeds and
+-- function methods to facilitate randomization with uniform and weighted
+-- distributions
+--
+-- Developed for :
+-- SynthWorks Design Inc.
+-- VHDL Training Classes
+-- 11898 SW 128th Ave. Tigard, Or 97223
+-- http ://www.SynthWorks.com
+--
+-- Revision History :
+-- Date Version Description
+-- 12/2006 : 0.1 Initial revision
+-- Numerous revisions for SynthWorks' Advanced VHDL Testbenches and Verification
+-- 02/2009 : 1.0 First Public Released Version
+-- 02/25/2009 1.1 Replaced reference to std_2008 with a reference to
+-- ieee_proposed.standard_additions.all ;
+-- 06/2010 1.2 Added Normal and Poisson distributions
+-- 03/2011 2.0 Major clean-up. Moved RandomParmType and control to here
+-- 07/2011 2.1 Bug fix to convenience functions for slv, unsigned, and signed.
+-- 06/2012 2.2 Removed '_' in the name of subprograms FavorBig and FavorSmall
+-- 04/2013 2013.04 Changed DistInt. Return array indices now match input
+-- Better Min, Max error handling in Uniform, FavorBig, FavorSmall, Normal, Poisson
+-- 5/2013 - Removed extra variable declaration in functions RandInt and RandReal
+-- 5/2013 2013.05 Big vector randomization added overloading RandUnsigned, RandSlv, and RandSigned
+-- Added NULL_RANGE_TYPE to minimize null range warnings
+-- 1/2014 2014.01 Added RandTime, RandReal(set), RandIntV, RandRealV, RandTimeV
+-- Made sort, revsort from SortListPkg_int visible via aliases
+-- 1/2015 2015.01 Changed Assert/Report to Alert
+-- 5/2015 2015.06 Revised Alerts to Alert(OSVVM_ALERTLOG_ID, ...) ;
+-- 11/2016 2016.11 No changes. Updated release numbers to make documentation and
+-- package have consistent release identifiers.
+--
+-- Copyright (c) 2006 - 2016 by SynthWorks Design Inc. All rights reserved.
+--
+-- Verbatim copies of this source file may be used and
+-- distributed without restriction.
+--
+-- This source file is free software ; you can redistribute it
+-- and/or modify it under the terms of the ARTISTIC License
+-- as published by The Perl Foundation ; either version 2.0 of
+-- the License, or (at your option) any later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY ; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the Artistic License for details.
+--
+-- You should have received a copy of the license with this source.
+-- If not download it from,
+-- http ://www.perlfoundation.org/artistic_license_2_0
+--
+
+use work.OsvvmGlobalPkg.all ;
+use work.AlertLogPkg.all ;
+use work.RandomBasePkg.all ;
+use work.SortListPkg_int.all ;
+
+use std.textio.all ;
+
+library ieee ;
+use ieee.std_logic_1164.all ;
+use ieee.numeric_std.all ;
+use ieee.numeric_std_unsigned.all ;
+use ieee.math_real.all ;
+
+-- comment out following 3 lines with VHDL-2008. Leave in for VHDL-2002
+-- library ieee_proposed ; -- remove with VHDL-2008
+-- use ieee_proposed.standard_additions.all ; -- remove with VHDL-2008
+-- use ieee_proposed.standard_textio_additions.all ; -- remove with VHDL-2008
+
+
+package RandomPkg is
+-- Uncomment the following with VHDL-2008 package generics.
+-- For now they are defined in the package RandomBasePkg.vhd
+-- package RandomGenericPkg is
+ -- generic (
+ -- type RandomSeedType ; -- base type for randomization
+ -- procedure Uniform (Result : out real ; Seed : inout RandomSeedType) ;
+ -- function GenRandSeed(IV : integer_vector) return RandomSeedType ;
+ -- function GenRandSeed(I : integer) return RandomSeedType ;
+ -- function GenRandSeed(S : string) return RandomSeedType ;
+ -- ) ;
+
+ -- make things from SortListPkg_int visible
+ alias sort is work.SortListPkg_int.sort[integer_vector return integer_vector] ;
+ alias revsort is work.SortListPkg_int.revsort[integer_vector return integer_vector] ;
+
+ -- note NULL_RANGE_TYPE should probably be in std.standard
+ subtype NULL_RANGE_TYPE is integer range 0 downto 1 ;
+ constant NULL_INTV : integer_vector (NULL_RANGE_TYPE) := (others => 0) ;
+
+ -- Supports DistValInt functionality
+ type DistRecType is record
+ Value : integer ;
+ Weight : integer ;
+ end record ;
+ type DistType is array (natural range <>) of DistRecType ;
+
+
+ -- Parameters for randomization
+ -- RandomDistType specifies the distribution to use for randomize
+ type RandomDistType is (NONE, UNIFORM, FAVOR_SMALL, FAVOR_BIG, NORMAL, POISSON) ;
+
+ type RandomParmType is record
+ Distribution : RandomDistType ;
+ Mean : Real ; -- also used as probability of success
+ StdDeviation : Real ; -- also used as number of trials for binomial
+ end record ;
+
+ -- RandomParm IO
+ function to_string(A : RandomDistType) return string ;
+ procedure write(variable L : inout line ; A : RandomDistType ) ;
+ procedure read(variable L : inout line ; A : out RandomDistType ; good : out boolean ) ;
+ procedure read(variable L : inout line ; A : out RandomDistType ) ;
+ function to_string(A : RandomParmType) return string ;
+ procedure write(variable L : inout line ; A : RandomParmType ) ;
+ procedure read(variable L : inout line ; A : out RandomParmType ; good : out boolean ) ;
+ procedure read(variable L : inout line ; A : out RandomParmType ) ;
+
+
+ type RandomPType is protected
+ -- Seed Manipulation
+ -- Known ambiguity between InitSeed with string and integer_vector
+ -- Recommendation, use : RV.InitSeed(RV'instance_path) ;
+ -- For integer_vector use either : RV.InitSeed(IV => (1,5)) ;
+ -- or : RV.InitSeed(integer_vector'(1,5)) ;
+ procedure InitSeed (S : string ) ;
+ procedure InitSeed (I : integer ) ;
+ procedure InitSeed (IV : integer_vector ) ;
+
+ -- SetSeed & GetSeed : Used to save and restore seed values
+ procedure SetSeed (RandomSeedIn : RandomSeedType ) ;
+ impure function GetSeed return RandomSeedType ;
+ -- SeedRandom = SetSeed & GetSeed for SV compatibility
+ -- replace with aliases when they work in popular simulators
+ procedure SeedRandom (RandomSeedIn : RandomSeedType ) ;
+ impure function SeedRandom return RandomSeedType ;
+ -- alias SeedRandom is SetSeed [RandomSeedType] ;
+ -- alias SeedRandom is GetSeed [return RandomSeedType] ;
+
+ -- Setting Randomization Parameters
+ -- Allows RandInt to have distributions other than uniform
+ procedure SetRandomParm (RandomParmIn : RandomParmType) ;
+ procedure SetRandomParm (
+ Distribution : RandomDistType ;
+ Mean : Real := 0.0 ;
+ Deviation : Real := 0.0
+ ) ;
+ impure function GetRandomParm return RandomParmType ;
+ impure function GetRandomParm return RandomDistType ;
+
+ -- For compatibility with previous version - replace with alias
+ procedure SetRandomMode (RandomDistIn : RandomDistType) ;
+ -- alias SetRandomMode is SetRandomParm [RandomDistType, Real, Real] ;
+
+ -- Base Randomization Distributions
+ -- Uniform : Generate a random number with a Uniform distribution
+ impure function Uniform (Min, Max : in real) return real ;
+ impure function Uniform (Min, Max : integer) return integer ;
+ impure function Uniform (Min, Max : integer ; Exclude : integer_vector) return integer ;
+
+ -- FavorSmall
+ -- Generate random numbers with a greater number of small
+ -- values than large values
+ impure function FavorSmall (Min, Max : real) return real ;
+ impure function FavorSmall (Min, Max : integer) return integer ;
+ impure function FavorSmall (Min, Max : integer ; Exclude : integer_vector) return integer ;
+
+ -- FavorBig
+ -- Generate random numbers with a greater number of large
+ -- values than small values
+ impure function FavorBig (Min, Max : real) return real ;
+ impure function FavorBig (Min, Max : integer) return integer ;
+ impure function FavorBig (Min, Max : integer ; Exclude : integer_vector) return integer ;
+
+ -- Normal : Generate a random number with a normal distribution
+ impure function Normal (Mean, StdDeviation : real) return real ;
+ -- Normal + RandomVal >= Min and RandomVal < Max
+ impure function Normal (Mean, StdDeviation, Min, Max : real) return real ;
+ impure function Normal (
+ Mean : real ;
+ StdDeviation : real ;
+ Min : integer ;
+ Max : integer ;
+ Exclude : integer_vector := NULL_INTV
+ ) return integer ;
+
+ -- Poisson : Generate a random number with a poisson distribution
+ -- Discrete distribution = only generates integral values
+ impure function Poisson (Mean : real) return real ;
+ -- Poisson + RandomVal >= Min and RandomVal < Max
+ impure function Poisson (Mean, Min, Max : real) return real ;
+ impure function Poisson (
+ Mean : real ;
+ Min : integer ;
+ Max : integer ;
+ Exclude : integer_vector := NULL_INTV
+ ) return integer ;
+
+ -- randomization with a range
+ impure function RandInt (Min, Max : integer) return integer ;
+ impure function RandReal(Min, Max : Real) return real ;
+ impure function RandTime (Min, Max : time ; Unit : time := ns) return time ;
+ impure function RandSlv (Min, Max, Size : natural) return std_logic_vector ;
+ impure function RandUnsigned (Min, Max, Size : natural) return Unsigned ;
+ impure function RandSigned (Min, Max : integer ; Size : natural ) return Signed ;
+ impure function RandIntV (Min, Max : integer ; Size : natural) return integer_vector ;
+ impure function RandIntV (Min, Max : integer ; Unique : natural ; Size : natural) return integer_vector ;
+ impure function RandRealV (Min, Max : real ; Size : natural) return real_vector ;
+ impure function RandTimeV (Min, Max : time ; Size : natural ; Unit : time := ns) return time_vector ;
+ impure function RandTimeV (Min, Max : time ; Unique : natural ; Size : natural ; Unit : time := ns) return time_vector ;
+
+ -- randomization with a range and exclude vector
+ impure function RandInt (Min, Max : integer ; Exclude : integer_vector ) return integer ;
+ impure function RandTime (Min, Max : time ; Exclude : time_vector ; Unit : time := ns) return time ;
+ impure function RandSlv (Min, Max : natural ; Exclude : integer_vector ; Size : natural ) return std_logic_vector ;
+ impure function RandUnsigned (Min, Max : natural ; Exclude : integer_vector ; Size : natural ) return Unsigned ;
+ impure function RandSigned (Min, Max : integer ; Exclude : integer_vector ; Size : natural ) return Signed ;
+ impure function RandIntV (Min, Max : integer ; Exclude : integer_vector ; Size : natural) return integer_vector ;
+ impure function RandIntV (Min, Max : integer ; Exclude : integer_vector ; Unique : natural ; Size : natural) return integer_vector ;
+ impure function RandTimeV (Min, Max : time ; Exclude : time_vector ; Size : natural ; Unit : in time := ns) return time_vector ;
+ impure function RandTimeV (Min, Max : time ; Exclude : time_vector ; Unique : natural ; Size : natural ; Unit : in time := ns) return time_vector ;
+
+ -- Randomly select a value within a set of values
+ impure function RandInt ( A : integer_vector ) return integer ;
+ impure function RandReal ( A : real_vector ) return real ;
+ impure function RandTime (A : time_vector) return time ;
+ impure function RandSlv (A : integer_vector ; Size : natural) return std_logic_vector ;
+ impure function RandUnsigned (A : integer_vector ; Size : natural) return Unsigned ;
+ impure function RandSigned (A : integer_vector ; Size : natural ) return Signed ;
+ impure function RandIntV (A : integer_vector ; Size : natural) return integer_vector ;
+ impure function RandIntV (A : integer_vector ; Unique : natural ; Size : natural) return integer_vector ;
+ impure function RandRealV (A : real_vector ; Size : natural) return real_vector ;
+ impure function RandRealV (A : real_vector ; Unique : natural ; Size : natural) return real_vector ;
+ impure function RandTimeV (A : time_vector ; Size : natural) return time_vector ;
+ impure function RandTimeV (A : time_vector ; Unique : natural ; Size : natural) return time_vector ;
+
+ -- Randomly select a value within a set of values with exclude values (so can skip last or last n)
+ impure function RandInt ( A, Exclude : integer_vector ) return integer ;
+ impure function RandReal ( A, Exclude : real_vector ) return real ;
+ impure function RandTime (A, Exclude : time_vector) return time ;
+ impure function RandSlv (A, Exclude : integer_vector ; Size : natural) return std_logic_vector ;
+ impure function RandUnsigned (A, Exclude : integer_vector ; Size : natural) return Unsigned ;
+ impure function RandSigned (A, Exclude : integer_vector ; Size : natural ) return Signed ;
+ impure function RandIntV (A, Exclude : integer_vector ; Size : natural) return integer_vector ;
+ impure function RandIntV (A, Exclude : integer_vector ; Unique : natural ; Size : natural) return integer_vector ;
+ impure function RandRealV (A, Exclude : real_vector ; Size : natural) return real_vector ;
+ impure function RandRealV (A, Exclude : real_vector ; Unique : natural ; Size : natural) return real_vector ;
+ impure function RandTimeV (A, Exclude : time_vector ; Size : natural) return time_vector ;
+ impure function RandTimeV (A, Exclude : time_vector ; Unique : natural ; Size : natural) return time_vector ;
+
+ -- Randomly select between 0 and N-1 based on the specified weight.
+ -- where N = number values in weight array
+ impure function DistInt ( Weight : integer_vector ) return integer ;
+ impure function DistSlv ( Weight : integer_vector ; Size : natural ) return std_logic_vector ;
+ impure function DistUnsigned ( Weight : integer_vector ; Size : natural ) return unsigned ;
+ impure function DistSigned ( Weight : integer_vector ; Size : natural ) return signed ;
+
+ -- Distribution with just weights and with exclude values
+ impure function DistInt ( Weight : integer_vector ; Exclude : integer_vector ) return integer ;
+ impure function DistSlv ( Weight : integer_vector ; Exclude : integer_vector ; Size : natural ) return std_logic_vector ;
+ impure function DistUnsigned ( Weight : integer_vector ; Exclude : integer_vector ; Size : natural ) return unsigned ;
+ impure function DistSigned ( Weight : integer_vector ; Exclude : integer_vector ; Size : natural ) return signed ;
+
+ -- Distribution with weight and value
+ impure function DistValInt ( A : DistType ) return integer ;
+ impure function DistValSlv ( A : DistType ; Size : natural) return std_logic_vector ;
+ impure function DistValUnsigned ( A : DistType ; Size : natural) return unsigned ;
+ impure function DistValSigned ( A : DistType ; Size : natural) return signed ;
+
+ -- Distribution with weight and value and with exclude values
+ impure function DistValInt ( A : DistType ; Exclude : integer_vector ) return integer ;
+ impure function DistValSlv ( A : DistType ; Exclude : integer_vector ; Size : natural) return std_logic_vector ;
+ impure function DistValUnsigned ( A : DistType ; Exclude : integer_vector ; Size : natural) return unsigned ;
+ impure function DistValSigned ( A : DistType ; Exclude : integer_vector ; Size : natural) return signed ;
+
+ -- Large vector handling.
+ impure function RandUnsigned (Size : natural) return unsigned ;
+ impure function RandSlv (Size : natural) return std_logic_vector ;
+ impure function RandSigned (Size : natural) return signed ;
+ impure function RandUnsigned (Max : Unsigned) return unsigned ;
+ impure function RandSlv (Max : std_logic_vector) return std_logic_vector ;
+ impure function RandSigned (Max : signed) return signed ;
+ impure function RandUnsigned (Min, Max : unsigned) return unsigned ;
+ impure function RandSlv (Min, Max : std_logic_vector) return std_logic_vector ;
+ impure function RandSigned (Min, Max : signed) return signed ;
+
+ -- Convenience Functions
+ impure function RandReal return real ; -- 0.0 to 1.0
+ impure function RandReal(Max : Real) return real ; -- 0.0 to Max
+ impure function RandInt (Max : integer) return integer ;
+ impure function RandSlv (Max, Size : natural) return std_logic_vector ;
+ impure function RandUnsigned (Max, Size : natural) return Unsigned ;
+ impure function RandSigned (Max : integer ; Size : natural ) return Signed ;
+
+ end protected RandomPType ;
+
+end RandomPkg ;
+
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+
+package body RandomPkg is
+
+ -----------------------------------------------------------------
+ -- Local Randomization Support
+ -----------------------------------------------------------------
+ constant NULL_SLV : std_logic_vector (NULL_RANGE_TYPE) := (others => '0') ;
+ constant NULL_UV : unsigned (NULL_RANGE_TYPE) := (others => '0') ;
+ constant NULL_SV : signed (NULL_RANGE_TYPE) := (others => '0') ;
+
+ -----------------------------------------------------------------
+ -- Scale -- Scale a value to be within a given range
+ --
+ function Scale (A, Min, Max : real) return real is
+ variable ValRange : Real ;
+ begin
+ if Max >= Min then
+ ValRange := Max - Min ;
+ return A * ValRange + Min ;
+ else
+ return real'left ;
+ end if ;
+ end function Scale ;
+
+ function Scale (A : real ; Min, Max : integer) return integer is
+ variable ValRange : real ;
+ variable rMin, rMax : real ;
+ begin
+ if Max >= Min then
+ rMin := real(Min) - 0.5 ;
+ rMax := real(Max) + 0.5 ;
+ ValRange := rMax - rMin ;
+ return integer(round(A * ValRange + rMin)) ;
+ else
+ return integer'left ;
+ end if ;
+ end function Scale ;
+
+ -- create more smaller values
+ function FavorSmall (A : real) return real is
+ begin
+ return 1.0 - sqrt(A) ;
+ end FavorSmall ;
+
+ -- create more larger values
+ -- alias FavorBig is sqrt[real return real] ;
+ function FavorBig (A : real) return real is
+ begin
+ return sqrt(A) ;
+ end FavorBig ;
+
+ -- local.
+ function to_time_vector (A : integer_vector ; Unit : time) return time_vector is
+ variable result : time_vector(A'range) ;
+ begin
+ for i in A'range loop
+ result(i) := A(i) * Unit ;
+ end loop ;
+ return result ;
+ end function to_time_vector ;
+
+ -- local
+ function to_integer_vector (A : time_vector ; Unit : time) return integer_vector is
+ variable result : integer_vector(A'range) ;
+ begin
+ for i in A'range loop
+ result(i) := A(i) / Unit ;
+ end loop ;
+ return result ;
+ end function to_integer_vector ;
+
+ -- Local. Remove the exclude list from the list - integer_vector
+ procedure RemoveExclude(A, Exclude : integer_vector ; variable NewA : out integer_vector ; variable NewALength : inout natural ) is
+ alias norm_NewA : integer_vector(1 to NewA'length) is NewA ;
+ begin
+ NewALength := 0 ;
+ for i in A'range loop
+ if not inside(A(i), Exclude) then
+ NewALength := NewALength + 1 ;
+ norm_NewA(NewALength) := A(i) ;
+ end if ;
+ end loop ;
+ end procedure RemoveExclude ;
+
+ -- Local. Inside - real_vector
+ function inside(A : real ; Exclude : real_vector) return boolean is
+ begin
+ for i in Exclude'range loop
+ if A = Exclude(i) then
+ return TRUE ;
+ end if ;
+ end loop ;
+ return FALSE ;
+ end function inside ;
+
+ -- Local. Remove the exclude list from the list - real_vector
+ procedure RemoveExclude(A, Exclude : real_vector ; variable NewA : out real_vector ; variable NewALength : inout natural ) is
+ alias norm_NewA : real_vector(1 to NewA'length) is NewA ;
+ begin
+ NewALength := 0 ;
+ for i in A'range loop
+ if not inside(A(i), Exclude) then
+ NewALength := NewALength + 1 ;
+ norm_NewA(NewALength) := A(i) ;
+ end if ;
+ end loop ;
+ end procedure RemoveExclude ;
+
+ -- Local. Inside - time_vector
+ function inside(A : time ; Exclude : time_vector) return boolean is
+ begin
+ for i in Exclude'range loop
+ if A = Exclude(i) then
+ return TRUE ;
+ end if ;
+ end loop ;
+ return FALSE ;
+ end function inside ;
+
+ -- Local. Remove the exclude list from the list - time_vector
+ procedure RemoveExclude(A, Exclude : time_vector ; variable NewA : out time_vector ; variable NewALength : inout natural ) is
+ alias norm_NewA : time_vector(1 to NewA'length) is NewA ;
+ begin
+ NewALength := 0 ;
+ for i in A'range loop
+ if not inside(A(i), Exclude) then
+ NewALength := NewALength + 1 ;
+ norm_NewA(NewALength) := A(i) ;
+ end if ;
+ end loop ;
+ end procedure RemoveExclude ;
+
+
+ -----------------------------------------------------------------
+ -- RandomParmType IO
+ -----------------------------------------------------------------
+ -----------------------------------------------------------------
+ function to_string(A : RandomDistType) return string is
+ begin
+ return RandomDistType'image(A) ;
+ end function to_string ;
+
+
+ -----------------------------------------------------------------
+ procedure write(variable L : inout line ; A : RandomDistType ) is
+ begin
+ write(L, to_string(A)) ;
+ end procedure write ;
+
+
+ -----------------------------------------------------------------
+ procedure read(variable L : inout line ; A : out RandomDistType ; good : out boolean ) is
+ variable strval : string(1 to 40) ;
+ variable len : natural ;
+ begin
+ -- procedure SREAD (L : inout LINE ; VALUE : out STRING ; STRLEN : out NATURAL) ;
+ sread(L, strval, len) ;
+ A := RandomDistType'value(strval(1 to len)) ;
+ good := len > 0 ;
+ end procedure read ;
+
+
+ -----------------------------------------------------------------
+ procedure read(variable L : inout line ; A : out RandomDistType ) is
+ variable ReadValid : boolean ;
+ begin
+ read(L, A, ReadValid) ;
+ AlertIfNot( OSVVM_ALERTLOG_ID, ReadValid, "RandomPkg.read[line, RandomDistType] failed", FAILURE) ;
+ end procedure read ;
+
+
+ -----------------------------------------------------------------
+ function to_string(A : RandomParmType) return string is
+ begin
+ return RandomDistType'image(A.Distribution) & " " &
+ to_string(A.Mean, 2) & " " & to_string(A.StdDeviation, 2) ;
+ end function to_string ;
+
+
+ -----------------------------------------------------------------
+ procedure write(variable L : inout line ; A : RandomParmType ) is
+ begin
+ write(L, to_string(A)) ;
+ end procedure write ;
+
+
+ -----------------------------------------------------------------
+ procedure read(variable L : inout line ; A : out RandomParmType ; good : out boolean ) is
+ variable strval : string(1 to 40) ;
+ variable len : natural ;
+ variable igood : boolean ;
+ begin
+ loop
+ -- procedure SREAD (L : inout LINE ; VALUE : out STRING ; STRLEN : out NATURAL) ;
+ sread(L, strval, len) ;
+ A.Distribution := RandomDistType'value(strval(1 to len)) ;
+ igood := len > 0 ;
+ exit when not igood ;
+
+ read(L, A.Mean, igood) ;
+ exit when not igood ;
+
+ read(L, A.StdDeviation, igood) ;
+ exit ;
+ end loop ;
+ good := igood ;
+ end procedure read ;
+
+
+ -----------------------------------------------------------------
+ procedure read(variable L : inout line ; A : out RandomParmType ) is
+ variable ReadValid : boolean ;
+ begin
+ read(L, A, ReadValid) ;
+ AlertIfNot( OSVVM_ALERTLOG_ID, ReadValid, "RandomPkg.read[line, RandomParmType] failed", FAILURE) ;
+ end procedure read ;
+
+
+
+ -----------------------------------------------------------------
+ -----------------------------------------------------------------
+ type RandomPType is protected body
+ --
+ -- RandomSeed manipulation
+ --
+ variable RandomSeed : RandomSeedType := GenRandSeed(integer_vector'(1,7)) ;
+
+ procedure InitSeed (S : string ) is
+ begin
+ RandomSeed := GenRandSeed(S) ;
+ end procedure InitSeed ;
+
+ procedure InitSeed (I : integer ) is
+ begin
+ RandomSeed := GenRandSeed(I) ;
+ end procedure InitSeed ;
+
+ procedure InitSeed (IV : integer_vector ) is
+ begin
+ RandomSeed := GenRandSeed(IV) ;
+ end procedure InitSeed ;
+
+ procedure SetSeed (RandomSeedIn : RandomSeedType ) is
+ begin
+ RandomSeed := RandomSeedIn ;
+ end procedure SetSeed ;
+
+ procedure SeedRandom (RandomSeedIn : RandomSeedType ) is
+ begin
+ RandomSeed := RandomSeedIn ;
+ end procedure SeedRandom ;
+
+ impure function GetSeed return RandomSeedType is
+ begin
+ return RandomSeed ;
+ end function GetSeed ;
+
+ impure function SeedRandom return RandomSeedType is
+ begin
+ return RandomSeed ;
+ end function SeedRandom ;
+
+
+ --
+ -- randomization mode
+ --
+ variable RandomParm : RandomParmType ; -- left most values ok for init
+
+ procedure SetRandomParm (RandomParmIn : RandomParmType) is
+ begin
+ RandomParm := RandomParmIn ;
+ end procedure SetRandomParm ;
+
+ procedure SetRandomParm (
+ Distribution : RandomDistType ;
+ Mean : Real := 0.0 ;
+ Deviation : Real := 0.0
+ ) is
+ begin
+ RandomParm := RandomParmType'(Distribution, Mean, Deviation) ;
+ end procedure SetRandomParm ;
+
+
+ impure function GetRandomParm return RandomParmType is
+ begin
+ return RandomParm ;
+ end function GetRandomParm ;
+
+
+ impure function GetRandomParm return RandomDistType is
+ begin
+ return RandomParm.Distribution ;
+ end function GetRandomParm ;
+
+
+ -- For compatibility with previous version
+ procedure SetRandomMode (RandomDistIn : RandomDistType) is
+ begin
+ SetRandomParm(RandomDistIn) ;
+ end procedure SetRandomMode ;
+
+
+ --
+ -- Base Randomization Distributions
+ --
+ --
+ -- Uniform : Generate a random number with a Uniform distribution
+ --
+ impure function Uniform (Min, Max : in real) return real is
+ variable rRandomVal : real ;
+ begin
+ AlertIf (OSVVM_ALERTLOG_ID, Max < Min, "RandomPkg.Uniform: Max < Min", FAILURE) ;
+ Uniform(rRandomVal, RandomSeed) ;
+ return scale(rRandomVal, Min, Max) ;
+ end function Uniform ;
+
+ impure function Uniform (Min, Max : integer) return integer is
+ variable rRandomVal : real ;
+ begin
+ AlertIf (OSVVM_ALERTLOG_ID, Max < Min, "RandomPkg.Uniform: Max < Min", FAILURE) ;
+ Uniform(rRandomVal, RandomSeed) ;
+ return scale(rRandomVal, Min, Max) ;
+ end function Uniform ;
+
+ impure function Uniform (Min, Max : integer ; Exclude : integer_vector) return integer is
+ variable iRandomVal : integer ;
+ variable ExcludeList : SortListPType ;
+ variable count : integer ;
+ begin
+ ExcludeList.add(Exclude, Min, Max) ;
+ count := ExcludeList.count ;
+ iRandomVal := Uniform(Min, Max - count) ;
+ -- adjust count, note iRandomVal changes while checking.
+ for i in 1 to count loop
+ exit when iRandomVal < ExcludeList.Get(i) ;
+ iRandomVal := iRandomVal + 1 ;
+ end loop ;
+ ExcludeList.erase ;
+ return iRandomVal ;
+ end function Uniform ;
+
+
+ --
+ -- FavorSmall
+ -- Generate random numbers with a greater number of small
+ -- values than large values
+ --
+ impure function FavorSmall (Min, Max : real) return real is
+ variable rRandomVal : real ;
+ begin
+ AlertIf (OSVVM_ALERTLOG_ID, Max < Min, "RandomPkg.FavorSmall: Max < Min", FAILURE) ;
+ Uniform(rRandomVal, RandomSeed) ;
+ return scale(FavorSmall(rRandomVal), Min, Max) ; -- real
+ end function FavorSmall ;
+
+ impure function FavorSmall (Min, Max : integer) return integer is
+ variable rRandomVal : real ;
+ begin
+ AlertIf (OSVVM_ALERTLOG_ID, Max < Min, "RandomPkg.FavorSmall: Max < Min", FAILURE) ;
+ Uniform(rRandomVal, RandomSeed) ;
+ return scale(FavorSmall(rRandomVal), Min, Max) ; -- integer
+ end function FavorSmall ;
+
+ impure function FavorSmall (Min, Max : integer ; Exclude : integer_vector) return integer is
+ variable iRandomVal : integer ;
+ variable ExcludeList : SortListPType ;
+ variable count : integer ;
+ begin
+ ExcludeList.add(Exclude, Min, Max) ;
+ count := ExcludeList.count ;
+ iRandomVal := FavorSmall(Min, Max - count) ;
+ -- adjust count, note iRandomVal changes while checking.
+ for i in 1 to count loop
+ exit when iRandomVal < ExcludeList.Get(i) ;
+ iRandomVal := iRandomVal + 1 ;
+ end loop ;
+ ExcludeList.erase ;
+ return iRandomVal ;
+ end function FavorSmall ;
+
+
+ --
+ -- FavorBig
+ -- Generate random numbers with a greater number of large
+ -- values than small values
+ --
+ impure function FavorBig (Min, Max : real) return real is
+ variable rRandomVal : real ;
+ begin
+ AlertIf (OSVVM_ALERTLOG_ID, Max < Min, "RandomPkg.FavorBig: Max < Min", FAILURE) ;
+ Uniform(rRandomVal, RandomSeed) ;
+ return scale(FavorBig(rRandomVal), Min, Max) ; -- real
+ end function FavorBig ;
+
+ impure function FavorBig (Min, Max : integer) return integer is
+ variable rRandomVal : real ;
+ begin
+ AlertIf (OSVVM_ALERTLOG_ID, Max < Min, "RandomPkg.FavorBig: Max < Min", FAILURE) ;
+ Uniform(rRandomVal, RandomSeed) ;
+ return scale(FavorBig(rRandomVal), Min, Max) ; -- integer
+ end function FavorBig ;
+
+ impure function FavorBig (Min, Max : integer ; Exclude : integer_vector) return integer is
+ variable iRandomVal : integer ;
+ variable ExcludeList : SortListPType ;
+ variable count : integer ;
+ begin
+ ExcludeList.add(Exclude, Min, Max) ;
+ count := ExcludeList.count ;
+ iRandomVal := FavorBig(Min, Max - count) ;
+ -- adjust count, note iRandomVal changes while checking.
+ for i in 1 to count loop
+ exit when iRandomVal < ExcludeList.Get(i) ;
+ iRandomVal := iRandomVal + 1 ;
+ end loop ;
+ ExcludeList.erase ;
+ return iRandomVal ;
+ end function FavorBig ;
+
+
+ -----------------------------------------------------------------
+ -- Normal
+ -- Generate a random number with a normal distribution
+ --
+ -- Use Box Muller, per Wikipedia :
+ -- http ://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
+ --
+ -- Use polar method, per Wikipedia :
+ -- http ://en.wikipedia.org/wiki/Marsaglia_polar_method
+ --
+ impure function Normal (Mean, StdDeviation : real) return real is
+ variable x01, y01 : real ;
+ variable StdNormalDist : real ; -- mean 0, variance 1
+ begin
+ -- add this check to set parameters?
+ if StdDeviation < 0.0 then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.Normal: Standard deviation must be >= 0.0", FAILURE) ;
+ return -1.0 ;
+ end if ;
+
+ -- Box Muller
+ Uniform (x01, RandomSeed) ;
+ Uniform (y01, RandomSeed) ;
+ StdNormalDist := sqrt(-2.0 * log(x01)) * cos(math_2_pi*y01) ;
+
+ -- Polar form rejected due to mean 50.0, std deviation = 5 resulted
+ -- in a median of 49
+ -- -- find two Uniform distributed values with range -1 to 1
+ -- -- that satisify S = X **2 + Y**2 < 1.0
+ -- loop
+ -- Uniform (x01, RandomSeed) ;
+ -- Uniform (y01, RandomSeed) ;
+ -- x := 2.0 * x01 - 1.0 ; -- scale to -1 to 1
+ -- y := 2.0 * y01 - 1.0 ;
+ -- s := x*x + y*y ;
+ -- exit when s < 1.0 and s > 0.0 ;
+ -- end loop ;
+
+ -- -- Calculate Standard Normal Distribution
+ -- StdNormalDist := x * sqrt((-2.0 * log(s)) / s) ;
+
+ -- Convert to have Mean and StdDeviation
+ return StdDeviation * StdNormalDist + Mean ;
+ end function Normal ;
+
+
+ -- Normal + RandomVal >= Min and RandomVal <= Max
+ impure function Normal (Mean, StdDeviation, Min, Max : real) return real is
+ variable rRandomVal : real ;
+ begin
+ if Max < Min then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.Normal: Max < Min", FAILURE) ;
+ return Mean ;
+ else
+ loop
+ rRandomVal := Normal (Mean, StdDeviation) ;
+ exit when rRandomVal >= Min and rRandomVal <= Max ;
+ end loop ;
+ end if ;
+ return rRandomVal ;
+ end function Normal ;
+
+ -- Normal + RandomVal >= Min and RandomVal <= Max
+ impure function Normal (
+ Mean : real ;
+ StdDeviation : real ;
+ Min : integer ;
+ Max : integer ;
+ Exclude : integer_vector := NULL_INTV
+ ) return integer is
+ variable iRandomVal : integer ;
+ begin
+ if Max < Min then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.Normal: Max < Min", FAILURE) ;
+ return integer(round(Mean)) ;
+ else
+ loop
+ iRandomVal := integer(round( Normal(Mean, StdDeviation) )) ;
+ exit when iRandomVal >= Min and iRandomVal <= Max and
+ not inside(iRandomVal, Exclude) ;
+ end loop ;
+ end if ;
+ return iRandomVal ;
+ end function Normal ;
+
+
+ -----------------------------------------------------------------
+ -- Poisson
+ -- Generate a random number with a poisson distribution
+ -- Discrete distribution = only generates integral values
+ --
+ -- Use knuth method, per Wikipedia :
+ -- http ://en.wikipedia.org/wiki/Poisson_distribution
+ --
+ impure function Poisson (Mean : real) return real is
+ variable Product : Real := 1.0 ;
+ variable Bound : Real := 0.0 ;
+ variable UniformRand : Real := 0.0 ;
+ variable PoissonRand : Real := 0.0 ;
+ begin
+ Bound := exp(-1.0 * Mean) ;
+ Product := 1.0 ;
+
+ -- add this check to set parameters?
+ if Mean <= 0.0 or Bound <= 0.0 then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.Poisson: Mean < 0 or too large. Mean = " & real'image(Mean), FAILURE) ;
+ return Mean ;
+ end if ;
+
+ while (Product >= Bound) loop
+ PoissonRand := PoissonRand + 1.0 ;
+ Uniform(UniformRand, RandomSeed) ;
+ Product := Product * UniformRand ;
+ end loop ;
+ return PoissonRand ;
+ end function Poisson ; -- no range
+
+ -- Poisson + RandomVal >= Min and RandomVal < Max
+ impure function Poisson (Mean, Min, Max : real) return real is
+ variable rRandomVal : real ;
+ begin
+ if Max < Min then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.Poisson: Max < Min", FAILURE) ;
+ return Mean ;
+ else
+ loop
+ rRandomVal := Poisson (Mean) ;
+ exit when rRandomVal >= Min and rRandomVal <= Max ;
+ end loop ;
+ end if ;
+ return rRandomVal ;
+ end function Poisson ;
+
+ impure function Poisson (
+ Mean : real ;
+ Min : integer ;
+ Max : integer ;
+ Exclude : integer_vector := NULL_INTV
+ ) return integer is
+ variable iRandomVal : integer ;
+ begin
+ if Max < Min then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.Poisson: Max < Min", FAILURE) ;
+ return integer(round(Mean)) ;
+ else
+ loop
+ iRandomVal := integer(round( Poisson (Mean) )) ;
+ exit when iRandomVal >= Min and iRandomVal <= Max and
+ not inside(iRandomVal, Exclude) ;
+ end loop ;
+ end if ;
+ return iRandomVal ;
+ end function Poisson ;
+
+
+ --
+ -- integer randomization with a range
+ -- Distribution determined by RandomParm
+ --
+ impure function RandInt (Min, Max : integer) return integer is
+ begin
+ case RandomParm.Distribution is
+ when NONE | UNIFORM => return Uniform(Min, Max) ;
+ when FAVOR_SMALL => return FavorSmall(Min, Max) ;
+ when FAVOR_BIG => return FavorBig (Min, Max) ;
+ when NORMAL => return Normal(RandomParm.Mean, RandomParm.StdDeviation, Min, Max) ;
+ when POISSON => return Poisson(RandomParm.Mean, Min, Max) ;
+ when others =>
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.RandInt: RandomParm.Distribution not implemented", FAILURE) ;
+ return integer'low ;
+ end case ;
+ end function RandInt ;
+
+ --
+ -- real randomization with a range
+ -- Distribution determined by RandomParm
+ --
+ impure function RandReal(Min, Max : Real) return real is
+ begin
+ case RandomParm.Distribution is
+ when NONE | UNIFORM => return Uniform(Min, Max) ;
+ when FAVOR_SMALL => return FavorSmall(Min, Max) ;
+ when FAVOR_BIG => return FavorBig (Min, Max) ;
+ when NORMAL => return Normal(RandomParm.Mean, RandomParm.StdDeviation, Min, Max) ;
+ when POISSON => return Poisson(RandomParm.Mean, Min, Max) ;
+ when others =>
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.RandReal: Specified RandomParm.Distribution not implemented", FAILURE) ;
+ return real(integer'low) ;
+ end case ;
+ end function RandReal ;
+
+ impure function RandTime (Min, Max : time ; Unit :time := ns) return time is
+ variable IntVal : integer ;
+ begin
+ -- if Max - Min > 2**31 result will be out of range
+ IntVal := RandInt(0, (Max - Min)/Unit) ;
+ Return Min + Unit*IntVal ;
+ end function RandTime ;
+
+ impure function RandSlv (Min, Max, Size : natural) return std_logic_vector is
+ begin
+ return std_logic_vector(to_unsigned(RandInt(Min, Max), Size)) ;
+ end function RandSlv ;
+
+ impure function RandUnsigned (Min, Max, Size : natural) return Unsigned is
+ begin
+ return to_unsigned(RandInt(Min, Max), Size) ;
+ end function RandUnsigned ;
+
+ impure function RandSigned (Min, Max : integer ; Size : natural ) return Signed is
+ begin
+ return to_signed(RandInt(Min, Max), Size) ;
+ end function RandSigned ;
+
+ impure function RandIntV (Min, Max : integer ; Size : natural) return integer_vector is
+ variable result : integer_vector(1 to Size) ;
+ begin
+ for i in result'range loop
+ result(i) := RandInt(Min, Max) ;
+ end loop ;
+ return result ;
+ end function RandIntV ;
+
+ impure function RandIntV (Min, Max : integer ; Unique : natural ; Size : natural) return integer_vector is
+ variable result : integer_vector(1 to Size) ;
+ variable iUnique : natural ;
+ begin
+ -- if Unique = 0, it is more efficient to call RandIntV(Min, Max, Size)
+ iUnique := Unique ;
+ if Max-Min+1 < Unique then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.(RandIntV | RandRealV | RandTimeV): Unique > number of values available", FAILURE) ;
+ iUnique := Max-Min+1 ;
+ end if ;
+ for i in result'range loop
+ result(i) := RandInt(Min, Max, result(maximum(1, 1 + i - iUnique) to Size)) ;
+ end loop ;
+ return result ;
+ end function RandIntV ;
+
+ impure function RandRealV (Min, Max : real ; Size : natural) return real_vector is
+ variable result : real_vector(1 to Size) ;
+ begin
+ for i in result'range loop
+ result(i) := RandReal(Min, Max) ;
+ end loop ;
+ return result ;
+ end function RandRealV ;
+
+ impure function RandTimeV (Min, Max : time ; Size : natural ; Unit : time := ns) return time_vector is
+ variable result : time_vector(1 to Size) ;
+ begin
+ for i in result'range loop
+ result(i) := RandTime(Min, Max, Unit) ;
+ end loop ;
+ return result ;
+ end function RandTimeV ;
+
+ impure function RandTimeV (Min, Max : time ; Unique : natural ; Size : natural ; Unit : time := ns) return time_vector is
+ begin
+ -- if Unique = 0, it is more efficient to call RandTimeV(Min, Max, Size)
+ return to_time_vector(RandIntV(Min/Unit, Max/Unit, Unique, Size), Unit) ;
+ end function RandTimeV ;
+
+
+ --
+ -- integer randomization with a range and exclude vector
+ -- Distribution determined by RandomParm
+ --
+ impure function RandInt (Min, Max : integer ; Exclude : integer_vector ) return integer is
+ begin
+ case RandomParm.Distribution is
+ when NONE | UNIFORM => return Uniform(Min, Max, Exclude) ;
+ when FAVOR_SMALL => return FavorSmall(Min, Max, Exclude) ;
+ when FAVOR_BIG => return FavorBig (Min, Max, Exclude) ;
+ when NORMAL => return Normal(RandomParm.Mean, RandomParm.StdDeviation, Min, Max, Exclude) ;
+ when POISSON => return Poisson(RandomParm.Mean, Min, Max, Exclude) ;
+ when others =>
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.RandInt: Specified RandomParm.Distribution not implemented", FAILURE) ;
+ return integer'low ;
+ end case ;
+ end function RandInt ;
+
+ impure function RandTime (Min, Max : time ; Exclude : time_vector ; Unit : time := ns) return time is
+ variable IntVal : integer ;
+ begin
+ -- if Min or Max > 2**31 value will be out of range
+ return RandInt(Min/Unit, Max/Unit, to_integer_vector(Exclude, Unit)) * Unit ;
+ end function RandTime ;
+
+ impure function RandSlv (Min, Max : natural ; Exclude : integer_vector ; Size : natural ) return std_logic_vector is
+ begin
+ return std_logic_vector(to_unsigned(RandInt(Min, Max, Exclude), Size)) ;
+ end function RandSlv ;
+
+ impure function RandUnsigned (Min, Max : natural ; Exclude : integer_vector ; Size : natural ) return Unsigned is
+ begin
+ return to_unsigned(RandInt(Min, Max, Exclude), Size) ;
+ end function RandUnsigned ;
+
+ impure function RandSigned (Min, Max : integer ; Exclude : integer_vector ; Size : natural ) return Signed is
+ begin
+ return to_signed(RandInt(Min, Max, Exclude), Size) ;
+ end function RandSigned ;
+
+ impure function RandIntV (Min, Max : integer ; Exclude : integer_vector ; Size : natural) return integer_vector is
+ variable result : integer_vector(1 to Size) ;
+ begin
+ for i in result'range loop
+ result(i) := RandInt(Min, Max, Exclude) ;
+ end loop ;
+ return result ;
+ end function RandIntV ;
+
+ impure function RandIntV (Min, Max : integer ; Exclude : integer_vector ; Unique : natural ; Size : natural) return integer_vector is
+ variable ResultPlus : integer_vector(1 to Size + Exclude'length) ;
+ begin
+ -- if Unique = 0, it is more efficient to call RandIntV(Min, Max, Size)
+ ResultPlus(Size+1 to ResultPlus'right) := Exclude ;
+ for i in 1 to Size loop
+ ResultPlus(i) := RandInt(Min, Max, ResultPlus(maximum(1, 1 + i - Unique) to ResultPlus'right)) ;
+ end loop ;
+ return ResultPlus(1 to Size) ;
+ end function RandIntV ;
+
+ impure function RandTimeV (Min, Max : time ; Exclude : time_vector ; Size : natural ; Unit : in time := ns) return time_vector is
+ begin
+ return to_time_vector( RandIntV(Min/Unit, Max/Unit, to_integer_vector(Exclude, Unit), Size), Unit ) ;
+ end function RandTimeV ;
+
+ impure function RandTimeV (Min, Max : time ; Exclude : time_vector ; Unique : natural ; Size : natural ; Unit : in time := ns) return time_vector is
+ begin
+ -- if Unique = 0, it is more efficient to call RandIntV(Min, Max, Size)
+ return to_time_vector( RandIntV(Min/Unit, Max/Unit, to_integer_vector(Exclude, Unit), Unique, Size), Unit ) ;
+ end function RandTimeV ;
+
+
+
+ --
+ -- Randomly select a value within a set of values
+ -- Distribution determined by RandomParm
+ --
+ impure function RandInt ( A : integer_vector ) return integer is
+ alias A_norm : integer_vector(1 to A'length) is A ;
+ begin
+ return A_norm( RandInt(1, A'length) ) ;
+ end function RandInt ;
+
+ impure function RandReal ( A : real_vector ) return real is
+ alias A_norm : real_vector(1 to A'length) is A ;
+ begin
+ return A_norm( RandInt(1, A'length) ) ;
+ end function RandReal ;
+
+ impure function RandTime ( A : time_vector ) return time is
+ alias A_norm : time_vector(1 to A'length) is A ;
+ begin
+ return A_norm( RandInt(1, A'length) ) ;
+ end function RandTime ;
+
+ impure function RandSlv (A : integer_vector ; Size : natural) return std_logic_vector is
+ begin
+ return std_logic_vector(to_unsigned(RandInt(A), Size)) ;
+ end function RandSlv ;
+
+ impure function RandUnsigned (A : integer_vector ; Size : natural) return Unsigned is
+ begin
+ return to_unsigned(RandInt(A), Size) ;
+ end function RandUnsigned ;
+
+ impure function RandSigned (A : integer_vector ; Size : natural ) return Signed is
+ begin
+ return to_signed(RandInt(A), Size) ;
+ end function RandSigned ;
+
+ impure function RandIntV (A : integer_vector ; Size : natural) return integer_vector is
+ variable result : integer_vector(1 to Size) ;
+ begin
+ for i in result'range loop
+ result(i) := RandInt(A) ;
+ end loop ;
+ return result ;
+ end function RandIntV ;
+
+ impure function RandIntV (A : integer_vector ; Unique : natural ; Size : natural) return integer_vector is
+ variable result : integer_vector(1 to Size) ;
+ variable iUnique : natural ;
+ begin
+ -- if Unique = 0, it is more efficient to call RandIntV(A, Size)
+ -- require A'length >= Unique
+ iUnique := Unique ;
+ if A'length < Unique then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.RandIntV: Unique > length of set of values", FAILURE) ;
+ iUnique := A'length ;
+ end if ;
+ for i in result'range loop
+ result(i) := RandInt(A, result(maximum(1, 1 + i - iUnique) to Size)) ;
+ end loop ;
+ return result ;
+ end function RandIntV ;
+
+ impure function RandRealV (A : real_vector ; Size : natural) return real_vector is
+ variable result : real_vector(1 to Size) ;
+ begin
+ for i in result'range loop
+ result(i) := RandReal(A) ;
+ end loop ;
+ return result ;
+ end function RandRealV ;
+
+ impure function RandRealV (A : real_vector ; Unique : natural ; Size : natural) return real_vector is
+ alias A_norm : real_vector(1 to A'length) is A ;
+ variable result : real_vector(1 to Size) ;
+ variable IntResult : integer_vector(result'range) ;
+ begin
+ -- randomly generate indices
+ IntResult := RandIntV(1, A'length, Unique, Size) ;
+ -- translate indicies into result values
+ for i in result'range loop
+ result(i) := A_norm(IntResult(i)) ;
+ end loop ;
+ return result ;
+ end function RandRealV ;
+
+ impure function RandTimeV (A : time_vector ; Size : natural) return time_vector is
+ variable result : time_vector(1 to Size) ;
+ begin
+ for i in result'range loop
+ result(i) := RandTime(A) ;
+ end loop ;
+ return result ;
+ end function RandTimeV ;
+
+ impure function RandTimeV (A : time_vector ; Unique : natural ; Size : natural) return time_vector is
+ alias A_norm : time_vector(1 to A'length) is A ;
+ variable result : time_vector(1 to Size) ;
+ variable IntResult : integer_vector(result'range) ;
+ begin
+ -- randomly generate indices
+ IntResult := RandIntV(1, A'length, Unique, Size) ;
+ -- translate indicies into result values
+ for i in result'range loop
+ result(i) := A_norm(IntResult(i)) ;
+ end loop ;
+ return result ;
+ end function RandTimeV ;
+
+
+ --
+ -- Randomly select a value within a set of values with exclude values (so can skip last or last n)
+ -- Distribution determined by RandomParm
+ --
+
+ impure function RandInt ( A, Exclude : integer_vector ) return integer is
+ variable NewA : integer_vector(1 to A'length) ;
+ variable NewALength : natural ;
+ begin
+ -- Remove Exclude from A
+ RemoveExclude(A, Exclude, NewA, NewALength) ;
+ -- Randomize Index
+ return NewA(RandInt(1, NewALength)) ;
+ end function RandInt ;
+
+ impure function RandReal ( A, Exclude : real_vector ) return real is
+ variable NewA : real_vector(1 to A'length) ;
+ variable NewALength : natural ;
+ begin
+ -- Remove Exclude from A
+ RemoveExclude(A, Exclude, NewA, NewALength) ;
+ -- Randomize Index
+ return NewA(RandInt(1, NewALength)) ;
+ end function RandReal ;
+
+ impure function RandTime ( A, Exclude : time_vector ) return time is
+ variable NewA : time_vector(1 to A'length) ;
+ variable NewALength : natural ;
+ begin
+ -- Remove Exclude from A
+ RemoveExclude(A, Exclude, NewA, NewALength) ;
+ -- Randomize Index
+ return NewA(RandInt(1, NewALength)) ;
+ end function RandTime ;
+
+ impure function RandSlv (A, Exclude : integer_vector ; Size : natural) return std_logic_vector is
+ begin
+ return std_logic_vector(to_unsigned(RandInt(A, Exclude), Size)) ;
+ end function RandSlv ;
+
+ impure function RandUnsigned (A, Exclude : integer_vector ; Size : natural) return Unsigned is
+ begin
+ return to_unsigned(RandInt(A, Exclude), Size) ;
+ end function RandUnsigned ;
+
+ impure function RandSigned (A, Exclude : integer_vector ; Size : natural ) return Signed is
+ begin
+ return to_signed(RandInt(A, Exclude), Size) ;
+ end function RandSigned ;
+
+ impure function RandIntV (A, Exclude : integer_vector ; Size : natural) return integer_vector is
+ variable result : integer_vector(1 to Size) ;
+ variable NewA : integer_vector(1 to A'length) ;
+ variable NewALength : natural ;
+ begin
+ -- Remove Exclude from A
+ RemoveExclude(A, Exclude, NewA, NewALength) ;
+ -- Randomize Index
+ for i in result'range loop
+ result(i) := NewA(RandInt(1, NewALength)) ;
+ end loop ;
+ return result ;
+ end function RandIntV ;
+
+ impure function RandIntV (A, Exclude : integer_vector ; Unique : natural ; Size : natural) return integer_vector is
+ variable result : integer_vector(1 to Size) ;
+ variable NewA : integer_vector(1 to A'length) ;
+ variable NewALength, iUnique : natural ;
+ begin
+ -- if Unique = 0, it is more efficient to call RandIntV(Min, Max, Size)
+ -- Remove Exclude from A
+ RemoveExclude(A, Exclude, NewA, NewALength) ;
+ -- Require NewALength >= Unique
+ iUnique := Unique ;
+ if NewALength < Unique then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.RandIntV: Unique > Length of Set A - Exclude", FAILURE) ;
+ iUnique := NewALength ;
+ end if ;
+ -- Randomize using exclude list of Unique # of newly generated values
+ for i in result'range loop
+ result(i) := RandInt(NewA(1 to NewALength), result(maximum(1, 1 + i - iUnique) to Size)) ;
+ end loop ;
+ return result ;
+ end function RandIntV ;
+
+ impure function RandRealV (A, Exclude : real_vector ; Size : natural) return real_vector is
+ variable result : real_vector(1 to Size) ;
+ variable NewA : real_vector(1 to A'length) ;
+ variable NewALength : natural ;
+ begin
+ -- Remove Exclude from A
+ RemoveExclude(A, Exclude, NewA, NewALength) ;
+ -- Randomize Index
+ for i in result'range loop
+ result(i) := NewA(RandInt(1, NewALength)) ;
+ end loop ;
+ return result ;
+ end function RandRealV ;
+
+ impure function RandRealV (A, Exclude : real_vector ; Unique : natural ; Size : natural) return real_vector is
+ variable result : real_vector(1 to Size) ;
+ variable NewA : real_vector(1 to A'length) ;
+ variable NewALength, iUnique : natural ;
+ begin
+ -- if Unique = 0, it is more efficient to call RandRealV(Min, Max, Size)
+ -- Remove Exclude from A
+ RemoveExclude(A, Exclude, NewA, NewALength) ;
+ -- Require NewALength >= Unique
+ iUnique := Unique ;
+ if NewALength < Unique then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.RandRealV: Unique > Length of Set A - Exclude", FAILURE) ;
+ iUnique := NewALength ;
+ end if ;
+ -- Randomize using exclude list of Unique # of newly generated values
+ for i in result'range loop
+ result(i) := RandReal(NewA(1 to NewALength), result(maximum(1, 1 + i - iUnique) to Size)) ;
+ end loop ;
+ return result ;
+ end function RandRealV ;
+
+ impure function RandTimeV (A, Exclude : time_vector ; Size : natural) return time_vector is
+ variable result : time_vector(1 to Size) ;
+ variable NewA : time_vector(1 to A'length) ;
+ variable NewALength : natural ;
+ begin
+ -- Remove Exclude from A
+ RemoveExclude(A, Exclude, NewA, NewALength) ;
+ -- Randomize Index
+ for i in result'range loop
+ result(i) := NewA(RandInt(1, NewALength)) ;
+ end loop ;
+ return result ;
+ end function RandTimeV ;
+
+ impure function RandTimeV (A, Exclude : time_vector ; Unique : natural ; Size : natural) return time_vector is
+ variable result : time_vector(1 to Size) ;
+ variable NewA : time_vector(1 to A'length) ;
+ variable NewALength, iUnique : natural ;
+ begin
+ -- if Unique = 0, it is more efficient to call RandRealV(Min, Max, Size)
+ -- Remove Exclude from A
+ RemoveExclude(A, Exclude, NewA, NewALength) ;
+ -- Require NewALength >= Unique
+ iUnique := Unique ;
+ if NewALength < Unique then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.RandTimeV: Unique > Length of Set A - Exclude", FAILURE) ;
+ iUnique := NewALength ;
+ end if ;
+ -- Randomize using exclude list of Unique # of newly generated values
+ for i in result'range loop
+ result(i) := RandTime(NewA(1 to NewALength), result(maximum(1, 1 + i - iUnique) to Size)) ;
+ end loop ;
+ return result ;
+ end function RandTimeV ;
+
+
+ --
+ -- Basic Discrete Distributions
+ -- Always uses Uniform
+ --
+ impure function DistInt ( Weight : integer_vector ) return integer is
+ variable DistArray : integer_vector(weight'range) ;
+ variable sum : integer ;
+ variable iRandomVal : integer ;
+ begin
+ DistArray := Weight ;
+ sum := 0 ;
+ for i in DistArray'range loop
+ DistArray(i) := DistArray(i) + sum ;
+ if DistArray(i) < sum then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.DistInt: negative weight or sum > 31 bits", FAILURE) ;
+ return DistArray'low ; -- allows debugging vs integer'left, out of range
+ end if ;
+ sum := DistArray(i) ;
+ end loop ;
+ if sum >= 1 then
+ iRandomVal := Uniform(1, sum) ;
+ for i in DistArray'range loop
+ if iRandomVal <= DistArray(i) then
+ return i ;
+ end if ;
+ end loop ;
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.DistInt: randomization failed", FAILURE) ;
+ else
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.DistInt: No randomization weights", FAILURE) ;
+ end if ;
+ return DistArray'low ; -- allows debugging vs integer'left, out of range
+ end function DistInt ;
+
+ impure function DistSlv ( Weight : integer_vector ; Size : natural ) return std_logic_vector is
+ begin
+ return std_logic_vector(to_unsigned(DistInt(Weight), Size)) ;
+ end function DistSlv ;
+
+ impure function DistUnsigned ( Weight : integer_vector ; Size : natural ) return unsigned is
+ begin
+ return to_unsigned(DistInt(Weight), Size) ;
+ end function DistUnsigned ;
+
+ impure function DistSigned ( Weight : integer_vector ; Size : natural ) return signed is
+ begin
+ return to_signed(DistInt(Weight), Size) ;
+ end function DistSigned ;
+
+
+ --
+ -- Basic Distributions with exclude values (so can skip last or last n)
+ -- Always uses Uniform via DistInt
+ --
+ impure function DistInt ( Weight : integer_vector ; Exclude : integer_vector ) return integer is
+ variable DistArray : integer_vector(weight'range) ;
+ variable ExcludeTemp : integer ;
+ begin
+ DistArray := Weight ;
+ for i in Exclude'range loop
+ ExcludeTemp := Exclude(i) ;
+ if ExcludeTemp >= DistArray'low and ExcludeTemp <= DistArray'high then
+ DistArray(ExcludeTemp) := 0 ;
+ end if ;
+ end loop ;
+ return DistInt(DistArray) ;
+ end function DistInt ;
+
+ impure function DistSlv ( Weight : integer_vector ; Exclude : integer_vector ; Size : natural ) return std_logic_vector is
+ begin
+ return std_logic_vector(to_unsigned(DistInt(Weight, Exclude), Size)) ;
+ end function DistSlv ;
+
+ impure function DistUnsigned ( Weight : integer_vector ; Exclude : integer_vector ; Size : natural ) return unsigned is
+ begin
+ return to_unsigned(DistInt(Weight, Exclude), Size) ;
+ end function DistUnsigned ;
+
+ impure function DistSigned ( Weight : integer_vector ; Exclude : integer_vector ; Size : natural ) return signed is
+ begin
+ return to_signed(DistInt(Weight, Exclude), Size) ;
+ end function DistSigned ;
+
+
+ --
+ -- Distribution for sparse values
+ -- Always uses Uniform via DistInt
+ --
+ impure function DistValInt ( A : DistType ) return integer is
+ variable DistArray : integer_vector(0 to A'length -1) ;
+ alias DistRecArray : DistType(DistArray'range) is A ;
+ begin
+ for i in DistArray'range loop
+ DistArray(i) := DistRecArray(i).Weight ;
+ end loop ;
+ return DistRecArray(DistInt(DistArray)).Value ;
+ end function DistValInt ;
+
+ impure function DistValSlv ( A : DistType ; Size : natural ) return std_logic_vector is
+ begin
+ return std_logic_vector(to_unsigned(DistValInt(A), Size)) ;
+ end function DistValSlv ;
+
+ impure function DistValUnsigned ( A : DistType ; Size : natural ) return unsigned is
+ begin
+ return to_unsigned(DistValInt(A), Size) ;
+ end function DistValUnsigned ;
+
+ impure function DistValSigned ( A : DistType ; Size : natural ) return signed is
+ begin
+ return to_signed(DistValInt(A), Size) ;
+ end function DistValSigned ;
+
+
+ --
+ -- Distribution for sparse values with exclude values (so can skip last or last n)
+ -- Always uses Uniform via DistInt
+ --
+ impure function DistValInt ( A : DistType ; Exclude : integer_vector ) return integer is
+ variable DistArray : integer_vector(0 to A'length -1) ;
+ alias DistRecArray : DistType(DistArray'range) is A ;
+ begin
+ for i in DistRecArray'range loop
+ if inside(DistRecArray(i).Value, exclude) then
+ DistArray(i) := 0 ; -- exclude
+ else
+ DistArray(i) := DistRecArray(i).Weight ;
+ end if ;
+ end loop ;
+ return DistRecArray(DistInt(DistArray)).Value ;
+ end function DistValInt ;
+
+ impure function DistValSlv ( A : DistType ; Exclude : integer_vector ; Size : natural ) return std_logic_vector is
+ begin
+ return std_logic_vector(to_unsigned(DistValInt(A, Exclude), Size)) ;
+ end function DistValSlv ;
+
+ impure function DistValUnsigned ( A : DistType ; Exclude : integer_vector ; Size : natural ) return unsigned is
+ begin
+ return to_unsigned(DistValInt(A, Exclude), Size) ;
+ end function DistValUnsigned ;
+
+ impure function DistValSigned ( A : DistType ; Exclude : integer_vector ; Size : natural ) return signed is
+ begin
+ return to_signed(DistValInt(A, Exclude), Size) ;
+ end function DistValSigned ;
+
+
+ --
+ -- Large vector handling.
+ --
+ impure function RandUnsigned (Size : natural) return unsigned is
+ constant NumLoops : integer := integer(ceil(real(Size)/30.0)) ;
+ constant Remain : integer := (Size - 1) mod 30 + 1 ; -- range 1 to 30
+ variable RandVal : unsigned(1 to Size) ;
+ begin
+ if size = 0 then
+ return NULL_UV ; -- Null array
+ end if ;
+ for i in 0 to NumLoops-2 loop
+ RandVal(1 + 30*i to 30 + 30*i) := to_unsigned(RandInt(0, 2**30-1), 30) ;
+ end loop ;
+ RandVal(1+30*(NumLoops-1) to Remain + 30*(NumLoops-1)) := to_unsigned(RandInt(0, 2**Remain-1), Remain) ;
+ return RandVal ;
+ end function RandUnsigned ;
+
+ impure function RandSlv (Size : natural) return std_logic_vector is
+ begin
+ return std_logic_vector(RandUnsigned(Size)) ;
+ end function RandSlv ;
+
+ impure function RandSigned (Size : natural) return signed is
+ begin
+ return signed(RandUnsigned(Size)) ;
+ end function RandSigned ;
+
+
+ impure function RandUnsigned (Max : unsigned) return unsigned is
+ alias normMax : unsigned (Max'length downto 1) is Max ;
+ variable Result : unsigned(Max'range) := (others => '0') ;
+ alias normResult : unsigned(normMax'range) is Result ;
+ variable Size : integer ;
+ begin
+ -- Size = -1 if not found or Max'length = 0
+ Size := find_leftmost(normMax, '1') ;
+
+ if Size > 0 then
+ loop
+ normResult(Size downto 1) := RandUnsigned(Size) ;
+ exit when normResult <= Max ;
+ end loop ;
+ return Result ; -- = normResult with range same as Max
+ else
+ return resize("0", Max'length) ;
+ end if ;
+ end function RandUnsigned ;
+
+ -- Working version that scales the value
+ -- impure function RandUnsigned (Max : unsigned) return unsigned is
+ -- constant MaxVal : unsigned(Max'length+3 downto 1) := (others => '1') ;
+ -- begin
+ -- if max'length > 0 then
+ -- -- "Max'length+3" creates 3 guard bits
+ -- return resize( RandUnsigned(Max'length+3) * ('0'&Max+1) / ('0'&MaxVal+1), Max'length) ;
+ -- else
+ -- return NULL_UV ; -- Null Array
+ -- end if ;
+ -- end function RandUnsigned ;
+
+ impure function RandSlv (Max : std_logic_vector) return std_logic_vector is
+ begin
+ return std_logic_vector(RandUnsigned( unsigned(Max))) ;
+ end function RandSlv ;
+
+ impure function RandSigned (Max : signed) return signed is
+ begin
+ if max'length > 0 then
+ AlertIf (OSVVM_ALERTLOG_ID, Max < 0, "RandomPkg.RandSigned: Max < 0", FAILURE) ;
+ return signed(RandUnsigned( unsigned(Max))) ;
+ else
+ return NULL_SV ; -- Null Array
+ end if ;
+ end function RandSigned ;
+
+
+ impure function RandUnsigned (Min, Max : unsigned) return unsigned is
+ constant LEN : integer := maximum(Max'length, Min'length) ;
+ begin
+ if LEN > 0 and Min <= Max then
+ return RandUnsigned(Max-Min) + Min ;
+ else
+ if Len > 0 then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.RandUnsigned: Max < Min", FAILURE) ;
+ end if ;
+ return NULL_UV ;
+ end if ;
+ end function RandUnsigned ;
+
+
+ impure function RandSlv (Min, Max : std_logic_vector) return std_logic_vector is
+ constant LEN : integer := maximum(Max'length, Min'length) ;
+ begin
+ if LEN > 0 and Min <= Max then
+ return RandSlv(Max-Min) + Min ;
+ else
+ if Len > 0 then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.RandSlv: Max < Min", FAILURE) ;
+ end if ;
+ return NULL_SlV ;
+ end if ;
+ end function RandSlv ;
+
+
+ impure function RandSigned (Min, Max : signed) return signed is
+ constant LEN : integer := maximum(Max'length, Min'length) ;
+ begin
+ if LEN > 0 and Min <= Max then
+ return resize(RandSigned(resize(Max,LEN+1) - resize(Min,LEN+1)) + Min, LEN) ;
+ else
+ if Len > 0 then
+ Alert(OSVVM_ALERTLOG_ID, "RandomPkg.RandSigned: Max < Min", FAILURE) ;
+ end if ;
+ return NULL_SV ;
+ end if ;
+ end function RandSigned ;
+
+
+ --
+ -- Convenience Functions. Resolve into calls into the other functions
+ --
+ impure function RandReal return real is
+ begin
+ return RandReal(0.0, 1.0) ;
+ end function RandReal ;
+
+ impure function RandReal(Max : Real) return real is -- 0.0 to Max
+ begin
+ return RandReal(0.0, Max) ;
+ end function RandReal ;
+
+ impure function RandInt (Max : integer) return integer is
+ begin
+ return RandInt(0, Max) ;
+ end function RandInt ;
+
+ impure function RandSlv (Max, Size : natural) return std_logic_vector is
+ begin
+ return std_logic_vector(to_unsigned(RandInt(0, Max), Size)) ;
+ end function RandSlv ;
+
+ impure function RandUnsigned (Max, Size : natural) return Unsigned is
+ begin
+ return to_unsigned(RandInt(0, Max), Size) ;
+ end function RandUnsigned ;
+
+
+ impure function RandSigned (Max : integer ; Size : natural ) return Signed is
+ begin
+ -- chose 0 to Max rather than -Max to +Max to be same as RandUnsigned, either seems logical
+ return to_signed(RandInt(0, Max), Size) ;
+ end function RandSigned ;
+
+ end protected body RandomPType ;
+
+end RandomPkg ; \ No newline at end of file
diff --git a/testsuite/gna/issue317/OSVVM/ScoreboardGenericPkg.vhd b/testsuite/gna/issue317/OSVVM/ScoreboardGenericPkg.vhd
new file mode 100644
index 000000000..17a227fa1
--- /dev/null
+++ b/testsuite/gna/issue317/OSVVM/ScoreboardGenericPkg.vhd
@@ -0,0 +1,1573 @@
+--
+-- File Name: ScoreBoardGenericPkg.vhd
+-- Design Unit Name: ScoreBoardGenericPkg
+-- Revision: STANDARD VERSION
+--
+-- Maintainer: Jim Lewis email: jim@synthworks.com
+-- Contributor(s):
+-- Jim Lewis email: jim@synthworks.com
+--
+--
+-- Description:
+-- Defines types and methods to implement a FIFO based Scoreboard
+-- Defines type ScoreBoardPType
+-- Defines methods for putting values the scoreboard
+--
+-- Developed for:
+-- SynthWorks Design Inc.
+-- VHDL Training Classes
+-- 11898 SW 128th Ave. Tigard, Or 97223
+-- http://www.SynthWorks.com
+--
+-- Latest standard version available at:
+-- http://www.SynthWorks.com/downloads
+--
+-- Revision History:
+-- Date Version Description
+-- 12/2006: 2006.12 Initial revision
+-- 08/2010 2010.08 Added Tailpointer
+-- 05/2012 2012.05 Changed FIFO to store pointers to ExpectedType
+-- Allows usage of unconstrained arrays
+-- 08/2012 2012.08 Added Type and Subprogram Generics
+-- 08/2013 2013.08 Generics: to_string replaced write, Match replaced check
+-- Added Tags - Experimental
+-- Added Array of Scoreboards
+-- 09/2013 2013.09 Added file handling, Check Count, Finish Status
+-- Find, Flush
+-- 06/2015 2015.06 Added Alerts, SetAlertLogID, Revised LocalPush, GetDropCount,
+-- Deprecated SetFinish and ReportMode - REPORT_NONE, FileOpen
+-- Deallocate, Initialized, Function SetName
+-- 11/2016 2016.11 Released as part of OSVVM
+--
+--
+--
+-- Copyright (c) 2006 - 2016 by SynthWorks Design Inc. All rights reserved.
+--
+-- Verbatim copies of this source file may be used and
+-- distributed without restriction.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the ARTISTIC License
+-- as published by The Perl Foundation; either version 2.0 of
+-- the License, or (at your option) any later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the Artistic License for details.
+--
+-- You should have received a copy of the license with this source.
+-- If not download it from,
+-- http://www.perlfoundation.org/artistic_license_2_0
+--
+--
+
+use std.textio.all ;
+
+library ieee ;
+ use ieee.std_logic_1164.all ;
+ use ieee.numeric_std.all ;
+
+ use work.TranscriptPkg.all ;
+ use work.AlertLogPkg.all ;
+ use work.NamePkg.all ;
+
+
+package ScoreboardGenericPkg is
+ generic (
+ type ExpectedType ;
+ type ActualType ;
+ function Match(Actual : ActualType ; -- defaults
+ Expected : ExpectedType) return boolean ; -- is "=" ;
+ function expected_to_string(A : ExpectedType) return string ; -- is to_string ;
+ function actual_to_string (A : ActualType) return string -- is to_string ;
+ ) ;
+
+-- -- For a VHDL-2002 package, comment out the generics and
+-- -- uncomment the following, it replaces a generic instance of the package.
+-- -- As a result, you will have multiple copies of the entire package.
+-- -- Inconvenient, but ok as it still works the same.
+-- subtype ExpectedType is std_logic_vector ;
+-- subtype ActualType is std_logic_vector ;
+-- alias Match is std_match [ActualType, ExpectedType return boolean] ; -- for std_logic_vector
+-- alias expected_to_string is to_hstring [ExpectedType return string]; -- VHDL-2008
+-- alias actual_to_string is to_hstring [ActualType return string]; -- VHDL-2008
+
+ -- ScoreboardReportType is deprecated
+ -- Replaced by Affirmations. ERROR is the default. ALL turns on PASSED flag
+ type ScoreboardReportType is (REPORT_ERROR, REPORT_ALL, REPORT_NONE) ; -- replaced by affirmations
+
+ type ScoreBoardPType is protected
+
+ ------------------------------------------------------------
+ -- Emulate arrays of scoreboards
+ procedure SetArrayIndex(L, R : integer) ; -- supports integer indices
+ procedure SetArrayIndex(R : natural) ; -- indicies 1 to R
+ impure function GetArrayIndex return integer_vector ;
+ impure function GetArrayLength return natural ;
+
+ ------------------------------------------------------------
+ -- Push items into the scoreboard/FIFO
+
+ -- Simple Scoreboard, no tag
+ procedure Push (Item : in ExpectedType) ;
+
+ -- Simple Tagged Scoreboard
+ procedure Push (
+ constant Tag : in string ;
+ constant Item : in ExpectedType
+ ) ;
+
+ -- Array of Scoreboards, no tag
+ procedure Push (
+ constant Index : in integer ;
+ constant Item : in ExpectedType
+ ) ;
+
+ -- Array of Tagged Scoreboards
+ procedure Push (
+ constant Index : in integer ;
+ constant Tag : in string ;
+ constant Item : in ExpectedType
+ ) ;
+
+-- ------------------------------------------------------------
+-- -- Push items into the scoreboard/FIFO
+-- -- Function form supports chaining of operations
+-- -- In 2013, this caused overloading issues in some simulators, will retest later
+--
+-- -- Simple Scoreboard, no tag
+-- impure function Push (Item : ExpectedType) return ExpectedType ;
+--
+-- -- Simple Tagged Scoreboard
+-- impure function Push (
+-- constant Tag : in string ;
+-- constant Item : in ExpectedType
+-- ) return ExpectedType ;
+--
+-- -- Array of Scoreboards, no tag
+-- impure function Push (
+-- constant Index : in integer ;
+-- constant Item : in ExpectedType
+-- ) return ExpectedType ;
+--
+-- -- Array of Tagged Scoreboards
+-- impure function Push (
+-- constant Index : in integer ;
+-- constant Tag : in string ;
+-- constant Item : in ExpectedType
+-- ) return ExpectedType ; -- for chaining of operations
+
+ ------------------------------------------------------------
+ -- Check received item with item in the scoreboard/FIFO
+
+ -- Simple Scoreboard, no tag
+ procedure Check (ActualData : ActualType) ;
+
+ -- Simple Tagged Scoreboard
+ procedure Check (
+ constant Tag : in string ;
+ constant ActualData : in ActualType
+ ) ;
+
+ -- Array of Scoreboards, no tag
+ procedure Check (
+ constant Index : in integer ;
+ constant ActualData : in ActualType
+ ) ;
+
+ -- Array of Tagged Scoreboards
+ procedure Check (
+ constant Index : in integer ;
+ constant Tag : in string ;
+ constant ActualData : in ActualType
+ ) ;
+
+ ------------------------------------------------------------
+ -- Pop the top item (FIFO) from the scoreboard/FIFO
+
+ -- Simple Scoreboard, no tag
+ procedure Pop (variable Item : out ExpectedType) ;
+
+ -- Simple Tagged Scoreboard
+ procedure Pop (
+ constant Tag : in string ;
+ variable Item : out ExpectedType
+ ) ;
+
+ -- Array of Scoreboards, no tag
+ procedure Pop (
+ constant Index : in integer ;
+ variable Item : out ExpectedType
+ ) ;
+
+ -- Array of Tagged Scoreboards
+ procedure Pop (
+ constant Index : in integer ;
+ constant Tag : in string ;
+ variable Item : out ExpectedType
+ ) ;
+
+-- ------------------------------------------------------------
+-- -- Pop the top item (FIFO) from the scoreboard/FIFO
+-- -- Function form supports chaining of operations
+-- -- In 2013, this caused overloading issues in some simulators, will retest later
+--
+-- -- Simple Scoreboard, no tag
+-- impure function Pop return ExpectedType ;
+--
+-- -- Simple Tagged Scoreboard
+-- impure function Pop (
+-- constant Tag : in string
+-- ) return ExpectedType ;
+--
+-- -- Array of Scoreboards, no tag
+-- impure function Pop (Index : integer) return ExpectedType ;
+--
+-- -- Array of Tagged Scoreboards
+-- impure function Pop (
+-- constant Index : in integer ;
+-- constant Tag : in string
+-- ) return ExpectedType ;
+
+ ------------------------------------------------------------
+ -- Empty - check to see if scoreboard is empty
+ impure function Empty return boolean ; -- Simple
+ impure function Empty (Tag : String) return boolean ; -- Simple, Tagged
+ impure function Empty (Index : integer) return boolean ; -- Array
+ impure function Empty (Index : integer; Tag : String) return boolean ; -- Array, Tagged
+
+ ------------------------------------------------------------
+ -- SetAlertLogID - associate an AlertLogID with a scoreboard to allow integrated error reporting
+ procedure SetAlertLogID(Index : Integer ; Name : string ; ParentID : AlertLogIDType := ALERTLOG_BASE_ID ; CreateHierarchy : Boolean := TRUE) ;
+ procedure SetAlertLogID(Name : string ; ParentID : AlertLogIDType := ALERTLOG_BASE_ID ; CreateHierarchy : Boolean := TRUE) ;
+ -- Use when an AlertLogID is used by multiple items (BFM or Scoreboards). See also AlertLogPkg.GetAlertLogID
+ procedure SetAlertLogID (Index : Integer ; A : AlertLogIDType) ;
+ procedure SetAlertLogID (A : AlertLogIDType) ;
+ impure function GetAlertLogID(Index : Integer) return AlertLogIDType ;
+ impure function GetAlertLogID return AlertLogIDType ;
+
+ ------------------------------------------------------------
+ -- Set a scoreboard name.
+ -- Used when scoreboard AlertLogID is shared between different sources.
+ procedure SetName (Name : String) ;
+ impure function SetName (Name : String) return string ;
+ impure function GetName (DefaultName : string := "Scoreboard") return string ;
+
+
+ ------------------------------------------------------------
+ -- Scoreboard Introspection
+
+ -- Number of items put into scoreboard
+ impure function GetItemCount return integer ; -- Simple, with or without tags
+ impure function GetItemCount (Index : integer) return integer ; -- Arrays, with or without tags
+
+ -- Number of items checked by scoreboard
+ impure function GetCheckCount return integer ; -- Simple, with or without tags
+ impure function GetCheckCount (Index : integer) return integer ; -- Arrays, with or without tags
+
+ -- Number of items dropped by scoreboard. See Find/Flush
+ impure function GetDropCount return integer ; -- Simple, with or without tags
+ impure function GetDropCount (Index : integer) return integer ; -- Arrays, with or without tags
+
+ ------------------------------------------------------------
+ -- Find - Returns the ItemNumber for a value and tag (if applicable) in a scoreboard.
+ -- Find returns integer'left if no match found
+ -- Also See Flush. Flush will drop items up through the ItemNumber
+
+ -- Simple Scoreboard
+ impure function Find (
+ constant ActualData : in ActualType
+ ) return integer ;
+
+ -- Tagged Scoreboard
+ impure function Find (
+ constant Tag : in string;
+ constant ActualData : in ActualType
+ ) return integer ;
+
+ -- Array of Simple Scoreboards
+ impure function Find (
+ constant Index : in integer ;
+ constant ActualData : in ActualType
+ ) return integer ;
+
+ -- Array of Tagged Scoreboards
+ impure function Find (
+ constant Index : in integer ;
+ constant Tag : in string;
+ constant ActualData : in ActualType
+ ) return integer ;
+
+ ------------------------------------------------------------
+ -- Flush - Remove elements in the scoreboard upto and including the one with ItemNumber
+ -- See Find to identify an ItemNumber of a particular value and tag (if applicable)
+
+ -- Simple Scoreboard
+ procedure Flush (
+ constant ItemNumber : in integer
+ ) ;
+
+ -- Tagged Scoreboard - only removes items that also match the tag
+ procedure Flush (
+ constant Tag : in string ;
+ constant ItemNumber : in integer
+ ) ;
+
+ -- Array of Simple Scoreboards
+ procedure Flush (
+ constant Index : in integer ;
+ constant ItemNumber : in integer
+ ) ;
+
+ -- Array of Tagged Scoreboards - only removes items that also match the tag
+ procedure Flush (
+ constant Index : in integer ;
+ constant Tag : in string ;
+ constant ItemNumber : in integer
+ ) ;
+
+ ------------------------------------------------------------
+ -- Generally these are not required. When a simulation ends and
+ -- another simulation is started, a simulator will release all allocated items.
+ procedure Deallocate ; -- Deletes all allocated items
+ procedure Initialize ; -- Creates initial data structure if it was destroyed with Deallocate
+
+
+ ------------------------------------------------------------
+ ------------------------------------------------------------
+ -- Deprecated. Use alerts directly instead.
+ -- AlertIF(SB.GetCheckCount < 10, ....) ;
+ -- AlertIf(Not SB.Empty, ...) ;
+ ------------------------------------------------------------
+ -- Set alerts if scoreboard not empty or if CheckCount <
+ -- Use if need to check empty or CheckCount for a specific scoreboard.
+
+ -- Simple Scoreboards, with or without tag
+ procedure CheckFinish (
+ FinishCheckCount : integer ;
+ FinishEmpty : boolean
+ ) ;
+
+ -- Array of Scoreboards, with or without tag
+ procedure CheckFinish (
+ Index : integer ;
+ FinishCheckCount : integer ;
+ FinishEmpty : boolean
+ ) ;
+
+ ------------------------------------------------------------
+ -- Get error count
+ -- Deprecated, replaced by usage of Alerts
+ -- AlertFLow: Instead use AlertLogPkg.ReportAlerts or AlertLogPkg.GetAlertCount
+ -- Not AlertFlow: use GetErrorCount to get total error count
+
+ -- Simple Scoreboards, with or without tag
+ impure function GetErrorCount return integer ;
+
+ -- Array of Scoreboards, with or without tag
+ impure function GetErrorCount(Index : integer) return integer ;
+
+ ------------------------------------------------------------
+ -- Error count manipulation
+
+ -- IncErrorCount - not recommended, use alerts instead - may be deprecated in the future
+ procedure IncErrorCount ; -- Simple, with or without tags
+ procedure IncErrorCount (Index : integer) ; -- Arrays, with or without tags
+
+ -- Clear error counter. Caution does not change AlertCounts, must also use AlertLogPkg.ClearAlerts
+ procedure SetErrorCountZero ; -- Simple, with or without tags
+ procedure SetErrorCountZero (Index : integer) ; -- Arrays, with or without tags
+
+ ------------------------------------------------------------
+ ------------------------------------------------------------
+ -- Deprecated. Names changed. Maintained for backward compatibility - would prefer an alias
+ ------------------------------------------------------------
+ procedure FileOpen (FileName : string; OpenKind : File_Open_Kind ) ; -- Replaced by TranscriptPkg.TranscriptOpen
+ procedure PutExpectedData (ExpectedData : ExpectedType) ; -- Replaced by push
+ procedure CheckActualData (ActualData : ActualType) ; -- Replaced by Check
+ impure function GetItemNumber return integer ; -- Replaced by GetItemCount
+ procedure SetMessage (MessageIn : String) ; -- Replaced by SetName
+ impure function GetMessage return string ; -- Replaced by GetName
+
+ -- Deprecated and may be deleted in a future revision
+ procedure SetFinish ( -- Replaced by CheckFinish
+ Index : integer ;
+ FCheckCount : integer ;
+ FEmpty : boolean := TRUE;
+ FStatus : boolean := TRUE
+ ) ;
+
+ procedure SetFinish ( -- Replaced by CheckFinish
+ FCheckCount : integer ;
+ FEmpty : boolean := TRUE;
+ FStatus : boolean := TRUE
+ ) ;
+
+ ------------------------------------------------------------
+ -- SetReportMode
+ -- Not AlertFlow
+ -- REPORT_ALL: Replaced by AlertLogPkg.SetLogEnable(PASSED, TRUE)
+ -- REPORT_ERROR: Replaced by AlertLogPkg.SetLogEnable(PASSED, FALSE)
+ -- REPORT_NONE: Deprecated, do not use.
+ -- AlertFlow:
+ -- REPORT_ALL: Replaced by AlertLogPkg.SetLogEnable(AlertLogID, PASSED, TRUE)
+ -- REPORT_ERROR: Replaced by AlertLogPkg.SetLogEnable(AlertLogID, PASSED, FALSE)
+ -- REPORT_NONE: Replaced by AlertLogPkg.SetAlertEnable(AlertLogID, ERROR, FALSE)
+ procedure SetReportMode (ReportModeIn : ScoreboardReportType) ;
+ impure function GetReportMode return ScoreboardReportType ;
+
+
+ end protected ScoreBoardPType ;
+
+end ScoreboardGenericPkg ;
+
+
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+package body ScoreboardGenericPkg is
+
+ type ScoreBoardPType is protected body
+ type ExpectedPointerType is access ExpectedType ;
+
+ type ListType ;
+ type ListPointerType is access ListType ;
+ type ListType is record
+ ItemNumber : integer ;
+ TagPtr : line ;
+ ExpectedPtr : ExpectedPointerType ;
+ NextPtr : ListPointerType ;
+ end record ;
+ type ListArrayType is array (integer range <>) of ListPointerType ;
+ type ListArrayPointerType is access ListArrayType ;
+
+ variable ArrayLengthVar : integer := 1 ;
+ variable HeadPointer : ListArrayPointerType := new ListArrayType(1 to 1) ;
+ variable TailPointer : ListArrayPointerType := new ListArrayType(1 to 1) ;
+ variable PopListPointer : ListArrayPointerType := new ListArrayType(1 to 1) ;
+
+ type IntegerArrayType is array (integer range <>) of Integer ;
+ type IntegerArrayPointerType is access IntegerArrayType ;
+
+ variable ErrCntVar : IntegerArrayPointerType := new IntegerArrayType'(1 => 0) ;
+ variable DropCountVar : IntegerArrayPointerType := new IntegerArrayType'(1 => 0) ;
+ variable ItemNumberVar : IntegerArrayPointerType := new IntegerArrayType'(1 => 0) ;
+ variable CheckCountVar : IntegerArrayPointerType := new IntegerArrayType'(1 => 0) ;
+ variable AlertLogIDVar : IntegerArrayPointerType := new IntegerArrayType'(1 => OSVVM_SCOREBOARD_ALERTLOG_ID) ;
+
+ variable NameVar : NamePType ;
+ variable ReportModeVar : ScoreboardReportType ;
+ variable FirstIndexVar : integer := 1 ;
+
+
+ ------------------------------------------------------------
+ procedure SetName (Name : String) is
+ ------------------------------------------------------------
+ begin
+ NameVar.Set(Name) ;
+ end procedure SetName ;
+
+ ------------------------------------------------------------
+ impure function SetName (Name : String) return string is
+ ------------------------------------------------------------
+ begin
+ NameVar.Set(Name) ;
+ return Name ;
+ end function SetName ;
+
+ ------------------------------------------------------------
+ impure function GetName (DefaultName : string := "Scoreboard") return string is
+ ------------------------------------------------------------
+ begin
+ return NameVar.Get(DefaultName) ;
+ end function GetName ;
+
+ ------------------------------------------------------------
+ procedure SetReportMode (ReportModeIn : ScoreboardReportType) is
+ ------------------------------------------------------------
+ begin
+ ReportModeVar := ReportModeIn ;
+ if ReportModeVar = REPORT_ALL then
+ Alert(OSVVM_SCOREBOARD_ALERTLOG_ID, "ScoreboardGenericPkg.SetReportMode: To turn off REPORT_ALL, use osvvm.AlertLogPkg.SetLogEnable(PASSED, FALSE)", WARNING) ;
+ for i in AlertLogIDVar'range loop
+ SetLogEnable(AlertLogIDVar(i), PASSED, TRUE) ;
+ end loop ;
+ end if ;
+ if ReportModeVar = REPORT_NONE then
+ Alert(OSVVM_SCOREBOARD_ALERTLOG_ID, "ScoreboardGenericPkg.SetReportMode: ReportMode REPORT_NONE has been deprecated and will be removed in next revision. Please contact OSVVM architect Jim Lewis if you need this capability.", WARNING) ;
+ end if ;
+ end procedure SetReportMode ;
+
+ ------------------------------------------------------------
+ impure function GetReportMode return ScoreboardReportType is
+ ------------------------------------------------------------
+ begin
+ return ReportModeVar ;
+ end function GetReportMode ;
+
+ ------------------------------------------------------------
+ procedure SetArrayIndex(L, R : integer) is
+ ------------------------------------------------------------
+ variable OldHeadPointer, OldTailPointer, OldPopListPointer : ListArrayPointerType ;
+ variable OldErrCnt, OldDropCount, OldItemNumber, OldCheckCount, OldAlertLogIDVar : IntegerArrayPointerType ;
+ variable Min, Max, Len, OldLen, OldMax : integer ;
+ begin
+ Min := minimum(L, R) ;
+ Max := maximum(L, R) ;
+ OldLen := ArrayLengthVar ;
+ OldMax := Min + ArrayLengthVar - 1 ;
+ Len := Max - Min + 1 ;
+ ArrayLengthVar := Len ;
+ if Len >= OldLen then
+ FirstIndexVar := Min ;
+
+ OldHeadPointer := HeadPointer ;
+ HeadPointer := new ListArrayType(Min to Max) ;
+ if OldHeadPointer /= NULL then
+ HeadPointer(Min to OldMax) := OldHeadPointer.all ; -- (OldHeadPointer'range) ;
+ Deallocate(OldHeadPointer) ;
+ end if ;
+
+ OldTailPointer := TailPointer ;
+ TailPointer := new ListArrayType(Min to Max) ;
+ if OldTailPointer /= NULL then
+ TailPointer(Min to OldMax) := OldTailPointer.all ;
+ Deallocate(OldTailPointer) ;
+ end if ;
+
+ OldPopListPointer := PopListPointer ;
+ PopListPointer := new ListArrayType(Min to Max) ;
+ if OldPopListPointer /= NULL then
+ PopListPointer(Min to OldMax) := OldPopListPointer.all ;
+ Deallocate(OldPopListPointer) ;
+ end if ;
+
+ OldErrCnt := ErrCntVar ;
+ ErrCntVar := new IntegerArrayType'(Min to Max => 0) ;
+ if OldErrCnt /= NULL then
+ ErrCntVar(Min to OldMax) := OldErrCnt.all ;
+ Deallocate(OldErrCnt) ;
+ end if ;
+
+ OldDropCount := DropCountVar ;
+ DropCountVar := new IntegerArrayType'(Min to Max => 0) ;
+ if OldDropCount /= NULL then
+ DropCountVar(Min to OldMax) := OldDropCount.all ;
+ Deallocate(OldDropCount) ;
+ end if ;
+
+ OldItemNumber := ItemNumberVar ;
+ ItemNumberVar := new IntegerArrayType'(Min to Max => 0) ;
+ if OldItemNumber /= NULL then
+ ItemNumberVar(Min to OldMax) := OldItemNumber.all ;
+ Deallocate(OldItemNumber) ;
+ end if ;
+
+ OldCheckCount := CheckCountVar ;
+ CheckCountVar := new IntegerArrayType'(Min to Max => 0) ;
+ if OldCheckCount /= NULL then
+ CheckCountVar(Min to OldMax) := OldCheckCount.all ;
+ Deallocate(OldCheckCount) ;
+ end if ;
+
+ OldAlertLogIDVar := AlertLogIDVar ;
+ AlertLogIDVar := new IntegerArrayType'(Min to Max => OSVVM_SCOREBOARD_ALERTLOG_ID) ;
+ if OldAlertLogIDVar /= NULL then
+ AlertLogIDVar(Min to OldMax) := OldAlertLogIDVar.all ;
+ Deallocate(OldAlertLogIDVar) ;
+ end if ;
+
+ elsif Len < OldLen then
+ report "ScoreboardGenericPkg: SetArrayIndex, new array Length <= current array length"
+ severity failure ;
+
+ end if ;
+ end procedure SetArrayIndex ;
+
+ ------------------------------------------------------------
+ procedure SetArrayIndex(R : natural) is
+ ------------------------------------------------------------
+ begin
+ SetArrayIndex(1, R) ;
+ end procedure SetArrayIndex ;
+
+ ------------------------------------------------------------
+ procedure Deallocate is
+ ------------------------------------------------------------
+ variable CurListPtr, LastListPtr : ListPointerType ;
+ begin
+ for Index in HeadPointer'range loop
+ -- Deallocate contents in the scoreboards
+ CurListPtr := HeadPointer(Index) ;
+ while CurListPtr /= Null loop
+ deallocate(CurListPtr.TagPtr) ;
+ deallocate(CurListPtr.ExpectedPtr) ;
+ LastListPtr := CurListPtr ;
+ CurListPtr := CurListPtr.NextPtr ;
+ Deallocate(LastListPtr) ;
+ end loop ;
+ end loop ;
+
+ for Index in PopListPointer'range loop
+ -- Deallocate PopListPointer - only has single element
+ CurListPtr := PopListPointer(Index) ;
+ if CurListPtr /= NULL then
+ deallocate(CurListPtr.TagPtr) ;
+ deallocate(CurListPtr.ExpectedPtr) ;
+ deallocate(CurListPtr) ;
+ end if ;
+ end loop ;
+
+ -- Deallocate arrays of pointers
+ Deallocate(HeadPointer) ;
+ Deallocate(TailPointer) ;
+ Deallocate(PopListPointer) ;
+
+ -- Deallocate supporting arrays
+ Deallocate(ErrCntVar) ;
+ Deallocate(DropCountVar) ;
+ Deallocate(ItemNumberVar) ;
+ Deallocate(CheckCountVar) ;
+ Deallocate(AlertLogIDVar) ;
+
+ -- Deallocate NameVar - NamePType
+ NameVar.Deallocate ;
+
+ ArrayLengthVar := 0 ;
+ end procedure Deallocate ;
+
+ ------------------------------------------------------------
+ -- Construct initial data structure
+ procedure Initialize is
+ ------------------------------------------------------------
+ begin
+ SetArrayIndex(1, 1) ;
+ end procedure Initialize ;
+
+ ------------------------------------------------------------
+ impure function GetArrayIndex return integer_vector is
+ ------------------------------------------------------------
+ begin
+ return (1 => HeadPointer'left, 2 => HeadPointer'right) ;
+ end function GetArrayIndex ;
+
+ ------------------------------------------------------------
+ impure function GetArrayLength return natural is
+ ------------------------------------------------------------
+ begin
+ return ArrayLengthVar ; -- HeadPointer'length ;
+ end function GetArrayLength ;
+
+ ------------------------------------------------------------
+ procedure SetAlertLogID (Index : Integer ; A : AlertLogIDType) is
+ ------------------------------------------------------------
+ begin
+ AlertLogIDVar(Index) := A ;
+ end procedure SetAlertLogID ;
+
+ ------------------------------------------------------------
+ procedure SetAlertLogID (A : AlertLogIDType) is
+ ------------------------------------------------------------
+ begin
+ AlertLogIDVar(FirstIndexVar) := A ;
+ end procedure SetAlertLogID ;
+
+ ------------------------------------------------------------
+ procedure SetAlertLogID(Index : Integer ; Name : string ; ParentID : AlertLogIDType := ALERTLOG_BASE_ID ; CreateHierarchy : Boolean := TRUE) is
+ ------------------------------------------------------------
+ begin
+ AlertLogIDVar(Index) := GetAlertLogID(Name, ParentID, CreateHierarchy) ;
+ end procedure SetAlertLogID ;
+
+ ------------------------------------------------------------
+ procedure SetAlertLogID(Name : string ; ParentID : AlertLogIDType := ALERTLOG_BASE_ID ; CreateHierarchy : Boolean := TRUE) is
+ ------------------------------------------------------------
+ begin
+ AlertLogIDVar(FirstIndexVar) := GetAlertLogID(Name, ParentID, CreateHierarchy) ;
+ end procedure SetAlertLogID ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogID(Index : Integer) return AlertLogIDType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogIDVar(Index) ;
+ end function GetAlertLogID ;
+
+ ------------------------------------------------------------
+ impure function GetAlertLogID return AlertLogIDType is
+ ------------------------------------------------------------
+ begin
+ return AlertLogIDVar(FirstIndexVar) ;
+ end function GetAlertLogID ;
+
+ ------------------------------------------------------------
+ impure function LocalOutOfRange(
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant Name : in string
+ ) return boolean is
+ begin
+ return AlertIf(OSVVM_SCOREBOARD_ALERTLOG_ID, Index < HeadPointer'Low or Index > HeadPointer'High,
+ GetName & " " & Name & " Index: " & to_string(Index) &
+ "is not in the range (" & to_string(HeadPointer'Low) &
+ "to " & to_string(HeadPointer'High) & ")",
+ FAILURE ) ;
+ end function LocalOutOfRange ;
+
+ ------------------------------------------------------------
+ procedure LocalPush (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant Tag : in string ;
+ constant Item : in ExpectedType
+ ) is
+ variable ExpectedPtr : ExpectedPointerType ;
+ variable TagPtr : line ;
+ begin
+ if LocalOutOfRange(Index, "Push") then
+ return ; -- error reporting in LocalOutOfRange
+ end if ;
+
+ ItemNumberVar(Index) := ItemNumberVar(Index) + 1 ;
+ ExpectedPtr := new ExpectedType'(Item) ;
+ TagPtr := new string'(Tag) ;
+
+ if HeadPointer(Index) = NULL then
+ -- 2015.05: allocation using ListTtype'(...) in a protected type does not work in some simulators
+ -- HeadPointer(Index) := new ListType'(ItemNumberVar(Index), TagPtr, ExpectedPtr, NULL) ;
+ HeadPointer(Index) := new ListType ;
+ HeadPointer(Index).ItemNumber := ItemNumberVar(Index) ;
+ HeadPointer(Index).TagPtr := TagPtr ;
+ HeadPointer(Index).ExpectedPtr := ExpectedPtr ;
+ HeadPointer(Index).NextPtr := NULL ;
+ TailPointer(Index) := HeadPointer(Index) ;
+ else
+ -- 2015.05: allocation using ListTtype'(...) in a protected type does not work in some simulators
+ -- TailPointer(Index).NextPtr := new ListType'(ItemNumberVar(Index), TagPtr, ExpectedPtr, NULL) ;
+ TailPointer(Index).NextPtr := new ListType ;
+ TailPointer(Index).NextPtr.ItemNumber := ItemNumberVar(Index) ;
+ TailPointer(Index).NextPtr.TagPtr := TagPtr ;
+ TailPointer(Index).NextPtr.ExpectedPtr := ExpectedPtr ;
+ TailPointer(Index).NextPtr.NextPtr := NULL ;
+ TailPointer(Index) := TailPointer(Index).NextPtr ;
+ end if ;
+ end procedure LocalPush ;
+
+ ------------------------------------------------------------
+ -- Array of Tagged Scoreboards
+ procedure Push (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant Tag : in string ;
+ constant Item : in ExpectedType
+ ) is
+ variable ExpectedPtr : ExpectedPointerType ;
+ variable TagPtr : line ;
+ begin
+ if LocalOutOfRange(Index, "Push") then
+ return ; -- error reporting in LocalOutOfRange
+ end if ;
+ LocalPush(Index, Tag, Item) ;
+ end procedure Push ;
+
+ ------------------------------------------------------------
+ -- Array of Scoreboards, no tag
+ procedure Push (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant Item : in ExpectedType
+ ) is
+ begin
+ if LocalOutOfRange(Index, "Push") then
+ return ; -- error reporting in LocalOutOfRange
+ end if ;
+ LocalPush(Index, "", Item) ;
+ end procedure Push ;
+
+ ------------------------------------------------------------
+ -- Simple Tagged Scoreboard
+ procedure Push (
+ ------------------------------------------------------------
+ constant Tag : in string ;
+ constant Item : in ExpectedType
+ ) is
+ begin
+ LocalPush(FirstIndexVar, Tag, Item) ;
+ end procedure Push ;
+
+ ------------------------------------------------------------
+ -- Simple Scoreboard, no tag
+ procedure Push (Item : in ExpectedType) is
+ ------------------------------------------------------------
+ begin
+ LocalPush(FirstIndexVar, "", Item) ;
+ end procedure Push ;
+
+ ------------------------------------------------------------
+ -- Array of Tagged Scoreboards
+ impure function Push (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant Tag : in string ;
+ constant Item : in ExpectedType
+ ) return ExpectedType is
+ begin
+ if LocalOutOfRange(Index, "Push") then
+ return Item ; -- error reporting in LocalOutOfRange
+ end if ;
+ LocalPush(Index, Tag, Item) ;
+ return Item ;
+ end function Push ;
+
+ ------------------------------------------------------------
+ -- Array of Scoreboards, no tag
+ impure function Push (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant Item : in ExpectedType
+ ) return ExpectedType is
+ begin
+ if LocalOutOfRange(Index, "Push") then
+ return Item ; -- error reporting in LocalOutOfRange
+ end if ;
+ LocalPush(Index, "", Item) ;
+ return Item ;
+ end function Push ;
+
+ ------------------------------------------------------------
+ -- Simple Tagged Scoreboard
+ impure function Push (
+ ------------------------------------------------------------
+ constant Tag : in string ;
+ constant Item : in ExpectedType
+ ) return ExpectedType is
+ begin
+ LocalPush(FirstIndexVar, Tag, Item) ;
+ return Item ;
+ end function Push ;
+
+ ------------------------------------------------------------
+ -- Simple Scoreboard, no tag
+ impure function Push (Item : ExpectedType) return ExpectedType is
+ ------------------------------------------------------------
+ begin
+ LocalPush(FirstIndexVar, "", Item) ;
+ return Item ;
+ end function Push ;
+
+ ------------------------------------------------------------
+ -- Local Only
+ -- Pops highest element matching Tag into PopListPointer(Index)
+ procedure LocalPop (Index : integer ; Tag : string; Name : string) is
+ ------------------------------------------------------------
+ variable CurPtr : ListPointerType ;
+ begin
+ if LocalOutOfRange(Index, "Pop/Check") then
+ return ; -- error reporting in LocalOutOfRange
+ end if ;
+ if HeadPointer(Index) = NULL then
+ ErrCntVar(Index) := ErrCntVar(Index) + 1 ;
+ Alert(AlertLogIDVar(Index), GetName & " Empty during " & Name, FAILURE) ;
+ return ;
+ end if ;
+ -- deallocate previous pointer
+ if PopListPointer(Index) /= NULL then
+ deallocate(PopListPointer(Index).TagPtr) ;
+ deallocate(PopListPointer(Index).ExpectedPtr) ;
+ deallocate(PopListPointer(Index)) ;
+ end if ;
+ -- Descend to find Tag field and extract
+ CurPtr := HeadPointer(Index) ;
+ if CurPtr.TagPtr.all = Tag then
+ -- Non-tagged scoreboards find this one.
+ PopListPointer(Index) := HeadPointer(Index) ;
+ HeadPointer(Index) := HeadPointer(Index).NextPtr ;
+ else
+ loop
+ if CurPtr.NextPtr = NULL then
+ ErrCntVar(Index) := ErrCntVar(Index) + 1 ;
+ Alert(AlertLogIDVar(Index), GetName & " Pop/Check (" & Name & "), tag: " & Tag & " not found", FAILURE) ;
+ exit ;
+ elsif CurPtr.NextPtr.TagPtr.all = Tag then
+ PopListPointer(Index) := CurPtr.NextPtr ;
+ CurPtr.NextPtr := CurPtr.NextPtr.NextPtr ;
+ if CurPtr.NextPtr = NULL then
+ TailPointer(Index) := CurPtr ;
+ end if ;
+ exit ;
+ else
+ CurPtr := CurPtr.NextPtr ;
+ end if ;
+ end loop ;
+ end if ;
+ end procedure LocalPop ;
+
+ ------------------------------------------------------------
+ -- Local Only
+ procedure LocalCheck (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant ActualData : in ActualType
+ ) is
+ variable ExpectedPtr : ExpectedPointerType ;
+ variable CurrentItem : integer ;
+ variable WriteBuf : line ;
+ variable FoundError : boolean ;
+ begin
+ CheckCountVar(Index) := CheckCountVar(Index) + 1 ;
+ ExpectedPtr := PopListPointer(Index).ExpectedPtr ;
+ CurrentItem := PopListPointer(Index).ItemNumber ;
+
+ if not Match(ActualData, ExpectedPtr.all) then
+ ErrCntVar(Index) := ErrCntVar(Index) + 1 ;
+ FoundError := TRUE ;
+ else
+ FoundError := FALSE ;
+ end if ;
+
+ IncAffirmCheckCount ;
+
+-- if FoundError or ReportModeVar = REPORT_ALL then
+ if FoundError or GetLogEnable(AlertLogIDVar(Index), PASSED) then
+ if AlertLogIDVar(Index) = OSVVM_SCOREBOARD_ALERTLOG_ID then
+ write(WriteBuf, GetName(DefaultName => "Scoreboard")) ;
+ else
+ write(WriteBuf, GetName(DefaultName => "")) ;
+ end if ;
+ if ArrayLengthVar > 1 then
+ write(WriteBuf, " (" & to_string(Index) & ") ") ;
+ end if ;
+ write(WriteBuf, " Expected: " & expected_to_string(ExpectedPtr.all)) ;
+ write(WriteBuf, " Actual: " & actual_to_string(ActualData)) ;
+ if PopListPointer(Index).TagPtr.all /= "" then
+ write(WriteBuf, " Tag: " & PopListPointer(Index).TagPtr.all) ;
+ end if;
+ write(WriteBuf, " Item Number: " & to_string(CurrentItem)) ;
+ if FoundError then
+ if ReportModeVar /= REPORT_NONE then
+ -- Affirmation Failed
+ Alert(AlertLogIDVar(Index), WriteBuf.all, ERROR) ;
+ else
+ -- Affirmation Failed, but silent, unless in DEBUG mode
+ Log(AlertLogIDVar(Index), "ERROR " & WriteBuf.all, DEBUG) ;
+ IncAlertCount(AlertLogIDVar(Index)) ; -- Silent Counted Alert
+ end if ;
+ else
+ -- Affirmation passed
+ Log(AlertLogIDVar(Index), WriteBuf.all, PASSED) ;
+ end if ;
+ deallocate(WriteBuf) ;
+ end if ;
+ end procedure LocalCheck ;
+
+ ------------------------------------------------------------
+ -- Array of Tagged Scoreboards
+ procedure Check (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant Tag : in string ;
+ constant ActualData : in ActualType
+ ) is
+ begin
+ if LocalOutOfRange(Index, "Check") then
+ return ; -- error reporting in LocalOutOfRange
+ end if ;
+ LocalPop(Index, Tag, "Check") ;
+ LocalCheck(Index, ActualData) ;
+ end procedure Check ;
+
+ ------------------------------------------------------------
+ -- Array of Scoreboards, no tag
+ procedure Check (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant ActualData : in ActualType
+ ) is
+ begin
+ if LocalOutOfRange(Index, "Check") then
+ return ; -- error reporting in LocalOutOfRange
+ end if ;
+ LocalPop(Index, "", "Check") ;
+ LocalCheck(Index, ActualData) ;
+ end procedure Check ;
+
+ ------------------------------------------------------------
+ -- Simple Tagged Scoreboard
+ procedure Check (
+ ------------------------------------------------------------
+ constant Tag : in string ;
+ constant ActualData : in ActualType
+ ) is
+ begin
+ LocalPop(FirstIndexVar, Tag, "Check") ;
+ LocalCheck(FirstIndexVar, ActualData) ;
+ end procedure Check ;
+
+ ------------------------------------------------------------
+ -- Simple Scoreboard, no tag
+ procedure Check (ActualData : ActualType) is
+ ------------------------------------------------------------
+ begin
+ LocalPop(FirstIndexVar, "", "Check") ;
+ LocalCheck(FirstIndexVar, ActualData) ;
+ end procedure Check ;
+
+ ------------------------------------------------------------
+ -- Array of Tagged Scoreboards
+ procedure Pop (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant Tag : in string ;
+ variable Item : out ExpectedType
+ ) is
+ begin
+ if LocalOutOfRange(Index, "Pop") then
+ return ; -- error reporting in LocalOutOfRange
+ end if ;
+ LocalPop(Index, Tag, "Pop") ;
+ Item := PopListPointer(Index).ExpectedPtr.all ;
+ end procedure Pop ;
+
+ ------------------------------------------------------------
+ -- Array of Scoreboards, no tag
+ procedure Pop (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ variable Item : out ExpectedType
+ ) is
+ begin
+ if LocalOutOfRange(Index, "Pop") then
+ return ; -- error reporting in LocalOutOfRange
+ end if ;
+ LocalPop(Index, "", "Pop") ;
+ Item := PopListPointer(Index).ExpectedPtr.all ;
+ end procedure Pop ;
+
+ ------------------------------------------------------------
+ -- Simple Tagged Scoreboard
+ procedure Pop (
+ ------------------------------------------------------------
+ constant Tag : in string ;
+ variable Item : out ExpectedType
+ ) is
+ begin
+ LocalPop(FirstIndexVar, Tag, "Pop") ;
+ Item := PopListPointer(FirstIndexVar).ExpectedPtr.all ;
+ end procedure Pop ;
+
+ ------------------------------------------------------------
+ -- Simple Scoreboard, no tag
+ procedure Pop (variable Item : out ExpectedType) is
+ ------------------------------------------------------------
+ begin
+ LocalPop(FirstIndexVar, "", "Pop") ;
+ Item := PopListPointer(FirstIndexVar).ExpectedPtr.all ;
+ end procedure Pop ;
+
+ ------------------------------------------------------------
+ -- Array of Tagged Scoreboards
+ impure function Pop (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant Tag : in string
+ ) return ExpectedType is
+ begin
+ if LocalOutOfRange(Index, "Pop") then
+ -- error reporting in LocalOutOfRange
+ return PopListPointer(FirstIndexVar).ExpectedPtr.all ;
+ end if ;
+ LocalPop(Index, Tag, "Pop") ;
+ return PopListPointer(Index).ExpectedPtr.all ;
+ end function Pop ;
+
+ ------------------------------------------------------------
+ -- Array of Scoreboards, no tag
+ impure function Pop (Index : integer) return ExpectedType is
+ ------------------------------------------------------------
+ begin
+ if LocalOutOfRange(Index, "Pop") then
+ -- error reporting in LocalOutOfRange
+ return PopListPointer(FirstIndexVar).ExpectedPtr.all ;
+ end if ;
+ LocalPop(Index, "", "Pop") ;
+ return PopListPointer(Index).ExpectedPtr.all ;
+ end function Pop ;
+
+ ------------------------------------------------------------
+ -- Simple Tagged Scoreboard
+ impure function Pop (
+ ------------------------------------------------------------
+ constant Tag : in string
+ ) return ExpectedType is
+ begin
+ LocalPop(FirstIndexVar, Tag, "Pop") ;
+ return PopListPointer(FirstIndexVar).ExpectedPtr.all ;
+ end function Pop ;
+
+ ------------------------------------------------------------
+ -- Simple Scoreboard, no tag
+ impure function Pop return ExpectedType is
+ ------------------------------------------------------------
+ begin
+ LocalPop(FirstIndexVar, "", "Pop") ;
+ return PopListPointer(FirstIndexVar).ExpectedPtr.all ;
+ end function Pop ;
+
+ ------------------------------------------------------------
+ -- Array of Tagged Scoreboards
+ impure function Empty (Index : integer; Tag : String) return boolean is
+ ------------------------------------------------------------
+ variable CurPtr : ListPointerType ;
+ begin
+ CurPtr := HeadPointer(Index) ;
+ while CurPtr /= NULL loop
+ if CurPtr.TagPtr.all = Tag then
+ return FALSE ; -- Found Tag
+ end if ;
+ CurPtr := CurPtr.NextPtr ;
+ end loop ;
+ return TRUE ; -- Tag not found
+ end function Empty ;
+
+ ------------------------------------------------------------
+ -- Array of Scoreboards, no tag
+ impure function Empty (Index : integer) return boolean is
+ ------------------------------------------------------------
+ begin
+ return HeadPointer(Index) = NULL ;
+ end function Empty ;
+
+ ------------------------------------------------------------
+ -- Simple Tagged Scoreboard
+ impure function Empty (Tag : String) return boolean is
+ ------------------------------------------------------------
+ variable CurPtr : ListPointerType ;
+ begin
+ return Empty(FirstIndexVar, Tag) ;
+ end function Empty ;
+
+ ------------------------------------------------------------
+ -- Simple Scoreboard, no tag
+ impure function Empty return boolean is
+ ------------------------------------------------------------
+ begin
+ return HeadPointer(FirstIndexVar) = NULL ;
+ end function Empty ;
+
+ ------------------------------------------------------------
+ procedure CheckFinish (
+ ------------------------------------------------------------
+ Index : integer ;
+ FinishCheckCount : integer ;
+ FinishEmpty : boolean
+ ) is
+ variable EmptyError : Boolean ;
+ variable WriteBuf : line ;
+ begin
+ if AlertLogIDVar(Index) = OSVVM_SCOREBOARD_ALERTLOG_ID then
+ write(WriteBuf, GetName(DefaultName => "Scoreboard")) ;
+ else
+ write(WriteBuf, GetName(DefaultName => "")) ;
+ end if ;
+ if ArrayLengthVar > 1 then
+ if WriteBuf.all /= "" then
+ swrite(WriteBuf, " ") ;
+ end if ;
+ write(WriteBuf, "Index(" & to_string(Index) & "), ") ;
+ else
+ if WriteBuf.all /= "" then
+ swrite(WriteBuf, ", ") ;
+ end if ;
+ end if ;
+ if FinishEmpty then
+ AffirmIf(AlertLogIDVar(Index), Empty(Index), WriteBuf.all & "Checking Empty: " & to_string(Empty(Index)) &
+ " FinishEmpty: " & to_string(FinishEmpty)) ;
+ if not Empty(Index) then
+ -- Increment internal count on FinishEmpty Error
+ ErrCntVar(Index) := ErrCntVar(Index) + 1 ;
+ end if ;
+ end if ;
+ AffirmIf(AlertLogIDVar(Index), CheckCountVar(Index) >= FinishCheckCount, WriteBuf.all &
+ "Checking CheckCount: " & to_string(CheckCountVar(Index)) &
+ " >= Expected: " & to_string(FinishCheckCount)) ;
+ if not (CheckCountVar(Index) >= FinishCheckCount) then
+ -- Increment internal count on FinishCheckCount Error
+ ErrCntVar(Index) := ErrCntVar(Index) + 1 ;
+ end if ;
+ deallocate(WriteBuf) ;
+ end procedure CheckFinish ;
+
+ ------------------------------------------------------------
+ procedure CheckFinish (
+ ------------------------------------------------------------
+ FinishCheckCount : integer ;
+ FinishEmpty : boolean
+ ) is
+ begin
+ for AlertLogID in AlertLogIDVar'range loop
+ CheckFinish(AlertLogID, FinishCheckCount, FinishEmpty) ;
+ end loop ;
+ end procedure CheckFinish ;
+
+ ------------------------------------------------------------
+ impure function GetErrorCount (Index : integer) return integer is
+ ------------------------------------------------------------
+ begin
+ return ErrCntVar(Index) ;
+ end function GetErrorCount ;
+
+ ------------------------------------------------------------
+ impure function GetErrorCount return integer is
+ ------------------------------------------------------------
+ variable TotalErrorCount : integer := 0 ;
+ begin
+ for Index in AlertLogIDVar'range loop
+ TotalErrorCount := TotalErrorCount + GetErrorCount(Index) ;
+ end loop ;
+ return TotalErrorCount ;
+ end function GetErrorCount ;
+
+ ------------------------------------------------------------
+ procedure IncErrorCount (Index : integer) is
+ ------------------------------------------------------------
+ begin
+ ErrCntVar(Index) := ErrCntVar(Index) + 1 ;
+ IncAlertCount(AlertLogIDVar(Index), ERROR) ;
+ end IncErrorCount ;
+
+ ------------------------------------------------------------
+ procedure IncErrorCount is
+ ------------------------------------------------------------
+ begin
+ ErrCntVar(FirstIndexVar) := ErrCntVar(FirstIndexVar) + 1 ;
+ IncAlertCount(AlertLogIDVar(FirstIndexVar), ERROR) ;
+ end IncErrorCount ;
+
+ ------------------------------------------------------------
+ procedure SetErrorCountZero (Index : integer) is
+ ------------------------------------------------------------
+ begin
+ ErrCntVar(Index) := 0;
+ end procedure SetErrorCountZero ;
+
+ ------------------------------------------------------------
+ procedure SetErrorCountZero is
+ ------------------------------------------------------------
+ begin
+ ErrCntVar(FirstIndexVar) := 0 ;
+ end procedure SetErrorCountZero ;
+
+ ------------------------------------------------------------
+ impure function GetItemCount (Index : integer) return integer is
+ ------------------------------------------------------------
+ begin
+ return ItemNumberVar(Index) ;
+ end function GetItemCount ;
+
+ ------------------------------------------------------------
+ impure function GetItemCount return integer is
+ ------------------------------------------------------------
+ begin
+ return ItemNumberVar(FirstIndexVar) ;
+ end function GetItemCount ;
+
+ ------------------------------------------------------------
+ impure function GetCheckCount (Index : integer) return integer is
+ ------------------------------------------------------------
+ begin
+ return CheckCountVar(Index) ;
+ end function GetCheckCount ;
+
+ ------------------------------------------------------------
+ impure function GetCheckCount return integer is
+ ------------------------------------------------------------
+ begin
+ return CheckCountVar(FirstIndexVar) ;
+ end function GetCheckCount ;
+
+ ------------------------------------------------------------
+ impure function GetDropCount (Index : integer) return integer is
+ ------------------------------------------------------------
+ begin
+ return DropCountVar(Index) ;
+ end function GetDropCount ;
+
+ ------------------------------------------------------------
+ impure function GetDropCount return integer is
+ ------------------------------------------------------------
+ begin
+ return DropCountVar(FirstIndexVar) ;
+ end function GetDropCount ;
+
+ ------------------------------------------------------------
+ procedure SetFinish (
+ ------------------------------------------------------------
+ Index : integer ;
+ FCheckCount : integer ;
+ FEmpty : boolean := TRUE;
+ FStatus : boolean := TRUE
+ ) is
+ begin
+ Alert(AlertLogIDVar(Index), "OSVVM.ScoreboardGenericPkg.SetFinish: Deprecated and removed. See CheckFinish", ERROR) ;
+ end procedure SetFinish ;
+
+ ------------------------------------------------------------
+ procedure SetFinish (
+ ------------------------------------------------------------
+ FCheckCount : integer ;
+ FEmpty : boolean := TRUE;
+ FStatus : boolean := TRUE
+ ) is
+ begin
+ SetFinish(FirstIndexVar, FCheckCount, FEmpty, FStatus) ;
+ end procedure SetFinish ;
+
+ ------------------------------------------------------------
+ -- Array of Tagged Scoreboards
+ -- Find Element with Matching Tag and ActualData
+ -- Returns integer'left if no match found
+ impure function Find (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant Tag : in string;
+ constant ActualData : in ActualType
+ ) return integer is
+ variable CurPtr : ListPointerType ;
+ begin
+ if LocalOutOfRange(Index, "Find") then
+ return integer'left ; -- error reporting in LocalOutOfRange
+ end if ;
+ CurPtr := HeadPointer(Index) ;
+ loop
+ if CurPtr = NULL then
+ -- Failed to find it
+ ErrCntVar(Index) := ErrCntVar(Index) + 1 ;
+ if Tag /= "" then
+ Alert(AlertLogIDVar(Index),
+ GetName & " Did not find Tag: " & Tag & " and Actual Data: " & actual_to_string(ActualData),
+ FAILURE ) ;
+ else
+ Alert(AlertLogIDVar(Index),
+ GetName & " Did not find Actual Data: " & actual_to_string(ActualData),
+ FAILURE ) ;
+ end if ;
+ return integer'left ;
+
+ elsif CurPtr.TagPtr.all = Tag and
+ Match(ActualData, CurPtr.ExpectedPtr.all) then
+ -- Found it. Return Index.
+ return CurPtr.ItemNumber ;
+
+ else -- Descend
+ CurPtr := CurPtr.NextPtr ;
+ end if ;
+ end loop ;
+ end function Find ;
+
+ ------------------------------------------------------------
+ -- Array of Simple Scoreboards
+ -- Find Element with Matching ActualData
+ impure function Find (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant ActualData : in ActualType
+ ) return integer is
+ begin
+ return Find(Index, "", ActualData) ;
+ end function Find ;
+
+ ------------------------------------------------------------
+ -- Tagged Scoreboard
+ -- Find Element with Matching ActualData
+ impure function Find (
+ ------------------------------------------------------------
+ constant Tag : in string;
+ constant ActualData : in ActualType
+ ) return integer is
+ begin
+ return Find(FirstIndexVar, Tag, ActualData) ;
+ end function Find ;
+
+ ------------------------------------------------------------
+ -- Simple Scoreboard
+ -- Find Element with Matching ActualData
+ impure function Find (
+ ------------------------------------------------------------
+ constant ActualData : in ActualType
+ ) return integer is
+ begin
+ return Find(FirstIndexVar, "", ActualData) ;
+ end function Find ;
+
+ ------------------------------------------------------------
+ -- Array of Tagged Scoreboards
+ -- Flush Remove elements with tag whose itemNumber is <= ItemNumber parameter
+ procedure Flush (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant Tag : in string ;
+ constant ItemNumber : in integer
+ ) is
+ variable CurPtr, RemovePtr, LastPtr : ListPointerType ;
+ begin
+ if LocalOutOfRange(Index, "Find") then
+ return ; -- error reporting in LocalOutOfRange
+ end if ;
+ CurPtr := HeadPointer(Index) ;
+ LastPtr := NULL ;
+ loop
+ if CurPtr = NULL then
+ -- Done
+ return ;
+ elsif CurPtr.TagPtr.all = Tag then
+ if ItemNumber >= CurPtr.ItemNumber then
+ -- remove it
+ RemovePtr := CurPtr ;
+ if CurPtr = TailPointer(Index) then
+ TailPointer(Index) := LastPtr ;
+ end if ;
+ if CurPtr = HeadPointer(Index) then
+ HeadPointer(Index) := CurPtr.NextPtr ;
+ else -- if LastPtr /= NULL then
+ LastPtr.NextPtr := LastPtr.NextPtr.NextPtr ;
+ end if ;
+ CurPtr := CurPtr.NextPtr ;
+ -- LastPtr := LastPtr ; -- no change
+ DropCountVar(Index) := DropCountVar(Index) + 1 ;
+ deallocate(RemovePtr.TagPtr) ;
+ deallocate(RemovePtr.ExpectedPtr) ;
+ deallocate(RemovePtr) ;
+ else
+ -- Done
+ return ;
+ end if ;
+ else
+ -- Descend
+ LastPtr := CurPtr ;
+ CurPtr := CurPtr.NextPtr ;
+ end if ;
+ end loop ;
+ end procedure Flush ;
+
+ ------------------------------------------------------------
+ -- Tagged Scoreboard
+ -- Flush Remove elements with tag whose itemNumber is <= ItemNumber parameter
+ procedure Flush (
+ ------------------------------------------------------------
+ constant Tag : in string ;
+ constant ItemNumber : in integer
+ ) is
+ begin
+ Flush(FirstIndexVar, Tag, ItemNumber) ;
+ end procedure Flush ;
+
+ ------------------------------------------------------------
+ -- Array of Simple Scoreboards
+ -- Flush - Remove Elements upto and including the one with ItemNumber
+ procedure Flush (
+ ------------------------------------------------------------
+ constant Index : in integer ;
+ constant ItemNumber : in integer
+ ) is
+ variable CurPtr : ListPointerType ;
+ begin
+ if LocalOutOfRange(Index, "Find") then
+ return ; -- error reporting in LocalOutOfRange
+ end if ;
+ CurPtr := HeadPointer(Index) ;
+ loop
+ if CurPtr = NULL then
+ -- Done
+ return ;
+ elsif ItemNumber >= CurPtr.ItemNumber then
+ -- Descend, Check Tail, Deallocate
+ HeadPointer(Index) := HeadPointer(Index).NextPtr ;
+ if CurPtr = TailPointer(Index) then
+ TailPointer(Index) := NULL ;
+ end if ;
+ DropCountVar(Index) := DropCountVar(Index) + 1 ;
+ deallocate(CurPtr.TagPtr) ;
+ deallocate(CurPtr.ExpectedPtr) ;
+ deallocate(CurPtr) ;
+ CurPtr := HeadPointer(Index) ;
+ else
+ -- Done
+ return ;
+ end if ;
+ end loop ;
+ end procedure Flush ;
+
+ ------------------------------------------------------------
+ -- Simple Scoreboard
+ -- Flush - Remove Elements upto and including the one with ItemNumber
+ procedure Flush (
+ ------------------------------------------------------------
+ constant ItemNumber : in integer
+ ) is
+ begin
+ Flush(FirstIndexVar, ItemNumber) ;
+ end procedure Flush ;
+
+ ------------------------------------------------------------
+ ------------------------------------------------------------
+ -- Remaining Deprecated.
+ ------------------------------------------------------------
+ ------------------------------------------------------------
+
+ ------------------------------------------------------------
+ -- Deprecated. Maintained for backward compatibility.
+ -- Use TranscriptPkg.TranscriptOpen
+ procedure FileOpen (FileName : string; OpenKind : File_Open_Kind ) is
+ ------------------------------------------------------------
+ begin
+ -- WriteFileInit := TRUE ;
+ -- file_open( WriteFile , FileName , OpenKind );
+ TranscriptOpen(FileName, OpenKind) ;
+ end procedure FileOpen ;
+
+
+ ------------------------------------------------------------
+ -- Deprecated. Maintained for backward compatibility.
+ procedure PutExpectedData (ExpectedData : ExpectedType) is
+ ------------------------------------------------------------
+ begin
+ Push(ExpectedData) ;
+ end procedure PutExpectedData ;
+
+ ------------------------------------------------------------
+ -- Deprecated. Maintained for backward compatibility.
+ procedure CheckActualData (ActualData : ActualType) is
+ ------------------------------------------------------------
+ begin
+ Check(ActualData) ;
+ end procedure CheckActualData ;
+
+ ------------------------------------------------------------
+ -- Deprecated. Maintained for backward compatibility.
+ impure function GetItemNumber return integer is
+ ------------------------------------------------------------
+ begin
+ return GetItemCount(FirstIndexVar) ;
+ end GetItemNumber ;
+
+ ------------------------------------------------------------
+ -- Deprecated. Maintained for backward compatibility.
+ procedure SetMessage (MessageIn : String) is
+ ------------------------------------------------------------
+ begin
+ -- deallocate(Message) ;
+ -- Message := new string'(MessageIn) ;
+ SetName(MessageIn) ;
+ end procedure SetMessage ;
+
+ ------------------------------------------------------------
+ -- Deprecated. Maintained for backward compatibility.
+ impure function GetMessage return string is
+ ------------------------------------------------------------
+ begin
+ -- return Message.all ;
+ return GetName("Scoreboard") ;
+ end function GetMessage ;
+
+ end protected body ScoreBoardPType ;
+end ScoreboardGenericPkg ; \ No newline at end of file
diff --git a/testsuite/gna/issue317/OSVVM/SortListPkg_int.vhd b/testsuite/gna/issue317/OSVVM/SortListPkg_int.vhd
new file mode 100644
index 000000000..6f32151c5
--- /dev/null
+++ b/testsuite/gna/issue317/OSVVM/SortListPkg_int.vhd
@@ -0,0 +1,417 @@
+--
+-- File Name: SortListPkg_int.vhd
+-- Design Unit Name: SortListPkg_int
+-- Revision: STANDARD VERSION
+--
+-- Maintainer: Jim Lewis email: jim@synthworks.com
+-- Contributor(s):
+-- Jim Lewis jim@synthworks.com
+--
+-- Description:
+-- Sorting utility for array of scalars
+-- Uses protected type so as to shrink and expand the data structure
+--
+-- Developed for:
+-- SynthWorks Design Inc.
+-- VHDL Training Classes
+-- 11898 SW 128th Ave. Tigard, Or 97223
+-- http://www.SynthWorks.com
+--
+-- Revision History:
+-- Date Version Description
+-- 06/2008: 0.1 Initial revision
+-- Numerous revisions for VHDL Testbenches and Verification
+-- 02/2009: 1.0 First Public Released Version
+-- 02/25/2009 1.1 Replaced reference to std_2008 with a reference to
+-- ieee_proposed.standard_additions.all ;
+-- 06/16/2010 1.2 Added EraseList parameter to to_array
+-- 3/2011 2.0 added inside as non protected type
+-- 6/2011 2.1 added sort as non protected type
+-- 4/2013 2013.04 No Changes
+-- 5/2013 2013.05 No changes of substance.
+-- Deleted extra variable declaration in procedure remove
+-- 1/2014 2014.01 Added RevSort. Added AllowDuplicate paramter to Add procedure
+-- 1/2015 2015.01 Changed Assert/Report to Alert
+-- 11/2016 2016.11 Revised Add. When AllowDuplicate, add a matching value last.
+--
+--
+--
+-- Copyright (c) 2008 - 2016 by SynthWorks Design Inc. All rights reserved.
+--
+-- Verbatim copies of this source file may be used and
+-- distributed without restriction.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the ARTISTIC License
+-- as published by The Perl Foundation; either version 2.0 of
+-- the License, or (at your option) any later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the Artistic License for details.
+--
+-- You should have received a copy of the license with this source.
+-- If not download it from,
+-- http://www.perlfoundation.org/artistic_license_2_0
+--
+
+use work.OsvvmGlobalPkg.all ;
+use work.AlertLogPkg.all ;
+use std.textio.all ;
+
+library ieee ;
+use ieee.std_logic_1164.all ;
+use ieee.numeric_std.all ;
+use ieee.std_logic_textio.all ;
+
+-- comment out following 2 lines with VHDL-2008. Leave in for VHDL-2002
+-- library ieee_proposed ; -- remove with VHDL-2008
+-- use ieee_proposed.standard_additions.all ; -- remove with VHDL-2008
+
+
+package SortListPkg_int is
+ -- with VHDL-2008, convert package to generic package
+ -- convert subtypes ElementType and ArrayofElementType to generics
+ -- package SortListGenericPkg is
+ subtype ElementType is integer ;
+ subtype ArrayofElementType is integer_vector ;
+
+ impure function inside (constant E : ElementType; constant A : in ArrayofElementType) return boolean ;
+ impure function sort (constant A : in ArrayofElementType) return ArrayofElementType ;
+ impure function revsort (constant A : in ArrayofElementType) return ArrayofElementType ;
+
+ type SortListPType is protected
+ procedure add ( constant A : in ElementType ; constant AllowDuplicate : Boolean := FALSE ) ;
+ procedure add ( constant A : in ArrayofElementType ) ;
+ procedure add ( constant A : in ArrayofElementType ; Min, Max : ElementType ) ;
+ procedure add ( variable A : inout SortListPType ) ;
+ -- Count items in list
+ impure function count return integer ;
+ impure function find_index ( constant A : ElementType) return integer ;
+ impure function inside (constant A : ElementType) return boolean ;
+ procedure insert ( constant A : in ElementType; constant index : in integer := 1 ) ;
+ impure function get ( constant index : in integer := 1 ) return ElementType ;
+ procedure erase ;
+ impure function Empty return boolean ;
+ procedure print ;
+
+ procedure remove ( constant A : in ElementType ) ;
+ procedure remove ( constant A : in ArrayofElementType ) ;
+ procedure remove ( variable A : inout SortListPType ) ;
+
+ impure function to_array (constant EraseList : boolean := FALSE) return ArrayofElementType ;
+ impure function to_rev_array (constant EraseList : boolean := FALSE) return ArrayofElementType ;
+ end protected SortListPType ;
+
+end SortListPkg_int ;
+
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+
+package body SortListPkg_int is
+
+ impure function inside (constant E : ElementType; constant A : in ArrayofElementType) return boolean is
+ begin
+ for i in A'range loop
+ if E = A(i) then
+ return TRUE ;
+ end if ;
+ end loop ;
+ return FALSE ;
+ end function inside ;
+
+ type SortListPType is protected body
+ type ListType ;
+ type ListPointerType is access ListType ;
+ type ListType is record
+ A : ElementType ;
+ -- item_num : integer ;
+ NextPtr : ListPointerType ;
+ -- PrevPtr : ListPointerType ;
+ end record ;
+ variable HeadPointer : ListPointerType := NULL ;
+ -- variable TailPointer : ListPointerType := NULL ;
+
+ procedure add ( constant A : in ElementType ; constant AllowDuplicate : Boolean := FALSE ) is
+ variable CurPtr, tempPtr : ListPointerType ;
+ begin
+ if HeadPointer = NULL then
+ HeadPointer := new ListType'(A, NULL) ;
+ elsif A = HeadPointer.A then -- ignore duplicates
+ if AllowDuplicate then
+ tempPtr := HeadPointer ;
+ HeadPointer := new ListType'(A, tempPtr) ;
+ end if ;
+ elsif A < HeadPointer.A then
+ tempPtr := HeadPointer ;
+ HeadPointer := new ListType'(A, tempPtr) ;
+ else
+ CurPtr := HeadPointer ;
+ AddLoop : loop
+ exit AddLoop when CurPtr.NextPtr = NULL ;
+ exit AddLoop when A < CurPtr.NextPtr.A ;
+ if A = CurPtr.NextPtr.A then
+-- if AllowDuplicate then -- changed s.t. insert at after match rather than before
+-- exit AddLoop ; -- insert
+-- else
+ if not AllowDuplicate then
+ return ; -- return without insert
+ end if;
+ end if ;
+ CurPtr := CurPtr.NextPtr ;
+ end loop AddLoop ;
+ tempPtr := CurPtr.NextPtr ;
+ CurPtr.NextPtr := new ListType'(A, tempPtr) ;
+ end if ;
+ end procedure add ;
+
+ procedure add ( constant A : in ArrayofElementType ) is
+ begin
+ for i in A'range loop
+ add(A(i)) ;
+ end loop ;
+ end procedure add ;
+
+ procedure add ( constant A : in ArrayofElementType ; Min, Max : ElementType ) is
+ begin
+ for i in A'range loop
+ if A(i) >= Min and A(i) <= Max then
+ add(A(i)) ;
+ end if ;
+ end loop ;
+ end procedure add ;
+
+ procedure add ( variable A : inout SortListPType ) is
+ begin
+ for i in 1 to A.Count loop
+ add(A.Get(i)) ;
+ end loop ;
+ end procedure add ;
+
+ -- Count items in list
+ impure function count return integer is
+ variable result : positive := 1 ;
+ variable CurPtr : ListPointerType ;
+ begin
+ if HeadPointer = NULL then
+ return 0 ;
+ else
+ CurPtr := HeadPointer ;
+ loop
+ exit when CurPtr.NextPtr = NULL ;
+ result := result + 1 ;
+ CurPtr := CurPtr.NextPtr ;
+ end loop ;
+ return result ;
+ end if ;
+ end function count ;
+
+ impure function find_index (constant A : ElementType) return integer is
+ variable result : positive := 2 ;
+ variable CurPtr : ListPointerType ;
+ begin
+ if HeadPointer = NULL then
+ return 0 ;
+ elsif A <= HeadPointer.A then
+ return 1 ;
+ else
+ CurPtr := HeadPointer ;
+ loop
+ exit when CurPtr.NextPtr = NULL ;
+ exit when A <= CurPtr.NextPtr.A ;
+ result := result + 1 ;
+ CurPtr := CurPtr.NextPtr ;
+ end loop ;
+ return result ;
+ end if ;
+ end function find_index ;
+
+ impure function inside (constant A : ElementType) return boolean is
+ variable CurPtr : ListPointerType ;
+ begin
+ if HeadPointer = NULL then
+ return FALSE ;
+ end if ;
+ if A = HeadPointer.A then
+ return TRUE ;
+ else
+ CurPtr := HeadPointer ;
+ loop
+ exit when CurPtr.NextPtr = NULL ;
+ exit when A < CurPtr.NextPtr.A ;
+ if A = CurPtr.NextPtr.A then
+ return TRUE ; -- exit
+ end if;
+ CurPtr := CurPtr.NextPtr ;
+ end loop ;
+ end if ;
+ return FALSE ;
+ end function inside ;
+
+
+ procedure insert( constant A : in ElementType; constant index : in integer := 1 ) is
+ variable CurPtr, tempPtr : ListPointerType ;
+ begin
+ if index <= 1 then
+ tempPtr := HeadPointer ;
+ HeadPointer := new ListType'(A, tempPtr) ;
+ else
+ CurPtr := HeadPointer ;
+ for i in 3 to index loop
+ exit when CurPtr.NextPtr = NULL ; -- end of list
+ CurPtr := CurPtr.NextPtr ;
+ end loop ;
+ tempPtr := CurPtr.NextPtr ;
+ CurPtr.NextPtr := new ListType'(A, tempPtr) ;
+ end if;
+ end procedure insert ;
+
+ impure function get ( constant index : in integer := 1 ) return ElementType is
+ variable CurPtr : ListPointerType ;
+ begin
+ if index > Count then
+ Alert(OSVVM_ALERTLOG_ID, "SortLIstPkg_int.get index out of range", FAILURE) ;
+ return ElementType'left ;
+ elsif HeadPointer = NULL then
+ return ElementType'left ;
+ elsif index <= 1 then
+ return HeadPointer.A ;
+ else
+ CurPtr := HeadPointer ;
+ for i in 2 to index loop
+ CurPtr := CurPtr.NextPtr ;
+ end loop ;
+ return CurPtr.A ;
+ end if;
+ end function get ;
+
+
+ procedure erase (variable CurPtr : inout ListPointerType ) is
+ begin
+ if CurPtr.NextPtr /= NULL then
+ erase (CurPtr.NextPtr) ;
+ end if ;
+ deallocate (CurPtr) ;
+ end procedure erase ;
+
+ procedure erase is
+ begin
+ if HeadPointer /= NULL then
+ erase(HeadPointer) ;
+ -- deallocate (HeadPointer) ;
+ HeadPointer := NULL ;
+ end if;
+ end procedure erase ;
+
+ impure function Empty return boolean is
+ begin
+ return HeadPointer = NULL ;
+ end Empty ;
+
+ procedure print is
+ variable buf : line ;
+ variable CurPtr : ListPointerType ;
+ begin
+ if HeadPointer = NULL then
+ write (buf, string'("( )")) ;
+ else
+ CurPtr := HeadPointer ;
+ write (buf, string'("(")) ;
+ loop
+ write (buf, CurPtr.A) ;
+ exit when CurPtr.NextPtr = NULL ;
+ write (buf, string'(", ")) ;
+ CurPtr := CurPtr.NextPtr ;
+ end loop ;
+ write (buf, string'(")")) ;
+ end if ;
+ writeline(OUTPUT, buf) ;
+ end procedure print ;
+
+ procedure remove ( constant A : in ElementType ) is
+ variable CurPtr, tempPtr : ListPointerType ;
+ begin
+ if HeadPointer = NULL then
+ return ;
+ elsif A = HeadPointer.A then
+ tempPtr := HeadPointer ;
+ HeadPointer := HeadPointer.NextPtr ;
+ deallocate (tempPtr) ;
+ else
+ CurPtr := HeadPointer ;
+ loop
+ exit when CurPtr.NextPtr = NULL ;
+ if A = CurPtr.NextPtr.A then
+ tempPtr := CurPtr.NextPtr ;
+ CurPtr.NextPtr := CurPtr.NextPtr.NextPtr ;
+ deallocate (tempPtr) ;
+ exit ;
+ end if ;
+ exit when A < CurPtr.NextPtr.A ;
+ CurPtr := CurPtr.NextPtr ;
+ end loop ;
+ end if ;
+ end procedure remove ;
+
+ procedure remove ( constant A : in ArrayofElementType ) is
+ begin
+ for i in A'range loop
+ remove(A(i)) ;
+ end loop ;
+ end procedure remove ;
+
+ procedure remove ( variable A : inout SortListPType ) is
+ begin
+ for i in 1 to A.Count loop
+ remove(A.Get(i)) ;
+ end loop ;
+ end procedure remove ;
+
+ impure function to_array (constant EraseList : boolean := FALSE) return ArrayofElementType is
+ variable result : ArrayofElementType(1 to Count) ;
+ begin
+ for i in 1 to Count loop
+ result(i) := Get(i) ;
+ end loop ;
+ if EraseList then
+ erase ;
+ end if ;
+ return result ;
+ end function to_array ;
+
+ impure function to_rev_array (constant EraseList : boolean := FALSE) return ArrayofElementType is
+ variable result : ArrayofElementType(Count downto 1) ;
+ begin
+ for i in 1 to Count loop
+ result(i) := Get(i) ;
+ end loop ;
+ if EraseList then
+ erase ;
+ end if ;
+ return result ;
+ end function to_rev_array ;
+
+ end protected body SortListPType ;
+
+
+ impure function sort (constant A : in ArrayofElementType) return ArrayofElementType is
+ variable Result : SortListPType ;
+ begin
+ for i in A'range loop
+ Result.Add(A(i), TRUE) ;
+ end loop ;
+ return Result.to_array(EraseList => TRUE) ;
+ end function sort ;
+
+ impure function revsort (constant A : in ArrayofElementType) return ArrayofElementType is
+ variable Result : SortListPType ;
+ begin
+ for i in A'range loop
+ Result.Add(A(i), TRUE) ;
+ end loop ;
+ return Result.to_rev_array(EraseList => TRUE) ;
+ end function revsort ;
+end SortListPkg_int ;
+
diff --git a/testsuite/gna/issue317/OSVVM/TextUtilPkg.vhd b/testsuite/gna/issue317/OSVVM/TextUtilPkg.vhd
new file mode 100644
index 000000000..d1c5ee17e
--- /dev/null
+++ b/testsuite/gna/issue317/OSVVM/TextUtilPkg.vhd
@@ -0,0 +1,407 @@
+--
+-- File Name: TextUtilPkg.vhd
+-- Design Unit Name: TextUtilPkg
+-- Revision: STANDARD VERSION
+--
+-- Maintainer: Jim Lewis email: jim@synthworks.com
+-- Contributor(s):
+-- Jim Lewis jim@synthworks.com
+--
+--
+-- Description:
+-- Shared Utilities for handling text files
+--
+--
+-- Developed for:
+-- SynthWorks Design Inc.
+-- VHDL Training Classes
+-- 11898 SW 128th Ave. Tigard, Or 97223
+-- http://www.SynthWorks.com
+--
+-- Revision History:
+-- Date Version Description
+-- 01/2015: 2015.05 Initial revision
+-- 01/2016: 2016.01 Update for L.all(L'left)
+-- 11/2016: 2016.11 Added IsUpper, IsLower, to_upper, to_lower
+--
+--
+-- Copyright (c) 2015-2016 by SynthWorks Design Inc. All rights reserved.
+--
+-- Verbatim copies of this source file may be used and
+-- distributed without restriction.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the ARTISTIC License
+-- as published by The Perl Foundation; either version 2.0 of
+-- the License, or (at your option) any later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the Artistic License for details.
+--
+-- You should have received a copy of the license with this source.
+-- If not download it from,
+-- http://www.perlfoundation.org/artistic_license_2_0
+--
+
+use std.textio.all ;
+library ieee ;
+use ieee.std_logic_1164.all ;
+
+package TextUtilPkg is
+ ------------------------------------------------------------
+ function IsUpper (constant Char : character ) return boolean ;
+ function IsLower (constant Char : character ) return boolean ;
+ function to_lower (constant Char : character ) return character ;
+ function to_lower (constant Str : string ) return string ;
+ function to_upper (constant Char : character ) return character ;
+ function to_upper (constant Str : string ) return string ;
+ function ishex (constant Char : character ) return boolean ;
+ function isstd_logic (constant Char : character ) return boolean ;
+
+ ------------------------------------------------------------
+ procedure SkipWhiteSpace (
+ ------------------------------------------------------------
+ variable L : InOut line ;
+ variable Empty : out boolean
+ ) ;
+ procedure SkipWhiteSpace (variable L : InOut line) ;
+
+ ------------------------------------------------------------
+ procedure EmptyOrCommentLine (
+ ------------------------------------------------------------
+ variable L : InOut line ;
+ variable Empty : InOut boolean ;
+ variable MultiLineComment : inout boolean
+ ) ;
+
+ ------------------------------------------------------------
+ procedure ReadHexToken (
+ -- Reads Upto Result'length values, less is ok.
+ -- Does not skip white space
+ ------------------------------------------------------------
+ variable L : InOut line ;
+ variable Result : Out std_logic_vector ;
+ variable StrLen : Out integer
+ ) ;
+
+ ------------------------------------------------------------
+ procedure ReadBinaryToken (
+ -- Reads Upto Result'length values, less is ok.
+ -- Does not skip white space
+ ------------------------------------------------------------
+ variable L : InOut line ;
+ variable Result : Out std_logic_vector ;
+ variable StrLen : Out integer
+ ) ;
+
+end TextUtilPkg ;
+
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+
+package body TextUtilPkg is
+ constant LOWER_TO_UPPER_OFFSET : integer := character'POS('a') - character'POS('A') ;
+
+ ------------------------------------------------------------
+ function "-" (R : character ; L : integer ) return character is
+ ------------------------------------------------------------
+ begin
+ return character'VAL(character'pos(R) - L) ;
+ end function "-" ;
+
+ ------------------------------------------------------------
+ function "+" (R : character ; L : integer ) return character is
+ ------------------------------------------------------------
+ begin
+ return character'VAL(character'pos(R) + L) ;
+ end function "+" ;
+
+ ------------------------------------------------------------
+ function IsUpper (constant Char : character ) return boolean is
+ ------------------------------------------------------------
+ begin
+ if Char >= 'A' and Char <= 'Z' then
+ return TRUE ;
+ else
+ return FALSE ;
+ end if ;
+ end function IsUpper ;
+
+ ------------------------------------------------------------
+ function IsLower (constant Char : character ) return boolean is
+ ------------------------------------------------------------
+ begin
+ if Char >= 'a' and Char <= 'z' then
+ return TRUE ;
+ else
+ return FALSE ;
+ end if ;
+ end function IsLower ;
+
+ ------------------------------------------------------------
+ function to_lower (constant Char : character ) return character is
+ ------------------------------------------------------------
+ begin
+ if IsUpper(Char) then
+ return Char + LOWER_TO_UPPER_OFFSET ;
+ else
+ return Char ;
+ end if ;
+ end function to_lower ;
+
+ ------------------------------------------------------------
+ function to_lower (constant Str : string ) return string is
+ ------------------------------------------------------------
+ variable result : string(Str'range) ;
+ begin
+ for i in Str'range loop
+ result(i) := to_lower(Str(i)) ;
+ end loop ;
+ return result ;
+ end function to_lower ;
+
+ ------------------------------------------------------------
+ function to_upper (constant Char : character ) return character is
+ ------------------------------------------------------------
+ begin
+ if IsLower(Char) then
+ return Char - LOWER_TO_UPPER_OFFSET ;
+ else
+ return Char ;
+ end if ;
+ end function to_upper ;
+
+ ------------------------------------------------------------
+ function to_upper (constant Str : string ) return string is
+ ------------------------------------------------------------
+ variable result : string(Str'range) ;
+ begin
+ for i in Str'range loop
+ result(i) := to_upper(Str(i)) ;
+ end loop ;
+ return result ;
+ end function to_upper ;
+
+ ------------------------------------------------------------
+ function ishex (constant Char : character ) return boolean is
+ ------------------------------------------------------------
+ begin
+ if Char >= '0' and Char <= '9' then
+ return TRUE ;
+ elsif Char >= 'a' and Char <= 'f' then
+ return TRUE ;
+ elsif Char >= 'A' and Char <= 'F' then
+ return TRUE ;
+ else
+ return FALSE ;
+ end if ;
+ end function ishex ;
+
+ ------------------------------------------------------------
+ function isstd_logic (constant Char : character ) return boolean is
+ ------------------------------------------------------------
+ begin
+ case Char is
+ when 'U' | 'X' | '0' | '1' | 'Z' | 'W' | 'L' | 'H' | '-' =>
+ return TRUE ;
+ when others =>
+ return FALSE ;
+ end case ;
+ end function isstd_logic ;
+
+-- ------------------------------------------------------------
+-- function iscomment (constant Char : character ) return boolean is
+-- ------------------------------------------------------------
+-- begin
+-- case Char is
+-- when '#' | '/' | '-' =>
+-- return TRUE ;
+-- when others =>
+-- return FALSE ;
+-- end case ;
+-- end function iscomment ;
+
+ ------------------------------------------------------------
+ procedure SkipWhiteSpace (
+ ------------------------------------------------------------
+ variable L : InOut line ;
+ variable Empty : out boolean
+ ) is
+ variable Valid : boolean ;
+ variable Char : character ;
+ constant NBSP : CHARACTER := CHARACTER'val(160); -- space character
+ begin
+ Empty := TRUE ;
+ WhiteSpLoop : while L /= null and L.all'length > 0 loop
+ if (L.all(L'left) = ' ' or L.all(L'left) = NBSP or L.all(L'left) = HT) then
+ read (L, Char, Valid) ;
+ exit when not Valid ;
+ else
+ Empty := FALSE ;
+ return ;
+ end if ;
+ end loop WhiteSpLoop ;
+ end procedure SkipWhiteSpace ;
+
+ ------------------------------------------------------------
+ procedure SkipWhiteSpace (
+ ------------------------------------------------------------
+ variable L : InOut line
+ ) is
+ variable Empty : boolean ;
+ begin
+ SkipWhiteSpace(L, Empty) ;
+ end procedure SkipWhiteSpace ;
+
+ ------------------------------------------------------------
+ -- Package Local
+ procedure FindCommentEnd (
+ ------------------------------------------------------------
+ variable L : InOut line ;
+ variable Empty : out boolean ;
+ variable MultiLineComment : inout boolean
+ ) is
+ variable Valid : boolean ;
+ variable Char : character ;
+ begin
+ MultiLineComment := TRUE ;
+ Empty := TRUE ;
+ FindEndOfCommentLoop : while L /= null and L.all'length > 1 loop
+ read(L, Char, Valid) ;
+ if Char = '*' and L.all(L'left) = '/' then
+ read(L, Char, Valid) ;
+ Empty := FALSE ;
+ MultiLineComment := FALSE ;
+ exit FindEndOfCommentLoop ;
+ end if ;
+ end loop ;
+ end procedure FindCommentEnd ;
+
+ ------------------------------------------------------------
+ procedure EmptyOrCommentLine (
+ ------------------------------------------------------------
+ variable L : InOut line ;
+ variable Empty : InOut boolean ;
+ variable MultiLineComment : inout boolean
+ ) is
+ variable Valid : boolean ;
+ variable Next2Char : string(1 to 2) ;
+ constant NBSP : CHARACTER := CHARACTER'val(160); -- space character
+ begin
+ if MultiLineComment then
+ FindCommentEnd(L, Empty, MultiLineComment) ;
+ end if ;
+
+ EmptyCheckLoop : while not MultiLineComment loop
+ SkipWhiteSpace(L, Empty) ;
+ exit when Empty ; -- line null or 0 in length detected by SkipWhite
+
+ Empty := TRUE ;
+
+ exit when L.all(L'left) = '#' ; -- shell style comment
+
+ if L.all'length >= 2 then
+ if L'ascending then
+ Next2Char := L.all(L'left to L'left+1) ;
+ else
+ Next2Char := L.all(L'left to L'left-1) ;
+ end if;
+ exit when Next2Char = "//" ; -- C style comment
+ exit when Next2Char = "--" ; -- VHDL style comment
+
+ if Next2Char = "/*" then -- C style multi line comment
+ FindCommentEnd(L, Empty, MultiLineComment) ;
+ exit when Empty ;
+ next EmptyCheckLoop ; -- Found end of comment, restart processing line
+ end if ;
+ end if ;
+
+ Empty := FALSE ;
+ exit ;
+ end loop EmptyCheckLoop ;
+ end procedure EmptyOrCommentLine ;
+
+ ------------------------------------------------------------
+ procedure ReadHexToken (
+ -- Reads Upto Result'length values, less is ok.
+ -- Does not skip white space
+ ------------------------------------------------------------
+ variable L : InOut line ;
+ variable Result : Out std_logic_vector ;
+ variable StrLen : Out integer
+ ) is
+ constant NumHexChars : integer := (Result'length+3)/4 ;
+ constant ResultNormLen : integer := NumHexChars * 4 ;
+ variable NextChar : character ;
+ variable CharCount : integer ;
+ variable ReturnVal : std_logic_vector(ResultNormLen-1 downto 0) ;
+ variable ReadVal : std_logic_vector(3 downto 0) ;
+ variable ReadValid : boolean ;
+ begin
+ ReturnVal := (others => '0') ;
+ CharCount := 0 ;
+
+ ReadLoop : while L /= null and L.all'length > 0 loop
+ NextChar := L.all(L'left) ;
+ if ishex(NextChar) or NextChar = 'X' or NextChar = 'Z' then
+ hread(L, ReadVal, ReadValid) ;
+ ReturnVal := ReturnVal(ResultNormLen-5 downto 0) & ReadVal ;
+ CharCount := CharCount + 1 ;
+ exit ReadLoop when CharCount >= NumHexChars ;
+ elsif NextChar = '_' then
+ read(L, NextChar, ReadValid) ;
+ else
+ exit ;
+ end if ;
+ end loop ReadLoop ;
+
+ if CharCount >= NumHexChars then
+ StrLen := Result'length ;
+ else
+ StrLen := CharCount * 4 ;
+ end if ;
+
+ Result := ReturnVal(Result'length-1 downto 0) ;
+ end procedure ReadHexToken ;
+
+ ------------------------------------------------------------
+ procedure ReadBinaryToken (
+ -- Reads Upto Result'length values, less is ok.
+ -- Does not skip white space
+ ------------------------------------------------------------
+ variable L : InOut line ;
+ variable Result : Out std_logic_vector ;
+ variable StrLen : Out integer
+ ) is
+ variable NextChar : character ;
+ variable CharCount : integer ;
+ variable ReadVal : std_logic ;
+ variable ReturnVal : std_logic_vector(Result'length-1 downto 0) ;
+ variable ReadValid : boolean ;
+ begin
+ ReturnVal := (others => '0') ;
+ CharCount := 0 ;
+
+ ReadLoop : while L /= null and L.all'length > 0 loop
+ NextChar := L.all(L'left) ;
+ if isstd_logic(NextChar) then
+ read(L, ReadVal, ReadValid) ;
+ ReturnVal := ReturnVal(Result'length-2 downto 0) & ReadVal ;
+ CharCount := CharCount + 1 ;
+ exit ReadLoop when CharCount >= Result'length ;
+ elsif NextChar = '_' then
+ read(L, NextChar, ReadValid) ;
+ else
+ exit ;
+ end if ;
+ end loop ReadLoop ;
+
+ StrLen := CharCount ;
+ Result := ReturnVal ;
+ end procedure ReadBinaryToken ;
+
+
+end package body TextUtilPkg ; \ No newline at end of file
diff --git a/testsuite/gna/issue317/OSVVM/TranscriptPkg.vhd b/testsuite/gna/issue317/OSVVM/TranscriptPkg.vhd
new file mode 100644
index 000000000..a88b00a25
--- /dev/null
+++ b/testsuite/gna/issue317/OSVVM/TranscriptPkg.vhd
@@ -0,0 +1,200 @@
+--
+-- File Name: TranscriptPkg.vhd
+-- Design Unit Name: TranscriptPkg
+-- Revision: STANDARD VERSION
+--
+-- Maintainer: Jim Lewis email: jim@synthworks.com
+-- Contributor(s):
+-- Jim Lewis jim@synthworks.com
+--
+--
+-- Description:
+-- Define file identifier TranscriptFile
+-- provide subprograms to open, close, and print to it.
+--
+--
+-- Developed for:
+-- SynthWorks Design Inc.
+-- VHDL Training Classes
+-- 11898 SW 128th Ave. Tigard, Or 97223
+-- http://www.SynthWorks.com
+--
+-- Revision History:
+-- Date Version Description
+-- 01/2015: 2015.01 Initial revision
+-- 01/2016: 2016.01 TranscriptOpen function now calls procedure of same name
+-- 11/2016: 2016.l1 Added procedure BlankLine
+--
+--
+-- Copyright (c) 2015-2016 by SynthWorks Design Inc. All rights reserved.
+--
+-- Verbatim copies of this source file may be used and
+-- distributed without restriction.
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the ARTISTIC License
+-- as published by The Perl Foundation; either version 2.0 of
+-- the License, or (at your option) any later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE. See the Artistic License for details.
+--
+-- You should have received a copy of the license with this source.
+-- If not download it from,
+-- http://www.perlfoundation.org/artistic_license_2_0
+--
+
+use std.textio.all ;
+package TranscriptPkg is
+
+ -- File Identifier to facilitate usage of one transcript file
+ file TranscriptFile : text ;
+
+ -- Cause compile errors if READ_MODE is passed to TranscriptOpen
+ subtype WRITE_APPEND_OPEN_KIND is FILE_OPEN_KIND range WRITE_MODE to APPEND_MODE ;
+
+ -- Open and close TranscriptFile. Function allows declarative opens
+ procedure TranscriptOpen (Status: out FILE_OPEN_STATUS; ExternalName: STRING; OpenKind: WRITE_APPEND_OPEN_KIND := WRITE_MODE) ;
+ procedure TranscriptOpen (ExternalName: STRING; OpenKind: WRITE_APPEND_OPEN_KIND := WRITE_MODE) ;
+ impure function TranscriptOpen (ExternalName: STRING; OpenKind: WRITE_APPEND_OPEN_KIND := WRITE_MODE) return FILE_OPEN_STATUS ;
+
+ procedure TranscriptClose ;
+ impure function IsTranscriptOpen return boolean ;
+ alias IsTranscriptEnabled is IsTranscriptOpen [return boolean] ;
+
+ -- Mirroring. When using TranscriptPkw WriteLine and Print, uses both TranscriptFile and OUTPUT
+ procedure SetTranscriptMirror (A : boolean := TRUE) ;
+ impure function IsTranscriptMirrored return boolean ;
+ alias GetTranscriptMirror is IsTranscriptMirrored [return boolean] ;
+
+ -- Write to TranscriptFile when open. Write to OUTPUT when not open or IsTranscriptMirrored
+ procedure WriteLine(buf : inout line) ;
+ procedure Print(s : string) ;
+
+ -- Create "count" number of blank lines
+ procedure BlankLine (count : integer := 1) ;
+
+end TranscriptPkg ;
+
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+--- ///////////////////////////////////////////////////////////////////////////
+
+package body TranscriptPkg is
+ ------------------------------------------------------------
+ type LocalBooleanPType is protected
+ procedure Set (A : boolean) ;
+ impure function get return boolean ;
+ end protected LocalBooleanPType ;
+ type LocalBooleanPType is protected body
+ variable GlobalVar : boolean := FALSE ;
+ procedure Set (A : boolean) is
+ begin
+ GlobalVar := A ;
+ end procedure Set ;
+ impure function get return boolean is
+ begin
+ return GlobalVar ;
+ end function get ;
+ end protected body LocalBooleanPType ;
+
+ ------------------------------------------------------------
+ shared variable TranscriptEnable : LocalBooleanPType ;
+ shared variable TranscriptMirror : LocalBooleanPType ;
+
+ ------------------------------------------------------------
+ procedure TranscriptOpen (Status: out FILE_OPEN_STATUS; ExternalName: STRING; OpenKind: WRITE_APPEND_OPEN_KIND := WRITE_MODE) is
+ ------------------------------------------------------------
+ begin
+ file_open(Status, TranscriptFile, ExternalName, OpenKind) ;
+ if Status = OPEN_OK then
+ TranscriptEnable.Set(TRUE) ;
+ end if ;
+ end procedure TranscriptOpen ;
+
+ ------------------------------------------------------------
+ procedure TranscriptOpen (ExternalName: STRING; OpenKind: WRITE_APPEND_OPEN_KIND := WRITE_MODE) is
+ ------------------------------------------------------------
+ variable Status : FILE_OPEN_STATUS ;
+ begin
+ TranscriptOpen(Status, ExternalName, OpenKind) ;
+ if Status /= OPEN_OK then
+ report "TranscriptPkg.TranscriptOpen file: " &
+ ExternalName & " status is: " & to_string(status) & " and is not OPEN_OK" severity FAILURE ;
+ end if ;
+ end procedure TranscriptOpen ;
+
+ ------------------------------------------------------------
+ impure function TranscriptOpen (ExternalName: STRING; OpenKind: WRITE_APPEND_OPEN_KIND := WRITE_MODE) return FILE_OPEN_STATUS is
+ ------------------------------------------------------------
+ variable Status : FILE_OPEN_STATUS ;
+ begin
+ TranscriptOpen(Status, ExternalName, OpenKind) ;
+ return Status ;
+ end function TranscriptOpen ;
+
+ ------------------------------------------------------------
+ procedure TranscriptClose is
+ ------------------------------------------------------------
+ begin
+ if TranscriptEnable.Get then
+ file_close(TranscriptFile) ;
+ end if ;
+ TranscriptEnable.Set(FALSE) ;
+ end procedure TranscriptClose ;
+
+ ------------------------------------------------------------
+ impure function IsTranscriptOpen return boolean is
+ ------------------------------------------------------------
+ begin
+ return TranscriptEnable.Get ;
+ end function IsTranscriptOpen ;
+
+ ------------------------------------------------------------
+ procedure SetTranscriptMirror (A : boolean := TRUE) is
+ ------------------------------------------------------------
+ begin
+ TranscriptMirror.Set(A) ;
+ end procedure SetTranscriptMirror ;
+
+ ------------------------------------------------------------
+ impure function IsTranscriptMirrored return boolean is
+ ------------------------------------------------------------
+ begin
+ return TranscriptMirror.Get ;
+ end function IsTranscriptMirrored ;
+
+ ------------------------------------------------------------
+ procedure WriteLine(buf : inout line) is
+ ------------------------------------------------------------
+ begin
+ if not TranscriptEnable.Get then
+ WriteLine(OUTPUT, buf) ;
+ elsif TranscriptMirror.Get then
+ TEE(TranscriptFile, buf) ;
+ else
+ WriteLine(TranscriptFile, buf) ;
+ end if ;
+ end procedure WriteLine ;
+
+ ------------------------------------------------------------
+ procedure Print(s : string) is
+ ------------------------------------------------------------
+ variable buf : line ;
+ begin
+ write(buf, s) ;
+ WriteLine(buf) ;
+ end procedure Print ;
+
+ ------------------------------------------------------------
+ procedure BlankLine (count : integer := 1) is
+ ------------------------------------------------------------
+ begin
+ for i in 1 to count loop
+ print("") ;
+ end loop ;
+ end procedure Blankline ;
+
+end package body TranscriptPkg ; \ No newline at end of file