dma2ahb_tp.vhd
1609 lines
| 65.9 KiB
| text/x-vhdl
|
VhdlLexer
martin
|
r284 | ------------------------------------------------------------------------------ | ||
-- 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 : DMA2AHB_TestPackage (package declaration) | ||||
-- | ||||
-- File name : dma2ahb_tp.vhd | ||||
-- | ||||
-- Purpose : Interface package for AMBA AHB master interface with DMA input | ||||
-- | ||||
-- Reference : AMBA(TM) Specification (Rev 2.0), ARM IHI 0011A, | ||||
-- 13th May 1999, issue A, first release, ARM Limited | ||||
-- The document can be retrieved from http://www.arm.com | ||||
-- AMBA is a trademark of ARM Limited. | ||||
-- ARM is a registered trademark of ARM Limited. | ||||
-- | ||||
-- Note : Naming convention according to AMBA(TM) Specification: | ||||
-- Signal names are in upper case, except for the following: | ||||
-- A lower case 'n' in the name indicates that the signal | ||||
-- is active low. | ||||
-- Constant names are in upper case. | ||||
-- The least significant bit of an array is located to the right, | ||||
-- carrying the index number zero. | ||||
-- | ||||
-- Limitations : See DMA2AHB VHDL core | ||||
-- | ||||
-- Library : {independent} | ||||
-- | ||||
-- Authors : Aeroflex Gaisler AB | ||||
-- | ||||
-- Contact : mailto:support@gaisler.com | ||||
-- http://www.gaisler.com | ||||
-- | ||||
-- 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 | ||||
-- | ||||
-- 1.4 SH 1 Jul 2005 New package | ||||
-- 1.5 SH 1 Sep 2005 New library TOPNET | ||||
-- 1.6 SH 20 Sep 2005 Added transparent HSIZE support | ||||
-- 1.8 SH 10 Nov 2005 Updated DMA2AHB interface usage | ||||
-- 1.9 SH 4 Jan 2006 Burst routines added | ||||
-- Fault reporting priority and timing improved | ||||
-- 1.9.1 SH 12 Jan 2006 Correct DmaComp8 | ||||
-- 1.9.2 SH ## ### #### Corrected compare to allow pull-up | ||||
-- Adjusted printouts | ||||
-- 1.9.3 JA 14 Dec 2007 Support for halfword and byte bursts | ||||
-- 1.9.4 MI 4 Aug 2008 Support for Lock | ||||
-- 1.9.5 SH 4 Mar 2011 Modifed burst accesses to mimic real hw | ||||
-------------------------------------------------------------------------------- | ||||
library IEEE; | ||||
use IEEE.Std_Logic_1164.all; | ||||
use IEEE.Numeric_Std.all; | ||||
library Std; | ||||
use Std.Standard.all; | ||||
use Std.TextIO.all; | ||||
library GRLIB; | ||||
use GRLIB.AMBA.all; | ||||
use GRLIB.STDIO.all; | ||||
use GRLIB.DMA2AHB_Package.all; | ||||
use GRLIB.STDLIB.all; | ||||
package DMA2AHB_TestPackage is | ||||
----------------------------------------------------------------------------- | ||||
-- Vector of words | ||||
----------------------------------------------------------------------------- | ||||
type Data_Vector is array (Natural range <> ) of | ||||
Std_Logic_Vector(32-1 downto 0); | ||||
----------------------------------------------------------------------------- | ||||
-- Constants for comparison | ||||
----------------------------------------------------------------------------- | ||||
constant DontCare32: Std_Logic_Vector(31 downto 0) := (others => '-'); | ||||
constant DontCare24: Std_Logic_Vector(23 downto 0) := (others => '-'); | ||||
constant DontCare16: Std_Logic_Vector(15 downto 0) := (others => '-'); | ||||
constant DontCare8: Std_Logic_Vector( 7 downto 0) := (others => '-'); | ||||
---------------------------------------------------------------------------- | ||||
-- Constant for calculating burst lengths | ||||
---------------------------------------------------------------------------- | ||||
constant WordSize: integer := 32; | ||||
----------------------------------------------------------------------------- | ||||
-- Initialize AHB interface | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAInit( | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
constant InstancePath: in String := "DMAInit"; | ||||
constant ScreenOutput: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWriteQuiet( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWrite( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAQuiet( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAQuiet"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMARead( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMARead"; | ||||
constant ScreenOutput: in Boolean := True; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAComp( | ||||
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 dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAComp"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWrite16( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(15 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite16"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAQuiet16( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(15 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAQuiet16"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMARead16( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(15 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMARead16"; | ||||
constant ScreenOutput: in Boolean := True; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAComp16( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant CxData: in Std_Logic_Vector(15 downto 0); | ||||
variable RxData: out Std_Logic_Vector(15 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAComp16"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWrite8( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector( 7 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite8"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAQuiet8( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector( 7 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAQuiet8"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMARead8( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector( 7 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMARead8"; | ||||
constant ScreenOutput: in Boolean := True; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAComp8( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant CxData: in Std_Logic_Vector( 7 downto 0); | ||||
variable RxData: out Std_Logic_Vector( 7 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAComp8"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWriteQuietBurst( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Data_Vector; | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Beat: in Integer := 1; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWriteBurst( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Data_Vector; | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Beat: in Integer := 1; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAQuietBurst( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Data_Vector; | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAQuiet"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Beat: in Integer := 1; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAReadBurst( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Data_Vector; | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMARead"; | ||||
constant ScreenOutput: in Boolean := True; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Beat: in Integer := 1; | ||||
constant Lock: in Boolean := False); | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMACompBurst( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable CxData: in Data_Vector; | ||||
variable RxData: out Data_Vector; | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAComp"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Beat: in Integer := 1; | ||||
constant Lock: in Boolean := False); | ||||
end package DMA2AHB_TestPackage; | ||||
package body DMA2AHB_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 (To_X01(O(i))=T(i) or T(i)='-' or T(i)='U') then | ||||
Result := False; | ||||
end if; | ||||
end loop; | ||||
return Result; | ||||
end function Compare; | ||||
----------------------------------------------------------------------------- | ||||
-- Function declarations | ||||
----------------------------------------------------------------------------- | ||||
function Conv_Std_Logic_Vector( | ||||
constant i: Integer; | ||||
w: Integer) | ||||
return Std_Logic_Vector is | ||||
variable tmp: Std_Logic_Vector(w-1 downto 0); | ||||
begin | ||||
tmp := Std_Logic_Vector(To_UnSigned(i, w)); | ||||
return(tmp); | ||||
end; | ||||
----------------------------------------------------------------------------- | ||||
-- Function declarations | ||||
----------------------------------------------------------------------------- | ||||
function Conv_Integer( | ||||
constant i: Std_Logic_Vector) | ||||
return Integer is | ||||
variable tmp: Integer; | ||||
begin | ||||
tmp := To_Integer(UnSigned(i)); | ||||
return(tmp); | ||||
end; | ||||
----------------------------------------------------------------------------- | ||||
-- Synchronisation with respect to clock and with output offset | ||||
----------------------------------------------------------------------------- | ||||
procedure Synchronise( | ||||
signal Clock: in Std_ULogic; | ||||
constant Offset: in Time := 5 ns; | ||||
constant Enable: in Boolean := True) is | ||||
begin | ||||
if Enable then | ||||
wait until Clock = '1'; -- synchronise | ||||
if Offset > 0 ns then | ||||
wait for Offset; -- output offset delay | ||||
end if; | ||||
end if; | ||||
end procedure Synchronise; | ||||
----------------------------------------------------------------------------- | ||||
-- Initialize AHB interface | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAInit( | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
constant InstancePath: in String := "DMAInit"; | ||||
constant ScreenOutput: in Boolean := False) is | ||||
variable L: Line; | ||||
begin | ||||
Synchronise(HCLK); | ||||
dmai.Reset <= '0'; | ||||
dmai.Address <= (others => '0'); | ||||
dmai.Request <= '0'; | ||||
dmai.Burst <= '0'; | ||||
dmai.Beat <= (others => '0'); | ||||
dmai.Store <= '0'; | ||||
dmai.Data <= (others => '0'); | ||||
dmai.Size <= "10"; | ||||
dmai.Lock <= '0'; | ||||
if ScreenOutput then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB initalised")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end procedure DMAInit; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWriteQuiet( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Lock: in Boolean := False) is | ||||
variable L: Line; | ||||
begin | ||||
-- do not synchronise when a back-to-back access is requested | ||||
if not cBack2Back then | ||||
Synchronise(HCLK); | ||||
end if; | ||||
dmai.Reset <= '0'; | ||||
dmai.Address <= Address; | ||||
dmai.Request <= '1'; | ||||
dmai.Burst <= '0'; | ||||
dmai.Beat <= (others => '0'); | ||||
dmai.Store <= '1'; | ||||
dmai.Data <= Data; | ||||
if Size=32 then | ||||
dmai.Size <= HSIZE32; | ||||
elsif Size=16 then | ||||
dmai.Size <= HSIZE16; | ||||
elsif Size=8 then | ||||
dmai.Size <= HSIZE8; | ||||
else | ||||
report "Unsupported data width" | ||||
severity Failure; | ||||
end if; | ||||
if Lock then | ||||
dmai.Lock <= '1'; | ||||
else | ||||
dmai.Lock <= '0'; | ||||
end if; | ||||
wait for 1 ns; | ||||
if dmao.Grant='0' then | ||||
while dmao.Grant='0' loop | ||||
Synchronise(HCLK, 0 ns); | ||||
end loop; | ||||
else | ||||
Synchronise(HCLK); | ||||
end if; | ||||
dmai.Reset <= '0'; | ||||
dmai.Request <= '0'; | ||||
dmai.Store <= '0'; | ||||
dmai.Burst <= '0'; | ||||
dmai.Data <= Data; | ||||
loop | ||||
Synchronise(HCLK); | ||||
while dmao.Ready='0' and dmao.Retry='0' and dmao.Fault='0' loop | ||||
Synchronise(HCLK); | ||||
end loop; | ||||
if dmao.Fault='1' 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 reponse ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
TP := False; | ||||
dmai.Reset <= '0'; | ||||
dmai.Address <= (others => '0'); | ||||
dmai.Data <= (others => '0'); | ||||
dmai.Request <= '0'; | ||||
dmai.Store <= '0'; | ||||
dmai.Burst <= '0'; | ||||
dmai.Beat <= (others => '0'); | ||||
dmai.Size <= (others => '0'); | ||||
dmai.Lock <= '0'; | ||||
Synchronise(HCLK); | ||||
Synchronise(HCLK); | ||||
exit; | ||||
elsif dmao.Ready='1' then | ||||
dmai.Reset <= '0'; | ||||
dmai.Address <= (others => '0'); | ||||
dmai.Data <= (others => '0'); | ||||
dmai.Request <= '0'; | ||||
dmai.Store <= '0'; | ||||
dmai.Burst <= '0'; | ||||
dmai.Beat <= (others => '0'); | ||||
dmai.Size <= (others => '0'); | ||||
dmai.Lock <= '0'; | ||||
exit; | ||||
end if; | ||||
if dmao.Retry='1' 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/SPLIT reponse ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end if; | ||||
end loop; | ||||
end procedure DMAWriteQuiet; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWrite( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Lock: in Boolean := False) is | ||||
variable OK: Boolean := True; | ||||
variable L: Line; | ||||
begin | ||||
DMAWriteQuiet(Address, Data, HCLK, dmai, dmao, OK, | ||||
InstancePath, True, cBack2Back, Size, Lock); | ||||
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 DMAWrite; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAQuiet( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAQuiet"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Lock: in Boolean := False) is | ||||
variable L: Line; | ||||
begin | ||||
-- do not Synchronise when a back-to-back access is requested | ||||
if not cBack2Back then | ||||
Synchronise(HCLK); | ||||
end if; | ||||
dmai.Reset <= '0'; | ||||
dmai.Address <= Address; | ||||
dmai.Request <= '1'; | ||||
dmai.Burst <= '0'; | ||||
dmai.Beat <= (others => '0'); | ||||
dmai.Store <= '0'; | ||||
dmai.Data <= (others => '0'); | ||||
if Size=32 then | ||||
dmai.Size <= HSIZE32; | ||||
elsif Size=16 then | ||||
dmai.Size <= HSIZE16; | ||||
elsif Size=8 then | ||||
dmai.Size <= HSIZE8; | ||||
else | ||||
report "Unsupported data width" | ||||
severity Failure; | ||||
end if; | ||||
if Lock then | ||||
dmai.Lock <= '1'; | ||||
else | ||||
dmai.Lock <= '0'; | ||||
end if; | ||||
wait for 1 ns; | ||||
if dmao.Grant='0' then | ||||
while dmao.Grant='0' loop | ||||
Synchronise(HCLK, 0 ns); | ||||
end loop; | ||||
else | ||||
Synchronise(HCLK); | ||||
end if; | ||||
dmai.Reset <= '0'; | ||||
dmai.Data <= (others => '0'); | ||||
dmai.Request <= '0'; | ||||
dmai.Store <= '0'; | ||||
dmai.Burst <= '0'; | ||||
dmai.Beat <= (others => '0'); | ||||
loop | ||||
Synchronise(HCLK); | ||||
while dmao.Ready='0' and dmao.Retry='0' and dmao.Fault='0' loop | ||||
Synchronise(HCLK); | ||||
end loop; | ||||
if dmao.Fault='1' 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 reponse ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
TP := False; | ||||
dmai.Reset <= '0'; | ||||
dmai.Address <= (others => '0'); | ||||
dmai.Data <= (others => '0'); | ||||
dmai.Request <= '0'; | ||||
dmai.Store <= '0'; | ||||
dmai.Burst <= '0'; | ||||
dmai.Beat <= (others => '0'); | ||||
dmai.Size <= (others => '0'); | ||||
Data := (others => 'X'); | ||||
Synchronise(HCLK); | ||||
Synchronise(HCLK); | ||||
exit; | ||||
elsif dmao.Ready='1' then | ||||
Data := dmao.Data; | ||||
dmai.Address <= (others => '0'); | ||||
dmai.Beat <= (others => '0'); | ||||
dmai.Size <= (others => '0'); | ||||
exit; | ||||
end if; | ||||
if dmao.Retry='1' 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/SPLIT reponse ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end if; | ||||
end loop; | ||||
end procedure DMAQuiet; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMARead( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(31 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMARead"; | ||||
constant ScreenOutput: in Boolean := True; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Lock: in Boolean := False) is | ||||
variable OK: Boolean := True; | ||||
variable L: Line; | ||||
variable Temp: Std_Logic_Vector(31 downto 0); | ||||
begin | ||||
DMAQuiet(Address, Temp, HCLK, dmai, dmao, OK, | ||||
InstancePath, True, cBack2Back, Size, Lock); | ||||
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 DMARead; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAComp( | ||||
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 dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAComp"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Lock: in Boolean := False) is | ||||
variable OK: Boolean := True; | ||||
variable L: Line; | ||||
variable Data: Std_Logic_Vector(31 downto 0); | ||||
begin | ||||
DMAQuiet(Address, Data, HCLK, dmai, dmao, OK, | ||||
InstancePath, True, cBack2Back, Size, Lock); | ||||
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 DMAComp; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWriteQuiet16( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(15 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite16"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False) is | ||||
begin | ||||
DMAWriteQuiet(Address, Data & Data, HCLK, dmai, dmao, TP, | ||||
InstancePath, ScreenOutput, cBack2Back, 16, Lock); | ||||
end procedure DMAWriteQuiet16; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWrite16( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector(15 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite16"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False) is | ||||
begin | ||||
DMAWrite(Address, Data & Data, HCLK, dmai, dmao, TP, | ||||
InstancePath, ScreenOutput, cBack2Back, 16, Lock); | ||||
end procedure DMAWrite16; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAQuiet16( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(15 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAQuiet16"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False) is | ||||
variable Tmp: Std_Logic_Vector(31 downto 0); | ||||
begin | ||||
DMAQuiet(Address, Tmp, HCLK, dmai, dmao, TP, | ||||
InstancePath, ScreenOutput, cBack2Back, 16, Lock); | ||||
if Address(1)='0' then | ||||
Data := Tmp(31 downto 16); | ||||
else | ||||
Data := Tmp(15 downto 0); | ||||
end if; | ||||
end procedure DMAQuiet16; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMARead16( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector(15 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMARead16"; | ||||
constant ScreenOutput: in Boolean := True; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False) is | ||||
variable Tmp: Std_Logic_Vector(31 downto 0); | ||||
begin | ||||
DMARead(Address, Tmp, HCLK, dmai, dmao, TP, | ||||
InstancePath, ScreenOutput, cBack2Back, 16, Lock); | ||||
if Address(1)='0' then | ||||
Data := Tmp(31 downto 16); | ||||
else | ||||
Data := Tmp(15 downto 0); | ||||
end if; | ||||
end procedure DMARead16; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAComp16( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant CxData: in Std_Logic_Vector(15 downto 0); | ||||
variable RxData: out Std_Logic_Vector(15 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAComp16"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False) is | ||||
variable TmpRx: Std_Logic_Vector(31 downto 0); | ||||
variable TmpCx: Std_Logic_Vector(31 downto 0); | ||||
begin | ||||
if Address(1)='0' then | ||||
TmpCx := CxData & "----------------"; | ||||
else | ||||
TmpCx := "----------------" & CxData; | ||||
end if; | ||||
DMAComp(Address, TmpCx, TmpRx, HCLK, dmai, dmao, TP, | ||||
InstancePath, ScreenOutput, cBack2Back, 16, Lock); | ||||
if Address(1)='0' then | ||||
RxData := TmpRx(31 downto 16); | ||||
else | ||||
RxData := TmpRx(15 downto 0); | ||||
end if; | ||||
end procedure DMAComp16; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWriteQuiet8( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector( 7 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite8"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False) is | ||||
begin | ||||
DMAWriteQuiet(Address, Data & Data & Data & Data, HCLK, dmai, dmao, TP, | ||||
InstancePath, ScreenOutput, cBack2Back, 8, Lock); | ||||
end procedure DMAWriteQuiet8; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWrite8( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Std_Logic_Vector( 7 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite8"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False) is | ||||
begin | ||||
DMAWrite(Address, Data & Data & Data & Data, HCLK, dmai, dmao, TP, | ||||
InstancePath, ScreenOutput, cBack2Back, 8, Lock); | ||||
end procedure DMAWrite8; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAQuiet8( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector( 7 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAQuiet8"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False) is | ||||
variable Tmp: Std_Logic_Vector(31 downto 0); | ||||
begin | ||||
DMAQuiet(Address, Tmp, HCLK, dmai, dmao, TP, | ||||
InstancePath, ScreenOutput, cBack2Back, 8, Lock); | ||||
if Address(1 downto 0)="00" then | ||||
Data := Tmp(31 downto 24); | ||||
elsif Address(1 downto 0)="01" then | ||||
Data := Tmp(23 downto 16); | ||||
elsif Address(1 downto 0)="10" then | ||||
Data := Tmp(15 downto 8); | ||||
else | ||||
Data := Tmp( 7 downto 0); | ||||
end if; | ||||
end procedure DMAQuiet8; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMARead8( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Std_Logic_Vector( 7 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMARead8"; | ||||
constant ScreenOutput: in Boolean := True; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False) is | ||||
variable Tmp: Std_Logic_Vector(31 downto 0); | ||||
begin | ||||
DMARead(Address, Tmp, HCLK, dmai, dmao, TP, | ||||
InstancePath, ScreenOutput, cBack2Back, 8, Lock); | ||||
if Address(1 downto 0)="00" then | ||||
Data := Tmp(31 downto 24); | ||||
elsif Address(1 downto 0)="01" then | ||||
Data := Tmp(23 downto 16); | ||||
elsif Address(1 downto 0)="10" then | ||||
Data := Tmp(15 downto 8); | ||||
else | ||||
Data := Tmp( 7 downto 0); | ||||
end if; | ||||
end procedure DMARead8; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAComp8( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant CxData: in Std_Logic_Vector( 7 downto 0); | ||||
variable RxData: out Std_Logic_Vector( 7 downto 0); | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAComp8"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Lock: in Boolean := False) is | ||||
variable TmpRx: Std_Logic_Vector(31 downto 0); | ||||
variable TmpCx: Std_Logic_Vector(31 downto 0); | ||||
begin | ||||
if Address(1 downto 0)="00" then | ||||
TmpCx := CxData & "--------" & "--------" & "--------"; | ||||
elsif Address(1 downto 0)="01" then | ||||
TmpCx := "--------" & CxData & "--------" & "--------"; | ||||
elsif Address(1 downto 0)="10" then | ||||
TmpCx := "--------" & "--------" & CxData & "--------"; | ||||
else | ||||
TmpCx := "--------" & "--------" & "--------" & CxData; | ||||
end if; | ||||
DMAComp(Address, TmpCx, TmpRx, HCLK, dmai, dmao, TP, | ||||
InstancePath, ScreenOutput, cBack2Back, 8, Lock); | ||||
if Address(1 downto 0)="00" then | ||||
RxData := TmpRx(31 downto 24); | ||||
elsif Address(1 downto 0)="01" then | ||||
RxData := TmpRx(23 downto 16); | ||||
elsif Address(1 downto 0)="10" then | ||||
RxData := TmpRx(15 downto 8); | ||||
else | ||||
RxData := TmpRx( 7 downto 0); | ||||
end if; | ||||
end procedure DMAComp8; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWriteQuietBurst( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Data_Vector; | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Beat: in Integer := 1; | ||||
constant Lock: in Boolean := False) is | ||||
variable L: Line; | ||||
constant Count: Integer := Data'Length*WordSize/Size; | ||||
variable GCount: Integer := Data'Length*WordSize/Size; | ||||
variable DCount: Integer := 1; | ||||
begin | ||||
-- do not synchronise when a back-to-back access is requested | ||||
if not cBack2Back then | ||||
Synchronise(HCLK); | ||||
end if; | ||||
dmai.Reset <= '0'; | ||||
dmai.Address <= Address; | ||||
dmai.Data <= (others => '0'); | ||||
dmai.Request <= '1'; | ||||
dmai.Store <= '1'; | ||||
if Count > 1 then | ||||
dmai.Burst <= '1'; | ||||
else | ||||
dmai.Burst <= '0'; | ||||
end if; | ||||
if Beat=1 then | ||||
dmai.Beat <= HINCR; | ||||
elsif Beat=4 then | ||||
dmai.Beat <= HINCR4; | ||||
elsif Beat=8 then | ||||
dmai.Beat <= HINCR8; | ||||
elsif Beat=16 then | ||||
dmai.Beat <= HINCR16; | ||||
else | ||||
report "Unsupported beat" | ||||
severity Failure; | ||||
end if; | ||||
if Size=32 then | ||||
dmai.Size <= HSIZE32; | ||||
elsif Size=16 then | ||||
dmai.Size <= HSIZE16; | ||||
elsif Size=8 then | ||||
dmai.Size <= HSIZE8; | ||||
else | ||||
report "Unsupported data width" | ||||
severity Failure; | ||||
end if; | ||||
if Lock then | ||||
dmai.Lock <= '1'; | ||||
else | ||||
dmai.Lock <= '0'; | ||||
end if; | ||||
-- wait for first grant, indicating start of accesses | ||||
Synchronise(HCLK, 0 ns); | ||||
if dmao.Grant='0' then | ||||
while dmao.Grant='0' loop | ||||
Synchronise(HCLK, 0 ns); | ||||
end loop; | ||||
end if; | ||||
GCount := GCount-1; | ||||
-- first data | ||||
if Size=32 then | ||||
dmai.Data <= Data(0); | ||||
elsif Size=16 then | ||||
dmai.Data <= Data(0)(31 downto 16) & Data(0)(31 downto 16); | ||||
elsif Size=8 then | ||||
dmai.Data <= Data(0)(31 downto 24) & Data(0)(31 downto 24) & | ||||
Data(0)(31 downto 24) & Data(0)(31 downto 24); | ||||
end if; | ||||
loop | ||||
-- remove request when all grants received | ||||
if dmao.Grant='1' then | ||||
if GCount=0 then | ||||
dmai.Reset <= '0'; | ||||
dmai.Request <= '0'; | ||||
dmai.Store <= '0'; | ||||
dmai.Burst <= '0'; | ||||
else | ||||
GCount := GCount-1; | ||||
end if; | ||||
end if; | ||||
Synchronise(HCLK, 0 ns); | ||||
while dmao.Grant='0' and dmao.Ready='0' and dmao.OKAY='0' and dmao.Retry='0' and dmao.Fault='0' loop | ||||
Synchronise(HCLK, 0 ns); | ||||
end loop; | ||||
if dmao.Fault='1' then | ||||
if ScreenOutput then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB write access, address: ")); | ||||
HWrite(L, Conv_Std_Logic_Vector(Conv_Integer(Address)+(DCount-1)*Beat*Size/8, 32)); | ||||
Write (L, String'(" ERROR response ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
TP := False; | ||||
dmai.Reset <= '0'; | ||||
dmai.Address <= (others => '0'); | ||||
dmai.Data <= (others => '0'); | ||||
dmai.Request <= '0'; | ||||
dmai.Store <= '0'; | ||||
dmai.Burst <= '0'; | ||||
dmai.Beat <= (others => '0'); | ||||
dmai.Size <= (others => '0'); | ||||
Synchronise(HCLK, 0 ns); | ||||
Synchronise(HCLK, 0 ns); | ||||
exit; | ||||
elsif dmao.OKAY='1' then | ||||
-- for each OKAY, provide new data | ||||
if DCount=Count then | ||||
dmai.Address <= (others => '0'); | ||||
dmai.Beat <= (others => '0'); | ||||
dmai.Size <= (others => '0'); | ||||
Synchronise(HCLK, 0 ns); | ||||
while dmao.Ready='0' loop | ||||
Synchronise(HCLK, 0 ns); | ||||
end loop; | ||||
if GCount/=0 then | ||||
report "DMAWriteQuietBurst: Too few grants received!" | ||||
severity Failure; | ||||
end if; | ||||
exit; | ||||
else | ||||
if Size=32 then | ||||
dmai.Data <= Data(DCount); | ||||
elsif Size=16 then | ||||
dmai.Data <= Data(DCount/2)((31-16*(DCount mod 2)) downto (16-(16*(DCount mod 2)))) & | ||||
Data(DCount/2)((31-16*(DCount mod 2)) downto (16-(16*(DCount mod 2)))); | ||||
elsif Size=8 then | ||||
dmai.Data <= Data(DCount/4)((31-8*(DCount mod 4)) downto (24-(8*(DCount mod 4)))) & | ||||
Data(DCount/4)((31-8*(DCount mod 4)) downto (24-(8*(DCount mod 4)))) & | ||||
Data(DCount/4)((31-8*(DCount mod 4)) downto (24-(8*(DCount mod 4)))) & | ||||
Data(DCount/4)((31-8*(DCount mod 4)) downto (24-(8*(DCount mod 4)))); | ||||
end if; | ||||
DCount := DCount+1; | ||||
end if; | ||||
end if; | ||||
if dmao.Retry='1' then | ||||
if ScreenOutput then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB write access, address: ")); | ||||
HWrite(L, Conv_Std_Logic_Vector(Conv_Integer(Address)+(DCount-1)*Beat*Size/8, 32)); | ||||
Write (L, String'(" RETRY/SPLIT response ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end if; | ||||
end loop; | ||||
end procedure DMAWriteQuietBurst; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB write access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAWriteBurst( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
constant Data: in Data_Vector; | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAWrite"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Beat: in Integer := 1; | ||||
constant Lock: in Boolean := False) is | ||||
variable OK: Boolean := True; | ||||
variable L: Line; | ||||
begin | ||||
DMAWriteQuietBurst(Address, Data, HCLK, dmai, dmao, OK, | ||||
InstancePath, ScreenOutput, cBack2Back, Size, Beat, Lock); | ||||
if ScreenOutput and OK then | ||||
for i in 0 to Data'Length-1 loop | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB write access, address: ")); | ||||
HWrite(L, Conv_Std_Logic_Vector(Conv_Integer(Address)+i*Beat*Size/8, 32)); | ||||
Write (L, String'(" : data: ")); | ||||
HWrite(L, Data(i)); | ||||
WriteLine(Output, L); | ||||
end loop; | ||||
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 DMAWriteBurst; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAQuietBurst( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Data_Vector; | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAQuiet"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Beat: in Integer := 1; | ||||
constant Lock: in Boolean := False) is | ||||
variable L: Line; | ||||
constant Count: Integer := Data'Length*WordSize/Size; | ||||
variable GCount: Integer := Data'Length*WordSize/Size; | ||||
variable DCount: Integer := 1; | ||||
variable DataPart: Integer := 0; | ||||
begin | ||||
-- do not synchronise when a back-to-back access is requested | ||||
if not cBack2Back then | ||||
Synchronise(HCLK); | ||||
end if; | ||||
dmai.Reset <= '0'; | ||||
dmai.Address <= Address; | ||||
dmai.Data <= (others => '0'); | ||||
dmai.Request <= '1'; | ||||
dmai.Store <= '0'; | ||||
if Count > 1 then | ||||
dmai.Burst <= '1'; | ||||
else | ||||
dmai.Burst <= '0'; | ||||
end if; | ||||
if Beat=1 then | ||||
dmai.Beat <= HINCR; | ||||
elsif Beat=4 then | ||||
dmai.Beat <= HINCR4; | ||||
elsif Beat=8 then | ||||
dmai.Beat <= HINCR8; | ||||
elsif Beat=16 then | ||||
dmai.Beat <= HINCR16; | ||||
else | ||||
report "Unsupported beat" | ||||
severity Failure; | ||||
end if; | ||||
if Size=32 then | ||||
dmai.Size <= HSIZE32; | ||||
elsif Size=16 then | ||||
dmai.Size <= HSIZE16; | ||||
if Address(1 downto 0) = "00" then | ||||
DataPart := 0; | ||||
else | ||||
DataPart := 1; | ||||
end if; | ||||
elsif Size=8 then | ||||
dmai.Size <= HSIZE8; | ||||
if Address(1 downto 0) = "00" then | ||||
DataPart := 0; | ||||
elsif Address(1 downto 0) = "01" then | ||||
DataPart := 1; | ||||
elsif Address(1 downto 0) = "10" then | ||||
DataPart := 2; | ||||
else | ||||
DataPart := 3; | ||||
end if; | ||||
else | ||||
report "Unsupported data width" | ||||
severity Failure; | ||||
end if; | ||||
if Lock then | ||||
dmai.Lock <= '1'; | ||||
else | ||||
dmai.Lock <= '0'; | ||||
end if; | ||||
-- wait for first grant, indicating start of accesses | ||||
Synchronise(HCLK, 0 ns); | ||||
if dmao.Grant='0' then | ||||
while dmao.Grant='0' loop | ||||
Synchronise(HCLK, 0 ns); | ||||
end loop; | ||||
end if; | ||||
GCount := GCount-1; | ||||
loop | ||||
-- remove request when all grants received | ||||
if dmao.Grant='1' then | ||||
if GCount=0 then | ||||
dmai.Reset <= '0'; | ||||
dmai.Data <= (others => '0'); | ||||
dmai.Request <= '0'; | ||||
dmai.Store <= '0'; | ||||
dmai.Burst <= '0'; | ||||
else | ||||
GCount := GCount-1; | ||||
end if; | ||||
end if; | ||||
Synchronise(HCLK, 0 ns); | ||||
while dmao.Grant='0' and dmao.Ready='0' and dmao.Retry='0' and dmao.Fault='0' loop | ||||
Synchronise(HCLK, 0 ns); | ||||
end loop; | ||||
if dmao.Fault='1' then | ||||
if ScreenOutput then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Conv_Std_Logic_Vector(Conv_Integer(Address)+(DCount-1)*Beat*Size/8, 32)); | ||||
Write (L, String'(" ERROR response")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
TP := False; | ||||
dmai.Reset <= '0'; | ||||
dmai.Address <= (others => '0'); | ||||
dmai.Data <= (others => '0'); | ||||
dmai.Request <= '0'; | ||||
dmai.Store <= '0'; | ||||
dmai.Burst <= '0'; | ||||
dmai.Beat <= (others => '0'); | ||||
dmai.Size <= (others => '0'); | ||||
Synchronise(HCLK); | ||||
Synchronise(HCLK); | ||||
exit; | ||||
elsif dmao.Ready='1' then | ||||
-- for each READY, store data | ||||
if Size=32 then | ||||
Data(DCount-1) := dmao.Data; | ||||
elsif Size=16 then | ||||
Data((DCount-1)/2)((31-16*((DCount-1) mod 2)) downto (16-(16*((DCount-1) mod 2)))) := | ||||
dmao.Data((31-16*DataPart) downto (16-16*DataPart)); | ||||
DataPart := (DataPart + 1) mod 2; | ||||
elsif Size=8 then | ||||
Data((DCount-1)/4)((31-8*((DCount-1) mod 4)) downto (24-(8*((DCount-1) mod 4)))) := | ||||
dmao.Data((31-8*DataPart) downto (24-8*DataPart)); | ||||
DataPart := (DataPart + 1) mod 4; | ||||
end if; | ||||
if DCount=Count then | ||||
dmai.Address <= (others => '0'); | ||||
dmai.Beat <= (others => '0'); | ||||
dmai.Size <= (others => '0'); | ||||
if GCount/=0 then | ||||
report "DMAQuietBurst: Too few grants received!" | ||||
severity Failure; | ||||
end if; | ||||
exit; | ||||
else | ||||
DCount := DCount+1; | ||||
end if; | ||||
end if; | ||||
if dmao.Retry='1' then | ||||
if ScreenOutput then | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Conv_Std_Logic_Vector(Conv_Integer(Address)+(DCount-1)*Beat*Size/8, 32)); | ||||
Write (L, String'(" RETRY/SPLIT response ")); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end if; | ||||
end loop; | ||||
end procedure DMAQuietBurst; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMAReadBurst( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable Data: out Data_Vector; | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMARead"; | ||||
constant ScreenOutput: in Boolean := True; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Beat: in Integer := 1; | ||||
constant Lock: in Boolean := False) is | ||||
variable OK: Boolean := True; | ||||
variable L: Line; | ||||
variable Temp: Data_Vector(0 to Data'Length-1); | ||||
begin | ||||
DMAQuietBurst(Address, Temp, HCLK, dmai, dmao, OK, | ||||
InstancePath, ScreenOutput, cBack2Back, Size, Beat, Lock); | ||||
if ScreenOutput and OK then | ||||
Data := Temp; | ||||
for i in 0 to Data'Length-1 loop | ||||
Write (L, Now, Right, 15); | ||||
Write (L, " : " & InstancePath); | ||||
Write (L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Conv_Std_Logic_Vector(Conv_Integer(Address)+i*Beat*Size/8, 32)); | ||||
Write (L, String'(" : data: ")); | ||||
HWrite(L, Temp(i)); | ||||
WriteLine(Output, L); | ||||
end loop; | ||||
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); | ||||
Temp := (others => (others => '-')); | ||||
Data := Temp; | ||||
TP := False; | ||||
end if; | ||||
end procedure DMAReadBurst; | ||||
----------------------------------------------------------------------------- | ||||
-- AMBA AHB read access | ||||
----------------------------------------------------------------------------- | ||||
procedure DMACompBurst( | ||||
constant Address: in Std_Logic_Vector(31 downto 0); | ||||
variable CxData: in Data_Vector; | ||||
variable RxData: out Data_Vector; | ||||
signal HCLK: in Std_ULogic; | ||||
signal dmai: out dma_in_type; | ||||
signal dmao: in dma_out_type; | ||||
variable TP: inout Boolean; | ||||
constant InstancePath: in String := "DMAComp"; | ||||
constant ScreenOutput: in Boolean := False; | ||||
constant cBack2Back: in Boolean := False; | ||||
constant Size: in Integer := 32; | ||||
constant Beat: in Integer := 1; | ||||
constant Lock: in Boolean := False) is | ||||
variable OK: Boolean := True; | ||||
variable L: Line; | ||||
variable Data: Data_Vector(0 to CxData'Length-1); | ||||
begin | ||||
DMAQuietBurst(Address, Data, HCLK, dmai, dmao, OK, | ||||
InstancePath, ScreenOutput, cBack2Back, Size, Beat, Lock); | ||||
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; | ||||
Data := (others => (others => '-')); | ||||
RxData := Data; | ||||
else | ||||
for i in 0 to Data'Length-1 loop | ||||
if not Compare(Data(i), CxData(i)) then | ||||
Write(L, Now, Right, 15); | ||||
Write(L, " : " & InstancePath); | ||||
Write(L, String'(" : AHB read access, address: ")); | ||||
HWrite(L, Conv_Std_Logic_Vector(Conv_Integer(Address)+i*Beat*Size/8, 32)); | ||||
Write(L, String'(" : data: ")); | ||||
HWrite(L, Data(i)); | ||||
Write(L, String'(" : expected: ")); | ||||
HWrite(L, CxData(i)); | ||||
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, Conv_Std_Logic_Vector(Conv_Integer(Address)+i*Beat*Size/8, 32)); | ||||
Write(L, String'(" : data: ")); | ||||
HWrite(L, Data(i)); | ||||
WriteLine(Output, L); | ||||
end if; | ||||
end loop; | ||||
RxData := Data; | ||||
end if; | ||||
end procedure DMACompBurst; | ||||
end package body DMA2AHB_TestPackage; --======================================-- | ||||