-- 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: Thomas B. Preusser
-- Martin Zabel
-- Patrick Lehmann
--
-- Package: Common functions and types
--
-- Description:
--
-- For detailed documentation see below.
--
-- License:
-- =============================================================================
-- Copyright 2007-2016 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.strings.all;
package [docs]vectors is
-- ==========================================================================
-- Type declarations
-- ==========================================================================
-- STD_LOGIC_VECTORs
subtype T_SLV_2 is std_logic_vector(1 downto 0);
subtype T_SLV_3 is std_logic_vector(2 downto 0);
subtype T_SLV_4 is std_logic_vector(3 downto 0);
subtype T_SLV_8 is std_logic_vector(7 downto 0);
subtype T_SLV_12 is std_logic_vector(11 downto 0);
subtype T_SLV_16 is std_logic_vector(15 downto 0);
subtype T_SLV_24 is std_logic_vector(23 downto 0);
subtype T_SLV_32 is std_logic_vector(31 downto 0);
subtype T_SLV_48 is std_logic_vector(47 downto 0);
subtype T_SLV_64 is std_logic_vector(63 downto 0);
subtype T_SLV_96 is std_logic_vector(95 downto 0);
subtype T_SLV_128 is std_logic_vector(127 downto 0);
subtype T_SLV_256 is std_logic_vector(255 downto 0);
subtype T_SLV_512 is std_logic_vector(511 downto 0);
-- STD_LOGIC_VECTOR_VECTORs
-- type T_SLVV is array(NATURAL range <>) of STD_LOGIC_VECTOR; -- VHDL 2008 syntax - not yet supported by Xilinx
type T_SLVV_2 is array(natural range <>) of T_SLV_2;
type T_SLVV_3 is array(natural range <>) of T_SLV_3;
type T_SLVV_4 is array(natural range <>) of T_SLV_4;
type T_SLVV_8 is array(natural range <>) of T_SLV_8;
type T_SLVV_12 is array(natural range <>) of T_SLV_12;
type T_SLVV_16 is array(natural range <>) of T_SLV_16;
type T_SLVV_24 is array(natural range <>) of T_SLV_24;
type T_SLVV_32 is array(natural range <>) of T_SLV_32;
type T_SLVV_48 is array(natural range <>) of T_SLV_48;
type T_SLVV_64 is array(natural range <>) of T_SLV_64;
type T_SLVV_128 is array(natural range <>) of T_SLV_128;
type T_SLVV_256 is array(natural range <>) of T_SLV_256;
type T_SLVV_512 is array(natural range <>) of T_SLV_512;
-- STD_LOGIC_MATRIXs
type T_SLM is array(natural range <>, natural range <>) of std_logic;
-- ATTENTION:
-- 1. you MUST initialize your matrix signal with 'Z' to get correct simulation results (iSIM, vSIM, ghdl/gtkwave)
-- Example: signal myMatrix : T_SLM(3 downto 0, 7 downto 0) := (others => (others => 'Z'));
-- 2. Xilinx iSIM bug: DON'T use myMatrix'range(n) for n >= 2
-- myMatrix'range(2) returns always myMatrix'range(1); see work-around notes below
--
-- USAGE NOTES:
-- dimension 1 => rows - e.g. Words
-- dimension 2 => columns - e.g. Bits/Bytes in a word
--
-- WORKAROUND: for Xilinx ISE/iSim
-- Version: 14.2
-- Issue: myMatrix'range(n) for n >= 2 returns always myMatrix'range(1)
-- ==========================================================================
-- Function declarations
-- ==========================================================================
-- slicing boundary calulations
function [docs]low (lenvec : T_POSVEC; index : natural) return natural;
function [docs]high(lenvec : T_POSVEC; index : natural) return natural;
-- Assign procedures: assign_*
procedure [docs]assign_row(signal slm : out T_SLM; slv : std_logic_vector; constant RowIndex : natural); -- assign vector to complete row
procedure [docs]assign_row(signal slm : out T_SLM; slv : std_logic_vector; constant RowIndex : natural; Position : natural); -- assign short vector to row starting at position
procedure [docs]assign_row(signal slm : out T_SLM; slv : std_logic_vector; constant RowIndex : natural; High : natural; Low : natural); -- assign short vector to row in range high:low
procedure [docs]assign_col(signal slm : out T_SLM; slv : std_logic_vector; constant ColIndex : natural); -- assign vector to complete column
-- ATTENTION: see T_SLM definition for further details and work-arounds
-- Matrix to matrix conversion: slm_slice*
function [docs]slm_slice(slm : T_SLM; RowIndex : natural; ColIndex : natural; Height : natural; Width : natural) return T_SLM; -- get submatrix in boundingbox RowIndex,ColIndex,Height,Width
function [docs]slm_slice_rows(slm : T_SLM; High : natural; Low : natural) return T_SLM; -- get submatrix / all rows in RowIndex range high:low
function [docs]slm_slice_cols(slm : T_SLM; High : natural; Low : natural) return T_SLM; -- get submatrix / all columns in ColIndex range high:low
-- Boolean Operators
function [docs]"not" (a : t_slm) return t_slm;
function [docs]"and" (a, b : t_slm) return t_slm;
function [docs]"or" (a, b : t_slm) return t_slm;
function [docs]"xor" (a, b : t_slm) return t_slm;
function [docs]"nand"(a, b : t_slm) return t_slm;
function [docs]"nor" (a, b : t_slm) return t_slm;
function [docs]"xnor"(a, b : t_slm) return t_slm;
-- Matrix concatenation: slm_merge_*
function [docs]slm_merge_rows(slm1 : T_SLM; slm2 : T_SLM) return T_SLM;
function [docs]slm_merge_cols(slm1 : T_SLM; slm2 : T_SLM) return T_SLM;
-- Matrix to vector conversion: get_*
function [docs]get_col(slm : T_SLM; ColIndex : natural) return std_logic_vector; -- get a matrix column
function [docs]get_row(slm : T_SLM; RowIndex : natural) return std_logic_vector; -- get a matrix row
function [docs]get_row(slm : T_SLM; RowIndex : natural; Length : positive) return std_logic_vector; -- get a matrix row of defined length [length - 1 downto 0]
function [docs]get_row(slm : T_SLM; RowIndex : natural; High : natural; Low : natural) return std_logic_vector; -- get a sub vector of a matrix row at high:low
-- Convert to vector: to_slv
function [docs]to_slv(slvv : T_SLVV_2) return std_logic_vector; -- convert vector-vector to flatten vector
function [docs]to_slv(slvv : T_SLVV_4) return std_logic_vector; -- ...
function [docs]to_slv(slvv : T_SLVV_8) return std_logic_vector; -- ...
function [docs]to_slv(slvv : T_SLVV_12) return std_logic_vector; -- ...
function [docs]to_slv(slvv : T_SLVV_16) return std_logic_vector; -- ...
function [docs]to_slv(slvv : T_SLVV_24) return std_logic_vector; -- ...
function [docs]to_slv(slvv : T_SLVV_32) return std_logic_vector; -- ...
function [docs]to_slv(slvv : T_SLVV_64) return std_logic_vector; -- ...
function [docs]to_slv(slvv : T_SLVV_128) return std_logic_vector; -- ...
function [docs]to_slv(slm : T_SLM) return std_logic_vector; -- convert matrix to flatten vector
-- Convert flat vector to avector-vector: to_slvv_*
function [docs]to_slvv_4(slv : std_logic_vector) return T_SLVV_4; --
function [docs]to_slvv_8(slv : std_logic_vector) return T_SLVV_8; --
function [docs]to_slvv_12(slv : std_logic_vector) return T_SLVV_12; --
function [docs]to_slvv_16(slv : std_logic_vector) return T_SLVV_16; --
function [docs]to_slvv_32(slv : std_logic_vector) return T_SLVV_32; --
function [docs]to_slvv_64(slv : std_logic_vector) return T_SLVV_64; --
function [docs]to_slvv_128(slv : std_logic_vector) return T_SLVV_128; --
function [docs]to_slvv_256(slv : std_logic_vector) return T_SLVV_256; --
function [docs]to_slvv_512(slv : std_logic_vector) return T_SLVV_512; --
-- Convert matrix to avector-vector: to_slvv_*
function [docs]to_slvv_4(slm : T_SLM) return T_SLVV_4; --
function [docs]to_slvv_8(slm : T_SLM) return T_SLVV_8; --
function [docs]to_slvv_12(slm : T_SLM) return T_SLVV_12; --
function [docs]to_slvv_16(slm : T_SLM) return T_SLVV_16; --
function [docs]to_slvv_32(slm : T_SLM) return T_SLVV_32; --
function [docs]to_slvv_64(slm : T_SLM) return T_SLVV_64; --
function [docs]to_slvv_128(slm : T_SLM) return T_SLVV_128; --
function [docs]to_slvv_256(slm : T_SLM) return T_SLVV_256; --
function [docs]to_slvv_512(slm : T_SLM) return T_SLVV_512; --
-- Convert vector-vector to matrix: to_slm
function [docs]to_slm(slv : std_logic_vector; ROWS : positive; COLS : positive) return T_SLM; -- create matrix from vector
function [docs]to_slm(slvv : T_SLVV_4) return T_SLM; -- create matrix from vector-vector
function [docs]to_slm(slvv : T_SLVV_8) return T_SLM; -- create matrix from vector-vector
function [docs]to_slm(slvv : T_SLVV_12) return T_SLM; -- create matrix from vector-vector
function [docs]to_slm(slvv : T_SLVV_16) return T_SLM; -- create matrix from vector-vector
function [docs]to_slm(slvv : T_SLVV_32) return T_SLM; -- create matrix from vector-vector
function [docs]to_slm(slvv : T_SLVV_48) return T_SLM; -- create matrix from vector-vector
function [docs]to_slm(slvv : T_SLVV_64) return T_SLM; -- create matrix from vector-vector
function [docs]to_slm(slvv : T_SLVV_128) return T_SLM; -- create matrix from vector-vector
function [docs]to_slm(slvv : T_SLVV_256) return T_SLM; -- create matrix from vector-vector
function [docs]to_slm(slvv : T_SLVV_512) return T_SLM; -- create matrix from vector-vector
-- Change vector direction
function [docs]dir(slvv : T_SLVV_8) return T_SLVV_8;
-- Reverse vector elements
function [docs]rev(slvv : T_SLVV_4) return T_SLVV_4;
function [docs]rev(slvv : T_SLVV_8) return T_SLVV_8;
function [docs]rev(slvv : T_SLVV_12) return T_SLVV_12;
function [docs]rev(slvv : T_SLVV_16) return T_SLVV_16;
function [docs]rev(slvv : T_SLVV_32) return T_SLVV_32;
function [docs]rev(slvv : T_SLVV_64) return T_SLVV_64;
function [docs]rev(slvv : T_SLVV_128) return T_SLVV_128;
function [docs]rev(slvv : T_SLVV_256) return T_SLVV_256;
function [docs]rev(slvv : T_SLVV_512) return T_SLVV_512;
-- TODO:
function [docs]resize(slm : T_SLM; size : positive) return T_SLM;
-- to_string
function [docs]to_string(slvv : T_SLVV_8; sep : character := ':') return string;
function [docs]to_string(slm : T_SLM; groups : positive := 4; format : character := 'b') return string;
end package vectors;
package body vectors is
-- slicing boundary calulations
-- ==========================================================================
function low(lenvec : T_POSVEC; index : natural) return natural is
variable pos : natural := 0;
begin
for i in lenvec'low to index - 1 loop
pos := pos + lenvec(i);
end loop;
return pos;
end function;
function high(lenvec : T_POSVEC; index : natural) return natural is
variable pos : natural := 0;
begin
for i in lenvec'low to index loop
pos := pos + lenvec(i);
end loop;
return pos - 1;
end function;
-- Assign procedures: assign_*
-- ==========================================================================
procedure assign_row(signal slm : out T_SLM; slv : std_logic_vector; constant RowIndex : natural) is
variable temp : std_logic_vector(slm'high(2) downto slm'low(2)); -- WORKAROUND: Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); see work-around notes at T_SLM type declaration
begin
temp := slv;
for i in temp'range loop
slm(RowIndex, i) <= temp(i);
end loop;
end procedure;
procedure assign_row(signal slm : out T_SLM; slv : std_logic_vector; constant RowIndex : natural; Position : natural) is
variable temp : std_logic_vector(Position + slv'length - 1 downto Position);
begin
temp := slv;
for i in temp'range loop
slm(RowIndex, i) <= temp(i);
end loop;
end procedure;
procedure assign_row(signal slm : out T_SLM; slv : std_logic_vector; constant RowIndex : natural; High : natural; Low : natural) is
variable temp : std_logic_vector(High downto Low);
begin
temp := slv;
for i in temp'range loop
slm(RowIndex, i) <= temp(i);
end loop;
end procedure;
procedure assign_col(signal slm : out T_SLM; slv : std_logic_vector; constant ColIndex : natural) is
variable temp : std_logic_vector(slm'range(1));
begin
temp := slv;
for i in temp'range loop
slm(i, ColIndex) <= temp(i);
end loop;
end procedure;
-- Matrix to matrix conversion: slm_slice*
-- ==========================================================================
function slm_slice(slm : T_SLM; RowIndex : natural; ColIndex : natural; Height : natural; Width : natural) return T_SLM is
variable Result : T_SLM(Height - 1 downto 0, Width - 1 downto 0) := (others => (others => '0'));
begin
for i in 0 to Height - 1 loop
for j in 0 to Width - 1 loop
Result(i, j) := slm(RowIndex + i, ColIndex + j);
end loop;
end loop;
return Result;
end function;
function slm_slice_rows(slm : T_SLM; High : natural; Low : natural) return T_SLM is
variable Result : T_SLM(High - Low downto 0, slm'length(2) - 1 downto 0) := (others => (others => '0'));
begin
for i in 0 to High - Low loop
for j in 0 to slm'length(2) - 1 loop
Result(i, j) := slm(Low + i, slm'low(2) + j);
end loop;
end loop;
return Result;
end function;
function slm_slice_cols(slm : T_SLM; High : natural; Low : natural) return T_SLM is
variable Result : T_SLM(slm'length(1) - 1 downto 0, High - Low downto 0) := (others => (others => '0'));
begin
for i in 0 to slm'length(1) - 1 loop
for j in 0 to High - Low loop
Result(i, j) := slm(slm'low(1) + i, Low + j);
end loop;
end loop;
return Result;
end function;
-- Boolean Operators
function "not"(a : t_slm) return t_slm is
variable res : t_slm(a'range(1), a'range(2));
begin
for i in res'range(1) loop
for j in res'range(2) loop
res(i, j) := not a(i, j);
end loop;
end loop;
return res;
end function;
function "and"(a, b : t_slm) return t_slm is
variable bb, res : t_slm(a'range(1), a'range(2));
begin
bb := b;
for i in res'range(1) loop
for j in res'range(2) loop
res(i, j) := a(i, j) and bb(i, j);
end loop;
end loop;
return res;
end function;
function "or"(a, b : t_slm) return t_slm is
variable bb, res : t_slm(a'range(1), a'range(2));
begin
bb := b;
for i in res'range(1) loop
for j in res'range(2) loop
res(i, j) := a(i, j) or bb(i, j);
end loop;
end loop;
return res;
end function;
function "xor"(a, b : t_slm) return t_slm is
variable bb, res : t_slm(a'range(1), a'range(2));
begin
bb := b;
for i in res'range(1) loop
for j in res'range(2) loop
res(i, j) := a(i, j) xor bb(i, j);
end loop;
end loop;
return res;
end function;
function "nand"(a, b : t_slm) return t_slm is
begin
return not(a and b);
end function;
function "nor"(a, b : t_slm) return t_slm is
begin
return not(a or b);
end function;
function "xnor"(a, b : t_slm) return t_slm is
begin
return not(a xor b);
end function;
-- Matrix concatenation: slm_merge_*
function slm_merge_rows(slm1 : T_SLM; slm2 : T_SLM) return T_SLM is
constant ROWS : positive := slm1'length(1) + slm2'length(1);
constant COLUMNS : positive := slm1'length(2);
variable slm : T_SLM(ROWS - 1 downto 0, COLUMNS - 1 downto 0);
begin
for i in slm1'range(1) loop
for j in slm1'low(2) to slm1'high(2) loop -- WORKAROUND: Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); see work-around notes at T_SLM type declaration
slm(i, j) := slm1(i, j);
end loop;
end loop;
for i in slm2'range(1) loop
for j in slm2'low(2) to slm2'high(2) loop -- WORKAROUND: Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); see work-around notes at T_SLM type declaration
slm(slm1'length(1) + i, j) := slm2(i, j);
end loop;
end loop;
return slm;
end function;
function slm_merge_cols(slm1 : T_SLM; slm2 : T_SLM) return T_SLM is
constant ROWS : positive := slm1'length(1);
constant COLUMNS : positive := slm1'length(2) + slm2'length(2);
variable slm : T_SLM(ROWS - 1 downto 0, COLUMNS - 1 downto 0);
begin
for i in slm1'range(1) loop
for j in slm1'low(2) to slm1'high(2) loop -- WORKAROUND: Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); see work-around notes at T_SLM type declaration
slm(i, j) := slm1(i, j);
end loop;
for j in slm2'low(2) to slm2'high(2) loop -- WORKAROUND: Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); see work-around notes at T_SLM type declaration
slm(i, slm1'length(2) + j) := slm2(i, j);
end loop;
end loop;
return slm;
end function;
-- Matrix to vector conversion: get_*
-- ==========================================================================
-- get a matrix column
function get_col(slm : T_SLM; ColIndex : natural) return std_logic_vector is
variable slv : std_logic_vector(slm'range(1));
begin
for i in slm'range(1) loop
slv(i) := slm(i, ColIndex);
end loop;
return slv;
end function;
-- get a matrix row
function get_row(slm : T_SLM; RowIndex : natural) return std_logic_vector is
variable slv : std_logic_vector(slm'high(2) downto slm'low(2)); -- WORKAROUND: Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); see work-around notes at T_SLM type declaration
begin
for i in slv'range loop
slv(i) := slm(RowIndex, i);
end loop;
return slv;
end function;
-- get a matrix row of defined length [length - 1 downto 0]
function get_row(slm : T_SLM; RowIndex : natural; Length : positive) return std_logic_vector is
begin
return get_row(slm, RowIndex, (Length - 1), 0);
end function;
-- get a sub vector of a matrix row at high:low
function get_row(slm : T_SLM; RowIndex : natural; High : natural; Low : natural) return std_logic_vector is
variable slv : std_logic_vector(High downto Low);
begin
for i in slv'range loop
slv(i) := slm(RowIndex, i);
end loop;
return slv;
end function;
-- Convert to vector: to_slv
-- ==========================================================================
-- convert vector-vector to flatten vector
function to_slv(slvv : T_SLVV_2) return std_logic_vector is
variable slv : std_logic_vector((slvv'length * 2) - 1 downto 0);
begin
for i in slvv'range loop
slv((i * 2) + 1 downto (i * 2)) := slvv(i);
end loop;
return slv;
end function;
function to_slv(slvv : T_SLVV_4) return std_logic_vector is
variable slv : std_logic_vector((slvv'length * 4) - 1 downto 0);
begin
for i in slvv'range loop
slv((i * 4) + 3 downto (i * 4)) := slvv(i);
end loop;
return slv;
end function;
function to_slv(slvv : T_SLVV_8) return std_logic_vector is
variable slv : std_logic_vector((slvv'length * 8) - 1 downto 0);
begin
for i in slvv'range loop
slv((i * 8) + 7 downto (i * 8)) := slvv(i);
end loop;
return slv;
end function;
function to_slv(slvv : T_SLVV_12) return std_logic_vector is
variable slv : std_logic_vector((slvv'length * 12) - 1 downto 0);
begin
for i in slvv'range loop
slv((i * 12) + 11 downto (i * 12)) := slvv(i);
end loop;
return slv;
end function;
function to_slv(slvv : T_SLVV_16) return std_logic_vector is
variable slv : std_logic_vector((slvv'length * 16) - 1 downto 0);
begin
for i in slvv'range loop
slv((i * 16) + 15 downto (i * 16)) := slvv(i);
end loop;
return slv;
end function;
function to_slv(slvv : T_SLVV_24) return std_logic_vector is
variable slv : std_logic_vector((slvv'length * 24) - 1 downto 0);
begin
for i in slvv'range loop
slv((i * 24) + 23 downto (i * 24)) := slvv(i);
end loop;
return slv;
end function;
function to_slv(slvv : T_SLVV_32) return std_logic_vector is
variable slv : std_logic_vector((slvv'length * 32) - 1 downto 0);
begin
for i in slvv'range loop
slv((i * 32) + 31 downto (i * 32)) := slvv(i);
end loop;
return slv;
end function;
function to_slv(slvv : T_SLVV_64) return std_logic_vector is
variable slv : std_logic_vector((slvv'length * 64) - 1 downto 0);
begin
for i in slvv'range loop
slv((i * 64) + 63 downto (i * 64)) := slvv(i);
end loop;
return slv;
end function;
function to_slv(slvv : T_SLVV_128) return std_logic_vector is
variable slv : std_logic_vector((slvv'length * 128) - 1 downto 0);
begin
for i in slvv'range loop
slv((i * 128) + 127 downto (i * 128)) := slvv(i);
end loop;
return slv;
end function;
-- convert matrix to flatten vector
function to_slv(slm : T_SLM) return std_logic_vector is
variable slv : std_logic_vector((slm'length(1) * slm'length(2)) - 1 downto 0);
begin
for i in slm'range(1) loop
for j in slm'high(2) downto slm'low(2) loop -- WORKAROUND: Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); see work-around notes at T_SLM type declaration
slv((i * slm'length(2)) + j) := slm(i, j);
end loop;
end loop;
return slv;
end function;
-- Convert flat vector to a vector-vector: to_slvv_*
-- ==========================================================================
-- create vector-vector from vector (4 bit)
function to_slvv_4(slv : std_logic_vector) return T_SLVV_4 is
variable Result : T_SLVV_4((slv'length / 4) - 1 downto 0);
begin
if ((slv'length mod 4) /= 0) then report "to_slvv_4: width mismatch - slv'length is no multiple of 4 (slv'length=" & INTEGER'image(slv'length) & ")" severity FAILURE; end if;
for i in Result'range loop
Result(i) := slv((i * 4) + 3 downto (i * 4));
end loop;
return Result;
end function;
-- create vector-vector from vector (8 bit)
function to_slvv_8(slv : std_logic_vector) return T_SLVV_8 is
variable Result : T_SLVV_8((slv'length / 8) - 1 downto 0);
begin
if ((slv'length mod 8) /= 0) then report "to_slvv_8: width mismatch - slv'length is no multiple of 8 (slv'length=" & INTEGER'image(slv'length) & ")" severity FAILURE; end if;
for i in Result'range loop
Result(i) := slv((i * 8) + 7 downto (i * 8));
end loop;
return Result;
end function;
-- create vector-vector from vector (12 bit)
function to_slvv_12(slv : std_logic_vector) return T_SLVV_12 is
variable Result : T_SLVV_12((slv'length / 12) - 1 downto 0);
begin
if ((slv'length mod 12) /= 0) then report "to_slvv_12: width mismatch - slv'length is no multiple of 12 (slv'length=" & INTEGER'image(slv'length) & ")" severity FAILURE; end if;
for i in Result'range loop
Result(i) := slv((i * 12) + 11 downto (i * 12));
end loop;
return Result;
end function;
-- create vector-vector from vector (16 bit)
function to_slvv_16(slv : std_logic_vector) return T_SLVV_16 is
variable Result : T_SLVV_16((slv'length / 16) - 1 downto 0);
begin
if ((slv'length mod 16) /= 0) then report "to_slvv_16: width mismatch - slv'length is no multiple of 16 (slv'length=" & INTEGER'image(slv'length) & ")" severity FAILURE; end if;
for i in Result'range loop
Result(i) := slv((i * 16) + 15 downto (i * 16));
end loop;
return Result;
end function;
-- create vector-vector from vector (32 bit)
function to_slvv_32(slv : std_logic_vector) return T_SLVV_32 is
variable Result : T_SLVV_32((slv'length / 32) - 1 downto 0);
begin
if ((slv'length mod 32) /= 0) then report "to_slvv_32: width mismatch - slv'length is no multiple of 32 (slv'length=" & INTEGER'image(slv'length) & ")" severity FAILURE; end if;
for i in Result'range loop
Result(i) := slv((i * 32) + 31 downto (i * 32));
end loop;
return Result;
end function;
-- create vector-vector from vector (64 bit)
function to_slvv_64(slv : std_logic_vector) return T_SLVV_64 is
variable Result : T_SLVV_64((slv'length / 64) - 1 downto 0);
begin
if ((slv'length mod 64) /= 0) then report "to_slvv_64: width mismatch - slv'length is no multiple of 64 (slv'length=" & INTEGER'image(slv'length) & ")" severity FAILURE; end if;
for i in Result'range loop
Result(i) := slv((i * 64) + 63 downto (i * 64));
end loop;
return Result;
end function;
-- create vector-vector from vector (128 bit)
function to_slvv_128(slv : std_logic_vector) return T_SLVV_128 is
variable Result : T_SLVV_128((slv'length / 128) - 1 downto 0);
begin
if ((slv'length mod 128) /= 0) then report "to_slvv_128: width mismatch - slv'length is no multiple of 128 (slv'length=" & INTEGER'image(slv'length) & ")" severity FAILURE; end if;
for i in Result'range loop
Result(i) := slv((i * 128) + 127 downto (i * 128));
end loop;
return Result;
end function;
-- create vector-vector from vector (256 bit)
function to_slvv_256(slv : std_logic_vector) return T_SLVV_256 is
variable Result : T_SLVV_256((slv'length / 256) - 1 downto 0);
begin
if ((slv'length mod 256) /= 0) then report "to_slvv_256: width mismatch - slv'length is no multiple of 256 (slv'length=" & INTEGER'image(slv'length) & ")" severity FAILURE; end if;
for i in Result'range loop
Result(i) := slv((i * 256) + 255 downto (i * 256));
end loop;
return Result;
end function;
-- create vector-vector from vector (512 bit)
function to_slvv_512(slv : std_logic_vector) return T_SLVV_512 is
variable Result : T_SLVV_512((slv'length / 512) - 1 downto 0);
begin
if ((slv'length mod 512) /= 0) then report "to_slvv_512: width mismatch - slv'length is no multiple of 512 (slv'length=" & INTEGER'image(slv'length) & ")" severity FAILURE; end if;
for i in Result'range loop
Result(i) := slv((i * 512) + 511 downto (i * 512));
end loop;
return Result;
end function;
-- Convert matrix to avector-vector: to_slvv_*
-- ==========================================================================
-- create vector-vector from matrix (4 bit)
function to_slvv_4(slm : T_SLM) return T_SLVV_4 is
variable Result : T_SLVV_4(slm'range(1));
begin
if (slm'length(2) /= 4) then report "to_slvv_4: type mismatch - slm'length(2)=" & integer'image(slm'length(2)) severity FAILURE; end if;
for i in slm'range(1) loop
Result(i) := get_row(slm, i);
end loop;
return Result;
end function;
-- create vector-vector from matrix (8 bit)
function to_slvv_8(slm : T_SLM) return T_SLVV_8 is
variable Result : T_SLVV_8(slm'range(1));
begin
if (slm'length(2) /= 8) then report "to_slvv_8: type mismatch - slm'length(2)=" & integer'image(slm'length(2)) severity FAILURE; end if;
for i in slm'range(1) loop
Result(i) := get_row(slm, i);
end loop;
return Result;
end function;
-- create vector-vector from matrix (12 bit)
function to_slvv_12(slm : T_SLM) return T_SLVV_12 is
variable Result : T_SLVV_12(slm'range(1));
begin
if (slm'length(2) /= 12) then report "to_slvv_12: type mismatch - slm'length(2)=" & integer'image(slm'length(2)) severity FAILURE; end if;
for i in slm'range(1) loop
Result(i) := get_row(slm, i);
end loop;
return Result;
end function;
-- create vector-vector from matrix (16 bit)
function to_slvv_16(slm : T_SLM) return T_SLVV_16 is
variable Result : T_SLVV_16(slm'range(1));
begin
if (slm'length(2) /= 16) then report "to_slvv_16: type mismatch - slm'length(2)=" & integer'image(slm'length(2)) severity FAILURE; end if;
for i in slm'range(1) loop
Result(i) := get_row(slm, i);
end loop;
return Result;
end function;
-- create vector-vector from matrix (32 bit)
function to_slvv_32(slm : T_SLM) return T_SLVV_32 is
variable Result : T_SLVV_32(slm'range(1));
begin
if (slm'length(2) /= 32) then report "to_slvv_32: type mismatch - slm'length(2)=" & integer'image(slm'length(2)) severity FAILURE; end if;
for i in slm'range(1) loop
Result(i) := get_row(slm, i);
end loop;
return Result;
end function;
-- create vector-vector from matrix (64 bit)
function to_slvv_64(slm : T_SLM) return T_SLVV_64 is
variable Result : T_SLVV_64(slm'range(1));
begin
if (slm'length(2) /= 64) then report "to_slvv_64: type mismatch - slm'length(2)=" & integer'image(slm'length(2)) severity FAILURE; end if;
for i in slm'range(1) loop
Result(i) := get_row(slm, i);
end loop;
return Result;
end function;
-- create vector-vector from matrix (128 bit)
function to_slvv_128(slm : T_SLM) return T_SLVV_128 is
variable Result : T_SLVV_128(slm'range(1));
begin
if (slm'length(2) /= 128) then report "to_slvv_128: type mismatch - slm'length(2)=" & integer'image(slm'length(2)) severity FAILURE; end if;
for i in slm'range(1) loop
Result(i) := get_row(slm, i);
end loop;
return Result;
end function;
-- create vector-vector from matrix (256 bit)
function to_slvv_256(slm : T_SLM) return T_SLVV_256 is
variable Result : T_SLVV_256(slm'range);
begin
if (slm'length(2) /= 256) then report "to_slvv_256: type mismatch - slm'length(2)=" & integer'image(slm'length(2)) severity FAILURE; end if;
for i in slm'range loop
Result(i) := get_row(slm, i);
end loop;
return Result;
end function;
-- create vector-vector from matrix (512 bit)
function to_slvv_512(slm : T_SLM) return T_SLVV_512 is
variable Result : T_SLVV_512(slm'range(1));
begin
if (slm'length(2) /= 512) then report "to_slvv_512: type mismatch - slm'length(2)=" & integer'image(slm'length(2)) severity FAILURE; end if;
for i in slm'range(1) loop
Result(i) := get_row(slm, i);
end loop;
return Result;
end function;
-- Convert vector-vector to matrix: to_slm
-- ==========================================================================
-- create matrix from vector
function to_slm(slv : std_logic_vector; ROWS : positive; COLS : positive) return T_SLM is
variable slm : T_SLM(ROWS - 1 downto 0, COLS - 1 downto 0);
begin
for i in 0 to ROWS - 1 loop
for j in 0 to COLS - 1 loop
slm(i, j) := slv((i * COLS) + j);
end loop;
end loop;
return slm;
end function;
-- create matrix from vector-vector
function to_slm(slvv : T_SLVV_4) return T_SLM is
variable slm : T_SLM(slvv'range, 3 downto 0);
begin
for i in slvv'range loop
for j in T_SLV_4'range loop
slm(i, j) := slvv(i)(j);
end loop;
end loop;
return slm;
end function;
function to_slm(slvv : T_SLVV_8) return T_SLM is
-- variable test : STD_LOGIC_VECTOR(T_SLV_8'range);
-- variable slm : T_SLM(slvv'range, test'range); -- BUG: iSIM 14.5 cascaded 'range accesses let iSIM break down
-- variable slm : T_SLM(slvv'range, T_SLV_8'range); -- BUG: iSIM 14.5 allocates 9 bits in dimension 2
variable slm : T_SLM(slvv'range, 7 downto 0); -- WORKAROUND: use constant range
begin
-- report "slvv: slvv.length=" & INTEGER'image(slvv'length) & " slm.dim0.length=" & INTEGER'image(slm'length(1)) & " slm.dim1.length=" & INTEGER'image(slm'length(2)) severity NOTE;
-- report "T_SLV_8: .length=" & INTEGER'image(T_SLV_8'length) & " .high=" & INTEGER'image(T_SLV_8'high) & " .low=" & INTEGER'image(T_SLV_8'low) severity NOTE;
-- report "test: test.length=" & INTEGER'image(test'length) & " .high=" & INTEGER'image(test'high) & " .low=" & INTEGER'image(test'low) severity NOTE;
for i in slvv'range loop
for j in T_SLV_8'range loop
slm(i, j) := slvv(i)(j);
end loop;
end loop;
return slm;
end function;
function to_slm(slvv : T_SLVV_12) return T_SLM is
variable slm : T_SLM(slvv'range, 11 downto 0);
begin
for i in slvv'range loop
for j in T_SLV_12'range loop
slm(i, j) := slvv(i)(j);
end loop;
end loop;
return slm;
end function;
function to_slm(slvv : T_SLVV_16) return T_SLM is
variable slm : T_SLM(slvv'range, 15 downto 0);
begin
for i in slvv'range loop
for j in T_SLV_16'range loop
slm(i, j) := slvv(i)(j);
end loop;
end loop;
return slm;
end function;
function to_slm(slvv : T_SLVV_32) return T_SLM is
variable slm : T_SLM(slvv'range, 31 downto 0);
begin
for i in slvv'range loop
for j in T_SLV_32'range loop
slm(i, j) := slvv(i)(j);
end loop;
end loop;
return slm;
end function;
function to_slm(slvv : T_SLVV_48) return T_SLM is
variable slm : T_SLM(slvv'range, 47 downto 0);
begin
for i in slvv'range loop
for j in T_SLV_48'range loop
slm(i, j) := slvv(i)(j);
end loop;
end loop;
return slm;
end function;
function to_slm(slvv : T_SLVV_64) return T_SLM is
variable slm : T_SLM(slvv'range, 63 downto 0);
begin
for i in slvv'range loop
for j in T_SLV_64'range loop
slm(i, j) := slvv(i)(j);
end loop;
end loop;
return slm;
end function;
function to_slm(slvv : T_SLVV_128) return T_SLM is
variable slm : T_SLM(slvv'range, 127 downto 0);
begin
for i in slvv'range loop
for j in T_SLV_128'range loop
slm(i, j) := slvv(i)(j);
end loop;
end loop;
return slm;
end function;
function to_slm(slvv : T_SLVV_256) return T_SLM is
variable slm : T_SLM(slvv'range, 255 downto 0);
begin
for i in slvv'range loop
for j in T_SLV_256'range loop
slm(i, j) := slvv(i)(j);
end loop;
end loop;
return slm;
end function;
function to_slm(slvv : T_SLVV_512) return T_SLM is
variable slm : T_SLM(slvv'range, 511 downto 0);
begin
for i in slvv'range loop
for j in T_SLV_512'range loop
slm(i, j) := slvv(i)(j);
end loop;
end loop;
return slm;
end function;
-- Change vector direction
-- ==========================================================================
function dir(slvv : T_SLVV_8) return T_SLVV_8 is
variable Result : T_SLVV_8(slvv'reverse_range);
begin
Result := slvv;
return Result;
end function;
-- Reverse vector elements
function rev(slvv : T_SLVV_4) return T_SLVV_4 is
variable Result : T_SLVV_4(slvv'range);
begin
for i in slvv'low to slvv'high loop
Result(slvv'high - i) := slvv(i);
end loop;
return Result;
end function;
function rev(slvv : T_SLVV_8) return T_SLVV_8 is
variable Result : T_SLVV_8(slvv'range);
begin
for i in slvv'low to slvv'high loop
Result(slvv'high - i) := slvv(i);
end loop;
return Result;
end function;
function rev(slvv : T_SLVV_12) return T_SLVV_12 is
variable Result : T_SLVV_12(slvv'range);
begin
for i in slvv'low to slvv'high loop
Result(slvv'high - i) := slvv(i);
end loop;
return Result;
end function;
function rev(slvv : T_SLVV_16) return T_SLVV_16 is
variable Result : T_SLVV_16(slvv'range);
begin
for i in slvv'low to slvv'high loop
Result(slvv'high - i) := slvv(i);
end loop;
return Result;
end function;
function rev(slvv : T_SLVV_32) return T_SLVV_32 is
variable Result : T_SLVV_32(slvv'range);
begin
for i in slvv'low to slvv'high loop
Result(slvv'high - i) := slvv(i);
end loop;
return Result;
end function;
function rev(slvv : T_SLVV_64) return T_SLVV_64 is
variable Result : T_SLVV_64(slvv'range);
begin
for i in slvv'low to slvv'high loop
Result(slvv'high - i) := slvv(i);
end loop;
return Result;
end function;
function rev(slvv : T_SLVV_128) return T_SLVV_128 is
variable Result : T_SLVV_128(slvv'range);
begin
for i in slvv'low to slvv'high loop
Result(slvv'high - i) := slvv(i);
end loop;
return Result;
end function;
function rev(slvv : T_SLVV_256) return T_SLVV_256 is
variable Result : T_SLVV_256(slvv'range);
begin
for i in slvv'low to slvv'high loop
Result(slvv'high - i) := slvv(i);
end loop;
return Result;
end function;
function rev(slvv : T_SLVV_512) return T_SLVV_512 is
variable Result : T_SLVV_512(slvv'range);
begin
for i in slvv'low to slvv'high loop
Result(slvv'high - i) := slvv(i);
end loop;
return Result;
end function;
-- Resize functions
-- ==========================================================================
-- Resizes the vector to the specified length. Input vectors larger than the specified size are truncated from the left side. Smaller input
-- vectors are extended on the left by the provided fill value (default: '0'). Use the resize functions of the numeric_std package for
-- value-preserving resizes of the signed and unsigned data types.
function resize(slm : T_SLM; size : positive) return T_SLM is
variable Result : T_SLM(size - 1 downto 0, slm'high(2) downto slm'low(2)) := (others => (others => '0')); -- WORKAROUND: Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); see work-around notes at T_SLM type declaration
begin
for i in slm'range(1) loop
for j in slm'high(2) downto slm'low(2) loop -- WORKAROUND: Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); see work-around notes at T_SLM type declaration
Result(i, j) := slm(i, j);
end loop;
end loop;
return Result;
end function;
function to_string(slvv : T_SLVV_8; sep : character := ':') return string is
constant hex_len : positive := ite((sep = C_POC_NUL), (slvv'length * 2), (slvv'length * 3) - 1);
variable Result : string(1 to hex_len) := (others => sep);
variable pos : positive := 1;
begin
for i in slvv'range loop
Result(pos to pos + 1) := to_string(slvv(i), 'h');
pos := pos + ite((sep = C_POC_NUL), 2, 3);
end loop;
return Result;
end function;
function to_string_bin(slm : T_SLM; groups : positive := 4; format : character := 'h') return string is
variable PerLineOverheader : positive := div_ceil(slm'length(2), groups);
variable Result : string(1 to (slm'length(1) * (slm'length(2) + PerLineOverheader)) + 10);
variable Writer : positive;
variable GroupCounter : natural;
begin
Result := (others => C_POC_NUL);
Result(1) := LF;
Writer := 2;
GroupCounter := 0;
for i in slm'low(1) to slm'high(1) loop
for j in slm'high(2) downto slm'low(2) loop -- WORKAROUND: Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); see work-around notes at T_SLM type declaration
Result(Writer) := to_char(slm(i, j));
Writer := Writer + 1;
GroupCounter := GroupCounter + 1;
if GroupCounter = groups then
Result(Writer) := ' ';
Writer := Writer + 1;
GroupCounter := 0;
end if;
end loop;
Result(Writer - 1) := LF;
GroupCounter := 0;
end loop;
return str_trim(Result);
end function;
function to_string(slm : T_SLM; groups : positive := 4; format : character := 'b') return string is
begin
if (format = 'b') then
return to_string_bin(slm, groups);
else
return "Format not supported.";
end if;
end function;
end package body;