1 // -*- mode: C++; c-file-style: "cc-mode" -*-
2 //*************************************************************************
3 // DESCRIPTION: Verilator: Large 4-state numbers
4 //
5 // Code available from: https://verilator.org
6 //
7 //*************************************************************************
8 //
9 // Copyright 2003-2021 by Wilson Snyder. This program is free software; you
10 // can redistribute it and/or modify it under the terms of either the GNU
11 // Lesser General Public License Version 3 or the Perl Artistic License
12 // Version 2.0.
13 // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
14 //
15 //*************************************************************************
16
17 #include "config_build.h"
18 #include "verilatedos.h"
19
20 #include "V3Global.h"
21 #include "V3Number.h"
22 #include "V3Ast.h"
23
24 #include <algorithm>
25 #include <cerrno>
26 #include <cmath>
27 #include <functional>
28
29 constexpr int MAX_SPRINTF_DOUBLE_SIZE
30 = 1100; // Maximum characters with a sprintf %e/%f/%g (really 1079)
31
32 // Number operations build output in-place so can't call e.g. foo.opX(foo)
33 #define NUM_ASSERT_OP_ARGS1(arg1) \
34 UASSERT((this != &(arg1)), "Number operation called with same source and dest")
35 #define NUM_ASSERT_OP_ARGS2(arg1, arg2) \
36 UASSERT((this != &(arg1) && this != &(arg2)), \
37 "Number operation called with same source and dest")
38 #define NUM_ASSERT_OP_ARGS3(arg1, arg2, arg3) \
39 UASSERT((this != &(arg1) && this != &(arg2) && this != &(arg3)), \
40 "Number operation called with same source and dest")
41 #define NUM_ASSERT_OP_ARGS4(arg1, arg2, arg3, arg4) \
42 UASSERT((this != &(arg1) && this != &(arg2) && this != &(arg3) && this != &(arg4)), \
43 "Number operation called with same source and dest")
44
45 #define NUM_ASSERT_LOGIC_ARGS1(arg1) \
46 UASSERT((!(arg1).isDouble() && !(arg1).isString()), \
47 "Number operation called with non-logic (double or string) argument: '" << (arg1) \
48 << '"')
49 #define NUM_ASSERT_LOGIC_ARGS2(arg1, arg2) \
50 NUM_ASSERT_LOGIC_ARGS1(arg1); \
51 NUM_ASSERT_LOGIC_ARGS1(arg2)
52
53 #define NUM_ASSERT_LOGIC_ARGS4(arg1, arg2, arg3, arg4) \
54 NUM_ASSERT_LOGIC_ARGS1(arg1); \
55 NUM_ASSERT_LOGIC_ARGS1(arg2); \
56 NUM_ASSERT_LOGIC_ARGS1(arg3); \
57 NUM_ASSERT_LOGIC_ARGS1(arg4)
58
59 #define NUM_ASSERT_STRING_ARGS1(arg1) \
60 UASSERT((arg1).isString(), \
61 "Number operation called with non-string argument: '" << (arg1) << '"')
62 #define NUM_ASSERT_STRING_ARGS2(arg1, arg2) \
63 NUM_ASSERT_STRING_ARGS1(arg1); \
64 NUM_ASSERT_STRING_ARGS1(arg2)
65
66 #define NUM_ASSERT_DOUBLE_ARGS1(arg1) \
67 UASSERT((arg1).isDouble(), \
68 "Number operation called with non-double argument: '" << (arg1) << '"')
69 #define NUM_ASSERT_DOUBLE_ARGS2(arg1, arg2) \
70 NUM_ASSERT_DOUBLE_ARGS1(arg1); \
71 NUM_ASSERT_DOUBLE_ARGS1(arg2)
72
73 //======================================================================
74 // Errors
75
v3errorEnd(std::ostringstream & str) const76 void V3Number::v3errorEnd(std::ostringstream& str) const {
77 std::ostringstream nsstr;
78 nsstr << str.str();
79 if (m_nodep) {
80 m_nodep->v3errorEnd(nsstr);
81 } else {
82 m_fileline->v3errorEnd(nsstr);
83 }
84 }
85
v3errorEndFatal(std::ostringstream & str) const86 void V3Number::v3errorEndFatal(std::ostringstream& str) const {
87 v3errorEnd(str);
88 assert(0); // LCOV_EXCL_LINE
89 VL_UNREACHABLE
90 }
91
92 //======================================================================
93 // Read class functions
94 // CREATION
95
V3Number(VerilogStringLiteral,AstNode * nodep,const string & str)96 V3Number::V3Number(VerilogStringLiteral, AstNode* nodep, const string& str) {
97 // Create a number using a verilog string as the value, thus 8 bits per character.
98 // cppcheck bug - doesn't see init() resets these
99 // cppcheck: Member variable 'm_sized/m_width' is not initialized in the constructor
100 init(nodep, str.length() * 8);
101 m_fromString = true;
102 for (unsigned pos = 0; pos < str.length(); ++pos) {
103 const int topos = str.length() - 1 - pos;
104 ValueAndX& v = m_value[topos / 4];
105 for (int bit = 0; bit < 8; ++bit) {
106 if (str[pos] & (1UL << bit)) { v.m_value |= (1UL << (bit + (topos % 4) * 8)); }
107 }
108 }
109 opCleanThis(true);
110 }
111
V3NumberCreate(AstNode * nodep,const char * sourcep,FileLine * fl)112 void V3Number::V3NumberCreate(AstNode* nodep, const char* sourcep, FileLine* fl) {
113 init(nodep, 0);
114 m_fileline = fl;
115 const char* value_startp = sourcep;
116 for (const char* cp = sourcep; *cp; cp++) {
117 if (*cp == '\'') {
118 value_startp = cp + 1;
119 break;
120 }
121 }
122
123 bool unbased = false;
124 char base = '\0';
125 if (value_startp != sourcep) { // Has a '
126 string widthn;
127 const char* cp = sourcep;
128 for (; *cp; cp++) {
129 if (*cp == '\'') {
130 cp++;
131 break;
132 }
133 if (*cp != '_') widthn += *cp;
134 }
135 while (*cp == '_') cp++;
136 if (*cp && tolower(*cp) == 's') {
137 cp++;
138 isSigned(true);
139 }
140 if (*cp) {
141 base = *cp;
142 cp++;
143 }
144 value_startp = cp;
145
146 if (atoi(widthn.c_str())) {
147 if (atoi(widthn.c_str()) < 0 || atoi(widthn.c_str()) > v3Global.opt.maxNumWidth()) {
148 // atoi might convert large number to negative, so can't tell which
149 v3error("Unsupported: Width of number exceeds implementation limit: "
150 << sourcep << " (IEEE 1800-2017 6.9.1)");
151 width(v3Global.opt.maxNumWidth(), true);
152 } else {
153 width(atoi(widthn.c_str()), true);
154 }
155 }
156 } else {
157 unbased = true;
158 base = 'd';
159 }
160
161 for (int i = 0; i < words(); ++i) m_value[i] = {0, 0};
162
163 // Special SystemVerilog unsized constructs
164 if (base == '0') {
165 setBit(0, 0);
166 width(1, false); // So we extend it
167 m_autoExtend = true;
168 } else if (base == '1') {
169 setBit(0, 1);
170 width(1, false); // So we extend it
171 m_autoExtend = true;
172 } else if (tolower(base) == 'z') {
173 setBit(0, 'z');
174 width(1, false); // So we extend it
175 m_autoExtend = true;
176 } else if (tolower(base) == 'x') {
177 setBit(0, 'x');
178 width(1, false); // So we extend it
179 m_autoExtend = true;
180 }
181 // Otherwise...
182 else if (!m_sized) {
183 width(32, false); // Says IEEE 1800-2012 5.7.1
184 if (unbased) isSigned(true); // Also says the spec.
185 }
186
187 // Ignore leading blanks
188 while (*value_startp == '_' || isspace(*value_startp)) value_startp++;
189 if (!*value_startp && !m_autoExtend) {
190 v3error("Number is missing value digits: " << sourcep);
191 }
192
193 int obit = 0; // Start at LSB
194 if (tolower(base) == 'd') {
195 // Ignore leading zeros so we don't issue too many digit errors when lots of leading 0's
196 while (*value_startp == '_' || *value_startp == '0') value_startp++;
197 // Convert decimal number to hex
198 int olen = 0;
199 uint32_t val = 0;
200 int got_x = 0;
201 int got_z = 0;
202 int got_01 = 0;
203 for (const char* cp = value_startp; *cp; cp++) {
204 switch (tolower(*cp)) {
205 case '0': // FALLTHRU
206 case '1': // FALLTHRU
207 case '2': // FALLTHRU
208 case '3': // FALLTHRU
209 case '4': // FALLTHRU
210 case '5': // FALLTHRU
211 case '6': // FALLTHRU
212 case '7': // FALLTHRU
213 case '8': // FALLTHRU
214 case '9': {
215 if (olen <= 7) { // 10000000 fits in 32 bits, so ok
216 // Constants are common, so for speed avoid wide math until we need it
217 val = val * 10 + (*cp - '0');
218 m_value[0].m_value = val;
219 } else { // Wide; all previous digits are already in m_value[0]
220 // this = (this * 10)/*product*/ + (*cp-'0')/*addend*/
221 // Assumed rare; lots of optimizations are possible here
222 V3Number product(this, width() + 4); // +4 for overflow detection
223 const V3Number ten(this, width() + 4, 10);
224 const V3Number addend(this, width(), (*cp - '0'));
225 product.opMul(*this, ten);
226 this->opAdd(product, addend);
227 if (product.bitsValue(width(), 4)) { // Overflowed
228 static int warned = 0;
229 v3error("Too many digits for "
230 << width() << " bit number: " << sourcep << '\n'
231 << ((!m_sized && !warned++) ? (
232 V3Error::warnMore() + "... As that number was unsized"
233 + " ('d...) it is limited to 32 bits (IEEE 1800-2017 "
234 "5.7.1)\n"
235 + V3Error::warnMore() + "... Suggest adding a size to it.")
236 : ""));
237 while (*(cp + 1)) cp++; // Skip ahead so don't get multiple warnings
238 }
239 }
240 olen++;
241 got_01 = 1;
242 break;
243 }
244 case 'z':
245 case '?': {
246 got_z = 1;
247 setAllBitsZ();
248 break;
249 }
250 case 'x': {
251 got_x = 1;
252 setAllBitsX();
253 break;
254 }
255 case '_': break;
256 default: {
257 v3error("Illegal character in decimal constant: " << *cp);
258 break;
259 }
260 }
261 }
262 obit = width();
263 if ((got_01 + got_x + got_z) > 1) {
264 v3error("Mixing X/Z/? with digits not legal in decimal constant: " << value_startp);
265 }
266 } else {
267 // Convert bin/octal number to hex
268 for (const char* cp = value_startp + strlen(value_startp) - 1; cp >= value_startp; cp--) {
269 if (*cp != '_' && *cp != '0' && obit >= width()) {
270 v3error("Too many digits for " << width() << " bit number: " << sourcep);
271 break;
272 }
273 switch (tolower(base)) {
274 case 'b': {
275 switch (tolower(*cp)) {
276 case '0': setBit(obit++, 0); break;
277 case '1': setBit(obit++, 1); break;
278 case 'z':
279 case '?': setBit(obit++, 'z'); break;
280 case 'x': setBit(obit++, 'x'); break;
281 case '_': break;
282 default: v3error("Illegal character in binary constant: " << *cp);
283 }
284 break;
285 }
286
287 case 'o':
288 case 'c': {
289 switch (tolower(*cp)) {
290 // clang-format off
291 case '0': setBit(obit++, 0); setBit(obit++, 0); setBit(obit++, 0); break;
292 case '1': setBit(obit++, 1); setBit(obit++, 0); setBit(obit++, 0); break;
293 case '2': setBit(obit++, 0); setBit(obit++, 1); setBit(obit++, 0); break;
294 case '3': setBit(obit++, 1); setBit(obit++, 1); setBit(obit++, 0); break;
295 case '4': setBit(obit++, 0); setBit(obit++, 0); setBit(obit++, 1); break;
296 case '5': setBit(obit++, 1); setBit(obit++, 0); setBit(obit++, 1); break;
297 case '6': setBit(obit++, 0); setBit(obit++, 1); setBit(obit++, 1); break;
298 case '7': setBit(obit++, 1); setBit(obit++, 1); setBit(obit++, 1); break;
299 case 'z':
300 case '?': setBit(obit++, 'z'); setBit(obit++, 'z'); setBit(obit++, 'z'); break;
301 case 'x': setBit(obit++, 'x'); setBit(obit++, 'x'); setBit(obit++, 'x'); break;
302 case '_': break;
303 // clang-format on
304 default: v3error("Illegal character in octal constant");
305 }
306 break;
307 }
308
309 case 'h': {
310 switch (tolower(*cp)) {
311 // clang-format off
312 case '0': setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); break;
313 case '1': setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); break;
314 case '2': setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); break;
315 case '3': setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); break;
316 case '4': setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); break;
317 case '5': setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); break;
318 case '6': setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); break;
319 case '7': setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); break;
320 case '8': setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); break;
321 case '9': setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); break;
322 case 'a': setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); break;
323 case 'b': setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); break;
324 case 'c': setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); break;
325 case 'd': setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); break;
326 case 'e': setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); break;
327 case 'f': setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); break;
328 case 'z':
329 case '?': setBit(obit++,'z'); setBit(obit++,'z'); setBit(obit++,'z'); setBit(obit++,'z'); break;
330 case 'x': setBit(obit++,'x'); setBit(obit++,'x'); setBit(obit++,'x'); setBit(obit++,'x'); break;
331 // clang-format on
332 case '_': break;
333 default: v3error("Illegal character in hex constant: " << *cp);
334 }
335 break;
336 }
337 default: v3error("Illegal base character: " << base);
338 }
339 }
340 }
341
342 // Z or X extend specific width values. Spec says we don't 1 extend.
343 // This fixes 2'bx to become 2'bxx.
344 while (obit <= width() && obit && bitIsXZ(obit - 1)) {
345 setBit(obit, bitIs(obit - 1));
346 obit++;
347 }
348 opCleanThis(true);
349
350 // printf("Dump \"%s\" CP \"%s\" B '%c' %d W %d\n", sourcep, value_startp, base, width(),
351 // m_value[0]);
352 }
353
setNames(AstNode * nodep)354 void V3Number::setNames(AstNode* nodep) {
355 m_nodep = nodep;
356 if (!nodep) return;
357 m_fileline = nodep->fileline();
358 }
359
360 //======================================================================
361 // Global
362
log2b(uint32_t num)363 int V3Number::log2b(uint32_t num) {
364 // See also opCLog2
365 for (int bit = 31; bit > 0; bit--) {
366 if (num & (1ULL << bit)) return bit;
367 }
368 return 0;
369 }
370
371 //======================================================================
372 // Setters
373
setZero()374 V3Number& V3Number::setZero() {
375 for (int i = 0; i < words(); i++) m_value[i] = {0, 0};
376 return *this;
377 }
setQuad(vluint64_t value)378 V3Number& V3Number::setQuad(vluint64_t value) {
379 for (int i = 0; i < words(); i++) m_value[i] = {0, 0};
380 m_value[0].m_value = value & 0xffffffffULL;
381 if (width() > 32) m_value[1].m_value = (value >> 32ULL) & 0xffffffffULL;
382 opCleanThis();
383 return *this;
384 }
setLong(uint32_t value)385 V3Number& V3Number::setLong(uint32_t value) {
386 for (int i = 0; i < words(); i++) m_value[i] = {0, 0};
387 m_value[0].m_value = value;
388 opCleanThis();
389 return *this;
390 }
setLongS(vlsint32_t value)391 V3Number& V3Number::setLongS(vlsint32_t value) {
392 for (int i = 0; i < words(); i++) m_value[i] = {0, 0};
393 union {
394 uint32_t u;
395 vlsint32_t s;
396 } u;
397 u.s = value;
398 if (u.s) {}
399 m_value[0].m_value = u.u;
400 opCleanThis();
401 return *this;
402 }
setDouble(double value)403 V3Number& V3Number::setDouble(double value) {
404 if (VL_UNCOVERABLE(width() != 64)) v3fatalSrc("Real operation on wrong sized number");
405 m_double = true;
406 union {
407 double d;
408 uint32_t u[2];
409 } u;
410 u.d = value;
411 if (u.d != 0.0) {}
412 for (int i = 2; i < words(); i++) m_value[i] = {0, 0};
413 m_value[0].m_value = u.u[0];
414 m_value[1].m_value = u.u[1];
415 return *this;
416 }
setSingleBits(char value)417 V3Number& V3Number::setSingleBits(char value) {
418 for (int i = 1 /*upper*/; i < words(); i++) m_value[i] = {0, 0};
419 m_value[0] = {(value == '1' || value == 'x' || value == 1 || value == 3),
420 (value == 'z' || value == 'x' || value == 2 || value == 3)};
421 return *this;
422 }
423
setAllBits0()424 V3Number& V3Number::setAllBits0() {
425 for (int i = 0; i < words(); i++) m_value[i] = {0, 0};
426 return *this;
427 }
setAllBits1()428 V3Number& V3Number::setAllBits1() {
429 for (int i = 0; i < words(); i++) m_value[i] = {~0U, 0};
430 opCleanThis();
431 return *this;
432 }
setAllBitsX()433 V3Number& V3Number::setAllBitsX() {
434 // Use setAllBitsXRemoved if calling this based on a non-X/Z input value such as divide by zero
435 for (int i = 0; i < words(); i++) m_value[i] = {~0U, ~0U};
436 opCleanThis();
437 return *this;
438 }
setAllBitsZ()439 V3Number& V3Number::setAllBitsZ() {
440 for (int i = 0; i < words(); i++) m_value[i] = {0, ~0U};
441 opCleanThis();
442 return *this;
443 }
setAllBitsXRemoved()444 V3Number& V3Number::setAllBitsXRemoved() {
445 if (!v3Global.constRemoveXs()) {
446 return setAllBitsX();
447 } else {
448 // If we get a divide by zero we get Xs.
449 // But after V3Unknown we have removed Xs, so use --x-assign to direct-insert 0/1
450 if (v3Global.opt.xAssign() == "1") {
451 return setAllBits1();
452 } else {
453 return setAllBits0();
454 }
455 }
456 }
457
setMask(int nbits)458 V3Number& V3Number::setMask(int nbits) {
459 setZero();
460 for (int bit = 0; bit < nbits; bit++) setBit(bit, 1);
461 return *this;
462 }
463
464 //======================================================================
465 // ACCESSORS - as strings
466
ascii(bool prefixed,bool cleanVerilog) const467 string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
468 std::ostringstream out;
469
470 if (isDouble()) {
471 out.precision(17);
472 if (VL_UNCOVERABLE(width() != 64)) {
473 out << "%E-bad-width-double"; // LCOV_EXCL_LINE
474 } else {
475 out << toDouble();
476 }
477 return out.str();
478 } else if (isString()) {
479 return '"' + toString() + '"';
480 } else {
481 if (VL_UNCOVERABLE((m_value[words() - 1].m_value | m_value[words() - 1].m_valueX)
482 & ~hiWordMask())) {
483 out << "%E-hidden-bits"; // LCOV_EXCL_LINE
484 }
485 }
486 if (prefixed) {
487 if (sized()) {
488 out << width() << "'";
489 } else if (autoExtend() && !sized() && width() == 1) {
490 out << "'";
491 if (bitIs0(0)) {
492 out << '0';
493 if (isNull()) out << "[null]";
494 } else if (bitIs1(0)) {
495 out << '1';
496 } else if (bitIsZ(0)) {
497 out << 'z';
498 } else {
499 out << 'x';
500 }
501 return out.str();
502 } else {
503 if (cleanVerilog) {
504 out << "'";
505 } else {
506 out << "?" << width() << "?";
507 }
508 }
509 if (isSigned()) out << "s";
510 }
511
512 const bool binary = (isFourState()
513 #ifdef V3NUMBER_ASCII_BINARY
514 // cppcheck-suppress konwnConditionTrueFalse
515 || true
516 #endif
517 );
518 // out<<"-"<<hex<<m_value[0]<<"-";
519
520 // cppcheck-suppress konwnConditionTrueFalse
521 if (binary) {
522 out << "b";
523 out << displayed("%0b");
524 } else {
525 if (prefixed) out << "h";
526 // Always deal with 4 bits at once. Note no 4-state, it's above.
527 out << displayed("%0h");
528 }
529 if (isNull() && VL_UNCOVERABLE(!isEqZero())) out << "-%E-null-not-zero";
530 return out.str();
531 }
532
displayedFmtLegal(char format,bool isScan)533 bool V3Number::displayedFmtLegal(char format, bool isScan) {
534 // Is this a valid format letter?
535 switch (tolower(format)) {
536 case 'b': return true;
537 case 'c': return true;
538 case 'd': return true; // Unsigned decimal
539 case 'e': return true;
540 case 'f': return true;
541 case 'g': return true;
542 case 'h': return true;
543 case 'o': return true;
544 case 'p': return true; // Pattern
545 case 's': return true;
546 case 't': return true;
547 case 'u': return true; // Packed 2-state
548 case 'v': return true; // Strength
549 case 'x': return true;
550 case 'z': return true; // Packed 4-state
551 case '@': return true; // Packed string
552 case '~': return true; // Signed decimal
553 case '*': return isScan; // $scan ignore argument
554 default: return false;
555 }
556 }
557
displayPad(size_t fmtsize,char pad,bool left,const string & in)558 string V3Number::displayPad(size_t fmtsize, char pad, bool left, const string& in) {
559 string padding;
560 if (in.length() < fmtsize) padding = string(fmtsize - in.length(), pad);
561 return left ? (in + padding) : (padding + in);
562 }
563
displayed(AstNode * nodep,const string & vformat) const564 string V3Number::displayed(AstNode* nodep, const string& vformat) const {
565 return displayed(nodep->fileline(), vformat);
566 }
567
displayed(FileLine * fl,const string & vformat) const568 string V3Number::displayed(FileLine* fl, const string& vformat) const {
569 auto pos = vformat.cbegin();
570 UASSERT(pos != vformat.cend() && pos[0] == '%',
571 "$display-like function with non format argument " << *this);
572 ++pos;
573 bool left = false;
574 if (pos[0] == '-') {
575 left = true;
576 ++pos;
577 }
578 string fmtsize;
579 for (; pos != vformat.cend() && (isdigit(pos[0]) || pos[0] == '.'); ++pos) {
580 fmtsize += pos[0];
581 }
582 string str;
583 const char code = tolower(pos[0]);
584 switch (code) {
585 case 'b': {
586 int bit = width() - 1;
587 if (fmtsize == "0")
588 while (bit && bitIs0(bit)) bit--;
589 for (; bit >= 0; bit--) {
590 if (bitIs0(bit)) {
591 str += '0';
592 } else if (bitIs1(bit)) {
593 str += '1';
594 } else if (bitIsZ(bit)) {
595 str += 'z';
596 } else {
597 str += 'x';
598 }
599 }
600 return str;
601 }
602 case 'o': {
603 int bit = width() - 1;
604 if (fmtsize == "0")
605 while (bit && bitIs0(bit)) bit--;
606 while ((bit % 3) != 2) bit++;
607 for (; bit > 0; bit -= 3) {
608 const int numX = countX(bit - 2, 3);
609 const int numZ = countZ(bit - 2, 3);
610 if (numX == 3 || numX == width() - (bit - 2)) {
611 str += 'x';
612 continue;
613 }
614 if (numZ == 3 || numZ == width() - (bit - 2)) {
615 str += 'z';
616 continue;
617 }
618 if (numX > 0) {
619 str += 'X';
620 continue;
621 }
622 if (numZ > 0) {
623 str += 'Z';
624 continue;
625 }
626 const int v = bitsValue(bit - 2, 3);
627 str += static_cast<char>('0' + v);
628 }
629 return str;
630 }
631 case 'h':
632 case 'x': {
633 int bit = width() - 1;
634 if (fmtsize == "0")
635 while (bit && bitIs0(bit)) bit--;
636 while ((bit % 4) != 3) bit++;
637 for (; bit > 0; bit -= 4) {
638 const int numX = countX(bit - 3, 4);
639 const int numZ = countZ(bit - 3, 4);
640 if (numX == 4 || numX == width() - (bit - 3)) {
641 str += 'x';
642 continue;
643 }
644 if (numZ == 4 || numZ == width() - (bit - 3)) {
645 str += 'z';
646 continue;
647 }
648 if (numX > 0) {
649 str += 'X';
650 continue;
651 }
652 if (numZ > 0) {
653 str += 'Z';
654 continue;
655 }
656 const int v = bitsValue(bit - 3, 4);
657 if (v >= 10) {
658 str += static_cast<char>('a' + v - 10);
659 } else {
660 str += static_cast<char>('0' + v);
661 }
662 }
663 return str;
664 }
665 case 'c': {
666 if (width() > 8) fl->v3warn(WIDTH, "$display-like format of %c format of > 8 bit value");
667 const unsigned int v = bitsValue(0, 8);
668 char strc[2];
669 strc[0] = v & 0xff;
670 strc[1] = '\0';
671 str = strc;
672 return str;
673 }
674 case 's': {
675 // Spec says always drop leading zeros, this isn't quite right, we space pad.
676 int bit = this->width() - 1;
677 bool start = true;
678 while ((bit % 8) != 7) bit++;
679 for (; bit >= 0; bit -= 8) {
680 const int v = bitsValue(bit - 7, 8);
681 if (!start || v) {
682 str += static_cast<char>((v == 0) ? ' ' : v);
683 start = false; // Drop leading 0s
684 } else {
685 if (fmtsize != "0") str += ' ';
686 }
687 }
688 const size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
689 str = displayPad(fmtsizen, ' ', left, str);
690 return str;
691 }
692 case '~': // Signed decimal
693 case 't': // Time
694 case 'd': { // Unsigned decimal
695 const bool issigned = (code == '~');
696 if (fmtsize == "") {
697 const double mantissabits = this->width() - (issigned ? 1 : 0);
698 // To get the number of digits required, we want to compute
699 // log10(2**mantissabits) and round it up. To be able to handle
700 // a very wide mantissa, we use log2(2**mantissabits)/log2(10),
701 // which is simply (+1.0 is for rounding bias):
702 double dchars = mantissabits / 3.321928094887362 + 1.0;
703 if (issigned) dchars++; // space for sign
704 fmtsize = cvtToStr(int(dchars));
705 }
706 bool hasXZ = false;
707 if (isAllX()) {
708 str = "x";
709 hasXZ = true;
710 } else if (isAllZ()) {
711 str = "z";
712 hasXZ = true;
713 } else if (isAnyX()) {
714 str = "X";
715 hasXZ = true;
716 } else if (isAnyZ()) {
717 str = "Z";
718 hasXZ = true;
719 }
720 if (!hasXZ) {
721 if (issigned) {
722 if (width() > 64) {
723 str = toDecimalS();
724 } else {
725 str = cvtToStr(toSQuad());
726 }
727 } else {
728 if (width() > 64) {
729 str = toDecimalU();
730 } else {
731 str = cvtToStr(toUQuad());
732 }
733 }
734 }
735 const bool zeropad = fmtsize.length() > 0 && fmtsize[0] == '0';
736 // fmtsize might have changed since we parsed the %fmtsize
737 const size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
738 str = displayPad(fmtsizen, (zeropad ? '0' : ' '), left, str);
739 return str;
740 }
741 case 'e':
742 case 'f':
743 case 'g':
744 case '^': { // Realtime
745 char tmp[MAX_SPRINTF_DOUBLE_SIZE];
746 VL_SNPRINTF(tmp, MAX_SPRINTF_DOUBLE_SIZE, vformat.c_str(), toDouble());
747 return tmp;
748 }
749 // 'l' // Library - converted to text by V3LinkResolve
750 // 'p' // Packed - converted to another code by V3Width
751 case 'u': { // Packed 2-state
752 for (int i = 0; i < words(); i++) {
753 const uint32_t v = m_value[i].m_value;
754 str += static_cast<char>((v >> 0) & 0xff);
755 str += static_cast<char>((v >> 8) & 0xff);
756 str += static_cast<char>((v >> 16) & 0xff);
757 str += static_cast<char>((v >> 24) & 0xff);
758 }
759 return str;
760 }
761 case 'z': { // Packed 4-state
762 for (int i = 0; i < words(); i++) {
763 const ValueAndX v = m_value[i];
764 str += static_cast<char>((v.m_value >> 0) & 0xff);
765 str += static_cast<char>((v.m_value >> 8) & 0xff);
766 str += static_cast<char>((v.m_value >> 16) & 0xff);
767 str += static_cast<char>((v.m_value >> 24) & 0xff);
768 str += static_cast<char>((v.m_valueX >> 0) & 0xff);
769 str += static_cast<char>((v.m_valueX >> 8) & 0xff);
770 str += static_cast<char>((v.m_valueX >> 16) & 0xff);
771 str += static_cast<char>((v.m_valueX >> 24) & 0xff);
772 }
773 return str;
774 }
775 case 'v': { // Strength
776 int bit = width() - 1;
777 for (; bit >= 0; bit--) {
778 if (bitIs0(bit)) {
779 str += "St0 ";
780 } // Yes, always a space even for bit 0
781 else if (bitIs1(bit)) {
782 str += "St1 ";
783 } else if (bitIsZ(bit)) {
784 str += "StZ ";
785 } else {
786 str += "StX";
787 }
788 }
789 return str;
790 }
791 case '@': { // Packed string
792 const size_t fmtsizen = static_cast<size_t>(atoi(fmtsize.c_str()));
793 str = displayPad(fmtsizen, ' ', left, toString());
794 return str;
795 }
796 default:
797 fl->v3fatalSrc("Unknown $display-like format code for number: %" << pos[0]);
798 return "ERR";
799 }
800 }
801
toDecimalS() const802 string V3Number::toDecimalS() const {
803 if (isNegative()) {
804 V3Number lhsNoSign = *this;
805 lhsNoSign.opNegate(*this);
806 return string("-") + lhsNoSign.toDecimalU();
807 } else {
808 return toDecimalU();
809 }
810 }
811
toDecimalU() const812 string V3Number::toDecimalU() const {
813 const int maxdecwidth = (width() + 3) * 4 / 3;
814
815 // Or (maxdecwidth+7)/8], but can't have more than 4 BCD bits per word
816 V3Number bcd(this, maxdecwidth + 4);
817 V3Number tmp(this, maxdecwidth + 4);
818 V3Number tmp2(this, maxdecwidth + 4);
819
820 int from_bit = width() - 1;
821 // Skip all leading zeros
822 for (; from_bit >= 0 && bitIs0(from_bit); --from_bit) {}
823 // Double-dabble algorithm
824 for (; from_bit >= 0; --from_bit) {
825 // Any digits >= 5 need an add 3 (via tmp)
826 for (int nibble_bit = 0; nibble_bit < maxdecwidth; nibble_bit += 4) {
827 if (bcd.bitsValue(nibble_bit, 4) >= 5) {
828 tmp2.setAllBits0();
829 tmp2.setBit(nibble_bit, 1); // Add 3, decomposed as two bits
830 tmp2.setBit(nibble_bit + 1, 1);
831 tmp.opAssign(bcd);
832 bcd.opAdd(tmp, tmp2);
833 }
834 }
835 // Shift; bcd = bcd << 1
836 tmp.opAssign(bcd);
837 bcd.opShiftL(tmp, V3Number(this, 32, 1));
838 // bcd[0] = this[from_bit]
839 if (bitIs1(from_bit)) bcd.setBit(0, 1);
840 }
841
842 string output;
843 int lsb = (maxdecwidth - 1) & ~3;
844 for (; lsb > 0; lsb -= 4) { // Skip leading zeros
845 if (bcd.bitsValue(lsb, 4)) break;
846 }
847 for (; lsb >= 0; lsb -= 4) {
848 output += static_cast<char>('0' + bcd.bitsValue(lsb, 4)); // 0..9
849 }
850 return output;
851 }
852
853 //======================================================================
854 // ACCESSORS - as numbers
855
toUInt() const856 uint32_t V3Number::toUInt() const {
857 UASSERT(!isFourState(), "toUInt with 4-state " << *this);
858 // We allow wide numbers that represent values <= 32 bits
859 for (int i = 1; i < words(); ++i) {
860 if (m_value[i].m_value) {
861 v3error("Value too wide for 32-bits expected in this context " << *this);
862 break;
863 }
864 }
865 return m_value[0].m_value;
866 }
867
toDouble() const868 double V3Number::toDouble() const {
869 if (VL_UNCOVERABLE(!isDouble() || width() != 64)) {
870 v3fatalSrc("Real operation on wrong sized/non-real number");
871 }
872 union {
873 double d;
874 uint32_t u[2];
875 } u;
876 u.u[0] = m_value[0].m_value;
877 u.u[1] = m_value[1].m_value;
878 return u.d;
879 }
880
toSInt() const881 vlsint32_t V3Number::toSInt() const {
882 if (isSigned()) {
883 const uint32_t v = toUInt();
884 const uint32_t signExtend = (-(v & (1UL << (width() - 1))));
885 const uint32_t extended = v | signExtend;
886 return static_cast<vlsint32_t>(extended);
887 } else {
888 // Where we use this (widths, etc) and care about signedness,
889 // we can reasonably assume the MSB isn't set on unsigned numbers.
890 return static_cast<vlsint32_t>(toUInt());
891 }
892 }
893
toUQuad() const894 vluint64_t V3Number::toUQuad() const {
895 UASSERT(!isFourState(), "toUQuad with 4-state " << *this);
896 // We allow wide numbers that represent values <= 64 bits
897 if (isDouble()) return static_cast<vluint64_t>(toDouble());
898 for (int i = 2; i < words(); ++i) {
899 if (m_value[i].m_value) {
900 v3error("Value too wide for 64-bits expected in this context " << *this);
901 break;
902 }
903 }
904 if (width() <= 32) return (static_cast<vluint64_t>(toUInt()));
905 return ((static_cast<vluint64_t>(m_value[1].m_value) << 32ULL)
906 | (static_cast<vluint64_t>(m_value[0].m_value)));
907 }
908
toSQuad() const909 vlsint64_t V3Number::toSQuad() const {
910 if (isDouble()) return static_cast<vlsint64_t>(toDouble());
911 const vluint64_t v = toUQuad();
912 const vluint64_t signExtend = (-(v & (1ULL << (width() - 1))));
913 const vluint64_t extended = v | signExtend;
914 return static_cast<vlsint64_t>(extended);
915 }
916
toString() const917 string V3Number::toString() const {
918 UASSERT(!isFourState(), "toString with 4-state " << *this);
919 // Spec says always drop leading zeros, this isn't quite right, we space pad.
920 if (isString()) return m_stringVal;
921 int bit = this->width() - 1;
922 bool start = true;
923 while ((bit % 8) != 7) bit++;
924 string str;
925 for (; bit >= 0; bit -= 8) {
926 const int v = bitsValue(bit - 7, 8);
927 if (!start || v) {
928 str += static_cast<char>((v == 0) ? ' ' : v);
929 start = false; // Drop leading 0s
930 }
931 }
932 return str;
933 }
934
toHash() const935 V3Hash V3Number::toHash() const {
936 V3Hash hash(m_width);
937 for (int i = 0; i < words(); ++i) { hash += m_value[i].m_value; }
938 return hash;
939 }
940
edataWord(int eword) const941 uint32_t V3Number::edataWord(int eword) const {
942 UASSERT(!isFourState(), "edataWord with 4-state " << *this);
943 return m_value[eword].m_value;
944 }
945
dataByte(int byte) const946 uint8_t V3Number::dataByte(int byte) const {
947 return (edataWord(byte / (VL_EDATASIZE / 8)) >> ((byte * 8) % VL_EDATASIZE)) & 0xff;
948 }
949
isAllZ() const950 bool V3Number::isAllZ() const {
951 for (int i = 0; i < width(); i++) {
952 if (!bitIsZ(i)) return false;
953 }
954 return true;
955 }
isAllX() const956 bool V3Number::isAllX() const {
957 uint32_t mask = hiWordMask();
958 for (int i = words() - 1; i >= 0; --i) {
959 const ValueAndX v = m_value[i];
960 if ((v.m_value & v.m_valueX) ^ mask) return false;
961 mask = ~0U;
962 }
963 return true;
964 }
isEqZero() const965 bool V3Number::isEqZero() const {
966 for (int i = 0; i < words(); i++) {
967 const ValueAndX v = m_value[i];
968 if (v.m_value || v.m_valueX) return false;
969 }
970 return true;
971 }
isNeqZero() const972 bool V3Number::isNeqZero() const {
973 for (int i = 0; i < words(); i++) {
974 const ValueAndX v = m_value[i];
975 if (v.m_value & ~v.m_valueX) return true;
976 }
977 return false;
978 }
isBitsZero(int msb,int lsb) const979 bool V3Number::isBitsZero(int msb, int lsb) const {
980 for (int i = lsb; i <= msb; i++) {
981 if (VL_UNLIKELY(!bitIs0(i))) return false;
982 }
983 return true;
984 }
isEqOne() const985 bool V3Number::isEqOne() const {
986 if (m_value[0].m_value != 1 || m_value[0].m_valueX) return false;
987 for (int i = 1; i < words(); i++) {
988 const ValueAndX v = m_value[i];
989 if (v.m_value || v.m_valueX) return false;
990 }
991 return true;
992 }
isEqAllOnes(int optwidth) const993 bool V3Number::isEqAllOnes(int optwidth) const {
994 if (!optwidth) optwidth = width();
995 for (int bit = 0; bit < optwidth; bit++) {
996 if (!bitIs1(bit)) return false;
997 }
998 return true;
999 }
isFourState() const1000 bool V3Number::isFourState() const {
1001 if (isDouble() || isString()) return false;
1002 for (int i = 0; i < words(); ++i) {
1003 if (m_value[i].m_valueX) return true;
1004 }
1005 return false;
1006 }
isAnyX() const1007 bool V3Number::isAnyX() const {
1008 if (isDouble() || isString()) return false;
1009 for (int bit = 0; bit < width(); bit++) {
1010 if (bitIsX(bit)) return true;
1011 }
1012 return false;
1013 }
isAnyXZ() const1014 bool V3Number::isAnyXZ() const { return isAnyX() || isAnyZ(); }
isAnyZ() const1015 bool V3Number::isAnyZ() const {
1016 if (isDouble() || isString()) return false;
1017 for (int bit = 0; bit < width(); bit++) {
1018 if (bitIsZ(bit)) return true;
1019 }
1020 return false;
1021 }
isLtXZ(const V3Number & rhs) const1022 bool V3Number::isLtXZ(const V3Number& rhs) const {
1023 // Include X/Z in comparisons for sort ordering
1024 for (int bit = 0; bit < std::max(this->width(), rhs.width()); bit++) {
1025 if (this->bitIs1(bit) && rhs.bitIs0(bit)) return true;
1026 if (rhs.bitIs1(bit) && this->bitIs0(bit)) return false;
1027 if (this->bitIsXZ(bit)) return true;
1028 if (rhs.bitIsXZ(bit)) return false;
1029 }
1030 return false;
1031 }
countX(int lsb,int nbits) const1032 int V3Number::countX(int lsb, int nbits) const {
1033 int count = 0;
1034 for (int bitn = 0; bitn < nbits; ++bitn) {
1035 if (lsb + bitn >= width()) return count;
1036 if (bitIsX(lsb + bitn)) ++count;
1037 }
1038 return count;
1039 }
countZ(int lsb,int nbits) const1040 int V3Number::countZ(int lsb, int nbits) const {
1041 int count = 0;
1042 for (int bitn = 0; bitn < nbits; ++bitn) {
1043 if (lsb + bitn >= width()) return count;
1044 if (bitIsZ(lsb + bitn)) ++count;
1045 }
1046 return count;
1047 }
1048
widthMin() const1049 int V3Number::widthMin() const {
1050 for (int bit = width() - 1; bit > 0; bit--) {
1051 if (!bitIs0(bit)) return bit + 1;
1052 }
1053 return 1; // one bit even if number is == 0
1054 }
1055
countBits(const V3Number & ctrl) const1056 uint32_t V3Number::countBits(const V3Number& ctrl) const {
1057 int n = 0;
1058 for (int bit = 0; bit < this->width(); ++bit) {
1059 switch (ctrl.bitIs(0)) {
1060 case '0':
1061 if (bitIs0(bit)) ++n;
1062 break;
1063 case '1':
1064 if (bitIs1(bit)) ++n;
1065 break;
1066 case 'x':
1067 if (bitIsX(bit)) ++n;
1068 break;
1069 case 'z':
1070 if (bitIsZ(bit)) ++n;
1071 break;
1072 }
1073 }
1074 return n;
1075 }
1076
countBits(const V3Number & ctrl1,const V3Number & ctrl2,const V3Number & ctrl3) const1077 uint32_t V3Number::countBits(const V3Number& ctrl1, const V3Number& ctrl2,
1078 const V3Number& ctrl3) const {
1079 int n = countBits(ctrl1);
1080 if (ctrl2.bitIs(0) != ctrl1.bitIs(0)) n += countBits(ctrl2);
1081 if ((ctrl3.bitIs(0) != ctrl1.bitIs(0)) && (ctrl3.bitIs(0) != ctrl2.bitIs(0))) {
1082 n += countBits(ctrl3);
1083 }
1084 return n;
1085 }
1086
countOnes() const1087 uint32_t V3Number::countOnes() const {
1088 int n = 0;
1089 for (int bit = 0; bit < this->width(); bit++) {
1090 if (bitIs1(bit)) n++;
1091 }
1092 return n;
1093 }
1094
mostSetBitP1() const1095 uint32_t V3Number::mostSetBitP1() const {
1096 for (int bit = this->width() - 1; bit >= 0; bit--) {
1097 if (bitIs1(bit)) return bit + 1;
1098 }
1099 return 0;
1100 }
1101 //======================================================================
1102
opBitsNonX(const V3Number & lhs)1103 V3Number& V3Number::opBitsNonX(const V3Number& lhs) { // 0/1->1, X/Z->0
1104 // op i, L(lhs) bit return
1105 NUM_ASSERT_OP_ARGS1(lhs);
1106 NUM_ASSERT_LOGIC_ARGS1(lhs);
1107 setZero();
1108 for (int bit = 0; bit < this->width(); bit++) {
1109 if (lhs.bitIs0(bit) || lhs.bitIs1(bit)) setBit(bit, 1);
1110 }
1111 return *this;
1112 }
opBitsOne(const V3Number & lhs)1113 V3Number& V3Number::opBitsOne(const V3Number& lhs) { // 1->1, 0/X/Z->0
1114 // op i, L(lhs) bit return
1115 NUM_ASSERT_OP_ARGS1(lhs);
1116 NUM_ASSERT_LOGIC_ARGS1(lhs);
1117 setZero();
1118 for (int bit = 0; bit < this->width(); bit++) {
1119 if (lhs.bitIs1(bit)) setBit(bit, 1);
1120 }
1121 return *this;
1122 }
opBitsXZ(const V3Number & lhs)1123 V3Number& V3Number::opBitsXZ(const V3Number& lhs) { // 0/1->1, X/Z->0
1124 // op i, L(lhs) bit return
1125 NUM_ASSERT_OP_ARGS1(lhs);
1126 NUM_ASSERT_LOGIC_ARGS1(lhs);
1127 setZero();
1128 for (int bit = 0; bit < this->width(); bit++) {
1129 if (lhs.bitIsXZ(bit)) setBit(bit, 1);
1130 }
1131 return *this;
1132 }
opBitsZ(const V3Number & lhs)1133 V3Number& V3Number::opBitsZ(const V3Number& lhs) { // 0/1->1, X/Z->0
1134 // op i, L(lhs) bit return
1135 NUM_ASSERT_OP_ARGS1(lhs);
1136 NUM_ASSERT_LOGIC_ARGS1(lhs);
1137 setZero();
1138 for (int bit = 0; bit < this->width(); bit++) {
1139 if (lhs.bitIsZ(bit)) setBit(bit, 1);
1140 }
1141 return *this;
1142 }
opBitsNonZ(const V3Number & lhs)1143 V3Number& V3Number::opBitsNonZ(const V3Number& lhs) { // 0/1->1, X/Z->0
1144 // op i, L(lhs) bit return
1145 NUM_ASSERT_OP_ARGS1(lhs);
1146 NUM_ASSERT_LOGIC_ARGS1(lhs);
1147 setZero();
1148 for (int bit = 0; bit < this->width(); bit++) {
1149 if (!lhs.bitIsZ(bit)) setBit(bit, 1);
1150 }
1151 return *this;
1152 }
1153
1154 //======================================================================
1155 // Operators - Simple per-bit logical ops
1156
opRedOr(const V3Number & lhs)1157 V3Number& V3Number::opRedOr(const V3Number& lhs) {
1158 // op i, 1 bit return
1159 NUM_ASSERT_OP_ARGS1(lhs);
1160 NUM_ASSERT_LOGIC_ARGS1(lhs);
1161 char outc = 0;
1162 for (int bit = 0; bit < lhs.width(); bit++) {
1163 if (lhs.bitIs1(bit)) {
1164 return setSingleBits(1);
1165 } else if (lhs.bitIs0(bit)) {
1166 } else {
1167 outc = 'x';
1168 }
1169 }
1170 return setSingleBits(outc);
1171 }
1172
opRedAnd(const V3Number & lhs)1173 V3Number& V3Number::opRedAnd(const V3Number& lhs) {
1174 // op i, 1 bit return
1175 NUM_ASSERT_OP_ARGS1(lhs);
1176 NUM_ASSERT_LOGIC_ARGS1(lhs);
1177 char outc = 1;
1178 for (int bit = 0; bit < lhs.width(); bit++) {
1179 if (lhs.bitIs0(bit)) {
1180 return setSingleBits(0);
1181 } else if (lhs.bitIs1(bit)) {
1182 } else {
1183 outc = 'x';
1184 }
1185 }
1186 return setSingleBits(outc);
1187 }
1188
opRedXor(const V3Number & lhs)1189 V3Number& V3Number::opRedXor(const V3Number& lhs) {
1190 // op i, 1 bit return
1191 NUM_ASSERT_OP_ARGS1(lhs);
1192 NUM_ASSERT_LOGIC_ARGS1(lhs);
1193 char outc = 0;
1194 for (int bit = 0; bit < lhs.width(); bit++) {
1195 if (lhs.bitIs1(bit)) {
1196 if (outc == 1) {
1197 outc = 0;
1198 } else if (outc == 0) {
1199 outc = 1;
1200 }
1201 } else if (lhs.bitIs0(bit)) {
1202 } else {
1203 outc = 'x';
1204 }
1205 }
1206 return setSingleBits(outc);
1207 }
1208
opCountBits(const V3Number & expr,const V3Number & ctrl1,const V3Number & ctrl2,const V3Number & ctrl3)1209 V3Number& V3Number::opCountBits(const V3Number& expr, const V3Number& ctrl1, const V3Number& ctrl2,
1210 const V3Number& ctrl3) {
1211 NUM_ASSERT_OP_ARGS4(expr, ctrl1, ctrl2, ctrl3);
1212 NUM_ASSERT_LOGIC_ARGS4(expr, ctrl1, ctrl2, ctrl3);
1213 setZero();
1214 m_value[0].m_value = expr.countBits(ctrl1, ctrl2, ctrl3);
1215 opCleanThis();
1216 return *this;
1217 }
opCountOnes(const V3Number & lhs)1218 V3Number& V3Number::opCountOnes(const V3Number& lhs) {
1219 NUM_ASSERT_OP_ARGS1(lhs);
1220 NUM_ASSERT_LOGIC_ARGS1(lhs);
1221 if (lhs.isFourState()) return setAllBitsX();
1222 setZero();
1223 m_value[0].m_value = lhs.countOnes();
1224 opCleanThis();
1225 return *this;
1226 }
opIsUnknown(const V3Number & lhs)1227 V3Number& V3Number::opIsUnknown(const V3Number& lhs) {
1228 NUM_ASSERT_OP_ARGS1(lhs);
1229 return setSingleBits(lhs.isAnyXZ());
1230 }
opOneHot(const V3Number & lhs)1231 V3Number& V3Number::opOneHot(const V3Number& lhs) {
1232 NUM_ASSERT_OP_ARGS1(lhs);
1233 if (lhs.isFourState()) return setAllBitsX();
1234 return setSingleBits(lhs.countOnes() == 1);
1235 }
opOneHot0(const V3Number & lhs)1236 V3Number& V3Number::opOneHot0(const V3Number& lhs) {
1237 NUM_ASSERT_OP_ARGS1(lhs);
1238 if (lhs.isFourState()) return setAllBitsX();
1239 return setSingleBits(lhs.countOnes() <= 1);
1240 }
opCLog2(const V3Number & lhs)1241 V3Number& V3Number::opCLog2(const V3Number& lhs) {
1242 NUM_ASSERT_OP_ARGS1(lhs);
1243 NUM_ASSERT_LOGIC_ARGS1(lhs);
1244 if (lhs.isFourState()) return setAllBitsX();
1245 // IE if 4, this algorithm didn't pre-subtract 1, so we need to post-correct now
1246 const int adjust = (lhs.countOnes() == 1) ? 0 : 1;
1247 for (int bit = lhs.width() - 1; bit >= 0; bit--) {
1248 if (lhs.bitIs1(bit)) {
1249 setLong(bit + adjust);
1250 return *this;
1251 }
1252 }
1253 setZero();
1254 return *this;
1255 }
1256
opLogNot(const V3Number & lhs)1257 V3Number& V3Number::opLogNot(const V3Number& lhs) {
1258 NUM_ASSERT_OP_ARGS1(lhs);
1259 NUM_ASSERT_LOGIC_ARGS1(lhs);
1260 // op i, 1 bit return
1261 char outc = 1;
1262 for (int bit = 0; bit < lhs.width(); bit++) {
1263 if (lhs.bitIs1(bit)) {
1264 outc = 0;
1265 goto last;
1266 } else if (lhs.bitIs0(bit)) {
1267 } else {
1268 outc = 'x';
1269 }
1270 }
1271 last:
1272 return setSingleBits(outc);
1273 }
1274
opNot(const V3Number & lhs)1275 V3Number& V3Number::opNot(const V3Number& lhs) {
1276 NUM_ASSERT_OP_ARGS1(lhs);
1277 NUM_ASSERT_LOGIC_ARGS1(lhs);
1278 // op i, L(lhs) bit return
1279 setZero();
1280 for (int bit = 0; bit < this->width(); bit++) {
1281 if (lhs.bitIs0(bit)) {
1282 setBit(bit, 1);
1283 } else if (lhs.bitIsXZ(bit)) {
1284 setBit(bit, 'x');
1285 }
1286 }
1287 return *this;
1288 }
1289
opAnd(const V3Number & lhs,const V3Number & rhs)1290 V3Number& V3Number::opAnd(const V3Number& lhs, const V3Number& rhs) {
1291 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1292 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1293 // i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
1294 setZero();
1295 for (int bit = 0; bit < this->width(); bit++) {
1296 if (lhs.bitIs1(bit) && rhs.bitIs1(bit)) {
1297 setBit(bit, 1);
1298 } else if (lhs.bitIs0(bit) || rhs.bitIs0(bit)) { // 0
1299 } else {
1300 setBit(bit, 'x');
1301 }
1302 }
1303 return *this;
1304 }
1305
opOr(const V3Number & lhs,const V3Number & rhs)1306 V3Number& V3Number::opOr(const V3Number& lhs, const V3Number& rhs) {
1307 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1308 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1309 // i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
1310 setZero();
1311 for (int bit = 0; bit < this->width(); bit++) {
1312 if (lhs.bitIs1(bit) || rhs.bitIs1(bit)) {
1313 setBit(bit, 1);
1314 } else if (lhs.bitIs0(bit) && rhs.bitIs0(bit)) {
1315 // 0
1316 } else {
1317 setBit(bit, 'x');
1318 }
1319 }
1320 return *this;
1321 }
1322
opChangeXor(const V3Number & lhs,const V3Number & rhs)1323 V3Number& V3Number::opChangeXor(const V3Number& lhs, const V3Number& rhs) {
1324 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1325 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1326 // 32 bit result
1327 opEq(lhs, rhs);
1328 return *this;
1329 }
1330
opXor(const V3Number & lhs,const V3Number & rhs)1331 V3Number& V3Number::opXor(const V3Number& lhs, const V3Number& rhs) {
1332 // i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
1333 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1334 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1335 setZero();
1336 for (int bit = 0; bit < this->width(); bit++) {
1337 if (lhs.bitIs1(bit) && rhs.bitIs0(bit)) {
1338 setBit(bit, 1);
1339 } else if (lhs.bitIs0(bit) && rhs.bitIs1(bit)) {
1340 setBit(bit, 1);
1341 } else if (lhs.bitIsXZ(bit) || rhs.bitIsXZ(bit)) {
1342 setBit(bit, 'x');
1343 }
1344 // else zero
1345 }
1346 return *this;
1347 }
1348
opConcat(const V3Number & lhs,const V3Number & rhs)1349 V3Number& V3Number::opConcat(const V3Number& lhs, const V3Number& rhs) {
1350 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1351 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1352 setZero();
1353 // See also error in V3Width
1354 if (!lhs.sized() || !rhs.sized()) {
1355 v3warn(WIDTHCONCAT, "Unsized numbers/parameters not allowed in concatenations.");
1356 }
1357 int obit = 0;
1358 for (int bit = 0; bit < rhs.width(); bit++) {
1359 setBit(obit, rhs.bitIs(bit));
1360 obit++;
1361 }
1362 for (int bit = 0; bit < lhs.width(); bit++) {
1363 setBit(obit, lhs.bitIs(bit));
1364 obit++;
1365 }
1366 return *this;
1367 }
1368
opLenN(const V3Number & lhs)1369 V3Number& V3Number::opLenN(const V3Number& lhs) {
1370 NUM_ASSERT_OP_ARGS1(lhs);
1371 NUM_ASSERT_STRING_ARGS1(lhs);
1372 setQuad(lhs.toString().length());
1373 return *this;
1374 }
1375
opRepl(const V3Number & lhs,const V3Number & rhs)1376 V3Number& V3Number::opRepl(const V3Number& lhs,
1377 const V3Number& rhs) { // rhs is # of times to replicate
1378 // Hopefully the using routine has a error check to, &rhso.
1379 // See also error in V3Width
1380 NUM_ASSERT_OP_ARGS1(lhs);
1381 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1382 if (!lhs.sized()) {
1383 v3warn(WIDTHCONCAT, "Unsized numbers/parameters not allowed in replications.");
1384 }
1385 return opRepl(lhs, rhs.toUInt());
1386 }
1387
opRepl(const V3Number & lhs,uint32_t rhsval)1388 V3Number& V3Number::opRepl(const V3Number& lhs,
1389 uint32_t rhsval) { // rhs is # of times to replicate
1390 // i op repl, L(i)*value(rhs) bit return
1391 NUM_ASSERT_OP_ARGS1(lhs);
1392 NUM_ASSERT_LOGIC_ARGS1(lhs);
1393 setZero();
1394 if (rhsval > 8192) {
1395 v3warn(WIDTHCONCAT, "More than a 8k bit replication is probably wrong: " << rhsval);
1396 }
1397 int obit = 0;
1398 for (unsigned times = 0; times < rhsval; times++) {
1399 for (int bit = 0; bit < lhs.width(); bit++) {
1400 setBit(obit, lhs.bitIs(bit));
1401 obit++;
1402 }
1403 }
1404 return *this;
1405 }
1406
opStreamL(const V3Number & lhs,const V3Number & rhs)1407 V3Number& V3Number::opStreamL(const V3Number& lhs, const V3Number& rhs) {
1408 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1409 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1410 setZero();
1411 // See also error in V3Width
1412 if (!lhs.sized()) {
1413 v3warn(WIDTHCONCAT, "Unsized numbers/parameters not allowed in streams.");
1414 }
1415 // Slice size should never exceed the lhs width
1416 const int ssize = std::min(rhs.toUInt(), static_cast<unsigned>(lhs.width()));
1417 for (int istart = 0; istart < lhs.width(); istart += ssize) {
1418 const int ostart = std::max(0, lhs.width() - ssize - istart);
1419 for (int bit = 0; bit < ssize && bit < lhs.width() - istart; bit++) {
1420 setBit(ostart + bit, lhs.bitIs(istart + bit));
1421 }
1422 }
1423 return *this;
1424 }
1425
opLogAnd(const V3Number & lhs,const V3Number & rhs)1426 V3Number& V3Number::opLogAnd(const V3Number& lhs, const V3Number& rhs) {
1427 // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation
1428 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1429 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1430 char loutc = 0;
1431 char routc = 0;
1432 for (int bit = 0; bit < lhs.width(); bit++) {
1433 if (lhs.bitIs1(bit)) {
1434 loutc = 1;
1435 break;
1436 }
1437 if (lhs.bitIsXZ(bit) && loutc == 0) loutc = 'x';
1438 }
1439 for (int bit = 0; bit < rhs.width(); bit++) {
1440 if (rhs.bitIs1(bit)) {
1441 routc = 1;
1442 break;
1443 }
1444 if (rhs.bitIsXZ(bit) && routc == 0) routc = 'x';
1445 }
1446 char outc = 'x';
1447 if (routc == 1 && loutc == 1) outc = 1;
1448 if (routc == 0 || loutc == 0) outc = 0;
1449 return setSingleBits(outc);
1450 }
1451
opLogOr(const V3Number & lhs,const V3Number & rhs)1452 V3Number& V3Number::opLogOr(const V3Number& lhs, const V3Number& rhs) {
1453 // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
1454 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1455 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1456 char outc = 0;
1457 for (int bit = 0; bit < lhs.width(); bit++) {
1458 if (lhs.bitIs1(bit)) {
1459 outc = 1;
1460 goto last;
1461 }
1462 if (lhs.bitIsXZ(bit) && outc == 0) outc = 'x';
1463 }
1464 for (int bit = 0; bit < rhs.width(); bit++) {
1465 if (rhs.bitIs1(bit)) {
1466 outc = 1;
1467 goto last;
1468 }
1469 if (rhs.bitIsXZ(bit) && outc == 0) outc = 'x';
1470 }
1471 last:
1472 return setSingleBits(outc);
1473 }
1474
opLogIf(const V3Number & lhs,const V3Number & rhs)1475 V3Number& V3Number::opLogIf(const V3Number& lhs, const V3Number& rhs) {
1476 // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to
1477 // X/Z extend. Use definition in IEEE to do this for us.
1478 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1479 V3Number lnot = lhs;
1480 lnot.opLogNot(lhs);
1481 return opLogOr(lnot, rhs);
1482 }
1483
opLogEq(const V3Number & lhs,const V3Number & rhs)1484 V3Number& V3Number::opLogEq(const V3Number& lhs, const V3Number& rhs) {
1485 // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to
1486 // X/Z extend. Use definition in IEEE to do this for us.
1487 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1488 V3Number ifa = lhs;
1489 ifa.opLogIf(lhs, rhs);
1490 V3Number ifb = rhs;
1491 ifb.opLogIf(rhs, lhs);
1492 return opLogAnd(ifa, ifb);
1493 }
1494
opAtoN(const V3Number & lhs,int base)1495 V3Number& V3Number::opAtoN(const V3Number& lhs, int base) {
1496 NUM_ASSERT_OP_ARGS1(lhs);
1497 NUM_ASSERT_STRING_ARGS1(lhs);
1498 UASSERT(base == AstAtoN::ATOREAL || base == 2 || base == 8 || base == 10 || base == 16,
1499 "base must be one of AstAtoN::ATOREAL, 2, 8, 10, or 16.");
1500
1501 std::string str = lhs.toString(); // new instance to edit later
1502 if (base == AstAtoN::ATOREAL) return setDouble(std::atof(str.c_str()));
1503
1504 // IEEE 1800-2017 6.16.9 says '_' may exist.
1505 str.erase(std::remove(str.begin(), str.end(), '_'), str.end());
1506
1507 errno = 0;
1508 auto v = std::strtol(str.c_str(), nullptr, base);
1509 if (errno != 0) v = 0;
1510 return setLongS(static_cast<vlsint32_t>(v));
1511 }
1512
opPutcN(const V3Number & lhs,const V3Number & rhs,const V3Number & ths)1513 V3Number& V3Number::opPutcN(const V3Number& lhs, const V3Number& rhs, const V3Number& ths) {
1514 NUM_ASSERT_OP_ARGS3(lhs, rhs, ths);
1515 NUM_ASSERT_STRING_ARGS1(lhs);
1516 string lstring = lhs.toString();
1517 const vlsint32_t i = rhs.toSInt();
1518 const vlsint32_t c = ths.toSInt() & 0xFF;
1519 // 6.16.2:str.putc(i, c) does not change the value when i < 0 || i >= str.len() || c == 0
1520 // when evaluating the second condition, i must be positive.
1521 if (0 <= i && static_cast<uint32_t>(i) < lstring.length() && c != 0) lstring[i] = c;
1522 return setString(lstring);
1523 }
1524
opGetcN(const V3Number & lhs,const V3Number & rhs)1525 V3Number& V3Number::opGetcN(const V3Number& lhs, const V3Number& rhs) {
1526 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1527 NUM_ASSERT_STRING_ARGS1(lhs);
1528 const string lstring = lhs.toString();
1529 const vlsint32_t i = rhs.toSInt();
1530 vlsint32_t v = 0;
1531 // 6.16.3:str.getc(i) returns 0 if i < 0 || i >= str.len()
1532 // when evaluating the second condition, i must be positive.
1533 if (0 <= i && static_cast<uint32_t>(i) < lstring.length()) v = lstring[i];
1534 return setLong(v);
1535 }
1536
opSubstrN(const V3Number & lhs,const V3Number & rhs,const V3Number & ths)1537 V3Number& V3Number::opSubstrN(const V3Number& lhs, const V3Number& rhs, const V3Number& ths) {
1538 NUM_ASSERT_OP_ARGS3(lhs, rhs, ths);
1539 NUM_ASSERT_STRING_ARGS1(lhs);
1540 const string lstring = lhs.toString();
1541 const vlsint32_t i = rhs.toSInt();
1542 const vlsint32_t j = ths.toSInt();
1543 // 6.16.8:str.substr(i, j) returns an empty string when i < 0 || j < i || j >= str.len()
1544 // when evaluating the third condition, j must be positive because 0 <= i <= j is guaranteed by
1545 // the former two conditions.
1546 if (i < 0 || j < i || static_cast<uint32_t>(j) >= lstring.length()) return setString("");
1547 // The second parameter of std::string::substr(i, n) is length, not position as SystemVerilog.
1548 return setString(lstring.substr(i, j - i + 1));
1549 }
1550
opCompareNN(const V3Number & lhs,const V3Number & rhs,bool ignoreCase)1551 V3Number& V3Number::opCompareNN(const V3Number& lhs, const V3Number& rhs, bool ignoreCase) {
1552 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1553 NUM_ASSERT_STRING_ARGS2(lhs, rhs);
1554 // SystemVerilog Language Standard does not allow a string variable to contain '\0'.
1555 // So C functions such as strcmp() can correctly compare strings.
1556 int result;
1557 const string lstring = lhs.toString();
1558 const string rstring = rhs.toString();
1559 if (ignoreCase) {
1560 result = VL_STRCASECMP(lstring.c_str(), rstring.c_str());
1561 } else {
1562 result = std::strcmp(lstring.c_str(), rstring.c_str());
1563 }
1564 return setLongS(result);
1565 }
1566
opEq(const V3Number & lhs,const V3Number & rhs)1567 V3Number& V3Number::opEq(const V3Number& lhs, const V3Number& rhs) {
1568 // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
1569 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1570 if (lhs.isString()) return opEqN(lhs, rhs);
1571 if (lhs.isDouble()) return opEqD(lhs, rhs);
1572 char outc = 1;
1573 for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); bit++) {
1574 if (lhs.bitIs1(bit) && rhs.bitIs0(bit)) {
1575 outc = 0;
1576 goto last;
1577 }
1578 if (lhs.bitIs0(bit) && rhs.bitIs1(bit)) {
1579 outc = 0;
1580 goto last;
1581 }
1582 if (lhs.bitIsXZ(bit)) outc = 'x';
1583 if (rhs.bitIsXZ(bit)) outc = 'x';
1584 }
1585 last:
1586 return setSingleBits(outc);
1587 }
1588
opNeq(const V3Number & lhs,const V3Number & rhs)1589 V3Number& V3Number::opNeq(const V3Number& lhs, const V3Number& rhs) {
1590 // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
1591 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1592 if (lhs.isString()) return opNeqN(lhs, rhs);
1593 if (lhs.isDouble()) return opNeqD(lhs, rhs);
1594 char outc = 0;
1595 for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); bit++) {
1596 if (lhs.bitIs1(bit) && rhs.bitIs0(bit)) {
1597 outc = 1;
1598 goto last;
1599 }
1600 if (lhs.bitIs0(bit) && rhs.bitIs1(bit)) {
1601 outc = 1;
1602 goto last;
1603 }
1604 if (lhs.bitIsXZ(bit)) outc = 'x';
1605 if (rhs.bitIsXZ(bit)) outc = 'x';
1606 }
1607 last:
1608 return setSingleBits(outc);
1609 }
1610
isCaseEq(const V3Number & rhs) const1611 bool V3Number::isCaseEq(const V3Number& rhs) const {
1612 // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
1613 if (isString()) return toString() == rhs.toString();
1614 if (isDouble()) return toDouble() == rhs.toDouble();
1615 if (this->width() != rhs.width()) return false;
1616 for (int i = 0; i < words(); ++i) {
1617 if (!(m_value[i] == rhs.m_value[i])) return false;
1618 }
1619 return true;
1620 }
1621
opCaseEq(const V3Number & lhs,const V3Number & rhs)1622 V3Number& V3Number::opCaseEq(const V3Number& lhs, const V3Number& rhs) {
1623 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1624 return setSingleBits(lhs.isCaseEq(rhs) ? 1 : 0);
1625 }
1626
opCaseNeq(const V3Number & lhs,const V3Number & rhs)1627 V3Number& V3Number::opCaseNeq(const V3Number& lhs, const V3Number& rhs) {
1628 // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
1629 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1630 char outc = 0;
1631 if (lhs.isString()) {
1632 return opNeqN(lhs, rhs);
1633 } else if (lhs.isDouble()) {
1634 return opNeqD(lhs, rhs);
1635 }
1636 for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); bit++) {
1637 if (lhs.bitIs(bit) != rhs.bitIs(bit)) {
1638 outc = 1;
1639 goto last;
1640 }
1641 }
1642 last:
1643 return setSingleBits(outc);
1644 }
1645
opWildEq(const V3Number & lhs,const V3Number & rhs)1646 V3Number& V3Number::opWildEq(const V3Number& lhs, const V3Number& rhs) {
1647 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1648 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1649 char outc = 1;
1650 for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); bit++) {
1651 if (!rhs.bitIsXZ(bit) && lhs.bitIs(bit) != rhs.bitIs(bit)) {
1652 outc = 0;
1653 goto last;
1654 }
1655 if (lhs.bitIsXZ(bit)) outc = 'x';
1656 }
1657 last:
1658 return setSingleBits(outc);
1659 }
1660
opWildNeq(const V3Number & lhs,const V3Number & rhs)1661 V3Number& V3Number::opWildNeq(const V3Number& lhs, const V3Number& rhs) {
1662 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1663 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1664 char outc = 0;
1665 for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); bit++) {
1666 if (!rhs.bitIsXZ(bit) && lhs.bitIs(bit) != rhs.bitIs(bit)) {
1667 outc = 1;
1668 goto last;
1669 }
1670 if (lhs.bitIsXZ(bit)) outc = 'x';
1671 }
1672 last:
1673 return setSingleBits(outc);
1674 }
1675
opGt(const V3Number & lhs,const V3Number & rhs)1676 V3Number& V3Number::opGt(const V3Number& lhs, const V3Number& rhs) {
1677 // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
1678 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1679 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1680 char outc = 0;
1681 for (int bit = 0; bit < std::max(lhs.width(), rhs.width()); bit++) {
1682 if (lhs.bitIs1(bit) && rhs.bitIs0(bit)) outc = 1;
1683 if (rhs.bitIs1(bit) && lhs.bitIs0(bit)) outc = 0;
1684 if (lhs.bitIsXZ(bit)) outc = 'x';
1685 if (rhs.bitIsXZ(bit)) outc = 'x';
1686 }
1687 return setSingleBits(outc);
1688 }
1689
opGtS(const V3Number & lhs,const V3Number & rhs)1690 V3Number& V3Number::opGtS(const V3Number& lhs, const V3Number& rhs) {
1691 // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
1692 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1693 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1694 char outc = 0;
1695 {
1696 const int mbit = std::max(lhs.width() - 1, rhs.width() - 1);
1697 if (lhs.bitIsXZ(mbit)) {
1698 outc = 'x';
1699 } else if (rhs.bitIsXZ(mbit)) {
1700 outc = 'x';
1701 } else if (lhs.bitIs0(mbit) && rhs.bitIs1Extend(mbit)) {
1702 outc = 1; // + > -
1703 } else if (lhs.bitIs1Extend(mbit) && rhs.bitIs0(mbit)) {
1704 outc = 0; // - !> +
1705 } else {
1706 // both positive or negative, normal >
1707 for (int bit = 0; bit < std::max(lhs.width() - 1, rhs.width() - 1); bit++) {
1708 if (lhs.bitIs1Extend(bit) && rhs.bitIs0(bit)) outc = 1;
1709 if (rhs.bitIs1Extend(bit) && lhs.bitIs0(bit)) outc = 0;
1710 if (lhs.bitIsXZ(bit)) outc = 'x';
1711 if (rhs.bitIsXZ(bit)) outc = 'x';
1712 }
1713 }
1714 }
1715 return setSingleBits(outc);
1716 }
1717
opGte(const V3Number & lhs,const V3Number & rhs)1718 V3Number& V3Number::opGte(const V3Number& lhs, const V3Number& rhs) {
1719 // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
1720 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1721 V3Number& eq = opEq(lhs, rhs);
1722 if (eq.isNeqZero()) return eq; // Return true
1723 return opGt(lhs, rhs);
1724 }
1725
opGteS(const V3Number & lhs,const V3Number & rhs)1726 V3Number& V3Number::opGteS(const V3Number& lhs, const V3Number& rhs) {
1727 // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
1728 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1729 V3Number& eq = opEq(lhs, rhs);
1730 if (eq.isNeqZero()) return eq; // Return true
1731 return opGtS(lhs, rhs);
1732 }
1733
opLt(const V3Number & lhs,const V3Number & rhs)1734 V3Number& V3Number::opLt(const V3Number& lhs, const V3Number& rhs) { return opGt(rhs, lhs); }
opLte(const V3Number & lhs,const V3Number & rhs)1735 V3Number& V3Number::opLte(const V3Number& lhs, const V3Number& rhs) { return opGte(rhs, lhs); }
opLtS(const V3Number & lhs,const V3Number & rhs)1736 V3Number& V3Number::opLtS(const V3Number& lhs, const V3Number& rhs) { return opGtS(rhs, lhs); }
opLteS(const V3Number & lhs,const V3Number & rhs)1737 V3Number& V3Number::opLteS(const V3Number& lhs, const V3Number& rhs) { return opGteS(rhs, lhs); }
1738
opShiftR(const V3Number & lhs,const V3Number & rhs)1739 V3Number& V3Number::opShiftR(const V3Number& lhs, const V3Number& rhs) {
1740 // L(lhs) bit return
1741 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1742 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1743 if (rhs.isFourState()) return setAllBitsX();
1744 setZero();
1745 for (int bit = 32; bit < rhs.width(); bit++) {
1746 if (rhs.bitIs1(bit)) return *this; // shift of over 2^32 must be zero
1747 }
1748 const uint32_t rhsval = rhs.toUInt();
1749 if (rhsval < static_cast<uint32_t>(lhs.width())) {
1750 for (int bit = 0; bit < this->width(); bit++) setBit(bit, lhs.bitIs(bit + rhsval));
1751 }
1752 return *this;
1753 }
1754
opShiftRS(const V3Number & lhs,const V3Number & rhs,uint32_t lbits)1755 V3Number& V3Number::opShiftRS(const V3Number& lhs, const V3Number& rhs, uint32_t lbits) {
1756 // L(lhs) bit return
1757 // The spec says a unsigned >>> still acts as a normal >>.
1758 // We presume it is signed; as that's V3Width's job to convert to opShiftR
1759 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1760 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1761 if (rhs.isFourState()) return setAllBitsX();
1762 setZero();
1763 for (int bit = 32; bit < rhs.width(); bit++) {
1764 for (int sbit = 0; sbit < this->width(); sbit++) {
1765 setBit(sbit, lhs.bitIs(lbits - 1)); // 0/1/X/Z
1766 }
1767 if (rhs.bitIs1(lbits - 1)) setAllBits1(); // -1 else 0
1768 return *this; // shift of over 2^32 must be -1/0
1769 }
1770 const uint32_t rhsval = rhs.toUInt();
1771 if (rhsval < static_cast<uint32_t>(lhs.width())) {
1772 for (int bit = 0; bit < this->width(); bit++) {
1773 setBit(bit, lhs.bitIsExtend(bit + rhsval, lbits));
1774 }
1775 } else {
1776 for (int bit = 0; bit < this->width(); bit++) {
1777 setBit(bit, lhs.bitIs(lbits - 1)); // 0/1/X/Z
1778 }
1779 }
1780 return *this;
1781 }
1782
opShiftL(const V3Number & lhs,const V3Number & rhs)1783 V3Number& V3Number::opShiftL(const V3Number& lhs, const V3Number& rhs) {
1784 // L(lhs) bit return
1785 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1786 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1787 if (rhs.isFourState()) return setAllBitsX();
1788 setZero();
1789 for (int bit = 32; bit < rhs.width(); bit++) {
1790 if (rhs.bitIs1(bit)) return *this; // shift of over 2^32 must be zero
1791 }
1792 const uint32_t rhsval = rhs.toUInt();
1793 for (int bit = 0; bit < this->width(); bit++) {
1794 if (bit >= static_cast<int>(rhsval)) setBit(bit, lhs.bitIs(bit - rhsval));
1795 }
1796 return *this;
1797 }
1798
1799 //======================================================================
1800 // Ops - Arithmetic
1801
opNegate(const V3Number & lhs)1802 V3Number& V3Number::opNegate(const V3Number& lhs) {
1803 // op i, L(lhs) bit return
1804 NUM_ASSERT_OP_ARGS1(lhs);
1805 NUM_ASSERT_LOGIC_ARGS1(lhs);
1806 if (lhs.isFourState()) return setAllBitsX();
1807 V3Number notlhs(&lhs, width());
1808 notlhs.opNot(lhs);
1809 const V3Number one(&lhs, width(), 1);
1810 opAdd(notlhs, one);
1811 return *this;
1812 }
opAdd(const V3Number & lhs,const V3Number & rhs)1813 V3Number& V3Number::opAdd(const V3Number& lhs, const V3Number& rhs) {
1814 // i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
1815 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1816 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1817 if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
1818 setZero();
1819 // Addem
1820 int carry = 0;
1821 for (int bit = 0; bit < this->width(); bit++) {
1822 const int sum = ((lhs.bitIs1(bit) ? 1 : 0) + (rhs.bitIs1(bit) ? 1 : 0) + carry);
1823 if (sum & 1) setBit(bit, 1);
1824 carry = (sum >= 2);
1825 }
1826 return *this;
1827 }
opSub(const V3Number & lhs,const V3Number & rhs)1828 V3Number& V3Number::opSub(const V3Number& lhs, const V3Number& rhs) {
1829 // i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
1830 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1831 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1832 if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
1833 V3Number negrhs(&rhs, rhs.width());
1834 negrhs.opNegate(rhs);
1835 return opAdd(lhs, negrhs);
1836 }
opMul(const V3Number & lhs,const V3Number & rhs)1837 V3Number& V3Number::opMul(const V3Number& lhs, const V3Number& rhs) {
1838 // i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
1839 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1840 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1841 if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
1842 setZero();
1843 if (width() <= 64) {
1844 setQuad(lhs.toUQuad() * rhs.toUQuad());
1845 opCleanThis(); // Mult produces extra bits in result
1846 } else {
1847 for (int lword = 0; lword < lhs.words(); lword++) {
1848 const vluint64_t lwordval = static_cast<vluint64_t>(lhs.m_value[lword].m_value);
1849 if (lwordval == 0) continue;
1850 for (int rword = 0; rword < rhs.words(); rword++) {
1851 const vluint64_t rwordval = static_cast<vluint64_t>(rhs.m_value[rword].m_value);
1852 if (rwordval == 0) continue;
1853 vluint64_t mul = lwordval * rwordval;
1854 for (int qword = lword + rword; qword < this->words(); qword++) {
1855 mul += static_cast<vluint64_t>(m_value[qword].m_value);
1856 m_value[qword].m_value = (mul & 0xffffffffULL);
1857 mul = (mul >> 32ULL) & 0xffffffffULL;
1858 if (mul == 0) break;
1859 }
1860 }
1861 }
1862 opCleanThis(); // Mult produces extra bits in result
1863 }
1864 return *this;
1865 }
opMulS(const V3Number & lhs,const V3Number & rhs)1866 V3Number& V3Number::opMulS(const V3Number& lhs, const V3Number& rhs) {
1867 // Signed multiply
1868 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1869 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1870 if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
1871 V3Number lhsNoSign = lhs;
1872 if (lhs.isNegative()) lhsNoSign.opNegate(lhs);
1873 V3Number rhsNoSign = rhs;
1874 if (rhs.isNegative()) rhsNoSign.opNegate(rhs);
1875 const V3Number qNoSign = opMul(lhsNoSign, rhsNoSign);
1876 if ((lhs.isNegative() && !rhs.isNegative()) || (!lhs.isNegative() && rhs.isNegative())) {
1877 opNegate(qNoSign);
1878 } else {
1879 opAssign(qNoSign);
1880 }
1881 return *this;
1882 }
opDiv(const V3Number & lhs,const V3Number & rhs)1883 V3Number& V3Number::opDiv(const V3Number& lhs, const V3Number& rhs) {
1884 // i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
1885 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1886 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1887 // UINFO(9, "opdiv "<<lhs<<" "<<rhs<<endl);
1888 if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
1889 if (rhs.isEqZero()) return setAllBitsXRemoved();
1890 if (lhs.width() <= 64) {
1891 setQuad(lhs.toUQuad() / rhs.toUQuad());
1892 return *this;
1893 } else {
1894 // Wide division
1895 return opModDivGuts(lhs, rhs, false);
1896 }
1897 }
opDivS(const V3Number & lhs,const V3Number & rhs)1898 V3Number& V3Number::opDivS(const V3Number& lhs, const V3Number& rhs) {
1899 // Signed divide
1900 // UINFO(9, ">>divs-start "<<lhs<<" "<<rhs<<endl);
1901 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1902 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1903 if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
1904 if (rhs.isEqZero()) return setAllBitsXRemoved();
1905 V3Number lhsNoSign = lhs;
1906 if (lhs.isNegative()) lhsNoSign.opNegate(lhs);
1907 V3Number rhsNoSign = rhs;
1908 if (rhs.isNegative()) rhsNoSign.opNegate(rhs);
1909 const V3Number qNoSign = opDiv(lhsNoSign, rhsNoSign);
1910 // UINFO(9, " >divs-mid "<<lhs<<" "<<rhs<<" "<<qNoSign<<endl);
1911 if ((lhs.isNegative() && !rhs.isNegative()) || (!lhs.isNegative() && rhs.isNegative())) {
1912 opNegate(qNoSign);
1913 } else {
1914 opAssign(qNoSign);
1915 }
1916 UINFO(9, " <divs-out " << lhs << " " << rhs << " =" << *this << endl);
1917 return *this;
1918 }
opModDiv(const V3Number & lhs,const V3Number & rhs)1919 V3Number& V3Number::opModDiv(const V3Number& lhs, const V3Number& rhs) {
1920 // i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
1921 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1922 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1923 if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
1924 if (rhs.isEqZero()) return setAllBitsXRemoved();
1925 if (lhs.width() <= 64) {
1926 setQuad(lhs.toUQuad() % rhs.toUQuad());
1927 return *this;
1928 } else {
1929 // Wide modulus
1930 return opModDivGuts(lhs, rhs, true);
1931 }
1932 }
opModDivS(const V3Number & lhs,const V3Number & rhs)1933 V3Number& V3Number::opModDivS(const V3Number& lhs, const V3Number& rhs) {
1934 // Signed moddiv
1935 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1936 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1937 if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
1938 if (rhs.isEqZero()) return setAllBitsXRemoved();
1939 V3Number lhsNoSign = lhs;
1940 if (lhs.isNegative()) lhsNoSign.opNegate(lhs);
1941 V3Number rhsNoSign = rhs;
1942 if (rhs.isNegative()) rhsNoSign.opNegate(rhs);
1943 const V3Number qNoSign = opModDiv(lhsNoSign, rhsNoSign);
1944 if (lhs.isNegative()) { // Just lhs' sign (*DIFFERENT FROM PERL, which uses rhs sign*)
1945 opNegate(qNoSign);
1946 } else {
1947 opAssign(qNoSign);
1948 }
1949 return *this;
1950 }
opModDivGuts(const V3Number & lhs,const V3Number & rhs,bool is_modulus)1951 V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool is_modulus) {
1952 // See Knuth Algorithm D. Computes u/v = q.r
1953 // This isn't massively tuned, as wide division is rare
1954 NUM_ASSERT_OP_ARGS2(lhs, rhs);
1955 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
1956 setZero();
1957 // Find MSB and check for zero.
1958 const int words = lhs.words();
1959 const int umsbp1 = lhs.mostSetBitP1(); // dividend
1960 const int vmsbp1 = rhs.mostSetBitP1(); // divisor
1961 if (VL_UNLIKELY(vmsbp1 == 0) // rwp==0 so division by zero. Return 0.
1962 || VL_UNLIKELY(umsbp1 == 0)) { // 0/x so short circuit and return 0
1963 UINFO(9, " opmoddiv-zero " << lhs << " " << rhs << " now=" << *this << endl);
1964 return *this;
1965 }
1966
1967 const int uw = (umsbp1 + 31) / 32; // aka "m" in the algorithm
1968 const int vw = (vmsbp1 + 31) / 32; // aka "n" in the algorithm
1969
1970 if (vw == 1) { // Single divisor word breaks rest of algorithm
1971 vluint64_t k = 0;
1972 for (int j = uw - 1; j >= 0; j--) {
1973 const vluint64_t unw64
1974 = ((k << 32ULL) + static_cast<vluint64_t>(lhs.m_value[j].m_value));
1975 m_value[j].m_value = unw64 / static_cast<vluint64_t>(rhs.m_value[0].m_value);
1976 k = unw64
1977 - (static_cast<vluint64_t>(m_value[j].m_value)
1978 * static_cast<vluint64_t>(rhs.m_value[0].m_value));
1979 }
1980 UINFO(9, " opmoddiv-1w " << lhs << " " << rhs << " q=" << *this << " rem=0x" << std::hex
1981 << k << std::dec << endl);
1982 if (is_modulus) {
1983 setZero();
1984 m_value[0].m_value = k;
1985 }
1986 opCleanThis();
1987 return *this;
1988 }
1989
1990 // +1 word as we may shift during normalization
1991 uint32_t un[VL_MULS_MAX_WORDS + 1]; // Fixed size, as MSVC++ doesn't allow [words] here
1992 uint32_t vn[VL_MULS_MAX_WORDS + 1]; // v normalized
1993
1994 // Zero for ease of debugging and to save having to zero for shifts
1995 for (int i = 0; i < words; i++) { m_value[i].m_value = 0; }
1996 for (int i = 0; i < words + 1; i++) { un[i] = vn[i] = 0; } // +1 as vn may get extra word
1997
1998 // Algorithm requires divisor MSB to be set
1999 // Copy and shift to normalize divisor so MSB of vn[vw-1] is set
2000 const int s = 31 - ((vmsbp1 - 1) & 31); // shift amount (0...31)
2001 const uint32_t shift_mask = s ? 0xffffffff : 0; // otherwise >> 32 won't mask the value
2002 for (int i = vw - 1; i > 0; i--) {
2003 vn[i] = (rhs.m_value[i].m_value << s)
2004 | (shift_mask & (rhs.m_value[i - 1].m_value >> (32 - s)));
2005 }
2006 vn[0] = rhs.m_value[0].m_value << s;
2007
2008 // Copy and shift dividend by same amount; may set new upper word
2009 if (s) {
2010 un[uw] = lhs.m_value[uw - 1].m_value >> (32 - s);
2011 } else {
2012 un[uw] = 0;
2013 }
2014 for (int i = uw - 1; i > 0; i--) {
2015 un[i] = (lhs.m_value[i].m_value << s)
2016 | (shift_mask & (lhs.m_value[i - 1].m_value >> (32 - s)));
2017 }
2018 un[0] = lhs.m_value[0].m_value << s;
2019
2020 // printf(" un="); for (int i=5; i>=0; i--) printf(" %08x",un[i]); printf("\n");
2021 // printf(" vn="); for (int i=5; i>=0; i--) printf(" %08x",vn[i]); printf("\n");
2022 // printf(" mv="); for (int i=5; i>=0; i--) printf(" %08x",m_value[i]); printf("\n");
2023
2024 // Main loop
2025 for (int j = uw - vw; j >= 0; j--) {
2026 // Estimate
2027 const vluint64_t unw64 = (static_cast<vluint64_t>(un[j + vw]) << 32ULL
2028 | static_cast<vluint64_t>(un[j + vw - 1]));
2029 vluint64_t qhat = unw64 / static_cast<vluint64_t>(vn[vw - 1]);
2030 vluint64_t rhat = unw64 - qhat * static_cast<vluint64_t>(vn[vw - 1]);
2031
2032 again:
2033 if (qhat >= 0x100000000ULL || ((qhat * vn[vw - 2]) > ((rhat << 32ULL) + un[j + vw - 2]))) {
2034 qhat = qhat - 1;
2035 rhat = rhat + vn[vw - 1];
2036 if (rhat < 0x100000000ULL) goto again;
2037 }
2038
2039 vlsint64_t t = 0; // Must be signed
2040 vluint64_t k = 0;
2041 for (int i = 0; i < vw; i++) {
2042 const vluint64_t p = qhat * vn[i]; // Multiply by estimate
2043 t = un[i + j] - k - (p & 0xFFFFFFFFULL); // Subtract
2044 un[i + j] = t;
2045 k = (p >> 32ULL) - (t >> 32ULL);
2046 }
2047 t = un[j + vw] - k;
2048 un[j + vw] = t;
2049 this->m_value[j].m_value = qhat; // Save quotient digit
2050
2051 if (t < 0) {
2052 // Over subtracted; correct by adding back
2053 this->m_value[j].m_value--;
2054 k = 0;
2055 for (int i = 0; i < vw; i++) {
2056 t = static_cast<vluint64_t>(un[i + j]) + static_cast<vluint64_t>(vn[i]) + k;
2057 un[i + j] = t;
2058 k = t >> 32ULL;
2059 }
2060 un[j + vw] = un[j + vw] + k;
2061 }
2062 }
2063
2064 // printf(" un="); for (int i=5; i>=0; i--) printf(" %08x",un[i]); printf("\n");
2065 // printf(" vn="); for (int i=5; i>=0; i--) printf(" %08x",vn[i]); printf("\n");
2066 // printf(" mv="); for (int i=5; i>=0; i--) printf(" %08x",m_value[i]); printf("\n");
2067
2068 if (is_modulus) { // modulus
2069 // Need to reverse normalization on copy to output
2070 for (int i = 0; i < vw; i++) {
2071 m_value[i].m_value = (un[i] >> s) | (shift_mask & (un[i + 1] << (32 - s)));
2072 }
2073 for (int i = vw; i < words; i++) m_value[i].m_value = 0;
2074 opCleanThis();
2075 UINFO(9, " opmoddiv-mod " << lhs << " " << rhs << " now=" << *this << endl);
2076 return *this;
2077 } else { // division
2078 opCleanThis();
2079 UINFO(9, " opmoddiv-div " << lhs << " " << rhs << " now=" << *this << endl);
2080 return *this;
2081 }
2082 }
2083
opPow(const V3Number & lhs,const V3Number & rhs,bool lsign,bool rsign)2084 V3Number& V3Number::opPow(const V3Number& lhs, const V3Number& rhs, bool lsign, bool rsign) {
2085 // L(i) bit return, if any 4-state, 4-state return
2086 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2087 NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
2088 if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
2089 if (rhs.isEqZero()) return setQuad(1); // Overrides lhs 0 -> return 0
2090 // We may want to special case when the lhs is 2, so we can get larger outputs
2091 if (rsign && rhs.isNegative()) {
2092 if (lhs.isEqZero()) {
2093 return setAllBitsXRemoved();
2094 } else if (lhs.isEqOne()) {
2095 return setQuad(1);
2096 } else if (lsign && lhs.isEqAllOnes()) {
2097 if (rhs.bitIs1(0)) {
2098 return setAllBits1(); // -1^odd=-1
2099 } else {
2100 return setQuad(1); // -1^even=1
2101 }
2102 }
2103 return setZero();
2104 }
2105 if (lhs.isEqZero()) return setZero();
2106 setZero();
2107 m_value[0].m_value = 1;
2108 V3Number power(&lhs, width());
2109 power.opAssign(lhs);
2110 for (int bit = 0; bit < rhs.width(); bit++) {
2111 if (bit > 0) { // power = power*power
2112 V3Number lastPower(&lhs, width());
2113 lastPower.opAssign(power);
2114 power.opMul(lastPower, lastPower);
2115 }
2116 if (rhs.bitIs1(bit)) { // out *= power
2117 V3Number lastOut(&lhs, width());
2118 lastOut.opAssign(*this);
2119 this->opMul(lastOut, power);
2120 // UINFO(0, "pow "<<lhs<<" "<<rhs<<" b"<<bit<<" pow="<<power<<" now="<<*this<<endl);
2121 }
2122 }
2123 return *this;
2124 }
opPowSU(const V3Number & lhs,const V3Number & rhs)2125 V3Number& V3Number::opPowSU(const V3Number& lhs, const V3Number& rhs) {
2126 return opPow(lhs, rhs, true, false);
2127 }
opPowSS(const V3Number & lhs,const V3Number & rhs)2128 V3Number& V3Number::opPowSS(const V3Number& lhs, const V3Number& rhs) {
2129 return opPow(lhs, rhs, true, true);
2130 }
opPowUS(const V3Number & lhs,const V3Number & rhs)2131 V3Number& V3Number::opPowUS(const V3Number& lhs, const V3Number& rhs) {
2132 return opPow(lhs, rhs, false, true);
2133 }
2134
opBufIf1(const V3Number & ens,const V3Number & if1s)2135 V3Number& V3Number::opBufIf1(const V3Number& ens, const V3Number& if1s) {
2136 NUM_ASSERT_OP_ARGS2(ens, if1s);
2137 NUM_ASSERT_LOGIC_ARGS2(ens, if1s);
2138 setZero();
2139 for (int bit = 0; bit < this->width(); bit++) {
2140 if (ens.bitIs1(bit)) {
2141 setBit(bit, if1s.bitIs(bit));
2142 } else {
2143 setBit(bit, 'z');
2144 }
2145 }
2146 return *this;
2147 }
2148
opAssign(const V3Number & lhs)2149 V3Number& V3Number::opAssign(const V3Number& lhs) { return opAssignNonXZ(lhs, false); }
opAssignNonXZ(const V3Number & lhs,bool ignoreXZ)2150 V3Number& V3Number::opAssignNonXZ(const V3Number& lhs, bool ignoreXZ) {
2151 // Note may be a width change during the assign.
2152 // Special case: opAssign unlike other ops, allows this an assignment
2153 // to itself; V3Simulate does this when hits "foo=foo;"
2154 // So no: NUM_ASSERT_OP_ARGS1(lhs);
2155 if (this != &lhs) {
2156 setZero();
2157 if (isString()) {
2158 m_stringVal = lhs.m_stringVal;
2159 } else {
2160 // Also handles double as is just bits
2161 for (int bit = 0; bit < this->width(); bit++) {
2162 setBit(bit, ignoreXZ ? lhs.bitIs1(bit) : lhs.bitIs(bit));
2163 }
2164 }
2165 }
2166 return *this;
2167 }
2168
opExtendS(const V3Number & lhs,uint32_t lbits)2169 V3Number& V3Number::opExtendS(const V3Number& lhs, uint32_t lbits) {
2170 // Note may be a width change during the sign extension
2171 NUM_ASSERT_OP_ARGS1(lhs);
2172 NUM_ASSERT_LOGIC_ARGS1(lhs);
2173 setZero();
2174 for (int bit = 0; bit < width(); bit++) {
2175 const char extendWith = lhs.bitIsExtend(bit, lbits);
2176 setBit(bit, extendWith);
2177 }
2178 return *this;
2179 }
2180
opExtendXZ(const V3Number & lhs,uint32_t lbits)2181 V3Number& V3Number::opExtendXZ(const V3Number& lhs, uint32_t lbits) {
2182 // Note may be a width change during the X/Z extension
2183 NUM_ASSERT_OP_ARGS1(lhs);
2184 NUM_ASSERT_LOGIC_ARGS1(lhs);
2185 setZero();
2186 for (int bit = 0; bit < width(); bit++) { setBit(bit, lhs.bitIsExtend(bit, lbits)); }
2187 return *this;
2188 }
2189
opClean(const V3Number & lhs,uint32_t bits)2190 V3Number& V3Number::opClean(const V3Number& lhs, uint32_t bits) { return opSel(lhs, bits - 1, 0); }
2191
opCleanThis(bool warnOnTruncation)2192 void V3Number::opCleanThis(bool warnOnTruncation) {
2193 // Clean MSB of number
2194 NUM_ASSERT_LOGIC_ARGS1(*this);
2195 const ValueAndX v = m_value[words() - 1];
2196 const uint32_t newValueMsb = v.m_value & hiWordMask();
2197 const uint32_t newValueXMsb = v.m_valueX & hiWordMask();
2198 if (warnOnTruncation && (newValueMsb != v.m_value || newValueXMsb != v.m_valueX)) {
2199 // Displaying in decimal avoids hiWordMask truncation
2200 v3warn(WIDTH, "Value too large for " << width() << " bit number: " << displayed("%d"));
2201 }
2202 m_value[words() - 1] = {newValueMsb, newValueXMsb};
2203 }
2204
opSel(const V3Number & lhs,const V3Number & msb,const V3Number & lsb)2205 V3Number& V3Number::opSel(const V3Number& lhs, const V3Number& msb, const V3Number& lsb) {
2206 NUM_ASSERT_OP_ARGS3(lhs, msb, lsb);
2207 NUM_ASSERT_LOGIC_ARGS1(lhs);
2208 NUM_ASSERT_LOGIC_ARGS2(msb, lsb);
2209 if (lsb.isFourState() || msb.isFourState()) return setAllBitsX();
2210 return opSel(lhs, msb.toUInt(), lsb.toUInt());
2211 }
2212
opSel(const V3Number & lhs,uint32_t msbval,uint32_t lsbval)2213 V3Number& V3Number::opSel(const V3Number& lhs, uint32_t msbval, uint32_t lsbval) {
2214 NUM_ASSERT_OP_ARGS1(lhs);
2215 NUM_ASSERT_LOGIC_ARGS1(lhs);
2216 setZero();
2217 int ibit = lsbval;
2218 for (int bit = 0; bit < this->width(); bit++) {
2219 if (ibit >= 0 && ibit < lhs.width() && ibit <= static_cast<int>(msbval)) {
2220 setBit(bit, lhs.bitIs(ibit));
2221 } else {
2222 setBit(bit, 'x');
2223 }
2224 ++ibit;
2225 }
2226 // UINFO(0,"RANGE "<<lhs<<" "<<msb<<" "<<lsb<<" = "<<*this<<endl);
2227 return *this;
2228 }
2229
opSelInto(const V3Number & lhs,const V3Number & lsb,int width)2230 V3Number& V3Number::opSelInto(const V3Number& lhs, const V3Number& lsb, int width) {
2231 return opSelInto(lhs, lsb.toSInt(), width);
2232 }
2233
opSelInto(const V3Number & lhs,int lsbval,int width)2234 V3Number& V3Number::opSelInto(const V3Number& lhs, int lsbval, int width) {
2235 // this[lsbval+width-1 : lsbval] = lhs; Other bits of this are not affected
2236 NUM_ASSERT_OP_ARGS1(lhs);
2237 NUM_ASSERT_LOGIC_ARGS1(lhs);
2238 int ibit = 0;
2239 for (int bit = lsbval; bit < lsbval + width; bit++) {
2240 if (ibit >= 0 && ibit < lhs.width()) {
2241 setBit(bit, lhs.bitIs(ibit));
2242 } else {
2243 setBit(bit, 'x');
2244 }
2245 ibit++;
2246 }
2247 return *this;
2248 }
2249
2250 //======================================================================
2251 // Ops - Floating point
2252
opIToRD(const V3Number & lhs,bool isSigned)2253 V3Number& V3Number::opIToRD(const V3Number& lhs, bool isSigned) {
2254 NUM_ASSERT_OP_ARGS1(lhs);
2255 NUM_ASSERT_LOGIC_ARGS1(lhs);
2256 // IEEE says we ignore x/z in real conversions
2257 V3Number noxz(lhs);
2258 noxz.opAssignNonXZ(lhs);
2259 double d = 0;
2260 const bool negate = isSigned && noxz.isNegative();
2261 if (negate) {
2262 const V3Number noxz_signed = noxz;
2263 noxz.opNegate(noxz_signed);
2264 }
2265 for (int bit = noxz.width() - 1; bit >= 0; bit--) {
2266 // Some precision might be lost in this add, that's what we want
2267 if (noxz.bitIs1(bit)) d += exp2(bit);
2268 }
2269 if (negate) d = -d;
2270 return setDouble(d);
2271 }
opRToIS(const V3Number & lhs)2272 V3Number& V3Number::opRToIS(const V3Number& lhs) {
2273 NUM_ASSERT_OP_ARGS1(lhs);
2274 NUM_ASSERT_DOUBLE_ARGS1(lhs);
2275 const double v = VL_TRUNC(lhs.toDouble());
2276 const vlsint32_t i = static_cast<vlsint32_t>(v); // C converts from double to vlsint32
2277 return setLongS(i);
2278 }
opRToIRoundS(const V3Number & lhs)2279 V3Number& V3Number::opRToIRoundS(const V3Number& lhs) {
2280 NUM_ASSERT_OP_ARGS1(lhs);
2281 NUM_ASSERT_DOUBLE_ARGS1(lhs);
2282 const double v = VL_ROUND(lhs.toDouble());
2283 setZero();
2284 union {
2285 double d;
2286 vluint64_t q;
2287 } u;
2288 u.d = v;
2289 if (u.d == 0.0) {}
2290
2291 const int exp = static_cast<int>((u.q >> 52ULL) & VL_MASK_Q(11)) - 1023;
2292 const int lsb = exp - 52;
2293 const vluint64_t mantissa = (u.q & VL_MASK_Q(52)) | (1ULL << 52);
2294 if (v != 0) {
2295 // IEEE format: [63]=sign [62:52]=exp+1023 [51:0]=mantissa
2296 // This does not need to support subnormals as they are sub-integral
2297 for (int bit = 0; bit <= 52; ++bit) {
2298 if (mantissa & (1ULL << bit)) {
2299 const int outbit = bit + lsb;
2300 if (outbit >= 0) setBit(outbit, 1);
2301 }
2302 }
2303 if (v < 0) {
2304 const V3Number noSign = *this;
2305 opNegate(noSign);
2306 }
2307 }
2308 return *this;
2309 }
opRealToBits(const V3Number & lhs)2310 V3Number& V3Number::opRealToBits(const V3Number& lhs) {
2311 NUM_ASSERT_OP_ARGS1(lhs);
2312 NUM_ASSERT_DOUBLE_ARGS1(lhs);
2313 // Conveniently our internal format is identical so we can copy bits...
2314 if (lhs.width() != 64 || this->width() != 64) {
2315 v3fatalSrc("Real operation on wrong sized number");
2316 }
2317 opAssign(lhs);
2318 m_double = false;
2319 return *this;
2320 }
opBitsToRealD(const V3Number & lhs)2321 V3Number& V3Number::opBitsToRealD(const V3Number& lhs) {
2322 NUM_ASSERT_OP_ARGS1(lhs);
2323 // Conveniently our internal format is identical so we can copy bits...
2324 if (lhs.width() != 64 || this->width() != 64) {
2325 v3fatalSrc("Real operation on wrong sized number");
2326 }
2327 opAssign(lhs);
2328 m_double = true;
2329 return *this;
2330 }
opNegateD(const V3Number & lhs)2331 V3Number& V3Number::opNegateD(const V3Number& lhs) {
2332 NUM_ASSERT_OP_ARGS1(lhs);
2333 NUM_ASSERT_DOUBLE_ARGS1(lhs);
2334 return setDouble(-lhs.toDouble());
2335 }
opAddD(const V3Number & lhs,const V3Number & rhs)2336 V3Number& V3Number::opAddD(const V3Number& lhs, const V3Number& rhs) {
2337 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2338 NUM_ASSERT_DOUBLE_ARGS2(lhs, rhs);
2339 return setDouble(lhs.toDouble() + rhs.toDouble());
2340 }
opSubD(const V3Number & lhs,const V3Number & rhs)2341 V3Number& V3Number::opSubD(const V3Number& lhs, const V3Number& rhs) {
2342 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2343 NUM_ASSERT_DOUBLE_ARGS2(lhs, rhs);
2344 return setDouble(lhs.toDouble() - rhs.toDouble());
2345 }
opMulD(const V3Number & lhs,const V3Number & rhs)2346 V3Number& V3Number::opMulD(const V3Number& lhs, const V3Number& rhs) {
2347 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2348 NUM_ASSERT_DOUBLE_ARGS2(lhs, rhs);
2349 return setDouble(lhs.toDouble() * rhs.toDouble());
2350 }
opDivD(const V3Number & lhs,const V3Number & rhs)2351 V3Number& V3Number::opDivD(const V3Number& lhs, const V3Number& rhs) {
2352 // On exceptions, we just generate 'inf' through floating point
2353 // IEEE says it's implementation defined what happens
2354 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2355 NUM_ASSERT_DOUBLE_ARGS2(lhs, rhs);
2356 return setDouble(lhs.toDouble() / rhs.toDouble());
2357 }
opPowD(const V3Number & lhs,const V3Number & rhs)2358 V3Number& V3Number::opPowD(const V3Number& lhs, const V3Number& rhs) {
2359 // On exceptions, we just generate 'inf' through floating point
2360 // IEEE says it's implementation defined what happens
2361 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2362 NUM_ASSERT_DOUBLE_ARGS2(lhs, rhs);
2363 return setDouble(pow(lhs.toDouble(), rhs.toDouble()));
2364 }
opEqD(const V3Number & lhs,const V3Number & rhs)2365 V3Number& V3Number::opEqD(const V3Number& lhs, const V3Number& rhs) {
2366 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2367 NUM_ASSERT_DOUBLE_ARGS2(lhs, rhs);
2368 return setSingleBits(lhs.toDouble() == rhs.toDouble());
2369 }
opNeqD(const V3Number & lhs,const V3Number & rhs)2370 V3Number& V3Number::opNeqD(const V3Number& lhs, const V3Number& rhs) {
2371 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2372 NUM_ASSERT_DOUBLE_ARGS2(lhs, rhs);
2373 return setSingleBits(lhs.toDouble() != rhs.toDouble());
2374 }
opGtD(const V3Number & lhs,const V3Number & rhs)2375 V3Number& V3Number::opGtD(const V3Number& lhs, const V3Number& rhs) {
2376 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2377 NUM_ASSERT_DOUBLE_ARGS2(lhs, rhs);
2378 return setSingleBits(lhs.toDouble() > rhs.toDouble());
2379 }
opGteD(const V3Number & lhs,const V3Number & rhs)2380 V3Number& V3Number::opGteD(const V3Number& lhs, const V3Number& rhs) {
2381 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2382 NUM_ASSERT_DOUBLE_ARGS2(lhs, rhs);
2383 return setSingleBits(lhs.toDouble() >= rhs.toDouble());
2384 }
opLtD(const V3Number & lhs,const V3Number & rhs)2385 V3Number& V3Number::opLtD(const V3Number& lhs, const V3Number& rhs) {
2386 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2387 NUM_ASSERT_DOUBLE_ARGS2(lhs, rhs);
2388 return setSingleBits(lhs.toDouble() < rhs.toDouble());
2389 }
opLteD(const V3Number & lhs,const V3Number & rhs)2390 V3Number& V3Number::opLteD(const V3Number& lhs, const V3Number& rhs) {
2391 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2392 NUM_ASSERT_DOUBLE_ARGS2(lhs, rhs);
2393 return setSingleBits(lhs.toDouble() <= rhs.toDouble());
2394 }
2395
2396 //======================================================================
2397 // Ops - String
2398
opConcatN(const V3Number & lhs,const V3Number & rhs)2399 V3Number& V3Number::opConcatN(const V3Number& lhs, const V3Number& rhs) {
2400 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2401 NUM_ASSERT_STRING_ARGS2(lhs, rhs);
2402 return setString(lhs.toString() + rhs.toString());
2403 }
opReplN(const V3Number & lhs,const V3Number & rhs)2404 V3Number& V3Number::opReplN(const V3Number& lhs, const V3Number& rhs) {
2405 NUM_ASSERT_STRING_ARGS1(lhs);
2406 NUM_ASSERT_LOGIC_ARGS1(rhs);
2407 return opReplN(lhs, rhs.toUInt());
2408 }
opReplN(const V3Number & lhs,uint32_t rhsval)2409 V3Number& V3Number::opReplN(const V3Number& lhs, uint32_t rhsval) {
2410 NUM_ASSERT_OP_ARGS1(lhs);
2411 NUM_ASSERT_STRING_ARGS1(lhs);
2412 string out;
2413 out.reserve(lhs.toString().length() * rhsval);
2414 for (unsigned times = 0; times < rhsval; times++) { out += lhs.toString(); }
2415 return setString(out);
2416 }
opToLowerN(const V3Number & lhs)2417 V3Number& V3Number::opToLowerN(const V3Number& lhs) {
2418 NUM_ASSERT_OP_ARGS1(lhs);
2419 NUM_ASSERT_STRING_ARGS1(lhs);
2420 std::string out = lhs.toString();
2421 for (auto& cr : out) cr = tolower(cr);
2422 return setString(out);
2423 }
opToUpperN(const V3Number & lhs)2424 V3Number& V3Number::opToUpperN(const V3Number& lhs) {
2425 NUM_ASSERT_OP_ARGS1(lhs);
2426 NUM_ASSERT_STRING_ARGS1(lhs);
2427 std::string out = lhs.toString();
2428 for (auto& cr : out) cr = toupper(cr);
2429 return setString(out);
2430 }
2431
opEqN(const V3Number & lhs,const V3Number & rhs)2432 V3Number& V3Number::opEqN(const V3Number& lhs, const V3Number& rhs) {
2433 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2434 NUM_ASSERT_STRING_ARGS2(lhs, rhs);
2435 return setSingleBits(lhs.toString() == rhs.toString());
2436 }
opNeqN(const V3Number & lhs,const V3Number & rhs)2437 V3Number& V3Number::opNeqN(const V3Number& lhs, const V3Number& rhs) {
2438 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2439 NUM_ASSERT_STRING_ARGS2(lhs, rhs);
2440 return setSingleBits(lhs.toString() != rhs.toString());
2441 }
opGtN(const V3Number & lhs,const V3Number & rhs)2442 V3Number& V3Number::opGtN(const V3Number& lhs, const V3Number& rhs) {
2443 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2444 NUM_ASSERT_STRING_ARGS2(lhs, rhs);
2445 return setSingleBits(lhs.toString() > rhs.toString());
2446 }
opGteN(const V3Number & lhs,const V3Number & rhs)2447 V3Number& V3Number::opGteN(const V3Number& lhs, const V3Number& rhs) {
2448 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2449 NUM_ASSERT_STRING_ARGS2(lhs, rhs);
2450 return setSingleBits(lhs.toString() >= rhs.toString());
2451 }
opLtN(const V3Number & lhs,const V3Number & rhs)2452 V3Number& V3Number::opLtN(const V3Number& lhs, const V3Number& rhs) {
2453 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2454 NUM_ASSERT_STRING_ARGS2(lhs, rhs);
2455 return setSingleBits(lhs.toString() < rhs.toString());
2456 }
opLteN(const V3Number & lhs,const V3Number & rhs)2457 V3Number& V3Number::opLteN(const V3Number& lhs, const V3Number& rhs) {
2458 NUM_ASSERT_OP_ARGS2(lhs, rhs);
2459 NUM_ASSERT_STRING_ARGS2(lhs, rhs);
2460 return setSingleBits(lhs.toString() <= rhs.toString());
2461 }
2462