aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/gna/bug019/PoC/src/common/vectors.vhdl
blob: f96d0e081be0d9d8ef2226cead8d3713e38ed697 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216pre { 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 */
/*
 *  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;