From 9bd5cd4ef3be5d016002fac430e0ae3dcb23d69e Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 5 Dec 2020 16:49:10 -0500 Subject: [PATCH] Internals: Track null separately from '0 --- src/V3AstNodes.h | 7 +++++++ src/V3Number.cpp | 2 ++ src/V3Number.h | 9 +++++++++ src/verilog.y | 2 +- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 3bbddb483..b04c2bd65 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -153,6 +153,13 @@ public: , m_num(this, 1, on) { dtypeSetBit(); } + class Null {}; + AstConst(FileLine* fl, Null) + : ASTGEN_SUPER(fl) + , m_num(V3Number::Null{}, this) { + dtypeSetBit(); // Events 1 bit, objects 64 bits, so autoExtend=1 and use bit here + initWithNumber(); + } ASTNODE_NODE_FUNCS(Const) virtual string name() const override { return num().ascii(); } // * = Value const V3Number& num() const { return m_num; } // * = Value diff --git a/src/V3Number.cpp b/src/V3Number.cpp index a2073dff7..2f8fb2544 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -495,6 +495,7 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const { out << "'"; if (bitIs0(0)) { out << '0'; + if (isNull()) out << "[null]"; } else if (bitIs1(0)) { out << '1'; } else if (bitIsZ(0)) { @@ -529,6 +530,7 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const { // Always deal with 4 bits at once. Note no 4-state, it's above. out << displayed("%0h"); } + if (isNull() && VL_UNCOVERABLE(!isEqZero())) out << "-%E-null-not-zero"; return out.str(); } diff --git a/src/V3Number.h b/src/V3Number.h index 240858ea9..e07b13c34 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -43,6 +43,7 @@ class V3Number final { bool m_sized : 1; // True if the user specified the width, else we track it. bool m_signed : 1; // True if signed value bool m_double : 1; // True if double real value + bool m_isNull : 1; // True if "null" versus normal 0 bool m_isString : 1; // True if string bool m_fromString : 1; // True if from string literal bool m_autoExtend : 1; // True if SystemVerilog extend-to-any-width @@ -176,6 +177,12 @@ public: init(nodep, 0); setString(value); } + class Null {}; + V3Number(Null, AstNode* nodep) { + init(nodep, 0); + m_isNull = true; + m_autoExtend = true; + } explicit V3Number(const V3Number* nump, int width = 1) { init(nullptr, width); m_fileline = nump->fileline(); @@ -193,6 +200,7 @@ private: setNames(nodep); m_signed = false; m_double = false; + m_isNull = false; m_isString = false; m_autoExtend = false; m_fromString = false; @@ -250,6 +258,7 @@ public: bool isString() const { return m_isString; } void isString(bool flag) { m_isString = flag; } bool isNegative() const { return bitIs1(width() - 1); } + bool isNull() const { return m_isNull; } bool isFourState() const; bool hasZ() const { for (int i = 0; i < words(); i++) { diff --git a/src/verilog.y b/src/verilog.y index b6b54483f..2bc8d565a 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -4274,7 +4274,7 @@ expr: // IEEE: part of expression/constant_expression/primary // // Indistinguishable from function_subroutine_call:method_call // | '$' { $$ = new AstUnbounded($1); } - | yNULL { $$ = new AstConst($1, AstConst::StringToParse(), "'0"); } + | yNULL { $$ = new AstConst($1, AstConst::Null{}); } // // IEEE: yTHIS // // See exprScope //