amba_tp.vhd
1684 lines
| 70.7 KiB
| text/x-vhdl
|
VhdlLexer
martin
|
r100 | ------------------------------------------------------------------------------ | ||
-- This file is a part of the GRLIB VHDL IP LIBRARY | ||||
-- Copyright (C) 2003 - 2008, Gaisler Research | ||||
-- Copyright (C) 2008 - 2010, Aeroflex Gaisler | ||||
-- | ||||
-- This program is free software; you can redistribute it and/or modify | ||||
-- it under the terms of the GNU General Public License as published by | ||||
-- the Free Software Foundation; either version 2 of the License, or | ||||
-- (at your option) any later version. | ||||
-- | ||||
-- This program 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 | ||||
-- GNU General Public License for more details. | ||||
-- | ||||
-- You should have received a copy of the GNU General Public License | ||||
-- along with this program; if not, write to the Free Software | ||||
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||
--============================================================================-- | ||||
-- Design unit : AMBA_TestPackage (Package and body declarations) | ||||
-- | ||||
-- File name : amba_tp.vhd | ||||
-- | ||||
-- Purpose : AMBA AHB and APB interface access procedures | ||||
-- | ||||
-- Library : {independent} | ||||
-- | ||||
-- Authors : Aeroflex Gaisler AB | ||||
-- | ||||
-- Contact : mailto:support@gaisler.com | ||||
-- http://www.aeroflex.com/gaisler | ||||
-- | ||||
-- Disclaimer : All information is provided "as is", there is no warranty that | ||||
-- the information is correct or suitable for any purpose, | ||||
-- neither implicit nor explicit. | ||||
-------------------------------------------------------------------------------- | ||||
-- Version Author Date Changes | ||||
-- 0.1 SH 15 Mar 2002 New package | ||||
-- 0.2 SH 17 Mar 2003 Updated most packages | ||||
-- 0.3 SH 20 May 2003 Memory based on Integer elements | ||||
-- 0.4 SH 1 Jul 2003 Name of package changed | ||||
-- Compare function improved | ||||
-- AHB 32 bit memory with preload added | ||||
-- AHB initialisation added | ||||
-- 0.5 SH 21 Jul 2003 AHB 32 memory with diagnostics added | ||||
-- 0.6 SH 1 Nov 2003 APB read access data sample made earlier | ||||
-- AHB 32 memory extended with byte/halfword | ||||
-- 0.7 SH 25 Jan 2004 AHB read access data output corrected | ||||
-- AHB 32 memory allows overlay addressing | ||||
-- 1.7 SH 1 Oct 2004 Ported to GRLIB | ||||
-- 1.8 SH 1 Jul 2005 Added configuration support for memories | ||||
-- Modified all procedure declarations | ||||
-- 1.9 SH 10 Nov 2005 AHB 32 responds with HREADY=0 when error | ||||
-- 1.11 SH 27 Dec 2004 Split support added, using HSPLIT element | ||||
-- Proper two-cycle error response implemented | ||||
-- 1.12 SH 15 Feb 2006 Added bank select to AHB bus accesses | ||||
-- 1.13 SH 1 May 2009 AHBQuite gave incorrect TP on error resps. | ||||
-------------------------------------------------------------------------------- | ||||
library Std; | ||||
use Std.Standard.all; | ||||
use Std.TextIO.all; | ||||
library IEEE; | ||||
use IEEE.Std_Logic_1164.all; | ||||
library GRLIB; | ||||
use GRLIB.AMBA.all; | ||||
use GRLIB.StdLib.all; | ||||
use GRLIB.StdIO.all; | ||||
package AMBA_TestPackage is | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA APB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure APBInit( | ||||
signal PCLK: in Std_ULogic; | ||||
signal APBIn: out APB_Slv_In_Type; | ||||
constant InstancePath: in String := "APBInit"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := True); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA APB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure APBWrite( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(31 downto 0); | ||||
signal PCLK: in Std_ULogic; | ||||
signal APBIn: out APB_Slv_In_Type; | ||||
signal APBOut: in APB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "APBWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant PINDEX: in Integer := 0); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA APB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure APBQuiet( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal PCLK: in Std_ULogic; | ||||
signal APBIn: out APB_Slv_In_Type; | ||||
signal APBOut: in APB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "APBQuiet"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant PINDEX: in Integer := 0); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA APB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure APBRead( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal PCLK: in Std_ULogic; | ||||
signal APBIn: out APB_Slv_In_Type; | ||||
signal APBOut: in APB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "APBRead"; | ||||
constant ScreenOutput: in Boolean := True; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant PINDEX: in Integer := 0); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA APB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure APBComp( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant CxData: in Std_Logic_Vector(31 downto 0); | ||||
variable RxData: out Std_Logic_Vector(31 downto 0); | ||||
signal PCLK: in Std_ULogic; | ||||
signal APBIn: out APB_Slv_In_Type; | ||||
signal APBOut: in APB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "APBComp"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant PINDEX: in Integer := 0); | ||||
----------------------------------------------------------------------------- | ||||
-- Initialise AMBA AHB interface | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBInit( | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBIn: out AHB_Slv_In_Type; | ||||
constant InstancePath: in String := "AHBInit"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := True); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBWriteQuiet( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBIn: out AHB_Slv_In_Type; | ||||
signal AHBOut: in AHB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "AHBWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant HINDEX: in Integer := 0; | ||||
constant HMBINDEX: in Integer := 0); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBWrite( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBIn: out AHB_Slv_In_Type; | ||||
signal AHBOut: in AHB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "AHBWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant HINDEX: in Integer := 0; | ||||
constant HMBINDEX: in Integer := 0); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBQuiet( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBIn: out AHB_Slv_In_Type; | ||||
signal AHBOut: in AHB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "AHBQuiet"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant HINDEX: in Integer := 0; | ||||
constant HMBINDEX: in Integer := 0); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBRead( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBIn: out AHB_Slv_In_Type; | ||||
signal AHBOut: in AHB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "AHBRead"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant HINDEX: in Integer := 0; | ||||
constant HMBINDEX: in Integer := 0); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBComp( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant CxData: in Std_Logic_Vector(31 downto 0); | ||||
variable RxData: out Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBIn: out AHB_Slv_In_Type; | ||||
signal AHBOut: in AHB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "AHBComp"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant HINDEX: in Integer := 0; | ||||
constant HMBINDEX: in Integer := 0); | ||||
----------------------------------------------------------------------------- | ||||
-- Diagnstics types for behavioural model of memory with AHB interface | ||||
----------------------------------------------------------------------------- | ||||
type AHB_Diagnostics_In_Type is | ||||
record | ||||
HADDR: Std_Logic_Vector(31 downto 0); | ||||
HWRITE: Std_ULogic; | ||||
HWDATA: Std_Logic_Vector(31 downto 0); | ||||
HRESP: Std_Logic_Vector(1 downto 0); -- response type | ||||
HSPLIT: Std_Logic_Vector(15 downto 0); -- split completion | ||||
end record AHB_Diagnostics_In_Type; | ||||
type AHB_Diagnostics_Out_Type is | ||||
record | ||||
HRDATA: Std_Logic_Vector(31 downto 0); | ||||
end record AHB_Diagnostics_Out_Type; | ||||
constant AHB_Diagnostics_Init: AHB_Diagnostics_In_Type := | ||||
(X"00000000", '0', X"00000000", HRESP_OKAY, X"0000"); | ||||
----------------------------------------------------------------------------- | ||||
-- Behavioural model of memory with AHB interface, no wait states | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBMemory( | ||||
constant gAWidth: in Positive := 15; -- address width | ||||
constant gDWidth: in Positive := 8; -- data width | ||||
signal HCLK: in Std_ULogic; | ||||
signal HRESETn: in Std_ULogic; | ||||
signal AHBIn: in AHB_Slv_In_Type; | ||||
signal AHBOut: out AHB_Slv_Out_Type; | ||||
constant InstancePath: in String := "AHBMemory"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant HINDEX: in Integer := 0; | ||||
constant HADDR: in Integer := 0; | ||||
constant HMASK: in Integer := 16#FFF#); | ||||
----------------------------------------------------------------------------- | ||||
-- Behavioural model of memory with AMBA AHB interface, no wait states | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBMemory32( | ||||
constant gAWidth: in Positive := 18; -- address width | ||||
signal HCLK: in Std_ULogic; | ||||
signal HRESETn: in Std_ULogic; | ||||
signal AHBIn: in AHB_Slv_In_Type; | ||||
signal AHBOut: out AHB_Slv_Out_Type; | ||||
constant InstancePath: in String := "AHBMemory32"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant FileName: in String := ""; -- file name | ||||
constant HINDEX: in Integer := 0; | ||||
constant HADDR: in Integer := 0; | ||||
constant HMASK: in Integer := 16#FFF#); | ||||
----------------------------------------------------------------------------- | ||||
-- Behavioural model of memory with AHB interface, no wait states | ||||
-- Supporting byte, halfword and word read/write accesses. | ||||
-- Provices diagnostic support. | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBMemory32( | ||||
constant gAWidth: in Positive := 18; -- address width | ||||
signal HCLK: in Std_ULogic; | ||||
signal HRESETn: in Std_ULogic; | ||||
signal AHBIn: in AHB_Slv_In_Type; | ||||
signal AHBOut: out AHB_Slv_Out_Type; | ||||
signal AHBInDiag: in AHB_Diagnostics_In_Type; | ||||
signal AHBOutDiag: out AHB_Diagnostics_Out_Type; | ||||
constant InstancePath: in String := "AHBMemory32"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant FileName: in String := ""; -- file name | ||||
constant HINDEX: in Integer := 0; | ||||
constant HADDR: in Integer := 0; | ||||
constant HMASK: in Integer := 16#FFF#); | ||||
----------------------------------------------------------------------------- | ||||
-- Routine for writig data directly to AHB memory | ||||
----------------------------------------------------------------------------- | ||||
procedure WrAHBMem32( | ||||
constant Addr: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBInDiag: out AHB_Diagnostics_In_Type; | ||||
signal AHBOutDiag: in AHB_Diagnostics_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant Comment: in String := ""; | ||||
constant Screen: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- Routine for reading data directly from AHB memory | ||||
----------------------------------------------------------------------------- | ||||
procedure RdAHBMem32( | ||||
constant Addr: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBInDiag: out AHB_Diagnostics_In_Type; | ||||
signal AHBOutDiag: in AHB_Diagnostics_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant Comment: in String := ""; | ||||
constant Screen: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- Routine for reading data directly from AHB memory | ||||
----------------------------------------------------------------------------- | ||||
procedure RcAHBMem32( | ||||
constant Addr: in Std_Logic_Vector(31 downto 0); | ||||
constant Expected: in Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBInDiag: out AHB_Diagnostics_In_Type; | ||||
signal AHBOutDiag: in AHB_Diagnostics_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant Comment: in String := ""; | ||||
constant Screen: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- Routine for generating a split ack from AHB memory | ||||
----------------------------------------------------------------------------- | ||||
procedure SplitAHBMem32( | ||||
constant Split: in Integer range 0 to 15; | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBInDiag: out AHB_Diagnostics_In_Type; | ||||
signal AHBOutDiag: in AHB_Diagnostics_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant Comment: in String := ""; | ||||
constant Screen: in Boolean := False); | ||||
end AMBA_TestPackage; | ||||
--============================================================================-- | ||||
package body AMBA_TestPackage is | ||||
----------------------------------------------------------------------------- | ||||
-- Compare function handling '-' | ||||
----------------------------------------------------------------------------- | ||||
function Compare(O, C: in Std_Logic_Vector) return Boolean is | ||||
variable T: Std_Logic_Vector(O'Range) := C; | ||||
variable Result: Boolean; | ||||
begin | ||||
Result := True; | ||||
for i in O'Range loop | ||||
if not (O(i)=T(i) or T(i)='-' or T(i)='U') then | ||||
Result := False; | ||||
end if; | ||||
end loop; | ||||
return Result; | ||||
end function Compare; | ||||
----------------------------------------------------------------------------- | ||||
-- Synchronisation with respect to clock and with output offset | ||||
----------------------------------------------------------------------------- | ||||
procedure Synchronise( | ||||
signal Clk: in Std_ULogic; | ||||
constant Offset: in Time := 5 ns) is | ||||
begin | ||||
wait until CLK = '1'; -- Synchronise | ||||
wait for Offset; -- output offset delay | ||||
end procedure Synchronise; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA APB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure APBInit( | ||||
signal PCLK: in Std_ULogic; | ||||
signal APBIn: out APB_Slv_In_Type; | ||||
constant InstancePath: in String := "APBInit"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := True) is | ||||
variable L: Line; | ||||
begin | ||||
if cBack2Back then | ||||
Synchronise(PCLK); | ||||
end if; | ||||
APBIn.PSEL <= (others => '0'); | ||||
APBIn.PENABLE <= '0'; | ||||
APBIn.PADDR <= (others => '0'); | ||||
APBIn.PWRITE <= '0'; | ||||
APBIn.PWDATA <= (others => '0'); | ||||
if ScreenOutput then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : APB initalised")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end procedure APBInit; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA APB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure APBWrite( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(31 downto 0); | ||||
signal PCLK: in Std_ULogic; | ||||
signal APBIn: out APB_Slv_In_Type; | ||||
signal APBOut: in APB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "APBWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant PINDEX: in Integer := 0) is | ||||
variable L: Line; | ||||
begin | ||||
-- do not Synchronise when a back-to-back access is requested | ||||
if not cBack2Back then | ||||
Synchronise(PCLK); | ||||
end if; | ||||
APBIn.PSEL <= (others => '0'); | ||||
APBIn.PSEL(PINDEX) <= '1'; -- first clock period | ||||
APBIn.PENABLE <= '0'; | ||||
APBIn.PADDR <= Address; | ||||
APBIn.PWRITE <= '1'; | ||||
APBIn.PWDATA <= Data; | ||||
Synchronise(PCLK); -- second clock period | ||||
APBIn.PENABLE <= '1'; | ||||
if ScreenOutput then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : APB write access, address: ")); | ||||
HWrite(L, Address); | ||||
Write (L, String'(" : data: ")); | ||||
HWrite(L, Data); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
Synchronise(PCLK); -- end of access | ||||
APBIn.PSEL <= (others => '0'); | ||||
APBIn.PENABLE <= '0'; | ||||
APBIn.PADDR <= (others => '-'); | ||||
APBIn.PWRITE <= '0'; | ||||
APBIn.PWDATA <= (others => '-'); | ||||
end procedure APBWrite; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA APB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure APBQuiet( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal PCLK: in Std_ULogic; | ||||
signal APBIn: out APB_Slv_In_Type; | ||||
signal APBOut: in APB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "APBQuiet"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant PINDEX: in Integer := 0) is | ||||
begin | ||||
-- do not Synchronise when a back-to-back access is requested | ||||
if not cBack2Back then | ||||
Synchronise(PCLK); | ||||
end if; | ||||
APBIn.PSEL <= (others => '0'); | ||||
APBIn.PSEL(PINDEX) <= '1'; -- first clock period | ||||
APBIn.PENABLE <= '0'; | ||||
APBIn.PADDR <= Address; | ||||
APBIn.PWRITE <= '0'; | ||||
APBIn.PWDATA <= (others => '-'); | ||||
Synchronise(PCLK); -- second clock period | ||||
APBIn.PENABLE <= '1'; | ||||
wait for 5 ns; | ||||
Data := APBOut.PRDATA; | ||||
Synchronise(PCLK); -- end of access | ||||
APBIn.PSEL <= (others => '0'); | ||||
APBIn.PENABLE <= '0'; | ||||
APBIn.PADDR <= (others => '-'); | ||||
end procedure APBQuiet; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA APB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure APBRead( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal PCLK: in Std_ULogic; | ||||
signal APBIn: out APB_Slv_In_Type; | ||||
signal APBOut: in APB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "APBRead"; | ||||
constant ScreenOutput: in Boolean := True; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant PINDEX: in Integer := 0) is | ||||
variable L: Line; | ||||
variable Temp: Std_Logic_Vector(31 downto 0); | ||||
begin | ||||
APBQuiet(Address, Temp, PCLK, APBIn, APBOut, TP, InstancePath, False, cBack2Back, PINDEX); | ||||
Data := Temp; | ||||
if ScreenOutput then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, " : " & InstancePath); | ||||
Write(L, String'(" : APB read access, address: ")); | ||||
HWrite(L, Address); | ||||
Write(L, String'(" : data: ")); | ||||
HWrite(L, Temp); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end procedure APBRead; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA APB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure APBComp( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant CxData: in Std_Logic_Vector(31 downto 0); | ||||
variable RxData: out Std_Logic_Vector(31 downto 0); | ||||
signal PCLK: in Std_ULogic; | ||||
signal APBIn: out APB_Slv_In_Type; | ||||
signal APBOut: in APB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "APBComp"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant PINDEX: in Integer := 0) is | ||||
variable L: Line; | ||||
variable Data: Std_Logic_Vector(31 downto 0); | ||||
begin | ||||
APBQuiet(Address, Data, PCLK, APBIn, APBOut, TP, InstancePath, False, cBack2Back, PINDEX); | ||||
if not Compare(Data, CxData) then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, " : " & InstancePath); | ||||
Write(L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Address); | ||||
Write(L, String'(" : data: ")); | ||||
HWrite(L, Data); | ||||
Write(L, String'(" : expected: ")); | ||||
HWrite(L, CxData); | ||||
Write(L, String'(" # Error #")); | ||||
WriteLine(Output, L); | ||||
TP := False; | ||||
elsif ScreenOutput then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, " : " & InstancePath); | ||||
Write(L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Address); | ||||
Write(L, String'(" : data: ")); | ||||
HWrite(L, Data); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
RxData := Data; | ||||
end procedure APBComp; | ||||
----------------------------------------------------------------------------- | ||||
-- Initialise AHB interface | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBInit( | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBIn: out AHB_Slv_In_Type; | ||||
constant InstancePath: in String := "AHBInit"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := True) is | ||||
variable L: Line; | ||||
begin | ||||
if cBack2Back then | ||||
Synchronise(HCLK); | ||||
end if; | ||||
AHBIn.HSEL <= (others => '0'); | ||||
AHBIn.HADDR <= (others => '0'); | ||||
AHBIn.HWRITE <= '0'; | ||||
AHBIn.HTRANS <= HTRANS_IDLE; | ||||
AHBIn.HSIZE <= HSIZE_WORD; | ||||
AHBIn.HBURST <= HBURST_SINGLE; | ||||
AHBIn.HWDATA <= (others => '-'); | ||||
AHBIn.HPROT <= (others => '0'); | ||||
AHBIn.HREADY <= '0'; | ||||
AHBIn.HMASTER <= (others => '0'); | ||||
AHBIn.HMASTLOCK <= '0'; | ||||
AHBIn.HMBSEL <= (others => '0'); | ||||
if ScreenOutput then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB initalised")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end procedure AHBInit; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBWriteQuiet( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBIn: out AHB_Slv_In_Type; | ||||
signal AHBOut: in AHB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "AHBWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant HINDEX: in Integer := 0; | ||||
constant HMBINDEX: in Integer := 0) is | ||||
variable L: Line; | ||||
begin | ||||
-- do not Synchronise when a back-to-back access is requested | ||||
if not cBack2Back then | ||||
Synchronise(HCLK); -- first clock period | ||||
end if; | ||||
AHBIn.HSEL <= (others => '0'); | ||||
AHBIn.HSEL(HINDEX)<= '1'; | ||||
AHBIn.HADDR <= Address; | ||||
AHBIn.HWRITE <= '1'; | ||||
AHBIn.HTRANS <= HTRANS_NONSEQ; | ||||
AHBIn.HSIZE <= HSIZE_WORD; | ||||
AHBIn.HBURST <= HBURST_SINGLE; | ||||
AHBIn.HWDATA <= (others => '-'); | ||||
AHBIn.HPROT <= (others => '0'); | ||||
AHBIn.HREADY <= '1'; | ||||
AHBIn.HMASTER <= (others => '0'); | ||||
AHBIn.HMASTLOCK <= '0'; | ||||
AHBIn.HMBSEL <= (others => '0'); | ||||
AHBIn.HMBSEL(HMBINDEX) <= '1'; | ||||
Synchronise(HCLK); -- second clock period | ||||
AHBIn.HSEL <= (others => '0'); | ||||
AHBIn.HSEL(HINDEX)<= '1'; | ||||
AHBIn.HADDR <= (others => '-'); | ||||
AHBIn.HWRITE <= '0'; | ||||
AHBIn.HTRANS <= HTRANS_IDLE; | ||||
AHBIn.HWDATA <= ahbdrivedata(Data); | ||||
AHBIn.HREADY <= AHBOut.HREADY; | ||||
AHBIn.HMBSEL <= (others => '0'); | ||||
AHBIn.HMBSEL(HMBINDEX) <= '1'; | ||||
while AHBOut.HREADY='0' loop | ||||
Synchronise(HCLK); | ||||
end loop; | ||||
if AHBOut.HRESP=HRESP_ERROR then | ||||
if ScreenOutput then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB write access, address: ")); | ||||
HWrite(L, Address); | ||||
Write (L, String'(" ERROR response ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
TP := False; | ||||
elsif AHBOut.HRESP=HRESP_RETRY then | ||||
if ScreenOutput then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB write access, address: ")); | ||||
HWrite(L, Address); | ||||
Write (L, String'(" RETRY response ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
TP := False; | ||||
elsif AHBOut.HRESP=HRESP_SPLIT then | ||||
if ScreenOutput then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB write access, address: ")); | ||||
HWrite(L, Address); | ||||
Write (L, String'(" SPLIT response ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
TP := False; | ||||
else | ||||
end if; | ||||
Synchronise(HCLK); -- end of access | ||||
AHBIn.HSEL <= (others => '0'); | ||||
AHBIn.HADDR <= (others => '-'); | ||||
AHBIn.HWRITE <= '1'; | ||||
AHBIn.HTRANS <= HTRANS_IDLE; | ||||
AHBIn.HSIZE <= HSIZE_WORD; | ||||
AHBIn.HBURST <= HBURST_SINGLE; | ||||
AHBIn.HWDATA <= (others => '-'); | ||||
AHBIn.HPROT <= (others => '0'); | ||||
AHBIn.HREADY <= '1'; | ||||
AHBIn.HMASTER <= (others => '0'); | ||||
AHBIn.HMASTLOCK <= '0'; | ||||
AHBIn.HMBSEL <= (others => '0'); | ||||
end procedure AHBWriteQuiet; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBWrite( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBIn: out AHB_Slv_In_Type; | ||||
signal AHBOut: in AHB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "AHBWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant HINDEX: in Integer := 0; | ||||
constant HMBINDEX: in Integer := 0) is | ||||
variable OK: Boolean := True; | ||||
variable L: Line; | ||||
begin | ||||
AHBWriteQuiet(Address, Data, HCLK, AHBIn, AHBOut, OK, | ||||
InstancePath, False, cBack2Back, HINDEX, HMBINDEX); | ||||
if ScreenOutput and OK then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB write access, address: ")); | ||||
HWrite(L, Address); | ||||
Write (L, String'(" : data: ")); | ||||
HWrite(L, Data); | ||||
WriteLine(Output, L); | ||||
elsif not OK then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB write access, address: ")); | ||||
HWrite(L, Address); | ||||
Write (L, String'(" : ## Failed ##")); | ||||
WriteLine(Output, L); | ||||
TP := False; | ||||
end if; | ||||
end procedure AHBWrite; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBQuiet( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBIn: out AHB_Slv_In_Type; | ||||
signal AHBOut: in AHB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "AHBQuiet"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant HINDEX: in Integer := 0; | ||||
constant HMBINDEX: in Integer := 0) is | ||||
variable L: Line; | ||||
begin | ||||
-- do not Synchronise when a back-to-back access is requested | ||||
if not cBack2Back then | ||||
Synchronise(HCLK); | ||||
end if; | ||||
AHBIn.HSEL <= (others => '0'); | ||||
AHBIn.HSEL(HINDEX)<= '1'; | ||||
AHBIn.HADDR <= Address; | ||||
AHBIn.HWRITE <= '0'; | ||||
AHBIn.HTRANS <= HTRANS_NONSEQ; | ||||
AHBIn.HSIZE <= HSIZE_WORD; | ||||
AHBIn.HBURST <= HBURST_SINGLE; | ||||
AHBIn.HWDATA <= (others => '-'); | ||||
AHBIn.HPROT <= (others => '0'); | ||||
AHBIn.HREADY <= '1'; | ||||
AHBIn.HMASTER <= (others => '0'); | ||||
AHBIn.HMASTLOCK <= '0'; | ||||
AHBIn.HMBSEL <= (others => '0'); | ||||
AHBIn.HMBSEL(HMBINDEX) <= '1'; | ||||
Synchronise(HCLK); -- second clock period | ||||
AHBIn.HSEL <= (others => '0'); | ||||
AHBIn.HSEL(HINDEX)<= '1'; | ||||
AHBIn.HADDR <= (others => '-'); | ||||
AHBIn.HWRITE <= '0'; | ||||
AHBIn.HTRANS <= HTRANS_IDLE; | ||||
AHBIn.HWDATA <= (others => '-'); | ||||
AHBIn.HREADY <= AHBOut.HREADY; | ||||
AHBIn.HMBSEL <= (others => '0'); | ||||
AHBIn.HMBSEL(HMBINDEX) <= '1'; | ||||
while AHBOut.HREADY='0' loop | ||||
Synchronise(HCLK); | ||||
end loop; | ||||
Data := AHBOut.HRDATA(31 downto 0); | ||||
if AHBOut.HRESP=HRESP_ERROR then | ||||
if ScreenOutput then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, " : " & InstancePath); | ||||
Write(L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Address); | ||||
Write(L, String'(" ERROR response ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
TP := False; | ||||
elsif AHBOut.HRESP=HRESP_RETRY then | ||||
if ScreenOutput then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, " : " & InstancePath); | ||||
Write(L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Address); | ||||
Write(L, String'(" RETRY response ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
TP := False; | ||||
elsif AHBOut.HRESP=HRESP_SPLIT then | ||||
if ScreenOutput then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, " : " & InstancePath); | ||||
Write(L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Address); | ||||
Write(L, String'(" SPLIT response ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
TP := False; | ||||
else | ||||
end if; | ||||
Synchronise(HCLK); -- end of access | ||||
AHBIn.HSEL <= (others => '0'); | ||||
AHBIn.HADDR <= (others => '-'); | ||||
AHBIn.HWRITE <= '0'; | ||||
AHBIn.HTRANS <= HTRANS_IDLE; | ||||
AHBIn.HSIZE <= HSIZE_WORD; | ||||
AHBIn.HBURST <= HBURST_SINGLE; | ||||
AHBIn.HWDATA <= (others => '-'); | ||||
AHBIn.HPROT <= (others => '0'); | ||||
AHBIn.HREADY <= '1'; | ||||
AHBIn.HMASTER <= (others => '0'); | ||||
AHBIn.HMASTLOCK <= '0'; | ||||
AHBIn.HMBSEL <= (others => '0'); | ||||
end procedure AHBQuiet; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBRead( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBIn: out AHB_Slv_In_Type; | ||||
signal AHBOut: in AHB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "AHBRead"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant HINDEX: in Integer := 0; | ||||
constant HMBINDEX: in Integer := 0) is | ||||
variable OK: Boolean := True; | ||||
variable L: Line; | ||||
variable Temp: Std_Logic_Vector(31 downto 0); | ||||
begin | ||||
AHBQuiet(Address, Temp, HCLK, AHBIn, AHBOut, OK, | ||||
InstancePath, False, cBack2Back, HINDEX, HMBINDEX); | ||||
if ScreenOutput and OK then | ||||
Data := Temp; | ||||
Write(L, Now, Right, 15); | ||||
Write(L, " : " & InstancePath); | ||||
Write(L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Address); | ||||
Write(L, String'(" : data: ")); | ||||
HWrite(L, Temp); | ||||
WriteLine(Output, L); | ||||
elsif OK then | ||||
Data := Temp; | ||||
else | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Address); | ||||
Write (L, String'(" : ## Failed ##")); | ||||
WriteLine(Output, L); | ||||
Data := (others => '-'); | ||||
TP := False; | ||||
end if; | ||||
end procedure AHBRead; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBComp( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant CxData: in Std_Logic_Vector(31 downto 0); | ||||
variable RxData: out Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBIn: out AHB_Slv_In_Type; | ||||
signal AHBOut: in AHB_Slv_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "AHBComp"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant HINDEX: in Integer := 0; | ||||
constant HMBINDEX: in Integer := 0) is | ||||
variable OK: Boolean := True; | ||||
variable L: Line; | ||||
variable Data: Std_Logic_Vector(31 downto 0); | ||||
variable Failed: Boolean; | ||||
begin | ||||
AHBQuiet(Address, Data, HCLK, AHBIn, AHBOut, OK, | ||||
InstancePath, False, cBack2Back, HINDEX, HMBINDEX); | ||||
if not OK then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Address); | ||||
Write (L, String'(" : ## Failed ##")); | ||||
WriteLine(Output, L); | ||||
TP := False; | ||||
RxData := (others => '-'); | ||||
elsif not Compare(Data, CxData) then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, " : " & InstancePath); | ||||
Write(L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Address); | ||||
Write(L, String'(" : data: ")); | ||||
HWrite(L, Data); | ||||
Write(L, String'(" : expected: ")); | ||||
HWrite(L, CxData); | ||||
Write(L, String'(" # Error #")); | ||||
WriteLine(Output, L); | ||||
TP := False; | ||||
RxData := Data; | ||||
elsif ScreenOutput then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, " : " & InstancePath); | ||||
Write(L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Address); | ||||
Write(L, String'(" : data: ")); | ||||
HWrite(L, Data); | ||||
WriteLine(Output, L); | ||||
RxData := Data; | ||||
else | ||||
RxData := Data; | ||||
end if; | ||||
end procedure AHBComp; | ||||
----------------------------------------------------------------------------- | ||||
-- Behavioural model of memory with AHB interface, no wait states | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBMemory( | ||||
constant gAWidth: in Positive := 15; -- address width | ||||
constant gDWidth: in Positive := 8; -- data width | ||||
signal HCLK: in Std_ULogic; | ||||
signal HRESETn: in Std_ULogic; | ||||
signal AHBIn: in AHB_Slv_In_Type; | ||||
signal AHBOut: out AHB_Slv_Out_Type; | ||||
constant InstancePath: in String := "AHBMemory"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant HINDEX: in Integer := 0; | ||||
constant HADDR: in Integer := 0; | ||||
constant HMASK: in Integer := 16#FFF#) is | ||||
-- memory definition | ||||
subtype ARange is Natural range 0 to 2**gAWidth-1; | ||||
subtype DRange is Natural range 0 to gDWidth-1; | ||||
type MType is array (ARange) of Integer; | ||||
-- memory initialisation | ||||
function Init return MType is | ||||
variable r: MType; | ||||
begin | ||||
for i in ARange loop | ||||
r(i) := -1; | ||||
end loop; | ||||
return r; | ||||
end function Init; | ||||
variable M: MType; | ||||
variable A: Std_Logic_Vector(gAWidth-1 downto 0); | ||||
variable D: Std_Logic_Vector(0 to gDWidth-1); | ||||
variable W: Std_Logic; | ||||
-- reset values | ||||
procedure Reset is | ||||
begin | ||||
AHBOut.HREADY <= '1'; | ||||
AHBOut.HRESP <= HRESP_OKAY; | ||||
AHBOut.HRDATA <= (others => '0'); | ||||
W := '0'; | ||||
end procedure Reset; | ||||
-- plug&play configuration | ||||
constant HCONFIG : ahb_config_type := ( | ||||
0 => ahb_device_reg (0, 0, 0, gAWidth, 0), | ||||
4 => ahb_membar(HADDR, '1', '1', HMASK), | ||||
others => zero32); | ||||
variable alow : std_logic_vector(1 downto 0); | ||||
begin | ||||
-- fixed AMBA AHB signals, etc. | ||||
AHBOut.HSPLIT <= (others => '0'); | ||||
AHBOut.HCONFIG <= HCONFIG; | ||||
loop | ||||
if HRESETn='0' then -- asynchronous reset | ||||
Reset; | ||||
elsif HCLK'Event and HCLK='1' then -- rising edge | ||||
-- data phase | ||||
if AHBIn.HREADY='1' then | ||||
if W='1' then | ||||
alow := A(1 downto 0); | ||||
case alow is | ||||
when "00" => | ||||
D := AHBIn.HWDATA(31 downto 24); | ||||
when "01" => | ||||
D := AHBIn.HWDATA(23 downto 16); | ||||
when "10" => | ||||
D := AHBIn.HWDATA(15 downto 8); | ||||
when others => | ||||
D := AHBIn.HWDATA( 7 downto 0); | ||||
end case; | ||||
M(Conv_Integer(A)) := Conv_Integer(D); | ||||
W := '0'; | ||||
end if; | ||||
end if; | ||||
-- address phase | ||||
if AHBIn.HSEL(HINDEX)='1' and | ||||
AHBIn.HREADY='1' and | ||||
AHBIn.HSIZE=HSIZE_BYTE and | ||||
(AHBIn.HTRANS=HTRANS_SEQ or | ||||
AHBIn.HTRANS=HTRANS_NONSEQ) and | ||||
AHBIn.HMASTLOCK='0' then | ||||
W := AHBIn.HWRITE; | ||||
A := AHBIn.HADDR(gAWidth-1 downto 0); | ||||
AHBOut.HREADY <= '1'; | ||||
AHBOut.HRESP <= HRESP_OKAY; | ||||
D := Conv_Std_Logic_Vector( | ||||
M(Conv_Integer(A)), D'Length); | ||||
case alow is | ||||
when "00" => | ||||
AHBOut.HRDATA(31 downto 24) <= D; | ||||
when "01" => | ||||
AHBOut.HRDATA(23 downto 16) <= D; | ||||
when "10" => | ||||
AHBOut.HRDATA(15 downto 8) <= D; | ||||
when others => | ||||
AHBOut.HRDATA( 7 downto 0) <= D; | ||||
end case; | ||||
else | ||||
w :='0'; | ||||
AHBOut.HREADY <= '1'; | ||||
AHBOut.HRESP <= HRESP_OKAY; | ||||
end if; | ||||
end if; | ||||
-- signal sensitivity | ||||
wait on HCLK, HRESETn; | ||||
end loop; | ||||
end procedure AHBMemory; | ||||
----------------------------------------------------------------------------- | ||||
-- Behavioural model of memory with AHB interface, no wait states | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBMemory32( | ||||
constant gAWidth: in Positive := 18; -- address width | ||||
signal HCLK: in Std_ULogic; | ||||
signal HRESETn: in Std_ULogic; | ||||
signal AHBIn: in AHB_Slv_In_Type; | ||||
signal AHBOut: out AHB_Slv_Out_Type; | ||||
constant InstancePath: in String := "AHBMemory32"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant FileName: in String := ""; -- File name | ||||
constant HINDEX: in Integer := 0; | ||||
constant HADDR: in Integer := 0; | ||||
constant HMASK: in Integer := 16#FFF#) is | ||||
-- memory definition | ||||
type MType is array (0 to 2**(gAWidth-2)-1) of | ||||
Std_Logic_Vector(31 downto 0); | ||||
-------------------------------------------------------------------------- | ||||
-- Load memory contents | ||||
-------------------------------------------------------------------------- | ||||
-- ## Does not warn if there is insufficient data in a line. | ||||
-- Address read from file is always byte oriented, always 32 bit wide | ||||
-- For 16 and 32 bit wide data, each data word read from file must be on a | ||||
-- single line and without white space between the characters. For 8 bit | ||||
-- wide date, no restrictions apply. Files generated for 32 bit wide data | ||||
-- can always be read by 16 or 8 bit memories. The byte/halfwrod address | ||||
-- is incremented internally. | ||||
-------------------------------------------------------------------------- | ||||
-- ----------------------------------------------------------------------- | ||||
-- -- PROM Initialisation Example | ||||
-- ----------------------------------------------------------------------- | ||||
-- -- Supports by 8, 16, 32 bit wide memories | ||||
-- 00000000 00010203 | ||||
-- 00000004 04050607 08090A0B | ||||
-- 0000000C 0C0D0E0F | ||||
-- | ||||
-- -- Supported by 8, 16 bit wide memories | ||||
-- 00000010 1011 1213 | ||||
-- 00000014 1415 | ||||
-- 00000016 1617 1819 1A1B 1C1D 1E1F 2021 | ||||
-- 00000022 2223 2425 2627 2829 2A2B 2C2D 2E2F | ||||
-- | ||||
-- -- Supported by 8 bit wide memories | ||||
-- 00000030 30 31 32 33 3435 3637 3839 3A3B 3C3D 3E3F | ||||
-- 00000040 40 | ||||
-- 00000041 41 | ||||
-- 00000042 42 43 | ||||
-- 00000044 4445 | ||||
-- 00000046 46474849 | ||||
-- 0000004A 4A4B 4C4D4E4F | ||||
-------------------------------------------------------------------------- | ||||
impure function Initialise( | ||||
constant FileName: in String := ""; | ||||
constant AWidth: in Natural; | ||||
constant DWidth: in Natural) | ||||
return MType is | ||||
variable L: Line; | ||||
variable Address: Std_Logic_Vector(31 downto 0); | ||||
variable Data: Std_Logic_Vector(31 downto 0); | ||||
variable Byte: Std_Logic_Vector( 7 downto 0); | ||||
variable Addr: Natural range 0 to 2**AWidth-1; | ||||
file ReadFile: Text; | ||||
variable Test: Boolean; | ||||
variable Result: MType; | ||||
begin | ||||
-- initialse all data to all zeros | ||||
Result := (others => (others => 'U')); | ||||
-- load contents from file only if a file name has been provided | ||||
if FileName /= "" then | ||||
File_Open(ReadFile, FileName, Read_Mode); | ||||
-- read data from file | ||||
while not EndFile(ReadFile) loop | ||||
-- read line | ||||
ReadLine(ReadFile, L); | ||||
-- read address, always byte oriented, always 32 bit wide | ||||
HRead(L, Address, Test); | ||||
if Test then -- address read | ||||
-- check whether byte address aligned with data width | ||||
if Conv_Integer(Address) mod (DWidth/8) /= 0 then | ||||
report "Unaligned data in memory initalisation file: " & | ||||
FileName | ||||
severity Failure; | ||||
Test := False; | ||||
else -- convert address | ||||
-- adapt byte address to address corresponding to the data | ||||
-- width of the memory | ||||
Addr := (Conv_Integer(Address)/(DWidth/8)) mod | ||||
(2**AWidth); | ||||
end if; | ||||
else -- comment detected | ||||
null; | ||||
end if; | ||||
while Test loop | ||||
-- read data | ||||
HRead(L, Data(DWidth-1 downto 0), Test); | ||||
if Test then | ||||
-- initialize memory element | ||||
Result(Addr) := Data(DWidth-1 downto 0); | ||||
-- increment address, with the memory width | ||||
Addr := (Addr + 1) mod (2**AWidth); | ||||
end if; | ||||
end loop; | ||||
end loop; | ||||
File_Close(ReadFile); | ||||
end if; | ||||
return Result; | ||||
end function Initialise; | ||||
-- memory contents | ||||
variable M: MType := Initialise(FileName, gAWidth-2, 32); | ||||
variable A: Std_Logic_Vector(gAWidth-1 downto 2); | ||||
variable W: Std_Logic; | ||||
-- reset values | ||||
procedure Reset is | ||||
begin | ||||
AHBOut.HREADY <= '1'; | ||||
AHBOut.HRESP <= HRESP_OKAY; | ||||
AHBOut.HRDATA <= (others => '0'); | ||||
W := '0'; | ||||
end procedure Reset; | ||||
-- plug&play configuration | ||||
constant HCONFIG : ahb_config_type := ( | ||||
0 => ahb_device_reg (0, 0, 0, gAWidth, 0), | ||||
4 => ahb_membar(HADDR, '1', '1', HMASK), | ||||
others => zero32); | ||||
begin | ||||
-- fixed AMBA AHB signals, etc. | ||||
AHBOut.HSPLIT <= (others => '0'); | ||||
AHBOut.HCONFIG <= HCONFIG; | ||||
loop | ||||
if HRESETn='0' then -- asynchronous reset | ||||
Reset; | ||||
elsif HCLK'Event and HCLK='1' then -- rising edge | ||||
-- data phase | ||||
if AHBIn.HREADY='1' then | ||||
if W='1' then | ||||
M(Conv_Integer(A)) := AHBIn.HWDATA(31 downto 0); | ||||
W := '0'; | ||||
end if; | ||||
end if; | ||||
-- address phase | ||||
if AHBIn.HSEL(HINDEX)='1' and | ||||
AHBIn.HREADY='1' and | ||||
AHBIn.HSIZE=HSIZE_WORD and | ||||
(AHBIn.HTRANS=HTRANS_SEQ or | ||||
AHBIn.HTRANS=HTRANS_NONSEQ) and | ||||
AHBIn.HMASTLOCK='0' then | ||||
W := AHBIn.HWRITE; | ||||
A := AHBIn.HADDR(gAWidth-1 downto 2); | ||||
AHBOut.HREADY <= '1'; | ||||
AHBOut.HRESP <= HRESP_OKAY; | ||||
AHBOut.HRDATA <= ahbdrivedata(M(Conv_Integer(A))); | ||||
else | ||||
W :='0'; | ||||
AHBOut.HREADY <= '1'; | ||||
AHBOut.HRESP <= HRESP_OKAY; | ||||
end if; | ||||
end if; | ||||
-- signal sensitivity | ||||
wait on HCLK, HRESETn; | ||||
end loop; | ||||
end procedure AHBMemory32; | ||||
----------------------------------------------------------------------------- | ||||
-- Behavioural model of memory with AHB interface, no wait states | ||||
-- Supporting byte, halfword and word read/write accesses. | ||||
-- Provices diagnostic support. | ||||
----------------------------------------------------------------------------- | ||||
procedure AHBMemory32( | ||||
constant gAWidth: in Positive := 18; -- address width | ||||
signal HCLK: in Std_ULogic; | ||||
signal HRESETn: in Std_ULogic; | ||||
signal AHBIn: in AHB_Slv_In_Type; | ||||
signal AHBOut: out AHB_Slv_Out_Type; | ||||
signal AHBInDiag: in AHB_Diagnostics_In_Type; | ||||
signal AHBOutDiag: out AHB_Diagnostics_Out_Type; | ||||
constant InstancePath: in String := "AHBMemory32"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant FileName: in String := ""; -- File name | ||||
constant HINDEX: in Integer := 0; | ||||
constant HADDR: in Integer := 0; | ||||
constant HMASK: in Integer := 16#FFF#) is | ||||
-- memory definition | ||||
type MType is array (0 to 2**(gAWidth-2)-1) of | ||||
Std_Logic_Vector(31 downto 0); | ||||
variable L: Line; | ||||
constant Padding: Std_ULogic_Vector(1 to | ||||
(4-((gAWidth-2) mod 4))) := | ||||
(others => '0'); | ||||
-------------------------------------------------------------------------- | ||||
-- Load memory contents | ||||
-------------------------------------------------------------------------- | ||||
-- ## Does not warn if there is insufficient data in a line. | ||||
-- Address read from file is always byte oriented, always 32 bit wide | ||||
-- For 16 and 32 bit wide data, each data word read from file must be on a | ||||
-- single line and without white space between the characters. For 8 bit | ||||
-- wide date, no restrictions apply. Files generated for 32 bit wide data | ||||
-- can always be read by 16 or 8 bit memories. The byte/halfwrod address | ||||
-- is incremented internally. | ||||
-------------------------------------------------------------------------- | ||||
-- ----------------------------------------------------------------------- | ||||
-- -- PROM Initialisation Example | ||||
-- ----------------------------------------------------------------------- | ||||
-- -- Supports by 8, 16, 32 bit wide memories | ||||
-- 00000000 00010203 | ||||
-- 00000004 04050607 08090A0B | ||||
-- 0000000C 0C0D0E0F | ||||
-- | ||||
-- -- Supported by 8, 16 bit wide memories | ||||
-- 00000010 1011 1213 | ||||
-- 00000014 1415 | ||||
-- 00000016 1617 1819 1A1B 1C1D 1E1F 2021 | ||||
-- 00000022 2223 2425 2627 2829 2A2B 2C2D 2E2F | ||||
-- | ||||
-- -- Supported by 8 bit wide memories | ||||
-- 00000030 30 31 32 33 3435 3637 3839 3A3B 3C3D 3E3F | ||||
-- 00000040 40 | ||||
-- 00000041 41 | ||||
-- 00000042 42 43 | ||||
-- 00000044 4445 | ||||
-- 00000046 46474849 | ||||
-- 0000004A 4A4B 4C4D4E4F | ||||
-------------------------------------------------------------------------- | ||||
impure function Initialise( | ||||
constant FileName: in String := ""; | ||||
constant AWidth: in Natural; | ||||
constant DWidth: in Natural) | ||||
return MType is | ||||
variable L: Line; | ||||
variable Address: Std_Logic_Vector(31 downto 0); | ||||
variable Data: Std_Logic_Vector(31 downto 0); | ||||
variable Byte: Std_Logic_Vector( 7 downto 0); | ||||
variable Addr: Natural range 0 to 2**AWidth-1; | ||||
file ReadFile: Text; | ||||
variable Test: Boolean; | ||||
variable Result: MType; | ||||
begin | ||||
-- initialse all data to all zeros | ||||
Result := (others => (others => 'U')); | ||||
-- load contents from file only if a file name has been provided | ||||
if FileName /= "" then | ||||
File_Open(ReadFile, FileName, Read_Mode); | ||||
-- read data from file | ||||
while not EndFile(ReadFile) loop | ||||
-- read line | ||||
ReadLine(ReadFile, L); | ||||
-- read address, always byte oriented, always 32 bit wide | ||||
HRead(L, Address, Test); | ||||
if Test then -- address read | ||||
-- check whether byte address aligned with data width | ||||
if Conv_Integer(Address) mod (DWidth/8) /= 0 then | ||||
report "Unaligned data in memory initalisation file: " & | ||||
FileName | ||||
severity Failure; | ||||
Test := False; | ||||
else -- convert address | ||||
-- adapt byte address to address corresponding to the data | ||||
-- width of the memory | ||||
Addr := (Conv_Integer(Address)/(DWidth/8)) mod | ||||
(2**AWidth); | ||||
end if; | ||||
else -- comment detected | ||||
null; | ||||
end if; | ||||
while Test loop | ||||
-- read data | ||||
HRead(L, Data(DWidth-1 downto 0), Test); | ||||
if Test then | ||||
-- initialize memory element | ||||
Result(Addr) := Data(DWidth-1 downto 0); | ||||
-- increment address, with the memory width | ||||
Addr := (Addr + 1) mod (2**AWidth); | ||||
end if; | ||||
end loop; | ||||
end loop; | ||||
File_Close(ReadFile); | ||||
end if; | ||||
return Result; | ||||
end function Initialise; | ||||
-- memory contents | ||||
variable M: MType := Initialise(FileName, gAWidth-2, 32); | ||||
variable A: Std_Logic_Vector(gAWidth-1 downto 2); | ||||
variable B: Std_Logic_Vector(1 downto 0); | ||||
variable W: Std_Logic; | ||||
variable S: Std_Logic_Vector(2 downto 0); | ||||
variable D: Std_Logic_Vector(31 downto 0); | ||||
variable twocycle:Boolean := False; | ||||
-- reset values | ||||
procedure Reset is | ||||
begin | ||||
AHBOut.HREADY <= '1'; | ||||
AHBOut.HRESP <= HRESP_OKAY; | ||||
AHBOut.HRDATA <= (others => '0'); | ||||
W := '0'; | ||||
twocycle := False; | ||||
end procedure Reset; | ||||
-- plug&play configuration | ||||
constant HCONFIG : ahb_config_type := ( | ||||
0 => ahb_device_reg (0, 0, 0, gAWidth, 0), | ||||
4 => ahb_membar(HADDR, '1', '1', HMASK), | ||||
others => zero32); | ||||
begin | ||||
-- fixed AMBA AHB signals, etc. | ||||
AHBOut.HSPLIT <= (others => '0'); | ||||
AHBOut.HCONFIG <= HCONFIG; | ||||
loop | ||||
if HRESETn='0' then -- asynchronous reset | ||||
Reset; | ||||
elsif HCLK'Event and HCLK='1' then -- rising edge | ||||
-- data phase | ||||
if AHBIn.HREADY='1' then | ||||
if W='1' then | ||||
-- read back memory | ||||
D := M(Conv_Integer(A)); | ||||
-- replace with new data | ||||
if S="000" then -- byte | ||||
if B(1 downto 0)="00" then | ||||
D := AHBIn.HWDATA(31 downto 24) & | ||||
D(23 downto 0); | ||||
elsif B(1 downto 0)="01" then | ||||
D := D(31 downto 24) & | ||||
AHBIn.HWDATA(23 downto 16) & | ||||
D(15 downto 0); | ||||
elsif B(1 downto 0)="10" then | ||||
D := D(31 downto 16) & | ||||
AHBIn.HWDATA(15 downto 8) & | ||||
D(7 downto 0); | ||||
elsif B(1 downto 0)="11" then | ||||
D := D(31 downto 8) & | ||||
AHBIn.HWDATA(7 downto 0); | ||||
end if; | ||||
elsif S="001" then -- halfword | ||||
if B(1 downto 0)="00" then | ||||
D := AHBIn.HWDATA(31 downto 16) & | ||||
D(15 downto 0); | ||||
elsif B(1 downto 0)="10" then | ||||
D := D(31 downto 16) & | ||||
AHBIn.HWDATA(15 downto 0); | ||||
end if; | ||||
else | ||||
D := AHBIn.HWDATA(31 downto 0); | ||||
end if; | ||||
-- write back memory | ||||
M(Conv_Integer(A)) := D; | ||||
W := '0'; | ||||
-- comment | ||||
if ScreenOutput then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, " : " & InstancePath & " Write acces to address :"); | ||||
if Padding'Length > 0 and Padding'Length < 4 then | ||||
HWrite(L, Std_Logic_Vector(Padding) & Std_Logic_Vector(A)); | ||||
else | ||||
HWrite(L, Std_Logic_Vector(A)); | ||||
end if; | ||||
Write(L, String'(" data :")); | ||||
HWrite(L, D); | ||||
Write(L, String'(" data :")); | ||||
Write(L, To_BitVector(D)); | ||||
Write(L, String'(" size :")); | ||||
HWrite(L, "0" & S); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end if; | ||||
end if; | ||||
-- address phase | ||||
if AHBIn.HSEL(HINDEX)='1' and | ||||
AHBIn.HREADY='1' and | ||||
(AHBIn.HSIZE=HSIZE_BYTE or | ||||
AHBIn.HSIZE=HSIZE_HWORD or | ||||
AHBIn.HSIZE=HSIZE_WORD) and | ||||
(AHBIn.HTRANS=HTRANS_SEQ or | ||||
AHBIn.HTRANS=HTRANS_NONSEQ) and | ||||
AHBIn.HMASTLOCK='0' then | ||||
if AHBInDiag.HRESP=HRESP_OKAY then | ||||
W := AHBIn.HWRITE; | ||||
S := AHBIn.HSIZE; | ||||
B := AHBIn.HADDR( 1 downto 0); | ||||
A := AHBIn.HADDR(gAWidth-1 downto 2); | ||||
AHBOut.HREADY <= '1'; | ||||
AHBOut.HRESP <= HRESP_OKAY; | ||||
AHBOut.HRDATA <= ahbdrivedata(M(Conv_Integer(A))); | ||||
elsif AHBInDiag.HRESP=HRESP_RETRY then | ||||
W :='0'; | ||||
AHBOut.HREADY <= '0'; | ||||
AHBOut.HRESP <= HRESP_RETRY; | ||||
AHBOut.HRDATA <= (others => 'X'); | ||||
twocycle := True; | ||||
elsif AHBInDiag.HRESP=HRESP_SPLIT then | ||||
W :='0'; | ||||
AHBOut.HREADY <= '0'; | ||||
AHBOut.HRESP <= HRESP_SPLIT; | ||||
AHBOut.HRDATA <= (others => 'X'); | ||||
twocycle := True; | ||||
else | ||||
W :='0'; | ||||
AHBOut.HREADY <= '0'; | ||||
AHBOut.HRESP <= HRESP_ERROR; | ||||
AHBOut.HRDATA <= (others => 'X'); | ||||
twocycle := True; | ||||
end if; | ||||
else | ||||
W :='0'; | ||||
AHBOut.HREADY <= '1'; | ||||
if twocycle then | ||||
twocycle := False; | ||||
else | ||||
AHBOut.HRESP <= HRESP_OKAY; | ||||
end if; | ||||
end if; | ||||
end if; | ||||
if HCLK'Event and HCLK='1' then -- rising edge | ||||
-- diagnostics | ||||
AHBOutDiag.HRData <= M((Conv_Integer(AHBInDiag.HAddr)/4) mod (2**(gAWidth-2))); | ||||
if AHBInDiag.HWrite='1' then | ||||
M((Conv_Integer(AHBInDiag.HAddr)/4) mod (2**(gAWidth-2))) := AHBInDiag.HWData; | ||||
-- Print("Diagnostic write to memory, address: " & | ||||
-- Integer'Image(Conv_Integer(AHBInDiag.HAddr)) & | ||||
-- " data: " & | ||||
-- Integer'Image(Conv_Integer(AHBInDiag.HWData))); | ||||
end if; | ||||
AHBOut.HSPLIT <= AHBInDiag.HSplit; | ||||
end if; | ||||
-- signal sensitivity | ||||
wait on HCLK, HRESETn; | ||||
end loop; | ||||
end procedure AHBMemory32; | ||||
----------------------------------------------------------------------------- | ||||
-- Routine for writig data directly to AHB memory | ||||
----------------------------------------------------------------------------- | ||||
procedure WrAHBMem32( | ||||
constant Addr: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBInDiag: out AHB_Diagnostics_In_Type; | ||||
signal AHBOutDiag: in AHB_Diagnostics_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant Comment: in String := ""; | ||||
constant Screen: in Boolean := False) is | ||||
variable L: Line; | ||||
begin | ||||
Synchronise(HCLK); | ||||
if Screen then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, String'(" : WrAHBMem32: ")); | ||||
HWrite(L, Std_Logic_Vector(Addr)); | ||||
Write(L, String'(" : ")); | ||||
HWrite(L, Std_Logic_Vector(Data)); | ||||
if Comment /= "" then | ||||
Write(L, " : " & Comment); | ||||
end if; | ||||
WriteLine(Output, L); | ||||
end if; | ||||
AHBInDiag.HAddr <= Addr; | ||||
AHBInDiag.HWData <= Data; | ||||
AHBInDiag.HWrite <= '1'; | ||||
Synchronise(HCLK); | ||||
AHBInDiag.HWrite <= '0'; | ||||
end procedure WrAHBMem32; | ||||
----------------------------------------------------------------------------- | ||||
-- Routine for reading data directly from AHB memory | ||||
----------------------------------------------------------------------------- | ||||
procedure RdAHBMem32( | ||||
constant Addr: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBInDiag: out AHB_Diagnostics_In_Type; | ||||
signal AHBOutDiag: in AHB_Diagnostics_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant Comment: in String := ""; | ||||
constant Screen: in Boolean := False) is | ||||
variable L: Line; | ||||
begin | ||||
Synchronise(HCLK); | ||||
AHBInDiag.HAddr <= Addr; | ||||
AHBInDiag.HWrite <= '0'; | ||||
Synchronise(HCLK); | ||||
Data := AHBOutDiag.HRData; | ||||
if Screen then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, String'(" : RdAHBMem32: ")); | ||||
HWrite(L, Std_Logic_Vector(Addr)); | ||||
Write(L, String'(" : ")); | ||||
HWrite(L, Std_Logic_Vector(AHBOutDiag.HRData)); | ||||
if Comment /= "" then | ||||
Write(L, " : " & Comment); | ||||
end if; | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end procedure RdAHBMem32; | ||||
----------------------------------------------------------------------------- | ||||
-- Routine for reading data directly from AHB memory | ||||
----------------------------------------------------------------------------- | ||||
procedure RcAHBMem32( | ||||
constant Addr: in Std_Logic_Vector(31 downto 0); | ||||
constant Expected: in Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBInDiag: out AHB_Diagnostics_In_Type; | ||||
signal AHBOutDiag: in AHB_Diagnostics_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant Comment: in String := ""; | ||||
constant Screen: in Boolean := False) is | ||||
variable Data: Std_Logic_Vector(31 downto 0); | ||||
variable L: Line; | ||||
begin | ||||
Synchronise(HCLK); | ||||
AHBInDiag.HAddr <= Addr; | ||||
AHBInDiag.HWrite <= '0'; | ||||
Synchronise(HCLK); | ||||
Data := AHBOutDiag.HRData; | ||||
if not Compare(Data, Expected) then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, String'(" : RcAHBMem32: ")); | ||||
HWrite(L, Std_Logic_Vector(Addr)); | ||||
Write(L, String'(", value: ")); | ||||
HWrite(L, Std_Logic_Vector(Data)); | ||||
Write(L, String'(", expected: ")); | ||||
HWrite(L, Std_Logic_Vector(Expected)); | ||||
Write(L, String'(" # Error ")); | ||||
if Comment /= "" then | ||||
Write(L, " : " & Comment); | ||||
end if; | ||||
WriteLine(Output, L); | ||||
TP := False; | ||||
elsif Screen then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, String'(" : RcAHBMem32: ")); | ||||
HWrite(L, Std_Logic_Vector(Addr)); | ||||
Write(L, String'(" : ")); | ||||
HWrite(L, Std_Logic_Vector(Data)); | ||||
Write(L, String'(" : ")); | ||||
HWrite(L, Std_Logic_Vector(Expected)); | ||||
if Comment /= "" then | ||||
Write(L, " : " & Comment); | ||||
end if; | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end procedure RcAHBMem32; | ||||
----------------------------------------------------------------------------- | ||||
-- Routine for generating a split ack from AHB memory | ||||
----------------------------------------------------------------------------- | ||||
procedure SplitAHBMem32( | ||||
constant Split: in Integer range 0 to 15; | ||||
signal HCLK: in Std_ULogic; | ||||
signal AHBInDiag: out AHB_Diagnostics_In_Type; | ||||
signal AHBOutDiag: in AHB_Diagnostics_Out_Type; | ||||
variable TP: inout Boolean; | ||||
constant Comment: in String := ""; | ||||
constant Screen: in Boolean := False) is | ||||
variable L: Line; | ||||
begin | ||||
Synchronise(HCLK); | ||||
AHBInDiag.HSPLIT <= (others => '0'); | ||||
AHBInDiag.HSPLIT(Split) <= '1'; | ||||
Synchronise(HCLK); | ||||
AHBInDiag.HSPLIT <= (others => '0'); | ||||
if Screen then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, String'(" : SplitAHBMem32: split acknowledge to master: ")); | ||||
Write(L, Split); | ||||
if Comment /= "" then | ||||
Write(L, " : " & Comment); | ||||
end if; | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end procedure SplitAHBMem32; | ||||
end package body AMBA_TestPackage; --=========================================-- | ||||