diff --git a/Changes b/Changes index b2c6be97c..010e972a2 100644 --- a/Changes +++ b/Changes @@ -70,6 +70,7 @@ Verilator 5.041 devel * Fix timeprecision backward assignment (#6469). [Artur Bieniek, Antmicro Ltd.] * Fix splitting hierarchically referenced variables (#6475). [Ryszard Rozak, Antmicro Ltd.] * Fix Windows compilation of Verilator with spaces in the path (#6477). [Fabian Keßler-Schulz] +* Fix PROTOTYPEMIS error on implicit logic (#6482). [Alex Solomatnikov] Verilator 5.040 2025-08-30 diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index f7379bf61..806d39285 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -430,7 +430,7 @@ public: void dumpJson(std::ostream& str) const override; // width/widthMin/numeric compared elsewhere bool sameNode(const AstNode* samep) const override; - bool similarDTypeNode(const AstNodeDType* samep) const override { return sameNode(samep); } + bool similarDTypeNode(const AstNodeDType* samep) const override; string name() const override VL_MT_STABLE { return m.m_keyword.ascii(); } string prettyDTypeName(bool full) const override; const char* broken() const override { diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index e4d4a619c..15ea7eee0 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -258,7 +258,23 @@ int AstBasicDType::widthTotalBytes() const { bool AstBasicDType::sameNode(const AstNode* samep) const { const AstBasicDType* const sp = VN_DBG_AS(samep, BasicDType); - if (!(m == sp->m) || numeric() != sp->numeric()) return false; + if (!(m == sp->m)) return false; + if (numeric() != sp->numeric()) return false; + if (!rangep() && !sp->rangep()) return true; + return rangep() && rangep()->sameTree(sp->rangep()); +} +bool AstBasicDType::similarDTypeNode(const AstNodeDType* samep) const { + if (sameNode(samep)) return true; + const AstBasicDType* const sp = VN_DBG_AS(samep, BasicDType); + if (!(m.m_keyword == sp->m.m_keyword + || (m.m_keyword == VBasicDTypeKwd::LOGIC_IMPLICIT + && sp->m.m_keyword == VBasicDTypeKwd::LOGIC) + || (m.m_keyword == VBasicDTypeKwd::LOGIC + && sp->m.m_keyword == VBasicDTypeKwd::LOGIC_IMPLICIT))) + return false; + if (!(m.m_nrange == sp->m.m_nrange)) return false; + // Squash so NOSIGN == UNSIGNED + if (numeric().isSigned() != sp->numeric().isSigned()) return false; if (!rangep() && !sp->rangep()) return true; return rangep() && rangep()->sameTree(sp->rangep()); } diff --git a/test_regress/t/t_class_extern.v b/test_regress/t/t_class_extern.v index 7310da8ea..da50973d9 100644 --- a/test_regress/t/t_class_extern.v +++ b/test_regress/t/t_class_extern.v @@ -9,6 +9,7 @@ class Cls; extern function int ext_f_np; extern function int ext_f_p(); extern function int ext_f_i(int in); + extern function ext_f_imp(in); extern static function int get_1(); extern task ext_t_np; extern task ext_t_p(); @@ -37,6 +38,10 @@ function int Cls::ext_f_i(int in); return in+1; endfunction +function Cls::ext_f_imp(in); + return ~in; +endfunction + function int Cls::get_1(); return 1; endfunction @@ -88,6 +93,7 @@ module t; if (c.ext_f_np() != 1) $stop; if (c.ext_f_p() != 2) $stop; if (c.ext_f_i(10) != 11) $stop; + if (c.ext_f_imp(1'b1) != 1'b0) $stop; if (Cls::get_1() != 1) $stop; subc.ext_t_i(20); if (subc.ext_f_np() != 10) $stop;