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 __SYSTEMC_EXT_DT_BIT_SC_BV_BASE_HH__
54#define __SYSTEMC_EXT_DT_BIT_SC_BV_BASE_HH__
55
56#include "../int/sc_length_param.hh"
57#include "messages.hh"
58#include "sc_bit_proxies.hh"
59#include "sc_proxy.hh"
60
61namespace sc_dt
62{
63
64// classes defined in this module
65class sc_bv_base;
66
67
68// ----------------------------------------------------------------------------
69//  CLASS : sc_bv_base
70//
71//  Arbitrary size bit vector base class.
72// ----------------------------------------------------------------------------
73
74class sc_bv_base : public sc_proxy<sc_bv_base>
75{
76    friend class sc_lv_base;
77
78    void init(int length_, bool init_value=false);
79    void assign_from_string(const std::string &);
80
81  public:
82    // typedefs
83    typedef sc_proxy<sc_bv_base> base_type;
84    typedef base_type::value_type value_type;
85
86    // constructors
87    explicit sc_bv_base(int length_=sc_length_param().len()) :
88        m_len(0), m_size(0), m_data(0)
89    {
90        init(length_);
91    }
92
93    explicit sc_bv_base(bool a, int length_=sc_length_param().len()) :
94        m_len(0), m_size(0), m_data(0)
95    {
96        init(length_, a);
97    }
98
99    sc_bv_base(const char *a);
100    sc_bv_base(const char *a, int length_);
101
102    template <class X>
103    sc_bv_base(const sc_proxy<X> &a) : m_len(0), m_size(0), m_data(0)
104    {
105        init(a.back_cast().length());
106        base_type::assign_(a);
107    }
108
109    sc_bv_base(const sc_bv_base &a);
110
111    // destructor
112    virtual ~sc_bv_base() { delete [] m_data; }
113
114    // assignment operators
115    template <class X>
116    sc_bv_base &
117    operator = (const sc_proxy<X> &a)
118    {
119        assign_p_(*this, a);
120        return *this;
121    }
122
123    sc_bv_base &
124    operator = (const sc_bv_base &a)
125    {
126        assign_p_(*this, a);
127        return *this;
128    }
129
130    sc_bv_base &operator = (const char *a);
131
132    sc_bv_base &
133    operator = (const bool *a)
134    {
135        base_type::assign_(a);
136        return *this;
137    }
138
139    sc_bv_base &
140    operator = (const sc_logic *a)
141    {
142        base_type::assign_(a);
143        return *this;
144    }
145
146    sc_bv_base &
147    operator = (const sc_unsigned &a)
148    {
149        base_type::assign_(a);
150        return *this;
151    }
152
153    sc_bv_base &
154    operator = (const sc_signed &a)
155    {
156        base_type::assign_(a);
157        return *this;
158    }
159
160    sc_bv_base &
161    operator = (const sc_uint_base &a)
162    {
163        base_type::assign_(a);
164        return *this;
165    }
166
167    sc_bv_base &
168    operator = (const sc_int_base &a)
169    {
170        base_type::assign_(a);
171        return *this;
172    }
173
174    sc_bv_base &
175    operator = (unsigned long a)
176    {
177        base_type::assign_(a);
178        return *this;
179    }
180
181    sc_bv_base &
182    operator = (long a)
183    {
184        base_type::assign_(a);
185        return *this;
186    }
187
188    sc_bv_base &
189    operator = (unsigned int a)
190    {
191        base_type::assign_(a);
192        return *this;
193    }
194
195    sc_bv_base &
196    operator = (int a)
197    {
198        base_type::assign_(a);
199        return *this;
200    }
201
202    sc_bv_base &
203    operator = (uint64 a)
204    {
205        base_type::assign_(a);
206        return *this;
207    }
208
209    sc_bv_base &
210    operator = (int64 a)
211    {
212        base_type::assign_(a);
213        return *this;
214    }
215
216    // common methods
217    int length() const { return m_len; }
218    int size() const { return m_size; }
219
220    value_type get_bit(int i) const;
221    void set_bit(int i, value_type value);
222
223    sc_digit get_word(int i) const { return m_data[i]; }
224
225    void set_word(int i, sc_digit w) { m_data[i] = w; }
226
227    sc_digit get_cword(int /*i*/) const { return SC_DIGIT_ZERO; }
228
229    void set_cword(int i, sc_digit w);
230
231    void clean_tail();
232
233    // other methods
234    bool is_01() const { return true; }
235
236  protected:
237    int m_len; // length in bits
238    int m_size; // size of data array
239    sc_digit *m_data; // data array
240};
241
242
243// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
244
245// common methods
246inline sc_bv_base::value_type
247sc_bv_base::get_bit(int i) const
248{
249    int wi = i / SC_DIGIT_SIZE;
250    int bi = i % SC_DIGIT_SIZE;
251    return value_type((m_data[wi] >> bi) & SC_DIGIT_ONE);
252}
253
254inline void
255sc_bv_base::set_bit(int i, value_type value)
256{
257    int wi = i / SC_DIGIT_SIZE;
258    int bi = i % SC_DIGIT_SIZE;
259    sc_digit mask = SC_DIGIT_ONE << bi;
260    m_data[wi] |= mask; // set bit to 1
261    m_data[wi] &= value << bi | ~mask;
262}
263
264inline void
265sc_bv_base::set_cword(int /*i*/, sc_digit w)
266{
267    if (w) {
268        SC_REPORT_WARNING(sc_core::SC_ID_SC_BV_CANNOT_CONTAIN_X_AND_Z_, 0);
269    }
270}
271
272inline void
273sc_bv_base::clean_tail()
274{
275    int wi = m_size - 1;
276    int bi = m_len % SC_DIGIT_SIZE;
277    if (bi != 0)
278        m_data[wi] &= ~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - bi);
279}
280
281} // namespace sc_dt
282
283#endif // __SYSTEMC_EXT_DT_BIT_SC_BV_BASE_HH__
284