| /***************************************************************************** | |
| Licensed to Accellera Systems Initiative Inc. (Accellera) under one or | |
| more contributor license agreements. See the NOTICE file distributed | |
| with this work for additional information regarding copyright ownership. | |
| Accellera licenses this file to you under the Apache License, Version 2.0 | |
| (the "License"); you may not use this file except in compliance with the | |
| License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
| implied. See the License for the specific language governing | |
| permissions and limitations under the License. | |
| *****************************************************************************/ | |
| /***************************************************************************** | |
| sc_signed_subref.h -- Proxy class that is declared in sc_signed.h. | |
| Original Author: Ali Dasdan, Synopsys, Inc. | |
| *****************************************************************************/ | |
| /***************************************************************************** | |
| MODIFICATION LOG - modifiers, enter your name, affiliation, date and | |
| changes you are making here. | |
| Name, Affiliation, Date: | |
| Description of Modification: | |
| *****************************************************************************/ | |
| // ---------------------------------------------------------------------------- | |
| // CLASS : sc_signed_subref_r | |
| // | |
| // Proxy class for sc_signed part selection (r-value only). | |
| // ---------------------------------------------------------------------------- | |
| // concatenation support | |
| uint64 | |
| sc_signed_subref_r::concat_get_uint64() const | |
| { | |
| sc_unsigned a(m_obj_p, m_left, m_right); | |
| return a.to_uint64(); | |
| } | |
| bool | |
| sc_signed_subref_r::concat_get_ctrl(sc_digit *dst_p, int low_i) const | |
| { | |
| sc_unsigned a(m_obj_p, m_left, m_right); | |
| return a.concat_get_ctrl(dst_p, low_i); | |
| } | |
| bool | |
| sc_signed_subref_r::concat_get_data(sc_digit *dst_p, int low_i) const | |
| { | |
| sc_unsigned a(m_obj_p, m_left, m_right); | |
| return a.concat_get_data(dst_p, low_i); | |
| } | |
| // implicit conversion to sc_signed | |
| sc_signed_subref_r::operator sc_unsigned () const | |
| { | |
| return sc_unsigned(m_obj_p, m_left, m_right); | |
| } | |
| // explicit conversions | |
| int | |
| sc_signed_subref_r::to_int() const | |
| { | |
| sc_unsigned a(m_obj_p, m_left, m_right); | |
| return a.to_int(); | |
| } | |
| unsigned int | |
| sc_signed_subref_r::to_uint() const | |
| { | |
| sc_unsigned a(m_obj_p, m_left, m_right); | |
| return a.to_uint(); | |
| } | |
| long | |
| sc_signed_subref_r::to_long() const | |
| { | |
| sc_unsigned a(m_obj_p, m_left, m_right); | |
| return a.to_long(); | |
| } | |
| unsigned long | |
| sc_signed_subref_r::to_ulong() const | |
| { | |
| sc_unsigned a(m_obj_p, m_left, m_right); | |
| return a.to_ulong(); | |
| } | |
| int64 | |
| sc_signed_subref_r::to_int64() const | |
| { | |
| sc_unsigned a(m_obj_p, m_left, m_right); | |
| return a.to_int64(); | |
| } | |
| uint64 | |
| sc_signed_subref_r::to_uint64() const | |
| { | |
| sc_unsigned a(m_obj_p, m_left, m_right); | |
| return a.to_uint64(); | |
| } | |
| double | |
| sc_signed_subref_r::to_double() const | |
| { | |
| sc_unsigned a(m_obj_p, m_left, m_right); | |
| return a.to_double(); | |
| } | |
| // explicit conversion to character string | |
| const std::string | |
| sc_signed_subref_r::to_string(sc_numrep numrep) const | |
| { | |
| sc_unsigned a(length()); | |
| a = *this; | |
| return a.to_string(numrep); | |
| } | |
| const std::string | |
| sc_signed_subref_r::to_string(sc_numrep numrep, bool w_prefix) const | |
| { | |
| sc_unsigned a(length()); | |
| a = *this; | |
| return a.to_string(numrep, w_prefix); | |
| } | |
| // ---------------------------------------------------------------------------- | |
| // CLASS : sc_signed_subref | |
| // | |
| // Proxy class for sc_signed part selection (r-value and l-value). | |
| // ---------------------------------------------------------------------------- | |
| // assignment operators | |
| const sc_signed_subref & | |
| sc_signed_subref::operator = (const sc_signed_subref_r &a) | |
| { | |
| return operator = ((sc_unsigned)(a)); | |
| } | |
| const sc_signed_subref & | |
| sc_signed_subref::operator = (const sc_signed_subref &v) | |
| { | |
| if (this == &v) { | |
| return *this; | |
| } | |
| return operator = ((sc_unsigned)(v)); | |
| } | |
| const sc_signed_subref & | |
| sc_signed_subref::operator = (const sc_signed &v) | |
| { | |
| int i; | |
| int l = sc_min(m_left, v.nbits - 1 + m_right); | |
| for (i = m_right; i <= l; ++i) | |
| m_obj_p->set(i, v.test(i - m_right)); | |
| for (; i <= m_left; i++) | |
| m_obj_p->set(i, v.test(l)); | |
| return *this; | |
| } | |
| const sc_signed_subref & | |
| sc_signed_subref::operator = (const sc_unsigned_subref_r &v) | |
| { | |
| return operator = ((sc_unsigned)(v)); | |
| } | |
| const sc_signed_subref & | |
| sc_signed_subref::operator = (const sc_unsigned &v) | |
| { | |
| int i; | |
| int l = sc_min(m_left, v.nbits - 1 + m_right); | |
| for (i = m_right; i <= l; ++i) | |
| m_obj_p->set(i, v.test(i - m_right)); | |
| for (; i <= m_left; i++) | |
| m_obj_p->set(i, 0); | |
| return *this; | |
| } | |
| const sc_signed_subref & | |
| sc_signed_subref::operator = (unsigned long v) | |
| { | |
| for (int i = m_right; i <= m_left; ++i) { | |
| m_obj_p->set(i, static_cast<bool>(v & 1)); | |
| v >>= 1; | |
| } | |
| return *this; | |
| } | |
| const sc_signed_subref & | |
| sc_signed_subref::operator = (long v) | |
| { | |
| unsigned long v2 = (unsigned long)v; | |
| for (int i = m_right; i <= m_left; ++i) { | |
| m_obj_p->set(i, static_cast<bool>(v2 & 1)); | |
| v2 >>= 1; | |
| } | |
| return *this; | |
| } | |
| const sc_signed_subref & | |
| sc_signed_subref::operator = (uint64 v) | |
| { | |
| for (int i = m_right; i <= m_left; ++i) { | |
| m_obj_p->set(i, static_cast<bool>(v & 1)); | |
| v >>= 1; | |
| } | |
| return *this; | |
| } | |
| const sc_signed_subref & | |
| sc_signed_subref::operator = (int64 v) | |
| { | |
| uint64 v2 = (uint64)v; | |
| for (int i = m_right; i <= m_left; ++i) { | |
| m_obj_p->set(i, static_cast<bool>(v2 & 1)); | |
| v2 >>= 1; | |
| } | |
| return *this; | |
| } | |
| const sc_signed_subref & | |
| sc_signed_subref::operator = (double v) | |
| { | |
| is_bad_double(v); | |
| int nb = m_left - m_right + 1; | |
| int nd = DIV_CEIL(nb); | |
| #ifdef SC_MAX_NBITS | |
| sc_digit d[MAX_NDIGITS]; | |
| #else | |
| sc_digit *d = new sc_digit[nd]; | |
| #endif | |
| if (v < 0) | |
| v = -v; | |
| int i = 0; | |
| while (std::floor(v) && (i < nd)) { | |
| #ifndef _WIN32 | |
| d[i++] = (sc_digit) std::floor(remainder(v, DIGIT_RADIX)); | |
| #else | |
| d[i++] = (sc_digit) std::floor(std::fmod(v, DIGIT_RADIX)); | |
| #endif | |
| v /= DIGIT_RADIX; | |
| } | |
| vec_zero(i, nd, d); | |
| sc_digit val = 1; // Bit value. | |
| int j = 0; // Current digit in d. | |
| i = 0; // Current bit in d. | |
| while (i < nb) { | |
| m_obj_p->set(i + m_right, (bool)(d[j] & val)); | |
| ++i; | |
| if (i % BITS_PER_DIGIT == 0) { | |
| val = 1; | |
| ++j; | |
| } else { | |
| val <<= 1; | |
| } | |
| } | |
| #ifndef SC_MAX_NBITS | |
| delete [] d; | |
| #endif | |
| return *this; | |
| } | |
| const sc_signed_subref & | |
| sc_signed_subref::operator = (const sc_int_base &a) | |
| { | |
| return operator = ((int64)a); | |
| } | |
| const sc_signed_subref & | |
| sc_signed_subref::operator = (const sc_uint_base &a) | |
| { | |
| return operator = ((uint64)a); | |
| } | |
| // concatenation methods | |
| void | |
| sc_signed_subref::concat_set(int64 src, int low_i) | |
| { | |
| int i; | |
| int l; | |
| bool sign = src < 0; | |
| if (low_i < 64) { | |
| src = src >> low_i; | |
| l = sc_min(m_left, (63 - low_i) + m_right); | |
| for (i = m_right; i <= l; ++i) { | |
| m_obj_p->set(i, src & 1); | |
| src = src >> 1; | |
| } | |
| for (; i <= m_left; i++) | |
| m_obj_p->set(i, sign); | |
| } else { | |
| for (i = m_right; i <= m_left; ++i) | |
| m_obj_p->set(i, sign); | |
| } | |
| } | |
| void | |
| sc_signed_subref::concat_set(const sc_signed &src, int low_i) | |
| { | |
| int i; | |
| int l; | |
| int src_i; | |
| bool sign = src.test(src.nbits - 1); | |
| l = src.nbits - (low_i + 1); | |
| if (l >= 0) { | |
| l = sc_min(m_left, l + m_right); | |
| src_i = low_i; | |
| for (i = m_right; i <= l; ++i, src_i++) { | |
| m_obj_p->set(i, src.test(src_i)); | |
| } | |
| for (; i <= m_left; i++) | |
| m_obj_p->set(i, sign); | |
| } else { | |
| for (i = m_right; i <= m_left; ++i) | |
| m_obj_p->set(i, sign); | |
| } | |
| } | |
| void | |
| sc_signed_subref::concat_set(const sc_unsigned &src, int low_i) | |
| { | |
| int i; | |
| int l; | |
| int src_i; | |
| l = src.nbits - (low_i + 2); | |
| if (l >= 0) { | |
| l = sc_min(m_left, l + m_right); | |
| src_i = low_i; | |
| for (i = m_right; i <= l; ++i, src_i++) { | |
| m_obj_p->set(i, src.test(src_i)); | |
| } | |
| for (; i <= m_left; i++) | |
| m_obj_p->set(false); | |
| } else { | |
| for (i = m_right; i <= m_left; ++i) | |
| m_obj_p->set(false); | |
| } | |
| } | |
| void | |
| sc_signed_subref::concat_set(uint64 src, int low_i) | |
| { | |
| int i; | |
| int l; | |
| if (low_i < 64) { | |
| src = src >> low_i; | |
| l = sc_min(m_left, (63 - low_i) + m_right); | |
| for (i = m_right; i <= l; ++i) { | |
| m_obj_p->set(i, src & 1); | |
| src = src >> 1; | |
| } | |
| for (; i <= m_left; i++) | |
| m_obj_p->set(false); | |
| } else { | |
| for (i = m_right; i <= m_left; ++i) | |
| m_obj_p->set(false); | |
| } | |
| } | |
| // other methods | |
| void | |
| sc_signed_subref::scan(::std::istream &is) | |
| { | |
| std::string s; | |
| is >> s; | |
| *this = s.c_str(); | |
| } |