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