diff --git a/docs/logging/user_guide.rst b/docs/logging/user_guide.rst index 1fbecaaef..324a5b857 100644 --- a/docs/logging/user_guide.rst +++ b/docs/logging/user_guide.rst @@ -356,6 +356,26 @@ and then let the location preprocessor know about the added procedure ui = VUnit.from_argv() ui.enable_location_preprocessing(additional_subprograms=['my_convenience_procedure']) +External Logging Framework Integration +-------------------------------------- + +VUnit provides a package ``common_log_pkg`` providing a single procedure ``write_to_log`` that is used to +output the string produced by a log entry. The implementation of this procedure can be changed to redirect VUnit log +messages to a third party logging framework, thereby aligning the logging styles in a testbench with code using several +logging frameworks. The feature is enabled by passing a reference to the file implementing the package body: + +.. code-block:: python + + ui.add_vhdl_builtins(use_external_log="path/to/other/common_log_pkg/body") + +The procedure interface is designed to be generic and suitable for third party logging frameworks as well. If provided, +third party log messages can also be redirected to VUnit logging: + +.. literalinclude:: ../../vunit/vhdl/logging/src/common_log_pkg.vhd + :language: vhdl + :lines: 7- + + Deprecated Interfaces --------------------- diff --git a/docs/news.d/776.feature.rst b/docs/news.d/776.feature.rst new file mode 100644 index 000000000..a82393b3d --- /dev/null +++ b/docs/news.d/776.feature.rst @@ -0,0 +1 @@ +Add common log interface for third-party logging framework integration. diff --git a/examples/vhdl/osvvm_log_integration/osvvm_integration/AlertLogPkg.vhd b/examples/vhdl/osvvm_log_integration/osvvm_integration/AlertLogPkg.vhd new file mode 100644 index 000000000..cb113aa81 --- /dev/null +++ b/examples/vhdl/osvvm_log_integration/osvvm_integration/AlertLogPkg.vhd @@ -0,0 +1,5841 @@ +-- +-- 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 +-- Rob Gaddi Highland Technology. Inspired SetAlertLogPrefix / Suffix +-- +-- +-- 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 +-- 09/2021 2021.09 Added EndOfTestSummary and CreateYamlReport - Experimental Release +-- 07/2021 2021.07 When printing time value from GetOsvvmDefaultTimeUnits is used. +-- 06/2021 2021.06 FindAlertLogID updated to allow an ID name to match the name set by SetAlertLogName (ALERTLOG_BASE_ID) +-- 12/2020 2020.12 Added MetaMatch to AffirmIfEqual and AffirmIfNotEqual for std_logic family to use MetaMatch +-- Added AffirmIfEqual for boolean +-- 10/2020 2020.10 Added MetaMatch. +-- Updated AlertIfEqual and AlertIfNotEqual for std_logic family to use MetaMatch +-- 08/2020 2020.08 Alpha Test Release of Specification Tracking - Changes are provisional and subject to change +-- Added Passed Goals - reported with ReportAlerts and ReportRequirements. +-- Added WriteAlerts - CSV format of the information in ReportAlerts +-- Tests fail when requirements are not met and FailOnRequirementErrors is true (default TRUE). +-- Set using: SetAlertLogOptions(FailOnRequirementErrors => TRUE) +-- Turn on requirements printing in summary and details with PrintRequirements (default FALSE, +-- Turn on requirements printing in summary with PrintIfHaveRequirements (Default TRUE) +-- Added Requirements Bin, ReadSpecification, GetReqID, SetPassedGoal +-- Added AffirmIf("Req ID 1", ...) -- will work even if ID not set by GetReqID or ReadSpecification +-- Added ReportRequirements, WriteRequirements, and ReadRequirements (to merge results of multiple tests) +-- Added WriteTestSummary, ReadTestSummaries, ReportTestSummaries, and WriteTestSummaries. +-- 05/2020 2020.05 Added internal variables AlertCount (W, E, F) and ErrorCount (integer) +-- that hold the error state. These can be displayed in wave windows +-- in simulation to track number of errors. +-- Calls to std.env.stop now return ErrorCount +-- Updated calls to check for valid AlertLogIDs +-- Added affirmation count for each level. +-- Turn off reporting with SetAlertLogOptions (PrintAffirmations => TRUE) ; +-- Disabled Alerts now handled in separate bins and reported separately. +-- Turn off reporting with SetAlertLogOptions (PrintDisabledAlerts => TRUE) ; +-- 01/2020 2020.01 Updated Licenses to Apache +-- 10/2018 2018.10 Added pragmas to allow alerts, logs, and affirmations in RTL code +-- Added local variable to mirror top level ErrorCount and display in simulator +-- Added prefix and suffix +-- Debug printing with number of errors as prefix +-- 04/2018 2018.04 Fix to PathTail. Prep to change AlertLogIDType to a type. +-- 05/2017 2017.05 AffirmIfEqual, AffirmIfDiff, +-- GetAffirmCount (deprecates GetAffirmCheckCount), IncAffirmCount (deprecates IncAffirmCheckCount), +-- IsAlertEnabled (alias), IsLogEnabled (alias) +-- 02/2016 2016.02 Fixed IsLogEnableType (for PASSED), AffirmIf (to pass AlertLevel) +-- Created LocalInitialize +-- 07/2015 2016.01 Fixed AlertLogID issue with > 32 IDs +-- 05/2015 2015.06 Added IncAlertCount, AffirmIf +-- 03/2015 2015.03 Added: AlertIfEqual, AlertIfNotEqual, AlertIfDiff, PathTail, +-- ReportNonZeroAlerts, ReadLogEnables +-- 01/2015 2015.01 Initial revision +-- +-- This file is part of OSVVM. +-- +-- Copyright (c) 2015 - 2021 by SynthWorks Design Inc. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- https://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + + +use std.textio.all ; +use work.OsvvmGlobalPkg.all ; +use work.TranscriptPkg.all ; +use work.TextUtilPkg.all ; +use work.common_log_pkg.all; + + +library IEEE ; +use ieee.std_logic_1164.all ; +use ieee.numeric_std.all ; + +package AlertLogPkg is + +-- type AlertLogIDType is range integer'low to integer'high ; -- next revision + subtype AlertLogIDType is integer ; + type AlertLogIDVectorType is array (integer range <>) of AlertLogIDType ; + 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 := ALERTLOG_BASE_ID + 1 ; + constant OSVVM_ALERTLOG_ID : AlertLogIDType := ALERTLOG_BASE_ID + 2 ; -- reporting for packages + constant REQUIREMENT_ALERTLOG_ID : AlertLogIDType := ALERTLOG_BASE_ID + 3 ; + -- May have its own ID or OSVVM_ALERTLOG_ID as default - most scoreboards allocate their own ID + constant OSVVM_SCOREBOARD_ALERTLOG_ID : AlertLogIDType := OSVVM_ALERTLOG_ID ; + + -- Same as ALERTLOG_DEFAULT_ID + constant ALERT_DEFAULT_ID : AlertLogIDType := ALERTLOG_DEFAULT_ID ; + constant LOG_DEFAULT_ID : AlertLogIDType := ALERTLOG_DEFAULT_ID ; + + 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 + + ------------------------------------------------------------ + -- 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 ; + + ------------------------------------------------------------ + -- 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 ; + + ------------------------------------------------------------ + -- 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( AlertLogID : AlertLogIDType ; L, R : time ; 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 AlertIfEqual( L, R : time ; 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( AlertLogID : AlertLogIDType ; L, R : time ; 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 ) ; + procedure AlertIfNotEqual( L, R : time ; 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 ; + ReceivedMessage : string ; + ExpectedMessage : string ; + Enable : boolean := FALSE -- override internal enable + ) ; + + procedure AffirmIf( condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) ; + impure function AffirmIf( AlertLogID : AlertLogIDType ; condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) return boolean ; + impure function AffirmIf( condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) return boolean ; + + procedure AffirmIf( + AlertLogID : AlertLogIDType ; + condition : boolean ; + Message : string ; + Enable : boolean := FALSE -- override internal enable + ) ; + + procedure AffirmIf(condition : boolean ; Message : string ; Enable : boolean := FALSE ) ; + impure function AffirmIf( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Enable : boolean := FALSE ) return boolean ; + impure function AffirmIf( condition : boolean ; Message : string ; Enable : boolean := FALSE ) return boolean ; + + ------------------------------------------------------------ + procedure AffirmIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) ; + procedure AffirmIfNot( condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) ; + impure function AffirmIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) return boolean ; + impure function AffirmIfNot( condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) return boolean ; + + ------------------------------------------------------------ + procedure AffirmIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Enable : boolean := FALSE ) ; + procedure AffirmIfNot( condition : boolean ; Message : string ; Enable : boolean := FALSE ) ; + impure function AffirmIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Enable : boolean := FALSE ) return boolean ; + impure function AffirmIfNot( condition : boolean ; Message : string ; Enable : boolean := FALSE ) return boolean ; + + ------------------------------------------------------------ + procedure AffirmPassed( AlertLogID : AlertLogIDType ; Message : string ; Enable : boolean := FALSE ) ; + procedure AffirmPassed( Message : string ; Enable : boolean := FALSE ) ; + procedure AffirmError( AlertLogID : AlertLogIDType ; Message : string ) ; + procedure AffirmError( Message : string ) ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : boolean ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : std_logic ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : std_logic_vector ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : unsigned ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : signed ; Message : string := "" ; Enable : boolean := FALSE ); + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : integer ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : real ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : character ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : string ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : time ; Message : string := "" ; Enable : boolean := FALSE ) ; + + -- Without AlertLogID + ------------------------------------------------------------ + procedure AffirmIfEqual( Received, Expected : boolean ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( Received, Expected : std_logic ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( Received, Expected : std_logic_vector ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( Received, Expected : unsigned ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( Received, Expected : signed ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( Received, Expected : integer ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( Received, Expected : real ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( Received, Expected : character ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( Received, Expected : string ; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfEqual( Received, Expected : time ; Message : string := "" ; Enable : boolean := FALSE ) ; + + ------------------------------------------------------------ + procedure AffirmIfNotDiff (AlertLogID : AlertLogIDType ; Name1, Name2 : string; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfNotDiff (Name1, Name2 : string; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfNotDiff (AlertLogID : AlertLogIDType ; file File1, File2 : text; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfNotDiff (file File1, File2 : text; Message : string := "" ; Enable : boolean := FALSE ) ; +-- Deprecated as they are misnamed - should be AffirmIfNotDiff + procedure AffirmIfDiff (AlertLogID : AlertLogIDType ; Name1, Name2 : string; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfDiff (Name1, Name2 : string; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfDiff (AlertLogID : AlertLogIDType ; file File1, File2 : text; Message : string := "" ; Enable : boolean := FALSE ) ; + procedure AffirmIfDiff (file File1, File2 : text; Message : string := "" ; Enable : boolean := FALSE ) ; + + ------------------------------------------------------------ + -- Support for Specification / Requirements Tracking + procedure AffirmIf( RequirementsIDName : string ; condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) ; + procedure AffirmIf( RequirementsIDName : string ; condition : boolean ; Message : string ; Enable : boolean := FALSE ) ; + + ------------------------------------------------------------ + procedure SetAlertLogJustify (Enable : boolean := TRUE) ; + procedure ReportAlerts ( Name : String ; AlertCount : AlertCountType ) ; + procedure ReportRequirements ; + procedure ReportAlerts ( + Name : string := OSVVM_STRING_INIT_PARM_DETECT ; + AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; + ExternalErrors : AlertCountType := (others => 0) ; + ReportAll : Boolean := FALSE + ) ; + procedure ReportNonZeroAlerts ( + Name : string := OSVVM_STRING_INIT_PARM_DETECT ; + AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; + ExternalErrors : AlertCountType := (others => 0) + ) ; + procedure CreateYamlReport (ExternalErrors : AlertCountType := (0,0,0)) ; + procedure EndOfTestSummary ( + ReportAll : boolean := FALSE ; + ExternalErrors : AlertCountType := (0,0,0) + ) ; + procedure WriteTestSummary ( + FileName : string ; + OpenKind : File_Open_Kind := APPEND_MODE ; + Prefix : string := "" ; + Suffix : string := "" ; + ExternalErrors : AlertCountType := (0,0,0) ; + WriteFieldName : boolean := FALSE + ) ; + procedure WriteTestSummaries ( FileName : string ; OpenKind : File_Open_Kind := WRITE_MODE ) ; + procedure ReportTestSummaries ; + procedure WriteAlerts ( + FileName : string ; + AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; + OpenKind : File_Open_Kind := WRITE_MODE + ) ; + procedure WriteRequirements ( + FileName : string ; + AlertLogID : AlertLogIDType := REQUIREMENT_ALERTLOG_ID ; + OpenKind : File_Open_Kind := WRITE_MODE + ) ; + procedure ReadSpecification (FileName : string ; PassedGoal : integer := -1) ; + procedure ReadRequirements ( + FileName : string ; + ThresholdPassed : boolean := FALSE + ) ; + procedure ReadTestSummaries (FileName : string) ; + procedure ClearAlerts ; + procedure ClearAlertStopCounts ; + procedure ClearAlertCounts ; + 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) ; + + ------------------------------------------------------------ + -- Alert Enables + 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 ; + alias IsAlertEnabled is GetAlertEnable[AlertLogIDType, AlertType return boolean] ; + alias IsAlertEnabled is GetAlertEnable[AlertType return boolean] ; + + -- Log Enables + 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 ; + alias IsLogEnabled is GetLogEnable [AlertLogIDType, LogType return boolean] ; -- same as GetLogEnable + alias IsLogEnabled is GetLogEnable [LogType return boolean] ; -- same as GetLogEnable + + procedure ReportLogEnables ; + + procedure SetAlertLogName(Name : string ) ; + -- synthesis translate_off + impure function GetAlertLogName(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return string ; + -- synthesis translate_on + 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_ID_NOT_ASSIGNED; CreateHierarchy : Boolean := TRUE; DoNotReport : Boolean := FALSE) return AlertLogIDType ; + impure function GetReqID(Name : string ; PassedGoal : integer := -1 ; ParentID : AlertLogIDType := ALERTLOG_ID_NOT_ASSIGNED ; CreateHierarchy : Boolean := TRUE) return AlertLogIDType ; + procedure SetPassedGoal(AlertLogID : AlertLogIDType ; PassedGoal : integer ) ; + impure function GetAlertLogParentID(AlertLogID : AlertLogIDType) return AlertLogIDType ; + procedure SetAlertLogPrefix(AlertLogID : AlertLogIDType; Name : string ) ; + procedure UnSetAlertLogPrefix(AlertLogID : AlertLogIDType) ; + -- synthesis translate_off + impure function GetAlertLogPrefix(AlertLogID : AlertLogIDType) return string ; + -- synthesis translate_on + procedure SetAlertLogSuffix(AlertLogID : AlertLogIDType; Name : string ) ; + procedure UnSetAlertLogSuffix(AlertLogID : AlertLogIDType) ; + -- synthesis translate_off + impure function GetAlertLogSuffix(AlertLogID : AlertLogIDType) return string ; + -- synthesis translate_on + + ------------------------------------------------------------ + -- Accessor Methods + procedure SetGlobalAlertEnable (A : boolean := TRUE) ; + impure function SetGlobalAlertEnable (A : boolean := TRUE) return boolean ; + impure function GetGlobalAlertEnable return boolean ; + procedure IncAffirmCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) ; + impure function GetAffirmCount return natural ; + procedure IncAffirmPassedCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) ; + impure function GetAffirmPassedCount 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 SetAlertLogOptions ( + FailOnWarning : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + FailOnDisabledErrors : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + FailOnRequirementErrors : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + ReportHierarchy : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteAlertErrorCount : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteAlertLevel : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteAlertName : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteAlertTime : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteLogErrorCount : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteLogLevel : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteLogName : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteLogTime : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + PrintPassed : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + PrintAffirmations : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + PrintDisabledAlerts : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + PrintRequirements : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + PrintIfHaveRequirements : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + DefaultPassedGoal : integer := integer'left ; + 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 ; + + + -- synthesis translate_off + + impure function GetAlertLogFailOnWarning return OsvvmOptionsType ; + impure function GetAlertLogFailOnDisabledErrors return OsvvmOptionsType ; + impure function GetAlertLogFailOnRequirementErrors return OsvvmOptionsType ; + impure function GetAlertLogReportHierarchy return OsvvmOptionsType ; + impure function GetAlertLogFoundReportHier return boolean ; + impure function GetAlertLogFoundAlertHier return boolean ; + impure function GetAlertLogWriteAlertErrorCount return OsvvmOptionsType ; + impure function GetAlertLogWriteAlertLevel return OsvvmOptionsType ; + impure function GetAlertLogWriteAlertName return OsvvmOptionsType ; + impure function GetAlertLogWriteAlertTime return OsvvmOptionsType ; + impure function GetAlertLogWriteLogErrorCount return OsvvmOptionsType ; + impure function GetAlertLogWriteLogLevel return OsvvmOptionsType ; + impure function GetAlertLogWriteLogName return OsvvmOptionsType ; + impure function GetAlertLogWriteLogTime return OsvvmOptionsType ; + impure function GetAlertLogPrintPassed return OsvvmOptionsType ; + impure function GetAlertLogPrintAffirmations return OsvvmOptionsType ; + impure function GetAlertLogPrintDisabledAlerts return OsvvmOptionsType ; + impure function GetAlertLogPrintRequirements return OsvvmOptionsType ; + impure function GetAlertLogPrintIfHaveRequirements return OsvvmOptionsType ; + impure function GetAlertLogDefaultPassedGoal return integer ; + + 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 ; + + ------------------------------------------------------------ + -- MetaMatch + -- Similar to STD_MATCH, except + -- it returns TRUE for U=U, X=X, Z=Z, and W=W + -- All other values are consistent with STD_MATCH + -- MetaMatch, BooleanTableType, and MetaMatchTable are derivatives + -- of STD_MATCH from IEEE.Numeric_Std copyright by IEEE. + -- Numeric_Std is also released under the Apache License, Version 2.0. + -- Coding Styles were updated to match OSVVM + ------------------------------------------------------------ + function MetaMatch (l, r : std_ulogic) return boolean ; + function MetaMatch (L, R : std_ulogic_vector) return boolean ; + function MetaMatch (L, R : unresolved_unsigned) return boolean ; + function MetaMatch (L, R : unresolved_signed) return boolean ; + + -- synthesis translate_on + + -- ------------------------------------------------------------ + -- Deprecated + -- + + -- 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 ; + + -- 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 ; + + -- deprecated + procedure AffirmIf( + AlertLogID : AlertLogIDType ; + condition : boolean ; + Message : string ; + LogLevel : LogType ; -- := PASSED + AlertLevel : AlertType := ERROR + ) ; + procedure AffirmIf( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; AlertLevel : AlertType ) ; + procedure AffirmIf(condition : boolean ; Message : string ; LogLevel : LogType ; AlertLevel : AlertType := ERROR) ; + procedure AffirmIf(condition : boolean ; Message : string ; AlertLevel : AlertType ) ; + + alias IncAffirmCheckCount is IncAffirmCount [AlertLogIDType] ; + alias GetAffirmCheckCount is GetAffirmCount [return natural] ; + alias IsLoggingEnabled is GetLogEnable [AlertLogIDType, LogType return boolean] ; -- same as IsLogEnabled + alias IsLoggingEnabled is GetLogEnable [LogType return boolean] ; -- same as IsLogEnabled + + +end AlertLogPkg ; + +--- /////////////////////////////////////////////////////////////////////////// +--- /////////////////////////////////////////////////////////////////////////// +--- /////////////////////////////////////////////////////////////////////////// + +use work.NamePkg.all ; + +package body AlertLogPkg is + +-- synthesis translate_off + + -- 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 " + + ------------------------------------------------------------ + -- Package Local + 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 ; + + + type AlertLogStructPType is protected + + ------------------------------------------------------------ + procedure alert ( + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + message : string ; + level : AlertType := ERROR + ) ; + + ------------------------------------------------------------ + procedure IncAlertCount ( AlertLogID : AlertLogIDType ; level : AlertType := ERROR ) ; + procedure SetJustify ( + Enable : boolean := TRUE ; + AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID + ) ; + procedure ReportAlerts ( Name : string ; AlertCount : AlertCountType ) ; +-- procedure EndOfTestSummary ( +-- constant ReportAll : boolean := FALSE ; +-- constant ExternalErrors : AlertCountType := (0,0,0) +-- ) ; + procedure ReportRequirements ; + procedure ReportAlerts ( + Name : string := OSVVM_STRING_INIT_PARM_DETECT ; + AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; + ExternalErrors : AlertCountType := (0,0,0) ; + ReportAll : boolean := FALSE ; + ReportWhenZero : boolean := TRUE + ) ; + procedure WriteTestSummary ( + FileName : string ; + OpenKind : File_Open_Kind ; + Prefix : string ; + Suffix : string ; + ExternalErrors : AlertCountType ; + WriteFieldName : boolean + ) ; + procedure WriteTestSummaries ( FileName : string ; OpenKind : File_Open_Kind ) ; + procedure ReportTestSummaries ; + procedure WriteAlerts ( + FileName : string ; + AlertLogID : AlertLogIDType ; + OpenKind : File_Open_Kind + ) ; + procedure WriteRequirements ( + FileName : string ; + AlertLogID : AlertLogIDType ; + OpenKind : File_Open_Kind + ) ; + procedure ReadSpecification (FileName : string ; PassedGoal : integer ) ; + procedure ReadRequirements ( + FileName : string ; + ThresholdPassed : boolean ; + TestSummary : boolean + ) ; + procedure ClearAlerts ; + procedure ClearAlertStopCounts ; + 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 : AlertLogIDType) ; + 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; DoNotReport : Boolean) return AlertLogIDType ; + impure function GetReqID(Name : string ; PassedGoal : integer ; ParentID : AlertLogIDType ; CreateHierarchy : Boolean) return AlertLogIDType ; + procedure SetPassedGoal(AlertLogID : AlertLogIDType ; PassedGoal : integer ) ; + impure function GetAlertLogParentID(AlertLogID : AlertLogIDType) return AlertLogIDType ; + procedure Initialize(NewNumAlertLogIDs : AlertLogIDType := MIN_NUM_AL_IDS) ; + procedure DeallocateAlertLogStruct ; + procedure SetAlertLogPrefix(AlertLogID : AlertLogIDType; Name : string ) ; + procedure UnSetAlertLogPrefix(AlertLogID : AlertLogIDType) ; + impure function GetAlertLogPrefix(AlertLogID : AlertLogIDType) return string ; + procedure SetAlertLogSuffix(AlertLogID : AlertLogIDType; Name : string ) ; + procedure UnSetAlertLogSuffix(AlertLogID : AlertLogIDType) ; + impure function GetAlertLogSuffix(AlertLogID : AlertLogIDType) return string ; + + ------------------------------------------------------------ + ------------------------------------------------------------ + -- Accessor Methods + ------------------------------------------------------------ + procedure SetGlobalAlertEnable (A : boolean := TRUE) ; + impure function GetAlertLogName(AlertLogID : AlertLogIDType) return string ; + impure function GetGlobalAlertEnable return boolean ; + procedure IncAffirmCount(AlertLogID : AlertLogIDType) ; + impure function GetAffirmCount return natural ; + procedure IncAffirmPassedCount(AlertLogID : AlertLogIDType) ; + impure function GetAffirmPassedCount 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 : OsvvmOptionsType ; + FailOnDisabledErrors : OsvvmOptionsType ; + FailOnRequirementErrors : OsvvmOptionsType ; + ReportHierarchy : OsvvmOptionsType ; + WriteAlertErrorCount : OsvvmOptionsType ; + WriteAlertLevel : OsvvmOptionsType ; + WriteAlertName : OsvvmOptionsType ; + WriteAlertTime : OsvvmOptionsType ; + WriteLogErrorCount : OsvvmOptionsType ; + WriteLogLevel : OsvvmOptionsType ; + WriteLogName : OsvvmOptionsType ; + WriteLogTime : OsvvmOptionsType ; + PrintPassed : OsvvmOptionsType ; + PrintAffirmations : OsvvmOptionsType ; + PrintDisabledAlerts : OsvvmOptionsType ; + PrintRequirements : OsvvmOptionsType ; + PrintIfHaveRequirements : OsvvmOptionsType ; + DefaultPassedGoal : integer ; + AlertPrefix : string ; + LogPrefix : string ; + ReportPrefix : string ; + DoneName : string ; + PassName : string ; + FailName : string + ) ; + procedure ReportAlertLogOptions ; + + impure function GetAlertLogFailOnWarning return OsvvmOptionsType ; + impure function GetAlertLogFailOnDisabledErrors return OsvvmOptionsType ; + impure function GetAlertLogFailOnRequirementErrors return OsvvmOptionsType ; + impure function GetAlertLogReportHierarchy return OsvvmOptionsType ; + impure function GetAlertLogFoundReportHier return boolean ; + impure function GetAlertLogFoundAlertHier return boolean ; + impure function GetAlertLogWriteAlertErrorCount return OsvvmOptionsType ; + impure function GetAlertLogWriteAlertLevel return OsvvmOptionsType ; + impure function GetAlertLogWriteAlertName return OsvvmOptionsType ; + impure function GetAlertLogWriteAlertTime return OsvvmOptionsType ; + impure function GetAlertLogWriteLogErrorCount return OsvvmOptionsType ; + impure function GetAlertLogWriteLogLevel return OsvvmOptionsType ; + impure function GetAlertLogWriteLogName return OsvvmOptionsType ; + impure function GetAlertLogWriteLogTime return OsvvmOptionsType ; + impure function GetAlertLogPrintPassed return OsvvmOptionsType ; + impure function GetAlertLogPrintAffirmations return OsvvmOptionsType ; + impure function GetAlertLogPrintDisabledAlerts return OsvvmOptionsType ; + impure function GetAlertLogPrintRequirements return OsvvmOptionsType ; + impure function GetAlertLogPrintIfHaveRequirements return OsvvmOptionsType ; + impure function GetAlertLogDefaultPassedGoal return integer ; + + 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 PassedCountVar : natural := 0 ; + + variable ErrorCount : integer := 0 ; + variable AlertCount : AlertCountType := (0, 0, 0) ; + + ------------------------------------------------------------ + type AlertLogRecType is record + ------------------------------------------------------------ + Name : Line ; + NameLower : Line ; + Prefix : Line ; + Suffix : Line ; + ParentID : AlertLogIDType ; + ParentIDSet : Boolean ; + SiblingID : AlertLogIDType ; + ChildID : AlertLogIDType ; + ChildIDLast : AlertLogIDType ; + AlertCount : AlertCountType ; + DisabledAlertCount : AlertCountType ; + AffirmCount : Integer ; + PassedCount : Integer ; + PassedGoal : Integer ; + PassedGoalSet : Boolean ; + AlertStopCount : AlertCountType ; + AlertEnabled : AlertEnableType ; + LogEnabled : LogEnableType ; + DoNotReport : Boolean ; + -- Used only by ReadTestSummaries + TotalErrors : integer ; + AffirmPassedCount : integer ; +-- IsRequirment : boolean ; + end record AlertLogRecType ; + + ------------------------------------------------------------ + -- Basis for AlertLog Data Structure + variable NumAlertLogIDsVar : AlertLogIDType := 0 ; -- defined by initialize + variable NumAllocatedAlertLogIDsVar : AlertLogIDType := 0 ; + + 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 PrintPassedVar : boolean := TRUE ; + variable PrintAffirmationsVar : boolean := FALSE ; + variable PrintDisabledAlertsVar : boolean := FALSE ; + variable PrintRequirementsVar : boolean := FALSE ; + variable HasRequirementsVar : boolean := FALSE ; + variable PrintIfHaveRequirementsVar : boolean := TRUE ; + + variable DefaultPassedGoalVar : integer := 1 ; + + variable FailOnWarningVar : boolean := TRUE ; + variable FailOnDisabledErrorsVar : boolean := TRUE ; + variable FailOnRequirementErrorsVar : boolean := TRUE ; + + variable ReportHierarchyVar : boolean := TRUE ; + variable FoundReportHierVar : boolean := FALSE ; + variable FoundAlertHierVar : boolean := FALSE ; + + variable WriteAlertErrorCountVar : boolean := FALSE ; + variable WriteAlertLevelVar : boolean := TRUE ; + variable WriteAlertNameVar : boolean := TRUE ; + variable WriteAlertTimeVar : boolean := TRUE ; + variable WriteLogErrorCountVar : boolean := FALSE ; + 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 VerifyID( + AlertLogID : AlertLogIDType ; + LOWEST_ID : AlertLogIDType := ALERTLOG_BASE_ID + ) return AlertLogIDType is + ------------------------------------------------------------ + begin + if AlertLogID < LOWEST_ID or AlertLogID > NumAlertLogIDsVar then + Alert("Invalid AlertLogID") ; + return LOWEST_ID ; + else + return AlertLogID ; + end if ; + end function VerifyID ; + + ------------------------------------------------------------ + procedure IncAffirmCount(AlertLogID : AlertLogIDType) is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + if GlobalAlertEnabledVar then + localAlertLogID := VerifyID(AlertLogID) ; + AlertLogPtr(localAlertLogID).AffirmCount := AlertLogPtr(localAlertLogID).AffirmCount + 1 ; + AffirmCheckCountVar := AffirmCheckCountVar + 1 ; + end if ; + end procedure IncAffirmCount ; + + ------------------------------------------------------------ + impure function GetAffirmCount return natural is + ------------------------------------------------------------ + begin + return AffirmCheckCountVar ; + end function GetAffirmCount ; + + ------------------------------------------------------------ + procedure IncAffirmPassedCount(AlertLogID : AlertLogIDType) is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + if GlobalAlertEnabledVar then + localAlertLogID := VerifyID(AlertLogID) ; + AlertLogPtr(localAlertLogID).PassedCount := AlertLogPtr(localAlertLogID).PassedCount + 1 ; + PassedCountVar := PassedCountVar + 1 ; + AlertLogPtr(localAlertLogID).AffirmCount := AlertLogPtr(localAlertLogID).AffirmCount + 1 ; + AffirmCheckCountVar := AffirmCheckCountVar + 1 ; + end if ; + end procedure IncAffirmPassedCount ; + + ------------------------------------------------------------ + impure function GetAffirmPassedCount return natural is + ------------------------------------------------------------ + begin + return PassedCountVar ; + end function GetAffirmPassedCount ; + + ------------------------------------------------------------ + -- PT Local + procedure IncrementAlertCount( + ------------------------------------------------------------ + constant AlertLogID : in AlertLogIDType ; + constant Level : in AlertType ; + variable StopDueToCount : inout boolean ; + variable IncrementByAmount : in integer := 1 + ) is + begin + if AlertLogPtr(AlertLogID).AlertEnabled(Level) then + AlertLogPtr(AlertLogID).AlertCount(Level) := AlertLogPtr(AlertLogID).AlertCount(Level) + IncrementByAmount ; + -- 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, IncrementByAmount) ; + end if ; + else + -- Disabled, increment disabled count + AlertLogPtr(AlertLogID).DisabledAlertCount(Level) := AlertLogPtr(AlertLogID).DisabledAlertCount(Level) + IncrementByAmount ; + 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 ; + variable localAlertLogID : AlertLogIDType ; + + impure function error_count return integer is + begin + if WriteAlertErrorCountVar then + return ErrorCount + 1; + else + return no_val; + end if ; + end; + + impure function alert_level return string is + begin + if WriteAlertLevelVar then + return ALERT_NAME(Level) ; -- uses constant lookup + else + return ""; + end if ; + end; + + impure function log_source_name return string is + begin + if FoundAlertHierVar and WriteAlertNameVar then + return AlertLogPtr(localAlertLogID).Name.all; + else + return ""; + end if ; + end; + + impure function prefix return string is + begin + if AlertLogPtr(localAlertLogID).Prefix /= NULL then + return AlertLogPtr(localAlertLogID).Prefix.all; + else + return ""; + end if ; + end; + + impure function suffix return string is + begin + if AlertLogPtr(localAlertLogID).Suffix /= NULL then + return AlertLogPtr(localAlertLogID).Suffix.all; + else + return ""; + end if ; + end; + + impure function log_time return time is + begin + if WriteAlertTimeVar then + return NOW; + else + return no_time; + end if ; + end; + begin + -- Only write and count when GlobalAlertEnabledVar is enabled + if GlobalAlertEnabledVar then + localAlertLogID := VerifyID(AlertLogID) ; + -- Write when Alert is Enabled + if AlertLogPtr(localAlertLogID).AlertEnabled(Level) then + if not IsTranscriptOpen or IsTranscriptMirrored then + write_to_log ( + output, + msg => message, + log_time => log_time, + log_level => alert_level, + log_source_name => log_source_name, + val_1 => AlertLogJustifyAmountVar, + val_2 => error_count, + str_1 => AlertPrefixVar.Get(OSVVM_DEFAULT_ALERT_PREFIX), + str_2 => prefix, + str_3 => suffix + ); + end if; + + if IsTranscriptOpen or IsTranscriptMirrored then + write_to_log ( + TranscriptFile, + msg => message, + log_time => log_time, + log_level => alert_level, + log_source_name => log_source_name, + val_1 => AlertLogJustifyAmountVar, + val_2 => error_count, + str_1 => AlertPrefixVar.Get(OSVVM_DEFAULT_ALERT_PREFIX), + str_2 => prefix, + str_3 => suffix + ); + end if; + end if ; + -- Always Count + IncrementAlertCount(localAlertLogID, Level, StopDueToCount) ; + AlertCount := AlertLogPtr(ALERTLOG_BASE_ID).AlertCount; + ErrorCount := SumAlertCount(AlertCount); + if StopDueToCount then +-- write(buf, LF & AlertPrefix & " Stop Count on " & ALERT_NAME(Level) & " reached") ; + write(buf, LF & AlertPrefixVar.Get(OSVVM_DEFAULT_ALERT_PREFIX) & " Stop Count on " & ALERT_NAME(Level) & " reached") ; + if FoundAlertHierVar then + write(buf, " in " & AlertLogPtr(localAlertLogID).Name.all) ; + end if ; + write(buf, " at " & to_string(NOW, 1 ns) & " ") ; + writeline(buf) ; + ReportAlerts(ReportWhenZero => TRUE) ; + std.env.stop(ErrorCount) ; + 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 ; + variable localAlertLogID : AlertLogIDType ; + begin + if GlobalAlertEnabledVar then + localAlertLogID := VerifyID(AlertLogID) ; + IncrementAlertCount(localAlertLogID, Level, StopDueToCount) ; + AlertCount := AlertLogPtr(ALERTLOG_BASE_ID).AlertCount; + ErrorCount := SumAlertCount(AlertCount); + if StopDueToCount then +-- write(buf, LF & AlertPrefix & " Stop Count on " & ALERT_NAME(Level) & " reached") ; + write(buf, LF & AlertPrefixVar.Get(OSVVM_DEFAULT_ALERT_PREFIX) & " Stop Count on " & ALERT_NAME(Level) & " reached") ; + if FoundAlertHierVar then + write(buf, " in " & AlertLogPtr(localAlertLogID).Name.all) ; + end if ; + write(buf, " at " & to_string(NOW, 1 ns) & " ") ; + writeline(buf) ; + ReportAlerts(ReportWhenZero => TRUE) ; + std.env.stop(ErrorCount) ; + 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 + variable CurID : AlertLogIDType ; + begin + ResultValues(1) := CurrentLength + 1 ; -- AlertLogJustifyAmountVar + ResultValues(2) := CurrentLength + IndentAmount ; -- ReportJustifyAmountVar + CurID := AlertLogPtr(AlertLogID).ChildID ; + while CurID > ALERTLOG_BASE_ID loop + if CurID = REQUIREMENT_ALERTLOG_ID and HasRequirementsVar = FALSE then + CurID := AlertLogPtr(CurID).SiblingID ; + next ; + end if ; + LowerLevelValues := CalcJustify(CurID, AlertLogPtr(CurID).Name'length, IndentAmount + 2) ; + ResultValues(1) := maximum(ResultValues(1), LowerLevelValues(1)) ; + if not AlertLogPtr(AlertLogID).DoNotReport then + ResultValues(2) := maximum(ResultValues(2), LowerLevelValues(2)) ; + end if ; + CurID := AlertLogPtr(CurID).SiblingID ; + end loop ; + return ResultValues ; + end function CalcJustify ; + + ------------------------------------------------------------ + procedure SetJustify ( + ------------------------------------------------------------ + Enable : boolean := TRUE ; + AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID + ) is + begin + if Enable then + (AlertLogJustifyAmountVar, ReportJustifyAmountVar) := CalcJustify(AlertLogID, 0, 0) ; + else + AlertLogJustifyAmountVar := 0 ; + ReportJustifyAmountVar := 0 ; + end if; + end procedure SetJustify ; + + ------------------------------------------------------------ + impure function GetAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return AlertCountType is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + return AlertLogPtr(localAlertLogID).AlertCount ; + end function GetAlertCount ; + + ------------------------------------------------------------ + -- Local + impure function RemoveNonFailingWarnings(A : AlertCountType) return AlertCountType is + ------------------------------------------------------------ + variable Count : AlertCountType ; + begin + Count := A ; + if not FailOnWarningVar then + Count(WARNING) := 0 ; + end if ; + return Count ; + end function RemoveNonFailingWarnings ; + + ------------------------------------------------------------ + impure function GetEnabledAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return AlertCountType is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + variable Count : AlertCountType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + return RemoveNonFailingWarnings( AlertLogPtr(localAlertLogID).AlertCount ) ; + end function GetEnabledAlertCount ; + + + ------------------------------------------------------------ + impure function GetDisabledAlertCount return AlertCountType is + ------------------------------------------------------------ + variable Count : AlertCountType := (others => 0) ; + begin + for i in ALERTLOG_BASE_ID to NumAlertLogIDsVar loop + Count := Count + AlertLogPtr(i).DisabledAlertCount ; +--? Should excluded warnings get counted as disabled errors? +--? if not FailOnWarningVar then +--? Count(WARNING) := Count(WARNING) + AlertLogPtr(i).AlertCount(WARNING) ; +--? end if ; + end loop ; + return Count ; + end function GetDisabledAlertCount ; + + ------------------------------------------------------------ + impure function LocalGetDisabledAlertCount(AlertLogID: AlertLogIDType) return AlertCountType is + ------------------------------------------------------------ + variable Count : AlertCountType ; + variable CurID : AlertLogIDType ; + begin + Count := AlertLogPtr(AlertLogID).DisabledAlertCount ; + -- Find Children of this ID + CurID := AlertLogPtr(AlertLogID).ChildID ; + while CurID > ALERTLOG_BASE_ID loop + Count := Count + LocalGetDisabledAlertCount(CurID) ; -- Recursively descend into children + CurID := AlertLogPtr(CurID).SiblingID ; + end loop ; + return Count ; + end function LocalGetDisabledAlertCount ; + + ------------------------------------------------------------ + impure function GetDisabledAlertCount(AlertLogID: AlertLogIDType) return AlertCountType is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + return LocalGetDisabledAlertCount(localAlertLogID) ; + end function GetDisabledAlertCount ; + + ------------------------------------------------------------ + -- Local + procedure GetRequirementsCount( + AlertLogID : AlertLogIDType; + RequirementsPassed : out integer ; + RequirementsGoal : out integer + ) is + ------------------------------------------------------------ + variable ChildRequirementsPassed, ChildRequirementsGoal : integer ; + variable CurID : AlertLogIDType ; + begin + RequirementsPassed := 0 ; + RequirementsGoal := 0 ; + if AlertLogPtr(AlertLogID).PassedGoal > 0 then + RequirementsGoal := 1 ; + if AlertLogPtr(AlertLogID).PassedCount >= AlertLogPtr(AlertLogID).PassedGoal then + RequirementsPassed := 1 ; + end if ; + end if ; + -- Find Children of this ID + CurID := AlertLogPtr(AlertLogID).ChildID ; + while CurID > ALERTLOG_BASE_ID loop + GetRequirementsCount(CurID, ChildRequirementsPassed, ChildRequirementsGoal) ; + RequirementsPassed := RequirementsPassed + ChildRequirementsPassed ; + RequirementsGoal := RequirementsGoal + ChildRequirementsGoal ; + CurID := AlertLogPtr(CurID).SiblingID ; + end loop ; + end procedure GetRequirementsCount ; + + ------------------------------------------------------------ + -- Local + procedure GetPassedAffirmCount( + AlertLogID : AlertLogIDType; + PassedCount : out integer ; + AffirmCount : out integer + ) is + ------------------------------------------------------------ + variable ChildPassedCount, ChildAffirmCount : integer ; + variable CurID : AlertLogIDType ; + begin + PassedCount := AlertLogPtr(AlertLogID).PassedCount ; + AffirmCount := AlertLogPtr(AlertLogID).AffirmCount ; + -- Find Children of this ID + CurID := AlertLogPtr(AlertLogID).ChildID ; + while CurID > ALERTLOG_BASE_ID loop + GetPassedAffirmCount(CurID, ChildPassedCount, ChildAffirmCount) ; + PassedCount := PassedCount + ChildPassedCount ; + AffirmCount := AffirmCount + ChildAffirmCount ; + CurID := AlertLogPtr(CurID).SiblingID ; + end loop ; + end procedure GetPassedAffirmCount ; + + ------------------------------------------------------------ + -- PT Local + procedure PrintTopAlerts ( + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + Name : string ; + ExternalErrors : AlertCountType ; + variable HasDisabledAlerts : inout Boolean ; + variable TestFailed : inout Boolean + ) 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 ; + variable TotalErrors : integer ; + variable TotalAlertErrors, TotalDisabledAlertErrors : integer ; + variable TotalRequirementsPassed, TotalRequirementsGoal, TotalRequirementErrors : integer ; + variable AlertCountVar, DisabledAlertCount : AlertCountType ; + variable PassedCount, AffirmCheckCount : integer ; + begin + AlertCountVar := AlertLogPtr(AlertLogID).AlertCount + ExternalErrors ; + TotalAlertErrors := SumAlertCount( RemoveNonFailingWarnings(AlertCountVar)) ; + + DisabledAlertCount := GetDisabledAlertCount(AlertLogID) ; + TotalDisabledAlertErrors := SumAlertCount( RemoveNonFailingWarnings(DisabledAlertCount) ) ; + HasDisabledAlerts := TotalDisabledAlertErrors /= 0 ; + + GetRequirementsCount(AlertLogID, TotalRequirementsPassed, TotalRequirementsGoal) ; + TotalRequirementErrors := TotalRequirementsGoal - TotalRequirementsPassed ; + + TotalErrors := TotalAlertErrors ; + if FailOnDisabledErrorsVar then + TotalErrors := TotalErrors + TotalDisabledAlertErrors ; + end if ; + if FailOnRequirementErrorsVar then + TotalErrors := TotalErrors + TotalRequirementErrors ; + end if ; + + TestFailed := TotalErrors /= 0 ; + + GetPassedAffirmCount(AlertLogID, PassedCount, AffirmCheckCount) ; + + if not TestFailed then + -- write(buf, ReportPrefix & DoneName & " " & PassName & " " & Name) ; -- PASSED + write(buf, + ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt) & -- ReportPrefix + ResolveOsvvmDoneName(DoneNameVar.GetOpt) & " " & -- DoneName + ResolveOsvvmPassName(PassNameVar.GetOpt) & " " & -- PassName + Name + ) ; + else + -- write(buf, ReportPrefix & DoneName & " " & FailName & " " & Name) ; -- FAILED + write(buf, + ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt) & -- ReportPrefix + ResolveOsvvmDoneName(DoneNameVar.GetOpt) & " " & -- DoneName + ResolveOsvvmFailName(FailNameVar.GetOpt) & " " & -- FailName + Name + ) ; + end if ; +--? Also print when warnings exist and are hidden by FailOnWarningVar=FALSE + if TestFailed then + write(buf, " Total Error(s) = " & to_string(TotalErrors) ) ; + write(buf, " Failures: " & to_string(AlertCountVar(FAILURE)) ) ; + write(buf, " Errors: " & to_string(AlertCountVar(ERROR) ) ) ; + write(buf, " Warnings: " & to_string(AlertCountVar(WARNING) ) ) ; + end if ; + if HasDisabledAlerts or PrintDisabledAlertsVar then -- print if exist or enabled + write(buf, " Total Disabled Error(s) = " & to_string(TotalDisabledAlertErrors)) ; + end if ; + if (HasDisabledAlerts and FailOnDisabledErrorsVar) or PrintDisabledAlertsVar then -- print if enabled + write(buf, " Failures: " & to_string(DisabledAlertCount(FAILURE)) ) ; + write(buf, " Errors: " & to_string(DisabledAlertCount(ERROR) ) ) ; + write(buf, " Warnings: " & to_string(DisabledAlertCount(WARNING) ) ) ; + end if ; + if PrintPassedVar or (AffirmCheckCount /= 0) or PrintAffirmationsVar then -- Print if passed or printing affirmations + write(buf, " Passed: " & to_string(PassedCount)) ; + end if; + if (AffirmCheckCount /= 0) or PrintAffirmationsVar then + write(buf, " Affirmations Checked: " & to_string(AffirmCheckCount)) ; + end if ; + if PrintRequirementsVar or + (PrintIfHaveRequirementsVar and HasRequirementsVar) or + (FailOnRequirementErrorsVar and TotalRequirementErrors /= 0) + then + write(buf, " Requirements Passed: " & to_string(TotalRequirementsPassed) & + " of " & to_string(TotalRequirementsGoal) ) ; + end if ; + write(buf, " at " & to_string(NOW, 1 ns)) ; + WriteLine(buf) ; + end procedure PrintTopAlerts ; + + ------------------------------------------------------------ + -- PT Local + procedure PrintOneChild( + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + Prefix : string ; + IndentAmount : integer ; + ReportWhenZero : boolean ; + HasDisabledErrors : boolean + ) is + variable buf : line ; + alias CurID : AlertLogIDType is AlertLogID ; + begin + if + ReportWhenZero or -- ReportAlerts + -- ReportNonZeroAlerts and (AlertCount or (FailOn and DisabledAlertCount)) + (SumAlertCount(AlertLogPtr(CurID).AlertCount) > 0) or + (FailOnDisabledErrorsVar and (SumAlertCount(AlertLogPtr(CurID).DisabledAlertCount) > 0)) or + (FailOnRequirementErrorsVar and (AlertLogPtr(CurID).PassedCount < AlertLogPtr(CurID).PassedGoal)) + then + write(buf, Prefix & " " & LeftJustify(AlertLogPtr(CurID).Name.all, ReportJustifyAmountVar - IndentAmount)) ; + write(buf, " Failures: " & to_string(AlertLogPtr(CurID).AlertCount(FAILURE) ) ) ; + write(buf, " Errors: " & to_string(AlertLogPtr(CurID).AlertCount(ERROR) ) ) ; + write(buf, " Warnings: " & to_string(AlertLogPtr(CurID).AlertCount(WARNING) ) ) ; + if (HasDisabledErrors and FailOnDisabledErrorsVar) or PrintDisabledAlertsVar then + write(buf, " Disabled Failures: " & to_string(AlertLogPtr(CurID).DisabledAlertCount(FAILURE) ) ) ; + write(buf, " Errors: " & to_string(AlertLogPtr(CurID).DisabledAlertCount(ERROR) ) ) ; + write(buf, " Warnings: " & to_string(AlertLogPtr(CurID).DisabledAlertCount(WARNING) ) ) ; + end if ; + if PrintPassedVar or PrintRequirementsVar then + write(buf, " Passed: " & to_string(AlertLogPtr(CurID).PassedCount)) ; + end if; + if PrintRequirementsVar then + write(buf, " of " & to_string(AlertLogPtr(CurID).PassedGoal) ) ; + end if ; + if PrintAffirmationsVar then + write(buf, " Affirmations: " & to_string(AlertLogPtr(CurID).AffirmCount ) ) ; + end if ; + WriteLine(buf) ; + end if ; + end procedure PrintOneChild ; + + ------------------------------------------------------------ + -- PT Local + procedure IterateAndPrintChildren( + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + Prefix : string ; + IndentAmount : integer ; + ReportWhenZero : boolean ; + HasDisabledErrors : boolean + ) is + variable buf : line ; + variable CurID : AlertLogIDType ; + begin + CurID := AlertLogPtr(AlertLogID).ChildID ; + while CurID > ALERTLOG_BASE_ID loop + -- Don't print requirements if there no requirements + if CurID = REQUIREMENT_ALERTLOG_ID and HasRequirementsVar = FALSE then + CurID := AlertLogPtr(CurID).SiblingID ; + next ; + end if ; + if not AlertLogPtr(AlertLogID).DoNotReport then + PrintOneChild( + AlertLogID => CurID, + Prefix => Prefix, + IndentAmount => IndentAmount, + ReportWhenZero => ReportWhenZero, + HasDisabledErrors => HasDisabledErrors + ) ; + IterateAndPrintChildren( + AlertLogID => CurID, + Prefix => Prefix & " ", + IndentAmount => IndentAmount + 2, + ReportWhenZero => ReportWhenZero, + HasDisabledErrors => HasDisabledErrors + ) ; + end if ; + CurID := AlertLogPtr(CurID).SiblingID ; + end loop ; + end procedure IterateAndPrintChildren ; + + ------------------------------------------------------------ + procedure ReportAlerts ( + Name : string := OSVVM_STRING_INIT_PARM_DETECT ; + AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; + ExternalErrors : AlertCountType := (0,0,0) ; + ReportAll : boolean := FALSE ; + ReportWhenZero : boolean := TRUE + ) is + ------------------------------------------------------------ + variable TestFailed, HasDisabledErrors : boolean ; + -- constant ReportPrefix : string := ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt) ; + variable TurnedOnJustify : boolean := FALSE ; + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + if ReportJustifyAmountVar <= 0 then + TurnedOnJustify := TRUE ; + SetJustify ; + end if ; + + if IsOsvvmStringSet(Name) then + PrintTopAlerts ( + AlertLogID => localAlertLogID, + Name => Name, + ExternalErrors => ExternalErrors, + HasDisabledAlerts => HasDisabledErrors, + TestFailed => TestFailed + ) ; + else + PrintTopAlerts ( + AlertLogID => localAlertLogID, + Name => AlertLogPtr(localAlertLogID).Name.all, + ExternalErrors => ExternalErrors, + HasDisabledAlerts => HasDisabledErrors, + TestFailed => TestFailed + ) ; + end if ; + --Print Hierarchy when enabled and test failed + if ReportAll or (FoundReportHierVar and ReportHierarchyVar and TestFailed) then + -- (NumErrors /= 0 or (NumDisabledErrors /=0 and FailOnDisabledErrorsVar)) then + IterateAndPrintChildren( + AlertLogID => localAlertLogID, +-- Prefix => ReportPrefix & " ", + Prefix => ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt) & " ", + IndentAmount => 2, + ReportWhenZero => ReportAll or ReportWhenZero, + HasDisabledErrors => HasDisabledErrors -- NumDisabledErrors /= 0 + ) ; + end if ; + if TurnedOnJustify then + -- Turn it back off + SetJustify(FALSE) ; + end if ; + end procedure ReportAlerts ; + + ------------------------------------------------------------ + procedure ReportRequirements is + ------------------------------------------------------------ + variable TestFailed, HasDisabledErrors : boolean ; +-- constant ReportPrefix : string := ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt) ; + variable TurnedOnJustify : boolean := FALSE ; + variable SavedPrintRequirementsVar : boolean ; + begin + SavedPrintRequirementsVar := PrintRequirementsVar ; + PrintRequirementsVar := TRUE ; + + if ReportJustifyAmountVar <= 0 then + TurnedOnJustify := TRUE ; + SetJustify ; + end if ; + PrintTopAlerts ( + AlertLogID => ALERTLOG_BASE_ID, + Name => AlertLogPtr(ALERTLOG_BASE_ID).Name.all, + ExternalErrors => (0,0,0), + HasDisabledAlerts => HasDisabledErrors, + TestFailed => TestFailed + ) ; + IterateAndPrintChildren( + AlertLogID => REQUIREMENT_ALERTLOG_ID, +-- Prefix => ReportPrefix & " ", + Prefix => ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt) & " ", + IndentAmount => 2, + ReportWhenZero => TRUE, + HasDisabledErrors => HasDisabledErrors -- NumDisabledErrors /= 0 + ) ; + if TurnedOnJustify then + -- Turn it back off + SetJustify(FALSE) ; + end if ; + PrintRequirementsVar := SavedPrintRequirementsVar ; + end procedure ReportRequirements ; + + ------------------------------------------------------------ + procedure ReportAlerts ( Name : string ; AlertCount : AlertCountType ) 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 ; + variable NumErrors : integer ; + begin + NumErrors := SumAlertCount(AlertCount) ; + if NumErrors = 0 then + -- Passed + -- write(buf, ReportPrefix & DoneName & " " & PassName & " " & Name) ; + write(buf, + ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt ) & -- ReportPrefix + ResolveOsvvmDoneName(DoneNameVar.GetOpt) & " " & -- DoneName + ResolveOsvvmPassName(PassNameVar.GetOpt) & " " & -- PassName + Name + ) ; + write(buf, " at " & to_string(NOW, 1 ns)) ; + WriteLine(buf) ; + else + -- Failed + -- write(buf, ReportPrefix & DoneName & " " & FailName & " "& Name) ; + write(buf, + ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt ) & -- ReportPrefix + ResolveOsvvmDoneName(DoneNameVar.GetOpt) & " " & -- DoneName + ResolveOsvvmFailName(FailNameVar.GetOpt) & " " & -- 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) ) ) ; + write(buf, " at " & to_string(NOW, 1 ns)) ; + writeLine(buf) ; + end if ; + end procedure ReportAlerts ; + +-- ------------------------------------------------------------ +-- procedure EndOfTestSummary ( +-- ------------------------------------------------------------ +-- -- variable TestErrorsOut : out integer ; +-- constant ReportAll : boolean := FALSE ; +-- constant ExternalErrors : AlertCountType := (0,0,0) +-- ) is +-- begin +-- ReportAlerts(ExternalErrors => ExternalErrors, ReportAll => ReportAll) ; +-- WriteTestSummary(FileName => "OsvvmRun.yml", OpenKind => APPEND_MODE, Prefix => " Results: """, Suffix => """", ExternalErrors => ExternalErrors) ; +-- std.env.stop(SumAlertCount(GetAlertCount + ExternalErrors)) ; +-- -- Alternative to Stopping here. +-- -- TestErrorsOut := SumAlertCount(GetAlertCount + ExternalErrors) ; +-- end procedure EndOfTestSummary ; + + ------------------------------------------------------------ + -- PT Local + impure function IsRequirement(AlertLogID : AlertLogIDType) return boolean is + ------------------------------------------------------------ + begin + if AlertLogID = REQUIREMENT_ALERTLOG_ID then + return TRUE ; + elsif AlertLogID <= ALERTLOG_BASE_ID then + return FALSE ; + else + return IsRequirement(AlertLogPtr(AlertLogID).ParentID) ; + end if ; + end function IsRequirement ; + + ------------------------------------------------------------ + -- pt local + procedure WriteOneTestSummary ( + ------------------------------------------------------------ + file TestFile : text ; + AlertLogID : AlertLogIDType ; + RequirementsGoal : integer ; + RequirementsPassed : integer ; + TotalErrors : integer ; + AlertCount : AlertCountType ; + AffirmCount : integer ; + PassedCount : integer ; + Delimiter : string ; + Prefix : string := "" ; + Suffix : string := "" ; + WriteFieldName : boolean := FALSE + ) is + variable buf : line ; + begin +-- Should disabled errors be included here? +-- In the previous step, we counted DisabledErrors as a regular error if FailOnDisabledErrorsVar (default TRUE) + + Write(buf, + Prefix & + IfElse(WriteFieldName, "Status: " & IfElse(TotalErrors=0, "PASSED", "FAILED") & LF, "") & + IfElse(WriteFieldName, Prefix & "Results: {Name: ", "") & + AlertLogPtr(AlertLogID).Name.all & Delimiter & + IfElse(WriteFieldName, "RequirementsGoal: ", "") & + to_string( RequirementsGoal ) & Delimiter & + IfElse(WriteFieldName, "RequirementsPassed: ", "") & + to_string( RequirementsPassed ) & Delimiter & + IfElse(WriteFieldName, "TotalErrors: ", "") & + to_string( TotalErrors ) & Delimiter & + IfElse(WriteFieldName, "Failure: ", "") & + to_string( AlertCount(FAILURE) ) & Delimiter & + IfElse(WriteFieldName, "Error: ", "") & + to_string( AlertCount(ERROR) ) & Delimiter & + IfElse(WriteFieldName, "Warning: ", "") & + to_string( AlertCount(WARNING) ) & Delimiter & + IfElse(WriteFieldName, "AffirmCount: ", "") & + to_string( AffirmCount ) & Delimiter & + IfElse(WriteFieldName, "PassedCount: ", "") & + to_string( PassedCount ) & + IfElse(WriteFieldName, "}", "") & + Suffix + ) ; +-- ## Write(buf, +-- ## Prefix & +-- ## IfElse(WriteFieldName, "Status: " & IfElse(TotalErrors=0, "PASSED", "FAILED") & Delimiter, "") & +-- ## IfElse(WriteFieldName, "Name: ", "") & +-- ## AlertLogPtr(AlertLogID).Name.all & Delimiter & +-- ## IfElse(WriteFieldName, "RequirementsGoal: ", "") & +-- ## to_string( RequirementsGoal ) & Delimiter & +-- ## IfElse(WriteFieldName, "RequirementsPassed: ", "") & +-- ## to_string( RequirementsPassed ) & Delimiter & +-- ## IfElse(WriteFieldName, "TotalErrors: ", "") & +-- ## to_string( TotalErrors ) & Delimiter & +-- ## IfElse(WriteFieldName, "Failure: ", "") & +-- ## to_string( AlertCount(FAILURE) ) & Delimiter & +-- ## IfElse(WriteFieldName, "Error: ", "") & +-- ## to_string( AlertCount(ERROR) ) & Delimiter & +-- ## IfElse(WriteFieldName, "Warning: ", "") & +-- ## to_string( AlertCount(WARNING) ) & Delimiter & +-- ## IfElse(WriteFieldName, "AffirmCount: ", "") & +-- ## to_string( AffirmCount ) & Delimiter & +-- ## IfElse(WriteFieldName, "PassedCount: ", "") & +-- ## to_string( PassedCount ) & Suffix +-- ## ) ; + + + WriteLine(TestFile, buf) ; + end procedure WriteOneTestSummary ; + + ------------------------------------------------------------ + -- pt local + procedure WriteTestSummary ( + ------------------------------------------------------------ + file TestFile : text ; + Prefix : string := "" ; + Suffix : string := "" ; + ExternalErrors : AlertCountType := (0,0,0) ; + WriteFieldName : boolean := FALSE + ) is + -- Format: Action Count min1 max1 min2 max2 + variable TotalErrors : integer ; + variable TotalAlertErrors, TotalDisabledAlertErrors : integer ; + variable TotalRequirementsPassed, TotalRequirementsGoal : integer ; + variable TotalRequirementErrors : integer ; + variable TotalAlertCount, DisabledAlertCount : AlertCountType ; + constant AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; + variable PassedCount, AffirmCount : integer ; + constant DELIMITER : string := ", " ; + begin + TotalAlertCount := AlertLogPtr(AlertLogID).AlertCount + ExternalErrors ; + TotalAlertErrors := SumAlertCount( RemoveNonFailingWarnings(TotalAlertCount)) ; + + DisabledAlertCount := GetDisabledAlertCount(AlertLogID) ; + TotalDisabledAlertErrors := SumAlertCount( RemoveNonFailingWarnings(DisabledAlertCount) ) ; + + GetRequirementsCount(AlertLogID, TotalRequirementsPassed, TotalRequirementsGoal) ; + TotalRequirementErrors := TotalRequirementsGoal - TotalRequirementsPassed ; + + TotalErrors := TotalAlertErrors ; + if FailOnDisabledErrorsVar then + TotalErrors := TotalErrors + TotalDisabledAlertErrors ; + TotalAlertCount := TotalAlertCount + DisabledAlertCount ; + end if ; + if FailOnRequirementErrorsVar then + TotalErrors := TotalErrors + TotalRequirementErrors ; + end if ; + + GetPassedAffirmCount(AlertLogID, PassedCount, AffirmCount) ; + + WriteOneTestSummary( + TestFile => TestFile, + AlertLogID => AlertLogID, + RequirementsGoal => TotalRequirementsGoal, + RequirementsPassed => TotalRequirementsPassed, + TotalErrors => TotalErrors, + AlertCount => TotalAlertCount, + AffirmCount => AffirmCount, + PassedCount => PassedCount, + Delimiter => DELIMITER, + Prefix => Prefix, + Suffix => Suffix, + WriteFieldName => WriteFieldName + ) ; + end procedure WriteTestSummary ; + + ------------------------------------------------------------ + procedure WriteTestSummary ( + ------------------------------------------------------------ + FileName : string ; + OpenKind : File_Open_Kind ; + Prefix : string ; + Suffix : string ; + ExternalErrors : AlertCountType ; + WriteFieldName : boolean + ) is + -- Format: Action Count min1 max1 min2 max2 + file TestFile : text open OpenKind is FileName ; + begin + WriteTestSummary(TestFile => TestFile, Prefix => Prefix, Suffix => Suffix, ExternalErrors => ExternalErrors, WriteFieldName => WriteFieldName) ; + end procedure WriteTestSummary ; + + ------------------------------------------------------------ + procedure WriteTestSummaries ( -- PT Local + ------------------------------------------------------------ + file TestFile : text ; + AlertLogID : AlertLogIDType + ) is + variable CurID : AlertLogIDType ; + variable TotalErrors, RequirementsGoal, RequirementsPassed : integer ; + begin + -- Descend from WriteRequirements + CurID := AlertLogPtr(AlertLogID).ChildID ; + while CurID > ALERTLOG_BASE_ID loop + TotalErrors := AlertLogPtr(CurID).TotalErrors ; + RequirementsGoal := AlertLogPtr(CurID).PassedGoal ; + RequirementsPassed := AlertLogPtr(CurID).PassedCount ; + if AlertLogPtr(CurID).AffirmCount <= 0 and FailOnRequirementErrorsVar and + (RequirementsGoal > RequirementsPassed) then + -- Add errors for tests that did not run. + TotalErrors := RequirementsGoal - RequirementsPassed ; + end if ; + WriteOneTestSummary( + TestFile => TestFile, + AlertLogID => CurID, + RequirementsGoal => RequirementsGoal, + RequirementsPassed => RequirementsPassed, + TotalErrors => TotalErrors, + AlertCount => AlertLogPtr(CurID).AlertCount, + AffirmCount => AlertLogPtr(CurID).AffirmCount, + PassedCount => AlertLogPtr(CurID).AffirmPassedCount, + Delimiter => "," + ) ; + WriteTestSummaries(TestFile, CurID) ; + CurID := AlertLogPtr(CurID).SiblingID ; + end loop ; + end procedure WriteTestSummaries ; + + ------------------------------------------------------------ + procedure WriteTestSummaries ( + ------------------------------------------------------------ + FileName : string ; + OpenKind : File_Open_Kind + ) is + -- Format: Action Count min1 max1 min2 max2 + file TestFile : text open OpenKind is FileName ; + begin + WriteTestSummaries( + TestFile => TestFile, + AlertLogID => REQUIREMENT_ALERTLOG_ID + ) ; + end procedure WriteTestSummaries ; + + ------------------------------------------------------------ + procedure ReportOneTestSummary ( -- PT Local + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + RequirementsGoal : integer ; + RequirementsPassed : integer ; + TotalErrors : integer ; + AlertCount : AlertCountType ; + AffirmCount : integer ; + PassedCount : integer ; + Delimiter : string + ) is + variable buf : line ; + -- constant ReportPrefix : string := ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt ) ; + -- constant PassName : string := ResolveOsvvmPassName(PassNameVar.GetOpt ) ; + -- constant FailName : string := ResolveOsvvmFailName(FailNameVar.GetOpt ) ; + begin +-- write(buf, ReportPrefix & " ") ; + write(buf, ResolveOsvvmWritePrefix(ReportPrefixVar.GetOpt) & " ") ; + + if (AffirmCount > 0) and (TotalErrors = 0) then +-- write(buf, PassName) ; + write(buf, ResolveOsvvmPassName(PassNameVar.GetOpt)) ; + elsif TotalErrors > 0 then +-- write(buf, FailName) ; + write(buf, ResolveOsvvmFailName(FailNameVar.GetOpt)) ; + else + write(buf, string'("??????")) ; + end if ; + write(buf, " " & LeftJustify(AlertLogPtr(AlertLogID).Name.all, ReportJustifyAmountVar)) ; + write(buf, " Total Error(s) = " & to_string(TotalErrors) ) ; + write(buf, " Failures: " & to_string(AlertCount(FAILURE) ) ) ; + write(buf, " Errors: " & to_string(AlertCount(ERROR) ) ) ; + write(buf, " Warnings: " & to_string(AlertCount(WARNING) ) ) ; + write(buf, " Affirmations Passed: " & to_string(PassedCount) & + " of " & to_string(AffirmCount)) ; + write(buf, " Requirements Passed: " & to_string(RequirementsPassed) & + " of " & to_string(RequirementsGoal) ) ; + WriteLine(buf) ; + end procedure ReportOneTestSummary ; + + ------------------------------------------------------------ + procedure ReportTestSummaries ( -- PT Local + ------------------------------------------------------------ + AlertLogID : AlertLogIDType + ) is + variable CurID : AlertLogIDType ; + variable TotalErrors, RequirementsGoal, RequirementsPassed : integer ; + begin + CurID := AlertLogPtr(AlertLogID).ChildID ; + while CurID > ALERTLOG_BASE_ID loop + TotalErrors := AlertLogPtr(CurID).TotalErrors ; + RequirementsGoal := AlertLogPtr(CurID).PassedGoal ; + RequirementsPassed := AlertLogPtr(CurID).PassedCount ; + if AlertLogPtr(CurID).AffirmCount <= 0 and FailOnRequirementErrorsVar and + (RequirementsGoal > RequirementsPassed) then + -- Add errors for tests that did not run. + TotalErrors := RequirementsGoal - RequirementsPassed ; + end if ; + ReportOneTestSummary( + AlertLogID => CurID, + RequirementsGoal => RequirementsGoal, + RequirementsPassed => RequirementsPassed, + TotalErrors => TotalErrors, + AlertCount => AlertLogPtr(CurID).AlertCount, + AffirmCount => AlertLogPtr(CurID).AffirmCount, + PassedCount => AlertLogPtr(CurID).AffirmPassedCount, + Delimiter => "," + ) ; + ReportTestSummaries( + AlertLogID => CurID + ) ; + CurID := AlertLogPtr(CurID).SiblingID ; + end loop ; + end procedure ReportTestSummaries ; + + + ------------------------------------------------------------ + procedure ReportTestSummaries is + ------------------------------------------------------------ + variable IgnoredValue, OldReportJustifyAmount : integer ; + begin + OldReportJustifyAmount := ReportJustifyAmountVar ; + (IgnoredValue, ReportJustifyAmountVar) := CalcJustify(REQUIREMENT_ALERTLOG_ID, 0, 0) ; + + ReportTestSummaries(AlertLogID => REQUIREMENT_ALERTLOG_ID) ; + ReportJustifyAmountVar := OldReportJustifyAmount ; + end procedure ReportTestSummaries ; + + ------------------------------------------------------------ + -- pt local + procedure WriteAlerts ( -- pt local + file AlertsFile : text ; + AlertLogID : AlertLogIDType + ) is + ------------------------------------------------------------ + -- Format: Name, PassedGoal, #Passed, #TotalErrors, FAILURE, ERROR, WARNING, Affirmations + variable buf : line ; + variable AlertCountVar : AlertCountType ; + constant DELIMITER : character := ',' ; + variable CurID : AlertLogIDType ; + begin + CurID := AlertLogPtr(AlertLogID).ChildID ; + while CurID > ALERTLOG_BASE_ID loop + write(buf, AlertLogPtr(CurID).Name.all) ; + write(buf, DELIMITER & to_string(AlertLogPtr(CurID).PassedGoal)) ; + -- Handling for PassedCount > PassedGoal done in ReadRequirements + write(buf, DELIMITER & to_string(AlertLogPtr(CurID).PassedCount)) ; + AlertCountVar := AlertLogPtr(CurID).AlertCount ; + if FailOnDisabledErrorsVar then + AlertCountVar := AlertCountVar + AlertLogPtr(CurID).DisabledAlertCount ; + end if; + -- TotalErrors + write(buf, DELIMITER & to_string( SumAlertCount(RemoveNonFailingWarnings(AlertCountVar)))) ; + write(buf, DELIMITER & to_string( AlertCountVar(FAILURE) )) ; + write(buf, DELIMITER & to_string( AlertCountVar(ERROR) )) ; + write(buf, DELIMITER & to_string( AlertCountVar(WARNING) )) ; + write(buf, DELIMITER & to_string( AlertLogPtr(CurID).AffirmCount )) ; +-- write(buf, DELIMITER & to_string(AlertLogPtr(CurID).PassedCount)) ; -- redundancy intentional, for reading WriteTestSummary + WriteLine(AlertsFile, buf) ; + WriteAlerts(AlertsFile, CurID) ; + CurID := AlertLogPtr(CurID).SiblingID ; + end loop ; + end procedure WriteAlerts ; + + ------------------------------------------------------------ + procedure WriteRequirements ( + ------------------------------------------------------------ + FileName : string ; + AlertLogID : AlertLogIDType ; + OpenKind : File_Open_Kind + ) is + -- Format: Action Count min1 max1 min2 max2 + file RequirementsFile : text open OpenKind is FileName ; + variable LocalAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + WriteTestSummary(RequirementsFile) ; + if IsRequirement(localAlertLogID) then + WriteAlerts(RequirementsFile, localAlertLogID) ; + else + Alert("WriteRequirements: Called without a Requirement") ; + WriteAlerts(RequirementsFile, REQUIREMENT_ALERTLOG_ID) ; + end if ; + end procedure WriteRequirements ; + + ------------------------------------------------------------ + procedure WriteAlerts ( + ------------------------------------------------------------ + FileName : string ; + AlertLogID : AlertLogIDType ; + OpenKind : File_Open_Kind + ) is + -- Format: Action Count min1 max1 min2 max2 + file AlertsFile : text open OpenKind is FileName ; + variable LocalAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + WriteTestSummary(AlertsFile) ; + WriteAlerts(AlertsFile, localAlertLogID) ; + end procedure WriteAlerts ; + + ------------------------------------------------------------ + procedure ReadSpecification (file SpecificationFile : text ; PassedGoalIn : integer ) is -- PT Local + ------------------------------------------------------------ + variable buf,Name,Description : line ; + variable ReadValid : boolean ; + variable Empty : boolean ; + variable MultiLineComment : boolean := FALSE ; + variable PassedGoal : integer ; + variable PassedGoalSet : boolean ; + variable Char : character ; + constant DELIMITER : character := ',' ; + variable AlertLogID : AlertLogIDType ; + begin + HasRequirementsVar := TRUE ; + + -- Format: Spec Name, [Spec Description = "",] [Requirement Goal = 0] + ReadFileLoop : while not EndFile(SpecificationFile) loop + ReadLoop : loop + ReadLine(SpecificationFile, buf) ; + EmptyOrCommentLine(buf, Empty, MultiLineComment) ; + next ReadFileLoop when Empty ; + + -- defaults + PassedGoal := DefaultPassedGoalVar ; + PassedGoalSet := FALSE ; + + -- Read Name and Remove delimiter + ReadUntilDelimiterOrEOL(buf, Name, DELIMITER, ReadValid) ; + exit ReadFileLoop when AlertIfNot(OSVVM_ALERTLOG_ID, ReadValid, + "AlertLogPkg.ReadSpecification: Failed while reading Name", FAILURE) ; + + -- If rest of line is blank or comment, then skip it. + EmptyOrCommentLine(buf, Empty, MultiLineComment) ; + exit ReadLoop when Empty ; + + -- Optional: Read Description + ReadUntilDelimiterOrEOL(buf, Description, DELIMITER, ReadValid) ; + exit ReadFileLoop when AlertIfNot(OSVVM_ALERTLOG_ID, ReadValid, + "AlertLogPkg.ReadSpecification: Failed while reading Description", FAILURE) ; + + if IsNumber(Description.all) then + read(Description, PassedGoal, ReadValid) ; + deallocate(Description) ; + exit ReadFileLoop when AlertIfNot(OSVVM_ALERTLOG_ID, ReadValid, + "AlertLogPkg.ReadSpecification: Failed while reading PassedGoal (while skipping Description)", FAILURE) ; + PassedGoalSet := TRUE ; + else + -- If rest of line is blank or comment, then skip it. + EmptyOrCommentLine(buf, Empty, MultiLineComment) ; + exit ReadLoop when Empty ; + + -- Read PassedGoal + read(buf, PassedGoal, ReadValid) ; + exit ReadFileLoop when AlertIfNot(OSVVM_ALERTLOG_ID, ReadValid, + "AlertLogPkg.ReadSpecification: Failed while reading PassedGoal", FAILURE) ; + PassedGoalSet := TRUE ; + end if ; + exit ReadLoop ; + end loop ReadLoop ; +-- AlertLogID := GetReqID(Name.all) ; -- For new items, sets DefaultPassedGoalVar and PassedGoalSet = FALSE. + AlertLogID := GetReqID(Name => Name.all, PassedGoal => -1, ParentID=> ALERTLOG_ID_NOT_ASSIGNED, CreateHierarchy => TRUE) ; + deallocate(Name) ; + deallocate(Description) ; -- not used + -- Implementation 1: Just put the values in + -- If Override values specified, then use them. + if PassedGoalIn >= 0 then + PassedGoal := PassedGoalIn ; + PassedGoalSet := TRUE ; + end if ; + if PassedGoalSet then + -- Is there a goal to update? + if AlertLogPtr(AlertLogID).PassedGoalSet then + -- Merge Old and New + AlertLogPtr(AlertLogID).PassedGoal := maximum(PassedGoal, AlertLogPtr(AlertLogID).PassedGoal) ; + else + -- No Old, Just use New + AlertLogPtr(AlertLogID).PassedGoal := PassedGoal ; + end if ; + AlertLogPtr(AlertLogID).PassedGoalSet := TRUE ; + end if ; + end loop ReadFileLoop ; + end procedure ReadSpecification ; + + ------------------------------------------------------------ + procedure ReadSpecification (FileName : string ; PassedGoal : integer ) is + ------------------------------------------------------------ + -- Format: Action Count min1 max1 min2 max2 + file SpecificationFile : text open READ_MODE is FileName ; + begin + ReadSpecification(SpecificationFile, PassedGoal) ; + end procedure ReadSpecification ; + + ------------------------------------------------------------ + -- PT Local + procedure ReadRequirements ( -- PT Local + file RequirementsFile : text ; + ThresholdPassed : boolean ; + TestSummary : boolean + ) is + ------------------------------------------------------------ + constant DELIMITER : character := ',' ; + variable buf,Name : line ; + variable ReadValid : boolean ; + variable Empty : boolean ; + variable MultiLineComment : boolean := FALSE ; + variable StopDueToCount : boolean := FALSE ; +-- variable ReadFailed : boolean := TRUE ; + variable Found : boolean ; + + variable ReqPassedGoal : integer ; + variable ReqPassedCount : integer ; + variable TotalErrorCount : integer ; + variable AlertCount : AlertCountType ; + variable AffirmCount : integer ; + variable AffirmPassedCount : integer ; + variable AlertLogID : AlertLogIDType ; + begin + if not TestSummary then + -- For requirements, skip the first line that has the test summary + ReadLine(RequirementsFile, buf) ; + end if ; + + ReadFileLoop : while not EndFile(RequirementsFile) loop + ReadLoop : loop + ReadLine(RequirementsFile, buf) ; + EmptyOrCommentLine(buf, Empty, MultiLineComment) ; + next ReadFileLoop when Empty ; + + -- defaults +-- ReadFailed := TRUE ; + ReqPassedGoal := 0 ; + ReqPassedCount := 0 ; + TotalErrorCount := 0 ; + AlertCount := (0, 0, 0) ; + AffirmCount := 0 ; + AffirmPassedCount := 0 ; + + -- Read Name. Remove delimiter + ReadUntilDelimiterOrEOL(buf, Name, DELIMITER, ReadValid) ; + exit ReadFileLoop when AlertIfNot(OSVVM_ALERTLOG_ID, ReadValid, + "AlertLogPkg.ReadRequirements: Failed while reading Name", FAILURE) ; + + -- Read ReqPassedGoal + read(buf, ReqPassedGoal, ReadValid) ; + exit ReadFileLoop when AlertIfNot(OSVVM_ALERTLOG_ID, ReadValid, + "AlertLogPkg.ReadRequirements: Failed while reading PassedGoal", FAILURE) ; + + FindDelimiter(buf, DELIMITER, Found) ; + exit ReadFileLoop when AlertIf(OSVVM_ALERTLOG_ID, not Found, + "AlertLogPkg.ReadRequirements: Failed after reading PassedGoal", FAILURE) ; + + -- Read ReqPassedCount + read(buf, ReqPassedCount, ReadValid) ; + exit ReadFileLoop when AlertIfNot(OSVVM_ALERTLOG_ID, ReadValid, + "AlertLogPkg.ReadRequirements: Failed while reading PassedCount", FAILURE) ; + + AffirmPassedCount := ReqPassedGoal ; + + FindDelimiter(buf, DELIMITER, Found) ; + exit ReadFileLoop when AlertIf(OSVVM_ALERTLOG_ID, not Found, + "AlertLogPkg.ReadRequirements: Failed after reading PassedCount", FAILURE) ; + + -- Read TotalErrorCount + read(buf, TotalErrorCount, ReadValid) ; + exit ReadFileLoop when AlertIfNot(OSVVM_ALERTLOG_ID, ReadValid, + "AlertLogPkg.ReadRequirements: Failed while reading TotalErrorCount", FAILURE) ; + AlertCount := (0, TotalErrorCount, 0) ; -- Default + + FindDelimiter(buf, DELIMITER, Found) ; + exit ReadFileLoop when AlertIf(OSVVM_ALERTLOG_ID, not Found, + "AlertLogPkg.ReadRequirements: Failed after reading PassedCount", FAILURE) ; + + -- Read AlertCount + for i in AlertType'left to AlertType'right loop + read(buf, AlertCount(i), ReadValid) ; + exit ReadFileLoop when AlertIfNot(OSVVM_ALERTLOG_ID, ReadValid, + "AlertLogPkg.ReadRequirements: Failed while reading " & + "AlertCount(" & to_string(i) & ")", FAILURE) ; + + FindDelimiter(buf, DELIMITER, Found) ; + exit ReadFileLoop when AlertIf(OSVVM_ALERTLOG_ID, not Found, + "AlertLogPkg.ReadRequirements: Failed after reading " & + "AlertCount(" & to_string(i) & ")", FAILURE) ; + end loop ; + + -- Read AffirmCount + read(buf, AffirmCount, ReadValid) ; + exit ReadFileLoop when AlertIfNot(OSVVM_ALERTLOG_ID, ReadValid, + "AlertLogPkg.ReadRequirements: Failed while reading AffirmCount", FAILURE) ; + + if TestSummary then + FindDelimiter(buf, DELIMITER, Found) ; + exit ReadFileLoop when AlertIf(OSVVM_ALERTLOG_ID, not Found, + "AlertLogPkg.ReadRequirements: Failed after reading AffirmCount", FAILURE) ; + + -- Read AffirmPassedCount + read(buf, AffirmPassedCount, ReadValid) ; + if not ReadValid then + AffirmPassedCount := ReqPassedGoal ; + Alert(OSVVM_ALERTLOG_ID, "AlertLogPkg.ReadRequirements: Failed while reading AffirmPassedCount", FAILURE) ; + exit ReadFileLoop ; + end if ; + end if ; + + exit ReadLoop ; + end loop ReadLoop ; + +-- AlertLogID := GetReqID(Name.all) ; + AlertLogID := GetReqID(Name => Name.all, PassedGoal => -1, ParentID=> ALERTLOG_ID_NOT_ASSIGNED, CreateHierarchy => TRUE) ; --! GHDL + deallocate(Name) ; +-- if Merge then + -- Passed Goal + if AlertLogPtr(AlertLogID).PassedGoalSet then + AlertLogPtr(AlertLogID).PassedGoal := maximum(AlertLogPtr(AlertLogID).PassedGoal, ReqPassedGoal) ; + else + AlertLogPtr(AlertLogID).PassedGoal := ReqPassedGoal ; + end if ; + -- Requirements Passed Count + if ThresholdPassed then + ReqPassedCount := minimum(ReqPassedCount, ReqPassedGoal) ; + end if ; + AlertLogPtr(AlertLogID).PassedCount := AlertLogPtr(AlertLogID).PassedCount + ReqPassedCount ; + + AlertLogPtr(AlertLogID).TotalErrors := AlertLogPtr(AlertLogID).TotalErrors + TotalErrorCount ; + + -- AlertCount + IncrementAlertCount(AlertLogID, FAILURE, StopDueToCount, AlertCount(FAILURE)) ; + IncrementAlertCount(AlertLogID, ERROR, StopDueToCount, AlertCount(ERROR)) ; + IncrementAlertCount(AlertLogID, WARNING, StopDueToCount, AlertCount(WARNING)) ; + + -- AffirmCount + AlertLogPtr(AlertLogID).AffirmCount := AlertLogPtr(AlertLogID).AffirmCount + AffirmCount ; + AlertLogPtr(AlertLogID).AffirmPassedCount := AlertLogPtr(AlertLogID).AffirmPassedCount + AffirmPassedCount ; + +-- else +-- AlertLogPtr(AlertLogID).PassedGoal := ReqPassedGoal ; +-- AlertLogPtr(AlertLogID).PassedCount := ReqPassedCount ; +-- +-- IncrementAlertCount(AlertLogID, FAILURE, StopDueToCount, AlertCount(FAILURE)) ; +-- IncrementAlertCount(AlertLogID, ERROR, StopDueToCount, AlertCount(ERROR)) ; +-- IncrementAlertCount(AlertLogID, WARNING, StopDueToCount, AlertCount(WARNING)) ; +-- +-- AlertLogPtr(AlertLogID).AffirmCount := ReqPassedCount + TotalErrorCount ; +-- end if; + AlertLogPtr(AlertLogID).PassedGoalSet := TRUE ; + end loop ReadFileLoop ; + end procedure ReadRequirements ; + + ------------------------------------------------------------ + procedure ReadRequirements ( + FileName : string ; + ThresholdPassed : boolean ; + TestSummary : boolean + ) is + ------------------------------------------------------------ + -- Format: Action Count min1 max1 min2 max2 + file RequirementsFile : text open READ_MODE is FileName ; + begin + ReadRequirements(RequirementsFile, ThresholdPassed, TestSummary) ; + end procedure ReadRequirements ; + + ------------------------------------------------------------ + procedure ClearAlerts is + ------------------------------------------------------------ + begin + AffirmCheckCountVar := 0 ; + PassedCountVar := 0 ; + AlertCount := (0, 0, 0) ; + ErrorCount := 0 ; + + for i in ALERTLOG_BASE_ID to NumAlertLogIDsVar loop + AlertLogPtr(i).AlertCount := (0, 0, 0) ; + AlertLogPtr(i).DisabledAlertCount := (0, 0, 0) ; + AlertLogPtr(i).AffirmCount := 0 ; + AlertLogPtr(i).PassedCount := 0 ; + AlertLogPtr(i).PassedGoal := 0 ; + end loop ; + end procedure ClearAlerts ; + + ------------------------------------------------------------ + procedure ClearAlertStopCounts is + ------------------------------------------------------------ + begin + 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).AlertStopCount := (FAILURE => integer'right, ERROR => integer'right, WARNING => integer'right) ; + end loop ; + end procedure ClearAlertStopCounts ; + + ------------------------------------------------------------ + -- PT Local + procedure LocalLog ( + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + Message : string ; + Level : LogType + ) is + impure function error_count return integer is + begin + if WriteLogErrorCountVar and WriteAlertErrorCountVar then + return ErrorCount; + else + return no_val; + end if ; + end; + + impure function log_level return string is + begin + if WriteLogLevelVar then + return LOG_NAME(Level); + else + return ""; + end if ; + end; + + impure function log_source_name return string is + begin + if FoundAlertHierVar and WriteLogNameVar then + return AlertLogPtr(AlertLogID).Name.all; + else + return ""; + end if; + end; + + impure function suffix return string is + begin + if AlertLogPtr(AlertLogID).Suffix /= NULL then + return AlertLogPtr(AlertLogID).Suffix.all; + else + return ""; + end if ; + end; + + impure function log_time return time is + begin + if WriteLogTimeVar then + return NOW; + else + return no_time; + end if ; + end; + begin + if not IsTranscriptOpen or IsTranscriptMirrored then + write_to_log ( + output, + msg => Message, + log_time => log_time, + log_level => log_level, + log_source_name => log_source_name, + val_1 => AlertLogJustifyAmountVar, + val_2 => error_count, + str_1 => LogPrefixVar.Get(OSVVM_DEFAULT_LOG_PREFIX), + str_3 => suffix + ); + end if; + + if IsTranscriptOpen or IsTranscriptMirrored then + write_to_log ( + TranscriptFile, + msg => Message, + log_time => log_time, + log_level => log_level, + log_source_name => log_source_name, + val_1 => AlertLogJustifyAmountVar, + val_2 => error_count, + str_1 => LogPrefixVar.Get(OSVVM_DEFAULT_LOG_PREFIX), + str_3 => suffix + ); + end if; + end procedure LocalLog ; + + ------------------------------------------------------------ + procedure log ( + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + Message : string ; + Level : LogType := ALWAYS ; + Enable : boolean := FALSE -- override internal enable + ) is + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + if Level = ALWAYS or Enable then + LocalLog(localAlertLogID, Message, Level) ; + elsif AlertLogPtr(localAlertLogID).LogEnabled(Level) then + LocalLog(localAlertLogID, Message, Level) ; + end if ; + if Level = PASSED then + IncAffirmPassedCount(AlertLogID) ; -- count the passed and affirmation + 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) ; + AlertLogPtr(ALERTLOG_BASE_ID).NameLower := new string'(to_lower(NAME)) ; + end procedure SetAlertLogName ; + + ------------------------------------------------------------ + impure function GetAlertLogName(AlertLogID : AlertLogIDType) return string is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + return AlertLogPtr(localAlertLogID).Name.all ; + end function GetAlertLogName ; + + ------------------------------------------------------------ + -- PT Local + procedure DeQueueID(AlertLogID : AlertLogIDType) is + ------------------------------------------------------------ + variable ParentID, CurID : AlertLogIDType ; + begin + ParentID := AlertLogPtr(AlertLogID).ParentID ; + CurID := AlertLogPtr(ParentID).ChildID ; + + -- Found at top of list + if AlertLogPtr(ParentID).ChildID = AlertLogID then + AlertLogPtr(ParentID).ChildID := AlertLogPtr(AlertLogID).SiblingID ; + else + -- Find among Siblings + loop + if AlertLogPtr(CurID).SiblingID = AlertLogID then + AlertLogPtr(CurID).SiblingID := AlertLogPtr(AlertLogID).SiblingID ; + exit ; + end if ; + if AlertLogPtr(CurID).SiblingID <= ALERTLOG_BASE_ID then + Alert("DeQueueID: AlertLogID not found") ; + exit ; + end if ; + CurID := AlertLogPtr(CurID).SiblingID ; + end loop ; + end if ; + end procedure DeQueueID ; + + ------------------------------------------------------------ + -- PT Local + procedure EnQueueID(AlertLogID, ParentID : AlertLogIDType ; ParentIDSet : boolean := TRUE) is + ------------------------------------------------------------ + variable CurID : AlertLogIDType ; + begin + AlertLogPtr(AlertLogID).ParentIDSet := ParentIDSet ; + AlertLogPtr(AlertLogID).ParentID := ParentID ; + AlertLogPtr(AlertLogID).SiblingID := ALERTLOG_ID_NOT_ASSIGNED ; + + if AlertLogPtr(ParentID).ChildID < ALERTLOG_BASE_ID then + AlertLogPtr(ParentID).ChildID := AlertLogID ; + else + CurID := AlertLogPtr(ParentID).ChildIDLast ; + AlertLogPtr(CurID).SiblingID := AlertLogID ; + end if ; + AlertLogPtr(ParentID).ChildIDLast := AlertLogID ; + end procedure EnQueueID ; + + ------------------------------------------------------------ + -- PT Local + procedure NewAlertLogRec(AlertLogID : AlertLogIDType ; Name : string ; ParentID : AlertLogIDType; DoNotReport : Boolean := FALSE) is + ------------------------------------------------------------ + variable AlertEnabled : AlertEnableType ; + variable AlertStopCount : AlertCountType ; + variable LogEnabled : LogEnableType ; + begin + AlertLogPtr(AlertLogID) := new AlertLogRecType ; + if AlertLogID = ALERTLOG_BASE_ID then + AlertEnabled := (TRUE, TRUE, TRUE) ; + LogEnabled := (others => FALSE) ; + AlertStopCount := (FAILURE => 0, ERROR => integer'right, WARNING => integer'right) ; + EnQueueID(AlertLogID, ALERTLOG_BASE_ID, TRUE) ; + else + if ParentID < ALERTLOG_BASE_ID then + AlertEnabled := AlertLogPtr(ALERTLOG_BASE_ID).AlertEnabled ; + LogEnabled := AlertLogPtr(ALERTLOG_BASE_ID).LogEnabled ; + EnQueueID(AlertLogID, ALERTLOG_BASE_ID, FALSE) ; + else + AlertEnabled := AlertLogPtr(ParentID).AlertEnabled ; + LogEnabled := AlertLogPtr(ParentID).LogEnabled ; + EnQueueID(AlertLogID, ParentID, TRUE) ; + end if ; + AlertStopCount := (FAILURE => integer'right, ERROR => integer'right, WARNING => integer'right) ; + end if ; + AlertLogPtr(AlertLogID).Name := new string'(NAME) ; + AlertLogPtr(AlertLogID).NameLower := new string'(to_lower(NAME)) ; + AlertLogPtr(AlertLogID).AlertCount := (0, 0, 0) ; + AlertLogPtr(AlertLogID).DisabledAlertCount := (0, 0, 0) ; + AlertLogPtr(AlertLogID).AffirmCount := 0 ; + AlertLogPtr(AlertLogID).PassedCount := 0 ; + AlertLogPtr(AlertLogID).PassedGoal := 0 ; + AlertLogPtr(AlertLogID).AlertEnabled := AlertEnabled ; + AlertLogPtr(AlertLogID).AlertStopCount := AlertStopCount ; + AlertLogPtr(AlertLogID).LogEnabled := LogEnabled ; + AlertLogPtr(AlertLogID).DoNotReport := DoNotReport ; + -- Set ChildID, ChildIDLast, SiblingID to ALERTLOG_ID_NOT_ASSIGNED + AlertLogPtr(AlertLogID).SiblingID := ALERTLOG_ID_NOT_ASSIGNED ; + AlertLogPtr(AlertLogID).ChildID := ALERTLOG_ID_NOT_ASSIGNED ; + AlertLogPtr(AlertLogID).ChildIDLast := ALERTLOG_ID_NOT_ASSIGNED ; + AlertLogPtr(AlertLogID).TotalErrors := 0 ; + AlertLogPtr(AlertLogID).AffirmPassedCount := 0 ; + end procedure NewAlertLogRec ; + + ------------------------------------------------------------ + -- PT Local + -- Construct initial data structure + procedure LocalInitialize(NewNumAlertLogIDs : AlertLogIDType := 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 + NewAlertLogRec(ALERTLOG_BASE_ID, "AlertLogTop", ALERTLOG_BASE_ID) ; + -- 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 REQUIREMENT_ALERTLOG_ID /= ALERT_DEFAULT_ID then + NewAlertLogRec(REQUIREMENT_ALERTLOG_ID, "Requirements", 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 : AlertLogIDType := 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 DeallocateAlertLogStruct 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 + PrintPassedVar := TRUE ; + PrintAffirmationsVar := FALSE ; + PrintDisabledAlertsVar := FALSE ; + PrintRequirementsVar := FALSE ; + PrintIfHaveRequirementsVar := TRUE ; + DefaultPassedGoalVar := 1 ; + NumAlertLogIDsVar := 0 ; + NumAllocatedAlertLogIDsVar := 0 ; + GlobalAlertEnabledVar := TRUE ; -- Allows turn off and on + AffirmCheckCountVar := 0 ; + PassedCountVar := 0 ; + FailOnWarningVar := TRUE ; + FailOnDisabledErrorsVar := TRUE ; + FailOnRequirementErrorsVar := TRUE ; + ReportHierarchyVar := TRUE ; + FoundReportHierVar := FALSE ; + FoundAlertHierVar := FALSE ; + WriteAlertErrorCountVar := FALSE ; + WriteAlertLevelVar := TRUE ; + WriteAlertNameVar := TRUE ; + WriteAlertTimeVar := TRUE ; + WriteLogErrorCountVar := FALSE ; + WriteLogLevelVar := TRUE ; + WriteLogNameVar := TRUE ; + WriteLogTimeVar := TRUE ; + end procedure DeallocateAlertLogStruct ; + + ------------------------------------------------------------ + -- PT Local. + procedure GrowAlertStructure (NewNumAlertLogIDs : AlertLogIDType) 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 : AlertLogIDType) 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 + ------------------------------------------------------------ + constant NameLower : string := to_lower(Name) ; + begin + for i in ALERTLOG_BASE_ID+1 to NumAlertLogIDsVar loop + if NameLower = AlertLogPtr(i).NameLower.all then + return i ; + end if ; + end loop ; + return ALERTLOG_ID_NOT_FOUND ; -- not found + end function FindAlertLogID ; + + ------------------------------------------------------------ + -- PT Local + impure function LocalFindAlertLogID(Name : string ; ParentID : AlertLogIDType) return AlertLogIDType is + ------------------------------------------------------------ + constant NameLower : string := to_lower(Name) ; + begin + if ParentID = ALERTLOG_ID_NOT_ASSIGNED then + return FindAlertLogID(Name) ; + else + for i in ALERTLOG_BASE_ID+1 to NumAlertLogIDsVar loop + if NameLower = AlertLogPtr(i).NameLower.all and + (AlertLogPtr(i).ParentID = ParentID or AlertLogPtr(i).ParentIDSet = FALSE) + then + return i ; + end if ; + end loop ; + return ALERTLOG_ID_NOT_FOUND ; -- not found + end if ; + end function LocalFindAlertLogID ; + + ------------------------------------------------------------ + impure function FindAlertLogID(Name : string ; ParentID : AlertLogIDType) return AlertLogIDType is + ------------------------------------------------------------ + variable localParentID : AlertLogIDType ; + begin + localParentID := VerifyID(ParentID, ALERTLOG_ID_NOT_ASSIGNED) ; + return LocalFindAlertLogID(Name, localParentID) ; + end function FindAlertLogID ; + + ------------------------------------------------------------ + -- PT Local + procedure AdjustID(AlertLogID, ParentID : AlertLogIDType ; ParentIDSet : boolean := TRUE) is + ------------------------------------------------------------ + begin + if IsRequirement(AlertLogID) and not IsRequirement(ParentID) then + Alert(AlertLogID, "GetAlertLogID/GetReqID: Parent of a Requirement must be a Requirement") ; + else + if ParentID /= AlertLogPtr(AlertLogID).ParentID then + DeQueueID(AlertLogID) ; + EnQueueID(AlertLogID, ParentID, ParentIDSet) ; + else + AlertLogPtr(AlertLogID).ParentIDSet := ParentIDSet ; + end if ; + end if ; + end procedure AdjustID ; + + ------------------------------------------------------------ + impure function GetAlertLogID(Name : string; ParentID : AlertLogIDType; CreateHierarchy : Boolean; DoNotReport : Boolean) return AlertLogIDType is + ------------------------------------------------------------ + variable ResultID : AlertLogIDType ; + variable localParentID : AlertLogIDType ; + begin + localParentID := VerifyID(ParentID, ALERTLOG_ID_NOT_ASSIGNED) ; + ResultID := LocalFindAlertLogID(Name, localParentID) ; + if ResultID /= ALERTLOG_ID_NOT_FOUND then -- found it, set localParentID + if AlertLogPtr(ResultID).ParentIDSet = FALSE and localParentID /= ALERTLOG_ID_NOT_ASSIGNED then + AdjustID(ResultID, localParentID, TRUE) ; + -- else -- do not update as ParentIDs are either same or input localParentID = ALERTLOG_ID_NOT_ASSIGNED + end if ; + else + -- Create a new ID + ResultID := GetNextAlertLogID ; + NewAlertLogRec(ResultID, Name, localParentID, DoNotReport) ; + FoundAlertHierVar := TRUE ; + if CreateHierarchy then + FoundReportHierVar := TRUE ; + end if ; + AlertLogPtr(ResultID).PassedGoal := 0 ; + AlertLogPtr(ResultID).PassedGoalSet := FALSE ; + end if ; + return ResultID ; + end function GetAlertLogID ; + + ------------------------------------------------------------ + impure function GetReqID(Name : string ; PassedGoal : integer ; ParentID : AlertLogIDType ; CreateHierarchy : Boolean) return AlertLogIDType is + ------------------------------------------------------------ + variable ResultID : AlertLogIDType ; + variable localParentID : AlertLogIDType ; + begin + HasRequirementsVar := TRUE ; + localParentID := VerifyID(ParentID, ALERTLOG_ID_NOT_ASSIGNED) ; + ResultID := LocalFindAlertLogID(Name, localParentID) ; + if ResultID /= ALERTLOG_ID_NOT_FOUND then -- found it, set localParentID + if AlertLogPtr(ResultID).ParentIDSet = FALSE then + if localParentID /= ALERTLOG_ID_NOT_ASSIGNED then + AdjustID(ResultID, localParentID, TRUE) ; + else + AdjustID(ResultID, REQUIREMENT_ALERTLOG_ID, FALSE) ; + end if ; + end if ; + if AlertLogPtr(ResultID).PassedGoalSet = FALSE then + if PassedGoal >= 0 then + AlertLogPtr(ResultID).PassedGoal := PassedGoal ; + AlertLogPtr(ResultID).PassedGoalSet := TRUE ; + else + AlertLogPtr(ResultID).PassedGoal := DefaultPassedGoalVar ; + AlertLogPtr(ResultID).PassedGoalSet := FALSE ; + end if ; + end if ; + else + -- Create a new ID + ResultID := GetNextAlertLogID ; + if localParentID = ALERTLOG_ID_NOT_ASSIGNED then + NewAlertLogRec(ResultID, Name, REQUIREMENT_ALERTLOG_ID) ; + AlertLogPtr(ResultID).ParentIDSet := FALSE ; + else + NewAlertLogRec(ResultID, Name, localParentID) ; + end if ; + FoundAlertHierVar := TRUE ; + if CreateHierarchy then + FoundReportHierVar := TRUE ; + end if ; + if PassedGoal >= 0 then + AlertLogPtr(ResultID).PassedGoal := PassedGoal ; + AlertLogPtr(ResultID).PassedGoalSet := TRUE ; + else + AlertLogPtr(ResultID).PassedGoal := DefaultPassedGoalVar ; + AlertLogPtr(ResultID).PassedGoalSet := FALSE ; + end if ; + end if ; + return ResultID ; + end function GetReqID ; + + ------------------------------------------------------------ + procedure SetPassedGoal(AlertLogID : AlertLogIDType ; PassedGoal : integer ) is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + HasRequirementsVar := TRUE ; + localAlertLogID := VerifyID(AlertLogID) ; + if PassedGoal >= 0 then + AlertLogPtr(localAlertLogID).PassedGoal := PassedGoal ; + else + AlertLogPtr(localAlertLogID).PassedGoal := DefaultPassedGoalVar ; + end if ; + end procedure SetPassedGoal ; + + ------------------------------------------------------------ + impure function GetAlertLogParentID(AlertLogID : AlertLogIDType) return AlertLogIDType is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + return AlertLogPtr(localAlertLogID).ParentID ; + end function GetAlertLogParentID ; + + ------------------------------------------------------------ + procedure SetAlertLogPrefix(AlertLogID : AlertLogIDType; Name : string ) is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + Deallocate(AlertLogPtr(localAlertLogID).Prefix) ; + if Name'length > 0 then + AlertLogPtr(localAlertLogID).Prefix := new string'(Name) ; + end if ; + end procedure SetAlertLogPrefix ; + + ------------------------------------------------------------ + procedure UnSetAlertLogPrefix(AlertLogID : AlertLogIDType) is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + Deallocate(AlertLogPtr(localAlertLogID).Prefix) ; + end procedure UnSetAlertLogPrefix ; + + ------------------------------------------------------------ + impure function GetAlertLogPrefix(AlertLogID : AlertLogIDType) return string is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + return AlertLogPtr(localAlertLogID).Prefix.all ; + end function GetAlertLogPrefix ; + + ------------------------------------------------------------ + procedure SetAlertLogSuffix(AlertLogID : AlertLogIDType; Name : string ) is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + Deallocate(AlertLogPtr(localAlertLogID).Suffix) ; + if Name'length > 0 then + AlertLogPtr(localAlertLogID).Suffix := new string'(Name) ; + end if ; + end procedure SetAlertLogSuffix ; + + ------------------------------------------------------------ + procedure UnSetAlertLogSuffix(AlertLogID : AlertLogIDType) is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + Deallocate(AlertLogPtr(localAlertLogID).Suffix) ; + end procedure UnSetAlertLogSuffix ; + + ------------------------------------------------------------ + impure function GetAlertLogSuffix(AlertLogID : AlertLogIDType) return string is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + return AlertLogPtr(localAlertLogID).Suffix.all ; + end function GetAlertLogSuffix ; + + ------------------------------------------------------------ + ------------------------------------------------------------ + -- 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 ; + + ------------------------------------------------------------ + -- 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 ; + + ------------------------------------------------------------ + -- PT Local + procedure LocalSetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType ; Count : integer) is + ------------------------------------------------------------ + begin + SetOneStopCount(AlertLogID, Level, Count) ; + if AlertLogID /= ALERTLOG_BASE_ID then + LocalSetAlertStopCount(AlertLogPtr(AlertLogID).ParentID, Level, Count) ; + end if ; + end procedure LocalSetAlertStopCount ; + + ------------------------------------------------------------ + procedure SetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType ; Count : integer) is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + LocalSetAlertStopCount(AlertLogID, Level, Count) ; + end procedure SetAlertStopCount ; + + ------------------------------------------------------------ + impure function GetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType) return integer is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + return AlertLogPtr(localAlertLogID).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 ; + + ------------------------------------------------------------ + -- PT Local + procedure LocalSetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) is + ------------------------------------------------------------ + variable CurID : AlertLogIDType ; + begin + AlertLogPtr(AlertLogID).AlertEnabled(Level) := Enable ; + if DescendHierarchy then + CurID := AlertLogPtr(AlertLogID).ChildID ; + while CurID > ALERTLOG_BASE_ID loop + LocalSetAlertEnable(CurID, Level, Enable, DescendHierarchy) ; + CurID := AlertLogPtr(CurID).SiblingID ; + end loop ; + end if ; + end procedure LocalSetAlertEnable ; + + ------------------------------------------------------------ + procedure SetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + LocalSetAlertEnable(localAlertLogID, Level, Enable, DescendHierarchy) ; + end procedure SetAlertEnable ; + + ------------------------------------------------------------ + impure function GetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType) return boolean is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + return AlertLogPtr(localAlertLogID).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 ; + + ------------------------------------------------------------ + -- PT Local + procedure LocalSetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) is + ------------------------------------------------------------ + variable CurID : AlertLogIDType ; + begin + AlertLogPtr(AlertLogID).LogEnabled(Level) := Enable ; + if DescendHierarchy then + CurID := AlertLogPtr(AlertLogID).ChildID ; + while CurID > ALERTLOG_BASE_ID loop + LocalSetLogEnable(CurID, Level, Enable, DescendHierarchy) ; + CurID := AlertLogPtr(CurID).SiblingID ; + end loop ; + end if ; + end procedure LocalSetLogEnable ; + + ------------------------------------------------------------ + procedure SetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + LocalSetLogEnable(localAlertLogID, Level, Enable, DescendHierarchy) ; + end procedure SetLogEnable ; + + ------------------------------------------------------------ + impure function GetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType) return boolean is + ------------------------------------------------------------ + variable localAlertLogID : AlertLogIDType ; + begin + localAlertLogID := VerifyID(AlertLogID) ; + if Level = ALWAYS then + return TRUE ; + else + return AlertLogPtr(localAlertLogID).LogEnabled(Level) ; + end if ; + end function GetLogEnable ; + + ------------------------------------------------------------ + -- PT Local + procedure PrintLogLevels( + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + Prefix : string ; + IndentAmount : integer + ) is + variable buf : line ; + variable CurID : AlertLogIDType ; + 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) ; + CurID := AlertLogPtr(AlertLogID).ChildID ; + while CurID > ALERTLOG_BASE_ID loop +-- Always print requirements +-- if CurID = REQUIREMENT_ALERTLOG_ID and HasRequirementsVar = FALSE then +-- CurID := AlertLogPtr(CurID).SiblingID ; +-- next ; +-- end if ; + PrintLogLevels( + AlertLogID => CurID, + Prefix => Prefix & " ", + IndentAmount => IndentAmount + 2 + ) ; + CurID := AlertLogPtr(CurID).SiblingID ; + end loop ; + end procedure PrintLogLevels ; + + ------------------------------------------------------------ + procedure ReportLogEnables is + ------------------------------------------------------------ + variable TurnedOnJustify : boolean := FALSE ; + begin + if ReportJustifyAmountVar <= 0 then + TurnedOnJustify := TRUE ; + SetJustify ; + end if ; + PrintLogLevels(ALERTLOG_BASE_ID, "", 0) ; + if TurnedOnJustify then + -- Turn it back off + SetJustify(FALSE) ; + end if ; + end procedure ReportLogEnables ; + + ------------------------------------------------------------ + procedure SetAlertLogOptions ( + ------------------------------------------------------------ + FailOnWarning : OsvvmOptionsType ; + FailOnDisabledErrors : OsvvmOptionsType ; + FailOnRequirementErrors : OsvvmOptionsType ; + ReportHierarchy : OsvvmOptionsType ; + WriteAlertErrorCount : OsvvmOptionsType ; + WriteAlertLevel : OsvvmOptionsType ; + WriteAlertName : OsvvmOptionsType ; + WriteAlertTime : OsvvmOptionsType ; + WriteLogErrorCount : OsvvmOptionsType ; + WriteLogLevel : OsvvmOptionsType ; + WriteLogName : OsvvmOptionsType ; + WriteLogTime : OsvvmOptionsType ; + PrintPassed : OsvvmOptionsType ; + PrintAffirmations : OsvvmOptionsType ; + PrintDisabledAlerts : OsvvmOptionsType ; + PrintRequirements : OsvvmOptionsType ; + PrintIfHaveRequirements : OsvvmOptionsType ; + DefaultPassedGoal : integer ; + AlertPrefix : string ; + LogPrefix : string ; + ReportPrefix : string ; + DoneName : string ; + PassName : string ; + FailName : string + ) 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 FailOnRequirementErrors /= OPT_INIT_PARM_DETECT then + FailOnRequirementErrorsVar := IsEnabled(FailOnRequirementErrors) ; + end if ; + if ReportHierarchy /= OPT_INIT_PARM_DETECT then + ReportHierarchyVar := IsEnabled(ReportHierarchy) ; + end if ; + if WriteAlertErrorCount /= OPT_INIT_PARM_DETECT then + WriteAlertErrorCountVar := IsEnabled(WriteAlertErrorCount) ; + 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 WriteLogErrorCount /= OPT_INIT_PARM_DETECT then + WriteLogErrorCountVar := IsEnabled(WriteLogErrorCount) ; + 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 PrintPassed /= OPT_INIT_PARM_DETECT then + PrintPassedVar := IsEnabled(PrintPassed) ; + end if ; + if PrintAffirmations /= OPT_INIT_PARM_DETECT then + PrintAffirmationsVar := IsEnabled(PrintAffirmations) ; + end if ; + if PrintDisabledAlerts /= OPT_INIT_PARM_DETECT then + PrintDisabledAlertsVar := IsEnabled(PrintDisabledAlerts) ; + end if ; + if PrintRequirements /= OPT_INIT_PARM_DETECT then + PrintRequirementsVar := IsEnabled(PrintRequirements) ; + end if ; + if PrintIfHaveRequirements /= OPT_INIT_PARM_DETECT then + PrintIfHaveRequirementsVar := IsEnabled(PrintIfHaveRequirements) ; + end if ; + if DefaultPassedGoal > 0 then + DefaultPassedGoalVar := DefaultPassedGoal ; + 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, "FailOnRequirementErrorsVar: " & to_string(FailOnRequirementErrorsVar ) & 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, "WriteAlertErrorCountVar: " & to_string(WriteAlertErrorCountVar ) & LF ) ; + swrite(buf, "WriteAlertLevelVar: " & to_string(WriteAlertLevelVar ) & LF ) ; + swrite(buf, "WriteAlertNameVar: " & to_string(WriteAlertNameVar ) & LF ) ; + swrite(buf, "WriteAlertTimeVar: " & to_string(WriteAlertTimeVar ) & LF ) ; + swrite(buf, "WriteLogErrorCountVar: " & to_string(WriteLogErrorCountVar ) & LF ) ; + swrite(buf, "WriteLogLevelVar: " & to_string(WriteLogLevelVar ) & LF ) ; + swrite(buf, "WriteLogNameVar: " & to_string(WriteLogNameVar ) & LF ) ; + swrite(buf, "WriteLogTimeVar: " & to_string(WriteLogTimeVar ) & LF ) ; + swrite(buf, "PrintPassedVar: " & to_string(PrintPassedVar ) & LF ) ; + swrite(buf, "PrintAffirmationsVar: " & to_string(PrintAffirmationsVar ) & LF ) ; + swrite(buf, "PrintDisabledAlertsVar: " & to_string(PrintDisabledAlertsVar ) & LF ) ; + swrite(buf, "PrintRequirementsVar: " & to_string(PrintRequirementsVar ) & LF ) ; + swrite(buf, "PrintIfHaveRequirementsVar: " & to_string(PrintIfHaveRequirementsVar ) & 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 OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(FailOnWarningVar) ; + end function GetAlertLogFailOnWarning ; + + ------------------------------------------------------------ + impure function GetAlertLogFailOnDisabledErrors return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(FailOnDisabledErrorsVar) ; + end function GetAlertLogFailOnDisabledErrors ; + + ------------------------------------------------------------ + impure function GetAlertLogFailOnRequirementErrors return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(FailOnRequirementErrorsVar) ; + end function GetAlertLogFailOnRequirementErrors ; + + ------------------------------------------------------------ + impure function GetAlertLogReportHierarchy return OsvvmOptionsType 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 GetAlertLogWriteAlertErrorCount return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(WriteAlertErrorCountVar) ; + end function GetAlertLogWriteAlertErrorCount ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteAlertLevel return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(WriteAlertLevelVar) ; + end function GetAlertLogWriteAlertLevel ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteAlertName return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(WriteAlertNameVar) ; + end function GetAlertLogWriteAlertName ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteAlertTime return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(WriteAlertTimeVar) ; + end function GetAlertLogWriteAlertTime ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteLogErrorCount return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(WriteLogErrorCountVar) ; + end function GetAlertLogWriteLogErrorCount ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteLogLevel return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(WriteLogLevelVar) ; + end function GetAlertLogWriteLogLevel ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteLogName return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(WriteLogNameVar) ; + end function GetAlertLogWriteLogName ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteLogTime return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(WriteLogTimeVar) ; + end function GetAlertLogWriteLogTime ; + + ------------------------------------------------------------ + impure function GetAlertLogPrintPassed return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(PrintPassedVar) ; + end function GetAlertLogPrintPassed ; + + ------------------------------------------------------------ + impure function GetAlertLogPrintAffirmations return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(PrintAffirmationsVar) ; + end function GetAlertLogPrintAffirmations ; + + ------------------------------------------------------------ + impure function GetAlertLogPrintDisabledAlerts return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(PrintDisabledAlertsVar) ; + end function GetAlertLogPrintDisabledAlerts ; + + ------------------------------------------------------------ + impure function GetAlertLogPrintRequirements return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(PrintRequirementsVar) ; + end function GetAlertLogPrintRequirements ; + + ------------------------------------------------------------ + impure function GetAlertLogPrintIfHaveRequirements return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return to_OsvvmOptionsType(PrintIfHaveRequirementsVar) ; + end function GetAlertLogPrintIfHaveRequirements ; + + ------------------------------------------------------------ + impure function GetAlertLogDefaultPassedGoal return integer is + ------------------------------------------------------------ + begin + return DefaultPassedGoalVar ; + end function GetAlertLogDefaultPassedGoal ; + + ------------------------------------------------------------ + 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 ; + +-- synthesis translate_on + +--- /////////////////////////////////////////////////////////////////////////// +--- /////////////////////////////////////////////////////////////////////////// +--- /////////////////////////////////////////////////////////////////////////// + + ------------------------------------------------------------ + procedure Alert( + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + Message : string ; + Level : AlertType := ERROR + ) is + begin + -- synthesis translate_off + AlertLogStruct.Alert(AlertLogID, Message, Level) ; + -- synthesis translate_on + end procedure alert ; + + ------------------------------------------------------------ + procedure Alert( Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message, Level) ; + -- synthesis translate_on + end procedure alert ; + + ------------------------------------------------------------ + procedure IncAlertCount( + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + Level : AlertType := ERROR + ) is + begin + -- synthesis translate_off + AlertLogStruct.IncAlertCount(AlertLogID, Level) ; + -- synthesis translate_on + end procedure IncAlertCount ; + + ------------------------------------------------------------ + procedure IncAlertCount( Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.IncAlertCount(ALERT_DEFAULT_ID, Level) ; + -- synthesis translate_on + end procedure IncAlertCount ; + + + ------------------------------------------------------------ + procedure AlertIf( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if condition then + AlertLogStruct.Alert(AlertLogID , Message, Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIf ; + + ------------------------------------------------------------ + procedure AlertIf( condition : boolean ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if condition then + AlertLogStruct.Alert(ALERT_DEFAULT_ID , Message, Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIf ; + + ------------------------------------------------------------ + -- useful in a loop: exit when AlertIf( not ReadValid, failure, "Read Failed") ; + impure function AlertIf( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Level : AlertType := ERROR ) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if condition then + AlertLogStruct.Alert(AlertLogID , Message, Level) ; + end if ; + -- synthesis translate_on + return condition ; + end function AlertIf ; + + ------------------------------------------------------------ + impure function AlertIf( condition : boolean ; Message : string ; Level : AlertType := ERROR ) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if condition then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message, Level) ; + end if ; + -- synthesis translate_on + return condition ; + end function AlertIf ; + + ------------------------------------------------------------ + procedure AlertIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if not condition then + AlertLogStruct.Alert(AlertLogID, Message, Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNot ; + + ------------------------------------------------------------ + procedure AlertIfNot( condition : boolean ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if not condition then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message, Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNot ; + + ------------------------------------------------------------ + -- useful in a loop: exit when AlertIfNot( not ReadValid, failure, "Read Failed") ; + impure function AlertIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Level : AlertType := ERROR ) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if not condition then + AlertLogStruct.Alert(AlertLogID, Message, Level) ; + end if ; + -- synthesis translate_on + return not condition ; + end function AlertIfNot ; + + ------------------------------------------------------------ + impure function AlertIfNot( condition : boolean ; Message : string ; Level : AlertType := ERROR ) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if not condition then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message, Level) ; + end if ; + -- synthesis translate_on + return not condition ; + end function AlertIfNot ; + + + ------------------------------------------------------------ + -- AlertIfEqual with AlertLogID + ------------------------------------------------------------ + procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : std_logic ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if MetaMatch(L, R) then + AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : std_logic_vector ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if MetaMatch(L, R) then + AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : unsigned ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if MetaMatch(L, R) then + AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : signed ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if MetaMatch(L, R) then + AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : integer ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L = R then + AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : real ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L = R then + AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L, 4) & " R = " & to_string(R, 4), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : character ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L = R then + AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & L & " R = " & R, Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : string ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L = R then + AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & L & " R = " & R, Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( AlertLogID : AlertLogIDType ; L, R : time ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L = R then + AlertLogStruct.Alert(AlertLogID, Message & " L = R, L = " & to_string(L, GetOsvvmDefaultTimeUnits) + & " R = " & to_string(R, GetOsvvmDefaultTimeUnits), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + + ------------------------------------------------------------ + -- AlertIfEqual without AlertLogID + ------------------------------------------------------------ + procedure AlertIfEqual( L, R : std_logic ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if MetaMatch(L, R) then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( L, R : std_logic_vector ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if MetaMatch(L, R) then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( L, R : unsigned ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if MetaMatch(L, R) then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( L, R : signed ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if MetaMatch(L, R) then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( L, R : integer ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L = R then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( L, R : real ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + 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 ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( L, R : character ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L = R then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & L & " R = " & R, Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( L, R : string ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L = R then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & L & " R = " & R, Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + ------------------------------------------------------------ + procedure AlertIfEqual( L, R : time ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L = R then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L = R, L = " & to_string(L, GetOsvvmDefaultTimeUnits) + & " R = " & to_string(R, GetOsvvmDefaultTimeUnits), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfEqual ; + + + ------------------------------------------------------------ + -- AlertIfNotEqual with AlertLogID + ------------------------------------------------------------ + procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : std_logic ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if not MetaMatch(L, R) then + AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : std_logic_vector ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if not MetaMatch(L, R) then + AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : unsigned ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if not MetaMatch(L, R) then + AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : signed ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if not MetaMatch(L, R) then + AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : integer ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L /= R then + AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : real ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L /= R then + AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L, 4) & " R = " & to_string(R, 4), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : character ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L /= R then + AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & L & " R = " & R, Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : string ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L /= R then + AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & L & " R = " & R, Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( AlertLogID : AlertLogIDType ; L, R : time ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L /= R then + AlertLogStruct.Alert(AlertLogID, Message & " L /= R, L = " & to_string(L, GetOsvvmDefaultTimeUnits) & + " R = " & to_string(R, GetOsvvmDefaultTimeUnits), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + + ------------------------------------------------------------ + -- AlertIfNotEqual without AlertLogID + ------------------------------------------------------------ + procedure AlertIfNotEqual( L, R : std_logic ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if not MetaMatch(L, R) then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( L, R : std_logic_vector ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if not MetaMatch(L, R) then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( L, R : unsigned ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if not MetaMatch(L, R) then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( L, R : signed ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if not MetaMatch(L, R) then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( L, R : integer ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L /= R then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & to_string(L) & " R = " & to_string(R), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( L, R : real ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + 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 ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( L, R : character ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L /= R then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & L & " R = " & R, Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( L, R : string ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L /= R then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & L & " R = " & R, Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + ------------------------------------------------------------ + procedure AlertIfNotEqual( L, R : time ; Message : string ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + if L /= R then + AlertLogStruct.Alert(ALERT_DEFAULT_ID, Message & " L /= R, L = " & to_string(L, GetOsvvmDefaultTimeUnits) & + " R = " & to_string(R, GetOsvvmDefaultTimeUnits), Level) ; + end if ; + -- synthesis translate_on + end procedure AlertIfNotEqual ; + + + ------------------------------------------------------------ + -- Local + procedure LocalAlertIfDiff (AlertLogID : AlertLogIDType ; file File1, File2 : text; Message : string ; Level : AlertType ; Valid : out boolean ) is + -- Simple diff. + ------------------------------------------------------------ + variable Buf1, Buf2 : line ; + variable File1Done, File2Done : boolean ; + variable LineCount : integer := 0 ; + begin + -- synthesis translate_off + 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; + if File1Done and File2Done then + Valid := TRUE ; + else + Valid := FALSE ; + end if ; + -- synthesis translate_on + end procedure LocalAlertIfDiff ; + + ------------------------------------------------------------ + -- Local + procedure LocalAlertIfDiff (AlertLogID : AlertLogIDType ; Name1, Name2 : string; Message : string ; Level : AlertType ; Valid : out boolean ) is + -- Open files and call AlertIfDiff[text, ...] + ------------------------------------------------------------ + file FileID1, FileID2 : text ; + variable status1, status2 : file_open_status ; + begin + -- synthesis translate_off + Valid := FALSE ; + file_open(status1, FileID1, Name1, READ_MODE) ; + file_open(status2, FileID2, Name2, READ_MODE) ; + if status1 = OPEN_OK and status2 = OPEN_OK then + LocalAlertIfDiff (AlertLogID, FileID1, FileID2, Message & " " & Name1 & " /= " & Name2 & ", ", Level, Valid) ; + 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; + -- synthesis translate_on + end procedure LocalAlertIfDiff ; + + ------------------------------------------------------------ + procedure AlertIfDiff (AlertLogID : AlertLogIDType ; Name1, Name2 : string; Message : string := "" ; Level : AlertType := ERROR ) is + -- Open files and call AlertIfDiff[text, ...] + ------------------------------------------------------------ + variable Valid : boolean ; + begin + -- synthesis translate_off + LocalAlertIfDiff (AlertLogID, Name1, Name2, Message, Level, Valid) ; + -- synthesis translate_on + end procedure AlertIfDiff ; + + ------------------------------------------------------------ + procedure AlertIfDiff (Name1, Name2 : string; Message : string := "" ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + variable Valid : boolean ; + begin + -- synthesis translate_off + LocalAlertIfDiff (ALERT_DEFAULT_ID, Name1, Name2, Message, Level, Valid) ; + -- synthesis translate_on + end procedure AlertIfDiff ; + + ------------------------------------------------------------ + procedure AlertIfDiff (AlertLogID : AlertLogIDType ; file File1, File2 : text; Message : string := "" ; Level : AlertType := ERROR ) is + -- Simple diff. + ------------------------------------------------------------ + variable Valid : boolean ; + begin + -- synthesis translate_off + LocalAlertIfDiff (AlertLogID, File1, File2, Message, Level, Valid ) ; + -- synthesis translate_on + end procedure AlertIfDiff ; + + ------------------------------------------------------------ + procedure AlertIfDiff (file File1, File2 : text; Message : string := "" ; Level : AlertType := ERROR ) is + ------------------------------------------------------------ + variable Valid : boolean ; + begin + -- synthesis translate_off + LocalAlertIfDiff (ALERT_DEFAULT_ID, File1, File2, Message, Level, Valid ) ; + -- synthesis translate_on + end procedure AlertIfDiff ; + + ------------------------------------------------------------ + procedure AffirmIf( + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + condition : boolean ; + ReceivedMessage : string ; + ExpectedMessage : string ; + Enable : boolean := FALSE -- override internal enable + ) is + begin + -- synthesis translate_off + if condition then + -- PASSED. Count affirmations and PASSED internal to LOG to catch all of them + AlertLogStruct.Log(AlertLogID, ReceivedMessage, PASSED, Enable) ; + else + AlertLogStruct.IncAffirmCount(AlertLogID) ; -- count the affirmation + AlertLogStruct.Alert(AlertLogID, ReceivedMessage & ' ' & ExpectedMessage, ERROR) ; + end if ; + -- synthesis translate_on + end procedure AffirmIf ; + + ------------------------------------------------------------ + procedure AffirmIf( condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, condition, ReceivedMessage, ExpectedMessage, Enable) ; + -- synthesis translate_on + end procedure AffirmIf ; + + ------------------------------------------------------------ + impure function AffirmIf( AlertLogID : AlertLogIDType ; condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, condition, ReceivedMessage, ExpectedMessage, Enable) ; + -- synthesis translate_on + return condition ; + end function AffirmIf ; + + ------------------------------------------------------------ + impure function AffirmIf( condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, condition, ReceivedMessage, ExpectedMessage, Enable) ; + -- synthesis translate_on + return condition ; + end function AffirmIf ; + + + ------------------------------------------------------------ + procedure AffirmIf( + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + condition : boolean ; + Message : string ; + Enable : boolean := FALSE -- override internal enable + ) is + begin + -- synthesis translate_off + if condition then + -- PASSED. Count affirmations and PASSED internal to LOG to catch all of them + AlertLogStruct.Log(AlertLogID, Message, PASSED, Enable) ; + else + AlertLogStruct.IncAffirmCount(AlertLogID) ; -- count the affirmation + AlertLogStruct.Alert(AlertLogID, Message, ERROR) ; + end if ; + -- synthesis translate_on + end procedure AffirmIf ; + + ------------------------------------------------------------ + procedure AffirmIf(condition : boolean ; Message : string ; Enable : boolean := FALSE) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, condition, Message, Enable) ; + -- synthesis translate_on + end procedure AffirmIf; + + ------------------------------------------------------------ + -- useful in a loop: exit when AffirmIf( ID, not ReadValid, "Read Failed") ; + impure function AffirmIf( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Enable : boolean := FALSE ) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, condition, Message, Enable) ; + -- synthesis translate_on + return condition ; + end function AffirmIf ; + + ------------------------------------------------------------ + impure function AffirmIf( condition : boolean ; Message : string ; Enable : boolean := FALSE ) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, condition, Message, Enable) ; + -- synthesis translate_on + return condition ; + end function AffirmIf ; + + ------------------------------------------------------------ + ------------------------------------------------------------ + procedure AffirmIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, not condition, ReceivedMessage, ExpectedMessage, Enable) ; + -- synthesis translate_on + end procedure AffirmIfNot ; + + ------------------------------------------------------------ + procedure AffirmIfNot( condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, not condition, ReceivedMessage, ExpectedMessage, Enable) ; + -- synthesis translate_on + end procedure AffirmIfNot ; + + ------------------------------------------------------------ + -- useful in a loop: exit when AffirmIfNot( not ReadValid, failure, "Read Failed") ; + impure function AffirmIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, not condition, ReceivedMessage, ExpectedMessage, Enable) ; + -- synthesis translate_on + return not condition ; + end function AffirmIfNot ; + + ------------------------------------------------------------ + impure function AffirmIfNot( condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, not condition, ReceivedMessage, ExpectedMessage, Enable) ; + -- synthesis translate_on + return not condition ; + end function AffirmIfNot ; + + ------------------------------------------------------------ + procedure AffirmIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, not condition, Message, Enable) ; + -- synthesis translate_on + end procedure AffirmIfNot ; + + ------------------------------------------------------------ + procedure AffirmIfNot( condition : boolean ; Message : string ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, not condition, Message, Enable) ; + -- synthesis translate_on + end procedure AffirmIfNot ; + + ------------------------------------------------------------ + -- useful in a loop: exit when AffirmIfNot( not ReadValid, failure, "Read Failed") ; + impure function AffirmIfNot( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; Enable : boolean := FALSE ) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, not condition, Message, Enable) ; + -- synthesis translate_on + return not condition ; + end function AffirmIfNot ; + + ------------------------------------------------------------ + impure function AffirmIfNot( condition : boolean ; Message : string ; Enable : boolean := FALSE ) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, not condition, Message, Enable) ; + -- synthesis translate_on + return not condition ; + end function AffirmIfNot ; + + + ------------------------------------------------------------ + ------------------------------------------------------------ + procedure AffirmPassed( AlertLogID : AlertLogIDType ; Message : string ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, TRUE, Message, Enable) ; + -- synthesis translate_on + end procedure AffirmPassed ; + + ------------------------------------------------------------ + procedure AffirmPassed( Message : string ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, TRUE, Message, Enable) ; + -- synthesis translate_on + end procedure AffirmPassed ; + + ------------------------------------------------------------ + procedure AffirmError( AlertLogID : AlertLogIDType ; Message : string ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, FALSE, Message, FALSE) ; + -- synthesis translate_on + end procedure AffirmError ; + + ------------------------------------------------------------ + procedure AffirmError( Message : string ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, FALSE, Message, FALSE) ; + -- synthesis translate_on + end procedure AffirmError ; + + -- With AlertLogID + ------------------------------------------------------------ + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : boolean ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, Received = Expected, + Message & " Received : " & to_string(Received), + "?= Expected : " & to_string(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : std_logic ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, MetaMatch(Received, Expected), + Message & " Received : " & to_string(Received), + "?= Expected : " & to_string(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : std_logic_vector ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, MetaMatch(Received, Expected), + Message & " Received : " & to_hstring(Received), + "?= Expected : " & to_hstring(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : unsigned ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, MetaMatch(Received, Expected), + Message & " Received : " & to_hstring(Received), + "?= Expected : " & to_hstring(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : signed ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, MetaMatch(Received, Expected), + Message & " Received : " & to_hstring(Received), + "?= Expected : " & to_hstring(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : integer ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, Received = Expected, + Message & " Received : " & to_string(Received), + "= Expected : " & to_string(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : real ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, Received = Expected, + Message & " Received : " & to_string(Received, 4), + "= Expected : " & to_string(Expected, 4), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : character ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, Received = Expected, + Message & " Received : " & to_string(Received), + "= Expected : " & to_string(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : string ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, Received = Expected, + Message & " Received : " & Received, + "= Expected : " & Expected, + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( AlertLogID : AlertLogIDType ; Received, Expected : time ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(AlertLogID, Received = Expected, + Message & " Received : " & to_string(Received, GetOsvvmDefaultTimeUnits), + "= Expected : " & to_string(Expected, GetOsvvmDefaultTimeUnits), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + -- Without AlertLogID + ------------------------------------------------------------ + procedure AffirmIfEqual( Received, Expected : boolean ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, Received = Expected, + Message & " Received : " & to_string(Received), + "?= Expected : " & to_string(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( Received, Expected : std_logic ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, MetaMatch(Received, Expected), + Message & " Received : " & to_string(Received), + "?= Expected : " & to_string(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( Received, Expected : std_logic_vector ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, MetaMatch(Received, Expected), + Message & " Received : " & to_hstring(Received), + "?= Expected : " & to_hstring(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( Received, Expected : unsigned ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, MetaMatch(Received, Expected), + Message & " Received : " & to_hstring(Received), + "?= Expected : " & to_hstring(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( Received, Expected : signed ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, MetaMatch(Received, Expected), + Message & " Received : " & to_hstring(Received), + "?= Expected : " & to_hstring(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( Received, Expected : integer ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, Received = Expected, + Message & " Received : " & to_string(Received), + "= Expected : " & to_string(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( Received, Expected : real ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, Received = Expected, + Message & " Received : " & to_string(Received, 4), + "= Expected : " & to_string(Expected, 4), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( Received, Expected : character ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, Received = Expected, + Message & " Received : " & to_string(Received), + "= Expected : " & to_string(Expected), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( Received, Expected : string ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, Received = Expected, + Message & " Received : " & Received, + "= Expected : " & Expected, + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfEqual( Received, Expected : time ; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, Received = Expected, + Message & " Received : " & to_string(Received, GetOsvvmDefaultTimeUnits), + "= Expected : " & to_string(Expected, GetOsvvmDefaultTimeUnits), + Enable) ; + -- synthesis translate_on + end procedure AffirmIfEqual ; + + ------------------------------------------------------------ + procedure AffirmIfNotDiff (AlertLogID : AlertLogIDType ; Name1, Name2 : string; Message : string := "" ; Enable : boolean := FALSE ) is + -- Open files and call AffirmIfNotDiff[text, ...] + ------------------------------------------------------------ + variable Valid : boolean ; + begin + -- synthesis translate_off + LocalAlertIfDiff (AlertLogID, Name1, Name2, Message, ERROR, Valid) ; + if Valid then + AlertLogStruct.Log(AlertLogID, Message & " " & Name1 & " = " & Name2, PASSED, Enable) ; + else + AlertLogStruct.IncAffirmCount(AlertLogID) ; -- count the affirmation + -- Alert already signaled by LocalAlertIfDiff + end if ; + -- synthesis translate_on + end procedure AffirmIfNotDiff ; + + ------------------------------------------------------------ + procedure AffirmIfNotDiff (Name1, Name2 : string; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIfNotDiff(ALERT_DEFAULT_ID, Name1, Name2, Message, Enable) ; + -- synthesis translate_on + end procedure AffirmIfNotDiff ; + + ------------------------------------------------------------ + procedure AffirmIfNotDiff (AlertLogID : AlertLogIDType ; file File1, File2 : text; Message : string := "" ; Enable : boolean := FALSE ) is + -- Simple diff. + ------------------------------------------------------------ + variable Valid : boolean ; + begin + -- synthesis translate_off + LocalAlertIfDiff (AlertLogID, File1, File2, Message, ERROR, Valid ) ; + if Valid then + AlertLogStruct.Log(AlertLogID, Message, PASSED, Enable) ; + else + AlertLogStruct.IncAffirmCount(AlertLogID) ; -- count the affirmation + -- Alert already signaled by LocalAlertIfDiff + end if ; + -- synthesis translate_on + end procedure AffirmIfNotDiff ; + + ------------------------------------------------------------ + procedure AffirmIfNotDiff (file File1, File2 : text; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIfNotDiff(ALERT_DEFAULT_ID, File1, File2, Message, Enable) ; + -- synthesis translate_on + end procedure AffirmIfNotDiff ; + + ------------------------------------------------------------ +-- DEPRECATED - naming polarity is incorrect. Should be AffirmIfNotDiff + procedure AffirmIfDiff (AlertLogID : AlertLogIDType ; Name1, Name2 : string; Message : string := "" ; Enable : boolean := FALSE ) is + -- Open files and call AffirmIfDiff[text, ...] + ------------------------------------------------------------ + variable Valid : boolean ; + begin + -- synthesis translate_off + LocalAlertIfDiff (AlertLogID, Name1, Name2, Message, ERROR, Valid) ; + if Valid then + AlertLogStruct.Log(AlertLogID, Message & " " & Name1 & " = " & Name2, PASSED, Enable) ; + else + AlertLogStruct.IncAffirmCount(AlertLogID) ; -- count the affirmation + -- Alert already signaled by LocalAlertIfDiff + end if ; + -- synthesis translate_on + end procedure AffirmIfDiff ; + + ------------------------------------------------------------ +-- DEPRECATED - naming polarity is incorrect. Should be AffirmIfNotDiff + procedure AffirmIfDiff (Name1, Name2 : string; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIfDiff(ALERT_DEFAULT_ID, Name1, Name2, Message, Enable) ; + -- synthesis translate_on + end procedure AffirmIfDiff ; + + ------------------------------------------------------------ +-- DEPRECATED - naming polarity is incorrect. Should be AffirmIfNotDiff + procedure AffirmIfDiff (AlertLogID : AlertLogIDType ; file File1, File2 : text; Message : string := "" ; Enable : boolean := FALSE ) is + -- Simple diff. + ------------------------------------------------------------ + variable Valid : boolean ; + begin + -- synthesis translate_off + LocalAlertIfDiff (AlertLogID, File1, File2, Message, ERROR, Valid ) ; + if Valid then + AlertLogStruct.Log(AlertLogID, Message, PASSED, Enable) ; + else + AlertLogStruct.IncAffirmCount(AlertLogID) ; -- count the affirmation + -- Alert already signaled by LocalAlertIfDiff + end if ; + -- synthesis translate_on + end procedure AffirmIfDiff ; + + ------------------------------------------------------------ +-- DEPRECATED - naming polarity is incorrect. Should be AffirmIfNotDiff + procedure AffirmIfDiff (file File1, File2 : text; Message : string := "" ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AffirmIfDiff(ALERT_DEFAULT_ID, File1, File2, Message, Enable) ; + -- synthesis translate_on + end procedure AffirmIfDiff ; + + + -- Support for Specification / Requirements Tracking + ------------------------------------------------------------ + procedure AffirmIf( RequirementsIDName : string ; condition : boolean ; ReceivedMessage, ExpectedMessage : string ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off +--?? Set Goal to 1? Should the ID already exist? + AffirmIf(GetReqID(RequirementsIDName), condition, ReceivedMessage, ExpectedMessage, Enable) ; + -- synthesis translate_on + end procedure AffirmIf ; + + ------------------------------------------------------------ + procedure AffirmIf( RequirementsIDName : string ; condition : boolean ; Message : string ; Enable : boolean := FALSE ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off +--?? Set Goal to 1? Should the ID already exist? + AffirmIf(GetReqID(RequirementsIDName), condition, Message, Enable) ; + -- synthesis translate_on + end procedure AffirmIf ; + + ------------------------------------------------------------ + procedure SetAlertLogJustify (Enable : boolean := TRUE) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetJustify(Enable) ; + -- synthesis translate_on + end procedure SetAlertLogJustify ; + + ------------------------------------------------------------ + procedure ReportAlerts ( Name : String ; AlertCount : AlertCountType ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.ReportAlerts(Name, AlertCount) ; + -- synthesis translate_on + end procedure ReportAlerts ; + + ------------------------------------------------------------ + procedure ReportRequirements is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.ReportRequirements ; + -- synthesis translate_on + end procedure ReportRequirements ; + + ------------------------------------------------------------ + procedure ReportAlerts ( + ------------------------------------------------------------ + Name : string := OSVVM_STRING_INIT_PARM_DETECT ; + AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; + ExternalErrors : AlertCountType := (others => 0) ; + ReportAll : Boolean := FALSE + ) is + begin + -- synthesis translate_off + AlertLogStruct.ReportAlerts(Name, AlertLogID, ExternalErrors, ReportAll, TRUE) ; + -- synthesis translate_on + end procedure ReportAlerts ; + + ------------------------------------------------------------ + procedure ReportNonZeroAlerts ( + ------------------------------------------------------------ + Name : string := OSVVM_STRING_INIT_PARM_DETECT ; + AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; + ExternalErrors : AlertCountType := (others => 0) + ) is + begin + -- synthesis translate_off + AlertLogStruct.ReportAlerts(Name, AlertLogID, ExternalErrors, FALSE, FALSE) ; + -- synthesis translate_on + end procedure ReportNonZeroAlerts ; + + ------------------------------------------------------------ + procedure CreateYamlReport (ExternalErrors : AlertCountType := (0,0,0)) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + -- WriteTestSummary(FileName => "OsvvmRun.yml", OpenKind => APPEND_MODE, Prefix => " Results: {", Suffix => "}", ExternalErrors => ExternalErrors) ; + WriteTestSummary(FileName => "OsvvmRun.yml", OpenKind => APPEND_MODE, Prefix => " ", Suffix => "", ExternalErrors => ExternalErrors, WriteFieldName => TRUE) ; + -- synthesis translate_on + end procedure CreateYamlReport ; + + ------------------------------------------------------------ + procedure EndOfTestSummary ( + ------------------------------------------------------------ + ReportAll : boolean := FALSE ; + ExternalErrors : AlertCountType := (0,0,0) + ) is + begin + -- synthesis translate_off + ReportAlerts(ExternalErrors => ExternalErrors, ReportAll => ReportAll) ; + CreateYamlReport(ExternalErrors => ExternalErrors) ; + std.env.stop(SumAlertCount(GetAlertCount + ExternalErrors)) ; + -- synthesis translate_on + end procedure EndOfTestSummary ; + + ------------------------------------------------------------ + procedure WriteTestSummary ( + ------------------------------------------------------------ + FileName : string ; + OpenKind : File_Open_Kind := APPEND_MODE ; + Prefix : string := "" ; + Suffix : string := "" ; + ExternalErrors : AlertCountType := (0,0,0) ; + WriteFieldName : boolean := FALSE + ) is + begin + -- synthesis translate_off + AlertLogStruct.WriteTestSummary(FileName, OpenKind, Prefix, Suffix, ExternalErrors, WriteFieldName) ; + -- synthesis translate_on + end procedure WriteTestSummary ; + + ------------------------------------------------------------ + procedure WriteTestSummaries ( + ------------------------------------------------------------ + FileName : string ; + OpenKind : File_Open_Kind := WRITE_MODE + ) is + begin + -- synthesis translate_off + AlertLogStruct.WriteTestSummaries(FileName, OpenKind) ; + -- synthesis translate_on + end procedure WriteTestSummaries ; + + ------------------------------------------------------------ + procedure ReportTestSummaries is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.ReportTestSummaries ; + -- synthesis translate_on + end procedure ReportTestSummaries ; + + ------------------------------------------------------------ + procedure WriteAlerts ( + ------------------------------------------------------------ + FileName : string ; + AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID ; + OpenKind : File_Open_Kind := WRITE_MODE + ) is + begin + -- synthesis translate_off + AlertLogStruct.WriteAlerts(FileName, AlertLogID, OpenKind) ; + -- synthesis translate_on + end procedure WriteAlerts ; + + ------------------------------------------------------------ + procedure WriteRequirements ( + ------------------------------------------------------------ + FileName : string ; + AlertLogID : AlertLogIDType := REQUIREMENT_ALERTLOG_ID ; + OpenKind : File_Open_Kind := WRITE_MODE + ) is + begin + -- synthesis translate_off + AlertLogStruct.WriteRequirements(FileName, AlertLogID, OpenKind) ; + -- synthesis translate_on + end procedure WriteRequirements ; + + ------------------------------------------------------------ + procedure ReadSpecification (FileName : string ; PassedGoal : integer := -1 ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.ReadSpecification(FileName, PassedGoal) ; + -- synthesis translate_on + end procedure ReadSpecification ; + + ------------------------------------------------------------ + procedure ReadRequirements ( + ------------------------------------------------------------ + FileName : string ; + ThresholdPassed : boolean := FALSE + ) is + begin + -- synthesis translate_off + AlertLogStruct.ReadRequirements(FileName, ThresholdPassed, TestSummary => FALSE) ; + -- synthesis translate_on + end procedure ReadRequirements ; + + ------------------------------------------------------------ + procedure ReadTestSummaries (FileName : string) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.ReadRequirements(FileName, ThresholdPassed => FALSE, TestSummary => TRUE) ; + -- synthesis translate_on + end procedure ReadTestSummaries ; + +-- ------------------------------------------------------------ +-- procedure ReportTestSummaries (FileName : string) is +-- ------------------------------------------------------------ +-- begin +-- -- synthesis translate_off +-- AlertLogStruct.ReadRequirements(FileName, ThresholdPassed => FALSE, TestSummary => TRUE) ; +-- -- synthesis translate_on +-- end procedure ReportTestSummaries ; + + ------------------------------------------------------------ + procedure ClearAlerts is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.ClearAlerts ; + -- synthesis translate_on + end procedure ClearAlerts ; + + ------------------------------------------------------------ + procedure ClearAlertStopCounts is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.ClearAlertStopCounts ; + -- synthesis translate_on + end procedure ClearAlertStopCounts ; + + ------------------------------------------------------------ + procedure ClearAlertCounts is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.ClearAlerts ; + AlertLogStruct.ClearAlertStopCounts ; + -- synthesis translate_on + end procedure ClearAlertCounts ; + + ------------------------------------------------------------ + function "ABS" (L : AlertCountType) return AlertCountType is + ------------------------------------------------------------ + variable Result : AlertCountType ; + begin + -- synthesis translate_off + Result(FAILURE) := ABS( L(FAILURE) ) ; + Result(ERROR) := ABS( L(ERROR) ) ; + Result(WARNING) := ABS( L(WARNING) ); + -- synthesis translate_on + return Result ; + end function "ABS" ; + + ------------------------------------------------------------ + function "+" (L, R : AlertCountType) return AlertCountType is + ------------------------------------------------------------ + variable Result : AlertCountType ; + begin + -- synthesis translate_off + Result(FAILURE) := L(FAILURE) + R(FAILURE) ; + Result(ERROR) := L(ERROR) + R(ERROR) ; + Result(WARNING) := L(WARNING) + R(WARNING) ; + -- synthesis translate_on + return Result ; + end function "+" ; + + ------------------------------------------------------------ + function "-" (L, R : AlertCountType) return AlertCountType is + ------------------------------------------------------------ + variable Result : AlertCountType ; + begin + -- synthesis translate_off + Result(FAILURE) := L(FAILURE) - R(FAILURE) ; + Result(ERROR) := L(ERROR) - R(ERROR) ; + Result(WARNING) := L(WARNING) - R(WARNING) ; + -- synthesis translate_on + return Result ; + end function "-" ; + + ------------------------------------------------------------ + function "-" (R : AlertCountType) return AlertCountType is + ------------------------------------------------------------ + variable Result : AlertCountType ; + begin + -- synthesis translate_off + Result(FAILURE) := - R(FAILURE) ; + Result(ERROR) := - R(ERROR) ; + Result(WARNING) := - R(WARNING) ; + -- synthesis translate_on + return Result ; + end function "-" ; + + ------------------------------------------------------------ + impure function SumAlertCount(AlertCount: AlertCountType) return integer is + ------------------------------------------------------------ + variable result : integer ; + begin + -- synthesis translate_off + -- Using ABS ensures correct expected error handling. + result := abs(AlertCount(FAILURE)) + abs(AlertCount(ERROR)) + abs(AlertCount(WARNING)) ; + -- synthesis translate_on + return result ; + end function SumAlertCount ; + + ------------------------------------------------------------ + impure function GetAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return AlertCountType is + ------------------------------------------------------------ + variable result : AlertCountType ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetAlertCount(AlertLogID) ; + -- synthesis translate_on + return result ; + end function GetAlertCount ; + + ------------------------------------------------------------ + impure function GetAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return integer is + ------------------------------------------------------------ + variable result : integer ; + begin + -- synthesis translate_off + result := SumAlertCount(AlertLogStruct.GetAlertCount(AlertLogID)) ; + -- synthesis translate_on + return result ; + end function GetAlertCount ; + + ------------------------------------------------------------ + impure function GetEnabledAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return AlertCountType is + ------------------------------------------------------------ + variable result : AlertCountType ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetEnabledAlertCount(AlertLogID) ; + -- synthesis translate_on + return result ; + end function GetEnabledAlertCount ; + + ------------------------------------------------------------ + impure function GetEnabledAlertCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return integer is + ------------------------------------------------------------ + variable result : integer ; + begin + -- synthesis translate_off + result := SumAlertCount(AlertLogStruct.GetEnabledAlertCount(AlertLogID)) ; + -- synthesis translate_on + return result ; + end function GetEnabledAlertCount ; + + ------------------------------------------------------------ + impure function GetDisabledAlertCount return AlertCountType is + ------------------------------------------------------------ + variable result : AlertCountType ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetDisabledAlertCount ; + -- synthesis translate_on + return result ; + end function GetDisabledAlertCount ; + + ------------------------------------------------------------ + impure function GetDisabledAlertCount return integer is + ------------------------------------------------------------ + variable result : integer ; + begin + -- synthesis translate_off + result := SumAlertCount(AlertLogStruct.GetDisabledAlertCount) ; + -- synthesis translate_on + return result ; + end function GetDisabledAlertCount ; + + ------------------------------------------------------------ + impure function GetDisabledAlertCount(AlertLogID: AlertLogIDType) return AlertCountType is + ------------------------------------------------------------ + variable result : AlertCountType ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetDisabledAlertCount(AlertLogID) ; + -- synthesis translate_on + return result ; + end function GetDisabledAlertCount ; + + ------------------------------------------------------------ + impure function GetDisabledAlertCount(AlertLogID: AlertLogIDType) return integer is + ------------------------------------------------------------ + variable result : integer ; + begin + -- synthesis translate_off + result := SumAlertCount(AlertLogStruct.GetDisabledAlertCount(AlertLogID)) ; + -- synthesis translate_on + return result ; + end function GetDisabledAlertCount ; + + ------------------------------------------------------------ + procedure Log( + ------------------------------------------------------------ + AlertLogID : AlertLogIDType ; + Message : string ; + Level : LogType := ALWAYS ; + Enable : boolean := FALSE -- override internal enable + ) is + begin + -- synthesis translate_off + AlertLogStruct.Log(AlertLogID, Message, Level, Enable) ; + -- synthesis translate_on + end procedure log ; + + ------------------------------------------------------------ + procedure Log( Message : string ; Level : LogType := ALWAYS ; Enable : boolean := FALSE) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.Log(LOG_DEFAULT_ID, Message, Level, Enable) ; + -- synthesis translate_on + end procedure log ; + + ------------------------------------------------------------ + procedure SetAlertEnable(Level : AlertType ; Enable : boolean) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetAlertEnable(Level, Enable) ; + -- synthesis translate_on + end procedure SetAlertEnable ; + + ------------------------------------------------------------ + procedure SetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetAlertEnable(AlertLogID, Level, Enable, DescendHierarchy) ; + -- synthesis translate_on + end procedure SetAlertEnable ; + + ------------------------------------------------------------ + impure function GetAlertEnable(AlertLogID : AlertLogIDType ; Level : AlertType) return boolean is + ------------------------------------------------------------ + variable result : boolean ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetAlertEnable(AlertLogID, Level) ; + -- synthesis translate_on + return result ; + end function GetAlertEnable ; + + ------------------------------------------------------------ + impure function GetAlertEnable(Level : AlertType) return boolean is + ------------------------------------------------------------ + variable result : boolean ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetAlertEnable(ALERT_DEFAULT_ID, Level) ; + -- synthesis translate_on + return result ; + end function GetAlertEnable ; + + ------------------------------------------------------------ + procedure SetLogEnable(Level : LogType ; Enable : boolean) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetLogEnable(Level, Enable) ; + -- synthesis translate_on + end procedure SetLogEnable ; + + ------------------------------------------------------------ + procedure SetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType ; Enable : boolean ; DescendHierarchy : boolean := TRUE) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetLogEnable(AlertLogID, Level, Enable, DescendHierarchy) ; + -- synthesis translate_on + end procedure SetLogEnable ; + + ------------------------------------------------------------ + impure function GetLogEnable(AlertLogID : AlertLogIDType ; Level : LogType) return boolean is + ------------------------------------------------------------ + variable result : boolean ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetLogEnable(AlertLogID, Level) ; + -- synthesis translate_on + return result ; + end function GetLogEnable ; + + ------------------------------------------------------------ + impure function GetLogEnable(Level : LogType) return boolean is + ------------------------------------------------------------ + variable result : boolean ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetLogEnable(LOG_DEFAULT_ID, Level) ; + -- synthesis translate_on + return result ; + end function GetLogEnable ; + + ------------------------------------------------------------ + procedure ReportLogEnables is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.ReportLogEnables ; + -- synthesis translate_on + end ReportLogEnables ; + + ------------------------------------------------------------ + procedure SetAlertLogName(Name : string ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetAlertLogName(Name) ; + -- synthesis translate_on + end procedure SetAlertLogName ; + + -- synthesis translate_off + ------------------------------------------------------------ + impure function GetAlertLogName(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) return string is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogName(AlertLogID) ; + end GetAlertLogName ; + -- synthesis translate_on + + ------------------------------------------------------------ + procedure DeallocateAlertLogStruct is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.DeallocateAlertLogStruct ; + -- synthesis translate_on + end procedure DeallocateAlertLogStruct ; + + ------------------------------------------------------------ + procedure InitializeAlertLogStruct is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.Initialize ; + -- synthesis translate_on + end procedure InitializeAlertLogStruct ; + + ------------------------------------------------------------ + impure function FindAlertLogID(Name : string ) return AlertLogIDType is + ------------------------------------------------------------ + variable result : AlertLogIDType ; + begin + -- synthesis translate_off + result := AlertLogStruct.FindAlertLogID(Name) ; + -- synthesis translate_on + return result ; + end function FindAlertLogID ; + + ------------------------------------------------------------ + impure function FindAlertLogID(Name : string ; ParentID : AlertLogIDType) return AlertLogIDType is + ------------------------------------------------------------ + variable result : AlertLogIDType ; + begin + -- synthesis translate_off + result := AlertLogStruct.FindAlertLogID(Name, ParentID) ; + -- synthesis translate_on + return result ; + end function FindAlertLogID ; + + ------------------------------------------------------------ + impure function GetAlertLogID(Name : string; ParentID : AlertLogIDType := ALERTLOG_ID_NOT_ASSIGNED; CreateHierarchy : Boolean := TRUE; DoNotReport : Boolean := FALSE) return AlertLogIDType is + ------------------------------------------------------------ + variable result : AlertLogIDType ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetAlertLogID(Name, ParentID, CreateHierarchy, DoNotReport) ; + -- synthesis translate_on + return result ; + end function GetAlertLogID ; + + ------------------------------------------------------------ + impure function GetReqID(Name : string ; PassedGoal : integer := -1 ; ParentID : AlertLogIDType := ALERTLOG_ID_NOT_ASSIGNED ; CreateHierarchy : Boolean := TRUE) return AlertLogIDType is + ------------------------------------------------------------ + variable result : AlertLogIDType ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetReqID(Name, PassedGoal, ParentID, CreateHierarchy) ; + -- synthesis translate_on + return result ; + end function GetReqID ; + + ------------------------------------------------------------ + procedure SetPassedGoal(AlertLogID : AlertLogIDType ; PassedGoal : integer ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetPassedGoal(AlertLogID, PassedGoal) ; + -- synthesis translate_on + end procedure SetPassedGoal ; + + ------------------------------------------------------------ + impure function GetAlertLogParentID(AlertLogID : AlertLogIDType) return AlertLogIDType is + ------------------------------------------------------------ + variable result : AlertLogIDType ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetAlertLogParentID(AlertLogID) ; + -- synthesis translate_on + return result ; + end function GetAlertLogParentID ; + + ------------------------------------------------------------ + procedure SetAlertLogPrefix(AlertLogID : AlertLogIDType; Name : string ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetAlertLogPrefix(AlertLogID, Name) ; + -- synthesis translate_on + end procedure SetAlertLogPrefix ; + + ------------------------------------------------------------ + procedure UnSetAlertLogPrefix(AlertLogID : AlertLogIDType ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.UnSetAlertLogPrefix(AlertLogID) ; + -- synthesis translate_on + end procedure UnSetAlertLogPrefix ; + + -- synthesis translate_off + ------------------------------------------------------------ + impure function GetAlertLogPrefix(AlertLogID : AlertLogIDType) return string is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogPrefix(AlertLogID) ; + end function GetAlertLogPrefix ; + -- synthesis translate_on + + ------------------------------------------------------------ + procedure SetAlertLogSuffix(AlertLogID : AlertLogIDType; Name : string ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetAlertLogSuffix(AlertLogID, Name) ; + -- synthesis translate_on + end procedure SetAlertLogSuffix ; + + ------------------------------------------------------------ + procedure UnSetAlertLogSuffix(AlertLogID : AlertLogIDType ) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.UnSetAlertLogSuffix(AlertLogID) ; + -- synthesis translate_on + end procedure UnSetAlertLogSuffix ; + + -- synthesis translate_off + ------------------------------------------------------------ + impure function GetAlertLogSuffix(AlertLogID : AlertLogIDType) return string is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogSuffix(AlertLogID) ; + end function GetAlertLogSuffix ; + -- synthesis translate_on + + ------------------------------------------------------------ + procedure SetGlobalAlertEnable (A : boolean := TRUE) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetGlobalAlertEnable(A) ; + -- synthesis translate_on + end procedure SetGlobalAlertEnable ; + + ------------------------------------------------------------ + -- Set using constant. Set before code runs. + impure function SetGlobalAlertEnable (A : boolean := TRUE) return boolean is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetGlobalAlertEnable(A) ; + -- synthesis translate_on + return A ; + end function SetGlobalAlertEnable ; + + ------------------------------------------------------------ + impure function GetGlobalAlertEnable return boolean is + ------------------------------------------------------------ + variable result : boolean ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetGlobalAlertEnable ; + -- synthesis translate_on + return result ; + end function GetGlobalAlertEnable ; + + ------------------------------------------------------------ + procedure IncAffirmCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.IncAffirmCount(AlertLogID) ; + -- synthesis translate_on + end procedure IncAffirmCount ; + + ------------------------------------------------------------ + impure function GetAffirmCount return natural is + ------------------------------------------------------------ + variable result : natural ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetAffirmCount ; + -- synthesis translate_on + return result ; + end function GetAffirmCount ; + + ------------------------------------------------------------ + procedure IncAffirmPassedCount(AlertLogID : AlertLogIDType := ALERTLOG_BASE_ID) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.IncAffirmPassedCount(AlertLogID) ; + -- synthesis translate_on + end procedure IncAffirmPassedCount ; + + ------------------------------------------------------------ + impure function GetAffirmPassedCount return natural is + ------------------------------------------------------------ + variable result : natural ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetAffirmPassedCount ; + -- synthesis translate_on + return result ; + end function GetAffirmPassedCount ; + + ------------------------------------------------------------ + procedure SetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType ; Count : integer) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetAlertStopCount(AlertLogID, Level, Count) ; + -- synthesis translate_on + end procedure SetAlertStopCount ; + + ------------------------------------------------------------ + procedure SetAlertStopCount(Level : AlertType ; Count : integer) is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.SetAlertStopCount(ALERTLOG_BASE_ID, Level, Count) ; + -- synthesis translate_on + end procedure SetAlertStopCount ; + + ------------------------------------------------------------ + impure function GetAlertStopCount(AlertLogID : AlertLogIDType ; Level : AlertType) return integer is + ------------------------------------------------------------ + variable result : integer ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetAlertStopCount(AlertLogID, Level) ; + -- synthesis translate_on + return result ; + end function GetAlertStopCount ; + + ------------------------------------------------------------ + impure function GetAlertStopCount(Level : AlertType) return integer is + ------------------------------------------------------------ + variable result : integer ; + begin + -- synthesis translate_off + result := AlertLogStruct.GetAlertStopCount(ALERTLOG_BASE_ID, Level) ; + -- synthesis translate_on + return result ; + end function GetAlertStopCount ; + + + ------------------------------------------------------------ + procedure SetAlertLogOptions ( + ------------------------------------------------------------ + FailOnWarning : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + FailOnDisabledErrors : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + FailOnRequirementErrors : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + ReportHierarchy : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteAlertErrorCount : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteAlertLevel : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteAlertName : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteAlertTime : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteLogErrorCount : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteLogLevel : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteLogName : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + WriteLogTime : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + PrintPassed : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + PrintAffirmations : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + PrintDisabledAlerts : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + PrintRequirements : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + PrintIfHaveRequirements : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; + DefaultPassedGoal : integer := integer'left ; + 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 + -- synthesis translate_off + AlertLogStruct.SetAlertLogOptions ( + FailOnWarning => FailOnWarning, + FailOnDisabledErrors => FailOnDisabledErrors, + FailOnRequirementErrors => FailOnRequirementErrors, + ReportHierarchy => ReportHierarchy, + WriteAlertErrorCount => WriteAlertErrorCount, + WriteAlertLevel => WriteAlertLevel, + WriteAlertName => WriteAlertName, + WriteAlertTime => WriteAlertTime, + WriteLogErrorCount => WriteLogErrorCount, + WriteLogLevel => WriteLogLevel, + WriteLogName => WriteLogName, + WriteLogTime => WriteLogTime, + PrintPassed => PrintPassed, + PrintAffirmations => PrintAffirmations, + PrintDisabledAlerts => PrintDisabledAlerts, + PrintRequirements => PrintRequirements, + PrintIfHaveRequirements => PrintIfHaveRequirements, + DefaultPassedGoal => DefaultPassedGoal, + AlertPrefix => AlertPrefix, + LogPrefix => LogPrefix, + ReportPrefix => ReportPrefix, + DoneName => DoneName, + PassName => PassName, + FailName => FailName + ); + -- synthesis translate_on + end procedure SetAlertLogOptions ; + + ------------------------------------------------------------ + procedure ReportAlertLogOptions is + ------------------------------------------------------------ + begin + -- synthesis translate_off + AlertLogStruct.ReportAlertLogOptions ; + -- synthesis translate_on + end procedure ReportAlertLogOptions ; + + + + -- synthesis translate_off + + ------------------------------------------------------------ + impure function GetAlertLogFailOnWarning return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogFailOnWarning ; + end function GetAlertLogFailOnWarning ; + + ------------------------------------------------------------ + impure function GetAlertLogFailOnDisabledErrors return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogFailOnDisabledErrors ; + end function GetAlertLogFailOnDisabledErrors ; + + ------------------------------------------------------------ + impure function GetAlertLogFailOnRequirementErrors return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogFailOnRequirementErrors ; + end function GetAlertLogFailOnRequirementErrors ; + + ------------------------------------------------------------ + impure function GetAlertLogReportHierarchy return OsvvmOptionsType 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 GetAlertLogWriteAlertErrorCount return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogWriteAlertErrorCount ; + end function GetAlertLogWriteAlertErrorCount ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteAlertLevel return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogWriteAlertLevel ; + end function GetAlertLogWriteAlertLevel ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteAlertName return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogWriteAlertName ; + end function GetAlertLogWriteAlertName ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteAlertTime return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogWriteAlertTime ; + end function GetAlertLogWriteAlertTime ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteLogErrorCount return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogWriteLogErrorCount ; + end function GetAlertLogWriteLogErrorCount ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteLogLevel return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogWriteLogLevel ; + end function GetAlertLogWriteLogLevel ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteLogName return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogWriteLogName ; + end function GetAlertLogWriteLogName ; + + ------------------------------------------------------------ + impure function GetAlertLogWriteLogTime return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogWriteLogTime ; + end function GetAlertLogWriteLogTime ; + + ------------------------------------------------------------ + impure function GetAlertLogPrintPassed return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogPrintPassed ; + end function GetAlertLogPrintPassed ; + + ------------------------------------------------------------ + impure function GetAlertLogPrintAffirmations return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogPrintAffirmations ; + end function GetAlertLogPrintAffirmations ; + + ------------------------------------------------------------ + impure function GetAlertLogPrintDisabledAlerts return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogPrintDisabledAlerts ; + end function GetAlertLogPrintDisabledAlerts ; + + ------------------------------------------------------------ + impure function GetAlertLogPrintRequirements return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogPrintRequirements ; + end function GetAlertLogPrintRequirements ; + + ------------------------------------------------------------ + impure function GetAlertLogPrintIfHaveRequirements return OsvvmOptionsType is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogPrintIfHaveRequirements ; + end function GetAlertLogPrintIfHaveRequirements ; + + ------------------------------------------------------------ + impure function GetAlertLogDefaultPassedGoal return integer is + ------------------------------------------------------------ + begin + return AlertLogStruct.GetAlertLogDefaultPassedGoal ; + end function GetAlertLogDefaultPassedGoal ; + + ------------------------------------------------------------ + 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 ; +-- Log(OSVVM_ALERTLOG_ID, "SetLogEnable(OSVVM_ALERTLOG_ID, " & Name(1 to NameLen) & ", TRUE) ;", DEBUG) ; + LogLevel := LogType'value("" & Name(1 to NameLen)) ; -- "" & added for RivieraPro 2020.10 + 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 ; + variable LenA : integer := A'length ; + begin + if aA(LenA) = ':' then + LenA := LenA - 1 ; + end if ; + for i in LenA downto 1 loop + if aA(i) = ':' then + return aA(i+1 to LenA) ; + end if ; + end loop ; + return aA(1 to LenA) ; + end function PathTail ; + + + ------------------------------------------------------------ + -- MetaMatch + -- Similar to STD_MATCH, except + -- it returns TRUE for U=U, X=X, Z=Z, and W=W + -- All other values are consistent with STD_MATCH + -- MetaMatch, BooleanTableType, and MetaMatchTable are derivatives + -- of STD_MATCH from IEEE.Numeric_Std copyright by IEEE. + -- Numeric_Std is also released under the Apache License, Version 2.0. + -- Coding Styles were updated to match OSVVM + ------------------------------------------------------------ + + type BooleanTableType is array(std_ulogic, std_ulogic) of boolean; + + constant MetaMatchTable : BooleanTableType := ( + -------------------------------------------------------------------------- + -- U X 0 1 Z W L H - + -------------------------------------------------------------------------- + (TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE), -- | U | + (FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE), -- | X | + (FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE), -- | 0 | + (FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE), -- | 1 | + (FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE), -- | Z | + (FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE), -- | W | + (FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE), -- | L | + (FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE), -- | H | + (TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) -- | - | + ); + + function MetaMatch (l, r : std_ulogic) return boolean is + begin + return MetaMatchTable(l, r); + end function MetaMatch; + + function MetaMatch (L, R : std_ulogic_vector) return boolean is + alias aL : std_ulogic_vector(1 to L'length) is L; + alias aR : std_ulogic_vector(1 to R'length) is R; + begin + if aL'length /= aR'length then + --! log(OSVVM_ALERTLOG_ID, "AlertLogPkg.MetaMatch: Length Mismatch", DEBUG) ; + return FALSE; + else + for i in aL'range loop + if not (MetaMatchTable(aL(i), aR(i))) then + return FALSE; + end if; + end loop; + return TRUE; + end if; + end function MetaMatch; + + function MetaMatch (L, R : unresolved_unsigned) return boolean is + begin + return MetaMatch( std_ulogic_vector(L), std_ulogic_vector(R)) ; + end function MetaMatch; + + function MetaMatch (L, R : unresolved_signed) return boolean is + begin + return MetaMatch( std_ulogic_vector(L), std_ulogic_vector(R)) ; + end function MetaMatch; + -- synthesis translate_on + + -- ------------------------------------------------------------ + -- Deprecated + -- + + ------------------------------------------------------------ + -- deprecated + procedure AlertIf( condition : boolean ; AlertLogID : AlertLogIDType ; Message : string ; Level : AlertType := ERROR ) is + begin + -- synthesis translate_off + AlertIf( AlertLogID, condition, Message, Level) ; + -- synthesis translate_on + end procedure AlertIf ; + + ------------------------------------------------------------ + -- deprecated + impure function AlertIf( condition : boolean ; AlertLogID : AlertLogIDType ; Message : string ; Level : AlertType := ERROR ) return boolean is + variable result : boolean ; + begin + -- synthesis translate_off + result := AlertIf( AlertLogID, condition, Message, Level) ; + -- synthesis translate_on + return result ; + end function AlertIf ; + + ------------------------------------------------------------ + -- deprecated + procedure AlertIfNot( condition : boolean ; AlertLogID : AlertLogIDType ; Message : string ; Level : AlertType := ERROR ) is + begin + -- synthesis translate_off + AlertIfNot( AlertLogID, condition, Message, Level) ; + -- synthesis translate_on + end procedure AlertIfNot ; + + ------------------------------------------------------------ + -- deprecated + impure function AlertIfNot( condition : boolean ; AlertLogID : AlertLogIDType ; Message : string ; Level : AlertType := ERROR ) return boolean is + variable result : boolean ; + begin + -- synthesis translate_off + result := AlertIfNot( AlertLogID, condition, Message, Level) ; + -- synthesis translate_on + return result ; + end function AlertIfNot ; + + ------------------------------------------------------------ + -- deprecated + procedure AffirmIf( + AlertLogID : AlertLogIDType ; + condition : boolean ; + Message : string ; + LogLevel : LogType ; -- := PASSED + AlertLevel : AlertType := ERROR + ) is + begin + -- synthesis translate_off + if condition then + -- PASSED. Count affirmations and PASSED internal to LOG to catch all of them + AlertLogStruct.Log(AlertLogID, Message, LogLevel) ; -- call log + else + AlertLogStruct.IncAffirmCount(AlertLogID) ; -- count the affirmation + AlertLogStruct.Alert(AlertLogID, Message, AlertLevel) ; -- signal failure + end if ; + -- synthesis translate_on + end procedure AffirmIf ; + + ------------------------------------------------------------ + -- deprecated + procedure AffirmIf( AlertLogID : AlertLogIDType ; condition : boolean ; Message : string ; AlertLevel : AlertType ) is + begin + -- synthesis translate_off + AffirmIf(AlertLogID, condition, Message, PASSED, AlertLevel) ; + -- synthesis translate_on + end procedure AffirmIf ; + + ------------------------------------------------------------ + -- deprecated + procedure AffirmIf(condition : boolean ; Message : string ; LogLevel : LogType ; AlertLevel : AlertType := ERROR) is + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, condition, Message, LogLevel, AlertLevel) ; + -- synthesis translate_on + end procedure AffirmIf; + + ------------------------------------------------------------ + -- deprecated + procedure AffirmIf(condition : boolean ; Message : string ; AlertLevel : AlertType ) is + begin + -- synthesis translate_off + AffirmIf(ALERT_DEFAULT_ID, condition, Message, PASSED, AlertLevel) ; + -- synthesis translate_on + end procedure AffirmIf; + +end package body AlertLogPkg ; \ No newline at end of file diff --git a/examples/vhdl/osvvm_log_integration/osvvm_integration/osvvm_to_vunit_common_log_pkg-body.vhd b/examples/vhdl/osvvm_log_integration/osvvm_integration/osvvm_to_vunit_common_log_pkg-body.vhd new file mode 100644 index 000000000..2c508c891 --- /dev/null +++ b/examples/vhdl/osvvm_log_integration/osvvm_integration/osvvm_to_vunit_common_log_pkg-body.vhd @@ -0,0 +1,58 @@ +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this file, +-- You can obtain one at http://mozilla.org/MPL/2.0/. +-- +-- Copyright (c) 2014-2023, Lars Asplund lars.anders.asplund@gmail.com + +library vunit_lib; +context vunit_lib.vunit_context; + +package body common_log_pkg is + procedure write_to_log( + file log_destination : text; + msg : string := ""; + log_time : time := no_time; + log_level : string := ""; + log_source_name : string := ""; + str_1, str_2, str_3, str_4, str_5, str_6, str_7, str_8, str_9, str_10 : string := ""; + val_1, val_2, val_3, val_4, val_5, val_6, val_7, val_8, val_9, val_10 : integer := no_val + ) is + constant stripped_log_level : string := strip(log_level); + + alias prefix is str_2; + alias suffix is str_3; + + variable logger : logger_t; + variable vunit_log_level : log_level_t; + variable full_msg : line; + begin + logger := get_logger(log_source_name); + + if stripped_log_level = "WARNING" then + vunit_log_level := warning; + elsif stripped_log_level = "ERROR" then + vunit_log_level := error; + elsif stripped_log_level = "FAILURE" then + vunit_log_level := failure; + elsif stripped_log_level = "DEBUG" then + vunit_log_level := debug; + elsif stripped_log_level = "PASSED" then + vunit_log_level := pass; + else + vunit_log_level := info; + end if; + + if prefix /= "" then + write(full_msg, prefix & " "); + end if; + + write(full_msg, msg); + + if suffix /= "" then + write(full_msg, " " & suffix); + end if; + + log(logger, msg, vunit_log_level, path_offset => 4); + end; + +end package body; diff --git a/examples/vhdl/osvvm_log_integration/osvvm_integration/vunit_to_osvvm_common_log_pkg-body.vhd b/examples/vhdl/osvvm_log_integration/osvvm_integration/vunit_to_osvvm_common_log_pkg-body.vhd new file mode 100644 index 000000000..90f7c8750 --- /dev/null +++ b/examples/vhdl/osvvm_log_integration/osvvm_integration/vunit_to_osvvm_common_log_pkg-body.vhd @@ -0,0 +1,37 @@ +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this file, +-- You can obtain one at http://mozilla.org/MPL/2.0/. +-- +-- Copyright (c) 2014-2023, Lars Asplund lars.anders.asplund@gmail.com + +use work.ansi_pkg.all; +use work.log_levels_pkg.all; +use work.string_ops.upper; + +library osvvm; +use osvvm.AlertLogPkg.all; + +package body common_log_pkg is + + procedure write_to_log( + file log_destination : text; + msg : string := ""; + log_time : time := no_time; + log_level : string := ""; + log_source_name : string := ""; + str_1, str_2, str_3, str_4, str_5, str_6, str_7, str_8, str_9, str_10 : string := ""; + val_1, val_2, val_3, val_4, val_5, val_6, val_7, val_8, val_9, val_10 : integer := no_val + ) is + begin + if (log_level = "warning") or (log_level = "error") or (log_level = "failure") then + Alert(GetAlertLogID(log_source_name), msg, AlertType'value(upper(log_level))); + elsif (log_level = "debug") then + osvvm.AlertLogPkg.Log(GetAlertLogID(log_source_name), msg, DEBUG); + elsif (log_level = "pass") then + osvvm.AlertLogPkg.Log(GetAlertLogID(log_source_name), msg, PASSED); + else + osvvm.AlertLogPkg.Log(GetAlertLogID(log_source_name), msg); + end if; + end; + +end package body; diff --git a/examples/vhdl/osvvm_log_integration/run.py b/examples/vhdl/osvvm_log_integration/run.py new file mode 100644 index 000000000..98295e1f7 --- /dev/null +++ b/examples/vhdl/osvvm_log_integration/run.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. +# +# Copyright (c) 2014-2023, Lars Asplund lars.anders.asplund@gmail.com + +from pathlib import Path +from itertools import product +from vunit import VUnit, VUnitCLI + +cli = VUnitCLI() +cli.parser.add_argument( + "--use-osvvm-log", + action="store_true", + default=False, + help="Re-direct VUnit log output to OSVVM log handling", +) +cli.parser.add_argument( + "--use-vunit-log", + action="store_true", + default=False, + help="Re-direct OSVVM log output to VUnit log handling", +) +args = cli.parse_args() +if args.use_osvvm_log and args.use_vunit_log: + raise RuntimeError("Only one of --use-osvvm-log and --use-vunit-log can be used at any time.") +args.clean = True +prj = VUnit.from_args(args=args) +root = Path(__file__).parent +if args.use_osvvm_log: + prj.add_vhdl_builtins(use_external_log=Path(root / "osvvm_integration" / "vunit_to_osvvm_common_log_pkg-body.vhd")) +else: + prj.add_vhdl_builtins() + +lib = prj.add_library("lib") +lib.add_source_files(root / "*.vhd") +lib.test_bench("tb_example").set_generic("use_osvvm_log", args.use_osvvm_log) +lib.test_bench("tb_example").set_generic("use_vunit_log", args.use_vunit_log) + +osvvm = prj.add_library("osvvm") +osvvm_files_to_compile = [ + "NamePkg.vhd", + "OsvvmGlobalPkg.vhd", + "TranscriptPkg.vhd", + "TextUtilPkg.vhd", + "OsvvmScriptSettingsPkg.vhd", + "OsvvmScriptSettingsPkg_default.vhd", +] +for osvvm_file in osvvm_files_to_compile: + osvvm.add_source_files(root / ".." / ".." / ".." / "vunit" / "vhdl" / "osvvm" / osvvm_file) + +if args.use_vunit_log: + osvvm.add_source_files(root / ".." / ".." / ".." / "vunit" / "vhdl" / "logging" / "src" / "common_log_pkg.vhd") + osvvm.add_source_files(root / "osvvm_integration" / "osvvm_to_vunit_common_log_pkg-body.vhd") + osvvm.add_source_files(root / "osvvm_integration" / "AlertLogPkg.vhd") +else: + osvvm.add_source_files(root / ".." / ".." / ".." / "vunit" / "vhdl" / "osvvm" / "AlertLogPkg.vhd") + + +prj.set_compile_option("rivierapro.vcom_flags", ["-dbg"]) +prj.main() diff --git a/examples/vhdl/osvvm_log_integration/tb_example.vhd b/examples/vhdl/osvvm_log_integration/tb_example.vhd new file mode 100644 index 000000000..ca48f0d90 --- /dev/null +++ b/examples/vhdl/osvvm_log_integration/tb_example.vhd @@ -0,0 +1,85 @@ +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this file, +-- You can obtain one at http://mozilla.org/MPL/2.0/. +-- +-- Copyright (c) 2014-2023, Lars Asplund lars.anders.asplund@gmail.com + +library vunit_lib; +context vunit_lib.vunit_context; + +library osvvm; +use osvvm.AlertLogPkg.all; + +library ieee; +use ieee.std_logic_1164.all; + +entity tb_example is + generic ( + runner_cfg : string; + use_osvvm_log : boolean; + use_vunit_log : boolean); +end entity; + +architecture tb of tb_example is + +begin + main : process + constant logger : logger_t := get_logger("A VUnit logger name"); + constant parent_logger : logger_t := get_logger("VUnit parent"); + constant child_logger : logger_t := get_logger("VUnit child", parent_logger); + constant checker : checker_t := new_checker(logger); + + constant id : AlertLogIDType := GetAlertLogID("An OSVVM ID"); + constant parent_id : AlertLogIDType := GetAlertLogID("OSVVM parent"); + constant child_id : AlertLogIDType := GetAlertLogID("OSVVM child", parent_id); + begin + test_runner_setup(runner, runner_cfg); + set_stop_level(failure); + + if use_osvvm_log then + print(LF & "-------------------------------------------------------------------"); + print("This is what VUnit log messages look like when piped through OSVVM:"); + print("-------------------------------------------------------------------" & LF); + else + print(LF & "------------------------------------------------------------------------"); + print("This is what standard VUnit log messages look like. Call run.py"); + print("with --use-osvvm-log to see what is looks like when piped through OSVVM."); + print("------------------------------------------------------------------------" & LF); + end if; + + info(logger, "Hello from VUnit"); + check(checker, false, "An error from VUnit"); + info(child_logger, "Hello from VUnit hierarchy"); + + if use_vunit_log then + print(LF & "-------------------------------------------------------------------"); + print("This is what OSVVM log messages look like when piped through VUnit:"); + print("-------------------------------------------------------------------" & LF); + else + print(LF & "------------------------------------------------------------------------"); + print("This is what standard OSVVM log messages look like. Call run.py"); + print("with --use-vunit-log to see what is looks like when piped through VUnit."); + print("------------------------------------------------------------------------" & LF); + end if; + + osvvm.AlertLogPkg.Log(id, "Hello from OSVVM"); + Alert(id, "An error from OSVVM"); + osvvm.AlertLogPkg.Log(child_id, "Hello from OSVVM hierarchy"); + + if use_osvvm_log then + print(LF & "------------------------------------------------------------------------"); + print("Only log messages are piped through OSVVM. Print messages outside of the"); + print("the logging framework are unaffected. For example this FAILURE"); + print("message."); + print("------------------------------------------------------------------------" & LF); + else + print(LF & ""); + end if; + + test_runner_cleanup(runner); + end process; + + test_runner_watchdog(runner, 1000 ns); + + +end architecture; diff --git a/tests/acceptance/artificial/vhdl/run.py b/tests/acceptance/artificial/vhdl/run.py index 0a9e155bb..b0699e7fa 100644 --- a/tests/acceptance/artificial/vhdl/run.py +++ b/tests/acceptance/artificial/vhdl/run.py @@ -19,6 +19,8 @@ for file in glob(str(root / "*.vhd")): if "tb_set_generic" in file: lib2.add_source_files(file) + elif "other_logging_framework" in file: + continue else: lib.add_source_files(file) diff --git a/tests/acceptance/test_external_run_scripts.py b/tests/acceptance/test_external_run_scripts.py index d528905bd..3773120b6 100644 --- a/tests/acceptance/test_external_run_scripts.py +++ b/tests/acceptance/test_external_run_scripts.py @@ -196,6 +196,13 @@ def test_vhdl_array_axis_vcs_example_project(self): def test_vhdl_axi_dma_example_project(self): self.check(ROOT / "examples/vhdl/axi_dma/run.py") + def test_vhdl_osvvm_log_integration(self): + self.check(ROOT / "examples/vhdl/osvvm_log_integration/run.py", exit_code=1) + check_report( + self.report_file, + [("failed", "lib.tb_example.all")], + ) + @mark.skipif( simulator_check(lambda simclass: not simclass.supports_vhdl_contexts()), reason="This simulator/backend does not support VHDL contexts", diff --git a/tests/lint/test_license.py b/tests/lint/test_license.py index fc2d37e16..4ed8520f0 100644 --- a/tests/lint/test_license.py +++ b/tests/lint/test_license.py @@ -142,6 +142,8 @@ def find_licensed_files(): (Path(root) / file_name).resolve(), ): continue + if file_name == "AlertLogPkg.vhd": + continue if is_prefix_of( (VHDL_PATH / "JSON-for-VHDL").resolve(), (Path(root) / file_name).resolve(), diff --git a/vunit/builtins.py b/vunit/builtins.py index 706cd7a19..ee36191a5 100755 --- a/vunit/builtins.py +++ b/vunit/builtins.py @@ -245,7 +245,7 @@ def add_verilog_builtins(self): """ self._vunit_lib.add_source_files(VERILOG_PATH / "vunit_pkg.sv") - def add_vhdl_builtins(self, external=None): + def add_vhdl_builtins(self, external=None, use_external_log=None): """ Add vunit VHDL builtin libraries @@ -273,6 +273,14 @@ def add_vhdl_builtins(self, external=None): ): self._add_files(VHDL_PATH / path / "src" / "*.vhd") + logging_files = glob(str(VHDL_PATH / "logging" / "src" / "*.vhd")) + for logging_file in logging_files: + if logging_file.endswith("common_log_pkg-body.vhd") and use_external_log: + self._add_files(Path(use_external_log)) + continue + + self._add_files(Path(logging_file)) + def osvvm_is_installed(): """ @@ -304,6 +312,7 @@ def add(self, name, args=None): """ Add builtin with arguments """ + args = {} if args is None else args if not self._add_check(name, args): diff --git a/vunit/ui/__init__.py b/vunit/ui/__init__.py index 8bcc2e1cb..1a573725f 100644 --- a/vunit/ui/__init__.py +++ b/vunit/ui/__init__.py @@ -972,11 +972,13 @@ def add_verilog_builtins(self): """ self._builtins.add_verilog_builtins() - def add_vhdl_builtins(self, external=None): + def add_vhdl_builtins(self, external=None, use_external_log=None): """ Add VUnit VHDL builtin libraries. :param external: struct to provide bridges for the external VHDL API. + :param use_external_log: path to external implementation of common_log_pkg-body to allow + VUnit log messages to be redirected to another logging framework. :example: @@ -992,7 +994,7 @@ def add_vhdl_builtins(self, external=None): VHDL users need to call this method explicitly in order to preserve the functionality. See :vunit_issue:`777`. """ - self._builtins.add_vhdl_builtins(external=external) + self._builtins.add_vhdl_builtins(external=external, use_external_log=use_external_log) def add_com(self): """ diff --git a/vunit/vhdl/logging/src/ansi_pkg.vhd b/vunit/vhdl/logging/src/ansi_pkg.vhd index d31936e14..df44397ca 100644 --- a/vunit/vhdl/logging/src/ansi_pkg.vhd +++ b/vunit/vhdl/logging/src/ansi_pkg.vhd @@ -5,9 +5,7 @@ -- Copyright (c) 2014-2023, Lars Asplund lars.anders.asplund@gmail.com use std.textio.all; - -library vunit_lib; -use vunit_lib.string_ptr_pkg.all; +use work.string_ptr_pkg.all; package ansi_pkg is diff --git a/vunit/vhdl/logging/src/common_log_pkg-body.vhd b/vunit/vhdl/logging/src/common_log_pkg-body.vhd new file mode 100644 index 000000000..1f7284acb --- /dev/null +++ b/vunit/vhdl/logging/src/common_log_pkg-body.vhd @@ -0,0 +1,193 @@ +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this file, +-- You can obtain one at http://mozilla.org/MPL/2.0/. +-- +-- Copyright (c) 2014-2023, Lars Asplund lars.anders.asplund@gmail.com + +use work.ansi_pkg.all; +use work.log_levels_pkg.all; +use work.string_ops.upper; + +package body common_log_pkg is + + procedure write_to_log( + file log_destination : text; + msg : string := ""; + log_time : time := no_time; + log_level : string := ""; + log_source_name : string := ""; + str_1, str_2, str_3, str_4, str_5, str_6, str_7, str_8, str_9, str_10 : string := ""; + val_1, val_2, val_3, val_4, val_5, val_6, val_7, val_8, val_9, val_10 : integer := no_val + ) is + + alias file_name is str_1; + + alias format is val_1; + alias line_num is val_2; + alias sequence_number is val_3; + alias use_color is val_4; + alias get_max_logger_name_length is val_5; + + constant max_time_str : string := time'image(1 sec); + constant max_time_length : natural := max_time_str'length; + + constant raw_format : integer := 0; + constant level_format : integer := 1; + constant verbose_format : integer := 2; + constant csv_format : integer := 3; + + procedure pad(variable l : inout line; len : integer) is + begin + if len > 0 then + write(l, string'(1 to len => ' ')); + end if; + end; + + procedure write_time(variable l : inout line; justify : boolean := false) is + constant time_string : string := time'image(log_time); + begin + if justify then + pad(l, max_time_length - time_string'length); + end if; + + if use_color = 1 then + write(l, color_start(fg => lightcyan)); + end if; + + write(l, time_string); + + if use_color = 1 then + write(l, color_end); + end if; + end procedure; + + procedure write_level(variable l : inout line; justify : boolean := false) is + constant level_name : string := get_name(log_level_t'value(log_level)); + variable color : ansi_colors_t; + begin + if justify then + pad(l, max_level_length - level_name'length); + end if; + + if use_color = 1 then + color := get_color(log_level_t'value(log_level)); + write(l, color_start(fg => color.fg, bg => color.bg, style => color.style)); + end if; + + write(l, upper(level_name)); + + if use_color = 1 then + write(l, color_end); + end if; + end; + + procedure write_source(variable l : inout line; justify : boolean := false) is + begin + if use_color = 1 then + write(l, color_start(fg => white, style => bright)); + + for i in log_source_name 'range loop + if log_source_name(i) = ':' then + write(l, color_start(fg => lightcyan, style => bright)); + write(l, log_source_name(i)); + write(l, color_start(fg => white, style => bright)); + else + write(l, log_source_name(i)); + end if; + end loop; + else + write(l, log_source_name); + end if; + + if use_color = 1 then + write(l, color_end); + end if; + + if justify then + pad(l, get_max_logger_name_length - log_source_name'length); + end if; + + end; + + procedure write_location(variable l : inout line) is + begin + if file_name /= "" then + write(l, " (" & file_name & ":" & integer'image(line_num) & ")"); + end if; + end; + + procedure write_message(variable l : inout line; multi_line_align : boolean := false) is + variable prefix_len : natural; + variable location_written : boolean := false; + begin + if not multi_line_align then + write(l, msg); + else + prefix_len := length_without_color(l.all); + for i in msg'range loop + + if msg(i) = LF and not location_written then + location_written := true; + write_location(l); + end if; + + write(l, msg(i)); + + if msg(i) = LF then + write(l, string'(1 to prefix_len => ' ')); + end if; + end loop; + end if; + + if not location_written then + write_location(l); + end if; + + end procedure; + + variable l : line; + begin + if format = raw_format then + write_message(l); + + elsif format = level_format then + write_level(l, justify => true); + write(l, string'(" - ")); + write_message(l, multi_line_align => true); + + elsif format = verbose_format then + write_time(l, justify => true); + write(l, string'(" - ")); + write_source(l, justify => true); + write(l, string'(" - ")); + write_level(l, justify => true); + write(l, string'(" - ")); + write_message(l, multi_line_align => true); + + elsif format = csv_format then + write(l, string'(integer'image(sequence_number) & ',')); + write_time(l); + write(l, ','); + write_level(l); + write(l, ','); + + if line_num = 0 then + write(l, string'(",,")); + else + write(l, file_name); + write(l, ','); + write(l, integer'image(line_num)); + write(l, ','); + end if; + + write_source(l); + write(l, ','); + write(l, msg); + + else + assert false report "Illegal format: " & integer'image(format) severity failure; + end if; + writeline(log_destination, l); + end; + +end package body; diff --git a/vunit/vhdl/logging/src/common_log_pkg.vhd b/vunit/vhdl/logging/src/common_log_pkg.vhd new file mode 100644 index 000000000..c6722c09f --- /dev/null +++ b/vunit/vhdl/logging/src/common_log_pkg.vhd @@ -0,0 +1,48 @@ +-- This Source Code Form is subject to the terms of the Mozilla Public +-- License, v. 2.0. If a copy of the MPL was not distributed with this file, +-- You can obtain one at http://mozilla.org/MPL/2.0/. +-- +-- Copyright (c) 2014-2023, Lars Asplund lars.anders.asplund@gmail.com + +use std.textio.all; + +package common_log_pkg is + constant no_time : time := -1 ns; + constant no_val : integer := integer'low; + + -- Converts a log message and associated metadata to a string written to the specified log destination. + procedure write_to_log( + ---------------------------------------------------- + -- Log entry items common to many logging frameworks + ---------------------------------------------------- + + -- Destination of the log message is either std.textio.output (std output) or a text file object previously opened + -- for writing + file log_destination : text; + -- Log message + msg : string := ""; + -- Simulation time associated with the log message + log_time : time := no_time; + -- Level associated with the log message. For example "DEBUG" or "WARNING". + log_level : string := ""; + -- Name of the producer of the log message. Hierarchical names use colon as the delimiter. + -- For example "parent_component:child_component". + log_source_name : string := ""; + + ---------------------------------------------------------------------------------------------------------------------------- + -- Log entry items less commonly used are passed to the procedure with no-name string and integer parameters which + -- meaning is specific to an implementation of the procedure. The documentation below is valid for VUnit only + ---------------------------------------------------------------------------------------------------------------------------- + + str_1, -- File name from which the log entry was issued if the location is known, empty string otherwise + + str_2, str_3, str_4, str_5, str_6, str_7, str_8, str_9, str_10 : string := ""; -- Not used + + val_1, -- Log format raw, level, verbose, or csv expressed as an integer 0 - 3. + val_2, -- Line number in file from which the log entry was issued if the location is known, 0 otherwise + val_3, -- Sequence number for log entry + val_4, -- 1 if log entry is to be in color, 0 otherwise + val_5, -- Max length of logger names (used for alignment) + + val_6, val_7, val_8, val_9, val_10 : integer := no_val); -- Not used +end package; diff --git a/vunit/vhdl/logging/src/file_pkg.vhd b/vunit/vhdl/logging/src/file_pkg.vhd index 2d7be9efa..2b630f232 100644 --- a/vunit/vhdl/logging/src/file_pkg.vhd +++ b/vunit/vhdl/logging/src/file_pkg.vhd @@ -7,6 +7,7 @@ use std.textio.all; use work.integer_vector_ptr_pkg.all; use work.string_ptr_pkg.all; +use work.common_log_pkg.all; package file_pkg is -- NOTE: This package is private, do not use outside of VUnit @@ -23,8 +24,16 @@ package file_pkg is procedure file_close(file_id : file_id_t); procedure file_open_for_write(file_id : inout file_id_t; file_name : string); - procedure writeline(file_id : file_id_t; - l : inout line); + + procedure write_to_log( + file_id : file_id_t; + msg : string; + log_time : time; + log_level : string; + log_source_name : string; + str_1: string; + val_1, val_2, val_3, val_4, val_5 : integer); + end package; package body file_pkg is @@ -210,52 +219,65 @@ package body file_pkg is assert_status(status, file_name); end; - procedure writeline(file_id : file_id_t; - l : inout line) is - variable id : natural := get(file_id.p_data, id_idx); + procedure write_to_log( + file_id : file_id_t; + msg : string; + log_time : time; + log_level : string; + log_source_name : string; + str_1: string; + val_1, val_2, val_3, val_4, val_5 : integer) is + + constant id : natural := get(file_id.p_data, id_idx); variable name_ptr : string_ptr_t; file ftmp : text; variable status : file_open_status; + + procedure write_to_log_i(file log_destination : text) is + begin + write_to_log(log_destination, msg, log_time, log_level, log_source_name, val_1 => val_1, val_2 => val_2, + val_3 => val_3, val_4 => val_4, val_5 => val_5, str_1 => str_1); + end; begin case id is - when 0 => writeline(f0, l); - when 1 => writeline(f1, l); - when 2 => writeline(f2, l); - when 3 => writeline(f3, l); - when 4 => writeline(f4, l); - when 5 => writeline(f5, l); - when 6 => writeline(f6, l); - when 7 => writeline(f7, l); - when 8 => writeline(f8, l); - when 9 => writeline(f9, l); - when 10 => writeline(f10, l); - when 11 => writeline(f11, l); - when 12 => writeline(f12, l); - when 13 => writeline(f13, l); - when 14 => writeline(f14, l); - when 15 => writeline(f15, l); - when 16 => writeline(f16, l); - when 17 => writeline(f17, l); - when 18 => writeline(f18, l); - when 19 => writeline(f19, l); - when 20 => writeline(f20, l); - when 21 => writeline(f21, l); - when 22 => writeline(f22, l); - when 23 => writeline(f23, l); - when 24 => writeline(f24, l); - when 25 => writeline(f25, l); - when 26 => writeline(f26, l); - when 27 => writeline(f27, l); - when 28 => writeline(f28, l); - when 29 => writeline(f29, l); - when 30 => writeline(f30, l); - when 31 => writeline(f31, l); + when 0 => write_to_log_i(f0); + when 1 => write_to_log_i(f1); + when 2 => write_to_log_i(f2); + when 3 => write_to_log_i(f3); + when 4 => write_to_log_i(f4); + when 5 => write_to_log_i(f5); + when 6 => write_to_log_i(f6); + when 7 => write_to_log_i(f7); + when 8 => write_to_log_i(f8); + when 9 => write_to_log_i(f9); + when 10 => write_to_log_i(f10); + when 11 => write_to_log_i(f11); + when 12 => write_to_log_i(f12); + when 13 => write_to_log_i(f13); + when 14 => write_to_log_i(f14); + when 15 => write_to_log_i(f15); + when 16 => write_to_log_i(f16); + when 17 => write_to_log_i(f17); + when 18 => write_to_log_i(f18); + when 19 => write_to_log_i(f19); + when 20 => write_to_log_i(f20); + when 21 => write_to_log_i(f21); + when 22 => write_to_log_i(f22); + when 23 => write_to_log_i(f23); + when 24 => write_to_log_i(f24); + when 25 => write_to_log_i(f25); + when 26 => write_to_log_i(f26); + when 27 => write_to_log_i(f27); + when 28 => write_to_log_i(f28); + when 29 => write_to_log_i(f29); + when 30 => write_to_log_i(f30); + when 31 => write_to_log_i(f31); when others => name_ptr := to_string_ptr(get(file_id.p_data, name_idx)); file_open(status, ftmp, to_string(name_ptr), append_mode); assert_status(status, to_string(name_ptr)); - writeline(ftmp, l); + write_to_log_i(ftmp); file_close(ftmp); end case; diff --git a/vunit/vhdl/logging/src/log_handler_pkg-body.vhd b/vunit/vhdl/logging/src/log_handler_pkg-body.vhd index dba096cf0..fffd15172 100644 --- a/vunit/vhdl/logging/src/log_handler_pkg-body.vhd +++ b/vunit/vhdl/logging/src/log_handler_pkg-body.vhd @@ -13,6 +13,7 @@ use vunit_lib.integer_vector_ptr_pkg.all; use work.ansi_pkg.all; use work.string_ops.upper; use work.file_pkg.all; +use work.common_log_pkg.all; package body log_handler_pkg is @@ -149,182 +150,21 @@ package body log_handler_pkg is line_num : natural := 0; file_name : string := "") is - variable l : line; constant log_file_name : string := get_file_name(log_handler); - procedure log_to_line(variable l : inout line) is - variable use_color : boolean := get(log_handler.p_data, use_color_idx) = 1; - - procedure pad(variable l : inout line; len : integer) is - begin - if len > 0 then - write(l, string'(1 to len => ' ')); - end if; - end; - - procedure write_time(variable l : inout line; justify : boolean := false) is - constant time_string : string := time'image(log_time); - begin - if justify then - pad(l, max_time_length - time_string'length); - end if; - - if use_color then - write(l, color_start(fg => lightcyan)); - end if; - - write(l, time_string); - - if use_color then - write(l, color_end); - end if; - end procedure; - - procedure write_level(variable l : inout line; justify : boolean := false) is - constant level_name : string := get_name(log_level); - variable color : ansi_colors_t; - begin - if justify then - pad(l, max_level_length - level_name'length); - end if; - - if use_color then - color := get_color(log_level); - write(l, color_start(fg => color.fg, bg => color.bg, style => color.style)); - end if; - - write(l, upper(level_name)); - - if use_color then - write(l, color_end); - end if; - end; - - procedure write_source(variable l : inout line; justify : boolean := false) is - begin - if use_color then - write(l, color_start(fg => white, style => bright)); - - for i in logger_name 'range loop - if logger_name(i) = ':' then - write(l, color_start(fg => lightcyan, style => bright)); - write(l, logger_name(i)); - write(l, color_start(fg => white, style => bright)); - else - write(l, logger_name(i)); - end if; - end loop; - else - write(l, logger_name); - end if; - - if use_color then - write(l, color_end); - end if; - - if justify then - pad(l, get_max_logger_name_length(log_handler) - logger_name'length); - end if; - - end; - - procedure write_location(variable l : inout line) is - begin - if file_name /= "" then - write(l, " (" & file_name & ":" & integer'image(line_num) & ")"); - end if; - end; - - procedure write_message(variable l : inout line; multi_line_align : boolean := false) is - variable prefix_len : natural; - variable location_written : boolean := false; - begin - if not multi_line_align then - write(l, msg); - else - prefix_len := length_without_color(l.all); - for i in msg'range loop - - if msg(i) = LF and not location_written then - location_written := true; - write_location(l); - end if; - - write(l, msg(i)); - - if msg(i) = LF then - write(l, string'(1 to prefix_len => ' ')); - end if; - end loop; - end if; - - if not location_written then - write_location(l); - end if; - - end procedure; - - constant format : log_format_t := log_format_t'val(get(log_handler.p_data, format_idx)); - begin - case format is - when raw => - write_message(l); - - when csv => - write(l, string'(integer'image(sequence_number) & ',')); - write_time(l); - write(l, ','); - write_level(l); - write(l, ','); - - if line_num = 0 then - write(l, string'(",,")); - else - write(l, file_name); - write(l, ','); - write(l, integer'image(line_num)); - write(l, ','); - end if; - - write_source(l); - write(l, ','); - write(l, msg); - - when level => - write_level(l, justify => true); - write(l, string'(" - ")); - write_message(l, multi_line_align => true); - - when verbose => - write_time(l, justify => true); - write(l, string'(" - ")); - write_source(l, justify => true); - write(l, string'(" - ")); - write_level(l, justify => true); - write(l, string'(" - ")); - write_message(l, multi_line_align => true); - end case; - end; - - procedure log_to_file(variable l : inout line) is - file fptr : text; - variable status : file_open_status; - begin - file_open(status, fptr, log_file_name, append_mode); - assert_status(status, log_file_name); - writeline(fptr, l); - file_close(fptr); - end; - begin if log_file_name = null_file_name then null; elsif log_file_name = stdout_file_name then - log_to_line(l); - writeline(OUTPUT, l); + write_to_log(OUTPUT, msg, log_time, log_level_t'image(log_level), logger_name, + val_1 => get(log_handler.p_data, format_idx), str_1 => file_name, + val_2 => line_num, val_3 => sequence_number, val_4 => get(log_handler.p_data, use_color_idx), + val_5 => get_max_logger_name_length(log_handler)); else - log_to_line(l); - writeline(to_file_id(get(log_handler.p_data, file_id_idx)), l); + write_to_log(to_file_id(get(log_handler.p_data, file_id_idx)), msg, log_time, log_level_t'image(log_level), logger_name, + val_1 => get(log_handler.p_data, format_idx), str_1 => file_name, + val_2 => line_num, val_3 => sequence_number, val_4 => get(log_handler.p_data, use_color_idx), + val_5 => get_max_logger_name_length(log_handler)); end if; end;