------------------------------------------------------------------------ -- Copyright 1996 by VHDL International. All rights reserved. -- -- This source file is considered to be an aid to check implementations of the -- the IEEE standard 1076.2 and may be distributed without restriction -- as long as it is not sold or distributed for profit. -- -- THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR -- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -- DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS, IEEE, OR VHDL -- INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- -- Title: Testbench for Standard VHDL MATH_REAL Package (PAR 1076.2) -- -- Developers: Members of the VHDL Mathematical Packages Working Group -- Code was written by Charles Swart (cswart@analogy.com) -- Data was supplied by many people. -- -- Purpose: An aid to check implementations of the IEEE MATH_REAL -- package, Standard 1076.2. -- -- -- Library: This can be compiled into any convient library. -- -- Limitation: Only values in the minimum required range may be tested -- to keep this test portable. -- That range is -1.0E38 to +1.0E38 inclusive. -- -- Notes: -- This file consists of an entity REAL_TESTS and a single -- architecture, ARCH. It references packages MATH_REAL -- and TEXTIO. -- -- To run this set of tests, choose an appropriate value for -- the constant FULL_RESULTS, compile and simulate for -- about 100 ns. -- -- Each process begins with a WAIT for a unique time interval. -- The purpose of this is to impose an order of evaluation -- on the tests to ease data comparisons between different -- implementations. -- -- The data was optained from a number of sources and is not -- guaranteed to be accurate. Many results are highly sensitive -- on the character to real conversion, which is often -- inaccurate in the last few places. -- -- Also, the tests are not comprehensive. -- -- The tests report the number of decimal digits of accuracy. -- There are several problems with this measurement. -- In some cases the number reported is one too many. -- The measurement also, probably correctly, reports that -- 5.0 and 4.99999 are close. -- A more fundamental problem involves values near zero. -- The test can (correctly) report 0 digits accuracy for small -- values. -- However, the results might still be perfectly reasonable. -- --- Suggestions, improvements and additional test points -- are welcome. -- -- ------------------------------------------------------------------------- -- Modification history: -- ------------------------------------------------------------------------- -- v0.91 | 05/01/96 | pre-release version ------------------------------------------------------------- use WORK.MATH_REAL.all; use STD.TEXTIO.all; entity REAL_TESTS is END REAL_TESTS; architecture ARCH of REAL_TESTS is type REAL_VECTOR is ARRAY( POSITIVE range <>) of REAL; type INT_VECTOR is ARRAY( POSITIVE range <>) of INTEGER; constant FULL_RESULTS: BOOLEAN := FALSE; -- TRUE for full results, FALSE for summary constant MAX_DIGITS: INTEGER := 60; -- large value to represent exact agreement constant NEAR_ZERO: REAL := 1.0E-07; -- values less than this are considered zero function COMPARE(EXPECTED: REAL; RESULT: REAL) return INTEGER is variable DENOMINATOR: REAL; variable TEMP1: REAL; variable EXPECTED1: REAL := EXPECTED; begin if EXPECTED1=RESULT then return MAX_DIGITS; end if; --This is a kludge to get more reasonable results for values near zero. --The basic problem is that small representational errors may cause the --computed result to be more accurate than the "correct" expected result if ((ABS(EXPECTED1) 0.0 then return 0; end if; return INTEGER(CEIL(-TEMP1)); end COMPARE; procedure PRINT_RESULTS(FUNC_NAME:STRING; ARG1:REAL_VECTOR; RESULTS: REAL_VECTOR; CORRECT_ANSWERS:REAL_VECTOR; ACCURACY:INT_VECTOR; FULL_RESULTS: BOOLEAN) is variable WORST_ACCURACY: INTEGER := ACCURACY(1); variable OUTLINE: LINE; begin if(FULL_RESULTS) then --write out header WRITE(OUTLINE,FUNC_NAME,LEFT,10); WRITE(OUTLINE,STRING'("argument"),LEFT,25); WRITE(OUTLINE,STRING'("result"),LEFT,25); WRITE(OUTLINE,STRING'("correct"),LEFT,25); WRITE(OUTLINE,STRING'("digits")); WRITELINE(OUTPUT,OUTLINE); --write out each value for I in 1 to ARG1'LENGTH loop WRITE(OUTLINE,STRING'(" ")); WRITE(OUTLINE,ARG1(I),LEFT,25); WRITE(OUTLINE,RESULTS(I),LEFT,25); WRITE(OUTLINE,CORRECT_ANSWERS(I),LEFT,25); WRITE(OUTLINE,ACCURACY(I),RIGHT,2); WRITELINE(OUTPUT,OUTLINE); end loop; end if; --update accuracy for I in 1 to ACCURACY'LENGTH loop if ACCURACY(I) < WORST_ACCURACY then WORST_ACCURACY := ACCURACY(I); end if; end loop; --in all cases print summary information WRITE(OUTLINE,FUNC_NAME); WRITE(OUTLINE,STRING'(" has worst case accuracy of ")); WRITE(OUTLINE,WORST_ACCURACY); WRITE(OUTLINE,STRING'(" digits.")); WRITELINE(OUTPUT,OUTLINE); --print blank line WRITELINE(OUTPUT,OUTLINE); end PRINT_RESULTS; procedure PRINT_RESULTS(FUNC_NAME:STRING; ARG1:REAL_VECTOR; ARG2:REAL_VECTOR; RESULTS: REAL_VECTOR; CORRECT_ANSWERS:REAL_VECTOR; ACCURACY:INT_VECTOR; FULL_RESULTS: BOOLEAN) is variable WORST_ACCURACY: INTEGER := ACCURACY(1); variable OUTLINE: LINE; begin if(FULL_RESULTS) then --write out header WRITE(OUTLINE,FUNC_NAME,LEFT,10); WRITE(OUTLINE,STRING'("argument1"),LEFT,25); WRITE(OUTLINE,STRING'("argument2"),LEFT,25); WRITE(OUTLINE,STRING'("result"),LEFT,25); WRITE(OUTLINE,STRING'("correct"),LEFT,25); WRITE(OUTLINE,STRING'("digits")); WRITELINE(OUTPUT,OUTLINE); --write out each value for I in 1 to ARG1'LENGTH loop WRITE(OUTLINE,STRING'(" ")); WRITE(OUTLINE,ARG1(I),LEFT,25); WRITE(OUTLINE,ARG2(I),LEFT,25); WRITE(OUTLINE,RESULTS(I),LEFT,25); WRITE(OUTLINE,CORRECT_ANSWERS(I),LEFT,25); WRITE(OUTLINE,ACCURACY(I),RIGHT,2); WRITELINE(OUTPUT,OUTLINE); end loop; end if; --update accuracy for I in 1 to ACCURACY'LENGTH loop if ACCURACY(I)