sc_int_base.cc (12854:c95c35407325) sc_int_base.cc (13138:31951157e41e)
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_int_base.cpp -- contains interface definitions between sc_int and
23 sc_signed, sc_unsigned, and definitions for sc_int_subref.
24
25 Original Author: Ali Dasdan, Synopsys, Inc.
26
27 *****************************************************************************/
28
29/*****************************************************************************
30
31 MODIFICATION LOG - modifiers, enter your name, affiliation, date and
32 changes you are making here.
33
34 Name, Affiliation, Date:
35 Description of Modification:
36
37 *****************************************************************************/
38
39
40// $Log: sc_int_base.cpp,v $
41// Revision 1.5 2011/02/18 20:19:14 acg
42// Andy Goodrich: updating Copyright notice.
43//
44// Revision 1.4 2010/02/04 22:23:29 acg
45// Andy Goodrich: fixed bug in concatenation reads for part selections,
46// the mask being used was 32 bits and should have been 64 bits.
47//
48// Revision 1.3 2008/06/19 17:47:56 acg
49// Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES.
50//
51// Revision 1.2 2007/11/04 21:27:00 acg
52// Andy Goodrich: changes to make sure the proper value is returned from
53// concat_get_data().
54//
55// Revision 1.1.1.1 2006/12/15 20:20:05 acg
56// SystemC 2.3
57//
58// Revision 1.3 2006/01/13 18:49:31 acg
59// Added $Log command so that CVS check in comments are reproduced in the
60// source.
61//
62
63#include <sstream>
64
65#include "systemc/ext/dt/bit/sc_bv_base.hh"
66#include "systemc/ext/dt/bit/sc_lv_base.hh"
67#include "systemc/ext/dt/fx/sc_fix.hh"
68#include "systemc/ext/dt/fx/scfx_other_defs.hh"
69#include "systemc/ext/dt/int/sc_int_base.hh"
70#include "systemc/ext/dt/int/sc_signed.hh"
71#include "systemc/ext/dt/int/sc_uint_base.hh"
72#include "systemc/ext/dt/int/sc_unsigned.hh"
73#include "systemc/ext/dt/misc/sc_concatref.hh"
74
75// explicit template instantiations
76namespace sc_core
77{
78
79template class sc_vpool<sc_dt::sc_int_bitref>;
80template class sc_vpool<sc_dt::sc_int_subref>;
81
82} // namespace sc_core
83
84namespace sc_dt
85{
86
87// to avoid code bloat in sc_int_concref<T1,T2>
88
89void
90sc_int_concref_invalid_length(int length)
91{
92 std::stringstream msg;
93 msg << "sc_int_concref<T1,T2> initialization: length = " << length <<
94 "violates 1 <= length <= " << SC_INTWIDTH;
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_int_base.cpp -- contains interface definitions between sc_int and
23 sc_signed, sc_unsigned, and definitions for sc_int_subref.
24
25 Original Author: Ali Dasdan, Synopsys, Inc.
26
27 *****************************************************************************/
28
29/*****************************************************************************
30
31 MODIFICATION LOG - modifiers, enter your name, affiliation, date and
32 changes you are making here.
33
34 Name, Affiliation, Date:
35 Description of Modification:
36
37 *****************************************************************************/
38
39
40// $Log: sc_int_base.cpp,v $
41// Revision 1.5 2011/02/18 20:19:14 acg
42// Andy Goodrich: updating Copyright notice.
43//
44// Revision 1.4 2010/02/04 22:23:29 acg
45// Andy Goodrich: fixed bug in concatenation reads for part selections,
46// the mask being used was 32 bits and should have been 64 bits.
47//
48// Revision 1.3 2008/06/19 17:47:56 acg
49// Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES.
50//
51// Revision 1.2 2007/11/04 21:27:00 acg
52// Andy Goodrich: changes to make sure the proper value is returned from
53// concat_get_data().
54//
55// Revision 1.1.1.1 2006/12/15 20:20:05 acg
56// SystemC 2.3
57//
58// Revision 1.3 2006/01/13 18:49:31 acg
59// Added $Log command so that CVS check in comments are reproduced in the
60// source.
61//
62
63#include <sstream>
64
65#include "systemc/ext/dt/bit/sc_bv_base.hh"
66#include "systemc/ext/dt/bit/sc_lv_base.hh"
67#include "systemc/ext/dt/fx/sc_fix.hh"
68#include "systemc/ext/dt/fx/scfx_other_defs.hh"
69#include "systemc/ext/dt/int/sc_int_base.hh"
70#include "systemc/ext/dt/int/sc_signed.hh"
71#include "systemc/ext/dt/int/sc_uint_base.hh"
72#include "systemc/ext/dt/int/sc_unsigned.hh"
73#include "systemc/ext/dt/misc/sc_concatref.hh"
74
75// explicit template instantiations
76namespace sc_core
77{
78
79template class sc_vpool<sc_dt::sc_int_bitref>;
80template class sc_vpool<sc_dt::sc_int_subref>;
81
82} // namespace sc_core
83
84namespace sc_dt
85{
86
87// to avoid code bloat in sc_int_concref<T1,T2>
88
89void
90sc_int_concref_invalid_length(int length)
91{
92 std::stringstream msg;
93 msg << "sc_int_concref<T1,T2> initialization: length = " << length <<
94 "violates 1 <= length <= " << SC_INTWIDTH;
95 SC_REPORT_ERROR("out of bounds", msg.str().c_str());
95 SC_REPORT_ERROR("(E5) out of bounds", msg.str().c_str());
96 sc_core::sc_abort(); // can't recover from here
97}
98
99
100// ----------------------------------------------------------------------------
101// CLASS : sc_int_bitref
102//
103// Proxy class for sc_int bit selection (r-value and l-value).
104// ----------------------------------------------------------------------------
105
106sc_core::sc_vpool<sc_int_bitref> sc_int_bitref::m_pool(9);
107
108// concatenation methods:
109
110// #### OPTIMIZE
111void sc_int_bitref::concat_set(int64 src, int low_i)
112{
113 sc_int_base aa(1);
114 *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
115}
116
117void sc_int_bitref::concat_set(const sc_signed &src, int low_i)
118{
119 sc_int_base aa(1);
120 if (low_i < src.length())
121 *this = aa = 1 & (src >> low_i);
122 else
123 *this = aa = (src < 0) ? (int_type)-1 : 0;
124}
125
126void sc_int_bitref::concat_set(const sc_unsigned &src, int low_i)
127{
128 sc_int_base aa(1);
129 if (low_i < src.length())
130 *this = aa = 1 & (src >> low_i);
131 else
132 *this = aa = 0;
133}
134
135void sc_int_bitref::concat_set(uint64 src, int low_i)
136{
137 sc_int_base aa(1);
138 *this = aa = (low_i < 64) ? src >> low_i : 0;
139}
140
141
142// other methods
143void
144sc_int_bitref::scan(::std::istream &is)
145{
146 bool b;
147 is >> b;
148 *this = b;
149}
150
151
152// ----------------------------------------------------------------------------
153// CLASS : sc_int_subref_r
154//
155// Proxy class for sc_int part selection (l-value).
156// ----------------------------------------------------------------------------
157
158bool
159sc_int_subref_r::concat_get_ctrl(sc_digit *dst_p, int low_i) const
160{
161 int dst_i; // Word in dst_p now processing.
162 int end_i; // Highest order word in dst_p to process.
163 int high_i; // Index of high order bit in dst_p to set.
164 uint_type mask; // Mask for bits to extract or keep.
165
166 dst_i = low_i / BITS_PER_DIGIT;
167 high_i = low_i + (m_left - m_right);
168 end_i = high_i / BITS_PER_DIGIT;
169 mask = ~mask_int[m_left][m_right];
170
171 // PROCESS THE FIRST WORD:
172 dst_p[dst_i] = (sc_digit)(dst_p[dst_i] & mask);
173 switch (end_i - dst_i) {
174 // BITS ARE ACROSS TWO WORDS:
175 case 1:
176 dst_i++;
177 dst_p[dst_i] = 0;
178 break;
179
180 // BITS ARE ACROSS THREE WORDS:
181 case 2:
182 dst_i++;
183 dst_p[dst_i++] = 0;
184 dst_p[dst_i] = 0;
185 break;
186
187 // BITS ARE ACROSS FOUR WORDS:
188 case 3:
189 dst_i++;
190 dst_p[dst_i++] = 0;
191 dst_p[dst_i++] = 0;
192 dst_p[dst_i] = 0;
193 break;
194 }
195 return false;
196}
197
198bool
199sc_int_subref_r::concat_get_data(sc_digit *dst_p, int low_i) const
200{
201 int dst_i; // Word in dst_p now processing.
202 int end_i; // Highest order word in dst_p to process.
203 int high_i; // Index of high order bit in dst_p to set.
204 int left_shift; // Left shift for val.
205 uint_type mask; // Mask for bits to extract or keep.
206 bool non_zero; // True if value inserted is non-zero.
207 uint_type val; // Selection value extracted from m_obj_p.
208
209 dst_i = low_i / BITS_PER_DIGIT;
210 left_shift = low_i % BITS_PER_DIGIT;
211 high_i = low_i + (m_left-m_right);
212 end_i = high_i / BITS_PER_DIGIT;
213 mask = ~mask_int[m_left][m_right];
214 val = (m_obj_p->m_val & mask) >> m_right;
215 non_zero = val != 0;
216
217 // PROCESS THE FIRST WORD:
218 mask = ~(~UINT_ZERO << left_shift);
219 dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask) |
220 ((val << left_shift) & DIGIT_MASK));
221
222 switch (end_i - dst_i) {
223 // BITS ARE ACROSS TWO WORDS:
224 case 1:
225 dst_i++;
226 val >>= (BITS_PER_DIGIT - left_shift);
227 dst_p[dst_i] = (sc_digit)(val & DIGIT_MASK);
228 break;
229
230 // BITS ARE ACROSS THREE WORDS:
231 case 2:
232 dst_i++;
233 val >>= (BITS_PER_DIGIT - left_shift);
234 dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
235 val >>= BITS_PER_DIGIT;
236 dst_p[dst_i] = (sc_digit)val;
237 break;
238
239 // BITS ARE ACROSS FOUR WORDS:
240 case 3:
241 dst_i++;
242 val >>= (BITS_PER_DIGIT - left_shift);
243 dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
244 val >>= BITS_PER_DIGIT;
245 dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
246 val >>= BITS_PER_DIGIT;
247 dst_p[dst_i] = (sc_digit)val;
248 break;
249 }
250 return non_zero;
251}
252
253// ----------------------------------------------------------------------------
254// CLASS : sc_int_subref
255//
256// Proxy class for sc_int part selection (r-value and l-value).
257// ----------------------------------------------------------------------------
258
259sc_core::sc_vpool<sc_int_subref> sc_int_subref::m_pool(9);
260
261// assignment operators
262
263sc_int_subref &
264sc_int_subref::operator = (int_type v)
265{
266 int_type val = m_obj_p->m_val;
267 uint_type mask = mask_int[m_left][m_right];
268 val &= mask;
269 val |= (v << m_right) & ~mask;
270 m_obj_p->m_val = val;
271 m_obj_p->extend_sign();
272 return *this;
273}
274
275sc_int_subref &
276sc_int_subref::operator = (const sc_signed &a)
277{
278 sc_int_base aa(length());
279 return (*this = aa = a);
280}
281
282sc_int_subref &
283sc_int_subref::operator = (const sc_unsigned &a)
284{
285 sc_int_base aa(length());
286 return (*this = aa = a);
287}
288
289sc_int_subref &
290sc_int_subref::operator = (const sc_bv_base &a)
291{
292 sc_int_base aa(length());
293 return (*this = aa = a);
294}
295
296sc_int_subref &
297sc_int_subref::operator = (const sc_lv_base &a)
298{
299 sc_int_base aa(length());
300 return (*this = aa = a);
301}
302
303
304// concatenation methods:
305// #### OPTIMIZE
306void
307sc_int_subref::concat_set(int64 src, int low_i)
308{
309 sc_int_base aa(length());
310 *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
311}
312
313void
314sc_int_subref::concat_set(const sc_signed &src, int low_i)
315{
316 sc_int_base aa(length());
317 if (low_i < src.length())
318 *this = aa = src >> low_i;
319 else
320 *this = (src < 0) ? (int_type)-1 : 0;
321}
322
323void
324sc_int_subref::concat_set(const sc_unsigned &src, int low_i)
325{
326 sc_int_base aa(length());
327 if (low_i < src.length())
328 *this = aa = src >> low_i;
329 else
330 *this = 0;
331}
332
333void
334sc_int_subref::concat_set(uint64 src, int low_i)
335{
336 sc_int_base aa (length());
337 *this = aa = (low_i < 64) ? src >> low_i : 0;
338}
339
340
341// other methods
342void
343sc_int_subref::scan(::std::istream &is)
344{
345 std::string s;
346 is >> s;
347 *this = s.c_str();
348}
349
350
351// ----------------------------------------------------------------------------
352// CLASS : sc_int_base
353//
354// Base class for sc_int.
355// ----------------------------------------------------------------------------
356
357// support methods
358void
359sc_int_base::invalid_length() const
360{
361 std::stringstream msg;
362 msg << "sc_int[_base] initialization: length = " << m_len <<
363 " violates 1 <= length <= " << SC_INTWIDTH;
96 sc_core::sc_abort(); // can't recover from here
97}
98
99
100// ----------------------------------------------------------------------------
101// CLASS : sc_int_bitref
102//
103// Proxy class for sc_int bit selection (r-value and l-value).
104// ----------------------------------------------------------------------------
105
106sc_core::sc_vpool<sc_int_bitref> sc_int_bitref::m_pool(9);
107
108// concatenation methods:
109
110// #### OPTIMIZE
111void sc_int_bitref::concat_set(int64 src, int low_i)
112{
113 sc_int_base aa(1);
114 *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
115}
116
117void sc_int_bitref::concat_set(const sc_signed &src, int low_i)
118{
119 sc_int_base aa(1);
120 if (low_i < src.length())
121 *this = aa = 1 & (src >> low_i);
122 else
123 *this = aa = (src < 0) ? (int_type)-1 : 0;
124}
125
126void sc_int_bitref::concat_set(const sc_unsigned &src, int low_i)
127{
128 sc_int_base aa(1);
129 if (low_i < src.length())
130 *this = aa = 1 & (src >> low_i);
131 else
132 *this = aa = 0;
133}
134
135void sc_int_bitref::concat_set(uint64 src, int low_i)
136{
137 sc_int_base aa(1);
138 *this = aa = (low_i < 64) ? src >> low_i : 0;
139}
140
141
142// other methods
143void
144sc_int_bitref::scan(::std::istream &is)
145{
146 bool b;
147 is >> b;
148 *this = b;
149}
150
151
152// ----------------------------------------------------------------------------
153// CLASS : sc_int_subref_r
154//
155// Proxy class for sc_int part selection (l-value).
156// ----------------------------------------------------------------------------
157
158bool
159sc_int_subref_r::concat_get_ctrl(sc_digit *dst_p, int low_i) const
160{
161 int dst_i; // Word in dst_p now processing.
162 int end_i; // Highest order word in dst_p to process.
163 int high_i; // Index of high order bit in dst_p to set.
164 uint_type mask; // Mask for bits to extract or keep.
165
166 dst_i = low_i / BITS_PER_DIGIT;
167 high_i = low_i + (m_left - m_right);
168 end_i = high_i / BITS_PER_DIGIT;
169 mask = ~mask_int[m_left][m_right];
170
171 // PROCESS THE FIRST WORD:
172 dst_p[dst_i] = (sc_digit)(dst_p[dst_i] & mask);
173 switch (end_i - dst_i) {
174 // BITS ARE ACROSS TWO WORDS:
175 case 1:
176 dst_i++;
177 dst_p[dst_i] = 0;
178 break;
179
180 // BITS ARE ACROSS THREE WORDS:
181 case 2:
182 dst_i++;
183 dst_p[dst_i++] = 0;
184 dst_p[dst_i] = 0;
185 break;
186
187 // BITS ARE ACROSS FOUR WORDS:
188 case 3:
189 dst_i++;
190 dst_p[dst_i++] = 0;
191 dst_p[dst_i++] = 0;
192 dst_p[dst_i] = 0;
193 break;
194 }
195 return false;
196}
197
198bool
199sc_int_subref_r::concat_get_data(sc_digit *dst_p, int low_i) const
200{
201 int dst_i; // Word in dst_p now processing.
202 int end_i; // Highest order word in dst_p to process.
203 int high_i; // Index of high order bit in dst_p to set.
204 int left_shift; // Left shift for val.
205 uint_type mask; // Mask for bits to extract or keep.
206 bool non_zero; // True if value inserted is non-zero.
207 uint_type val; // Selection value extracted from m_obj_p.
208
209 dst_i = low_i / BITS_PER_DIGIT;
210 left_shift = low_i % BITS_PER_DIGIT;
211 high_i = low_i + (m_left-m_right);
212 end_i = high_i / BITS_PER_DIGIT;
213 mask = ~mask_int[m_left][m_right];
214 val = (m_obj_p->m_val & mask) >> m_right;
215 non_zero = val != 0;
216
217 // PROCESS THE FIRST WORD:
218 mask = ~(~UINT_ZERO << left_shift);
219 dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask) |
220 ((val << left_shift) & DIGIT_MASK));
221
222 switch (end_i - dst_i) {
223 // BITS ARE ACROSS TWO WORDS:
224 case 1:
225 dst_i++;
226 val >>= (BITS_PER_DIGIT - left_shift);
227 dst_p[dst_i] = (sc_digit)(val & DIGIT_MASK);
228 break;
229
230 // BITS ARE ACROSS THREE WORDS:
231 case 2:
232 dst_i++;
233 val >>= (BITS_PER_DIGIT - left_shift);
234 dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
235 val >>= BITS_PER_DIGIT;
236 dst_p[dst_i] = (sc_digit)val;
237 break;
238
239 // BITS ARE ACROSS FOUR WORDS:
240 case 3:
241 dst_i++;
242 val >>= (BITS_PER_DIGIT - left_shift);
243 dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
244 val >>= BITS_PER_DIGIT;
245 dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
246 val >>= BITS_PER_DIGIT;
247 dst_p[dst_i] = (sc_digit)val;
248 break;
249 }
250 return non_zero;
251}
252
253// ----------------------------------------------------------------------------
254// CLASS : sc_int_subref
255//
256// Proxy class for sc_int part selection (r-value and l-value).
257// ----------------------------------------------------------------------------
258
259sc_core::sc_vpool<sc_int_subref> sc_int_subref::m_pool(9);
260
261// assignment operators
262
263sc_int_subref &
264sc_int_subref::operator = (int_type v)
265{
266 int_type val = m_obj_p->m_val;
267 uint_type mask = mask_int[m_left][m_right];
268 val &= mask;
269 val |= (v << m_right) & ~mask;
270 m_obj_p->m_val = val;
271 m_obj_p->extend_sign();
272 return *this;
273}
274
275sc_int_subref &
276sc_int_subref::operator = (const sc_signed &a)
277{
278 sc_int_base aa(length());
279 return (*this = aa = a);
280}
281
282sc_int_subref &
283sc_int_subref::operator = (const sc_unsigned &a)
284{
285 sc_int_base aa(length());
286 return (*this = aa = a);
287}
288
289sc_int_subref &
290sc_int_subref::operator = (const sc_bv_base &a)
291{
292 sc_int_base aa(length());
293 return (*this = aa = a);
294}
295
296sc_int_subref &
297sc_int_subref::operator = (const sc_lv_base &a)
298{
299 sc_int_base aa(length());
300 return (*this = aa = a);
301}
302
303
304// concatenation methods:
305// #### OPTIMIZE
306void
307sc_int_subref::concat_set(int64 src, int low_i)
308{
309 sc_int_base aa(length());
310 *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
311}
312
313void
314sc_int_subref::concat_set(const sc_signed &src, int low_i)
315{
316 sc_int_base aa(length());
317 if (low_i < src.length())
318 *this = aa = src >> low_i;
319 else
320 *this = (src < 0) ? (int_type)-1 : 0;
321}
322
323void
324sc_int_subref::concat_set(const sc_unsigned &src, int low_i)
325{
326 sc_int_base aa(length());
327 if (low_i < src.length())
328 *this = aa = src >> low_i;
329 else
330 *this = 0;
331}
332
333void
334sc_int_subref::concat_set(uint64 src, int low_i)
335{
336 sc_int_base aa (length());
337 *this = aa = (low_i < 64) ? src >> low_i : 0;
338}
339
340
341// other methods
342void
343sc_int_subref::scan(::std::istream &is)
344{
345 std::string s;
346 is >> s;
347 *this = s.c_str();
348}
349
350
351// ----------------------------------------------------------------------------
352// CLASS : sc_int_base
353//
354// Base class for sc_int.
355// ----------------------------------------------------------------------------
356
357// support methods
358void
359sc_int_base::invalid_length() const
360{
361 std::stringstream msg;
362 msg << "sc_int[_base] initialization: length = " << m_len <<
363 " violates 1 <= length <= " << SC_INTWIDTH;
364 SC_REPORT_ERROR("out of bounds", msg.str().c_str());
364 SC_REPORT_ERROR("(E5) out of bounds", msg.str().c_str());
365 sc_core::sc_abort(); // can't recover from here
366}
367
368void
369sc_int_base::invalid_index(int i) const
370{
371 std::stringstream msg;
372 msg << "sc_int[_base] bit selection: index = " << i <<
373 " violates 0 <= index <= " << (m_len - 1);
365 sc_core::sc_abort(); // can't recover from here
366}
367
368void
369sc_int_base::invalid_index(int i) const
370{
371 std::stringstream msg;
372 msg << "sc_int[_base] bit selection: index = " << i <<
373 " violates 0 <= index <= " << (m_len - 1);
374 SC_REPORT_ERROR("out of bounds", msg.str().c_str());
374 SC_REPORT_ERROR("(E5) out of bounds", msg.str().c_str());
375 sc_core::sc_abort(); // can't recover from here
376}
377
378void
379sc_int_base::invalid_range(int l, int r) const
380{
381 std::stringstream msg;
382 msg << "sc_int[_base] part selection: " <<
383 "left = " << l << ", right = " << r << " violates " <<
384 (m_len-1) << " >= left >= right >= 0";
375 sc_core::sc_abort(); // can't recover from here
376}
377
378void
379sc_int_base::invalid_range(int l, int r) const
380{
381 std::stringstream msg;
382 msg << "sc_int[_base] part selection: " <<
383 "left = " << l << ", right = " << r << " violates " <<
384 (m_len-1) << " >= left >= right >= 0";
385 SC_REPORT_ERROR("out of bounds", msg.str().c_str());
385 SC_REPORT_ERROR("(E5) out of bounds", msg.str().c_str());
386 sc_core::sc_abort(); // can't recover from here
387}
388
389void
390sc_int_base::check_value() const
391{
392 int_type limit = (int_type)1 << (m_len - 1);
393 if (m_val < -limit || m_val >= limit) {
394 std::stringstream msg;
395 msg << "sc_int[_base]: value does not fit into a length of " << m_len;
386 sc_core::sc_abort(); // can't recover from here
387}
388
389void
390sc_int_base::check_value() const
391{
392 int_type limit = (int_type)1 << (m_len - 1);
393 if (m_val < -limit || m_val >= limit) {
394 std::stringstream msg;
395 msg << "sc_int[_base]: value does not fit into a length of " << m_len;
396 SC_REPORT_WARNING("out of bounds", msg.str().c_str());
396 SC_REPORT_WARNING("(E5) out of bounds", msg.str().c_str());
397 }
398}
399
400
401// constructors
402sc_int_base::sc_int_base(const sc_bv_base &v) :
403 m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
404{
405 check_length();
406 *this = v;
407}
408sc_int_base::sc_int_base(const sc_lv_base &v) :
409 m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
410{
411 check_length();
412 *this = v;
413}
414sc_int_base::sc_int_base(const sc_uint_subref_r &v) :
415 m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
416{
417 check_length();
418 *this = v.to_uint64();
419}
420sc_int_base::sc_int_base(const sc_signed_subref_r &v) :
421 m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
422{
423 check_length();
424 *this = v.to_uint64();
425}
426sc_int_base::sc_int_base(const sc_unsigned_subref_r &v) :
427 m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
428{
429 check_length();
430 *this = v.to_uint64();
431}
432
433sc_int_base::sc_int_base(const sc_signed &a) :
434 m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
435{
436 check_length();
437 *this = a.to_int64();
438}
439
440sc_int_base::sc_int_base(const sc_unsigned &a) :
441 m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
442{
443 check_length();
444 *this = a.to_int64();
445}
446
447
448// assignment operators
449sc_int_base &
450sc_int_base::operator = (const sc_signed &a)
451{
452 int minlen = sc_min(m_len, a.length());
453 int i = 0;
454 for (; i < minlen; ++i) {
455 set(i, a.test(i));
456 }
457 bool sgn = a.sign();
458 for (; i < m_len; ++i) {
459 // sign extension
460 set(i, sgn);
461 }
462 extend_sign();
463 return *this;
464}
465
466sc_int_base &
467sc_int_base::operator = (const sc_unsigned &a)
468{
469 int minlen = sc_min(m_len, a.length());
470 int i = 0;
471 for (; i < minlen; ++i) {
472 set(i, a.test(i));
473 }
474 for (; i < m_len; ++i) {
475 // zero extension
476 set(i, 0);
477 }
478 extend_sign();
479 return *this;
480}
481
482
483sc_int_base &
484sc_int_base::operator = (const sc_bv_base &a)
485{
486 int minlen = sc_min(m_len, a.length());
487 int i = 0;
488 for (; i < minlen; ++i) {
489 set(i, a.get_bit(i));
490 }
491 for (; i < m_len; ++i) {
492 // zero extension
493 set(i, 0);
494 }
495 extend_sign();
496 return *this;
497}
498
499sc_int_base &
500sc_int_base::operator = (const sc_lv_base &a)
501{
502 int minlen = sc_min(m_len, a.length());
503 int i = 0;
504 for (; i < minlen; ++i) {
505 set(i, sc_logic(a.get_bit(i)).to_bool());
506 }
507 for (; i < m_len; ++i) {
508 // zero extension
509 set(i, 0);
510 }
511 extend_sign();
512 return *this;
513}
514
515sc_int_base &
516sc_int_base::operator = (const char *a)
517{
518 if (a == 0) {
519 SC_REPORT_ERROR("conversion failed",
520 "character string is zero");
521 } else if (*a == 0) {
522 SC_REPORT_ERROR("conversion failed",
523 "character string is empty");
524 } else try {
525 int len = m_len;
526 sc_fix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
527 return this->operator = (aa);
528 } catch(const sc_core::sc_report &) {
529 std::stringstream msg;
530 msg << "character string '" << a << "' is not valid";
531 SC_REPORT_ERROR("conversion failed", msg.str().c_str());
532 }
533 return *this;
534}
535
536// explicit conversion to character string
537const std::string
538sc_int_base::to_string(sc_numrep numrep) const
539{
540 int len = m_len;
541 sc_fix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
542 return aa.to_string(numrep);
543}
544
545const std::string
546sc_int_base::to_string(sc_numrep numrep, bool w_prefix) const
547{
548 int len = m_len;
549 sc_fix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
550 return aa.to_string(numrep, w_prefix);
551}
552
553
554// reduce methods
555bool sc_int_base::and_reduce() const { return (m_val == int_type(-1)); }
556bool sc_int_base::or_reduce() const { return (m_val != int_type(0)); }
557
558bool
559sc_int_base::xor_reduce() const
560{
561 uint_type mask = ~UINT_ZERO;
562 uint_type val = m_val & (mask >> m_ulen);
563 int n = SC_INTWIDTH;
564 do {
565 n >>= 1;
566 mask >>= n;
567 val = ((val & (mask << n)) >> n) ^ (val & mask);
568 } while (n != 1);
569 return (val != uint_type(0));
570}
571
572bool
573sc_int_base::concat_get_ctrl(sc_digit *dst_p, int low_i) const
574{
575 int dst_i; // Word in dst_p now processing.
576 int end_i; // Highest order word in dst_p to process.
577 int left_shift; // Left shift for val.
578 uint_type mask; // Mask for bits to extract or keep.
579
580 dst_i = low_i / BITS_PER_DIGIT;
581 left_shift = low_i % BITS_PER_DIGIT;
582 end_i = (low_i + (m_len - 1)) / BITS_PER_DIGIT;
583
584 mask = ~(~UINT_ZERO << left_shift);
585 dst_p[dst_i] = (sc_digit)(dst_p[dst_i] & mask);
586 dst_i++;
587 for (; dst_i <= end_i; dst_i++)
588 dst_p[dst_i] = 0;
589 return false;
590}
591
592//-----------------------------------------------------------------------------
593//"sc_int_base::concat_get_data"
594//
595// This method transfers the value of this object instance to the supplied
596// array of sc_unsigned digits starting with the bit specified by low_i within
597// the array of digits.
598//
599// Notes:
600// (1) we don't worry about masking the high order data we transfer since
601// concat_get_data() is called from low order bit to high order bit. So
602// the bits above where we place ours will be filled in by someone else.
603//
604// dst_p -> array of sc_unsigned digits to be filled in.
605// low_i = first bit within dst_p to be set.
606//-----------------------------------------------------------------------------
607bool
608sc_int_base::concat_get_data(sc_digit *dst_p, int low_i) const
609{
610 int dst_i; // Word in dst_p now processing.
611 int end_i; // Highest order word in dst_p to process.
612 int high_i; // Index of high order bit in dst_p to set.
613 int left_shift; // Left shift for val.
614 uint_type mask; // Mask for bits to extract or keep.
615 bool non_zero; // True if value inserted is non-zero.
616 uint_type val; // Value for this object.
617
618 dst_i = low_i / BITS_PER_DIGIT;
619 left_shift = low_i % BITS_PER_DIGIT;
620 high_i = low_i + (m_len - 1);
621 end_i = high_i / BITS_PER_DIGIT;
622 val = m_val;
623 non_zero = val != 0;
624
625 // MASK OFF DATA TO BE TRANSFERRED BASED ON WIDTH:
626 if (m_len < 64) {
627 mask = ~(~UINT_ZERO << m_len);
628 val &= mask;
629 }
630
631 // PROCESS THE FIRST WORD:
632 mask = (~UINT_ZERO << left_shift);
633 dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & ~mask) |
634 ((val <<left_shift) & DIGIT_MASK));
635 switch (end_i - dst_i) {
636 // BITS ARE ACROSS TWO WORDS:
637 case 1:
638 dst_i++;
639 val >>= (BITS_PER_DIGIT - left_shift);
640 dst_p[dst_i] = (sc_digit)val;
641 break;
642
643 // BITS ARE ACROSS THREE WORDS:
644 case 2:
645 dst_i++;
646 val >>= (BITS_PER_DIGIT - left_shift);
647 dst_p[dst_i++] = ((sc_digit)val) & DIGIT_MASK;
648 val >>= BITS_PER_DIGIT;
649 dst_p[dst_i] = (sc_digit)val;
650 break;
651
652 // BITS ARE ACROSS FOUR WORDS:
653 case 3:
654 dst_i++;
655 val >>= (BITS_PER_DIGIT - left_shift);
656 dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
657 val >>= BITS_PER_DIGIT;
658 dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
659 val >>= BITS_PER_DIGIT;
660 dst_p[dst_i] = (sc_digit)val;
661 break;
662 }
663 return non_zero;
664}
665
666// #### OPTIMIZE
667void
668sc_int_base::concat_set(int64 src, int low_i)
669{
670 *this = (low_i < 64) ? src >> low_i : src >> 63;
671}
672
673void
674sc_int_base::concat_set(const sc_signed &src, int low_i)
675{
676 if (low_i < src.length())
677 *this = src >> low_i;
678 else
679 *this = (src < 0) ? (int_type)-1 : 0;
680}
681
682void
683sc_int_base::concat_set(const sc_unsigned &src, int low_i)
684{
685 if (low_i < src.length())
686 *this = src >> low_i;
687 else
688 *this = 0;
689}
690
691void
692sc_int_base::concat_set(uint64 src, int low_i)
693{
694 *this = (low_i < 64) ? src >> low_i : 0;
695}
696
697// other methods
698void
699sc_int_base::scan(::std::istream &is)
700{
701 std::string s;
702 is >> s;
703 *this = s.c_str();
704}
705
706} // namespace sc_dt;
397 }
398}
399
400
401// constructors
402sc_int_base::sc_int_base(const sc_bv_base &v) :
403 m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
404{
405 check_length();
406 *this = v;
407}
408sc_int_base::sc_int_base(const sc_lv_base &v) :
409 m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
410{
411 check_length();
412 *this = v;
413}
414sc_int_base::sc_int_base(const sc_uint_subref_r &v) :
415 m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
416{
417 check_length();
418 *this = v.to_uint64();
419}
420sc_int_base::sc_int_base(const sc_signed_subref_r &v) :
421 m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
422{
423 check_length();
424 *this = v.to_uint64();
425}
426sc_int_base::sc_int_base(const sc_unsigned_subref_r &v) :
427 m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
428{
429 check_length();
430 *this = v.to_uint64();
431}
432
433sc_int_base::sc_int_base(const sc_signed &a) :
434 m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
435{
436 check_length();
437 *this = a.to_int64();
438}
439
440sc_int_base::sc_int_base(const sc_unsigned &a) :
441 m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
442{
443 check_length();
444 *this = a.to_int64();
445}
446
447
448// assignment operators
449sc_int_base &
450sc_int_base::operator = (const sc_signed &a)
451{
452 int minlen = sc_min(m_len, a.length());
453 int i = 0;
454 for (; i < minlen; ++i) {
455 set(i, a.test(i));
456 }
457 bool sgn = a.sign();
458 for (; i < m_len; ++i) {
459 // sign extension
460 set(i, sgn);
461 }
462 extend_sign();
463 return *this;
464}
465
466sc_int_base &
467sc_int_base::operator = (const sc_unsigned &a)
468{
469 int minlen = sc_min(m_len, a.length());
470 int i = 0;
471 for (; i < minlen; ++i) {
472 set(i, a.test(i));
473 }
474 for (; i < m_len; ++i) {
475 // zero extension
476 set(i, 0);
477 }
478 extend_sign();
479 return *this;
480}
481
482
483sc_int_base &
484sc_int_base::operator = (const sc_bv_base &a)
485{
486 int minlen = sc_min(m_len, a.length());
487 int i = 0;
488 for (; i < minlen; ++i) {
489 set(i, a.get_bit(i));
490 }
491 for (; i < m_len; ++i) {
492 // zero extension
493 set(i, 0);
494 }
495 extend_sign();
496 return *this;
497}
498
499sc_int_base &
500sc_int_base::operator = (const sc_lv_base &a)
501{
502 int minlen = sc_min(m_len, a.length());
503 int i = 0;
504 for (; i < minlen; ++i) {
505 set(i, sc_logic(a.get_bit(i)).to_bool());
506 }
507 for (; i < m_len; ++i) {
508 // zero extension
509 set(i, 0);
510 }
511 extend_sign();
512 return *this;
513}
514
515sc_int_base &
516sc_int_base::operator = (const char *a)
517{
518 if (a == 0) {
519 SC_REPORT_ERROR("conversion failed",
520 "character string is zero");
521 } else if (*a == 0) {
522 SC_REPORT_ERROR("conversion failed",
523 "character string is empty");
524 } else try {
525 int len = m_len;
526 sc_fix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
527 return this->operator = (aa);
528 } catch(const sc_core::sc_report &) {
529 std::stringstream msg;
530 msg << "character string '" << a << "' is not valid";
531 SC_REPORT_ERROR("conversion failed", msg.str().c_str());
532 }
533 return *this;
534}
535
536// explicit conversion to character string
537const std::string
538sc_int_base::to_string(sc_numrep numrep) const
539{
540 int len = m_len;
541 sc_fix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
542 return aa.to_string(numrep);
543}
544
545const std::string
546sc_int_base::to_string(sc_numrep numrep, bool w_prefix) const
547{
548 int len = m_len;
549 sc_fix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
550 return aa.to_string(numrep, w_prefix);
551}
552
553
554// reduce methods
555bool sc_int_base::and_reduce() const { return (m_val == int_type(-1)); }
556bool sc_int_base::or_reduce() const { return (m_val != int_type(0)); }
557
558bool
559sc_int_base::xor_reduce() const
560{
561 uint_type mask = ~UINT_ZERO;
562 uint_type val = m_val & (mask >> m_ulen);
563 int n = SC_INTWIDTH;
564 do {
565 n >>= 1;
566 mask >>= n;
567 val = ((val & (mask << n)) >> n) ^ (val & mask);
568 } while (n != 1);
569 return (val != uint_type(0));
570}
571
572bool
573sc_int_base::concat_get_ctrl(sc_digit *dst_p, int low_i) const
574{
575 int dst_i; // Word in dst_p now processing.
576 int end_i; // Highest order word in dst_p to process.
577 int left_shift; // Left shift for val.
578 uint_type mask; // Mask for bits to extract or keep.
579
580 dst_i = low_i / BITS_PER_DIGIT;
581 left_shift = low_i % BITS_PER_DIGIT;
582 end_i = (low_i + (m_len - 1)) / BITS_PER_DIGIT;
583
584 mask = ~(~UINT_ZERO << left_shift);
585 dst_p[dst_i] = (sc_digit)(dst_p[dst_i] & mask);
586 dst_i++;
587 for (; dst_i <= end_i; dst_i++)
588 dst_p[dst_i] = 0;
589 return false;
590}
591
592//-----------------------------------------------------------------------------
593//"sc_int_base::concat_get_data"
594//
595// This method transfers the value of this object instance to the supplied
596// array of sc_unsigned digits starting with the bit specified by low_i within
597// the array of digits.
598//
599// Notes:
600// (1) we don't worry about masking the high order data we transfer since
601// concat_get_data() is called from low order bit to high order bit. So
602// the bits above where we place ours will be filled in by someone else.
603//
604// dst_p -> array of sc_unsigned digits to be filled in.
605// low_i = first bit within dst_p to be set.
606//-----------------------------------------------------------------------------
607bool
608sc_int_base::concat_get_data(sc_digit *dst_p, int low_i) const
609{
610 int dst_i; // Word in dst_p now processing.
611 int end_i; // Highest order word in dst_p to process.
612 int high_i; // Index of high order bit in dst_p to set.
613 int left_shift; // Left shift for val.
614 uint_type mask; // Mask for bits to extract or keep.
615 bool non_zero; // True if value inserted is non-zero.
616 uint_type val; // Value for this object.
617
618 dst_i = low_i / BITS_PER_DIGIT;
619 left_shift = low_i % BITS_PER_DIGIT;
620 high_i = low_i + (m_len - 1);
621 end_i = high_i / BITS_PER_DIGIT;
622 val = m_val;
623 non_zero = val != 0;
624
625 // MASK OFF DATA TO BE TRANSFERRED BASED ON WIDTH:
626 if (m_len < 64) {
627 mask = ~(~UINT_ZERO << m_len);
628 val &= mask;
629 }
630
631 // PROCESS THE FIRST WORD:
632 mask = (~UINT_ZERO << left_shift);
633 dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & ~mask) |
634 ((val <<left_shift) & DIGIT_MASK));
635 switch (end_i - dst_i) {
636 // BITS ARE ACROSS TWO WORDS:
637 case 1:
638 dst_i++;
639 val >>= (BITS_PER_DIGIT - left_shift);
640 dst_p[dst_i] = (sc_digit)val;
641 break;
642
643 // BITS ARE ACROSS THREE WORDS:
644 case 2:
645 dst_i++;
646 val >>= (BITS_PER_DIGIT - left_shift);
647 dst_p[dst_i++] = ((sc_digit)val) & DIGIT_MASK;
648 val >>= BITS_PER_DIGIT;
649 dst_p[dst_i] = (sc_digit)val;
650 break;
651
652 // BITS ARE ACROSS FOUR WORDS:
653 case 3:
654 dst_i++;
655 val >>= (BITS_PER_DIGIT - left_shift);
656 dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
657 val >>= BITS_PER_DIGIT;
658 dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
659 val >>= BITS_PER_DIGIT;
660 dst_p[dst_i] = (sc_digit)val;
661 break;
662 }
663 return non_zero;
664}
665
666// #### OPTIMIZE
667void
668sc_int_base::concat_set(int64 src, int low_i)
669{
670 *this = (low_i < 64) ? src >> low_i : src >> 63;
671}
672
673void
674sc_int_base::concat_set(const sc_signed &src, int low_i)
675{
676 if (low_i < src.length())
677 *this = src >> low_i;
678 else
679 *this = (src < 0) ? (int_type)-1 : 0;
680}
681
682void
683sc_int_base::concat_set(const sc_unsigned &src, int low_i)
684{
685 if (low_i < src.length())
686 *this = src >> low_i;
687 else
688 *this = 0;
689}
690
691void
692sc_int_base::concat_set(uint64 src, int low_i)
693{
694 *this = (low_i < 64) ? src >> low_i : 0;
695}
696
697// other methods
698void
699sc_int_base::scan(::std::istream &is)
700{
701 std::string s;
702 is >> s;
703 *this = s.c_str();
704}
705
706} // namespace sc_dt;