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 SC_LOGIC_H
63#define SC_LOGIC_H
64
65
66#include <cstdio>
67
68#include "sysc/utils/sc_iostream.h"
69#include "sysc/kernel/sc_macros.h"
70#include "sysc/utils/sc_mempool.h"
71#include "sysc/datatypes/bit/sc_bit.h"
72
73
74namespace sc_dt
75{
76
77// classes defined in this module
78class sc_logic;
79
80
81// ----------------------------------------------------------------------------
82//  ENUM : sc_logic_value_t
83//
84//  Enumeration of values for sc_logic.
85// ----------------------------------------------------------------------------
86
87enum sc_logic_value_t
88{
89    Log_0 = 0,
90    Log_1,
91    Log_Z,
92    Log_X
93};
94
95// ----------------------------------------------------------------------------
96//  CLASS : sc_logic
97//
98//  Four-valued logic type.
99// ----------------------------------------------------------------------------
100
101class sc_logic
102{
103private:
104
105    // support methods
106
107    static void invalid_value( sc_logic_value_t );
108    static void invalid_value( char );
109    static void invalid_value( int );
110
111    static sc_logic_value_t to_value( sc_logic_value_t v )
112	{
113	    if( v < Log_0 || v > Log_X ) {
114		invalid_value( v );
115	    }
116	    return v;
117	}
118
119    static sc_logic_value_t to_value( bool b )
120	{ return ( b ? Log_1 : Log_0 ); }
121
122    static sc_logic_value_t to_value( char c )
123	{
124	    sc_logic_value_t v;
125	    unsigned int index = (int)c;
126	    if ( index > 127 )
127	    {
128	        invalid_value(c);
129		v = Log_X;
130	    }
131	    else
132	    {
133		v = char_to_logic[index];
134		if( v < Log_0 || v > Log_X ) {
135		    invalid_value( c );
136		}
137	    }
138	    return v;
139	}
140
141    static sc_logic_value_t to_value( int i )
142	{
143	    if( i < 0 || i > 3 ) {
144		invalid_value( i );
145	    }
146	    return sc_logic_value_t( i );
147	}
148
149
150    void invalid_01() const;
151
152public:
153
154    // conversion tables
155
156    static const sc_logic_value_t char_to_logic[128];
157    static const char logic_to_char[4];
158    static const sc_logic_value_t and_table[4][4];
159    static const sc_logic_value_t or_table[4][4];
160    static const sc_logic_value_t xor_table[4][4];
161    static const sc_logic_value_t not_table[4];
162
163
164    // constructors
165
166    sc_logic()
167	: m_val( Log_X )
168	{}
169
170    sc_logic( const sc_logic& a )
171	: m_val( a.m_val )
172	{}
173
174    sc_logic( sc_logic_value_t v )
175	: m_val( to_value( v ) )
176	{}
177
178    explicit sc_logic( bool a )
179	: m_val( to_value( a ) )
180	{}
181
182    explicit sc_logic( char a )
183	: m_val( to_value( a ) )
184	{}
185
186    explicit sc_logic( int a )
187	: m_val( to_value( a ) )
188	{}
189
190    explicit sc_logic( const sc_bit& a )
191	: m_val( to_value( a.to_bool() ) )
192	{}
193
194
195    // destructor
196
197    ~sc_logic()
198	{}
199
200
201    // (bitwise) assignment operators
202
203#define DEFN_ASN_OP_T(op,tp)                       \
204    sc_logic& operator op ( tp v )                 \
205        { *this op sc_logic( v ); return *this; }
206
207#define DEFN_ASN_OP(op)                            \
208    DEFN_ASN_OP_T(op, sc_logic_value_t)            \
209    DEFN_ASN_OP_T(op, bool)                        \
210    DEFN_ASN_OP_T(op, char)                        \
211    DEFN_ASN_OP_T(op, int )                        \
212    DEFN_ASN_OP_T(op, const sc_bit& )
213
214    sc_logic& operator = ( const sc_logic& a )
215        { m_val = a.m_val; return *this; }
216
217    sc_logic& operator &= ( const sc_logic& b )
218        { m_val = and_table[m_val][b.m_val]; return *this; }
219
220    sc_logic& operator |= ( const sc_logic& b )
221        { m_val = or_table[m_val][b.m_val]; return *this; }
222
223    sc_logic& operator ^= ( const sc_logic& b )
224        { m_val = xor_table[m_val][b.m_val]; return *this; }
225
226    DEFN_ASN_OP(=)
227    DEFN_ASN_OP(&=)
228    DEFN_ASN_OP(|=)
229    DEFN_ASN_OP(^=)
230
231#undef DEFN_ASN_OP_T
232#undef DEFN_ASN_OP
233
234
235    // bitwise operators and functions
236
237
238    friend const sc_logic operator & ( const sc_logic&, const sc_logic& );
239    friend const sc_logic operator | ( const sc_logic&, const sc_logic& );
240    friend const sc_logic operator ^ ( const sc_logic&, const sc_logic& );
241
242    // relational operators
243
244    friend bool operator == ( const sc_logic&, const sc_logic& );
245    friend bool operator != ( const sc_logic&, const sc_logic& );
246
247    // bitwise complement
248
249    const sc_logic operator ~ () const
250	{ return sc_logic( not_table[m_val] ); }
251
252    sc_logic& b_not()
253	{ m_val = not_table[m_val]; return *this; }
254
255
256    // explicit conversions
257
258    sc_logic_value_t value() const
259	{ return m_val; }
260
261
262    bool is_01() const
263	{ return ( (int) m_val == Log_0 || (int) m_val == Log_1 ); }
264
265    bool to_bool() const
266	{ if( ! is_01() ) { invalid_01(); } return ( (int) m_val != Log_0 ); }
267
268    char to_char() const
269	{ return logic_to_char[m_val]; }
270
271
272    // other methods
273
274    void print( ::std::ostream& os = ::std::cout ) const
275	{ os << to_char(); }
276
277    void scan( ::std::istream& is = ::std::cin );
278
279
280    // memory (de)allocation
281
282    static void* operator new( std::size_t, void* p ) // placement new
283	{ return p; }
284
285    static void* operator new( std::size_t sz )
286	{ return sc_core::sc_mempool::allocate( sz ); }
287
288    static void operator delete( void* p, std::size_t sz )
289	{ sc_core::sc_mempool::release( p, sz ); }
290
291    static void* operator new [] ( std::size_t sz )
292	{ return sc_core::sc_mempool::allocate( sz ); }
293
294    static void operator delete [] ( void* p, std::size_t sz )
295	{ sc_core::sc_mempool::release( p, sz ); }
296
297private:
298
299    sc_logic_value_t m_val;
300
301private:
302
303    // disabled
304    explicit sc_logic( const char* );
305    sc_logic& operator = ( const char* );
306};
307
308// ----------------------------------------------------------------------------
309
310// bitwise operators
311
312inline const sc_logic operator & ( const sc_logic& a, const sc_logic& b )
313       { return sc_logic( sc_logic::and_table[a.m_val][b.m_val] ); }
314
315inline const sc_logic operator | ( const sc_logic& a, const sc_logic& b )
316       { return sc_logic( sc_logic::or_table[a.m_val][b.m_val] ); }
317
318inline const sc_logic operator ^ ( const sc_logic& a, const sc_logic& b )
319       { return sc_logic( sc_logic::xor_table[a.m_val][b.m_val] ); }
320
321#define DEFN_BIN_OP_T(ret,op,tp)                       \
322    inline ret operator op ( const sc_logic& a, tp b ) \
323        { return ( a op sc_logic( b ) ); }             \
324    inline ret operator op ( tp a, const sc_logic& b ) \
325        { return ( sc_logic( a ) op b ); }
326
327#define DEFN_BIN_OP(ret,op)                            \
328    DEFN_BIN_OP_T(ret,op,sc_logic_value_t)             \
329    DEFN_BIN_OP_T(ret,op,bool)                         \
330    DEFN_BIN_OP_T(ret,op,char)                         \
331    DEFN_BIN_OP_T(ret,op,int)
332
333DEFN_BIN_OP(const sc_logic,&)
334DEFN_BIN_OP(const sc_logic,|)
335DEFN_BIN_OP(const sc_logic,^)
336
337// relational operators and functions
338
339inline bool operator == ( const sc_logic& a, const sc_logic& b )
340       { return ( (int) a.m_val == b.m_val ); }
341
342inline bool operator != ( const sc_logic& a, const sc_logic& b )
343       { return ( (int) a.m_val != b.m_val ); }
344
345DEFN_BIN_OP(bool,==)
346DEFN_BIN_OP(bool,!=)
347
348#undef DEFN_BIN_OP_T
349#undef DEFN_BIN_OP
350
351// ----------------------------------------------------------------------------
352
353inline
354::std::ostream&
355operator << ( ::std::ostream& os, const sc_logic& a )
356{
357    a.print( os );
358    return os;
359}
360
361inline
362::std::istream&
363operator >> ( ::std::istream& is, sc_logic& a )
364{
365    a.scan( is );
366    return is;
367}
368
369
370extern const sc_logic SC_LOGIC_0;
371extern const sc_logic SC_LOGIC_1;
372extern const sc_logic SC_LOGIC_Z;
373extern const sc_logic SC_LOGIC_X;
374
375// #ifdef SC_DT_DEPRECATED
376extern const sc_logic sc_logic_0;
377extern const sc_logic sc_logic_1;
378extern const sc_logic sc_logic_Z;
379extern const sc_logic sc_logic_X;
380// #endif
381
382} // namespace sc_dt
383
384#endif
385