##// END OF EJS Templates
temp
temp

File last commit:

r100:fc97c34d69e3 martin
r249:279a122aaba5 JC
Show More
dma2ahb_tp.vhd
1609 lines | 65.9 KiB | text/x-vhdl | VhdlLexer
------------------------------------------------------------------------------
-- 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; --======================================--