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 sc_signed_subref_r::concat_get_uint64() const
48{
49    sc_unsigned a( m_obj_p, m_left, m_right );
50    return a.to_uint64();
51}
52
53
54bool sc_signed_subref_r::concat_get_ctrl(sc_digit* dst_p, int low_i ) const
55{
56    sc_unsigned a( m_obj_p, m_left, m_right );
57    return a.concat_get_ctrl( dst_p, low_i );
58}
59
60
61bool sc_signed_subref_r::concat_get_data(sc_digit* dst_p, int low_i ) const
62{
63    sc_unsigned a( m_obj_p, m_left, m_right );
64    return a.concat_get_data( dst_p, low_i );
65}
66
67
68// implicit conversion to sc_signed
69
70sc_signed_subref_r::operator sc_unsigned () const
71{
72    return sc_unsigned( m_obj_p, m_left, m_right );
73}
74
75
76// explicit conversions
77
78int
79sc_signed_subref_r::to_int() const
80{
81    sc_unsigned a( m_obj_p, m_left, m_right );
82    return a.to_int();
83}
84
85unsigned int
86sc_signed_subref_r::to_uint() const
87{
88    sc_unsigned a( m_obj_p, m_left, m_right );
89    return a.to_uint();
90}
91
92long
93sc_signed_subref_r::to_long() const
94{
95    sc_unsigned a( m_obj_p, m_left, m_right );
96    return a.to_long();
97}
98
99unsigned long
100sc_signed_subref_r::to_ulong() const
101{
102    sc_unsigned a( m_obj_p, m_left, m_right );
103    return a.to_ulong();
104}
105
106int64
107sc_signed_subref_r::to_int64() const
108{
109    sc_unsigned a( m_obj_p, m_left, m_right );
110    return a.to_int64();
111}
112
113uint64
114sc_signed_subref_r::to_uint64() const
115{
116    sc_unsigned a( m_obj_p, m_left, m_right );
117    return a.to_uint64();
118}
119
120double
121sc_signed_subref_r::to_double() const
122{
123    sc_unsigned a( m_obj_p, m_left, m_right );
124    return a.to_double();
125}
126
127
128// explicit conversion to character string
129
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 ) m_obj_p->set( i, v.test( i - m_right ) );
177    for ( ; i <= m_left; i++ ) m_obj_p->set( i, v.test( l ) );
178
179    return *this;
180}
181
182const sc_signed_subref&
183sc_signed_subref::operator = ( const sc_unsigned_subref_r& v )
184{
185    return operator = ( (sc_unsigned)( v ) );
186}
187
188const sc_signed_subref&
189sc_signed_subref::operator = ( const sc_unsigned& 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_signed_subref&
200sc_signed_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_signed_subref&
210sc_signed_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_signed_subref&
221sc_signed_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_signed_subref&
231sc_signed_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_signed_subref&
242sc_signed_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_signed_subref&
298sc_signed_subref::operator = ( const sc_int_base& a )
299{
300    return operator = ( (int64) a );
301}
302
303const sc_signed_subref&
304sc_signed_subref::operator = ( const sc_uint_base& a )
305{
306    return operator = ( (uint64) a );
307}
308
309// concatenation methods
310
311
312void sc_signed_subref::concat_set( int64 src, int low_i )
313{
314    int  i;
315    int  l;
316    bool sign = src < 0;
317
318    if ( low_i < 64 )
319    {
320	src = src >> low_i;
321	l = sc_min( m_left, (63-low_i) + m_right );
322	for( i = m_right; i <= l; ++ i ) {
323		m_obj_p->set( i, src & 1 );
324		src = src >> 1;
325	}
326	for ( ; i <= m_left; i++ ) m_obj_p->set(i, sign);
327    }
328    else
329    {
330	for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(i, sign);
331    }
332}
333
334void sc_signed_subref::concat_set( const sc_signed& src, int low_i )
335{
336    int i;
337    int l;
338    int src_i;
339    bool sign = src.test(src.nbits-1);
340    l = src.nbits - (low_i+1);
341    if ( l >= 0 )
342    {
343	l = sc_min( m_left, l + m_right );
344	src_i = low_i;
345	for( i = m_right; i <= l; ++ i, src_i++ ) {
346	    m_obj_p->set( i, src.test( src_i ) );
347	}
348	for ( ; i <= m_left; i++ ) m_obj_p->set(i, sign);
349    }
350    else
351    {
352	for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(i, sign);
353    }
354}
355
356void sc_signed_subref::concat_set( const sc_unsigned& src, int low_i )
357{
358    int i;
359    int l;
360    int src_i;
361    l = src.nbits - (low_i+2);
362    if ( l >= 0 )
363    {
364	l = sc_min( m_left, l + m_right );
365	src_i = low_i;
366	for( i = m_right; i <= l; ++ i, src_i++ ) {
367	    m_obj_p->set( i, src.test( src_i ) );
368	}
369	for ( ; i <= m_left; i++ ) m_obj_p->set(false);
370    }
371    else
372    {
373	for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(false);
374    }
375}
376
377void sc_signed_subref::concat_set( uint64 src, int low_i )
378{
379    int  i;
380    int  l;
381
382    if ( low_i < 64 )
383    {
384	src = src >> low_i;
385	l = sc_min( m_left, (63-low_i) + m_right );
386	for( i = m_right; i <= l; ++ i ) {
387		m_obj_p->set( i, src & 1 );
388		src = src >> 1;
389	}
390	for ( ; i <= m_left; i++ ) m_obj_p->set(false);
391    }
392    else
393    {
394	for( i = m_right; i <= m_left; ++ i ) m_obj_p->set(false);
395    }
396}
397// other methods
398
399void
400sc_signed_subref::scan( ::std::istream& is )
401{
402    std::string s;
403    is >> s;
404    *this = s.c_str();
405}
406
407
408// End of file
409