sc_bv_base.cc revision 12854
112854Sgabeblack@google.com/***************************************************************************** 212854Sgabeblack@google.com 312854Sgabeblack@google.com Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 412854Sgabeblack@google.com more contributor license agreements. See the NOTICE file distributed 512854Sgabeblack@google.com with this work for additional information regarding copyright ownership. 612854Sgabeblack@google.com Accellera licenses this file to you under the Apache License, Version 2.0 712854Sgabeblack@google.com (the "License"); you may not use this file except in compliance with the 812854Sgabeblack@google.com License. You may obtain a copy of the License at 912854Sgabeblack@google.com 1012854Sgabeblack@google.com http://www.apache.org/licenses/LICENSE-2.0 1112854Sgabeblack@google.com 1212854Sgabeblack@google.com Unless required by applicable law or agreed to in writing, software 1312854Sgabeblack@google.com distributed under the License is distributed on an "AS IS" BASIS, 1412854Sgabeblack@google.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1512854Sgabeblack@google.com implied. See the License for the specific language governing 1612854Sgabeblack@google.com permissions and limitations under the License. 1712854Sgabeblack@google.com 1812854Sgabeblack@google.com *****************************************************************************/ 1912854Sgabeblack@google.com 2012854Sgabeblack@google.com/***************************************************************************** 2112854Sgabeblack@google.com 2212854Sgabeblack@google.com sc_bv_base.cpp -- Arbitrary size bit vector class. 2312854Sgabeblack@google.com 2412854Sgabeblack@google.com Original Author: Gene Bushuyev, Synopsys, Inc. 2512854Sgabeblack@google.com 2612854Sgabeblack@google.com *****************************************************************************/ 2712854Sgabeblack@google.com 2812854Sgabeblack@google.com/***************************************************************************** 2912854Sgabeblack@google.com 3012854Sgabeblack@google.com MODIFICATION LOG - modifiers, enter your name, affiliation, date and 3112854Sgabeblack@google.com changes you are making here. 3212854Sgabeblack@google.com 3312854Sgabeblack@google.com Name, Affiliation, Date: 3412854Sgabeblack@google.com Description of Modification: 3512854Sgabeblack@google.com 3612854Sgabeblack@google.com *****************************************************************************/ 3712854Sgabeblack@google.com 3812854Sgabeblack@google.com 3912854Sgabeblack@google.com// $Log: sc_bv_base.cpp,v $ 4012854Sgabeblack@google.com// Revision 1.2 2011/08/24 22:05:40 acg 4112854Sgabeblack@google.com// Torsten Maehne: initialization changes to remove warnings. 4212854Sgabeblack@google.com// 4312854Sgabeblack@google.com// Revision 1.1.1.1 2006/12/15 20:20:04 acg 4412854Sgabeblack@google.com// SystemC 2.3 4512854Sgabeblack@google.com// 4612854Sgabeblack@google.com// Revision 1.4 2006/04/11 23:12:26 acg 4712854Sgabeblack@google.com// Andy Goodrich: Fixed bug in parsing of extended string constants like 4812854Sgabeblack@google.com// 0bus1110011. 4912854Sgabeblack@google.com// 5012854Sgabeblack@google.com// Revision 1.3 2006/01/13 18:53:53 acg 5112854Sgabeblack@google.com// Andy Goodrich: added $Log command so that CVS comments are reproduced in 5212854Sgabeblack@google.com// the source. 5312854Sgabeblack@google.com// 5412854Sgabeblack@google.com 5512854Sgabeblack@google.com#include <cstring> 5612854Sgabeblack@google.com#include <sstream> 5712854Sgabeblack@google.com 5812854Sgabeblack@google.com#include "systemc/ext/dt/bit/sc_bv_base.hh" 5912854Sgabeblack@google.com#include "systemc/ext/dt/fx/sc_fix.hh" 6012854Sgabeblack@google.com#include "systemc/ext/dt/fx/sc_ufix.hh" 6112854Sgabeblack@google.com#include "systemc/ext/utils/sc_report.hh" 6212854Sgabeblack@google.com 6312854Sgabeblack@google.comnamespace sc_dt 6412854Sgabeblack@google.com{ 6512854Sgabeblack@google.com 6612854Sgabeblack@google.com// ---------------------------------------------------------------------------- 6712854Sgabeblack@google.com// CLASS : sc_bv_base 6812854Sgabeblack@google.com// 6912854Sgabeblack@google.com// Arbitrary size bit vector base class. 7012854Sgabeblack@google.com// ---------------------------------------------------------------------------- 7112854Sgabeblack@google.com 7212854Sgabeblack@google.comvoid 7312854Sgabeblack@google.comsc_bv_base::init(int length_, bool init_value) 7412854Sgabeblack@google.com{ 7512854Sgabeblack@google.com // check the length 7612854Sgabeblack@google.com if (length_ <= 0) { 7712854Sgabeblack@google.com SC_REPORT_ERROR("zero length", 0); 7812854Sgabeblack@google.com sc_core::sc_abort(); // can't recover from here 7912854Sgabeblack@google.com } 8012854Sgabeblack@google.com // allocate memory for the data and control words 8112854Sgabeblack@google.com m_len = length_; 8212854Sgabeblack@google.com m_size = (m_len - 1) / SC_DIGIT_SIZE + 1; 8312854Sgabeblack@google.com m_data = new sc_digit[m_size]; 8412854Sgabeblack@google.com // initialize the bits to 'init_value' 8512854Sgabeblack@google.com sc_digit dw = init_value ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO; 8612854Sgabeblack@google.com int sz = m_size; 8712854Sgabeblack@google.com for (int i = 0; i < sz; ++i) { 8812854Sgabeblack@google.com m_data[i] = dw; 8912854Sgabeblack@google.com } 9012854Sgabeblack@google.com clean_tail(); 9112854Sgabeblack@google.com} 9212854Sgabeblack@google.com 9312854Sgabeblack@google.comvoid 9412854Sgabeblack@google.comsc_bv_base::assign_from_string(const std::string &s) 9512854Sgabeblack@google.com{ 9612854Sgabeblack@google.com // s must have been converted to bin 9712854Sgabeblack@google.com int len = m_len; 9812854Sgabeblack@google.com int s_len = s.length() - 1; 9912854Sgabeblack@google.com int min_len = sc_min(len, s_len); 10012854Sgabeblack@google.com int i = 0; 10112854Sgabeblack@google.com for (; i < min_len; ++i) { 10212854Sgabeblack@google.com char c = s[s_len - i - 1]; 10312854Sgabeblack@google.com if (c != '0' && c != '1') { 10412854Sgabeblack@google.com SC_REPORT_ERROR("cannot perform conversion", 10512854Sgabeblack@google.com "string can contain only '0' and '1' characters"); 10612854Sgabeblack@google.com // may continue, if suppressed 10712854Sgabeblack@google.com c = '0'; 10812854Sgabeblack@google.com } 10912854Sgabeblack@google.com set_bit(i, sc_logic_value_t(c - '0')); 11012854Sgabeblack@google.com } 11112854Sgabeblack@google.com // if formatted, fill the rest with sign(s), otherwise fill with zeros 11212854Sgabeblack@google.com sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t(s[0] - '0') 11312854Sgabeblack@google.com : sc_logic_value_t(0)); 11412854Sgabeblack@google.com for (; i < len; ++i) { 11512854Sgabeblack@google.com set_bit(i, fill); 11612854Sgabeblack@google.com } 11712854Sgabeblack@google.com} 11812854Sgabeblack@google.com 11912854Sgabeblack@google.com// constructors 12012854Sgabeblack@google.comsc_bv_base::sc_bv_base(const char *a) : m_len(0), m_size(0), m_data(0) 12112854Sgabeblack@google.com{ 12212854Sgabeblack@google.com std::string s = convert_to_bin(a); 12312854Sgabeblack@google.com init(s.length() - 1); 12412854Sgabeblack@google.com assign_from_string(s); 12512854Sgabeblack@google.com} 12612854Sgabeblack@google.com 12712854Sgabeblack@google.comsc_bv_base::sc_bv_base(const char *a, int length_) : 12812854Sgabeblack@google.com m_len(0), m_size(0), m_data(0) 12912854Sgabeblack@google.com{ 13012854Sgabeblack@google.com init(length_); 13112854Sgabeblack@google.com assign_from_string(convert_to_bin(a)); 13212854Sgabeblack@google.com} 13312854Sgabeblack@google.com 13412854Sgabeblack@google.comsc_bv_base::sc_bv_base(const sc_bv_base &a) : 13512854Sgabeblack@google.com sc_proxy<sc_bv_base>(), m_len(a.m_len), m_size(a.m_size), 13612854Sgabeblack@google.com m_data(new sc_digit[m_size]) 13712854Sgabeblack@google.com{ 13812854Sgabeblack@google.com // copy the bits 13912854Sgabeblack@google.com int sz = m_size; 14012854Sgabeblack@google.com for (int i = 0; i < sz; ++i) { 14112854Sgabeblack@google.com m_data[i] = a.m_data[i]; 14212854Sgabeblack@google.com } 14312854Sgabeblack@google.com} 14412854Sgabeblack@google.com 14512854Sgabeblack@google.com// assignment operators 14612854Sgabeblack@google.comsc_bv_base & 14712854Sgabeblack@google.comsc_bv_base::operator = (const char *a) 14812854Sgabeblack@google.com{ 14912854Sgabeblack@google.com assign_from_string(convert_to_bin(a)); 15012854Sgabeblack@google.com return *this; 15112854Sgabeblack@google.com} 15212854Sgabeblack@google.com 15312854Sgabeblack@google.com 15412854Sgabeblack@google.com// ---------------------------------------------------------------------------- 15512854Sgabeblack@google.com// convert formatted string to binary string 15612854Sgabeblack@google.com 15712854Sgabeblack@google.comconst std::string 15812854Sgabeblack@google.comconvert_to_bin(const char *s) 15912854Sgabeblack@google.com{ 16012854Sgabeblack@google.com // Beware: logic character strings cannot start with '0x' or '0X', 16112854Sgabeblack@google.com // because this is seen as a hexadecimal encoding prefix! 16212854Sgabeblack@google.com 16312854Sgabeblack@google.com if (s == 0) { 16412854Sgabeblack@google.com SC_REPORT_ERROR("cannot perform conversion", 16512854Sgabeblack@google.com "character string is zero"); 16612854Sgabeblack@google.com return std::string(); 16712854Sgabeblack@google.com } 16812854Sgabeblack@google.com if (*s == 0) { 16912854Sgabeblack@google.com SC_REPORT_ERROR("cannot perform conversion", 17012854Sgabeblack@google.com "character string is empty"); 17112854Sgabeblack@google.com return std::string(); 17212854Sgabeblack@google.com } 17312854Sgabeblack@google.com 17412854Sgabeblack@google.com int n = strlen(s); 17512854Sgabeblack@google.com int i = 0; 17612854Sgabeblack@google.com if (s[0] == '-' || s[0] == '+') { 17712854Sgabeblack@google.com ++i; 17812854Sgabeblack@google.com } 17912854Sgabeblack@google.com if (n > (i + 2) && s[i] == '0') { 18012854Sgabeblack@google.com if (s[i + 1] == 'b' || s[i + 1] == 'B') { 18112854Sgabeblack@google.com if (s[i + 2] == '0' || s[i + 2] == '1') { 18212854Sgabeblack@google.com std::string str(&s[2]); 18312854Sgabeblack@google.com str += "F"; 18412854Sgabeblack@google.com return str; 18512854Sgabeblack@google.com } 18612854Sgabeblack@google.com } 18712854Sgabeblack@google.com if (s[i + 1] == 'b' || s[i + 1] == 'B' || 18812854Sgabeblack@google.com s[i + 1] == 'c' || s[i + 1] == 'C' || 18912854Sgabeblack@google.com s[i + 1] == 'd' || s[i + 1] == 'D' || 19012854Sgabeblack@google.com s[i + 1] == 'o' || s[i + 1] == 'O' || 19112854Sgabeblack@google.com s[i + 1] == 'x' || s[i + 1] == 'X') { 19212854Sgabeblack@google.com try { 19312854Sgabeblack@google.com // worst case length = n * 4 19412854Sgabeblack@google.com sc_fix a(s, n * 4, n * 4, SC_TRN, SC_WRAP, 0, SC_ON); 19512854Sgabeblack@google.com std::string str = a.to_bin(); 19612854Sgabeblack@google.com str += "F"; // mark the string as formatted 19712854Sgabeblack@google.com // get rid of prefix (0b) and redundant leading bits 19812854Sgabeblack@google.com const char *p = str.c_str() + 2; 19912854Sgabeblack@google.com while (p[1] && p[0] == p[1]) { 20012854Sgabeblack@google.com ++p; 20112854Sgabeblack@google.com } 20212854Sgabeblack@google.com return std::string(p); 20312854Sgabeblack@google.com } catch (const sc_core::sc_report &) { 20412854Sgabeblack@google.com std::stringstream msg; 20512854Sgabeblack@google.com msg << "character string '" << s << "' is not valid"; 20612854Sgabeblack@google.com SC_REPORT_ERROR("cannot perform conversion", 20712854Sgabeblack@google.com msg.str().c_str()); 20812854Sgabeblack@google.com return std::string(); 20912854Sgabeblack@google.com } 21012854Sgabeblack@google.com } 21112854Sgabeblack@google.com } 21212854Sgabeblack@google.com 21312854Sgabeblack@google.com // bin by default 21412854Sgabeblack@google.com std::string str(s); 21512854Sgabeblack@google.com str += "U"; // mark the string as unformatted 21612854Sgabeblack@google.com return str; 21712854Sgabeblack@google.com} 21812854Sgabeblack@google.com 21912854Sgabeblack@google.com// convert binary string to formatted string 22012854Sgabeblack@google.comconst std::string 22112854Sgabeblack@google.comconvert_to_fmt(const std::string &s, sc_numrep numrep, bool w_prefix) 22212854Sgabeblack@google.com{ 22312854Sgabeblack@google.com int n = s.length(); 22412854Sgabeblack@google.com std::string str("0bus"); 22512854Sgabeblack@google.com // str += "0bus"; 22612854Sgabeblack@google.com str += s; 22712854Sgabeblack@google.com sc_ufix a(str.c_str(), n, n, SC_TRN, SC_WRAP, 0, SC_ON); 22812854Sgabeblack@google.com return a.to_string(numrep, w_prefix); 22912854Sgabeblack@google.com} 23012854Sgabeblack@google.com 23112854Sgabeblack@google.com} // namespace sc_dt 232