URL
https://opencores.org/ocsvn/common_pkg/common_pkg/trunk
Subversion Repositories common_pkg
Compare Revisions
- This comparison shows the changes necessary to convert path
/common_pkg
- from Rev 5 to Rev 6
- ↔ Reverse comparison
Rev 5 → Rev 6
/trunk/common_lfsr_sequences_pkg.vhd
0,0 → 1,193
-------------------------------------------------------------------------------- |
-- |
-- Copyright (C) 2009 |
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> |
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> |
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands |
-- |
-- This program is free software: you can redistribute it and/or modify |
-- it under the terms of the GNU General Public License as published by |
-- the Free Software Foundation, either version 3 of the License, or |
-- (at your option) any later version. |
-- |
-- This program is distributed in the hope that it will be useful, |
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
-- GNU General Public License for more details. |
-- |
-- You should have received a copy of the GNU General Public License |
-- along with this program. If not, see <http://www.gnu.org/licenses/>. |
-- |
-------------------------------------------------------------------------------- |
|
LIBRARY IEEE; |
USE IEEE.std_logic_1164.ALL; |
USE IEEE.numeric_std.ALL; |
USE work.common_pkg.ALL; |
|
PACKAGE common_lfsr_sequences_pkg IS |
|
CONSTANT c_common_lfsr_max_nof_feedbacks : NATURAL := 6; |
CONSTANT c_common_lfsr_first : NATURAL := 1; -- also support n = 1 and 2 in addition to n >= 3 |
|
TYPE t_FEEDBACKS IS ARRAY (c_common_lfsr_max_nof_feedbacks-1 DOWNTO 0) OF NATURAL; |
TYPE t_SEQUENCES IS ARRAY (NATURAL RANGE <>) OF t_FEEDBACKS; |
|
-- XNOR feedbacks for n = 1: |
-- (0,0,0,0,0, 0) yields repeat <1> |
-- (0,0,0,0,0, 1) yields repeat <0, 1> |
|
-- XNOR feedbacks for n = 2: |
-- (0,0,0,0, 0, 1) yields repeat <1, 2> |
-- (0,0,0,0, 0, 2) yields repeat <0, 1, 3, 2> |
-- (0,0,0,0, 2, 1) yields repeat <0, 1, 2> |
|
-- XNOR feedbacks from outputs for n = 3 .. 72 from Xilinx xapp052.pdf (that lists feedbacks for in total 168 sequences) |
CONSTANT c_common_lfsr_sequences : t_SEQUENCES := ((0,0,0,0,0, 1), -- 1 : <0, 1> |
(0,0,0,0, 0, 2), -- 2 : <0, 1, 3, 2> |
(0,0,0,0, 3, 2), -- 3 |
(0,0,0,0, 4, 3), -- 4 |
(0,0,0,0, 5, 3), -- 5 |
(0,0,0,0, 6, 5), -- 6 |
(0,0,0,0, 7, 6), -- 7 |
(0,0, 8, 6, 5, 4), -- 8 |
(0,0,0,0, 9, 5), -- 9 |
(0,0,0,0, 10, 7), -- 10 |
(0,0,0,0, 11, 9), -- 11 |
(0,0, 12, 6, 4, 1), -- 12 |
(0,0, 13, 4, 3, 1), -- 13 |
(0,0, 14, 5, 3, 1), -- 14 |
(0,0,0,0, 15,14 ), -- 15 |
(0,0, 16,15,13, 4), -- 16 |
(0,0,0,0, 17,14 ), -- 17 |
(0,0,0,0, 18,11 ), -- 18 |
(0,0, 19, 6, 2, 1), -- 19 |
(0,0,0,0, 20,17 ), -- 20 |
(0,0,0,0, 21,19 ), -- 21 |
(0,0,0,0, 22,21 ), -- 22 |
(0,0,0,0, 23,18 ), -- 23 |
(0,0, 24,23,22,17), -- 24 |
(0,0,0,0, 25,22 ), -- 25 |
(0,0, 26, 6, 2, 1), -- 26 |
(0,0, 27, 5, 2, 1), -- 27 |
(0,0,0,0, 28,25 ), -- 28 |
(0,0,0,0, 29,27 ), -- 29 |
(0,0, 30, 6, 4, 1), -- 30 |
(0,0,0,0, 31,28 ), -- 31 |
(0,0, 32,22, 2, 1), -- 32 |
(0,0,0,0, 33,20 ), -- 33 |
(0,0, 34,27, 2, 1), -- 34 |
(0,0,0,0, 35,33 ), -- 35 |
(0,0,0,0, 36,25 ), -- 36 |
( 37, 5, 4, 3, 2, 1), -- 37 |
(0,0, 38, 6, 5, 1), -- 38 |
(0,0,0,0, 39,35 ), -- 39 |
(0,0, 40,38,21,19), -- 40 |
(0,0,0,0, 41,38 ), -- 41 |
(0,0, 42,41,20,19), -- 42 |
(0,0, 43,42,38,37), -- 43 |
(0,0, 44,43,18,17), -- 44 |
(0,0, 45,44,42,41), -- 45 |
(0,0, 46,45,26,25), -- 46 |
(0,0,0,0, 47,42 ), -- 47 |
(0,0, 48,47,21,20), -- 48 |
(0,0,0,0, 49,40 ), -- 49 |
(0,0, 50,49,24,23), -- 50 |
(0,0, 51,50,36,35), -- 51 |
(0,0,0,0, 52,49 ), -- 52 |
(0,0, 53,52,38,37), -- 53 |
(0,0, 54,53,18,17), -- 54 |
(0,0,0,0, 55,31 ), -- 55 |
(0,0, 56,55,35,34), -- 56 |
(0,0,0,0, 57,50 ), -- 57 |
(0,0,0,0, 58,39 ), -- 58 |
(0,0, 59,58,38,37), -- 59 |
(0,0,0,0, 60,59 ), -- 60 |
(0,0, 61,60,46,45), -- 61 |
(0,0, 62,61, 6, 5), -- 62 |
(0,0,0,0, 63,62 ), -- 63 |
(0,0, 64,63,61,60), -- 64 |
(0,0,0,0, 65,47 ), -- 65 |
(0,0, 66,65,57,56), -- 66 |
(0,0, 67,66,58,57), -- 67 |
(0,0,0,0, 68,59 ), -- 68 |
(0,0, 69,67,42,40), -- 69 |
(0,0, 70,69,55,54), -- 70 |
(0,0,0,0, 71,65 ), -- 71 |
(0,0, 72,66,25,19)); -- 72 |
|
|
-- Procedure for calculating the next PSRG and COUNTER sequence value |
PROCEDURE common_lfsr_nxt_seq(CONSTANT c_lfsr_nr : IN NATURAL; |
CONSTANT g_incr : IN INTEGER; |
in_en : IN STD_LOGIC; |
in_req : IN STD_LOGIC; |
in_dat : IN STD_LOGIC_VECTOR; |
prsg : IN STD_LOGIC_VECTOR; |
cntr : IN STD_LOGIC_VECTOR; |
SIGNAL nxt_prsg : OUT STD_LOGIC_VECTOR; |
SIGNAL nxt_cntr : OUT STD_LOGIC_VECTOR); |
|
-- Use lfsr part of common_lfsr_nxt_seq to make a random bit generator function |
-- . width of lfsr selects the LFSR sequence |
-- . initialized lfsr with (OTHERS=>'0') |
-- . use lfsr(lfsr'HIGH) as random bit |
FUNCTION func_common_random(lfsr : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; |
|
END common_lfsr_sequences_pkg; |
|
|
PACKAGE BODY common_lfsr_sequences_pkg IS |
|
PROCEDURE common_lfsr_nxt_seq(CONSTANT c_lfsr_nr : IN NATURAL; |
CONSTANT g_incr : IN INTEGER; |
in_en : IN STD_LOGIC; |
in_req : IN STD_LOGIC; |
in_dat : IN STD_LOGIC_VECTOR; |
prsg : IN STD_LOGIC_VECTOR; |
cntr : IN STD_LOGIC_VECTOR; |
SIGNAL nxt_prsg : OUT STD_LOGIC_VECTOR; |
SIGNAL nxt_cntr : OUT STD_LOGIC_VECTOR) IS |
VARIABLE v_feedback : STD_LOGIC; |
BEGIN |
nxt_prsg <= prsg; |
nxt_cntr <= cntr; |
IF in_en='0' THEN -- init reference value |
nxt_prsg <= in_dat; |
nxt_cntr <= in_dat; |
ELSIF in_req='1' THEN -- next reference value |
-- PRSG shift |
nxt_prsg <= prsg(prsg'HIGH-1 DOWNTO 0) & '0'; |
-- PRSG feedback |
v_feedback := '0'; |
FOR I IN c_common_lfsr_max_nof_feedbacks-1 DOWNTO 0 LOOP |
IF c_common_lfsr_sequences(c_lfsr_nr)(I) /= 0 THEN |
v_feedback := v_feedback XOR prsg(c_common_lfsr_sequences(c_lfsr_nr)(I)-1); |
END IF; |
END LOOP; |
nxt_prsg(0) <= NOT v_feedback; |
|
-- COUNTER |
nxt_cntr <= INCR_UVEC(cntr, g_incr); |
END IF; |
END common_lfsr_nxt_seq; |
|
FUNCTION func_common_random(lfsr : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
CONSTANT c_lfsr_nr : NATURAL := lfsr'LENGTH - c_common_lfsr_first; |
VARIABLE v_nxt_lfsr : STD_LOGIC_VECTOR(lfsr'RANGE); |
VARIABLE v_feedback : STD_LOGIC; |
BEGIN |
-- shift |
v_nxt_lfsr := lfsr(lfsr'HIGH-1 DOWNTO 0) & '0'; |
-- feedback |
v_feedback := '0'; |
FOR I IN c_common_lfsr_max_nof_feedbacks-1 DOWNTO 0 LOOP |
IF c_common_lfsr_sequences(c_lfsr_nr)(I) /= 0 THEN |
v_feedback := v_feedback XOR lfsr(c_common_lfsr_sequences(c_lfsr_nr)(I)-1); |
END IF; |
END LOOP; |
v_nxt_lfsr(0) := NOT v_feedback; |
RETURN v_nxt_lfsr; |
END func_common_random; |
|
END common_lfsr_sequences_pkg; |
/trunk/common_pkg.vhd
0,0 → 1,2294
|
------------------------------------------------------------------------------- |
-- |
-- Copyright (C) 2009 |
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> |
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands |
-- |
-- This program is free software: you can redistribute it and/or modify |
-- it under the terms of the GNU General Public License as published by |
-- the Free Software Foundation, either version 3 of the License, or |
-- (at your option) any later version. |
-- |
-- This program is distributed in the hope that it will be useful, |
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
-- GNU General Public License for more details. |
-- |
-- You should have received a copy of the GNU General Public License |
-- along with this program. If not, see <http://www.gnu.org/licenses/>. |
-- |
------------------------------------------------------------------------------- |
|
LIBRARY IEEE; |
USE IEEE.STD_LOGIC_1164.ALL; |
USE IEEE.NUMERIC_STD.ALL; |
USE IEEE.MATH_REAL.ALL; |
|
PACKAGE common_pkg IS |
|
-- CONSTANT DECLARATIONS ---------------------------------------------------- |
|
-- some integers |
CONSTANT c_0 : NATURAL := 0; |
CONSTANT c_zero : NATURAL := 0; |
CONSTANT c_1 : NATURAL := 1; |
CONSTANT c_one : NATURAL := 1; |
CONSTANT c_2 : NATURAL := 2; |
CONSTANT c_4 : NATURAL := 4; |
CONSTANT c_quad : NATURAL := 4; |
CONSTANT c_8 : NATURAL := 8; |
CONSTANT c_16 : NATURAL := 16; |
CONSTANT c_32 : NATURAL := 32; |
CONSTANT c_64 : NATURAL := 64; |
CONSTANT c_128 : NATURAL := 128; |
CONSTANT c_256 : NATURAL := 256; |
|
-- widths and sizes |
CONSTANT c_halfword_sz : NATURAL := 2; |
CONSTANT c_word_sz : NATURAL := 4; |
CONSTANT c_longword_sz : NATURAL := 8; |
CONSTANT c_nibble_w : NATURAL := 4; |
CONSTANT c_byte_w : NATURAL := 8; |
CONSTANT c_octet_w : NATURAL := 8; |
CONSTANT c_halfword_w : NATURAL := c_byte_w*c_halfword_sz; |
CONSTANT c_word_w : NATURAL := c_byte_w*c_word_sz; |
CONSTANT c_integer_w : NATURAL := 32; -- unfortunately VHDL integer type is limited to 32 bit values |
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 |
CONSTANT c_longword_w : NATURAL := c_byte_w*c_longword_sz; |
|
-- logic |
CONSTANT c_sl0 : STD_LOGIC := '0'; |
CONSTANT c_sl1 : STD_LOGIC := '1'; |
CONSTANT c_unsigned_0 : UNSIGNED(0 DOWNTO 0) := TO_UNSIGNED(0,1); |
CONSTANT c_unsigned_1 : UNSIGNED(0 DOWNTO 0) := TO_UNSIGNED(1,1); |
CONSTANT c_signed_0 : SIGNED(1 DOWNTO 0) := TO_SIGNED(0,2); |
CONSTANT c_signed_1 : SIGNED(1 DOWNTO 0) := TO_SIGNED(1,2); |
CONSTANT c_slv0 : STD_LOGIC_VECTOR(255 DOWNTO 0) := (OTHERS=>'0'); |
CONSTANT c_slv1 : STD_LOGIC_VECTOR(255 DOWNTO 0) := (OTHERS=>'1'); |
CONSTANT c_word_01 : STD_LOGIC_VECTOR(31 DOWNTO 0) := "01010101010101010101010101010101"; |
CONSTANT c_word_10 : STD_LOGIC_VECTOR(31 DOWNTO 0) := "10101010101010101010101010101010"; |
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; |
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; |
|
-- math |
CONSTANT c_nof_complex : NATURAL := 2; -- Real and imaginary part of complex number |
CONSTANT c_sign_w : NATURAL := 1; -- Sign bit, can be used to skip one of the double sign bits of a product |
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 |
|
-- FF, block RAM, FIFO |
CONSTANT c_meta_delay_len : NATURAL := 3; -- default nof flipflops (FF) in meta stability recovery delay line (e.g. for clock domain crossing) |
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 |
|
CONSTANT c_bram_m9k_nof_bits : NATURAL := 1024*9; -- size of 1 Altera M9K block RAM in bits |
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 |
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 |
|
CONSTANT c_fifo_afull_margin : NATURAL := 4; -- default or minimal FIFO almost full margin |
|
-- DSP |
CONSTANT c_dsp_mult_w : NATURAL := 18; -- Width of the embedded multipliers in Stratix IV |
|
-- TYPE DECLARATIONS -------------------------------------------------------- |
TYPE t_boolean_arr IS ARRAY (INTEGER RANGE <>) OF BOOLEAN; -- INTEGER left index starts default at -2**31 |
TYPE t_integer_arr IS ARRAY (INTEGER RANGE <>) OF INTEGER; -- INTEGER left index starts default at -2**31 |
TYPE t_natural_arr IS ARRAY (INTEGER RANGE <>) OF NATURAL; -- INTEGER left index starts default at -2**31 |
TYPE t_nat_boolean_arr IS ARRAY (NATURAL RANGE <>) OF BOOLEAN; -- NATURAL left index starts default at 0 |
TYPE t_nat_integer_arr IS ARRAY (NATURAL RANGE <>) OF INTEGER; -- NATURAL left index starts default at 0 |
TYPE t_nat_natural_arr IS ARRAY (NATURAL RANGE <>) OF NATURAL; -- NATURAL left index starts default at 0 |
TYPE t_sl_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC; |
TYPE t_slv_1_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(0 DOWNTO 0); |
TYPE t_slv_2_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(1 DOWNTO 0); |
TYPE t_slv_4_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(3 DOWNTO 0); |
TYPE t_slv_8_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(7 DOWNTO 0); |
TYPE t_slv_12_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(11 DOWNTO 0); |
TYPE t_slv_16_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(15 DOWNTO 0); |
TYPE t_slv_18_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(17 DOWNTO 0); |
TYPE t_slv_24_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(23 DOWNTO 0); |
TYPE t_slv_32_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(31 DOWNTO 0); |
TYPE t_slv_44_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(43 DOWNTO 0); |
TYPE t_slv_48_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(47 DOWNTO 0); |
TYPE t_slv_64_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(63 DOWNTO 0); |
TYPE t_slv_128_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(127 DOWNTO 0); |
TYPE t_slv_256_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(255 DOWNTO 0); |
TYPE t_slv_512_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(511 DOWNTO 0); |
TYPE t_slv_1024_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(1023 DOWNTO 0); |
|
CONSTANT c_boolean_arr : t_boolean_arr := (TRUE, FALSE); -- array all possible values that can be iterated over |
CONSTANT c_nat_boolean_arr : t_nat_boolean_arr := (TRUE, FALSE); -- array all possible values that can be iterated over |
|
TYPE t_integer_matrix IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF INTEGER; |
TYPE t_boolean_matrix IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF BOOLEAN; |
TYPE t_sl_matrix IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF STD_LOGIC; |
TYPE t_slv_8_matrix IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF STD_LOGIC_VECTOR(7 DOWNTO 0); |
TYPE t_slv_16_matrix IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF STD_LOGIC_VECTOR(15 DOWNTO 0); |
TYPE t_slv_32_matrix IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF STD_LOGIC_VECTOR(31 DOWNTO 0); |
TYPE t_slv_64_matrix IS ARRAY (INTEGER RANGE <>, INTEGER RANGE <>) OF STD_LOGIC_VECTOR(63 DOWNTO 0); |
|
TYPE t_natural_2arr_2 IS ARRAY (INTEGER RANGE <>) OF t_natural_arr(1 DOWNTO 0); |
|
-- STRUCTURE DECLARATIONS --------------------------------------------------- |
|
-- Clock and Reset |
-- |
-- . rst = Reset. Can be used asynchronously to take effect immediately |
-- when used before the clk'EVENT section. May also be used as |
-- synchronous reset using it as first condition in the clk'EVENT |
-- section. As synchronous reset it requires clock activity to take |
-- effect. A synchronous rst may or may not depend on clken, |
-- however typically rst should take priority over clken. |
-- . clk = Clock. Used in clk'EVENT line via rising_edge(clk) or sometimes |
-- as falling_edge(clk). |
-- . clken = Clock Enable. Used for the whole clk'EVENT section. |
TYPE t_sys_rce IS RECORD |
rst : STD_LOGIC; |
clk : STD_LOGIC; |
clken : STD_LOGIC; -- := '1'; |
END RECORD; |
|
TYPE t_sys_ce IS RECORD |
clk : STD_LOGIC; |
clken : STD_LOGIC; -- := '1'; |
END RECORD; |
|
|
-- FUNCTION DECLARATIONS ---------------------------------------------------- |
|
-- All functions assume [high downto low] input ranges |
|
FUNCTION pow2(n : NATURAL) RETURN NATURAL; -- = 2**n |
FUNCTION ceil_pow2(n : INTEGER) RETURN NATURAL; -- = 2**n, returns 1 for n<0 |
|
FUNCTION true_log2(n : NATURAL) RETURN NATURAL; -- true_log2(n) = log2(n) |
FUNCTION ceil_log2(n : NATURAL) RETURN NATURAL; -- ceil_log2(n) = log2(n), but force ceil_log2(1) = 1 |
|
FUNCTION floor_log10(n : NATURAL) RETURN NATURAL; |
|
FUNCTION is_pow2(n : NATURAL) RETURN BOOLEAN; -- return TRUE when n is a power of 2, so 0, 1, 2, 4, 8, 16, ... |
FUNCTION true_log_pow2(n : NATURAL) RETURN NATURAL; -- 2**true_log2(n), return power of 2 that is >= n |
|
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 |
FUNCTION ratio2(n, m : NATURAL) RETURN NATURAL; -- return integer ratio of n/m or m/n, whichever is the largest |
|
FUNCTION ceil_div( n, d : NATURAL) RETURN NATURAL; -- ceil_div = n/d + (n MOD d)/=0 |
FUNCTION ceil_value( n, d : NATURAL) RETURN NATURAL; -- ceil_value = ceil_div(n, d) * d |
FUNCTION floor_value(n, d : NATURAL) RETURN NATURAL; -- floor_value = (n/d) * d |
FUNCTION ceil_div( n : UNSIGNED; d: NATURAL) RETURN UNSIGNED; |
FUNCTION ceil_value( n : UNSIGNED; d: NATURAL) RETURN UNSIGNED; |
FUNCTION floor_value(n : UNSIGNED; d: NATURAL) RETURN UNSIGNED; |
|
FUNCTION slv(n: IN STD_LOGIC) RETURN STD_LOGIC_VECTOR; -- standard logic to 1 element standard logic vector |
FUNCTION sl( n: IN STD_LOGIC_VECTOR) RETURN STD_LOGIC; -- 1 element standard logic vector to standard logic |
|
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 |
FUNCTION to_natural_arr(n : t_nat_natural_arr) RETURN t_natural_arr; |
FUNCTION to_integer_arr(n : t_natural_arr) RETURN t_integer_arr; |
FUNCTION to_integer_arr(n : t_nat_natural_arr) RETURN t_integer_arr; |
FUNCTION to_slv_32_arr( n : t_integer_arr) RETURN t_slv_32_arr; |
FUNCTION to_slv_32_arr( n : t_natural_arr) RETURN t_slv_32_arr; |
|
FUNCTION vector_tree(slv : STD_LOGIC_VECTOR; operation : STRING) RETURN STD_LOGIC; -- Core operation tree function for vector "AND", "OR", "XOR" |
FUNCTION vector_and(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC; -- '1' when all slv bits are '1' else '0' |
FUNCTION vector_or( slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC; -- '0' when all slv bits are '0' else '1' |
FUNCTION vector_xor(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC; -- '1' when the slv has an odd number of '1' bits else '0' |
FUNCTION vector_one_hot(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- Returns slv when it contains one hot bit, else returns 0. |
|
FUNCTION andv(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC; -- alias of vector_and |
FUNCTION orv( slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC; -- alias of vector_or |
FUNCTION xorv(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC; -- alias of vector_xor |
|
FUNCTION matrix_and(mat : t_sl_matrix; wi, wj : NATURAL) RETURN STD_LOGIC; -- '1' when all matrix bits are '1' else '0' |
FUNCTION matrix_or( mat : t_sl_matrix; wi, wj : NATURAL) RETURN STD_LOGIC; -- '0' when all matrix bits are '0' else '1' |
|
FUNCTION smallest(n, m : INTEGER) RETURN INTEGER; |
FUNCTION smallest(n, m, l : INTEGER) RETURN INTEGER; |
FUNCTION smallest(n : t_natural_arr) RETURN NATURAL; |
|
FUNCTION largest(n, m : INTEGER) RETURN INTEGER; |
FUNCTION largest(n : t_natural_arr) RETURN NATURAL; |
|
FUNCTION func_sum( n : t_natural_arr) RETURN NATURAL; -- sum of all elements in array |
FUNCTION func_sum( n : t_nat_natural_arr) RETURN NATURAL; |
FUNCTION func_product(n : t_natural_arr) RETURN NATURAL; -- product of all elements in array |
FUNCTION func_product(n : t_nat_natural_arr) RETURN NATURAL; |
|
FUNCTION "+" (L, R: t_natural_arr) RETURN t_natural_arr; -- element wise sum |
FUNCTION "+" (L : t_natural_arr; R : INTEGER) RETURN t_natural_arr; -- element wise sum |
FUNCTION "+" (L : INTEGER; R : t_natural_arr) RETURN t_natural_arr; -- element wise sum |
|
FUNCTION "-" (L, R: t_natural_arr) RETURN t_natural_arr; -- element wise subtract |
FUNCTION "-" (L, R: t_natural_arr) RETURN t_integer_arr; -- element wise subtract, support negative result |
FUNCTION "-" (L : t_natural_arr; R : INTEGER) RETURN t_natural_arr; -- element wise subtract |
FUNCTION "-" (L : INTEGER; R : t_natural_arr) RETURN t_natural_arr; -- element wise subtract |
|
FUNCTION "*" (L, R: t_natural_arr) RETURN t_natural_arr; -- element wise product |
FUNCTION "*" (L : t_natural_arr; R : NATURAL) RETURN t_natural_arr; -- element wise product |
FUNCTION "*" (L : NATURAL; R : t_natural_arr) RETURN t_natural_arr; -- element wise product |
|
FUNCTION "/" (L, R: t_natural_arr) RETURN t_natural_arr; -- element wise division |
FUNCTION "/" (L : t_natural_arr; R : POSITIVE) RETURN t_natural_arr; -- element wise division |
FUNCTION "/" (L : NATURAL; R : t_natural_arr) RETURN t_natural_arr; -- element wise division |
|
FUNCTION is_true(a : STD_LOGIC) RETURN BOOLEAN; |
FUNCTION is_true(a : STD_LOGIC) RETURN NATURAL; |
FUNCTION is_true(a : BOOLEAN) RETURN STD_LOGIC; |
FUNCTION is_true(a : BOOLEAN) RETURN NATURAL; |
FUNCTION is_true(a : INTEGER) RETURN BOOLEAN; -- also covers NATURAL because it is a subtype of INTEGER |
FUNCTION is_true(a : INTEGER) RETURN STD_LOGIC; -- also covers NATURAL because it is a subtype of INTEGER |
|
FUNCTION sel_a_b(sel, a, b : BOOLEAN) RETURN BOOLEAN; |
FUNCTION sel_a_b(sel, a, b : INTEGER) RETURN INTEGER; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : INTEGER) RETURN INTEGER; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : REAL) RETURN REAL; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : STD_LOGIC) RETURN STD_LOGIC; |
FUNCTION sel_a_b(sel : INTEGER; a, b : STD_LOGIC) RETURN STD_LOGIC; |
FUNCTION sel_a_b(sel : INTEGER; a, b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : SIGNED) RETURN SIGNED; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : UNSIGNED) RETURN UNSIGNED; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_integer_arr) RETURN t_integer_arr; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_natural_arr) RETURN t_natural_arr; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_nat_integer_arr) RETURN t_nat_integer_arr; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_nat_natural_arr) RETURN t_nat_natural_arr; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : STRING) RETURN STRING; |
FUNCTION sel_a_b(sel : INTEGER; a, b : STRING) RETURN STRING; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : TIME) RETURN TIME; |
FUNCTION sel_a_b(sel : BOOLEAN; a, b : SEVERITY_LEVEL) RETURN SEVERITY_LEVEL; |
|
-- sel_n() index sel = 0, 1, 2, ... will return a, b, c, ... |
FUNCTION sel_n(sel : NATURAL; a, b, c : BOOLEAN) RETURN BOOLEAN; -- 3 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d : BOOLEAN) RETURN BOOLEAN; -- 4 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e : BOOLEAN) RETURN BOOLEAN; -- 5 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f : BOOLEAN) RETURN BOOLEAN; -- 6 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g : BOOLEAN) RETURN BOOLEAN; -- 7 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h : BOOLEAN) RETURN BOOLEAN; -- 8 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i : BOOLEAN) RETURN BOOLEAN; -- 9 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i, j : BOOLEAN) RETURN BOOLEAN; -- 10 |
|
FUNCTION sel_n(sel : NATURAL; a, b, c : INTEGER) RETURN INTEGER; -- 3 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d : INTEGER) RETURN INTEGER; -- 4 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e : INTEGER) RETURN INTEGER; -- 5 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f : INTEGER) RETURN INTEGER; -- 6 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g : INTEGER) RETURN INTEGER; -- 7 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h : INTEGER) RETURN INTEGER; -- 8 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i : INTEGER) RETURN INTEGER; -- 9 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i, j : INTEGER) RETURN INTEGER; -- 10 |
|
FUNCTION sel_n(sel : NATURAL; a, b : STRING) RETURN STRING; -- 2 |
FUNCTION sel_n(sel : NATURAL; a, b, c : STRING) RETURN STRING; -- 3 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d : STRING) RETURN STRING; -- 4 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e : STRING) RETURN STRING; -- 5 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f : STRING) RETURN STRING; -- 6 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g : STRING) RETURN STRING; -- 7 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h : STRING) RETURN STRING; -- 8 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i : STRING) RETURN STRING; -- 9 |
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i, j : STRING) RETURN STRING; -- 10 |
|
FUNCTION array_init(init : STD_LOGIC; nof : NATURAL) RETURN STD_LOGIC_VECTOR; -- useful to init a unconstrained array of size 1 |
FUNCTION array_init(init, nof : NATURAL) RETURN t_natural_arr; -- useful to init a unconstrained array of size 1 |
FUNCTION array_init(init, nof : NATURAL) RETURN t_nat_natural_arr; -- useful to init a unconstrained array of size 1 |
FUNCTION array_init(init, nof, incr : NATURAL) RETURN t_natural_arr; -- useful to init an array with incrementing numbers |
FUNCTION array_init(init, nof, incr : NATURAL) RETURN t_nat_natural_arr; |
FUNCTION array_init(init, nof, incr : INTEGER) RETURN t_slv_16_arr; |
FUNCTION array_init(init, nof, incr : INTEGER) RETURN t_slv_32_arr; |
FUNCTION array_init(init, nof, width : NATURAL) RETURN STD_LOGIC_VECTOR; -- useful to init an unconstrained std_logic_vector with repetitive content |
FUNCTION array_init(init, nof, width, incr : NATURAL) RETURN STD_LOGIC_VECTOR; -- useful to init an unconstrained std_logic_vector with incrementing content |
FUNCTION array_sinit(init : INTEGER; nof, width : NATURAL) RETURN STD_LOGIC_VECTOR; -- useful to init an unconstrained std_logic_vector with repetitive content |
|
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 |
|
-- Concatenate two or more STD_LOGIC_VECTORs into a single STD_LOGIC_VECTOR or extract one of them from a concatenated STD_LOGIC_VECTOR |
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; |
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; |
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; |
FUNCTION func_slv_concat( use_a, use_b, use_c, use_d : BOOLEAN; a, b, c, d : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; |
FUNCTION func_slv_concat( use_a, use_b, use_c : BOOLEAN; a, b, c : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; |
FUNCTION func_slv_concat( use_a, use_b : BOOLEAN; a, b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; |
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; |
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; |
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; |
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; |
FUNCTION func_slv_concat_w(use_a, use_b, use_c : BOOLEAN; a_w, b_w, c_w : NATURAL) RETURN NATURAL; |
FUNCTION func_slv_concat_w(use_a, use_b : BOOLEAN; a_w, b_w : NATURAL) RETURN NATURAL; |
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; |
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; |
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; |
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; |
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; |
FUNCTION func_slv_extract( use_a, use_b : BOOLEAN; a_w, b_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR; |
|
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 |
FUNCTION TO_SINT(vec : STD_LOGIC_VECTOR) RETURN INTEGER; |
|
FUNCTION TO_UVEC(dec, w : NATURAL) RETURN STD_LOGIC_VECTOR; |
FUNCTION TO_SVEC(dec, w : INTEGER) RETURN STD_LOGIC_VECTOR; |
|
FUNCTION TO_SVEC_32(dec : INTEGER) RETURN STD_LOGIC_VECTOR; -- = TO_SVEC() with w=32 for t_slv_32_arr slv elements |
|
-- The RESIZE for SIGNED in IEEE.NUMERIC_STD extends the sign bit or it keeps the sign bit and LS part. This |
-- behaviour of preserving the sign bit is less suitable for DSP and not necessary in general. A more |
-- appropriate approach is to ignore the MSbit sign and just keep the LS part. For too large values this |
-- means that the result gets wrapped, but that is fine for default behaviour, because that is also what |
-- happens for RESIZE of UNSIGNED. Therefor this is what the RESIZE_NUM for SIGNED and the RESIZE_SVEC do |
-- and better not use RESIZE for SIGNED anymore. |
FUNCTION RESIZE_NUM( u : UNSIGNED; w : NATURAL) RETURN UNSIGNED; -- left extend with '0' or keep LS part (same as RESIZE for UNSIGNED) |
FUNCTION RESIZE_NUM( s : SIGNED; w : NATURAL) RETURN SIGNED; -- extend sign bit or keep LS part |
FUNCTION RESIZE_UVEC(sl : STD_LOGIC; w : NATURAL) RETURN STD_LOGIC_VECTOR; -- left extend with '0' into slv |
FUNCTION RESIZE_UVEC(vec : STD_LOGIC_VECTOR; w : NATURAL) RETURN STD_LOGIC_VECTOR; -- left extend with '0' or keep LS part |
FUNCTION RESIZE_SVEC(vec : STD_LOGIC_VECTOR; w : NATURAL) RETURN STD_LOGIC_VECTOR; -- extend sign bit or keep LS part |
FUNCTION RESIZE_UINT(u : INTEGER; w : NATURAL) RETURN INTEGER; -- left extend with '0' or keep LS part |
FUNCTION RESIZE_SINT(s : INTEGER; w : NATURAL) RETURN INTEGER; -- extend sign bit or keep LS part |
|
FUNCTION RESIZE_UVEC_32(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- = RESIZE_UVEC() with w=32 for t_slv_32_arr slv elements |
FUNCTION RESIZE_SVEC_32(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- = RESIZE_SVEC() with w=32 for t_slv_32_arr slv elements |
|
FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : INTEGER) RETURN STD_LOGIC_VECTOR; |
FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : UNSIGNED) RETURN STD_LOGIC_VECTOR; |
FUNCTION INCR_SVEC(vec : STD_LOGIC_VECTOR; dec : INTEGER) RETURN STD_LOGIC_VECTOR; |
FUNCTION INCR_SVEC(vec : STD_LOGIC_VECTOR; dec : SIGNED) RETURN STD_LOGIC_VECTOR; |
-- Used in common_add_sub.vhd |
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 |
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 |
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 |
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 |
|
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 |
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 |
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 |
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 |
|
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 |
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 |
|
FUNCTION SHIFT_UVEC(vec : STD_LOGIC_VECTOR; shift : INTEGER) RETURN STD_LOGIC_VECTOR; -- < 0 shift left, > 0 shift right |
FUNCTION SHIFT_SVEC(vec : STD_LOGIC_VECTOR; shift : INTEGER) RETURN STD_LOGIC_VECTOR; -- < 0 shift left, > 0 shift right |
|
FUNCTION offset_binary(a : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; |
|
FUNCTION truncate( vec : STD_LOGIC_VECTOR; n : NATURAL) RETURN STD_LOGIC_VECTOR; -- remove n LSBits from vec, so result has width vec'LENGTH-n |
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 |
FUNCTION truncate_and_resize_svec(vec : STD_LOGIC_VECTOR; n, w : NATURAL) RETURN STD_LOGIC_VECTOR; -- idem for signed values |
FUNCTION scale( vec : STD_LOGIC_VECTOR; n: NATURAL) RETURN STD_LOGIC_VECTOR; -- add n '0' LSBits to vec |
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 |
FUNCTION scale_and_resize_svec( vec : STD_LOGIC_VECTOR; n, w : NATURAL) RETURN STD_LOGIC_VECTOR; -- idem for signed values |
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 |
FUNCTION truncate_or_resize_svec( vec : STD_LOGIC_VECTOR; b : BOOLEAN; w : NATURAL) RETURN STD_LOGIC_VECTOR; -- idem for signed values |
|
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 |
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 |
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) |
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) |
FUNCTION u_round( vec : STD_LOGIC_VECTOR; n : NATURAL; clip : BOOLEAN) RETURN STD_LOGIC_VECTOR; -- idem round up for unsigned values |
FUNCTION u_round( vec : STD_LOGIC_VECTOR; n : NATURAL) RETURN STD_LOGIC_VECTOR; -- idem round up for unsigned values |
|
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 |
FUNCTION hton(a : STD_LOGIC_VECTOR; sz : NATURAL) RETURN STD_LOGIC_VECTOR; -- convert endianity from host to network, sz in bytes |
FUNCTION hton(a : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR; -- convert endianity from host to network, for all bytes in a |
FUNCTION ntoh(a : STD_LOGIC_VECTOR; sz : NATURAL) RETURN STD_LOGIC_VECTOR; -- convert endianity from network to host, sz in bytes, ntoh() = hton() |
FUNCTION ntoh(a : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR; -- convert endianity from network to host, for all bytes in a, ntoh() = hton() |
|
FUNCTION flip(a : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- bit flip a vector, map a[h:0] to [0:h] |
FUNCTION flip(a, w : NATURAL) RETURN NATURAL; -- bit flip a vector, map a[h:0] to [0:h], h = w-1 |
FUNCTION flip(a : t_slv_32_arr) RETURN t_slv_32_arr; |
FUNCTION flip(a : t_integer_arr) RETURN t_integer_arr; |
FUNCTION flip(a : t_natural_arr) RETURN t_natural_arr; |
FUNCTION flip(a : t_nat_natural_arr) RETURN t_nat_natural_arr; |
|
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] |
FUNCTION transpose(a, row, col : NATURAL) RETURN NATURAL; -- transpose index a = [i*row+j] to output index [j*col+i] |
|
FUNCTION split_w(input_w: NATURAL; min_out_w: NATURAL; max_out_w: NATURAL) RETURN NATURAL; |
|
FUNCTION pad(str: STRING; width: NATURAL; pad_char: CHARACTER) RETURN STRING; |
|
FUNCTION slice_up(str: STRING; width: NATURAL; i: NATURAL) RETURN STRING; |
FUNCTION slice_up(str: STRING; width: NATURAL; i: NATURAL; pad_char: CHARACTER) RETURN STRING; |
FUNCTION slice_dn(str: STRING; width: NATURAL; i: NATURAL) RETURN STRING; |
|
FUNCTION nat_arr_to_concat_slv(nat_arr: t_natural_arr; nof_elements: NATURAL) RETURN STD_LOGIC_VECTOR; |
|
------------------------------------------------------------------------------ |
-- Component specific functions |
------------------------------------------------------------------------------ |
|
-- common_fifo_* |
PROCEDURE proc_common_fifo_asserts (CONSTANT c_fifo_name : IN STRING; |
CONSTANT c_note_is_ful : IN BOOLEAN; |
CONSTANT c_fail_rd_emp : IN BOOLEAN; |
SIGNAL wr_rst : IN STD_LOGIC; |
SIGNAL wr_clk : IN STD_LOGIC; |
SIGNAL wr_full : IN STD_LOGIC; |
SIGNAL wr_en : IN STD_LOGIC; |
SIGNAL rd_clk : IN STD_LOGIC; |
SIGNAL rd_empty : IN STD_LOGIC; |
SIGNAL rd_en : IN STD_LOGIC); |
|
-- common_fanout_tree |
FUNCTION func_common_fanout_tree_pipelining(c_nof_stages, c_nof_output_per_cell, c_nof_output : NATURAL; |
c_cell_pipeline_factor_arr, c_cell_pipeline_arr : t_natural_arr) RETURN t_natural_arr; |
|
-- common_reorder_symbol |
FUNCTION func_common_reorder2_is_there(I, J : NATURAL) RETURN BOOLEAN; |
FUNCTION func_common_reorder2_is_active(I, J, N : NATURAL) RETURN BOOLEAN; |
FUNCTION func_common_reorder2_get_select_index(I, J, N : NATURAL) RETURN INTEGER; |
FUNCTION func_common_reorder2_get_select(I, J, N : NATURAL; select_arr : t_natural_arr) RETURN NATURAL; |
FUNCTION func_common_reorder2_inverse_select(N : NATURAL; select_arr : t_natural_arr) RETURN t_natural_arr; |
|
-- Generate faster sample SCLK from digital DCLK for sim only |
PROCEDURE proc_common_dclk_generate_sclk(CONSTANT Pfactor : IN POSITIVE; |
SIGNAL dclk : IN STD_LOGIC; |
SIGNAL sclk : INOUT STD_LOGIC); |
|
END common_pkg; |
|
PACKAGE BODY common_pkg IS |
|
FUNCTION pow2(n : NATURAL) RETURN NATURAL IS |
BEGIN |
RETURN 2**n; |
END; |
|
FUNCTION ceil_pow2(n : INTEGER) RETURN NATURAL IS |
-- Also allows negative exponents and rounds up before returning the value |
BEGIN |
RETURN natural(integer(ceil(2**real(n)))); |
END; |
|
FUNCTION true_log2(n : NATURAL) RETURN NATURAL IS |
-- Purpose: For calculating extra vector width of existing vector |
-- Description: Return mathematical ceil(log2(n)) |
-- n log2() |
-- 0 -> -oo --> FAILURE |
-- 1 -> 0 |
-- 2 -> 1 |
-- 3 -> 2 |
-- 4 -> 2 |
-- 5 -> 3 |
-- 6 -> 3 |
-- 7 -> 3 |
-- 8 -> 3 |
-- 9 -> 4 |
-- etc, up to n = NATURAL'HIGH = 2**31-1 |
BEGIN |
RETURN natural(integer(ceil(log2(real(n))))); |
END; |
|
FUNCTION ceil_log2(n : NATURAL) RETURN NATURAL IS |
-- Purpose: For calculating vector width of new vector |
-- Description: |
-- Same as true_log2() except ceil_log2(1) = 1, which is needed to support |
-- the vector width width for 1 address, to avoid NULL array for single |
-- word register address. |
-- If n = 0, return 0 so we get a NULL array when using |
-- STD_LOGIC_VECTOR(ceil_log2(g_addr_w)-1 DOWNTO 0), instead of an error. |
BEGIN |
IF n = 0 THEN |
RETURN 0; -- Get NULL array |
ELSIF n = 1 THEN |
RETURN 1; -- avoid NULL array |
ELSE |
RETURN true_log2(n); |
END IF; |
END; |
|
FUNCTION floor_log10(n : NATURAL) RETURN NATURAL IS |
BEGIN |
RETURN natural(integer(floor(log10(real(n))))); |
END; |
|
FUNCTION is_pow2(n : NATURAL) RETURN BOOLEAN IS |
BEGIN |
RETURN n=2**true_log2(n); |
END; |
|
FUNCTION true_log_pow2(n : NATURAL) RETURN NATURAL IS |
BEGIN |
RETURN 2**true_log2(n); |
END; |
|
FUNCTION ratio(n, d : NATURAL) RETURN NATURAL IS |
BEGIN |
IF n MOD d = 0 THEN |
RETURN n/d; |
ELSE |
RETURN 0; |
END IF; |
END; |
|
FUNCTION ratio2(n, m : NATURAL) RETURN NATURAL IS |
BEGIN |
RETURN largest(ratio(n,m), ratio(m,n)); |
END; |
|
FUNCTION ceil_div(n, d : NATURAL) RETURN NATURAL IS |
BEGIN |
RETURN n/d + sel_a_b(n MOD d = 0, 0, 1); |
END; |
|
FUNCTION ceil_value(n, d : NATURAL) RETURN NATURAL IS |
BEGIN |
RETURN ceil_div(n, d) * d; |
END; |
|
FUNCTION floor_value(n, d : NATURAL) RETURN NATURAL IS |
BEGIN |
RETURN (n / d) * d; |
END; |
|
FUNCTION ceil_div(n : UNSIGNED; d: NATURAL) RETURN UNSIGNED IS |
BEGIN |
RETURN n/d + sel_a_b(n MOD d = 0, 0, 1); -- "/" returns same width as n |
END; |
|
FUNCTION ceil_value(n : UNSIGNED; d: NATURAL) RETURN UNSIGNED IS |
CONSTANT w : NATURAL := n'LENGTH; |
VARIABLE p : UNSIGNED(2*w-1 DOWNTO 0); |
BEGIN |
p := ceil_div(n, d) * d; |
RETURN p(w-1 DOWNTO 0); -- return same width as n |
END; |
|
FUNCTION floor_value(n : UNSIGNED; d: NATURAL) RETURN UNSIGNED IS |
CONSTANT w : NATURAL := n'LENGTH; |
VARIABLE p : UNSIGNED(2*w-1 DOWNTO 0); |
BEGIN |
p := (n / d) * d; |
RETURN p(w-1 DOWNTO 0); -- return same width as n |
END; |
|
FUNCTION slv(n: IN STD_LOGIC) RETURN STD_LOGIC_VECTOR IS |
VARIABLE r : STD_LOGIC_VECTOR(0 DOWNTO 0); |
BEGIN |
r(0) := n; |
RETURN r; |
END; |
|
FUNCTION sl(n: IN STD_LOGIC_VECTOR) RETURN STD_LOGIC IS |
VARIABLE r : STD_LOGIC; |
BEGIN |
r := n(n'LOW); |
RETURN r; |
END; |
|
FUNCTION to_natural_arr(n : t_integer_arr; to_zero : BOOLEAN) RETURN t_natural_arr IS |
VARIABLE vN : t_integer_arr(n'LENGTH-1 DOWNTO 0); |
VARIABLE vR : t_natural_arr(n'LENGTH-1 DOWNTO 0); |
BEGIN |
vN := n; |
FOR I IN vN'RANGE LOOP |
IF to_zero=FALSE THEN |
vR(I) := vN(I); |
ELSE |
vR(I) := 0; |
IF vN(I)>0 THEN |
vR(I) := vN(I); |
END IF; |
END IF; |
END LOOP; |
RETURN vR; |
END; |
|
FUNCTION to_natural_arr(n : t_nat_natural_arr) RETURN t_natural_arr IS |
VARIABLE vN : t_nat_natural_arr(n'LENGTH-1 DOWNTO 0); |
VARIABLE vR : t_natural_arr(n'LENGTH-1 DOWNTO 0); |
BEGIN |
vN := n; |
FOR I IN vN'RANGE LOOP |
vR(I) := vN(I); |
END LOOP; |
RETURN vR; |
END; |
|
FUNCTION to_integer_arr(n : t_natural_arr) RETURN t_integer_arr IS |
VARIABLE vN : t_natural_arr(n'LENGTH-1 DOWNTO 0); |
VARIABLE vR : t_integer_arr(n'LENGTH-1 DOWNTO 0); |
BEGIN |
vN := n; |
FOR I IN vN'RANGE LOOP |
vR(I) := vN(I); |
END LOOP; |
RETURN vR; |
END; |
|
FUNCTION to_integer_arr(n : t_nat_natural_arr) RETURN t_integer_arr IS |
VARIABLE vN : t_natural_arr(n'LENGTH-1 DOWNTO 0); |
BEGIN |
vN := to_natural_arr(n); |
RETURN to_integer_arr(vN); |
END; |
|
FUNCTION to_slv_32_arr(n : t_integer_arr) RETURN t_slv_32_arr IS |
VARIABLE vN : t_integer_arr(n'LENGTH-1 DOWNTO 0); |
VARIABLE vR : t_slv_32_arr(n'LENGTH-1 DOWNTO 0); |
BEGIN |
vN := n; |
FOR I IN vN'RANGE LOOP |
vR(I) := TO_SVEC(vN(I), 32); |
END LOOP; |
RETURN vR; |
END; |
|
FUNCTION to_slv_32_arr(n : t_natural_arr) RETURN t_slv_32_arr IS |
VARIABLE vN : t_natural_arr(n'LENGTH-1 DOWNTO 0); |
VARIABLE vR : t_slv_32_arr(n'LENGTH-1 DOWNTO 0); |
BEGIN |
vN := n; |
FOR I IN vN'RANGE LOOP |
vR(I) := TO_UVEC(vN(I), 32); |
END LOOP; |
RETURN vR; |
END; |
|
FUNCTION vector_tree(slv : STD_LOGIC_VECTOR; operation : STRING) RETURN STD_LOGIC IS |
-- Linear loop to determine result takes combinatorial delay that is proportional to slv'LENGTH: |
-- FOR I IN slv'RANGE LOOP |
-- v_result := v_result OPERATION slv(I); |
-- END LOOP; |
-- RETURN v_result; |
-- Instead use binary tree to determine result with smallest combinatorial delay that depends on log2(slv'LENGTH) |
CONSTANT c_slv_w : NATURAL := slv'LENGTH; |
CONSTANT c_nof_stages : NATURAL := ceil_log2(c_slv_w); |
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 |
TYPE t_stage_arr IS ARRAY (-1 TO c_nof_stages-1) OF STD_LOGIC_VECTOR(c_w-1 DOWNTO 0); |
VARIABLE v_stage_arr : t_stage_arr; |
VARIABLE v_result : STD_LOGIC := '0'; |
BEGIN |
-- default any unused, the stage results will be kept in the LSBits and the last result in bit 0 |
IF operation="AND" THEN v_stage_arr := (OTHERS=>(OTHERS=>'1')); |
ELSIF operation="OR" THEN v_stage_arr := (OTHERS=>(OTHERS=>'0')); |
ELSIF operation="XOR" THEN v_stage_arr := (OTHERS=>(OTHERS=>'0')); |
ELSE |
ASSERT TRUE REPORT "common_pkg: Unsupported vector_tree operation" SEVERITY FAILURE; |
END IF; |
v_stage_arr(-1)(c_slv_w-1 DOWNTO 0) := slv; -- any unused input c_w : c_slv_w bits have void default value |
FOR J IN 0 TO c_nof_stages-1 LOOP |
FOR I IN 0 TO c_w/(2**(J+1))-1 LOOP |
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); |
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); |
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); |
END IF; |
END LOOP; |
END LOOP; |
RETURN v_stage_arr(c_nof_stages-1)(0); |
END; |
|
FUNCTION vector_and(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS |
BEGIN |
RETURN vector_tree(slv, "AND"); |
END; |
|
FUNCTION vector_or(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS |
BEGIN |
RETURN vector_tree(slv, "OR"); |
END; |
|
FUNCTION vector_xor(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS |
BEGIN |
RETURN vector_tree(slv, "XOR"); |
END; |
|
FUNCTION vector_one_hot(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_one_hot : BOOLEAN := FALSE; |
VARIABLE v_zeros : STD_LOGIC_VECTOR(slv'RANGE) := (OTHERS=>'0'); |
BEGIN |
FOR i IN slv'RANGE LOOP |
IF slv(i) = '1' THEN |
IF NOT(v_one_hot) THEN |
-- No hot bits found so far |
v_one_hot := TRUE; |
ELSE |
-- This is the second hot bit found; return zeros. |
RETURN v_zeros; |
END IF; |
END IF; |
END LOOP; |
-- No or a single hot bit found in slv; return slv. |
RETURN slv; |
END; |
|
FUNCTION andv(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS |
BEGIN |
RETURN vector_tree(slv, "AND"); |
END; |
|
FUNCTION orv(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS |
BEGIN |
RETURN vector_tree(slv, "OR"); |
END; |
|
FUNCTION xorv(slv : STD_LOGIC_VECTOR) RETURN STD_LOGIC IS |
BEGIN |
RETURN vector_tree(slv, "XOR"); |
END; |
|
FUNCTION matrix_and(mat : t_sl_matrix; wi, wj : NATURAL) RETURN STD_LOGIC IS |
VARIABLE v_mat : t_sl_matrix(0 TO wi-1, 0 TO wj-1) := mat; -- map to fixed range |
VARIABLE v_result : STD_LOGIC := '1'; |
BEGIN |
FOR I IN 0 TO wi-1 LOOP |
FOR J IN 0 TO wj-1 LOOP |
v_result := v_result AND v_mat(I,J); |
END LOOP; |
END LOOP; |
RETURN v_result; |
END; |
|
FUNCTION matrix_or(mat : t_sl_matrix; wi, wj : NATURAL) RETURN STD_LOGIC IS |
VARIABLE v_mat : t_sl_matrix(0 TO wi-1, 0 TO wj-1) := mat; -- map to fixed range |
VARIABLE v_result : STD_LOGIC := '0'; |
BEGIN |
FOR I IN 0 TO wi-1 LOOP |
FOR J IN 0 TO wj-1 LOOP |
v_result := v_result OR v_mat(I,J); |
END LOOP; |
END LOOP; |
RETURN v_result; |
END; |
|
FUNCTION smallest(n, m : INTEGER) RETURN INTEGER IS |
BEGIN |
IF n < m THEN |
RETURN n; |
ELSE |
RETURN m; |
END IF; |
END; |
|
FUNCTION smallest(n, m, l : INTEGER) RETURN INTEGER IS |
VARIABLE v : NATURAL; |
BEGIN |
v := n; |
IF v > m THEN v := m; END IF; |
IF v > l THEN v := l; END IF; |
RETURN v; |
END; |
|
FUNCTION smallest(n : t_natural_arr) RETURN NATURAL IS |
VARIABLE m : NATURAL := 0; |
BEGIN |
FOR I IN n'RANGE LOOP |
IF n(I) < m THEN |
m := n(I); |
END IF; |
END LOOP; |
RETURN m; |
END; |
|
FUNCTION largest(n, m : INTEGER) RETURN INTEGER IS |
BEGIN |
IF n > m THEN |
RETURN n; |
ELSE |
RETURN m; |
END IF; |
END; |
|
FUNCTION largest(n : t_natural_arr) RETURN NATURAL IS |
VARIABLE m : NATURAL := 0; |
BEGIN |
FOR I IN n'RANGE LOOP |
IF n(I) > m THEN |
m := n(I); |
END IF; |
END LOOP; |
RETURN m; |
END; |
|
FUNCTION func_sum(n : t_natural_arr) RETURN NATURAL IS |
VARIABLE vS : NATURAL; |
BEGIN |
vS := 0; |
FOR I IN n'RANGE LOOP |
vS := vS + n(I); |
END LOOP; |
RETURN vS; |
END; |
|
FUNCTION func_sum(n : t_nat_natural_arr) RETURN NATURAL IS |
VARIABLE vN : t_natural_arr(n'LENGTH-1 DOWNTO 0); |
BEGIN |
vN := to_natural_arr(n); |
RETURN func_sum(vN); |
END; |
|
FUNCTION func_product(n : t_natural_arr) RETURN NATURAL IS |
VARIABLE vP : NATURAL; |
BEGIN |
vP := 1; |
FOR I IN n'RANGE LOOP |
vP := vP * n(I); |
END LOOP; |
RETURN vP; |
END; |
|
FUNCTION func_product(n : t_nat_natural_arr) RETURN NATURAL IS |
VARIABLE vN : t_natural_arr(n'LENGTH-1 DOWNTO 0); |
BEGIN |
vN := to_natural_arr(n); |
RETURN func_product(vN); |
END; |
|
FUNCTION "+" (L, R: t_natural_arr) RETURN t_natural_arr IS |
CONSTANT w : NATURAL := L'LENGTH; |
VARIABLE vL : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vR : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vP : t_natural_arr(w-1 DOWNTO 0); |
BEGIN |
vL := L; |
vR := R; |
FOR I IN vL'RANGE LOOP |
vP(I) := vL(I) + vR(I); |
END LOOP; |
RETURN vP; |
END; |
|
FUNCTION "+" (L: t_natural_arr; R : INTEGER) RETURN t_natural_arr IS |
CONSTANT w : NATURAL := L'LENGTH; |
VARIABLE vL : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vP : t_natural_arr(w-1 DOWNTO 0); |
BEGIN |
vL := L; |
FOR I IN vL'RANGE LOOP |
vP(I) := vL(I) + R; |
END LOOP; |
RETURN vP; |
END; |
|
FUNCTION "+" (L: INTEGER; R : t_natural_arr) RETURN t_natural_arr IS |
BEGIN |
RETURN R + L; |
END; |
|
FUNCTION "-" (L, R: t_natural_arr) RETURN t_natural_arr IS |
CONSTANT w : NATURAL := L'LENGTH; |
VARIABLE vL : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vR : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vP : t_natural_arr(w-1 DOWNTO 0); |
BEGIN |
vL := L; |
vR := R; |
FOR I IN vL'RANGE LOOP |
vP(I) := vL(I) - vR(I); |
END LOOP; |
RETURN vP; |
END; |
|
FUNCTION "-" (L, R: t_natural_arr) RETURN t_integer_arr IS |
CONSTANT w : NATURAL := L'LENGTH; |
VARIABLE vL : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vR : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vP : t_integer_arr(w-1 DOWNTO 0); |
BEGIN |
vL := L; |
vR := R; |
FOR I IN vL'RANGE LOOP |
vP(I) := vL(I) - vR(I); |
END LOOP; |
RETURN vP; |
END; |
|
FUNCTION "-" (L: t_natural_arr; R : INTEGER) RETURN t_natural_arr IS |
CONSTANT w : NATURAL := L'LENGTH; |
VARIABLE vL : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vP : t_natural_arr(w-1 DOWNTO 0); |
BEGIN |
vL := L; |
FOR I IN vL'RANGE LOOP |
vP(I) := vL(I) - R; |
END LOOP; |
RETURN vP; |
END; |
|
FUNCTION "-" (L: INTEGER; R : t_natural_arr) RETURN t_natural_arr IS |
CONSTANT w : NATURAL := R'LENGTH; |
VARIABLE vR : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vP : t_natural_arr(w-1 DOWNTO 0); |
BEGIN |
vR := R; |
FOR I IN vR'RANGE LOOP |
vP(I) := L - vR(I); |
END LOOP; |
RETURN vP; |
END; |
|
FUNCTION "*" (L, R: t_natural_arr) RETURN t_natural_arr IS |
CONSTANT w : NATURAL := L'LENGTH; |
VARIABLE vL : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vR : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vP : t_natural_arr(w-1 DOWNTO 0); |
BEGIN |
vL := L; |
vR := R; |
FOR I IN vL'RANGE LOOP |
vP(I) := vL(I) * vR(I); |
END LOOP; |
RETURN vP; |
END; |
|
FUNCTION "*" (L: t_natural_arr; R : NATURAL) RETURN t_natural_arr IS |
CONSTANT w : NATURAL := L'LENGTH; |
VARIABLE vL : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vP : t_natural_arr(w-1 DOWNTO 0); |
BEGIN |
vL := L; |
FOR I IN vL'RANGE LOOP |
vP(I) := vL(I) * R; |
END LOOP; |
RETURN vP; |
END; |
|
FUNCTION "*" (L: NATURAL; R : t_natural_arr) RETURN t_natural_arr IS |
BEGIN |
RETURN R * L; |
END; |
|
FUNCTION "/" (L, R: t_natural_arr) RETURN t_natural_arr IS |
CONSTANT w : NATURAL := L'LENGTH; |
VARIABLE vL : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vR : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vP : t_natural_arr(w-1 DOWNTO 0); |
BEGIN |
vL := L; |
vR := R; |
FOR I IN vL'RANGE LOOP |
vP(I) := vL(I) / vR(I); |
END LOOP; |
RETURN vP; |
END; |
|
FUNCTION "/" (L: t_natural_arr; R : POSITIVE) RETURN t_natural_arr IS |
CONSTANT w : NATURAL := L'LENGTH; |
VARIABLE vL : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vP : t_natural_arr(w-1 DOWNTO 0); |
BEGIN |
vL := L; |
FOR I IN vL'RANGE LOOP |
vP(I) := vL(I) / R; |
END LOOP; |
RETURN vP; |
END; |
|
FUNCTION "/" (L: NATURAL; R : t_natural_arr) RETURN t_natural_arr IS |
CONSTANT w : NATURAL := R'LENGTH; |
VARIABLE vR : t_natural_arr(w-1 DOWNTO 0); |
VARIABLE vP : t_natural_arr(w-1 DOWNTO 0); |
BEGIN |
vR := R; |
FOR I IN vR'RANGE LOOP |
vP(I) := L / vR(I); |
END LOOP; |
RETURN vP; |
END; |
|
FUNCTION is_true(a : STD_LOGIC) RETURN BOOLEAN IS BEGIN IF a='1' THEN RETURN TRUE; ELSE RETURN FALSE; END IF; END; |
FUNCTION is_true(a : STD_LOGIC) RETURN NATURAL IS BEGIN IF a='1' THEN RETURN 1; ELSE RETURN 0; END IF; END; |
FUNCTION is_true(a : BOOLEAN) RETURN STD_LOGIC IS BEGIN IF a=TRUE THEN RETURN '1'; ELSE RETURN '0'; END IF; END; |
FUNCTION is_true(a : BOOLEAN) RETURN NATURAL IS BEGIN IF a=TRUE THEN RETURN 1; ELSE RETURN 0; END IF; END; |
FUNCTION is_true(a : INTEGER) RETURN BOOLEAN IS BEGIN IF a/=0 THEN RETURN TRUE; ELSE RETURN FALSE; END IF; END; |
FUNCTION is_true(a : INTEGER) RETURN STD_LOGIC IS BEGIN IF a/=0 THEN RETURN '1'; ELSE RETURN '0'; END IF; END; |
|
FUNCTION sel_a_b(sel, a, b : INTEGER) RETURN INTEGER IS |
BEGIN |
IF sel /= 0 THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel, a, b : BOOLEAN) RETURN BOOLEAN IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : INTEGER) RETURN INTEGER IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : REAL) RETURN REAL IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : STD_LOGIC) RETURN STD_LOGIC IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : INTEGER; a, b : STD_LOGIC) RETURN STD_LOGIC IS |
BEGIN |
IF sel /= 0 THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : INTEGER; a, b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
IF sel /= 0 THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : SIGNED) RETURN SIGNED IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : UNSIGNED) RETURN UNSIGNED IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_integer_arr) RETURN t_integer_arr IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_natural_arr) RETURN t_natural_arr IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_nat_integer_arr) RETURN t_nat_integer_arr IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_nat_natural_arr) RETURN t_nat_natural_arr IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : STRING) RETURN STRING IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : INTEGER; a, b : STRING) RETURN STRING IS |
BEGIN |
IF sel /= 0 THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : TIME) RETURN TIME IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
FUNCTION sel_a_b(sel : BOOLEAN; a, b : SEVERITY_LEVEL) RETURN SEVERITY_LEVEL IS |
BEGIN |
IF sel = TRUE THEN |
RETURN a; |
ELSE |
RETURN b; |
END IF; |
END; |
|
-- sel_n : boolean |
FUNCTION sel_n(sel : NATURAL; a, b, c : BOOLEAN) RETURN BOOLEAN IS |
CONSTANT c_arr : t_nat_boolean_arr := (a, b, c); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d : BOOLEAN) RETURN BOOLEAN IS |
CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e : BOOLEAN) RETURN BOOLEAN IS |
CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d, e); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f : BOOLEAN) RETURN BOOLEAN IS |
CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d, e, f); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g : BOOLEAN) RETURN BOOLEAN IS |
CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d, e, f, g); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h : BOOLEAN) RETURN BOOLEAN IS |
CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d, e, f, g, h); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i : BOOLEAN) RETURN BOOLEAN IS |
CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d, e, f, g, h, i); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i, j : BOOLEAN) RETURN BOOLEAN IS |
CONSTANT c_arr : t_nat_boolean_arr := (a, b, c, d, e, f, g, h, i, j); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
-- sel_n : integer |
FUNCTION sel_n(sel : NATURAL; a, b, c : INTEGER) RETURN INTEGER IS |
CONSTANT c_arr : t_nat_integer_arr := (a, b, c); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d : INTEGER) RETURN INTEGER IS |
CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e : INTEGER) RETURN INTEGER IS |
CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d, e); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f : INTEGER) RETURN INTEGER IS |
CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d, e, f); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g : INTEGER) RETURN INTEGER IS |
CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d, e, f, g); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h : INTEGER) RETURN INTEGER IS |
CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d, e, f, g, h); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i : INTEGER) RETURN INTEGER IS |
CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d, e, f, g, h, i); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
FUNCTION sel_n(sel : NATURAL; a, b, c, d, e, f, g, h, i, j : INTEGER) RETURN INTEGER IS |
CONSTANT c_arr : t_nat_integer_arr := (a, b, c, d, e, f, g, h, i, j); |
BEGIN |
RETURN c_arr(sel); |
END; |
|
-- sel_n : string |
FUNCTION sel_n(sel : NATURAL; a, b : STRING) RETURN STRING IS BEGIN IF sel=0 THEN RETURN a ; ELSE RETURN b; END IF; END; |
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; |
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; |
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; |
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; |
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; |
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; |
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; |
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; |
|
FUNCTION array_init(init : STD_LOGIC; nof : NATURAL) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_arr : STD_LOGIC_VECTOR(0 TO nof-1); |
BEGIN |
FOR I IN v_arr'RANGE LOOP |
v_arr(I) := init; |
END LOOP; |
RETURN v_arr; |
END; |
|
FUNCTION array_init(init, nof : NATURAL) RETURN t_natural_arr IS |
VARIABLE v_arr : t_natural_arr(0 TO nof-1); |
BEGIN |
FOR I IN v_arr'RANGE LOOP |
v_arr(I) := init; |
END LOOP; |
RETURN v_arr; |
END; |
|
FUNCTION array_init(init, nof : NATURAL) RETURN t_nat_natural_arr IS |
VARIABLE v_arr : t_nat_natural_arr(0 TO nof-1); |
BEGIN |
FOR I IN v_arr'RANGE LOOP |
v_arr(I) := init; |
END LOOP; |
RETURN v_arr; |
END; |
|
FUNCTION array_init(init, nof, incr : NATURAL) RETURN t_natural_arr IS |
VARIABLE v_arr : t_natural_arr(0 TO nof-1); |
VARIABLE v_i : NATURAL; |
BEGIN |
v_i := 0; |
FOR I IN v_arr'RANGE LOOP |
v_arr(I) := init + v_i * incr; |
v_i := v_i + 1; |
END LOOP; |
RETURN v_arr; |
END; |
|
FUNCTION array_init(init, nof, incr : NATURAL) RETURN t_nat_natural_arr IS |
VARIABLE v_arr : t_nat_natural_arr(0 TO nof-1); |
VARIABLE v_i : NATURAL; |
BEGIN |
v_i := 0; |
FOR I IN v_arr'RANGE LOOP |
v_arr(I) := init + v_i * incr; |
v_i := v_i + 1; |
END LOOP; |
RETURN v_arr; |
END; |
|
FUNCTION array_init(init, nof, incr : INTEGER) RETURN t_slv_16_arr IS |
VARIABLE v_arr : t_slv_16_arr(0 TO nof-1); |
VARIABLE v_i : NATURAL; |
BEGIN |
v_i := 0; |
FOR I IN v_arr'RANGE LOOP |
v_arr(I) := TO_SVEC(init + v_i * incr, 16); |
v_i := v_i + 1; |
END LOOP; |
RETURN v_arr; |
END; |
|
FUNCTION array_init(init, nof, incr : INTEGER) RETURN t_slv_32_arr IS |
VARIABLE v_arr : t_slv_32_arr(0 TO nof-1); |
VARIABLE v_i : NATURAL; |
BEGIN |
v_i := 0; |
FOR I IN v_arr'RANGE LOOP |
v_arr(I) := TO_SVEC(init + v_i * incr, 32); |
v_i := v_i + 1; |
END LOOP; |
RETURN v_arr; |
END; |
|
FUNCTION array_init(init, nof, width : NATURAL) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_arr : STD_LOGIC_VECTOR(nof*width-1 DOWNTO 0); |
BEGIN |
FOR I IN 0 TO nof-1 LOOP |
v_arr(width*(I+1)-1 DOWNTO width*I) := TO_UVEC(init, width); |
END LOOP; |
RETURN v_arr; |
END; |
|
FUNCTION array_init(init, nof, width, incr : NATURAL) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_arr : STD_LOGIC_VECTOR(nof*width-1 DOWNTO 0); |
VARIABLE v_i : NATURAL; |
BEGIN |
v_i := 0; |
FOR I IN 0 TO nof-1 LOOP |
v_arr(width*(I+1)-1 DOWNTO width*I) := TO_UVEC(init + v_i * incr, width); |
v_i := v_i + 1; |
END LOOP; |
RETURN v_arr; |
END; |
|
FUNCTION array_sinit(init :INTEGER; nof, width : NATURAL) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_arr : STD_LOGIC_VECTOR(nof*width-1 DOWNTO 0); |
BEGIN |
FOR I IN 0 TO nof-1 LOOP |
v_arr(width*(I+1)-1 DOWNTO width*I) := TO_SVEC(init, width); |
END LOOP; |
RETURN v_arr; |
END; |
|
FUNCTION init_slv_64_matrix(nof_a, nof_b, k : INTEGER) RETURN t_slv_64_matrix IS |
VARIABLE v_mat : t_slv_64_matrix(nof_a-1 DOWNTO 0, nof_b-1 DOWNTO 0); |
BEGIN |
FOR I IN 0 TO nof_a-1 LOOP |
FOR J IN 0 TO nof_b-1 LOOP |
v_mat(I,J) := TO_SVEC(k, 64); |
END LOOP; |
END LOOP; |
RETURN v_mat; |
END; |
|
|
-- Support concatenation of up to 7 slv into 1 slv |
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 |
CONSTANT c_max_w : NATURAL := a'LENGTH + b'LENGTH + c'LENGTH + d'LENGTH + e'LENGTH + f'LENGTH + g'LENGTH; |
VARIABLE v_res : STD_LOGIC_VECTOR(c_max_w-1 DOWNTO 0) := (OTHERS=>'0'); |
VARIABLE v_len : NATURAL := 0; |
BEGIN |
IF use_a = TRUE THEN v_res(a'LENGTH-1 + v_len DOWNTO v_len) := a; v_len := v_len + a'LENGTH; END IF; |
IF use_b = TRUE THEN v_res(b'LENGTH-1 + v_len DOWNTO v_len) := b; v_len := v_len + b'LENGTH; END IF; |
IF use_c = TRUE THEN v_res(c'LENGTH-1 + v_len DOWNTO v_len) := c; v_len := v_len + c'LENGTH; END IF; |
IF use_d = TRUE THEN v_res(d'LENGTH-1 + v_len DOWNTO v_len) := d; v_len := v_len + d'LENGTH; END IF; |
IF use_e = TRUE THEN v_res(e'LENGTH-1 + v_len DOWNTO v_len) := e; v_len := v_len + e'LENGTH; END IF; |
IF use_f = TRUE THEN v_res(f'LENGTH-1 + v_len DOWNTO v_len) := f; v_len := v_len + f'LENGTH; END IF; |
IF use_g = TRUE THEN v_res(g'LENGTH-1 + v_len DOWNTO v_len) := g; v_len := v_len + g'LENGTH; END IF; |
RETURN v_res(v_len-1 DOWNTO 0); |
END func_slv_concat; |
|
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 |
BEGIN |
RETURN func_slv_concat(use_a, use_b, use_c, use_d, use_e, use_f, FALSE, a, b, c, d, e, f, "0"); |
END func_slv_concat; |
|
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 |
BEGIN |
RETURN func_slv_concat(use_a, use_b, use_c, use_d, use_e, FALSE, FALSE, a, b, c, d, e, "0", "0"); |
END func_slv_concat; |
|
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 |
BEGIN |
RETURN func_slv_concat(use_a, use_b, use_c, use_d, FALSE, FALSE, FALSE, a, b, c, d, "0", "0", "0"); |
END func_slv_concat; |
|
FUNCTION func_slv_concat(use_a, use_b, use_c : BOOLEAN; a, b, c : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN func_slv_concat(use_a, use_b, use_c, FALSE, FALSE, FALSE, FALSE, a, b, c, "0", "0", "0", "0"); |
END func_slv_concat; |
|
FUNCTION func_slv_concat(use_a, use_b : BOOLEAN; a, b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN func_slv_concat(use_a, use_b, FALSE, FALSE, FALSE, FALSE, FALSE, a, b, "0", "0", "0", "0", "0"); |
END func_slv_concat; |
|
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 |
VARIABLE v_len : NATURAL := 0; |
BEGIN |
IF use_a = TRUE THEN v_len := v_len + a_w; END IF; |
IF use_b = TRUE THEN v_len := v_len + b_w; END IF; |
IF use_c = TRUE THEN v_len := v_len + c_w; END IF; |
IF use_d = TRUE THEN v_len := v_len + d_w; END IF; |
IF use_e = TRUE THEN v_len := v_len + e_w; END IF; |
IF use_f = TRUE THEN v_len := v_len + f_w; END IF; |
IF use_g = TRUE THEN v_len := v_len + g_w; END IF; |
RETURN v_len; |
END func_slv_concat_w; |
|
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 |
BEGIN |
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); |
END func_slv_concat_w; |
|
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 |
BEGIN |
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); |
END func_slv_concat_w; |
|
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 |
BEGIN |
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); |
END func_slv_concat_w; |
|
FUNCTION func_slv_concat_w(use_a, use_b, use_c : BOOLEAN; a_w, b_w, c_w : NATURAL) RETURN NATURAL IS |
BEGIN |
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); |
END func_slv_concat_w; |
|
FUNCTION func_slv_concat_w(use_a, use_b : BOOLEAN; a_w, b_w : NATURAL) RETURN NATURAL IS |
BEGIN |
RETURN func_slv_concat_w(use_a, use_b, FALSE, FALSE, FALSE, FALSE, FALSE, a_w, b_w, 0, 0, 0, 0, 0); |
END func_slv_concat_w; |
|
-- extract slv |
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 |
VARIABLE v_w : NATURAL := 0; |
VARIABLE v_lo : NATURAL := 0; |
BEGIN |
-- if the selected slv is not used in vec, then return dummy, else return the selected slv from vec |
CASE sel IS |
WHEN 0 => |
IF use_a = TRUE THEN v_w := a_w; ELSE RETURN c_slv0(a_w-1 DOWNTO 0); END IF; |
WHEN 1 => |
IF use_b = TRUE THEN v_w := b_w; ELSE RETURN c_slv0(b_w-1 DOWNTO 0); END IF; |
IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF; |
WHEN 2 => |
IF use_c = TRUE THEN v_w := c_w; ELSE RETURN c_slv0(c_w-1 DOWNTO 0); END IF; |
IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF; |
IF use_b = TRUE THEN v_lo := v_lo + b_w; END IF; |
WHEN 3 => |
IF use_d = TRUE THEN v_w := d_w; ELSE RETURN c_slv0(d_w-1 DOWNTO 0); END IF; |
IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF; |
IF use_b = TRUE THEN v_lo := v_lo + b_w; END IF; |
IF use_c = TRUE THEN v_lo := v_lo + c_w; END IF; |
WHEN 4 => |
IF use_e = TRUE THEN v_w := e_w; ELSE RETURN c_slv0(e_w-1 DOWNTO 0); END IF; |
IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF; |
IF use_b = TRUE THEN v_lo := v_lo + b_w; END IF; |
IF use_c = TRUE THEN v_lo := v_lo + c_w; END IF; |
IF use_d = TRUE THEN v_lo := v_lo + d_w; END IF; |
WHEN 5 => |
IF use_f = TRUE THEN v_w := f_w; ELSE RETURN c_slv0(f_w-1 DOWNTO 0); END IF; |
IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF; |
IF use_b = TRUE THEN v_lo := v_lo + b_w; END IF; |
IF use_c = TRUE THEN v_lo := v_lo + c_w; END IF; |
IF use_d = TRUE THEN v_lo := v_lo + d_w; END IF; |
IF use_e = TRUE THEN v_lo := v_lo + e_w; END IF; |
WHEN 6 => |
IF use_g = TRUE THEN v_w := g_w; ELSE RETURN c_slv0(g_w-1 DOWNTO 0); END IF; |
IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF; |
IF use_b = TRUE THEN v_lo := v_lo + b_w; END IF; |
IF use_c = TRUE THEN v_lo := v_lo + c_w; END IF; |
IF use_d = TRUE THEN v_lo := v_lo + d_w; END IF; |
IF use_e = TRUE THEN v_lo := v_lo + e_w; END IF; |
IF use_f = TRUE THEN v_lo := v_lo + f_w; END IF; |
WHEN OTHERS => REPORT "Unknown common_pkg func_slv_extract argument" SEVERITY FAILURE; |
END CASE; |
RETURN vec(v_w-1 + v_lo DOWNTO v_lo); -- extracted slv |
END func_slv_extract; |
|
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 |
BEGIN |
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); |
END func_slv_extract; |
|
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 |
BEGIN |
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); |
END func_slv_extract; |
|
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 |
BEGIN |
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); |
END func_slv_extract; |
|
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 |
BEGIN |
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); |
END func_slv_extract; |
|
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 |
BEGIN |
RETURN func_slv_extract(use_a, use_b, FALSE, FALSE, FALSE, FALSE, FALSE, a_w, b_w, 0, 0, 0, 0, 0, vec, sel); |
END func_slv_extract; |
|
|
FUNCTION TO_UINT(vec : STD_LOGIC_VECTOR) RETURN NATURAL IS |
BEGIN |
RETURN TO_INTEGER(UNSIGNED(vec)); |
END; |
|
FUNCTION TO_SINT(vec : STD_LOGIC_VECTOR) RETURN INTEGER IS |
BEGIN |
RETURN TO_INTEGER(SIGNED(vec)); |
END; |
|
FUNCTION TO_UVEC(dec, w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN STD_LOGIC_VECTOR(TO_UNSIGNED(dec, w)); |
END; |
|
FUNCTION TO_SVEC(dec, w : INTEGER) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN STD_LOGIC_VECTOR(TO_SIGNED(dec, w)); |
END; |
|
FUNCTION TO_SVEC_32(dec : INTEGER) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN TO_SVEC(dec, 32); |
END; |
|
FUNCTION RESIZE_NUM(u : UNSIGNED; w : NATURAL) RETURN UNSIGNED IS |
BEGIN |
-- left extend with '0' or keep LS part (same as RESIZE for UNSIGNED) |
RETURN RESIZE(u, w); |
END; |
|
FUNCTION RESIZE_NUM(s : SIGNED; w : NATURAL) RETURN SIGNED IS |
BEGIN |
-- extend sign bit or keep LS part |
IF w>s'LENGTH THEN |
RETURN RESIZE(s, w); -- extend sign bit |
ELSE |
RETURN SIGNED(RESIZE(UNSIGNED(s), w)); -- keep LSbits (= vec[w-1:0]) |
END IF; |
END; |
|
FUNCTION RESIZE_UVEC(sl : STD_LOGIC; w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_slv0 : STD_LOGIC_VECTOR(w-1 DOWNTO 1) := (OTHERS=>'0'); |
BEGIN |
RETURN v_slv0 & sl; |
END; |
|
FUNCTION RESIZE_UVEC(vec : STD_LOGIC_VECTOR; w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN STD_LOGIC_VECTOR(RESIZE_NUM(UNSIGNED(vec), w)); |
END; |
|
FUNCTION RESIZE_SVEC(vec : STD_LOGIC_VECTOR; w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN STD_LOGIC_VECTOR(RESIZE_NUM(SIGNED(vec), w)); |
END; |
|
FUNCTION RESIZE_UINT(u : INTEGER; w : NATURAL) RETURN INTEGER IS |
VARIABLE v : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); |
BEGIN |
v := TO_UVEC(u, c_word_w); |
RETURN TO_UINT(v(w-1 DOWNTO 0)); |
END; |
|
FUNCTION RESIZE_SINT(s : INTEGER; w : NATURAL) RETURN INTEGER IS |
VARIABLE v : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); |
BEGIN |
v := TO_SVEC(s, c_word_w); |
RETURN TO_SINT(v(w-1 DOWNTO 0)); |
END; |
|
FUNCTION RESIZE_UVEC_32(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN RESIZE_UVEC(vec, 32); |
END; |
|
FUNCTION RESIZE_SVEC_32(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN RESIZE_SVEC(vec, 32); |
END; |
|
FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : INTEGER) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_dec : INTEGER; |
BEGIN |
IF dec < 0 THEN |
v_dec := -dec; |
RETURN STD_LOGIC_VECTOR(UNSIGNED(vec) - v_dec); -- uses function "-" (L : UNSIGNED, R : NATURAL), there is no function + with R : INTEGER argument |
ELSE |
v_dec := dec; |
RETURN STD_LOGIC_VECTOR(UNSIGNED(vec) + v_dec); -- uses function "+" (L : UNSIGNED, R : NATURAL) |
END IF; |
END; |
|
FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : UNSIGNED) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN STD_LOGIC_VECTOR(UNSIGNED(vec) + dec); |
END; |
|
FUNCTION INCR_SVEC(vec : STD_LOGIC_VECTOR; dec : INTEGER) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_dec : INTEGER; |
BEGIN |
RETURN STD_LOGIC_VECTOR(SIGNED(vec) + v_dec); -- uses function "+" (L : SIGNED, R : INTEGER) |
END; |
|
FUNCTION INCR_SVEC(vec : STD_LOGIC_VECTOR; dec : SIGNED) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN STD_LOGIC_VECTOR(SIGNED(vec) + dec); |
END; |
|
FUNCTION ADD_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN STD_LOGIC_VECTOR(RESIZE_NUM(SIGNED(l_vec), res_w) + SIGNED(r_vec)); |
END; |
|
FUNCTION SUB_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN STD_LOGIC_VECTOR(RESIZE_NUM(SIGNED(l_vec), res_w) - SIGNED(r_vec)); |
END; |
|
FUNCTION ADD_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN STD_LOGIC_VECTOR(RESIZE_NUM(UNSIGNED(l_vec), res_w) + UNSIGNED(r_vec)); |
END; |
|
FUNCTION SUB_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR; res_w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN STD_LOGIC_VECTOR(RESIZE_NUM(UNSIGNED(l_vec), res_w) - UNSIGNED(r_vec)); |
END; |
|
|
FUNCTION ADD_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN ADD_SVEC(l_vec, r_vec, l_vec'LENGTH); |
END; |
|
FUNCTION SUB_SVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN SUB_SVEC(l_vec, r_vec, l_vec'LENGTH); |
END; |
|
FUNCTION ADD_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN ADD_UVEC(l_vec, r_vec, l_vec'LENGTH); |
END; |
|
FUNCTION SUB_UVEC(l_vec : STD_LOGIC_VECTOR; r_vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN SUB_UVEC(l_vec, r_vec, l_vec'LENGTH); |
END; |
|
FUNCTION COMPLEX_MULT_REAL(a_re, a_im, b_re, b_im : INTEGER) RETURN INTEGER IS |
BEGIN |
RETURN (a_re*b_re - a_im*b_im); |
END; |
|
FUNCTION COMPLEX_MULT_IMAG(a_re, a_im, b_re, b_im : INTEGER) RETURN INTEGER IS |
BEGIN |
RETURN (a_im*b_re + a_re*b_im); |
END; |
|
FUNCTION SHIFT_UVEC(vec : STD_LOGIC_VECTOR; shift : INTEGER) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
IF shift < 0 THEN |
RETURN STD_LOGIC_VECTOR(SHIFT_LEFT(UNSIGNED(vec), -shift)); -- fill zeros from right |
ELSE |
RETURN STD_LOGIC_VECTOR(SHIFT_RIGHT(UNSIGNED(vec), shift)); -- fill zeros from left |
END IF; |
END; |
|
FUNCTION SHIFT_SVEC(vec : STD_LOGIC_VECTOR; shift : INTEGER) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
IF shift < 0 THEN |
RETURN STD_LOGIC_VECTOR(SHIFT_LEFT(SIGNED(vec), -shift)); -- same as SHIFT_LEFT for UNSIGNED |
ELSE |
RETURN STD_LOGIC_VECTOR(SHIFT_RIGHT(SIGNED(vec), shift)); -- extend sign |
END IF; |
END; |
|
-- |
-- offset_binary() : maps offset binary to or from two-complement binary. |
-- |
-- National ADC08DC1020 offset binary two-complement binary |
-- + full scale = 127.5 : 11111111 = 255 127 = 01111111 |
-- ... |
-- + = +0.5 : 10000000 = 128 0 = 00000000 |
-- 0 |
-- - = -0.5 : 01111111 = 127 -1 = 11111111 |
-- ... |
-- - full scale = -127.5 : 00000000 = 0 -128 = 10000000 |
-- |
-- To map between the offset binary and two complement binary involves |
-- adding 128 to the binary value or equivalently inverting the sign bit. |
-- The offset_binary() mapping can be done and undone both ways. |
-- The offset_binary() mapping to two-complement binary yields a DC offset |
-- of -0.5 Lsb. |
FUNCTION offset_binary(a : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_res : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0) := a; |
BEGIN |
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 |
RETURN v_res; |
END; |
|
FUNCTION truncate(vec : STD_LOGIC_VECTOR; n : NATURAL) RETURN STD_LOGIC_VECTOR IS |
CONSTANT c_vec_w : NATURAL := vec'LENGTH; |
CONSTANT c_trunc_w : NATURAL := c_vec_w-n; |
VARIABLE v_vec : STD_LOGIC_VECTOR(c_vec_w-1 DOWNTO 0) := vec; |
VARIABLE v_res : STD_LOGIC_VECTOR(c_trunc_w-1 DOWNTO 0); |
BEGIN |
v_res := v_vec(c_vec_w-1 DOWNTO n); -- keep MS part |
RETURN v_res; |
END; |
|
FUNCTION truncate_and_resize_uvec(vec : STD_LOGIC_VECTOR; n, w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
CONSTANT c_vec_w : NATURAL := vec'LENGTH; |
CONSTANT c_trunc_w : NATURAL := c_vec_w-n; |
VARIABLE v_trunc : STD_LOGIC_VECTOR(c_trunc_w-1 DOWNTO 0); |
VARIABLE v_res : STD_LOGIC_VECTOR(w-1 DOWNTO 0); |
BEGIN |
v_trunc := truncate(vec, n); -- first keep MS part |
v_res := RESIZE_UVEC(v_trunc, w); -- then keep LS part or left extend with '0' |
RETURN v_res; |
END; |
|
FUNCTION truncate_and_resize_svec(vec : STD_LOGIC_VECTOR; n, w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
CONSTANT c_vec_w : NATURAL := vec'LENGTH; |
CONSTANT c_trunc_w : NATURAL := c_vec_w-n; |
VARIABLE v_trunc : STD_LOGIC_VECTOR(c_trunc_w-1 DOWNTO 0); |
VARIABLE v_res : STD_LOGIC_VECTOR(w-1 DOWNTO 0); |
BEGIN |
v_trunc := truncate(vec, n); -- first keep MS part |
v_res := RESIZE_SVEC(v_trunc, w); -- then keep sign bit and LS part or left extend sign bit |
RETURN v_res; |
END; |
|
FUNCTION scale(vec : STD_LOGIC_VECTOR; n: NATURAL) RETURN STD_LOGIC_VECTOR IS |
CONSTANT c_vec_w : NATURAL := vec'LENGTH; |
CONSTANT c_scale_w : NATURAL := c_vec_w+n; |
VARIABLE v_res : STD_LOGIC_VECTOR(c_scale_w-1 DOWNTO 0) := (OTHERS=>'0'); |
BEGIN |
v_res(c_scale_w-1 DOWNTO n) := vec; -- scale by adding n zero bits at the right |
RETURN v_res; |
END; |
|
FUNCTION scale_and_resize_uvec(vec : STD_LOGIC_VECTOR; n, w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
CONSTANT c_vec_w : NATURAL := vec'LENGTH; |
CONSTANT c_scale_w : NATURAL := c_vec_w+n; |
VARIABLE v_scale : STD_LOGIC_VECTOR(c_scale_w-1 DOWNTO 0) := (OTHERS=>'0'); |
VARIABLE v_res : STD_LOGIC_VECTOR(w-1 DOWNTO 0); |
BEGIN |
v_scale(c_scale_w-1 DOWNTO n) := vec; -- first scale by adding n zero bits at the right |
v_res := RESIZE_UVEC(v_scale, w); -- then keep LS part or left extend with '0' |
RETURN v_res; |
END; |
|
FUNCTION scale_and_resize_svec(vec : STD_LOGIC_VECTOR; n, w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
CONSTANT c_vec_w : NATURAL := vec'LENGTH; |
CONSTANT c_scale_w : NATURAL := c_vec_w+n; |
VARIABLE v_scale : STD_LOGIC_VECTOR(c_scale_w-1 DOWNTO 0) := (OTHERS=>'0'); |
VARIABLE v_res : STD_LOGIC_VECTOR(w-1 DOWNTO 0); |
BEGIN |
v_scale(c_scale_w-1 DOWNTO n) := vec; -- first scale by adding n zero bits at the right |
v_res := RESIZE_SVEC(v_scale, w); -- then keep LS part or left extend sign bit |
RETURN v_res; |
END; |
|
FUNCTION truncate_or_resize_uvec(vec : STD_LOGIC_VECTOR; b : BOOLEAN; w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
CONSTANT c_vec_w : NATURAL := vec'LENGTH; |
VARIABLE c_n : INTEGER := c_vec_w-w; |
VARIABLE v_res : STD_LOGIC_VECTOR(w-1 DOWNTO 0); |
BEGIN |
IF b=TRUE AND c_n>0 THEN |
v_res := truncate_and_resize_uvec(vec, c_n, w); |
ELSE |
v_res := RESIZE_UVEC(vec, w); |
END IF; |
RETURN v_res; |
END; |
|
FUNCTION truncate_or_resize_svec(vec : STD_LOGIC_VECTOR; b : BOOLEAN; w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
CONSTANT c_vec_w : NATURAL := vec'LENGTH; |
VARIABLE c_n : INTEGER := c_vec_w-w; |
VARIABLE v_res : STD_LOGIC_VECTOR(w-1 DOWNTO 0); |
BEGIN |
IF b=TRUE AND c_n>0 THEN |
v_res := truncate_and_resize_svec(vec, c_n, w); |
ELSE |
v_res := RESIZE_SVEC(vec, w); |
END IF; |
RETURN v_res; |
END; |
|
|
-- Functions s_round, s_round_up and u_round: |
-- |
-- . The returned output width is input width - n. |
-- . If n=0 then the return value is the same as the input value so only |
-- wires (NOP, no operation). |
-- . Both have the same implementation but different c_max and c_clip values. |
-- . Round up for unsigned so +2.5 becomes 3 |
-- . 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. |
-- . Round away from zero is also used by round() in Matlab, Python, TCL |
-- . Rounding up implies adding 0.5 and then truncation, use clip = TRUE to |
-- clip the potential overflow due to adding 0.5 to +max. |
-- . For negative values overflow due to rounding can not occur, because c_half-1 >= 0 for n>0 |
-- . If the input comes from a product and is rounded to the input width then |
-- clip can safely be FALSE, because e.g. for unsigned 4b*4b=8b->4b the |
-- maximum product is 15*15=225 <= 255-8, and for signed 4b*4b=8b->4b the |
-- maximum product is -8*-8=+64 <= 127-8, so wrapping due to rounding |
-- overflow will never occur. |
|
FUNCTION s_round(vec : STD_LOGIC_VECTOR; n : NATURAL; clip : BOOLEAN) RETURN STD_LOGIC_VECTOR IS |
-- Use SIGNED to avoid NATURAL (32 bit range) overflow error |
CONSTANT c_in_w : NATURAL := vec'LENGTH; |
CONSTANT c_out_w : NATURAL := vec'LENGTH - n; |
CONSTANT c_one : SIGNED(c_in_w-1 DOWNTO 0) := TO_SIGNED(1, c_in_w); |
CONSTANT c_half : SIGNED(c_in_w-1 DOWNTO 0) := SHIFT_LEFT(c_one, n-1); -- = 2**(n-1) |
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 |
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 |
VARIABLE v_in : SIGNED(c_in_w-1 DOWNTO 0); |
VARIABLE v_out : SIGNED(c_out_w-1 DOWNTO 0); |
BEGIN |
v_in := SIGNED(vec); |
IF n > 0 THEN |
IF clip = TRUE AND v_in > c_max THEN |
v_out := c_clip; -- Round clip to maximum positive to avoid wrap to negative |
ELSE |
IF vec(vec'HIGH)='0' THEN |
v_out := RESIZE_NUM(SHIFT_RIGHT(v_in + c_half + 0, n), c_out_w); -- Round up for positive |
ELSE |
v_out := RESIZE_NUM(SHIFT_RIGHT(v_in + c_half - 1, n), c_out_w); -- Round down for negative |
END IF; |
END IF; |
ELSE |
v_out := RESIZE_NUM(v_in, c_out_w); -- NOP |
END IF; |
RETURN STD_LOGIC_VECTOR(v_out); |
END; |
|
FUNCTION s_round(vec : STD_LOGIC_VECTOR; n : NATURAL) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN s_round(vec, n, FALSE); -- no round clip |
END; |
|
-- An alternative is to always round up, also for negative numbers (i.e. s_round_up = u_round). |
FUNCTION s_round_up(vec : STD_LOGIC_VECTOR; n : NATURAL; clip : BOOLEAN) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN u_round(vec, n, clip); |
END; |
|
FUNCTION s_round_up(vec : STD_LOGIC_VECTOR; n : NATURAL) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN u_round(vec, n, FALSE); -- no round clip |
END; |
|
-- Unsigned numbers are round up (almost same as s_round, but without the else on negative vec) |
FUNCTION u_round(vec : STD_LOGIC_VECTOR; n : NATURAL; clip : BOOLEAN ) RETURN STD_LOGIC_VECTOR IS |
-- Use UNSIGNED to avoid NATURAL (32 bit range) overflow error |
CONSTANT c_in_w : NATURAL := vec'LENGTH; |
CONSTANT c_out_w : NATURAL := vec'LENGTH - n; |
CONSTANT c_one : UNSIGNED(c_in_w-1 DOWNTO 0) := TO_UNSIGNED(1, c_in_w); |
CONSTANT c_half : UNSIGNED(c_in_w-1 DOWNTO 0) := SHIFT_LEFT(c_one, n-1); -- = 2**(n-1) |
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 |
CONSTANT c_clip : UNSIGNED(c_out_w-1 DOWNTO 0) := UNSIGNED(c_slv1(c_out_w-1 DOWNTO 0)); -- = 2**c_out_w-1 |
VARIABLE v_in : UNSIGNED(c_in_w-1 DOWNTO 0); |
VARIABLE v_out : UNSIGNED(c_out_w-1 DOWNTO 0); |
BEGIN |
v_in := UNSIGNED(vec); |
IF n > 0 THEN |
IF clip = TRUE AND v_in > c_max THEN |
v_out := c_clip; -- Round clip to +max to avoid wrap to 0 |
ELSE |
v_out := RESIZE_NUM(SHIFT_RIGHT(v_in + c_half, n), c_out_w); -- Round up |
END IF; |
ELSE |
v_out := RESIZE_NUM(v_in, c_out_w); -- NOP |
END IF; |
RETURN STD_LOGIC_VECTOR(v_out); |
END; |
|
FUNCTION u_round(vec : STD_LOGIC_VECTOR; n : NATURAL) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN u_round(vec, n, FALSE); -- no round clip |
END; |
|
|
FUNCTION hton(a : STD_LOGIC_VECTOR; w, sz : NATURAL) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_a : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0) := a; -- map a to range [h:0] |
VARIABLE v_b : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0) := a; -- default b = a |
VARIABLE vL : NATURAL; |
VARIABLE vK : NATURAL; |
BEGIN |
-- Note: |
-- . if sz = 1 then v_b = v_a |
-- . if a'LENGTH > sz*w then v_b(a'LENGTH:sz*w) = v_a(a'LENGTH:sz*w) |
FOR vL IN 0 TO sz-1 LOOP |
vK := sz-1 - vL; |
v_b((vL+1)*w-1 DOWNTO vL*w) := v_a((vK+1)*w-1 DOWNTO vK*w); |
END LOOP; |
RETURN v_b; |
END FUNCTION; |
|
FUNCTION hton(a : STD_LOGIC_VECTOR; sz : NATURAL) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN hton(a, c_byte_w, sz); -- symbol width w = c_byte_w = 8 |
END FUNCTION; |
|
FUNCTION hton(a : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
CONSTANT c_sz : NATURAL := a'LENGTH/ c_byte_w; |
BEGIN |
RETURN hton(a, c_byte_w, c_sz); -- symbol width w = c_byte_w = 8 |
END FUNCTION; |
|
FUNCTION ntoh(a : STD_LOGIC_VECTOR; sz : NATURAL) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN hton(a, sz); -- i.e. ntoh() = hton() |
END FUNCTION; |
|
FUNCTION ntoh(a : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
BEGIN |
RETURN hton(a); -- i.e. ntoh() = hton() |
END FUNCTION; |
|
FUNCTION flip(a : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_a : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0) := a; |
VARIABLE v_b : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0); |
BEGIN |
FOR I IN v_a'RANGE LOOP |
v_b(a'LENGTH-1-I) := v_a(I); |
END LOOP; |
RETURN v_b; |
END; |
|
FUNCTION flip(a, w : NATURAL) RETURN NATURAL IS |
BEGIN |
RETURN TO_UINT(flip(TO_UVEC(a, w))); |
END; |
|
FUNCTION flip(a : t_slv_32_arr) RETURN t_slv_32_arr IS |
VARIABLE v_a : t_slv_32_arr(a'LENGTH-1 DOWNTO 0) := a; |
VARIABLE v_b : t_slv_32_arr(a'LENGTH-1 DOWNTO 0); |
BEGIN |
FOR I IN v_a'RANGE LOOP |
v_b(a'LENGTH-1-I) := v_a(I); |
END LOOP; |
RETURN v_b; |
END; |
|
FUNCTION flip(a : t_integer_arr) RETURN t_integer_arr IS |
VARIABLE v_a : t_integer_arr(a'LENGTH-1 DOWNTO 0) := a; |
VARIABLE v_b : t_integer_arr(a'LENGTH-1 DOWNTO 0); |
BEGIN |
FOR I IN v_a'RANGE LOOP |
v_b(a'LENGTH-1-I) := v_a(I); |
END LOOP; |
RETURN v_b; |
END; |
|
FUNCTION flip(a : t_natural_arr) RETURN t_natural_arr IS |
VARIABLE v_a : t_natural_arr(a'LENGTH-1 DOWNTO 0) := a; |
VARIABLE v_b : t_natural_arr(a'LENGTH-1 DOWNTO 0); |
BEGIN |
FOR I IN v_a'RANGE LOOP |
v_b(a'LENGTH-1-I) := v_a(I); |
END LOOP; |
RETURN v_b; |
END; |
|
FUNCTION flip(a : t_nat_natural_arr) RETURN t_nat_natural_arr IS |
VARIABLE v_a : t_nat_natural_arr(a'LENGTH-1 DOWNTO 0) := a; |
VARIABLE v_b : t_nat_natural_arr(a'LENGTH-1 DOWNTO 0); |
BEGIN |
FOR I IN v_a'RANGE LOOP |
v_b(a'LENGTH-1-I) := v_a(I); |
END LOOP; |
RETURN v_b; |
END; |
|
FUNCTION transpose(a : STD_LOGIC_VECTOR; row, col : NATURAL) RETURN STD_LOGIC_VECTOR IS |
VARIABLE vIn : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0); |
VARIABLE vOut : STD_LOGIC_VECTOR(a'LENGTH-1 DOWNTO 0); |
BEGIN |
vIn := a; -- map input vector to h:0 range |
vOut := vIn; -- default leave any unused MSbits the same |
FOR J IN 0 TO row-1 LOOP |
FOR I IN 0 TO col-1 LOOP |
vOut(J*col + I) := vIn(I*row + J); -- transpose vector, map input index [i*row+j] to output index [j*col+i] |
END LOOP; |
END LOOP; |
RETURN vOut; |
END FUNCTION; |
|
FUNCTION transpose(a, row, col : NATURAL) RETURN NATURAL IS -- transpose index a = [i*row+j] to output index [j*col+i] |
VARIABLE vI : NATURAL; |
VARIABLE vJ : NATURAL; |
BEGIN |
vI := a / row; |
vJ := a MOD row; |
RETURN vJ * col + vI; |
END; |
|
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 |
-- 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. |
VARIABLE r: NATURAL; |
BEGIN |
r := input_w; |
FOR i IN 1 TO ceil_log2(input_w) LOOP -- Useless to divide the number beyond this |
IF r <= max_out_w AND r >= min_out_w THEN |
RETURN r; |
ELSIF i = ceil_log2(input_w) THEN -- last iteration |
RETURN 0; -- Indicates wrong values were used |
END IF; |
r := r / 2; |
END LOOP; |
END; |
|
FUNCTION pad(str: STRING; width: NATURAL; pad_char: CHARACTER) RETURN STRING IS |
VARIABLE v_str : STRING(1 TO width) := (OTHERS => pad_char); |
BEGIN |
v_str(width-str'LENGTH+1 TO width) := str; |
RETURN v_str; |
END; |
|
FUNCTION slice_up(str: STRING; width: NATURAL; i: NATURAL) RETURN STRING IS |
BEGIN |
RETURN str(i*width+1 TO (i+1)*width); |
END; |
|
-- If the input value is not a multiple of the desired width, the return value is padded with |
-- the passed pad value. E.g. if input='10' and desired width is 4, return value is '0010'. |
FUNCTION slice_up(str: STRING; width: NATURAL; i: NATURAL; pad_char: CHARACTER) RETURN STRING IS |
VARIABLE padded_str : STRING(1 TO width) := (OTHERS=>'0'); |
BEGIN |
padded_str := pad(str(i*width+1 TO (i+1)*width), width, '0'); |
RETURN padded_str; |
END; |
|
FUNCTION slice_dn(str: STRING; width: NATURAL; i: NATURAL) RETURN STRING IS |
BEGIN |
RETURN str((i+1)*width-1 DOWNTO i*width); |
END; |
|
|
FUNCTION nat_arr_to_concat_slv(nat_arr: t_natural_arr; nof_elements: NATURAL) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_concat_slv : STD_LOGIC_VECTOR(nof_elements*32-1 DOWNTO 0) := (OTHERS=>'0'); |
BEGIN |
FOR i IN 0 TO nof_elements-1 LOOP |
v_concat_slv(i*32+32-1 DOWNTO i*32) := TO_UVEC(nat_arr(i), 32); |
END LOOP; |
RETURN v_concat_slv; |
END; |
|
|
------------------------------------------------------------------------------ |
-- common_fifo_* |
------------------------------------------------------------------------------ |
|
PROCEDURE proc_common_fifo_asserts (CONSTANT c_fifo_name : IN STRING; |
CONSTANT c_note_is_ful : IN BOOLEAN; |
CONSTANT c_fail_rd_emp : IN BOOLEAN; |
SIGNAL wr_rst : IN STD_LOGIC; |
SIGNAL wr_clk : IN STD_LOGIC; |
SIGNAL wr_full : IN STD_LOGIC; |
SIGNAL wr_en : IN STD_LOGIC; |
SIGNAL rd_clk : IN STD_LOGIC; |
SIGNAL rd_empty : IN STD_LOGIC; |
SIGNAL rd_en : IN STD_LOGIC) IS |
BEGIN |
-- c_fail_rd_emp : when TRUE report FAILURE when read from an empty FIFO, important when FIFO rd_val is not used |
-- c_note_is_ful : when TRUE report NOTE when FIFO goes full, to note that operation is on the limit |
-- FIFO overflow is always reported as FAILURE |
|
-- 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. |
-- Therefore only check on wr_full going high when wr_rst='0'. |
|
--synthesis translate_off |
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; |
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; |
ASSERT NOT( rising_edge(wr_clk) AND wr_full='1' AND wr_en='1') REPORT c_fifo_name & " : fifo overflow occurred!" SEVERITY FAILURE; |
--synthesis translate_on |
END PROCEDURE proc_common_fifo_asserts; |
|
|
------------------------------------------------------------------------------ |
-- common_fanout_tree |
------------------------------------------------------------------------------ |
|
FUNCTION func_common_fanout_tree_pipelining(c_nof_stages, c_nof_output_per_cell, c_nof_output : NATURAL; |
c_cell_pipeline_factor_arr, c_cell_pipeline_arr : t_natural_arr) RETURN t_natural_arr IS |
CONSTANT k_cell_pipeline_factor_arr : t_natural_arr(c_nof_stages-1 DOWNTO 0) := c_cell_pipeline_factor_arr; |
CONSTANT k_cell_pipeline_arr : t_natural_arr(c_nof_output_per_cell-1 DOWNTO 0) := c_cell_pipeline_arr; |
VARIABLE v_stage_pipeline_arr : t_natural_arr(c_nof_output-1 DOWNTO 0) := (OTHERS=>0); |
VARIABLE v_prev_stage_pipeline_arr : t_natural_arr(c_nof_output-1 DOWNTO 0) := (OTHERS=>0); |
BEGIN |
loop_stage : FOR j IN 0 TO c_nof_stages-1 LOOP |
v_prev_stage_pipeline_arr := v_stage_pipeline_arr; |
loop_cell : FOR i IN 0 TO c_nof_output_per_cell**j-1 LOOP |
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); |
END LOOP; |
END LOOP; |
RETURN v_stage_pipeline_arr; |
END FUNCTION func_common_fanout_tree_pipelining; |
|
|
------------------------------------------------------------------------------ |
-- common_reorder_symbol |
------------------------------------------------------------------------------ |
|
-- Determine whether the stage I and row J index refer to any (active or redundant) 2-input reorder cell instantiation |
FUNCTION func_common_reorder2_is_there(I, J : NATURAL) RETURN BOOLEAN IS |
VARIABLE v_odd : BOOLEAN; |
VARIABLE v_even : BOOLEAN; |
BEGIN |
v_odd := (I MOD 2 = 1) AND (J MOD 2 = 1); -- for odd stage at each odd row |
v_even := (I MOD 2 = 0) AND (J MOD 2 = 0); -- for even stage at each even row |
RETURN v_odd OR v_even; |
END func_common_reorder2_is_there; |
|
-- 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 |
FUNCTION func_common_reorder2_is_active(I, J, N : NATURAL) RETURN BOOLEAN IS |
VARIABLE v_inst : BOOLEAN; |
VARIABLE v_act : BOOLEAN; |
BEGIN |
v_inst := func_common_reorder2_is_there(I, J); |
v_act := (I > 0) AND (I <= N) AND (J > 0) AND (J < N); |
RETURN v_inst AND v_act; |
END func_common_reorder2_is_active; |
|
-- 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 |
FUNCTION func_common_reorder2_get_select_index(I, J, N : NATURAL) RETURN INTEGER IS |
CONSTANT c_nof_reorder2_per_odd_stage : NATURAL := N/2; |
CONSTANT c_nof_reorder2_per_even_stage : NATURAL := (N-1)/2; |
VARIABLE v_nof_odd_stages : NATURAL; |
VARIABLE v_nof_even_stages : NATURAL; |
VARIABLE v_offset : NATURAL; |
VARIABLE v_K : INTEGER; |
BEGIN |
-- for I, J that do not refer to an reorder cell instance for -1 as dummy return value. |
-- for the redundant two port reorder cells at the border rows for -1 to indicate that the cell should pass on the input. |
v_K := -1; |
IF func_common_reorder2_is_active(I, J, N) THEN |
-- for the active two port reorder cells use the setting at index v_K from the select setting array |
v_nof_odd_stages := I/2; |
v_nof_even_stages := (I-1)/2; |
v_offset := (J-1)/2; -- suits both odd stage and even stage |
v_K := v_nof_odd_stages * c_nof_reorder2_per_odd_stage + v_nof_even_stages * c_nof_reorder2_per_even_stage + v_offset; |
END IF; |
RETURN v_K; |
END func_common_reorder2_get_select_index; |
|
-- Get the select setting for the reorder2 cell on stage I and row J in a reorder network with N stages |
FUNCTION func_common_reorder2_get_select(I, J, N : NATURAL; select_arr : t_natural_arr) RETURN NATURAL IS |
CONSTANT c_nof_select : NATURAL := select_arr'LENGTH; |
CONSTANT c_select_arr : t_natural_arr(c_nof_select-1 DOWNTO 0) := select_arr; -- force range downto 0 |
VARIABLE v_sel : NATURAL; |
VARIABLE v_K : INTEGER; |
BEGIN |
v_sel := 0; |
v_K := func_common_reorder2_get_select_index(I, J, N); |
IF v_K>=0 THEN |
v_sel := c_select_arr(v_K); |
END IF; |
RETURN v_sel; |
END func_common_reorder2_get_select; |
|
-- Determine the inverse of a reorder network by using two reorder networks in series |
FUNCTION func_common_reorder2_inverse_select(N : NATURAL; select_arr : t_natural_arr) RETURN t_natural_arr IS |
CONSTANT c_nof_select : NATURAL := select_arr'LENGTH; |
CONSTANT c_select_arr : t_natural_arr(c_nof_select-1 DOWNTO 0) := select_arr; -- force range downto 0 |
VARIABLE v_sel : NATURAL; |
VARIABLE v_Ki : INTEGER; |
VARIABLE v_Ii : NATURAL; |
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 |
BEGIN |
-- the inverse select consists of inverse_in reorder and inverse_out reorder in series |
IF N MOD 2 = 1 THEN |
-- N is odd so only need to fill in the inverse_in reorder, the inverse_out reorder remains at default pass on |
FOR I IN 1 TO N LOOP |
FOR J IN 0 TO N-1 LOOP |
-- get the DUT setting |
v_sel := func_common_reorder2_get_select(I, J, N, c_select_arr); |
-- map DUT I to inverse v_Ii stage index and determine the index for the inverse setting |
v_Ii := 1+N-I; |
v_Ki := func_common_reorder2_get_select_index(v_Ii, J, N); |
IF v_Ki>=0 THEN |
v_inverse_arr(v_Ki) := v_sel; |
END IF; |
END LOOP; |
END LOOP; |
ELSE |
-- N is even so only use stage 1 of the inverse_out reorder, the other stages remain at default pass on |
FOR K IN 0 TO N/2-1 LOOP |
v_Ki := c_nof_select + K; -- stage 1 of the inverse_out reorder |
v_inverse_arr(v_Ki) := c_select_arr(K); |
END LOOP; |
-- N is even so leave stage 1 of the inverse_in reorder at default pass on, and do inverse the other stages |
FOR I IN 2 TO N LOOP |
FOR J IN 0 TO N-1 LOOP |
-- get the DUT setting |
v_sel := func_common_reorder2_get_select(I, J, N, c_select_arr); |
-- map DUT I to inverse v_Ii stage index and determine the index for the inverse setting |
v_Ii := 2+N-I; |
v_Ki := func_common_reorder2_get_select_index(v_Ii, J, N); |
IF v_Ki>=0 THEN |
v_inverse_arr(v_Ki) := v_sel; |
END IF; |
END LOOP; |
END LOOP; |
END IF; |
RETURN v_inverse_arr; |
END func_common_reorder2_inverse_select; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Generate faster sample SCLK from digital DCLK for sim only |
-- Description: |
-- The SCLK kan be used to serialize Pfactor >= 1 symbols per word and then |
-- view them in a scope component that is use internally in the design. |
-- The scope component is only instantiated for simulation, to view the |
-- serialized symbols, typically with decimal radix and analogue format. |
-- The scope component will not be synthesized, because the SCLK can not |
-- be synthesized. |
-- |
-- Pfactor = 4 |
-- _______ _______ _______ _______ |
-- DCLK ___| |_______| |_______| |_______| |_______ |
-- ___________________ _ _ _ _ _ _ _ _ _ _ _ _ |
-- SCLK |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |
-- |
-- The rising edges of SCLK occur after the rising edge of DCLK, to ensure |
-- that they all apply to the same wide data word that was clocked by the |
-- rising edge of the DCLK. |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_dclk_generate_sclk(CONSTANT Pfactor : IN POSITIVE; |
SIGNAL dclk : IN STD_LOGIC; |
SIGNAL sclk : INOUT STD_LOGIC) IS |
VARIABLE v_dperiod : TIME; |
VARIABLE v_speriod : TIME; |
BEGIN |
SCLK <= '1'; |
-- Measure DCLK period |
WAIT UNTIL rising_edge(DCLK); |
v_dperiod := NOW; |
WAIT UNTIL rising_edge(DCLK); |
v_dperiod := NOW - v_dperiod; |
v_speriod := v_dperiod / Pfactor; |
-- Generate Pfactor SCLK periods per DCLK period |
WHILE TRUE LOOP |
-- Realign at every DCLK |
WAIT UNTIL rising_edge(DCLK); |
-- Create Pfactor SCLK periods within this DCLK period |
SCLK <= '0'; |
IF Pfactor>1 THEN |
FOR I IN 0 TO 2*Pfactor-1-2 LOOP |
WAIT FOR v_speriod/2; |
SCLK <= NOT SCLK; |
END LOOP; |
END IF; |
WAIT FOR v_speriod/2; |
SCLK <= '1'; |
-- Wait for next DCLK |
END LOOP; |
WAIT; |
END proc_common_dclk_generate_sclk; |
|
END common_pkg; |
|
/trunk/common_str_pkg.vhd
0,0 → 1,282
------------------------------------------------------------------------------- |
-- |
-- Copyright (C) 2012 |
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> |
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands |
-- |
-- This program is free software: you can redistribute it and/or modify |
-- it under the terms of the GNU General Public License as published by |
-- the Free Software Foundation, either version 3 of the License, or |
-- (at your option) any later version. |
-- |
-- This program is distributed in the hope that it will be useful, |
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
-- GNU General Public License for more details. |
-- |
-- You should have received a copy of the GNU General Public License |
-- along with this program. If not, see <http://www.gnu.org/licenses/>. |
-- |
------------------------------------------------------------------------------- |
|
LIBRARY IEEE; |
USE IEEE.STD_LOGIC_1164.ALL; |
USE IEEE.NUMERIC_STD.ALL; |
USE STD.TEXTIO.ALL; |
USE IEEE.STD_LOGIC_TEXTIO.ALL; |
USE work.common_pkg.ALL; |
|
PACKAGE common_str_pkg IS |
|
TYPE t_str_4_arr IS ARRAY (INTEGER RANGE <>) OF STRING(1 TO 4); |
|
FUNCTION nof_digits(number: NATURAL) RETURN NATURAL; |
FUNCTION nof_digits_int(number: INTEGER) RETURN NATURAL; |
|
FUNCTION time_to_str(in_time : TIME) RETURN STRING; |
FUNCTION str_to_time(in_str : STRING) RETURN TIME; |
FUNCTION slv_to_str(slv : STD_LOGIC_VECTOR) RETURN STRING; |
FUNCTION str_to_hex(str : STRING) RETURN STRING; |
FUNCTION slv_to_hex(slv : STD_LOGIC_VECTOR) RETURN STRING; |
FUNCTION hex_to_slv(str : STRING) RETURN STD_LOGIC_VECTOR; |
|
Function hex_nibble_to_slv(c: character) return std_logic_vector; |
|
FUNCTION int_to_str(int: INTEGER) RETURN STRING; |
FUNCTION real_to_str(re: REAL; width : INTEGER; digits : INTEGER) RETURN STRING; |
|
PROCEDURE print_str(str : STRING); |
|
FUNCTION str_to_ascii_integer_arr(s: STRING) RETURN t_integer_arr; |
FUNCTION str_to_ascii_slv_8_arr( s: STRING) RETURN t_slv_8_arr; |
FUNCTION str_to_ascii_slv_32_arr( s: STRING) RETURN t_slv_32_arr; |
FUNCTION str_to_ascii_slv_32_arr( s: STRING; arr_size : NATURAL) RETURN t_slv_32_arr; |
|
END common_str_pkg; |
|
PACKAGE BODY common_str_pkg IS |
|
FUNCTION nof_digits(number: NATURAL) RETURN NATURAL IS |
-- Returns number of digits in a natural number. Only used in string processing, so defined here. |
-- log10(0) is not allowed so: |
-- . nof_digits(0) = 1 |
-- We're adding 1 so: |
-- . nof_digits(1) = 1 |
-- . nof_digits(9) = 1 |
-- . nof_digits(10) = 2 |
BEGIN |
IF number>0 THEN |
RETURN floor_log10(number)+1; |
ELSE |
RETURN 1; |
END IF; |
END; |
|
FUNCTION nof_digits_int(number: INTEGER) RETURN NATURAL IS |
-- Returns number of digits in a natural number. Only used in string processing, so defined here. |
-- log10(0) is not allowed so: |
-- . nof_digits(0) = 1 |
-- We're adding 1 so: |
-- . nof_digits(1) = 1 |
-- . nof_digits(9) = 1 |
-- . nof_digits(10) = 2 |
-- . nof_digits(1) = 2 |
BEGIN |
IF number=0 THEN |
RETURN 1; |
ELSE |
IF number > 0 THEN |
RETURN floor_log10(number)+1; |
ELSE |
RETURN floor_log10(-1*number)+2; |
END IF; |
END IF; |
END; |
|
FUNCTION time_to_str(in_time : TIME) RETURN STRING IS |
CONSTANT c_max_len_time : NATURAL := 20; |
VARIABLE v_line : LINE; |
VARIABLE v_str : STRING(1 TO c_max_len_time):= (OTHERS => ' '); |
BEGIN |
write(v_line, in_time); |
v_str(v_line.ALL'RANGE) := v_line.ALL; |
deallocate(v_line); |
RETURN v_str; |
END; |
|
FUNCTION str_to_time(in_str : STRING) RETURN TIME IS |
BEGIN |
RETURN TIME'VALUE(in_str); |
END; |
|
FUNCTION slv_to_str(slv : STD_LOGIC_VECTOR) RETURN STRING IS |
VARIABLE v_line : LINE; |
VARIABLE v_str : STRING(1 TO slv'LENGTH) := (OTHERS => ' '); |
BEGIN |
write(v_line, slv); |
v_str(v_line.ALL'RANGE) := v_line.ALL; |
deallocate(v_line); |
RETURN v_str; |
END; |
|
FUNCTION str_to_hex(str : STRING) RETURN STRING IS |
CONSTANT c_nof_nibbles : NATURAL := ceil_div(str'LENGTH, c_nibble_w); |
VARIABLE v_nibble_arr : t_str_4_arr(0 TO c_nof_nibbles-1) := (OTHERS=>(OTHERS=>'0')); |
VARIABLE v_hex : STRING(1 TO c_nof_nibbles) := (OTHERS => '0'); |
BEGIN |
FOR i IN 0 TO v_hex'RIGHT-1 LOOP |
v_nibble_arr(i) := slice_up(str, c_nibble_w, i, '0'); |
|
CASE v_nibble_arr(i) IS |
WHEN "0000" => v_hex(i+1) := '0'; |
WHEN "0001" => v_hex(i+1) := '1'; |
WHEN "0010" => v_hex(i+1) := '2'; |
WHEN "0011" => v_hex(i+1) := '3'; |
WHEN "0100" => v_hex(i+1) := '4'; |
WHEN "0101" => v_hex(i+1) := '5'; |
WHEN "0110" => v_hex(i+1) := '6'; |
WHEN "0111" => v_hex(i+1) := '7'; |
WHEN "1000" => v_hex(i+1) := '8'; |
WHEN "1001" => v_hex(i+1) := '9'; |
WHEN "1010" => v_hex(i+1) := 'A'; |
WHEN "1011" => v_hex(i+1) := 'B'; |
WHEN "1100" => v_hex(i+1) := 'C'; |
WHEN "1101" => v_hex(i+1) := 'D'; |
WHEN "1110" => v_hex(i+1) := 'E'; |
WHEN "1111" => v_hex(i+1) := 'F'; |
WHEN OTHERS => v_hex(i+1) := 'X'; |
END CASE; |
END LOOP; |
RETURN v_hex; |
END; |
|
FUNCTION slv_to_hex(slv :STD_LOGIC_VECTOR) RETURN STRING IS |
BEGIN |
RETURN str_to_hex(slv_to_str(slv)); |
END; |
|
FUNCTION hex_to_slv(str: STRING) RETURN STD_LOGIC_VECTOR IS |
CONSTANT c_length : NATURAL := str'LENGTH; |
VARIABLE v_str : STRING(1 TO str'LENGTH) := str; -- Keep local copy of str to prevent range mismatch |
VARIABLE v_result : STD_LOGIC_VECTOR(c_length * 4 - 1 DOWNTO 0); |
BEGIN |
FOR i IN c_length DOWNTO 1 LOOP |
v_result(3 +(c_length - i)*4 DOWNTO (c_length-i)*4) := hex_nibble_to_slv(v_str(i)); |
END LOOP; |
RETURN v_result; |
END; |
|
FUNCTION hex_nibble_to_slv(c: CHARACTER) RETURN STD_LOGIC_VECTOR IS |
VARIABLE v_result : STD_LOGIC_VECTOR(3 DOWNTO 0); |
BEGIN |
CASE c IS |
WHEN '0' => v_result := "0000"; |
WHEN '1' => v_result := "0001"; |
WHEN '2' => v_result := "0010"; |
WHEN '3' => v_result := "0011"; |
WHEN '4' => v_result := "0100"; |
WHEN '5' => v_result := "0101"; |
WHEN '6' => v_result := "0110"; |
WHEN '7' => v_result := "0111"; |
WHEN '8' => v_result := "1000"; |
WHEN '9' => v_result := "1001"; |
WHEN 'A' => v_result := "1010"; |
WHEN 'B' => v_result := "1011"; |
WHEN 'C' => v_result := "1100"; |
WHEN 'D' => v_result := "1101"; |
WHEN 'E' => v_result := "1110"; |
WHEN 'F' => v_result := "1111"; |
WHEN 'a' => v_result := "1010"; |
WHEN 'b' => v_result := "1011"; |
WHEN 'c' => v_result := "1100"; |
WHEN 'd' => v_result := "1101"; |
WHEN 'e' => v_result := "1110"; |
WHEN 'f' => v_result := "1111"; |
WHEN 'x' => v_result := "XXXX"; |
WHEN 'X' => v_result := "XXXX"; |
WHEN 'z' => v_result := "ZZZZ"; |
WHEN 'Z' => v_result := "ZZZZ"; |
|
WHEN OTHERS => v_result := "0000"; |
END CASE; |
RETURN v_result; |
END hex_nibble_to_slv; |
|
FUNCTION int_to_str(int: INTEGER) RETURN STRING IS |
-- CONSTANT c_max_len_int : NATURAL := 20; |
VARIABLE v_line: LINE; |
VARIABLE v_str: STRING(1 TO nof_digits_int(int)):= (OTHERS => ' '); |
BEGIN |
STD.TEXTIO.WRITE(v_line, int); |
v_str(v_line.ALL'RANGE) := v_line.ALL; |
deallocate(v_line); |
RETURN v_str; |
END; |
|
FUNCTION real_to_str(re: REAL; width : INTEGER; digits : INTEGER) RETURN STRING IS |
VARIABLE v_line: LINE; |
VARIABLE v_str: STRING(1 TO width):= (OTHERS => ' '); |
BEGIN |
STD.TEXTIO.WRITE(v_line, re, right, width, digits); |
v_str(v_line.ALL'RANGE) := v_line.ALL; |
deallocate(v_line); |
RETURN v_str; |
END; |
|
PROCEDURE print_str(str: STRING) IS |
VARIABLE v_line: LINE; |
BEGIN |
write(v_line, str); |
writeline(output, v_line); |
deallocate(v_line); |
END; |
|
FUNCTION str_to_ascii_integer_arr(s: STRING) RETURN t_integer_arr IS |
VARIABLE r: t_integer_arr(0 TO s'RIGHT-1); |
BEGIN |
FOR i IN s'RANGE LOOP |
r(i-1) := CHARACTER'POS(s(i)); |
END LOOP; |
RETURN r; |
END; |
|
FUNCTION str_to_ascii_slv_8_arr(s: STRING) RETURN t_slv_8_arr IS |
VARIABLE r: t_slv_8_arr(0 TO s'RIGHT-1); |
BEGIN |
FOR i IN s'RANGE LOOP |
r(i-1) := TO_UVEC(str_to_ascii_integer_arr(s)(i-1), 8); |
END LOOP; |
RETURN r; |
END; |
|
-- Returns minimum array size required to fit the string |
FUNCTION str_to_ascii_slv_32_arr(s: STRING) RETURN t_slv_32_arr IS |
CONSTANT c_slv_8: t_slv_8_arr(0 TO s'RIGHT-1) := str_to_ascii_slv_8_arr(s); |
CONSTANT c_bytes_per_word : NATURAL := 4; |
-- Initialize all elements to (OTHERS=>'0') so any unused bytes become a NULL character |
VARIABLE r: t_slv_32_arr(0 TO ceil_div(s'RIGHT * c_byte_w, c_word_w)-1) := (OTHERS=>(OTHERS=>'0')); |
BEGIN |
FOR word IN r'RANGE LOOP --0, 1 |
FOR byte IN 0 TO c_bytes_per_word-1 LOOP -- 0,1,2,3 |
IF byte+c_bytes_per_word*word<=c_slv_8'RIGHT THEN |
r(word)(byte*c_byte_w+c_byte_w-1 DOWNTO byte*c_byte_w) := c_slv_8(byte+c_bytes_per_word*word); |
END IF; |
END LOOP; |
END LOOP; |
|
RETURN r; |
END; |
|
-- Overloaded version to match array size to arr_size |
FUNCTION str_to_ascii_slv_32_arr(s: STRING; arr_size: NATURAL) RETURN t_slv_32_arr IS |
CONSTANT slv_32: t_slv_32_arr(0 TO ceil_div(s'RIGHT * c_byte_w, c_word_w)-1) := str_to_ascii_slv_32_arr(s); |
VARIABLE r: t_slv_32_arr(0 TO arr_size-1) := (OTHERS=>(OTHERS=>'0')); |
BEGIN |
FOR word IN slv_32'RANGE LOOP |
r(word) := slv_32(word); |
END LOOP; |
RETURN r; |
END; |
|
END common_str_pkg; |
|
/trunk/hdllib.cfg
0,0 → 1,21
hdl_lib_name = common_pkg |
hdl_library_clause_name = common_pkg_lib |
hdl_lib_uses_synth = |
hdl_lib_uses_sim = |
hdl_lib_technology = |
|
synth_files = |
common_pkg.vhd |
common_str_pkg.vhd |
common_lfsr_sequences_pkg.vhd |
tb_common_pkg.vhd |
|
test_bench_files = |
|
regression_test_vhdl = |
|
[modelsim_project_file] |
modelsim_copy_files = |
|
[quartus_project_file] |
|
/trunk/tb_common_pkg.vhd
0,0 → 1,1358
------------------------------------------------------------------------------- |
-- |
-- Copyright (C) 2011 |
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> |
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> |
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands |
-- |
-- This program is free software: you can redistribute it and/or modify |
-- it under the terms of the GNU General Public License as published by |
-- the Free Software Foundation, either version 3 of the License, or |
-- (at your option) any later version. |
-- |
-- This program is distributed in the hope that it will be useful, |
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
-- GNU General Public License for more details. |
-- |
-- You should have received a copy of the GNU General Public License |
-- along with this program. If not, see <http://www.gnu.org/licenses/>. |
-- |
------------------------------------------------------------------------------- |
|
LIBRARY IEEE; |
USE IEEE.std_logic_1164.ALL; |
USE IEEE.NUMERIC_STD.ALL; |
USE std.textio.ALL; -- for boolean, integer file IO |
USE IEEE.std_logic_textio.ALL; -- for std_logic, std_logic_vector file IO |
USE work.common_pkg.ALL; |
|
|
PACKAGE tb_common_pkg IS |
|
PROCEDURE proc_common_wait_some_cycles(SIGNAL clk : IN STD_LOGIC; |
c_nof_cycles : IN NATURAL); |
|
PROCEDURE proc_common_wait_some_cycles(SIGNAL clk : IN STD_LOGIC; |
c_nof_cycles : IN REAL); |
|
PROCEDURE proc_common_wait_some_cycles(SIGNAL clk_in : IN STD_LOGIC; |
SIGNAL clk_out : IN STD_LOGIC; |
c_nof_cycles : IN NATURAL); |
|
PROCEDURE proc_common_wait_some_pulses(SIGNAL clk : IN STD_LOGIC; |
SIGNAL pulse : IN STD_LOGIC; |
c_nof_pulses : IN NATURAL); |
|
PROCEDURE proc_common_wait_until_evt(SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC); |
|
PROCEDURE proc_common_wait_until_evt(SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN INTEGER); |
|
PROCEDURE proc_common_wait_until_evt(CONSTANT c_timeout : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC); |
|
PROCEDURE proc_common_wait_until_high(CONSTANT c_timeout : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC); |
|
PROCEDURE proc_common_wait_until_high(SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC); |
|
PROCEDURE proc_common_wait_until_low(CONSTANT c_timeout : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC); |
|
PROCEDURE proc_common_wait_until_low(SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC); |
|
PROCEDURE proc_common_wait_until_hi_lo(CONSTANT c_timeout : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC); |
|
PROCEDURE proc_common_wait_until_hi_lo(SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC); |
|
PROCEDURE proc_common_wait_until_lo_hi(CONSTANT c_timeout : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC); |
|
PROCEDURE proc_common_wait_until_lo_hi(SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC); |
|
PROCEDURE proc_common_wait_until_value(CONSTANT c_value : IN INTEGER; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN INTEGER); |
|
PROCEDURE proc_common_wait_until_value(CONSTANT c_value : IN INTEGER; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC_VECTOR); |
|
PROCEDURE proc_common_wait_until_value(CONSTANT c_timeout : IN NATURAL; |
CONSTANT c_value : IN INTEGER; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC_VECTOR); |
|
-- Wait until absolute simulation time NOW = c_time |
PROCEDURE proc_common_wait_until_time(SIGNAL clk : IN STD_LOGIC; |
CONSTANT c_time : IN TIME); |
|
-- Exit simulation on timeout failure |
PROCEDURE proc_common_timeout_failure(CONSTANT c_timeout : IN TIME; |
SIGNAL tb_end : IN STD_LOGIC); |
|
|
-- Stop simulation using severity FAILURE when g_tb_end=TRUE, else for use in multi tb report as severity NOTE |
PROCEDURE proc_common_stop_simulation(SIGNAL tb_end : IN STD_LOGIC); |
|
PROCEDURE proc_common_stop_simulation(CONSTANT g_tb_end : IN BOOLEAN; |
CONSTANT g_latency : IN NATURAL; -- latency between tb_done and tb_)end |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL tb_done : IN STD_LOGIC; |
SIGNAL tb_end : OUT STD_LOGIC); |
|
PROCEDURE proc_common_stop_simulation(CONSTANT g_tb_end : IN BOOLEAN; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL tb_done : IN STD_LOGIC; |
SIGNAL tb_end : OUT STD_LOGIC); |
|
-- Handle stream ready signal, only support ready latency c_rl = 0 or 1. |
PROCEDURE proc_common_ready_latency(CONSTANT c_rl : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL enable : IN STD_LOGIC; -- when '1' then active output when ready |
SIGNAL ready : IN STD_LOGIC; |
SIGNAL out_valid : OUT STD_LOGIC); |
|
|
-- Generate a single active, inactive pulse |
PROCEDURE proc_common_gen_pulse(CONSTANT c_active : IN NATURAL; -- pulse active for nof clk |
CONSTANT c_period : IN NATURAL; -- pulse period for nof clk |
CONSTANT c_level : IN STD_LOGIC; -- pulse level when active |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL pulse : OUT STD_LOGIC); |
|
-- Pulse forever after rst was released |
PROCEDURE proc_common_gen_pulse(CONSTANT c_active : IN NATURAL; -- pulse active for nof clk |
CONSTANT c_period : IN NATURAL; -- pulse period for nof clk |
CONSTANT c_level : IN STD_LOGIC; -- pulse level when active |
SIGNAL rst : IN STD_LOGIC; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL pulse : OUT STD_LOGIC); |
|
-- Generate a single '1', '0' pulse |
PROCEDURE proc_common_gen_pulse(SIGNAL clk : IN STD_LOGIC; |
SIGNAL pulse : OUT STD_LOGIC); |
|
-- Generate a periodic pulse with arbitrary duty cycle |
PROCEDURE proc_common_gen_duty_pulse(CONSTANT c_delay : IN NATURAL; -- delay pulse for nof_clk after enable |
CONSTANT c_active : IN NATURAL; -- pulse active for nof clk |
CONSTANT c_period : IN NATURAL; -- pulse period for nof clk |
CONSTANT c_level : IN STD_LOGIC; -- pulse level when active |
SIGNAL rst : IN STD_LOGIC; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL enable : IN STD_LOGIC; -- once enabled, the pulse remains enabled |
SIGNAL pulse : OUT STD_LOGIC); |
|
PROCEDURE proc_common_gen_duty_pulse(CONSTANT c_active : IN NATURAL; -- pulse active for nof clk |
CONSTANT c_period : IN NATURAL; -- pulse period for nof clk |
CONSTANT c_level : IN STD_LOGIC; -- pulse level when active |
SIGNAL rst : IN STD_LOGIC; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL enable : IN STD_LOGIC; -- once enabled, the pulse remains enabled |
SIGNAL pulse : OUT STD_LOGIC); |
|
-- Generate counter data with valid and arbitrary increment or fixed increment=1 |
PROCEDURE proc_common_gen_data(CONSTANT c_rl : IN NATURAL; -- 0, 1 are supported by proc_common_ready_latency() |
CONSTANT c_init : IN INTEGER; |
CONSTANT c_incr : IN INTEGER; |
SIGNAL rst : IN STD_LOGIC; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL enable : IN STD_LOGIC; -- when '0' then no valid output even when ready='1' |
SIGNAL ready : IN STD_LOGIC; |
SIGNAL out_data : OUT STD_LOGIC_VECTOR; |
SIGNAL out_valid : OUT STD_LOGIC); |
|
PROCEDURE proc_common_gen_data(CONSTANT c_rl : IN NATURAL; -- 0, 1 are supported by proc_common_ready_latency() |
CONSTANT c_init : IN INTEGER; |
SIGNAL rst : IN STD_LOGIC; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL enable : IN STD_LOGIC; -- when '0' then no valid output even when ready='1' |
SIGNAL ready : IN STD_LOGIC; |
SIGNAL out_data : OUT STD_LOGIC_VECTOR; |
SIGNAL out_valid : OUT STD_LOGIC); |
|
-- Generate frame control |
PROCEDURE proc_common_sop(SIGNAL clk : IN STD_LOGIC; |
SIGNAL in_val : OUT STD_LOGIC; |
SIGNAL in_sop : OUT STD_LOGIC); |
|
PROCEDURE proc_common_eop(SIGNAL clk : IN STD_LOGIC; |
SIGNAL in_val : OUT STD_LOGIC; |
SIGNAL in_eop : OUT STD_LOGIC); |
|
PROCEDURE proc_common_val(CONSTANT c_val_len : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL in_val : OUT STD_LOGIC); |
|
PROCEDURE proc_common_val_duty(CONSTANT c_hi_len : IN NATURAL; |
CONSTANT c_lo_len : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL in_val : OUT STD_LOGIC); |
|
PROCEDURE proc_common_eop_flush(CONSTANT c_flush_len : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL in_val : OUT STD_LOGIC; |
SIGNAL in_eop : OUT STD_LOGIC); |
|
-- Verify the DUT output incrementing data, only support ready latency c_rl = 0 or 1. |
PROCEDURE proc_common_verify_data(CONSTANT c_rl : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL verify_en : IN STD_LOGIC; |
SIGNAL ready : IN STD_LOGIC; |
SIGNAL out_valid : IN STD_LOGIC; |
SIGNAL out_data : IN STD_LOGIC_VECTOR; |
SIGNAL prev_out_data : INOUT STD_LOGIC_VECTOR); |
|
-- Verify the DUT output valid for ready latency, only support ready latency c_rl = 0 or 1. |
PROCEDURE proc_common_verify_valid(CONSTANT c_rl : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL verify_en : IN STD_LOGIC; |
SIGNAL ready : IN STD_LOGIC; |
SIGNAL prev_ready : INOUT STD_LOGIC; |
SIGNAL out_valid : IN STD_LOGIC); |
|
-- Verify the DUT input to output latency for SL ctrl signals |
PROCEDURE proc_common_verify_latency(CONSTANT c_str : IN STRING; -- e.g. "valid", "sop", "eop" |
CONSTANT c_latency : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL verify_en : IN STD_LOGIC; |
SIGNAL in_ctrl : IN STD_LOGIC; |
SIGNAL pipe_ctrl_vec : INOUT STD_LOGIC_VECTOR; -- range [0:c_latency] |
SIGNAL out_ctrl : IN STD_LOGIC); |
|
-- Verify the DUT input to output latency for SLV data signals |
PROCEDURE proc_common_verify_latency(CONSTANT c_str : IN STRING; -- e.g. "data" |
CONSTANT c_latency : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL verify_en : IN STD_LOGIC; |
SIGNAL in_data : IN STD_LOGIC_VECTOR; |
SIGNAL pipe_data_vec : INOUT STD_LOGIC_VECTOR; -- range [0:(1 + c_latency)*c_data_w-1] |
SIGNAL out_data : IN STD_LOGIC_VECTOR); |
|
-- Verify the expected value, e.g. to check that a test has ran at all |
PROCEDURE proc_common_verify_value(CONSTANT mode : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL en : IN STD_LOGIC; |
SIGNAL exp : IN STD_LOGIC_VECTOR; |
SIGNAL res : IN STD_LOGIC_VECTOR); |
-- open, read line, close file |
PROCEDURE proc_common_open_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT; |
file_name : IN STRING; |
file_mode : IN FILE_OPEN_KIND); |
|
PROCEDURE proc_common_readline_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT; |
read_value_0 : OUT INTEGER); |
|
PROCEDURE proc_common_readline_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT; |
read_value_0 : OUT INTEGER; |
read_value_1 : OUT INTEGER); |
|
PROCEDURE proc_common_readline_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT; |
value_array : OUT t_integer_arr; |
nof_reads : IN INTEGER); |
|
PROCEDURE proc_common_readline_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT; |
read_slv : OUT STD_LOGIC_VECTOR); |
|
PROCEDURE proc_common_readline_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT; |
res_string : OUT STRING); |
|
PROCEDURE proc_common_close_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT); |
|
-- read entire file |
PROCEDURE proc_common_read_integer_file(file_name : IN STRING; |
nof_header_lines : NATURAL; |
nof_row : NATURAL; |
nof_col : NATURAL; |
SIGNAL return_array : OUT t_integer_arr); |
|
PROCEDURE proc_common_read_mif_file(file_name : IN STRING; |
SIGNAL return_array : OUT t_integer_arr); |
|
-- Complex multiply function with conjugate option for input b |
FUNCTION func_complex_multiply(in_ar, in_ai, in_br, in_bi : STD_LOGIC_VECTOR; conjugate_b : BOOLEAN; str : STRING; g_out_dat_w : NATURAL) RETURN STD_LOGIC_VECTOR; |
|
FUNCTION func_decstring_to_integer(in_string: STRING) RETURN INTEGER; |
|
FUNCTION func_hexstring_to_integer(in_string: STRING) RETURN INTEGER; |
|
FUNCTION func_find_char_in_string(in_string: STRING; find_char: CHARACTER) RETURN INTEGER; |
|
FUNCTION func_find_string_in_string(in_string: STRING; find_string: STRING) RETURN BOOLEAN; |
|
END tb_common_pkg; |
|
|
PACKAGE BODY tb_common_pkg IS |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Wait some clock cycles |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_wait_some_cycles(SIGNAL clk : IN STD_LOGIC; |
c_nof_cycles : IN NATURAL) IS |
BEGIN |
FOR I IN 0 TO c_nof_cycles-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP; |
END proc_common_wait_some_cycles; |
|
PROCEDURE proc_common_wait_some_cycles(SIGNAL clk : IN STD_LOGIC; |
c_nof_cycles : IN REAL) IS |
BEGIN |
proc_common_wait_some_cycles(clk, NATURAL(c_nof_cycles)); |
END proc_common_wait_some_cycles; |
|
PROCEDURE proc_common_wait_some_cycles(SIGNAL clk_in : IN STD_LOGIC; |
SIGNAL clk_out : IN STD_LOGIC; |
c_nof_cycles : IN NATURAL) IS |
BEGIN |
proc_common_wait_some_cycles(clk_in, c_nof_cycles); |
proc_common_wait_some_cycles(clk_out, c_nof_cycles); |
END proc_common_wait_some_cycles; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Wait some pulses |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_wait_some_pulses(SIGNAL clk : IN STD_LOGIC; |
SIGNAL pulse : IN STD_LOGIC; |
c_nof_pulses : IN NATURAL) IS |
BEGIN |
FOR I IN 0 TO c_nof_pulses-1 LOOP |
proc_common_wait_until_hi_lo(clk, pulse); |
END LOOP; |
END proc_common_wait_some_pulses; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Wait until the level input event |
-- PROCEDURE: Wait until the level input is high |
-- PROCEDURE: Wait until the level input is low |
-- PROCEDURE: Wait until the input is equal to c_value |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_wait_until_evt(SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC) IS |
VARIABLE v_level : STD_LOGIC := level; |
BEGIN |
WAIT UNTIL rising_edge(clk); |
WHILE v_level=level LOOP |
v_level := level; |
WAIT UNTIL rising_edge(clk); |
END LOOP; |
END proc_common_wait_until_evt; |
|
PROCEDURE proc_common_wait_until_evt(SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN INTEGER) IS |
VARIABLE v_level : INTEGER := level; |
BEGIN |
WAIT UNTIL rising_edge(clk); |
WHILE v_level=level LOOP |
v_level := level; |
WAIT UNTIL rising_edge(clk); |
END LOOP; |
END proc_common_wait_until_evt; |
|
PROCEDURE proc_common_wait_until_evt(CONSTANT c_timeout : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC) IS |
VARIABLE v_level : STD_LOGIC := level; |
VARIABLE v_I : NATURAL := 0; |
BEGIN |
WAIT UNTIL rising_edge(clk); |
WHILE v_level=level LOOP |
v_level := level; |
WAIT UNTIL rising_edge(clk); |
v_I := v_I + 1; |
IF v_I>=c_timeout-1 THEN |
REPORT "COMMON : level evt timeout" SEVERITY ERROR; |
EXIT; |
END IF; |
END LOOP; |
END proc_common_wait_until_evt; |
|
PROCEDURE proc_common_wait_until_high(SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC) IS |
BEGIN |
IF level/='1' THEN |
WAIT UNTIL rising_edge(clk) AND level='1'; |
END IF; |
END proc_common_wait_until_high; |
|
PROCEDURE proc_common_wait_until_high(CONSTANT c_timeout : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC) IS |
BEGIN |
FOR I IN 0 TO c_timeout-1 LOOP |
IF level='1' THEN |
EXIT; |
ELSE |
IF I=c_timeout-1 THEN |
REPORT "COMMON : level high timeout" SEVERITY ERROR; |
END IF; |
WAIT UNTIL rising_edge(clk); |
END IF; |
END LOOP; |
END proc_common_wait_until_high; |
|
PROCEDURE proc_common_wait_until_low(SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC) IS |
BEGIN |
IF level/='0' THEN |
WAIT UNTIL rising_edge(clk) AND level='0'; |
END IF; |
END proc_common_wait_until_low; |
|
PROCEDURE proc_common_wait_until_low(CONSTANT c_timeout : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC) IS |
BEGIN |
FOR I IN 0 TO c_timeout-1 LOOP |
IF level='0' THEN |
EXIT; |
ELSE |
IF I=c_timeout-1 THEN |
REPORT "COMMON : level low timeout" SEVERITY ERROR; |
END IF; |
WAIT UNTIL rising_edge(clk); |
END IF; |
END LOOP; |
END proc_common_wait_until_low; |
|
PROCEDURE proc_common_wait_until_hi_lo(SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC) IS |
BEGIN |
IF level/='1' THEN |
proc_common_wait_until_high(clk, level); |
END IF; |
proc_common_wait_until_low(clk, level); |
END proc_common_wait_until_hi_lo; |
|
PROCEDURE proc_common_wait_until_hi_lo(CONSTANT c_timeout : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC) IS |
BEGIN |
IF level/='1' THEN |
proc_common_wait_until_high(c_timeout, clk, level); |
END IF; |
proc_common_wait_until_low(c_timeout, clk, level); |
END proc_common_wait_until_hi_lo; |
|
PROCEDURE proc_common_wait_until_lo_hi(SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC) IS |
BEGIN |
IF level/='0' THEN |
proc_common_wait_until_low(clk, level); |
END IF; |
proc_common_wait_until_high(clk, level); |
END proc_common_wait_until_lo_hi; |
|
PROCEDURE proc_common_wait_until_lo_hi(CONSTANT c_timeout : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC) IS |
BEGIN |
IF level/='0' THEN |
proc_common_wait_until_low(c_timeout, clk, level); |
END IF; |
proc_common_wait_until_high(c_timeout, clk, level); |
END proc_common_wait_until_lo_hi; |
|
PROCEDURE proc_common_wait_until_value(CONSTANT c_value : IN INTEGER; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN INTEGER) IS |
BEGIN |
WHILE level/=c_value LOOP |
WAIT UNTIL rising_edge(clk); |
END LOOP; |
END proc_common_wait_until_value; |
|
PROCEDURE proc_common_wait_until_value(CONSTANT c_value : IN INTEGER; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC_VECTOR) IS |
BEGIN |
WHILE SIGNED(level)/=c_value LOOP |
WAIT UNTIL rising_edge(clk); |
END LOOP; |
END proc_common_wait_until_value; |
|
PROCEDURE proc_common_wait_until_value(CONSTANT c_timeout : IN NATURAL; |
CONSTANT c_value : IN INTEGER; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL level : IN STD_LOGIC_VECTOR) IS |
BEGIN |
FOR I IN 0 TO c_timeout-1 LOOP |
IF SIGNED(level)=c_value THEN |
EXIT; |
ELSE |
IF I=c_timeout-1 THEN |
REPORT "COMMON : level value timeout" SEVERITY ERROR; |
END IF; |
WAIT UNTIL rising_edge(clk); |
END IF; |
END LOOP; |
END proc_common_wait_until_value; |
|
PROCEDURE proc_common_wait_until_time(SIGNAL clk : IN STD_LOGIC; |
CONSTANT c_time : IN TIME) IS |
BEGIN |
WHILE NOW < c_time LOOP |
WAIT UNTIL rising_edge(clk); |
END LOOP; |
END PROCEDURE; |
|
PROCEDURE proc_common_timeout_failure(CONSTANT c_timeout : IN TIME; |
SIGNAL tb_end : IN STD_LOGIC) IS |
BEGIN |
WHILE tb_end='0' LOOP |
ASSERT NOW < c_timeout REPORT "Test bench timeout." SEVERITY FAILURE; |
WAIT FOR 1 us; |
END LOOP; |
END PROCEDURE; |
|
PROCEDURE proc_common_stop_simulation(SIGNAL tb_end : IN STD_LOGIC) IS |
BEGIN |
WAIT UNTIL tb_end='1'; |
-- For modelsim_regression_test_vhdl.py: |
-- The tb_end will stop the test verification bases on error or failure. The wait is necessary to |
-- stop the simulation using failure, without causing the test to fail. |
WAIT FOR 1 ns; |
REPORT "Tb simulation finished." SEVERITY FAILURE; |
WAIT; |
END PROCEDURE; |
|
PROCEDURE proc_common_stop_simulation(CONSTANT g_tb_end : IN BOOLEAN; |
CONSTANT g_latency : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL tb_done : IN STD_LOGIC; |
SIGNAL tb_end : OUT STD_LOGIC) IS |
BEGIN |
-- Wait until simulation indicates done |
proc_common_wait_until_high(clk, tb_done); |
|
-- Wait some more cycles |
proc_common_wait_some_cycles(clk, g_latency); |
|
-- Stop the simulation or only report NOTE |
tb_end <= '1'; |
-- For modelsim_regression_test_vhdl.py: |
-- The tb_end will stop the test verification bases on error or failure. The wait is necessary to |
-- stop the simulation using failure, without causing the test to fail. |
WAIT FOR 1 ns; |
IF g_tb_end=FALSE THEN |
REPORT "Tb Simulation finished." SEVERITY NOTE; |
ELSE |
REPORT "Tb Simulation finished." SEVERITY FAILURE; |
END IF; |
WAIT; |
END PROCEDURE; |
|
PROCEDURE proc_common_stop_simulation(CONSTANT g_tb_end : IN BOOLEAN; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL tb_done : IN STD_LOGIC; |
SIGNAL tb_end : OUT STD_LOGIC) IS |
BEGIN |
proc_common_stop_simulation(g_tb_end, 0, clk, tb_done, tb_end); |
END PROCEDURE; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Handle stream ready signal for data valid |
-- . output active when ready='1' and enable='1' |
-- . only support ready latency c_rl = 0 or 1 |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_ready_latency(CONSTANT c_rl : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL enable : IN STD_LOGIC; |
SIGNAL ready : IN STD_LOGIC; |
SIGNAL out_valid : OUT STD_LOGIC) IS |
BEGIN |
-- skip ready cycles until enable='1' |
out_valid <= '0'; |
WHILE enable='0' LOOP |
IF c_rl=0 THEN |
WAIT UNTIL rising_edge(clk); |
WHILE ready /= '1' LOOP |
WAIT UNTIL rising_edge(clk); |
END LOOP; |
END IF; |
IF c_rl=1 THEN |
WHILE ready /= '1' LOOP |
WAIT UNTIL rising_edge(clk); |
END LOOP; |
WAIT UNTIL rising_edge(clk); |
END IF; |
END LOOP; |
-- active output when ready |
IF c_rl=0 THEN |
out_valid <= '1'; |
WAIT UNTIL rising_edge(clk); |
WHILE ready /= '1' LOOP |
WAIT UNTIL rising_edge(clk); |
END LOOP; |
END IF; |
IF c_rl=1 THEN |
WHILE ready /= '1' LOOP |
out_valid <= '0'; |
WAIT UNTIL rising_edge(clk); |
END LOOP; |
out_valid <= '1'; |
WAIT UNTIL rising_edge(clk); |
END IF; |
END proc_common_ready_latency; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Generate a single active, inactive pulse |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_gen_pulse(CONSTANT c_active : IN NATURAL; -- pulse active for nof clk |
CONSTANT c_period : IN NATURAL; -- pulse period for nof clk |
CONSTANT c_level : IN STD_LOGIC; -- pulse level when active |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL pulse : OUT STD_LOGIC) IS |
VARIABLE v_cnt : NATURAL RANGE 0 TO c_period := 0; |
BEGIN |
WHILE v_cnt<c_period LOOP |
IF v_cnt<c_active THEN |
pulse <= c_level; |
ELSE |
pulse <= NOT c_level; |
END IF; |
v_cnt := v_cnt+1; |
WAIT UNTIL rising_edge(clk); |
END LOOP; |
END proc_common_gen_pulse; |
|
-- Pulse forever after rst was released |
PROCEDURE proc_common_gen_pulse(CONSTANT c_active : IN NATURAL; -- pulse active for nof clk |
CONSTANT c_period : IN NATURAL; -- pulse period for nof clk |
CONSTANT c_level : IN STD_LOGIC; -- pulse level when active |
SIGNAL rst : IN STD_LOGIC; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL pulse : OUT STD_LOGIC) IS |
VARIABLE v_cnt : NATURAL RANGE 0 TO c_period := 0; |
BEGIN |
pulse <= NOT c_level; |
IF rst='0' THEN |
WAIT UNTIL rising_edge(clk); |
WHILE TRUE LOOP |
proc_common_gen_pulse(c_active, c_period, c_level, clk, pulse); |
END LOOP; |
END IF; |
END proc_common_gen_pulse; |
|
-- pulse '1', '0' |
PROCEDURE proc_common_gen_pulse(SIGNAL clk : IN STD_LOGIC; |
SIGNAL pulse : OUT STD_LOGIC) IS |
BEGIN |
proc_common_gen_pulse(1, 2, '1', clk, pulse); |
END proc_common_gen_pulse; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Generate a periodic pulse with arbitrary duty cycle |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_gen_duty_pulse(CONSTANT c_delay : IN NATURAL; -- delay pulse for nof_clk after enable |
CONSTANT c_active : IN NATURAL; -- pulse active for nof clk |
CONSTANT c_period : IN NATURAL; -- pulse period for nof clk |
CONSTANT c_level : IN STD_LOGIC; -- pulse level when active |
SIGNAL rst : IN STD_LOGIC; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL enable : IN STD_LOGIC; |
SIGNAL pulse : OUT STD_LOGIC) IS |
VARIABLE v_cnt : NATURAL RANGE 0 TO c_period-1 := 0; |
BEGIN |
pulse <= NOT c_level; |
IF rst='0' THEN |
proc_common_wait_until_high(clk, enable); -- if enabled then continue immediately else wait here |
proc_common_wait_some_cycles(clk, c_delay); -- apply initial c_delay. Once enabled, the pulse remains enabled |
WHILE TRUE LOOP |
WAIT UNTIL rising_edge(clk); |
IF v_cnt<c_active THEN |
pulse <= c_level; |
ELSE |
pulse <= NOT c_level; |
END IF; |
IF v_cnt<c_period-1 THEN |
v_cnt := v_cnt+1; |
ELSE |
v_cnt := 0; |
END IF; |
END LOOP; |
END IF; |
END proc_common_gen_duty_pulse; |
|
PROCEDURE proc_common_gen_duty_pulse(CONSTANT c_active : IN NATURAL; -- pulse active for nof clk |
CONSTANT c_period : IN NATURAL; -- pulse period for nof clk |
CONSTANT c_level : IN STD_LOGIC; -- pulse level when active |
SIGNAL rst : IN STD_LOGIC; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL enable : IN STD_LOGIC; |
SIGNAL pulse : OUT STD_LOGIC) IS |
BEGIN |
proc_common_gen_duty_pulse(0, c_active, c_period, c_level, rst, clk, enable, pulse); |
END proc_common_gen_duty_pulse; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Generate counter data with valid |
-- . Output counter data dependent on enable and ready |
------------------------------------------------------------------------------ |
-- arbitrary c_incr |
PROCEDURE proc_common_gen_data(CONSTANT c_rl : IN NATURAL; -- 0, 1 are supported by proc_common_ready_latency() |
CONSTANT c_init : IN INTEGER; |
CONSTANT c_incr : IN INTEGER; |
SIGNAL rst : IN STD_LOGIC; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL enable : IN STD_LOGIC; -- when '0' then no valid output even when ready='1' |
SIGNAL ready : IN STD_LOGIC; |
SIGNAL out_data : OUT STD_LOGIC_VECTOR; |
SIGNAL out_valid : OUT STD_LOGIC) IS |
CONSTANT c_data_w : NATURAL := out_data'LENGTH; |
VARIABLE v_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0):= TO_SVEC(c_init, c_data_w); |
BEGIN |
out_valid <= '0'; |
out_data <= v_data; |
IF rst='0' THEN |
WAIT UNTIL rising_edge(clk); |
WHILE TRUE LOOP |
out_data <= v_data; |
proc_common_ready_latency(c_rl, clk, enable, ready, out_valid); |
v_data := INCR_UVEC(v_data, c_incr); |
END LOOP; |
END IF; |
END proc_common_gen_data; |
|
-- c_incr = 1 |
PROCEDURE proc_common_gen_data(CONSTANT c_rl : IN NATURAL; -- 0, 1 are supported by proc_common_ready_latency() |
CONSTANT c_init : IN INTEGER; |
SIGNAL rst : IN STD_LOGIC; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL enable : IN STD_LOGIC; -- when '0' then no valid output even when ready='1' |
SIGNAL ready : IN STD_LOGIC; |
SIGNAL out_data : OUT STD_LOGIC_VECTOR; |
SIGNAL out_valid : OUT STD_LOGIC) IS |
BEGIN |
proc_common_gen_data(c_rl, c_init, 1, rst, clk, enable, ready, out_data, out_valid); |
END proc_common_gen_data; |
|
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Generate frame control |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_sop(SIGNAL clk : IN STD_LOGIC; |
SIGNAL in_val : OUT STD_LOGIC; |
SIGNAL in_sop : OUT STD_LOGIC) IS |
BEGIN |
in_val <= '1'; |
in_sop <= '1'; |
proc_common_wait_some_cycles(clk, 1); |
in_sop <= '0'; |
END proc_common_sop; |
|
PROCEDURE proc_common_eop(SIGNAL clk : IN STD_LOGIC; |
SIGNAL in_val : OUT STD_LOGIC; |
SIGNAL in_eop : OUT STD_LOGIC) IS |
BEGIN |
in_val <= '1'; |
in_eop <= '1'; |
proc_common_wait_some_cycles(clk, 1); |
in_val <= '0'; |
in_eop <= '0'; |
END proc_common_eop; |
|
PROCEDURE proc_common_val(CONSTANT c_val_len : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL in_val : OUT STD_LOGIC) IS |
BEGIN |
in_val <= '1'; |
proc_common_wait_some_cycles(clk, c_val_len); |
in_val <= '0'; |
END proc_common_val; |
|
PROCEDURE proc_common_val_duty(CONSTANT c_hi_len : IN NATURAL; |
CONSTANT c_lo_len : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL in_val : OUT STD_LOGIC) IS |
BEGIN |
in_val <= '1'; |
proc_common_wait_some_cycles(clk, c_hi_len); |
in_val <= '0'; |
proc_common_wait_some_cycles(clk, c_lo_len); |
END proc_common_val_duty; |
|
PROCEDURE proc_common_eop_flush(CONSTANT c_flush_len : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL in_val : OUT STD_LOGIC; |
SIGNAL in_eop : OUT STD_LOGIC) IS |
BEGIN |
-- . eop |
proc_common_eop(clk, in_val, in_eop); |
-- . flush after in_eop to empty the shift register |
proc_common_wait_some_cycles(clk, c_flush_len); |
END proc_common_eop_flush; |
|
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Verify incrementing data |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_verify_data(CONSTANT c_rl : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL verify_en : IN STD_LOGIC; |
SIGNAL ready : IN STD_LOGIC; |
SIGNAL out_valid : IN STD_LOGIC; |
SIGNAL out_data : IN STD_LOGIC_VECTOR; |
SIGNAL prev_out_data : INOUT STD_LOGIC_VECTOR) IS |
VARIABLE v_exp_data : STD_LOGIC_VECTOR(out_data'RANGE); |
BEGIN |
IF rising_edge(clk) THEN |
-- out_valid must be active, because only the out_data will it differ from the previous out_data |
IF out_valid='1' THEN |
-- for ready_latency = 1 out_valid indicates new data |
-- for ready_latency = 0 out_valid only indicates new data when it is confirmed by ready |
IF c_rl=1 OR (c_rl=0 AND ready='1') THEN |
prev_out_data <= out_data; |
v_exp_data := INCR_UVEC(prev_out_data, 1); -- increment first then compare to also support increment wrap around |
IF verify_en='1' AND UNSIGNED(out_data) /= UNSIGNED(v_exp_data) THEN |
REPORT "COMMON : Wrong out_data count" SEVERITY ERROR; |
END IF; |
END IF; |
END IF; |
END IF; |
END proc_common_verify_data; |
|
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Verify the DUT output valid |
-- . only support ready latency c_rl = 0 or 1 |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_verify_valid(CONSTANT c_rl : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL verify_en : IN STD_LOGIC; |
SIGNAL ready : IN STD_LOGIC; |
SIGNAL prev_ready : INOUT STD_LOGIC; |
SIGNAL out_valid : IN STD_LOGIC) IS |
BEGIN |
IF rising_edge(clk) THEN |
-- for ready latency c_rl = 1 out_valid may only be asserted after ready |
-- for ready latency c_rl = 0 out_valid may always be asserted |
prev_ready <= '0'; |
IF c_rl=1 THEN |
prev_ready <= ready; |
IF verify_en='1' AND out_valid='1' THEN |
IF prev_ready/='1' THEN |
REPORT "COMMON : Wrong ready latency between ready and out_valid" SEVERITY ERROR; |
END IF; |
END IF; |
END IF; |
END IF; |
END proc_common_verify_valid; |
|
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Verify the DUT input to output latency |
------------------------------------------------------------------------------ |
-- for SL ctrl |
PROCEDURE proc_common_verify_latency(CONSTANT c_str : IN STRING; -- e.g. "valid", "sop", "eop" |
CONSTANT c_latency : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL verify_en : IN STD_LOGIC; |
SIGNAL in_ctrl : IN STD_LOGIC; |
SIGNAL pipe_ctrl_vec : INOUT STD_LOGIC_VECTOR; -- range [0:c_latency] |
SIGNAL out_ctrl : IN STD_LOGIC) IS |
BEGIN |
IF rising_edge(clk) THEN |
pipe_ctrl_vec <= in_ctrl & pipe_ctrl_vec(0 TO c_latency-1); -- note: pipe_ctrl_vec(c_latency) is a dummy place holder to avoid [0:-1] range |
IF verify_en='1' THEN |
IF c_latency=0 THEN |
IF in_ctrl/=out_ctrl THEN |
REPORT "COMMON : Wrong zero latency between input " & c_str & " and output " & c_str SEVERITY ERROR; |
END IF; |
ELSE |
IF pipe_ctrl_vec(c_latency-1)/=out_ctrl THEN |
REPORT "COMMON : Wrong latency between input " & c_str & " and output " & c_str SEVERITY ERROR; |
END IF; |
END IF; |
END IF; |
END IF; |
END proc_common_verify_latency; |
|
|
-- for SLV data |
PROCEDURE proc_common_verify_latency(CONSTANT c_str : IN STRING; -- e.g. "data" |
CONSTANT c_latency : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL verify_en : IN STD_LOGIC; |
SIGNAL in_data : IN STD_LOGIC_VECTOR; |
SIGNAL pipe_data_vec : INOUT STD_LOGIC_VECTOR; -- range [0:(1 + c_latency)*c_data_w-1] |
SIGNAL out_data : IN STD_LOGIC_VECTOR) IS |
CONSTANT c_data_w : NATURAL := in_data'LENGTH; |
CONSTANT c_data_vec_w : NATURAL := pipe_data_vec'LENGTH; -- = (1 + c_latency) * c_data_w |
BEGIN |
IF rising_edge(clk) THEN |
pipe_data_vec <= in_data & pipe_data_vec(0 TO c_data_vec_w-c_data_w-1); -- note: pipe_data_vec(c_latency) is a dummy place holder to avoid [0:-1] range |
IF verify_en='1' THEN |
IF c_latency=0 THEN |
IF UNSIGNED(in_data)/=UNSIGNED(out_data) THEN |
REPORT "COMMON : Wrong zero latency between input " & c_str & " and output " & c_str SEVERITY ERROR; |
END IF; |
ELSE |
IF UNSIGNED(pipe_data_vec(c_data_vec_w-c_data_w-c_data_w TO c_data_vec_w-c_data_w-1))/=UNSIGNED(out_data) THEN |
REPORT "COMMON : Wrong latency between input " & c_str & " and output " & c_str SEVERITY ERROR; |
END IF; |
END IF; |
END IF; |
END IF; |
END proc_common_verify_latency; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Verify the expected value |
-- . e.g. to check that a test has ran at all |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_verify_value(CONSTANT mode : IN NATURAL; |
SIGNAL clk : IN STD_LOGIC; |
SIGNAL en : IN STD_LOGIC; |
SIGNAL exp : IN STD_LOGIC_VECTOR; |
SIGNAL res : IN STD_LOGIC_VECTOR) IS |
BEGIN |
IF rising_edge(clk) THEN |
IF en='1' THEN |
IF mode = 0 AND UNSIGNED(res) /= UNSIGNED(exp) THEN |
REPORT "COMMON : Wrong result value" SEVERITY ERROR; -- == (equal) |
END IF; |
IF mode = 1 AND UNSIGNED(res) < UNSIGNED(exp) THEN |
REPORT "COMMON : Wrong result value too small" SEVERITY ERROR; -- >= (at least) |
END IF; |
END IF; |
END IF; |
END proc_common_verify_value; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Opens a file for access and reports fail or success of opening. |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_open_file( file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT; |
file_name : IN STRING; |
file_mode : IN FILE_OPEN_KIND) IS |
BEGIN |
IF file_status=OPEN_OK THEN |
file_close(in_file); |
END IF; |
file_open (file_status, in_file, file_name, file_mode); |
IF file_status=OPEN_OK THEN |
REPORT "COMMON : File opened " SEVERITY NOTE; |
ELSE |
REPORT "COMMON : Unable to open file " SEVERITY FAILURE; |
END IF; |
END proc_common_open_file; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Reads an integer from a file. |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_readline_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT; |
read_value_0 : OUT INTEGER) IS |
VARIABLE v_line : LINE; |
VARIABLE v_good : BOOLEAN; |
BEGIN |
IF file_status/=OPEN_OK THEN |
REPORT "COMMON : File is not opened " SEVERITY FAILURE; |
ELSE |
IF ENDFILE(in_file) THEN |
REPORT "COMMON : end of file " SEVERITY NOTE; |
ELSE |
READLINE(in_file, v_line); |
READ(v_line, read_value_0, v_good); |
IF v_good = FALSE THEN |
REPORT "COMMON : Read from line unsuccessful " SEVERITY FAILURE; |
END IF; |
END IF; |
END IF; |
END proc_common_readline_file; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Reads two integers from two columns in a file. |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_readline_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT; |
read_value_0 : OUT INTEGER; |
read_value_1 : OUT INTEGER) IS |
VARIABLE v_line : LINE; |
VARIABLE v_good : BOOLEAN; |
BEGIN |
IF file_status/=OPEN_OK THEN |
REPORT "COMMON : File is not opened " SEVERITY FAILURE; |
ELSE |
IF ENDFILE(in_file) THEN |
REPORT "COMMON : end of file " SEVERITY NOTE; |
ELSE |
READLINE(in_file, v_line); |
READ(v_line, read_value_0, v_good); |
IF v_good = FALSE THEN |
REPORT "COMMON : Read from line unsuccessful " SEVERITY FAILURE; |
END IF; |
READ(v_line, read_value_1, v_good); |
IF v_good = FALSE THEN |
REPORT "COMMON : Read from line unsuccessful " SEVERITY FAILURE; |
END IF; |
END IF; |
END IF; |
END proc_common_readline_file; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Reads an array of integer from a file. |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_readline_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT; |
value_array : OUT t_integer_arr; |
nof_reads : IN INTEGER) IS |
VARIABLE v_line : LINE; |
VARIABLE v_good : BOOLEAN; |
BEGIN |
IF file_status/=OPEN_OK THEN |
REPORT "COMMON : File is not opened " SEVERITY FAILURE; |
ELSE |
IF ENDFILE(in_file) THEN |
REPORT "COMMON : end of file " SEVERITY NOTE; |
ELSE |
READLINE(in_file, v_line); |
FOR I IN 0 TO nof_reads - 1 LOOP |
READ(v_line, value_array(I), v_good); |
IF v_good = FALSE THEN |
REPORT "COMMON : Read from line unsuccessful " SEVERITY FAILURE; |
END IF; |
END LOOP; |
END IF; |
END IF; |
END proc_common_readline_file; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Reads an std_logic_vector from a file |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_readline_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT; |
read_slv : OUT STD_LOGIC_VECTOR) IS |
VARIABLE v_line : LINE; |
VARIABLE v_good : BOOLEAN; |
BEGIN |
IF file_status/=OPEN_OK THEN |
REPORT "COMMON : File is not opened " SEVERITY FAILURE; |
ELSE |
IF ENDFILE(in_file) THEN |
REPORT "COMMON : end of file " SEVERITY NOTE; |
ELSE |
READLINE(in_file, v_line); |
READ(v_line, read_slv, v_good); |
IF v_good = FALSE THEN |
REPORT "COMMON : Read from line unsuccessful " SEVERITY FAILURE; |
END IF; |
END IF; |
END IF; |
END proc_common_readline_file; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Reads a string of any length from a file pointer. |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_readline_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT; |
res_string : OUT STRING) IS |
VARIABLE v_line : LINE; |
VARIABLE v_char : CHARACTER; |
VARIABLE is_string : BOOLEAN; |
BEGIN |
IF file_status/=OPEN_OK THEN |
REPORT "COMMON : File is not opened " SEVERITY FAILURE; |
ELSE |
IF ENDFILE(in_file) THEN |
REPORT "COMMON : end of file " SEVERITY NOTE; |
ELSE |
readline(in_file, v_line); |
-- clear the contents of the result string |
FOR I IN res_string'RANGE LOOP |
res_string(I) := ' '; |
END LOOP; |
-- read all characters of the line, up to the length |
-- of the results string |
FOR I IN res_string'RANGE LOOP |
read(v_line, v_char, is_string); |
IF NOT is_string THEN -- found end of line |
EXIT; |
END IF; |
res_string(I) := v_char; |
END LOOP; |
END IF; |
END IF; |
END proc_common_readline_file; |
|
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Closes a file. |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_close_file(file_status : INOUT FILE_OPEN_STATUS; |
FILE in_file : TEXT) IS |
BEGIN |
IF file_status/=OPEN_OK THEN |
REPORT "COMMON : File was not opened " SEVERITY WARNING; |
END IF; |
FILE_CLOSE(in_file); |
REPORT "COMMON : File closed " SEVERITY NOTE; |
END proc_common_close_file; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Reads the integer data from nof_rows with nof_col values per |
-- row from a file and returns it row by row in an array of |
-- integers. |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_read_integer_file(file_name : IN STRING; |
nof_header_lines : NATURAL; |
nof_row : NATURAL; |
nof_col : NATURAL; |
SIGNAL return_array : OUT t_integer_arr) IS |
VARIABLE v_file_status : FILE_OPEN_STATUS; |
FILE v_in_file : TEXT; |
VARIABLE v_input_line : LINE; |
VARIABLE v_string : STRING(1 TO 80); |
VARIABLE v_row_arr : t_integer_arr(0 TO nof_col-1); |
BEGIN |
IF file_name/="UNUSED" AND file_name/="unused" THEN |
-- Open the file for reading |
proc_common_open_file(v_file_status, v_in_file, file_name, READ_MODE); |
-- Read and skip the header |
FOR J IN 0 TO nof_header_lines-1 LOOP |
proc_common_readline_file(v_file_status, v_in_file, v_string); |
END LOOP; |
FOR J IN 0 TO nof_row-1 LOOP |
proc_common_readline_file(v_file_status, v_in_file, v_row_arr, nof_col); |
FOR I IN 0 TO nof_col-1 LOOP |
return_array(J*nof_col + I) <= v_row_arr(I); -- use loop to be independent of t_integer_arr downto or to range |
END LOOP; |
IF ENDFILE(v_in_file) THEN |
IF J/=nof_row-1 THEN |
REPORT "COMMON : Unexpected end of file" SEVERITY FAILURE; |
END IF; |
EXIT; |
END IF; |
END LOOP; |
-- Close the file |
proc_common_close_file(v_file_status, v_in_file); |
ELSE |
return_array <= (return_array'RANGE=>0); |
END IF; |
END proc_common_read_integer_file; |
|
------------------------------------------------------------------------------ |
-- PROCEDURE: Reads the data column from a .mif file and returns it in an |
-- array of integers |
------------------------------------------------------------------------------ |
PROCEDURE proc_common_read_mif_file( file_name : IN STRING; |
SIGNAL return_array : OUT t_integer_arr) IS |
VARIABLE v_file_status : FILE_OPEN_STATUS; |
FILE v_in_file : TEXT; |
VARIABLE v_input_line : LINE; |
VARIABLE v_string : STRING(1 TO 80); |
VARIABLE v_mem_width : NATURAL := 0; |
VARIABLE v_mem_depth : NATURAL := 0; |
VARIABLE v_up_bound : NATURAL := 0; |
VARIABLE v_low_bound : NATURAL := 0; |
VARIABLE v_end_header : BOOLEAN := FALSE; |
VARIABLE v_char : CHARACTER; |
BEGIN |
-- Open the .mif file for reading |
proc_common_open_file(v_file_status, v_in_file, file_name, READ_MODE); |
-- Read the header. |
WHILE NOT v_end_header LOOP |
proc_common_readline_file(v_file_status, v_in_file, v_string); |
IF(func_find_string_in_string(v_string, "WIDTH=")) THEN -- check for "WIDTH=" |
v_up_bound := func_find_char_in_string(v_string, ';'); |
v_low_bound := func_find_char_in_string(v_string, '='); |
v_mem_width := func_decstring_to_integer(v_string(v_low_bound+1 TO v_up_bound-1)); |
ELSIF(func_find_string_in_string(v_string, "DEPTH=")) THEN -- check for "DEPTH=" |
v_up_bound := func_find_char_in_string(v_string, ';'); |
v_low_bound := func_find_char_in_string(v_string, '='); |
v_mem_depth := func_decstring_to_integer(v_string(v_low_bound+1 TO v_up_bound-1)); |
ELSIF(func_find_string_in_string(v_string, "CONTENT BEGIN")) THEN |
v_end_header := TRUE; |
END IF; |
END LOOP; |
-- Read the data |
FOR I IN 0 TO v_mem_depth-1 LOOP |
proc_common_readline_file(v_file_status, v_in_file, v_string); -- Read the next line from the file. |
v_low_bound := func_find_char_in_string(v_string, ':'); -- Find the left position of the string that contains the data field |
v_up_bound := func_find_char_in_string(v_string, ';'); -- Find the right position of the string that contains the data field |
return_array(I) <= func_hexstring_to_integer(v_string(v_low_bound+1 TO v_up_bound-1)); |
END LOOP; |
-- Close the file |
proc_common_close_file(v_file_status, v_in_file); |
END proc_common_read_mif_file; |
|
------------------------------------------------------------------------------ |
-- FUNCTION: Complex multiply with conjugate option for input b |
------------------------------------------------------------------------------ |
FUNCTION func_complex_multiply(in_ar, in_ai, in_br, in_bi : STD_LOGIC_VECTOR; conjugate_b : BOOLEAN; str : STRING; g_out_dat_w : NATURAL) RETURN STD_LOGIC_VECTOR IS |
-- Function: Signed complex multiply |
-- p = a * b when g_conjugate_b = FALSE |
-- = (ar + j ai) * (br + j bi) |
-- = ar*br - ai*bi + j ( ar*bi + ai*br) |
-- |
-- p = a * conj(b) when g_conjugate_b = TRUE |
-- = (ar + j ai) * (br - j bi) |
-- = ar*br + ai*bi + j (-ar*bi + ai*br) |
-- From mti_numeric_std.vhd follows: |
-- . SIGNED * --> output width = 2 * input width |
-- . SIGNED + --> output width = largest(input width) |
CONSTANT c_in_w : NATURAL := in_ar'LENGTH; -- all input have same width |
CONSTANT c_res_w : NATURAL := 2*c_in_w+1; -- *2 for multiply, +1 for sum of two products |
VARIABLE v_ar : SIGNED(c_in_w-1 DOWNTO 0); |
VARIABLE v_ai : SIGNED(c_in_w-1 DOWNTO 0); |
VARIABLE v_br : SIGNED(c_in_w-1 DOWNTO 0); |
VARIABLE v_bi : SIGNED(c_in_w-1 DOWNTO 0); |
VARIABLE v_result_re : SIGNED(c_res_w-1 DOWNTO 0); |
VARIABLE v_result_im : SIGNED(c_res_w-1 DOWNTO 0); |
BEGIN |
-- Calculate expected result |
v_ar := RESIZE_NUM(SIGNED(in_ar), c_in_w); |
v_ai := RESIZE_NUM(SIGNED(in_ai), c_in_w); |
v_br := RESIZE_NUM(SIGNED(in_br), c_in_w); |
v_bi := RESIZE_NUM(SIGNED(in_bi), c_in_w); |
IF conjugate_b=FALSE THEN |
v_result_re := RESIZE_NUM(v_ar*v_br, c_res_w) - v_ai*v_bi; |
v_result_im := RESIZE_NUM(v_ar*v_bi, c_res_w) + v_ai*v_br; |
ELSE |
v_result_re := RESIZE_NUM(v_ar*v_br, c_res_w) + v_ai*v_bi; |
v_result_im := RESIZE_NUM(v_ai*v_br, c_res_w) - v_ar*v_bi; |
END IF; |
-- Note that for the product needs as many bits as the sum of the input widths. However the |
-- sign bit is then only needed for the case that both inputs have the largest negative |
-- values, only then the MSBits will be "01". For all other inputs the MSbits will always |
-- be "00" for positive numbers or "11" for negative numbers. MSbits "10" can not occur. |
-- For largest negative inputs the complex multiply result becomes: |
-- |
-- 3b inputs --> 6b products --> c_res_w = 7b |
-- -4 * -4 + -4 * -4 = +16 + +16 = +64 -- most negative valued inputs |
-- b100 * b100 + b100 * b100 = b010000 + b010000 = b0100000 |
-- |
-- --> if g_out_dat_w = 6b then |
-- a) IEEE unsigned resizing skips the MSbits so b0100000 = +64 becomes b_100000 = -64 |
-- b) IEEE signed resizing preserves the MSbit so b0100000 = +64 becomes b0_00000 = 0 |
-- c) detect MSbits = "01" to clip max positive to get _b011111 = +63 |
-- Option a) seems to map best on the FPGA hardware multiplier IP. |
IF str="RE" THEN |
RETURN STD_LOGIC_VECTOR(RESIZE_NUM(v_result_re, g_out_dat_w)); -- conform option a) |
ELSE |
RETURN STD_LOGIC_VECTOR(RESIZE_NUM(v_result_im, g_out_dat_w)); -- conform option a) |
END IF; |
END; |
|
------------------------------------------------------------------------------ |
-- FUNCTION: Converts the decimal value represented in a string to an integer value. |
------------------------------------------------------------------------------ |
FUNCTION func_decstring_to_integer(in_string: STRING) RETURN INTEGER IS |
CONSTANT c_nof_digits : NATURAL := in_string'LENGTH; -- Define the length of the string |
VARIABLE v_char : CHARACTER; |
VARIABLE v_weight : INTEGER := 1; |
VARIABLE v_return_int : INTEGER := 0; |
BEGIN |
-- Walk through the string character by character. |
FOR I IN c_nof_digits-1 DOWNTO 0 LOOP |
v_char := in_string(I+in_string'LOW); |
CASE v_char IS |
WHEN '0' => v_return_int := v_return_int + 0*v_weight; |
WHEN '1' => v_return_int := v_return_int + 1*v_weight; |
WHEN '2' => v_return_int := v_return_int + 2*v_weight; |
WHEN '3' => v_return_int := v_return_int + 3*v_weight; |
WHEN '4' => v_return_int := v_return_int + 4*v_weight; |
WHEN '5' => v_return_int := v_return_int + 5*v_weight; |
WHEN '6' => v_return_int := v_return_int + 6*v_weight; |
WHEN '7' => v_return_int := v_return_int + 7*v_weight; |
WHEN '8' => v_return_int := v_return_int + 8*v_weight; |
WHEN '9' => v_return_int := v_return_int + 9*v_weight; |
WHEN OTHERS => NULL; |
END CASE; |
IF (v_char /= ' ') THEN -- Only increment the weight when the character is NOT a spacebar. |
v_weight := v_weight*10; -- Addapt the weight for the next decimal digit. |
END IF; |
END LOOP; |
RETURN(v_return_int); |
END FUNCTION func_decstring_to_integer; |
|
------------------------------------------------------------------------------ |
-- FUNCTION: Converts the hexadecimal value represented in a string to an integer value. |
------------------------------------------------------------------------------ |
FUNCTION func_hexstring_to_integer(in_string: STRING) RETURN INTEGER IS |
CONSTANT c_nof_digits : NATURAL := in_string'LENGTH; -- Define the length of the string |
VARIABLE v_char : CHARACTER; |
VARIABLE v_weight : INTEGER := 1; |
VARIABLE v_return_int : INTEGER := 0; |
BEGIN |
-- Walk through the string character by character. |
FOR I IN c_nof_digits-1 DOWNTO 0 LOOP |
v_char := in_string(I+in_string'LOW); |
CASE v_char IS |
WHEN '0' => v_return_int := v_return_int + 0*v_weight; |
WHEN '1' => v_return_int := v_return_int + 1*v_weight; |
WHEN '2' => v_return_int := v_return_int + 2*v_weight; |
WHEN '3' => v_return_int := v_return_int + 3*v_weight; |
WHEN '4' => v_return_int := v_return_int + 4*v_weight; |
WHEN '5' => v_return_int := v_return_int + 5*v_weight; |
WHEN '6' => v_return_int := v_return_int + 6*v_weight; |
WHEN '7' => v_return_int := v_return_int + 7*v_weight; |
WHEN '8' => v_return_int := v_return_int + 8*v_weight; |
WHEN '9' => v_return_int := v_return_int + 9*v_weight; |
WHEN 'A' | 'a' => v_return_int := v_return_int + 10*v_weight; |
WHEN 'B' | 'b' => v_return_int := v_return_int + 11*v_weight; |
WHEN 'C' | 'c' => v_return_int := v_return_int + 12*v_weight; |
WHEN 'D' | 'd' => v_return_int := v_return_int + 13*v_weight; |
WHEN 'E' | 'e' => v_return_int := v_return_int + 14*v_weight; |
WHEN 'F' | 'f' => v_return_int := v_return_int + 15*v_weight; |
WHEN OTHERS => NULL; |
END CASE; |
IF (v_char /= ' ') THEN -- Only increment the weight when the character is NOT a spacebar. |
v_weight := v_weight*16; -- Addapt the weight for the next hexadecimal digit. |
END IF; |
END LOOP; |
RETURN(v_return_int); |
END FUNCTION func_hexstring_to_integer; |
|
------------------------------------------------------------------------------ |
-- FUNCTION: Finds the first instance of a given character in a string |
-- and returns its position. |
------------------------------------------------------------------------------ |
FUNCTION func_find_char_in_string(in_string: STRING; find_char: CHARACTER) RETURN INTEGER IS |
VARIABLE v_char_position : INTEGER := 0; |
BEGIN |
FOR I IN 1 TO in_string'LENGTH LOOP |
IF(in_string(I) = find_char) THEN |
v_char_position := I; |
END IF; |
END LOOP; |
RETURN(v_char_position); |
END FUNCTION func_find_char_in_string; |
|
------------------------------------------------------------------------------ |
-- FUNCTION: Checks if a string(find_string) is part of a larger string(in_string). |
-- The result is returned as a BOOLEAN. |
------------------------------------------------------------------------------ |
FUNCTION func_find_string_in_string(in_string: STRING; find_string: STRING) RETURN BOOLEAN IS |
CONSTANT c_in_length : NATURAL := in_string'LENGTH; -- Define the length of the string to search in |
CONSTANT c_find_length : NATURAL := find_string'LENGTH; -- Define the length of the string to be find |
VARIABLE v_found_it : BOOLEAN := FALSE; |
BEGIN |
FOR I IN 1 TO c_in_length-c_find_length LOOP |
IF(in_string(I TO (I+c_find_length-1)) = find_string) THEN |
v_found_it := TRUE; |
END IF; |
END LOOP; |
RETURN(v_found_it); |
END FUNCTION func_find_string_in_string; |
|
END tb_common_pkg; |
|