Library of reusable VHDL components
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

851 lines
29 KiB

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