OpenCores
URL https://opencores.org/ocsvn/common_pkg/common_pkg/trunk

Subversion Repositories common_pkg

[/] [common_pkg/] [trunk/] [common_pkg.vhd] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 danv
 
2
-------------------------------------------------------------------------------
3
--
4
-- Copyright (C) 2009
5
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
6
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
7
--
8
-- This program is free software: you can redistribute it and/or modify
9
-- it under the terms of the GNU General Public License as published by
10
-- the Free Software Foundation, either version 3 of the License, or
11
-- (at your option) any later version.
12
--
13
-- This program is distributed in the hope that it will be useful,
14
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
15
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
-- GNU General Public License for more details.
17
--
18
-- You should have received a copy of the GNU General Public License
19
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
--
21
-------------------------------------------------------------------------------
22
 
23
LIBRARY IEEE;
24
USE IEEE.STD_LOGIC_1164.ALL;
25
USE IEEE.NUMERIC_STD.ALL;
26
USE IEEE.MATH_REAL.ALL;
27
 
28
PACKAGE common_pkg IS
29
 
30
  -- CONSTANT DECLARATIONS ----------------------------------------------------
31
 
32
  -- some integers
33
  CONSTANT c_0                    : NATURAL := 0;
34
  CONSTANT c_zero                 : NATURAL := 0;
35
  CONSTANT c_1                    : NATURAL := 1;
36
  CONSTANT c_one                  : NATURAL := 1;
37
  CONSTANT c_2                    : NATURAL := 2;
38
  CONSTANT c_4                    : NATURAL := 4;
39
  CONSTANT c_quad                 : NATURAL := 4;
40
  CONSTANT c_8                    : NATURAL := 8;
41
  CONSTANT c_16                   : NATURAL := 16;
42
  CONSTANT c_32                   : NATURAL := 32;
43
  CONSTANT c_64                   : NATURAL := 64;
44
  CONSTANT c_128                  : NATURAL := 128;
45
  CONSTANT c_256                  : NATURAL := 256;
46
 
47
  -- widths and sizes
48
  CONSTANT c_halfword_sz          : NATURAL := 2;
49
  CONSTANT c_word_sz              : NATURAL := 4;
50
  CONSTANT c_longword_sz          : NATURAL := 8;
51
  CONSTANT c_nibble_w             : NATURAL := 4;
52
  CONSTANT c_byte_w               : NATURAL := 8;
53
  CONSTANT c_octet_w              : NATURAL := 8;
54
  CONSTANT c_halfword_w           : NATURAL := c_byte_w*c_halfword_sz;
55
  CONSTANT c_word_w               : NATURAL := c_byte_w*c_word_sz;
56
  CONSTANT c_integer_w            : NATURAL := 32;              -- unfortunately VHDL integer type is limited to 32 bit values
57
  CONSTANT c_natural_w            : NATURAL := c_integer_w-1;   -- unfortunately VHDL natural type is limited to 31 bit values (0 and the positive subset of the VHDL integer type0
58
  CONSTANT c_longword_w           : NATURAL := c_byte_w*c_longword_sz;
59
 
60
  -- logic
61
  CONSTANT c_sl0                  : STD_LOGIC := '0';
62
  CONSTANT c_sl1                  : STD_LOGIC := '1';
63
  CONSTANT c_unsigned_0           : UNSIGNED(0 DOWNTO 0) := TO_UNSIGNED(0,1);
64
  CONSTANT c_unsigned_1           : UNSIGNED(0 DOWNTO 0) := TO_UNSIGNED(1,1);
65
  CONSTANT c_signed_0             : SIGNED(1 DOWNTO 0) := TO_SIGNED(0,2);
66
  CONSTANT c_signed_1             : SIGNED(1 DOWNTO 0) := TO_SIGNED(1,2);
67
  CONSTANT c_slv0                 : STD_LOGIC_VECTOR(255 DOWNTO 0) := (OTHERS=>'0');
68
  CONSTANT c_slv1                 : STD_LOGIC_VECTOR(255 DOWNTO 0) := (OTHERS=>'1');
69
  CONSTANT c_word_01              : STD_LOGIC_VECTOR(31 DOWNTO 0) := "01010101010101010101010101010101";
70
  CONSTANT c_word_10              : STD_LOGIC_VECTOR(31 DOWNTO 0) := "10101010101010101010101010101010";
71
  CONSTANT c_slv01                : STD_LOGIC_VECTOR(255 DOWNTO 0) := c_word_01 & c_word_01 & c_word_01 & c_word_01 & c_word_01 & c_word_01 & c_word_01 & c_word_01;
72
  CONSTANT c_slv10                : STD_LOGIC_VECTOR(255 DOWNTO 0) := c_word_10 & c_word_10 & c_word_10 & c_word_10 & c_word_10 & c_word_10 & c_word_10 & c_word_10;
73
 
74
  -- math
75
  CONSTANT c_nof_complex          : NATURAL := 2;   -- Real and imaginary part of complex number
76
  CONSTANT c_sign_w               : NATURAL := 1;   -- Sign bit, can be used to skip one of the double sign bits of a product
77
  CONSTANT c_sum_of_prod_w        : NATURAL := 1;   -- Bit growth for sum of 2 products, can be used in case complex multiply has normalized real and imag inputs instead of normalized amplitude inputs
78
 
79
  -- FF, block RAM, FIFO
80
  CONSTANT c_meta_delay_len       : NATURAL := 3;   -- default nof flipflops (FF) in meta stability recovery delay line (e.g. for clock domain crossing)
81
  CONSTANT c_meta_fifo_depth      : NATURAL := 16;  -- default use 16 word deep FIFO to cross clock domain, typically > 2*c_meta_delay_len or >~ 8 is enough
82
 
83
  CONSTANT c_bram_m9k_nof_bits    : NATURAL := 1024*9;  -- size of 1 Altera M9K block RAM in bits
84
  CONSTANT c_bram_m9k_max_w       : NATURAL := 36;      -- maximum width of 1 Altera M9K block RAM, so the size is then 256 words of 36 bits
85
  CONSTANT c_bram_m9k_fifo_depth  : NATURAL := c_bram_m9k_nof_bits/c_bram_m9k_max_w;  -- using a smaller FIFO depth than this leaves part of the RAM unused
86
 
87
  CONSTANT c_fifo_afull_margin    : NATURAL := 4;       -- default or minimal FIFO almost full margin
88
 
89
  -- DSP
90
  CONSTANT c_dsp_mult_w           : NATURAL := 18;   -- Width of the embedded multipliers in Stratix IV
91
 
92
  -- TYPE DECLARATIONS --------------------------------------------------------
93
  TYPE t_boolean_arr     IS ARRAY (INTEGER RANGE <>) OF BOOLEAN;   -- INTEGER left index starts default at -2**31
94
  TYPE t_integer_arr     IS ARRAY (INTEGER RANGE <>) OF INTEGER;   -- INTEGER left index starts default at -2**31
95
  TYPE t_natural_arr     IS ARRAY (INTEGER RANGE <>) OF NATURAL;   -- INTEGER left index starts default at -2**31
96
  TYPE t_nat_boolean_arr IS ARRAY (NATURAL RANGE <>) OF BOOLEAN;   -- NATURAL left index starts default at 0
97
  TYPE t_nat_integer_arr IS ARRAY (NATURAL RANGE <>) OF INTEGER;   -- NATURAL left index starts default at 0
98
  TYPE t_nat_natural_arr IS ARRAY (NATURAL RANGE <>) OF NATURAL;   -- NATURAL left index starts default at 0
99
  TYPE t_sl_arr          IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC;
100
  TYPE t_slv_1_arr       IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(0 DOWNTO 0);
101
  TYPE t_slv_2_arr       IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(1 DOWNTO 0);
102
  TYPE t_slv_4_arr       IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(3 DOWNTO 0);
103
  TYPE t_slv_8_arr       IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
104
  TYPE t_slv_12_arr      IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(11 DOWNTO 0);
105
  TYPE t_slv_16_arr      IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(15 DOWNTO 0);
106
  TYPE t_slv_18_arr      IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(17 DOWNTO 0);
107
  TYPE t_slv_24_arr      IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(23 DOWNTO 0);
108
  TYPE t_slv_32_arr      IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(31 DOWNTO 0);
109
  TYPE t_slv_44_arr      IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(43 DOWNTO 0);
110
  TYPE t_slv_48_arr      IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(47 DOWNTO 0);
111
  TYPE t_slv_64_arr      IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(63 DOWNTO 0);
112
  TYPE t_slv_128_arr     IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(127 DOWNTO 0);
113
  TYPE t_slv_256_arr     IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(255 DOWNTO 0);
114
  TYPE t_slv_512_arr     IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(511 DOWNTO 0);
115
  TYPE t_slv_1024_arr    IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(1023 DOWNTO 0);
116
 
117
  CONSTANT c_boolean_arr     : t_boolean_arr     := (TRUE, FALSE);  -- array all possible values that can be iterated over
118
  CONSTANT c_nat_boolean_arr : t_nat_boolean_arr := (TRUE, FALSE);  -- array all possible values that can be iterated over
119
 
120
  TYPE t_integer_matrix IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF INTEGER;
121
  TYPE t_boolean_matrix IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF BOOLEAN;
122
  TYPE t_sl_matrix      IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF STD_LOGIC;
123
  TYPE t_slv_8_matrix   IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
124
  TYPE t_slv_16_matrix  IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF STD_LOGIC_VECTOR(15 DOWNTO 0);
125
  TYPE t_slv_32_matrix  IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF STD_LOGIC_VECTOR(31 DOWNTO 0);
126
  TYPE t_slv_64_matrix  IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF STD_LOGIC_VECTOR(63 DOWNTO 0);
127
 
128
  TYPE t_natural_2arr_2 IS ARRAY (INTEGER RANGE <>) OF t_natural_arr(1 DOWNTO 0);
129
 
130
  -- STRUCTURE DECLARATIONS ---------------------------------------------------
131
 
132
  -- Clock and Reset
133
  --
134
  -- . rst   = Reset. Can be used asynchronously to take effect immediately
135
  --           when used before the clk'EVENT section. May also be used as
136
  --           synchronous reset using it as first condition in the clk'EVENT
137
  --           section. As synchronous reset it requires clock activity to take
138
  --           effect. A synchronous rst may or may not depend on clken,
139
  --           however typically rst should take priority over clken.
140
  -- . clk   = Clock. Used in clk'EVENT line via rising_edge(clk) or sometimes
141
  --           as falling_edge(clk).
142
  -- . clken = Clock Enable. Used for the whole clk'EVENT section.
143
  TYPE t_sys_rce IS RECORD
144
    rst   : STD_LOGIC;
145
    clk   : STD_LOGIC;
146
    clken : STD_LOGIC;  -- := '1';
147
  END RECORD;
148
 
149
  TYPE t_sys_ce IS RECORD
150
    clk   : STD_LOGIC;
151
    clken : STD_LOGIC;  -- := '1';
152
  END RECORD;
153
 
154
 
155
  -- FUNCTION DECLARATIONS ----------------------------------------------------
156
 
157
  -- All functions assume [high downto low] input ranges
158
 
159
  FUNCTION pow2(n : NATURAL) RETURN NATURAL;  -- = 2**n
160
  FUNCTION ceil_pow2(n : INTEGER) RETURN NATURAL;  -- = 2**n, returns 1 for n<0
161
 
162
  FUNCTION true_log2(n : NATURAL) RETURN NATURAL;  -- true_log2(n) = log2(n)
163
  FUNCTION ceil_log2(n : NATURAL) RETURN NATURAL;  -- ceil_log2(n) = log2(n), but force ceil_log2(1) = 1
164
 
165
  FUNCTION floor_log10(n : NATURAL) RETURN NATURAL;
166
 
167
  FUNCTION is_pow2(n : NATURAL) RETURN BOOLEAN;        -- return TRUE when n is a power of 2, so 0, 1, 2, 4, 8, 16, ...
168
  FUNCTION true_log_pow2(n : NATURAL) RETURN NATURAL;  -- 2**true_log2(n), return power of 2 that is >= n
169
 
170
  FUNCTION ratio( n, d : NATURAL) RETURN NATURAL;  -- return n/d when n MOD d = 0 else return 0, so ratio * d = n only when integer ratio > 0
171
  FUNCTION ratio2(n, m : NATURAL) RETURN NATURAL;  -- return integer ratio of n/m or m/n, whichever is the largest
172
 
173
  FUNCTION ceil_div(   n, d : NATURAL)  RETURN NATURAL;   -- ceil_div    = n/d + (n MOD d)/=0
174
  FUNCTION ceil_value( n, d : NATURAL)  RETURN NATURAL;   -- ceil_value  = ceil_div(n, d) * d
175
  FUNCTION floor_value(n, d : NATURAL)  RETURN NATURAL;   -- floor_value = (n/d) * d
176
  FUNCTION ceil_div(   n : UNSIGNED; d: NATURAL) RETURN UNSIGNED;
177
  FUNCTION ceil_value( n : UNSIGNED; d: NATURAL) RETURN UNSIGNED;
178
  FUNCTION floor_value(n : UNSIGNED; d: NATURAL) RETURN UNSIGNED;
179
 
180
  FUNCTION slv(n: IN STD_LOGIC)        RETURN STD_LOGIC_VECTOR;  -- standard logic to 1 element standard logic vector
181
  FUNCTION sl( n: IN STD_LOGIC_VECTOR) RETURN STD_LOGIC;         -- 1 element standard logic vector to standard logic
182
 
183
  FUNCTION to_natural_arr(n : t_integer_arr; to_zero : BOOLEAN) RETURN t_natural_arr;  -- if to_zero=TRUE then negative numbers are forced to zero, otherwise they will give a compile range error
184
  FUNCTION to_natural_arr(n : t_nat_natural_arr)                RETURN t_natural_arr;
185
  FUNCTION to_integer_arr(n : t_natural_arr)                    RETURN t_integer_arr;
186
  FUNCTION to_integer_arr(n : t_nat_natural_arr)                RETURN t_integer_arr;
187
  FUNCTION to_slv_32_arr( n : t_integer_arr)                    RETURN t_slv_32_arr;
188
  FUNCTION to_slv_32_arr( n : t_natural_arr)                    RETURN t_slv_32_arr;
189
 
190
  FUNCTION vector_tree(slv : STD_LOGIC_VECTOR; operation : STRING) RETURN STD_LOGIC;  -- Core operation tree function for vector "AND", "OR", "XOR"
191
  FUNCTION vector_and(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC;  -- '1' when all slv bits are '1' else '0'
192
  FUNCTION vector_or( slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC;  -- '0' when all slv bits are '0' else '1'
193
  FUNCTION vector_xor(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC;  -- '1' when the slv has an odd number of '1' bits else '0'
194
  FUNCTION vector_one_hot(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- Returns slv when it contains one hot bit, else returns 0.
195
 
196
  FUNCTION andv(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC;  -- alias of vector_and
197
  FUNCTION orv( slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC;  -- alias of vector_or
198
  FUNCTION xorv(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC;  -- alias of vector_xor
199
 
200
  FUNCTION matrix_and(mat : t_sl_matrix; wi, wj : NATURAL) RETURN STD_LOGIC;  -- '1' when all matrix bits are '1' else '0'
201
  FUNCTION matrix_or( mat : t_sl_matrix; wi, wj : NATURAL) RETURN STD_LOGIC;  -- '0' when all matrix bits are '0' else '1'
202
 
203
  FUNCTION smallest(n, m    : INTEGER)       RETURN INTEGER;
204
  FUNCTION smallest(n, m, l : INTEGER)       RETURN INTEGER;
205
  FUNCTION smallest(n       : t_natural_arr) RETURN NATURAL;
206
 
207
  FUNCTION largest(n, m : INTEGER)       RETURN INTEGER;
208
  FUNCTION largest(n    : t_natural_arr) RETURN NATURAL;
209
 
210
  FUNCTION func_sum(    n : t_natural_arr)     RETURN NATURAL;      -- sum     of all elements in array
211
  FUNCTION func_sum(    n : t_nat_natural_arr) RETURN NATURAL;
212
  FUNCTION func_product(n : t_natural_arr)     RETURN NATURAL;      -- product of all elements in array
213
  FUNCTION func_product(n : t_nat_natural_arr) RETURN NATURAL;
214
 
215
  FUNCTION "+" (L, R: t_natural_arr)               RETURN t_natural_arr;  -- element wise sum
216
  FUNCTION "+" (L   : t_natural_arr; R : INTEGER)  RETURN t_natural_arr;  -- element wise sum
217
  FUNCTION "+" (L   : INTEGER; R : t_natural_arr)  RETURN t_natural_arr;  -- element wise sum
218
 
219
  FUNCTION "-" (L, R: t_natural_arr)               RETURN t_natural_arr;  -- element wise subtract
220
  FUNCTION "-" (L, R: t_natural_arr)               RETURN t_integer_arr;  -- element wise subtract, support negative result
221
  FUNCTION "-" (L   : t_natural_arr; R : INTEGER)  RETURN t_natural_arr;  -- element wise subtract
222
  FUNCTION "-" (L   : INTEGER; R : t_natural_arr)  RETURN t_natural_arr;  -- element wise subtract
223
 
224
  FUNCTION "*" (L, R: t_natural_arr)               RETURN t_natural_arr;  -- element wise product
225
  FUNCTION "*" (L   : t_natural_arr; R : NATURAL)  RETURN t_natural_arr;  -- element wise product
226
  FUNCTION "*" (L   : NATURAL; R : t_natural_arr)  RETURN t_natural_arr;  -- element wise product
227
 
228
  FUNCTION "/" (L, R: t_natural_arr)               RETURN t_natural_arr;  -- element wise division
229
  FUNCTION "/" (L   : t_natural_arr; R : POSITIVE) RETURN t_natural_arr;  -- element wise division
230
  FUNCTION "/" (L   : NATURAL; R : t_natural_arr)  RETURN t_natural_arr;  -- element wise division
231
 
232
  FUNCTION is_true(a : STD_LOGIC) RETURN BOOLEAN;
233
  FUNCTION is_true(a : STD_LOGIC) RETURN NATURAL;
234
  FUNCTION is_true(a : BOOLEAN)   RETURN STD_LOGIC;
235
  FUNCTION is_true(a : BOOLEAN)   RETURN NATURAL;
236
  FUNCTION is_true(a : INTEGER)   RETURN BOOLEAN;    -- also covers NATURAL because it is a subtype of INTEGER
237
  FUNCTION is_true(a : INTEGER)   RETURN STD_LOGIC;  -- also covers NATURAL because it is a subtype of INTEGER
238
 
239
  FUNCTION sel_a_b(sel,           a, b : BOOLEAN)           RETURN BOOLEAN;
240
  FUNCTION sel_a_b(sel,           a, b : INTEGER)           RETURN INTEGER;
241
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : INTEGER)           RETURN INTEGER;
242
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : REAL)              RETURN REAL;
243
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : STD_LOGIC)         RETURN STD_LOGIC;
244
  FUNCTION sel_a_b(sel : INTEGER; a, b : STD_LOGIC)         RETURN STD_LOGIC;
245
  FUNCTION sel_a_b(sel : INTEGER; a, b : STD_LOGIC_VECTOR)  RETURN STD_LOGIC_VECTOR;
246
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : STD_LOGIC_VECTOR)  RETURN STD_LOGIC_VECTOR;
247
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : SIGNED)            RETURN SIGNED;
248
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : UNSIGNED)          RETURN UNSIGNED;
249
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_integer_arr)     RETURN t_integer_arr;
250
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_natural_arr)     RETURN t_natural_arr;
251
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_nat_integer_arr) RETURN t_nat_integer_arr;
252
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_nat_natural_arr) RETURN t_nat_natural_arr;
253
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : STRING)            RETURN STRING;
254
  FUNCTION sel_a_b(sel : INTEGER; a, b : STRING)            RETURN STRING;
255
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : TIME)              RETURN TIME;
256
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : SEVERITY_LEVEL)    RETURN SEVERITY_LEVEL;
257
 
258
  -- sel_n() index sel = 0, 1, 2, ... will return a, b, c, ...
259
  FUNCTION sel_n(sel : NATURAL; a, b, c                      : BOOLEAN) RETURN BOOLEAN;  --  3
260
  FUNCTION sel_n(sel : NATURAL; a, b, c, d                   : BOOLEAN) RETURN BOOLEAN;  --  4
261
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e                : BOOLEAN) RETURN BOOLEAN;  --  5
262
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f             : BOOLEAN) RETURN BOOLEAN;  --  6
263
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g          : BOOLEAN) RETURN BOOLEAN;  --  7
264
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h       : BOOLEAN) RETURN BOOLEAN;  --  8
265
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i    : BOOLEAN) RETURN BOOLEAN;  --  9
266
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i, j : BOOLEAN) RETURN BOOLEAN;  -- 10
267
 
268
  FUNCTION sel_n(sel : NATURAL; a, b, c                      : INTEGER) RETURN INTEGER;  --  3
269
  FUNCTION sel_n(sel : NATURAL; a, b, c, d                   : INTEGER) RETURN INTEGER;  --  4
270
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e                : INTEGER) RETURN INTEGER;  --  5
271
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f             : INTEGER) RETURN INTEGER;  --  6
272
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g          : INTEGER) RETURN INTEGER;  --  7
273
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h       : INTEGER) RETURN INTEGER;  --  8
274
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i    : INTEGER) RETURN INTEGER;  --  9
275
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i, j : INTEGER) RETURN INTEGER;  -- 10
276
 
277
  FUNCTION sel_n(sel : NATURAL; a, b                         : STRING) RETURN STRING;    --  2
278
  FUNCTION sel_n(sel : NATURAL; a, b, c                      : STRING) RETURN STRING;    --  3
279
  FUNCTION sel_n(sel : NATURAL; a, b, c, d                   : STRING) RETURN STRING;    --  4
280
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e                : STRING) RETURN STRING;    --  5
281
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f             : STRING) RETURN STRING;    --  6
282
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g          : STRING) RETURN STRING;    --  7
283
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h       : STRING) RETURN STRING;    --  8
284
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i    : STRING) RETURN STRING;    --  9
285
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i, j : STRING) RETURN STRING;    -- 10
286
 
287
  FUNCTION array_init(init : STD_LOGIC; nof              : NATURAL) RETURN STD_LOGIC_VECTOR;  -- useful to init a unconstrained array of size 1
288
  FUNCTION array_init(init,             nof              : NATURAL) RETURN t_natural_arr;     -- useful to init a unconstrained array of size 1
289
  FUNCTION array_init(init,             nof              : NATURAL) RETURN t_nat_natural_arr; -- useful to init a unconstrained array of size 1
290
  FUNCTION array_init(init,             nof, incr        : NATURAL) RETURN t_natural_arr;     -- useful to init an array with incrementing numbers
291
  FUNCTION array_init(init,             nof, incr        : NATURAL) RETURN t_nat_natural_arr;
292
  FUNCTION array_init(init,             nof, incr        : INTEGER) RETURN t_slv_16_arr;
293
  FUNCTION array_init(init,             nof, incr        : INTEGER) RETURN t_slv_32_arr;
294
  FUNCTION array_init(init,             nof, width       : NATURAL) RETURN STD_LOGIC_VECTOR;  -- useful to init an unconstrained std_logic_vector with repetitive content
295
  FUNCTION array_init(init,             nof, width, incr : NATURAL) RETURN STD_LOGIC_VECTOR;  -- useful to init an unconstrained std_logic_vector with incrementing content
296
  FUNCTION array_sinit(init : INTEGER;   nof, width       : NATURAL) RETURN STD_LOGIC_VECTOR;  -- useful to init an unconstrained std_logic_vector with repetitive content
297
 
298
  FUNCTION init_slv_64_matrix(nof_a, nof_b, k : INTEGER) RETURN t_slv_64_matrix;  -- initialize all elements in t_slv_64_matrix to value k
299
 
300
  -- Concatenate two or more STD_LOGIC_VECTORs into a single STD_LOGIC_VECTOR or extract one of them from a concatenated STD_LOGIC_VECTOR
301
  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a, b, c, d, e, f, g : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
302
  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d, use_e, use_f        : BOOLEAN; a, b, c, d, e, f    : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
303
  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d, use_e               : BOOLEAN; a, b, c, d, e       : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
304
  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d                      : BOOLEAN; a, b, c, d          : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
305
  FUNCTION func_slv_concat(  use_a, use_b, use_c                             : BOOLEAN; a, b, c             : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
306
  FUNCTION func_slv_concat(  use_a, use_b                                    : BOOLEAN; a, b                : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
307
  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w : NATURAL) RETURN NATURAL;
308
  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f        : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w      : NATURAL) RETURN NATURAL;
309
  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e               : BOOLEAN; a_w, b_w, c_w, d_w, e_w           : NATURAL) RETURN NATURAL;
310
  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d                      : BOOLEAN; a_w, b_w, c_w, d_w                : NATURAL) RETURN NATURAL;
311
  FUNCTION func_slv_concat_w(use_a, use_b, use_c                             : BOOLEAN; a_w, b_w, c_w                     : NATURAL) RETURN NATURAL;
312
  FUNCTION func_slv_concat_w(use_a, use_b                                    : BOOLEAN; a_w, b_w                          : NATURAL) RETURN NATURAL;
313
  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
314
  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d, use_e, use_f        : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w      : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
315
  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d, use_e               : BOOLEAN; a_w, b_w, c_w, d_w, e_w           : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
316
  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d                      : BOOLEAN; a_w, b_w, c_w, d_w                : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
317
  FUNCTION func_slv_extract( use_a, use_b, use_c                             : BOOLEAN; a_w, b_w, c_w                     : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
318
  FUNCTION func_slv_extract( use_a, use_b                                    : BOOLEAN; a_w, b_w                          : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
319
 
320
  FUNCTION TO_UINT(vec : STD_LOGIC_VECTOR) RETURN NATURAL;  -- beware: NATURAL'HIGH = 2**31-1, not 2*32-1, use TO_SINT to avoid warning
321
  FUNCTION TO_SINT(vec : STD_LOGIC_VECTOR) RETURN INTEGER;
322
 
323
  FUNCTION TO_UVEC(dec, w : NATURAL) RETURN STD_LOGIC_VECTOR;
324
  FUNCTION TO_SVEC(dec, w : INTEGER) RETURN STD_LOGIC_VECTOR;
325
 
326
  FUNCTION TO_SVEC_32(dec : INTEGER) RETURN STD_LOGIC_VECTOR;  -- = TO_SVEC() with w=32 for t_slv_32_arr slv elements
327
 
328
-- The RESIZE for SIGNED in IEEE.NUMERIC_STD extends the sign bit or it keeps the sign bit and LS part. This
329
  -- behaviour of preserving the sign bit is less suitable for DSP and not necessary in general. A more
330
  -- appropriate approach is to ignore the MSbit sign and just keep the LS part. For too large values this 
331
  -- means that the result gets wrapped, but that is fine for default behaviour, because that is also what
332
  -- happens for RESIZE of UNSIGNED. Therefor this is what the RESIZE_NUM for SIGNED and the RESIZE_SVEC do
333
  -- and better not use RESIZE for SIGNED anymore.
334
  FUNCTION RESIZE_NUM( u   : UNSIGNED;         w : NATURAL) RETURN UNSIGNED;          -- left extend with '0' or keep LS part (same as RESIZE for UNSIGNED)
335
  FUNCTION RESIZE_NUM( s   : SIGNED;           w : NATURAL) RETURN SIGNED;            -- extend sign bit or keep LS part
336
  FUNCTION RESIZE_UVEC(sl  : STD_LOGIC;        w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- left extend with '0' into slv
337
  FUNCTION RESIZE_UVEC(vec : STD_LOGIC_VECTOR; w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- left extend with '0' or keep LS part
338
  FUNCTION RESIZE_SVEC(vec : STD_LOGIC_VECTOR; w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- extend sign bit or keep LS part
339
  FUNCTION RESIZE_UINT(u   : INTEGER;          w : NATURAL) RETURN INTEGER;           -- left extend with '0' or keep LS part
340
  FUNCTION RESIZE_SINT(s   : INTEGER;          w : NATURAL) RETURN INTEGER;           -- extend sign bit or keep LS part
341
 
342
  FUNCTION RESIZE_UVEC_32(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;  -- = RESIZE_UVEC() with w=32 for t_slv_32_arr slv elements
343
  FUNCTION RESIZE_SVEC_32(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;  -- = RESIZE_SVEC() with w=32 for t_slv_32_arr slv elements
344
 
345
  FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : INTEGER)  RETURN STD_LOGIC_VECTOR;
346
  FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : UNSIGNED) RETURN STD_LOGIC_VECTOR;
347
  FUNCTION INCR_SVEC(vec : STD_LOGIC_VECTOR; dec : INTEGER)  RETURN STD_LOGIC_VECTOR;
348
  FUNCTION INCR_SVEC(vec : STD_LOGIC_VECTOR; dec : SIGNED)   RETURN STD_LOGIC_VECTOR;
349
                                                                                                                   -- Used in common_add_sub.vhd
350
  FUNCTION ADD_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- l_vec + r_vec, treat slv operands as signed,   slv output width is res_w
351
  FUNCTION SUB_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- l_vec - r_vec, treat slv operands as signed,   slv output width is res_w
352
  FUNCTION ADD_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- l_vec + r_vec, treat slv operands as unsigned, slv output width is res_w
353
  FUNCTION SUB_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- l_vec - r_vec, treat slv operands as unsigned, slv output width is res_w
354
 
355
  FUNCTION ADD_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;                   -- l_vec + r_vec, treat slv operands as signed,   slv output width is l_vec'LENGTH
356
  FUNCTION SUB_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;                   -- l_vec - r_vec, treat slv operands as signed,   slv output width is l_vec'LENGTH
357
  FUNCTION ADD_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;                   -- l_vec + r_vec, treat slv operands as unsigned, slv output width is l_vec'LENGTH
358
  FUNCTION SUB_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;                   -- l_vec - r_vec, treat slv operands as unsigned, slv output width is l_vec'LENGTH
359
 
360
  FUNCTION COMPLEX_MULT_REAL(a_re, a_im, b_re, b_im : INTEGER) RETURN INTEGER;  -- Calculate real part of complex multiplication: a_re*b_re - a_im*b_im 
361
  FUNCTION COMPLEX_MULT_IMAG(a_re, a_im, b_re, b_im : INTEGER) RETURN INTEGER;  -- Calculate imag part of complex multiplication: a_im*b_re + a_re*b_im 
362
 
363
  FUNCTION SHIFT_UVEC(vec : STD_LOGIC_VECTOR; shift : INTEGER) RETURN STD_LOGIC_VECTOR;  -- < 0 shift left, > 0 shift right
364
  FUNCTION SHIFT_SVEC(vec : STD_LOGIC_VECTOR; shift : INTEGER) RETURN STD_LOGIC_VECTOR;  -- < 0 shift left, > 0 shift right
365
 
366
  FUNCTION offset_binary(a : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
367
 
368
  FUNCTION truncate(                vec : STD_LOGIC_VECTOR; n              : NATURAL) RETURN STD_LOGIC_VECTOR;  -- remove n LSBits from vec, so result has width vec'LENGTH-n
369
  FUNCTION truncate_and_resize_uvec(vec : STD_LOGIC_VECTOR; n,           w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- remove n LSBits from vec and then resize to width w
370
  FUNCTION truncate_and_resize_svec(vec : STD_LOGIC_VECTOR; n,           w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- idem for signed values
371
  FUNCTION scale(                   vec : STD_LOGIC_VECTOR; n:               NATURAL) RETURN STD_LOGIC_VECTOR;  -- add n '0' LSBits to vec
372
  FUNCTION scale_and_resize_uvec(   vec : STD_LOGIC_VECTOR; n,           w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- add n '0' LSBits to vec and then resize to width w
373
  FUNCTION scale_and_resize_svec(   vec : STD_LOGIC_VECTOR; n,           w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- idem for signed values
374
  FUNCTION truncate_or_resize_uvec( vec : STD_LOGIC_VECTOR; b : BOOLEAN; w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- when b=TRUE then truncate to width w, else resize to width w
375
  FUNCTION truncate_or_resize_svec( vec : STD_LOGIC_VECTOR; b : BOOLEAN; w : NATURAL) RETURN STD_LOGIC_VECTOR;  -- idem for signed values
376
 
377
  FUNCTION s_round(   vec : STD_LOGIC_VECTOR; n : NATURAL; clip : BOOLEAN) RETURN STD_LOGIC_VECTOR;  -- remove n LSBits from vec by rounding away from 0, so result has width vec'LENGTH-n, and clip to avoid wrap
378
  FUNCTION s_round(   vec : STD_LOGIC_VECTOR; n : NATURAL)                 RETURN STD_LOGIC_VECTOR;  -- remove n LSBits from vec by rounding away from 0, so result has width vec'LENGTH-n
379
  FUNCTION s_round_up(vec : STD_LOGIC_VECTOR; n : NATURAL; clip : BOOLEAN) RETURN STD_LOGIC_VECTOR;  -- idem but round up to +infinity (s_round_up = u_round)
380
  FUNCTION s_round_up(vec : STD_LOGIC_VECTOR; n : NATURAL)                 RETURN STD_LOGIC_VECTOR;  -- idem but round up to +infinity (s_round_up = u_round)
381
  FUNCTION u_round(   vec : STD_LOGIC_VECTOR; n : NATURAL; clip : BOOLEAN) RETURN STD_LOGIC_VECTOR;  -- idem round up for unsigned values
382
  FUNCTION u_round(   vec : STD_LOGIC_VECTOR; n : NATURAL)                 RETURN STD_LOGIC_VECTOR;  -- idem round up for unsigned values
383
 
384
  FUNCTION hton(a : STD_LOGIC_VECTOR; w, sz : NATURAL) RETURN STD_LOGIC_VECTOR;  -- convert endianity from host to network, sz in symbols of width w
385
  FUNCTION hton(a : STD_LOGIC_VECTOR;    sz : NATURAL) RETURN STD_LOGIC_VECTOR;  -- convert endianity from host to network, sz in bytes
386
  FUNCTION hton(a : STD_LOGIC_VECTOR                 ) RETURN STD_LOGIC_VECTOR;  -- convert endianity from host to network, for all bytes in a
387
  FUNCTION ntoh(a : STD_LOGIC_VECTOR;    sz : NATURAL) RETURN STD_LOGIC_VECTOR;  -- convert endianity from network to host, sz in bytes, ntoh() = hton()
388
  FUNCTION ntoh(a : STD_LOGIC_VECTOR                 ) RETURN STD_LOGIC_VECTOR;  -- convert endianity from network to host, for all bytes in a, ntoh() = hton()
389
 
390
  FUNCTION flip(a : STD_LOGIC_VECTOR)  RETURN STD_LOGIC_VECTOR;  -- bit flip a vector, map a[h:0] to [0:h]
391
  FUNCTION flip(a, w : NATURAL)        RETURN NATURAL;           -- bit flip a vector, map a[h:0] to [0:h], h = w-1
392
  FUNCTION flip(a : t_slv_32_arr)      RETURN t_slv_32_arr;
393
  FUNCTION flip(a : t_integer_arr)     RETURN t_integer_arr;
394
  FUNCTION flip(a : t_natural_arr)     RETURN t_natural_arr;
395
  FUNCTION flip(a : t_nat_natural_arr) RETURN t_nat_natural_arr;
396
 
397
  FUNCTION transpose(a : STD_LOGIC_VECTOR; row, col : NATURAL) RETURN STD_LOGIC_VECTOR;  -- transpose a vector, map a[i*row+j] to output index [j*col+i]
398
  FUNCTION transpose(a,                    row, col : NATURAL) RETURN NATURAL;           -- transpose index a = [i*row+j] to output index [j*col+i]
399
 
400
  FUNCTION split_w(input_w: NATURAL; min_out_w: NATURAL; max_out_w: NATURAL) RETURN NATURAL;
401
 
402
  FUNCTION pad(str: STRING; width: NATURAL; pad_char: CHARACTER) RETURN STRING;
403
 
404
  FUNCTION slice_up(str: STRING; width: NATURAL; i: NATURAL) RETURN STRING;
405
  FUNCTION slice_up(str: STRING; width: NATURAL; i: NATURAL; pad_char: CHARACTER) RETURN STRING;
406
  FUNCTION slice_dn(str: STRING; width: NATURAL; i: NATURAL) RETURN STRING;
407
 
408
  FUNCTION nat_arr_to_concat_slv(nat_arr: t_natural_arr; nof_elements: NATURAL) RETURN STD_LOGIC_VECTOR;
409
 
410
  ------------------------------------------------------------------------------
411
  -- Component specific functions
412
  ------------------------------------------------------------------------------
413
 
414
  -- common_fifo_*  
415
  PROCEDURE proc_common_fifo_asserts (CONSTANT c_fifo_name   : IN STRING;
416
                                      CONSTANT c_note_is_ful : IN BOOLEAN;
417
                                      CONSTANT c_fail_rd_emp : IN BOOLEAN;
418
                                      SIGNAL   wr_rst        : IN STD_LOGIC;
419
                                      SIGNAL   wr_clk        : IN STD_LOGIC;
420
                                      SIGNAL   wr_full       : IN STD_LOGIC;
421
                                      SIGNAL   wr_en         : IN STD_LOGIC;
422
                                      SIGNAL   rd_clk        : IN STD_LOGIC;
423
                                      SIGNAL   rd_empty      : IN STD_LOGIC;
424
                                      SIGNAL   rd_en         : IN STD_LOGIC);
425
 
426
  -- common_fanout_tree  
427
  FUNCTION func_common_fanout_tree_pipelining(c_nof_stages, c_nof_output_per_cell, c_nof_output : NATURAL;
428
                                              c_cell_pipeline_factor_arr, c_cell_pipeline_arr : t_natural_arr) RETURN t_natural_arr;
429
 
430
  -- common_reorder_symbol 
431
  FUNCTION func_common_reorder2_is_there(I, J : NATURAL) RETURN BOOLEAN;
432
  FUNCTION func_common_reorder2_is_active(I, J, N : NATURAL) RETURN BOOLEAN;
433
  FUNCTION func_common_reorder2_get_select_index(I, J, N : NATURAL) RETURN INTEGER;
434
  FUNCTION func_common_reorder2_get_select(I, J, N : NATURAL; select_arr : t_natural_arr) RETURN NATURAL;
435
  FUNCTION func_common_reorder2_inverse_select(N : NATURAL; select_arr : t_natural_arr) RETURN t_natural_arr;
436
 
437
  -- Generate faster sample SCLK from digital DCLK for sim only
438
  PROCEDURE proc_common_dclk_generate_sclk(CONSTANT Pfactor : IN    POSITIVE;
439
                                           SIGNAL   dclk    : IN    STD_LOGIC;
440
                                           SIGNAL   sclk    : INOUT STD_LOGIC);
441
 
442
END common_pkg;
443
 
444
PACKAGE BODY common_pkg IS
445
 
446
  FUNCTION pow2(n : NATURAL) RETURN NATURAL IS
447
  BEGIN
448
    RETURN 2**n;
449
  END;
450
 
451
  FUNCTION ceil_pow2(n : INTEGER) RETURN NATURAL IS
452
  -- Also allows negative exponents and rounds up before returning the value
453
  BEGIN
454
    RETURN natural(integer(ceil(2**real(n))));
455
  END;
456
 
457
  FUNCTION true_log2(n : NATURAL) RETURN NATURAL IS
458
  -- Purpose: For calculating extra vector width of existing vector
459
  -- Description: Return mathematical ceil(log2(n))
460
  --   n    log2()
461
  --   0 -> -oo  --> FAILURE
462
  --   1 ->  0
463
  --   2 ->  1
464
  --   3 ->  2
465
  --   4 ->  2
466
  --   5 ->  3
467
  --   6 ->  3
468
  --   7 ->  3
469
  --   8 ->  3
470
  --   9 ->  4
471
  --   etc, up to n = NATURAL'HIGH = 2**31-1
472
  BEGIN
473
    RETURN natural(integer(ceil(log2(real(n)))));
474
  END;
475
 
476
  FUNCTION ceil_log2(n : NATURAL) RETURN NATURAL IS
477
  -- Purpose: For calculating vector width of new vector 
478
  -- Description:
479
  --   Same as true_log2() except ceil_log2(1) = 1, which is needed to support
480
  --   the vector width width for 1 address, to avoid NULL array for single
481
  --   word register address.
482
  --   If n = 0, return 0 so we get a NULL array when using 
483
  --   STD_LOGIC_VECTOR(ceil_log2(g_addr_w)-1 DOWNTO 0), instead of an error.
484
  BEGIN
485
    IF n = 0 THEN
486
      RETURN 0;  -- Get NULL array
487
    ELSIF n = 1 THEN
488
      RETURN 1;  -- avoid NULL array
489
    ELSE
490
      RETURN true_log2(n);
491
    END IF;
492
  END;
493
 
494
  FUNCTION floor_log10(n : NATURAL) RETURN NATURAL IS
495
  BEGIN
496
    RETURN natural(integer(floor(log10(real(n)))));
497
  END;
498
 
499
  FUNCTION is_pow2(n : NATURAL) RETURN BOOLEAN IS
500
  BEGIN
501
    RETURN n=2**true_log2(n);
502
  END;
503
 
504
  FUNCTION true_log_pow2(n : NATURAL) RETURN NATURAL IS
505
  BEGIN
506
    RETURN 2**true_log2(n);
507
  END;
508
 
509
  FUNCTION ratio(n, d : NATURAL) RETURN NATURAL IS
510
  BEGIN
511
    IF n MOD d = 0 THEN
512
      RETURN n/d;
513
    ELSE
514
      RETURN 0;
515
    END IF;
516
  END;
517
 
518
  FUNCTION ratio2(n, m : NATURAL) RETURN NATURAL IS
519
  BEGIN
520
    RETURN largest(ratio(n,m), ratio(m,n));
521
  END;
522
 
523
  FUNCTION ceil_div(n, d : NATURAL) RETURN NATURAL IS
524
  BEGIN
525
    RETURN n/d + sel_a_b(n MOD d = 0, 0, 1);
526
  END;
527
 
528
  FUNCTION ceil_value(n, d : NATURAL) RETURN NATURAL IS
529
  BEGIN
530
    RETURN ceil_div(n, d) * d;
531
  END;
532
 
533
  FUNCTION floor_value(n, d : NATURAL) RETURN NATURAL IS
534
  BEGIN
535
    RETURN (n / d) * d;
536
  END;
537
 
538
  FUNCTION ceil_div(n : UNSIGNED; d: NATURAL) RETURN UNSIGNED IS
539
  BEGIN
540
    RETURN n/d + sel_a_b(n MOD d = 0, 0, 1);  -- "/" returns same width as n
541
  END;
542
 
543
  FUNCTION ceil_value(n : UNSIGNED; d: NATURAL) RETURN UNSIGNED IS
544
    CONSTANT w : NATURAL := n'LENGTH;
545
    VARIABLE p : UNSIGNED(2*w-1 DOWNTO 0);
546
  BEGIN
547
    p := ceil_div(n, d) * d;
548
    RETURN p(w-1 DOWNTO 0);  -- return same width as n
549
  END;
550
 
551
  FUNCTION floor_value(n : UNSIGNED; d: NATURAL) RETURN UNSIGNED IS
552
    CONSTANT w : NATURAL := n'LENGTH;
553
    VARIABLE p : UNSIGNED(2*w-1 DOWNTO 0);
554
  BEGIN
555
    p := (n / d) * d;
556
    RETURN p(w-1 DOWNTO 0);  -- return same width as n
557
  END;
558
 
559
  FUNCTION slv(n: IN STD_LOGIC) RETURN STD_LOGIC_VECTOR IS
560
    VARIABLE r : STD_LOGIC_VECTOR(0 DOWNTO 0);
561
  BEGIN
562
    r(0) := n;
563
    RETURN r;
564
  END;
565
 
566
  FUNCTION sl(n: IN STD_LOGIC_VECTOR) RETURN STD_LOGIC IS
567
    VARIABLE r : STD_LOGIC;
568
  BEGIN
569
    r := n(n'LOW);
570
    RETURN r;
571
  END;
572
 
573
  FUNCTION to_natural_arr(n : t_integer_arr; to_zero : BOOLEAN) RETURN t_natural_arr IS
574
    VARIABLE vN : t_integer_arr(n'LENGTH-1 DOWNTO 0);
575
    VARIABLE vR : t_natural_arr(n'LENGTH-1 DOWNTO 0);
576
  BEGIN
577
    vN := n;
578
    FOR I IN vN'RANGE LOOP
579
      IF to_zero=FALSE THEN
580
        vR(I) := vN(I);
581
      ELSE
582
        vR(I) := 0;
583
        IF vN(I)>0 THEN
584
          vR(I) := vN(I);
585
        END IF;
586
      END IF;
587
    END LOOP;
588
    RETURN vR;
589
  END;
590
 
591
  FUNCTION to_natural_arr(n : t_nat_natural_arr) RETURN t_natural_arr IS
592
    VARIABLE vN : t_nat_natural_arr(n'LENGTH-1 DOWNTO 0);
593
    VARIABLE vR : t_natural_arr(n'LENGTH-1 DOWNTO 0);
594
  BEGIN
595
    vN := n;
596
    FOR I IN vN'RANGE LOOP
597
      vR(I) := vN(I);
598
    END LOOP;
599
    RETURN vR;
600
  END;
601
 
602
  FUNCTION to_integer_arr(n : t_natural_arr) RETURN t_integer_arr IS
603
    VARIABLE vN : t_natural_arr(n'LENGTH-1 DOWNTO 0);
604
    VARIABLE vR : t_integer_arr(n'LENGTH-1 DOWNTO 0);
605
  BEGIN
606
    vN := n;
607
    FOR I IN vN'RANGE LOOP
608
      vR(I) := vN(I);
609
    END LOOP;
610
    RETURN vR;
611
  END;
612
 
613
  FUNCTION to_integer_arr(n : t_nat_natural_arr) RETURN t_integer_arr IS
614
    VARIABLE vN : t_natural_arr(n'LENGTH-1 DOWNTO 0);
615
  BEGIN
616
    vN := to_natural_arr(n);
617
    RETURN to_integer_arr(vN);
618
  END;
619
 
620
  FUNCTION to_slv_32_arr(n : t_integer_arr) RETURN t_slv_32_arr IS
621
    VARIABLE vN : t_integer_arr(n'LENGTH-1 DOWNTO 0);
622
    VARIABLE vR : t_slv_32_arr(n'LENGTH-1 DOWNTO 0);
623
  BEGIN
624
    vN := n;
625
    FOR I IN vN'RANGE LOOP
626
      vR(I) := TO_SVEC(vN(I), 32);
627
    END LOOP;
628
    RETURN vR;
629
  END;
630
 
631
  FUNCTION to_slv_32_arr(n : t_natural_arr) RETURN t_slv_32_arr IS
632
    VARIABLE vN : t_natural_arr(n'LENGTH-1 DOWNTO 0);
633
    VARIABLE vR : t_slv_32_arr(n'LENGTH-1 DOWNTO 0);
634
  BEGIN
635
    vN := n;
636
    FOR I IN vN'RANGE LOOP
637
      vR(I) := TO_UVEC(vN(I), 32);
638
    END LOOP;
639
    RETURN vR;
640
  END;
641
 
642
  FUNCTION vector_tree(slv : STD_LOGIC_VECTOR; operation : STRING) RETURN STD_LOGIC IS
643
    -- Linear loop to determine result takes combinatorial delay that is proportional to slv'LENGTH:
644
    --   FOR I IN slv'RANGE LOOP
645
    --     v_result := v_result OPERATION slv(I);
646
    --   END LOOP;
647
    --   RETURN v_result;
648
    -- Instead use binary tree to determine result with smallest combinatorial delay that depends on log2(slv'LENGTH)
649
    CONSTANT c_slv_w      : NATURAL := slv'LENGTH;
650
    CONSTANT c_nof_stages : NATURAL := ceil_log2(c_slv_w);
651
    CONSTANT c_w          : NATURAL := 2**c_nof_stages;  -- extend the input slv to a vector with length power of 2 to ease using binary tree
652
    TYPE t_stage_arr IS ARRAY (-1 TO c_nof_stages-1) OF STD_LOGIC_VECTOR(c_w-1 DOWNTO 0);
653
    VARIABLE v_stage_arr  : t_stage_arr;
654
    VARIABLE v_result     : STD_LOGIC := '0';
655
  BEGIN
656
    -- default any unused, the stage results will be kept in the LSBits and the last result in bit 0
657
    IF    operation="AND" THEN v_stage_arr := (OTHERS=>(OTHERS=>'1'));
658
    ELSIF operation="OR"  THEN v_stage_arr := (OTHERS=>(OTHERS=>'0'));
659
    ELSIF operation="XOR" THEN v_stage_arr := (OTHERS=>(OTHERS=>'0'));
660
    ELSE
661
      ASSERT TRUE REPORT "common_pkg: Unsupported vector_tree operation" SEVERITY FAILURE;
662
    END IF;
663
    v_stage_arr(-1)(c_slv_w-1 DOWNTO 0) := slv;  -- any unused input c_w : c_slv_w bits have void default value
664
    FOR J IN 0 TO c_nof_stages-1 LOOP
665
      FOR I IN 0 TO c_w/(2**(J+1))-1 LOOP
666
        IF    operation="AND" THEN v_stage_arr(J)(I) := v_stage_arr(J-1)(2*I) AND v_stage_arr(J-1)(2*I+1);
667
        ELSIF operation="OR"  THEN v_stage_arr(J)(I) := v_stage_arr(J-1)(2*I) OR  v_stage_arr(J-1)(2*I+1);
668
        ELSIF operation="XOR" THEN v_stage_arr(J)(I) := v_stage_arr(J-1)(2*I) XOR v_stage_arr(J-1)(2*I+1);
669
        END IF;
670
      END LOOP;
671
    END LOOP;
672
    RETURN v_stage_arr(c_nof_stages-1)(0);
673
  END;
674
 
675
  FUNCTION vector_and(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS
676
  BEGIN
677
    RETURN vector_tree(slv, "AND");
678
  END;
679
 
680
  FUNCTION vector_or(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS
681
  BEGIN
682
    RETURN vector_tree(slv, "OR");
683
  END;
684
 
685
  FUNCTION vector_xor(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS
686
  BEGIN
687
    RETURN vector_tree(slv, "XOR");
688
  END;
689
 
690
  FUNCTION vector_one_hot(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
691
    VARIABLE v_one_hot : BOOLEAN := FALSE;
692
    VARIABLE v_zeros   : STD_LOGIC_VECTOR(slv'RANGE) := (OTHERS=>'0');
693
  BEGIN
694
    FOR i IN slv'RANGE LOOP
695
      IF slv(i) = '1' THEN
696
        IF NOT(v_one_hot) THEN
697
          -- No hot bits found so far
698
          v_one_hot := TRUE;
699
        ELSE
700
          -- This is the second hot bit found; return zeros.
701
          RETURN v_zeros;
702
        END IF;
703
      END IF;
704
    END LOOP;
705
    -- No or a single hot bit found in slv; return slv.
706
    RETURN slv;
707
  END;
708
 
709
  FUNCTION andv(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS
710
  BEGIN
711
    RETURN vector_tree(slv, "AND");
712
  END;
713
 
714
  FUNCTION orv(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS
715
  BEGIN
716
    RETURN vector_tree(slv, "OR");
717
  END;
718
 
719
  FUNCTION xorv(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS
720
  BEGIN
721
    RETURN vector_tree(slv, "XOR");
722
  END;
723
 
724
  FUNCTION matrix_and(mat : t_sl_matrix; wi, wj : NATURAL) RETURN STD_LOGIC IS
725
    VARIABLE v_mat    : t_sl_matrix(0 TO wi-1, 0 TO wj-1) := mat;  -- map to fixed range
726
    VARIABLE v_result : STD_LOGIC := '1';
727
  BEGIN
728
    FOR I IN 0 TO wi-1 LOOP
729
      FOR J IN 0 TO wj-1 LOOP
730
        v_result := v_result AND v_mat(I,J);
731
      END LOOP;
732
    END LOOP;
733
    RETURN v_result;
734
  END;
735
 
736
  FUNCTION matrix_or(mat : t_sl_matrix; wi, wj : NATURAL) RETURN STD_LOGIC IS
737
    VARIABLE v_mat    : t_sl_matrix(0 TO wi-1, 0 TO wj-1) := mat;  -- map to fixed range
738
    VARIABLE v_result : STD_LOGIC := '0';
739
  BEGIN
740
    FOR I IN 0 TO wi-1 LOOP
741
      FOR J IN 0 TO wj-1 LOOP
742
        v_result := v_result OR v_mat(I,J);
743
      END LOOP;
744
    END LOOP;
745
    RETURN v_result;
746
  END;
747
 
748
  FUNCTION smallest(n, m : INTEGER) RETURN INTEGER IS
749
  BEGIN
750
    IF n < m THEN
751
      RETURN n;
752
    ELSE
753
      RETURN m;
754
    END IF;
755
  END;
756
 
757
  FUNCTION smallest(n, m, l : INTEGER) RETURN INTEGER IS
758
    VARIABLE v : NATURAL;
759
  BEGIN
760
                  v := n;
761
    IF v > m THEN v := m; END IF;
762
    IF v > l THEN v := l; END IF;
763
    RETURN v;
764
  END;
765
 
766
  FUNCTION smallest(n : t_natural_arr) RETURN NATURAL IS
767
    VARIABLE m : NATURAL := 0;
768
  BEGIN
769
    FOR I IN n'RANGE LOOP
770
      IF n(I) < m THEN
771
        m := n(I);
772
      END IF;
773
    END LOOP;
774
    RETURN m;
775
  END;
776
 
777
  FUNCTION largest(n, m : INTEGER) RETURN INTEGER IS
778
  BEGIN
779
    IF n > m THEN
780
      RETURN n;
781
    ELSE
782
      RETURN m;
783
    END IF;
784
  END;
785
 
786
  FUNCTION largest(n : t_natural_arr) RETURN NATURAL IS
787
    VARIABLE m : NATURAL := 0;
788
  BEGIN
789
    FOR I IN n'RANGE LOOP
790
      IF n(I) > m THEN
791
        m := n(I);
792
      END IF;
793
    END LOOP;
794
    RETURN m;
795
  END;
796
 
797
  FUNCTION func_sum(n : t_natural_arr) RETURN NATURAL IS
798
    VARIABLE vS : NATURAL;
799
  BEGIN
800
    vS := 0;
801
    FOR I IN n'RANGE LOOP
802
      vS := vS + n(I);
803
    END LOOP;
804
    RETURN vS;
805
  END;
806
 
807
  FUNCTION func_sum(n : t_nat_natural_arr) RETURN NATURAL IS
808
    VARIABLE vN : t_natural_arr(n'LENGTH-1 DOWNTO 0);
809
  BEGIN
810
    vN := to_natural_arr(n);
811
    RETURN func_sum(vN);
812
  END;
813
 
814
  FUNCTION func_product(n : t_natural_arr) RETURN NATURAL IS
815
    VARIABLE vP : NATURAL;
816
  BEGIN
817
    vP := 1;
818
    FOR I IN n'RANGE LOOP
819
      vP := vP * n(I);
820
    END LOOP;
821
    RETURN vP;
822
  END;
823
 
824
  FUNCTION func_product(n : t_nat_natural_arr) RETURN NATURAL IS
825
    VARIABLE vN : t_natural_arr(n'LENGTH-1 DOWNTO 0);
826
  BEGIN
827
    vN := to_natural_arr(n);
828
    RETURN func_product(vN);
829
  END;
830
 
831
  FUNCTION "+" (L, R: t_natural_arr) RETURN t_natural_arr IS
832
    CONSTANT w  : NATURAL := L'LENGTH;
833
    VARIABLE vL : t_natural_arr(w-1 DOWNTO 0);
834
    VARIABLE vR : t_natural_arr(w-1 DOWNTO 0);
835
    VARIABLE vP : t_natural_arr(w-1 DOWNTO 0);
836
  BEGIN
837
    vL := L;
838
    vR := R;
839
    FOR I IN vL'RANGE LOOP
840
      vP(I) := vL(I) + vR(I);
841
    END LOOP;
842
    RETURN vP;
843
  END;
844
 
845
  FUNCTION "+" (L: t_natural_arr; R : INTEGER) RETURN t_natural_arr IS
846
    CONSTANT w  : NATURAL := L'LENGTH;
847
    VARIABLE vL : t_natural_arr(w-1 DOWNTO 0);
848
    VARIABLE vP : t_natural_arr(w-1 DOWNTO 0);
849
  BEGIN
850
    vL := L;
851
    FOR I IN vL'RANGE LOOP
852
      vP(I) := vL(I) + R;
853
    END LOOP;
854
    RETURN vP;
855
  END;
856
 
857
  FUNCTION "+" (L: INTEGER; R : t_natural_arr) RETURN t_natural_arr IS
858
  BEGIN
859
    RETURN R + L;
860
  END;
861
 
862
  FUNCTION "-" (L, R: t_natural_arr) RETURN t_natural_arr IS
863
    CONSTANT w  : NATURAL := L'LENGTH;
864
    VARIABLE vL : t_natural_arr(w-1 DOWNTO 0);
865
    VARIABLE vR : t_natural_arr(w-1 DOWNTO 0);
866
    VARIABLE vP : t_natural_arr(w-1 DOWNTO 0);
867
  BEGIN
868
    vL := L;
869
    vR := R;
870
    FOR I IN vL'RANGE LOOP
871
      vP(I) := vL(I) - vR(I);
872
    END LOOP;
873
    RETURN vP;
874
  END;
875
 
876
  FUNCTION "-" (L, R: t_natural_arr) RETURN t_integer_arr IS
877
    CONSTANT w  : NATURAL := L'LENGTH;
878
    VARIABLE vL : t_natural_arr(w-1 DOWNTO 0);
879
    VARIABLE vR : t_natural_arr(w-1 DOWNTO 0);
880
    VARIABLE vP : t_integer_arr(w-1 DOWNTO 0);
881
  BEGIN
882
    vL := L;
883
    vR := R;
884
    FOR I IN vL'RANGE LOOP
885
      vP(I) := vL(I) - vR(I);
886
    END LOOP;
887
    RETURN vP;
888
  END;
889
 
890
  FUNCTION "-" (L: t_natural_arr; R : INTEGER) RETURN t_natural_arr IS
891
    CONSTANT w  : NATURAL := L'LENGTH;
892
    VARIABLE vL : t_natural_arr(w-1 DOWNTO 0);
893
    VARIABLE vP : t_natural_arr(w-1 DOWNTO 0);
894
  BEGIN
895
    vL := L;
896
    FOR I IN vL'RANGE LOOP
897
      vP(I) := vL(I) - R;
898
    END LOOP;
899
    RETURN vP;
900
  END;
901
 
902
  FUNCTION "-" (L: INTEGER; R : t_natural_arr) RETURN t_natural_arr IS
903
    CONSTANT w  : NATURAL := R'LENGTH;
904
    VARIABLE vR : t_natural_arr(w-1 DOWNTO 0);
905
    VARIABLE vP : t_natural_arr(w-1 DOWNTO 0);
906
  BEGIN
907
    vR := R;
908
    FOR I IN vR'RANGE LOOP
909
      vP(I) := L - vR(I);
910
    END LOOP;
911
    RETURN vP;
912
  END;
913
 
914
  FUNCTION "*" (L, R: t_natural_arr) RETURN t_natural_arr IS
915
    CONSTANT w  : NATURAL := L'LENGTH;
916
    VARIABLE vL : t_natural_arr(w-1 DOWNTO 0);
917
    VARIABLE vR : t_natural_arr(w-1 DOWNTO 0);
918
    VARIABLE vP : t_natural_arr(w-1 DOWNTO 0);
919
  BEGIN
920
    vL := L;
921
    vR := R;
922
    FOR I IN vL'RANGE LOOP
923
      vP(I) := vL(I) * vR(I);
924
    END LOOP;
925
    RETURN vP;
926
  END;
927
 
928
  FUNCTION "*" (L: t_natural_arr; R : NATURAL) RETURN t_natural_arr IS
929
    CONSTANT w  : NATURAL := L'LENGTH;
930
    VARIABLE vL : t_natural_arr(w-1 DOWNTO 0);
931
    VARIABLE vP : t_natural_arr(w-1 DOWNTO 0);
932
  BEGIN
933
    vL := L;
934
    FOR I IN vL'RANGE LOOP
935
      vP(I) := vL(I) * R;
936
    END LOOP;
937
    RETURN vP;
938
  END;
939
 
940
  FUNCTION "*" (L: NATURAL; R : t_natural_arr) RETURN t_natural_arr IS
941
  BEGIN
942
    RETURN R * L;
943
  END;
944
 
945
  FUNCTION "/" (L, R: t_natural_arr) RETURN t_natural_arr IS
946
    CONSTANT w  : NATURAL := L'LENGTH;
947
    VARIABLE vL : t_natural_arr(w-1 DOWNTO 0);
948
    VARIABLE vR : t_natural_arr(w-1 DOWNTO 0);
949
    VARIABLE vP : t_natural_arr(w-1 DOWNTO 0);
950
  BEGIN
951
    vL := L;
952
    vR := R;
953
    FOR I IN vL'RANGE LOOP
954
      vP(I) := vL(I) / vR(I);
955
    END LOOP;
956
    RETURN vP;
957
  END;
958
 
959
  FUNCTION "/" (L: t_natural_arr; R : POSITIVE) RETURN t_natural_arr IS
960
    CONSTANT w  : NATURAL := L'LENGTH;
961
    VARIABLE vL : t_natural_arr(w-1 DOWNTO 0);
962
    VARIABLE vP : t_natural_arr(w-1 DOWNTO 0);
963
  BEGIN
964
    vL := L;
965
    FOR I IN vL'RANGE LOOP
966
      vP(I) := vL(I) / R;
967
    END LOOP;
968
    RETURN vP;
969
  END;
970
 
971
  FUNCTION "/" (L: NATURAL; R : t_natural_arr) RETURN t_natural_arr IS
972
    CONSTANT w  : NATURAL := R'LENGTH;
973
    VARIABLE vR : t_natural_arr(w-1 DOWNTO 0);
974
    VARIABLE vP : t_natural_arr(w-1 DOWNTO 0);
975
  BEGIN
976
    vR := R;
977
    FOR I IN vR'RANGE LOOP
978
      vP(I) := L / vR(I);
979
    END LOOP;
980
    RETURN vP;
981
  END;
982
 
983
  FUNCTION is_true(a : STD_LOGIC) RETURN BOOLEAN   IS BEGIN IF a='1'  THEN RETURN TRUE; ELSE RETURN FALSE; END IF; END;
984
  FUNCTION is_true(a : STD_LOGIC) RETURN NATURAL   IS BEGIN IF a='1'  THEN RETURN 1;    ELSE RETURN 0;     END IF; END;
985
  FUNCTION is_true(a : BOOLEAN)   RETURN STD_LOGIC IS BEGIN IF a=TRUE THEN RETURN '1';  ELSE RETURN '0';   END IF; END;
986
  FUNCTION is_true(a : BOOLEAN)   RETURN NATURAL   IS BEGIN IF a=TRUE THEN RETURN 1;    ELSE RETURN 0;     END IF; END;
987
  FUNCTION is_true(a : INTEGER)   RETURN BOOLEAN   IS BEGIN IF a/=0   THEN RETURN TRUE; ELSE RETURN FALSE; END IF; END;
988
  FUNCTION is_true(a : INTEGER)   RETURN STD_LOGIC IS BEGIN IF a/=0   THEN RETURN '1';  ELSE RETURN '0';   END IF; END;
989
 
990
  FUNCTION sel_a_b(sel, a, b : INTEGER) RETURN INTEGER IS
991
  BEGIN
992
    IF sel /= 0 THEN
993
      RETURN a;
994
    ELSE
995
      RETURN b;
996
    END IF;
997
  END;
998
 
999
  FUNCTION sel_a_b(sel, a, b : BOOLEAN) RETURN BOOLEAN IS
1000
  BEGIN
1001
    IF sel = TRUE THEN
1002
      RETURN a;
1003
    ELSE
1004
      RETURN b;
1005
    END IF;
1006
  END;
1007
 
1008
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : INTEGER) RETURN INTEGER IS
1009
  BEGIN
1010
    IF sel = TRUE THEN
1011
      RETURN a;
1012
    ELSE
1013
      RETURN b;
1014
    END IF;
1015
  END;
1016
 
1017
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : REAL) RETURN REAL IS
1018
  BEGIN
1019
    IF sel = TRUE THEN
1020
      RETURN a;
1021
    ELSE
1022
      RETURN b;
1023
    END IF;
1024
  END;
1025
 
1026
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : STD_LOGIC) RETURN STD_LOGIC IS
1027
  BEGIN
1028
    IF sel = TRUE THEN
1029
      RETURN a;
1030
    ELSE
1031
      RETURN b;
1032
    END IF;
1033
  END;
1034
 
1035
  FUNCTION sel_a_b(sel : INTEGER; a, b : STD_LOGIC) RETURN STD_LOGIC IS
1036
  BEGIN
1037
    IF sel /= 0 THEN
1038
      RETURN a;
1039
    ELSE
1040
      RETURN b;
1041
    END IF;
1042
  END;
1043
 
1044
  FUNCTION sel_a_b(sel : INTEGER; a, b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1045
  BEGIN
1046
    IF sel /= 0 THEN
1047
      RETURN a;
1048
    ELSE
1049
      RETURN b;
1050
    END IF;
1051
  END;
1052
 
1053
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1054
  BEGIN
1055
    IF sel = TRUE THEN
1056
      RETURN a;
1057
    ELSE
1058
      RETURN b;
1059
    END IF;
1060
  END;
1061
 
1062
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : SIGNED) RETURN SIGNED IS
1063
  BEGIN
1064
    IF sel = TRUE THEN
1065
      RETURN a;
1066
    ELSE
1067
      RETURN b;
1068
    END IF;
1069
  END;
1070
 
1071
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : UNSIGNED) RETURN UNSIGNED IS
1072
  BEGIN
1073
    IF sel = TRUE THEN
1074
      RETURN a;
1075
    ELSE
1076
      RETURN b;
1077
    END IF;
1078
  END;
1079
 
1080
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_integer_arr) RETURN t_integer_arr IS
1081
  BEGIN
1082
    IF sel = TRUE THEN
1083
      RETURN a;
1084
    ELSE
1085
      RETURN b;
1086
    END IF;
1087
  END;
1088
 
1089
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_natural_arr) RETURN t_natural_arr IS
1090
  BEGIN
1091
    IF sel = TRUE THEN
1092
      RETURN a;
1093
    ELSE
1094
      RETURN b;
1095
    END IF;
1096
  END;
1097
 
1098
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_nat_integer_arr) RETURN t_nat_integer_arr IS
1099
  BEGIN
1100
    IF sel = TRUE THEN
1101
      RETURN a;
1102
    ELSE
1103
      RETURN b;
1104
    END IF;
1105
  END;
1106
 
1107
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_nat_natural_arr) RETURN t_nat_natural_arr IS
1108
  BEGIN
1109
    IF sel = TRUE THEN
1110
      RETURN a;
1111
    ELSE
1112
      RETURN b;
1113
    END IF;
1114
  END;
1115
 
1116
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : STRING) RETURN STRING IS
1117
  BEGIN
1118
    IF sel = TRUE THEN
1119
      RETURN a;
1120
    ELSE
1121
      RETURN b;
1122
    END IF;
1123
  END;
1124
 
1125
  FUNCTION sel_a_b(sel : INTEGER; a, b : STRING) RETURN STRING IS
1126
  BEGIN
1127
    IF sel /= 0 THEN
1128
      RETURN a;
1129
    ELSE
1130
      RETURN b;
1131
    END IF;
1132
  END;
1133
 
1134
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : TIME) RETURN TIME IS
1135
  BEGIN
1136
    IF sel = TRUE THEN
1137
      RETURN a;
1138
    ELSE
1139
      RETURN b;
1140
    END IF;
1141
  END;
1142
 
1143
  FUNCTION sel_a_b(sel : BOOLEAN; a, b : SEVERITY_LEVEL) RETURN SEVERITY_LEVEL IS
1144
  BEGIN
1145
    IF sel = TRUE THEN
1146
      RETURN a;
1147
    ELSE
1148
      RETURN b;
1149
    END IF;
1150
  END;
1151
 
1152
  -- sel_n : boolean
1153
  FUNCTION sel_n(sel : NATURAL; a, b, c : BOOLEAN) RETURN BOOLEAN IS
1154
    CONSTANT c_arr : t_nat_boolean_arr := (a, b, c);
1155
  BEGIN
1156
    RETURN c_arr(sel);
1157
  END;
1158
 
1159
  FUNCTION sel_n(sel : NATURAL; a, b, c, d : BOOLEAN) RETURN BOOLEAN IS
1160
    CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d);
1161
  BEGIN
1162
    RETURN c_arr(sel);
1163
  END;
1164
 
1165
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e : BOOLEAN) RETURN BOOLEAN IS
1166
    CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d, e);
1167
  BEGIN
1168
    RETURN c_arr(sel);
1169
  END;
1170
 
1171
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f : BOOLEAN) RETURN BOOLEAN IS
1172
    CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d, e, f);
1173
  BEGIN
1174
    RETURN c_arr(sel);
1175
  END;
1176
 
1177
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g : BOOLEAN) RETURN BOOLEAN IS
1178
    CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d, e, f, g);
1179
  BEGIN
1180
    RETURN c_arr(sel);
1181
  END;
1182
 
1183
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h : BOOLEAN) RETURN BOOLEAN IS
1184
    CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d, e, f, g, h);
1185
  BEGIN
1186
    RETURN c_arr(sel);
1187
  END;
1188
 
1189
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i : BOOLEAN) RETURN BOOLEAN IS
1190
    CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d, e, f, g, h, i);
1191
  BEGIN
1192
    RETURN c_arr(sel);
1193
  END;
1194
 
1195
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i, j : BOOLEAN) RETURN BOOLEAN IS
1196
    CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d, e, f, g, h, i, j);
1197
  BEGIN
1198
    RETURN c_arr(sel);
1199
  END;
1200
 
1201
  -- sel_n : integer
1202
  FUNCTION sel_n(sel : NATURAL; a, b, c : INTEGER) RETURN INTEGER IS
1203
    CONSTANT c_arr : t_nat_integer_arr := (a, b, c);
1204
  BEGIN
1205
    RETURN c_arr(sel);
1206
  END;
1207
 
1208
  FUNCTION sel_n(sel : NATURAL; a, b, c, d : INTEGER) RETURN INTEGER IS
1209
    CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d);
1210
  BEGIN
1211
    RETURN c_arr(sel);
1212
  END;
1213
 
1214
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e : INTEGER) RETURN INTEGER IS
1215
    CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d, e);
1216
  BEGIN
1217
    RETURN c_arr(sel);
1218
  END;
1219
 
1220
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f : INTEGER) RETURN INTEGER IS
1221
    CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d, e, f);
1222
  BEGIN
1223
    RETURN c_arr(sel);
1224
  END;
1225
 
1226
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g : INTEGER) RETURN INTEGER IS
1227
    CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d, e, f, g);
1228
  BEGIN
1229
    RETURN c_arr(sel);
1230
  END;
1231
 
1232
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h : INTEGER) RETURN INTEGER IS
1233
    CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d, e, f, g, h);
1234
  BEGIN
1235
    RETURN c_arr(sel);
1236
  END;
1237
 
1238
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i : INTEGER) RETURN INTEGER IS
1239
    CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d, e, f, g, h, i);
1240
  BEGIN
1241
    RETURN c_arr(sel);
1242
  END;
1243
 
1244
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i, j : INTEGER) RETURN INTEGER IS
1245
    CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d, e, f, g, h, i, j);
1246
  BEGIN
1247
    RETURN c_arr(sel);
1248
  END;
1249
 
1250
  -- sel_n : string
1251
  FUNCTION sel_n(sel : NATURAL; a, b                         : STRING) RETURN STRING IS BEGIN IF sel=0 THEN RETURN            a                         ; ELSE RETURN b; END IF; END;
1252
  FUNCTION sel_n(sel : NATURAL; a, b, c                      : STRING) RETURN STRING IS BEGIN IF sel<2 THEN RETURN sel_n(sel, a, b                     ); ELSE RETURN c; END IF; END;
1253
  FUNCTION sel_n(sel : NATURAL; a, b, c, d                   : STRING) RETURN STRING IS BEGIN IF sel<3 THEN RETURN sel_n(sel, a, b, c                  ); ELSE RETURN d; END IF; END;
1254
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e                : STRING) RETURN STRING IS BEGIN IF sel<4 THEN RETURN sel_n(sel, a, b, c, d               ); ELSE RETURN e; END IF; END;
1255
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f             : STRING) RETURN STRING IS BEGIN IF sel<5 THEN RETURN sel_n(sel, a, b, c, d, e            ); ELSE RETURN f; END IF; END;
1256
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g          : STRING) RETURN STRING IS BEGIN IF sel<6 THEN RETURN sel_n(sel, a, b, c, d, e, f         ); ELSE RETURN g; END IF; END;
1257
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h       : STRING) RETURN STRING IS BEGIN IF sel<7 THEN RETURN sel_n(sel, a, b, c, d, e, f, g      ); ELSE RETURN h; END IF; END;
1258
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i    : STRING) RETURN STRING IS BEGIN IF sel<8 THEN RETURN sel_n(sel, a, b, c, d, e, f, g, h   ); ELSE RETURN i; END IF; END;
1259
  FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i, j : STRING) RETURN STRING IS BEGIN IF sel<9 THEN RETURN sel_n(sel, a, b, c, d, e, f, g, h, i); ELSE RETURN j; END IF; END;
1260
 
1261
  FUNCTION array_init(init : STD_LOGIC; nof : NATURAL) RETURN STD_LOGIC_VECTOR IS
1262
    VARIABLE v_arr : STD_LOGIC_VECTOR(0 TO nof-1);
1263
  BEGIN
1264
    FOR I IN v_arr'RANGE LOOP
1265
      v_arr(I) := init;
1266
    END LOOP;
1267
    RETURN v_arr;
1268
  END;
1269
 
1270
  FUNCTION array_init(init, nof : NATURAL) RETURN t_natural_arr IS
1271
    VARIABLE v_arr : t_natural_arr(0 TO nof-1);
1272
  BEGIN
1273
    FOR I IN v_arr'RANGE LOOP
1274
      v_arr(I) := init;
1275
    END LOOP;
1276
    RETURN v_arr;
1277
  END;
1278
 
1279
  FUNCTION array_init(init, nof : NATURAL) RETURN t_nat_natural_arr IS
1280
    VARIABLE v_arr : t_nat_natural_arr(0 TO nof-1);
1281
  BEGIN
1282
    FOR I IN v_arr'RANGE LOOP
1283
      v_arr(I) := init;
1284
    END LOOP;
1285
    RETURN v_arr;
1286
  END;
1287
 
1288
  FUNCTION array_init(init, nof, incr : NATURAL) RETURN t_natural_arr IS
1289
    VARIABLE v_arr : t_natural_arr(0 TO nof-1);
1290
    VARIABLE v_i   : NATURAL;
1291
  BEGIN
1292
    v_i := 0;
1293
    FOR I IN v_arr'RANGE LOOP
1294
      v_arr(I) := init + v_i * incr;
1295
      v_i := v_i + 1;
1296
    END LOOP;
1297
    RETURN v_arr;
1298
  END;
1299
 
1300
  FUNCTION array_init(init, nof, incr : NATURAL) RETURN t_nat_natural_arr IS
1301
    VARIABLE v_arr : t_nat_natural_arr(0 TO nof-1);
1302
    VARIABLE v_i   : NATURAL;
1303
  BEGIN
1304
    v_i := 0;
1305
    FOR I IN v_arr'RANGE LOOP
1306
      v_arr(I) := init + v_i * incr;
1307
      v_i := v_i + 1;
1308
    END LOOP;
1309
    RETURN v_arr;
1310
  END;
1311
 
1312
  FUNCTION array_init(init, nof, incr : INTEGER) RETURN t_slv_16_arr IS
1313
    VARIABLE v_arr : t_slv_16_arr(0 TO nof-1);
1314
    VARIABLE v_i   : NATURAL;
1315
  BEGIN
1316
    v_i := 0;
1317
    FOR I IN v_arr'RANGE LOOP
1318
      v_arr(I) := TO_SVEC(init + v_i * incr, 16);
1319
      v_i := v_i + 1;
1320
    END LOOP;
1321
    RETURN v_arr;
1322
  END;
1323
 
1324
  FUNCTION array_init(init, nof, incr : INTEGER) RETURN t_slv_32_arr IS
1325
    VARIABLE v_arr : t_slv_32_arr(0 TO nof-1);
1326
    VARIABLE v_i   : NATURAL;
1327
  BEGIN
1328
    v_i := 0;
1329
    FOR I IN v_arr'RANGE LOOP
1330
      v_arr(I) := TO_SVEC(init + v_i * incr, 32);
1331
      v_i := v_i + 1;
1332
    END LOOP;
1333
    RETURN v_arr;
1334
  END;
1335
 
1336
  FUNCTION array_init(init, nof, width : NATURAL) RETURN STD_LOGIC_VECTOR IS
1337
    VARIABLE v_arr : STD_LOGIC_VECTOR(nof*width-1 DOWNTO 0);
1338
  BEGIN
1339
    FOR I IN 0 TO nof-1 LOOP
1340
      v_arr(width*(I+1)-1 DOWNTO width*I) := TO_UVEC(init, width);
1341
    END LOOP;
1342
    RETURN v_arr;
1343
  END;
1344
 
1345
  FUNCTION array_init(init, nof, width, incr : NATURAL) RETURN STD_LOGIC_VECTOR IS
1346
    VARIABLE v_arr : STD_LOGIC_VECTOR(nof*width-1 DOWNTO 0);
1347
    VARIABLE v_i   : NATURAL;
1348
  BEGIN
1349
    v_i := 0;
1350
    FOR I IN 0 TO nof-1 LOOP
1351
      v_arr(width*(I+1)-1 DOWNTO width*I) := TO_UVEC(init + v_i * incr, width);
1352
      v_i := v_i + 1;
1353
    END LOOP;
1354
    RETURN v_arr;
1355
  END;
1356
 
1357
  FUNCTION array_sinit(init :INTEGER; nof, width : NATURAL) RETURN STD_LOGIC_VECTOR IS
1358
    VARIABLE v_arr : STD_LOGIC_VECTOR(nof*width-1 DOWNTO 0);
1359
  BEGIN
1360
    FOR I IN 0 TO nof-1 LOOP
1361
      v_arr(width*(I+1)-1 DOWNTO width*I) := TO_SVEC(init, width);
1362
    END LOOP;
1363
    RETURN v_arr;
1364
  END;
1365
 
1366
  FUNCTION init_slv_64_matrix(nof_a, nof_b, k : INTEGER) RETURN t_slv_64_matrix IS
1367
    VARIABLE v_mat : t_slv_64_matrix(nof_a-1 DOWNTO 0, nof_b-1 DOWNTO 0);
1368
  BEGIN
1369
    FOR I IN 0 TO nof_a-1 LOOP
1370
      FOR J IN 0 TO nof_b-1 LOOP
1371
        v_mat(I,J) := TO_SVEC(k, 64);
1372
      END LOOP;
1373
    END LOOP;
1374
    RETURN v_mat;
1375
  END;
1376
 
1377
 
1378
  -- Support concatenation of up to 7 slv into 1 slv
1379
  FUNCTION func_slv_concat(use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a, b, c, d, e, f, g : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1380
    CONSTANT c_max_w : NATURAL := a'LENGTH + b'LENGTH + c'LENGTH + d'LENGTH + e'LENGTH + f'LENGTH + g'LENGTH;
1381
    VARIABLE v_res   : STD_LOGIC_VECTOR(c_max_w-1 DOWNTO 0) := (OTHERS=>'0');
1382
    VARIABLE v_len   : NATURAL := 0;
1383
  BEGIN
1384
    IF use_a = TRUE THEN v_res(a'LENGTH-1 + v_len DOWNTO v_len) := a; v_len := v_len + a'LENGTH; END IF;
1385
    IF use_b = TRUE THEN v_res(b'LENGTH-1 + v_len DOWNTO v_len) := b; v_len := v_len + b'LENGTH; END IF;
1386
    IF use_c = TRUE THEN v_res(c'LENGTH-1 + v_len DOWNTO v_len) := c; v_len := v_len + c'LENGTH; END IF;
1387
    IF use_d = TRUE THEN v_res(d'LENGTH-1 + v_len DOWNTO v_len) := d; v_len := v_len + d'LENGTH; END IF;
1388
    IF use_e = TRUE THEN v_res(e'LENGTH-1 + v_len DOWNTO v_len) := e; v_len := v_len + e'LENGTH; END IF;
1389
    IF use_f = TRUE THEN v_res(f'LENGTH-1 + v_len DOWNTO v_len) := f; v_len := v_len + f'LENGTH; END IF;
1390
    IF use_g = TRUE THEN v_res(g'LENGTH-1 + v_len DOWNTO v_len) := g; v_len := v_len + g'LENGTH; END IF;
1391
    RETURN v_res(v_len-1 DOWNTO 0);
1392
  END func_slv_concat;
1393
 
1394
  FUNCTION func_slv_concat(use_a, use_b, use_c, use_d, use_e, use_f : BOOLEAN; a, b, c, d, e, f : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1395
  BEGIN
1396
    RETURN func_slv_concat(use_a, use_b, use_c, use_d, use_e, use_f, FALSE, a, b, c, d, e, f, "0");
1397
  END func_slv_concat;
1398
 
1399
  FUNCTION func_slv_concat(use_a, use_b, use_c, use_d, use_e : BOOLEAN; a, b, c, d, e : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1400
  BEGIN
1401
    RETURN func_slv_concat(use_a, use_b, use_c, use_d, use_e, FALSE, FALSE, a, b, c, d, e, "0", "0");
1402
  END func_slv_concat;
1403
 
1404
  FUNCTION func_slv_concat(use_a, use_b, use_c, use_d : BOOLEAN; a, b, c, d : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1405
  BEGIN
1406
    RETURN func_slv_concat(use_a, use_b, use_c, use_d, FALSE, FALSE, FALSE, a, b, c, d, "0", "0", "0");
1407
  END func_slv_concat;
1408
 
1409
  FUNCTION func_slv_concat(use_a, use_b, use_c : BOOLEAN; a, b, c : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1410
  BEGIN
1411
    RETURN func_slv_concat(use_a, use_b, use_c, FALSE, FALSE, FALSE, FALSE, a, b, c, "0", "0", "0", "0");
1412
  END func_slv_concat;
1413
 
1414
  FUNCTION func_slv_concat(use_a, use_b : BOOLEAN; a, b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1415
  BEGIN
1416
    RETURN func_slv_concat(use_a, use_b, FALSE, FALSE, FALSE, FALSE, FALSE, a, b, "0", "0", "0", "0", "0");
1417
  END func_slv_concat;
1418
 
1419
  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w : NATURAL) RETURN NATURAL IS
1420
    VARIABLE v_len : NATURAL := 0;
1421
  BEGIN
1422
    IF use_a = TRUE THEN v_len := v_len + a_w; END IF;
1423
    IF use_b = TRUE THEN v_len := v_len + b_w; END IF;
1424
    IF use_c = TRUE THEN v_len := v_len + c_w; END IF;
1425
    IF use_d = TRUE THEN v_len := v_len + d_w; END IF;
1426
    IF use_e = TRUE THEN v_len := v_len + e_w; END IF;
1427
    IF use_f = TRUE THEN v_len := v_len + f_w; END IF;
1428
    IF use_g = TRUE THEN v_len := v_len + g_w; END IF;
1429
    RETURN v_len;
1430
  END func_slv_concat_w;
1431
 
1432
  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w : NATURAL) RETURN NATURAL IS
1433
  BEGIN
1434
    RETURN func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f, FALSE, a_w, b_w, c_w, d_w, e_w, f_w, 0);
1435
  END func_slv_concat_w;
1436
 
1437
  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e : BOOLEAN; a_w, b_w, c_w, d_w, e_w : NATURAL) RETURN NATURAL IS
1438
  BEGIN
1439
    RETURN func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, FALSE, FALSE, a_w, b_w, c_w, d_w, e_w, 0, 0);
1440
  END func_slv_concat_w;
1441
 
1442
  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d : BOOLEAN; a_w, b_w, c_w, d_w : NATURAL) RETURN NATURAL IS
1443
  BEGIN
1444
    RETURN func_slv_concat_w(use_a, use_b, use_c, use_d, FALSE, FALSE, FALSE, a_w, b_w, c_w, d_w, 0, 0, 0);
1445
  END func_slv_concat_w;
1446
 
1447
  FUNCTION func_slv_concat_w(use_a, use_b, use_c : BOOLEAN; a_w, b_w, c_w : NATURAL) RETURN NATURAL IS
1448
  BEGIN
1449
    RETURN func_slv_concat_w(use_a, use_b, use_c, FALSE, FALSE, FALSE, FALSE, a_w, b_w, c_w, 0, 0, 0, 0);
1450
  END func_slv_concat_w;
1451
 
1452
  FUNCTION func_slv_concat_w(use_a, use_b : BOOLEAN; a_w, b_w : NATURAL) RETURN NATURAL IS
1453
  BEGIN
1454
    RETURN func_slv_concat_w(use_a, use_b, FALSE, FALSE, FALSE, FALSE, FALSE, a_w, b_w, 0, 0, 0, 0, 0);
1455
  END func_slv_concat_w;
1456
 
1457
  -- extract slv
1458
  FUNCTION func_slv_extract(use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
1459
    VARIABLE v_w  : NATURAL := 0;
1460
    VARIABLE v_lo : NATURAL := 0;
1461
  BEGIN
1462
    -- if the selected slv is not used in vec, then return dummy, else return the selected slv from vec
1463
    CASE sel IS
1464
      WHEN 0 =>
1465
        IF use_a = TRUE THEN v_w := a_w; ELSE RETURN c_slv0(a_w-1 DOWNTO 0); END IF;
1466
      WHEN 1 =>
1467
        IF use_b = TRUE THEN v_w := b_w; ELSE RETURN c_slv0(b_w-1 DOWNTO 0); END IF;
1468
        IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF;
1469
      WHEN 2 =>
1470
        IF use_c = TRUE THEN v_w := c_w; ELSE RETURN c_slv0(c_w-1 DOWNTO 0); END IF;
1471
        IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF;
1472
        IF use_b = TRUE THEN v_lo := v_lo + b_w; END IF;
1473
      WHEN 3 =>
1474
        IF use_d = TRUE THEN v_w := d_w; ELSE RETURN c_slv0(d_w-1 DOWNTO 0); END IF;
1475
        IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF;
1476
        IF use_b = TRUE THEN v_lo := v_lo + b_w; END IF;
1477
        IF use_c = TRUE THEN v_lo := v_lo + c_w; END IF;
1478
      WHEN 4 =>
1479
        IF use_e = TRUE THEN v_w := e_w; ELSE RETURN c_slv0(e_w-1 DOWNTO 0); END IF;
1480
        IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF;
1481
        IF use_b = TRUE THEN v_lo := v_lo + b_w; END IF;
1482
        IF use_c = TRUE THEN v_lo := v_lo + c_w; END IF;
1483
        IF use_d = TRUE THEN v_lo := v_lo + d_w; END IF;
1484
      WHEN 5 =>
1485
        IF use_f = TRUE THEN v_w := f_w; ELSE RETURN c_slv0(f_w-1 DOWNTO 0); END IF;
1486
        IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF;
1487
        IF use_b = TRUE THEN v_lo := v_lo + b_w; END IF;
1488
        IF use_c = TRUE THEN v_lo := v_lo + c_w; END IF;
1489
        IF use_d = TRUE THEN v_lo := v_lo + d_w; END IF;
1490
        IF use_e = TRUE THEN v_lo := v_lo + e_w; END IF;
1491
      WHEN 6 =>
1492
        IF use_g = TRUE THEN v_w := g_w; ELSE RETURN c_slv0(g_w-1 DOWNTO 0); END IF;
1493
        IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF;
1494
        IF use_b = TRUE THEN v_lo := v_lo + b_w; END IF;
1495
        IF use_c = TRUE THEN v_lo := v_lo + c_w; END IF;
1496
        IF use_d = TRUE THEN v_lo := v_lo + d_w; END IF;
1497
        IF use_e = TRUE THEN v_lo := v_lo + e_w; END IF;
1498
        IF use_f = TRUE THEN v_lo := v_lo + f_w; END IF;
1499
      WHEN OTHERS => REPORT "Unknown common_pkg func_slv_extract argument" SEVERITY FAILURE;
1500
    END CASE;
1501
    RETURN vec(v_w-1 + v_lo DOWNTO v_lo);  -- extracted slv
1502
  END func_slv_extract;
1503
 
1504
  FUNCTION func_slv_extract(use_a, use_b, use_c, use_d, use_e, use_f : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
1505
  BEGIN
1506
    RETURN func_slv_extract(use_a, use_b, use_c, use_d, use_e, use_f, FALSE, a_w, b_w, c_w, d_w, e_w, f_w, 0, vec, sel);
1507
  END func_slv_extract;
1508
 
1509
  FUNCTION func_slv_extract(use_a, use_b, use_c, use_d, use_e : BOOLEAN; a_w, b_w, c_w, d_w, e_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
1510
  BEGIN
1511
    RETURN func_slv_extract(use_a, use_b, use_c, use_d, use_e, FALSE, FALSE, a_w, b_w, c_w, d_w, e_w, 0, 0, vec, sel);
1512
  END func_slv_extract;
1513
 
1514
  FUNCTION func_slv_extract(use_a, use_b, use_c, use_d : BOOLEAN; a_w, b_w, c_w, d_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
1515
  BEGIN
1516
    RETURN func_slv_extract(use_a, use_b, use_c, use_d, FALSE, FALSE, FALSE, a_w, b_w, c_w, d_w, 0, 0, 0, vec, sel);
1517
  END func_slv_extract;
1518
 
1519
  FUNCTION func_slv_extract(use_a, use_b, use_c : BOOLEAN; a_w, b_w, c_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
1520
  BEGIN
1521
    RETURN func_slv_extract(use_a, use_b, use_c, FALSE, FALSE, FALSE, FALSE, a_w, b_w, c_w, 0, 0, 0, 0, vec, sel);
1522
  END func_slv_extract;
1523
 
1524
  FUNCTION func_slv_extract(use_a, use_b : BOOLEAN; a_w, b_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
1525
  BEGIN
1526
    RETURN func_slv_extract(use_a, use_b, FALSE, FALSE, FALSE, FALSE, FALSE, a_w, b_w, 0, 0, 0, 0, 0, vec, sel);
1527
  END func_slv_extract;
1528
 
1529
 
1530
  FUNCTION TO_UINT(vec : STD_LOGIC_VECTOR) RETURN NATURAL IS
1531
  BEGIN
1532
    RETURN TO_INTEGER(UNSIGNED(vec));
1533
  END;
1534
 
1535
  FUNCTION TO_SINT(vec : STD_LOGIC_VECTOR) RETURN INTEGER IS
1536
  BEGIN
1537
    RETURN TO_INTEGER(SIGNED(vec));
1538
  END;
1539
 
1540
  FUNCTION TO_UVEC(dec, w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1541
  BEGIN
1542
    RETURN STD_LOGIC_VECTOR(TO_UNSIGNED(dec, w));
1543
  END;
1544
 
1545
  FUNCTION TO_SVEC(dec, w : INTEGER) RETURN STD_LOGIC_VECTOR IS
1546
  BEGIN
1547
    RETURN STD_LOGIC_VECTOR(TO_SIGNED(dec, w));
1548
  END;
1549
 
1550
  FUNCTION TO_SVEC_32(dec : INTEGER) RETURN STD_LOGIC_VECTOR IS
1551
  BEGIN
1552
    RETURN TO_SVEC(dec, 32);
1553
  END;
1554
 
1555
  FUNCTION RESIZE_NUM(u : UNSIGNED; w : NATURAL) RETURN UNSIGNED IS
1556
  BEGIN
1557
    -- left extend with '0' or keep LS part (same as RESIZE for UNSIGNED)
1558
    RETURN RESIZE(u, w);
1559
  END;
1560
 
1561
  FUNCTION RESIZE_NUM(s : SIGNED; w : NATURAL) RETURN SIGNED IS
1562
  BEGIN
1563
    -- extend sign bit or keep LS part
1564
    IF w>s'LENGTH THEN
1565
      RETURN RESIZE(s, w);                    -- extend sign bit
1566
    ELSE
1567
      RETURN SIGNED(RESIZE(UNSIGNED(s), w));  -- keep LSbits (= vec[w-1:0])
1568
    END IF;
1569
  END;
1570
 
1571
  FUNCTION RESIZE_UVEC(sl : STD_LOGIC; w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1572
    VARIABLE v_slv0 : STD_LOGIC_VECTOR(w-1 DOWNTO 1) := (OTHERS=>'0');
1573
  BEGIN
1574
    RETURN v_slv0 & sl;
1575
  END;
1576
 
1577
  FUNCTION RESIZE_UVEC(vec : STD_LOGIC_VECTOR; w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1578
  BEGIN
1579
    RETURN STD_LOGIC_VECTOR(RESIZE_NUM(UNSIGNED(vec), w));
1580
  END;
1581
 
1582
  FUNCTION RESIZE_SVEC(vec : STD_LOGIC_VECTOR; w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1583
  BEGIN
1584
    RETURN STD_LOGIC_VECTOR(RESIZE_NUM(SIGNED(vec), w));
1585
  END;
1586
 
1587
  FUNCTION RESIZE_UINT(u : INTEGER; w : NATURAL) RETURN INTEGER IS
1588
    VARIABLE v : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
1589
  BEGIN
1590
    v := TO_UVEC(u, c_word_w);
1591
    RETURN TO_UINT(v(w-1 DOWNTO 0));
1592
  END;
1593
 
1594
  FUNCTION RESIZE_SINT(s : INTEGER; w : NATURAL) RETURN INTEGER IS
1595
    VARIABLE v : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
1596
  BEGIN
1597
    v := TO_SVEC(s, c_word_w);
1598
    RETURN TO_SINT(v(w-1 DOWNTO 0));
1599
  END;
1600
 
1601
  FUNCTION RESIZE_UVEC_32(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1602
  BEGIN
1603
    RETURN RESIZE_UVEC(vec, 32);
1604
  END;
1605
 
1606
  FUNCTION RESIZE_SVEC_32(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1607
  BEGIN
1608
    RETURN RESIZE_SVEC(vec, 32);
1609
  END;
1610
 
1611
  FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : INTEGER) RETURN STD_LOGIC_VECTOR IS
1612
    VARIABLE v_dec : INTEGER;
1613
  BEGIN
1614
    IF dec < 0 THEN
1615
      v_dec := -dec;
1616
      RETURN STD_LOGIC_VECTOR(UNSIGNED(vec) - v_dec);  -- uses function "-" (L : UNSIGNED, R : NATURAL), there is no function + with R : INTEGER argument
1617
    ELSE
1618
      v_dec := dec;
1619
      RETURN STD_LOGIC_VECTOR(UNSIGNED(vec) + v_dec);  -- uses function "+" (L : UNSIGNED, R : NATURAL)
1620
    END IF;
1621
  END;
1622
 
1623
  FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : UNSIGNED) RETURN STD_LOGIC_VECTOR IS
1624
  BEGIN
1625
    RETURN STD_LOGIC_VECTOR(UNSIGNED(vec) + dec);
1626
  END;
1627
 
1628
  FUNCTION INCR_SVEC(vec : STD_LOGIC_VECTOR; dec : INTEGER) RETURN STD_LOGIC_VECTOR IS
1629
    VARIABLE v_dec : INTEGER;
1630
  BEGIN
1631
    RETURN STD_LOGIC_VECTOR(SIGNED(vec) + v_dec);  -- uses function "+" (L : SIGNED, R : INTEGER)
1632
  END;
1633
 
1634
  FUNCTION INCR_SVEC(vec : STD_LOGIC_VECTOR; dec : SIGNED) RETURN STD_LOGIC_VECTOR IS
1635
  BEGIN
1636
    RETURN STD_LOGIC_VECTOR(SIGNED(vec) + dec);
1637
  END;
1638
 
1639
  FUNCTION ADD_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1640
  BEGIN
1641
    RETURN STD_LOGIC_VECTOR(RESIZE_NUM(SIGNED(l_vec), res_w) + SIGNED(r_vec));
1642
  END;
1643
 
1644
  FUNCTION SUB_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1645
  BEGIN
1646
    RETURN STD_LOGIC_VECTOR(RESIZE_NUM(SIGNED(l_vec), res_w) - SIGNED(r_vec));
1647
  END;
1648
 
1649
  FUNCTION ADD_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1650
  BEGIN
1651
    RETURN STD_LOGIC_VECTOR(RESIZE_NUM(UNSIGNED(l_vec), res_w) + UNSIGNED(r_vec));
1652
  END;
1653
 
1654
  FUNCTION SUB_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1655
  BEGIN
1656
    RETURN STD_LOGIC_VECTOR(RESIZE_NUM(UNSIGNED(l_vec), res_w) - UNSIGNED(r_vec));
1657
  END;
1658
 
1659
 
1660
  FUNCTION ADD_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1661
  BEGIN
1662
    RETURN ADD_SVEC(l_vec, r_vec, l_vec'LENGTH);
1663
  END;
1664
 
1665
  FUNCTION SUB_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1666
  BEGIN
1667
    RETURN SUB_SVEC(l_vec, r_vec, l_vec'LENGTH);
1668
  END;
1669
 
1670
  FUNCTION ADD_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1671
  BEGIN
1672
    RETURN ADD_UVEC(l_vec, r_vec, l_vec'LENGTH);
1673
  END;
1674
 
1675
  FUNCTION SUB_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1676
  BEGIN
1677
    RETURN SUB_UVEC(l_vec, r_vec, l_vec'LENGTH);
1678
  END;
1679
 
1680
  FUNCTION COMPLEX_MULT_REAL(a_re, a_im, b_re, b_im : INTEGER) RETURN INTEGER IS
1681
  BEGIN
1682
    RETURN (a_re*b_re - a_im*b_im);
1683
  END;
1684
 
1685
  FUNCTION COMPLEX_MULT_IMAG(a_re, a_im, b_re, b_im : INTEGER) RETURN INTEGER IS
1686
  BEGIN
1687
    RETURN (a_im*b_re + a_re*b_im);
1688
  END;
1689
 
1690
  FUNCTION SHIFT_UVEC(vec : STD_LOGIC_VECTOR; shift : INTEGER) RETURN STD_LOGIC_VECTOR IS
1691
  BEGIN
1692
    IF shift < 0 THEN
1693
      RETURN STD_LOGIC_VECTOR(SHIFT_LEFT(UNSIGNED(vec), -shift));  -- fill zeros from right
1694
    ELSE
1695
      RETURN STD_LOGIC_VECTOR(SHIFT_RIGHT(UNSIGNED(vec), shift));  -- fill zeros from left
1696
    END IF;
1697
  END;
1698
 
1699
  FUNCTION SHIFT_SVEC(vec : STD_LOGIC_VECTOR; shift : INTEGER) RETURN STD_LOGIC_VECTOR IS
1700
  BEGIN
1701
    IF shift < 0 THEN
1702
      RETURN STD_LOGIC_VECTOR(SHIFT_LEFT(SIGNED(vec), -shift));  -- same as SHIFT_LEFT for UNSIGNED
1703
    ELSE
1704
      RETURN STD_LOGIC_VECTOR(SHIFT_RIGHT(SIGNED(vec), shift));  -- extend sign
1705
    END IF;
1706
  END;
1707
 
1708
  --
1709
  -- offset_binary() : maps offset binary to or from two-complement binary.
1710
  --
1711
  --   National ADC08DC1020     offset binary     two-complement binary
1712
  --   + full scale =  127.5 :  11111111 = 255     127 = 01111111
1713
  --     ...                                  
1714
  --   +            =   +0.5 :  10000000 = 128       0 = 00000000
1715
  --   0
1716
  --   -            =   -0.5 :  01111111 = 127      -1 = 11111111
1717
  --     ...                                  
1718
  --   - full scale = -127.5 :  00000000 =   0    -128 = 10000000
1719
  --
1720
  -- To map between the offset binary and two complement binary involves
1721
  -- adding 128 to the binary value or equivalently inverting the sign bit.
1722
  -- The offset_binary() mapping can be done and undone both ways.
1723
  -- The offset_binary() mapping to two-complement binary yields a DC offset
1724
  -- of -0.5 Lsb.
1725
  FUNCTION offset_binary(a : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1726
    VARIABLE v_res : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0) := a;
1727
  BEGIN
1728
   v_res(v_res'HIGH) := NOT v_res(v_res'HIGH);  -- invert MSbit to get to from offset binary to two's complement, or vice versa
1729
   RETURN v_res;
1730
  END;
1731
 
1732
  FUNCTION truncate(vec : STD_LOGIC_VECTOR; n : NATURAL) RETURN STD_LOGIC_VECTOR IS
1733
    CONSTANT c_vec_w   : NATURAL := vec'LENGTH;
1734
    CONSTANT c_trunc_w : NATURAL := c_vec_w-n;
1735
    VARIABLE v_vec     : STD_LOGIC_VECTOR(c_vec_w-1 DOWNTO 0) := vec;
1736
    VARIABLE v_res     : STD_LOGIC_VECTOR(c_trunc_w-1 DOWNTO 0);
1737
  BEGIN
1738
   v_res := v_vec(c_vec_w-1 DOWNTO n);  -- keep MS part
1739
   RETURN v_res;
1740
  END;
1741
 
1742
  FUNCTION truncate_and_resize_uvec(vec : STD_LOGIC_VECTOR; n, w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1743
    CONSTANT c_vec_w   : NATURAL := vec'LENGTH;
1744
    CONSTANT c_trunc_w : NATURAL := c_vec_w-n;
1745
    VARIABLE v_trunc   : STD_LOGIC_VECTOR(c_trunc_w-1 DOWNTO 0);
1746
    VARIABLE v_res     : STD_LOGIC_VECTOR(w-1 DOWNTO 0);
1747
  BEGIN
1748
    v_trunc := truncate(vec, n);       -- first keep MS part
1749
    v_res := RESIZE_UVEC(v_trunc, w);  -- then keep LS part or left extend with '0'
1750
    RETURN v_res;
1751
  END;
1752
 
1753
  FUNCTION truncate_and_resize_svec(vec : STD_LOGIC_VECTOR; n, w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1754
    CONSTANT c_vec_w   : NATURAL := vec'LENGTH;
1755
    CONSTANT c_trunc_w : NATURAL := c_vec_w-n;
1756
    VARIABLE v_trunc   : STD_LOGIC_VECTOR(c_trunc_w-1 DOWNTO 0);
1757
    VARIABLE v_res     : STD_LOGIC_VECTOR(w-1 DOWNTO 0);
1758
  BEGIN
1759
    v_trunc := truncate(vec, n);       -- first keep MS part
1760
    v_res := RESIZE_SVEC(v_trunc, w);  -- then keep sign bit and LS part or left extend sign bit
1761
    RETURN v_res;
1762
  END;
1763
 
1764
  FUNCTION scale(vec : STD_LOGIC_VECTOR; n: NATURAL) RETURN STD_LOGIC_VECTOR IS
1765
    CONSTANT c_vec_w   : NATURAL := vec'LENGTH;
1766
    CONSTANT c_scale_w : NATURAL := c_vec_w+n;
1767
    VARIABLE v_res     : STD_LOGIC_VECTOR(c_scale_w-1 DOWNTO 0) := (OTHERS=>'0');
1768
  BEGIN
1769
    v_res(c_scale_w-1 DOWNTO n) := vec;  -- scale by adding n zero bits at the right
1770
    RETURN v_res;
1771
  END;
1772
 
1773
  FUNCTION scale_and_resize_uvec(vec : STD_LOGIC_VECTOR; n, w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1774
    CONSTANT c_vec_w   : NATURAL := vec'LENGTH;
1775
    CONSTANT c_scale_w : NATURAL := c_vec_w+n;
1776
    VARIABLE v_scale   : STD_LOGIC_VECTOR(c_scale_w-1 DOWNTO 0) := (OTHERS=>'0');
1777
    VARIABLE v_res     : STD_LOGIC_VECTOR(w-1 DOWNTO 0);
1778
  BEGIN
1779
    v_scale(c_scale_w-1 DOWNTO n) := vec;  -- first scale by adding n zero bits at the right
1780
    v_res := RESIZE_UVEC(v_scale, w);      -- then keep LS part or left extend with '0'
1781
    RETURN v_res;
1782
  END;
1783
 
1784
  FUNCTION scale_and_resize_svec(vec : STD_LOGIC_VECTOR; n, w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1785
    CONSTANT c_vec_w   : NATURAL := vec'LENGTH;
1786
    CONSTANT c_scale_w : NATURAL := c_vec_w+n;
1787
    VARIABLE v_scale   : STD_LOGIC_VECTOR(c_scale_w-1 DOWNTO 0) := (OTHERS=>'0');
1788
    VARIABLE v_res     : STD_LOGIC_VECTOR(w-1 DOWNTO 0);
1789
  BEGIN
1790
    v_scale(c_scale_w-1 DOWNTO n) := vec;  -- first scale by adding n zero bits at the right
1791
    v_res := RESIZE_SVEC(v_scale, w);      -- then keep LS part or left extend sign bit
1792
    RETURN v_res;
1793
  END;
1794
 
1795
  FUNCTION truncate_or_resize_uvec(vec : STD_LOGIC_VECTOR; b : BOOLEAN; w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1796
    CONSTANT c_vec_w : NATURAL := vec'LENGTH;
1797
    VARIABLE c_n     : INTEGER := c_vec_w-w;
1798
    VARIABLE v_res   : STD_LOGIC_VECTOR(w-1 DOWNTO 0);
1799
  BEGIN
1800
    IF b=TRUE AND c_n>0 THEN
1801
      v_res := truncate_and_resize_uvec(vec, c_n, w);
1802
    ELSE
1803
      v_res := RESIZE_UVEC(vec, w);
1804
    END IF;
1805
    RETURN v_res;
1806
  END;
1807
 
1808
  FUNCTION truncate_or_resize_svec(vec : STD_LOGIC_VECTOR; b : BOOLEAN; w : NATURAL) RETURN STD_LOGIC_VECTOR IS
1809
    CONSTANT c_vec_w : NATURAL := vec'LENGTH;
1810
    VARIABLE c_n     : INTEGER := c_vec_w-w;
1811
    VARIABLE v_res   : STD_LOGIC_VECTOR(w-1 DOWNTO 0);
1812
  BEGIN
1813
    IF b=TRUE AND c_n>0 THEN
1814
      v_res := truncate_and_resize_svec(vec, c_n, w);
1815
    ELSE
1816
      v_res := RESIZE_SVEC(vec, w);
1817
    END IF;
1818
    RETURN v_res;
1819
  END;
1820
 
1821
 
1822
  -- Functions s_round, s_round_up and u_round:
1823
  --
1824
  -- . The returned output width is input width - n.
1825
  -- . If n=0 then the return value is the same as the input value so only
1826
  --   wires (NOP, no operation).
1827
  -- . Both have the same implementation but different c_max and c_clip values.
1828
  -- . Round up for unsigned so +2.5 becomes 3
1829
  -- . Round away from zero for signed so round up for positive and round down for negative, so +2.5 becomes 3 and -2.5 becomes -3.
1830
  -- . Round away from zero is also used by round() in Matlab, Python, TCL
1831
  -- . Rounding up implies adding 0.5 and then truncation, use clip = TRUE to
1832
  --   clip the potential overflow due to adding 0.5 to +max.
1833
  -- . For negative values overflow due to rounding can not occur, because c_half-1 >= 0 for n>0
1834
  -- . If the input comes from a product and is rounded to the input width then
1835
  --   clip can safely be FALSE, because e.g. for unsigned 4b*4b=8b->4b the
1836
  --   maximum product is 15*15=225 <= 255-8, and for signed 4b*4b=8b->4b the
1837
  --   maximum product is -8*-8=+64 <= 127-8, so wrapping due to rounding
1838
  --   overflow will never occur.
1839
 
1840
  FUNCTION s_round(vec : STD_LOGIC_VECTOR; n : NATURAL; clip : BOOLEAN) RETURN STD_LOGIC_VECTOR IS
1841
    -- Use SIGNED to avoid NATURAL (32 bit range) overflow error
1842
    CONSTANT c_in_w  : NATURAL := vec'LENGTH;
1843
    CONSTANT c_out_w : NATURAL := vec'LENGTH - n;
1844
    CONSTANT c_one   : SIGNED(c_in_w-1 DOWNTO 0) := TO_SIGNED(1, c_in_w);
1845
    CONSTANT c_half  : SIGNED(c_in_w-1 DOWNTO 0) := SHIFT_LEFT(c_one, n-1);                            -- = 2**(n-1)
1846
    CONSTANT c_max   : SIGNED(c_in_w-1 DOWNTO 0) := SIGNED('0' & c_slv1(c_in_w-2 DOWNTO 0)) - c_half;  -- = 2**(c_in_w-1)-1 - c_half  
1847
    CONSTANT c_clip  : SIGNED(c_out_w-1 DOWNTO 0) := SIGNED('0' & c_slv1(c_out_w-2 DOWNTO 0));         -- = 2**(c_out_w-1)-1
1848
    VARIABLE v_in    : SIGNED(c_in_w-1 DOWNTO 0);
1849
    VARIABLE v_out   : SIGNED(c_out_w-1 DOWNTO 0);
1850
  BEGIN
1851
    v_in := SIGNED(vec);
1852
    IF n > 0 THEN
1853
      IF clip = TRUE AND v_in > c_max THEN
1854
        v_out := c_clip;                                              -- Round clip to maximum positive to avoid wrap to negative
1855
      ELSE
1856
        IF vec(vec'HIGH)='0' THEN
1857
          v_out := RESIZE_NUM(SHIFT_RIGHT(v_in + c_half + 0, n), c_out_w);  -- Round up for positive
1858
        ELSE
1859
          v_out := RESIZE_NUM(SHIFT_RIGHT(v_in + c_half - 1, n), c_out_w);  -- Round down for negative
1860
        END IF;
1861
      END IF;
1862
    ELSE
1863
      v_out := RESIZE_NUM(v_in, c_out_w);                             -- NOP
1864
    END IF;
1865
    RETURN STD_LOGIC_VECTOR(v_out);
1866
  END;
1867
 
1868
  FUNCTION s_round(vec : STD_LOGIC_VECTOR; n : NATURAL) RETURN STD_LOGIC_VECTOR IS
1869
  BEGIN
1870
    RETURN s_round(vec, n, FALSE);  -- no round clip
1871
  END;
1872
 
1873
  -- An alternative is to always round up, also for negative numbers (i.e. s_round_up = u_round).
1874
  FUNCTION s_round_up(vec : STD_LOGIC_VECTOR; n : NATURAL; clip : BOOLEAN) RETURN STD_LOGIC_VECTOR IS
1875
  BEGIN
1876
    RETURN u_round(vec, n, clip);
1877
  END;
1878
 
1879
  FUNCTION s_round_up(vec : STD_LOGIC_VECTOR; n : NATURAL) RETURN STD_LOGIC_VECTOR IS
1880
  BEGIN
1881
    RETURN u_round(vec, n, FALSE);  -- no round clip
1882
  END;
1883
 
1884
  -- Unsigned numbers are round up (almost same as s_round, but without the else on negative vec)
1885
  FUNCTION u_round(vec : STD_LOGIC_VECTOR; n : NATURAL; clip : BOOLEAN ) RETURN STD_LOGIC_VECTOR IS
1886
    -- Use UNSIGNED to avoid NATURAL (32 bit range) overflow error
1887
    CONSTANT c_in_w  : NATURAL := vec'LENGTH;
1888
    CONSTANT c_out_w : NATURAL := vec'LENGTH - n;
1889
    CONSTANT c_one   : UNSIGNED(c_in_w-1 DOWNTO 0) := TO_UNSIGNED(1, c_in_w);
1890
    CONSTANT c_half  : UNSIGNED(c_in_w-1 DOWNTO 0) := SHIFT_LEFT(c_one, n-1);                        -- = 2**(n-1)
1891
    CONSTANT c_max   : UNSIGNED(c_in_w-1 DOWNTO 0) := UNSIGNED(c_slv1(c_in_w-1 DOWNTO 0)) - c_half;  -- = 2**c_in_w-1 - c_half  
1892
    CONSTANT c_clip  : UNSIGNED(c_out_w-1 DOWNTO 0) := UNSIGNED(c_slv1(c_out_w-1 DOWNTO 0));         -- = 2**c_out_w-1
1893
    VARIABLE v_in    : UNSIGNED(c_in_w-1 DOWNTO 0);
1894
    VARIABLE v_out   : UNSIGNED(c_out_w-1 DOWNTO 0);
1895
  BEGIN
1896
    v_in := UNSIGNED(vec);
1897
    IF n > 0 THEN
1898
      IF clip = TRUE AND v_in > c_max THEN
1899
        v_out := c_clip;                                              -- Round clip to +max to avoid wrap to 0
1900
      ELSE
1901
        v_out := RESIZE_NUM(SHIFT_RIGHT(v_in + c_half, n), c_out_w);  -- Round up
1902
      END IF;
1903
    ELSE
1904
      v_out := RESIZE_NUM(v_in, c_out_w);                             -- NOP
1905
    END IF;
1906
    RETURN STD_LOGIC_VECTOR(v_out);
1907
  END;
1908
 
1909
  FUNCTION u_round(vec : STD_LOGIC_VECTOR; n : NATURAL) RETURN STD_LOGIC_VECTOR IS
1910
  BEGIN
1911
    RETURN u_round(vec, n, FALSE);  -- no round clip
1912
  END;
1913
 
1914
 
1915
  FUNCTION hton(a : STD_LOGIC_VECTOR; w, sz : NATURAL) RETURN STD_LOGIC_VECTOR IS
1916
    VARIABLE v_a : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0) := a;  -- map a to range [h:0]
1917
    VARIABLE v_b : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0) := a;  -- default b = a
1918
    VARIABLE vL  : NATURAL;
1919
    VARIABLE vK  : NATURAL;
1920
  BEGIN
1921
    -- Note:
1922
    -- . if sz = 1          then v_b = v_a
1923
    -- . if a'LENGTH > sz*w then v_b(a'LENGTH:sz*w) = v_a(a'LENGTH:sz*w)
1924
    FOR vL IN 0 TO sz-1 LOOP
1925
      vK := sz-1 - vL;
1926
      v_b((vL+1)*w-1 DOWNTO vL*w) := v_a((vK+1)*w-1 DOWNTO vK*w);
1927
    END LOOP;
1928
    RETURN v_b;
1929
  END FUNCTION;
1930
 
1931
  FUNCTION hton(a : STD_LOGIC_VECTOR; sz : NATURAL) RETURN STD_LOGIC_VECTOR IS
1932
  BEGIN
1933
    RETURN hton(a, c_byte_w, sz);  -- symbol width w = c_byte_w = 8
1934
  END FUNCTION;
1935
 
1936
  FUNCTION hton(a : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1937
    CONSTANT c_sz : NATURAL := a'LENGTH/ c_byte_w;
1938
  BEGIN
1939
    RETURN hton(a, c_byte_w, c_sz);  -- symbol width w = c_byte_w = 8
1940
  END FUNCTION;
1941
 
1942
  FUNCTION ntoh(a : STD_LOGIC_VECTOR; sz : NATURAL) RETURN STD_LOGIC_VECTOR IS
1943
  BEGIN
1944
    RETURN hton(a, sz);  -- i.e. ntoh() = hton()
1945
  END FUNCTION;
1946
 
1947
  FUNCTION ntoh(a : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1948
  BEGIN
1949
    RETURN hton(a);  -- i.e. ntoh() = hton()
1950
  END FUNCTION;
1951
 
1952
  FUNCTION flip(a : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
1953
    VARIABLE v_a : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0) := a;
1954
    VARIABLE v_b : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0);
1955
  BEGIN
1956
    FOR I IN v_a'RANGE LOOP
1957
      v_b(a'LENGTH-1-I) := v_a(I);
1958
    END LOOP;
1959
    RETURN v_b;
1960
  END;
1961
 
1962
  FUNCTION flip(a, w : NATURAL) RETURN NATURAL IS
1963
  BEGIN
1964
    RETURN TO_UINT(flip(TO_UVEC(a, w)));
1965
  END;
1966
 
1967
  FUNCTION flip(a : t_slv_32_arr) RETURN t_slv_32_arr IS
1968
    VARIABLE v_a : t_slv_32_arr(a'LENGTH-1 DOWNTO 0) := a;
1969
    VARIABLE v_b : t_slv_32_arr(a'LENGTH-1 DOWNTO 0);
1970
  BEGIN
1971
    FOR I IN v_a'RANGE LOOP
1972
      v_b(a'LENGTH-1-I) := v_a(I);
1973
    END LOOP;
1974
    RETURN v_b;
1975
  END;
1976
 
1977
  FUNCTION flip(a : t_integer_arr) RETURN t_integer_arr IS
1978
    VARIABLE v_a : t_integer_arr(a'LENGTH-1 DOWNTO 0) := a;
1979
    VARIABLE v_b : t_integer_arr(a'LENGTH-1 DOWNTO 0);
1980
  BEGIN
1981
    FOR I IN v_a'RANGE LOOP
1982
      v_b(a'LENGTH-1-I) := v_a(I);
1983
    END LOOP;
1984
    RETURN v_b;
1985
  END;
1986
 
1987
  FUNCTION flip(a : t_natural_arr) RETURN t_natural_arr IS
1988
    VARIABLE v_a : t_natural_arr(a'LENGTH-1 DOWNTO 0) := a;
1989
    VARIABLE v_b : t_natural_arr(a'LENGTH-1 DOWNTO 0);
1990
  BEGIN
1991
    FOR I IN v_a'RANGE LOOP
1992
      v_b(a'LENGTH-1-I) := v_a(I);
1993
    END LOOP;
1994
    RETURN v_b;
1995
  END;
1996
 
1997
  FUNCTION flip(a : t_nat_natural_arr) RETURN t_nat_natural_arr IS
1998
    VARIABLE v_a : t_nat_natural_arr(a'LENGTH-1 DOWNTO 0) := a;
1999
    VARIABLE v_b : t_nat_natural_arr(a'LENGTH-1 DOWNTO 0);
2000
  BEGIN
2001
    FOR I IN v_a'RANGE LOOP
2002
      v_b(a'LENGTH-1-I) := v_a(I);
2003
    END LOOP;
2004
    RETURN v_b;
2005
  END;
2006
 
2007
  FUNCTION transpose(a : STD_LOGIC_VECTOR; row, col : NATURAL) RETURN STD_LOGIC_VECTOR IS
2008
    VARIABLE vIn  : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0);
2009
    VARIABLE vOut : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0);
2010
  BEGIN
2011
    vIn  := a;    -- map input vector to h:0 range
2012
    vOut := vIn;  -- default leave any unused MSbits the same
2013
    FOR J IN 0 TO row-1 LOOP
2014
      FOR I IN 0 TO col-1 LOOP
2015
        vOut(J*col + I) := vIn(I*row + J);  -- transpose vector, map input index [i*row+j] to output index [j*col+i]
2016
      END LOOP;
2017
    END LOOP;
2018
    RETURN vOut;
2019
  END FUNCTION;
2020
 
2021
  FUNCTION transpose(a, row, col : NATURAL) RETURN NATURAL IS  -- transpose index a = [i*row+j] to output index [j*col+i]
2022
    VARIABLE vI  : NATURAL;
2023
    VARIABLE vJ  : NATURAL;
2024
  BEGIN
2025
    vI := a / row;
2026
    vJ := a MOD row;
2027
    RETURN vJ * col + vI;
2028
  END;
2029
 
2030
  FUNCTION split_w(input_w: NATURAL; min_out_w: NATURAL; max_out_w: NATURAL) RETURN NATURAL IS -- Calculate input_w in multiples as close as possible to max_out_w
2031
    -- Examples: split_w(256, 8, 32) = 32;  split_w(16, 8, 32) = 16; split_w(72, 8, 32) = 18;    -- Input_w must be multiple of 2.
2032
    VARIABLE r: NATURAL;
2033
  BEGIN
2034
    r := input_w;
2035
    FOR i IN 1 TO ceil_log2(input_w) LOOP -- Useless to divide the number beyond this       
2036
      IF r <= max_out_w AND r >= min_out_w THEN
2037
        RETURN r;
2038
      ELSIF i = ceil_log2(input_w) THEN -- last iteration
2039
        RETURN 0; -- Indicates wrong values were used
2040
      END IF;
2041
      r := r / 2;
2042
    END LOOP;
2043
  END;
2044
 
2045
  FUNCTION pad(str: STRING; width: NATURAL; pad_char: CHARACTER) RETURN STRING IS
2046
    VARIABLE v_str : STRING(1 TO width) := (OTHERS => pad_char);
2047
  BEGIN
2048
    v_str(width-str'LENGTH+1 TO width) := str;
2049
    RETURN v_str;
2050
  END;
2051
 
2052
  FUNCTION slice_up(str: STRING; width: NATURAL; i: NATURAL) RETURN STRING IS
2053
  BEGIN
2054
    RETURN str(i*width+1 TO (i+1)*width);
2055
  END;
2056
 
2057
  -- If the input value is not a multiple of the desired width, the return value is padded with
2058
  -- the passed pad value. E.g. if input='10' and desired width is 4, return value is '0010'.
2059
  FUNCTION slice_up(str: STRING; width: NATURAL; i: NATURAL; pad_char: CHARACTER) RETURN STRING IS
2060
    VARIABLE padded_str : STRING(1 TO width) := (OTHERS=>'0');
2061
  BEGIN
2062
    padded_str := pad(str(i*width+1 TO (i+1)*width), width, '0');
2063
    RETURN padded_str;
2064
  END;
2065
 
2066
  FUNCTION slice_dn(str: STRING; width: NATURAL; i: NATURAL) RETURN STRING IS
2067
  BEGIN
2068
    RETURN str((i+1)*width-1 DOWNTO i*width);
2069
  END;
2070
 
2071
 
2072
  FUNCTION nat_arr_to_concat_slv(nat_arr: t_natural_arr; nof_elements: NATURAL) RETURN STD_LOGIC_VECTOR IS
2073
    VARIABLE v_concat_slv : STD_LOGIC_VECTOR(nof_elements*32-1 DOWNTO 0) := (OTHERS=>'0');
2074
  BEGIN
2075
    FOR i IN 0 TO nof_elements-1 LOOP
2076
      v_concat_slv(i*32+32-1 DOWNTO i*32) :=  TO_UVEC(nat_arr(i), 32);
2077
    END LOOP;
2078
    RETURN v_concat_slv;
2079
  END;
2080
 
2081
 
2082
  ------------------------------------------------------------------------------
2083
  -- common_fifo_*  
2084
  ------------------------------------------------------------------------------
2085
 
2086
  PROCEDURE proc_common_fifo_asserts (CONSTANT c_fifo_name   : IN STRING;
2087
                                      CONSTANT c_note_is_ful : IN BOOLEAN;
2088
                                      CONSTANT c_fail_rd_emp : IN BOOLEAN;
2089
                                      SIGNAL   wr_rst        : IN STD_LOGIC;
2090
                                      SIGNAL   wr_clk        : IN STD_LOGIC;
2091
                                      SIGNAL   wr_full       : IN STD_LOGIC;
2092
                                      SIGNAL   wr_en         : IN STD_LOGIC;
2093
                                      SIGNAL   rd_clk        : IN STD_LOGIC;
2094
                                      SIGNAL   rd_empty      : IN STD_LOGIC;
2095
                                      SIGNAL   rd_en         : IN STD_LOGIC) IS
2096
  BEGIN
2097
    -- c_fail_rd_emp : when TRUE report FAILURE when read from an empty FIFO, important when FIFO rd_val is not used
2098
    -- c_note_is_ful : when TRUE report NOTE when FIFO goes full, to note that operation is on the limit
2099
    -- FIFO overflow is always reported as FAILURE
2100
 
2101
    -- The FIFO wr_full goes high at reset to indicate that it can not be written and it goes low a few cycles after reset.
2102
    -- Therefore only check on wr_full going high when wr_rst='0'.
2103
 
2104
    --synthesis translate_off
2105
    ASSERT NOT(c_fail_rd_emp=TRUE AND rising_edge(rd_clk)  AND rd_empty='1' AND rd_en='1')  REPORT c_fifo_name & " : read from empty fifo occurred!" SEVERITY FAILURE;
2106
    ASSERT NOT(c_note_is_ful=TRUE AND rising_edge(wr_full) AND wr_rst='0')                  REPORT c_fifo_name & " : fifo is full now"               SEVERITY NOTE;
2107
    ASSERT NOT(                       rising_edge(wr_clk)  AND wr_full='1'  AND wr_en='1')  REPORT c_fifo_name & " : fifo overflow occurred!"        SEVERITY FAILURE;
2108
    --synthesis translate_on
2109
  END PROCEDURE proc_common_fifo_asserts;
2110
 
2111
 
2112
  ------------------------------------------------------------------------------
2113
  -- common_fanout_tree 
2114
  ------------------------------------------------------------------------------
2115
 
2116
  FUNCTION func_common_fanout_tree_pipelining(c_nof_stages, c_nof_output_per_cell, c_nof_output : NATURAL;
2117
                                              c_cell_pipeline_factor_arr, c_cell_pipeline_arr : t_natural_arr) RETURN t_natural_arr IS
2118
    CONSTANT k_cell_pipeline_factor_arr : t_natural_arr(c_nof_stages-1 DOWNTO 0) := c_cell_pipeline_factor_arr;
2119
    CONSTANT k_cell_pipeline_arr        : t_natural_arr(c_nof_output_per_cell-1 DOWNTO 0) := c_cell_pipeline_arr;
2120
    VARIABLE v_stage_pipeline_arr       : t_natural_arr(c_nof_output-1 DOWNTO 0) := (OTHERS=>0);
2121
    VARIABLE v_prev_stage_pipeline_arr  : t_natural_arr(c_nof_output-1 DOWNTO 0) := (OTHERS=>0);
2122
  BEGIN
2123
    loop_stage : FOR j IN 0 TO c_nof_stages-1 LOOP
2124
      v_prev_stage_pipeline_arr := v_stage_pipeline_arr;
2125
      loop_cell : FOR i IN 0 TO c_nof_output_per_cell**j-1 LOOP
2126
        v_stage_pipeline_arr((i+1)*c_nof_output_per_cell-1 DOWNTO i*c_nof_output_per_cell) := v_prev_stage_pipeline_arr(i) + (k_cell_pipeline_factor_arr(j) * k_cell_pipeline_arr);
2127
      END LOOP;
2128
    END LOOP;
2129
    RETURN v_stage_pipeline_arr;
2130
  END FUNCTION func_common_fanout_tree_pipelining;
2131
 
2132
 
2133
  ------------------------------------------------------------------------------
2134
  -- common_reorder_symbol 
2135
  ------------------------------------------------------------------------------
2136
 
2137
  -- Determine whether the stage I and row J index refer to any (active or redundant) 2-input reorder cell instantiation
2138
  FUNCTION func_common_reorder2_is_there(I, J : NATURAL) RETURN BOOLEAN IS
2139
    VARIABLE v_odd  : BOOLEAN;
2140
    VARIABLE v_even : BOOLEAN;
2141
  BEGIN
2142
    v_odd  := (I MOD 2 = 1) AND (J MOD 2 = 1);  -- for odd  stage at each odd  row
2143
    v_even := (I MOD 2 = 0) AND (J MOD 2 = 0);  -- for even stage at each even row
2144
    RETURN v_odd OR v_even;
2145
  END func_common_reorder2_is_there;
2146
 
2147
  -- Determine whether the stage I and row J index refer to an active 2-input reorder cell instantiation in a reorder network with N stages
2148
  FUNCTION func_common_reorder2_is_active(I, J, N : NATURAL) RETURN BOOLEAN IS
2149
    VARIABLE v_inst : BOOLEAN;
2150
    VARIABLE v_act  : BOOLEAN;
2151
  BEGIN
2152
    v_inst := func_common_reorder2_is_there(I, J);
2153
    v_act  := (I > 0) AND (I <= N) AND (J > 0) AND (J < N);
2154
    RETURN v_inst AND v_act;
2155
  END func_common_reorder2_is_active;
2156
 
2157
  -- Get the index K in the select setting array for the reorder2 cell on stage I and row J in a reorder network with N stages
2158
  FUNCTION func_common_reorder2_get_select_index(I, J, N : NATURAL) RETURN INTEGER IS
2159
    CONSTANT c_nof_reorder2_per_odd_stage  : NATURAL := N/2;
2160
    CONSTANT c_nof_reorder2_per_even_stage : NATURAL := (N-1)/2;
2161
    VARIABLE v_nof_odd_stages  : NATURAL;
2162
    VARIABLE v_nof_even_stages : NATURAL;
2163
    VARIABLE v_offset          : NATURAL;
2164
    VARIABLE v_K               : INTEGER;
2165
  BEGIN
2166
    -- for I, J that do not refer to an reorder cell instance for -1 as dummy return value.
2167
    -- for the redundant two port reorder cells at the border rows for -1 to indicate that the cell should pass on the input.
2168
    v_K := -1;
2169
    IF func_common_reorder2_is_active(I, J, N) THEN
2170
      -- for the active two port reorder cells use the setting at index v_K from the select setting array
2171
      v_nof_odd_stages  :=  I/2;
2172
      v_nof_even_stages := (I-1)/2;
2173
      v_offset          := (J-1)/2;  -- suits both odd stage and even stage
2174
      v_K := v_nof_odd_stages * c_nof_reorder2_per_odd_stage + v_nof_even_stages * c_nof_reorder2_per_even_stage + v_offset;
2175
    END IF;
2176
    RETURN v_K;
2177
  END func_common_reorder2_get_select_index;
2178
 
2179
  -- Get the select setting for the reorder2 cell on stage I and row J in a reorder network with N stages
2180
  FUNCTION func_common_reorder2_get_select(I, J, N : NATURAL; select_arr : t_natural_arr) RETURN NATURAL IS
2181
    CONSTANT c_nof_select : NATURAL := select_arr'LENGTH;
2182
    CONSTANT c_select_arr : t_natural_arr(c_nof_select-1 DOWNTO 0) := select_arr;  -- force range downto 0
2183
    VARIABLE v_sel        : NATURAL;
2184
    VARIABLE v_K          : INTEGER;
2185
  BEGIN
2186
    v_sel := 0;
2187
    v_K := func_common_reorder2_get_select_index(I, J, N);
2188
    IF v_K>=0 THEN
2189
      v_sel := c_select_arr(v_K);
2190
    END IF;
2191
    RETURN v_sel;
2192
  END func_common_reorder2_get_select;
2193
 
2194
  -- Determine the inverse of a reorder network by using two reorder networks in series
2195
  FUNCTION func_common_reorder2_inverse_select(N : NATURAL; select_arr : t_natural_arr) RETURN t_natural_arr IS
2196
    CONSTANT c_nof_select      : NATURAL := select_arr'LENGTH;
2197
    CONSTANT c_select_arr      : t_natural_arr(c_nof_select-1 DOWNTO 0) := select_arr;  -- force range downto 0
2198
    VARIABLE v_sel             : NATURAL;
2199
    VARIABLE v_Ki              : INTEGER;
2200
    VARIABLE v_Ii              : NATURAL;
2201
    VARIABLE v_inverse_arr     : t_natural_arr(2*c_nof_select-1 DOWNTO 0) := (OTHERS=>0);  -- default set identity for the reorder2 cells in both reorder instances
2202
  BEGIN
2203
    -- the inverse select consists of inverse_in reorder and inverse_out reorder in series
2204
    IF N MOD 2 = 1 THEN
2205
      -- N is odd so only need to fill in the inverse_in reorder, the inverse_out reorder remains at default pass on
2206
      FOR I IN 1 TO N LOOP
2207
        FOR J IN 0 TO N-1 LOOP
2208
          -- get the DUT setting
2209
          v_sel := func_common_reorder2_get_select(I, J, N, c_select_arr);
2210
          -- map DUT I to inverse v_Ii stage index and determine the index for the inverse setting
2211
          v_Ii := 1+N-I;
2212
          v_Ki := func_common_reorder2_get_select_index(v_Ii, J, N);
2213
          IF v_Ki>=0 THEN
2214
            v_inverse_arr(v_Ki) := v_sel;
2215
          END IF;
2216
        END LOOP;
2217
      END LOOP;
2218
    ELSE
2219
      -- N is even so only use stage 1 of the inverse_out reorder, the other stages remain at default pass on
2220
      FOR K IN 0 TO N/2-1 LOOP
2221
         v_Ki := c_nof_select + K;  -- stage 1 of the inverse_out reorder
2222
         v_inverse_arr(v_Ki) := c_select_arr(K);
2223
      END LOOP;
2224
      -- N is even so leave stage 1 of the inverse_in reorder at default pass on, and do inverse the other stages
2225
      FOR I IN 2 TO N LOOP
2226
        FOR J IN 0 TO N-1 LOOP
2227
          -- get the DUT setting
2228
          v_sel := func_common_reorder2_get_select(I, J, N, c_select_arr);
2229
          -- map DUT I to inverse v_Ii stage index and determine the index for the inverse setting
2230
          v_Ii := 2+N-I;
2231
          v_Ki := func_common_reorder2_get_select_index(v_Ii, J, N);
2232
          IF v_Ki>=0 THEN
2233
            v_inverse_arr(v_Ki) := v_sel;
2234
          END IF;
2235
        END LOOP;
2236
      END LOOP;
2237
    END IF;
2238
    RETURN v_inverse_arr;
2239
  END func_common_reorder2_inverse_select;
2240
 
2241
  ------------------------------------------------------------------------------
2242
  -- PROCEDURE: Generate faster sample SCLK from digital DCLK for sim only
2243
  -- Description:
2244
  --   The SCLK kan be used to serialize Pfactor >= 1 symbols per word and then 
2245
  --   view them in a scope component that is use internally in the design.
2246
  --   The scope component is only instantiated for simulation, to view the
2247
  --   serialized symbols, typically with decimal radix and analogue format.
2248
  --   The scope component will not be synthesized, because the SCLK can not
2249
  --   be synthesized.
2250
  --   
2251
  --   Pfactor = 4
2252
  --            _______         _______         _______         _______
2253
  --   DCLK ___|       |_______|       |_______|       |_______|       |_______
2254
  --        ___________________   _   _   _   _   _   _   _   _   _   _   _   _
2255
  --   SCLK                    |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_|
2256
  --
2257
  --   The rising edges of SCLK occur after the rising edge of DCLK, to ensure
2258
  --   that they all apply to the same wide data word that was clocked by the
2259
  --   rising edge of the DCLK.
2260
  ------------------------------------------------------------------------------
2261
  PROCEDURE proc_common_dclk_generate_sclk(CONSTANT Pfactor : IN    POSITIVE;
2262
                                           SIGNAL   dclk    : IN    STD_LOGIC;
2263
                                           SIGNAL   sclk    : INOUT STD_LOGIC) IS
2264
    VARIABLE v_dperiod : TIME;
2265
    VARIABLE v_speriod : TIME;
2266
  BEGIN
2267
    SCLK <= '1';
2268
    -- Measure DCLK period
2269
    WAIT UNTIL rising_edge(DCLK);
2270
    v_dperiod := NOW;
2271
    WAIT UNTIL rising_edge(DCLK);
2272
    v_dperiod := NOW - v_dperiod;
2273
    v_speriod := v_dperiod / Pfactor;
2274
    -- Generate Pfactor SCLK periods per DCLK period
2275
    WHILE TRUE LOOP
2276
      -- Realign at every DCLK
2277
      WAIT UNTIL rising_edge(DCLK);
2278
      -- Create Pfactor SCLK periods within this DCLK period
2279
      SCLK <= '0';
2280
      IF Pfactor>1 THEN
2281
        FOR I IN 0 TO 2*Pfactor-1-2 LOOP
2282
          WAIT FOR v_speriod/2;
2283
          SCLK <= NOT SCLK;
2284
        END LOOP;
2285
      END IF;
2286
      WAIT FOR v_speriod/2;
2287
      SCLK <= '1';
2288
      -- Wait for next DCLK
2289
    END LOOP;
2290
    WAIT;
2291
  END proc_common_dclk_generate_sclk;
2292
 
2293
END common_pkg;
2294
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.