| @ -0,0 +1,672 @@ | |||
| -- | |||
| -- File Name: MemoryPkg.vhd | |||
| -- Design Unit Name: MemoryPkg | |||
| -- Revision: STANDARD VERSION | |||
| -- | |||
| -- Maintainer: Jim Lewis email: jim@synthworks.com | |||
| -- Contributor(s): | |||
| -- Jim Lewis email: jim@synthworks.com | |||
| -- | |||
| -- Description | |||
| -- Package defines a protected type, MemoryPType, and methods | |||
| -- for efficiently implementing memory data structures | |||
| -- | |||
| -- Developed for: | |||
| -- SynthWorks Design Inc. | |||
| -- VHDL Training Classes | |||
| -- 11898 SW 128th Ave. Tigard, Or 97223 | |||
| -- http://www.SynthWorks.com | |||
| -- | |||
| -- Revision History: | |||
| -- Date Version Description | |||
| -- 05/2005: 0.1 Initial revision | |||
| -- 06/2015: 2015.06 Updated for Alerts, ... | |||
| -- Numerous revisions for VHDL Testbenches and Verification | |||
| -- 01/2016: 2016.01 Update for buf.all(buf'left) | |||
| -- 11/2016: 2016.11 Refinement to MemRead to return value, X (if X), U (if not initialized) | |||
| -- | |||
| -- | |||
| -- Copyright (c) 2005 - 2016 by SynthWorks Design Inc. All rights reserved. | |||
| -- | |||
| -- Verbatim copies of this source file may be used and | |||
| -- distributed without restriction. | |||
| -- | |||
| -- This source file is free software; you can redistribute it | |||
| -- and/or modify it under the terms of the ARTISTIC License | |||
| -- as published by The Perl Foundation; either version 2.0 of | |||
| -- the License, or (at your option) any later version. | |||
| -- | |||
| -- This source is distributed in the hope that it will be | |||
| -- useful, but WITHOUT ANY WARRANTY; without even the implied | |||
| -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||
| -- PURPOSE. See the Artistic License for details. | |||
| -- | |||
| -- You should have received a copy of the license with this source. | |||
| -- If not download it from, | |||
| -- http://www.perlfoundation.org/artistic_license_2_0 | |||
| -- | |||
| use std.textio.all ; | |||
| library IEEE ; | |||
| use IEEE.std_logic_1164.all ; | |||
| use IEEE.numeric_std.all ; | |||
| use IEEE.numeric_std_unsigned.all ; | |||
| use IEEE.math_real.all ; | |||
| use work.TextUtilPkg.all ; | |||
| use work.TranscriptPkg.all ; | |||
| use work.AlertLogPkg.all ; | |||
| package MemoryPkg is | |||
| type MemoryPType is protected | |||
| ------------------------------------------------------------ | |||
| procedure MemInit ( AddrWidth, DataWidth : in integer ) ; | |||
| ------------------------------------------------------------ | |||
| procedure MemWrite ( Addr, Data : in std_logic_vector ) ; | |||
| ------------------------------------------------------------ | |||
| procedure MemRead ( | |||
| Addr : in std_logic_vector ; | |||
| Data : out std_logic_vector | |||
| ) ; | |||
| impure function MemRead ( Addr : std_logic_vector ) return std_logic_vector ; | |||
| ------------------------------------------------------------ | |||
| procedure MemErase ; | |||
| procedure deallocate ; | |||
| ------------------------------------------------------------ | |||
| procedure SetAlertLogID (A : AlertLogIDType) ; | |||
| procedure SetAlertLogID (Name : string ; ParentID : AlertLogIDType := ALERTLOG_BASE_ID ; CreateHierarchy : Boolean := TRUE) ; | |||
| impure function GetAlertLogID return AlertLogIDType ; | |||
| ------------------------------------------------------------ | |||
| procedure FileReadH ( -- Hexadecimal File Read | |||
| FileName : string ; | |||
| StartAddr : std_logic_vector ; | |||
| EndAddr : std_logic_vector | |||
| ) ; | |||
| procedure FileReadH (FileName : string ; StartAddr : std_logic_vector) ; | |||
| procedure FileReadH (FileName : string) ; | |||
| ------------------------------------------------------------ | |||
| procedure FileReadB ( -- Binary File Read | |||
| FileName : string ; | |||
| StartAddr : std_logic_vector ; | |||
| EndAddr : std_logic_vector | |||
| ) ; | |||
| procedure FileReadB (FileName : string ; StartAddr : std_logic_vector) ; | |||
| procedure FileReadB (FileName : string) ; | |||
| ------------------------------------------------------------ | |||
| procedure FileWriteH ( -- Hexadecimal File Write | |||
| FileName : string ; | |||
| StartAddr : std_logic_vector ; | |||
| EndAddr : std_logic_vector | |||
| ) ; | |||
| procedure FileWriteH (FileName : string ; StartAddr : std_logic_vector) ; | |||
| procedure FileWriteH (FileName : string) ; | |||
| ------------------------------------------------------------ | |||
| procedure FileWriteB ( -- Binary File Write | |||
| FileName : string ; | |||
| StartAddr : std_logic_vector ; | |||
| EndAddr : std_logic_vector | |||
| ) ; | |||
| procedure FileWriteB (FileName : string ; StartAddr : std_logic_vector) ; | |||
| procedure FileWriteB (FileName : string) ; | |||
| end protected MemoryPType ; | |||
| end MemoryPkg ; | |||
| package body MemoryPkg is | |||
| constant BLOCK_WIDTH : integer := 10 ; | |||
| type MemoryPType is protected body | |||
| type MemBlockType is array (integer range <>) of integer ; | |||
| type MemBlockPtrType is access MemBlockType ; | |||
| type MemArrayType is array (integer range <>) of MemBlockPtrType ; | |||
| type ArrayPtrVarType is access MemArrayType ; | |||
| variable ArrayPtrVar : ArrayPtrVarType := NULL ; | |||
| variable AddrWidthVar : integer := -1 ; -- set by MemInit - merges addr length and initialized checks. | |||
| variable DataWidthVar : natural := 1 ; -- set by MemInit | |||
| variable BlockkWidthVar : natural := 0 ; -- set by MemInit | |||
| variable AlertLogIDVar : AlertLogIDType := OSVVM_ALERTLOG_ID ; | |||
| type FileFormatType is (BINARY, HEX) ; | |||
| ------------------------------------------------------------ | |||
| procedure MemInit ( AddrWidth, DataWidth : In integer ) is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| if AddrWidth <= 0 then | |||
| Alert(AlertLogIDVar, "MemoryPType.MemInit. AddrWidth = " & to_string(AddrWidth) & " must be > 0.", FAILURE) ; | |||
| return ; | |||
| end if ; | |||
| if DataWidth <= 0 then | |||
| Alert(AlertLogIDVar, "MemoryPType.MemInit. DataWidth = " & to_string(DataWidth) & " must be > 0.", FAILURE) ; | |||
| return ; | |||
| end if ; | |||
| AddrWidthVar := AddrWidth ; | |||
| DataWidthVar := DataWidth ; | |||
| BlockkWidthVar := minimum(BLOCK_WIDTH, AddrWidth) ; | |||
| ArrayPtrVar := new MemArrayType(0 to 2**(AddrWidth-BlockkWidthVar)-1) ; | |||
| end procedure MemInit ; | |||
| ------------------------------------------------------------ | |||
| procedure MemWrite ( Addr, Data : in std_logic_vector ) is | |||
| ------------------------------------------------------------ | |||
| variable BlockAddr, WordAddr : integer ; | |||
| alias aAddr : std_logic_vector (Addr'length-1 downto 0) is Addr ; | |||
| begin | |||
| -- Check Bounds of Address and if memory is initialized | |||
| if Addr'length /= AddrWidthVar then | |||
| if (ArrayPtrVar = NULL) then | |||
| Alert(AlertLogIDVar, "MemoryPType.MemWrite: Memory not initialized, Write Ignored.", FAILURE) ; | |||
| else | |||
| Alert(AlertLogIDVar, "MemoryPType.MemWrite: Addr'length: " & to_string(Addr'length) & " /= Memory Address Width: " & to_string(AddrWidthVar), FAILURE) ; | |||
| end if ; | |||
| return ; | |||
| end if ; | |||
| -- Check Bounds on Data | |||
| if Data'length /= DataWidthVar then | |||
| Alert(AlertLogIDVar, "MemoryPType.MemWrite: Data'length: " & to_string(Data'length) & " /= Memory Data Width: " & to_string(DataWidthVar), FAILURE) ; | |||
| return ; | |||
| end if ; | |||
| if is_X( Addr ) then | |||
| Alert(AlertLogIDVar, "MemoryPType.MemWrite: Address X, Write Ignored.") ; | |||
| return ; | |||
| end if ; | |||
| -- Slice out upper address to form block address | |||
| if aAddr'high >= BlockkWidthVar then | |||
| BlockAddr := to_integer(aAddr(aAddr'high downto BlockkWidthVar)) ; | |||
| else | |||
| BlockAddr := 0 ; | |||
| end if ; | |||
| -- If empty, allocate a memory block | |||
| if (ArrayPtrVar(BlockAddr) = NULL) then | |||
| ArrayPtrVar(BlockAddr) := new MemBlockType(0 to 2**BlockkWidthVar-1) ; | |||
| end if ; | |||
| -- Address of a word within a block | |||
| WordAddr := to_integer(aAddr(BlockkWidthVar -1 downto 0)) ; | |||
| -- Write to BlockAddr, WordAddr | |||
| if (Is_X(Data)) then | |||
| ArrayPtrVar(BlockAddr)(WordAddr) := -1 ; | |||
| else | |||
| ArrayPtrVar(BlockAddr)(WordAddr) := to_integer( Data ) ; | |||
| end if ; | |||
| end procedure MemWrite ; | |||
| ------------------------------------------------------------ | |||
| procedure MemRead ( | |||
| ------------------------------------------------------------ | |||
| Addr : In std_logic_vector ; | |||
| Data : Out std_logic_vector | |||
| ) is | |||
| variable BlockAddr, WordAddr : integer ; | |||
| alias aAddr : std_logic_vector (Addr'length-1 downto 0) is Addr ; | |||
| begin | |||
| -- Check Bounds of Address and if memory is initialized | |||
| if Addr'length /= AddrWidthVar then | |||
| if (ArrayPtrVar = NULL) then | |||
| Alert(AlertLogIDVar, "MemoryPType.MemRead: Memory not initialized. Returning U", FAILURE) ; | |||
| else | |||
| Alert(AlertLogIDVar, "MemoryPType.MemRead: Addr'length: " & to_string(Addr'length) & " /= Memory Address Width: " & to_string(AddrWidthVar), FAILURE) ; | |||
| end if ; | |||
| Data := (Data'range => 'U') ; | |||
| return ; | |||
| end if ; | |||
| -- Check Bounds on Data | |||
| if Data'length /= DataWidthVar then | |||
| Alert(AlertLogIDVar, "MemoryPType.MemRead: Data'length: " & to_string(Data'length) & " /= Memory Data Width: " & to_string(DataWidthVar), FAILURE) ; | |||
| Data := (Data'range => 'U') ; | |||
| return ; | |||
| end if ; | |||
| -- If Addr X, data = X | |||
| if is_X( aAddr ) then | |||
| Data := (Data'range => 'X') ; | |||
| return ; | |||
| end if ; | |||
| -- Slice out upper address to form block address | |||
| if aAddr'high >= BlockkWidthVar then | |||
| BlockAddr := to_integer(aAddr(aAddr'high downto BlockkWidthVar)) ; | |||
| else | |||
| BlockAddr := 0 ; | |||
| end if ; | |||
| -- Empty Block, return all U | |||
| if (ArrayPtrVar(BlockAddr) = NULL) then | |||
| Data := (Data'range => 'U') ; | |||
| return ; | |||
| end if ; | |||
| -- Address of a word within a block | |||
| WordAddr := to_integer(aAddr(BlockkWidthVar -1 downto 0)) ; | |||
| if ArrayPtrVar(BlockAddr)(WordAddr) >= 0 then | |||
| -- Get the Word from the Array | |||
| Data := to_slv(ArrayPtrVar(BlockAddr)(WordAddr), Data'length) ; | |||
| elsif ArrayPtrVar(BlockAddr)(WordAddr) = -1 then | |||
| -- X in Word, return all X | |||
| Data := (Data'range => 'X') ; | |||
| else | |||
| -- Location Uninitialized, return all X | |||
| Data := (Data'range => 'U') ; | |||
| end if ; | |||
| end procedure MemRead ; | |||
| ------------------------------------------------------------ | |||
| impure function MemRead ( Addr : std_logic_vector ) return std_logic_vector is | |||
| ------------------------------------------------------------ | |||
| variable BlockAddr, WordAddr : integer ; | |||
| alias aAddr : std_logic_vector (Addr'length-1 downto 0) is Addr ; | |||
| variable Data : std_logic_vector(DataWidthVar-1 downto 0) ; | |||
| begin | |||
| MemRead(Addr, Data) ; | |||
| return Data ; | |||
| end function MemRead ; | |||
| ------------------------------------------------------------ | |||
| procedure MemErase is | |||
| -- Deallocate the memory, but not the array of pointers | |||
| ------------------------------------------------------------ | |||
| begin | |||
| for BlockAddr in ArrayPtrVar'range loop | |||
| if (ArrayPtrVar(BlockAddr) /= NULL) then | |||
| deallocate (ArrayPtrVar(BlockAddr)) ; | |||
| end if ; | |||
| end loop ; | |||
| end procedure ; | |||
| ------------------------------------------------------------ | |||
| procedure deallocate is | |||
| -- Deallocate all allocated memory | |||
| ------------------------------------------------------------ | |||
| begin | |||
| MemErase ; | |||
| deallocate(ArrayPtrVar) ; | |||
| AddrWidthVar := -1 ; | |||
| DataWidthVar := 1 ; | |||
| BlockkWidthVar := 0 ; | |||
| end procedure ; | |||
| ------------------------------------------------------------ | |||
| procedure SetAlertLogID (A : AlertLogIDType) is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| AlertLogIDVar := A ; | |||
| end procedure SetAlertLogID ; | |||
| ------------------------------------------------------------ | |||
| procedure SetAlertLogID(Name : string ; ParentID : AlertLogIDType := ALERTLOG_BASE_ID ; CreateHierarchy : Boolean := TRUE) is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| AlertLogIDVar := GetAlertLogID(Name, ParentID, CreateHierarchy) ; | |||
| end procedure SetAlertLogID ; | |||
| ------------------------------------------------------------ | |||
| impure function GetAlertLogID return AlertLogIDType is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return AlertLogIDVar ; | |||
| end function GetAlertLogID ; | |||
| ------------------------------------------------------------ | |||
| -- PT Local | |||
| procedure FileReadX ( | |||
| -- Hexadecimal or Binary File Read | |||
| ------------------------------------------------------------ | |||
| FileName : string ; | |||
| DataFormat : FileFormatType ; | |||
| StartAddr : std_logic_vector ; | |||
| EndAddr : std_logic_vector | |||
| ) is | |||
| -- Format: | |||
| -- @hh..h -- Address in hex | |||
| -- hhh_XX_ZZ -- data values in hex - space delimited | |||
| -- "--" or "//" -- comments | |||
| file MemFile : text open READ_MODE is FileName ; | |||
| variable Addr : std_logic_vector(AddrWidthVar - 1 downto 0) ; | |||
| variable SmallAddr : std_logic_vector(AddrWidthVar - 1 downto 0) ; | |||
| variable BigAddr : std_logic_vector(AddrWidthVar - 1 downto 0) ; | |||
| variable Data : std_logic_vector(DataWidthVar - 1 downto 0) ; | |||
| variable LineNum : natural ; | |||
| variable ItemNum : natural ; | |||
| variable AddrInc : std_logic_vector(AddrWidthVar - 1 downto 0) ; | |||
| variable buf : line ; | |||
| variable ReadValid : boolean ; | |||
| variable Empty : boolean ; | |||
| variable MultiLineComment : boolean ; | |||
| variable NextChar : character ; | |||
| variable StrLen : integer ; | |||
| begin | |||
| MultiLineComment := FALSE ; | |||
| if StartAddr'length /= AddrWidthVar and EndAddr'length /= AddrWidthVar then | |||
| if (ArrayPtrVar = NULL) then | |||
| Alert(AlertLogIDVar, "MemoryPType.FileReadX: Memory not initialized, FileRead Ignored.", FAILURE) ; | |||
| else | |||
| Alert(AlertLogIDVar, "MemoryPType.FileReadX: Addr'length: " & to_string(Addr'length) & " /= Memory Address Width: " & to_string(AddrWidthVar), FAILURE) ; | |||
| end if ; | |||
| return ; | |||
| end if ; | |||
| Addr := StartAddr ; | |||
| LineNum := 0 ; | |||
| if StartAddr <= EndAddr then | |||
| SmallAddr := StartAddr ; | |||
| BigAddr := EndAddr ; | |||
| AddrInc := (AddrWidthVar -1 downto 0 => '0') + 1 ; | |||
| else | |||
| SmallAddr := EndAddr ; | |||
| BigAddr := StartAddr ; | |||
| AddrInc := (others => '1') ; -- -1 | |||
| end if; | |||
| ReadLineLoop : while not EndFile(MemFile) loop | |||
| ReadLine(MemFile, buf) ; | |||
| LineNum := LineNum + 1 ; | |||
| ItemNum := 0 ; | |||
| ItemLoop : loop | |||
| EmptyOrCommentLine(buf, Empty, MultiLineComment) ; | |||
| exit ItemLoop when Empty ; | |||
| ItemNum := ItemNum + 1 ; | |||
| NextChar := buf.all(buf'left) ; | |||
| if (NextChar = '@') then | |||
| -- Get Address | |||
| read(buf, NextChar) ; | |||
| ReadHexToken(buf, Addr, StrLen) ; | |||
| exit ReadLineLoop when AlertIf(AlertLogIDVar, StrLen = 0, "MemoryPType.FileReadX: Address length 0 on line: " & to_string(LineNum), FAILURE) ; | |||
| exit ItemLoop when AlertIf(AlertLogIDVar, Addr < SmallAddr, | |||
| "MemoryPType.FileReadX: Address in file: " & to_hstring(Addr) & | |||
| " < StartAddr: " & to_hstring(StartAddr) & " on line: " & to_string(LineNum)) ; | |||
| exit ItemLoop when AlertIf(AlertLogIDVar, Addr > BigAddr, | |||
| "MemoryPType.FileReadX: Address in file: " & to_hstring(Addr) & | |||
| " > EndAddr: " & to_hstring(BigAddr) & " on line: " & to_string(LineNum)) ; | |||
| elsif DataFormat = HEX and ishex(NextChar) then | |||
| -- Get Hex Data | |||
| ReadHexToken(buf, data, StrLen) ; | |||
| exit ReadLineLoop when AlertIfNot(AlertLogIDVar, StrLen > 0, | |||
| "MemoryPType.FileReadH: Error while reading data on line: " & to_string(LineNum) & | |||
| " Item number: " & to_string(ItemNum), FAILURE) ; | |||
| log("MemoryPType.FileReadX: MemWrite(Addr => " & to_hstring(Addr) & ", Data => " & to_hstring(Data) & ")", DEBUG) ; | |||
| MemWrite(Addr, data) ; | |||
| Addr := Addr + AddrInc ; | |||
| elsif DataFormat = BINARY and isstd_logic(NextChar) then | |||
| -- Get Binary Data | |||
| -- read(buf, data, ReadValid) ; | |||
| ReadBinaryToken(buf, data, StrLen) ; | |||
| -- exit ReadLineLoop when AlertIfNot(AlertLogIDVar, ReadValid, | |||
| exit ReadLineLoop when AlertIfNot(AlertLogIDVar, StrLen > 0, | |||
| "MemoryPType.FileReadB: Error while reading data on line: " & to_string(LineNum) & | |||
| " Item number: " & to_string(ItemNum), FAILURE) ; | |||
| log("MemoryPType.FileReadX: MemWrite(Addr => " & to_hstring(Addr) & ", Data => " & to_string(Data) & ")", DEBUG) ; | |||
| MemWrite(Addr, data) ; | |||
| Addr := Addr + AddrInc ; | |||
| else | |||
| -- Invalid Text, Issue Warning and skip it | |||
| Alert(AlertLogIDVar, | |||
| "MemoryPType.FileReadX: Invalid text on line: " & to_string(LineNum) & | |||
| " Item: " & to_string(ItemNum) & ". Skipping text: " & buf.all) ; | |||
| exit ItemLoop ; | |||
| end if ; | |||
| end loop ItemLoop ; | |||
| end loop ReadLineLoop ; | |||
| -- -- must read EndAddr-StartAddr number of words if both start and end specified | |||
| -- if (StartAddr /= 0 or (not EndAddr) /= 0) and (Addr /= EndAddr) then | |||
| -- Alert("MemoryPType.FileReadH: insufficient data values", WARNING) ; | |||
| -- end if ; | |||
| file_close(MemFile) ; | |||
| end FileReadX ; | |||
| ------------------------------------------------------------ | |||
| procedure FileReadH ( | |||
| -- Hexadecimal File Read | |||
| ------------------------------------------------------------ | |||
| FileName : string ; | |||
| StartAddr : std_logic_vector ; | |||
| EndAddr : std_logic_vector | |||
| ) is | |||
| begin | |||
| FileReadX(FileName, HEX, StartAddr, EndAddr) ; | |||
| end FileReadH ; | |||
| ------------------------------------------------------------ | |||
| procedure FileReadH (FileName : string ; StartAddr : std_logic_vector) is | |||
| -- Hexadecimal File Read | |||
| ------------------------------------------------------------ | |||
| constant EndAddr : std_logic_vector(AddrWidthVar - 1 downto 0) := (others => '1') ; | |||
| begin | |||
| FileReadX(FileName, HEX, StartAddr, EndAddr) ; | |||
| end FileReadH ; | |||
| ------------------------------------------------------------ | |||
| procedure FileReadH (FileName : string) is | |||
| -- Hexadecimal File Read | |||
| ------------------------------------------------------------ | |||
| constant StartAddr : std_logic_vector(AddrWidthVar - 1 downto 0) := (others => '0') ; | |||
| constant EndAddr : std_logic_vector(AddrWidthVar - 1 downto 0) := (others => '1') ; | |||
| begin | |||
| FileReadX(FileName, HEX, StartAddr, EndAddr) ; | |||
| end FileReadH ; | |||
| ------------------------------------------------------------ | |||
| procedure FileReadB ( | |||
| -- Binary File Read | |||
| ------------------------------------------------------------ | |||
| FileName : string ; | |||
| StartAddr : std_logic_vector ; | |||
| EndAddr : std_logic_vector | |||
| ) is | |||
| begin | |||
| FileReadX(FileName, BINARY, StartAddr, EndAddr) ; | |||
| end FileReadB ; | |||
| ------------------------------------------------------------ | |||
| procedure FileReadB (FileName : string ; StartAddr : std_logic_vector) is | |||
| -- Binary File Read | |||
| ------------------------------------------------------------ | |||
| constant EndAddr : std_logic_vector(AddrWidthVar - 1 downto 0) := (others => '1') ; | |||
| begin | |||
| FileReadX(FileName, BINARY, StartAddr, EndAddr) ; | |||
| end FileReadB ; | |||
| ------------------------------------------------------------ | |||
| procedure FileReadB (FileName : string) is | |||
| -- Binary File Read | |||
| ------------------------------------------------------------ | |||
| constant StartAddr : std_logic_vector(AddrWidthVar - 1 downto 0) := (others => '0') ; | |||
| constant EndAddr : std_logic_vector(AddrWidthVar - 1 downto 0) := (others => '1') ; | |||
| begin | |||
| FileReadX(FileName, BINARY, StartAddr, EndAddr) ; | |||
| end FileReadB ; | |||
| ------------------------------------------------------------ | |||
| -- PT Local | |||
| procedure FileWriteX ( | |||
| -- Hexadecimal or Binary File Write | |||
| ------------------------------------------------------------ | |||
| FileName : string ; | |||
| DataFormat : FileFormatType ; | |||
| StartAddr : std_logic_vector ; | |||
| EndAddr : std_logic_vector | |||
| ) is | |||
| -- Format: | |||
| -- @hh..h -- Address in hex | |||
| -- hhhhh -- data one per line in either hex or binary as specified | |||
| file MemFile : text open WRITE_MODE is FileName ; | |||
| alias normStartAddr : std_logic_vector(StartAddr'length-1 downto 0) is StartAddr ; | |||
| alias normEndAddr : std_logic_vector(EndAddr'length-1 downto 0) is EndAddr ; | |||
| variable StartBlockAddr : natural ; | |||
| variable EndBlockAddr : natural ; | |||
| variable StartWordAddr : natural ; | |||
| variable EndWordAddr : natural ; | |||
| variable Data : std_logic_vector(DataWidthVar - 1 downto 0) ; | |||
| variable FoundData : boolean ; | |||
| variable buf : line ; | |||
| begin | |||
| if StartAddr'length /= AddrWidthVar and EndAddr'length /= AddrWidthVar then | |||
| -- Check StartAddr and EndAddr Widths and Memory not initialized | |||
| if (ArrayPtrVar = NULL) then | |||
| Alert(AlertLogIDVar, "MemoryPType.FileWriteX: Memory not initialized, FileRead Ignored.", FAILURE) ; | |||
| else | |||
| AlertIf(AlertLogIDVar, StartAddr'length /= AddrWidthVar, "MemoryPType.FileWriteX: StartAddr'length: " | |||
| & to_string(StartAddr'length) & | |||
| " /= Memory Address Width: " & to_string(AddrWidthVar), FAILURE) ; | |||
| AlertIf(AlertLogIDVar, EndAddr'length /= AddrWidthVar, "MemoryPType.FileWriteX: EndAddr'length: " | |||
| & to_string(EndAddr'length) & | |||
| " /= Memory Address Width: " & to_string(AddrWidthVar), FAILURE) ; | |||
| end if ; | |||
| return ; | |||
| end if ; | |||
| if StartAddr > EndAddr then | |||
| -- Only support ascending addresses | |||
| Alert(AlertLogIDVar, "MemoryPType.FileWriteX: StartAddr: " & to_hstring(StartAddr) & | |||
| " > EndAddr: " & to_hstring(EndAddr), FAILURE) ; | |||
| return ; | |||
| end if ; | |||
| -- Slice out upper address to form block address | |||
| if AddrWidthVar >= BlockkWidthVar then | |||
| StartBlockAddr := to_integer(normStartAddr(AddrWidthVar-1 downto BlockkWidthVar)) ; | |||
| EndBlockAddr := to_integer( normEndAddr(AddrWidthVar-1 downto BlockkWidthVar)) ; | |||
| else | |||
| StartBlockAddr := 0 ; | |||
| EndBlockAddr := 0 ; | |||
| end if ; | |||
| BlockAddrLoop : for BlockAddr in StartBlockAddr to EndBlockAddr loop | |||
| next BlockAddrLoop when ArrayPtrVar(BlockAddr) = NULL ; | |||
| if BlockAddr = StartBlockAddr then | |||
| StartWordAddr := to_integer(normStartAddr(BlockkWidthVar-1 downto 0)) ; | |||
| else | |||
| StartWordAddr := 0 ; | |||
| end if ; | |||
| if BlockAddr = EndBlockAddr then | |||
| EndWordAddr := to_integer(normEndAddr(BlockkWidthVar-1 downto 0)) ; | |||
| else | |||
| EndWordAddr := 2**BlockkWidthVar-1 ; | |||
| end if ; | |||
| FoundData := FALSE ; | |||
| WordAddrLoop : for WordAddr in StartWordAddr to EndWordAddr loop | |||
| if (ArrayPtrVar(BlockAddr)(WordAddr) < 0) then | |||
| -- X in Word, return all X | |||
| Data := (Data'range => 'X') ; | |||
| FoundData := FALSE ; | |||
| else | |||
| -- Get the Word from the Array | |||
| Data := to_slv(ArrayPtrVar(BlockAddr)(WordAddr), Data'length) ; | |||
| if not FoundData then | |||
| -- Write Address | |||
| write(buf, '@') ; | |||
| hwrite(buf, to_slv(BlockAddr, AddrWidthVar-BlockkWidthVar) & to_slv(WordAddr, BlockkWidthVar)) ; | |||
| writeline(MemFile, buf) ; | |||
| end if ; | |||
| FoundData := TRUE ; | |||
| end if ; | |||
| if FoundData then -- Write Data | |||
| if DataFormat = HEX then | |||
| hwrite(buf, Data) ; | |||
| writeline(MemFile, buf) ; | |||
| else | |||
| write(buf, Data) ; | |||
| writeline(MemFile, buf) ; | |||
| end if; | |||
| end if ; | |||
| end loop WordAddrLoop ; | |||
| end loop BlockAddrLoop ; | |||
| file_close(MemFile) ; | |||
| end FileWriteX ; | |||
| ------------------------------------------------------------ | |||
| procedure FileWriteH ( | |||
| -- Hexadecimal File Write | |||
| ------------------------------------------------------------ | |||
| FileName : string ; | |||
| StartAddr : std_logic_vector ; | |||
| EndAddr : std_logic_vector | |||
| ) is | |||
| begin | |||
| FileWriteX(FileName, HEX, StartAddr, EndAddr) ; | |||
| end FileWriteH ; | |||
| ------------------------------------------------------------ | |||
| procedure FileWriteH (FileName : string ; StartAddr : std_logic_vector) is | |||
| -- Hexadecimal File Write | |||
| ------------------------------------------------------------ | |||
| constant EndAddr : std_logic_vector(AddrWidthVar - 1 downto 0) := (others => '1') ; | |||
| begin | |||
| FileWriteX(FileName, HEX, StartAddr, EndAddr) ; | |||
| end FileWriteH ; | |||
| ------------------------------------------------------------ | |||
| procedure FileWriteH (FileName : string) is | |||
| -- Hexadecimal File Write | |||
| ------------------------------------------------------------ | |||
| constant StartAddr : std_logic_vector(AddrWidthVar - 1 downto 0) := (others => '0') ; | |||
| constant EndAddr : std_logic_vector(AddrWidthVar - 1 downto 0) := (others => '1') ; | |||
| begin | |||
| FileWriteX(FileName, HEX, StartAddr, EndAddr) ; | |||
| end FileWriteH ; | |||
| ------------------------------------------------------------ | |||
| procedure FileWriteB ( | |||
| -- Binary File Write | |||
| ------------------------------------------------------------ | |||
| FileName : string ; | |||
| StartAddr : std_logic_vector ; | |||
| EndAddr : std_logic_vector | |||
| ) is | |||
| begin | |||
| FileWriteX(FileName, BINARY, StartAddr, EndAddr) ; | |||
| end FileWriteB ; | |||
| ------------------------------------------------------------ | |||
| procedure FileWriteB (FileName : string ; StartAddr : std_logic_vector) is | |||
| -- Binary File Write | |||
| ------------------------------------------------------------ | |||
| constant EndAddr : std_logic_vector(AddrWidthVar - 1 downto 0) := (others => '1') ; | |||
| begin | |||
| FileWriteX(FileName, BINARY, StartAddr, EndAddr) ; | |||
| end FileWriteB ; | |||
| ------------------------------------------------------------ | |||
| procedure FileWriteB (FileName : string) is | |||
| -- Binary File Write | |||
| ------------------------------------------------------------ | |||
| constant StartAddr : std_logic_vector(AddrWidthVar - 1 downto 0) := (others => '0') ; | |||
| constant EndAddr : std_logic_vector(AddrWidthVar - 1 downto 0) := (others => '1') ; | |||
| begin | |||
| FileWriteX(FileName, BINARY, StartAddr, EndAddr) ; | |||
| end FileWriteB ; | |||
| end protected body MemoryPType ; | |||
| end MemoryPkg ; | |||
| @ -0,0 +1,129 @@ | |||
| -- | |||
| -- File Name: NamePkg.vhd | |||
| -- Design Unit Name: NamePkg | |||
| -- Revision: STANDARD VERSION | |||
| -- | |||
| -- Maintainer: Jim Lewis email: jim@synthworks.com | |||
| -- Contributor(s): | |||
| -- Jim Lewis SynthWorks | |||
| -- | |||
| -- | |||
| -- Package Defines | |||
| -- Data structure for name. | |||
| -- | |||
| -- Developed for: | |||
| -- SynthWorks Design Inc. | |||
| -- VHDL Training Classes | |||
| -- 11898 SW 128th Ave. Tigard, Or 97223 | |||
| -- http://www.SynthWorks.com | |||
| -- | |||
| -- Latest standard version available at: | |||
| -- http://www.SynthWorks.com/downloads | |||
| -- | |||
| -- Revision History: | |||
| -- Date Version Description | |||
| -- 06/2010: 0.1 Initial revision | |||
| -- 07/2014: 2014.07 Moved specialization required by CoveragePkg to CoveragePkg | |||
| -- Separated name handling from message handling to simplify naming | |||
| -- 12/2014: 2014.07a Removed initialized pointers which can lead to memory leaks. | |||
| -- 05/2015 2015.06 Added input to Get to return when not initialized | |||
| -- | |||
| -- | |||
| -- Copyright (c) 2010 - 2015 by SynthWorks Design Inc. All rights reserved. | |||
| -- | |||
| -- Verbatim copies of this source file may be used and | |||
| -- distributed without restriction. | |||
| -- | |||
| -- This source file is free software; you can redistribute it | |||
| -- and/or modify it under the terms of the ARTISTIC License | |||
| -- as published by The Perl Foundation; either version 2.0 of | |||
| -- the License, or (at your option) any later version. | |||
| -- | |||
| -- This source is distributed in the hope that it will be | |||
| -- useful, but WITHOUT ANY WARRANTY; without even the implied | |||
| -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||
| -- PURPOSE. See the Artistic License for details. | |||
| -- | |||
| -- You should have received a copy of the license with this source. | |||
| -- If not download it from, | |||
| -- http://www.perlfoundation.org/artistic_license_2_0 | |||
| -- | |||
| use std.textio.all ; | |||
| package NamePkg is | |||
| type NamePType is protected | |||
| procedure Set (NameIn : String) ; | |||
| impure function Get (DefaultName : string := "") return string ; | |||
| impure function GetOpt return string ; | |||
| impure function IsSet return boolean ; | |||
| procedure Clear ; -- clear name | |||
| procedure Deallocate ; -- effectively alias to clear name | |||
| end protected NamePType ; | |||
| end package NamePkg ; | |||
| --- /////////////////////////////////////////////////////////////////////////// | |||
| --- /////////////////////////////////////////////////////////////////////////// | |||
| --- /////////////////////////////////////////////////////////////////////////// | |||
| package body NamePkg is | |||
| type NamePType is protected body | |||
| variable NamePtr : line ; | |||
| ------------------------------------------------------------ | |||
| procedure Set (NameIn : String) is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| deallocate(NamePtr) ; | |||
| NamePtr := new string'(NameIn) ; | |||
| end procedure Set ; | |||
| ------------------------------------------------------------ | |||
| impure function Get (DefaultName : string := "") return string is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| if NamePtr = NULL then | |||
| return DefaultName ; | |||
| else | |||
| return NamePtr.all ; | |||
| end if ; | |||
| end function Get ; | |||
| ------------------------------------------------------------ | |||
| impure function GetOpt return string is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| if NamePtr = NULL then | |||
| return NUL & "" ; | |||
| else | |||
| return NamePtr.all ; | |||
| end if ; | |||
| end function GetOpt ; | |||
| ------------------------------------------------------------ | |||
| impure function IsSet return boolean is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return NamePtr /= NULL ; | |||
| end function IsSet ; | |||
| ------------------------------------------------------------ | |||
| procedure Clear is -- clear name | |||
| ------------------------------------------------------------ | |||
| begin | |||
| deallocate(NamePtr) ; | |||
| end procedure Clear ; | |||
| ------------------------------------------------------------ | |||
| procedure Deallocate is -- clear name | |||
| ------------------------------------------------------------ | |||
| begin | |||
| Clear ; | |||
| end procedure Deallocate ; | |||
| end protected body NamePType ; | |||
| end package body NamePkg ; | |||
| @ -0,0 +1,63 @@ | |||
| -- | |||
| -- File Name: OsvvmContext.vhd | |||
| -- Design Unit Name: OsvvmContext | |||
| -- Revision: STANDARD VERSION | |||
| -- | |||
| -- Maintainer: Jim Lewis email: jim@synthworks.com-- | |||
| -- | |||
| -- Description | |||
| -- Context Declaration for OSVVM packages | |||
| -- | |||
| -- Developed by/for: | |||
| -- SynthWorks Design Inc. | |||
| -- VHDL Training Classes | |||
| -- 11898 SW 128th Ave. Tigard, Or 97223 | |||
| -- http://www.SynthWorks.com | |||
| -- | |||
| -- Latest standard version available at: | |||
| -- http://www.SynthWorks.com/downloads | |||
| -- | |||
| -- Revision History: | |||
| -- Date Version Description | |||
| -- 01/2015 2015.01 Initial Revision | |||
| -- 06/2015 2015.06 Added MemoryPkg | |||
| -- 11/2016 2016.11 Added TbUtilPkg and ResolutionPkg | |||
| -- | |||
| -- | |||
| -- Copyright (c) 2015 - 2016 by SynthWorks Design Inc. All rights reserved. | |||
| -- | |||
| -- Verbatim copies of this source file may be used and | |||
| -- distributed without restriction. | |||
| -- | |||
| -- This source file is free software; you can redistribute it | |||
| -- and/or modify it under the terms of the ARTISTIC License | |||
| -- as published by The Perl Foundation; either version 2.0 of | |||
| -- the License, or (at your option) any later version. | |||
| -- | |||
| -- This source is distributed in the hope that it will be | |||
| -- useful, but WITHOUT ANY WARRANTY; without even the implied | |||
| -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||
| -- PURPOSE. See the Artistic License for details. | |||
| -- | |||
| -- You should have received a copy of the license with this source. | |||
| -- If not download it from, | |||
| -- http://www.perlfoundation.org/artistic_license_2_0 | |||
| -- | |||
| -- | |||
| context OsvvmContext is | |||
| library OSVVM ; | |||
| use OSVVM.NamePkg.all ; | |||
| use OSVVM.TranscriptPkg.all ; | |||
| use OSVVM.TextUtilPkg.all ; | |||
| use OSVVM.OsvvmGlobalPkg.all ; | |||
| use OSVVM.AlertLogPkg.all ; | |||
| use OSVVM.RandomPkg.all ; | |||
| use OSVVM.CoveragePkg.all ; | |||
| use OSVVM.MemoryPkg.all ; | |||
| use OSVVM.ResolutionPkg.all ; | |||
| use OSVVM.TbUtilPkg.all ; | |||
| end context OsvvmContext ; | |||
| @ -0,0 +1,350 @@ | |||
| -- | |||
| -- File Name: OsvvmGlobalPkg.vhd | |||
| -- Design Unit Name: OsvvmGlobalPkg | |||
| -- Revision: STANDARD VERSION, revision 2015.01 | |||
| -- | |||
| -- Maintainer: Jim Lewis email: jim@synthworks.com | |||
| -- Contributor(s): | |||
| -- Jim Lewis jim@synthworks.com | |||
| -- | |||
| -- | |||
| -- Description: | |||
| -- Global Settings for OSVVM packages | |||
| -- | |||
| -- | |||
| -- Developed for: | |||
| -- SynthWorks Design Inc. | |||
| -- VHDL Training Classes | |||
| -- 11898 SW 128th Ave. Tigard, Or 97223 | |||
| -- http://www.SynthWorks.com | |||
| -- | |||
| -- Revision History: | |||
| -- Date Version Description | |||
| -- 01/2014: 2015.01 Initial revision | |||
| -- | |||
| -- | |||
| -- Copyright (c) 2015 by SynthWorks Design Inc. All rights reserved. | |||
| -- | |||
| -- Verbatim copies of this source file may be used and | |||
| -- distributed without restriction. | |||
| -- | |||
| -- This source file is free software; you can redistribute it | |||
| -- and/or modify it under the terms of the ARTISTIC License | |||
| -- as published by The Perl Foundation; either version 2.0 of | |||
| -- the License, or (at your option) any later version. | |||
| -- | |||
| -- This source is distributed in the hope that it will be | |||
| -- useful, but WITHOUT ANY WARRANTY; without even the implied | |||
| -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||
| -- PURPOSE. See the Artistic License for details. | |||
| -- | |||
| -- You should have received a copy of the license with this source. | |||
| -- If not download it from, | |||
| -- http://www.perlfoundation.org/artistic_license_2_0 | |||
| -- | |||
| library ieee ; | |||
| use std.textio.all ; | |||
| use work.NamePkg.all ; | |||
| package OsvvmGlobalPkg is | |||
| -- FILE IO Global File Identifier -- Open using AlertLogPkg.TranscriptOpen | |||
| -- file TranscriptFile : text ; | |||
| -- Shared Options Type used in OSVVM | |||
| type OsvvmOptionsType is (OPT_INIT_PARM_DETECT, OPT_USE_DEFAULT, DISABLED, FALSE, ENABLED, TRUE) ; | |||
| function IsEnabled (A : OsvvmOptionsType) return boolean ; -- Requires that TRUE is last and ENABLED is 2nd to last | |||
| function to_OsvvmOptionsType (A : boolean) return OsvvmOptionsType ; | |||
| -- Defaults for String values | |||
| constant OSVVM_DEFAULT_ALERT_PREFIX : string := "%% Alert" ; | |||
| constant OSVVM_DEFAULT_LOG_PREFIX : string := "%% Log " ; | |||
| constant OSVVM_DEFAULT_WRITE_PREFIX : string := "%% " ; | |||
| constant OSVVM_DEFAULT_DONE_NAME : string := "DONE" ; | |||
| constant OSVVM_DEFAULT_PASS_NAME : string := "PASSED" ; | |||
| constant OSVVM_DEFAULT_FAIL_NAME : string := "FAILED" ; | |||
| constant OSVVM_STRING_INIT_PARM_DETECT : string := NUL & NUL & NUL ; | |||
| constant OSVVM_STRING_USE_DEFAULT : string := NUL & "" ; | |||
| -- Coverage Settings | |||
| constant OSVVM_DEFAULT_WRITE_PASS_FAIL : OsvvmOptionsType := FALSE ; | |||
| constant OSVVM_DEFAULT_WRITE_BIN_INFO : OsvvmOptionsType := TRUE ; | |||
| constant OSVVM_DEFAULT_WRITE_COUNT : OsvvmOptionsType := TRUE ; | |||
| constant OSVVM_DEFAULT_WRITE_ANY_ILLEGAL : OsvvmOptionsType := FALSE ; | |||
| ------------------------------------------------------------ | |||
| procedure SetOsvvmGlobalOptions ( | |||
| ------------------------------------------------------------ | |||
| WritePassFail : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; | |||
| WriteBinInfo : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; | |||
| WriteCount : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; | |||
| WriteAnyIllegal : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; | |||
| WritePrefix : string := OSVVM_STRING_INIT_PARM_DETECT ; | |||
| DoneName : string := OSVVM_STRING_INIT_PARM_DETECT ; | |||
| PassName : string := OSVVM_STRING_INIT_PARM_DETECT ; | |||
| FailName : string := OSVVM_STRING_INIT_PARM_DETECT | |||
| ) ; | |||
| ------------------------------------------------------------ | |||
| -- Accessor Functions | |||
| function ResolveOsvvmOption(A, B, C : OsvvmOptionsType) return OsvvmOptionsType ; | |||
| function ResolveOsvvmOption(A, B, C, D : OsvvmOptionsType) return OsvvmOptionsType ; | |||
| function IsOsvvmStringSet (A : string) return boolean ; | |||
| function ResolveOsvvmOption(A, B : string) return string ; | |||
| function ResolveOsvvmOption(A, B, C : string) return string ; | |||
| function ResolveOsvvmOption(A, B, C, D : string) return string ; | |||
| impure function ResolveOsvvmWritePrefix(A : String) return string ; | |||
| impure function ResolveOsvvmWritePrefix(A, B : String) return string ; | |||
| impure function ResolveOsvvmDoneName(A : String) return string ; | |||
| impure function ResolveOsvvmDoneName(A, B : String) return string ; | |||
| impure function ResolveOsvvmPassName(A : String) return string ; | |||
| impure function ResolveOsvvmPassName(A, B : String) return string ; | |||
| impure function ResolveOsvvmFailName(A : String) return string ; | |||
| impure function ResolveOsvvmFailName(A, B : String) return string ; | |||
| impure function ResolveCovWritePassFail(A, B : OsvvmOptionsType) return OsvvmOptionsType ; -- Cov | |||
| impure function ResolveCovWriteBinInfo(A, B : OsvvmOptionsType) return OsvvmOptionsType ; -- Cov | |||
| impure function ResolveCovWriteCount(A, B : OsvvmOptionsType) return OsvvmOptionsType ; -- Cov | |||
| impure function ResolveCovWriteAnyIllegal(A, B : OsvvmOptionsType) return OsvvmOptionsType ; -- Cov | |||
| procedure OsvvmDeallocate ; | |||
| type OptionsPType is protected | |||
| procedure Set (A: OsvvmOptionsType) ; | |||
| impure function get return OsvvmOptionsType ; | |||
| end protected OptionsPType ; | |||
| end OsvvmGlobalPkg ; | |||
| --- /////////////////////////////////////////////////////////////////////////// | |||
| --- /////////////////////////////////////////////////////////////////////////// | |||
| --- /////////////////////////////////////////////////////////////////////////// | |||
| package body OsvvmGlobalPkg is | |||
| type OptionsPType is protected body | |||
| variable GlobalVar : OsvvmOptionsType ; | |||
| procedure Set (A : OsvvmOptionsType) is | |||
| begin | |||
| GlobalVar := A ; | |||
| end procedure Set ; | |||
| impure function get return OsvvmOptionsType is | |||
| begin | |||
| return GlobalVar ; | |||
| end function get ; | |||
| end protected body OptionsPType ; | |||
| shared variable WritePrefixVar : NamePType ; | |||
| shared variable DoneNameVar : NamePType ; | |||
| shared variable PassNameVar : NamePType ; | |||
| shared variable FailNameVar : NamePType ; | |||
| shared variable WritePassFailVar : OptionsPType ; -- := FALSE ; | |||
| shared variable WriteBinInfoVar : OptionsPType ; -- := TRUE ; | |||
| shared variable WriteCountVar : OptionsPType ; -- := TRUE ; | |||
| shared variable WriteAnyIllegalVar : OptionsPType ; -- := FALSE ; | |||
| function IsEnabled (A : OsvvmOptionsType) return boolean is | |||
| begin | |||
| return A >= ENABLED ; | |||
| end function IsEnabled ; | |||
| function to_OsvvmOptionsType (A : boolean) return OsvvmOptionsType is | |||
| begin | |||
| if A then | |||
| return TRUE ; | |||
| else | |||
| return FALSE ; | |||
| end if ; | |||
| end function to_OsvvmOptionsType ; | |||
| ------------------------------------------------------------ | |||
| procedure SetOsvvmGlobalOptions ( | |||
| ------------------------------------------------------------ | |||
| WritePassFail : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; | |||
| WriteBinInfo : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; | |||
| WriteCount : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; | |||
| WriteAnyIllegal : OsvvmOptionsType := OPT_INIT_PARM_DETECT ; | |||
| WritePrefix : string := OSVVM_STRING_INIT_PARM_DETECT ; | |||
| DoneName : string := OSVVM_STRING_INIT_PARM_DETECT ; | |||
| PassName : string := OSVVM_STRING_INIT_PARM_DETECT ; | |||
| FailName : string := OSVVM_STRING_INIT_PARM_DETECT | |||
| ) is | |||
| begin | |||
| if WritePassFail /= OPT_INIT_PARM_DETECT then | |||
| WritePassFailVar.Set(WritePassFail) ; | |||
| end if ; | |||
| if WriteBinInfo /= OPT_INIT_PARM_DETECT then | |||
| WriteBinInfoVar.Set(WriteBinInfo) ; | |||
| end if ; | |||
| if WriteCount /= OPT_INIT_PARM_DETECT then | |||
| WriteCountVar.Set(WriteCount) ; | |||
| end if ; | |||
| if WriteAnyIllegal /= OPT_INIT_PARM_DETECT then | |||
| WriteAnyIllegalVar.Set(WriteAnyIllegal) ; | |||
| end if ; | |||
| if WritePrefix /= OSVVM_STRING_INIT_PARM_DETECT then | |||
| WritePrefixVar.Set(WritePrefix) ; | |||
| end if ; | |||
| if DoneName /= OSVVM_STRING_INIT_PARM_DETECT then | |||
| DoneNameVar.Set(DoneName) ; | |||
| end if ; | |||
| if PassName /= OSVVM_STRING_INIT_PARM_DETECT then | |||
| PassNameVar.Set(PassName) ; | |||
| end if ; | |||
| if FailName /= OSVVM_STRING_INIT_PARM_DETECT then | |||
| FailNameVar.Set(FailName) ; | |||
| end if ; | |||
| end procedure SetOsvvmGlobalOptions ; | |||
| ------------------------------------------------------------ | |||
| -- Accessor Functions | |||
| -- Local Function | |||
| function IsOsvvmOptionSet (A : OsvvmOptionsType) return boolean is | |||
| begin | |||
| return A > OPT_USE_DEFAULT ; | |||
| end function IsOsvvmOptionSet ; | |||
| function ResolveOsvvmOption(A, B, C : OsvvmOptionsType) return OsvvmOptionsType is | |||
| begin | |||
| if IsOsvvmOptionSet(A) then | |||
| return A ; | |||
| elsif IsOsvvmOptionSet(B) then | |||
| return B ; | |||
| else | |||
| return C ; | |||
| end if ; | |||
| end function ResolveOsvvmOption ; | |||
| function ResolveOsvvmOption(A, B, C, D : OsvvmOptionsType) return OsvvmOptionsType is | |||
| begin | |||
| if IsOsvvmOptionSet(A) then | |||
| return A ; | |||
| elsif IsOsvvmOptionSet(B) then | |||
| return B ; | |||
| elsif IsOsvvmOptionSet(C) then | |||
| return C ; | |||
| else | |||
| return D ; | |||
| end if ; | |||
| end function ResolveOsvvmOption ; | |||
| -- Local Function | |||
| function IsOsvvmStringSet (A : string) return boolean is | |||
| begin | |||
| if A'length = 0 then -- Null strings permitted | |||
| return TRUE ; | |||
| else | |||
| return A(A'left) /= NUL ; | |||
| end if; | |||
| end function IsOsvvmStringSet ; | |||
| function ResolveOsvvmOption(A, B : string) return string is | |||
| begin | |||
| if IsOsvvmStringSet(A) then | |||
| return A ; | |||
| else | |||
| return B ; | |||
| end if ; | |||
| end function ResolveOsvvmOption ; | |||
| function ResolveOsvvmOption(A, B, C : string) return string is | |||
| begin | |||
| if IsOsvvmStringSet(A) then | |||
| return A ; | |||
| elsif IsOsvvmStringSet(B) then | |||
| return B ; | |||
| else | |||
| return C ; | |||
| end if ; | |||
| end function ResolveOsvvmOption ; | |||
| function ResolveOsvvmOption(A, B, C, D : string) return string is | |||
| begin | |||
| if IsOsvvmStringSet(A) then | |||
| return A ; | |||
| elsif IsOsvvmStringSet(B) then | |||
| return B ; | |||
| elsif IsOsvvmStringSet(C) then | |||
| return C ; | |||
| else | |||
| return D ; | |||
| end if ; | |||
| end function ResolveOsvvmOption ; | |||
| impure function ResolveOsvvmWritePrefix(A : String) return string is | |||
| begin | |||
| return ResolveOsvvmOption(A, WritePrefixVar.GetOpt, OSVVM_DEFAULT_WRITE_PREFIX) ; | |||
| end function ResolveOsvvmWritePrefix ; | |||
| impure function ResolveOsvvmWritePrefix(A, B : String) return string is | |||
| begin | |||
| return ResolveOsvvmOption(A, B, WritePrefixVar.GetOpt, OSVVM_DEFAULT_WRITE_PREFIX) ; | |||
| end function ResolveOsvvmWritePrefix ; | |||
| impure function ResolveOsvvmDoneName(A : String) return string is | |||
| begin | |||
| return ResolveOsvvmOption(A, DoneNameVar.GetOpt, OSVVM_DEFAULT_DONE_NAME) ; | |||
| end function ResolveOsvvmDoneName ; | |||
| impure function ResolveOsvvmDoneName(A, B : String) return string is | |||
| begin | |||
| return ResolveOsvvmOption(A, DoneNameVar.GetOpt, OSVVM_DEFAULT_DONE_NAME) ; | |||
| end function ResolveOsvvmDoneName ; | |||
| impure function ResolveOsvvmPassName(A : String) return string is | |||
| begin | |||
| return ResolveOsvvmOption(A, PassNameVar.GetOpt, OSVVM_DEFAULT_PASS_NAME) ; | |||
| end function ResolveOsvvmPassName ; | |||
| impure function ResolveOsvvmPassName(A, B : String) return string is | |||
| begin | |||
| return ResolveOsvvmOption(A, B, PassNameVar.GetOpt, OSVVM_DEFAULT_PASS_NAME) ; | |||
| end function ResolveOsvvmPassName ; | |||
| impure function ResolveOsvvmFailName(A : String) return string is | |||
| begin | |||
| return ResolveOsvvmOption(A, FailNameVar.GetOpt, OSVVM_DEFAULT_FAIL_NAME) ; | |||
| end function ResolveOsvvmFailName ; | |||
| impure function ResolveOsvvmFailName(A, B : String) return string is | |||
| begin | |||
| return ResolveOsvvmOption(A, B, FailNameVar.GetOpt, OSVVM_DEFAULT_FAIL_NAME) ; | |||
| end function ResolveOsvvmFailName ; | |||
| impure function ResolveCovWritePassFail(A, B : OsvvmOptionsType) return OsvvmOptionsType is | |||
| begin | |||
| return ResolveOsvvmOption(A, B, WritePassFailVar.Get, OSVVM_DEFAULT_WRITE_PASS_FAIL) ; | |||
| end function ResolveCovWritePassFail ; -- Cov | |||
| impure function ResolveCovWriteBinInfo(A, B : OsvvmOptionsType) return OsvvmOptionsType is | |||
| begin | |||
| return ResolveOsvvmOption(A, B, WriteBinInfoVar.Get, OSVVM_DEFAULT_WRITE_BIN_INFO) ; | |||
| end function ResolveCovWriteBinInfo ; -- Cov | |||
| impure function ResolveCovWriteCount(A, B : OsvvmOptionsType) return OsvvmOptionsType is | |||
| begin | |||
| return ResolveOsvvmOption(A, B, WriteCountVar.Get, OSVVM_DEFAULT_WRITE_COUNT) ; | |||
| end function ResolveCovWriteCount ; -- Cov | |||
| impure function ResolveCovWriteAnyIllegal(A, B : OsvvmOptionsType) return OsvvmOptionsType is | |||
| begin | |||
| return ResolveOsvvmOption(A, B, WriteAnyIllegalVar.Get, OSVVM_DEFAULT_WRITE_ANY_ILLEGAL) ; | |||
| end function ResolveCovWriteAnyIllegal ; -- Cov | |||
| procedure OsvvmDeallocate is | |||
| begin | |||
| -- Free up space used by NamePType within OsvvmGlobalPkg | |||
| WritePrefixVar.Deallocate ; | |||
| DoneNameVar.Deallocate ; | |||
| PassNameVar.Deallocate ; | |||
| FailNameVar.Deallocate ; | |||
| WritePassFailVar.Set(FALSE) ; -- := FALSE ; | |||
| WriteBinInfoVar.Set(TRUE ) ; -- := TRUE ; | |||
| WriteCountVar.Set(TRUE ) ; -- := TRUE ; | |||
| WriteAnyIllegalVar.Set(FALSE) ; -- := FALSE ; | |||
| end procedure OsvvmDeallocate ; | |||
| end package body OsvvmGlobalPkg ; | |||
| @ -0,0 +1,392 @@ | |||
| -- | |||
| -- File Name: ResolutionPkg.vhd | |||
| -- Design Unit Name: ResolutionPkg | |||
| -- Revision: STANDARD VERSION | |||
| -- | |||
| -- Maintainer: Jim Lewis email: jim@SynthWorks.com | |||
| -- Contributor(s): | |||
| -- Jim Lewis email: jim@SynthWorks.com | |||
| -- | |||
| -- Package Defines | |||
| -- resolved resolution functions for integer, real, and time | |||
| -- types resolved_integer, resolved_real, resolved_time | |||
| -- | |||
| -- 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/2006: 0.1 Initial revision | |||
| -- Numerous revisions for VHDL Testbenches and Verification | |||
| -- 02/2009: 1.0 VHDL-2008 STANDARD VERSION | |||
| -- 05/2015 2015.05 Added Alerts | |||
| -- -- Replaced Alerts with asserts as alerts are illegal in pure functions | |||
| -- 11/2016 2016.11 Removed Asserts as they are not working as intended. | |||
| -- See ResolutionPkg_debug as it uses Alerts to correctly detect errors | |||
| -- | |||
| -- | |||
| -- Copyright (c) 2005 - 2016 by SynthWorks Design Inc. All rights reserved. | |||
| -- | |||
| -- Verbatim copies of this source file may be used and | |||
| -- distributed without restriction. | |||
| -- | |||
| -- This source file may be modified and distributed under | |||
| -- the terms of the ARTISTIC License as published by | |||
| -- The Perl Foundation; either version 2.0 of the License, | |||
| -- or (at your option) any later version. | |||
| -- | |||
| -- This source is distributed in the hope that it will be | |||
| -- useful, but WITHOUT ANY WARRANTY; without even the implied | |||
| -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||
| -- PURPOSE. See the Artistic License for details. | |||
| -- | |||
| -- You should have received a copy of the license with this source. | |||
| -- If not download it from, | |||
| -- http://www.perlfoundation.org/artistic_license_2_0 | |||
| -- | |||
| library ieee ; | |||
| use ieee.std_logic_1164.all ; | |||
| use ieee.numeric_std.all ; | |||
| library osvvm ; | |||
| use osvvm.AlertLogPkg.all ; | |||
| package ResolutionPkg is | |||
| constant MULTIPLE_DRIVER_SEVERITY : severity_level := ERROR ; | |||
| -- | |||
| -- Note that not all simulators support resolution functions of the form: | |||
| -- subtype std_logic_vector_max is (resolved_max) std_ulogic_vector ; | |||
| -- | |||
| -- Hence, types of the form are offered as a temporary workaround until they do: | |||
| -- std_logic_vector_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008 | |||
| -- | |||
| -- resolved_max | |||
| -- return maximum value. | |||
| -- No initializations required on ports, default of type'left is ok | |||
| function resolved_max ( s : std_ulogic_vector) return std_ulogic ; | |||
| subtype std_logic_max is resolved_max std_ulogic ; | |||
| subtype std_logic_vector_max is (resolved_max) std_ulogic_vector ; | |||
| type std_logic_vector_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008 | |||
| subtype unsigned_max is (resolved_max) unresolved_unsigned ; | |||
| type unsigned_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008 | |||
| subtype signed_max is (resolved_max) unresolved_signed ; | |||
| type signed_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008 | |||
| function resolved_max ( s : bit_vector) return bit ; | |||
| subtype bit_max is resolved_max bit ; | |||
| subtype bit_vector_max is (resolved_max) bit_vector ; | |||
| type bit_vector_max_c is array (natural range <>) of bit_max ; -- for non VHDL-2008 | |||
| function resolved_max ( s : integer_vector ) return integer ; | |||
| subtype integer_max is resolved_max integer ; | |||
| subtype integer_vector_max is (resolved_max) integer_vector ; | |||
| type integer_vector_max_c is array (natural range <>) of integer_max ; -- for non VHDL-2008 | |||
| function resolved_max ( s : time_vector ) return time ; | |||
| subtype time_max is resolved_max time ; | |||
| subtype time_vector_max is (resolved_max) time_vector ; | |||
| type time_vector_max_c is array (natural range <>) of time_max ; -- for non VHDL-2008 | |||
| function resolved_max ( s : real_vector ) return real ; | |||
| subtype real_max is resolved_max real ; | |||
| subtype real_vector_max is (resolved_max) real_vector ; | |||
| type real_vector_max_c is array (natural range <>) of real_max ; -- for non VHDL-2008 | |||
| function resolved_max ( s : string) return character ; | |||
| subtype character_max is resolved_max character ; | |||
| subtype string_max is (resolved_max) string ; | |||
| type string_max_c is array (positive range <>) of character_max ; -- for non VHDL-2008 | |||
| function resolved_max ( s : boolean_vector) return boolean ; | |||
| subtype boolean_max is resolved_max boolean ; | |||
| subtype boolean_vector_max is (resolved_max) boolean_vector ; | |||
| type boolean_vector_max_c is array (natural range <>) of boolean_max ; -- for non VHDL-2008 | |||
| -- return sum of values that /= type'left | |||
| -- No initializations required on ports, default of type'left is ok | |||
| function resolved_sum ( s : integer_vector ) return integer ; | |||
| subtype integer_sum is resolved_sum integer ; | |||
| subtype integer_vector_sum is (resolved_sum) integer_vector ; | |||
| type integer_vector_sum_c is array (natural range <>) of integer_sum ; -- for non VHDL-2008 | |||
| function resolved_sum ( s : time_vector ) return time ; | |||
| subtype time_sum is resolved_sum time ; | |||
| subtype time_vector_sum is (resolved_sum) time_vector ; | |||
| type time_vector_sum_c is array (natural range <>) of time_sum ; -- for non VHDL-2008 | |||
| function resolved_sum ( s : real_vector ) return real ; | |||
| subtype real_sum is resolved_sum real ; | |||
| subtype real_vector_sum is (resolved_sum) real_vector ; | |||
| type real_vector_sum_c is array (natural range <>) of real_sum ; -- for non VHDL-2008 | |||
| -- resolved_weak | |||
| -- Special just for std_ulogic | |||
| -- No initializations required on ports, default of type'left is ok | |||
| function resolved_weak (s : std_ulogic_vector) return std_ulogic ; -- no init, type'left | |||
| subtype std_logic_weak is resolved_weak std_ulogic ; | |||
| subtype std_logic_vector_weak is (resolved_weak) std_ulogic_vector ; | |||
| -- legacy stuff | |||
| -- requires ports to be initialized to 0 in the appropriate type. | |||
| function resolved ( s : integer_vector ) return integer ; | |||
| subtype resolved_integer is resolved integer ; | |||
| function resolved ( s : time_vector ) return time ; | |||
| subtype resolved_time is resolved time ; | |||
| function resolved ( s : real_vector ) return real ; | |||
| subtype resolved_real is resolved real ; | |||
| function resolved (s : string) return character ; -- same as resolved_max | |||
| subtype resolved_character is resolved character ; | |||
| -- subtype resolved_string is (resolved) string ; -- subtype will replace type later | |||
| type resolved_string is array (positive range <>) of resolved_character; -- will change to subtype -- assert but no init | |||
| function resolved ( s : boolean_vector) return boolean ; --same as resolved_max | |||
| subtype resolved_boolean is resolved boolean ; | |||
| end package ResolutionPkg ; | |||
| package body ResolutionPkg is | |||
| -- resolved_max | |||
| -- return maximum value. Assert FAILURE if more than 1 /= type'left | |||
| -- No initializations required on ports, default of type'left is ok | |||
| -- Optimized version is just the following: | |||
| -- ------------------------------------------------------------ | |||
| -- function resolved_max ( s : <array_type> ) return <element_type> is | |||
| -- ------------------------------------------------------------ | |||
| -- begin | |||
| -- return maximum(s) ; | |||
| -- end function resolved_max ; | |||
| ------------------------------------------------------------ | |||
| function resolved_max (s : std_ulogic_vector) return std_ulogic is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return maximum(s) ; | |||
| end function resolved_max ; | |||
| ------------------------------------------------------------ | |||
| function resolved_max ( s : bit_vector ) return bit is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return maximum(s) ; | |||
| end function resolved_max ; | |||
| ------------------------------------------------------------ | |||
| function resolved_max ( s : integer_vector ) return integer is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return maximum(s) ; | |||
| end function resolved_max ; | |||
| ------------------------------------------------------------ | |||
| function resolved_max ( s : time_vector ) return time is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return maximum(s) ; | |||
| end function resolved_max ; | |||
| ------------------------------------------------------------ | |||
| function resolved_max ( s : real_vector ) return real is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return maximum(s) ; | |||
| end function resolved_max ; | |||
| ------------------------------------------------------------ | |||
| function resolved_max ( s : string ) return character is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return maximum(s) ; | |||
| end function resolved_max ; | |||
| ------------------------------------------------------------ | |||
| function resolved_max ( s : boolean_vector) return boolean is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return maximum(s) ; | |||
| end function resolved_max ; | |||
| -- resolved_sum - appropriate for numeric types | |||
| -- return sum of values that /= type'left | |||
| -- No initializations required on ports, default of type'left is ok | |||
| ------------------------------------------------------------ | |||
| function resolved_sum ( s : integer_vector ) return integer is | |||
| ------------------------------------------------------------ | |||
| variable result : integer := 0 ; | |||
| begin | |||
| for i in s'RANGE loop | |||
| if s(i) /= integer'left then | |||
| result := s(i) + result; | |||
| end if ; | |||
| end loop ; | |||
| return result ; | |||
| end function resolved_sum ; | |||
| ------------------------------------------------------------ | |||
| function resolved_sum ( s : time_vector ) return time is | |||
| ------------------------------------------------------------ | |||
| variable result : time := 0 sec ; | |||
| begin | |||
| for i in s'RANGE loop | |||
| if s(i) /= time'left then | |||
| result := s(i) + result; | |||
| end if ; | |||
| end loop ; | |||
| return result ; | |||
| end function resolved_sum ; | |||
| ------------------------------------------------------------ | |||
| function resolved_sum ( s : real_vector ) return real is | |||
| ------------------------------------------------------------ | |||
| variable result : real := 0.0 ; | |||
| begin | |||
| for i in s'RANGE loop | |||
| if s(i) /= real'left then | |||
| result := s(i) + result; | |||
| end if ; | |||
| end loop ; | |||
| return result ; | |||
| end function resolved_sum ; | |||
| -- resolved_weak | |||
| -- Special just for std_ulogic | |||
| -- No initializations required on ports, default of type'left is ok | |||
| type stdlogic_table is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC; | |||
| constant weak_resolution_table : stdlogic_table := ( | |||
| -- Resolution order: Z < U < W < X < - < L < H < 0 < 1 | |||
| -- --------------------------------------------------------- | |||
| -- | U X 0 1 Z W L H - | | | |||
| -- --------------------------------------------------------- | |||
| ('U', 'X', '0', '1', 'U', 'W', 'L', 'H', '-'), -- | U | | |||
| ('X', 'X', '0', '1', 'X', 'X', 'L', 'H', '-'), -- | X | | |||
| ('0', '0', '0', '1', '0', '0', '0', '0', '0'), -- | 0 | | |||
| ('1', '1', '1', '1', '1', '1', '1', '1', '1'), -- | 1 | | |||
| ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'), -- | Z | | |||
| ('W', 'X', '0', '1', 'W', 'W', 'L', 'H', '-'), -- | W | | |||
| ('L', 'L', '0', '1', 'L', 'L', 'L', 'H', 'L'), -- | L | | |||
| ('H', 'H', '0', '1', 'H', 'H', 'W', 'H', 'H'), -- | H | | |||
| ('-', '-', '0', '1', '-', '-', 'L', 'H', '-') -- | - | | |||
| ); | |||
| ------------------------------------------------------------ | |||
| function resolved_weak (s : std_ulogic_vector) return std_ulogic is | |||
| ------------------------------------------------------------ | |||
| variable result : std_ulogic := 'Z' ; | |||
| begin | |||
| for i in s'RANGE loop | |||
| result := weak_resolution_table(result, s(i)) ; | |||
| end loop ; | |||
| return result ; | |||
| end function resolved_weak ; | |||
| -- legacy stuff. | |||
| -- requires ports to be initialized to 0 in the appropriate type. | |||
| ------------------------------------------------------------ | |||
| function resolved ( s : integer_vector ) return integer is | |||
| -- requires interface to be initialized to 0 | |||
| ------------------------------------------------------------ | |||
| variable result : integer := 0 ; | |||
| variable failed : boolean := FALSE ; | |||
| begin | |||
| for i in s'RANGE loop | |||
| if s(i) /= 0 then | |||
| failed := failed or (result /= 0) ; | |||
| result := maximum(s(i),result); | |||
| end if ; | |||
| end loop ; | |||
| assert not failed report "ResolutionPkg.resolved: multiple drivers on integer" severity MULTIPLE_DRIVER_SEVERITY ; | |||
| -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on integer") ; | |||
| return result ; | |||
| end function resolved ; | |||
| ------------------------------------------------------------ | |||
| function resolved ( s : time_vector ) return time is | |||
| -- requires interface to be initialized to 0 ns | |||
| ------------------------------------------------------------ | |||
| variable result : time := 0 ns ; | |||
| variable failed : boolean := FALSE ; | |||
| begin | |||
| for i in s'RANGE loop | |||
| if s(i) > 0 ns then | |||
| failed := failed or (result /= 0 ns) ; | |||
| result := maximum(s(i),result); | |||
| end if ; | |||
| end loop ; | |||
| assert not failed report "ResolutionPkg.resolved: multiple drivers on time" severity MULTIPLE_DRIVER_SEVERITY ; | |||
| -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on time") ; | |||
| return result ; | |||
| end function resolved ; | |||
| ------------------------------------------------------------ | |||
| function resolved ( s : real_vector ) return real is | |||
| -- requires interface to be initialized to 0.0 | |||
| ------------------------------------------------------------ | |||
| variable result : real := 0.0 ; | |||
| variable failed : boolean := FALSE ; | |||
| begin | |||
| for i in s'RANGE loop | |||
| if s(i) /= 0.0 then | |||
| failed := failed or (result /= 0.0) ; | |||
| result := maximum(s(i),result); | |||
| end if ; | |||
| end loop ; | |||
| assert not failed report "ResolutionPkg.resolved: multiple drivers on real" severity MULTIPLE_DRIVER_SEVERITY ; | |||
| -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on real") ; | |||
| return result ; | |||
| end function resolved ; | |||
| ------------------------------------------------------------ | |||
| function resolved (s : string) return character is | |||
| -- same as resolved_max | |||
| ------------------------------------------------------------ | |||
| variable result : character := NUL ; | |||
| variable failed : boolean := FALSE ; | |||
| begin | |||
| for i in s'RANGE loop | |||
| if s(i) /= NUL then | |||
| failed := failed or (result /= NUL) ; | |||
| result := maximum(result, s(i)) ; | |||
| end if ; | |||
| end loop ; | |||
| assert not failed report "ResolutionPkg.resolved: multiple drivers on character" severity MULTIPLE_DRIVER_SEVERITY ; | |||
| -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on character") ; | |||
| return result ; | |||
| end function resolved ; | |||
| ------------------------------------------------------------ | |||
| function resolved ( s : boolean_vector) return boolean is | |||
| -- same as resolved_max | |||
| ------------------------------------------------------------ | |||
| variable result : boolean := FALSE ; | |||
| variable failed : boolean := FALSE ; | |||
| begin | |||
| for i in s'RANGE loop | |||
| if s(i) then | |||
| failed := failed or result ; | |||
| result := TRUE ; | |||
| end if ; | |||
| end loop ; | |||
| assert not failed report "ResolutionPkg.resolved: multiple drivers on boolean" severity MULTIPLE_DRIVER_SEVERITY ; | |||
| -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on boolean") ; | |||
| return result ; | |||
| end function resolved ; | |||
| end package body ResolutionPkg ; | |||
| @ -0,0 +1,65 @@ | |||
| -- | |||
| -- File Name: ScoreBoardPkg_int.vhd | |||
| -- Design Unit Name: ScoreBoardPkg_int | |||
| -- Revision: STANDARD VERSION | |||
| -- | |||
| -- Maintainer: Jim Lewis email: jim@synthworks.com | |||
| -- Contributor(s): | |||
| -- Jim Lewis email: jim@synthworks.com | |||
| -- | |||
| -- | |||
| -- Description: | |||
| -- Instance of Generic Package ScoreboardGenericPkg for integer | |||
| -- | |||
| -- Developed for: | |||
| -- SynthWorks Design Inc. | |||
| -- VHDL Training Classes | |||
| -- 11898 SW 128th Ave. Tigard, Or 97223 | |||
| -- http://www.SynthWorks.com | |||
| -- | |||
| -- Latest standard version available at: | |||
| -- http://www.SynthWorks.com/downloads | |||
| -- | |||
| -- Revision History: | |||
| -- Date Version Description | |||
| -- 08/2012 2012.08 Generic Instance of ScoreboardGenericPkg | |||
| -- 08/2014 2013.08 Updated interface for Match and to_string | |||
| -- 11/2016 2016.11 Released as part of OSVVM library | |||
| -- | |||
| -- | |||
| -- Copyright (c) 2006 - 2016 by SynthWorks Design Inc. All rights reserved. | |||
| -- | |||
| -- Verbatim copies of this source file may be used and | |||
| -- distributed without restriction. | |||
| -- | |||
| -- This source file is free software; you can redistribute it | |||
| -- and/or modify it under the terms of the ARTISTIC License | |||
| -- as published by The Perl Foundation; either version 2.0 of | |||
| -- the License, or (at your option) any later version. | |||
| -- | |||
| -- This source is distributed in the hope that it will be | |||
| -- useful, but WITHOUT ANY WARRANTY; without even the implied | |||
| -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||
| -- PURPOSE. See the Artistic License for details. | |||
| -- | |||
| -- You should have received a copy of the license with this source. | |||
| -- If not download it from, | |||
| -- http://www.perlfoundation.org/artistic_license_2_0 | |||
| -- | |||
| -- | |||
| use std.textio.all ; | |||
| library ieee ; | |||
| use ieee.std_logic_1164.all ; | |||
| use ieee.numeric_std.all ; | |||
| package ScoreBoardPkg_int is new work.ScoreboardGenericPkg | |||
| generic map ( | |||
| ExpectedType => integer, | |||
| ActualType => integer, | |||
| Match => "=", | |||
| expected_to_string => to_string, | |||
| actual_to_string => to_string | |||
| ) ; | |||
| @ -0,0 +1,65 @@ | |||
| -- | |||
| -- File Name: ScoreBoardPkg_slv.vhd | |||
| -- Design Unit Name: ScoreBoardPkg_slv | |||
| -- Revision: STANDARD VERSION | |||
| -- | |||
| -- Maintainer: Jim Lewis email: jim@synthworks.com | |||
| -- Contributor(s): | |||
| -- Jim Lewis email: jim@synthworks.com | |||
| -- | |||
| -- | |||
| -- Description: | |||
| -- Instance of Generic Package ScoreboardGenericPkg for std_logic_vector | |||
| -- | |||
| -- Developed for: | |||
| -- SynthWorks Design Inc. | |||
| -- VHDL Training Classes | |||
| -- 11898 SW 128th Ave. Tigard, Or 97223 | |||
| -- http://www.SynthWorks.com | |||
| -- | |||
| -- Latest standard version available at: | |||
| -- http://www.SynthWorks.com/downloads | |||
| -- | |||
| -- Revision History: | |||
| -- Date Version Description | |||
| -- 08/2012 2012.08 Generic Instance of ScoreboardGenericPkg | |||
| -- 08/2014 2013.08 Updated interface for Match and to_string | |||
| -- 11/2016 2016.11 Released as part of OSVVM library | |||
| -- | |||
| -- | |||
| -- Copyright (c) 2006 - 2016 by SynthWorks Design Inc. All rights reserved. | |||
| -- | |||
| -- Verbatim copies of this source file may be used and | |||
| -- distributed without restriction. | |||
| -- | |||
| -- This source file is free software; you can redistribute it | |||
| -- and/or modify it under the terms of the ARTISTIC License | |||
| -- as published by The Perl Foundation; either version 2.0 of | |||
| -- the License, or (at your option) any later version. | |||
| -- | |||
| -- This source is distributed in the hope that it will be | |||
| -- useful, but WITHOUT ANY WARRANTY; without even the implied | |||
| -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||
| -- PURPOSE. See the Artistic License for details. | |||
| -- | |||
| -- You should have received a copy of the license with this source. | |||
| -- If not download it from, | |||
| -- http://www.perlfoundation.org/artistic_license_2_0 | |||
| -- | |||
| -- | |||
| use std.textio.all ; | |||
| library ieee ; | |||
| use ieee.std_logic_1164.all ; | |||
| use ieee.numeric_std.all ; | |||
| package ScoreBoardPkg_slv is new work.ScoreboardGenericPkg | |||
| generic map ( | |||
| ExpectedType => std_logic_vector, | |||
| ActualType => std_logic_vector, | |||
| Match => std_match, -- "=", [std_logic_vector, std_logic_vector return boolean] | |||
| expected_to_string => to_hstring, -- [std_logic_vector return string] | |||
| actual_to_string => to_hstring -- [std_logic_vector return string] | |||
| ) ; | |||
| @ -0,0 +1,851 @@ | |||
| -- | |||
| -- File Name: TbUtilPkg.vhd | |||
| -- Design Unit Name: TbUtilPkg | |||
| -- Revision: STANDARD VERSION | |||
| -- | |||
| -- Maintainer: Jim Lewis email: jim@SynthWorks.com | |||
| -- Contributor(s): | |||
| -- Jim Lewis email: jim@SynthWorks.com | |||
| -- | |||
| -- Package Defines | |||
| -- | |||
| -- Developed for: | |||
| -- SynthWorks Design Inc. | |||
| -- VHDL Training Classes | |||
| -- 11898 SW 128th Ave. Tigard, Or 97223 | |||
| -- http://www.SynthWorks.com | |||
| -- | |||
| -- Revision History: | |||
| -- Date Version Description | |||
| -- 11/1999: 0.1 Initial revision | |||
| -- Numerous revisions for VHDL Testbenches and Verification | |||
| -- 10/2013 2013.10 Split out Text Utilities | |||
| -- 11/2016 2016.11 First Public Release Version | |||
| -- Updated naming for consistency. | |||
| -- | |||
| -- | |||
| -- Copyright (c) 1999 - 2016 by SynthWorks Design Inc. All rights reserved. | |||
| -- | |||
| -- Verbatim copies of this source file may be used and | |||
| -- distributed without restriction. | |||
| -- | |||
| -- This source file is free software; you can redistribute it | |||
| -- and/or modify it under the terms of the ARTISTIC License | |||
| -- as published by The Perl Foundation; either version 2.0 of | |||
| -- the License, or (at your option) any later version. | |||
| -- | |||
| -- This source is distributed in the hope that it will be | |||
| -- useful, but WITHOUT ANY WARRANTY; without even the implied | |||
| -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||
| -- PURPOSE. See the Artistic License for details. | |||
| -- | |||
| -- You should have received a copy of the license with this source. | |||
| -- If not download it from, | |||
| -- http://www.perlfoundation.org/artistic_license_2_0 | |||
| -- | |||
| library ieee ; | |||
| use ieee.std_logic_1164.all ; | |||
| library osvvm ; | |||
| use osvvm.AlertLogPkg.all ; | |||
| use osvvm.TranscriptPkg.all ; | |||
| package TbUtilPkg is | |||
| constant CLK_ACTIVE : std_logic := '1' ; | |||
| constant t_sim_resolution : time := std.env.resolution_limit ; -- VHDL-2008 | |||
| -- constant t_sim_resolution : time := 1 ns ; -- for non VHDL-2008 simulators | |||
| ------------------------------------------------------------ | |||
| -- ZeroOneHot, OneHot | |||
| -- OneHot: return true if exactly one value is 1 | |||
| -- ZeroOneHot: return false when more than one value is a 1 | |||
| ------------------------------------------------------------ | |||
| function OneHot ( constant A : in std_logic_vector ) return boolean ; | |||
| function ZeroOneHot ( constant A : in std_logic_vector ) return boolean ; | |||
| ------------------------------------------------------------ | |||
| -- RequestTransaction | |||
| -- Transaction initiation side of handshaking | |||
| -- Pairs with WaitForTransaction or one of its variations | |||
| ------------------------------------------------------------ | |||
| procedure RequestTransaction ( | |||
| signal Rdy : Out std_logic ; | |||
| signal Ack : In std_logic | |||
| ) ; | |||
| ------------------------------------------------------------ | |||
| -- WaitForTransaction | |||
| -- Model side of handshaking | |||
| -- Pairs with RequestTransaction | |||
| ------------------------------------------------------------ | |||
| procedure WaitForTransaction ( | |||
| signal Clk : In std_logic ; | |||
| signal Rdy : In std_logic ; | |||
| signal Ack : Out std_logic | |||
| ) ; | |||
| -- Variation for model that stops waiting when TimeOut is asserted | |||
| -- Intended for models that need to switch between instruction streams | |||
| -- such as a CPU when interrupt is pending | |||
| procedure WaitForTransaction ( | |||
| signal Clk : In std_logic ; | |||
| signal Rdy : In std_logic ; | |||
| signal Ack : Out std_logic ; | |||
| signal TimeOut : In std_logic ; | |||
| constant Polarity : In std_logic := '1' | |||
| ) ; | |||
| -- Set Ack to Model starting value | |||
| procedure StartTransaction ( signal Ack : Out std_logic ) ; | |||
| -- Set Ack to Model finishing value | |||
| procedure FinishTransaction ( signal Ack : Out std_logic ) ; | |||
| -- If a transaction is pending, return true | |||
| function TransactionPending ( signal Rdy : In std_logic ) return boolean ; | |||
| -- Variation for clockless models | |||
| procedure WaitForTransaction ( | |||
| signal Rdy : In std_logic ; | |||
| signal Ack : Out std_logic | |||
| ) ; | |||
| ------------------------------------------------------------ | |||
| -- Toggle, WaitForToggle | |||
| -- Used for communicating between processes | |||
| ------------------------------------------------------------ | |||
| procedure Toggle ( | |||
| signal Sig : InOut std_logic ; | |||
| constant DelayVal : time | |||
| ) ; | |||
| procedure Toggle ( signal Sig : InOut std_logic ) ; | |||
| procedure ToggleHS ( signal Sig : InOut std_logic ) ; | |||
| function IsToggle ( signal Sig : In std_logic ) return boolean ; | |||
| procedure WaitForToggle ( signal Sig : In std_logic ) ; | |||
| -- Bit type versions | |||
| procedure Toggle ( signal Sig : InOut bit ; constant DelayVal : time ) ; | |||
| procedure Toggle ( signal Sig : InOut bit ) ; | |||
| procedure ToggleHS ( signal Sig : InOut bit ) ; | |||
| function IsToggle ( signal Sig : In bit ) return boolean ; | |||
| procedure WaitForToggle ( signal Sig : In bit ) ; | |||
| ------------------------------------------------------------ | |||
| -- WaitForBarrier | |||
| -- Barrier Synchronization | |||
| -- Multiple processes call it, it finishes when all have called it | |||
| ------------------------------------------------------------ | |||
| procedure WaitForBarrier ( signal Sig : InOut std_logic ) ; | |||
| procedure WaitForBarrier ( signal Sig : InOut std_logic ; signal TimeOut : std_logic ; constant Polarity : in std_logic := '1') ; | |||
| procedure WaitForBarrier ( signal Sig : InOut std_logic ; constant TimeOut : time ) ; | |||
| -- resolved_barrier : summing resolution used in conjunction with integer based barriers | |||
| function resolved_barrier ( s : integer_vector ) return integer ; | |||
| subtype integer_barrier is resolved_barrier integer ; | |||
| -- Usage of integer barriers requires resolved_barrier. Initialization to 1 recommended, but not required | |||
| -- signal barrier1 : resolved_barrier integer := 1 ; -- using the resolution function | |||
| -- signal barrier2 : integer_barrier := 1 ; -- using the subtype that already applies the resolution function | |||
| procedure WaitForBarrier ( signal Sig : InOut integer ) ; | |||
| procedure WaitForBarrier ( signal Sig : InOut integer ; signal TimeOut : std_logic ; constant Polarity : in std_logic := '1') ; | |||
| procedure WaitForBarrier ( signal Sig : InOut integer ; constant TimeOut : time ) ; | |||
| -- Using separate signals | |||
| procedure WaitForBarrier2 ( signal SyncOut : out std_logic ; signal SyncIn : in std_logic ) ; | |||
| procedure WaitForBarrier2 ( signal SyncOut : out std_logic ; signal SyncInV : in std_logic_vector ) ; | |||
| ------------------------------------------------------------ | |||
| -- WaitForClock | |||
| -- Sync to Clock - after a delay, after a number of clocks | |||
| ------------------------------------------------------------ | |||
| procedure WaitForClock ( signal Clk : in std_logic ; constant Delay : in time ) ; | |||
| procedure WaitForClock ( signal Clk : in std_logic ; constant NumberOfClocks : in integer := 1) ; | |||
| procedure WaitForClock ( signal Clk : in std_logic ; signal Enable : in boolean ) ; | |||
| procedure WaitForClock ( signal Clk : in std_logic ; signal Enable : in std_logic ; constant Polarity : std_logic := '1' ) ; | |||
| ------------------------------------------------------------ | |||
| -- WaitForLevel | |||
| -- Find a signal at a level | |||
| ------------------------------------------------------------ | |||
| procedure WaitForLevel ( signal A : in boolean ) ; | |||
| procedure WaitForLevel ( signal A : in std_logic ; Polarity : std_logic := '1' ) ; | |||
| ------------------------------------------------------------ | |||
| -- CreateClock, CreateReset | |||
| -- Note these do not exit | |||
| ------------------------------------------------------------ | |||
| procedure CreateClock ( | |||
| signal Clk : inout std_logic ; | |||
| constant Period : time ; | |||
| constant DutyCycle : real := 0.5 | |||
| ) ; | |||
| procedure CheckClockPeriod ( | |||
| constant AlertLogID : AlertLogIDType ; | |||
| signal Clk : in std_logic ; | |||
| constant Period : time ; | |||
| constant ClkName : string := "Clock" ; | |||
| constant HowMany : integer := 5 | |||
| ) ; | |||
| procedure CheckClockPeriod ( | |||
| signal Clk : in std_logic ; | |||
| constant Period : time ; | |||
| constant ClkName : string := "Clock" ; | |||
| constant HowMany : integer := 5 | |||
| ) ; | |||
| procedure CreateReset ( | |||
| signal Reset : out std_logic ; | |||
| constant ResetActive : in std_logic ; | |||
| signal Clk : in std_logic ; | |||
| constant Period : time ; | |||
| constant tpd : time | |||
| ) ; | |||
| procedure LogReset ( | |||
| constant AlertLogID : AlertLogIDType ; | |||
| signal Reset : in std_logic ; | |||
| constant ResetActive : in std_logic ; | |||
| constant ResetName : in string := "Reset" ; | |||
| constant LogLevel : in LogType := ALWAYS | |||
| ) ; | |||
| procedure LogReset ( | |||
| signal Reset : in std_logic ; | |||
| constant ResetActive : in std_logic ; | |||
| constant ResetName : in string := "Reset" ; | |||
| constant LogLevel : in LogType := ALWAYS | |||
| ) ; | |||
| ------------------------------------------------------------ | |||
| -- Deprecated subprogram names | |||
| -- Maintaining backward compatibility using aliases | |||
| ------------------------------------------------------------ | |||
| -- History of RequestTransaction / WaitForTransaction | |||
| alias RequestAction is RequestTransaction [std_logic, std_logic] ; | |||
| alias WaitForRequest is WaitForTransaction [std_logic, std_logic, std_logic] ; | |||
| -- History of WaitForToggle | |||
| alias WaitOnToggle is WaitForToggle [std_logic] ; | |||
| -- History of WaitForBarrier | |||
| alias WayPointBlock is WaitForBarrier [std_logic] ; | |||
| alias SyncTo is WaitForBarrier2[std_logic, std_logic] ; | |||
| alias SyncTo is WaitForBarrier2[std_logic, std_logic_vector] ; | |||
| -- Backward compatible name | |||
| alias SyncToClk is WaitForClock [std_logic, time] ; | |||
| ------------------------------------------------------------ | |||
| -- Deprecated | |||
| -- subsumed by WaitForTransaction with Ack and TimeOut. | |||
| -- TimeOut works exactly like IntReq | |||
| ------------------------------------------------------------ | |||
| procedure WaitForTransactionOrIrq ( | |||
| signal Clk : In std_logic ; | |||
| signal Rdy : In std_logic ; | |||
| signal IntReq : In std_logic | |||
| ) ; | |||
| ------------------------------------------------------------ | |||
| -- Deprecated | |||
| -- WaitForAck, StrobeAck | |||
| -- Replaced by WaitForToggle and Toggle | |||
| ------------------------------------------------------------ | |||
| procedure WaitForAck ( signal Ack : In std_logic ) ; | |||
| procedure StrobeAck ( signal Ack : Out std_logic ) ; | |||
| end TbUtilPkg ; | |||
| -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||
| -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||
| package body TbUtilPkg is | |||
| ------------------------------------------------------------ | |||
| -- ZeroOneHot, OneHot | |||
| -- OneHot: return true if exactly one value is 1 | |||
| -- ZeroOneHot: return false when more than one value is a 1 | |||
| ------------------------------------------------------------ | |||
| function OneHot ( constant A : in std_logic_vector ) return boolean is | |||
| variable found_one : boolean := FALSE ; | |||
| begin | |||
| for i in A'range loop | |||
| if A(i) = '1' or A(i) = 'H' then | |||
| if found_one then | |||
| return FALSE ; | |||
| end if ; | |||
| found_one := TRUE ; | |||
| end if ; | |||
| end loop ; | |||
| return found_one ; -- found a one | |||
| end function OneHot ; | |||
| function ZeroOneHot ( constant A : in std_logic_vector ) return boolean is | |||
| variable found_one : boolean := FALSE ; | |||
| begin | |||
| for i in A'range loop | |||
| if A(i) = '1' or A(i) = 'H' then | |||
| if found_one then | |||
| return FALSE ; | |||
| end if ; | |||
| found_one := TRUE ; | |||
| end if ; | |||
| end loop ; | |||
| return TRUE ; -- all zero or found a one | |||
| end function ZeroOneHot ; | |||
| ------------------------------------------------------------ | |||
| -- RequestTransaction | |||
| -- Transaction initiation side of handshaking | |||
| -- Pairs with WaitForTransaction or one of its variations | |||
| ------------------------------------------------------------ | |||
| procedure RequestTransaction ( | |||
| signal Rdy : Out std_logic ; | |||
| signal Ack : In std_logic | |||
| ) is | |||
| begin | |||
| -- Record contains new transaction | |||
| Rdy <= '1' ; | |||
| -- Find Ack low = '0' | |||
| wait until Ack = '0' ; | |||
| -- Prepare for Next Transaction | |||
| Rdy <= '0' ; | |||
| -- Transaction Done | |||
| wait until Ack = '1' ; | |||
| end procedure ; | |||
| ------------------------------------------------------------ | |||
| -- WaitForTransaction | |||
| -- Model side of handshaking | |||
| -- Pairs with RequestTransaction | |||
| ------------------------------------------------------------ | |||
| procedure WaitForTransaction ( | |||
| signal Clk : In std_logic ; | |||
| signal Rdy : In std_logic ; | |||
| signal Ack : Out std_logic | |||
| ) is | |||
| variable AckTime : time ; | |||
| begin | |||
| -- End of Previous Cycle. Signal Done | |||
| Ack <= '1' ; -- #6 | |||
| AckTime := NOW ; | |||
| -- Find Start of Transaction | |||
| if Rdy /= '1' then -- #2 | |||
| wait until Rdy = '1' ; | |||
| else | |||
| wait for 0 ns ; -- allow Ack to update | |||
| end if ; | |||
| -- align to clock if needed (not back-to-back transactions) | |||
| if NOW /= AckTime then | |||
| wait until Clk = CLK_ACTIVE ; | |||
| end if ; | |||
| -- Model active and owns the record | |||
| Ack <= '0' ; -- #3 | |||
| end procedure ; | |||
| -- Variation for model that stops waiting when TimeOut is asserted | |||
| -- Intended for models that need to switch between instruction streams | |||
| -- such as a CPU when interrupt is pending | |||
| procedure WaitForTransaction ( | |||
| signal Clk : In std_logic ; | |||
| signal Rdy : In std_logic ; | |||
| signal Ack : Out std_logic ; | |||
| signal TimeOut : In std_logic ; | |||
| constant Polarity : In std_logic := '1' | |||
| ) is | |||
| variable AckTime : time ; | |||
| variable FoundRdy : boolean ; | |||
| begin | |||
| -- End of Previous Cycle. Signal Done | |||
| Ack <= '1' ; -- #6 | |||
| AckTime := NOW ; | |||
| -- Find Ready or Time out | |||
| if (Rdy /= '1' and TimeOut /= Polarity) then | |||
| wait until Rdy = '1' or TimeOut = Polarity ; | |||
| else | |||
| wait for 0 ns ; -- allow Ack to update | |||
| end if ; | |||
| FoundRdy := Rdy = '1' ; | |||
| -- align to clock if Rdy or TimeOut does not happen within delta cycles from Ack | |||
| if NOW /= AckTime then | |||
| wait until Clk = CLK_ACTIVE ; | |||
| end if ; | |||
| if FoundRdy then | |||
| -- Model active and owns the record | |||
| Ack <= '0' ; -- #3 | |||
| end if ; | |||
| end procedure ; | |||
| -- Set Ack to Model starting value | |||
| -- Pairs with WaitForTransactionOrIrq above | |||
| procedure StartTransaction ( signal Ack : Out std_logic ) is | |||
| begin | |||
| Ack <= '0' ; | |||
| end procedure ; | |||
| -- Set Ack to Model finishing value | |||
| -- Pairs with WaitForTransactionOrIrq above | |||
| procedure FinishTransaction ( signal Ack : Out std_logic ) is | |||
| begin | |||
| -- End of Cycle | |||
| Ack <= '1' ; | |||
| end procedure ; | |||
| -- If a transaction is pending, return true | |||
| -- Used to detect presence of transaction stream, | |||
| -- such as an interrupt handler | |||
| function TransactionPending ( | |||
| signal Rdy : In std_logic | |||
| ) return boolean is | |||
| begin | |||
| return Rdy = '1' ; | |||
| end function ; | |||
| -- Variation for clockless models | |||
| procedure WaitForTransaction ( | |||
| signal Rdy : In std_logic ; | |||
| signal Ack : Out std_logic | |||
| ) is | |||
| variable AckTime : time ; | |||
| begin | |||
| -- End of Previous Cycle. Signal Done | |||
| Ack <= '1' ; -- #6 | |||
| -- Find Start of Transaction | |||
| if Rdy /= '1' then -- #2 | |||
| wait until Rdy = '1' ; | |||
| else | |||
| wait for 0 ns ; -- allow Ack to update | |||
| end if ; | |||
| -- Model active and owns the record | |||
| Ack <= '0' ; -- #3 | |||
| end procedure ; | |||
| ------------------------------------------------------------ | |||
| -- Toggle, WaitForToggle | |||
| -- Used for communicating between processes | |||
| ------------------------------------------------------------ | |||
| type stdulogic_indexby_stdulogic is array (std_ulogic) of std_ulogic; | |||
| constant toggle_sl_table : stdulogic_indexby_stdulogic := ( | |||
| '0' => '1', | |||
| 'L' => '1', | |||
| others => '0' | |||
| ); | |||
| procedure Toggle ( | |||
| signal Sig : InOut std_logic ; | |||
| constant DelayVal : time | |||
| ) is | |||
| variable iDelayVal : time ; | |||
| begin | |||
| iDelayVal := DelayVal ; | |||
| if iDelayVal > t_sim_resolution then | |||
| iDelayVal := iDelayVal - t_sim_resolution ; | |||
| end if ; | |||
| Sig <= toggle_sl_table(Sig) after iDelayVal ; | |||
| end procedure ; | |||
| procedure Toggle ( signal Sig : InOut std_logic ) is | |||
| begin | |||
| Sig <= toggle_sl_table(Sig) ; | |||
| end procedure ; | |||
| procedure ToggleHS ( signal Sig : InOut std_logic ) is | |||
| begin | |||
| Sig <= toggle_sl_table(Sig) ; | |||
| wait for 0 ns ; -- Sig toggles | |||
| wait for 0 ns ; -- new values updated into record | |||
| end procedure ; | |||
| function IsToggle ( signal Sig : In std_logic ) return boolean is | |||
| begin | |||
| return Sig'event ; | |||
| end function ; | |||
| procedure WaitForToggle ( signal Sig : In std_logic ) is | |||
| begin | |||
| wait on Sig ; | |||
| end procedure ; | |||
| -- Bit type versions | |||
| procedure Toggle ( signal Sig : InOut bit ; constant DelayVal : time ) is | |||
| variable iDelayVal : time ; | |||
| begin | |||
| iDelayVal := DelayVal ; | |||
| if iDelayVal > t_sim_resolution then | |||
| iDelayVal := iDelayVal - t_sim_resolution ; | |||
| end if ; | |||
| Sig <= not Sig after iDelayVal ; | |||
| end procedure ; | |||
| procedure Toggle ( signal Sig : InOut bit ) is | |||
| begin | |||
| Sig <= not Sig ; | |||
| end procedure ; | |||
| procedure ToggleHS ( signal Sig : InOut bit ) is | |||
| begin | |||
| Sig <= not Sig ; | |||
| wait for 0 ns ; -- Sig toggles | |||
| wait for 0 ns ; -- new values updated into record | |||
| end procedure ; | |||
| function IsToggle ( signal Sig : In bit ) return boolean is | |||
| begin | |||
| return Sig'event ; | |||
| end function ; | |||
| procedure WaitForToggle ( signal Sig : In bit ) is | |||
| begin | |||
| wait on Sig ; | |||
| end procedure ; | |||
| ------------------------------------------------------------ | |||
| -- WaitForBarrier | |||
| -- Barrier Synchronization | |||
| -- Multiple processes call it, it finishes when all have called it | |||
| ------------------------------------------------------------ | |||
| procedure WaitForBarrier ( signal Sig : InOut std_logic ) is | |||
| begin | |||
| Sig <= 'H' ; | |||
| -- Wait until all processes set Sig to H | |||
| -- Level check not necessary since last value /= H yet | |||
| wait until Sig = 'H' ; | |||
| -- Deactivate and propagate to allow back to back calls | |||
| Sig <= '0' ; | |||
| wait for 0 ns ; | |||
| end procedure WaitForBarrier ; | |||
| procedure WaitForBarrier ( signal Sig : InOut std_logic ; signal TimeOut : std_logic ; constant Polarity : in std_logic := '1') is | |||
| begin | |||
| Sig <= 'H' ; | |||
| -- Wait until all processes set Sig to H | |||
| -- Level check not necessary since last value /= H yet | |||
| wait until Sig = 'H' or TimeOut = Polarity ; | |||
| -- Deactivate and propagate to allow back to back calls | |||
| Sig <= '0' ; | |||
| wait for 0 ns ; | |||
| end procedure WaitForBarrier ; | |||
| procedure WaitForBarrier ( signal Sig : InOut std_logic ; constant TimeOut : time ) is | |||
| begin | |||
| Sig <= 'H' ; | |||
| -- Wait until all processes set Sig to H | |||
| -- Level check not necessary since last value /= H yet | |||
| wait until Sig = 'H' for TimeOut ; | |||
| -- Deactivate and propagate to allow back to back calls | |||
| Sig <= '0' ; | |||
| wait for 0 ns ; | |||
| end procedure WaitForBarrier ; | |||
| ------------------------------------------------------------ | |||
| -- resolved_barrier | |||
| -- summing resolution used in conjunction with integer based barriers | |||
| function resolved_barrier ( s : integer_vector ) return integer is | |||
| variable result : integer := 0 ; | |||
| begin | |||
| for i in s'RANGE loop | |||
| if s(i) /= integer'left then | |||
| result := s(i) + result; | |||
| else | |||
| return integer'left ; -- removes the initialization requirement | |||
| end if ; | |||
| end loop ; | |||
| return result ; | |||
| end function resolved_barrier ; | |||
| -- Usage of integer barriers requires resolved_barrier. Initialization to 1 recommended, but not required | |||
| -- signal barrier1 : resolved_barrier integer := 1 ; -- using the resolution function | |||
| -- signal barrier2 : integer_barrier := 1 ; -- using the subtype that already applies the resolution function | |||
| procedure WaitForBarrier ( signal Sig : InOut integer ) is | |||
| begin | |||
| Sig <= 0 ; | |||
| -- Wait until all processes set Sig to 0 | |||
| -- Level check not necessary since last value /= 0 yet | |||
| wait until Sig = 0 ; | |||
| -- Deactivate and propagate to allow back to back calls | |||
| Sig <= 1 ; | |||
| wait for 0 ns ; | |||
| end procedure WaitForBarrier ; | |||
| procedure WaitForBarrier ( signal Sig : InOut integer ; signal TimeOut : std_logic ; constant Polarity : in std_logic := '1') is | |||
| begin | |||
| Sig <= 0 ; | |||
| -- Wait until all processes set Sig to 0 | |||
| -- Level check not necessary since last value /= 0 yet | |||
| wait until Sig = 0 or TimeOut = Polarity ; | |||
| -- Deactivate and propagate to allow back to back calls | |||
| Sig <= 1 ; | |||
| wait for 0 ns ; | |||
| end procedure WaitForBarrier ; | |||
| procedure WaitForBarrier ( signal Sig : InOut integer ; constant TimeOut : time ) is | |||
| begin | |||
| Sig <= 0 ; | |||
| -- Wait until all processes set Sig to 0 | |||
| -- Level check not necessary since last value /= 0 yet | |||
| wait until Sig = 0 for TimeOut ; | |||
| -- Deactivate and propagate to allow back to back calls | |||
| Sig <= 1 ; | |||
| wait for 0 ns ; | |||
| end procedure WaitForBarrier ; | |||
| -- Using separate signals | |||
| procedure WaitForBarrier2 ( signal SyncOut : out std_logic ; signal SyncIn : in std_logic ) is | |||
| begin | |||
| -- Activate Rdy | |||
| SyncOut <= '1' ; | |||
| -- Make sure our Rdy is seen | |||
| wait for 0 ns ; | |||
| -- Wait until other process' Rdy is at level 1 | |||
| if SyncIn /= '1' then | |||
| wait until SyncIn = '1' ; | |||
| end if ; | |||
| -- Deactivate Rdy | |||
| SyncOut <= '0' ; | |||
| end procedure WaitForBarrier2 ; | |||
| procedure WaitForBarrier2 ( signal SyncOut : out std_logic ; signal SyncInV : in std_logic_vector ) is | |||
| constant ALL_ONE : std_logic_vector(SyncInV'Range) := (others => '1'); | |||
| begin | |||
| -- Activate Rdy | |||
| SyncOut <= '1' ; | |||
| -- Make sure our Rdy is seen | |||
| wait for 0 ns ; | |||
| -- Wait until all other process' Rdy is at level 1 | |||
| if SyncInV /= ALL_ONE then | |||
| wait until SyncInV = ALL_ONE ; | |||
| end if ; | |||
| -- Deactivate Rdy | |||
| SyncOut <= '0' ; | |||
| end procedure WaitForBarrier2 ; | |||
| ------------------------------------------------------------ | |||
| -- WaitForClock | |||
| -- Sync to Clock - after a delay, after a number of clocks | |||
| ------------------------------------------------------------ | |||
| procedure WaitForClock ( signal Clk : in std_logic ; constant Delay : in time ) is | |||
| begin | |||
| if delay > t_sim_resolution then | |||
| wait for delay - t_sim_resolution ; | |||
| end if ; | |||
| wait until Clk = CLK_ACTIVE ; | |||
| end procedure WaitForClock ; | |||
| procedure WaitForClock ( signal Clk : in std_logic ; constant NumberOfClocks : in integer := 1) is | |||
| begin | |||
| for i in 1 to NumberOfClocks loop | |||
| wait until Clk = CLK_ACTIVE ; | |||
| end loop ; | |||
| end procedure WaitForClock ; | |||
| procedure WaitForClock ( signal Clk : in std_logic ; signal Enable : in boolean ) is | |||
| begin | |||
| wait on Clk until Clk = CLK_ACTIVE and Enable ; | |||
| end procedure WaitForClock ; | |||
| procedure WaitForClock ( signal Clk : in std_logic ; signal Enable : in std_logic ; constant Polarity : std_logic := '1' ) is | |||
| begin | |||
| wait on Clk until Clk = CLK_ACTIVE and Enable = Polarity ; | |||
| end procedure WaitForClock ; | |||
| ------------------------------------------------------------ | |||
| -- WaitForLevel | |||
| -- Find a signal at a level | |||
| ------------------------------------------------------------ | |||
| procedure WaitForLevel ( signal A : in boolean ) is | |||
| begin | |||
| if not A then | |||
| wait until A ; | |||
| end if ; | |||
| end procedure WaitForLevel ; | |||
| procedure WaitForLevel ( signal A : in std_logic ; Polarity : std_logic := '1' ) is | |||
| begin | |||
| if A /= Polarity then | |||
| -- wait on A until A = Polarity ; | |||
| if Polarity = '1' then | |||
| wait until A = '1' ; | |||
| else | |||
| wait until A = '0' ; | |||
| end if ; | |||
| end if ; | |||
| end procedure WaitForLevel ; | |||
| ------------------------------------------------------------ | |||
| -- CreateClock, CreateReset | |||
| -- Note these do not exit | |||
| ------------------------------------------------------------ | |||
| procedure CreateClock ( | |||
| signal Clk : inout std_logic ; | |||
| constant Period : time ; | |||
| constant DutyCycle : real := 0.5 | |||
| ) is | |||
| constant HIGH_TIME : time := Period * DutyCycle ; | |||
| constant LOW_TIME : time := Period - HIGH_TIME ; | |||
| begin | |||
| if HIGH_TIME = LOW_TIME then | |||
| loop | |||
| Clk <= toggle_sl_table(Clk) after HIGH_TIME ; | |||
| wait on Clk ; | |||
| end loop ; | |||
| else | |||
| -- Schedule s.t. all assignments after the first occur on delta cycle 0 | |||
| Clk <= '0', '1' after LOW_TIME ; | |||
| wait for period - 1 ns ; -- allows after on future Clk <= '0' | |||
| loop | |||
| Clk <= '0' after 1 ns, '1' after LOW_TIME + 1 ns ; | |||
| wait for period ; | |||
| end loop ; | |||
| end if ; | |||
| end procedure CreateClock ; | |||
| procedure CheckClockPeriod ( | |||
| constant AlertLogID : AlertLogIDType ; | |||
| signal Clk : in std_logic ; | |||
| constant Period : time ; | |||
| constant ClkName : string := "Clock" ; | |||
| constant HowMany : integer := 5 | |||
| ) is | |||
| variable LastLogTime, ObservedPeriod : time ; | |||
| begin | |||
| wait until Clk = CLK_ACTIVE ; | |||
| LastLogTime := now ; | |||
| -- Check First HowMany clocks | |||
| for i in 1 to HowMany loop | |||
| wait until Clk = CLK_ACTIVE ; | |||
| ObservedPeriod := now - LastLogTime ; | |||
| AffirmIf(AlertLogID, ObservedPeriod = Period, | |||
| "CheckClockPeriod: " & ClkName & " Period: " & to_string(ObservedPeriod) & | |||
| " = Expected " & to_string(Period)) ; | |||
| LastLogTime := now ; | |||
| end loop ; | |||
| wait ; | |||
| end procedure CheckClockPeriod ; | |||
| procedure CheckClockPeriod ( | |||
| signal Clk : in std_logic ; | |||
| constant Period : time ; | |||
| constant ClkName : string := "Clock" ; | |||
| constant HowMany : integer := 5 | |||
| ) is | |||
| begin | |||
| CheckClockPeriod ( | |||
| AlertLogID => ALERTLOG_DEFAULT_ID, | |||
| Clk => Clk, | |||
| Period => Period, | |||
| ClkName => ClkName, | |||
| HowMany => HowMany | |||
| ) ; | |||
| end procedure CheckClockPeriod ; | |||
| procedure CreateReset ( | |||
| signal Reset : out std_logic ; | |||
| constant ResetActive : in std_logic ; | |||
| signal Clk : in std_logic ; | |||
| constant Period : time ; | |||
| constant tpd : time | |||
| ) is | |||
| begin | |||
| wait until Clk = CLK_ACTIVE ; | |||
| Reset <= ResetActive after tpd ; | |||
| wait for Period - t_sim_resolution ; | |||
| wait until Clk = CLK_ACTIVE ; | |||
| Reset <= not ResetActive after tpd ; | |||
| wait ; | |||
| end procedure CreateReset ; | |||
| procedure LogReset ( | |||
| constant AlertLogID : AlertLogIDType ; | |||
| signal Reset : in std_logic ; | |||
| constant ResetActive : in std_logic ; | |||
| constant ResetName : in string := "Reset" ; | |||
| constant LogLevel : in LogType := ALWAYS | |||
| ) is | |||
| begin | |||
| -- Does not log the value of Reset at time 0. | |||
| for_ever : loop | |||
| wait on Reset ; | |||
| if Reset = ResetActive then | |||
| LOG(AlertLogID, ResetName & " now active", INFO) ; | |||
| print("") ; | |||
| elsif Reset = not ResetActive then | |||
| LOG(AlertLogID, ResetName & " now inactive", INFO) ; | |||
| print("") ; | |||
| else | |||
| LOG(AlertLogID, ResetName & " = " & to_string(Reset), INFO) ; | |||
| print("") ; | |||
| end if ; | |||
| end loop for_ever ; | |||
| end procedure LogReset ; | |||
| procedure LogReset ( | |||
| signal Reset : in std_logic ; | |||
| constant ResetActive : in std_logic ; | |||
| constant ResetName : in string := "Reset" ; | |||
| constant LogLevel : in LogType := ALWAYS | |||
| ) is | |||
| begin | |||
| LogReset ( | |||
| AlertLogID => ALERTLOG_DEFAULT_ID, | |||
| Reset => Reset, | |||
| ResetActive => ResetActive, | |||
| ResetName => ResetName, | |||
| LogLevel => LogLevel | |||
| ) ; | |||
| end procedure LogReset ; | |||
| ------------------------------------------------------------ | |||
| -- Deprecated | |||
| -- subsumed by WaitForTransaction with Ack and TimeOut. | |||
| -- TimeOut works exactly like IntReq | |||
| ------------------------------------------------------------ | |||
| procedure WaitForTransactionOrIrq ( | |||
| signal Clk : In std_logic ; | |||
| signal Rdy : In std_logic ; | |||
| signal IntReq : In std_logic | |||
| ) is | |||
| variable AckTime : time ; | |||
| constant POLARITY : std_logic := '1' ; | |||
| begin | |||
| AckTime := NOW ; | |||
| -- Find Ready or Time out | |||
| if (Rdy /= '1' and IntReq /= POLARITY) then | |||
| wait until Rdy = '1' or IntReq = POLARITY ; | |||
| else | |||
| wait for 0 ns ; -- allow Ack to update | |||
| end if ; | |||
| -- align to clock if Rdy or IntReq does not happen within delta cycles from Ack | |||
| if NOW /= AckTime then | |||
| wait until Clk = CLK_ACTIVE ; | |||
| end if ; | |||
| end procedure ; | |||
| ------------------------------------------------------------ | |||
| -- Deprecated | |||
| -- WaitForAck, StrobeAck | |||
| -- Replaced by WaitForToggle and Toggle | |||
| ------------------------------------------------------------ | |||
| procedure WaitForAck ( signal Ack : In std_logic ) is | |||
| begin | |||
| -- Wait for Model to be done | |||
| wait until Ack = '1' ; | |||
| end procedure ; | |||
| procedure StrobeAck ( signal Ack : Out std_logic ) is | |||
| begin | |||
| -- Model done, drive rising edge on Ack | |||
| Ack <= '0' ; | |||
| wait for 0 ns ; | |||
| Ack <= '1' ; | |||
| end procedure ; | |||
| end TbUtilPkg ; | |||
| @ -0,0 +1,407 @@ | |||
| -- | |||
| -- File Name: TextUtilPkg.vhd | |||
| -- Design Unit Name: TextUtilPkg | |||
| -- Revision: STANDARD VERSION | |||
| -- | |||
| -- Maintainer: Jim Lewis email: jim@synthworks.com | |||
| -- Contributor(s): | |||
| -- Jim Lewis jim@synthworks.com | |||
| -- | |||
| -- | |||
| -- Description: | |||
| -- Shared Utilities for handling text files | |||
| -- | |||
| -- | |||
| -- Developed for: | |||
| -- SynthWorks Design Inc. | |||
| -- VHDL Training Classes | |||
| -- 11898 SW 128th Ave. Tigard, Or 97223 | |||
| -- http://www.SynthWorks.com | |||
| -- | |||
| -- Revision History: | |||
| -- Date Version Description | |||
| -- 01/2015: 2015.05 Initial revision | |||
| -- 01/2016: 2016.01 Update for L.all(L'left) | |||
| -- 11/2016: 2016.11 Added IsUpper, IsLower, to_upper, to_lower | |||
| -- | |||
| -- | |||
| -- Copyright (c) 2015-2016 by SynthWorks Design Inc. All rights reserved. | |||
| -- | |||
| -- Verbatim copies of this source file may be used and | |||
| -- distributed without restriction. | |||
| -- | |||
| -- This source file is free software; you can redistribute it | |||
| -- and/or modify it under the terms of the ARTISTIC License | |||
| -- as published by The Perl Foundation; either version 2.0 of | |||
| -- the License, or (at your option) any later version. | |||
| -- | |||
| -- This source is distributed in the hope that it will be | |||
| -- useful, but WITHOUT ANY WARRANTY; without even the implied | |||
| -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||
| -- PURPOSE. See the Artistic License for details. | |||
| -- | |||
| -- You should have received a copy of the license with this source. | |||
| -- If not download it from, | |||
| -- http://www.perlfoundation.org/artistic_license_2_0 | |||
| -- | |||
| use std.textio.all ; | |||
| library ieee ; | |||
| use ieee.std_logic_1164.all ; | |||
| package TextUtilPkg is | |||
| ------------------------------------------------------------ | |||
| function IsUpper (constant Char : character ) return boolean ; | |||
| function IsLower (constant Char : character ) return boolean ; | |||
| function to_lower (constant Char : character ) return character ; | |||
| function to_lower (constant Str : string ) return string ; | |||
| function to_upper (constant Char : character ) return character ; | |||
| function to_upper (constant Str : string ) return string ; | |||
| function ishex (constant Char : character ) return boolean ; | |||
| function isstd_logic (constant Char : character ) return boolean ; | |||
| ------------------------------------------------------------ | |||
| procedure SkipWhiteSpace ( | |||
| ------------------------------------------------------------ | |||
| variable L : InOut line ; | |||
| variable Empty : out boolean | |||
| ) ; | |||
| procedure SkipWhiteSpace (variable L : InOut line) ; | |||
| ------------------------------------------------------------ | |||
| procedure EmptyOrCommentLine ( | |||
| ------------------------------------------------------------ | |||
| variable L : InOut line ; | |||
| variable Empty : InOut boolean ; | |||
| variable MultiLineComment : inout boolean | |||
| ) ; | |||
| ------------------------------------------------------------ | |||
| procedure ReadHexToken ( | |||
| -- Reads Upto Result'length values, less is ok. | |||
| -- Does not skip white space | |||
| ------------------------------------------------------------ | |||
| variable L : InOut line ; | |||
| variable Result : Out std_logic_vector ; | |||
| variable StrLen : Out integer | |||
| ) ; | |||
| ------------------------------------------------------------ | |||
| procedure ReadBinaryToken ( | |||
| -- Reads Upto Result'length values, less is ok. | |||
| -- Does not skip white space | |||
| ------------------------------------------------------------ | |||
| variable L : InOut line ; | |||
| variable Result : Out std_logic_vector ; | |||
| variable StrLen : Out integer | |||
| ) ; | |||
| end TextUtilPkg ; | |||
| --- /////////////////////////////////////////////////////////////////////////// | |||
| --- /////////////////////////////////////////////////////////////////////////// | |||
| --- /////////////////////////////////////////////////////////////////////////// | |||
| package body TextUtilPkg is | |||
| constant LOWER_TO_UPPER_OFFSET : integer := character'POS('a') - character'POS('A') ; | |||
| ------------------------------------------------------------ | |||
| function "-" (R : character ; L : integer ) return character is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return character'VAL(character'pos(R) - L) ; | |||
| end function "-" ; | |||
| ------------------------------------------------------------ | |||
| function "+" (R : character ; L : integer ) return character is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return character'VAL(character'pos(R) + L) ; | |||
| end function "+" ; | |||
| ------------------------------------------------------------ | |||
| function IsUpper (constant Char : character ) return boolean is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| if Char >= 'A' and Char <= 'Z' then | |||
| return TRUE ; | |||
| else | |||
| return FALSE ; | |||
| end if ; | |||
| end function IsUpper ; | |||
| ------------------------------------------------------------ | |||
| function IsLower (constant Char : character ) return boolean is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| if Char >= 'a' and Char <= 'z' then | |||
| return TRUE ; | |||
| else | |||
| return FALSE ; | |||
| end if ; | |||
| end function IsLower ; | |||
| ------------------------------------------------------------ | |||
| function to_lower (constant Char : character ) return character is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| if IsUpper(Char) then | |||
| return Char + LOWER_TO_UPPER_OFFSET ; | |||
| else | |||
| return Char ; | |||
| end if ; | |||
| end function to_lower ; | |||
| ------------------------------------------------------------ | |||
| function to_lower (constant Str : string ) return string is | |||
| ------------------------------------------------------------ | |||
| variable result : string(Str'range) ; | |||
| begin | |||
| for i in Str'range loop | |||
| result(i) := to_lower(Str(i)) ; | |||
| end loop ; | |||
| return result ; | |||
| end function to_lower ; | |||
| ------------------------------------------------------------ | |||
| function to_upper (constant Char : character ) return character is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| if IsLower(Char) then | |||
| return Char - LOWER_TO_UPPER_OFFSET ; | |||
| else | |||
| return Char ; | |||
| end if ; | |||
| end function to_upper ; | |||
| ------------------------------------------------------------ | |||
| function to_upper (constant Str : string ) return string is | |||
| ------------------------------------------------------------ | |||
| variable result : string(Str'range) ; | |||
| begin | |||
| for i in Str'range loop | |||
| result(i) := to_upper(Str(i)) ; | |||
| end loop ; | |||
| return result ; | |||
| end function to_upper ; | |||
| ------------------------------------------------------------ | |||
| function ishex (constant Char : character ) return boolean is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| if Char >= '0' and Char <= '9' then | |||
| return TRUE ; | |||
| elsif Char >= 'a' and Char <= 'f' then | |||
| return TRUE ; | |||
| elsif Char >= 'A' and Char <= 'F' then | |||
| return TRUE ; | |||
| else | |||
| return FALSE ; | |||
| end if ; | |||
| end function ishex ; | |||
| ------------------------------------------------------------ | |||
| function isstd_logic (constant Char : character ) return boolean is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| case Char is | |||
| when 'U' | 'X' | '0' | '1' | 'Z' | 'W' | 'L' | 'H' | '-' => | |||
| return TRUE ; | |||
| when others => | |||
| return FALSE ; | |||
| end case ; | |||
| end function isstd_logic ; | |||
| -- ------------------------------------------------------------ | |||
| -- function iscomment (constant Char : character ) return boolean is | |||
| -- ------------------------------------------------------------ | |||
| -- begin | |||
| -- case Char is | |||
| -- when '#' | '/' | '-' => | |||
| -- return TRUE ; | |||
| -- when others => | |||
| -- return FALSE ; | |||
| -- end case ; | |||
| -- end function iscomment ; | |||
| ------------------------------------------------------------ | |||
| procedure SkipWhiteSpace ( | |||
| ------------------------------------------------------------ | |||
| variable L : InOut line ; | |||
| variable Empty : out boolean | |||
| ) is | |||
| variable Valid : boolean ; | |||
| variable Char : character ; | |||
| constant NBSP : CHARACTER := CHARACTER'val(160); -- space character | |||
| begin | |||
| Empty := TRUE ; | |||
| WhiteSpLoop : while L /= null and L.all'length > 0 loop | |||
| if (L.all(L'left) = ' ' or L.all(L'left) = NBSP or L.all(L'left) = HT) then | |||
| read (L, Char, Valid) ; | |||
| exit when not Valid ; | |||
| else | |||
| Empty := FALSE ; | |||
| return ; | |||
| end if ; | |||
| end loop WhiteSpLoop ; | |||
| end procedure SkipWhiteSpace ; | |||
| ------------------------------------------------------------ | |||
| procedure SkipWhiteSpace ( | |||
| ------------------------------------------------------------ | |||
| variable L : InOut line | |||
| ) is | |||
| variable Empty : boolean ; | |||
| begin | |||
| SkipWhiteSpace(L, Empty) ; | |||
| end procedure SkipWhiteSpace ; | |||
| ------------------------------------------------------------ | |||
| -- Package Local | |||
| procedure FindCommentEnd ( | |||
| ------------------------------------------------------------ | |||
| variable L : InOut line ; | |||
| variable Empty : out boolean ; | |||
| variable MultiLineComment : inout boolean | |||
| ) is | |||
| variable Valid : boolean ; | |||
| variable Char : character ; | |||
| begin | |||
| MultiLineComment := TRUE ; | |||
| Empty := TRUE ; | |||
| FindEndOfCommentLoop : while L /= null and L.all'length > 1 loop | |||
| read(L, Char, Valid) ; | |||
| if Char = '*' and L.all(L'left) = '/' then | |||
| read(L, Char, Valid) ; | |||
| Empty := FALSE ; | |||
| MultiLineComment := FALSE ; | |||
| exit FindEndOfCommentLoop ; | |||
| end if ; | |||
| end loop ; | |||
| end procedure FindCommentEnd ; | |||
| ------------------------------------------------------------ | |||
| procedure EmptyOrCommentLine ( | |||
| ------------------------------------------------------------ | |||
| variable L : InOut line ; | |||
| variable Empty : InOut boolean ; | |||
| variable MultiLineComment : inout boolean | |||
| ) is | |||
| variable Valid : boolean ; | |||
| variable Next2Char : string(1 to 2) ; | |||
| constant NBSP : CHARACTER := CHARACTER'val(160); -- space character | |||
| begin | |||
| if MultiLineComment then | |||
| FindCommentEnd(L, Empty, MultiLineComment) ; | |||
| end if ; | |||
| EmptyCheckLoop : while not MultiLineComment loop | |||
| SkipWhiteSpace(L, Empty) ; | |||
| exit when Empty ; -- line null or 0 in length detected by SkipWhite | |||
| Empty := TRUE ; | |||
| exit when L.all(L'left) = '#' ; -- shell style comment | |||
| if L.all'length >= 2 then | |||
| if L'ascending then | |||
| Next2Char := L.all(L'left to L'left+1) ; | |||
| else | |||
| Next2Char := L.all(L'left to L'left-1) ; | |||
| end if; | |||
| exit when Next2Char = "//" ; -- C style comment | |||
| exit when Next2Char = "--" ; -- VHDL style comment | |||
| if Next2Char = "/*" then -- C style multi line comment | |||
| FindCommentEnd(L, Empty, MultiLineComment) ; | |||
| exit when Empty ; | |||
| next EmptyCheckLoop ; -- Found end of comment, restart processing line | |||
| end if ; | |||
| end if ; | |||
| Empty := FALSE ; | |||
| exit ; | |||
| end loop EmptyCheckLoop ; | |||
| end procedure EmptyOrCommentLine ; | |||
| ------------------------------------------------------------ | |||
| procedure ReadHexToken ( | |||
| -- Reads Upto Result'length values, less is ok. | |||
| -- Does not skip white space | |||
| ------------------------------------------------------------ | |||
| variable L : InOut line ; | |||
| variable Result : Out std_logic_vector ; | |||
| variable StrLen : Out integer | |||
| ) is | |||
| constant NumHexChars : integer := (Result'length+3)/4 ; | |||
| constant ResultNormLen : integer := NumHexChars * 4 ; | |||
| variable NextChar : character ; | |||
| variable CharCount : integer ; | |||
| variable ReturnVal : std_logic_vector(ResultNormLen-1 downto 0) ; | |||
| variable ReadVal : std_logic_vector(3 downto 0) ; | |||
| variable ReadValid : boolean ; | |||
| begin | |||
| ReturnVal := (others => '0') ; | |||
| CharCount := 0 ; | |||
| ReadLoop : while L /= null and L.all'length > 0 loop | |||
| NextChar := L.all(L'left) ; | |||
| if ishex(NextChar) or NextChar = 'X' or NextChar = 'Z' then | |||
| hread(L, ReadVal, ReadValid) ; | |||
| ReturnVal := ReturnVal(ResultNormLen-5 downto 0) & ReadVal ; | |||
| CharCount := CharCount + 1 ; | |||
| exit ReadLoop when CharCount >= NumHexChars ; | |||
| elsif NextChar = '_' then | |||
| read(L, NextChar, ReadValid) ; | |||
| else | |||
| exit ; | |||
| end if ; | |||
| end loop ReadLoop ; | |||
| if CharCount >= NumHexChars then | |||
| StrLen := Result'length ; | |||
| else | |||
| StrLen := CharCount * 4 ; | |||
| end if ; | |||
| Result := ReturnVal(Result'length-1 downto 0) ; | |||
| end procedure ReadHexToken ; | |||
| ------------------------------------------------------------ | |||
| procedure ReadBinaryToken ( | |||
| -- Reads Upto Result'length values, less is ok. | |||
| -- Does not skip white space | |||
| ------------------------------------------------------------ | |||
| variable L : InOut line ; | |||
| variable Result : Out std_logic_vector ; | |||
| variable StrLen : Out integer | |||
| ) is | |||
| variable NextChar : character ; | |||
| variable CharCount : integer ; | |||
| variable ReadVal : std_logic ; | |||
| variable ReturnVal : std_logic_vector(Result'length-1 downto 0) ; | |||
| variable ReadValid : boolean ; | |||
| begin | |||
| ReturnVal := (others => '0') ; | |||
| CharCount := 0 ; | |||
| ReadLoop : while L /= null and L.all'length > 0 loop | |||
| NextChar := L.all(L'left) ; | |||
| if isstd_logic(NextChar) then | |||
| read(L, ReadVal, ReadValid) ; | |||
| ReturnVal := ReturnVal(Result'length-2 downto 0) & ReadVal ; | |||
| CharCount := CharCount + 1 ; | |||
| exit ReadLoop when CharCount >= Result'length ; | |||
| elsif NextChar = '_' then | |||
| read(L, NextChar, ReadValid) ; | |||
| else | |||
| exit ; | |||
| end if ; | |||
| end loop ReadLoop ; | |||
| StrLen := CharCount ; | |||
| Result := ReturnVal ; | |||
| end procedure ReadBinaryToken ; | |||
| end package body TextUtilPkg ; | |||
| @ -0,0 +1,200 @@ | |||
| -- | |||
| -- File Name: TranscriptPkg.vhd | |||
| -- Design Unit Name: TranscriptPkg | |||
| -- Revision: STANDARD VERSION | |||
| -- | |||
| -- Maintainer: Jim Lewis email: jim@synthworks.com | |||
| -- Contributor(s): | |||
| -- Jim Lewis jim@synthworks.com | |||
| -- | |||
| -- | |||
| -- Description: | |||
| -- Define file identifier TranscriptFile | |||
| -- provide subprograms to open, close, and print to it. | |||
| -- | |||
| -- | |||
| -- Developed for: | |||
| -- SynthWorks Design Inc. | |||
| -- VHDL Training Classes | |||
| -- 11898 SW 128th Ave. Tigard, Or 97223 | |||
| -- http://www.SynthWorks.com | |||
| -- | |||
| -- Revision History: | |||
| -- Date Version Description | |||
| -- 01/2015: 2015.01 Initial revision | |||
| -- 01/2016: 2016.01 TranscriptOpen function now calls procedure of same name | |||
| -- 11/2016: 2016.l1 Added procedure BlankLine | |||
| -- | |||
| -- | |||
| -- Copyright (c) 2015-2016 by SynthWorks Design Inc. All rights reserved. | |||
| -- | |||
| -- Verbatim copies of this source file may be used and | |||
| -- distributed without restriction. | |||
| -- | |||
| -- This source file is free software; you can redistribute it | |||
| -- and/or modify it under the terms of the ARTISTIC License | |||
| -- as published by The Perl Foundation; either version 2.0 of | |||
| -- the License, or (at your option) any later version. | |||
| -- | |||
| -- This source is distributed in the hope that it will be | |||
| -- useful, but WITHOUT ANY WARRANTY; without even the implied | |||
| -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||
| -- PURPOSE. See the Artistic License for details. | |||
| -- | |||
| -- You should have received a copy of the license with this source. | |||
| -- If not download it from, | |||
| -- http://www.perlfoundation.org/artistic_license_2_0 | |||
| -- | |||
| use std.textio.all ; | |||
| package TranscriptPkg is | |||
| -- File Identifier to facilitate usage of one transcript file | |||
| file TranscriptFile : text ; | |||
| -- Cause compile errors if READ_MODE is passed to TranscriptOpen | |||
| subtype WRITE_APPEND_OPEN_KIND is FILE_OPEN_KIND range WRITE_MODE to APPEND_MODE ; | |||
| -- Open and close TranscriptFile. Function allows declarative opens | |||
| procedure TranscriptOpen (Status: out FILE_OPEN_STATUS; ExternalName: STRING; OpenKind: WRITE_APPEND_OPEN_KIND := WRITE_MODE) ; | |||
| procedure TranscriptOpen (ExternalName: STRING; OpenKind: WRITE_APPEND_OPEN_KIND := WRITE_MODE) ; | |||
| impure function TranscriptOpen (ExternalName: STRING; OpenKind: WRITE_APPEND_OPEN_KIND := WRITE_MODE) return FILE_OPEN_STATUS ; | |||
| procedure TranscriptClose ; | |||
| impure function IsTranscriptOpen return boolean ; | |||
| alias IsTranscriptEnabled is IsTranscriptOpen [return boolean] ; | |||
| -- Mirroring. When using TranscriptPkw WriteLine and Print, uses both TranscriptFile and OUTPUT | |||
| procedure SetTranscriptMirror (A : boolean := TRUE) ; | |||
| impure function IsTranscriptMirrored return boolean ; | |||
| alias GetTranscriptMirror is IsTranscriptMirrored [return boolean] ; | |||
| -- Write to TranscriptFile when open. Write to OUTPUT when not open or IsTranscriptMirrored | |||
| procedure WriteLine(buf : inout line) ; | |||
| procedure Print(s : string) ; | |||
| -- Create "count" number of blank lines | |||
| procedure BlankLine (count : integer := 1) ; | |||
| end TranscriptPkg ; | |||
| --- /////////////////////////////////////////////////////////////////////////// | |||
| --- /////////////////////////////////////////////////////////////////////////// | |||
| --- /////////////////////////////////////////////////////////////////////////// | |||
| package body TranscriptPkg is | |||
| ------------------------------------------------------------ | |||
| type LocalBooleanPType is protected | |||
| procedure Set (A : boolean) ; | |||
| impure function get return boolean ; | |||
| end protected LocalBooleanPType ; | |||
| type LocalBooleanPType is protected body | |||
| variable GlobalVar : boolean := FALSE ; | |||
| procedure Set (A : boolean) is | |||
| begin | |||
| GlobalVar := A ; | |||
| end procedure Set ; | |||
| impure function get return boolean is | |||
| begin | |||
| return GlobalVar ; | |||
| end function get ; | |||
| end protected body LocalBooleanPType ; | |||
| ------------------------------------------------------------ | |||
| shared variable TranscriptEnable : LocalBooleanPType ; | |||
| shared variable TranscriptMirror : LocalBooleanPType ; | |||
| ------------------------------------------------------------ | |||
| procedure TranscriptOpen (Status: out FILE_OPEN_STATUS; ExternalName: STRING; OpenKind: WRITE_APPEND_OPEN_KIND := WRITE_MODE) is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| file_open(Status, TranscriptFile, ExternalName, OpenKind) ; | |||
| if Status = OPEN_OK then | |||
| TranscriptEnable.Set(TRUE) ; | |||
| end if ; | |||
| end procedure TranscriptOpen ; | |||
| ------------------------------------------------------------ | |||
| procedure TranscriptOpen (ExternalName: STRING; OpenKind: WRITE_APPEND_OPEN_KIND := WRITE_MODE) is | |||
| ------------------------------------------------------------ | |||
| variable Status : FILE_OPEN_STATUS ; | |||
| begin | |||
| TranscriptOpen(Status, ExternalName, OpenKind) ; | |||
| if Status /= OPEN_OK then | |||
| report "TranscriptPkg.TranscriptOpen file: " & | |||
| ExternalName & " status is: " & to_string(status) & " and is not OPEN_OK" severity FAILURE ; | |||
| end if ; | |||
| end procedure TranscriptOpen ; | |||
| ------------------------------------------------------------ | |||
| impure function TranscriptOpen (ExternalName: STRING; OpenKind: WRITE_APPEND_OPEN_KIND := WRITE_MODE) return FILE_OPEN_STATUS is | |||
| ------------------------------------------------------------ | |||
| variable Status : FILE_OPEN_STATUS ; | |||
| begin | |||
| TranscriptOpen(Status, ExternalName, OpenKind) ; | |||
| return Status ; | |||
| end function TranscriptOpen ; | |||
| ------------------------------------------------------------ | |||
| procedure TranscriptClose is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| if TranscriptEnable.Get then | |||
| file_close(TranscriptFile) ; | |||
| end if ; | |||
| TranscriptEnable.Set(FALSE) ; | |||
| end procedure TranscriptClose ; | |||
| ------------------------------------------------------------ | |||
| impure function IsTranscriptOpen return boolean is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return TranscriptEnable.Get ; | |||
| end function IsTranscriptOpen ; | |||
| ------------------------------------------------------------ | |||
| procedure SetTranscriptMirror (A : boolean := TRUE) is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| TranscriptMirror.Set(A) ; | |||
| end procedure SetTranscriptMirror ; | |||
| ------------------------------------------------------------ | |||
| impure function IsTranscriptMirrored return boolean is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| return TranscriptMirror.Get ; | |||
| end function IsTranscriptMirrored ; | |||
| ------------------------------------------------------------ | |||
| procedure WriteLine(buf : inout line) is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| if not TranscriptEnable.Get then | |||
| WriteLine(OUTPUT, buf) ; | |||
| elsif TranscriptMirror.Get then | |||
| TEE(TranscriptFile, buf) ; | |||
| else | |||
| WriteLine(TranscriptFile, buf) ; | |||
| end if ; | |||
| end procedure WriteLine ; | |||
| ------------------------------------------------------------ | |||
| procedure Print(s : string) is | |||
| ------------------------------------------------------------ | |||
| variable buf : line ; | |||
| begin | |||
| write(buf, s) ; | |||
| WriteLine(buf) ; | |||
| end procedure Print ; | |||
| ------------------------------------------------------------ | |||
| procedure BlankLine (count : integer := 1) is | |||
| ------------------------------------------------------------ | |||
| begin | |||
| for i in 1 to count loop | |||
| print("") ; | |||
| end loop ; | |||
| end procedure Blankline ; | |||
| end package body TranscriptPkg ; | |||
| @ -0,0 +1,120 @@ | |||
| -- | |||
| -- File Name: VendorCovApiPkg.vhd | |||
| -- Design Unit Name: VendorCovApiPkg | |||
| -- Revision: STANDARD VERSION | |||
| -- | |||
| -- Maintainer: Jim Lewis email: jim@synthworks.com | |||
| -- | |||
| -- Based on work done in package VendorCovApiPkg_Aldec.vhd by: | |||
| -- ... | |||
| -- | |||
| -- | |||
| -- Package Defines | |||
| -- A set of foreign procedures that link OSVVM's CoveragePkg | |||
| -- coverage model creation and coverage capture with the | |||
| -- built-in capability of a simulator. | |||
| -- | |||
| -- | |||
| -- Revision History: For more details, see CoveragePkg_release_notes.pdf | |||
| -- Date Version Description | |||
| -- 11/2016: 2016.11 Initial revision | |||
| -- | |||
| -- | |||
| -- Copyright (c) 2016 by SynthWorks Design Inc. All rights reserved. | |||
| -- | |||
| -- Verbatim copies of this source file may be used and | |||
| -- distributed without restriction. | |||
| -- | |||
| -- Modified copies of this source file may be distributed | |||
| -- under the terms of the ARTISTIC License as published by | |||
| -- The Perl Foundation; either version 2.0 of the License, | |||
| -- or (at your option) any later version. | |||
| -- | |||
| -- This source is distributed in the hope that it will be | |||
| -- useful, but WITHOUT ANY WARRANTY; without even the implied | |||
| -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||
| -- PURPOSE. See the Artistic License for details. | |||
| -- | |||
| -- You should have received a copy of the license with this source. | |||
| -- If not download it from, | |||
| -- http://www.perlfoundation.org/artistic_license_2_0 | |||
| -- -- | |||
| -------------------------------------------------------------------------- | |||
| package VendorCovApiPkg is | |||
| subtype VendorCovHandleType is integer; | |||
| -- Types for how coverage bins are represented. Matches OSVVM types. | |||
| type VendorCovRangeType is record | |||
| min: integer; | |||
| max: integer; | |||
| end record; | |||
| type VendorCovRangeArrayType is array ( integer range <> ) of VendorCovRangeType; | |||
| -- Create Initial Data Structure for Point/Item Functional Coverage Model | |||
| -- Sets initial name of the coverage model if available | |||
| impure function VendorCovPointCreate( name: string ) return VendorCovHandleType; | |||
| -- Create Initial Data Structure for Cross Functional Coverage Model | |||
| -- Sets initial name of the coverage model if available | |||
| impure function VendorCovCrossCreate( name: string ) return VendorCovHandleType; | |||
| -- Sets/Updates the name of the Coverage Model. | |||
| -- Should not be called until the data structure is created by VendorCovPointCreate or VendorCovCrossCreate. | |||
| -- Replaces name that was set by VendorCovPointCreate or VendorCovCrossCreate. | |||
| procedure VendorCovSetName( obj: VendorCovHandleType; name: string ); | |||
| -- Add a bin or set of bins to either a Point/Item or Cross Functional Coverage Model | |||
| -- Checking for sizing that is different from original sizing already done in OSVVM CoveragePkg | |||
| -- It is important to maintain an index that corresponds to the order the bins were entered as | |||
| -- that is used when coverage is recorded. | |||
| procedure VendorCovBinAdd( obj: VendorCovHandleType; bins: VendorCovRangeArrayType; Action: integer; atleast: integer; name: string ); | |||
| -- Increment the coverage of bin identified by index number. | |||
| -- Index ranges from 1 to Number of Bins. | |||
| -- Index corresponds to the order the bins were entered (starting from 1) | |||
| procedure VendorCovBinInc( obj: VendorCovHandleType; index: integer ); | |||
| end package; | |||
| package body VendorCovApiPkg is | |||
| -- Create Initial Data Structure for Point/Item Functional Coverage Model | |||
| -- Sets initial name of the coverage model if available | |||
| impure function VendorCovPointCreate( name: string ) return VendorCovHandleType is | |||
| begin | |||
| return 0 ; | |||
| end function VendorCovPointCreate ; | |||
| -- Create Initial Data Structure for Cross Functional Coverage Model | |||
| -- Sets initial name of the coverage model if available | |||
| impure function VendorCovCrossCreate( name: string ) return VendorCovHandleType is | |||
| begin | |||
| return 0 ; | |||
| end function VendorCovCrossCreate ; | |||
| -- Sets/Updates the name of the Coverage Model. | |||
| -- Should not be called until the data structure is created by VendorCovPointCreate or VendorCovCrossCreate. | |||
| -- Replaces name that was set by VendorCovPointCreate or VendorCovCrossCreate. | |||
| procedure VendorCovSetName( obj: VendorCovHandleType; name: string ) is | |||
| begin | |||
| end procedure VendorCovSetName ; | |||
| -- Add a bin or set of bins to either a Point/Item or Cross Functional Coverage Model | |||
| -- Checking for sizing that is different from original sizing already done in OSVVM CoveragePkg | |||
| -- It is important to maintain an index that corresponds to the order the bins were entered as | |||
| -- that is used when coverage is recorded. | |||
| procedure VendorCovBinAdd( obj: VendorCovHandleType; bins: VendorCovRangeArrayType; Action: integer; atleast: integer; name: string )is | |||
| begin | |||
| end procedure VendorCovBinAdd ; | |||
| -- Increment the coverage of bin identified by index number. | |||
| -- Index ranges from 1 to Number of Bins. | |||
| -- Index corresponds to the order the bins were entered (starting from 1) | |||
| procedure VendorCovBinInc( obj: VendorCovHandleType; index: integer )is | |||
| begin | |||
| end procedure VendorCovBinInc ; | |||
| end package body VendorCovApiPkg ; | |||
| @ -0,0 +1,92 @@ | |||
| -- | |||
| -- File Name: VendorCovApiPkg_Aldec.vhd | |||
| -- Design Unit Name: VendorCovApiPkg | |||
| -- Revision: ALDEC VERSION | |||
| -- | |||
| -- Maintainer: | |||
| -- | |||
| -- Package Defines | |||
| -- A set of foreign procedures that link OSVVM's CoveragePkg | |||
| -- coverage model creation and coverage capture with the | |||
| -- built-in capability of a simulator. | |||
| -- | |||
| -- | |||
| -- Revision History: For more details, see CoveragePkg_release_notes.pdf | |||
| -- Date Version Description | |||
| -- 11/2016: 2016.11 Initial revision | |||
| -- 12/2016 2016.11a Fixed an issue with attributes | |||
| -- | |||
| -- | |||
| -- Copyright (c) 2016 by Aldec. All rights reserved. | |||
| -- | |||
| -- Verbatim copies of this source file may be used and | |||
| -- distributed without restriction. | |||
| -- | |||
| -- Modified copies of this source file may be distributed | |||
| -- under the terms of the ARTISTIC License as published by | |||
| -- The Perl Foundation; either version 2.0 of the License, | |||
| -- or (at your option) any later version. | |||
| -- | |||
| -- This source is distributed in the hope that it will be | |||
| -- useful, but WITHOUT ANY WARRANTY; without even the implied | |||
| -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||
| -- PURPOSE. See the Artistic License for details. | |||
| -- | |||
| -- You should have received a copy of the license with this source. | |||
| -- If not download it from, | |||
| -- http://www.perlfoundation.org/artistic_license_2_0 | |||
| -- -- | |||
| -------------------------------------------------------------------------- | |||
| package VendorCovApiPkg is | |||
| subtype VendorCovHandleType is integer; | |||
| -- Types for how coverage bins are represented. Matches OSVVM types. | |||
| type VendorCovRangeType is record | |||
| min: integer; | |||
| max: integer; | |||
| end record; | |||
| type VendorCovRangeArrayType is array ( integer range <> ) of VendorCovRangeType; | |||
| -- Create Initial Data Structure for Point/Item Functional Coverage Model | |||
| -- Sets initial name of the coverage model if available | |||
| impure function VendorCovPointCreate( name: string ) return VendorCovHandleType; | |||
| attribute foreign of VendorCovPointCreate[ string return VendorCovHandleType ]: function is "VHPI systf; cvg_CvpCreate"; | |||
| -- Create Initial Data Structure for Cross Functional Coverage Model | |||
| -- Sets initial name of the coverage model if available | |||
| impure function VendorCovCrossCreate( name: string ) return VendorCovHandleType; | |||
| attribute foreign of VendorCovCrossCreate[ string return VendorCovHandleType ]: function is "VHPI systf; cvg_CrCreate"; | |||
| -- Sets/Updates the name of the Coverage Model. | |||
| -- Should not be called until the data structure is created by VendorCovPointCreate or VendorCovCrossCreate. | |||
| -- Replaces name that was set by VendorCovPointCreate or VendorCovCrossCreate. | |||
| procedure VendorCovSetName( obj: VendorCovHandleType; name: string ); | |||
| attribute foreign of VendorCovSetName[ VendorCovHandleType, string ]: procedure is "VHPI systf; cvg_SetCoverName"; | |||
| -- Add a bin or set of bins to either a Point/Item or Cross Functional Coverage Model | |||
| -- Checking for sizing that is different from original sizing already done in OSVVM CoveragePkg | |||
| -- It is important to maintain an index that corresponds to the order the bins were entered as | |||
| -- that is used when coverage is recorded. | |||
| procedure VendorCovBinAdd( obj: VendorCovHandleType; bins: VendorCovRangeArrayType; Action: integer; atleast: integer; name: string ); | |||
| attribute foreign of VendorCovBinAdd[ VendorCovHandleType, VendorCovRangeArrayType, integer, integer, string ]: procedure is "VHPI systf; cvg_CvpCrBinCreate"; | |||
| -- Increment the coverage of bin identified by index number. | |||
| -- Index ranges from 1 to Number of Bins. | |||
| -- Index corresponds to the order the bins were entered (starting from 1) | |||
| procedure VendorCovBinInc( obj: VendorCovHandleType; index: integer ); | |||
| attribute foreign of VendorCovBinInc[ VendorCovHandleType, integer ]: procedure is "VHPI systf; cvg_CvpCrBinIncr"; | |||
| -- Action (integer): | |||
| -- constant COV_COUNT : integer := 1; | |||
| -- constant COV_IGNORE : integer := 0; | |||
| -- constant COV_ILLEGAL : integer := -1; | |||
| end package; | |||
| package body VendorCovApiPkg is | |||
| -- Replace any existing package body for this package | |||
| end package body VendorCovApiPkg ; | |||