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_bv_base.h -- Arbitrary size bit vector class.
23
24  Original Author: Gene Bushuyev, Synopsys, Inc.
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// $Log: sc_bv_base.h,v $
39// Revision 1.3  2011/08/26 22:32:00  acg
40//  Torsten Maehne: added parentheses to make opearator ordering more obvious.
41//
42// Revision 1.2  2011/08/15 16:43:24  acg
43//  Torsten Maehne: changes to remove unused argument warnings.
44//
45// Revision 1.1.1.1  2006/12/15 20:20:04  acg
46// SystemC 2.3
47//
48// Revision 1.3  2006/01/13 18:53:53  acg
49// Andy Goodrich: added $Log command so that CVS comments are reproduced in
50// the source.
51//
52
53#ifndef SC_BV_BASE_H
54#define SC_BV_BASE_H
55
56
57#include "sysc/datatypes/bit/sc_bit_ids.h"
58#include "sysc/datatypes/bit/sc_bit_proxies.h"
59#include "sysc/datatypes/bit/sc_proxy.h"
60#include "sysc/datatypes/int/sc_length_param.h"
61
62
63namespace sc_dt
64{
65
66// classes defined in this module
67class sc_bv_base;
68
69
70// ----------------------------------------------------------------------------
71//  CLASS : sc_bv_base
72//
73//  Arbitrary size bit vector base class.
74// ----------------------------------------------------------------------------
75
76class sc_bv_base
77    : public sc_proxy<sc_bv_base>
78{
79    friend class sc_lv_base;
80
81
82    void init( int length_, bool init_value = false );
83
84    void assign_from_string( const std::string& );
85
86public:
87
88    // typedefs
89
90    typedef sc_proxy<sc_bv_base> base_type;
91
92
93    // constructors
94
95    explicit sc_bv_base( int length_ = sc_length_param().len() )
96	: m_len( 0 ), m_size( 0 ), m_data( 0 )
97	{ init( length_ ); }
98
99    explicit sc_bv_base( bool a,
100			 int length_ = sc_length_param().len() )
101	: m_len( 0 ), m_size( 0 ), m_data( 0 )
102	{ init( length_, a ); }
103
104    sc_bv_base( const char* a );
105
106    sc_bv_base( const char* a, int length_ );
107
108    template <class X>
109    sc_bv_base( const sc_proxy<X>& a )
110	: m_len( 0 ), m_size( 0 ), m_data( 0 )
111	{ init( a.back_cast().length() ); base_type::assign_( a ); }
112
113    sc_bv_base( const sc_bv_base& a );
114
115#ifdef SC_DT_DEPRECATED
116
117    explicit sc_bv_base( const sc_unsigned& a )
118	: m_len( 0 ), m_size( 0 ), m_data( 0 )
119	{ init( a.length() ); base_type::assign_( a ); }
120
121    explicit sc_bv_base( const sc_signed& a )
122	: m_len( 0 ), m_size( 0 ), m_data( 0 )
123	{ init( a.length() ); base_type::assign_( a ); }
124
125    explicit sc_bv_base( const sc_uint_base& a)
126	: m_len( 0 ), m_size( 0 ), m_data( 0 )
127	{ init( a.length() ); base_type::assign_( a ); }
128
129    explicit sc_bv_base( const sc_int_base& a)
130	: m_len( 0 ), m_size( 0 ), m_data( 0 )
131	{ init( a.length() ); base_type::assign_( a ); }
132
133#endif
134
135
136    // destructor
137
138    virtual ~sc_bv_base()
139	{ delete [] m_data; }
140
141
142    // assignment operators
143
144    template <class X>
145    sc_bv_base& operator = ( const sc_proxy<X>& a )
146	{ assign_p_( *this, a ); return *this; }
147
148    sc_bv_base& operator = ( const sc_bv_base& a )
149	{ assign_p_( *this, a ); return *this; }
150
151    sc_bv_base& operator = ( const char* a );
152
153    sc_bv_base& operator = ( const bool* a )
154	{ base_type::assign_( a ); return *this; }
155
156    sc_bv_base& operator = ( const sc_logic* a )
157	{ base_type::assign_( a ); return *this; }
158
159    sc_bv_base& operator = ( const sc_unsigned& a )
160	{ base_type::assign_( a ); return *this; }
161
162    sc_bv_base& operator = ( const sc_signed& a )
163	{ base_type::assign_( a ); return *this; }
164
165    sc_bv_base& operator = ( const sc_uint_base& a )
166	{ base_type::assign_( a ); return *this; }
167
168    sc_bv_base& operator = ( const sc_int_base& a )
169	{ base_type::assign_( a ); return *this; }
170
171    sc_bv_base& operator = ( unsigned long a )
172	{ base_type::assign_( a ); return *this; }
173
174    sc_bv_base& operator = ( long a )
175	{ base_type::assign_( a ); return *this; }
176
177    sc_bv_base& operator = ( unsigned int a )
178	{ base_type::assign_( a ); return *this; }
179
180    sc_bv_base& operator = ( int a )
181	{ base_type::assign_( a ); return *this; }
182
183    sc_bv_base& operator = ( uint64 a )
184	{ base_type::assign_( a ); return *this; }
185
186    sc_bv_base& operator = ( int64 a )
187	{ base_type::assign_( a ); return *this; }
188
189
190#if 0
191
192    // bitwise complement
193
194    sc_bv_base& b_not();
195
196    const sc_bv_base operator ~ () const
197	{ sc_bv_base a( *this ); return a.b_not(); }
198
199
200    // bitwise left shift
201
202    sc_bv_base& operator <<= ( int n );
203
204    const sc_bv_base operator << ( int n ) const
205	{ sc_bv_base a( *this ); return ( a <<= n ); }
206
207
208    // bitwise right shift
209
210    sc_bv_base& operator >>= ( int n );
211
212    const sc_bv_base operator >> ( int n ) const
213	{ sc_bv_base a( *this ); return ( a >>= n ); }
214
215
216    // bitwise left rotate
217
218    sc_bv_base& lrotate( int n );
219
220
221    // bitwise right rotate
222
223    sc_bv_base& rrotate( int n );
224
225#endif
226
227
228    // common methods
229
230    int length() const
231	{ return m_len; }
232
233    int size() const
234	{ return m_size; }
235
236    sc_logic_value_t get_bit( int i ) const;
237    void set_bit( int i, sc_logic_value_t value );
238
239    sc_digit get_word( int i ) const
240	{ return m_data[i]; }
241
242    void set_word( int i, sc_digit w )
243	{ m_data[i] = w; }
244
245    sc_digit get_cword( int /*i*/ ) const
246	{ return SC_DIGIT_ZERO; }
247
248    void set_cword( int i, sc_digit w );
249
250    void clean_tail();
251
252
253    // other methods
254
255    bool is_01() const
256	{ return true; }
257
258protected:
259
260    int     m_len;  // length in bits
261    int     m_size; // size of data array
262    sc_digit* m_data; // data array
263};
264
265
266// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
267
268#if 0
269
270// bitwise left rotate
271
272inline
273const sc_bv_base
274lrotate( const sc_bv_base& x, int n )
275{
276    sc_bv_base a( x );
277    return a.lrotate( n );
278}
279
280
281// bitwise right rotate
282
283inline
284const sc_bv_base
285rrotate( const sc_bv_base& x, int n )
286{
287    sc_bv_base a( x );
288    return a.rrotate( n );
289}
290
291#endif
292
293
294// common methods
295
296inline
297sc_logic_value_t
298sc_bv_base::get_bit( int i ) const
299{
300    int wi = i / SC_DIGIT_SIZE;
301    int bi = i % SC_DIGIT_SIZE;
302    return sc_logic_value_t( (m_data[wi] >> bi) & SC_DIGIT_ONE );
303}
304
305inline
306void
307sc_bv_base::set_bit( int i, sc_logic_value_t value )
308{
309    int wi = i / SC_DIGIT_SIZE;
310    int bi = i % SC_DIGIT_SIZE;
311    sc_digit mask = SC_DIGIT_ONE << bi;
312    m_data[wi] |= mask; // set bit to 1
313    m_data[wi] &= value << bi | ~mask;
314}
315
316
317inline
318void
319sc_bv_base::set_cword( int /*i*/, sc_digit w )
320{
321    if( w ) {
322	SC_REPORT_WARNING( sc_core::SC_ID_SC_BV_CANNOT_CONTAIN_X_AND_Z_, 0 );
323    }
324}
325
326
327inline
328void
329sc_bv_base::clean_tail()
330{
331    int wi = m_size - 1;
332    int bi = m_len % SC_DIGIT_SIZE;
333	if ( bi != 0 ) m_data[wi] &= ~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - bi);
334}
335
336} // namespace sc_dt
337
338
339#endif
340