array.cpp revision 12855:588919e0e4aa
1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19 20/***************************************************************************** 21 22 array.cpp -- 23 24 Original Author: Martin Janssen, Synopsys, Inc., 2002-02-15 25 26 *****************************************************************************/ 27 28/***************************************************************************** 29 30 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 changes you are making here. 32 33 Name, Affiliation, Date: 34 Description of Modification: 35 36 *****************************************************************************/ 37 38// array.cxx -- 39// Copyright Synopsys 1998 40// Author : Ric Hilderink 41// Created On : Wed Dec 30 11:55:50 1998 42// Status : none 43// 44 45#include <limits.h> 46#define SC_INCLUDE_FX 47#include "systemc.h" 48#include "fx_precision_double.h" 49 50// Without this, conversions use the implicit 51// operator double, which is both lossy and 52// can cause UB in certain cases. 53template <typename From> 54class converter { 55 From val; 56public: 57 converter(From val): val(val) {} 58 operator int() const { return val.to_int(); } 59 operator unsigned int() const { return val.to_uint(); } 60 operator short() const { return val.to_short(); } 61 operator unsigned short() const { return val.to_ushort(); } 62 operator long() const { return val.to_long(); } 63 operator unsigned long() const { return val.to_ulong(); } 64 operator float() const { return val.to_float(); } 65 operator double() const { return val.to_double(); } 66}; 67 68template <typename To, typename From> 69To convert(From val) { 70 return converter<From>(val); 71} 72 73 74template <typename T> 75void show(char const *const name, int i, T val) { 76 cerr << name << "[" << i << "] : " << val.to_double() << " : " << val.to_string(SC_HEX) << "\n"; 77} 78 79template <typename T, typename U> 80void test_fx(U a_mul, U b_init, U b_mul, char const *t_name, char const *u_name) 81{ 82 cerr << "--array-Inf-Inf-Inf-Inf-Inf- test_fx_" << t_name << "_" << u_name << "\n"; 83 84 T a(static_cast<U>(0)); 85 T b(b_init); 86 show("a", 0, a); 87 show("b", 0, b); 88 89 for (U i = 1; i < 4; ++i) { 90 // Be careful here. We don't want a T to ever be implicitly converted, 91 // else we have a double which cannot be safely cast, but converting early 92 // means we can be subject to implicit upcasts. That's minimized by having all 93 // of the values of type U, but if U is smaller than int it can still be 94 // implicitly upcast, ergo the outer cast. 95 a = static_cast<U>(i * i * a_mul); 96 b = static_cast<U>(convert<U>(b) * i * b_mul); 97 show("a", i, a); 98 show("b", i, b); 99 } 100} 101 102template <typename T> 103void batch_test_fx(char const *t_name, int uinit) { 104 cerr << "************** array test_fx_" << t_name << "_\n"; 105 test_fx<T, int >(1, -1, -1, t_name, "int"); 106 test_fx<T, unsigned int >(1, uinit, -1, t_name, "uint"); 107 test_fx<T, short >(1, -1, -1, t_name, "short"); 108 test_fx<T, unsigned short>(1, uinit, -1, t_name, "ushort"); 109 test_fx<T, long >(1, -1, -1, t_name, "long"); 110 test_fx<T, unsigned long >(1, uinit, -1, t_name, "ulong"); 111 test_fx<T, float >(1.123456789f, -1.987654321f, -1.789654123f, t_name, "float"); 112 test_fx<T, double>(1.123456789, -1.987654321, -1.789654123, t_name, "double"); 113} 114 115void array() { 116 batch_test_fx<sc_fxval>("float", -1); 117 batch_test_fx<sc_ufix>("ufix", -1); 118 batch_test_fx<sc_fix>("fix", -1); 119 batch_test_fx<sc_fixed<8, 5> >("fixed", 1); 120 batch_test_fx<sc_ufixed<8, 5> >("ufixed", 1); 121} 122