From 13e0fc7c275e99d80de77f128313f7f814d19f6d Mon Sep 17 00:00:00 2001 From: Krzysztof Bieganski Date: Wed, 21 Aug 2024 11:40:52 +0200 Subject: [PATCH] Fix virtual interface null checks (#5391) --- include/verilated_types.h | 8 ++++++-- src/V3AstNodeDType.h | 4 ++-- src/V3Width.cpp | 3 +-- test_regress/t/t_interface_virtual.v | 9 +++++++++ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/verilated_types.h b/include/verilated_types.h index fa99d32e5..ea831514a 100644 --- a/include/verilated_types.h +++ b/include/verilated_types.h @@ -1787,12 +1787,16 @@ public: }; //=================================================================== -// Represents the null pointer. Used for setting VlClassRef to null instead of -// via nullptr_t, to prevent the implicit conversion of 0 to nullptr. +// Represents the null pointer. Used for: +// * setting VlClassRef to null instead of via nullptr_t, to prevent the implicit conversion of 0 +// to nullptr, +// * comparing interface pointers to null. struct VlNull final { operator bool() const { return false; } + bool operator==(void* ptr) const { return !ptr; } }; +inline bool operator==(void* ptr, VlNull) { return !ptr; } //=================================================================== // Verilog class reference container diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 1dc08e6bc..7e7f4be4b 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -876,8 +876,8 @@ public: AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } bool similarDType(const AstNodeDType* samep) const override { return this == samep; } - int widthAlignBytes() const override { return 1; } - int widthTotalBytes() const override { return 1; } + int widthAlignBytes() const override { return 0; } + int widthTotalBytes() const override { return 0; } bool isVirtual() const { return m_virtual; } void isVirtual(bool flag) { m_virtual = flag; diff --git a/src/V3Width.cpp b/src/V3Width.cpp index d813c2c5c..cdfd4cae5 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2744,7 +2744,6 @@ class WidthVisitor final : public VNVisitor { UINFO(5, " IFACEREF " << nodep << endl); userIterateChildren(nodep, m_vup); nodep->dtypep(nodep); - nodep->widthForce(1, 1); // Not really relevant UINFO(4, "dtWidthed " << nodep << endl); } void visit(AstNodeUOrStructDType* nodep) override { @@ -7024,7 +7023,7 @@ class WidthVisitor final : public VNVisitor { = new AstNeqD{nodep->fileline(), VN_AS(underp, NodeExpr), new AstConst{nodep->fileline(), AstConst::RealDouble{}, 0.0}}; linker.relink(newp); - } else if (VN_IS(underVDTypep, ClassRefDType) + } else if (VN_IS(underVDTypep, ClassRefDType) || VN_IS(underVDTypep, IfaceRefDType) || (VN_IS(underVDTypep, BasicDType) && VN_AS(underVDTypep, BasicDType)->keyword() == VBasicDTypeKwd::CHANDLE)) { // Allow warning-free "if (handle)" diff --git a/test_regress/t/t_interface_virtual.v b/test_regress/t/t_interface_virtual.v index 2b36e1a30..abb9e7d51 100644 --- a/test_regress/t/t_interface_virtual.v +++ b/test_regress/t/t_interface_virtual.v @@ -34,6 +34,9 @@ module t (/*AUTOARG*/); initial begin va = ia; vb = ia; + + if (va == null) $stop; + $display("va==vb? %b", va==vb); $display("va!=vb? %b", va!=vb); vb = ib; @@ -53,6 +56,8 @@ module t (/*AUTOARG*/); $display("va.addr=%x", va.addr, " va.data=%x", va.data, " ia.addr=%x", ia.addr, " ia.data=%x", ia.data); $display("vb.addr=%x", vb.addr, " vb.data=%x", vb.data, " ib.addr=%x", ib.addr, " ib.data=%x", ib.data); + if (ca.fa) $stop; + ca.fa = ia; ca.fb = ib; cb.fa = ib; @@ -60,6 +65,10 @@ module t (/*AUTOARG*/); gen.x[0] = va; gen.x[1] = vb; + if (ca == null) $stop; + if (ca.fa == null) $stop; + if (!ca.fa ) $stop; + pa = va; pb = vb;