From f0e742418639c5a3afd58dd601b6dc6b31795d77 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Sun, 21 May 2017 18:37:49 +0200 Subject: Add testcase for #349 --- testsuite/gna/issue349/ResolutionPkg.vhd | 392 ++++++++++++++++++++++++++++++ testsuite/gna/issue349/repro.vhdl | 30 +++ testsuite/gna/issue349/resolution-tb.vhdl | 9 + testsuite/gna/issue349/testsuite.sh | 16 ++ 4 files changed, 447 insertions(+) create mode 100644 testsuite/gna/issue349/ResolutionPkg.vhd create mode 100644 testsuite/gna/issue349/repro.vhdl create mode 100644 testsuite/gna/issue349/resolution-tb.vhdl create mode 100755 testsuite/gna/issue349/testsuite.sh (limited to 'testsuite') diff --git a/testsuite/gna/issue349/ResolutionPkg.vhd b/testsuite/gna/issue349/ResolutionPkg.vhd new file mode 100644 index 000000000..137b8af61 --- /dev/null +++ b/testsuite/gna/issue349/ResolutionPkg.vhd @@ -0,0 +1,392 @@ +-- +-- File Name: ResolutionPkg.vhd +-- Design Unit Name: ResolutionPkg +-- Revision: STANDARD VERSION +-- +-- Maintainer: Jim Lewis email: jim@SynthWorks.com +-- Contributor(s): +-- Jim Lewis email: jim@SynthWorks.com +-- +-- Package Defines +-- resolved resolution functions for integer, real, and time +-- types resolved_integer, resolved_real, resolved_time +-- +-- Developed for: +-- SynthWorks Design Inc. +-- VHDL Training Classes +-- 11898 SW 128th Ave. Tigard, Or 97223 +-- http://www.SynthWorks.com +-- +-- Revision History: +-- Date Version Description +-- 09/2006: 0.1 Initial revision +-- Numerous revisions for VHDL Testbenches and Verification +-- 02/2009: 1.0 VHDL-2008 STANDARD VERSION +-- 05/2015 2015.05 Added Alerts +-- -- Replaced Alerts with asserts as alerts are illegal in pure functions +-- 11/2016 2016.11 Removed Asserts as they are not working as intended. +-- See ResolutionPkg_debug as it uses Alerts to correctly detect errors +-- +-- +-- Copyright (c) 2005 - 2016 by SynthWorks Design Inc. All rights reserved. +-- +-- Verbatim copies of this source file may be used and +-- distributed without restriction. +-- +-- This source file may be modified and distributed under +-- the terms of the ARTISTIC License as published by +-- The Perl Foundation; either version 2.0 of the License, +-- or (at your option) any later version. +-- +-- This source 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 Artistic License for details. +-- +-- You should have received a copy of the license with this source. +-- If not download it from, +-- http://www.perlfoundation.org/artistic_license_2_0 +-- + +library ieee ; +use ieee.std_logic_1164.all ; +use ieee.numeric_std.all ; + +--library osvvm ; +--use osvvm.AlertLogPkg.all ; + +package ResolutionPkg is + constant MULTIPLE_DRIVER_SEVERITY : severity_level := ERROR ; + +-- +-- Note that not all simulators support resolution functions of the form: +-- subtype std_logic_vector_max is (resolved_max) std_ulogic_vector ; +-- +-- Hence, types of the form are offered as a temporary workaround until they do: +-- std_logic_vector_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008 +-- + + -- resolved_max + -- return maximum value. + -- No initializations required on ports, default of type'left is ok + function resolved_max ( s : std_ulogic_vector) return std_ulogic ; + subtype std_logic_max is resolved_max std_ulogic ; + subtype std_logic_vector_max is (resolved_max) std_ulogic_vector ; + type std_logic_vector_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008 + + subtype unsigned_max is (resolved_max) unresolved_unsigned ; + type unsigned_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008 + subtype signed_max is (resolved_max) unresolved_signed ; + type signed_max_c is array (natural range <>) of std_logic_max ; -- for non VHDL-2008 + + function resolved_max ( s : bit_vector) return bit ; + subtype bit_max is resolved_max bit ; + subtype bit_vector_max is (resolved_max) bit_vector ; + type bit_vector_max_c is array (natural range <>) of bit_max ; -- for non VHDL-2008 + + function resolved_max ( s : integer_vector ) return integer ; + subtype integer_max is resolved_max integer ; + subtype integer_vector_max is (resolved_max) integer_vector ; + type integer_vector_max_c is array (natural range <>) of integer_max ; -- for non VHDL-2008 + + function resolved_max ( s : time_vector ) return time ; + subtype time_max is resolved_max time ; + subtype time_vector_max is (resolved_max) time_vector ; + type time_vector_max_c is array (natural range <>) of time_max ; -- for non VHDL-2008 + + function resolved_max ( s : real_vector ) return real ; + subtype real_max is resolved_max real ; + subtype real_vector_max is (resolved_max) real_vector ; + type real_vector_max_c is array (natural range <>) of real_max ; -- for non VHDL-2008 + + function resolved_max ( s : string) return character ; + subtype character_max is resolved_max character ; + subtype string_max is (resolved_max) string ; + type string_max_c is array (positive range <>) of character_max ; -- for non VHDL-2008 + + function resolved_max ( s : boolean_vector) return boolean ; + subtype boolean_max is resolved_max boolean ; + subtype boolean_vector_max is (resolved_max) boolean_vector ; + type boolean_vector_max_c is array (natural range <>) of boolean_max ; -- for non VHDL-2008 + + + -- return sum of values that /= type'left + -- No initializations required on ports, default of type'left is ok + function resolved_sum ( s : integer_vector ) return integer ; + subtype integer_sum is resolved_sum integer ; + subtype integer_vector_sum is (resolved_sum) integer_vector ; + type integer_vector_sum_c is array (natural range <>) of integer_sum ; -- for non VHDL-2008 + + function resolved_sum ( s : time_vector ) return time ; + subtype time_sum is resolved_sum time ; + subtype time_vector_sum is (resolved_sum) time_vector ; + type time_vector_sum_c is array (natural range <>) of time_sum ; -- for non VHDL-2008 + + function resolved_sum ( s : real_vector ) return real ; + subtype real_sum is resolved_sum real ; + subtype real_vector_sum is (resolved_sum) real_vector ; + type real_vector_sum_c is array (natural range <>) of real_sum ; -- for non VHDL-2008 + + + -- resolved_weak + -- Special just for std_ulogic + -- No initializations required on ports, default of type'left is ok + function resolved_weak (s : std_ulogic_vector) return std_ulogic ; -- no init, type'left + subtype std_logic_weak is resolved_weak std_ulogic ; + subtype std_logic_vector_weak is (resolved_weak) std_ulogic_vector ; + + + -- legacy stuff + -- requires ports to be initialized to 0 in the appropriate type. + function resolved ( s : integer_vector ) return integer ; + subtype resolved_integer is resolved integer ; + + function resolved ( s : time_vector ) return time ; + subtype resolved_time is resolved time ; + + function resolved ( s : real_vector ) return real ; + subtype resolved_real is resolved real ; + + function resolved (s : string) return character ; -- same as resolved_max + subtype resolved_character is resolved character ; + -- subtype resolved_string is (resolved) string ; -- subtype will replace type later + type resolved_string is array (positive range <>) of resolved_character; -- will change to subtype -- assert but no init + + function resolved ( s : boolean_vector) return boolean ; --same as resolved_max + subtype resolved_boolean is resolved boolean ; + +end package ResolutionPkg ; +package body ResolutionPkg is + + -- resolved_max + -- return maximum value. Assert FAILURE if more than 1 /= type'left + -- No initializations required on ports, default of type'left is ok + + -- Optimized version is just the following: + -- ------------------------------------------------------------ + -- function resolved_max ( s : ) return is + -- ------------------------------------------------------------ + -- begin + -- return maximum(s) ; + -- end function resolved_max ; + + ------------------------------------------------------------ + function resolved_max (s : std_ulogic_vector) return std_ulogic is + ------------------------------------------------------------ + begin + return maximum(s) ; + end function resolved_max ; + + ------------------------------------------------------------ + function resolved_max ( s : bit_vector ) return bit is + ------------------------------------------------------------ + begin + return maximum(s) ; + end function resolved_max ; + + ------------------------------------------------------------ + function resolved_max ( s : integer_vector ) return integer is + ------------------------------------------------------------ + begin + return maximum(s) ; + end function resolved_max ; + + ------------------------------------------------------------ + function resolved_max ( s : time_vector ) return time is + ------------------------------------------------------------ + begin + return maximum(s) ; + end function resolved_max ; + + ------------------------------------------------------------ + function resolved_max ( s : real_vector ) return real is + ------------------------------------------------------------ + begin + return maximum(s) ; + end function resolved_max ; + + ------------------------------------------------------------ + function resolved_max ( s : string ) return character is + ------------------------------------------------------------ + begin + return maximum(s) ; + end function resolved_max ; + + ------------------------------------------------------------ + function resolved_max ( s : boolean_vector) return boolean is + ------------------------------------------------------------ + begin + return maximum(s) ; + end function resolved_max ; + + + -- resolved_sum - appropriate for numeric types + -- return sum of values that /= type'left + -- No initializations required on ports, default of type'left is ok + ------------------------------------------------------------ + function resolved_sum ( s : integer_vector ) return integer is + ------------------------------------------------------------ + variable result : integer := 0 ; + begin + for i in s'RANGE loop + if s(i) /= integer'left then + result := s(i) + result; + end if ; + end loop ; + return result ; + end function resolved_sum ; + + ------------------------------------------------------------ + function resolved_sum ( s : time_vector ) return time is + ------------------------------------------------------------ + variable result : time := 0 sec ; + begin + for i in s'RANGE loop + if s(i) /= time'left then + result := s(i) + result; + end if ; + end loop ; + return result ; + end function resolved_sum ; + + ------------------------------------------------------------ + function resolved_sum ( s : real_vector ) return real is + ------------------------------------------------------------ + variable result : real := 0.0 ; + begin + for i in s'RANGE loop + if s(i) /= real'left then + result := s(i) + result; + end if ; + end loop ; + return result ; + end function resolved_sum ; + + + -- resolved_weak + -- Special just for std_ulogic + -- No initializations required on ports, default of type'left is ok + type stdlogic_table is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC; + + constant weak_resolution_table : stdlogic_table := ( + -- Resolution order: Z < U < W < X < - < L < H < 0 < 1 + -- --------------------------------------------------------- + -- | U X 0 1 Z W L H - | | + -- --------------------------------------------------------- + ('U', 'X', '0', '1', 'U', 'W', 'L', 'H', '-'), -- | U | + ('X', 'X', '0', '1', 'X', 'X', 'L', 'H', '-'), -- | X | + ('0', '0', '0', '1', '0', '0', '0', '0', '0'), -- | 0 | + ('1', '1', '1', '1', '1', '1', '1', '1', '1'), -- | 1 | + ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'), -- | Z | + ('W', 'X', '0', '1', 'W', 'W', 'L', 'H', '-'), -- | W | + ('L', 'L', '0', '1', 'L', 'L', 'L', 'H', 'L'), -- | L | + ('H', 'H', '0', '1', 'H', 'H', 'W', 'H', 'H'), -- | H | + ('-', '-', '0', '1', '-', '-', 'L', 'H', '-') -- | - | + ); + + ------------------------------------------------------------ + function resolved_weak (s : std_ulogic_vector) return std_ulogic is + ------------------------------------------------------------ + variable result : std_ulogic := 'Z' ; + begin + for i in s'RANGE loop + result := weak_resolution_table(result, s(i)) ; + end loop ; + return result ; + end function resolved_weak ; + + + -- legacy stuff. + -- requires ports to be initialized to 0 in the appropriate type. + + ------------------------------------------------------------ + function resolved ( s : integer_vector ) return integer is + -- requires interface to be initialized to 0 + ------------------------------------------------------------ + variable result : integer := 0 ; + variable failed : boolean := FALSE ; + begin + for i in s'RANGE loop + if s(i) /= 0 then + failed := failed or (result /= 0) ; + result := maximum(s(i),result); + end if ; + end loop ; + assert not failed report "ResolutionPkg.resolved: multiple drivers on integer" severity MULTIPLE_DRIVER_SEVERITY ; + -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on integer") ; + return result ; + end function resolved ; + + ------------------------------------------------------------ + function resolved ( s : time_vector ) return time is + -- requires interface to be initialized to 0 ns + ------------------------------------------------------------ + variable result : time := 0 ns ; + variable failed : boolean := FALSE ; + begin + for i in s'RANGE loop + if s(i) > 0 ns then + failed := failed or (result /= 0 ns) ; + result := maximum(s(i),result); + end if ; + end loop ; + assert not failed report "ResolutionPkg.resolved: multiple drivers on time" severity MULTIPLE_DRIVER_SEVERITY ; + -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on time") ; + return result ; + end function resolved ; + + ------------------------------------------------------------ + function resolved ( s : real_vector ) return real is + -- requires interface to be initialized to 0.0 + ------------------------------------------------------------ + variable result : real := 0.0 ; + variable failed : boolean := FALSE ; + begin + for i in s'RANGE loop + if s(i) /= 0.0 then + failed := failed or (result /= 0.0) ; + result := maximum(s(i),result); + end if ; + end loop ; + assert not failed report "ResolutionPkg.resolved: multiple drivers on real" severity MULTIPLE_DRIVER_SEVERITY ; + -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on real") ; + return result ; + end function resolved ; + + ------------------------------------------------------------ + function resolved (s : string) return character is + -- same as resolved_max + ------------------------------------------------------------ + variable result : character := NUL ; + variable failed : boolean := FALSE ; + begin + for i in s'RANGE loop + if s(i) /= NUL then + failed := failed or (result /= NUL) ; + result := maximum(result, s(i)) ; + end if ; + end loop ; + assert not failed report "ResolutionPkg.resolved: multiple drivers on character" severity MULTIPLE_DRIVER_SEVERITY ; + -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on character") ; + return result ; + end function resolved ; + + ------------------------------------------------------------ + function resolved ( s : boolean_vector) return boolean is + -- same as resolved_max + ------------------------------------------------------------ + variable result : boolean := FALSE ; + variable failed : boolean := FALSE ; + begin + for i in s'RANGE loop + if s(i) then + failed := failed or result ; + result := TRUE ; + end if ; + end loop ; + assert not failed report "ResolutionPkg.resolved: multiple drivers on boolean" severity MULTIPLE_DRIVER_SEVERITY ; + -- AlertIf(OSVVM_ALERTLOG_ID, failed, "ResolutionPkg.resolved: multiple drivers on boolean") ; + return result ; + end function resolved ; + +end package body ResolutionPkg ; diff --git a/testsuite/gna/issue349/repro.vhdl b/testsuite/gna/issue349/repro.vhdl new file mode 100644 index 000000000..bde0491f0 --- /dev/null +++ b/testsuite/gna/issue349/repro.vhdl @@ -0,0 +1,30 @@ +package ReproPkg is + function resolved_max ( s : time_vector ) return time ; + subtype time_vector_max is (resolved_max) time_vector ; + + subtype integer2 is integer; + + function resolved_max ( s : integer_vector ) return integer ; + subtype integer_vector_max is (resolved_max) integer_vector ; +end package ReproPkg ; + +package body ReproPkg is + function resolved_max ( s : time_vector ) return time is + begin + return maximum(s) ; + end function resolved_max ; + + function resolved_max ( s : integer_vector ) return integer is + begin + return maximum(s) ; + end function resolved_max ; +end package body ReproPkg ; + +use work.ReproPkg.all; + +entity repro is +end; + +architecture none of repro is +begin +end none; diff --git a/testsuite/gna/issue349/resolution-tb.vhdl b/testsuite/gna/issue349/resolution-tb.vhdl new file mode 100644 index 000000000..72ab768ff --- /dev/null +++ b/testsuite/gna/issue349/resolution-tb.vhdl @@ -0,0 +1,9 @@ +--library osvvm; +use work.ResolutionPkg.all; + +entity Resolution_TB is +end Resolution_TB; + +architecture none of Resolution_TB is +begin +end none; diff --git a/testsuite/gna/issue349/testsuite.sh b/testsuite/gna/issue349/testsuite.sh new file mode 100755 index 000000000..3102a0939 --- /dev/null +++ b/testsuite/gna/issue349/testsuite.sh @@ -0,0 +1,16 @@ +#! /bin/sh + +. ../../testenv.sh + +export GHDL_STD_FLAGS=--std=08 +analyze repro.vhdl +elab_simulate repro + + +#analyze ResolutionPkg.vhd +#analyze resolution-tb.vhdl +#elab_simulate resolution_tb + +clean + +echo "Test successful" -- cgit v1.2.3