/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#ifndef MACC_H
#define MACC_H
#include "kernel/yosys.h"
YOSYS_NAMESPACE_BEGIN
struct Macc
{
struct port_t {
RTLIL::SigSpec in_a, in_b;
bool is_signed, do_subtract;
};
std::vector<port_t> ports;
RTLIL::SigSpec bit_ports;
void optimize(int width)
{
std::vector<port_t> new_ports;
RTLIL::SigSpec new_bit_ports;
RTLIL::Const off(0, width);
for (auto &port : ports)
{
if (GetSize(port.in_a) == 0 && GetSize(port.in_b) == 0)
continue;
if (GetSize(port.in_a) < GetSize(port.in_b))
std::swap(port.in_a, port.in_b);
if (GetSize(port.in_a) == 1 && GetSize(port.in_b) == 0 && !port.is_signed && !port.do_subtract) {
bit_ports.append(port.in_a);
continue;
}
if (port.in_a.is_fully_const() && port.in_b.is_fully_const()) {
RTLIL::Const v = port.in_a.as_const();
if (GetSize(port.in_b))
v = const_mul(v, port.in_b.as_const(), port.is_signed, port.is_signed, width);
if (port.do_subtract)
off = const_sub(off, v, port.is_signed, port.is_signed, width);
else
off = const_add(off, v, port.is_signed, port.is_signed, width);
continue;
}
if (port.is_signed) {
while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == port.in_a[GetSize(port.in_a)-2])
port.in_a.remove(GetSize(port.in_a)-1);
while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == port.in_b[GetSize(port.in_b)-2])
port.in_b.remove(GetSize(port.in_b)-1);
} else {
while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == State::S0)
port.in_a.remove(GetSize(port.in_a)-1);
while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == State::pre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */-- 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;
--
-- ============================================================================
-- Package: Common functions and types
--
-- Authors: Thomas B. Preusser
-- Martin Zabel
-- Patrick Lehmann
--
-- Description:
-- ------------------------------------
-- For detailed documentation see below.
--
-- License:
-- ============================================================================
-- Copyright 2007-2014 Technische Universitaet Dresden - Germany
-- Chair for 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 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 work-around: DON'T use myMatrix'range(n) for n >= 2
-- because: myMatrix'range(2) returns always myMatrix'range(1); tested with ISE/iSIM 14.2
-- USAGE NOTES:
-- dimmension 1 => rows - e.g. Words
-- dimmension 2 => columns - e.g. Bits/Bytes in a word
-- ==========================================================================
-- Function declarations
-- ==========================================================================
-- slicing boundary calulations
function low (lenvec : T_POSVEC; index : NATURAL) return NATURAL;
function high(lenvec : T_POSVEC; index : NATURAL) return NATURAL;
-- Assign procedures: assign_*
procedure assign_row(signal slm : out T_SLM; slv : STD_LOGIC_VECTOR; constant RowIndex : NATURAL); -- assign vector to complete row
procedure 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 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 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 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 slm_slice_cols(slm : T_SLM; High : NATURAL; Low : NATURAL) return T_SLM; -- get submatrix / all columns in ColIndex range high:low
-- Matrix to vector conversion: get_*
function get_col(slm : T_SLM; ColIndex : NATURAL) return STD_LOGIC_VECTOR; -- get a matrix column
function get_row(slm : T_SLM; RowIndex : NATURAL) return STD_LOGIC_VECTOR; -- get a matrix row
function 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 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 to_slv(slvv : T_SLVV_8) return STD_LOGIC_VECTOR; -- convert vector-vector to flatten vector
-- Convert flat vector to avector-vector: to_slvv_*
function to_slvv_4(slv : STD_LOGIC_VECTOR) return T_SLVV_4; --
function to_slvv_8(slv : STD_LOGIC_VECTOR) return T_SLVV_8; --
function to_slvv_12(slv : STD_LOGIC_VECTOR) return T_SLVV_12; --
function to_slvv_16(slv : STD_LOGIC_VECTOR) return T_SLVV_16; --
function to_slvv_32(slv : STD_LOGIC_VECTOR) return T_SLVV_32; --
function to_slvv_64(slv : STD_LOGIC_VECTOR) return T_SLVV_64; --
function to_slvv_128(slv : STD_LOGIC_VECTOR) return T_SLVV_128; --
function to_slvv_256(slv : STD_LOGIC_VECTOR) return T_SLVV_256; --
function to_slvv_512(slv : STD_LOGIC_VECTOR) return T_SLVV_512; --
-- Convert matrix to avector-vector: to_slvv_*
function to_slvv_4(slm : T_SLM) return T_SLVV_4; --
function to_slvv_8(slm : T_SLM) return T_SLVV_8; --
function to_slvv_12(slm : T_SLM) return T_SLVV_12; --
function to_slvv_16(slm : T_SLM) return T_SLVV_16; --
function to_slvv_32(slm : T_SLM) return T_SLVV_32; --
function to_slvv_64(slm : T_SLM) return T_SLVV_64; --
function to_slvv_128(slm : T_SLM) return T_SLVV_128; --
function to_slvv_256(slm : T_SLM) return T_SLVV_256; --
function to_slvv_512(slm : T_SLM) return T_SLVV_512; --
-- Convert vector-vector to matrix: to_slm
function to_slm(slvv : T_SLVV_4) return T_SLM; -- create matrix from vector-vector
function to_slm(slvv : T_SLVV_8) return T_SLM; -- create matrix from vector-vector
function to_slm(slvv : T_SLVV_12) return T_SLM; -- create matrix from vector-vector
function to_slm(slvv : T_SLVV_16) return T_SLM; -- create matrix from vector-vector
function to_slm(slvv : T_SLVV_32) return T_SLM; -- create matrix from vector-vector
function to_slm(slvv : T_SLVV_48) return T_SLM; -- create matrix from vector-vector
function to_slm(slvv : T_SLVV_64) return T_SLM; -- create matrix from vector-vector
function to_slm(slvv : T_SLVV_128) return T_SLM; -- create matrix from vector-vector
function to_slm(slvv : T_SLVV_256) return T_SLM; -- create matrix from vector-vector
function to_slm(slvv : T_SLVV_512) return T_SLM; -- create matrix from vector-vector
-- Change vector direction
function dir(slvv : T_SLVV_8) return T_SLVV_8;
-- Reverse vector elements
function rev(slvv : T_SLVV_4) return T_SLVV_4;
function rev(slvv : T_SLVV_8) return T_SLVV_8;
function rev(slvv : T_SLVV_12) return T_SLVV_12;
function rev(slvv : T_SLVV_16) return T_SLVV_16;
function rev(slvv : T_SLVV_32) return T_SLVV_32;
function rev(slvv : T_SLVV_64) return T_SLVV_64;
function rev(slvv : T_SLVV_128) return T_SLVV_128;
function rev(slvv : T_SLVV_256) return T_SLVV_256;
function rev(slvv : T_SLVV_512) return T_SLVV_512;
-- TODO:
function resize(slm : T_SLM; size : POSITIVE) return T_SLM;
-- to_string
function to_string(slvv : T_SLVV_8; sep : CHARACTER := ':') 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)); -- Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); tested with ISE/iSIM 14.2
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_cols(slm : T_SLM; High : NATURAL; Low : NATURAL) return T_SLM is
variable Result : T_SLM(slm'range(1), High - Low downto 0) := (others => (others => '0'));
begin
for i in slm'range(1) loop
for j in 0 to High - Low loop
Result(i, j) := slm(i, low + j);
end loop;
end loop;
return Result;
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)); -- Xilinx iSIM work-around, because 'range(2) = 'range(1); tested with ISE/iSIM 14.2
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); -- Xilinx iSIM work-around, because 'range(2) = 'range(1); tested with ISE/iSIM 14.2
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_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;
-- 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-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 dimmension 2
variable slm : T_SLM(slvv'range, 7 downto 0);
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'));
begin
for i in slm'range(1) loop
for j in slm'high(2) downto slm'low(2) loop
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;
end package body;