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_unsigned_subref.h -- Proxy class that is declared in sc_unsigned.h.
23
24  Original Author: Ali Dasdan, 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
39// ----------------------------------------------------------------------------
40//  CLASS : sc_unsigned_subref_r
41//
42//  Proxy class for sc_unsigned part selection (r-value only).
43// ----------------------------------------------------------------------------
44
45// concatenation support
46
47uint64
48sc_unsigned_subref_r::concat_get_uint64() const // #### Speed up!
49{
50    sc_unsigned a(m_obj_p, m_left, m_right);
51    return a.to_uint64();
52}
53
54
55bool
56sc_unsigned_subref_r::concat_get_ctrl(sc_digit *dst_p, int low_i) const
57// #### Speed up!
58{
59    sc_unsigned a(m_obj_p, m_left, m_right);
60    return a.concat_get_ctrl(dst_p, low_i);
61}
62
63bool
64sc_unsigned_subref_r::concat_get_data(sc_digit *dst_p, int low_i) const
65// #### Speed up!
66{
67    sc_unsigned a(m_obj_p, m_left, m_right);
68    return a.concat_get_data(dst_p, low_i);
69}
70
71// implicit conversion to sc_unsigned
72sc_unsigned_subref_r::operator sc_unsigned () const
73{
74    return sc_unsigned(m_obj_p, m_left, m_right);
75}
76
77
78// explicit conversions
79int
80sc_unsigned_subref_r::to_int() const
81{
82    sc_unsigned a(m_obj_p, m_left, m_right);
83    return a.to_int();
84}
85
86unsigned int
87sc_unsigned_subref_r::to_uint() const
88{
89    sc_unsigned a(m_obj_p, m_left, m_right);
90    return a.to_uint();
91}
92
93long
94sc_unsigned_subref_r::to_long() const
95{
96    sc_unsigned a(m_obj_p, m_left, m_right);
97    return a.to_long();
98}
99
100unsigned long
101sc_unsigned_subref_r::to_ulong() const
102{
103    sc_unsigned a(m_obj_p, m_left, m_right);
104    return a.to_ulong();
105}
106
107int64
108sc_unsigned_subref_r::to_int64() const
109{
110    sc_unsigned a(m_obj_p, m_left, m_right);
111    return a.to_int64();
112}
113
114uint64
115sc_unsigned_subref_r::to_uint64() const
116{
117    sc_unsigned a(m_obj_p, m_left, m_right);
118    return a.to_uint64();
119}
120
121double
122sc_unsigned_subref_r::to_double() const
123{
124    sc_unsigned a(m_obj_p, m_left, m_right);
125    return a.to_double();
126}
127
128
129// explicit conversion to character string
130const std::string
131sc_unsigned_subref_r::to_string(sc_numrep numrep) const
132{
133    sc_unsigned a(length());
134    a = *this;
135    return a.to_string(numrep);
136}
137
138const std::string
139sc_unsigned_subref_r::to_string(sc_numrep numrep, bool w_prefix) const
140{
141    sc_unsigned a(length());
142    a = *this;
143    return a.to_string(numrep, w_prefix);
144}
145
146
147// ----------------------------------------------------------------------------
148//  CLASS : sc_unsigned_subref
149//
150//  Proxy class for sc_unsigned part selection (r-value and l-value).
151// ----------------------------------------------------------------------------
152
153// assignment operators
154
155const sc_unsigned_subref &
156sc_unsigned_subref::operator = (const sc_unsigned_subref_r &a)
157{
158    return operator = ((sc_unsigned)(a));
159}
160
161const sc_unsigned_subref &
162sc_unsigned_subref::operator = (const sc_unsigned_subref &a)
163{
164    if (this == &a) {
165        return *this;
166    }
167    return operator = ((sc_unsigned)(a));
168}
169
170const sc_unsigned_subref &
171sc_unsigned_subref::operator = (const sc_unsigned &v)
172{
173    int i;
174    int l = sc_min(m_left, v.nbits - 1 + m_right);
175
176    for (i = m_right; i <= l; ++i)
177        m_obj_p->set(i, v.test(i - m_right));
178    for (; i <= m_left; i++)
179        m_obj_p->set(i, v.test(l));
180    return *this;
181}
182
183const sc_unsigned_subref &
184sc_unsigned_subref::operator = (const sc_signed_subref_r &v)
185{
186    return operator = ((sc_unsigned)(v));
187}
188
189const sc_unsigned_subref &
190sc_unsigned_subref::operator = (const sc_signed &v)
191{
192    int i;
193    int l = sc_min(m_left, v.nbits - 1 + m_right);
194
195    for (i = m_right; i <= l; ++i)
196        m_obj_p->set(i, v.test(i - m_right));
197    for (; i <= m_left; i++)
198        m_obj_p->set(i, 0);
199    return *this;
200}
201
202const sc_unsigned_subref &
203sc_unsigned_subref::operator = (unsigned long v)
204{
205    for (int i = m_right; i <= m_left; ++i) {
206        m_obj_p->set(i, static_cast<bool>(v & 1));
207        v >>= 1;
208    }
209    return *this;
210}
211
212const sc_unsigned_subref &
213sc_unsigned_subref::operator = (long v)
214{
215    unsigned long v2 = (unsigned long)v;
216    for (int i = m_right; i <= m_left; ++i) {
217        m_obj_p->set(i, static_cast<bool>(v2 & 1));
218        v2 >>= 1;
219    }
220    return *this;
221}
222
223const sc_unsigned_subref &
224sc_unsigned_subref::operator = (uint64 v)
225{
226    for (int i = m_right; i <= m_left; ++i) {
227        m_obj_p->set(i, static_cast<bool>(v & 1));
228        v >>= 1;
229    }
230    return *this;
231}
232
233const sc_unsigned_subref &
234sc_unsigned_subref::operator = (int64 v)
235{
236    uint64 v2 = (uint64)v;
237    for (int i = m_right; i <= m_left; ++i) {
238        m_obj_p->set(i, static_cast<bool>(v2 & 1));
239        v2 >>= 1;
240    }
241    return *this;
242}
243
244const sc_unsigned_subref &
245sc_unsigned_subref::operator = (double v)
246{
247    is_bad_double(v);
248
249    int nb = m_left - m_right + 1;
250    int nd = DIV_CEIL(nb);
251
252#ifdef SC_MAX_NBITS
253    sc_digit d[MAX_NDIGITS];
254#else
255    sc_digit *d = new sc_digit[nd];
256#endif
257
258    if (v < 0)
259        v = -v;
260
261    int i = 0;
262    while (std::floor(v) && (i < nd)) {
263        d[i++] = (sc_digit) std::floor(remainder(v, DIGIT_RADIX));
264        v /= DIGIT_RADIX;
265    }
266    vec_zero(i, nd, d);
267
268    sc_digit val = 1; // Bit value.
269    int j = 0; // Current digit in d.
270
271    i = 0; // Current bit in d.
272    while (i < nb) {
273        m_obj_p->set(i + m_right, (bool)(d[j] & val));
274        ++i;
275        if (i % BITS_PER_DIGIT == 0) {
276            val = 1;
277            ++j;
278        } else {
279            val <<= 1;
280        }
281    }
282#ifndef SC_MAX_NBITS
283    delete [] d;
284#endif
285    return *this;
286}
287
288const sc_unsigned_subref &
289sc_unsigned_subref::operator = (const sc_int_base &a)
290{
291    return operator = ((int64)a);
292}
293
294const sc_unsigned_subref &
295sc_unsigned_subref::operator = (const sc_uint_base &a)
296{
297    return operator = ((uint64)a);
298}
299
300// concatenation methods
301void
302sc_unsigned_subref::concat_set(int64 src, int low_i)
303{
304    int i;
305    int l;
306    bool sign = src < 0;
307
308    if (low_i < 64) {
309        src = src >> low_i;
310        l = sc_min(m_left, (63 - low_i) + m_right);
311        for (i = m_right; i <= l; ++i) {
312            m_obj_p->set(i, src & 1);
313            src = src >> 1;
314        }
315        for (; i <= m_left; i++)
316            m_obj_p->set(sign);
317    } else {
318        for (i = m_right; i <= m_left; ++i)
319            m_obj_p->set(sign);
320    }
321}
322
323void
324sc_unsigned_subref::concat_set(const sc_signed &src, int low_i)
325{
326    int i;
327    int l;
328    int src_i;
329    bool sign = src.test(src.nbits - 1);
330    l = src.nbits - (low_i + 1);
331    if (l >= 0) {
332        src_i = low_i;
333        l = sc_min(m_left, l + m_right);
334        for (i = m_right; i <= l; ++i, src_i++) {
335            m_obj_p->set(i, src.test(src_i));
336        }
337        for (; i <= m_left; i++)
338            m_obj_p->set(i, sign);
339    } else {
340        for (i = m_right; i <= m_left; ++i)
341            m_obj_p->set(i, sign);
342    }
343}
344
345void
346sc_unsigned_subref::concat_set(const sc_unsigned &src, int low_i)
347{
348    int i;
349    int l;
350    int src_i;
351    l = src.nbits - (low_i + 2);
352    if (l >= 0) {
353        src_i = low_i;
354        l = sc_min(m_left, l + m_right);
355        for (i = m_right; i <= l; ++i, src_i++) {
356            m_obj_p->set(i, src.test(src_i));
357        }
358        for (; i <= m_left; i++)
359            m_obj_p->set(i, false);
360    } else {
361        for (i = m_right; i <= m_left; ++i)
362            m_obj_p->set(i, false);
363    }
364}
365
366void
367sc_unsigned_subref::concat_set(uint64 src, int low_i)
368{
369    int  i;
370    int  l;
371
372    if (low_i < 64) {
373        src = src >> low_i;
374        l = sc_min(m_left, (63 - low_i) + m_right);
375        for (i = m_right; i <= l; ++i) {
376            m_obj_p->set(i, src & 1);
377            src = src >> 1;
378        }
379        for (; i <= m_left; i++)
380            m_obj_p->set(false);
381    } else {
382        for (i = m_right; i <= m_left; ++i)
383            m_obj_p->set(false);
384    }
385}
386
387// other methods
388void
389sc_unsigned_subref::scan(::std::istream &is)
390{
391    std::string s;
392    is >> s;
393    *this = s.c_str();
394}
395