diff options
author | Tristan Gingold <tgingold@free.fr> | 2022-06-20 20:56:28 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2022-06-21 06:33:24 +0200 |
commit | a83d1e6682d63b99d1a83d7a73dc5079cf781b25 (patch) | |
tree | 8b13437d61f978e76594f11f483b5becd693fd7f /testsuite/gna | |
parent | 12f428f27ba4bcec645b9f904aff8b5632420ad4 (diff) | |
download | ghdl-a83d1e6682d63b99d1a83d7a73dc5079cf781b25.tar.gz ghdl-a83d1e6682d63b99d1a83d7a73dc5079cf781b25.tar.bz2 ghdl-a83d1e6682d63b99d1a83d7a73dc5079cf781b25.zip |
testsuite/gna: add a test for #2103
Diffstat (limited to 'testsuite/gna')
-rw-r--r-- | testsuite/gna/issue2103/pkg_logic_misc.vhdl | 155 | ||||
-rw-r--r-- | testsuite/gna/issue2103/pkg_math_signed.vhdl | 110 | ||||
-rw-r--r-- | testsuite/gna/issue2103/pkg_math_utils.vhdl | 250 | ||||
-rw-r--r-- | testsuite/gna/issue2103/repro.vhdl | 10 | ||||
-rw-r--r-- | testsuite/gna/issue2103/repro2.vhdl | 10 | ||||
-rw-r--r-- | testsuite/gna/issue2103/repro3.vhdl | 13 | ||||
-rw-r--r-- | testsuite/gna/issue2103/repro4.vhdl | 16 | ||||
-rw-r--r-- | testsuite/gna/issue2103/repro5.vhdl | 13 | ||||
-rwxr-xr-x | testsuite/gna/issue2103/testsuite.sh | 17 |
9 files changed, 594 insertions, 0 deletions
diff --git a/testsuite/gna/issue2103/pkg_logic_misc.vhdl b/testsuite/gna/issue2103/pkg_logic_misc.vhdl new file mode 100644 index 000000000..8a8bdba00 --- /dev/null +++ b/testsuite/gna/issue2103/pkg_logic_misc.vhdl @@ -0,0 +1,155 @@ +
------------------------------------------------------------------------------
-- ____ _____________ __ --
-- / __ \/ ____/ ___/\ \/ / _ _ _ --
-- / / / / __/ \__ \ \ / / \ / \ / \ --
-- / /_/ / /___ ___/ / / / = ( M | S | K )= --
-- /_____/_____//____/ /_/ \_/ \_/ \_/ --
-- --
------------------------------------------------------------------------------
--! @copyright Copyright 2022 DESY
--! SPDX-License-Identifier: CERN-OHL-W-2.0
------------------------------------------------------------------------------
--! @date 2022-06-07
--! @author Andrea Bellandi
--! @email andrea.bellandi@desy.de
------------------------------------------------------------------------------
--! @brief
--! Miscellaneous logic utilities
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
--!-------------------------------------------------------
--! Miscellaneous logic functions. All ported functions from
--! IEEE.std_logic_misc belongs here.
package logic_misc is
--!-------------------------------------------------------
--! f_to_std_logic:
--! Converts std_logic to boolean.
function f_to_std_logic (arg: boolean) return std_logic;
--!-------------------------------------------------------
--! f_to_boolean:
--! Converts std_logic to boolean
function f_to_boolean (arg: std_logic) return boolean;
--!-------------------------------------------------------
--! f_all_ones:
--! Checks whether all bits of **arg** are equal to '1'.
--! Equivalent to _and_reduce_.
function f_all_ones (arg: std_logic_vector) return std_logic;
--!-------------------------------------------------------
--! f_all_zeroes:
--! Checks wheter all bits of **arg** are equal to '0'.
--! Equivalent to _nor_reduce_.
function f_all_zeroes (arg: std_logic_vector) return std_logic;
--!-------------------------------------------------------
--! f_odd_ones:
--! Return '1' if an odd number of bits in **arg** are '1'.
--! Equivalent to _xor_reduce_.
function f_odd_ones (arg: std_logic_vector) return std_logic;
--!-------------------------------------------------------
--! f_even_ones:
--! Return '1' if an even number of bits in **arg** are '1'.
--! Return '1' if zero bits in **arg** are '1'.
--! Equivalent to _xnor_reduce_.
function f_even_ones (arg: std_logic_vector) return std_logic;
--!-------------------------------------------------------
--! f_odd_zeroes:
--! Return '1' if an odd number of bits in **arg** are '0'.
--! Equivalent to _xor_reduce_.
function f_odd_zeroes (arg: std_logic_vector) return std_logic;
--!-------------------------------------------------------
--! f_even_zeroes:
--! Return '1' if an even number of bits in **arg** are '0'.
--! Return '1' if zero bits in **arg** are '0'.
--! Equivalent to _xnor_reduce_.
function f_even_zeroes (arg: std_logic_vector) return std_logic;
-- vsg_off function_101
--!-------------------------------------------------------
--! or_reduce:
--! Reduction of bits in **arg** with the **or** logical operator.
--! Port of nonstandard _ieee.std_logic_misc.or_reduce_
function or_reduce (arg: std_logic_vector) return std_logic;
--!-------------------------------------------------------
--! and_reduce:
--! Reduction of bits in **arg** with the **and** logical operator.
--! Port of nonstandard _ieee.std_logic_misc.and_reduce_
function and_reduce (arg: std_logic_vector) return std_logic;
--!-------------------------------------------------------
--! xor_reduce:
--! Reduction of bits in **arg** with the **xor** logical operator.
--! Port of nonstandard _ieee.std_logic_misc.xor_reduce_
function xor_reduce (arg: std_logic_vector) return std_logic;
--!------------------------- + --! nor_reduce: + --! Negated reduction of bits in **arg** with the **or** logical operator. + --! Port of nonstandard _ieee.std_logic_misc.nor_reduce_ + + function nor_reduce (arg: std_logic_vector) return std_logic; + + --!------------------------------------------------------- + --! nand_reduce: + --! Negated reduction of bits in **arg** with the **and** logical operator. + --! Port of nonstandard _ieee.std_logic_misc.nand_reduce_ + + function nand_reduce (arg: std_logic_vector) return std_logic; + + --!------------------------------------------------------- + --! xnor_reduce: + --! Negated reduction of bits in **arg** with the **xor** logical operator. + --! Port of nonstandard _ieee.std_logic_misc.xnor_reduce_ + + function xnor_reduce (arg: std_logic_vector) return std_logic; + +-- vsg_on + +end package logic_misc; + +package body logic_misc is + + function f_to_std_logic (arg: boolean) return std_logic is + begin + + if (arg) then + return '1'; + else + return '0'; + end if; + + end function; + + function f_to_boolean (arg: std_logic) return boolean is + begin + + return arg = '1'; + + end function; + + function f_all_ones (arg: std_logic_vector) return std_logic is + + constant C_ONES : std_logic_vector(arg'length - 1 downto 0) := + ( + others => '1' + ); + + begin + + return f_to_std_logic(arg = C_ONES); + + end function; + + function f_all_zeroes (arg: std_logic_vector) return std_logic is + + constant C_ZEROES : std_logic_vector(arg'length - 1 downto 0) := + ( + others => '0' + ); + + begin + + return f_to_std_logic(arg = C_ZEROES); + + end function; + + function f_odd_ones (arg: std_logic_vector) return std_logic is + + variable var_result : std_logic := '0'; + + begin + + for i in arg'low to arg'high loop + + var_result := var_result xor arg(i); + + end loop; + + return var_result; + + end function; + + function f_even_ones (arg: std_logic_vector) return std_logic is + begin + + return not f_odd_ones(arg); + + end function; + + function f_odd_zeroes (arg: std_logic_vector) return std_logic is + begin + + return f_odd_ones(not arg); + + end function; + + function f_even_zeroes (arg: std_logic_vector) return std_logic is + begin + + return not f_odd_zeroes(arg); + + end function; + + -- vsg_off function_101 + + function or_reduce (arg: std_logic_vector) return std_logic is + begin + + return not f_all_zeroes(arg); + + end function; + + function and_reduce (arg: std_logic_vector) return std_logic is + begin + + return f_all_ones(arg); + + end function; + + function xor_reduce (arg: std_logic_vector) return std_logic is + begin + + return f_odd_ones(arg); + + end function; + + function nor_reduce (arg: std_logic_vector) return std_logic is + begin + + return f_all_zeroes(arg); + + end function; + + function nand_reduce (arg: std_logic_vector) return std_logic is + begin + + return not f_all_ones(arg); + + end function; + + function xnor_reduce (arg: std_logic_vector) return std_logic is + begin + + return f_even_ones(arg); + + end function; + +-- vsg_on + +end package body logic_misc; diff --git a/testsuite/gna/issue2103/pkg_math_signed.vhdl b/testsuite/gna/issue2103/pkg_math_signed.vhdl new file mode 100644 index 000000000..8dedeb43c --- /dev/null +++ b/testsuite/gna/issue2103/pkg_math_signed.vhdl @@ -0,0 +1,110 @@ + +------------------------------------------------------------------------------ +-- ____ _____________ __ -- +-- / __ \/ ____/ ___/\ \/ / _ _ _ -- +-- / / / / __/ \__ \ \ / / \ / \ / \ -- +-- / /_/ / /___ ___/ / / / = ( M | S | K )= -- +-- /_____/_____//____/ /_/ \_/ \_/ \_/ -- +-- -- +------------------------------------------------------------------------------ +--! @copyright Copyright 2020-2022 DESY +--! SPDX-License-Identifier: CERN-OHL-W-2.0 +------------------------------------------------------------------------------ +--! @date 2020-10-02/2022-04-01 +--! @author Lukasz Butkowski <lukasz.butkowski@desy.de> +--! @author Michael Buechler <michael.buechler@desy.de> +------------------------------------------------------------------------------ +--! @brief +--! Provides math function/procedures with signed signals +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.math_utils.all; +use work.logic_misc.all; + +package math_signed is + + --! Saturate *arg* to the maximum or minimum representable value depending on + --! sat + function f_saturate (arg : signed; sat : t_saturation) return signed; + + --! Resize with saturation protection + function f_resize_sat (arg : signed; length : positive) return signed; + + --! Resize with saturation protection and saturation flag + --! Like the <<f_resize_sat>> function but also sets an overflow bit. + --! To be able to combine this with another preceding operation like shift_right + --! in a process, the argument 'arg' must be a variable instead of a signal. + procedure prd_resize_sat ( + signal arg : in signed; + constant length : in positive; + signal result : out signed; + signal sat : out t_saturation + ); + +end package math_signed; + +--****************************************************************************** + +package body math_signed is + + function f_saturate (arg : signed; sat : t_saturation) return signed is + begin + + if (sat = ST_SAT_OVERFLOWN) then + return f_max_val_of(arg); + elsif (sat = ST_SAT_UNDERFLOWN) then + return f_min_val_of(arg); + else + return arg; + end if; + + end function f_saturate; + + function f_resize_sat (arg : signed; length : natural) return signed is + + variable var_result : signed(length - 1 downto 0); + + begin + + prd_resize_sat(arg => arg, length => length, result => var_result); + return var_result; + + end function; + + procedure prd_resize_sat ( + signal arg : in signed; + constant length : in positive; + signal result : out signed; + signal sat : out t_saturation + ) is + + variable var_sat : t_saturation; + + begin + + if (length >= arg'length) then + var_sat := ST_SAT_OK; + else + -- check overflow saturation + if (arg(arg'high) = '0' and + f_all_zeroes(arg(arg'high-1 downto length - 1)) = '0') then + var_sat := ST_SAT_OVERFLOWN; + -- check underflow saturation + elsif (arg(arg'high) = '1' and + f_all_ones(arg(arg'high-1 downto length - 1)) = '0') then + var_sat := ST_SAT_UNDERFLOWN; + else + var_sat := ST_SAT_OK; + end if; + result <= f_saturate(resize(arg, length), var_sat); + sat <= var_sat; + end if; + + end procedure prd_resize_sat; + +end package body math_signed; diff --git a/testsuite/gna/issue2103/pkg_math_utils.vhdl b/testsuite/gna/issue2103/pkg_math_utils.vhdl new file mode 100644 index 000000000..4d3804082 --- /dev/null +++ b/testsuite/gna/issue2103/pkg_math_utils.vhdl @@ -0,0 +1,250 @@ +------------------------------------------------------------------------------ +-- ____ _____________ __ -- +-- / __ \/ ____/ ___/\ \/ / _ _ _ -- +-- / / / / __/ \__ \ \ / / \ / \ / \ -- +-- / /_/ / /___ ___/ / / / = ( M | S | K )= -- +-- /_____/_____//____/ /_/ \_/ \_/ \_/ -- +-- -- +------------------------------------------------------------------------------ +--! @copyright Copyright 2022 DESY +--! SPDX-License-Identifier: CERN-OHL-W-2.0 +------------------------------------------------------------------------------ +--! @date 2022-04-01 +--! @author Michael Buechler <michael.buechler@desy.de> +--! @author Lukasz Butkowski <lukasz.butkowski@desy.de> +------------------------------------------------------------------------------ +--! @brief +--! Math utilities +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.math_real.all; + +--! Package of mathematical utilities and support functions +package math_utils is + + --! Saturation status after an operation. + type t_saturation is (ST_SAT_OK, ST_SAT_OVERFLOWN, ST_SAT_UNDERFLOWN); + + --! The encoding for _t_staturation_ is + --! + --! * ST_SAT_OK = "00" (No saturation) + --! * ST_SAT_OVERFLOWN = "10" (Operation has overflown) + --! * ST_SAT_UNDERFLOWN = "01" (Operation has underflown) + attribute enum_encoding : string; + attribute enum_encoding of t_saturation : type is "00 10 01"; + + --! f_bit_length: + --! Comparable to Python's int.bit_length(), + --! but when arg is negative, calculate for two's complement. + --! Attention: returns 1 for argument -1. + --! When arg is zero, return 0. + function f_bit_length (arg: integer) return integer; + + --! f_unsigned_length: + --! Calculates the minimum unsigned signal length to store **arg**, + --! When arg is zero, return 0. + function f_unsigned_length (arg: natural) return natural; + + --! Calculates the minimum signed signal length to store *arg*, + --! When arg is zero, return 0. + function f_signed_length (arg: integer) return integer; + + --! f_maximum: + --! Porting of 'maximum' from VHDL 08' not present in the + --! 93' standard. + function f_maximum (a, b: integer) return integer; + + --! f_minimum: + --! Porting of 'minimum' from VHDL 08' not present in the + --! 93' standard + function f_minimum (a, b: integer) return integer; + + --! f_max_val_for_length: + --! Returns the maximum value representable by a numeric type of length + --! _length_ and sign _sign_. + function f_max_val_for_length (length: natural; sign : boolean) return integer; + + function f_max_val_of (arg: unsigned) return unsigned; + + --! f_max_val_of: + --! Returns the maximum value representable by a numeric type. + --! Signed and unsigned version. + function f_max_val_of (arg: signed) return signed; + + --! f_max_val_for_length: + --! Returns the maximum value representable by a numeric type of length + --! _length_ and sign _sign_. + function f_min_val_for_length (length: natural; sign : boolean) return integer; + + function f_min_val_of (arg: unsigned) return unsigned; + + --! f_min_val_of: + --! Returns the minimum value representable by a numeric type. + --! Signed and unsigned version. + function f_min_val_of (arg: signed) return signed; + + function f_is_max (arg: unsigned) return boolean; + + --! f_is_max: + --! Checks whether a signal is at its maximum value. + --! Signed and unsigned version. + function f_is_max (arg: signed) return boolean; + + function f_is_min (arg: unsigned) return boolean; + + --! f_is_min: + --! Checks whether a signal is at its minimum value. + --! Signed and unsigned version. + function f_is_min (arg: signed) return boolean; + +end package math_utils; + +--****************************************************************************** + +--****************************************************************************** + +package body math_utils is + + function f_bit_length (arg: integer) return integer is + begin + + if (arg = 0) then + return 0; + elsif (arg > 0) then + return integer(ceil(log2(real(arg + 1)))); + else + return integer(ceil(log2(-real(arg)))) + 1; + end if; + + end function; + + function f_unsigned_length (arg: natural) return natural is + begin + + return natural(f_bit_length(integer(arg))); + + end function; + + function f_signed_length (arg: integer) return integer is + begin + + if (arg >= 0) then + return f_bit_length(arg) + 1; + else + return f_bit_length(arg); + end if; + + end function; + + function f_maximum (a, b: integer) return integer is + begin + + if (a > b) then + return a; + else + return b; + end if; + + end function; + + function f_minimum (a, b: integer) return integer is + begin + + if (a < b) then + return a; + else + return b; + end if; + + end function; + + function f_max_val_for_length (length: natural; sign : boolean) return integer is + + constant C_SMAX : integer := (2 ** (length - 1)) - 1; + constant C_UMAX : integer := (2 ** length) - 1; + + begin + + if (sign) then + return C_SMAX; + else + return C_UMAX; + end if; + + end function; + + function f_max_val_of (arg: unsigned) return unsigned is + begin + + return to_unsigned(f_max_val_for_length(arg'length, false), arg'length); + + end function; + + function f_max_val_of (arg: signed) return signed is + begin + + return to_signed(f_max_val_for_length(arg'length, true), arg'length); + + end function; + + function f_min_val_for_length (length: natural; sign : boolean) return integer is + + constant C_SMIN : integer := - (2 ** (length - 1)); + constant C_UMIN : integer := 0; + + begin + + if (sign) then + return C_SMIN; + else + return C_UMIN; + end if; + + end function; + + function f_min_val_of (arg: unsigned) return unsigned is + begin + + return to_unsigned(f_min_val_for_length(arg'length, false), arg'length); + + end function; + + function f_min_val_of (arg: signed) return signed is + begin + + return to_signed(f_min_val_for_length(arg'length, true), arg'length); + + end function; + + function f_is_max (arg: unsigned) return boolean is + begin + + return arg = f_max_val_of(arg); + + end; + + function f_is_max (arg: signed) return boolean is + begin + + return arg = f_max_val_of(arg); + + end; + + function f_is_min (arg: unsigned) return boolean is + begin + + return arg = f_min_val_of(arg); + + end; + + function f_is_min (arg: signed) return boolean is + begin + + return arg = f_min_val_of(arg); + + end; + +end package body math_utils; diff --git a/testsuite/gna/issue2103/repro.vhdl b/testsuite/gna/issue2103/repro.vhdl new file mode 100644 index 000000000..0393ad2c5 --- /dev/null +++ b/testsuite/gna/issue2103/repro.vhdl @@ -0,0 +1,10 @@ +package repro is + function f (arg : bit; length : natural) return bit; +end repro; + +package body repro is + function f (arg : bit; length : positive) return bit is + begin + return arg; + end; +end repro; diff --git a/testsuite/gna/issue2103/repro2.vhdl b/testsuite/gna/issue2103/repro2.vhdl new file mode 100644 index 000000000..7bbeefe10 --- /dev/null +++ b/testsuite/gna/issue2103/repro2.vhdl @@ -0,0 +1,10 @@ +package repro2 is + function f (arg : bit; length : string) return bit; +end repro2; + +package body repro2 is + function f (arg : bit; length : bit_vector) return bit is + begin + return arg; + end; +end repro2; diff --git a/testsuite/gna/issue2103/repro3.vhdl b/testsuite/gna/issue2103/repro3.vhdl new file mode 100644 index 000000000..9150c27eb --- /dev/null +++ b/testsuite/gna/issue2103/repro3.vhdl @@ -0,0 +1,13 @@ +package repro3 is + constant a1 : natural := 1; + constant a2 : natural := 1; + + function f (arg : bit; length : string (1 to a1)) return bit; +end; + +package body repro3 is + function f (arg : bit; length : string (1 to a2)) return bit is + begin + return arg; + end; +end; diff --git a/testsuite/gna/issue2103/repro4.vhdl b/testsuite/gna/issue2103/repro4.vhdl new file mode 100644 index 000000000..bc5c6048d --- /dev/null +++ b/testsuite/gna/issue2103/repro4.vhdl @@ -0,0 +1,16 @@ +package repro4 is + constant a1 : natural := 1; + constant a2 : natural := 1; + + alias b1 : natural is a1; + alias b2 : natural is a2; + + function f (arg : bit; length : string (1 to b1)) return bit; +end; + +package body repro4 is + function f (arg : bit; length : string (1 to b2)) return bit is + begin + return arg; + end; +end; diff --git a/testsuite/gna/issue2103/repro5.vhdl b/testsuite/gna/issue2103/repro5.vhdl new file mode 100644 index 000000000..9eca4a391 --- /dev/null +++ b/testsuite/gna/issue2103/repro5.vhdl @@ -0,0 +1,13 @@ +package repro4 is + alias n1 is natural; + alias n2 is natural; + + function f (arg : bit; length : n1) return bit; +end; + +package body repro4 is + function f (arg : bit; length : n2) return bit is + begin + return arg; + end; +end; diff --git a/testsuite/gna/issue2103/testsuite.sh b/testsuite/gna/issue2103/testsuite.sh new file mode 100755 index 000000000..7bc24fd37 --- /dev/null +++ b/testsuite/gna/issue2103/testsuite.sh @@ -0,0 +1,17 @@ +#! /bin/sh + +. ../../testenv.sh + +analyze_failure repro.vhdl +analyze_failure repro2.vhdl +analyze_failure repro3.vhdl +analyze_failure repro4.vhdl +analyze_failure repro5.vhdl + +analyze pkg_logic_misc.vhdl +analyze pkg_math_utils.vhdl +analyze_failure pkg_math_signed.vhdl + +clean + +echo "Test successful" |