| /***************************************************************************** |
| |
| 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(); |
| } |