// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Ordering graph // // Code available from: https://verilator.org // //************************************************************************* // // Copyright 2003-2023 by Wilson Snyder. This program is free software; you // can redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 // //************************************************************************* // // TODO: Fix comment // //************************************************************************* #ifndef VERILATOR_V3ORDERMOVEGRAPH_H_ #define VERILATOR_V3ORDERMOVEGRAPH_H_ #include "config_build.h" #include "verilatedos.h" #include "V3Ast.h" #include "V3Graph.h" #include "V3OrderGraph.h" #include class OrderMoveDomScope; class OrderMoveVertex final : public V3GraphVertex { enum OrderMState : uint8_t { POM_WAIT, POM_READY, POM_MOVED }; OrderLogicVertex* const m_logicp; OrderMState m_state; // Movement state OrderMoveDomScope* m_domScopep; // Domain/scope list information protected: friend class OrderProcess; friend class OrderMoveVertexMaker; // These only contain the "next" item, // for the head of the list, see the same var name under OrderProcess V3ListEnt m_pomWaitingE; // List of nodes needing inputs to become ready V3ListEnt m_readyVerticesE; // List of ready under domain/scope public: // CONSTRUCTORS OrderMoveVertex(V3Graph* graphp, OrderLogicVertex* logicp) : V3GraphVertex{graphp} , m_logicp{logicp} , m_state{POM_WAIT} , m_domScopep{nullptr} {} ~OrderMoveVertex() override = default; // METHODS string dotColor() const override { if (logicp()) { return logicp()->dotColor(); } else { return ""; } } string name() const override VL_MT_STABLE { string nm; if (VL_UNCOVERABLE(!logicp())) { // Avoid crash when debugging nm = "nul"; // LCOV_EXCL_LINE } else { nm = logicp()->name(); nm += (string("\\nMV:") + " d=" + cvtToHex(logicp()->domainp()) + " s=" + cvtToHex(logicp()->scopep())); } return nm; } OrderLogicVertex* logicp() const { return m_logicp; } bool isWait() const { return m_state == POM_WAIT; } void setReady() { UASSERT(m_state == POM_WAIT, "Wait->Ready on node not in proper state"); m_state = POM_READY; } void setMoved() { UASSERT(m_state == POM_READY, "Ready->Moved on node not in proper state"); m_state = POM_MOVED; } OrderMoveDomScope* domScopep() const { return m_domScopep; } OrderMoveVertex* pomWaitingNextp() const { return m_pomWaitingE.nextp(); } void domScopep(OrderMoveDomScope* ds) { m_domScopep = ds; } }; // Similar to OrderMoveVertex, but modified for threaded code generation. class MTaskMoveVertex final : public V3GraphVertex { // This could be more compact, since we know m_varp and m_logicp // cannot both be set. Each MTaskMoveVertex represents a logic node // or a var node, it can't be both. OrderLogicVertex* const m_logicp; // Logic represented by this vertex const OrderEitherVertex* const m_varp; // Var represented by this vertex const AstSenTree* const m_domainp; public: MTaskMoveVertex(V3Graph* graphp, OrderLogicVertex* logicp, const OrderEitherVertex* varp, const AstSenTree* domainp) : V3GraphVertex{graphp} , m_logicp{logicp} , m_varp{varp} , m_domainp{domainp} { UASSERT(!(logicp && varp), "MTaskMoveVertex: logicp and varp may not both be set!\n"); } ~MTaskMoveVertex() override = default; // ACCESSORS OrderLogicVertex* logicp() const { return m_logicp; } const OrderEitherVertex* varp() const { return m_varp; } const AstScope* scopep() const { return m_logicp ? m_logicp->scopep() : nullptr; } const AstSenTree* domainp() const { return m_domainp; } string dotColor() const override { if (logicp()) { return logicp()->dotColor(); } else { return "yellow"; } } string name() const override { string nm; if (logicp()) { nm = logicp()->name(); nm += (string("\\nMV:") + " d=" + cvtToHex(logicp()->domainp()) + " s=" + cvtToHex(logicp()->scopep()) // "color()" represents the mtask ID. + "\\nt=" + cvtToStr(color())); } else { nm = "nolog\\nt=" + cvtToStr(color()); } return nm; } }; #endif // Guard