Deleted Added
sdiff udiff text old ( 12854:c95c35407325 ) new ( 13325:86323e6cc8ec )
full compact
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