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