sc_bv_base.cc revision 13325
16899SN/A/***************************************************************************** 26899SN/A 36899SN/A Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 46899SN/A more contributor license agreements. See the NOTICE file distributed 56899SN/A with this work for additional information regarding copyright ownership. 66899SN/A Accellera licenses this file to you under the Apache License, Version 2.0 76899SN/A (the "License"); you may not use this file except in compliance with the 86899SN/A License. You may obtain a copy of the License at 96899SN/A 106899SN/A http://www.apache.org/licenses/LICENSE-2.0 116899SN/A 126899SN/A Unless required by applicable law or agreed to in writing, software 136899SN/A distributed under the License is distributed on an "AS IS" BASIS, 146899SN/A WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 156899SN/A implied. See the License for the specific language governing 166899SN/A permissions and limitations under the License. 176899SN/A 186899SN/A *****************************************************************************/ 196899SN/A 206899SN/A/***************************************************************************** 216899SN/A 226899SN/A sc_bv_base.cpp -- Arbitrary size bit vector class. 236899SN/A 246899SN/A Original Author: Gene Bushuyev, Synopsys, Inc. 256899SN/A 266899SN/A *****************************************************************************/ 276899SN/A 286899SN/A/***************************************************************************** 296899SN/A 307632SBrad.Beckmann@amd.com MODIFICATION LOG - modifiers, enter your name, affiliation, date and 318232Snate@binkert.org changes you are making here. 327053SN/A 336899SN/A Name, Affiliation, Date: 346899SN/A Description of Modification: 356899SN/A 367053SN/A *****************************************************************************/ 377053SN/A 387053SN/A 397053SN/A// $Log: sc_bv_base.cpp,v $ 407053SN/A// Revision 1.2 2011/08/24 22:05:40 acg 416899SN/A// Torsten Maehne: initialization changes to remove warnings. 427053SN/A// 436899SN/A// Revision 1.1.1.1 2006/12/15 20:20:04 acg 447053SN/A// SystemC 2.3 457053SN/A// 467053SN/A// Revision 1.4 2006/04/11 23:12:26 acg 477053SN/A// Andy Goodrich: Fixed bug in parsing of extended string constants like 488164Snilay@cs.wisc.edu// 0bus1110011. 497053SN/A// 506899SN/A// Revision 1.3 2006/01/13 18:53:53 acg 516899SN/A// Andy Goodrich: added $Log command so that CVS comments are reproduced in 527053SN/A// the source. 537053SN/A// 546899SN/A 557053SN/A#include <cstring> 567053SN/A#include <sstream> 576899SN/A 587053SN/A#include "systemc/ext/dt/bit/messages.hh" 597053SN/A#include "systemc/ext/dt/bit/sc_bv_base.hh" 607053SN/A#include "systemc/ext/dt/fx/sc_fix.hh" 617053SN/A#include "systemc/ext/dt/fx/sc_ufix.hh" 626899SN/A#include "systemc/ext/utils/sc_report.hh" 638184Ssomayeh@cs.wisc.edu 648184Ssomayeh@cs.wisc.edunamespace sc_dt 658184Ssomayeh@cs.wisc.edu{ 668184Ssomayeh@cs.wisc.edu 677053SN/A// ---------------------------------------------------------------------------- 687053SN/A// CLASS : sc_bv_base 697053SN/A// 707053SN/A// Arbitrary size bit vector base class. 717053SN/A// ---------------------------------------------------------------------------- 727053SN/A 737053SN/Avoid 747053SN/Asc_bv_base::init(int length_, bool init_value) 757053SN/A{ 766899SN/A // check the length 776899SN/A if (length_ <= 0) { 787053SN/A SC_REPORT_ERROR(sc_core::SC_ID_ZERO_LENGTH_, 0); 797053SN/A sc_core::sc_abort(); // can't recover from here 806899SN/A } 817053SN/A // allocate memory for the data and control words 826899SN/A m_len = length_; 837053SN/A m_size = (m_len - 1) / SC_DIGIT_SIZE + 1; 847053SN/A m_data = new sc_digit[m_size]; 857053SN/A // initialize the bits to 'init_value' 866899SN/A sc_digit dw = init_value ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO; 877053SN/A int sz = m_size; 887053SN/A for (int i = 0; i < sz; ++i) { 896899SN/A m_data[i] = dw; 907053SN/A } 916899SN/A clean_tail(); 927053SN/A} 937053SN/A 947053SN/Avoid 957053SN/Asc_bv_base::assign_from_string(const std::string &s) 967053SN/A{ 977053SN/A // s must have been converted to bin 987053SN/A int len = m_len; 997053SN/A int s_len = s.length() - 1; 1007053SN/A int min_len = sc_min(len, s_len); 1017053SN/A int i = 0; 1027053SN/A for (; i < min_len; ++i) { 1036899SN/A char c = s[s_len - i - 1]; 1046899SN/A if (c != '0' && c != '1') { 1057568SN/A SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_, 1067823Ssteve.reinhardt@amd.com "string can contain only '0' and '1' characters"); 1077568SN/A // may continue, if suppressed 1088190SLisa.Hsu@amd.com c = '0'; 1097568SN/A } 1107053SN/A set_bit(i, sc_logic_value_t(c - '0')); 1116899SN/A } 1127053SN/A // if formatted, fill the rest with sign(s), otherwise fill with zeros 1137053SN/A sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t(s[0] - '0') 1147053SN/A : sc_logic_value_t(0)); 1157053SN/A for (; i < len; ++i) { 1166899SN/A set_bit(i, fill); 1177053SN/A } 1187053SN/A} 1197053SN/A 1207053SN/A// constructors 1217053SN/Asc_bv_base::sc_bv_base(const char *a) : m_len(0), m_size(0), m_data(0) 1227053SN/A{ 1237053SN/A std::string s = convert_to_bin(a); 1247053SN/A init(s.length() - 1); 1257053SN/A assign_from_string(s); 1266899SN/A} 1277053SN/A 1287053SN/Asc_bv_base::sc_bv_base(const char *a, int length_) : 1297053SN/A m_len(0), m_size(0), m_data(0) 1306899SN/A{ 1316899SN/A init(length_); 1327053SN/A assign_from_string(convert_to_bin(a)); 1338184Ssomayeh@cs.wisc.edu} 1348184Ssomayeh@cs.wisc.edu 1358184Ssomayeh@cs.wisc.edusc_bv_base::sc_bv_base(const sc_bv_base &a) : 1368184Ssomayeh@cs.wisc.edu sc_proxy<sc_bv_base>(), m_len(a.m_len), m_size(a.m_size), 1378184Ssomayeh@cs.wisc.edu m_data(new sc_digit[m_size]) 1388184Ssomayeh@cs.wisc.edu{ 1398184Ssomayeh@cs.wisc.edu // copy the bits 1408184Ssomayeh@cs.wisc.edu int sz = m_size; 1418184Ssomayeh@cs.wisc.edu for (int i = 0; i < sz; ++i) { 1428184Ssomayeh@cs.wisc.edu m_data[i] = a.m_data[i]; 1438184Ssomayeh@cs.wisc.edu } 1448184Ssomayeh@cs.wisc.edu} 1458184Ssomayeh@cs.wisc.edu 1468184Ssomayeh@cs.wisc.edu// assignment operators 1478184Ssomayeh@cs.wisc.edusc_bv_base & 1488184Ssomayeh@cs.wisc.edusc_bv_base::operator = (const char *a) 1498184Ssomayeh@cs.wisc.edu{ 1508184Ssomayeh@cs.wisc.edu assign_from_string(convert_to_bin(a)); 1518184Ssomayeh@cs.wisc.edu return *this; 1528184Ssomayeh@cs.wisc.edu} 1538184Ssomayeh@cs.wisc.edu 1548184Ssomayeh@cs.wisc.edu 1558184Ssomayeh@cs.wisc.edu// ---------------------------------------------------------------------------- 1568184Ssomayeh@cs.wisc.edu// convert formatted string to binary string 1578184Ssomayeh@cs.wisc.edu 1588184Ssomayeh@cs.wisc.educonst std::string 1598184Ssomayeh@cs.wisc.educonvert_to_bin(const char *s) 1608184Ssomayeh@cs.wisc.edu{ 1618184Ssomayeh@cs.wisc.edu // Beware: logic character strings cannot start with '0x' or '0X', 1628184Ssomayeh@cs.wisc.edu // because this is seen as a hexadecimal encoding prefix! 1638184Ssomayeh@cs.wisc.edu 1647053SN/A if (s == 0) { 1656899SN/A SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_, 1667053SN/A "character string is zero"); 1677053SN/A return std::string(); 1686899SN/A } 1697053SN/A if (*s == 0) { 1707053SN/A SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_, 1717053SN/A "character string is empty"); 1726899SN/A return std::string(); 1737053SN/A } 1746899SN/A 1757053SN/A int n = strlen(s); 1767053SN/A int i = 0; 1776899SN/A if (s[0] == '-' || s[0] == '+') { 1787053SN/A ++i; 1797823Ssteve.reinhardt@amd.com } 1807053SN/A if (n > (i + 2) && s[i] == '0') { 1816899SN/A if (s[i + 1] == 'b' || s[i + 1] == 'B') { 1828190SLisa.Hsu@amd.com if (s[i + 2] == '0' || s[i + 2] == '1') { 1837053SN/A std::string str(&s[2]); 1847053SN/A str += "F"; 1857053SN/A return str; 1867053SN/A } 1877053SN/A } 1887053SN/A if (s[i + 1] == 'b' || s[i + 1] == 'B' || 1896899SN/A s[i + 1] == 'c' || s[i + 1] == 'C' || 1907053SN/A s[i + 1] == 'd' || s[i + 1] == 'D' || 1916899SN/A s[i + 1] == 'o' || s[i + 1] == 'O' || 1927053SN/A s[i + 1] == 'x' || s[i + 1] == 'X') { 1937053SN/A try { 1947053SN/A // worst case length = n * 4 1957053SN/A sc_fix a(s, n * 4, n * 4, SC_TRN, SC_WRAP, 0, SC_ON); 1966899SN/A std::string str = a.to_bin(); 1977053SN/A str += "F"; // mark the string as formatted 1987053SN/A // get rid of prefix (0b) and redundant leading bits 1996899SN/A const char *p = str.c_str() + 2; 2007053SN/A while (p[1] && p[0] == p[1]) { 2017053SN/A ++p; 2027053SN/A } 2037053SN/A return std::string(p); 2046899SN/A } catch (const sc_core::sc_report &) { 2057053SN/A std::stringstream msg; 2067053SN/A msg << "character string '" << s << "' is not valid"; 2077053SN/A SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_, 2087053SN/A msg.str().c_str()); 2097053SN/A return std::string(); 2107053SN/A } 2117053SN/A } 2127053SN/A } 2137053SN/A 2147053SN/A // bin by default 2157053SN/A std::string str(s); 2167053SN/A str += "U"; // mark the string as unformatted 2177053SN/A return str; 2187053SN/A} 2197053SN/A 2207053SN/A// convert binary string to formatted string 2217053SN/Aconst std::string 2227053SN/Aconvert_to_fmt(const std::string &s, sc_numrep numrep, bool w_prefix) 2237053SN/A{ 2246899SN/A int n = s.length(); 2256899SN/A std::string str("0bus"); 2266899SN/A // str += "0bus"; 2277053SN/A str += s; 2287053SN/A sc_ufix a(str.c_str(), n, n, SC_TRN, SC_WRAP, 0, SC_ON); 2296899SN/A return a.to_string(numrep, w_prefix); 2307053SN/A} 2317053SN/A 2326899SN/A} // namespace sc_dt 2337053SN/A