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 9

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

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

powered by: WebSVN 2.1.0

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