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 49// Without this, conversions use the implicit 50// operator double, which is both lossy and 51// can cause UB in certain cases. 52template <typename From> 53class converter { 54 From val; 55public: 56 converter(From val): val(val) {} 57 operator int() const { return val.to_int(); } 58 operator unsigned int() const { return val.to_uint(); } 59 operator short() const { return val.to_short(); } 60 operator unsigned short() const { return val.to_ushort(); } 61 operator long() const { return val.to_long(); } 62 operator unsigned long() const { return val.to_ulong(); } 63 operator float() const { return val.to_float(); } 64 operator double() const { return val.to_double(); } 65}; 66 67template <typename To, typename From> 68To convert(From val) { 69 return converter<From>(val); 70} 71 72 73template <typename T> 74void show(char const *const name, int i, T val) { 75 cerr << name << "[" << i << "] : " << val.to_double() << " : " << val.to_string(SC_HEX) << "\n"; 76} 77 78template <typename T, typename U> 79void test_fx(U a_mul, U b_init, U b_mul, char const *t_name, char const *u_name) 80{ 81 cerr << "--array-Inf-Inf-Inf-Inf-Inf- test_fx_" << t_name << "_" << u_name << "\n"; 82 83 T a(static_cast<U>(0)); 84 T b(b_init); 85 show("a", 0, a); 86 show("b", 0, b); 87 88 for (U i = 1; i < 4; ++i) { 89 // Be careful here. We don't want a T to ever be implicitly converted, 90 // else we have a double which cannot be safely cast, but converting early 91 // means we can be subject to implicit upcasts. That's minimized by having all 92 // of the values of type U, but if U is smaller than int it can still be 93 // implicitly upcast, ergo the outer cast. 94 a = static_cast<U>(i * i * a_mul); 95 b = static_cast<U>(convert<U>(b) * i * b_mul); 96 show("a", i, a); 97 show("b", i, b); 98 } 99} 100 101template <typename T> 102void batch_test_fx(char const *t_name, int uinit) { 103 cerr << "************** array test_fx_" << t_name << "_\n"; 104 test_fx<T, int >(1, -1, -1, t_name, "int"); 105 test_fx<T, unsigned int >(1, uinit, -1, t_name, "uint"); 106 test_fx<T, short >(1, -1, -1, t_name, "short"); 107 test_fx<T, unsigned short>(1, uinit, -1, t_name, "ushort"); 108 test_fx<T, long >(1, -1, -1, t_name, "long"); 109 test_fx<T, unsigned long >(1, uinit, -1, t_name, "ulong"); 110 test_fx<T, float >(1.123456789f, -1.987654321f, -1.789654123f, t_name, "float"); 111 test_fx<T, double>(1.123456789, -1.987654321, -1.789654123, t_name, "double"); 112} 113 114void array() { 115 batch_test_fx<sc_fxval>("float", -1); 116 batch_test_fx<sc_ufix>("ufix", -1); 117 batch_test_fx<sc_fix>("fix", -1); 118 batch_test_fx<sc_fixed<8, 5> >("fixed", 1); 119 batch_test_fx<sc_ufixed<8, 5> >("ufixed", 1); 120} 121