diff --git a/Changes b/Changes index ed764aacf..42c0aefa2 100644 --- a/Changes +++ b/Changes @@ -4,7 +4,7 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 4.025 devel -*** Add BOUNDED warning and promote bounded queues to unbounded. +*** Support bounded queues. *** Support string compare, icompare, ato* methods, bug1606. [Yutetsu TAKATSUKASA] diff --git a/include/verilated_heavy.h b/include/verilated_heavy.h index c041b56eb..766bafc5e 100644 --- a/include/verilated_heavy.h +++ b/include/verilated_heavy.h @@ -185,7 +185,8 @@ std::string VL_TO_STRING(const VlAssocArray& obj) { // There are no multithreaded locks on this; the base variable must // be protected by other means // -template class VlQueue { +// Bound here is the maximum size() allowed, e.g. 1 + SystemVerilog bound +template class VlQueue { private: // TYPES typedef std::deque Deque; @@ -215,9 +216,14 @@ public: void erase(size_t index) { if (VL_LIKELY(index < m_deque.size())) m_deque.erase(index); } // function void q.push_front(value) - void push_front(const T_Value& value) { m_deque.push_front(value); } + void push_front(const T_Value& value) { + m_deque.push_front(value); + if (VL_UNLIKELY(T_MaxSize != 0 && m_deque.size() > T_MaxSize)) m_deque.pop_back(); + } // function void q.push_back(value) - void push_back(const T_Value& value) { m_deque.push_back(value); } + void push_back(const T_Value& value) { + if (VL_LIKELY(T_MaxSize == 0 || m_deque.size() < T_MaxSize)) m_deque.push_back(value); + } // function value_t q.pop_front(); T_Value pop_front() { if (m_deque.empty()) return m_defaultValue; diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 648fc09ff..e7c17fd15 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -285,6 +285,8 @@ AstVar::VlArgTypeRecursed AstVar::vlArgTypeRecurse(bool forFunc, const AstNodeDT if (!sub.m_osuffix.empty() || !sub.m_oref.empty()) { out += " " + sub.m_osuffix + sub.m_oref; } + // + 1 below as VlQueue uses 0 to mean unlimited, 1 to mean size() max is 1 + if (adtypep->boundp()) out += ", " + cvtToStr(adtypep->boundConst() + 1); out += "> "; info.m_oprefix = out; return info; diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 423fc5171..d93eb4722 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -743,8 +743,9 @@ class AstQueueDType : public AstNodeDType { private: AstNodeDType* m_refDTypep; // Elements of this type (after widthing) public: - AstQueueDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp) + AstQueueDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* boundp) : AstNodeDType(fl) { + setNOp2p(boundp); childDTypep(dtp); // Only for parser refDTypep(NULL); dtypep(NULL); // V3Width will resolve @@ -770,6 +771,9 @@ public: void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } + AstNode* boundp() const { return op2p(); } // op2 = Bound, NULL = none + void boundp(AstNode* nodep) { setNOp2p(nodep); } + int boundConst() const { AstConst* constp = VN_CAST(boundp(), Const); return (constp?constp->toSInt() : 0); } virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; } virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } // METHODS diff --git a/src/V3Error.h b/src/V3Error.h index 8f2892c16..98ce5220f 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -105,7 +105,6 @@ public: SYMRSVDWORD, // Symbol is Reserved Word SYNCASYNCNET, // Mixed sync + async reset TICKCOUNT, // Too large tick count - UNBOUNDED, // Unbounded queue UNDRIVEN, // No drivers UNOPT, // Unoptimizable block UNOPTFLAT, // Unoptimizable block after flattening @@ -155,7 +154,7 @@ public: "REALCVT", "REDEFMACRO", "SELRANGE", "SHORTREAL", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET", "TICKCOUNT", - "UNBOUNDED", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS", + "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS", "UNPACKED", "UNSIGNED", "UNUSED", "USERERROR", "USERFATAL", "USERINFO", "USERWARN", "VARHIDDEN", "WIDTH", "WIDTHCONCAT", diff --git a/src/V3ParseGrammar.cpp b/src/V3ParseGrammar.cpp index 13155ac15..af9a23c6c 100644 --- a/src/V3ParseGrammar.cpp +++ b/src/V3ParseGrammar.cpp @@ -118,14 +118,11 @@ AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep, (rangep->fileline(), VFlagChildDType(), arrayp, rangep); } else if (VN_IS(nrangep, QueueRange)) { arrayp = new AstQueueDType - (nrangep->fileline(), VFlagChildDType(), arrayp); + (nrangep->fileline(), VFlagChildDType(), arrayp, NULL); } else if (rangep && (VN_IS(rangep->leftp(), Unbounded) || VN_IS(rangep->rightp(), Unbounded))) { - if (!VN_IS(rangep->rightp(), Unbounded)) { - rangep->v3warn(UNBOUNDED, - "Unsupported: Bounded queues. Converting to unbounded."); - } - arrayp = new AstQueueDType(nrangep->fileline(), VFlagChildDType(), arrayp); + arrayp = new AstQueueDType(nrangep->fileline(), VFlagChildDType(), arrayp, + rangep->rightp()->cloneTree(true)); } else if (rangep) { arrayp = new AstUnpackArrayDType (rangep->fileline(), VFlagChildDType(), arrayp, rangep); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index d67dae471..6eadf53a9 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1124,6 +1124,9 @@ private: // Iterate into subDTypep() to resolve that type and update pointer. nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep())); nodep->dtypep(nodep); // The array itself, not subDtype + if (VN_IS(nodep->boundp(), Unbounded)) { + nodep->boundp()->unlinkFrBack()->deleteTree(); // NULL will represent unbounded + } UINFO(4,"dtWidthed "< 1); - -lint( - fails => 1, - expect_filename => $Self->{golden_filename}, - ); - -ok(1); -1; diff --git a/test_regress/t/t_queue_bounded_unsup_bad.v b/test_regress/t/t_queue_bounded_unsup_bad.v deleted file mode 100644 index 6a4c94da4..000000000 --- a/test_regress/t/t_queue_bounded_unsup_bad.v +++ /dev/null @@ -1,8 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// This file ONLY is placed into the Public Domain, for any use, -// without warranty, 2019 by Wilson Snyder. - -module t (/*AUTOARG*/); - int q[$ : 3]; -endmodule