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