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_bv_base.cpp -- Arbitrary size bit vector class. 23 24 Original Author: Gene Bushuyev, Synopsys, Inc. 25 26 *****************************************************************************/ 27 28/***************************************************************************** 29 30 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 changes you are making here. 32 33 Name, Affiliation, Date: 34 Description of Modification: 35 36 *****************************************************************************/ 37 38 39// $Log: sc_bv_base.cpp,v $ 40// Revision 1.2 2011/08/24 22:05:40 acg 41// Torsten Maehne: initialization changes to remove warnings. 42// 43// Revision 1.1.1.1 2006/12/15 20:20:04 acg 44// SystemC 2.3 45// 46// Revision 1.4 2006/04/11 23:12:26 acg 47// Andy Goodrich: Fixed bug in parsing of extended string constants like 48// 0bus1110011. 49// 50// Revision 1.3 2006/01/13 18:53:53 acg 51// Andy Goodrich: added $Log command so that CVS comments are reproduced in 52// the source. 53// 54 55#include <cstring> 56#include <sstream> 57 58#include "systemc/ext/dt/bit/messages.hh" 59#include "systemc/ext/dt/bit/sc_bv_base.hh" 60#include "systemc/ext/dt/fx/sc_fix.hh" 61#include "systemc/ext/dt/fx/sc_ufix.hh" 62#include "systemc/ext/utils/sc_report.hh" 63 64namespace sc_dt 65{ 66 67// ---------------------------------------------------------------------------- 68// CLASS : sc_bv_base 69// 70// Arbitrary size bit vector base class. 71// ---------------------------------------------------------------------------- 72 73void 74sc_bv_base::init(int length_, bool init_value) 75{ 76 // check the length 77 if (length_ <= 0) { 78 SC_REPORT_ERROR(sc_core::SC_ID_ZERO_LENGTH_, 0); 79 sc_core::sc_abort(); // can't recover from here 80 } 81 // allocate memory for the data and control words 82 m_len = length_; 83 m_size = (m_len - 1) / SC_DIGIT_SIZE + 1; 84 m_data = new sc_digit[m_size]; 85 // initialize the bits to 'init_value' 86 sc_digit dw = init_value ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO; 87 int sz = m_size; 88 for (int i = 0; i < sz; ++i) { 89 m_data[i] = dw; 90 } 91 clean_tail(); 92} 93 94void 95sc_bv_base::assign_from_string(const std::string &s) 96{ 97 // s must have been converted to bin 98 int len = m_len; 99 int s_len = s.length() - 1; 100 int min_len = sc_min(len, s_len); 101 int i = 0; 102 for (; i < min_len; ++i) { 103 char c = s[s_len - i - 1]; 104 if (c != '0' && c != '1') { 105 SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_, 106 "string can contain only '0' and '1' characters"); 107 // may continue, if suppressed 108 c = '0'; 109 } 110 set_bit(i, sc_logic_value_t(c - '0')); 111 } 112 // if formatted, fill the rest with sign(s), otherwise fill with zeros 113 sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t(s[0] - '0') 114 : sc_logic_value_t(0)); 115 for (; i < len; ++i) { 116 set_bit(i, fill); 117 } 118} 119 120// constructors 121sc_bv_base::sc_bv_base(const char *a) : m_len(0), m_size(0), m_data(0) 122{ 123 std::string s = convert_to_bin(a); 124 init(s.length() - 1); 125 assign_from_string(s); 126} 127 128sc_bv_base::sc_bv_base(const char *a, int length_) : 129 m_len(0), m_size(0), m_data(0) 130{ 131 init(length_); 132 assign_from_string(convert_to_bin(a)); 133} 134 135sc_bv_base::sc_bv_base(const sc_bv_base &a) : 136 sc_proxy<sc_bv_base>(), m_len(a.m_len), m_size(a.m_size), 137 m_data(new sc_digit[m_size]) 138{ 139 // copy the bits 140 int sz = m_size; 141 for (int i = 0; i < sz; ++i) { 142 m_data[i] = a.m_data[i]; 143 } 144} 145 146// assignment operators 147sc_bv_base & 148sc_bv_base::operator = (const char *a) 149{ 150 assign_from_string(convert_to_bin(a)); 151 return *this; 152} 153 154 155// ---------------------------------------------------------------------------- 156// convert formatted string to binary string 157 158const std::string 159convert_to_bin(const char *s) 160{ 161 // Beware: logic character strings cannot start with '0x' or '0X', 162 // because this is seen as a hexadecimal encoding prefix! 163 164 if (s == 0) { 165 SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_, 166 "character string is zero"); 167 return std::string(); 168 } 169 if (*s == 0) { 170 SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_, 171 "character string is empty"); 172 return std::string(); 173 } 174 175 int n = strlen(s); 176 int i = 0; 177 if (s[0] == '-' || s[0] == '+') { 178 ++i; 179 } 180 if (n > (i + 2) && s[i] == '0') { 181 if (s[i + 1] == 'b' || s[i + 1] == 'B') { 182 if (s[i + 2] == '0' || s[i + 2] == '1') { 183 std::string str(&s[2]); 184 str += "F"; 185 return str; 186 } 187 } 188 if (s[i + 1] == 'b' || s[i + 1] == 'B' || 189 s[i + 1] == 'c' || s[i + 1] == 'C' || 190 s[i + 1] == 'd' || s[i + 1] == 'D' || 191 s[i + 1] == 'o' || s[i + 1] == 'O' || 192 s[i + 1] == 'x' || s[i + 1] == 'X') { 193 try { 194 // worst case length = n * 4 195 sc_fix a(s, n * 4, n * 4, SC_TRN, SC_WRAP, 0, SC_ON); 196 std::string str = a.to_bin(); 197 str += "F"; // mark the string as formatted 198 // get rid of prefix (0b) and redundant leading bits 199 const char *p = str.c_str() + 2; 200 while (p[1] && p[0] == p[1]) { 201 ++p; 202 } 203 return std::string(p); 204 } catch (const sc_core::sc_report &) { 205 std::stringstream msg; 206 msg << "character string '" << s << "' is not valid"; 207 SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_, 208 msg.str().c_str()); 209 return std::string(); 210 } 211 } 212 } 213 214 // bin by default 215 std::string str(s); 216 str += "U"; // mark the string as unformatted 217 return str; 218} 219 220// convert binary string to formatted string 221const std::string 222convert_to_fmt(const std::string &s, sc_numrep numrep, bool w_prefix) 223{ 224 int n = s.length(); 225 std::string str("0bus"); 226 // str += "0bus"; 227 str += s; 228 sc_ufix a(str.c_str(), n, n, SC_TRN, SC_WRAP, 0, SC_ON); 229 return a.to_string(numrep, w_prefix); 230} 231 232} // namespace sc_dt 233