-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*-
-- vim: tabstop=2:shiftwidth=2:noexpandtab
-- kate: tab-width 2; replace-tabs off; indent-width 2;
-- =============================================================================
-- Authors: Patrick Lehmann
--
-- Package: VHDL package for component declarations, types and functions
-- associated to the PoC.bus.stream namespace
--
-- Description:
--
-- .. TODO:: No documentation available.
--
-- License:
-- =============================================================================
-- Copyright 2007-2015 Technische Universitaet Dresden - Germany
-- Chair of VLSI-Design, Diagnostics and Architecture
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS of ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-- =============================================================================
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
library PoC;
use PoC.utils.all;
use PoC.vectors.all;
use PoC.strings.all;
package [docs]stream is
-- single dataword for TestRAM
type T_SIM_STREAM_WORD_8 is record
Valid : std_logic;
Data : T_SLV_8;
SOF : std_logic;
EOF : std_logic;
Ready : std_logic;
EOFG : boolean;
end record;
type T_SIM_STREAM_WORD_32 is record
Valid : std_logic;
Data : T_SLV_32;
SOF : std_logic;
EOF : std_logic;
Ready : std_logic;
EOFG : boolean;
end record;
-- define array indices
constant C_SIM_STREAM_MAX_PATTERN_COUNT : positive := 128;-- * 1024; -- max data size per testcase
constant C_SIM_STREAM_MAX_FRAMEGROUP_COUNT : positive := 8;
constant C_SIM_STREAM_WORD_INDEX_BW : positive := log2ceilnz(C_SIM_STREAM_MAX_PATTERN_COUNT);
constant C_SIM_STREAM_FRAMEGROUP_INDEX_BW : positive := log2ceilnz(C_SIM_STREAM_MAX_FRAMEGROUP_COUNT);
subtype T_SIM_STREAM_WORD_INDEX is integer range 0 to C_SIM_STREAM_MAX_PATTERN_COUNT - 1;
subtype T_SIM_STREAM_FRAMEGROUP_INDEX is integer range 0 to C_SIM_STREAM_MAX_FRAMEGROUP_COUNT - 1;
subtype T_SIM_DELAY is T_UINT_16;
type T_SIM_DELAY_VECTOR is array (natural range <>) of T_SIM_DELAY;
-- define array of datawords
type T_SIM_STREAM_WORD_VECTOR_8 is array (natural range <>) of T_SIM_STREAM_WORD_8;
type T_SIM_STREAM_WORD_VECTOR_32 is array (natural range <>) of T_SIM_STREAM_WORD_32;
-- define link layer directions
type T_SIM_STREAM_DIRECTION is (Send, RECEIVE);
-- define framegroup information
type T_SIM_STREAM_FRAMEGROUP_8 is record
Active : boolean;
Name : string(1 to 64);
PrePause : natural;
PostPause : natural;
DataCount : T_SIM_STREAM_WORD_INDEX;
Data : T_SIM_STREAM_WORD_VECTOR_8(0 to C_SIM_STREAM_MAX_PATTERN_COUNT - 1);
end record;
type T_SIM_STREAM_FRAMEGROUP_32 is record
Active : boolean;
Name : string(1 to 64);
PrePause : natural;
PostPause : natural;
DataCount : T_SIM_STREAM_WORD_INDEX;
Data : T_SIM_STREAM_WORD_VECTOR_32(T_SIM_STREAM_WORD_INDEX);
end record;
-- define array of framegroups
type T_SIM_STREAM_FRAMEGROUP_VECTOR_8 is array (natural range <>) of T_SIM_STREAM_FRAMEGROUP_8;
type T_SIM_STREAM_FRAMEGROUP_VECTOR_32 is array (natural range <>) of T_SIM_STREAM_FRAMEGROUP_32;
-- define constants (stored in RAMB36's parity-bits)
constant C_SIM_STREAM_WORD_8_EMPTY : T_SIM_STREAM_WORD_8 := (Valid => '0', Data => (others => 'U'), SOF => '0', EOF => '0', Ready => '0', EOFG => FALSE);
constant C_SIM_STREAM_WORD_32_EMPTY : T_SIM_STREAM_WORD_32 := (Valid => '0', Data => (others => 'U'), SOF => '0', EOF => '0', Ready => '0', EOFG => FALSE);
constant C_SIM_STREAM_WORD_8_INVALID : T_SIM_STREAM_WORD_8 := (Valid => '0', Data => (others => 'U'), SOF => '0', EOF => '0', Ready => '0', EOFG => FALSE);
constant C_SIM_STREAM_WORD_32_INVALID : T_SIM_STREAM_WORD_32 := (Valid => '0', Data => (others => 'U'), SOF => '0', EOF => '0', Ready => '0', EOFG => FALSE);
constant C_SIM_STREAM_WORD_8_ZERO : T_SIM_STREAM_WORD_8 := (Valid => '1', Data => (others => 'Z'), SOF => '0', EOF => '0', Ready => '0', EOFG => FALSE);
constant C_SIM_STREAM_WORD_32_ZERO : T_SIM_STREAM_WORD_32 := (Valid => '1', Data => (others => 'Z'), SOF => '0', EOF => '0', Ready => '0', EOFG => FALSE);
constant C_SIM_STREAM_WORD_8_UNDEF : T_SIM_STREAM_WORD_8 := (Valid => '1', Data => (others => 'U'), SOF => '0', EOF => '0', Ready => '0', EOFG => FALSE);
constant C_SIM_STREAM_WORD_32_UNDEF : T_SIM_STREAM_WORD_32 := (Valid => '1', Data => (others => 'U'), SOF => '0', EOF => '0', Ready => '0', EOFG => FALSE);
constant C_SIM_STREAM_FRAMEGROUP_8_EMPTY : T_SIM_STREAM_FRAMEGROUP_8 := (
Active => FALSE,
Name => (others => C_POC_NUL),
PrePause => 0,
PostPause => 0,
DataCount => 0,
Data => (others => C_SIM_STREAM_WORD_8_EMPTY)
);
constant C_SIM_STREAM_FRAMEGROUP_32_EMPTY : T_SIM_STREAM_FRAMEGROUP_32 := (
Active => FALSE,
Name => (others => C_POC_NUL),
PrePause => 0,
PostPause => 0,
DataCount => 0,
Data => (others => C_SIM_STREAM_WORD_32_EMPTY)
);
function [docs]CountPatterns(Data : T_SIM_STREAM_WORD_VECTOR_8) return natural;
function [docs]CountPatterns(Data : T_SIM_STREAM_WORD_VECTOR_32) return natural;
function [docs]dat(slv : T_SLV_8) return T_SIM_STREAM_WORD_8;
function [docs]dat(slvv : T_SLVV_8) return T_SIM_STREAM_WORD_VECTOR_8;
function [docs]dat(slv : T_SLV_32) return T_SIM_STREAM_WORD_32;
function [docs]dat(slvv : T_SLVV_32) return T_SIM_STREAM_WORD_VECTOR_32;
function [docs]sof(slv : T_SLV_8) return T_SIM_STREAM_WORD_8;
function [docs]sof(slvv : T_SLVV_8) return T_SIM_STREAM_WORD_VECTOR_8;
function [docs]sof(slv : T_SLV_32) return T_SIM_STREAM_WORD_32;
function [docs]sof(slvv : T_SLVV_32) return T_SIM_STREAM_WORD_VECTOR_32;
function [docs]eof(slv : T_SLV_8) return T_SIM_STREAM_WORD_8;
function [docs]eof(slvv : T_SLVV_8) return T_SIM_STREAM_WORD_VECTOR_8;
function [docs]eof(slv : T_SLV_32) return T_SIM_STREAM_WORD_32;
function [docs]eof(slvv : T_SLVV_32) return T_SIM_STREAM_WORD_VECTOR_32;
function [docs]eof(stmw : T_SIM_STREAM_WORD_8) return T_SIM_STREAM_WORD_8;
function [docs]eof(stmwv : T_SIM_STREAM_WORD_VECTOR_8) return T_SIM_STREAM_WORD_VECTOR_8;
function [docs]eof(stmw : T_SIM_STREAM_WORD_32) return T_SIM_STREAM_WORD_32;
function [docs]eofg(stmw : T_SIM_STREAM_WORD_8) return T_SIM_STREAM_WORD_8;
function [docs]eofg(stmwv : T_SIM_STREAM_WORD_VECTOR_8) return T_SIM_STREAM_WORD_VECTOR_8;
function [docs]eofg(stmw : T_SIM_STREAM_WORD_32) return T_SIM_STREAM_WORD_32;
function [docs]to_string(stmw : T_SIM_STREAM_WORD_8) return string;
function [docs]to_string(stmw : T_SIM_STREAM_WORD_32) return string;
-- checksum functions
-- ================================================================
function [docs]sim_CRC8(words : T_SIM_STREAM_WORD_VECTOR_8) return std_logic_vector;
-- function sim_CRC16(words : T_SIM_STREAM_WORD_VECTOR_8) return STD_LOGIC_VECTOR;
end;
package body stream is
function CountPatterns(Data : T_SIM_STREAM_WORD_VECTOR_8) return natural is
begin
for i in 0 to Data'length - 1 loop
if (Data(i).EOFG = TRUE) then
return i + 1;
end if;
end loop;
return 0;
end;
function CountPatterns(Data : T_SIM_STREAM_WORD_VECTOR_32) return natural is
begin
for i in 0 to Data'length - 1 loop
if (Data(i).EOFG = TRUE) then
return i + 1;
end if;
end loop;
return 0;
end;
function dat(slv : T_SLV_8) return T_SIM_STREAM_WORD_8 is
variable result : T_SIM_STREAM_WORD_8;
begin
result := (Valid => '1', Data => slv, SOF => '0', EOF => '0', Ready => '-', EOFG => FALSE);
report "dat: " & to_string(result) severity NOTE;
return result;
end;
function dat(slvv : T_SLVV_8) return T_SIM_STREAM_WORD_VECTOR_8 is
variable result : T_SIM_STREAM_WORD_VECTOR_8(slvv'range);
begin
for i in slvv'range loop
result(i) := dat(slvv(i));
end loop;
return result;
end;
function dat(slv : T_SLV_32) return T_SIM_STREAM_WORD_32 is
variable result : T_SIM_STREAM_WORD_32;
begin
result := (Valid => '1', Data => slv, SOF => '0', EOF => '0', Ready => '-', EOFG => FALSE);
report "dat: " & to_string(result) severity NOTE;
return result;
end;
function dat(slvv : T_SLVV_32) return T_SIM_STREAM_WORD_VECTOR_32 is
variable result : T_SIM_STREAM_WORD_VECTOR_32(slvv'range);
begin
for i in slvv'range loop
result(i) := dat(slvv(i));
end loop;
return result;
end;
function sof(slv : T_SLV_8) return T_SIM_STREAM_WORD_8 is
variable result : T_SIM_STREAM_WORD_8;
begin
result := (Valid => '1', Data => slv, SOF => '1', EOF => '0', Ready => '-', EOFG => FALSE);
report "sof: " & to_string(result) severity NOTE;
return result;
end;
function sof(slvv : T_SLVV_8) return T_SIM_STREAM_WORD_VECTOR_8 is
variable result : T_SIM_STREAM_WORD_VECTOR_8(slvv'range);
begin
result(slvv'low) := sof(slvv(slvv'low));
for i in slvv'low + 1 to slvv'high loop
result(i) := dat(slvv(i));
end loop;
return result;
end;
function sof(slv : T_SLV_32) return T_SIM_STREAM_WORD_32 is
variable result : T_SIM_STREAM_WORD_32;
begin
result := (Valid => '1', Data => slv, SOF => '1', EOF => '0', Ready => '-', EOFG => FALSE);
report "sof: " & to_string(result) severity NOTE;
return result;
end;
function sof(slvv : T_SLVV_32) return T_SIM_STREAM_WORD_VECTOR_32 is
variable result : T_SIM_STREAM_WORD_VECTOR_32(slvv'range);
begin
result(slvv'low) := sof(slvv(slvv'low));
for i in slvv'low + 1 to slvv'high loop
result(i) := dat(slvv(i));
end loop;
return result;
end;
function eof(slv : T_SLV_8) return T_SIM_STREAM_WORD_8 is
variable result : T_SIM_STREAM_WORD_8;
begin
result := (Valid => '1', Data => slv, SOF => '0', EOF => '1', Ready => '-', EOFG => FALSE);
report "eof: " & to_string(result) severity NOTE;
return result;
end;
function eof(slvv : T_SLVV_8) return T_SIM_STREAM_WORD_VECTOR_8 is
variable result : T_SIM_STREAM_WORD_VECTOR_8(slvv'range);
begin
for i in slvv'low to slvv'high - 1 loop
result(i) := dat(slvv(i));
end loop;
result(slvv'high) := eof(slvv(slvv'high));
return result;
end;
function eof(slv : T_SLV_32) return T_SIM_STREAM_WORD_32 is
variable result : T_SIM_STREAM_WORD_32;
begin
result := (Valid => '1', Data => slv, SOF => '0', EOF => '1', Ready => '-', EOFG => FALSE);
report "eof: " & to_string(result) severity NOTE;
return result;
end;
function eof(slvv : T_SLVV_32) return T_SIM_STREAM_WORD_VECTOR_32 is
variable result : T_SIM_STREAM_WORD_VECTOR_32(slvv'range);
begin
for i in slvv'low to slvv'high - 1 loop
result(i) := dat(slvv(i));
end loop;
result(slvv'high) := eof(slvv(slvv'high));
return result;
end;
function eof(stmw : T_SIM_STREAM_WORD_8) return T_SIM_STREAM_WORD_8 is
begin
return T_SIM_STREAM_WORD_8'(
Valid => stmw.Valid,
Data => stmw.Data,
SOF => stmw.SOF,
EOF => '1',
Ready => '-',
EOFG => stmw.EOFG);
end function;
function eof(stmw : T_SIM_STREAM_WORD_32) return T_SIM_STREAM_WORD_32 is
begin
return T_SIM_STREAM_WORD_32'(
Valid => stmw.Valid,
Data => stmw.Data,
SOF => stmw.SOF,
EOF => '1',
Ready => '-',
EOFG => stmw.EOFG);
end function;
function eof(stmwv : T_SIM_STREAM_WORD_VECTOR_8) return T_SIM_STREAM_WORD_VECTOR_8 is
variable result : T_SIM_STREAM_WORD_VECTOR_8(stmwv'range);
begin
for i in stmwv'low to stmwv'high - 1 loop
result(i) := stmwv(i);
end loop;
result(stmwv'high) := eof(stmwv(stmwv'high));
return result;
end;
function eofg(stmw : T_SIM_STREAM_WORD_8) return T_SIM_STREAM_WORD_8 is
begin
return T_SIM_STREAM_WORD_8'(
Valid => stmw.Valid,
Data => stmw.Data,
SOF => stmw.SOF,
EOF => stmw.EOF,
Ready => stmw.Ready,
EOFG => TRUE);
end function;
function eofg(stmw : T_SIM_STREAM_WORD_32) return T_SIM_STREAM_WORD_32 is
begin
return T_SIM_STREAM_WORD_32'(
Valid => stmw.Valid,
Data => stmw.Data,
SOF => stmw.SOF,
EOF => stmw.EOF,
Ready => stmw.Ready,
EOFG => TRUE);
end function;
function eofg(stmwv : T_SIM_STREAM_WORD_VECTOR_8) return T_SIM_STREAM_WORD_VECTOR_8 is
variable result : T_SIM_STREAM_WORD_VECTOR_8(stmwv'range);
begin
for i in stmwv'low to stmwv'high - 1 loop
result(i) := stmwv(i);
end loop;
result(stmwv'high) := eofg(stmwv(stmwv'high));
return result;
end;
function to_flag1_string(stmw : T_SIM_STREAM_WORD_8) return string is
variable flag : std_logic_vector(2 downto 0) := to_sl(stmw.EOFG) & stmw.EOF & stmw.SOF;
begin
case flag is
when "000" => return "";
when "001" => return "SOF";
when "010" => return "EOF";
when "011" => return "SOF+EOF";
when "100" => return "*";
when "101" => return "SOF*";
when "110" => return "EOF*";
when "111" => return "SOF+EOF*";
when others => return "ERROR";
end case;
end function;
function to_flag1_string(stmw : T_SIM_STREAM_WORD_32) return string is
variable flag : std_logic_vector(2 downto 0) := to_sl(stmw.EOFG) & stmw.EOF & stmw.SOF;
begin
case flag is
when "000" => return "";
when "001" => return "SOF";
when "010" => return "EOF";
when "011" => return "SOF+EOF";
when "100" => return "*";
when "101" => return "SOF*";
when "110" => return "EOF*";
when "111" => return "SOF+EOF*";
when others => return "ERROR";
end case;
end function;
function to_flag2_string(stmw : T_SIM_STREAM_WORD_8) return string is
variable flag : std_logic_vector(1 downto 0) := stmw.Ready & stmw.Valid;
begin
case flag is
when "00" => return " ";
when "01" => return " V";
when "10" => return "R ";
when "11" => return "RV";
when "-0" => return "- ";
when "-1" => return "-V";
when others => return "??";
end case;
end function;
function to_flag2_string(stmw : T_SIM_STREAM_WORD_32) return string is
variable flag : std_logic_vector(1 downto 0) := stmw.Ready & stmw.Valid;
begin
case flag is
when "00" => return " ";
when "01" => return " V";
when "10" => return "R ";
when "11" => return "RV";
when "-0" => return "- ";
when "-1" => return "-V";
when others => return "??";
end case;
end function;
function to_string(stmw : T_SIM_STREAM_WORD_8) return string is
begin
return to_flag2_string(stmw) & " 0x" & to_string(stmw.Data, 'h') & " " & to_flag1_string(stmw);
end function;
function to_string(stmw : T_SIM_STREAM_WORD_32) return string is
begin
return to_flag2_string(stmw) & " 0x" & to_string(stmw.Data, 'h') & " " & to_flag1_string(stmw);
end function;
-- checksum functions
-- ================================================================
-- -- Private function to_01 copied from GlobalTypes
-- function to_01(slv : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
-- begin
-- return to_stdlogicvector(to_bitvector(slv));
-- end;
function sim_CRC8(words : T_SIM_STREAM_WORD_VECTOR_8) return std_logic_vector is
constant CRC8_INIT : T_SLV_8 := x"FF";
constant CRC8_POLYNOMIAL : T_SLV_8 := x"31"; -- 0x131
variable CRC8_Value : T_SLV_8 := CRC8_INIT;
-- variable Pattern : T_DATAFifO_PATTERN;
variable Word : unsigned(T_SLV_8'range);
begin
report "Computing CRC8 for Words " & to_string(words'low) & " to " & to_string(words'high) severity NOTE;
for i in words'range loop
if (words(i).Valid = '1') then
Word := to_01(unsigned(words(i).Data));
-- assert (J > 9) report str_merge(" Word: 0x", hstr(Word), " CRC16_Value: 0x", hstr(CRC16_Value)) severity NOTE;
for j in Word'range loop
CRC8_Value := (CRC8_Value(CRC8_Value'high - 1 downto 0) & '0') xor (CRC8_POLYNOMIAL and (CRC8_POLYNOMIAL'range => (Word(j) xor CRC8_Value(CRC8_Value'high))));
end loop;
end if;
exit when (words(i).EOFG = TRUE);
end loop;
report " CRC8: 0x" & to_string(CRC8_Value, 'h') severity NOTE;
return CRC8_Value;
end;
-- function sim_CRC16(words : T_SIM_STREAM_WORD_VECTOR_8) return STD_LOGIC_VECTOR is
-- constant CRC16_INIT : T_SLV_16 := x"FFFF";
-- constant CRC16_POLYNOMIAL : T_SLV_16 := x"8005"; -- 0x18005
--
-- variable CRC16_Value : T_SLV_16 := CRC16_INIT;
--
-- variable Pattern : T_DATAFifO_PATTERN;
-- variable Word : T_SLV_32;
-- begin
-- report str_merge("Computing CRC16 for Frames ", str(Frames'low), " to ", str(Frames'high)) severity NOTE;
--
-- for i in Frames'range loop
-- NEXT when (NOT ((Frames(i).Direction = DEV_HOST) AND (Frames(i).DataFifOPatterns(0).Data(7 downto 0) = x"46")));
--
---- report Frames(i).Name severity NOTE;
--
-- for j in 1 to Frames(i).Count - 1 loop
-- Pattern := Frames(i).DataFifOPatterns(J);
--
-- if (Pattern.Valid = '1') then
-- Word := to_01(Pattern.Data);
--
---- assert (J > 9) report str_merge(" Word: 0x", hstr(Word), " CRC16_Value: 0x", hstr(CRC16_Value)) severity NOTE;
--
-- for k in Word'range loop
-- CRC16_Value := (CRC16_Value(CRC16_Value'high - 1 downto 0) & '0') XOR (CRC16_POLYNOMIAL AND (CRC16_POLYNOMIAL'range => (Word(K) XOR CRC16_Value(CRC16_Value'high))));
-- end loop;
-- end if;
--
-- EXIT when (Pattern.EOTP = TRUE);
-- end loop;
-- end loop;
--
-- report str_merge(" CRC16: 0x", hstr(CRC16_Value)) severity NOTE;
--
-- return CRC16_Value;
-- end;
end package body;