| @ -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 ; | |||||