diff options
Diffstat (limited to 'testsuite/gna/bug035/utils.vhdl')
-rw-r--r-- | testsuite/gna/bug035/utils.vhdl | 946 |
1 files changed, 946 insertions, 0 deletions
diff --git a/testsuite/gna/bug035/utils.vhdl b/testsuite/gna/bug035/utils.vhdl new file mode 100644 index 0000000..76347d3 --- /dev/null +++ b/testsuite/gna/bug035/utils.vhdl @@ -0,0 +1,946 @@ +-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*- +-- vim: tabstop=2:shiftwidth=2:noexpandtab +-- kate: tab-width 2; replace-tabs off; indent-width 2; +-- +-- ============================================================================ +-- Package: Common functions and types +-- +-- Authors: Thomas B. Preusser +-- Martin Zabel +-- Patrick Lehmann +-- +-- Description: +-- ------------------------------------ +-- For detailed documentation see below. +-- +-- License: +-- ============================================================================ +-- Copyright 2007-2015 Technische Universitaet Dresden - Germany +-- Chair for VLSI-Design, Diagnostics and Architecture +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- ============================================================================ + +library IEEE; + +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +library PoC; +use PoC.my_config.all; + + +package utils is + -- PoC settings + -- ========================================================================== + constant POC_VERBOSE : BOOLEAN := MY_VERBOSE; + + -- Environment + -- ========================================================================== + -- Distinguishes simulation from synthesis + constant SIMULATION : BOOLEAN; -- deferred constant declaration + + -- Type declarations + -- ========================================================================== + + --+ Vectors of primitive standard types +++++++++++++++++++++++++++++++++++++ + type T_BOOLVEC is array(NATURAL range <>) of BOOLEAN; + type T_INTVEC is array(NATURAL range <>) of INTEGER; + type T_NATVEC is array(NATURAL range <>) of NATURAL; + type T_POSVEC is array(NATURAL range <>) of POSITIVE; + type T_REALVEC is array(NATURAL range <>) of REAL; + + --+ Integer subranges sometimes useful for speeding up simulation ++++++++++ + subtype T_INT_8 is INTEGER range -128 to 127; + subtype T_INT_16 is INTEGER range -32768 to 32767; + subtype T_UINT_8 is INTEGER range 0 to 255; + subtype T_UINT_16 is INTEGER range 0 to 65535; + + --+ Enums ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + -- Intellectual Property (IP) type + type T_IPSTYLE is (IPSTYLE_HARD, IPSTYLE_SOFT); + + -- Bit Order + type T_BIT_ORDER is (LSB_FIRST, MSB_FIRST); + + -- Byte Order (Endian) + type T_BYTE_ORDER is (LITTLE_ENDIAN, BIG_ENDIAN); + + -- rounding style + type T_ROUNDING_STYLE is (ROUND_TO_NEAREST, ROUND_TO_ZERO, ROUND_TO_INF, ROUND_UP, ROUND_DOWN); + + type T_BCD is array(3 downto 0) of std_logic; + type T_BCD_VECTOR is array(NATURAL range <>) of T_BCD; + constant C_BCD_MINUS : T_BCD := "1010"; + constant C_BCD_OFF : T_BCD := "1011"; + + + -- Function declarations + -- ========================================================================== + + --+ Division ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + -- Calculates: ceil(a / b) + function div_ceil(a : NATURAL; b : POSITIVE) return NATURAL; + + --+ Power +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + -- is input a power of 2? + function is_pow2(int : NATURAL) return BOOLEAN; + -- round to next power of 2 + function ceil_pow2(int : NATURAL) return POSITIVE; + -- round to previous power of 2 + function floor_pow2(int : NATURAL) return NATURAL; + + --+ Logarithm ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + -- Calculates: ceil(ld(arg)) + function log2ceil(arg : positive) return natural; + -- Calculates: max(1, ceil(ld(arg))) + function log2ceilnz(arg : positive) return positive; + -- Calculates: ceil(lg(arg)) + function log10ceil(arg : POSITIVE) return NATURAL; + -- Calculates: max(1, ceil(lg(arg))) + function log10ceilnz(arg : POSITIVE) return POSITIVE; + + --+ if-then-else (ite) +++++++++++++++++++++++++++++++++++++++++++++++++++++ + function ite(cond : BOOLEAN; value1 : BOOLEAN; value2 : BOOLEAN) return BOOLEAN; + function ite(cond : BOOLEAN; value1 : INTEGER; value2 : INTEGER) return INTEGER; + function ite(cond : BOOLEAN; value1 : REAL; value2 : REAL) return REAL; + function ite(cond : BOOLEAN; value1 : STD_LOGIC; value2 : STD_LOGIC) return STD_LOGIC; + function ite(cond : BOOLEAN; value1 : STD_LOGIC_VECTOR; value2 : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR; + function ite(cond : BOOLEAN; value1 : BIT_VECTOR; value2 : BIT_VECTOR) return BIT_VECTOR; + function ite(cond : BOOLEAN; value1 : UNSIGNED; value2 : UNSIGNED) return UNSIGNED; + function ite(cond : BOOLEAN; value1 : CHARACTER; value2 : CHARACTER) return CHARACTER; + function ite(cond : BOOLEAN; value1 : STRING; value2 : STRING) return STRING; + + --+ Max / Min / Sum ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function imin(arg1 : integer; arg2 : integer) return integer; -- Calculates: min(arg1, arg2) for integers + function rmin(arg1 : real; arg2 : real) return real; -- Calculates: min(arg1, arg2) for reals + + function imin(vec : T_INTVEC) return INTEGER; -- Calculates: min(vec) for a integer vector + function imin(vec : T_NATVEC) return NATURAL; -- Calculates: min(vec) for a natural vector + function imin(vec : T_POSVEC) return POSITIVE; -- Calculates: min(vec) for a positive vector + function rmin(vec : T_REALVEC) return real; -- Calculates: min(vec) of real vector + + function imax(arg1 : integer; arg2 : integer) return integer; -- Calculates: max(arg1, arg2) for integers + function rmax(arg1 : real; arg2 : real) return real; -- Calculates: max(arg1, arg2) for reals + + function imax(vec : T_INTVEC) return INTEGER; -- Calculates: max(vec) for a integer vector + function imax(vec : T_NATVEC) return NATURAL; -- Calculates: max(vec) for a natural vector + function imax(vec : T_POSVEC) return POSITIVE; -- Calculates: max(vec) for a positive vector + function rmax(vec : T_REALVEC) return real; -- Calculates: max(vec) of real vector + + function isum(vec : T_NATVEC) return NATURAL; -- Calculates: sum(vec) for a natural vector + function isum(vec : T_POSVEC) return natural; -- Calculates: sum(vec) for a positive vector + function isum(vec : T_INTVEC) return integer; -- Calculates: sum(vec) of integer vector + function rsum(vec : T_REALVEC) return real; -- Calculates: sum(vec) of real vector + + --+ Conversions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + -- to integer: to_int + function to_int(bool : BOOLEAN; zero : INTEGER := 0; one : INTEGER := 1) return INTEGER; + function to_int(sl : STD_LOGIC; zero : INTEGER := 0; one : INTEGER := 1) return INTEGER; + + -- to std_logic: to_sl + function to_sl(Value : BOOLEAN) return STD_LOGIC; + function to_sl(Value : CHARACTER) return STD_LOGIC; + + -- to std_logic_vector: to_slv + function to_slv(Value : NATURAL; Size : POSITIVE) return STD_LOGIC_VECTOR; -- short for std_logic_vector(to_unsigned(Value, Size)) + + -- TODO: comment + function to_index(slv : UNSIGNED; max : NATURAL := 0) return INTEGER; + function to_index(slv : STD_LOGIC_VECTOR; max : NATURAL := 0) return INTEGER; + + -- is_* + function is_sl(c : CHARACTER) return BOOLEAN; + + --+ Basic Vector Utilities +++++++++++++++++++++++++++++++++++++++++++++++++ + + -- Aggregate functions + function slv_or (vec : STD_LOGIC_VECTOR) return STD_LOGIC; + function slv_nor (vec : STD_LOGIC_VECTOR) return STD_LOGIC; + function slv_and (vec : STD_LOGIC_VECTOR) return STD_LOGIC; + function slv_nand(vec : STD_LOGIC_VECTOR) return STD_LOGIC; + function slv_xor (vec : std_logic_vector) return std_logic; + -- NO slv_xnor! This operation would not be well-defined as + -- not xor(vec) /= vec_{n-1} xnor ... xnor vec_1 xnor vec_0 iff n is odd. + + -- Reverses the elements of the passed Vector. + -- + -- @synthesis supported + -- + function reverse(vec : std_logic_vector) return std_logic_vector; + function reverse(vec : bit_vector) return bit_vector; + function reverse(vec : unsigned) return unsigned; + + -- Resizes the vector to the specified length. The adjustment is make on + -- on the 'high end of the vector. The 'low index remains as in the argument. + -- If the result vector is larger, the extension uses the provided fill value + -- (default: '0'). + -- Use the resize functions of the numeric_std package for value-preserving + -- resizes of the signed and unsigned data types. + -- + -- @synthesis supported + -- + function resize(vec : bit_vector; length : natural; fill : bit := '0') + return bit_vector; + function resize(vec : std_logic_vector; length : natural; fill : std_logic := '0') + return std_logic_vector; + + -- Shift the index range of a vector by the specified offset. + function move(vec : std_logic_vector; ofs : integer) return std_logic_vector; + + -- Shift the index range of a vector making vec'low = 0. + function movez(vec : std_logic_vector) return std_logic_vector; + + function ascend(vec : std_logic_vector) return std_logic_vector; + function descend(vec : std_logic_vector) return std_logic_vector; + + -- Least-Significant Set Bit (lssb): + -- Computes a vector of the same length as the argument with + -- at most one bit set at the rightmost '1' found in arg. + -- + -- @synthesis supported + -- + function lssb(arg : std_logic_vector) return std_logic_vector; + function lssb(arg : bit_vector) return bit_vector; + + -- Returns the index of the least-significant set bit. + -- + -- @synthesis supported + -- + function lssb_idx(arg : std_logic_vector) return integer; + function lssb_idx(arg : bit_vector) return integer; + + -- Most-Significant Set Bit (mssb): computes a vector of the same length + -- with at most one bit set at the leftmost '1' found in arg. + function mssb(arg : std_logic_vector) return std_logic_vector; + function mssb(arg : bit_vector) return bit_vector; + function mssb_idx(arg : std_logic_vector) return integer; + function mssb_idx(arg : bit_vector) return integer; + + -- Swap sub vectors in vector (endian reversal) + function swap(slv : STD_LOGIC_VECTOR; Size : POSITIVE) return STD_LOGIC_VECTOR; + + -- generate bit masks + function genmask_high(Bits : NATURAL; MaskLength : POSITIVE) return STD_LOGIC_VECTOR; + function genmask_low(Bits : NATURAL; MaskLength : POSITIVE) return STD_LOGIC_VECTOR; + + --+ Encodings ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + -- One-Hot-Code to Binary-Code. + function onehot2bin(onehot : std_logic_vector) return unsigned; + + -- Converts Gray-Code into Binary-Code. + -- + -- @synthesis supported + -- + function gray2bin (gray_val : std_logic_vector) return std_logic_vector; + + -- Binary-Code to One-Hot-Code + function bin2onehot(value : std_logic_vector) return std_logic_vector; + + -- Binary-Code to Gray-Code + function bin2gray(value : std_logic_vector) return std_logic_vector; + +end package; + + +package body utils is + + -- Environment + -- ========================================================================== + function is_simulation return boolean is + variable ret : boolean; + begin + ret := false; + --synthesis translate_off + if Is_X('X') then ret := true; end if; + --synthesis translate_on + return ret; + end function; + + -- deferred constant assignment + constant SIMULATION : BOOLEAN := is_simulation; + + -- Divisions: div_* + function div_ceil(a : NATURAL; b : POSITIVE) return NATURAL is -- calculates: ceil(a / b) + begin + return (a + (b - 1)) / b; + end function; + + -- Power functions: *_pow2 + -- ========================================================================== + -- is input a power of 2? + function is_pow2(int : NATURAL) return BOOLEAN is + begin + return ceil_pow2(int) = int; + end function; + + -- round to next power of 2 + function ceil_pow2(int : NATURAL) return POSITIVE is + begin + return 2 ** log2ceil(int); + end function; + + -- round to previous power of 2 + function floor_pow2(int : NATURAL) return NATURAL is + variable temp : UNSIGNED(30 downto 0); + begin + temp := to_unsigned(int, 31); + for i in temp'range loop + if (temp(i) = '1') then + return 2 ** i; + end if; + end loop; + return 0; + end function; + + -- Logarithms: log*ceil* + -- ========================================================================== + function log2ceil(arg : positive) return natural is + variable tmp : positive; + variable log : natural; + begin + if arg = 1 then return 0; end if; + tmp := 1; + log := 0; + while arg > tmp loop + tmp := tmp * 2; + log := log + 1; + end loop; + return log; + end function; + + function log2ceilnz(arg : positive) return positive is + begin + return imax(1, log2ceil(arg)); + end function; + + function log10ceil(arg : positive) return natural is + variable tmp : positive; + variable log : natural; + begin + if arg = 1 then return 0; end if; + tmp := 1; + log := 0; + while arg > tmp loop + tmp := tmp * 10; + log := log + 1; + end loop; + return log; + end function; + + function log10ceilnz(arg : positive) return positive is + begin + return imax(1, log10ceil(arg)); + end function; + + -- if-then-else (ite) + -- ========================================================================== + function ite(cond : BOOLEAN; value1 : BOOLEAN; value2 : BOOLEAN) return BOOLEAN is + begin + if cond then + return value1; + else + return value2; + end if; + end function; + + function ite(cond : BOOLEAN; value1 : INTEGER; value2 : INTEGER) return INTEGER is + begin + if cond then + return value1; + else + return value2; + end if; + end function; + + function ite(cond : BOOLEAN; value1 : REAL; value2 : REAL) return REAL is + begin + if cond then + return value1; + else + return value2; + end if; + end function; + + function ite(cond : BOOLEAN; value1 : STD_LOGIC; value2 : STD_LOGIC) return STD_LOGIC is + begin + if cond then + return value1; + else + return value2; + end if; + end function; + + function ite(cond : BOOLEAN; value1 : STD_LOGIC_VECTOR; value2 : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is + begin + if cond then + return value1; + else + return value2; + end if; + end function; + + function ite(cond : BOOLEAN; value1 : BIT_VECTOR; value2 : BIT_VECTOR) return BIT_VECTOR is + begin + if cond then + return value1; + else + return value2; + end if; + end function; + + function ite(cond : BOOLEAN; value1 : UNSIGNED; value2 : UNSIGNED) return UNSIGNED is + begin + if cond then + return value1; + else + return value2; + end if; + end function; + + function ite(cond : BOOLEAN; value1 : CHARACTER; value2 : CHARACTER) return CHARACTER is + begin + if cond then + return value1; + else + return value2; + end if; + end function; + + function ite(cond : BOOLEAN; value1 : STRING; value2 : STRING) return STRING is + begin + if cond then + return value1; + else + return value2; + end if; + end function; + + -- *min / *max / *sum + -- ========================================================================== + function imin(arg1 : integer; arg2 : integer) return integer is + begin + if arg1 < arg2 then return arg1; end if; + return arg2; + end function; + + function rmin(arg1 : real; arg2 : real) return real is + begin + if arg1 < arg2 then return arg1; end if; + return arg2; + end function; + + function imin(vec : T_INTVEC) return INTEGER is + variable Result : INTEGER; + begin + Result := INTEGER'high; + for i in vec'range loop + if (vec(I) < Result) then + Result := vec(I); + end if; + end loop; + return Result; + end function; + + function imin(vec : T_NATVEC) return NATURAL is + variable Result : NATURAL; + begin + Result := NATURAL'high; + for i in vec'range loop + if (vec(I) < Result) then + Result := vec(I); + end if; + end loop; + return Result; + end function; + + function imin(vec : T_POSVEC) return POSITIVE is + variable Result : POSITIVE; + begin + Result := POSITIVE'high; + for i in vec'range loop + if (vec(I) < Result) then + Result := vec(I); + end if; + end loop; + return Result; + end function; + + function rmin(vec : T_REALVEC) return REAL is + variable Result : REAL; + begin + Result := REAL'high; + for i in vec'range loop + if vec(i) < Result then + Result := vec(i); + end if; + end loop; + return Result; + end function; + + function imax(arg1 : integer; arg2 : integer) return integer is + begin + if arg1 > arg2 then return arg1; end if; + return arg2; + end function; + + function rmax(arg1 : real; arg2 : real) return real is + begin + if arg1 > arg2 then return arg1; end if; + return arg2; + end function; + + function imax(vec : T_INTVEC) return INTEGER is + variable Result : INTEGER; + begin + Result := INTEGER'low; + for i in vec'range loop + if (vec(I) > Result) then + Result := vec(I); + end if; + end loop; + return Result; + end function; + + function imax(vec : T_NATVEC) return NATURAL is + variable Result : NATURAL; + begin + Result := NATURAL'low; + for i in vec'range loop + if (vec(I) > Result) then + Result := vec(I); + end if; + end loop; + return Result; + end function; + + function imax(vec : T_POSVEC) return POSITIVE is + variable Result : POSITIVE; + begin + Result := POSITIVE'low; + for i in vec'range loop + if (vec(I) > Result) then + Result := vec(I); + end if; + end loop; + return Result; + end function; + + function rmax(vec : T_REALVEC) return REAL is + variable Result : REAL; + begin + Result := REAL'low; + for i in vec'range loop + if vec(i) > Result then + Result := vec(i); + end if; + end loop; + return Result; + end function; + + function isum(vec : T_INTVEC) return INTEGER is + variable Result : INTEGER; + begin + Result := 0; + for i in vec'range loop + Result := Result + vec(i); + end loop; + return Result; + end function; + + function isum(vec : T_NATVEC) return NATURAL is + variable Result : NATURAL; + begin + Result := 0; + for i in vec'range loop + Result := Result + vec(I); + end loop; + return Result; + end function; + + function isum(vec : T_POSVEC) return natural is + variable Result : natural; + begin + Result := 0; + for i in vec'range loop + Result := Result + vec(I); + end loop; + return Result; + end function; + + function rsum(vec : T_REALVEC) return REAL is + variable Result : REAL; + begin + Result := 0.0; + for i in vec'range loop + Result := Result + vec(i); + end loop; + return Result; + end function; + + -- Vector aggregate functions: slv_* + -- ========================================================================== + function slv_or(vec : STD_LOGIC_VECTOR) return STD_LOGIC is + variable Result : STD_LOGIC; + begin + Result := '0'; + for i in vec'range loop + Result := Result or vec(i); + end loop; + return Result; + end function; + + function slv_nor(vec : STD_LOGIC_VECTOR) return STD_LOGIC is + begin + return not slv_or(vec); + end function; + + function slv_and(vec : STD_LOGIC_VECTOR) return STD_LOGIC is + variable Result : STD_LOGIC; + begin + Result := '1'; + for i in vec'range loop + Result := Result and vec(i); + end loop; + return Result; + end function; + + function slv_nand(vec : STD_LOGIC_VECTOR) return STD_LOGIC is + begin + return not slv_and(vec); + end function; + + function slv_xor(vec : std_logic_vector) return std_logic is + variable res : std_logic; + begin + res := '0'; + for i in vec'range loop + res := res xor vec(i); + end loop; + return res; + end slv_xor; + + -- Convert to integer: to_int + function to_int(bool : BOOLEAN; zero : INTEGER := 0; one : INTEGER := 1) return INTEGER is + begin + return ite(bool, one, zero); + end function; + + function to_int(sl : STD_LOGIC; zero : INTEGER := 0; one : INTEGER := 1) return INTEGER is + begin + if (sl = '1') then + return one; + end if; + return zero; + end function; + + -- Convert to bit: to_sl + -- ========================================================================== + function to_sl(Value : BOOLEAN) return STD_LOGIC is + begin + return ite(Value, '1', '0'); + end function; + + function to_sl(Value : CHARACTER) return STD_LOGIC is + begin + case Value is + when 'U' => return 'U'; + when '0' => return '0'; + when '1' => return '1'; + when 'Z' => return 'Z'; + when 'W' => return 'W'; + when 'L' => return 'L'; + when 'H' => return 'H'; + when '-' => return '-'; + when OTHERS => return 'X'; + end case; + end function; + + -- Convert to vector: to_slv + -- ========================================================================== + -- short for std_logic_vector(to_unsigned(Value, Size)) + -- the return value is guaranteed to have the range (Size-1 downto 0) + function to_slv(Value : NATURAL; Size : POSITIVE) return STD_LOGIC_VECTOR is + constant res : std_logic_vector(Size-1 downto 0) := std_logic_vector(to_unsigned(Value, Size)); + begin + return res; + end function; + + function to_index(slv : UNSIGNED; max : NATURAL := 0) return INTEGER is + variable res : integer; + begin + if (slv'length = 0) then return 0; end if; + + res := to_integer(slv); + if SIMULATION and max > 0 then + res := imin(res, max); + end if; + return res; + end function; + + function to_index(slv : STD_LOGIC_VECTOR; max : NATURAL := 0) return INTEGER is + begin + return to_index(unsigned(slv), max); + end function; + + -- is_* + -- ========================================================================== + function is_sl(c : CHARACTER) return BOOLEAN is + begin + case c is + when 'U'|'X'|'0'|'1'|'Z'|'W'|'L'|'H'|'-' => return true; + when OTHERS => return false; + end case; + end function; + + + -- Reverse vector elements + function reverse(vec : std_logic_vector) return std_logic_vector is + variable res : std_logic_vector(vec'range); + begin + for i in vec'low to vec'high loop + res(vec'low + (vec'high-i)) := vec(i); + end loop; + return res; + end function; + + function reverse(vec : bit_vector) return bit_vector is + variable res : bit_vector(vec'range); + begin + res := to_bitvector(reverse(to_stdlogicvector(vec))); + return res; + end reverse; + + function reverse(vec : unsigned) return unsigned is + begin + return unsigned(reverse(std_logic_vector(vec))); + end function; + + + -- Swap sub vectors in vector + -- ========================================================================== + function swap(slv : STD_LOGIC_VECTOR; Size : POSITIVE) return STD_LOGIC_VECTOR IS + CONSTANT SegmentCount : NATURAL := slv'length / Size; + variable FromH : NATURAL; + variable FromL : NATURAL; + variable ToH : NATURAL; + variable ToL : NATURAL; + variable Result : STD_LOGIC_VECTOR(slv'length - 1 DOWNTO 0); + begin + for i in 0 TO SegmentCount - 1 loop + FromH := ((I + 1) * Size) - 1; + FromL := I * Size; + ToH := ((SegmentCount - I) * Size) - 1; + ToL := (SegmentCount - I - 1) * Size; + Result(ToH DOWNTO ToL) := slv(FromH DOWNTO FromL); + end loop; + return Result; + end function; + + -- generate bit masks + -- ========================================================================== + function genmask_high(Bits : NATURAL; MaskLength : POSITIVE) return STD_LOGIC_VECTOR IS + begin + if (Bits = 0) then + return (MaskLength - 1 DOWNTO 0 => '0'); + else + return (MaskLength - 1 DOWNTO MaskLength - Bits + 1 => '1') & (MaskLength - Bits DOWNTO 0 => '0'); + end if; + end function; + + function genmask_low(Bits : NATURAL; MaskLength : POSITIVE) return STD_LOGIC_VECTOR is + begin + if (Bits = 0) then + return (MaskLength - 1 DOWNTO 0 => '0'); + else + return (MaskLength - 1 DOWNTO Bits => '0') & (Bits - 1 DOWNTO 0 => '1'); + end if; + end function; + + -- binary encoding conversion functions + -- ========================================================================== + -- One-Hot-Code to Binary-Code + function onehot2bin(onehot : std_logic_vector) return unsigned is + variable res : unsigned(log2ceilnz(onehot'high+1)-1 downto 0); + variable chk : natural; + begin + res := (others => '0'); + chk := 0; + for i in onehot'range loop + if onehot(i) = '1' then + res := res or to_unsigned(i, res'length); + chk := chk + 1; + end if; + end loop; + if SIMULATION and chk /= 1 then + report "Broken 1-Hot-Code with "&integer'image(chk)&" bits set." + severity error; + end if; + return res; + end onehot2bin; + + -- Gray-Code to Binary-Code + function gray2bin(gray_val : std_logic_vector) return std_logic_vector is + variable res : std_logic_vector(gray_val'range); + begin -- gray2bin + res(res'left) := gray_val(gray_val'left); + for i in res'left-1 downto res'right loop + res(i) := res(i+1) xor gray_val(i); + end loop; + return res; + end gray2bin; + + -- Binary-Code to One-Hot-Code + function bin2onehot(value : std_logic_vector) return std_logic_vector is + variable result : std_logic_vector(2**value'length - 1 downto 0); + begin + result := (others => '0'); + result(to_index(value, 0)) := '1'; + return result; + end function; + + -- Binary-Code to Gray-Code + function bin2gray(value : std_logic_vector) return std_logic_vector is + variable result : std_logic_vector(value'range); + begin + result(result'left) := value(value'left); + for i in (result'left - 1) downto result'right loop + result(i) := value(i) xor value(i + 1); + end loop; + return result; + end function; + + -- bit searching / bit indices + -- ========================================================================== + -- Least-Significant Set Bit (lssb): computes a vector of the same length with at most one bit set at the rightmost '1' found in arg. + function lssb(arg : std_logic_vector) return std_logic_vector is + variable res : std_logic_vector(arg'range); + begin + res := arg and std_logic_vector(unsigned(not arg)+1); + return res; + end function; + + function lssb(arg : bit_vector) return bit_vector is + variable res : bit_vector(arg'range); + begin + res := to_bitvector(lssb(to_stdlogicvector(arg))); + return res; + end lssb; + + -- Most-Significant Set Bit (mssb): computes a vector of the same length with at most one bit set at the leftmost '1' found in arg. + function mssb(arg : std_logic_vector) return std_logic_vector is + begin + return reverse(lssb(reverse(arg))); + end function; + + function mssb(arg : bit_vector) return bit_vector is + begin + return reverse(lssb(reverse(arg))); + end mssb; + + -- Index of lssb + function lssb_idx(arg : std_logic_vector) return integer is + begin + return to_integer(onehot2bin(lssb(arg))); + end function; + + function lssb_idx(arg : bit_vector) return integer is + variable slv : std_logic_vector(arg'range); + begin + slv := to_stdlogicvector(arg); + return lssb_idx(slv); + end lssb_idx; + + -- Index of mssb + function mssb_idx(arg : std_logic_vector) return integer is + begin + return to_integer(onehot2bin(mssb(arg))); + end function; + + function mssb_idx(arg : bit_vector) return integer is + variable slv : std_logic_vector(arg'range); + begin + slv := to_stdlogicvector(arg); + return mssb_idx(slv); + end mssb_idx; + + function resize(vec : bit_vector; length : natural; fill : bit := '0') return bit_vector is + constant high2b : natural := vec'low+length-1; + constant highcp : natural := imin(vec'high, high2b); + variable res_up : bit_vector(vec'low to high2b); + variable res_dn : bit_vector(high2b downto vec'low); + begin + if vec'ascending then + res_up := (others => fill); + res_up(vec'low to highcp) := vec(vec'low to highcp); + return res_up; + else + res_dn := (others => fill); + res_dn(highcp downto vec'low) := vec(highcp downto vec'low); + return res_dn; + end if; + end resize; + + function resize(vec : std_logic_vector; length : natural; fill : std_logic := '0') return std_logic_vector is + constant high2b : natural := vec'low+length-1; + constant highcp : natural := imin(vec'high, high2b); + variable res_up : std_logic_vector(vec'low to high2b); + variable res_dn : std_logic_vector(high2b downto vec'low); + begin + if vec'ascending then + res_up := (others => fill); + res_up(vec'low to highcp) := vec(vec'low to highcp); + return res_up; + else + res_dn := (others => fill); + res_dn(highcp downto vec'low) := vec(highcp downto vec'low); + return res_dn; + end if; + end resize; + + -- Move vector boundaries + -- ========================================================================== + function move(vec : std_logic_vector; ofs : integer) return std_logic_vector is + variable res_up : std_logic_vector(vec'low +ofs to vec'high+ofs); + variable res_dn : std_logic_vector(vec'high+ofs downto vec'low +ofs); + begin + if vec'ascending then + res_up := vec; + return res_up; + else + res_dn := vec; + return res_dn; + end if; + end move; + + function movez(vec : std_logic_vector) return std_logic_vector is + begin + return move(vec, -vec'low); + end movez; + + function ascend(vec : std_logic_vector) return std_logic_vector is + variable res : std_logic_vector(vec'low to vec'high); + begin + res := vec; + return res; + end ascend; + + function descend(vec : std_logic_vector) return std_logic_vector is + variable res : std_logic_vector(vec'high downto vec'low); + begin + res := vec; + return res; + end descend; +end package body; |