112855Sgabeblack@google.com/*****************************************************************************
212855Sgabeblack@google.com
312855Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412855Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512855Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612855Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712855Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812855Sgabeblack@google.com  License.  You may obtain a copy of the License at
912855Sgabeblack@google.com
1012855Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112855Sgabeblack@google.com
1212855Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312855Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412855Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512855Sgabeblack@google.com  implied.  See the License for the specific language governing
1612855Sgabeblack@google.com  permissions and limitations under the License.
1712855Sgabeblack@google.com
1812855Sgabeblack@google.com *****************************************************************************/
1912855Sgabeblack@google.com
2012855Sgabeblack@google.com/*****************************************************************************
2112855Sgabeblack@google.com
2212855Sgabeblack@google.com  array.cpp --
2312855Sgabeblack@google.com
2412855Sgabeblack@google.com  Original Author: Martin Janssen, Synopsys, Inc., 2002-02-15
2512855Sgabeblack@google.com
2612855Sgabeblack@google.com *****************************************************************************/
2712855Sgabeblack@google.com
2812855Sgabeblack@google.com/*****************************************************************************
2912855Sgabeblack@google.com
3012855Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3112855Sgabeblack@google.com  changes you are making here.
3212855Sgabeblack@google.com
3312855Sgabeblack@google.com      Name, Affiliation, Date:
3412855Sgabeblack@google.com  Description of Modification:
3512855Sgabeblack@google.com
3612855Sgabeblack@google.com *****************************************************************************/
3712855Sgabeblack@google.com
3812855Sgabeblack@google.com// array.cxx --
3912855Sgabeblack@google.com// Copyright Synopsys 1998
4012855Sgabeblack@google.com// Author          : Ric Hilderink
4112855Sgabeblack@google.com// Created On      : Wed Dec 30 11:55:50 1998
4212855Sgabeblack@google.com// Status          : none
4312855Sgabeblack@google.com//
4412855Sgabeblack@google.com
4512855Sgabeblack@google.com#include <limits.h>
4612855Sgabeblack@google.com#define SC_INCLUDE_FX
4712855Sgabeblack@google.com#include "systemc.h"
4812855Sgabeblack@google.com
4912855Sgabeblack@google.com// Without this, conversions use the implicit
5012855Sgabeblack@google.com// operator double, which is both lossy and
5112855Sgabeblack@google.com// can cause UB in certain cases.
5212855Sgabeblack@google.comtemplate <typename From>
5312855Sgabeblack@google.comclass converter {
5412855Sgabeblack@google.com  From val;
5512855Sgabeblack@google.compublic:
5612855Sgabeblack@google.com  converter(From val): val(val) {}
5712855Sgabeblack@google.com  operator int() const            { return val.to_int();    }
5812855Sgabeblack@google.com  operator unsigned int() const   { return val.to_uint();   }
5912855Sgabeblack@google.com  operator short() const          { return val.to_short();  }
6012855Sgabeblack@google.com  operator unsigned short() const { return val.to_ushort(); }
6112855Sgabeblack@google.com  operator long() const           { return val.to_long();   }
6212855Sgabeblack@google.com  operator unsigned long() const  { return val.to_ulong();  }
6312855Sgabeblack@google.com  operator float() const          { return val.to_float();  }
6412855Sgabeblack@google.com  operator double() const         { return val.to_double(); }
6512855Sgabeblack@google.com};
6612855Sgabeblack@google.com
6712855Sgabeblack@google.comtemplate <typename To, typename From>
6812855Sgabeblack@google.comTo convert(From val) {
6912855Sgabeblack@google.com  return converter<From>(val);
7012855Sgabeblack@google.com}
7112855Sgabeblack@google.com
7212855Sgabeblack@google.com
7312855Sgabeblack@google.comtemplate <typename T>
7412855Sgabeblack@google.comvoid show(char const *const name, int i, T val) {
7512855Sgabeblack@google.com  cerr << name << "[" << i << "] : " << val.to_double() << " : " << val.to_string(SC_HEX) << "\n";
7612855Sgabeblack@google.com}
7712855Sgabeblack@google.com
7812855Sgabeblack@google.comtemplate <typename T, typename U>
7912855Sgabeblack@google.comvoid test_fx(U a_mul, U b_init, U b_mul, char const *t_name, char const *u_name)
8012855Sgabeblack@google.com{
8112855Sgabeblack@google.com  cerr << "--array-Inf-Inf-Inf-Inf-Inf- test_fx_" << t_name << "_" << u_name << "\n";
8212855Sgabeblack@google.com
8312855Sgabeblack@google.com  T a(static_cast<U>(0));
8412855Sgabeblack@google.com  T b(b_init);
8512855Sgabeblack@google.com  show("a", 0, a);
8612855Sgabeblack@google.com  show("b", 0, b);
8712855Sgabeblack@google.com
8812855Sgabeblack@google.com  for (U i = 1; i < 4; ++i) {
8912855Sgabeblack@google.com    // Be careful here. We don't want a T to ever be implicitly converted,
9012855Sgabeblack@google.com    // else we have a double which cannot be safely cast, but converting early
9112855Sgabeblack@google.com    // means we can be subject to implicit upcasts. That's minimized by having all
9212855Sgabeblack@google.com    // of the values of type U, but if U is smaller than int it can still be
9312855Sgabeblack@google.com    // implicitly upcast, ergo the outer cast.
9412855Sgabeblack@google.com    a = static_cast<U>(i * i * a_mul);
9512855Sgabeblack@google.com    b = static_cast<U>(convert<U>(b) * i * b_mul);
9612855Sgabeblack@google.com    show("a", i, a);
9712855Sgabeblack@google.com    show("b", i, b);
9812855Sgabeblack@google.com  }
9912855Sgabeblack@google.com}
10012855Sgabeblack@google.com
10112855Sgabeblack@google.comtemplate <typename T>
10212855Sgabeblack@google.comvoid batch_test_fx(char const *t_name, int uinit) {
10312855Sgabeblack@google.com  cerr << "************** array test_fx_" << t_name << "_\n";
10412855Sgabeblack@google.com  test_fx<T, int           >(1,     -1, -1, t_name, "int");
10512855Sgabeblack@google.com  test_fx<T, unsigned int  >(1,  uinit, -1, t_name, "uint");
10612855Sgabeblack@google.com  test_fx<T, short         >(1,     -1, -1, t_name, "short");
10712855Sgabeblack@google.com  test_fx<T, unsigned short>(1,  uinit, -1, t_name, "ushort");
10812855Sgabeblack@google.com  test_fx<T, long          >(1,     -1, -1, t_name, "long");
10912855Sgabeblack@google.com  test_fx<T, unsigned long >(1,  uinit, -1, t_name, "ulong");
11012855Sgabeblack@google.com  test_fx<T, float >(1.123456789f, -1.987654321f, -1.789654123f, t_name, "float");
11112855Sgabeblack@google.com  test_fx<T, double>(1.123456789,  -1.987654321,  -1.789654123,  t_name, "double");
11212855Sgabeblack@google.com}
11312855Sgabeblack@google.com
11412855Sgabeblack@google.comvoid array() {
11512855Sgabeblack@google.com  batch_test_fx<sc_fxval>("float", -1);
11612855Sgabeblack@google.com  batch_test_fx<sc_ufix>("ufix", -1);
11712855Sgabeblack@google.com  batch_test_fx<sc_fix>("fix", -1);
11812855Sgabeblack@google.com  batch_test_fx<sc_fixed<8, 5> >("fixed", 1);
11912855Sgabeblack@google.com  batch_test_fx<sc_ufixed<8, 5> >("ufixed", 1);
12012855Sgabeblack@google.com}
121