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