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
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