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  sc_logic.h -- C++ implementation of logic type. Behaves
23                pretty much the same way as HDLs except with 4 values.
24
25  Original Author: Stan Y. Liao, Synopsys, Inc.
26
27 *****************************************************************************/
28
29/*****************************************************************************
30
31  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
32  changes you are making here.
33
34      Name, Affiliation, Date:
35  Description of Modification:
36
37 *****************************************************************************/
38
39// $Log: sc_logic.h,v $
40// Revision 1.3  2011/08/07 18:54:19  acg
41//  Philipp A. Hartmann: remove friend function declarations that implement
42//  code, and clean up how bit and logic operators are defined in general.
43//
44// Revision 1.2  2011/01/25 20:50:37  acg
45//  Andy Goodrich: changes for IEEE 1666 2011.
46//
47// Revision 1.1.1.1  2006/12/15 20:20:04  acg
48// SystemC 2.3
49//
50// Revision 1.5  2006/12/02 21:00:57  acg
51//  Andy Goodrich: fixes for concatenation support.
52//
53// Revision 1.4  2006/05/08 17:49:59  acg
54//   Andy Goodrich: Added David Long's declarations for friend operators,
55//   functions, and methods, to keep the Microsoft compiler happy.
56//
57// Revision 1.3  2006/01/13 18:53:53  acg
58// Andy Goodrich: added $Log command so that CVS comments are reproduced in
59// the source.
60//
61
62#ifndef __SYSTEMC_EXT_DT_BIT_SC_LOGIC_HH__
63#define __SYSTEMC_EXT_DT_BIT_SC_LOGIC_HH__
64
65#include <cstdio>
66#include <iostream>
67
68#include "../sc_mempool.hh"
69#include "sc_bit.hh"
70
71namespace sc_dt
72{
73
74// classes defined in this module
75class sc_logic;
76
77
78// ----------------------------------------------------------------------------
79//  ENUM : sc_logic_value_t
80//
81//  Enumeration of values for sc_logic.
82// ----------------------------------------------------------------------------
83
84enum sc_logic_value_t
85{
86    Log_0 = 0,
87    Log_1,
88    Log_Z,
89    Log_X
90};
91
92// ----------------------------------------------------------------------------
93//  CLASS : sc_logic
94//
95//  Four-valued logic type.
96// ----------------------------------------------------------------------------
97
98class sc_logic
99{
100  private:
101    // support methods
102    static void invalid_value(sc_logic_value_t);
103    static void invalid_value(char);
104    static void invalid_value(int);
105
106    static sc_logic_value_t
107    to_value(sc_logic_value_t v)
108    {
109        if (v < Log_0 || v > Log_X) {
110            invalid_value(v);
111            // may continue, if suppressed
112            v = Log_X;
113        }
114        return v;
115    }
116
117    static sc_logic_value_t to_value(bool b) { return (b ? Log_1 : Log_0); }
118
119    static sc_logic_value_t
120    to_value(char c)
121    {
122        unsigned int index = (int)c;
123        if (index > 127) {
124            invalid_value(c);
125            // may continue, if suppressed
126            index = 127; // aka Log_X
127        }
128        return char_to_logic[index];
129    }
130
131    static sc_logic_value_t
132    to_value(int i)
133    {
134        if (i < Log_0 || i > Log_X) {
135            invalid_value(i);
136            // may continue, if suppressed
137            i = Log_X;
138        }
139        return sc_logic_value_t(i);
140    }
141
142    void invalid_01() const;
143
144  public:
145    // conversion tables
146    static const sc_logic_value_t char_to_logic[128];
147    static const char logic_to_char[4];
148    static const sc_logic_value_t and_table[4][4];
149    static const sc_logic_value_t or_table[4][4];
150    static const sc_logic_value_t xor_table[4][4];
151    static const sc_logic_value_t not_table[4];
152
153    // constructors
154    sc_logic() : m_val(Log_X) {}
155    sc_logic(const sc_logic &a) : m_val(a.m_val) {}
156    sc_logic(sc_logic_value_t v) : m_val(to_value(v)) {}
157    explicit sc_logic(bool a) : m_val(to_value(a)) {}
158    explicit sc_logic(char a) : m_val(to_value(a)) {}
159    explicit sc_logic(int a) : m_val(to_value(a)) {}
160    explicit sc_logic(const sc_bit &a) : m_val(to_value(a.to_bool())) {}
161
162    // destructor
163    ~sc_logic() {}
164
165    // (bitwise) assignment operators
166#define DEFN_ASN_OP_T(op,tp) \
167    sc_logic & \
168    operator op (tp v) \
169    { \
170        *this op sc_logic(v); \
171        return *this; \
172    }
173
174#define DEFN_ASN_OP(op) \
175    DEFN_ASN_OP_T(op, sc_logic_value_t) \
176    DEFN_ASN_OP_T(op, bool) \
177    DEFN_ASN_OP_T(op, char) \
178    DEFN_ASN_OP_T(op, int) \
179    DEFN_ASN_OP_T(op, const sc_bit &)
180
181    sc_logic &
182    operator = (const sc_logic &a)
183    {
184        m_val = a.m_val;
185        return *this;
186    }
187
188    sc_logic &
189    operator &= (const sc_logic &b)
190    {
191        m_val = and_table[m_val][b.m_val];
192        return *this;
193    }
194
195    sc_logic &
196    operator |= (const sc_logic &b)
197    {
198        m_val = or_table[m_val][b.m_val];
199        return *this;
200    }
201
202    sc_logic &
203    operator ^= (const sc_logic &b)
204    {
205        m_val = xor_table[m_val][b.m_val];
206        return *this;
207    }
208
209    DEFN_ASN_OP(=)
210    DEFN_ASN_OP(&=)
211    DEFN_ASN_OP(|=)
212    DEFN_ASN_OP(^=)
213
214#undef DEFN_ASN_OP_T
215#undef DEFN_ASN_OP
216
217    // bitwise operators and functions
218    friend const sc_logic operator & (const sc_logic &, const sc_logic &);
219    friend const sc_logic operator | (const sc_logic &, const sc_logic &);
220    friend const sc_logic operator ^ (const sc_logic &, const sc_logic &);
221
222    // relational operators
223    friend bool operator == (const sc_logic &, const sc_logic &);
224    friend bool operator != (const sc_logic &, const sc_logic &);
225
226    // bitwise complement
227    const sc_logic operator ~ () const { return sc_logic(not_table[m_val]); }
228    sc_logic &
229    b_not()
230    {
231        m_val = not_table[m_val];
232        return *this;
233    }
234
235    // explicit conversions
236    sc_logic_value_t value() const { return m_val; }
237
238    bool is_01() const { return ((int)m_val == Log_0 || (int)m_val == Log_1); }
239    bool
240    to_bool() const
241    {
242        if (!is_01()) {
243            invalid_01();
244        }
245        return ((int)m_val != Log_0);
246    }
247
248    char to_char() const { return logic_to_char[m_val]; }
249
250    // other methods
251    void print(::std::ostream &os=::std::cout) const { os << to_char(); }
252    void scan(::std::istream &is=::std::cin);
253
254    // memory (de)allocation
255    // placement new
256    static void *operator new (std::size_t, void *p) { return p; }
257    static void *
258    operator new (std::size_t sz)
259    {
260        return sc_core::sc_mempool::allocate(sz);
261    }
262    static void
263    operator delete (void *p, std::size_t sz)
264    {
265        sc_core::sc_mempool::release(p, sz);
266    }
267    static void *
268    operator new [] (std::size_t sz)
269    {
270        return sc_core::sc_mempool::allocate(sz);
271    }
272    static void
273    operator delete [] (void *p, std::size_t sz)
274    {
275        sc_core::sc_mempool::release(p, sz);
276    }
277
278  private:
279    sc_logic_value_t m_val;
280
281  private:
282    // Disabled
283    explicit sc_logic(const char *);
284    sc_logic &operator = (const char *);
285};
286
287// ----------------------------------------------------------------------------
288
289// bitwise operators
290inline const sc_logic
291operator & (const sc_logic &a, const sc_logic &b)
292{
293    return sc_logic(sc_logic::and_table[a.m_val][b.m_val]);
294}
295
296inline const sc_logic
297operator | (const sc_logic &a, const sc_logic &b)
298{
299    return sc_logic(sc_logic::or_table[a.m_val][b.m_val]);
300}
301
302inline const sc_logic
303operator ^ (const sc_logic &a, const sc_logic &b)
304{
305    return sc_logic(sc_logic::xor_table[a.m_val][b.m_val]);
306}
307
308#define DEFN_BIN_OP_T(ret,op,tp) \
309    inline ret \
310    operator op (const sc_logic &a, tp b) \
311    { \
312        return (a op sc_logic(b)); \
313    } \
314    inline ret \
315    operator op (tp a, const sc_logic &b) \
316    { \
317        return (sc_logic(a) op b); \
318    }
319
320#define DEFN_BIN_OP(ret, op) \
321    DEFN_BIN_OP_T(ret, op, sc_logic_value_t) \
322    DEFN_BIN_OP_T(ret, op, bool) \
323    DEFN_BIN_OP_T(ret, op, char) \
324    DEFN_BIN_OP_T(ret, op, int)
325
326DEFN_BIN_OP(const sc_logic, &)
327DEFN_BIN_OP(const sc_logic, |)
328DEFN_BIN_OP(const sc_logic, ^)
329
330// relational operators and functions
331
332inline bool
333operator == (const sc_logic &a, const sc_logic &b)
334{
335    return ((int)a.m_val == b.m_val);
336}
337
338inline bool
339operator != (const sc_logic &a, const sc_logic &b)
340{
341    return ((int)a.m_val != b.m_val);
342}
343
344DEFN_BIN_OP(bool, ==)
345DEFN_BIN_OP(bool, !=)
346
347#undef DEFN_BIN_OP_T
348#undef DEFN_BIN_OP
349
350// ----------------------------------------------------------------------------
351
352inline ::std::ostream &
353operator << (::std::ostream &os, const sc_logic &a)
354{
355    a.print(os);
356    return os;
357}
358
359inline ::std::istream &
360operator >> (::std::istream &is, sc_logic &a)
361{
362    a.scan(is);
363    return is;
364}
365
366
367extern const sc_logic SC_LOGIC_0;
368extern const sc_logic SC_LOGIC_1;
369extern const sc_logic SC_LOGIC_Z;
370extern const sc_logic SC_LOGIC_X;
371
372// #ifdef SC_DT_DEPRECATED
373extern const sc_logic sc_logic_0;
374extern const sc_logic sc_logic_1;
375extern const sc_logic sc_logic_Z;
376extern const sc_logic sc_logic_X;
377// #endif
378
379} // namespace sc_dt
380
381#endif // __SYSTEMC_EXT_DT_BIT_SC_LOGIC_HH__
382