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_signed_subref.h -- Proxy class that is declared in sc_signed.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_signed_subref_r
41//
42//  Proxy class for sc_signed part selection (r-value only).
43// ----------------------------------------------------------------------------
44
45// concatenation support
46
47uint64
48sc_signed_subref_r::concat_get_uint64() const
49{
50    sc_unsigned a(m_obj_p, m_left, m_right);
51    return a.to_uint64();
52}
53
54
55bool
56sc_signed_subref_r::concat_get_ctrl(sc_digit *dst_p, int low_i) const
57{
58    sc_unsigned a(m_obj_p, m_left, m_right);
59    return a.concat_get_ctrl(dst_p, low_i);
60}
61
62
63bool
64sc_signed_subref_r::concat_get_data(sc_digit *dst_p, int low_i) const
65{
66    sc_unsigned a(m_obj_p, m_left, m_right);
67    return a.concat_get_data(dst_p, low_i);
68}
69
70
71// implicit conversion to sc_signed
72sc_signed_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_signed_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_signed_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_signed_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_signed_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_signed_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_signed_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_signed_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_signed_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_signed_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_signed_subref
149//
150//  Proxy class for sc_signed part selection (r-value and l-value).
151// ----------------------------------------------------------------------------
152
153// assignment operators
154
155const sc_signed_subref &
156sc_signed_subref::operator = (const sc_signed_subref_r &a)
157{
158    return operator = ((sc_unsigned)(a));
159}
160
161const sc_signed_subref &
162sc_signed_subref::operator = (const sc_signed_subref &v)
163{
164    if (this == &v) {
165        return *this;
166    }
167    return operator = ((sc_unsigned)(v));
168}
169
170const sc_signed_subref &
171sc_signed_subref::operator = (const sc_signed &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
181    return *this;
182}
183
184const sc_signed_subref &
185sc_signed_subref::operator = (const sc_unsigned_subref_r &v)
186{
187    return operator = ((sc_unsigned)(v));
188}
189
190const sc_signed_subref &
191sc_signed_subref::operator = (const sc_unsigned &v)
192{
193    int i;
194    int l = sc_min(m_left, v.nbits - 1 + m_right);
195
196    for (i = m_right; i <= l; ++i)
197        m_obj_p->set(i, v.test(i - m_right));
198    for (; i <= m_left; i++)
199        m_obj_p->set(i, 0);
200    return *this;
201}
202
203const sc_signed_subref &
204sc_signed_subref::operator = (unsigned long v)
205{
206    for (int i = m_right; i <= m_left; ++i) {
207        m_obj_p->set(i, static_cast<bool>(v & 1));
208        v >>= 1;
209    }
210    return *this;
211}
212
213const sc_signed_subref &
214sc_signed_subref::operator = (long v)
215{
216    unsigned long v2 = (unsigned long)v;
217    for (int i = m_right; i <= m_left; ++i) {
218        m_obj_p->set(i, static_cast<bool>(v2 & 1));
219        v2 >>= 1;
220    }
221    return *this;
222}
223
224const sc_signed_subref &
225sc_signed_subref::operator = (uint64 v)
226{
227    for (int i = m_right; i <= m_left; ++i) {
228        m_obj_p->set(i, static_cast<bool>(v & 1));
229        v >>= 1;
230    }
231    return *this;
232}
233
234const sc_signed_subref &
235sc_signed_subref::operator = (int64 v)
236{
237    uint64 v2 = (uint64)v;
238    for (int i = m_right; i <= m_left; ++i) {
239        m_obj_p->set(i, static_cast<bool>(v2 & 1));
240        v2 >>= 1;
241    }
242    return *this;
243}
244
245const sc_signed_subref &
246sc_signed_subref::operator = (double v)
247{
248    is_bad_double(v);
249
250    int nb = m_left - m_right + 1;
251    int nd = DIV_CEIL(nb);
252
253#ifdef SC_MAX_NBITS
254    sc_digit d[MAX_NDIGITS];
255#else
256    sc_digit *d = new sc_digit[nd];
257#endif
258
259    if (v < 0)
260        v = -v;
261
262    int i = 0;
263
264    while (std::floor(v) && (i < nd)) {
265#ifndef _WIN32
266        d[i++] = (sc_digit) std::floor(remainder(v, DIGIT_RADIX));
267#else
268        d[i++] = (sc_digit) std::floor(std::fmod(v, DIGIT_RADIX));
269#endif
270        v /= DIGIT_RADIX;
271    }
272
273    vec_zero(i, nd, d);
274    sc_digit val = 1;  // Bit value.
275    int j = 0;   // Current digit in d.
276    i = 0;  // Current bit in d.
277    while (i < nb) {
278        m_obj_p->set(i + m_right, (bool)(d[j] & val));
279        ++i;
280        if (i % BITS_PER_DIGIT == 0) {
281            val = 1;
282            ++j;
283        } else {
284            val <<= 1;
285        }
286    }
287
288#ifndef SC_MAX_NBITS
289    delete [] d;
290#endif
291    return *this;
292}
293
294const sc_signed_subref &
295sc_signed_subref::operator = (const sc_int_base &a)
296{
297    return operator = ((int64)a);
298}
299
300const sc_signed_subref &
301sc_signed_subref::operator = (const sc_uint_base &a)
302{
303    return operator = ((uint64)a);
304}
305
306// concatenation methods
307
308
309void
310sc_signed_subref::concat_set(int64 src, int low_i)
311{
312    int  i;
313    int  l;
314    bool sign = src < 0;
315
316    if (low_i < 64) {
317        src = src >> low_i;
318        l = sc_min(m_left, (63 - low_i) + m_right);
319        for (i = m_right; i <= l; ++i) {
320            m_obj_p->set(i, src & 1);
321            src = src >> 1;
322        }
323        for (; i <= m_left; i++)
324            m_obj_p->set(i, sign);
325    } else {
326        for (i = m_right; i <= m_left; ++i)
327            m_obj_p->set(i, sign);
328    }
329}
330
331void
332sc_signed_subref::concat_set(const sc_signed &src, int low_i)
333{
334    int i;
335    int l;
336    int src_i;
337    bool sign = src.test(src.nbits - 1);
338    l = src.nbits - (low_i + 1);
339    if (l >= 0) {
340        l = sc_min(m_left, l + m_right);
341        src_i = low_i;
342        for (i = m_right; i <= l; ++i, src_i++) {
343            m_obj_p->set(i, src.test(src_i));
344        }
345        for (; i <= m_left; i++)
346            m_obj_p->set(i, sign);
347    } else {
348        for (i = m_right; i <= m_left; ++i)
349            m_obj_p->set(i, sign);
350    }
351}
352
353void
354sc_signed_subref::concat_set(const sc_unsigned &src, int low_i)
355{
356    int i;
357    int l;
358    int src_i;
359    l = src.nbits - (low_i + 2);
360    if (l >= 0) {
361        l = sc_min(m_left, l + m_right);
362        src_i = low_i;
363        for (i = m_right; i <= l; ++i, src_i++) {
364            m_obj_p->set(i, src.test(src_i));
365        }
366        for (; i <= m_left; i++)
367            m_obj_p->set(false);
368    } else {
369        for (i = m_right; i <= m_left; ++i)
370            m_obj_p->set(false);
371    }
372}
373
374void
375sc_signed_subref::concat_set(uint64 src, int low_i)
376{
377    int  i;
378    int  l;
379
380    if (low_i < 64) {
381        src = src >> low_i;
382        l = sc_min(m_left, (63 - low_i) + m_right);
383        for (i = m_right; i <= l; ++i) {
384            m_obj_p->set(i, src & 1);
385            src = src >> 1;
386        }
387        for (; i <= m_left; i++)
388            m_obj_p->set(false);
389    } else {
390        for (i = m_right; i <= m_left; ++i)
391            m_obj_p->set(false);
392    }
393}
394
395// other methods
396void
397sc_signed_subref::scan(::std::istream &is)
398{
399    std::string s;
400    is >> s;
401    *this = s.c_str();
402}
403