|
|
------------------------------------------------------------------------------
|
|
|
-- 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
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- package: testlib
|
|
|
-- file: testlib.vhd
|
|
|
-- author: Marko Isomaki - Aeroflex Gaisler
|
|
|
-- description: package for common vhdl functions for testbenches
|
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
library std;
|
|
|
use std.standard.all;
|
|
|
use std.textio.all;
|
|
|
|
|
|
library ieee;
|
|
|
use ieee.std_logic_1164.all;
|
|
|
use ieee.numeric_std.all;
|
|
|
use ieee.math_real.all;
|
|
|
|
|
|
library grlib;
|
|
|
use grlib.stdio.all;
|
|
|
use grlib.stdlib.tost;
|
|
|
|
|
|
package testlib is
|
|
|
type octet_vector is array (natural range <>) of std_logic_vector(7 downto 0);
|
|
|
subtype data_vector8 is octet_vector;
|
|
|
type data_vector16 is array (natural range <>) of std_logic_vector(15 downto 0);
|
|
|
type data_vector32 is array (natural range <>) of std_logic_vector(31 downto 0);
|
|
|
type data_vector64 is array (natural range <>) of std_logic_vector(63 downto 0);
|
|
|
type data_vector128 is array (natural range <>) of std_logic_vector(127 downto 0);
|
|
|
type data_vector256 is array (natural range <>) of std_logic_vector(255 downto 0);
|
|
|
type nibble_vector is array (natural range <>) of std_logic_vector(3 downto 0);
|
|
|
subtype data_vector is data_vector32;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- compare function handling '-'. c is the expected data parameter. If it is
|
|
|
--'-' or 'U' then this bit is not compared. Returns true if the vectors match
|
|
|
-----------------------------------------------------------------------------
|
|
|
function compare(o, c: in std_logic_vector) return boolean;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- compare function handling '-'
|
|
|
-----------------------------------------------------------------------------
|
|
|
function compare(o, c: in std_ulogic_vector) return boolean;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- this procedure prints a message to standard output. Also includes the time
|
|
|
-- at which it occurs.
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure print(
|
|
|
constant comment: in string := "-";
|
|
|
constant severe: in severity_level := note;
|
|
|
constant screen: in boolean := true);
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- 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);
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- this procedure initialises the test error counters. Used in testbenches
|
|
|
-- with a test variable to check if a subtest has failed and at the end how
|
|
|
-- many subtests have failed. This procedure is called before the first
|
|
|
-- subtest
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure tinitialise(
|
|
|
variable test: inout boolean;
|
|
|
variable testcount: inout integer);
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- this procedure completes the sub-test. Called at the end of each subtest
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure tintermediate(
|
|
|
variable test: inout boolean;
|
|
|
variable testcount: inout integer);
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- this procedure completes the test. Called at the end of the complete test
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure tterminate(
|
|
|
variable test: inout boolean;
|
|
|
variable testcount: inout integer);
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- check std_logic_vector array
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure check(
|
|
|
variable tp: inout boolean;
|
|
|
constant received: in std_logic_vector;
|
|
|
constant expected: in std_logic_vector;
|
|
|
constant message: in string := "");
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- check std_logic
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure check(
|
|
|
variable tp: inout boolean;
|
|
|
constant received: in std_logic;
|
|
|
constant expected: in std_logic;
|
|
|
constant message: in string := "");
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- check std_ulogic_vector array
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure check(
|
|
|
variable tp: inout boolean;
|
|
|
constant received: in std_ulogic_vector;
|
|
|
constant expected: in std_ulogic_vector;
|
|
|
constant message: in string := "");
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- check natural
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure check(
|
|
|
variable tp: inout boolean;
|
|
|
constant received: in natural;
|
|
|
constant expected: in natural;
|
|
|
constant message: in string := "");
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- check time
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure check(
|
|
|
variable tp: inout boolean;
|
|
|
constant received: in time;
|
|
|
constant expected: in time;
|
|
|
constant spread: in time;
|
|
|
constant message: in string := "");
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- check boolean
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure check(
|
|
|
variable tp: inout boolean;
|
|
|
constant received: in boolean;
|
|
|
constant expected: in boolean;
|
|
|
constant message: in string := "");
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- Convert Data_Vector to Octet_Vector
|
|
|
-----------------------------------------------------------------------------
|
|
|
function conv_octet_vector(
|
|
|
constant d: in data_vector)
|
|
|
return octet_vector;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- Convert Octet_Vector to Data_Vector, with padding
|
|
|
-----------------------------------------------------------------------------
|
|
|
function conv_data_vector(
|
|
|
constant o: in octet_vector)
|
|
|
return data_vector;
|
|
|
|
|
|
procedure compare(
|
|
|
constant data: in octet_vector;
|
|
|
constant cxdata: in octet_vector;
|
|
|
variable tP: inout boolean);
|
|
|
|
|
|
----------------------------------------------------------------------------
|
|
|
-- Read file contents to octet vector
|
|
|
----------------------------------------------------------------------------
|
|
|
--Expects data only in hex with four bytes on each line.
|
|
|
procedure readfile(
|
|
|
constant filename: in string := "";
|
|
|
constant filetype: in integer := 0;
|
|
|
constant size: in integer := 0;
|
|
|
variable dataout: out octet_vector);
|
|
|
|
|
|
--Reads bytes from a file with the format packets are output from ethereal
|
|
|
procedure readfile(
|
|
|
constant filename: in string := "";
|
|
|
constant size: in integer := 0;
|
|
|
variable dataout: out octet_vector);
|
|
|
|
|
|
----------------------------------------------------------------------------
|
|
|
-- Read file contents to data_vector
|
|
|
----------------------------------------------------------------------------
|
|
|
--Expects data only in hex with four bytes on each line.
|
|
|
procedure readfile(
|
|
|
constant filename: in string := "";
|
|
|
constant size: in integer := 0;
|
|
|
variable dataout: out data_vector);
|
|
|
|
|
|
--generates an random integer from 0 to the maximum value specified with max
|
|
|
procedure gen_rand_int(
|
|
|
constant max : in real;
|
|
|
variable seed1 : inout positive;
|
|
|
variable seed2 : inout positive;
|
|
|
variable rand : out integer);
|
|
|
|
|
|
--reverses std_logic_vector
|
|
|
function reverse(din : std_logic_vector) return std_logic_vector;
|
|
|
|
|
|
-- Returns offset to start of valid data for an access of size 'size' in
|
|
|
-- AMBA data vector
|
|
|
function ahb_doff (
|
|
|
constant dw : integer;
|
|
|
constant size : integer; -- access size
|
|
|
constant addr : std_logic_vector(4 downto 0))
|
|
|
return integer;
|
|
|
|
|
|
end package testlib;
|
|
|
|
|
|
--============================================================================--
|
|
|
|
|
|
package body testlib is
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- compare function handling '-'
|
|
|
-----------------------------------------------------------------------------
|
|
|
function compare(o, c: in std_logic_vector) return boolean is
|
|
|
variable t: std_logic_vector(o'range) := c;
|
|
|
variable result: boolean;
|
|
|
begin
|
|
|
result := true;
|
|
|
for i in o'range loop
|
|
|
if not (o(i)=t(i) or t(i)='-' or t(i)='U') then
|
|
|
result := false;
|
|
|
end if;
|
|
|
end loop;
|
|
|
return result;
|
|
|
end function compare;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- compare function handling '-'
|
|
|
-----------------------------------------------------------------------------
|
|
|
function compare(o, c: in std_ulogic_vector) return boolean is
|
|
|
variable t: std_ulogic_vector(o'range) := c;
|
|
|
variable result: boolean;
|
|
|
begin
|
|
|
result := true;
|
|
|
for i in o'range loop
|
|
|
if not (o(i)=t(i) or t(i)='-' or t(i)='U') then
|
|
|
result := false;
|
|
|
end if;
|
|
|
end loop;
|
|
|
return result;
|
|
|
end function compare;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- this procedure prints a message to standard output
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure print(
|
|
|
constant comment: in string := "-";
|
|
|
constant severe: in severity_level := note;
|
|
|
constant screen: in boolean := true) is
|
|
|
variable l: line;
|
|
|
begin
|
|
|
if screen then
|
|
|
write(l, now, right, 15);
|
|
|
write(l, " : " & comment);
|
|
|
if severe = warning then
|
|
|
write(l, string'(" # warning, "));
|
|
|
elsif severe = error then
|
|
|
write(l, string'(" # error, "));
|
|
|
elsif severe = failure then
|
|
|
write(l, string'(" # failure, "));
|
|
|
end if;
|
|
|
writeline(output, l);
|
|
|
end if;
|
|
|
end procedure print;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- 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
|
|
|
wait for offset; -- output offset delay
|
|
|
end if;
|
|
|
end procedure synchronise;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- this procedure initialises the test error counters
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure tinitialise(
|
|
|
variable test: inout boolean;
|
|
|
variable testcount: inout integer) is
|
|
|
begin
|
|
|
--------------------------------------------------------------------------
|
|
|
-- initialise test status
|
|
|
--------------------------------------------------------------------------
|
|
|
test := true; -- reset any errors
|
|
|
testcount := 0;
|
|
|
print("--=========================================================--");
|
|
|
print("*** test initialised � ***");
|
|
|
print("--=========================================================--");
|
|
|
end procedure tinitialise;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- this procedure completes the sub-test
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure tintermediate(
|
|
|
variable test: inout boolean;
|
|
|
variable testcount: inout integer) is
|
|
|
variable l: line;
|
|
|
begin
|
|
|
--------------------------------------------------------------------------
|
|
|
-- report test status
|
|
|
--------------------------------------------------------------------------
|
|
|
wait for 10 us;
|
|
|
print("--=========================================================--");
|
|
|
if test then
|
|
|
print("*** sub-test completed successfully ***");
|
|
|
if testcount > 0 then
|
|
|
write(l, now, right, 15);
|
|
|
write(l, string'(" : "));
|
|
|
write(l, testcount);
|
|
|
write(l, string'(" sub-test(s) ended with one or more errors."));
|
|
|
writeline(output, l);
|
|
|
end if;
|
|
|
else
|
|
|
print("*** sub-test completed with errors -- # error # -- ***");
|
|
|
testcount := testcount + 1;
|
|
|
test := true;
|
|
|
if testcount > 0 then
|
|
|
write(l, now, right, 15);
|
|
|
write(l, string'(" : "));
|
|
|
write(l, testcount);
|
|
|
write(l, string'(" sub-test(s) ended with one or more errors."));
|
|
|
writeline(output, l);
|
|
|
end if;
|
|
|
end if;
|
|
|
print("--=========================================================--");
|
|
|
end procedure tintermediate;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- this procedure completes the test
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure tterminate(
|
|
|
variable test: inout boolean;
|
|
|
variable testcount: inout integer) is
|
|
|
variable l: line;
|
|
|
begin
|
|
|
--------------------------------------------------------------------------
|
|
|
-- end of test
|
|
|
--------------------------------------------------------------------------
|
|
|
wait for 1 ms;
|
|
|
print("--=========================================================--");
|
|
|
if testcount = 0 then
|
|
|
print("*** test completed successfully ***");
|
|
|
else
|
|
|
print("*** test completed with errors -- # error # -- ***");
|
|
|
write(l, now, right, 15);
|
|
|
write(l, string'(" : "));
|
|
|
write(l, testcount);
|
|
|
write(l, string'(" sub-test(s) ended with one or more errors."));
|
|
|
writeline(output, l);
|
|
|
end if;
|
|
|
print("--=========================================================--");
|
|
|
report "---- end of test ----"
|
|
|
severity failure;
|
|
|
wait;
|
|
|
end procedure tterminate;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- check std_logic_vector array
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure check(
|
|
|
variable tp: inout boolean;
|
|
|
constant received: in std_logic_vector;
|
|
|
constant expected: in std_logic_vector;
|
|
|
constant message: in string := "") is
|
|
|
variable l: line;
|
|
|
constant padding: std_logic_vector(1 to
|
|
|
(4-(received'length mod 4))) :=
|
|
|
(others => '0');
|
|
|
begin
|
|
|
if not compare(received, expected) then
|
|
|
write(l, now, right, 15);
|
|
|
write(l, string'(" : ") & message & string'(" :"));
|
|
|
write(l, string'(" received: "));
|
|
|
if padding'length > 0 and padding'length < 4 then
|
|
|
hwrite(l, padding & std_logic_vector(received));
|
|
|
else
|
|
|
hwrite(l, std_logic_vector(received));
|
|
|
end if;
|
|
|
write(l, string'(" expected: "));
|
|
|
if padding'length > 0 and padding'length < 4 then
|
|
|
hwrite(l, padding & std_logic_vector(expected));
|
|
|
else
|
|
|
hwrite(l, std_logic_vector(expected));
|
|
|
end if;
|
|
|
write(l, string'(" # error"));
|
|
|
writeline(output, l);
|
|
|
tp := false;
|
|
|
end if;
|
|
|
end procedure check;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- check std_logic
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure check(
|
|
|
variable tp: inout boolean;
|
|
|
constant received: in std_logic;
|
|
|
constant expected: in std_logic;
|
|
|
constant message: in string := "") is
|
|
|
variable l: line;
|
|
|
begin
|
|
|
if not (to_x01z(received)=to_x01z(expected)) then
|
|
|
write(l, now, right, 15);
|
|
|
write(l, string'(" : ") & message & string'(" :"));
|
|
|
write(l, string'(" received: "));
|
|
|
write(l, received);
|
|
|
write(l, string'(" expected: "));
|
|
|
write(l, expected);
|
|
|
write(l, string'(" # error"));
|
|
|
writeline(output, l);
|
|
|
tp := false;
|
|
|
end if;
|
|
|
end procedure check;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- check std_ulogic_vector array
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure check(
|
|
|
variable tp: inout boolean;
|
|
|
constant received: in std_ulogic_vector;
|
|
|
constant expected: in std_ulogic_vector;
|
|
|
constant message: in string := "") is
|
|
|
variable l: line;
|
|
|
constant padding: std_ulogic_vector(1 to
|
|
|
(4-(received'length mod 4))) :=
|
|
|
(others => '0');
|
|
|
begin
|
|
|
if not compare(received, expected) then
|
|
|
write(l, now, right, 15);
|
|
|
write(l, string'(" : ") & message & string'(" :"));
|
|
|
write(l, string'(" received: "));
|
|
|
if padding'length > 0 and padding'length < 4 then
|
|
|
hwrite(l, std_logic_vector(padding) & std_logic_vector(received));
|
|
|
else
|
|
|
hwrite(l, std_logic_vector(received));
|
|
|
end if;
|
|
|
write(l, string'(" expected: "));
|
|
|
if padding'length > 0 and padding'length < 4 then
|
|
|
hwrite(l, std_logic_vector(padding) & std_logic_vector(expected));
|
|
|
else
|
|
|
hwrite(l, std_logic_vector(expected));
|
|
|
end if;
|
|
|
write(l, string'(" # error"));
|
|
|
writeline(output, l);
|
|
|
tp := false;
|
|
|
end if;
|
|
|
end procedure check;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- check natural
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure check(
|
|
|
variable tp: inout boolean;
|
|
|
constant received: in natural;
|
|
|
constant expected: in natural;
|
|
|
constant message: in string := "") is
|
|
|
variable l: line;
|
|
|
begin
|
|
|
if received /= expected then
|
|
|
write(l, now, right, 15);
|
|
|
write(l, string'(" : ") & message & string'(" :"));
|
|
|
write(l, string'(" received: "));
|
|
|
write(l, received);
|
|
|
write(l, string'(" expected: "));
|
|
|
write(l, expected);
|
|
|
write(l, string'(" # error"));
|
|
|
writeline(output, l);
|
|
|
tp := false;
|
|
|
end if;
|
|
|
end procedure check;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- check time
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure check(
|
|
|
variable tp: inout boolean;
|
|
|
constant received: in time;
|
|
|
constant expected: in time;
|
|
|
constant spread: in time;
|
|
|
constant message: in string := "") is
|
|
|
variable l: line;
|
|
|
begin
|
|
|
if (received > expected+spread) or
|
|
|
(received < expected-spread) then
|
|
|
write(l, now, right, 15);
|
|
|
write(l, string'(" : ") & message & string'(" :"));
|
|
|
write(l, string'(" received: "));
|
|
|
write(l, received);
|
|
|
write(l, string'(" expected: "));
|
|
|
write(l, expected);
|
|
|
write(l, string'(" # error"));
|
|
|
writeline(output, l);
|
|
|
tp := false;
|
|
|
end if;
|
|
|
end procedure check;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- check boolean
|
|
|
-----------------------------------------------------------------------------
|
|
|
procedure check(
|
|
|
variable tp: inout boolean;
|
|
|
constant received: in boolean;
|
|
|
constant expected: in boolean;
|
|
|
constant message: in string := "") is
|
|
|
variable l: line;
|
|
|
begin
|
|
|
if received /= expected then
|
|
|
write(l, now, right, 15);
|
|
|
write(l, string'(" : ") & message & string'(" :"));
|
|
|
write(l, string'(" received: "));
|
|
|
write(l, received);
|
|
|
write(l, string'(" expected: "));
|
|
|
write(l, expected);
|
|
|
write(l, string'(" # error"));
|
|
|
writeline(output, l);
|
|
|
tp := false;
|
|
|
end if;
|
|
|
end procedure check;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- Convert Data_Vector to Octet_Vector
|
|
|
-----------------------------------------------------------------------------
|
|
|
function conv_octet_vector(
|
|
|
constant d: in data_vector)
|
|
|
return octet_vector is
|
|
|
variable o: octet_vector(0 to d'Length*4-1);
|
|
|
begin
|
|
|
for i in o'range loop
|
|
|
o(i) := d(i/4)((3-(i mod 4))*8+7 downto (3-(i mod 4))*8);
|
|
|
end loop;
|
|
|
return o;
|
|
|
end function conv_octet_vector;
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
-- Convert Octet_Vector to Data_Vector, with padding
|
|
|
-----------------------------------------------------------------------------
|
|
|
function conv_data_vector(
|
|
|
constant o: in octet_vector)
|
|
|
return data_vector is
|
|
|
variable d: data_vector(0 to (1+(o'Length-1)/4)-1);
|
|
|
begin
|
|
|
for i in o'Range loop
|
|
|
d(i/4)((3-(i mod 4))*8+7 downto (3-(i mod 4))*8) := o(i);
|
|
|
end loop;
|
|
|
return d;
|
|
|
end function conv_data_vector;
|
|
|
|
|
|
procedure compare(
|
|
|
constant data: in octet_vector;
|
|
|
constant cxdata: in octet_vector;
|
|
|
variable tp: inout boolean) is
|
|
|
begin
|
|
|
if (data'length /= cxdata'length) then
|
|
|
tp := false;
|
|
|
print("compare error: lengths do not match");
|
|
|
else
|
|
|
for i in data'low to data'low+data'length-1 loop
|
|
|
if not compare(data(i), cxdata(i)) then
|
|
|
tp := false;
|
|
|
print("compare error. index: " & tost(i) & " data: " & tost(data(i)) & " expected: " & tost(cxdata(i)));
|
|
|
end if;
|
|
|
end loop;
|
|
|
end if;
|
|
|
end compare;
|
|
|
|
|
|
function FromChar(C: Character) return Std_Logic_Vector is
|
|
|
variable R: Std_Logic_Vector(0 to 3);
|
|
|
begin
|
|
|
case C is
|
|
|
when '0' => R := "0000";
|
|
|
when '1' => R := "0001";
|
|
|
when '2' => R := "0010";
|
|
|
when '3' => R := "0011";
|
|
|
when '4' => R := "0100";
|
|
|
when '5' => R := "0101";
|
|
|
when '6' => R := "0110";
|
|
|
when '7' => R := "0111";
|
|
|
when '8' => R := "1000";
|
|
|
when '9' => R := "1001";
|
|
|
|
|
|
when 'A' => R := "1010";
|
|
|
when 'B' => R := "1011";
|
|
|
when 'C' => R := "1100";
|
|
|
when 'D' => R := "1101";
|
|
|
when 'E' => R := "1110";
|
|
|
when 'F' => R := "1111";
|
|
|
|
|
|
when 'a' => R := "1010";
|
|
|
when 'b' => R := "1011";
|
|
|
when 'c' => R := "1100";
|
|
|
when 'd' => R := "1101";
|
|
|
when 'e' => R := "1110";
|
|
|
when 'f' => R := "1111";
|
|
|
when others => R := "XXXX";
|
|
|
end case;
|
|
|
return R;
|
|
|
end FromChar;
|
|
|
|
|
|
procedure readfile(
|
|
|
constant filename: in string := "";
|
|
|
constant filetype: in integer := 0;
|
|
|
constant size: in integer := 0;
|
|
|
variable dataout: out octet_vector) is
|
|
|
file readfile: text;
|
|
|
variable l: line;
|
|
|
variable test: boolean := true;
|
|
|
variable count: integer := 0;
|
|
|
variable dtmp: std_logic_vector(31 downto 0);
|
|
|
variable data: octet_vector(0 to size-1);
|
|
|
variable i: integer := 0;
|
|
|
variable good: boolean := true;
|
|
|
variable c: character;
|
|
|
begin
|
|
|
if size /= 0 then
|
|
|
if filename = "" then
|
|
|
print("no file given");
|
|
|
else
|
|
|
if filetype = 0 then
|
|
|
file_open(readfile, filename, read_mode);
|
|
|
while not endfile(readfile) loop
|
|
|
readline(readfile, l);
|
|
|
hread(l, dtmp, test);
|
|
|
if (not test) then
|
|
|
print("illegal data in file");
|
|
|
exit;
|
|
|
end if;
|
|
|
for i in 0 to 3 loop
|
|
|
data(count) := dtmp(31-i*8 downto 24-i*8);
|
|
|
count := count + 1;
|
|
|
if count >= size then
|
|
|
exit;
|
|
|
end if;
|
|
|
end loop;
|
|
|
if count >= size then
|
|
|
exit;
|
|
|
end if;
|
|
|
end loop;
|
|
|
if count < size then
|
|
|
print("not enough data in file");
|
|
|
else
|
|
|
for i in 0 to size-1 loop
|
|
|
dataout(dataout'low+i) := data(i);
|
|
|
end loop;
|
|
|
end if;
|
|
|
else
|
|
|
file_open(readfile, filename, read_mode);
|
|
|
while not endfile(readfile) loop
|
|
|
readline(readfile, L);
|
|
|
while (i < 4) loop
|
|
|
Read(L, C, good);
|
|
|
if not good then
|
|
|
Print("Error in read data");
|
|
|
exit;
|
|
|
end if;
|
|
|
if (C = character'val(32)) or (C = character'val(160)) or (C = HT) then
|
|
|
next;
|
|
|
else
|
|
|
i := i + 1;
|
|
|
end if;
|
|
|
end loop;
|
|
|
i := 0;
|
|
|
while (i < 32) loop
|
|
|
Read(L, C, good);
|
|
|
if not good then
|
|
|
Print("Error in read data");
|
|
|
exit;
|
|
|
end if;
|
|
|
if (C = character'val(32)) or (C = character'val(160)) or (C = HT) then
|
|
|
next;
|
|
|
else
|
|
|
if (i mod 2) = 0 then
|
|
|
data(count)(7 downto 4) := fromchar(C);
|
|
|
else
|
|
|
data(count)(3 downto 0) := fromchar(C);
|
|
|
-- Print(tost(data(count)));
|
|
|
count := count + 1;
|
|
|
if count >= size then
|
|
|
exit;
|
|
|
end if;
|
|
|
end if;
|
|
|
i := i + 1;
|
|
|
end if;
|
|
|
end loop;
|
|
|
i := 0;
|
|
|
end loop;
|
|
|
if count < size then
|
|
|
Print("Not enough data in file");
|
|
|
else
|
|
|
dataout := data;
|
|
|
end if;
|
|
|
end if;
|
|
|
end if;
|
|
|
else
|
|
|
print("size is zero. no data read");
|
|
|
end if;
|
|
|
end procedure;
|
|
|
|
|
|
procedure readfile(
|
|
|
constant filename: in string := "";
|
|
|
constant size: in integer := 0;
|
|
|
variable dataout: out octet_vector) is
|
|
|
begin
|
|
|
readfile(filename, 0, size, dataout);
|
|
|
end procedure;
|
|
|
|
|
|
procedure readfile(
|
|
|
constant filename: in string := "";
|
|
|
constant size: in integer := 0;
|
|
|
variable dataout: out data_vector) is
|
|
|
file readfile: text;
|
|
|
variable l: line;
|
|
|
variable test: boolean := true;
|
|
|
variable count: integer := 0;
|
|
|
variable data: data_vector(0 to size/4);
|
|
|
begin
|
|
|
if size /= 0 then
|
|
|
if filename = "" then
|
|
|
print("no file given");
|
|
|
else
|
|
|
file_open(readfile, filename, read_mode);
|
|
|
while not endfile(readfile) loop
|
|
|
readline(readfile, l);
|
|
|
hread(l, data(count/4), test);
|
|
|
if (not test) then
|
|
|
print("illegal data in file");
|
|
|
exit;
|
|
|
end if;
|
|
|
count := count + 4;
|
|
|
if count >= size then
|
|
|
exit;
|
|
|
end if;
|
|
|
end loop;
|
|
|
if count < size then
|
|
|
print("not enough data in file");
|
|
|
else
|
|
|
if (size mod 4) = 0 then
|
|
|
dataout(dataout'low to dataout'low+data'high-1) :=
|
|
|
data(0 to data'high-1);
|
|
|
else
|
|
|
dataout(dataout'low to dataout'low+data'high) := data(0 to data'high);
|
|
|
end if;
|
|
|
end if;
|
|
|
end if;
|
|
|
else
|
|
|
print("size is zero. no data read");
|
|
|
end if;
|
|
|
end procedure;
|
|
|
|
|
|
procedure gen_rand_int(
|
|
|
constant max : in real;
|
|
|
variable seed1 : inout positive;
|
|
|
variable seed2 : inout positive;
|
|
|
variable rand : out integer) is
|
|
|
variable rand_tmp : real;
|
|
|
begin
|
|
|
uniform(seed1, seed2, rand_tmp);
|
|
|
rand := integer(floor(rand_tmp*max));
|
|
|
end procedure;
|
|
|
|
|
|
function reverse(din : std_logic_vector)
|
|
|
return std_logic_vector is
|
|
|
variable dout: std_logic_vector(din'REVERSE_RANGE);
|
|
|
begin
|
|
|
for i in din'RANGE loop dout(i) := din(i); end loop;
|
|
|
return dout;
|
|
|
end function reverse;
|
|
|
|
|
|
function ahb_doff (
|
|
|
constant dw : integer;
|
|
|
constant size : integer;
|
|
|
constant addr : std_logic_vector(4 downto 0))
|
|
|
return integer is
|
|
|
variable off : integer;
|
|
|
begin -- ahb_doff
|
|
|
if size < 256 and dw = 256 and addr(4) = '0' then off := 128; else off := 0; end if;
|
|
|
if size < 128 and dw >= 128 and addr(3) = '0' then off := off + 64; end if;
|
|
|
if size < 64 and dw >= 64 and addr(2) = '0' then off := off + 32; end if;
|
|
|
if size < 32 and addr(1) = '0' then off := off + 16; end if;
|
|
|
if size < 16 and addr(0) = '0' then off := off + 8; end if;
|
|
|
return off;
|
|
|
end ahb_doff;
|
|
|
|
|
|
end package body ; --=======================================--
|
|
|
|
|
|
|