Generate AstNode accessors via astgen
Introduce the @astgen directives parsed by astgen, currently used for the generation child node (operand) accessors. Please see the updated internal documentation for details.
This commit is contained in:
parent
0a8cfb8d2c
commit
ce03293128
|
|
@ -96,10 +96,11 @@ this.
|
|||
Each ``AstNode`` has pointers to up to four children, accessed by the
|
||||
``op1p`` through ``op4p`` methods. These methods are then abstracted in a
|
||||
specific Ast\* node class to a more specific name. For example with the
|
||||
``AstIf`` node (for ``if`` statements), ``ifsp`` calls ``op2p`` to give the
|
||||
``AstIf`` node (for ``if`` statements), ``thensp`` calls ``op2p`` to give the
|
||||
pointer to the AST for the "then" block, while ``elsesp`` calls ``op3p`` to
|
||||
give the pointer to the AST for the "else" block, or NULL if there is not
|
||||
one.
|
||||
one. These accessors are automatically generated by ``astgen`` after
|
||||
parsing the ``@astgen`` directives in the specific ``AstNode`` subclasses.
|
||||
|
||||
``AstNode`` has the concept of a next and previous AST - for example the
|
||||
next and previous statements in a block. Pointers to the AST for these
|
||||
|
|
@ -501,22 +502,99 @@ code:
|
|||
The ``astgen`` Script
|
||||
---------------------
|
||||
|
||||
Some of the code implementing passes is extremely repetitive, and must be
|
||||
implemented for each sub-class of ``AstNode``. However, while repetitive,
|
||||
there is more variability than can be handled in C++ macros.
|
||||
The ``astgen`` script is used to generate some of the repetitive C++ code
|
||||
related to the ``AstNode`` type hierarchy. An example is the abstract ``visit``
|
||||
methods in ``VNVisitor``. There are other uses, please see the ``*__gen*``
|
||||
files in the bulid directories and the ``astgen`` script itself for details. A
|
||||
description of the more advanced features of ``astgen`` are provided here.
|
||||
|
||||
In Verilator this is implemented by using a script, ``astgen`` to
|
||||
pre-process the C++ code. For example in ``V3Const.cpp`` this is used to
|
||||
implement the ``visit()`` functions for each binary operation using the
|
||||
``TREEOP`` macro.
|
||||
|
||||
The original C source code is transformed into C code in the ``obj_opt``
|
||||
Generating ``AstNode`` members
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Some of the member s of ``AstNode`` sub-classes are generated by ``astgen``.
|
||||
These are emitted as pre-processor macro definitions, which then need to be
|
||||
added to the ``AstNode`` sub-classes they correspond to. Specifically ``class
|
||||
AstFoo`` should contain an instance of ``ASTGEN_MEMBERS_Foo;`` at class scope.
|
||||
The ``astgen`` script checks and errors if this is not present. The method
|
||||
generated depends on whether the class is a concrete final class, or an
|
||||
abstract ``AstNode*`` base-class, and on ``@astgen`` directives present in
|
||||
comment sections in the body of the ``AstNode`` sub-class definitions.
|
||||
|
||||
|
||||
List of ``@astgen`` directives
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``@astgen`` directives in comments contained in the body of ``AstNode``
|
||||
sub-class definitions are parsed and contribute to the code generated by
|
||||
``astgen``. The general syntax is ``@astgen <keywords> := <description>``,
|
||||
where ``<keywords>`` determines what is being defined, and ``<description>`` is
|
||||
a ``<keywords>`` dependent description of the definition. The list of
|
||||
``@astgen`` directives is as follows:
|
||||
|
||||
|
||||
``op<N>`` operand directives
|
||||
"""""""""""""""""""""""""""""
|
||||
|
||||
The ``op1``, ``op2``, ``op3`` and ``op4`` directives are used to describe the
|
||||
name and type of the up to 4 child operands of a node. The syntax of the
|
||||
``<description>`` field is ``<identifier> : <type>``, where ``<identifier>``
|
||||
will be used as the base name of the generated operand accessors, and
|
||||
``<type>`` is one of:
|
||||
|
||||
1. An ``AstNode`` sub-class, defining the operand to be of that type, always
|
||||
no-null, and with an always null ``nextp()``. That is, the child node is
|
||||
always present, and is a single ``AstNode`` (as opposed to a list).
|
||||
|
||||
2. ``Optional[<AstNode sub-class>]``. This is just like in point 1 above, but
|
||||
defines the child node to be optional, meaning it may be null.
|
||||
|
||||
3. ``List[AstNode sub-class]`` describes a list operand, which means the child
|
||||
node may have a non-null ``nextp()`` and in addition the child itself may be
|
||||
null, representing an empty list.
|
||||
|
||||
|
||||
An example of the full syntax of the directive is
|
||||
``@astgen op1 := lhsp : AstNodeMath``.
|
||||
|
||||
``astnode`` generates accessors for the child nodes based on these directives.
|
||||
For non-list children, the names of the getter and setter both are that of the
|
||||
given ``<identifier>``. For list type children, the getter is ``<identifier>``,
|
||||
and instead of the setter, there an ``add<Identifier>`` method is generated
|
||||
that appends new nodes (or lists of nodes) to the child list.
|
||||
|
||||
``alias op<N>`` operand alias directives
|
||||
""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
If a super-class already defined a name and type for a child node using the
|
||||
``op<N>`` directive, but a more appropriate name exists in the context of a
|
||||
sub-class, then the alias directive can be used to introduce an additional name
|
||||
for the child node. The is ``alias op<N> := <identifier>`` where
|
||||
``<identifier>`` is the new name. ``op<N>`` must have been defined in some
|
||||
super-class of the current node.
|
||||
|
||||
Example: ``@astgen alias op1 := condp``
|
||||
|
||||
|
||||
Additional features of ``astgen``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In addition to generating ``AstNode`` members as described above,
|
||||
``astgen`` is also use to handle some of the repetitive implementation code
|
||||
that is still variable enough not to be handled in C++ macros.
|
||||
|
||||
In particular, ``astgen`` is used to pre-process some of the C++ source
|
||||
files. For example in ``V3Const.cpp``, it is used to implement the
|
||||
``visit()`` functions for each binary operation using the ``TREEOP`` macro.
|
||||
|
||||
The original C++ source code is transformed into C++ code in the ``obj_opt``
|
||||
and ``obj_dbg`` sub-directories (the former for the optimized version of
|
||||
Verilator, the latter for the debug version). So for example
|
||||
``V3Const.cpp`` into ``V3Const__gen.cpp``.
|
||||
|
||||
|
||||
Visitor Functions -----------------
|
||||
Visitor Functions
|
||||
-----------------
|
||||
|
||||
Verilator uses the "Visitor" design pattern to implement its refinement and
|
||||
optimization passes. This allows separation of the pass algorithm from the
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ private:
|
|||
// METHODS
|
||||
void addActive(AstActive* nodep) {
|
||||
UASSERT_OBJ(m_scopep, nodep, "nullptr scope");
|
||||
m_scopep->addActivep(nodep);
|
||||
m_scopep->addBlocksp(nodep);
|
||||
}
|
||||
// VISITORS
|
||||
void visit(AstScope* nodep) override {
|
||||
|
|
@ -302,7 +302,7 @@ private:
|
|||
LatchDetectGraphVertex* const parentp = m_graph.currentp();
|
||||
LatchDetectGraphVertex* const branchp = m_graph.addPathVertex(parentp, "BRANCH", true);
|
||||
m_graph.addPathVertex(branchp, "IF");
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
iterateAndNextNull(nodep->thensp());
|
||||
m_graph.addPathVertex(branchp, "ELSE");
|
||||
iterateAndNextNull(nodep->elsesp());
|
||||
m_graph.currentp(parentp);
|
||||
|
|
@ -458,7 +458,7 @@ private:
|
|||
void visit(AstFinal* nodep) override {
|
||||
// Relink to CFUNC for the final
|
||||
UINFO(4, " FINAL " << nodep << endl);
|
||||
if (!nodep->bodysp()) { // Empty, Kill it.
|
||||
if (!nodep->stmtsp()) { // Empty, Kill it.
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
}
|
||||
|
|
@ -471,10 +471,10 @@ private:
|
|||
m_scopeFinalp->isStatic(false);
|
||||
m_scopeFinalp->isLoose(true);
|
||||
m_scopeFinalp->slow(true);
|
||||
m_namer.scopep()->addActivep(m_scopeFinalp);
|
||||
m_namer.scopep()->addBlocksp(m_scopeFinalp);
|
||||
}
|
||||
nodep->unlinkFrBack();
|
||||
m_scopeFinalp->addStmtsp(nodep->bodysp()->unlinkFrBackWithNext());
|
||||
m_scopeFinalp->addStmtsp(nodep->stmtsp()->unlinkFrBackWithNext());
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
|
||||
|
|
@ -542,7 +542,7 @@ private:
|
|||
UINFO(4, " ALW " << nodep << endl);
|
||||
// if (debug() >= 9) nodep->dumpTree(cout, " Alw: ");
|
||||
|
||||
if (!nodep->bodysp()) {
|
||||
if (!nodep->stmtsp()) {
|
||||
// Empty always. Kill it.
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
|
|
@ -551,7 +551,7 @@ private:
|
|||
}
|
||||
void visit(AstAlwaysPostponed* nodep) override {
|
||||
UINFO(4, " ALW " << nodep << endl);
|
||||
if (!nodep->bodysp()) {
|
||||
if (!nodep->stmtsp()) {
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ private:
|
|||
if (!m_monitorNumVarp) {
|
||||
m_monitorNumVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorNum",
|
||||
nodep->findUInt64DType()};
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(m_monitorNumVarp);
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(m_monitorNumVarp);
|
||||
}
|
||||
const auto varrefp = new AstVarRef(nodep->fileline(), m_monitorNumVarp, access);
|
||||
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
|
||||
|
|
@ -80,7 +80,7 @@ private:
|
|||
if (!m_monitorOffVarp) {
|
||||
m_monitorOffVarp = new AstVar{nodep->fileline(), VVarType::MODULETEMP, "__VmonitorOff",
|
||||
nodep->findBitDType()};
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(m_monitorOffVarp);
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(m_monitorOffVarp);
|
||||
}
|
||||
const auto varrefp = new AstVarRef(nodep->fileline(), m_monitorOffVarp, access);
|
||||
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
|
||||
|
|
@ -147,7 +147,7 @@ private:
|
|||
selfDestruct = true;
|
||||
} else {
|
||||
// V3Coverage assigned us a bucket to increment.
|
||||
AstCoverInc* const covincp = VN_AS(snodep->coverincp(), CoverInc);
|
||||
AstCoverInc* const covincp = VN_AS(snodep->coverincsp(), CoverInc);
|
||||
UASSERT_OBJ(covincp, snodep, "Missing AstCoverInc under assertion");
|
||||
covincp->unlinkFrBackWithNext(); // next() might have AstAssign for trace
|
||||
if (message != "") covincp->declp()->comment(message);
|
||||
|
|
@ -209,7 +209,7 @@ private:
|
|||
iterateAndNextNull(ifp->condp());
|
||||
|
||||
// Recurse into the true case.
|
||||
iterateAndNextNull(ifp->ifsp());
|
||||
iterateAndNextNull(ifp->thensp());
|
||||
|
||||
// If the last else is not an else if, recurse into that too.
|
||||
if (ifp->elsesp() && !nextifp) { //
|
||||
|
|
@ -338,15 +338,15 @@ private:
|
|||
sentreep->unlinkFrBack();
|
||||
AstAlways* const alwaysp
|
||||
= new AstAlways(nodep->fileline(), VAlwaysKwd::ALWAYS, sentreep, nullptr);
|
||||
m_modp->addStmtp(alwaysp);
|
||||
m_modp->addStmtsp(alwaysp);
|
||||
for (uint32_t i = 0; i < ticks; ++i) {
|
||||
AstVar* const outvarp = new AstVar(
|
||||
nodep->fileline(), VVarType::MODULETEMP,
|
||||
"_Vpast_" + cvtToStr(m_modPastNum++) + "_" + cvtToStr(i), inp->dtypep());
|
||||
m_modp->addStmtp(outvarp);
|
||||
m_modp->addStmtsp(outvarp);
|
||||
AstNode* const assp = new AstAssignDly(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), outvarp, VAccess::WRITE), inp);
|
||||
alwaysp->addStmtp(assp);
|
||||
alwaysp->addStmtsp(assp);
|
||||
// if (debug() >= 9) assp->dumpTree(cout, "-ass: ");
|
||||
invarp = outvarp;
|
||||
inp = new AstVarRef(nodep->fileline(), invarp, VAccess::READ);
|
||||
|
|
@ -387,7 +387,7 @@ private:
|
|||
stmtsp};
|
||||
ifp->branchPred(VBranchPred::BP_UNLIKELY);
|
||||
AstNode* const newp = new AstAlwaysPostponed{fl, ifp};
|
||||
m_modp->addStmtp(newp);
|
||||
m_modp->addStmtsp(newp);
|
||||
} else if (nodep->displayType() == VDisplayType::DT_STROBE) {
|
||||
nodep->displayType(VDisplayType::DT_DISPLAY);
|
||||
// Need one-shot
|
||||
|
|
@ -395,7 +395,7 @@ private:
|
|||
const auto varp
|
||||
= new AstVar{fl, VVarType::MODULETEMP, "__Vstrobe" + cvtToStr(m_modStrobeNum++),
|
||||
nodep->findBitDType()};
|
||||
m_modp->addStmtp(varp);
|
||||
m_modp->addStmtsp(varp);
|
||||
// Where $strobe was we do "__Vstrobe = '1;"
|
||||
const auto newsetp = new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},
|
||||
new AstConst{fl, AstConst::BitTrue{}}};
|
||||
|
|
@ -407,7 +407,7 @@ private:
|
|||
AstNode* const newp = new AstAlwaysPostponed{fl, ifp};
|
||||
stmtsp->addNext(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},
|
||||
new AstConst{fl, AstConst::BitFalse{}}});
|
||||
m_modp->addStmtp(newp);
|
||||
m_modp->addStmtsp(newp);
|
||||
}
|
||||
}
|
||||
void visit(AstMonitorOff* nodep) override {
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ private:
|
|||
void visit(AstAlways* nodep) override {
|
||||
iterateAndNextNull(nodep->sensesp());
|
||||
if (nodep->sensesp()) m_seniAlwaysp = nodep->sensesp()->sensesp();
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
m_seniAlwaysp = nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ bool AstNode::sameGateTree(const AstNode* node2p) const {
|
|||
return sameTreeIter(this, node2p, true, true);
|
||||
}
|
||||
|
||||
void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); }
|
||||
int AstNodeArrayDType::left() const { return rangep()->leftConst(); }
|
||||
int AstNodeArrayDType::right() const { return rangep()->rightConst(); }
|
||||
int AstNodeArrayDType::hi() const { return rangep()->hiConst(); }
|
||||
|
|
@ -71,13 +70,13 @@ VNumRange AstNodeArrayDType::declRange() const { return VNumRange{left(), right(
|
|||
|
||||
AstRange::AstRange(FileLine* fl, int left, int right)
|
||||
: ASTGEN_SUPER_Range(fl) {
|
||||
setOp2p(new AstConst{fl, static_cast<uint32_t>(left)});
|
||||
setOp3p(new AstConst{fl, static_cast<uint32_t>(right)});
|
||||
leftp(new AstConst{fl, static_cast<uint32_t>(left)});
|
||||
rightp(new AstConst{fl, static_cast<uint32_t>(right)});
|
||||
}
|
||||
AstRange::AstRange(FileLine* fl, const VNumRange& range)
|
||||
: ASTGEN_SUPER_Range(fl) {
|
||||
setOp2p(new AstConst{fl, static_cast<uint32_t>(range.left())});
|
||||
setOp3p(new AstConst{fl, static_cast<uint32_t>(range.right())});
|
||||
leftp(new AstConst{fl, static_cast<uint32_t>(range.left())});
|
||||
rightp(new AstConst{fl, static_cast<uint32_t>(range.right())});
|
||||
}
|
||||
int AstRange::leftConst() const {
|
||||
AstConst* const constp = VN_CAST(leftp(), Const);
|
||||
|
|
@ -97,7 +96,7 @@ AstPin::AstPin(FileLine* fl, int pinNum, AstVarRef* varname, AstNode* exprp)
|
|||
: ASTGEN_SUPER_Pin(fl)
|
||||
, m_pinNum{pinNum}
|
||||
, m_name{varname->name()} {
|
||||
setNOp1p(exprp);
|
||||
this->exprp(exprp);
|
||||
}
|
||||
|
||||
AstDpiExportUpdated::AstDpiExportUpdated(FileLine* fl, AstVarScope* varScopep)
|
||||
|
|
@ -112,7 +111,7 @@ AstPackArrayDType::AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType
|
|||
: ASTGEN_SUPER_PackArrayDType(fl) {
|
||||
childDTypep(dtp); // Only for parser
|
||||
refDTypep(nullptr);
|
||||
setOp2p(rangep);
|
||||
this->rangep(rangep);
|
||||
dtypep(nullptr); // V3Width will resolve
|
||||
const int width = subDTypep()->width() * rangep->elementsConst();
|
||||
widthForce(width, width);
|
||||
|
|
@ -120,7 +119,7 @@ AstPackArrayDType::AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType
|
|||
AstPackArrayDType::AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep)
|
||||
: ASTGEN_SUPER_PackArrayDType(fl) {
|
||||
refDTypep(dtp);
|
||||
setOp2p(rangep);
|
||||
this->rangep(rangep);
|
||||
dtypep(this);
|
||||
const int width = subDTypep()->width() * rangep->elementsConst();
|
||||
widthForce(width, width);
|
||||
|
|
@ -141,20 +140,20 @@ bool AstActive::hasClocked() const { return m_sensesp->hasClocked(); }
|
|||
|
||||
AstElabDisplay::AstElabDisplay(FileLine* fl, VDisplayType dispType, AstNode* exprsp)
|
||||
: ASTGEN_SUPER_ElabDisplay(fl) {
|
||||
setOp1p(new AstSFormatF{fl, AstSFormatF::NoFormat(), exprsp});
|
||||
addFmtp(new AstSFormatF{fl, AstSFormatF::NoFormat(), exprsp});
|
||||
m_displayType = dispType;
|
||||
}
|
||||
|
||||
AstCStmt::AstCStmt(FileLine* fl, const string& textStmt)
|
||||
: ASTGEN_SUPER_CStmt(fl) {
|
||||
addNOp1p(new AstText{fl, textStmt, true});
|
||||
addExprsp(new AstText{fl, textStmt, true});
|
||||
}
|
||||
|
||||
AstCMath::AstCMath(FileLine* fl, const string& textStmt, int setwidth, bool cleanOut)
|
||||
: ASTGEN_SUPER_CMath(fl)
|
||||
, m_cleanOut{cleanOut}
|
||||
, m_pure{true} {
|
||||
addNOp1p(new AstText{fl, textStmt, true});
|
||||
addExprsp(new AstText{fl, textStmt, true});
|
||||
if (setwidth) dtypeSetLogicSized(setwidth, VSigning::UNSIGNED);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -132,11 +132,13 @@ private:
|
|||
};
|
||||
class AstNodeArrayDType VL_NOT_FINAL : public AstNodeDType {
|
||||
// Array data type, ie "some_dtype var_name [2:0]"
|
||||
// Children: DTYPE (moved to refDTypep() in V3Width)
|
||||
// Children: RANGE (array bounds)
|
||||
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
||||
// @astgen op2 := rangep : Optional[AstRange] // array bounds
|
||||
private:
|
||||
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
|
||||
AstNode* rangenp() const { return op2p(); } // op2 = Array(s) of variable
|
||||
|
||||
AstNode* rangenp() const { return reinterpret_cast<AstNode*>(rangep()); }
|
||||
|
||||
protected:
|
||||
AstNodeArrayDType(VNType t, FileLine* fl)
|
||||
: AstNodeDType{t, fl} {}
|
||||
|
|
@ -165,14 +167,10 @@ public:
|
|||
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
|
||||
}
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
||||
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
||||
AstRange* rangep() const { return VN_AS(op2p(), Range); } // op2 = Array(s) of variable
|
||||
inline void rangep(AstRange* nodep);
|
||||
// METHODS
|
||||
AstBasicDType* basicp() const override {
|
||||
return subDTypep()->basicp();
|
||||
|
|
@ -193,6 +191,7 @@ public:
|
|||
};
|
||||
class AstNodeUOrStructDType VL_NOT_FINAL : public AstNodeDType {
|
||||
// A struct or union; common handling
|
||||
// @astgen op1 := membersp : List[AstMemberDType]
|
||||
private:
|
||||
// TYPES
|
||||
using MemberNameMap = std::map<const std::string, AstMemberDType*>;
|
||||
|
|
@ -233,16 +232,11 @@ public:
|
|||
int widthAlignBytes() const override;
|
||||
// (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
||||
int widthTotalBytes() const override;
|
||||
// op1 = members
|
||||
bool similarDType(AstNodeDType* samep) const override {
|
||||
return this == samep; // We don't compare members, require exact equivalence
|
||||
}
|
||||
string name() const override { return m_name; }
|
||||
void name(const string& flag) override { m_name = flag; }
|
||||
AstMemberDType* membersp() const {
|
||||
return VN_AS(op1p(), MemberDType);
|
||||
} // op1 = AstMember list
|
||||
void addMembersp(AstNode* nodep) { addNOp1p(nodep); }
|
||||
bool packed() const { return m_packed; }
|
||||
// packed() but as don't support unpacked, presently all structs
|
||||
static bool packedUnsup() { return true; }
|
||||
|
|
@ -263,33 +257,31 @@ public:
|
|||
|
||||
// === AstNode ===
|
||||
class AstEnumItem final : public AstNode {
|
||||
// @astgen op1 := rangep : Optional[AstRange] // Range for name appending
|
||||
// @astgen op2 := valuep : Optional[AstNode]
|
||||
private:
|
||||
string m_name;
|
||||
|
||||
public:
|
||||
// Parents: ENUM
|
||||
AstEnumItem(FileLine* fl, const string& name, AstNode* rangep, AstNode* initp)
|
||||
AstEnumItem(FileLine* fl, const string& name, AstRange* rangep, AstNode* valuep)
|
||||
: ASTGEN_SUPER_EnumItem(fl)
|
||||
, m_name{name} {
|
||||
addNOp1p(rangep);
|
||||
addNOp2p(initp);
|
||||
this->rangep(rangep);
|
||||
this->valuep(valuep);
|
||||
}
|
||||
ASTGEN_MEMBERS_EnumItem;
|
||||
string name() const override { return m_name; }
|
||||
bool maybePointedTo() const override { return true; }
|
||||
bool hasDType() const override { return true; }
|
||||
void name(const string& flag) override { m_name = flag; }
|
||||
AstRange* rangep() const { return VN_AS(op1p(), Range); } // op1 = Range for name appending
|
||||
void rangep(AstRange* nodep) { addOp1p((AstNode*)nodep); }
|
||||
AstNode* valuep() const { return op2p(); } // op2 = Value
|
||||
void valuep(AstNode* nodep) { addOp2p(nodep); }
|
||||
};
|
||||
|
||||
// === AstNodeDType ===
|
||||
class AstAssocArrayDType final : public AstNodeDType {
|
||||
// Associative array data type, ie "[some_dtype]"
|
||||
// Children: DTYPE (moved to refDTypep() in V3Width)
|
||||
// Children: DTYPE (the key, which remains here as a pointer)
|
||||
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
||||
// @astgen op2 := keyChildDTypep : AstNodeDType // the key, which remains here as a pointer
|
||||
private:
|
||||
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
|
||||
AstNodeDType* m_keyDTypep; // Keys of this type (after widthing)
|
||||
|
|
@ -335,9 +327,6 @@ public:
|
|||
void dumpSmall(std::ostream& str) const override;
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
AstNodeDType* getChild2DTypep() const override { return keyChildDTypep(); }
|
||||
// op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
||||
|
|
@ -347,9 +336,6 @@ public:
|
|||
//
|
||||
AstNodeDType* keyDTypep() const { return m_keyDTypep ? m_keyDTypep : keyChildDTypep(); }
|
||||
void keyDTypep(AstNodeDType* nodep) { m_keyDTypep = nodep; }
|
||||
// op1 = Range of variable
|
||||
AstNodeDType* keyChildDTypep() const { return VN_AS(op2p(), NodeDType); }
|
||||
void keyChildDTypep(AstNodeDType* nodep) { setOp2p(nodep); }
|
||||
// METHODS
|
||||
AstBasicDType* basicp() const override { return nullptr; }
|
||||
AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
||||
|
|
@ -361,7 +347,7 @@ public:
|
|||
};
|
||||
class AstBasicDType final : public AstNodeDType {
|
||||
// Builtin atomic/vectored data type
|
||||
// Children: RANGE (converted to constant in V3Width)
|
||||
// @astgen op1 := rangep : Optional[AstRange] // Range of variable
|
||||
private:
|
||||
struct Members {
|
||||
VBasicDTypeKwd m_keyword; // (also in VBasicTypeKey) What keyword created basic type
|
||||
|
|
@ -415,8 +401,6 @@ public:
|
|||
BROKEN_RTN(dtypep() != this);
|
||||
return nullptr;
|
||||
}
|
||||
AstRange* rangep() const { return VN_AS(op1p(), Range); } // op1 = Range of variable
|
||||
void rangep(AstRange* nodep) { setNOp1p((AstNode*)nodep); }
|
||||
void setSignedState(const VSigning& signst) {
|
||||
// Note NOSIGN does NOT change the state; this is required by the parser
|
||||
if (signst == VSigning::UNSIGNED) {
|
||||
|
|
@ -470,21 +454,18 @@ public:
|
|||
class AstBracketArrayDType final : public AstNodeDType {
|
||||
// Associative/Queue/Normal array data type, ie "[dtype_or_expr]"
|
||||
// only for early parsing then becomes another data type
|
||||
// Children: DTYPE (moved to refDTypep() in V3Width)
|
||||
// Children: DTYPE (the key)
|
||||
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
||||
// @astgen op2 := elementsp : AstNode // ??? key dtype ???
|
||||
public:
|
||||
AstBracketArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* elementsp)
|
||||
AstBracketArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* childDTypep,
|
||||
AstNode* elementsp)
|
||||
: ASTGEN_SUPER_BracketArrayDType(fl) {
|
||||
setOp1p(dtp); // Only for parser
|
||||
setOp2p(elementsp); // Only for parser
|
||||
this->childDTypep(childDTypep);
|
||||
this->elementsp(elementsp);
|
||||
}
|
||||
ASTGEN_MEMBERS_BracketArrayDType;
|
||||
bool similarDType(AstNodeDType* samep) const override { V3ERROR_NA_RETURN(false); }
|
||||
// op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
||||
AstNodeDType* subDTypep() const override { return childDTypep(); }
|
||||
// op2 = Range of variable
|
||||
AstNode* elementsp() const { return op2p(); }
|
||||
// METHODS
|
||||
// Will be removed in V3Width, which relies on this
|
||||
// being a child not a dtype pointed node
|
||||
|
|
@ -499,16 +480,16 @@ public:
|
|||
};
|
||||
class AstClassRefDType final : public AstNodeDType {
|
||||
// Reference to a class
|
||||
// Children: PINs (for parameter settings)
|
||||
// @astgen op1 := paramsp: List[AstPin]
|
||||
private:
|
||||
AstClass* m_classp; // data type pointed to, BELOW the AstTypedef
|
||||
AstNodeModule* m_classOrPackagep = nullptr; // Package hierarchy
|
||||
public:
|
||||
AstClassRefDType(FileLine* fl, AstClass* classp, AstNode* paramsp)
|
||||
AstClassRefDType(FileLine* fl, AstClass* classp, AstPin* paramsp)
|
||||
: ASTGEN_SUPER_ClassRefDType(fl)
|
||||
, m_classp{classp} {
|
||||
dtypep(this);
|
||||
addNOp4p(paramsp);
|
||||
this->dtypep(this);
|
||||
this->addParamsp(paramsp);
|
||||
}
|
||||
ASTGEN_MEMBERS_ClassRefDType;
|
||||
// METHODS
|
||||
|
|
@ -537,13 +518,13 @@ public:
|
|||
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
|
||||
AstClass* classp() const { return m_classp; }
|
||||
void classp(AstClass* nodep) { m_classp = nodep; }
|
||||
AstPin* paramsp() const { return VN_AS(op4p(), Pin); }
|
||||
bool isCompound() const override { return true; }
|
||||
};
|
||||
class AstConstDType final : public AstNodeDType {
|
||||
// const data type, ie "const some_dtype var_name [2:0]"
|
||||
// ConstDType are removed in V3LinkLValue and become AstVar::isConst.
|
||||
// When more generic types are supported AstConstDType will be propagated further.
|
||||
// @astgen op1 := childDTypep : Optional[AstNodeDType]
|
||||
private:
|
||||
AstNodeDType* m_refDTypep = nullptr; // Inherit from this base data type
|
||||
public:
|
||||
|
|
@ -571,9 +552,6 @@ public:
|
|||
return skipRefp()->similarDType(samep->skipRefp());
|
||||
}
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
// op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
||||
|
|
@ -594,6 +572,7 @@ class AstDefImplicitDType final : public AstNodeDType {
|
|||
// For parsing enum/struct/unions that are declared with a variable rather than typedef
|
||||
// This allows "var enum {...} a,b" to share the enum definition for both variables
|
||||
// After link, these become typedefs
|
||||
// @astgen op1 := childDTypep : Optional[AstNodeDType]
|
||||
private:
|
||||
string m_name;
|
||||
void* m_containerp; // In what scope is the name unique, so we can know what are duplicate
|
||||
|
|
@ -620,9 +599,6 @@ public:
|
|||
return type() == samep->type() && same(samep);
|
||||
}
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
// op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const override { return dtypep() ? dtypep() : childDTypep(); }
|
||||
void* containerp() const { return m_containerp; }
|
||||
// METHODS
|
||||
|
|
@ -640,7 +616,7 @@ public:
|
|||
};
|
||||
class AstDynArrayDType final : public AstNodeDType {
|
||||
// Dynamic array data type, ie "[]"
|
||||
// Children: DTYPE (moved to refDTypep() in V3Width)
|
||||
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
||||
private:
|
||||
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
|
||||
public:
|
||||
|
|
@ -677,9 +653,6 @@ public:
|
|||
string prettyDTypeName() const override;
|
||||
void dumpSmall(std::ostream& str) const override;
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
// op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
||||
|
|
@ -722,19 +695,20 @@ public:
|
|||
};
|
||||
class AstEnumDType final : public AstNodeDType {
|
||||
// Parents: TYPEDEF/MODULE
|
||||
// Children: ENUMVALUEs
|
||||
// @astgen op1 := childDTypep : Optional[AstNodeDType]
|
||||
// @astgen op2 := itemsp : List[AstEnumItem]
|
||||
private:
|
||||
string m_name; // Name from upper typedef, if any
|
||||
AstNodeDType* m_refDTypep = nullptr; // Elements are of this type after V3Width
|
||||
const int m_uniqueNum = 0;
|
||||
|
||||
public:
|
||||
AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* itemsp)
|
||||
AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstEnumItem* itemsp)
|
||||
: ASTGEN_SUPER_EnumDType(fl)
|
||||
, m_uniqueNum{uniqueNumInc()} {
|
||||
childDTypep(dtp); // Only for parser
|
||||
refDTypep(nullptr);
|
||||
addNOp2p(itemsp);
|
||||
addItemsp(itemsp);
|
||||
dtypep(nullptr); // V3Width will resolve
|
||||
widthFromSub(subDTypep());
|
||||
}
|
||||
|
|
@ -754,16 +728,12 @@ public:
|
|||
}
|
||||
bool similarDType(AstNodeDType* samep) const override { return this == samep; }
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } // op1 = Data type
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
// op1 = Range of variable
|
||||
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
||||
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
||||
string name() const override { return m_name; }
|
||||
void name(const string& flag) override { m_name = flag; }
|
||||
AstEnumItem* itemsp() const { return VN_AS(op2p(), EnumItem); } // op2 = AstEnumItem's
|
||||
// METHODS
|
||||
AstBasicDType* basicp() const override { return subDTypep()->basicp(); }
|
||||
AstNodeDType* skipRefp() const override { return subDTypep()->skipRefp(); }
|
||||
|
|
@ -835,6 +805,7 @@ public:
|
|||
class AstMemberDType final : public AstNodeDType {
|
||||
// A member of a struct/union
|
||||
// PARENT: AstNodeUOrStructDType
|
||||
// @astgen op1 := childDTypep : Optional[AstNodeDType]
|
||||
private:
|
||||
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
|
||||
string m_name; // Name of variable
|
||||
|
|
@ -869,9 +840,6 @@ public:
|
|||
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
||||
}
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
// op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
||||
|
|
@ -904,6 +872,7 @@ public:
|
|||
class AstParamTypeDType final : public AstNodeDType {
|
||||
// Parents: MODULE
|
||||
// A parameter type statement; much like a var or typedef
|
||||
// @astgen op1 := childDTypep : Optional[AstNodeDType]
|
||||
private:
|
||||
const VVarType m_varType; // Type of variable (for localparam vs. param)
|
||||
string m_name; // Name of variable
|
||||
|
|
@ -918,9 +887,6 @@ public:
|
|||
}
|
||||
ASTGEN_MEMBERS_ParamTypeDType;
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
// op1 = Type assigning to
|
||||
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const override { return dtypep() ? dtypep() : childDTypep(); }
|
||||
AstBasicDType* basicp() const override { return subDTypep()->basicp(); }
|
||||
AstNodeDType* skipRefp() const override { return subDTypep()->skipRefp(); }
|
||||
|
|
@ -972,20 +938,21 @@ public:
|
|||
};
|
||||
class AstQueueDType final : public AstNodeDType {
|
||||
// Queue array data type, ie "[ $ ]"
|
||||
// Children: DTYPE (moved to refDTypep() in V3Width)
|
||||
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
||||
// @astgen op2 := boundp : Optional[AstNode]
|
||||
private:
|
||||
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
|
||||
public:
|
||||
AstQueueDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* boundp)
|
||||
: ASTGEN_SUPER_QueueDType(fl) {
|
||||
setNOp2p(boundp);
|
||||
childDTypep(dtp); // Only for parser
|
||||
this->childDTypep(dtp);
|
||||
this->boundp(boundp);
|
||||
refDTypep(nullptr);
|
||||
dtypep(nullptr); // V3Width will resolve
|
||||
}
|
||||
AstQueueDType(FileLine* fl, AstNodeDType* dtp, AstNode* boundp)
|
||||
: ASTGEN_SUPER_QueueDType(fl) {
|
||||
setNOp2p(boundp);
|
||||
this->boundp(boundp);
|
||||
refDTypep(dtp);
|
||||
dtypep(dtp);
|
||||
}
|
||||
|
|
@ -1011,13 +978,8 @@ public:
|
|||
void dumpSmall(std::ostream& str) const override;
|
||||
string prettyDTypeName() const override;
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
// op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
AstNode* boundp() const { return op2p(); } // op2 = Bound, nullptr = none
|
||||
void boundp(AstNode* nodep) { setNOp2p(nodep); }
|
||||
inline int boundConst() const;
|
||||
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
||||
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
||||
|
|
@ -1034,6 +996,9 @@ public:
|
|||
bool isCompound() const override { return true; }
|
||||
};
|
||||
class AstRefDType final : public AstNodeDType {
|
||||
// @astgen op1 := typeofp : AstNode
|
||||
// @astgen op2 := classOrPackageOpp : Optional[AstNode]
|
||||
// @astgen op3 := paramsp : List[AstPin]
|
||||
private:
|
||||
// Pre-Width must reference the Typeref, not what it points to, as some child
|
||||
// types like AstBracketArrayType will disappear and can't lose the handle
|
||||
|
|
@ -1046,16 +1011,16 @@ public:
|
|||
AstRefDType(FileLine* fl, const string& name)
|
||||
: ASTGEN_SUPER_RefDType(fl)
|
||||
, m_name{name} {}
|
||||
AstRefDType(FileLine* fl, const string& name, AstNode* classOrPackagep, AstNode* paramsp)
|
||||
AstRefDType(FileLine* fl, const string& name, AstNode* classOrPackagep, AstPin* paramsp)
|
||||
: ASTGEN_SUPER_RefDType(fl)
|
||||
, m_name{name} {
|
||||
setNOp3p(classOrPackagep);
|
||||
addNOp4p(paramsp);
|
||||
this->classOrPackageOpp(classOrPackagep);
|
||||
addParamsp(paramsp);
|
||||
}
|
||||
class FlagTypeOfExpr {}; // type(expr) for parser only
|
||||
AstRefDType(FileLine* fl, FlagTypeOfExpr, AstNode* typeofp)
|
||||
: ASTGEN_SUPER_RefDType(fl) {
|
||||
setOp2p(typeofp);
|
||||
this->typeofp(typeofp);
|
||||
}
|
||||
ASTGEN_MEMBERS_RefDType;
|
||||
// METHODS
|
||||
|
|
@ -1106,7 +1071,6 @@ public:
|
|||
int widthAlignBytes() const override { return dtypeSkipRefp()->widthAlignBytes(); }
|
||||
int widthTotalBytes() const override { return dtypeSkipRefp()->widthTotalBytes(); }
|
||||
void name(const string& flag) override { m_name = flag; }
|
||||
// op1 = Range of variable
|
||||
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); }
|
||||
AstTypedef* typedefp() const { return m_typedefp; }
|
||||
void typedefp(AstTypedef* nodep) { m_typedefp = nodep; }
|
||||
|
|
@ -1116,9 +1080,6 @@ public:
|
|||
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
||||
AstNodeModule* classOrPackagep() const { return m_classOrPackagep; }
|
||||
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
|
||||
AstNode* typeofp() const { return op2p(); }
|
||||
AstNode* classOrPackageOpp() const { return op3p(); }
|
||||
AstPin* paramsp() const { return VN_AS(op4p(), Pin); }
|
||||
bool isCompound() const override {
|
||||
v3fatalSrc("call isCompound on subdata type, not reference");
|
||||
return false;
|
||||
|
|
@ -1126,7 +1087,7 @@ public:
|
|||
};
|
||||
class AstUnsizedArrayDType final : public AstNodeDType {
|
||||
// Unsized/open-range Array data type, ie "some_dtype var_name []"
|
||||
// Children: DTYPE (moved to refDTypep() in V3Width)
|
||||
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
||||
private:
|
||||
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
|
||||
public:
|
||||
|
|
@ -1149,9 +1110,6 @@ public:
|
|||
bool similarDType(AstNodeDType* samep) const override;
|
||||
void dumpSmall(std::ostream& str) const override;
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
// op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
||||
|
|
@ -1194,7 +1152,7 @@ public:
|
|||
};
|
||||
class AstWildcardArrayDType final : public AstNodeDType {
|
||||
// Wildcard index type associative array data type, ie "some_dtype var_name [*]"
|
||||
// Children: DTYPE (moved to refDTypep() in V3Width)
|
||||
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
||||
private:
|
||||
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
|
||||
public:
|
||||
|
|
@ -1217,9 +1175,6 @@ public:
|
|||
bool similarDType(AstNodeDType* samep) const override;
|
||||
void dumpSmall(std::ostream& str) const override;
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
// op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const override { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
||||
|
|
@ -1237,8 +1192,6 @@ public:
|
|||
// === AstNodeArrayDType ===
|
||||
class AstPackArrayDType final : public AstNodeArrayDType {
|
||||
// Packed array data type, ie "some_dtype [2:0] var_name"
|
||||
// Children: DTYPE (moved to refDTypep() in V3Width)
|
||||
// Children: RANGE (array bounds)
|
||||
public:
|
||||
inline AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep);
|
||||
inline AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep);
|
||||
|
|
@ -1248,15 +1201,13 @@ public:
|
|||
};
|
||||
class AstUnpackArrayDType final : public AstNodeArrayDType {
|
||||
// Array data type, ie "some_dtype var_name [2:0]"
|
||||
// Children: DTYPE (moved to refDTypep() in V3Width)
|
||||
// Children: RANGE (array bounds)
|
||||
bool m_isCompound = false; // Non-POD subDType, or parent requires compound
|
||||
public:
|
||||
AstUnpackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep)
|
||||
: ASTGEN_SUPER_UnpackArrayDType(fl) {
|
||||
childDTypep(dtp); // Only for parser
|
||||
this->childDTypep(dtp); // Only for parser
|
||||
this->rangep(rangep);
|
||||
refDTypep(nullptr);
|
||||
setOp2p((AstNode*)rangep);
|
||||
dtypep(nullptr); // V3Width will resolve
|
||||
// For backward compatibility AstNodeArrayDType and others inherit
|
||||
// width and signing from the subDType/base type
|
||||
|
|
@ -1264,8 +1215,8 @@ public:
|
|||
}
|
||||
AstUnpackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep)
|
||||
: ASTGEN_SUPER_UnpackArrayDType(fl) {
|
||||
this->rangep(rangep);
|
||||
refDTypep(dtp);
|
||||
setOp2p((AstNode*)rangep);
|
||||
dtypep(this);
|
||||
// For backward compatibility AstNodeArrayDType and others inherit
|
||||
// width and signing from the subDType/base type
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
1057
src/V3AstNodeOther.h
1057
src/V3AstNodeOther.h
File diff suppressed because it is too large
Load Diff
|
|
@ -188,8 +188,8 @@ void AstBasicDType::init(VBasicDTypeKwd kwd, VSigning numer, int wantwidth, int
|
|||
widthForce(rangep->elementsConst(),
|
||||
rangep->elementsConst()); // Maybe unknown if parameters underneath it
|
||||
}
|
||||
setNOp1p(rangep);
|
||||
dtypep(this);
|
||||
this->rangep(rangep);
|
||||
this->dtypep(this);
|
||||
}
|
||||
|
||||
void AstBasicDType::cvtRangeConst() {
|
||||
|
|
@ -660,25 +660,15 @@ AstVar* AstVar::scVarRecurse(AstNode* nodep) {
|
|||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
} else if (VN_IS(nodep, VarRef)) {
|
||||
if (VN_AS(nodep, VarRef)->varp()->isSc()) {
|
||||
return VN_AS(nodep, VarRef)->varp();
|
||||
} else if (AstVarRef* const vrefp = VN_CAST(nodep, VarRef)) {
|
||||
if (vrefp->varp()->isSc()) {
|
||||
return vrefp->varp();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
} else if (VN_IS(nodep, ArraySel)) {
|
||||
if (nodep->op1p()) {
|
||||
if (AstVar* p = scVarRecurse(nodep->op1p())) return p;
|
||||
}
|
||||
if (nodep->op2p()) {
|
||||
if (AstVar* p = scVarRecurse(nodep->op2p())) return p;
|
||||
}
|
||||
if (nodep->op3p()) {
|
||||
if (AstVar* p = scVarRecurse(nodep->op3p())) return p;
|
||||
}
|
||||
if (nodep->op4p()) {
|
||||
if (AstVar* p = scVarRecurse(nodep->op4p())) return p;
|
||||
}
|
||||
} else if (AstArraySel* const arraySelp = VN_CAST(nodep, ArraySel)) {
|
||||
if (AstVar* const p = scVarRecurse(arraySelp->fromp())) return p;
|
||||
if (AstVar* const p = scVarRecurse(arraySelp->bitp())) return p;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -1070,8 +1060,8 @@ AstConstPool::AstConstPool(FileLine* fl)
|
|||
: ASTGEN_SUPER_ConstPool(fl)
|
||||
, m_modp{new AstModule(fl, "@CONST-POOL@")}
|
||||
, m_scopep{new AstScope(fl, m_modp, "@CONST-POOL@", nullptr, nullptr)} {
|
||||
addOp1p(m_modp);
|
||||
m_modp->addStmtp(m_scopep);
|
||||
this->modulep(m_modp);
|
||||
m_modp->addStmtsp(m_scopep);
|
||||
}
|
||||
const char* AstConstPool::broken() const {
|
||||
BROKEN_RTN(m_modp && !m_modp->brokeExists());
|
||||
|
|
@ -1085,9 +1075,9 @@ AstVarScope* AstConstPool::createNewEntry(const string& name, AstNode* initp) {
|
|||
varp->isConst(true);
|
||||
varp->isStatic(true);
|
||||
varp->valuep(initp->cloneTree(false));
|
||||
m_modp->addStmtp(varp);
|
||||
m_modp->addStmtsp(varp);
|
||||
AstVarScope* const varScopep = new AstVarScope(fl, m_scopep, varp);
|
||||
m_scopep->addVarp(varScopep);
|
||||
m_scopep->addVarsp(varScopep);
|
||||
return varScopep;
|
||||
}
|
||||
|
||||
|
|
@ -1233,7 +1223,7 @@ void AstWhile::addBeforeStmt(AstNode* newp, AstNode* belowp) {
|
|||
} else if (belowp == condp()) {
|
||||
// Goes before condition, IE in preconditions
|
||||
addPrecondsp(newp);
|
||||
} else if (belowp == bodysp()) {
|
||||
} else if (belowp == stmtsp()) {
|
||||
// Was first statement in body, so new front
|
||||
belowp->addHereThisAsNext(newp);
|
||||
} else {
|
||||
|
|
@ -1250,12 +1240,12 @@ void AstWhile::addNextStmt(AstNode* newp, AstNode* belowp) {
|
|||
belowp->addNextHere(newp);
|
||||
} else if (belowp == condp()) {
|
||||
// Becomes first statement in body, body may have been empty
|
||||
if (bodysp()) {
|
||||
bodysp()->addHereThisAsNext(newp);
|
||||
if (stmtsp()) {
|
||||
stmtsp()->addHereThisAsNext(newp);
|
||||
} else {
|
||||
addBodysp(newp);
|
||||
addStmtsp(newp);
|
||||
}
|
||||
} else if (belowp == bodysp()) {
|
||||
} else if (belowp == stmtsp()) {
|
||||
// Next statement in body
|
||||
belowp->addNextHere(newp);
|
||||
} else {
|
||||
|
|
@ -1521,19 +1511,15 @@ void AstInitArray::cloneRelink() {
|
|||
if (it->second->clonep()) it->second = it->second->clonep();
|
||||
}
|
||||
}
|
||||
AstNode* AstInitArray::addIndexValuep(uint64_t index, AstNode* newp) {
|
||||
// Returns old value, caller must garbage collect
|
||||
AstNode* oldp = nullptr;
|
||||
void AstInitArray::addIndexValuep(uint64_t index, AstNode* newp) {
|
||||
const auto it = m_map.find(index);
|
||||
if (it != m_map.end()) {
|
||||
oldp = it->second->valuep();
|
||||
it->second->valuep(newp);
|
||||
} else {
|
||||
AstInitItem* const itemp = new AstInitItem(fileline(), newp);
|
||||
m_map.emplace(index, itemp);
|
||||
addOp2p(itemp);
|
||||
addInitsp(itemp);
|
||||
}
|
||||
return oldp;
|
||||
}
|
||||
AstNode* AstInitArray::getIndexValuep(uint64_t index) const {
|
||||
const auto it = m_map.find(index);
|
||||
|
|
@ -1808,7 +1794,7 @@ AstPackage* AstNetlist::dollarUnitPkgAddp() {
|
|||
m_dollarUnitPkgp->inLibrary(true);
|
||||
m_dollarUnitPkgp->modTrace(false); // may reconsider later
|
||||
m_dollarUnitPkgp->internal(true);
|
||||
addModulep(m_dollarUnitPkgp);
|
||||
addModulesp(m_dollarUnitPkgp);
|
||||
}
|
||||
return m_dollarUnitPkgp;
|
||||
}
|
||||
|
|
@ -1816,7 +1802,7 @@ void AstNetlist::createTopScope(AstScope* scopep) {
|
|||
UASSERT(scopep, "Must not be nullptr");
|
||||
UASSERT_OBJ(!m_topScopep, scopep, "TopScope already exits");
|
||||
m_topScopep = new AstTopScope{scopep->modp()->fileline(), scopep};
|
||||
scopep->modp()->addStmtp(v3Global.rootp()->topScopep());
|
||||
scopep->modp()->addStmtsp(v3Global.rootp()->topScopep());
|
||||
}
|
||||
void AstNodeModule::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ private:
|
|||
}
|
||||
} else {
|
||||
// Move to module
|
||||
m_modp->addStmtp(nodep);
|
||||
m_modp->addStmtsp(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ private:
|
|||
UINFO(8, " rename to " << nodep->name() << endl);
|
||||
// Move to module
|
||||
nodep->unlinkFrBack();
|
||||
m_modp->addStmtp(nodep);
|
||||
m_modp->addStmtsp(nodep);
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
|
@ -233,10 +233,10 @@ private:
|
|||
const string scname = nodep->forFormat() ? m_displayScope : m_namedScope;
|
||||
if (!scname.empty()) {
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstNode* const afterp = nodep->scopeAttrp();
|
||||
AstText* const afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeAttrp(new AstText{nodep->fileline(), string("__DOT__") + scname});
|
||||
if (afterp) nodep->scopeAttrp(afterp);
|
||||
nodep->addScopeAttrp(new AstText{nodep->fileline(), string("__DOT__") + scname});
|
||||
if (afterp) nodep->addScopeAttrp(afterp);
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ private:
|
|||
{
|
||||
// Do if
|
||||
reset();
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
iterateAndNextNull(nodep->thensp());
|
||||
const int ifLikely = m_likely;
|
||||
const int ifUnlikely = m_unlikely;
|
||||
// Do else
|
||||
|
|
|
|||
|
|
@ -275,9 +275,9 @@ private:
|
|||
pushLocalScope();
|
||||
processEnter(nodep);
|
||||
processAndIterate(nodep->condp());
|
||||
if (AstNode* const ifsp = nodep->ifsp()) {
|
||||
if (AstNode* const thensp = nodep->thensp()) {
|
||||
pushLocalScope();
|
||||
processAndIterateList(ifsp);
|
||||
processAndIterateList(thensp);
|
||||
popLocalScope();
|
||||
}
|
||||
if (AstNode* const elsesp = nodep->elsesp()) {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ private:
|
|||
if (!preventUnusedStmt.empty()) {
|
||||
funcp->addStmtsp(new AstCStmt{m_modp->fileline(), preventUnusedStmt});
|
||||
}
|
||||
m_modp->addStmtp(funcp);
|
||||
m_modp->addStmtsp(funcp);
|
||||
m_numStmts = 0;
|
||||
return funcp;
|
||||
}
|
||||
|
|
@ -136,7 +136,7 @@ void V3CCtors::evalAsserts() {
|
|||
funcp->isLoose(true);
|
||||
funcp->slow(false);
|
||||
funcp->ifdef("VL_DEBUG");
|
||||
modp->addStmtp(funcp);
|
||||
modp->addStmtsp(funcp);
|
||||
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
|
||||
if (AstVar* const varp = VN_CAST(np, Var)) {
|
||||
if (varp->isPrimaryInish() && !varp->isSc()) {
|
||||
|
|
@ -209,7 +209,7 @@ void V3CCtors::cctorsAll() {
|
|||
// If can be referred to by base pointer, need virtual delete
|
||||
funcp->isVirtual(classp->isExtended());
|
||||
funcp->slow(false);
|
||||
modp->addStmtp(funcp);
|
||||
modp->addStmtsp(funcp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class CUseVisitor final : public VNVisitor {
|
|||
void addNewUse(AstNode* nodep, VUseType useType, const string& name) {
|
||||
if (m_didUse.emplace(useType, name).second) {
|
||||
AstCUse* const newp = new AstCUse{nodep->fileline(), useType, name};
|
||||
m_modp->addStmtp(newp);
|
||||
m_modp->addStmtsp(newp);
|
||||
UINFO(8, "Insert " << newp << endl);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ private:
|
|||
// Convert valueItem from AstCaseItem* to the expression
|
||||
// Not done earlier, as we may now have a nullptr because it's just a ";" NOP branch
|
||||
for (uint32_t i = 0; i < numCases; ++i) {
|
||||
m_valueItem[i] = VN_AS(m_valueItem[i], CaseItem)->bodysp();
|
||||
m_valueItem[i] = VN_AS(m_valueItem[i], CaseItem)->stmtsp();
|
||||
}
|
||||
return true; // All is fine
|
||||
}
|
||||
|
|
@ -346,7 +346,7 @@ private:
|
|||
itemp = VN_AS(itemp->nextp(), CaseItem)) {
|
||||
if (!itemp->condsp()) {
|
||||
// Default clause. Just make true, we'll optimize it away later
|
||||
itemp->condsp(new AstConst(itemp->fileline(), AstConst::BitTrue()));
|
||||
itemp->addCondsp(new AstConst(itemp->fileline(), AstConst::BitTrue()));
|
||||
hadDefault = true;
|
||||
} else {
|
||||
// Expressioned clause
|
||||
|
|
@ -397,7 +397,7 @@ private:
|
|||
}
|
||||
}
|
||||
// Replace expression in tree
|
||||
itemp->condsp(ifexprp);
|
||||
itemp->addCondsp(ifexprp);
|
||||
}
|
||||
}
|
||||
VL_DO_DANGLING(cexprp->deleteTree(), cexprp);
|
||||
|
|
@ -420,7 +420,7 @@ private:
|
|||
AstIf* itemnextp = nullptr;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp;
|
||||
itemp = VN_AS(itemp->nextp(), CaseItem)) {
|
||||
AstNode* const istmtsp = itemp->bodysp(); // Maybe null -- no action.
|
||||
AstNode* const istmtsp = itemp->stmtsp(); // Maybe null -- no action.
|
||||
if (istmtsp) istmtsp->unlinkFrBackWithNext();
|
||||
// Expressioned clause
|
||||
AstNode* const ifexprp = itemp->condsp()->unlinkFrBack();
|
||||
|
|
@ -452,7 +452,7 @@ private:
|
|||
if (itemnextp) {
|
||||
itemnextp->addElsesp(newp);
|
||||
} else {
|
||||
groupnextp->addIfsp(newp); // First in a new group
|
||||
groupnextp->addThensp(newp); // First in a new group
|
||||
}
|
||||
itemnextp = newp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public:
|
|||
m_tlChgFuncp->isStatic(false);
|
||||
m_tlChgFuncp->isLoose(true);
|
||||
m_tlChgFuncp->declPrivate(true);
|
||||
m_scopetopp->addActivep(m_tlChgFuncp);
|
||||
m_scopetopp->addBlocksp(m_tlChgFuncp);
|
||||
// Each change detection function needs at least one AstChangeDet
|
||||
// to ensure that V3EmitC outputs the necessary code.
|
||||
maybeCreateMidChg();
|
||||
|
|
@ -86,7 +86,7 @@ public:
|
|||
m_chgFuncp->isStatic(false);
|
||||
m_chgFuncp->isLoose(true);
|
||||
m_chgFuncp->declPrivate(true);
|
||||
m_scopetopp->addActivep(m_chgFuncp);
|
||||
m_scopetopp->addBlocksp(m_chgFuncp);
|
||||
|
||||
// Add a top call to it
|
||||
AstCCall* const callp = new AstCCall{m_scopetopp->fileline(), m_chgFuncp};
|
||||
|
|
@ -218,9 +218,9 @@ public:
|
|||
// CHANGEDET(VARREF(_last), VARREF(var))
|
||||
AstVar* const newvarp
|
||||
= new AstVar{varp->fileline(), VVarType::MODULETEMP, newvarname, varp};
|
||||
m_state.m_topModp->addStmtp(newvarp);
|
||||
m_state.m_topModp->addStmtsp(newvarp);
|
||||
m_newvscp = new AstVarScope{m_vscp->fileline(), m_state.m_scopetopp, newvarp};
|
||||
m_state.m_scopetopp->addVarp(m_newvscp);
|
||||
m_state.m_scopetopp->addVarsp(m_newvscp);
|
||||
|
||||
m_varEqnp = new AstVarRef{m_vscp->fileline(), m_vscp, VAccess::READ};
|
||||
m_newLvEqnp = new AstVarRef{m_vscp->fileline(), m_newvscp, VAccess::WRITE};
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ private:
|
|||
// Move this class
|
||||
nodep->name(m_prefix + nodep->name());
|
||||
nodep->unlinkFrBack();
|
||||
v3Global.rootp()->addModulep(nodep);
|
||||
v3Global.rootp()->addModulesp(nodep);
|
||||
// Make containing package
|
||||
// Note origName is the same as the class origName so errors look correct
|
||||
AstClassPackage* const packagep
|
||||
|
|
@ -62,7 +62,7 @@ private:
|
|||
packagep->name(nodep->name() + "__Vclpkg");
|
||||
nodep->classOrPackagep(packagep);
|
||||
packagep->classp(nodep);
|
||||
v3Global.rootp()->addModulep(packagep);
|
||||
v3Global.rootp()->addModulesp(packagep);
|
||||
// Add package to hierarchy
|
||||
AstCell* const cellp = new AstCell{packagep->fileline(),
|
||||
packagep->fileline(),
|
||||
|
|
@ -72,7 +72,7 @@ private:
|
|||
nullptr,
|
||||
nullptr};
|
||||
cellp->modp(packagep);
|
||||
v3Global.rootp()->topModulep()->addStmtp(cellp);
|
||||
v3Global.rootp()->topModulep()->addStmtsp(cellp);
|
||||
// Find class's scope
|
||||
// Alternative would be to move this and related to V3Scope
|
||||
const AstScope* classScopep = nullptr;
|
||||
|
|
@ -85,7 +85,7 @@ private:
|
|||
AstScope* const scopep
|
||||
= new AstScope{nodep->fileline(), packagep, classScopep->name(),
|
||||
classScopep->aboveScopep(), classScopep->aboveCellp()};
|
||||
packagep->addStmtp(scopep);
|
||||
packagep->addStmtsp(scopep);
|
||||
// Iterate
|
||||
VL_RESTORER(m_prefix);
|
||||
VL_RESTORER(m_classPackagep);
|
||||
|
|
@ -178,15 +178,15 @@ public:
|
|||
AstScope* const scopep = moved.second;
|
||||
UINFO(9, "moving " << nodep << " to " << scopep << endl);
|
||||
if (VN_IS(nodep, NodeFTask)) {
|
||||
scopep->addActivep(nodep->unlinkFrBack());
|
||||
scopep->addBlocksp(nodep->unlinkFrBack());
|
||||
} else if (VN_IS(nodep, Var)) {
|
||||
AstVarScope* const vscp = VN_AS(nodep->user1p(), VarScope);
|
||||
vscp->scopep(scopep);
|
||||
vscp->unlinkFrBack();
|
||||
scopep->addVarp(vscp);
|
||||
scopep->addVarsp(vscp);
|
||||
} else if (VN_IS(nodep, Initial) || VN_IS(nodep, InitialStatic)) {
|
||||
nodep->unlinkFrBack();
|
||||
scopep->addActivep(nodep);
|
||||
scopep->addBlocksp(nodep);
|
||||
} else {
|
||||
nodep->v3fatalSrc("Bad case");
|
||||
}
|
||||
|
|
@ -196,7 +196,7 @@ public:
|
|||
AstNodeModule* const modp = moved.second;
|
||||
UINFO(9, "moving " << nodep << " to " << modp << endl);
|
||||
nodep->unlinkFrBack();
|
||||
modp->addStmtp(nodep);
|
||||
modp->addStmtsp(nodep);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ private:
|
|||
setClean(nodep, false);
|
||||
// We always clean, as we don't trust those pesky users.
|
||||
if (!VN_IS(nodep->backp(), And)) insertClean(nodep);
|
||||
ensureCleanAndNext(nodep->bodysp());
|
||||
ensureCleanAndNext(nodep->exprsp());
|
||||
}
|
||||
void visit(AstTraceDecl* nodep) override {
|
||||
// No cleaning, or would loose pointer to enum
|
||||
|
|
@ -259,7 +259,7 @@ private:
|
|||
void visit(AstNodeCond* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureClean(nodep->condp());
|
||||
setClean(nodep, isClean(nodep->expr1p()) && isClean(nodep->expr2p()));
|
||||
setClean(nodep, isClean(nodep->thenp()) && isClean(nodep->elsep()));
|
||||
}
|
||||
void visit(AstWhile* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -276,7 +276,7 @@ private:
|
|||
}
|
||||
void visit(AstUCStmt* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureCleanAndNext(nodep->bodysp());
|
||||
ensureCleanAndNext(nodep->exprsp());
|
||||
}
|
||||
void visit(AstNodeCCall* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
|
|
|
|||
|
|
@ -102,10 +102,10 @@ private:
|
|||
AstVar* const newvarp = new AstVar(vscp->fileline(), VVarType::MODULETEMP, newvarname,
|
||||
VFlagLogicPacked{}, 1);
|
||||
newvarp->noReset(true); // Reset by below assign
|
||||
m_modp->addStmtp(newvarp);
|
||||
m_modp->addStmtsp(newvarp);
|
||||
AstVarScope* const newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
|
||||
vscp->user1p(newvscp);
|
||||
m_scopep->addVarp(newvscp);
|
||||
m_scopep->addVarsp(newvscp);
|
||||
// Add init
|
||||
AstNode* fromp = new AstVarRef(newvarp->fileline(), vscp, VAccess::READ);
|
||||
if (v3Global.opt.xInitialEdge()) fromp = new AstNot(fromp->fileline(), fromp);
|
||||
|
|
@ -202,7 +202,7 @@ private:
|
|||
funcp->slow(slow);
|
||||
funcp->isConst(false);
|
||||
funcp->declPrivate(true);
|
||||
m_topScopep->scopep()->addActivep(funcp);
|
||||
m_topScopep->scopep()->addBlocksp(funcp);
|
||||
return funcp;
|
||||
}
|
||||
void splitCheck(AstCFunc* ofuncp) {
|
||||
|
|
@ -229,7 +229,7 @@ private:
|
|||
funcp->isStatic(false);
|
||||
funcp->isLoose(true);
|
||||
funcp->slow(ofuncp->slow());
|
||||
m_topScopep->scopep()->addActivep(funcp);
|
||||
m_topScopep->scopep()->addBlocksp(funcp);
|
||||
//
|
||||
AstCCall* const callp = new AstCCall{funcp->fileline(), funcp};
|
||||
ofuncp->addStmtsp(callp);
|
||||
|
|
@ -297,7 +297,7 @@ private:
|
|||
m_scopep = nullptr;
|
||||
}
|
||||
void visit(AstNodeProcedure* nodep) override {
|
||||
if (AstNode* const stmtsp = nodep->bodysp()) {
|
||||
if (AstNode* const stmtsp = nodep->stmtsp()) {
|
||||
stmtsp->unlinkFrBackWithNext();
|
||||
nodep->addNextHere(stmtsp);
|
||||
}
|
||||
|
|
@ -316,7 +316,7 @@ private:
|
|||
// We could add another IF to detect posedges, and only increment if so.
|
||||
// It's another whole branch though versus a potential memory miss.
|
||||
// We'll go with the miss.
|
||||
newp->addIfsp(new AstAssign(nodep->fileline(), changeWrp, origp->cloneTree(false)));
|
||||
newp->addThensp(new AstAssign(nodep->fileline(), changeWrp, origp->cloneTree(false)));
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
|
|
@ -367,7 +367,7 @@ private:
|
|||
m_mtaskBodyp->addStmtsp(m_lastIfp);
|
||||
}
|
||||
// Move statements to if
|
||||
m_lastIfp->addIfsp(stmtsp);
|
||||
m_lastIfp->addThensp(stmtsp);
|
||||
} else if (nodep->hasInitial() || nodep->hasSettle()) {
|
||||
nodep->v3fatalSrc("MTask should not include initial/settle logic.");
|
||||
} else {
|
||||
|
|
@ -393,7 +393,7 @@ private:
|
|||
addToEvalLoop(m_lastIfp);
|
||||
}
|
||||
// Move statements to if
|
||||
m_lastIfp->addIfsp(stmtsp);
|
||||
m_lastIfp->addThensp(stmtsp);
|
||||
} else if (nodep->hasInitial()) {
|
||||
// Don't need to: clearLastSen();, as we're adding it to different cfunc
|
||||
// Move statements to function
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ static void makeVlToString(AstClass* nodep) {
|
|||
AstNode* const exprp = new AstCMath{nodep->fileline(), "obj ? obj->to_string() : \"null\"", 0};
|
||||
exprp->dtypeSetString();
|
||||
funcp->addStmtsp(new AstCReturn{nodep->fileline(), exprp});
|
||||
nodep->addStmtp(funcp);
|
||||
nodep->addStmtsp(funcp);
|
||||
}
|
||||
static void makeToString(AstClass* nodep) {
|
||||
AstCFunc* const funcp = new AstCFunc{nodep->fileline(), "to_string", nullptr, "std::string"};
|
||||
|
|
@ -54,7 +54,7 @@ static void makeToString(AstClass* nodep) {
|
|||
= new AstCMath{nodep->fileline(), R"(std::string{"'{"} + to_string_middle() + "}")", 0};
|
||||
exprp->dtypeSetString();
|
||||
funcp->addStmtsp(new AstCReturn{nodep->fileline(), exprp});
|
||||
nodep->addStmtp(funcp);
|
||||
nodep->addStmtsp(funcp);
|
||||
}
|
||||
static void makeToStringMiddle(AstClass* nodep) {
|
||||
AstCFunc* const funcp
|
||||
|
|
@ -96,7 +96,7 @@ static void makeToStringMiddle(AstClass* nodep) {
|
|||
funcp->addStmtsp(new AstCStmt{nodep->fileline(), stmt});
|
||||
}
|
||||
funcp->addStmtsp(new AstCStmt{nodep->fileline(), "return out;\n"});
|
||||
nodep->addStmtp(funcp);
|
||||
nodep->addStmtsp(funcp);
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -193,11 +193,11 @@ public:
|
|||
const VPragmaType type
|
||||
= m_inlineValue ? VPragmaType::INLINE_MODULE : VPragmaType::NO_INLINE_MODULE;
|
||||
AstNode* const nodep = new AstPragma(modp->fileline(), type);
|
||||
modp->addStmtp(nodep);
|
||||
modp->addStmtsp(nodep);
|
||||
}
|
||||
for (const auto& itr : m_modPragmas) {
|
||||
AstNode* const nodep = new AstPragma{modp->fileline(), itr};
|
||||
modp->addStmtp(nodep);
|
||||
modp->addStmtsp(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
105
src/V3Const.cpp
105
src/V3Const.cpp
|
|
@ -1042,20 +1042,19 @@ private:
|
|||
// as high as possible, which is usally the right choice, except for this.
|
||||
AstNodeCond* const condp = VN_CAST(nodep->rhsp(), NodeCond);
|
||||
if (!condp) return false;
|
||||
if (!VN_IS(condp->expr1p(), Const) && !VN_IS(condp->expr2p(), Const)) return false;
|
||||
if (!VN_IS(condp->thenp(), Const) && !VN_IS(condp->elsep(), Const)) return false;
|
||||
AstConst* const maskp = VN_CAST(nodep->lhsp(), Const);
|
||||
if (!maskp) return false;
|
||||
UINFO(4, "AND(CONSTm, CONDcond(c, i, e))->CONDcond(c, AND(m,i), AND(m, e)) " << nodep
|
||||
<< endl);
|
||||
AstNodeCond* const newp = static_cast<AstNodeCond*>(
|
||||
condp->cloneType(condp->condp()->unlinkFrBack(),
|
||||
new AstAnd(nodep->fileline(), maskp->cloneTree(false),
|
||||
condp->expr1p()->unlinkFrBack()),
|
||||
new AstAnd(nodep->fileline(), maskp->cloneTree(false),
|
||||
condp->expr2p()->unlinkFrBack())));
|
||||
AstNodeCond* const newp = static_cast<AstNodeCond*>(condp->cloneType(
|
||||
condp->condp()->unlinkFrBack(),
|
||||
new AstAnd(nodep->fileline(), maskp->cloneTree(false), condp->thenp()->unlinkFrBack()),
|
||||
new AstAnd(nodep->fileline(), maskp->cloneTree(false),
|
||||
condp->elsep()->unlinkFrBack())));
|
||||
newp->dtypeFrom(nodep);
|
||||
newp->expr1p()->dtypeFrom(nodep); // As And might have been to change widths
|
||||
newp->expr2p()->dtypeFrom(nodep);
|
||||
newp->thenp()->dtypeFrom(nodep); // As And might have been to change widths
|
||||
newp->elsep()->dtypeFrom(nodep);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
return true;
|
||||
|
|
@ -1443,19 +1442,19 @@ private:
|
|||
}
|
||||
}
|
||||
bool ifSameAssign(const AstNodeIf* nodep) {
|
||||
const AstNodeAssign* const ifp = VN_CAST(nodep->ifsp(), NodeAssign);
|
||||
const AstNodeAssign* const elsep = VN_CAST(nodep->elsesp(), NodeAssign);
|
||||
if (!ifp || ifp->nextp()) return false; // Must be SINGLE statement
|
||||
if (!elsep || elsep->nextp()) return false;
|
||||
if (ifp->type() != elsep->type()) return false; // Can't mix an assigndly and an assign
|
||||
if (!ifp->lhsp()->sameGateTree(elsep->lhsp())) return false;
|
||||
if (!ifp->rhsp()->gateTree()) return false;
|
||||
if (!elsep->rhsp()->gateTree()) return false;
|
||||
const AstNodeAssign* const thensp = VN_CAST(nodep->thensp(), NodeAssign);
|
||||
const AstNodeAssign* const elsesp = VN_CAST(nodep->elsesp(), NodeAssign);
|
||||
if (!thensp || thensp->nextp()) return false; // Must be SINGLE statement
|
||||
if (!elsesp || elsesp->nextp()) return false;
|
||||
if (thensp->type() != elsesp->type()) return false; // Can't mix an assigndly with assign
|
||||
if (!thensp->lhsp()->sameGateTree(elsesp->lhsp())) return false;
|
||||
if (!thensp->rhsp()->gateTree()) return false;
|
||||
if (!elsesp->rhsp()->gateTree()) return false;
|
||||
return true;
|
||||
}
|
||||
bool operandIfIf(const AstNodeIf* nodep) {
|
||||
if (nodep->elsesp()) return false;
|
||||
const AstNodeIf* const lowerIfp = VN_CAST(nodep->ifsp(), NodeIf);
|
||||
const AstNodeIf* const lowerIfp = VN_CAST(nodep->thensp(), NodeIf);
|
||||
if (!lowerIfp || lowerIfp->nextp()) return false;
|
||||
if (nodep->type() != lowerIfp->type()) return false;
|
||||
if (afterComment(lowerIfp->elsesp())) return false;
|
||||
|
|
@ -2097,8 +2096,8 @@ private:
|
|||
AstVar* const temp2p
|
||||
= new AstVar(sel2p->fileline(), VVarType::BLOCKTEMP,
|
||||
m_concswapNames.get(sel2p), VFlagLogicPacked(), msb2 - lsb2 + 1);
|
||||
m_modp->addStmtp(temp1p);
|
||||
m_modp->addStmtp(temp2p);
|
||||
m_modp->addStmtsp(temp1p);
|
||||
m_modp->addStmtsp(temp2p);
|
||||
AstNodeAssign* const asn1ap
|
||||
= VN_AS(nodep->cloneType(
|
||||
new AstVarRef(sel1p->fileline(), temp1p, VAccess::WRITE), sel1p),
|
||||
|
|
@ -2862,7 +2861,7 @@ private:
|
|||
varrefp->unlinkFrBack();
|
||||
AstInitial* const newinitp = new AstInitial(
|
||||
nodep->fileline(), new AstAssign(nodep->fileline(), varrefp, exprp));
|
||||
m_modp->addStmtp(newinitp);
|
||||
m_modp->addStmtsp(newinitp);
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
// Set the initial value right in the variable so we can constant propagate
|
||||
AstNode* const initvaluep = exprp->cloneTree(false);
|
||||
|
|
@ -2892,7 +2891,7 @@ private:
|
|||
keepp = nodep->elsesp();
|
||||
} else if (!m_doV || constp->isNeqZero()) { // Might be X in Verilog
|
||||
UINFO(4, "IF(!0,{x},{any}) => {x}: " << nodep << endl);
|
||||
keepp = nodep->ifsp();
|
||||
keepp = nodep->thensp();
|
||||
} else {
|
||||
UINFO(4, "IF condition is X, retaining: " << nodep << endl);
|
||||
return;
|
||||
|
|
@ -2904,7 +2903,7 @@ private:
|
|||
nodep->unlinkFrBack();
|
||||
}
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
} else if (!afterComment(nodep->ifsp()) && !afterComment(nodep->elsesp())) {
|
||||
} else if (!afterComment(nodep->thensp()) && !afterComment(nodep->elsesp())) {
|
||||
if (!isTreePureRecurse(nodep->condp())) {
|
||||
// Condition has side effect - leave - perhaps in
|
||||
// future simplify to remove all but side effect terms
|
||||
|
|
@ -2912,27 +2911,27 @@ private:
|
|||
// Empty block, remove it
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
} else if (!afterComment(nodep->ifsp())) {
|
||||
} else if (!afterComment(nodep->thensp())) {
|
||||
UINFO(4, "IF({x}) nullptr {...} => IF(NOT{x}}: " << nodep << endl);
|
||||
AstNode* const condp = nodep->condp();
|
||||
AstNode* const elsesp = nodep->elsesp();
|
||||
condp->unlinkFrBackWithNext();
|
||||
elsesp->unlinkFrBackWithNext();
|
||||
if (nodep->ifsp()) { // Must have been comment
|
||||
nodep->ifsp()->unlinkFrBackWithNext()->deleteTree();
|
||||
if (nodep->thensp()) { // Must have been comment
|
||||
nodep->thensp()->unlinkFrBackWithNext()->deleteTree();
|
||||
}
|
||||
nodep->condp(new AstLogNot(condp->fileline(),
|
||||
condp)); // LogNot, as C++ optimization also possible
|
||||
nodep->addIfsp(elsesp);
|
||||
nodep->addThensp(elsesp);
|
||||
} else if (((VN_IS(nodep->condp(), Not) && nodep->condp()->width() == 1)
|
||||
|| VN_IS(nodep->condp(), LogNot))
|
||||
&& nodep->ifsp() && nodep->elsesp()) {
|
||||
&& nodep->thensp() && nodep->elsesp()) {
|
||||
UINFO(4, "IF(NOT {x}) => IF(x) swapped if/else" << nodep << endl);
|
||||
AstNode* const condp
|
||||
= VN_AS(nodep->condp(), NodeUniop)->lhsp()->unlinkFrBackWithNext();
|
||||
AstNode* const ifsp = nodep->ifsp()->unlinkFrBackWithNext();
|
||||
AstNode* const thensp = nodep->thensp()->unlinkFrBackWithNext();
|
||||
AstNode* const elsesp = nodep->elsesp()->unlinkFrBackWithNext();
|
||||
AstIf* const ifp = new AstIf(nodep->fileline(), condp, elsesp, ifsp);
|
||||
AstIf* const ifp = new AstIf(nodep->fileline(), condp, elsesp, thensp);
|
||||
ifp->branchPred(nodep->branchPred().invert());
|
||||
nodep->replaceWith(ifp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
|
|
@ -2940,25 +2939,25 @@ private:
|
|||
UINFO(
|
||||
4,
|
||||
"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})\n");
|
||||
AstNodeAssign* const ifp = VN_AS(nodep->ifsp(), NodeAssign);
|
||||
AstNodeAssign* const elsep = VN_AS(nodep->elsesp(), NodeAssign);
|
||||
ifp->unlinkFrBack();
|
||||
AstNodeAssign* const thensp = VN_AS(nodep->thensp(), NodeAssign);
|
||||
AstNodeAssign* const elsesp = VN_AS(nodep->elsesp(), NodeAssign);
|
||||
thensp->unlinkFrBack();
|
||||
AstNode* const condp = nodep->condp()->unlinkFrBack();
|
||||
AstNode* const truep = ifp->rhsp()->unlinkFrBack();
|
||||
AstNode* const falsep = elsep->rhsp()->unlinkFrBack();
|
||||
ifp->rhsp(new AstCond(truep->fileline(), condp, truep, falsep));
|
||||
nodep->replaceWith(ifp);
|
||||
AstNode* const truep = thensp->rhsp()->unlinkFrBack();
|
||||
AstNode* const falsep = elsesp->rhsp()->unlinkFrBack();
|
||||
thensp->rhsp(new AstCond(truep->fileline(), condp, truep, falsep));
|
||||
nodep->replaceWith(thensp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
} else if (false // Disabled, as vpm assertions are faster
|
||||
// without due to short-circuiting
|
||||
&& operandIfIf(nodep)) {
|
||||
UINFO(9, "IF({a}) IF({b}) => IF({a} && {b})" << endl);
|
||||
AstNodeIf* const lowerIfp = VN_AS(nodep->ifsp(), NodeIf);
|
||||
AstNodeIf* const lowerIfp = VN_AS(nodep->thensp(), NodeIf);
|
||||
AstNode* const condp = nodep->condp()->unlinkFrBack();
|
||||
AstNode* const lowerIfsp = lowerIfp->ifsp()->unlinkFrBackWithNext();
|
||||
AstNode* const lowerThensp = lowerIfp->thensp()->unlinkFrBackWithNext();
|
||||
AstNode* const lowerCondp = lowerIfp->condp()->unlinkFrBackWithNext();
|
||||
nodep->condp(new AstLogAnd(lowerIfp->fileline(), condp, lowerCondp));
|
||||
lowerIfp->replaceWith(lowerIfsp);
|
||||
lowerIfp->replaceWith(lowerThensp);
|
||||
VL_DO_DANGLING(lowerIfp->deleteTree(), lowerIfp);
|
||||
} else if (operandBoolShift(nodep->condp())) {
|
||||
replaceBoolShift(nodep->condp());
|
||||
|
|
@ -3015,8 +3014,10 @@ private:
|
|||
pformatp->text(pformatp->text() + nformatp->text());
|
||||
if (!prevp->addNewline() && nodep->addNewline()) pformatp->text(pformatp->text() + "\n");
|
||||
if (nformatp->exprsp()) pformatp->addExprsp(nformatp->exprsp()->unlinkFrBackWithNext());
|
||||
if (nformatp->scopeNamep())
|
||||
pformatp->scopeNamep(nformatp->scopeNamep()->unlinkFrBackWithNext());
|
||||
if (AstScopeName* const scopeNamep = nformatp->scopeNamep()) {
|
||||
scopeNamep->unlinkFrBackWithNext();
|
||||
pformatp->scopeNamep(scopeNamep);
|
||||
}
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -3300,19 +3301,19 @@ private:
|
|||
TREEOPC("AstAnd {$lhsp.isOne, matchRedundantClean(nodep)}", "DONE") // 1 & (a == b) -> (IData)(a == b)
|
||||
// Trinary ops
|
||||
// Note V3Case::Sel requires Cond to always be conditionally executed in C to prevent core dump!
|
||||
TREEOP ("AstNodeCond{$condp.isZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr2p)");
|
||||
TREEOP ("AstNodeCond{$condp.isNeqZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr1p)");
|
||||
TREEOPA("AstNodeCond{$condp.isZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr2p)");
|
||||
TREEOPA("AstNodeCond{$condp.isNeqZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr1p)");
|
||||
TREEOP ("AstNodeCond{$condp, operandsSame($expr1p,,$expr2p)}","replaceWChild(nodep,$expr1p)");
|
||||
TREEOP ("AstNodeCond{$condp.isZero, $thenp, $elsep}", "replaceWChild(nodep,$elsep)");
|
||||
TREEOP ("AstNodeCond{$condp.isNeqZero, $thenp, $elsep}", "replaceWChild(nodep,$thenp)");
|
||||
TREEOPA("AstNodeCond{$condp.isZero, $thenp.castConst, $elsep.castConst}", "replaceWChild(nodep,$elsep)");
|
||||
TREEOPA("AstNodeCond{$condp.isNeqZero, $thenp.castConst, $elsep.castConst}", "replaceWChild(nodep,$thenp)");
|
||||
TREEOP ("AstNodeCond{$condp, operandsSame($thenp,,$elsep)}","replaceWChild(nodep,$thenp)");
|
||||
// This visit function here must allow for short-circuiting.
|
||||
TREEOPS("AstCond {$lhsp.isZero}", "replaceWIteratedThs(nodep)");
|
||||
TREEOPS("AstCond {$lhsp.isNeqZero}", "replaceWIteratedRhs(nodep)");
|
||||
TREEOP ("AstCond{$condp.castNot, $expr1p, $expr2p}", "AstCond{$condp->op1p(), $expr2p, $expr1p}");
|
||||
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isAllOnes, $expr2p}", "AstLogOr {$condp, $expr2p}"); // a?1:b == a||b
|
||||
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isZero}", "AstLogAnd{$condp, $expr1p}"); // a?b:0 == a&&b
|
||||
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isAllOnes}", "AstLogOr {AstNot{$condp}, $expr1p}"); // a?b:1 == ~a||b
|
||||
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isZero, $expr2p}", "AstLogAnd{AstNot{$condp}, $expr2p}"); // a?0:b == ~a&&b
|
||||
TREEOP ("AstCond{$condp.castNot, $thenp, $elsep}", "AstCond{$condp->op1p(), $elsep, $thenp}");
|
||||
TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp.isAllOnes, $elsep}", "AstLogOr {$condp, $elsep}"); // a?1:b == a||b
|
||||
TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp, $elsep.isZero}", "AstLogAnd{$condp, $thenp}"); // a?b:0 == a&&b
|
||||
TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp, $elsep.isAllOnes}", "AstLogOr {AstNot{$condp}, $thenp}"); // a?b:1 == ~a||b
|
||||
TREEOP ("AstNodeCond{$condp.width1, $thenp.width1, $thenp.isZero, $elsep}", "AstLogAnd{AstNot{$condp}, $elsep}"); // a?0:b == ~a&&b
|
||||
TREEOP ("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())");
|
||||
// Prefer constants on left, since that often needs a shift, it lets
|
||||
// constant red remove the shift
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ private:
|
|||
|
||||
AstCoverDecl* const declp = new AstCoverDecl(fl, page, comment, linescov, offset);
|
||||
declp->hier(hier);
|
||||
m_modp->addStmtp(declp);
|
||||
m_modp->addStmtsp(declp);
|
||||
UINFO(9, "new " << declp << endl);
|
||||
|
||||
AstCoverInc* const incp = new AstCoverInc(fl, declp);
|
||||
|
|
@ -128,7 +128,7 @@ private:
|
|||
incp->findUInt32DType());
|
||||
varp->trace(true);
|
||||
varp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true);
|
||||
m_modp->addStmtp(varp);
|
||||
m_modp->addStmtsp(varp);
|
||||
UINFO(5, "New coverage trace: " << varp << endl);
|
||||
AstAssign* const assp = new AstAssign(
|
||||
incp->fileline(), new AstVarRef(incp->fileline(), varp, VAccess::WRITE),
|
||||
|
|
@ -245,11 +245,11 @@ private:
|
|||
= newCoverInc(nodep->fileline(), "", "v_line", "block",
|
||||
linesCov(m_state, nodep), 0, traceNameForLine(nodep, "block"));
|
||||
if (AstNodeProcedure* const itemp = VN_CAST(nodep, NodeProcedure)) {
|
||||
itemp->addStmtp(newp);
|
||||
itemp->addStmtsp(newp);
|
||||
} else if (AstNodeFTask* const itemp = VN_CAST(nodep, NodeFTask)) {
|
||||
itemp->addStmtsp(newp);
|
||||
} else if (AstWhile* const itemp = VN_CAST(nodep, While)) {
|
||||
itemp->addBodysp(newp);
|
||||
itemp->addStmtsp(newp);
|
||||
} else {
|
||||
nodep->v3fatalSrc("Bad node type");
|
||||
}
|
||||
|
|
@ -283,7 +283,7 @@ private:
|
|||
AstVar* const chgVarp
|
||||
= new AstVar(nodep->fileline(), VVarType::MODULETEMP, newvarname, nodep);
|
||||
chgVarp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true);
|
||||
m_modp->addStmtp(chgVarp);
|
||||
m_modp->addStmtsp(chgVarp);
|
||||
|
||||
// Create bucket for each dimension * bit.
|
||||
// This is necessarily an O(n^2) expansion, which is why
|
||||
|
|
@ -304,7 +304,7 @@ private:
|
|||
newCoverInc(varp->fileline(), "", "v_toggle", varp->name() + above.m_comment, "", 0,
|
||||
""),
|
||||
above.m_varRefp->cloneTree(true), above.m_chgRefp->cloneTree(true));
|
||||
m_modp->addStmtp(newp);
|
||||
m_modp->addStmtsp(newp);
|
||||
}
|
||||
|
||||
void toggleVarRecurse(AstNodeDType* dtypep, int depth, // per-iteration
|
||||
|
|
@ -388,7 +388,7 @@ private:
|
|||
if (m_state.m_on) {
|
||||
// An else-if. When we iterate the if, use "elsif" marking
|
||||
const bool elsif
|
||||
= nodep->ifsp() && VN_IS(nodep->elsesp(), If) && !nodep->elsesp()->nextp();
|
||||
= nodep->thensp() && VN_IS(nodep->elsesp(), If) && !nodep->elsesp()->nextp();
|
||||
if (elsif) VN_AS(nodep->elsesp(), If)->user1(true);
|
||||
const bool first_elsif = !nodep->user1() && elsif;
|
||||
const bool cont_elsif = nodep->user1() && elsif;
|
||||
|
|
@ -403,7 +403,7 @@ private:
|
|||
CheckState elseState;
|
||||
{
|
||||
createHandle(nodep);
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
iterateAndNextNull(nodep->thensp());
|
||||
lineTrack(nodep);
|
||||
ifState = m_state;
|
||||
}
|
||||
|
|
@ -422,9 +422,9 @@ private:
|
|||
// Normal if. Linecov shows what's inside the if (not condition that is
|
||||
// always executed)
|
||||
UINFO(4, " COVER-branch: " << nodep << endl);
|
||||
nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_branch", "if",
|
||||
linesCov(ifState, nodep), 0,
|
||||
traceNameForLine(nodep, "if")));
|
||||
nodep->addThensp(newCoverInc(nodep->fileline(), "", "v_branch", "if",
|
||||
linesCov(ifState, nodep), 0,
|
||||
traceNameForLine(nodep, "if")));
|
||||
// The else has a column offset of 1 to uniquify it relative to the if
|
||||
// As "if" and "else" are more than one character wide, this won't overlap
|
||||
// another token
|
||||
|
|
@ -436,18 +436,18 @@ private:
|
|||
else if (first_elsif || cont_elsif) {
|
||||
UINFO(4, " COVER-elsif: " << nodep << endl);
|
||||
if (ifState.lineCoverageOn(nodep)) {
|
||||
nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "elsif",
|
||||
linesCov(ifState, nodep), 0,
|
||||
traceNameForLine(nodep, "elsif")));
|
||||
nodep->addThensp(newCoverInc(nodep->fileline(), "", "v_line", "elsif",
|
||||
linesCov(ifState, nodep), 0,
|
||||
traceNameForLine(nodep, "elsif")));
|
||||
}
|
||||
// and we don't insert the else as the child if-else will do so
|
||||
} else {
|
||||
// Cover as separate blocks (not a branch as is not two-legged)
|
||||
if (ifState.lineCoverageOn(nodep)) {
|
||||
UINFO(4, " COVER-half-if: " << nodep << endl);
|
||||
nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "if",
|
||||
linesCov(ifState, nodep), 0,
|
||||
traceNameForLine(nodep, "if")));
|
||||
nodep->addThensp(newCoverInc(nodep->fileline(), "", "v_line", "if",
|
||||
linesCov(ifState, nodep), 0,
|
||||
traceNameForLine(nodep, "if")));
|
||||
}
|
||||
if (elseState.lineCoverageOn(nodep)) {
|
||||
UINFO(4, " COVER-half-el: " << nodep << endl);
|
||||
|
|
@ -468,11 +468,11 @@ private:
|
|||
VL_RESTORER(m_state);
|
||||
{
|
||||
createHandle(nodep);
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
if (m_state.lineCoverageOn(nodep)) { // if the case body didn't disable it
|
||||
lineTrack(nodep);
|
||||
UINFO(4, " COVER: " << nodep << endl);
|
||||
nodep->addBodysp(newCoverInc(nodep->fileline(), "", "v_line", "case",
|
||||
nodep->addStmtsp(newCoverInc(nodep->fileline(), "", "v_line", "case",
|
||||
linesCov(m_state, nodep), 0,
|
||||
traceNameForLine(nodep, "case")));
|
||||
}
|
||||
|
|
@ -486,12 +486,12 @@ private:
|
|||
m_state.m_on = true; // Always do cover blocks, even if there's a $stop
|
||||
createHandle(nodep);
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->coverincp() && v3Global.opt.coverageUser()) {
|
||||
if (!nodep->coverincsp() && v3Global.opt.coverageUser()) {
|
||||
// Note the name may be overridden by V3Assert processing
|
||||
lineTrack(nodep);
|
||||
nodep->coverincp(newCoverInc(nodep->fileline(), m_beginHier, "v_user", "cover",
|
||||
linesCov(m_state, nodep), 0,
|
||||
m_beginHier + "_vlCoverageUserTrace"));
|
||||
nodep->addCoverincsp(newCoverInc(nodep->fileline(), m_beginHier, "v_user", "cover",
|
||||
linesCov(m_state, nodep), 0,
|
||||
m_beginHier + "_vlCoverageUserTrace"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,13 +153,13 @@ private:
|
|||
varp = new AstVar(oldvarscp->fileline(), VVarType::BLOCKTEMP, name,
|
||||
VFlagBitPacked(), width);
|
||||
}
|
||||
addmodp->addStmtp(varp);
|
||||
addmodp->addStmtsp(varp);
|
||||
m_modVarMap.emplace(std::make_pair(addmodp, name), varp);
|
||||
}
|
||||
|
||||
AstVarScope* const varscp
|
||||
= new AstVarScope(oldvarscp->fileline(), oldvarscp->scopep(), varp);
|
||||
oldvarscp->scopep()->addVarp(varscp);
|
||||
oldvarscp->scopep()->addVarsp(varscp);
|
||||
return varscp;
|
||||
}
|
||||
|
||||
|
|
@ -356,11 +356,11 @@ private:
|
|||
postLogicp = new AstIf(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), setvscp, VAccess::READ));
|
||||
UINFO(9, " Created " << postLogicp << endl);
|
||||
finalp->addStmtp(postLogicp);
|
||||
finalp->addStmtsp(postLogicp);
|
||||
finalp->user3p(setvscp); // Remember IF's vset variable
|
||||
finalp->user4p(postLogicp); // and the associated IF, as we may be able to reuse it
|
||||
}
|
||||
postLogicp->addIfsp(new AstAssign(nodep->fileline(), selectsp, valreadp));
|
||||
postLogicp->addThensp(new AstAssign(nodep->fileline(), selectsp, valreadp));
|
||||
return newlhsp;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ private:
|
|||
funcp->isStatic(m_cfuncp->isStatic());
|
||||
funcp->isLoose(m_cfuncp->isLoose());
|
||||
funcp->addStmtsp(nodep);
|
||||
scopep->addActivep(funcp);
|
||||
scopep->addBlocksp(funcp);
|
||||
// Call sub function at the point where the body was removed from
|
||||
AstCCall* const callp = new AstCCall(nodep->fileline(), funcp);
|
||||
if (VN_IS(m_modp, Class)) {
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ private:
|
|||
// If it's under a scope, move it up to the top
|
||||
if (m_scopep) {
|
||||
nodep->unlinkFrBack();
|
||||
m_modp->addStmtp(nodep);
|
||||
m_modp->addStmtsp(nodep);
|
||||
|
||||
if (nodep->funcPublic()) {
|
||||
// There may be multiple public functions by the same name;
|
||||
|
|
|
|||
|
|
@ -828,7 +828,7 @@ public:
|
|||
puts("while (");
|
||||
iterateAndNextNull(nodep->condp());
|
||||
puts(") {\n");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
iterateAndNextNull(nodep->incsp());
|
||||
iterateAndNextNull(nodep->precondsp()); // Need to recompute before next loop
|
||||
puts("}\n");
|
||||
|
|
@ -842,7 +842,7 @@ public:
|
|||
iterateAndNextNull(nodep->condp());
|
||||
if (!nodep->branchPred().unknown()) puts(")");
|
||||
puts(") {\n");
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
iterateAndNextNull(nodep->thensp());
|
||||
puts("}");
|
||||
if (!nodep->elsesp()) {
|
||||
puts("\n");
|
||||
|
|
@ -935,17 +935,17 @@ public:
|
|||
}
|
||||
void visit(AstCStmt* nodep) override {
|
||||
putbs("");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->exprsp());
|
||||
}
|
||||
void visit(AstCMath* nodep) override {
|
||||
putbs("");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->exprsp());
|
||||
}
|
||||
void visit(AstUCStmt* nodep) override {
|
||||
VL_RESTORER(m_inUC);
|
||||
m_inUC = true;
|
||||
putsDecoration(ifNoProtect("// $c statement at " + nodep->fileline()->ascii() + "\n"));
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->exprsp());
|
||||
puts("\n");
|
||||
}
|
||||
void visit(AstUCFunc* nodep) override {
|
||||
|
|
@ -953,7 +953,7 @@ public:
|
|||
m_inUC = true;
|
||||
puts("\n");
|
||||
putsDecoration(ifNoProtect("// $c function at " + nodep->fileline()->ascii() + "\n"));
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->exprsp());
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
|
|
@ -1033,15 +1033,15 @@ public:
|
|||
}
|
||||
void visit(AstNodeCond* nodep) override {
|
||||
// Widths match up already, so we'll just use C++'s operator w/o any temps.
|
||||
if (nodep->expr1p()->isWide()) {
|
||||
emitOpName(nodep, nodep->emitC(), nodep->condp(), nodep->expr1p(), nodep->expr2p());
|
||||
if (nodep->thenp()->isWide()) {
|
||||
emitOpName(nodep, nodep->emitC(), nodep->condp(), nodep->thenp(), nodep->elsep());
|
||||
} else {
|
||||
putbs("(");
|
||||
iterateAndNextNull(nodep->condp());
|
||||
putbs(" ? ");
|
||||
iterateAndNextNull(nodep->expr1p());
|
||||
iterateAndNextNull(nodep->thenp());
|
||||
putbs(" : ");
|
||||
iterateAndNextNull(nodep->expr2p());
|
||||
iterateAndNextNull(nodep->elsep());
|
||||
puts(")");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->sensesp());
|
||||
}
|
||||
putbs(" begin\n");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
void visit(AstAlwaysPublic* nodep) override {
|
||||
|
|
@ -122,7 +122,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->sensesp());
|
||||
}
|
||||
putqs(nodep, " ");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
putqs(nodep, "*/\n");
|
||||
}
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
|
|
@ -204,7 +204,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
putbs("default");
|
||||
}
|
||||
putfs(nodep, ": begin ");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
void visit(AstComment* nodep) override {
|
||||
|
|
@ -326,14 +326,14 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->incsp());
|
||||
}
|
||||
puts(") begin\n");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
void visit(AstRepeat* nodep) override {
|
||||
putfs(nodep, "repeat (");
|
||||
iterateAndNextConstNull(nodep->countp());
|
||||
puts(") begin\n");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
putfs(nodep, "end\n");
|
||||
}
|
||||
void visit(AstWhile* nodep) override {
|
||||
|
|
@ -341,7 +341,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
putfs(nodep, "while (");
|
||||
iterateAndNextConstNull(nodep->condp());
|
||||
puts(") begin\n");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
iterateAndNextConstNull(nodep->incsp());
|
||||
iterateAndNextConstNull(nodep->precondsp()); // Need to recompute before next loop
|
||||
putfs(nodep, "end\n");
|
||||
|
|
@ -356,7 +356,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
puts("if (");
|
||||
iterateAndNextConstNull(nodep->condp());
|
||||
puts(") begin\n");
|
||||
iterateAndNextConstNull(nodep->ifsp());
|
||||
iterateAndNextConstNull(nodep->thensp());
|
||||
if (nodep->elsesp()) {
|
||||
putqs(nodep, "end\n");
|
||||
putqs(nodep, "else begin\n");
|
||||
|
|
@ -401,22 +401,22 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
void visit(AstScopeName* nodep) override {}
|
||||
void visit(AstCStmt* nodep) override {
|
||||
putfs(nodep, "$_CSTMT(");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->exprsp());
|
||||
puts(");\n");
|
||||
}
|
||||
void visit(AstCMath* nodep) override {
|
||||
putfs(nodep, "$_CMATH(");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->exprsp());
|
||||
puts(");\n");
|
||||
}
|
||||
void visit(AstUCStmt* nodep) override {
|
||||
putfs(nodep, "$c(");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->exprsp());
|
||||
puts(");\n");
|
||||
}
|
||||
void visit(AstUCFunc* nodep) override {
|
||||
putfs(nodep, "$c(");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->exprsp());
|
||||
puts(")");
|
||||
}
|
||||
|
||||
|
|
@ -521,9 +521,9 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
putbs("(");
|
||||
iterateAndNextConstNull(nodep->condp());
|
||||
putfs(nodep, " ? ");
|
||||
iterateAndNextConstNull(nodep->expr1p());
|
||||
iterateAndNextConstNull(nodep->thenp());
|
||||
putbs(" : ");
|
||||
iterateAndNextConstNull(nodep->expr2p());
|
||||
iterateAndNextConstNull(nodep->elsep());
|
||||
puts(")");
|
||||
}
|
||||
void visit(AstRange* nodep) override {
|
||||
|
|
|
|||
|
|
@ -306,8 +306,8 @@ private:
|
|||
for (int w = 0; w < nodep->widthWords(); ++w) {
|
||||
addWordAssign(nodep, w,
|
||||
new AstCond{fl, rhsp->condp()->cloneTree(true),
|
||||
newAstWordSelClone(rhsp->expr1p(), w),
|
||||
newAstWordSelClone(rhsp->expr2p(), w)});
|
||||
newAstWordSelClone(rhsp->thenp(), w),
|
||||
newAstWordSelClone(rhsp->elsep(), w)});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ class ForceConvertVisitor final : public VNVisitor {
|
|||
new AstSenTree{flp, new AstSenItem{flp, AstSenItem::Initial{}}}};
|
||||
activep->sensesStorep(activep->sensesp());
|
||||
activep->addStmtsp(new AstInitial{flp, assignp});
|
||||
vscp->scopep()->addActivep(activep);
|
||||
vscp->scopep()->addBlocksp(activep);
|
||||
}
|
||||
|
||||
{ // Add the combinational override
|
||||
|
|
@ -127,7 +127,7 @@ class ForceConvertVisitor final : public VNVisitor {
|
|||
new AstSenTree{flp, new AstSenItem{flp, AstSenItem::Combo{}}}};
|
||||
activep->sensesStorep(activep->sensesp());
|
||||
activep->addStmtsp(new AstAssignW{flp, lhsp, rhsp});
|
||||
vscp->scopep()->addActivep(activep);
|
||||
vscp->scopep()->addBlocksp(activep);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -921,7 +921,7 @@ private:
|
|||
if (m_dedupable) {
|
||||
if (!m_always) {
|
||||
m_always = true;
|
||||
iterateAndNextNull(alwaysp->bodysp());
|
||||
iterateAndNextNull(alwaysp->stmtsp());
|
||||
} else {
|
||||
m_dedupable = false;
|
||||
}
|
||||
|
|
@ -936,7 +936,7 @@ private:
|
|||
if (m_always && !m_ifCondp && !ifp->elsesp()) {
|
||||
// we're under an always, this is the first IF, and there's no else
|
||||
m_ifCondp = ifp->condp();
|
||||
iterateAndNextNull(ifp->ifsp());
|
||||
iterateAndNextNull(ifp->thensp());
|
||||
} else {
|
||||
m_dedupable = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,13 +76,13 @@ private:
|
|||
// ASSIGN(VARREF(inpclk), VARREF(var))
|
||||
AstVar* const newvarp
|
||||
= new AstVar(varp->fileline(), VVarType::MODULETEMP, newvarname, varp);
|
||||
m_topModp->addStmtp(newvarp);
|
||||
m_topModp->addStmtsp(newvarp);
|
||||
AstVarScope* const newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp);
|
||||
m_scopetopp->addVarp(newvscp);
|
||||
m_scopetopp->addVarsp(newvscp);
|
||||
AstAssign* const asninitp = new AstAssign(
|
||||
vscp->fileline(), new AstVarRef(vscp->fileline(), newvscp, VAccess::WRITE),
|
||||
new AstVarRef(vscp->fileline(), vscp, VAccess::READ));
|
||||
m_scopetopp->addFinalClkp(asninitp);
|
||||
m_scopetopp->addFinalClksp(asninitp);
|
||||
//
|
||||
vscp->user2p(newvscp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -294,15 +294,15 @@ private:
|
|||
UASSERT_OBJ(exprconstp || exprvarrefp, nodep,
|
||||
"Unknown interconnect type; pinReconnectSimple should have cleared up");
|
||||
if (exprconstp) {
|
||||
m_modp->addStmtp(new AstAssignW(flp, new AstVarRef(flp, nodep, VAccess::WRITE),
|
||||
exprconstp->cloneTree(false)));
|
||||
m_modp->addStmtsp(new AstAssignW(flp, new AstVarRef(flp, nodep, VAccess::WRITE),
|
||||
exprconstp->cloneTree(false)));
|
||||
} else if (nodep->user3()) {
|
||||
// Public variable at the lower module end - we need to make sure we propagate
|
||||
// the logic changes up and down; if we aliased, we might
|
||||
// remove the change detection on the output variable.
|
||||
UINFO(9, "public pin assign: " << exprvarrefp << endl);
|
||||
UASSERT_OBJ(!nodep->isNonOutput(), nodep, "Outputs only - inputs use AssignAlias");
|
||||
m_modp->addStmtp(
|
||||
m_modp->addStmtsp(
|
||||
new AstAssignW(flp, new AstVarRef(flp, exprvarrefp->varp(), VAccess::WRITE),
|
||||
new AstVarRef(flp, nodep, VAccess::READ)));
|
||||
} else if (nodep->isSigPublic() && VN_IS(nodep->dtypep(), UnpackArrayDType)) {
|
||||
|
|
@ -310,11 +310,11 @@ private:
|
|||
// instead of aliased, because otherwise it will pass V3Slice and invalid
|
||||
// code will be emitted.
|
||||
UINFO(9, "assign to public and unpacked: " << nodep << endl);
|
||||
m_modp->addStmtp(
|
||||
m_modp->addStmtsp(
|
||||
new AstAssignW{flp, new AstVarRef{flp, nodep, VAccess::WRITE},
|
||||
new AstVarRef{flp, exprvarrefp->varp(), VAccess::READ}});
|
||||
} else if (nodep->isIfaceRef()) {
|
||||
m_modp->addStmtp(
|
||||
m_modp->addStmtsp(
|
||||
new AstAssignVarScope(flp, new AstVarRef(flp, nodep, VAccess::WRITE),
|
||||
new AstVarRef(flp, exprvarrefp->varp(), VAccess::READ)));
|
||||
FileLine* const flbp = exprvarrefp->varp()->fileline();
|
||||
|
|
@ -323,7 +323,7 @@ private:
|
|||
} else {
|
||||
// Do to inlining child's variable now within the same
|
||||
// module, so a AstVarRef not AstVarXRef below
|
||||
m_modp->addStmtp(
|
||||
m_modp->addStmtsp(
|
||||
new AstAssignAlias(flp, new AstVarRef(flp, nodep, VAccess::WRITE),
|
||||
new AstVarRef(flp, exprvarrefp->varp(), VAccess::READ)));
|
||||
FileLine* const flbp = exprvarrefp->varp()->fileline();
|
||||
|
|
@ -423,16 +423,16 @@ private:
|
|||
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||
// Similar code in V3Begin
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstNode* afterp = nodep->scopeAttrp();
|
||||
AstText* afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeAttrp(
|
||||
nodep->addScopeAttrp(
|
||||
new AstText{nodep->fileline(), std::string{"__DOT__"} + m_cellp->name()});
|
||||
if (afterp) nodep->scopeAttrp(afterp);
|
||||
if (afterp) nodep->addScopeAttrp(afterp);
|
||||
afterp = nodep->scopeEntrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeEntrp(
|
||||
nodep->addScopeEntrp(
|
||||
new AstText{nodep->fileline(), std::string{"__DOT__"} + m_cellp->name()});
|
||||
if (afterp) nodep->scopeEntrp(afterp);
|
||||
if (afterp) nodep->addScopeEntrp(afterp);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstCoverDecl* nodep) override {
|
||||
|
|
@ -566,7 +566,7 @@ private:
|
|||
// Move statements under the module we are inlining into
|
||||
if (AstNode* const stmtsp = newmodp->stmtsp()) {
|
||||
stmtsp->unlinkFrBackWithNext();
|
||||
m_modp->addStmtp(stmtsp);
|
||||
m_modp->addStmtsp(stmtsp);
|
||||
}
|
||||
// Clear any leftover ports, etc
|
||||
VL_DO_DANGLING(newmodp->deleteTree(), newmodp);
|
||||
|
|
@ -649,7 +649,7 @@ private:
|
|||
}
|
||||
|
||||
if (VN_IS(nodep->modp(), Iface)) {
|
||||
nodep->addIntfRefp(new AstIntfRef{nodep->fileline(), m_scope});
|
||||
nodep->addIntfRefsp(new AstIntfRef{nodep->fileline(), m_scope});
|
||||
}
|
||||
{
|
||||
AstNodeModule* const modp = nodep->modp();
|
||||
|
|
@ -666,7 +666,7 @@ private:
|
|||
if ((cellp = VN_CAST(fromVarp->user1p(), Cell)) || (cellp = irdtp->cellp())) {
|
||||
varp->user1p(cellp);
|
||||
const string alias = m_scope + "__DOT__" + pinp->name();
|
||||
cellp->addIntfRefp(new AstIntfRef(pinp->fileline(), alias));
|
||||
cellp->addIntfRefsp(new AstIntfRef(pinp->fileline(), alias));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -695,7 +695,7 @@ private:
|
|||
string alias;
|
||||
if (!m_scope.empty()) alias = m_scope + "__DOT__";
|
||||
alias += varlp->name();
|
||||
cellp->addIntfRefp(new AstIntfRef(varlp->fileline(), alias));
|
||||
cellp->addIntfRefsp(new AstIntfRef(varlp->fileline(), alias));
|
||||
}
|
||||
//--------------------
|
||||
void visit(AstNodeMath*) override {} // Accelerate
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ private:
|
|||
|
||||
UINFO(8, "ifsp:\n");
|
||||
m_instrCount = 0;
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
iterateAndNextNull(nodep->thensp());
|
||||
uint32_t ifCount = m_instrCount;
|
||||
if (nodep->branchPred().unlikely()) ifCount = 0;
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ private:
|
|||
if (nodep->elsesp()) nodep->elsesp()->user4(0); // Don't dump it
|
||||
} else {
|
||||
m_instrCount = savedCount + elseCount;
|
||||
if (nodep->ifsp()) nodep->ifsp()->user4(0); // Don't dump it
|
||||
if (nodep->thensp()) nodep->thensp()->user4(0); // Don't dump it
|
||||
}
|
||||
}
|
||||
void visit(AstNodeCond* nodep) override {
|
||||
|
|
@ -197,20 +197,20 @@ private:
|
|||
|
||||
UINFO(8, "?\n");
|
||||
m_instrCount = 0;
|
||||
iterateAndNextNull(nodep->expr1p());
|
||||
iterateAndNextNull(nodep->thenp());
|
||||
const uint32_t ifCount = m_instrCount;
|
||||
|
||||
UINFO(8, ":\n");
|
||||
m_instrCount = 0;
|
||||
iterateAndNextNull(nodep->expr2p());
|
||||
iterateAndNextNull(nodep->elsep());
|
||||
const uint32_t elseCount = m_instrCount;
|
||||
|
||||
if (ifCount < elseCount) {
|
||||
m_instrCount = savedCount + elseCount;
|
||||
if (nodep->expr1p()) nodep->expr1p()->user4(0); // Don't dump it
|
||||
if (nodep->thenp()) nodep->thenp()->user4(0); // Don't dump it
|
||||
} else {
|
||||
m_instrCount = savedCount + ifCount;
|
||||
if (nodep->expr2p()) nodep->expr2p()->user4(0); // Don't dump it
|
||||
if (nodep->elsep()) nodep->elsep()->user4(0); // Don't dump it
|
||||
}
|
||||
}
|
||||
void visit(AstActive* nodep) override {
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ private:
|
|||
LifeBlock* const elseLifep = new LifeBlock(prevLifep, m_statep);
|
||||
{
|
||||
m_lifep = ifLifep;
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
iterateAndNextNull(nodep->thensp());
|
||||
}
|
||||
{
|
||||
m_lifep = elseLifep;
|
||||
|
|
@ -375,7 +375,7 @@ private:
|
|||
}
|
||||
{
|
||||
m_lifep = bodyLifep;
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
iterateAndNextNull(nodep->incsp());
|
||||
}
|
||||
m_lifep = prevLifep;
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ private:
|
|||
{
|
||||
m_modp = modp;
|
||||
// Important that this adds to end, as next iterate assumes does all cells
|
||||
modp->addStmtp(cellsp);
|
||||
modp->addStmtsp(cellsp);
|
||||
iterateAndNextNull(cellsp);
|
||||
}
|
||||
}
|
||||
|
|
@ -321,7 +321,7 @@ private:
|
|||
otherModp->recursiveClone(true);
|
||||
// user1 etc will retain its pre-clone value
|
||||
cellmodp->user2p(otherModp);
|
||||
v3Global.rootp()->addModulep(otherModp);
|
||||
v3Global.rootp()->addModulesp(otherModp);
|
||||
new V3GraphEdge(&m_graph, vertex(cellmodp), vertex(otherModp), 1,
|
||||
false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -994,7 +994,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
if (!nodep->isExternDef()) {
|
||||
// Move it to proper spot under the target class
|
||||
nodep->unlinkFrBack();
|
||||
classp->addStmtp(nodep);
|
||||
classp->addStmtsp(nodep);
|
||||
nodep->isExternDef(true); // So we check there's a matching extern
|
||||
nodep->classOrPackagep()->unlinkFrBack()->deleteTree();
|
||||
}
|
||||
|
|
@ -1030,7 +1030,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
newvarp->funcReturn(true);
|
||||
newvarp->trace(false); // Not user visible
|
||||
newvarp->attrIsolateAssign(nodep->attrIsolateAssign());
|
||||
nodep->addFvarp(newvarp);
|
||||
nodep->fvarp(newvarp);
|
||||
// Explicit insert required, as the var name shadows the upper level's task name
|
||||
m_statep->insertSym(m_curSymp, newvarp->name(), newvarp,
|
||||
nullptr /*classOrPackagep*/);
|
||||
|
|
@ -1938,7 +1938,7 @@ private:
|
|||
VFlagLogicPacked{}, 1);
|
||||
newp->trace(modp->modTrace());
|
||||
nodep->varp(newp);
|
||||
modp->addStmtp(newp);
|
||||
modp->addStmtsp(newp);
|
||||
// Link it to signal list, must add the variable under the module;
|
||||
// current scope might be lower now
|
||||
m_statep->insertSym(moduleSymp, newp->name(), newp, nullptr /*classOrPackagep*/);
|
||||
|
|
@ -3097,7 +3097,7 @@ private:
|
|||
nodep->classOrPackagep(foundp->classOrPackagep());
|
||||
}
|
||||
} else if (AstClass* const defp = foundp ? VN_AS(foundp->nodep(), Class) : nullptr) {
|
||||
AstNode* const paramsp = nodep->paramsp();
|
||||
AstPin* const paramsp = nodep->paramsp();
|
||||
if (paramsp) paramsp->unlinkFrBackWithNext();
|
||||
AstClassRefDType* const newp
|
||||
= new AstClassRefDType{nodep->fileline(), defp, paramsp};
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ private:
|
|||
iterateAndNextNull(nodep->condp());
|
||||
// Body insert just before themselves
|
||||
m_insStmtp = nullptr; // First thing should be new statement
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
iterateAndNextNull(nodep->incsp());
|
||||
// Done the loop
|
||||
m_insStmtp = nullptr; // Next thing should be new statement
|
||||
|
|
@ -131,7 +131,7 @@ private:
|
|||
m_insStmtp = nodep;
|
||||
iterateAndNextNull(nodep->condp());
|
||||
m_insStmtp = nullptr;
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
iterateAndNextNull(nodep->thensp());
|
||||
iterateAndNextNull(nodep->elsesp());
|
||||
m_insStmtp = nullptr;
|
||||
}
|
||||
|
|
@ -143,7 +143,7 @@ private:
|
|||
iterateAndNextNull(nodep->condsp());
|
||||
}
|
||||
m_insStmtp = nullptr; // Next thing should be new statement
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
}
|
||||
void visit(AstNodeFor* nodep) override { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc(
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ private:
|
|||
underp = VN_AS(nodep, NodeFTask)->stmtsp();
|
||||
} else if (VN_IS(nodep, Foreach)) {
|
||||
if (endOfIter) {
|
||||
underp = VN_AS(nodep, Foreach)->bodysp();
|
||||
underp = VN_AS(nodep, Foreach)->stmtsp();
|
||||
} else {
|
||||
underp = nodep;
|
||||
under_and_next = false; // IE we skip the entire foreach
|
||||
|
|
@ -78,7 +78,7 @@ private:
|
|||
if (endOfIter) {
|
||||
// Note we jump to end of bodysp; a FOR loop has its
|
||||
// increment under incsp() which we don't skip
|
||||
underp = VN_AS(nodep, While)->bodysp();
|
||||
underp = VN_AS(nodep, While)->stmtsp();
|
||||
} else {
|
||||
underp = nodep;
|
||||
under_and_next = false; // IE we skip the entire while
|
||||
|
|
@ -157,7 +157,7 @@ private:
|
|||
AstVar* const varp
|
||||
= new AstVar(nodep->fileline(), VVarType::BLOCKTEMP, name, nodep->findSigned32DType());
|
||||
varp->usedLoopIdx(true);
|
||||
m_modp->addStmtp(varp);
|
||||
m_modp->addStmtsp(varp);
|
||||
AstNode* initsp = new AstAssign(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::WRITE), countp);
|
||||
AstNode* const decp = new AstAssign(
|
||||
|
|
@ -167,7 +167,7 @@ private:
|
|||
AstNode* const zerosp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0);
|
||||
AstNode* const condp = new AstGtS(
|
||||
nodep->fileline(), new AstVarRef(nodep->fileline(), varp, VAccess::READ), zerosp);
|
||||
AstNode* const bodysp = nodep->bodysp();
|
||||
AstNode* const bodysp = nodep->stmtsp();
|
||||
if (bodysp) bodysp->unlinkFrBackWithNext();
|
||||
AstNode* newp = new AstWhile(nodep->fileline(), condp, bodysp, decp);
|
||||
initsp = initsp->addNext(newp);
|
||||
|
|
@ -178,7 +178,7 @@ private:
|
|||
void visit(AstWait* nodep) override {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: wait statements");
|
||||
// Statements we'll just execute immediately; equivalent to if they followed this
|
||||
if (AstNode* const bodysp = nodep->bodysp()) {
|
||||
if (AstNode* const bodysp = nodep->stmtsp()) {
|
||||
bodysp->unlinkFrBackWithNext();
|
||||
nodep->replaceWith(bodysp);
|
||||
} else {
|
||||
|
|
@ -195,7 +195,7 @@ private:
|
|||
m_loopInc = false;
|
||||
iterateAndNextNull(nodep->precondsp());
|
||||
iterateAndNextNull(nodep->condp());
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
m_loopInc = true;
|
||||
iterateAndNextNull(nodep->incsp());
|
||||
}
|
||||
|
|
@ -204,7 +204,7 @@ private:
|
|||
VL_RESTORER(m_loopp);
|
||||
{
|
||||
m_loopp = nodep;
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
}
|
||||
}
|
||||
void visit(AstReturn* nodep) override {
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ void V3LinkLevel::modSortByLevel() {
|
|||
UINFO(9, "modSortByLevel() sorted\n"); // Comment required for gcc4.6.3 / bug666
|
||||
for (AstNodeModule* nodep : mods) nodep->unlinkFrBack();
|
||||
UASSERT_OBJ(!v3Global.rootp()->modulesp(), v3Global.rootp(), "Unlink didn't work");
|
||||
for (AstNodeModule* nodep : mods) v3Global.rootp()->addModulep(nodep);
|
||||
for (AstNodeModule* nodep : mods) v3Global.rootp()->addModulesp(nodep);
|
||||
UINFO(9, "modSortByLevel() done\n"); // Comment required for gcc4.6.3 / bug666
|
||||
V3Global::dumpCheckGlobalTree("cells", false, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
}
|
||||
|
|
@ -154,7 +154,7 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
|
|||
newmodp->modPublic(true);
|
||||
newmodp->protect(false);
|
||||
newmodp->timeunit(oldmodp->timeunit());
|
||||
rootp->addModulep(newmodp);
|
||||
rootp->addModulesp(newmodp);
|
||||
|
||||
// TODO the module creation above could be done after linkcells, but
|
||||
// the rest must be done after data type resolution
|
||||
|
|
@ -170,7 +170,7 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
|
|||
// with module names/"v"
|
||||
modp->name(), modp->name(), nullptr, nullptr, nullptr);
|
||||
cellp->modp(modp);
|
||||
newmodp->addStmtp(cellp);
|
||||
newmodp->addStmtsp(cellp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +213,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
|||
(!v3Global.opt.l2Name().empty() ? v3Global.opt.l2Name() : oldmodp->name()),
|
||||
oldmodp->name(), nullptr, nullptr, nullptr);
|
||||
cellp->modp(oldmodp);
|
||||
newmodp->addStmtp(cellp);
|
||||
newmodp->addStmtsp(cellp);
|
||||
|
||||
// Add pins
|
||||
for (AstNode* subnodep = oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {
|
||||
|
|
@ -229,7 +229,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
|||
AstVar* const varp = oldvarp->cloneTree(false);
|
||||
varp->name(name);
|
||||
varp->protect(false);
|
||||
newmodp->addStmtp(varp);
|
||||
newmodp->addStmtsp(varp);
|
||||
varp->sigPublic(true); // User needs to be able to get to it...
|
||||
if (oldvarp->isIO()) {
|
||||
oldvarp->primaryIO(false);
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ private:
|
|||
// lvalue is true, because we know we have a verilator public_flat_rw
|
||||
// but someday we may be more general
|
||||
const bool lvalue = m_varp->isSigUserRWPublic();
|
||||
nodep->addStmtp(
|
||||
nodep->addStmtsp(
|
||||
new AstVarRef(nodep->fileline(), m_varp, lvalue ? VAccess::WRITE : VAccess::READ));
|
||||
}
|
||||
}
|
||||
|
|
@ -596,7 +596,7 @@ private:
|
|||
sensesp->unlinkFrBackWithNext();
|
||||
alwaysp->sensesp(sensesp);
|
||||
}
|
||||
if (nodep->stmtsp()) alwaysp->addStmtp(nodep->stmtsp()->unlinkFrBackWithNext());
|
||||
if (nodep->stmtsp()) alwaysp->addStmtsp(nodep->stmtsp()->unlinkFrBackWithNext());
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ private:
|
|||
// Initial assignments under function/tasks can just be simple
|
||||
// assignments without the initial
|
||||
if (m_ftaskp) {
|
||||
VL_DO_DANGLING(nodep->replaceWith(nodep->bodysp()->unlinkFrBackWithNext()), nodep);
|
||||
VL_DO_DANGLING(nodep->replaceWith(nodep->stmtsp()->unlinkFrBackWithNext()), nodep);
|
||||
}
|
||||
}
|
||||
void visit(AstNodeCoverOrAssert* nodep) override {
|
||||
|
|
@ -483,7 +483,7 @@ private:
|
|||
}
|
||||
varoutp = varp;
|
||||
// Tie off
|
||||
m_modp->addStmtp(
|
||||
m_modp->addStmtsp(
|
||||
new AstAssignW(varp->fileline(),
|
||||
new AstVarRef(varp->fileline(), varp, VAccess::WRITE),
|
||||
new AstConst(varp->fileline(), AstConst::BitFalse())));
|
||||
|
|
|
|||
|
|
@ -565,7 +565,7 @@ private:
|
|||
return false;
|
||||
}
|
||||
if (const AstNodeCond* const condp = VN_CAST(nodep, NodeCond)) {
|
||||
return yieldsOneOrZero(condp->expr1p()) && yieldsOneOrZero(condp->expr2p());
|
||||
return yieldsOneOrZero(condp->thenp()) && yieldsOneOrZero(condp->elsep());
|
||||
}
|
||||
if (const AstCCast* const castp = VN_CAST(nodep, CCast)) {
|
||||
// Cast never sign extends
|
||||
|
|
@ -593,7 +593,7 @@ private:
|
|||
return new AstConst{rhsp->fileline(), AstConst::BitTrue{}, condTrue};
|
||||
} else if (const AstNodeCond* const condp = extractCondFromRhs(rhsp)) {
|
||||
AstNode* const resp
|
||||
= condTrue ? condp->expr1p()->unlinkFrBack() : condp->expr2p()->unlinkFrBack();
|
||||
= condTrue ? condp->thenp()->unlinkFrBack() : condp->elsep()->unlinkFrBack();
|
||||
if (condp == rhsp) return resp;
|
||||
if (const AstAnd* const andp = VN_CAST(rhsp, And)) {
|
||||
UASSERT_OBJ(andp->rhsp() == condp, rhsp, "Should not try to fold this");
|
||||
|
|
@ -676,7 +676,7 @@ private:
|
|||
// Construct the new RHSs and add to branches
|
||||
thenp->rhsp(foldAndUnlink(rhsp, true));
|
||||
elsep->rhsp(foldAndUnlink(rhsp, false));
|
||||
resultp->addIfsp(thenp);
|
||||
resultp->addThensp(thenp);
|
||||
resultp->addElsesp(elsep);
|
||||
// Cleanup
|
||||
VL_DO_DANGLING(rhsp->deleteTree(), rhsp);
|
||||
|
|
@ -684,8 +684,8 @@ private:
|
|||
AstNodeIf* const ifp = VN_AS(currp, NodeIf);
|
||||
UASSERT_OBJ(ifp, currp, "Must be AstNodeIf");
|
||||
// Move branch contents under new if
|
||||
if (AstNode* const listp = ifp->ifsp()) {
|
||||
resultp->addIfsp(listp->unlinkFrBackWithNext());
|
||||
if (AstNode* const listp = ifp->thensp()) {
|
||||
resultp->addThensp(listp->unlinkFrBackWithNext());
|
||||
}
|
||||
if (AstNode* const listp = ifp->elsesp()) {
|
||||
resultp->addElsesp(listp->unlinkFrBackWithNext());
|
||||
|
|
@ -695,7 +695,7 @@ private:
|
|||
}
|
||||
} while (nextp);
|
||||
// Merge the branches of the resulting AstIf after re-analysis
|
||||
if (resultp->ifsp()) m_workQueuep->push(resultp->ifsp());
|
||||
if (resultp->thensp()) m_workQueuep->push(resultp->thensp());
|
||||
if (resultp->elsesp()) m_workQueuep->push(resultp->elsesp());
|
||||
} else if (AstNodeIf* const ifp = VN_CAST(m_mgFirstp, NodeIf)) {
|
||||
// There was nothing to merge this AstNodeIf with, so try to merge its branches.
|
||||
|
|
@ -711,7 +711,7 @@ private:
|
|||
AstNode::user2ClearTree();
|
||||
// Merge recursively within the branches of an un-merged AstNodeIF
|
||||
if (recursivep) {
|
||||
iterateAndNextNull(recursivep->ifsp());
|
||||
iterateAndNextNull(recursivep->thensp());
|
||||
iterateAndNextNull(recursivep->elsesp());
|
||||
// Close a pending merge to ensure merge state is
|
||||
// reset as expected at the end of this function
|
||||
|
|
@ -840,7 +840,7 @@ private:
|
|||
// Check if mergeable
|
||||
if (!checkOrMakeMergeable(nodep)) {
|
||||
// If not mergeable, try to merge the branches
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
iterateAndNextNull(nodep->thensp());
|
||||
iterateAndNextNull(nodep->elsesp());
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1789,7 +1789,7 @@ void OrderProcess::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
|
|||
<< " s=" << cvtToHex(scopep) << " " << lvertexp << endl);
|
||||
AstActive* const newActivep
|
||||
= processMoveOneLogic(lvertexp, m_pomNewFuncp /*ref*/, m_pomNewStmts /*ref*/);
|
||||
if (newActivep) m_scopetop.addActivep(newActivep);
|
||||
if (newActivep) m_scopetop.addBlocksp(newActivep);
|
||||
processMoveDoneOne(vertexp);
|
||||
}
|
||||
|
||||
|
|
@ -1811,7 +1811,7 @@ AstActive* OrderProcess::processMoveOneLogic(const OrderLogicVertex* lvertexp,
|
|||
// procedures. Everything else is handled in one go
|
||||
AstNodeProcedure* const procp = VN_CAST(nodep, NodeProcedure);
|
||||
if (procp && !v3Global.opt.profCFuncs()) {
|
||||
nodep = procp->bodysp();
|
||||
nodep = procp->stmtsp();
|
||||
pushDeletep(procp);
|
||||
}
|
||||
|
||||
|
|
@ -1831,7 +1831,7 @@ AstActive* OrderProcess::processMoveOneLogic(const OrderLogicVertex* lvertexp,
|
|||
newFuncpr->isLoose(true);
|
||||
newStmtsr = 0;
|
||||
if (domainp->hasInitial() || domainp->hasSettle()) newFuncpr->slow(true);
|
||||
scopep->addActivep(newFuncpr);
|
||||
scopep->addBlocksp(newFuncpr);
|
||||
// Create top call to it
|
||||
AstCCall* const callp = new AstCCall(nodep->fileline(), newFuncpr);
|
||||
// Where will we be adding the call?
|
||||
|
|
@ -1886,7 +1886,7 @@ void OrderProcess::processMTasksInitial(InitialLogicE logic_type) {
|
|||
}
|
||||
AstActive* const newActivep
|
||||
= processMoveOneLogic(initp, initCFunc /*ref*/, initStmts /*ref*/);
|
||||
if (newActivep) m_scopetop.addActivep(newActivep);
|
||||
if (newActivep) m_scopetop.addBlocksp(newActivep);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1966,7 +1966,7 @@ void OrderProcess::processMTasks() {
|
|||
// of the MTask graph.
|
||||
FileLine* const rootFlp = v3Global.rootp()->fileline();
|
||||
AstExecGraph* const execGraphp = new AstExecGraph{rootFlp, "eval"};
|
||||
m_scopetop.addActivep(execGraphp);
|
||||
m_scopetop.addBlocksp(execGraphp);
|
||||
|
||||
// Create CFuncs and bodies for each MTask.
|
||||
GraphStream<MTaskVxIdLessThan> emit_mtasks(&mtasks);
|
||||
|
|
@ -2018,7 +2018,7 @@ void OrderProcess::processMTasks() {
|
|||
const MTaskState& fromState = mtaskStates[fromp->id()];
|
||||
new V3GraphEdge(depGraphp, fromState.m_execMTaskp, state.m_execMTaskp, 1);
|
||||
}
|
||||
execGraphp->addMTaskBodyp(bodyp);
|
||||
execGraphp->addMTaskBodiesp(bodyp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1132,7 +1132,7 @@ class ParamVisitor final : public VNVisitor {
|
|||
// NOT recurse the body.
|
||||
V3Const::constifyGenerateParamsEdit(nodep->condp()); // condp may change
|
||||
if (const AstConst* const constp = VN_CAST(nodep->condp(), Const)) {
|
||||
if (AstNode* const keepp = (constp->isZero() ? nodep->elsesp() : nodep->ifsp())) {
|
||||
if (AstNode* const keepp = (constp->isZero() ? nodep->elsesp() : nodep->thensp())) {
|
||||
keepp->unlinkFrBackWithNext();
|
||||
nodep->replaceWith(keepp);
|
||||
} else {
|
||||
|
|
@ -1150,9 +1150,7 @@ class ParamVisitor final : public VNVisitor {
|
|||
//! expression, since this is currently restricted to simple comparisons. If we ever do
|
||||
//! move to more generic constant expressions, such code will be needed here.
|
||||
void visit(AstBegin* nodep) override {
|
||||
if (nodep->genforp()) {
|
||||
AstGenFor* const forp = VN_AS(nodep->genforp(), GenFor);
|
||||
UASSERT_OBJ(forp, nodep, "Non-GENFOR under generate-for BEGIN");
|
||||
if (AstGenFor* const forp = VN_AS(nodep->genforp(), GenFor)) {
|
||||
// We should have a GENFOR under here. We will be replacing the begin,
|
||||
// so process here rather than at the generate to avoid iteration problems
|
||||
UINFO(9, " BEGIN " << nodep << endl);
|
||||
|
|
@ -1211,7 +1209,7 @@ class ParamVisitor final : public VNVisitor {
|
|||
if (const AstConst* const ccondp = VN_CAST(ep, Const)) {
|
||||
V3Number match(nodep, 1);
|
||||
match.opEq(ccondp->num(), exprp->num());
|
||||
if (!keepp && match.isNeqZero()) keepp = itemp->bodysp();
|
||||
if (!keepp && match.isNeqZero()) keepp = itemp->stmtsp();
|
||||
} else {
|
||||
itemp->v3error("Generate Case item does not evaluate to constant");
|
||||
}
|
||||
|
|
@ -1222,7 +1220,7 @@ class ParamVisitor final : public VNVisitor {
|
|||
for (AstCaseItem* itemp = nodep->itemsp(); itemp;
|
||||
itemp = VN_AS(itemp->nextp(), CaseItem)) {
|
||||
if (itemp->isDefault()) {
|
||||
if (!keepp) keepp = itemp->bodysp();
|
||||
if (!keepp) keepp = itemp->stmtsp();
|
||||
}
|
||||
}
|
||||
// Replace
|
||||
|
|
@ -1269,7 +1267,7 @@ public:
|
|||
});
|
||||
|
||||
// Re-insert modules
|
||||
for (AstNodeModule* const modp : modps) netlistp->addModulep(modp);
|
||||
for (AstNodeModule* const modp : modps) netlistp->addModulesp(modp);
|
||||
}
|
||||
}
|
||||
~ParamVisitor() override = default;
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
|
|||
if (errmsg != "") return; // Threw error already
|
||||
// Create fake node for later error reporting
|
||||
AstNodeModule* const nodep = new AstNotFoundModule(fileline, modname);
|
||||
v3Global.rootp()->addModulep(nodep);
|
||||
v3Global.rootp()->addModulesp(nodep);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3051,7 +3051,7 @@ static void addMTaskToFunction(const ThreadSchedule& schedule, const uint32_t th
|
|||
AstVar* const varp = new AstVar(fl, VVarType::MODULETEMP, name, mtaskStateDtypep);
|
||||
varp->valuep(new AstConst(fl, nDependencies));
|
||||
varp->protect(false); // Do not protect as we still have references in AstText
|
||||
modp->addStmtp(varp);
|
||||
modp->addStmtsp(varp);
|
||||
// For now, reference is still via text bashing
|
||||
addStrStmt("vlSelf->" + name + +".waitUntilUpstreamDone(even_cycle);\n");
|
||||
}
|
||||
|
|
@ -3112,7 +3112,7 @@ static const std::vector<AstCFunc*> createThreadFunctions(const ThreadSchedule&
|
|||
const uint32_t threadId = schedule.threadId(thread.front());
|
||||
const string name{"__Vthread__" + tag + "__" + cvtToStr(threadId)};
|
||||
AstCFunc* const funcp = new AstCFunc(fl, name, nullptr, "void");
|
||||
modp->addStmtp(funcp);
|
||||
modp->addStmtsp(funcp);
|
||||
funcps.push_back(funcp);
|
||||
funcp->isStatic(true); // Uses void self pointer, so static and hand rolled
|
||||
funcp->isLoose(true);
|
||||
|
|
@ -3140,7 +3140,7 @@ static const std::vector<AstCFunc*> createThreadFunctions(const ThreadSchedule&
|
|||
= new AstVar(fl, VVarType::MODULETEMP, "__Vm_mtaskstate_final", mtaskStateDtypep);
|
||||
varp->valuep(new AstConst(fl, funcps.size()));
|
||||
varp->protect(false); // Do not protect as we still have references in AstText
|
||||
modp->addStmtp(varp);
|
||||
modp->addStmtsp(varp);
|
||||
|
||||
return funcps;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ private:
|
|||
iterateAndNextNull(nodep->condp());
|
||||
m_inWhilep = nullptr;
|
||||
startStatement(nodep);
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
iterateAndNextNull(nodep->incsp());
|
||||
m_stmtp = nullptr;
|
||||
}
|
||||
|
|
@ -329,7 +329,7 @@ private:
|
|||
}
|
||||
void visit(AstNodeCond* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (nodep->expr1p()->isWide() && !VN_IS(nodep->condp(), Const)
|
||||
if (nodep->thenp()->isWide() && !VN_IS(nodep->condp(), Const)
|
||||
&& !VN_IS(nodep->condp(), VarRef)) {
|
||||
// We're going to need the expression several times in the expanded code,
|
||||
// so might as well make it a common expression
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ private:
|
|||
}
|
||||
|
||||
void addComment(AstTextBlock* txtp, FileLine* fl, const string& comment) {
|
||||
txtp->addNodep(new AstComment{fl, comment});
|
||||
txtp->addNodesp(new AstComment{fl, comment});
|
||||
}
|
||||
|
||||
void hashComment(AstTextBlock* txtp, FileLine* fl) {
|
||||
|
|
@ -143,7 +143,7 @@ private:
|
|||
|
||||
// Module declaration
|
||||
m_modPortsp = new AstTextBlock{fl, "module " + m_libName + " (\n", false, true};
|
||||
txtp->addNodep(m_modPortsp);
|
||||
txtp->addNodesp(m_modPortsp);
|
||||
txtp->addText(fl, ");\n\n");
|
||||
|
||||
// Timescale
|
||||
|
|
@ -177,7 +177,7 @@ private:
|
|||
"(\n",
|
||||
false, true};
|
||||
m_comboPortsp->addText(fl, "chandle handle__V\n");
|
||||
txtp->addNodep(m_comboPortsp);
|
||||
txtp->addNodesp(m_comboPortsp);
|
||||
txtp->addText(fl, ");\n\n");
|
||||
seqComment(txtp, fl);
|
||||
if (m_hasClk) {
|
||||
|
|
@ -187,7 +187,7 @@ private:
|
|||
"(\n",
|
||||
false, true};
|
||||
m_seqPortsp->addText(fl, "chandle handle__V\n");
|
||||
txtp->addNodep(m_seqPortsp);
|
||||
txtp->addNodesp(m_seqPortsp);
|
||||
txtp->addText(fl, ");\n\n");
|
||||
}
|
||||
comboIgnoreComment(txtp, fl);
|
||||
|
|
@ -197,7 +197,7 @@ private:
|
|||
"(\n",
|
||||
false, true};
|
||||
m_comboIgnorePortsp->addText(fl, "chandle handle__V\n");
|
||||
txtp->addNodep(m_comboIgnorePortsp);
|
||||
txtp->addNodesp(m_comboIgnorePortsp);
|
||||
txtp->addText(fl, ");\n\n");
|
||||
|
||||
finalComment(txtp, fl);
|
||||
|
|
@ -227,17 +227,17 @@ private:
|
|||
txtp->addText(fl, "\n");
|
||||
|
||||
m_comboDeclsp = new AstTextBlock{fl};
|
||||
txtp->addNodep(m_comboDeclsp);
|
||||
txtp->addNodesp(m_comboDeclsp);
|
||||
m_seqDeclsp = new AstTextBlock{fl};
|
||||
txtp->addNodep(m_seqDeclsp);
|
||||
txtp->addNodesp(m_seqDeclsp);
|
||||
m_tmpDeclsp = new AstTextBlock{fl};
|
||||
txtp->addNodep(m_tmpDeclsp);
|
||||
txtp->addNodesp(m_tmpDeclsp);
|
||||
|
||||
// CPP hash value
|
||||
addComment(txtp, fl, "Hash value to make sure this file and the corresponding");
|
||||
addComment(txtp, fl, "library agree");
|
||||
m_hashValuep = new AstTextBlock{fl, "localparam int protectlib_hash__V = 32'd"};
|
||||
txtp->addNodep(m_hashValuep);
|
||||
txtp->addNodesp(m_hashValuep);
|
||||
txtp->addText(fl, "\n");
|
||||
|
||||
// Initial
|
||||
|
|
@ -256,7 +256,7 @@ private:
|
|||
+ m_libName + "_protectlib_combo_update(\n",
|
||||
false, true};
|
||||
m_comboParamsp->addText(fl, "handle__V\n");
|
||||
txtp->addNodep(m_comboParamsp);
|
||||
txtp->addNodesp(m_comboParamsp);
|
||||
txtp->addText(fl, ");\n");
|
||||
txtp->addText(fl, "end\n\n");
|
||||
|
||||
|
|
@ -264,21 +264,21 @@ private:
|
|||
if (m_hasClk) {
|
||||
addComment(txtp, fl, "Evaluate clock edges");
|
||||
m_clkSensp = new AstTextBlock{fl, "always @(", false, true};
|
||||
txtp->addNodep(m_clkSensp);
|
||||
txtp->addNodesp(m_clkSensp);
|
||||
txtp->addText(fl, ") begin\n");
|
||||
m_comboIgnoreParamsp
|
||||
= new AstTextBlock{fl, m_libName + "_protectlib_combo_ignore(\n", false, true};
|
||||
m_comboIgnoreParamsp->addText(fl, "handle__V\n");
|
||||
txtp->addNodep(m_comboIgnoreParamsp);
|
||||
txtp->addNodesp(m_comboIgnoreParamsp);
|
||||
txtp->addText(fl, ");\n");
|
||||
m_seqParamsp = new AstTextBlock{
|
||||
fl, "last_seq_seqnum__V <= " + m_libName + "_protectlib_seq_update(\n", false,
|
||||
true};
|
||||
m_seqParamsp->addText(fl, "handle__V\n");
|
||||
txtp->addNodep(m_seqParamsp);
|
||||
txtp->addNodesp(m_seqParamsp);
|
||||
txtp->addText(fl, ");\n");
|
||||
m_nbAssignsp = new AstTextBlock{fl};
|
||||
txtp->addNodep(m_nbAssignsp);
|
||||
txtp->addNodesp(m_nbAssignsp);
|
||||
txtp->addText(fl, "end\n\n");
|
||||
}
|
||||
|
||||
|
|
@ -288,13 +288,13 @@ private:
|
|||
if (m_hasClk) {
|
||||
m_seqAssignsp = new AstTextBlock{fl, "if (last_seq_seqnum__V > "
|
||||
"last_combo_seqnum__V) begin\n"};
|
||||
txtp->addNodep(m_seqAssignsp);
|
||||
txtp->addNodesp(m_seqAssignsp);
|
||||
m_comboAssignsp = new AstTextBlock{fl, "end\nelse begin\n"};
|
||||
txtp->addNodep(m_comboAssignsp);
|
||||
txtp->addNodesp(m_comboAssignsp);
|
||||
txtp->addText(fl, "end\n");
|
||||
} else {
|
||||
m_comboAssignsp = new AstTextBlock{fl, ""};
|
||||
txtp->addNodep(m_comboAssignsp);
|
||||
txtp->addNodesp(m_comboAssignsp);
|
||||
}
|
||||
txtp->addText(fl, "end\n\n");
|
||||
|
||||
|
|
@ -341,7 +341,7 @@ private:
|
|||
+ "_protectlib_check_hash"
|
||||
"(int protectlib_hash__V) {\n");
|
||||
m_cHashValuep = new AstTextBlock{fl, "const int expected_hash__V = "};
|
||||
txtp->addNodep(m_cHashValuep);
|
||||
txtp->addNodesp(m_cHashValuep);
|
||||
txtp->addText(fl, /**/ "if (protectlib_hash__V != expected_hash__V) {\n");
|
||||
txtp->addText(fl, /****/ "fprintf(stderr, \"%%Error: cannot use " + m_libName
|
||||
+ " library, "
|
||||
|
|
@ -364,13 +364,13 @@ private:
|
|||
m_cComboParamsp = new AstTextBlock{
|
||||
fl, "long long " + m_libName + "_protectlib_combo_update(\n", false, true};
|
||||
m_cComboParamsp->addText(fl, "void* vhandlep__V\n");
|
||||
txtp->addNodep(m_cComboParamsp);
|
||||
txtp->addNodesp(m_cComboParamsp);
|
||||
txtp->addText(fl, ")\n");
|
||||
m_cComboInsp = new AstTextBlock{fl, "{\n"};
|
||||
castPtr(fl, m_cComboInsp);
|
||||
txtp->addNodep(m_cComboInsp);
|
||||
txtp->addNodesp(m_cComboInsp);
|
||||
m_cComboOutsp = new AstTextBlock{fl, "handlep__V->eval();\n"};
|
||||
txtp->addNodep(m_cComboOutsp);
|
||||
txtp->addNodesp(m_cComboOutsp);
|
||||
txtp->addText(fl, "return handlep__V->m_seqnum++;\n");
|
||||
txtp->addText(fl, "}\n\n");
|
||||
|
||||
|
|
@ -379,13 +379,13 @@ private:
|
|||
m_cSeqParamsp = new AstTextBlock{
|
||||
fl, "long long " + m_libName + "_protectlib_seq_update(\n", false, true};
|
||||
m_cSeqParamsp->addText(fl, "void* vhandlep__V\n");
|
||||
txtp->addNodep(m_cSeqParamsp);
|
||||
txtp->addNodesp(m_cSeqParamsp);
|
||||
txtp->addText(fl, ")\n");
|
||||
m_cSeqClksp = new AstTextBlock{fl, "{\n"};
|
||||
castPtr(fl, m_cSeqClksp);
|
||||
txtp->addNodep(m_cSeqClksp);
|
||||
txtp->addNodesp(m_cSeqClksp);
|
||||
m_cSeqOutsp = new AstTextBlock{fl, "handlep__V->eval();\n"};
|
||||
txtp->addNodep(m_cSeqOutsp);
|
||||
txtp->addNodesp(m_cSeqOutsp);
|
||||
txtp->addText(fl, "return handlep__V->m_seqnum++;\n");
|
||||
txtp->addText(fl, "}\n\n");
|
||||
}
|
||||
|
|
@ -394,7 +394,7 @@ private:
|
|||
m_cIgnoreParamsp = new AstTextBlock{
|
||||
fl, "void " + m_libName + "_protectlib_combo_ignore(\n", false, true};
|
||||
m_cIgnoreParamsp->addText(fl, "void* vhandlep__V\n");
|
||||
txtp->addNodep(m_cIgnoreParamsp);
|
||||
txtp->addNodesp(m_cIgnoreParamsp);
|
||||
txtp->addText(fl, ")\n");
|
||||
txtp->addText(fl, "{ }\n\n");
|
||||
|
||||
|
|
@ -448,7 +448,7 @@ private:
|
|||
void handleClock(AstVar* varp) {
|
||||
FileLine* const fl = varp->fileline();
|
||||
handleInput(varp);
|
||||
m_seqPortsp->addNodep(varp->cloneTree(false));
|
||||
m_seqPortsp->addNodesp(varp->cloneTree(false));
|
||||
if (m_hasClk) {
|
||||
m_seqParamsp->addText(fl, varp->name() + "\n");
|
||||
m_clkSensp->addText(fl, "posedge " + varp->name() + " or negedge " + varp->name());
|
||||
|
|
@ -460,30 +460,30 @@ private:
|
|||
void handleDataInput(AstVar* varp) {
|
||||
FileLine* const fl = varp->fileline();
|
||||
handleInput(varp);
|
||||
m_comboPortsp->addNodep(varp->cloneTree(false));
|
||||
m_comboPortsp->addNodesp(varp->cloneTree(false));
|
||||
m_comboParamsp->addText(fl, varp->name() + "\n");
|
||||
m_comboIgnorePortsp->addNodep(varp->cloneTree(false));
|
||||
m_comboIgnorePortsp->addNodesp(varp->cloneTree(false));
|
||||
if (m_hasClk) m_comboIgnoreParamsp->addText(fl, varp->name() + "\n");
|
||||
m_cComboParamsp->addText(fl, varp->dpiArgType(true, false) + "\n");
|
||||
m_cComboInsp->addText(fl, cInputConnection(varp));
|
||||
m_cIgnoreParamsp->addText(fl, varp->dpiArgType(true, false) + "\n");
|
||||
}
|
||||
|
||||
void handleInput(AstVar* varp) { m_modPortsp->addNodep(varp->cloneTree(false)); }
|
||||
void handleInput(AstVar* varp) { m_modPortsp->addNodesp(varp->cloneTree(false)); }
|
||||
|
||||
static void addLocalVariable(AstTextBlock* textp, AstVar* varp, const char* suffix) {
|
||||
AstVar* const newVarp
|
||||
= new AstVar{varp->fileline(), VVarType::VAR, varp->name() + suffix, varp->dtypep()};
|
||||
textp->addNodep(newVarp);
|
||||
textp->addNodesp(newVarp);
|
||||
}
|
||||
|
||||
void handleOutput(AstVar* varp) {
|
||||
FileLine* const fl = varp->fileline();
|
||||
m_modPortsp->addNodep(varp->cloneTree(false));
|
||||
m_comboPortsp->addNodep(varp->cloneTree(false));
|
||||
m_modPortsp->addNodesp(varp->cloneTree(false));
|
||||
m_comboPortsp->addNodesp(varp->cloneTree(false));
|
||||
m_comboParamsp->addText(fl, varp->name() + "_combo__V\n");
|
||||
if (m_hasClk) {
|
||||
m_seqPortsp->addNodep(varp->cloneTree(false));
|
||||
m_seqPortsp->addNodesp(varp->cloneTree(false));
|
||||
m_seqParamsp->addText(fl, varp->name() + "_tmp__V\n");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ private:
|
|||
varp->isStatic(true);
|
||||
varp->valuep(initp);
|
||||
// Add to root, as don't know module we are in, and aids later structure sharing
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp);
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp);
|
||||
UASSERT_OBJ(nodep->itemsp(), nodep, "Enum without items");
|
||||
for (AstEnumItem* itemp = nodep->itemsp(); itemp;
|
||||
itemp = VN_AS(itemp->nextp(), EnumItem)) {
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ private:
|
|||
AstWhile* const whilep = new AstWhile(fl, condp, nullptr, incp);
|
||||
initp->addNext(whilep);
|
||||
bodyp->replaceWith(initp);
|
||||
whilep->addBodysp(bodyp);
|
||||
whilep->addStmtsp(bodyp);
|
||||
|
||||
// Replace constant index with new loop index
|
||||
AstNode* const offsetp
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ private:
|
|||
if (m_modp->isTop()) {
|
||||
v3Global.rootp()->createTopScope(m_scopep);
|
||||
} else {
|
||||
m_modp->addStmtp(m_scopep);
|
||||
m_modp->addStmtsp(m_scopep);
|
||||
}
|
||||
|
||||
// Copy blocks into this scope
|
||||
|
|
@ -188,7 +188,7 @@ private:
|
|||
UINFO(4, " Move " << nodep << endl);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
m_scopep->addBlocksp(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
}
|
||||
void visit(AstAssignAlias* nodep) override {
|
||||
|
|
@ -196,7 +196,7 @@ private:
|
|||
UINFO(4, " Move " << nodep << endl);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
m_scopep->addBlocksp(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
}
|
||||
void visit(AstAssignVarScope* nodep) override {
|
||||
|
|
@ -204,7 +204,7 @@ private:
|
|||
UINFO(4, " Move " << nodep << endl);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
m_scopep->addBlocksp(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
}
|
||||
void visit(AstAssignW* nodep) override {
|
||||
|
|
@ -212,7 +212,7 @@ private:
|
|||
UINFO(4, " Move " << nodep << endl);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
m_scopep->addBlocksp(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
}
|
||||
void visit(AstAlwaysPublic* nodep) override {
|
||||
|
|
@ -220,7 +220,7 @@ private:
|
|||
UINFO(4, " Move " << nodep << endl);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
m_scopep->addBlocksp(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
}
|
||||
void visit(AstCoverToggle* nodep) override {
|
||||
|
|
@ -228,7 +228,7 @@ private:
|
|||
UINFO(4, " Move " << nodep << endl);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
m_scopep->addBlocksp(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
}
|
||||
void visit(AstCFunc* nodep) override {
|
||||
|
|
@ -236,7 +236,7 @@ private:
|
|||
UINFO(4, " CFUNC " << nodep << endl);
|
||||
AstCFunc* const clonep = nodep->cloneTree(false);
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
m_scopep->addBlocksp(clonep);
|
||||
clonep->scopep(m_scopep);
|
||||
// We iterate under the *clone*
|
||||
iterateChildren(clonep);
|
||||
|
|
@ -253,7 +253,7 @@ private:
|
|||
clonep = nodep->cloneTree(false);
|
||||
}
|
||||
nodep->user2p(clonep);
|
||||
m_scopep->addActivep(clonep);
|
||||
m_scopep->addBlocksp(clonep);
|
||||
// We iterate under the *clone*
|
||||
iterateChildren(clonep);
|
||||
}
|
||||
|
|
@ -272,7 +272,7 @@ private:
|
|||
}
|
||||
UASSERT_OBJ(m_scopep, nodep, "No scope for var");
|
||||
m_varScopes.emplace(std::make_pair(nodep, m_scopep), varscp);
|
||||
m_scopep->addVarp(varscp);
|
||||
m_scopep->addVarsp(varscp);
|
||||
}
|
||||
}
|
||||
void visit(AstVarRef* nodep) override {
|
||||
|
|
@ -295,14 +295,14 @@ private:
|
|||
// TOP and above will be the user's name().
|
||||
// Note 'TOP.' is stripped by scopePrettyName
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstNode* afterp = nodep->scopeAttrp();
|
||||
AstText* afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeAttrp(new AstText(nodep->fileline(), prefix));
|
||||
if (afterp) nodep->scopeAttrp(afterp);
|
||||
nodep->addScopeAttrp(new AstText(nodep->fileline(), prefix));
|
||||
if (afterp) nodep->addScopeAttrp(afterp);
|
||||
afterp = nodep->scopeEntrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeEntrp(new AstText(nodep->fileline(), prefix));
|
||||
if (afterp) nodep->scopeEntrp(afterp);
|
||||
nodep->addScopeEntrp(new AstText(nodep->fileline(), prefix));
|
||||
if (afterp) nodep->addScopeEntrp(afterp);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstScope* nodep) override {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public:
|
|||
|
||||
// Not found, create a new one
|
||||
AstSenTree* const newSenTreep = senTreep->cloneTree(false);
|
||||
m_topScopep->addSenTreep(newSenTreep);
|
||||
m_topScopep->addSenTreesp(newSenTreep);
|
||||
m_trees.emplace(*newSenTreep);
|
||||
return newSenTreep;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -513,7 +513,7 @@ private:
|
|||
iterateAndNextNull(nodep->condp());
|
||||
if (optimizable()) {
|
||||
if (fetchConst(nodep->condp())->num().isNeqZero()) {
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
iterateAndNextNull(nodep->thensp());
|
||||
} else {
|
||||
iterateAndNextNull(nodep->elsesp());
|
||||
}
|
||||
|
|
@ -647,11 +647,11 @@ private:
|
|||
iterate(nodep->condp());
|
||||
if (optimizable()) {
|
||||
if (fetchConst(nodep->condp())->num().isNeqZero()) {
|
||||
iterate(nodep->expr1p());
|
||||
newValue(nodep, fetchValue(nodep->expr1p()));
|
||||
iterate(nodep->thenp());
|
||||
newValue(nodep, fetchValue(nodep->thenp()));
|
||||
} else {
|
||||
iterate(nodep->expr2p());
|
||||
newValue(nodep, fetchValue(nodep->expr2p()));
|
||||
iterate(nodep->elsep());
|
||||
newValue(nodep, fetchValue(nodep->elsep()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -835,7 +835,7 @@ private:
|
|||
V3Number match{nodep, 1};
|
||||
match.opEq(fetchConst(nodep->exprp())->num(), fetchConst(ep)->num());
|
||||
if (match.isNeqZero()) {
|
||||
iterateAndNextNull(itemp->bodysp());
|
||||
iterateAndNextNull(itemp->stmtsp());
|
||||
hit = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -847,7 +847,7 @@ private:
|
|||
itemp = VN_AS(itemp->nextp(), CaseItem)) {
|
||||
if (hit) break;
|
||||
if (!hit && itemp->isDefault()) {
|
||||
iterateAndNextNull(itemp->bodysp());
|
||||
iterateAndNextNull(itemp->stmtsp());
|
||||
hit = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -917,7 +917,7 @@ private:
|
|||
if (!fetchConst(nodep->condp())->num().isNeqZero()) { //
|
||||
break;
|
||||
}
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
iterateAndNextNull(nodep->incsp());
|
||||
if (loops++ > unrollCount() * 16) {
|
||||
clearOptimizable(nodep, "Loop unrolling took too long; probably this is an"
|
||||
|
|
@ -952,7 +952,7 @@ private:
|
|||
if (!fetchConst(nodep->condp())->num().isNeqZero()) { //
|
||||
break;
|
||||
}
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
if (jumpingOver(nodep)) break;
|
||||
iterateAndNextNull(nodep->incsp());
|
||||
if (jumpingOver(nodep)) break;
|
||||
|
|
|
|||
|
|
@ -101,8 +101,8 @@ class SliceVisitor final : public VNVisitor {
|
|||
} else if (AstNodeCond* const snodep = VN_CAST(nodep, NodeCond)) {
|
||||
UINFO(9, " cloneCond(" << elements << "," << offset << ") " << nodep << endl);
|
||||
return snodep->cloneType(snodep->condp()->cloneTree(false),
|
||||
cloneAndSel(snodep->expr1p(), elements, offset),
|
||||
cloneAndSel(snodep->expr2p(), elements, offset));
|
||||
cloneAndSel(snodep->thenp(), elements, offset),
|
||||
cloneAndSel(snodep->elsep(), elements, offset));
|
||||
} else if (const AstSliceSel* const snodep = VN_CAST(nodep, SliceSel)) {
|
||||
UINFO(9, " cloneSliceSel(" << elements << "," << offset << ") " << nodep << endl);
|
||||
const int leOffset = (snodep->declRange().lo()
|
||||
|
|
|
|||
|
|
@ -601,14 +601,14 @@ protected:
|
|||
UINFO(4, " ALW " << nodep << endl);
|
||||
if (debug() >= 9) nodep->dumpTree(cout, " alwIn:: ");
|
||||
scoreboardClear();
|
||||
processBlock(nodep->bodysp());
|
||||
processBlock(nodep->stmtsp());
|
||||
if (debug() >= 9) nodep->dumpTree(cout, " alwOut: ");
|
||||
}
|
||||
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
UINFO(4, " IF " << nodep << endl);
|
||||
iterateAndNextNull(nodep->condp());
|
||||
processBlock(nodep->ifsp());
|
||||
processBlock(nodep->thensp());
|
||||
processBlock(nodep->elsesp());
|
||||
}
|
||||
|
||||
|
|
@ -713,14 +713,14 @@ public:
|
|||
// Put a placeholder node into stmtp to track our position.
|
||||
// We'll strip these out after the blocks are fully cloned.
|
||||
AstSplitPlaceholder* const placeholderp = makePlaceholderp();
|
||||
alwaysp->addStmtp(placeholderp);
|
||||
alwaysp->addStmtsp(placeholderp);
|
||||
m_addAfter[color] = placeholderp;
|
||||
m_newBlocksp->push_back(alwaysp);
|
||||
}
|
||||
// Scan the body of the always. We'll handle if/else
|
||||
// specially, everything else is a leaf node that we can
|
||||
// just clone into one of the split always blocks.
|
||||
iterateAndNextNull(m_origAlwaysp->bodysp());
|
||||
iterateAndNextNull(m_origAlwaysp->stmtsp());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
@ -776,7 +776,7 @@ protected:
|
|||
m_addAfter[color] = if_placeholderp;
|
||||
}
|
||||
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
iterateAndNextNull(nodep->thensp());
|
||||
|
||||
for (const auto& color : colors) m_addAfter[color] = clones[color]->elsesp();
|
||||
|
||||
|
|
@ -804,7 +804,7 @@ class RemovePlaceholdersVisitor final : public VNVisitor {
|
|||
VL_RESTORER(m_isPure);
|
||||
m_isPure = true;
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->ifsp() && !nodep->elsesp() && m_isPure) pushDeletep(nodep->unlinkFrBack());
|
||||
if (!nodep->thensp() && !nodep->elsesp() && m_isPure) pushDeletep(nodep->unlinkFrBack());
|
||||
}
|
||||
void visit(AstAlways* nodep) override {
|
||||
VL_RESTORER(m_isPure);
|
||||
|
|
@ -812,7 +812,7 @@ class RemovePlaceholdersVisitor final : public VNVisitor {
|
|||
iterateChildren(nodep);
|
||||
if (m_isPure) {
|
||||
bool emptyOrCommentOnly = true;
|
||||
for (AstNode* bodysp = nodep->bodysp(); bodysp; bodysp = bodysp->nextp()) {
|
||||
for (AstNode* bodysp = nodep->stmtsp(); bodysp; bodysp = bodysp->nextp()) {
|
||||
// If this always block contains only AstComment, remove here.
|
||||
// V3Gate will remove anyway.
|
||||
if (!VN_IS(bodysp, Comment)) {
|
||||
|
|
@ -955,7 +955,7 @@ protected:
|
|||
void visit(AstAlways* nodep) override {
|
||||
// build the scoreboard
|
||||
scoreboardClear();
|
||||
scanBlock(nodep->bodysp());
|
||||
scanBlock(nodep->stmtsp());
|
||||
|
||||
if (m_noReorderWhy != "") {
|
||||
// We saw a jump or something else rare that we don't handle.
|
||||
|
|
@ -989,7 +989,7 @@ protected:
|
|||
m_curIfConditional = nodep;
|
||||
iterateAndNextNull(nodep->condp());
|
||||
m_curIfConditional = nullptr;
|
||||
scanBlock(nodep->ifsp());
|
||||
scanBlock(nodep->thensp());
|
||||
scanBlock(nodep->elsesp());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -191,16 +191,16 @@ struct SplitVarImpl {
|
|||
|
||||
template <class T_ALWAYSLIKE>
|
||||
void insertBeginCore(T_ALWAYSLIKE* ap, AstNodeStmt* stmtp, AstNodeModule* modp) {
|
||||
if (ap->isJustOneBodyStmt() && ap->bodysp() == stmtp) {
|
||||
if (ap->isJustOneBodyStmt() && ap->stmtsp() == stmtp) {
|
||||
stmtp->unlinkFrBack();
|
||||
// Insert begin-end because temp value may be inserted to this block later.
|
||||
const std::string name = "__VsplitVarBlk" + cvtToStr(modp->user1Inc(1));
|
||||
ap->addStmtp(new AstBegin{ap->fileline(), name, stmtp});
|
||||
ap->addStmtsp(new AstBegin{ap->fileline(), name, stmtp});
|
||||
}
|
||||
}
|
||||
|
||||
void insertBeginCore(AstInitial* initp, AstNodeStmt* stmtp, AstNodeModule* modp) {
|
||||
if (initp->isJustOneBodyStmt() && initp->bodysp() == stmtp) {
|
||||
if (initp->isJustOneBodyStmt() && initp->stmtsp() == stmtp) {
|
||||
stmtp->unlinkFrBack();
|
||||
// Insert begin-end because temp value may be inserted to this block later.
|
||||
FileLine* const fl = initp->fileline();
|
||||
|
|
@ -477,7 +477,7 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
|||
if (nodep->sensesp()) { // When visiting sensitivity list, always is the context
|
||||
setContextAndIterate(nodep, nodep->sensesp());
|
||||
}
|
||||
for (AstNode* bodysp = nodep->bodysp(); bodysp; bodysp = bodysp->nextp()) {
|
||||
for (AstNode* bodysp = nodep->stmtsp(); bodysp; bodysp = bodysp->nextp()) {
|
||||
iterate(bodysp);
|
||||
}
|
||||
};
|
||||
|
|
@ -485,7 +485,7 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
|||
if (nodep->sensesp()) { // When visiting sensitivity list, always is the context
|
||||
setContextAndIterate(nodep, nodep->sensesp());
|
||||
}
|
||||
for (AstNode* bodysp = nodep->bodysp(); bodysp; bodysp = bodysp->nextp()) {
|
||||
for (AstNode* bodysp = nodep->stmtsp(); bodysp; bodysp = bodysp->nextp()) {
|
||||
iterate(bodysp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ private:
|
|||
{
|
||||
m_counting = false;
|
||||
m_instrs = 0.0;
|
||||
iterateAndNextConstNull(nodep->ifsp());
|
||||
iterateAndNextConstNull(nodep->thensp());
|
||||
ifInstrs = m_instrs;
|
||||
}
|
||||
}
|
||||
|
|
@ -158,7 +158,7 @@ private:
|
|||
// Now collect the stats
|
||||
if (m_counting) {
|
||||
if (ifInstrs >= elseInstrs) {
|
||||
iterateAndNextConstNull(nodep->ifsp());
|
||||
iterateAndNextConstNull(nodep->thensp());
|
||||
} else {
|
||||
iterateAndNextConstNull(nodep->elsesp());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -253,9 +253,9 @@ private:
|
|||
AstVar* const indexVarp
|
||||
= new AstVar{fl, VVarType::BLOCKTEMP, "__Vtableidx" + cvtToStr(m_modTables),
|
||||
VFlagBitPacked{}, static_cast<int>(m_inWidthBits)};
|
||||
m_modp->addStmtp(indexVarp);
|
||||
m_modp->addStmtsp(indexVarp);
|
||||
AstVarScope* const indexVscp = new AstVarScope{indexVarp->fileline(), m_scopep, indexVarp};
|
||||
m_scopep->addVarp(indexVscp);
|
||||
m_scopep->addVarsp(indexVscp);
|
||||
|
||||
// The 'output assigned' table builder
|
||||
TableBuilder outputAssignedTableBuilder{fl};
|
||||
|
|
@ -274,8 +274,8 @@ private:
|
|||
|
||||
// Link it in.
|
||||
// Keep sensitivity list, but delete all else
|
||||
nodep->bodysp()->unlinkFrBackWithNext()->deleteTree();
|
||||
nodep->addStmtp(stmtsp);
|
||||
nodep->stmtsp()->unlinkFrBackWithNext()->deleteTree();
|
||||
nodep->addStmtsp(stmtsp);
|
||||
if (debug() >= 6) nodep->dumpTree(cout, " table_new: ");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ private:
|
|||
}
|
||||
UASSERT_OBJ(m_ctorp, nodep, "class constructor missing"); // LinkDot always makes it
|
||||
for (AstInitialAutomatic* initialp : m_initialps) {
|
||||
if (AstNode* const newp = initialp->bodysp()) {
|
||||
if (AstNode* const newp = initialp->stmtsp()) {
|
||||
newp->unlinkFrBackWithNext();
|
||||
if (!m_ctorp->stmtsp()) {
|
||||
m_ctorp->addStmtsp(newp);
|
||||
|
|
@ -371,7 +371,7 @@ private:
|
|||
newvarp->funcLocal(true);
|
||||
funcp->addInitsp(newvarp);
|
||||
AstVarScope* const newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
|
||||
m_scopep->addVarp(newvscp);
|
||||
m_scopep->addVarsp(newvscp);
|
||||
return newvscp;
|
||||
}
|
||||
AstVarScope* createInputVar(AstCFunc* funcp, const string& name, VBasicDTypeKwd kwd) {
|
||||
|
|
@ -381,7 +381,7 @@ private:
|
|||
newvarp->direction(VDirection::INPUT);
|
||||
funcp->addArgsp(newvarp);
|
||||
AstVarScope* const newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
|
||||
m_scopep->addVarp(newvscp);
|
||||
m_scopep->addVarsp(newvscp);
|
||||
return newvscp;
|
||||
}
|
||||
AstVarScope* createVarScope(AstVar* invarp, const string& name) {
|
||||
|
|
@ -397,9 +397,9 @@ private:
|
|||
= new AstVar{invarp->fileline(), VVarType::BLOCKTEMP, name, invarp};
|
||||
newvarp->funcLocal(false);
|
||||
newvarp->propagateAttrFrom(invarp);
|
||||
m_modp->addStmtp(newvarp);
|
||||
m_modp->addStmtsp(newvarp);
|
||||
AstVarScope* const newvscp = new AstVarScope{newvarp->fileline(), m_scopep, newvarp};
|
||||
m_scopep->addVarp(newvscp);
|
||||
m_scopep->addVarsp(newvscp);
|
||||
return newvscp;
|
||||
}
|
||||
}
|
||||
|
|
@ -766,7 +766,7 @@ private:
|
|||
funcp->protect(false);
|
||||
funcp->cname(nodep->cname());
|
||||
// Add DPI Export to top, since it's a global function
|
||||
m_topScopep->scopep()->addActivep(funcp);
|
||||
m_topScopep->scopep()->addBlocksp(funcp);
|
||||
|
||||
{ // Create dispatch wrapper
|
||||
// Note this function may dispatch to myfunc on a different class.
|
||||
|
|
@ -855,9 +855,9 @@ private:
|
|||
// doesn't rip up the variables on us
|
||||
args += ");\n";
|
||||
AstCStmt* const newp = new AstCStmt(nodep->fileline(), "(*__Vcb)(");
|
||||
newp->addBodysp(argnodesp);
|
||||
newp->addExprsp(argnodesp);
|
||||
VL_DANGLING(argnodesp);
|
||||
newp->addBodysp(new AstText(nodep->fileline(), args, true));
|
||||
newp->addExprsp(new AstText(nodep->fileline(), args, true));
|
||||
funcp->addStmtsp(newp);
|
||||
}
|
||||
|
||||
|
|
@ -899,7 +899,7 @@ private:
|
|||
funcp->protect(false);
|
||||
funcp->pure(nodep->pure());
|
||||
// Add DPI Import to top, since it's a global function
|
||||
m_topScopep->scopep()->addActivep(funcp);
|
||||
m_topScopep->scopep()->addBlocksp(funcp);
|
||||
makePortList(nodep, funcp);
|
||||
return funcp;
|
||||
}
|
||||
|
|
@ -1064,9 +1064,9 @@ private:
|
|||
FileLine* const fl = m_topScopep->fileline();
|
||||
AstVar* const varp
|
||||
= new AstVar{fl, VVarType::VAR, "__Vdpi_export_trigger", VFlagBitPacked{}, 1};
|
||||
m_topScopep->scopep()->modp()->addStmtp(varp);
|
||||
m_topScopep->scopep()->modp()->addStmtsp(varp);
|
||||
dpiExportTriggerp = new AstVarScope{fl, m_topScopep->scopep(), varp};
|
||||
m_topScopep->scopep()->addVarp(dpiExportTriggerp);
|
||||
m_topScopep->scopep()->addVarsp(dpiExportTriggerp);
|
||||
v3Global.rootp()->dpiExportTriggerp(dpiExportTriggerp);
|
||||
}
|
||||
return dpiExportTriggerp;
|
||||
|
|
@ -1134,7 +1134,7 @@ private:
|
|||
AstVarScope* rtnvscp = nullptr;
|
||||
if (rtnvarp) {
|
||||
rtnvscp = new AstVarScope(rtnvarp->fileline(), m_scopep, rtnvarp);
|
||||
m_scopep->addVarp(rtnvscp);
|
||||
m_scopep->addVarsp(rtnvscp);
|
||||
rtnvarp->user2p(rtnvscp);
|
||||
}
|
||||
|
||||
|
|
@ -1228,7 +1228,7 @@ private:
|
|||
}
|
||||
AstVarScope* const newvscp
|
||||
= new AstVarScope{portp->fileline(), m_scopep, portp};
|
||||
m_scopep->addVarp(newvscp);
|
||||
m_scopep->addVarsp(newvscp);
|
||||
portp->user2p(newvscp);
|
||||
}
|
||||
}
|
||||
|
|
@ -1314,9 +1314,9 @@ private:
|
|||
new AstVarRef{fl, dpiExportTriggerp, VAccess::READ}}},
|
||||
nullptr};
|
||||
for (AstVarScope* const varScopep : writtenps) {
|
||||
alwaysp->addStmtp(new AstDpiExportUpdated{fl, varScopep});
|
||||
alwaysp->addStmtsp(new AstDpiExportUpdated{fl, varScopep});
|
||||
}
|
||||
m_scopep->addActivep(alwaysp);
|
||||
m_scopep->addBlocksp(alwaysp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1516,7 +1516,7 @@ private:
|
|||
iterateAndNextNull(nodep->condp());
|
||||
// Body insert just before themselves
|
||||
m_insStmtp = nullptr; // First thing should be new statement
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
iterateAndNextNull(nodep->incsp());
|
||||
// Done the loop
|
||||
m_insStmtp = nullptr; // Next thing should be new statement
|
||||
|
|
|
|||
|
|
@ -454,9 +454,9 @@ private:
|
|||
v3Global.rootp()->typeTablep()->addTypesp(newArrDtp);
|
||||
AstVar* const newvarp
|
||||
= new AstVar(flp, VVarType::MODULETEMP, "__Vm_traceActivity", newArrDtp);
|
||||
m_topModp->addStmtp(newvarp);
|
||||
m_topModp->addStmtsp(newvarp);
|
||||
AstVarScope* const newvscp = new AstVarScope(flp, m_topScopep, newvarp);
|
||||
m_topScopep->addVarp(newvscp);
|
||||
m_topScopep->addVarsp(newvscp);
|
||||
m_activityVscp = newvscp;
|
||||
|
||||
// Insert activity setters
|
||||
|
|
@ -493,7 +493,7 @@ private:
|
|||
funcp->slow(full);
|
||||
funcp->isStatic(isTopFunc);
|
||||
// Add it to top scope
|
||||
m_topScopep->addActivep(funcp);
|
||||
m_topScopep->addBlocksp(funcp);
|
||||
const auto addInitStr = [funcp, flp](const string& str) -> void {
|
||||
funcp->addInitsp(new AstCStmt(flp, str));
|
||||
};
|
||||
|
|
@ -676,7 +676,7 @@ private:
|
|||
// Add TraceInc node
|
||||
AstTraceInc* const incp
|
||||
= new AstTraceInc(declp->fileline(), declp, /* full: */ false, baseCode);
|
||||
ifp->addIfsp(incp);
|
||||
ifp->addThensp(incp);
|
||||
subStmts += incp->nodeCount();
|
||||
|
||||
// Track partitioning
|
||||
|
|
@ -698,7 +698,7 @@ private:
|
|||
cleanupFuncp->slow(false);
|
||||
cleanupFuncp->isStatic(true);
|
||||
cleanupFuncp->isLoose(true);
|
||||
m_topScopep->addActivep(cleanupFuncp);
|
||||
m_topScopep->addBlocksp(cleanupFuncp);
|
||||
cleanupFuncp->addInitsp(new AstCStmt(fl, voidSelfAssign(m_topModp)));
|
||||
cleanupFuncp->addInitsp(new AstCStmt(fl, symClassAssign()));
|
||||
|
||||
|
|
@ -755,7 +755,7 @@ private:
|
|||
m_regFuncp->slow(true);
|
||||
m_regFuncp->isStatic(false);
|
||||
m_regFuncp->isLoose(true);
|
||||
m_topScopep->addActivep(m_regFuncp);
|
||||
m_topScopep->addBlocksp(m_regFuncp);
|
||||
|
||||
// Create the full dump functions, also allocates signal numbers
|
||||
createFullTraceFunction(traces, nFullCodes, m_parallelism);
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ private:
|
|||
funcp->isStatic(false);
|
||||
funcp->isLoose(true);
|
||||
funcp->slow(true);
|
||||
topScopep->addActivep(funcp);
|
||||
topScopep->addBlocksp(funcp);
|
||||
return funcp;
|
||||
}
|
||||
|
||||
|
|
@ -303,8 +303,8 @@ private:
|
|||
scopeName = scopeName.substr(0, lastDot + 1);
|
||||
const size_t scopeLen = scopeName.length();
|
||||
|
||||
UASSERT_OBJ(cellp->intfRefp(), cellp, "Interface without tracing reference");
|
||||
for (AstIntfRef *irp = cellp->intfRefp(), *nextIrp; irp; irp = nextIrp) {
|
||||
UASSERT_OBJ(cellp->intfRefsp(), cellp, "Interface without tracing reference");
|
||||
for (AstIntfRef *irp = cellp->intfRefsp(), *nextIrp; irp; irp = nextIrp) {
|
||||
nextIrp = VN_AS(irp->nextp(), IntfRef);
|
||||
|
||||
const string irpName = irp->prettyName();
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
"Unsupported: Creating tristate signal not underneath a module: "
|
||||
<< nodep->prettyNameQ());
|
||||
} else {
|
||||
m_modp->addStmtp(newp);
|
||||
m_modp->addStmtsp(newp);
|
||||
}
|
||||
}
|
||||
void associateLogic(AstNode* fromp, AstNode* top) {
|
||||
|
|
@ -554,7 +554,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
AstNode* const newp = new AstAssignW(varp->fileline(), varrefp, constp);
|
||||
UINFO(9, " newoev " << newp << endl);
|
||||
varrefp->user1p(newAllZerosOrOnes(varp, false));
|
||||
nodep->addStmtp(newp);
|
||||
nodep->addStmtsp(newp);
|
||||
mapInsertLhsVarRef(varrefp); // insertTristates will convert
|
||||
// // to a varref to the __out# variable
|
||||
}
|
||||
|
|
@ -627,7 +627,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
lhsp->name() + "__out" + cvtToStr(m_unique),
|
||||
VFlagBitPacked(), w); // 2-state ok; sep enable
|
||||
UINFO(9, " newout " << newlhsp << endl);
|
||||
nodep->addStmtp(newlhsp);
|
||||
nodep->addStmtsp(newlhsp);
|
||||
refp->varp(newlhsp); // assign the new var to the varref
|
||||
refp->name(newlhsp->name());
|
||||
|
||||
|
|
@ -636,13 +636,13 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
lhsp->name() + "__en" + cvtToStr(m_unique++),
|
||||
VFlagBitPacked(), w); // 2-state ok
|
||||
UINFO(9, " newenp " << newenp << endl);
|
||||
nodep->addStmtp(newenp);
|
||||
nodep->addStmtsp(newenp);
|
||||
|
||||
AstNode* const enassp = new AstAssignW(
|
||||
refp->fileline(), new AstVarRef(refp->fileline(), newenp, VAccess::WRITE),
|
||||
getEnp(refp));
|
||||
UINFO(9, " newass " << enassp << endl);
|
||||
nodep->addStmtp(enassp);
|
||||
nodep->addStmtsp(enassp);
|
||||
|
||||
// now append this driver to the driver logic.
|
||||
AstNode* const ref1p = new AstVarRef(refp->fileline(), newlhsp, VAccess::READ);
|
||||
|
|
@ -675,7 +675,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
VL_DO_DANGLING(undrivenp->deleteTree(), undrivenp);
|
||||
}
|
||||
if (envarp) {
|
||||
nodep->addStmtp(new AstAssignW(
|
||||
nodep->addStmtsp(new AstAssignW(
|
||||
enp->fileline(), new AstVarRef(envarp->fileline(), envarp, VAccess::WRITE), enp));
|
||||
}
|
||||
// __out (child) or <in> (parent) = drive-value expression
|
||||
|
|
@ -683,7 +683,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
lhsp->fileline(), new AstVarRef(lhsp->fileline(), lhsp, VAccess::WRITE), orp);
|
||||
assp->user2(U2_BOTH); // Don't process further; already resolved
|
||||
if (debug() >= 9) assp->dumpTree(cout, "-lhsp-eqn: ");
|
||||
nodep->addStmtp(assp);
|
||||
nodep->addStmtsp(assp);
|
||||
}
|
||||
|
||||
void addToAssignmentList(AstAssignW* nodep) {
|
||||
|
|
@ -864,11 +864,11 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
if (m_graphing) {
|
||||
iterateChildren(nodep);
|
||||
if (m_alhs) {
|
||||
associateLogic(nodep, nodep->expr1p());
|
||||
associateLogic(nodep, nodep->expr2p());
|
||||
associateLogic(nodep, nodep->thenp());
|
||||
associateLogic(nodep, nodep->elsep());
|
||||
} else {
|
||||
associateLogic(nodep->expr1p(), nodep);
|
||||
associateLogic(nodep->expr2p(), nodep);
|
||||
associateLogic(nodep->thenp(), nodep);
|
||||
associateLogic(nodep->elsep(), nodep);
|
||||
}
|
||||
} else {
|
||||
if (m_alhs && nodep->user1p()) {
|
||||
|
|
@ -887,20 +887,20 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
condp->v3warn(E_UNSUPPORTED, "Unsupported: don't know how to deal with "
|
||||
"tristate logic in the conditional expression");
|
||||
}
|
||||
AstNode* const expr1p = nodep->expr1p();
|
||||
AstNode* const expr2p = nodep->expr2p();
|
||||
if (expr1p->user1p() || expr2p->user1p()) { // else no tristates
|
||||
AstNode* const thenp = nodep->thenp();
|
||||
AstNode* const elsep = nodep->elsep();
|
||||
if (thenp->user1p() || elsep->user1p()) { // else no tristates
|
||||
m_tgraph.didProcess(nodep);
|
||||
AstNode* const en1p = getEnp(expr1p);
|
||||
AstNode* const en2p = getEnp(expr2p);
|
||||
AstNode* const en1p = getEnp(thenp);
|
||||
AstNode* const en2p = getEnp(elsep);
|
||||
// The output enable of a cond is a cond of the output enable of the
|
||||
// two expressions with the same conditional.
|
||||
AstNode* const enp
|
||||
= new AstCond(nodep->fileline(), condp->cloneTree(false), en1p, en2p);
|
||||
UINFO(9, " newcond " << enp << endl);
|
||||
nodep->user1p(enp); // propagate up COND(lhsp->enable, rhsp->enable)
|
||||
expr1p->user1p(nullptr);
|
||||
expr2p->user1p(nullptr);
|
||||
thenp->user1p(nullptr);
|
||||
elsep->user1p(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1391,7 +1391,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
UINFO(9, " newpin " << enpinp << endl);
|
||||
enpinp->user2(U2_BOTH); // don't iterate the pin later
|
||||
nodep->addNextHere(enpinp);
|
||||
m_modp->addStmtp(enVarp);
|
||||
m_modp->addStmtsp(enVarp);
|
||||
enrefp = new AstVarRef(nodep->fileline(), enVarp, VAccess::READ);
|
||||
UINFO(9, " newvrf " << enrefp << endl);
|
||||
if (debug() >= 9) enpinp->dumpTree(cout, "-pin-ena: ");
|
||||
|
|
@ -1608,7 +1608,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
|
||||
void visit(AstCaseItem* nodep) override {
|
||||
// don't deal with casez compare '???? values
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
}
|
||||
|
||||
void visit(AstCell* nodep) override {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ private:
|
|||
} else {
|
||||
AstVar* const varp
|
||||
= new AstVar(fl, VVarType::MODULETEMP, m_lvboundNames.get(prep), prep->dtypep());
|
||||
m_modp->addStmtp(varp);
|
||||
m_modp->addStmtsp(varp);
|
||||
AstNode* const abovep = prep->backp(); // Grab above point before we replace 'prep'
|
||||
prep->replaceWith(new AstVarRef(fl, varp, VAccess::WRITE));
|
||||
AstIf* const newp = new AstIf(
|
||||
|
|
@ -173,7 +173,7 @@ private:
|
|||
m_constXCvt = false; // Avoid losing the X's in casex
|
||||
iterateAndNextNull(nodep->condsp());
|
||||
m_constXCvt = true;
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
}
|
||||
}
|
||||
void visit(AstNodeDType* nodep) override {
|
||||
|
|
@ -353,9 +353,9 @@ private:
|
|||
// Add inits in front of other statement.
|
||||
// In the future, we should stuff the initp into the module's constructor.
|
||||
AstNode* const afterp = m_modp->stmtsp()->unlinkFrBackWithNext();
|
||||
m_modp->addStmtp(newvarp);
|
||||
m_modp->addStmtp(newinitp);
|
||||
m_modp->addStmtp(afterp);
|
||||
m_modp->addStmtsp(newvarp);
|
||||
m_modp->addStmtsp(newinitp);
|
||||
m_modp->addStmtsp(afterp);
|
||||
if (debug() >= 9) newref1p->dumpTree(cout, " _new: ");
|
||||
if (debug() >= 9) newvarp->dumpTree(cout, " _new: ");
|
||||
if (debug() >= 9) newinitp->dumpTree(cout, " _new: ");
|
||||
|
|
|
|||
|
|
@ -387,21 +387,21 @@ private:
|
|||
if (nodep->backp()->nextp() == nodep) initp = nodep->backp();
|
||||
// Grab assignment
|
||||
AstNode* incp = nullptr; // Should be last statement
|
||||
AstNode* bodysp = nodep->bodysp();
|
||||
AstNode* stmtsp = nodep->stmtsp();
|
||||
if (nodep->incsp()) V3Const::constifyEdit(nodep->incsp());
|
||||
// cppcheck-suppress duplicateCondition
|
||||
if (nodep->incsp()) {
|
||||
incp = nodep->incsp();
|
||||
} else {
|
||||
for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {}
|
||||
for (incp = nodep->stmtsp(); incp && incp->nextp(); incp = incp->nextp()) {}
|
||||
if (incp) VL_DO_DANGLING(V3Const::constifyEdit(incp), incp);
|
||||
// Again, as may have changed
|
||||
bodysp = nodep->bodysp();
|
||||
for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {}
|
||||
if (incp == bodysp) bodysp = nullptr;
|
||||
stmtsp = nodep->stmtsp();
|
||||
for (incp = nodep->stmtsp(); incp && incp->nextp(); incp = incp->nextp()) {}
|
||||
if (incp == stmtsp) stmtsp = nullptr;
|
||||
}
|
||||
// And check it
|
||||
if (forUnrollCheck(nodep, initp, nodep->precondsp(), nodep->condp(), incp, bodysp)) {
|
||||
if (forUnrollCheck(nodep, initp, nodep->precondsp(), nodep->condp(), incp, stmtsp)) {
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement
|
||||
}
|
||||
}
|
||||
|
|
@ -426,7 +426,7 @@ private:
|
|||
// deleted by V3Const.
|
||||
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||||
} else if (forUnrollCheck(nodep, nodep->initsp(), nullptr, nodep->condp(),
|
||||
nodep->incsp(), nodep->bodysp())) {
|
||||
nodep->incsp(), nodep->stmtsp())) {
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement
|
||||
} else {
|
||||
nodep->v3error("For loop doesn't have genvar index, or is malformed");
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ class VariableOrder final {
|
|||
stmtsp->unlinkFrBackWithNext();
|
||||
AstNode::addNext<AstNode, AstNode>(firstp, stmtsp);
|
||||
}
|
||||
modp->addStmtp(firstp);
|
||||
modp->addStmtsp(firstp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -462,22 +462,22 @@ private:
|
|||
iterateCheckBool(nodep, "Conditional Test", nodep->condp(), BOTH);
|
||||
// Determine sub expression widths only relying on what's in the subops
|
||||
// CONTEXT determined, but need data type for pattern assignments
|
||||
userIterateAndNext(nodep->expr1p(), WidthVP(m_vup->dtypeNullp(), PRELIM).p());
|
||||
userIterateAndNext(nodep->expr2p(), WidthVP(m_vup->dtypeNullp(), PRELIM).p());
|
||||
userIterateAndNext(nodep->thenp(), WidthVP(m_vup->dtypeNullp(), PRELIM).p());
|
||||
userIterateAndNext(nodep->elsep(), WidthVP(m_vup->dtypeNullp(), PRELIM).p());
|
||||
// Calculate width of this expression.
|
||||
// First call (prelim()) m_vup->width() is probably zero, so we'll return
|
||||
// the size of this subexpression only.
|
||||
// Second call (final()) m_vup->width() is probably the expression size, so
|
||||
// the expression includes the size of the output too.
|
||||
if (nodep->expr1p()->isDouble() || nodep->expr2p()->isDouble()) {
|
||||
if (nodep->thenp()->isDouble() || nodep->elsep()->isDouble()) {
|
||||
nodep->dtypeSetDouble();
|
||||
} else if (nodep->expr1p()->isString() || nodep->expr2p()->isString()) {
|
||||
} else if (nodep->thenp()->isString() || nodep->elsep()->isString()) {
|
||||
nodep->dtypeSetString();
|
||||
} else {
|
||||
const int width = std::max(nodep->expr1p()->width(), nodep->expr2p()->width());
|
||||
const int width = std::max(nodep->thenp()->width(), nodep->elsep()->width());
|
||||
const int mwidth
|
||||
= std::max(nodep->expr1p()->widthMin(), nodep->expr2p()->widthMin());
|
||||
const bool issigned = nodep->expr1p()->isSigned() && nodep->expr2p()->isSigned();
|
||||
= std::max(nodep->thenp()->widthMin(), nodep->elsep()->widthMin());
|
||||
const bool issigned = nodep->thenp()->isSigned() && nodep->elsep()->isSigned();
|
||||
nodep->dtypeSetLogicUnsized(width, mwidth, VSigning::fromBool(issigned));
|
||||
}
|
||||
}
|
||||
|
|
@ -486,9 +486,9 @@ private:
|
|||
AstNodeDType* const subDTypep = expDTypep;
|
||||
nodep->dtypeFrom(expDTypep);
|
||||
// Error report and change sizes for suboperands of this node.
|
||||
iterateCheck(nodep, "Conditional True", nodep->expr1p(), CONTEXT, FINAL, subDTypep,
|
||||
iterateCheck(nodep, "Conditional True", nodep->thenp(), CONTEXT, FINAL, subDTypep,
|
||||
EXTEND_EXP);
|
||||
iterateCheck(nodep, "Conditional False", nodep->expr2p(), CONTEXT, FINAL, subDTypep,
|
||||
iterateCheck(nodep, "Conditional False", nodep->elsep(), CONTEXT, FINAL, subDTypep,
|
||||
EXTEND_EXP);
|
||||
}
|
||||
}
|
||||
|
|
@ -1834,7 +1834,7 @@ private:
|
|||
castSized(nodep, nodep->fromp(), width);
|
||||
// Note castSized might modify nodep->fromp()
|
||||
} else {
|
||||
iterateCheck(nodep, "value", nodep->lhsp(), SELF, FINAL, fromDtp, EXTEND_EXP,
|
||||
iterateCheck(nodep, "value", nodep->fromp(), SELF, FINAL, fromDtp, EXTEND_EXP,
|
||||
false);
|
||||
}
|
||||
if (basicp->isDouble() && !nodep->fromp()->isDouble()) {
|
||||
|
|
@ -1866,14 +1866,14 @@ private:
|
|||
<< toDtp->prettyDTypeNameQ());
|
||||
}
|
||||
if (!newp) newp = nodep->fromp()->unlinkFrBack();
|
||||
nodep->lhsp(newp);
|
||||
nodep->fromp(newp);
|
||||
// if (debug()) nodep->dumpTree(cout, " CastOut: ");
|
||||
// if (debug()) nodep->backp()->dumpTree(cout, " CastOutUpUp: ");
|
||||
}
|
||||
if (m_vup->final()) {
|
||||
iterateCheck(nodep, "value", nodep->lhsp(), SELF, FINAL, nodep->lhsp()->dtypep(),
|
||||
iterateCheck(nodep, "value", nodep->fromp(), SELF, FINAL, nodep->fromp()->dtypep(),
|
||||
EXTEND_EXP, false);
|
||||
AstNode* const underp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* const underp = nodep->fromp()->unlinkFrBack();
|
||||
// if (debug()) underp->dumpTree(cout, " CastRep: ");
|
||||
nodep->replaceWith(underp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
|
@ -3972,7 +3972,7 @@ private:
|
|||
userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT, PRELIM).p());
|
||||
for (AstCaseItem *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) {
|
||||
nextip = VN_AS(itemp->nextp(), CaseItem); // Prelim may cause the node to get replaced
|
||||
if (!VN_IS(nodep, GenCase)) userIterateAndNext(itemp->bodysp(), nullptr);
|
||||
if (!VN_IS(nodep, GenCase)) userIterateAndNext(itemp->stmtsp(), nullptr);
|
||||
for (AstNode *nextcp, *condp = itemp->condsp(); condp; condp = nextcp) {
|
||||
nextcp = condp->nextp(); // Prelim may cause the node to get replaced
|
||||
VL_DO_DANGLING(userIterate(condp, WidthVP(CONTEXT, PRELIM).p()), condp);
|
||||
|
|
@ -4015,27 +4015,27 @@ private:
|
|||
userIterateAndNext(nodep->initsp(), nullptr);
|
||||
iterateCheckBool(nodep, "For Test Condition", nodep->condp(),
|
||||
BOTH); // it's like an if() condition.
|
||||
if (!VN_IS(nodep, GenFor)) userIterateAndNext(nodep->bodysp(), nullptr);
|
||||
if (!VN_IS(nodep, GenFor)) userIterateAndNext(nodep->stmtsp(), nullptr);
|
||||
userIterateAndNext(nodep->incsp(), nullptr);
|
||||
}
|
||||
void visit(AstRepeat* nodep) override {
|
||||
assertAtStatement(nodep);
|
||||
userIterateAndNext(nodep->countp(), WidthVP(SELF, BOTH).p());
|
||||
userIterateAndNext(nodep->bodysp(), nullptr);
|
||||
userIterateAndNext(nodep->stmtsp(), nullptr);
|
||||
}
|
||||
void visit(AstWhile* nodep) override {
|
||||
assertAtStatement(nodep);
|
||||
userIterateAndNext(nodep->precondsp(), nullptr);
|
||||
iterateCheckBool(nodep, "For Test Condition", nodep->condp(),
|
||||
BOTH); // it's like an if() condition.
|
||||
userIterateAndNext(nodep->bodysp(), nullptr);
|
||||
userIterateAndNext(nodep->stmtsp(), nullptr);
|
||||
userIterateAndNext(nodep->incsp(), nullptr);
|
||||
}
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
assertAtStatement(nodep);
|
||||
// if (debug()) nodep->dumpTree(cout, " IfPre: ");
|
||||
if (!VN_IS(nodep, GenIf)) { // for m_paramsOnly
|
||||
userIterateAndNext(nodep->ifsp(), nullptr);
|
||||
userIterateAndNext(nodep->thensp(), nullptr);
|
||||
userIterateAndNext(nodep->elsesp(), nullptr);
|
||||
}
|
||||
iterateCheckBool(nodep, "If", nodep->condp(), BOTH); // it's like an if() condition.
|
||||
|
|
@ -4056,7 +4056,7 @@ private:
|
|||
UASSERT_OBJ(fromp->dtypep(), fromp, "Missing data type");
|
||||
AstNodeDType* fromDtp = fromp->dtypep()->skipRefp();
|
||||
// Split into for loop
|
||||
AstNode* bodyp = nodep->bodysp(); // Might be null
|
||||
AstNode* bodyp = nodep->stmtsp(); // Might be null
|
||||
if (bodyp) bodyp->unlinkFrBackWithNext();
|
||||
// We record where the body needs to eventually go with bodyPointp
|
||||
// (Can't use bodyp as might be null)
|
||||
|
|
@ -4348,8 +4348,8 @@ private:
|
|||
argp->unlinkFrBack(&handle);
|
||||
AstCMath* const newp
|
||||
= new AstCMath(nodep->fileline(), "VL_TO_STRING(", 0, true);
|
||||
newp->addBodysp(argp);
|
||||
newp->addBodysp(new AstText(nodep->fileline(), ")", true));
|
||||
newp->addExprsp(argp);
|
||||
newp->addExprsp(new AstText(nodep->fileline(), ")", true));
|
||||
newp->dtypeSetString();
|
||||
newp->pure(true);
|
||||
newp->protect(false);
|
||||
|
|
@ -6356,7 +6356,7 @@ private:
|
|||
varp->isStatic(true);
|
||||
varp->valuep(initp);
|
||||
// Add to root, as don't know module we are in, and aids later structure sharing
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp);
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp);
|
||||
// Element 0 is a non-index and has speced values
|
||||
initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, 0));
|
||||
for (unsigned i = 1; i < msbdim + 1; ++i) {
|
||||
|
|
@ -6421,7 +6421,7 @@ private:
|
|||
varp->isStatic(true);
|
||||
varp->valuep(initp);
|
||||
// Add to root, as don't know module we are in, and aids later structure sharing
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp);
|
||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtsp(varp);
|
||||
|
||||
// Default for all unspecified values
|
||||
if (attrType == VAttrType::ENUM_NAME) {
|
||||
|
|
|
|||
146
src/astgen
146
src/astgen
|
|
@ -24,6 +24,8 @@ class Node:
|
|||
self._file = file # File this class is defined in
|
||||
self._lineno = lineno # Line this class is defined on
|
||||
self._ordIdx = None # Ordering index of this class
|
||||
self._arity = -1 # Arity of node
|
||||
self._ops = {} # Operands of node
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
|
@ -33,6 +35,10 @@ class Node:
|
|||
def superClass(self):
|
||||
return self._superClass
|
||||
|
||||
@property
|
||||
def isRoot(self):
|
||||
return self.superClass is None
|
||||
|
||||
@property
|
||||
def isCompleted(self):
|
||||
return isinstance(self._subClasses, tuple)
|
||||
|
|
@ -50,6 +56,20 @@ class Node:
|
|||
assert not self.isCompleted
|
||||
self._subClasses.append(subClass)
|
||||
|
||||
def addOp(self, n, name, monad, kind):
|
||||
assert 1 <= n <= 4
|
||||
self._ops[n] = (name, monad, kind)
|
||||
self._arity = max(self._arity, n)
|
||||
|
||||
def getOp(self, n):
|
||||
assert 1 <= n <= 4
|
||||
op = self._ops.get(n, None)
|
||||
if op is not None:
|
||||
return op
|
||||
if not self.isRoot:
|
||||
return self.superClass.getOp(n)
|
||||
return None
|
||||
|
||||
# Computes derived properties over entire class hierarchy.
|
||||
# No more changes to the hierarchy are allowed once this was called
|
||||
def complete(self, typeId=0, ordIdx=0):
|
||||
|
|
@ -62,6 +82,11 @@ class Node:
|
|||
self._ordIdx = ordIdx
|
||||
ordIdx = ordIdx + 1
|
||||
|
||||
if self.isRoot:
|
||||
self._arity = 0
|
||||
else:
|
||||
self._arity = max(self._arity, self._superClass.arity)
|
||||
|
||||
# Leaves
|
||||
if self.isLeaf:
|
||||
self._typeId = typeId
|
||||
|
|
@ -78,11 +103,6 @@ class Node:
|
|||
assert self.isCompleted
|
||||
return self._subClasses
|
||||
|
||||
@property
|
||||
def isRoot(self):
|
||||
assert self.isCompleted
|
||||
return self.superClass is None
|
||||
|
||||
@property
|
||||
def isLeaf(self):
|
||||
assert self.isCompleted
|
||||
|
|
@ -140,6 +160,11 @@ class Node:
|
|||
assert self.isCompleted
|
||||
return self._ordIdx
|
||||
|
||||
@property
|
||||
def arity(self):
|
||||
assert self.isCompleted
|
||||
return self._arity
|
||||
|
||||
def isSubClassOf(self, other):
|
||||
assert self.isCompleted
|
||||
if self is other:
|
||||
|
|
@ -495,6 +520,25 @@ class Cpt:
|
|||
######################################################################
|
||||
|
||||
|
||||
def partitionAndStrip(string, separator):
|
||||
return map(lambda _: _.strip(), string.partition(separator))
|
||||
|
||||
|
||||
def parseOpType(string):
|
||||
match = re.match(r'^(\w+)\[(\w+)\]$', string)
|
||||
if match:
|
||||
monad, kind = match.groups()
|
||||
if monad not in ("Optional", "List"):
|
||||
return None
|
||||
kind = parseOpType(kind)
|
||||
if not kind or kind[0]:
|
||||
return None
|
||||
return monad, kind[1]
|
||||
if re.match(r'^Ast(\w+)$', string):
|
||||
return "", string[3:]
|
||||
return None
|
||||
|
||||
|
||||
def read_types(filename):
|
||||
hasErrors = False
|
||||
|
||||
|
|
@ -539,12 +583,65 @@ def read_types(filename):
|
|||
node = Node(classn, superClass, filename, lineno)
|
||||
superClass.addSubClass(node)
|
||||
Nodes[classn] = node
|
||||
|
||||
if not node:
|
||||
continue
|
||||
|
||||
if re.match(r'^\s*ASTGEN_MEMBERS_' + node.name + ';', line):
|
||||
hasAstgenMembers = True
|
||||
match = re.match(r'^\s*//\s*@astgen\s+(.*)$', line)
|
||||
if match:
|
||||
decl = re.sub(r'//.*$', '', match.group(1))
|
||||
what, sep, rest = partitionAndStrip(decl, ":=")
|
||||
what = re.sub(r'\s+', ' ', what)
|
||||
if not sep:
|
||||
error(
|
||||
lineno,
|
||||
"Malformed '@astgen' directive (expecting '<keywords> := <description>'): "
|
||||
+ decl)
|
||||
elif what in ("op1", "op2", "op3", "op4"):
|
||||
n = int(what[-1])
|
||||
ident, sep, kind = partitionAndStrip(rest, ":")
|
||||
ident = ident.strip()
|
||||
if not sep or not re.match(r'^\w+$', ident):
|
||||
error(
|
||||
lineno, "Malformed '@astgen " + what +
|
||||
"' directive (expecting '" + what +
|
||||
" := <identifier> : <type>': " + decl)
|
||||
else:
|
||||
kind = parseOpType(kind)
|
||||
if not kind:
|
||||
error(
|
||||
lineno, "Bad type for '@astgen " + what +
|
||||
"' (expecting Ast*, Optional[Ast*], or List[Ast*]):"
|
||||
+ decl)
|
||||
elif node.getOp(n) is not None:
|
||||
error(
|
||||
lineno, "Already defined " + what + " for " +
|
||||
node.name)
|
||||
else:
|
||||
node.addOp(n, ident, *kind)
|
||||
elif what in ("alias op1", "alias op2", "alias op3",
|
||||
"alias op4"):
|
||||
n = int(what[-1])
|
||||
ident = rest.strip()
|
||||
if not re.match(r'^\w+$', ident):
|
||||
error(
|
||||
lineno, "Malformed '@astgen " + what +
|
||||
"' directive (expecting '" + what +
|
||||
" := <identifier>': " + decl)
|
||||
else:
|
||||
op = node.getOp(n)
|
||||
if op is None:
|
||||
error(lineno,
|
||||
"Alaised op" + str(n) + " is not defined")
|
||||
else:
|
||||
node.addOp(n, ident, *op[1:])
|
||||
else:
|
||||
line = re.sub(r'//.*$', '', line)
|
||||
if re.match(r'.*[Oo]p[1-9].*', line):
|
||||
error(lineno,
|
||||
"Use generated accessors to access op<N> operands")
|
||||
|
||||
checkFinishedNode(node)
|
||||
if hasErrors:
|
||||
sys.exit("%Error: Stopping due to errors reported above")
|
||||
|
|
@ -614,6 +711,7 @@ def write_report(filename):
|
|||
fh.write("\nClasses:\n")
|
||||
for node in SortedNodes:
|
||||
fh.write(" class Ast%-17s\n" % node.name)
|
||||
fh.write(" arity: {}\n".format(node.arity))
|
||||
fh.write(" parent: ")
|
||||
for superClass in node.allSuperClasses:
|
||||
if not superClass.isRoot:
|
||||
|
|
@ -759,6 +857,42 @@ def write_macros(filename):
|
|||
''',
|
||||
t=node.name)
|
||||
|
||||
for n in (1, 2, 3, 4):
|
||||
op = node.getOp(n)
|
||||
if not op:
|
||||
continue
|
||||
name, monad, kind = op
|
||||
retrieve = ("VN_AS(op{n}p(), {kind})" if kind != "Node" else
|
||||
"op{n}p()").format(n=n, kind=kind)
|
||||
if monad == "List":
|
||||
emitBlock('''\
|
||||
Ast{kind}* {name}() const {{ return {retrieve}; }}
|
||||
void add{Name}(Ast{kind}* nodep) {{ addNOp{n}p(reinterpret_cast<AstNode*>(nodep)); }}
|
||||
''',
|
||||
kind=kind,
|
||||
name=name,
|
||||
Name=name[0].upper() + name[1:],
|
||||
n=n,
|
||||
retrieve=retrieve)
|
||||
elif monad == "Optional":
|
||||
emitBlock('''\
|
||||
Ast{kind}* {name}() const {{ return {retrieve}; }}
|
||||
void {name}(Ast{kind}* nodep) {{ setNOp{n}p(reinterpret_cast<AstNode*>(nodep)); }}
|
||||
''',
|
||||
kind=kind,
|
||||
name=name,
|
||||
n=n,
|
||||
retrieve=retrieve)
|
||||
else:
|
||||
emitBlock('''\
|
||||
Ast{kind}* {name}() const {{ return {retrieve}; }}
|
||||
void {name}(Ast{kind}* nodep) {{ setOp{n}p(reinterpret_cast<AstNode*>(nodep)); }}
|
||||
''',
|
||||
kind=kind,
|
||||
name=name,
|
||||
n=n,
|
||||
retrieve=retrieve)
|
||||
|
||||
fh.write(
|
||||
" static_assert(true, \"\")\n") # Swallowing the semicolon
|
||||
|
||||
|
|
|
|||
|
|
@ -391,9 +391,8 @@ def clean_input(filename, outname):
|
|||
if not re.match(r'^\s*$', line):
|
||||
sys.exit(
|
||||
"%Error: " + filename + ":" + str(lineno) + ": Need " +
|
||||
needmore +
|
||||
" more blank lines to keep line numbers are constant\n"
|
||||
)
|
||||
str(needmore) +
|
||||
" more blank lines to keep line numbers constant\n")
|
||||
needmore -= 1
|
||||
else:
|
||||
lines.append(line)
|
||||
|
|
|
|||
|
|
@ -1068,6 +1068,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
|
|||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
|
||||
%start source_text
|
||||
|
||||
|
|
@ -1092,8 +1093,8 @@ description: // ==IEEE: description
|
|||
| interface_declaration { }
|
||||
| program_declaration { }
|
||||
| package_declaration { }
|
||||
| package_item { if ($1) PARSEP->unitPackage($1->fileline())->addStmtp($1); }
|
||||
| bind_directive { if ($1) PARSEP->unitPackage($1->fileline())->addStmtp($1); }
|
||||
| package_item { if ($1) PARSEP->unitPackage($1->fileline())->addStmtsp($1); }
|
||||
| bind_directive { if ($1) PARSEP->unitPackage($1->fileline())->addStmtsp($1); }
|
||||
// unsupported // IEEE: config_declaration
|
||||
// // Verilator only
|
||||
| yaT_RESETALL { } // Else, under design, and illegal based on IEEE 22.3
|
||||
|
|
@ -1119,7 +1120,7 @@ timeunits_declaration<nodep>: // ==IEEE: timeunits_declaration
|
|||
package_declaration: // ==IEEE: package_declaration
|
||||
packageFront package_itemListE yENDPACKAGE endLabelE
|
||||
{ $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc
|
||||
if ($2) $1->addStmtp($2);
|
||||
if ($2) $1->addStmtsp($2);
|
||||
GRAMMARP->m_modp = nullptr;
|
||||
SYMP->popScope($1);
|
||||
GRAMMARP->endLabel($<fl>4,$1,$4); }
|
||||
|
|
@ -1132,7 +1133,7 @@ packageFront<nodeModulep>:
|
|||
$$->lifetime($2);
|
||||
$$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
|
||||
$$->timeunit(PARSEP->timeLastUnit());
|
||||
PARSEP->rootp()->addModulep($$);
|
||||
PARSEP->rootp()->addModulesp($$);
|
||||
SYMP->pushNew($$);
|
||||
GRAMMARP->m_modp = $$; }
|
||||
;
|
||||
|
|
@ -1228,18 +1229,18 @@ module_declaration: // ==IEEE: module_declaration
|
|||
modFront importsAndParametersE portsStarE ';'
|
||||
/*cont*/ module_itemListE yENDMODULE endLabelE
|
||||
{ $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc
|
||||
if ($2) $1->addStmtp($2);
|
||||
if ($3) $1->addStmtp($3);
|
||||
if ($5) $1->addStmtp($5);
|
||||
if ($2) $1->addStmtsp($2);
|
||||
if ($3) $1->addStmtsp($3);
|
||||
if ($5) $1->addStmtsp($5);
|
||||
GRAMMARP->m_modp = nullptr;
|
||||
SYMP->popScope($1);
|
||||
GRAMMARP->endLabel($<fl>7,$1,$7); }
|
||||
| udpFront parameter_port_listE portsStarE ';'
|
||||
/*cont*/ module_itemListE yENDPRIMITIVE endLabelE
|
||||
{ $1->modTrace(false); // Stash for implicit wires, etc
|
||||
if ($2) $1->addStmtp($2);
|
||||
if ($3) $1->addStmtp($3);
|
||||
if ($5) $1->addStmtp($5);
|
||||
if ($2) $1->addStmtsp($2);
|
||||
if ($3) $1->addStmtsp($3);
|
||||
if ($5) $1->addStmtsp($5);
|
||||
GRAMMARP->m_tracingParse = true;
|
||||
GRAMMARP->m_modp = nullptr;
|
||||
SYMP->popScope($1);
|
||||
|
|
@ -1259,7 +1260,7 @@ modFront<nodeModulep>:
|
|||
$$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
|
||||
$$->timeunit(PARSEP->timeLastUnit());
|
||||
$$->unconnectedDrive(PARSEP->unconnectedDrive());
|
||||
PARSEP->rootp()->addModulep($$);
|
||||
PARSEP->rootp()->addModulesp($$);
|
||||
SYMP->pushNew($$);
|
||||
GRAMMARP->m_modp = $$; }
|
||||
;
|
||||
|
|
@ -1275,9 +1276,9 @@ udpFront<nodeModulep>:
|
|||
{ $$ = new AstPrimitive($<fl>3, *$3); $$->inLibrary(true);
|
||||
$$->lifetime($2);
|
||||
$$->modTrace(false);
|
||||
$$->addStmtp(new AstPragma($<fl>3, VPragmaType::INLINE_MODULE));
|
||||
$$->addStmtsp(new AstPragma($<fl>3, VPragmaType::INLINE_MODULE));
|
||||
GRAMMARP->m_tracingParse = false;
|
||||
PARSEP->rootp()->addModulep($$);
|
||||
PARSEP->rootp()->addModulesp($$);
|
||||
SYMP->pushNew($$); }
|
||||
;
|
||||
|
||||
|
|
@ -1489,9 +1490,9 @@ interface_declaration: // IEEE: interface_declaration + interface_nonan
|
|||
// // timeunits_delcarationE is instead in interface_item
|
||||
intFront importsAndParametersE portsStarE ';'
|
||||
interface_itemListE yENDINTERFACE endLabelE
|
||||
{ if ($2) $1->addStmtp($2);
|
||||
if ($3) $1->addStmtp($3);
|
||||
if ($5) $1->addStmtp($5);
|
||||
{ if ($2) $1->addStmtsp($2);
|
||||
if ($3) $1->addStmtsp($3);
|
||||
if ($5) $1->addStmtsp($5);
|
||||
SYMP->popScope($1); }
|
||||
| yEXTERN intFront parameter_port_listE portsStarE ';'
|
||||
{ BBUNSUP($<fl>1, "Unsupported: extern interface"); }
|
||||
|
|
@ -1502,7 +1503,7 @@ intFront<nodeModulep>:
|
|||
{ $$ = new AstIface($<fl>3, *$3);
|
||||
$$->inLibrary(true);
|
||||
$$->lifetime($2);
|
||||
PARSEP->rootp()->addModulep($$);
|
||||
PARSEP->rootp()->addModulesp($$);
|
||||
SYMP->pushNew($$); }
|
||||
;
|
||||
|
||||
|
|
@ -1578,9 +1579,9 @@ program_declaration: // IEEE: program_declaration + program_nonansi_h
|
|||
pgmFront parameter_port_listE portsStarE ';'
|
||||
/*cont*/ program_itemListE yENDPROGRAM endLabelE
|
||||
{ $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc
|
||||
if ($2) $1->addStmtp($2);
|
||||
if ($3) $1->addStmtp($3);
|
||||
if ($5) $1->addStmtp($5);
|
||||
if ($2) $1->addStmtsp($2);
|
||||
if ($3) $1->addStmtsp($3);
|
||||
if ($5) $1->addStmtsp($5);
|
||||
GRAMMARP->m_modp = nullptr;
|
||||
SYMP->popScope($1);
|
||||
GRAMMARP->endLabel($<fl>7,$1,$7); }
|
||||
|
|
@ -1596,7 +1597,7 @@ pgmFront<nodeModulep>:
|
|||
$$->inLibrary(PARSEP->inLibrary() || $$->fileline()->celldefineOn());
|
||||
$$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
|
||||
$$->timeunit(PARSEP->timeLastUnit());
|
||||
PARSEP->rootp()->addModulep($$);
|
||||
PARSEP->rootp()->addModulesp($$);
|
||||
SYMP->pushNew($$);
|
||||
GRAMMARP->m_modp = $$; }
|
||||
;
|
||||
|
|
@ -2008,12 +2009,13 @@ struct_unionDecl<nodeUOrStructDTypep>: // IEEE: part of data_type
|
|||
{ $$ = $<nodeUOrStructDTypep>5; $$->addMembersp($6); SYMP->popScope($$); }
|
||||
;
|
||||
|
||||
struct_union_memberList<nodep>: // IEEE: { struct_union_member }
|
||||
struct_union_memberList<memberDTypep>: // IEEE: { struct_union_member }
|
||||
struct_union_member { $$ = $1; }
|
||||
|
||||
| struct_union_memberList struct_union_member { $$ = addNextNull($1, $2); }
|
||||
;
|
||||
|
||||
struct_union_member<nodep>: // ==IEEE: struct_union_member
|
||||
struct_union_member<memberDTypep>: // ==IEEE: struct_union_member
|
||||
// // UNSUP random_qualifer not propagagted until have randomize support
|
||||
random_qualifierE data_type_or_void
|
||||
/*mid*/ { GRAMMARP->m_memDTypep = $2; } // As a list follows, need to attach this dtype to each member.
|
||||
|
|
@ -2021,7 +2023,7 @@ struct_union_member<nodep>: // ==IEEE: struct_union_member
|
|||
| vlTag { $$ = nullptr; }
|
||||
;
|
||||
|
||||
list_of_member_decl_assignments<nodep>: // Derived from IEEE: list_of_variable_decl_assignments
|
||||
list_of_member_decl_assignments<memberDTypep>: // Derived from IEEE: list_of_variable_decl_assignments
|
||||
member_decl_assignment { $$ = $1; }
|
||||
| list_of_member_decl_assignments ',' member_decl_assignment { $$ = addNextNull($1, $3); }
|
||||
;
|
||||
|
|
@ -2177,17 +2179,17 @@ enum_base_typeE<nodeDTypep>: // IEEE: enum_base_type
|
|||
$$ = GRAMMARP->createArray(refp, $3, true); }
|
||||
;
|
||||
|
||||
enum_nameList<nodep>:
|
||||
enum_nameList<enumItemp>:
|
||||
enum_name_declaration { $$ = $1; }
|
||||
| enum_nameList ',' enum_name_declaration { $$ = addNextNull($1, $3); }
|
||||
;
|
||||
|
||||
enum_name_declaration<nodep>: // ==IEEE: enum_name_declaration
|
||||
enum_name_declaration<enumItemp>: // ==IEEE: enum_name_declaration
|
||||
idAny/*enum_identifier*/ enumNameRangeE enumNameStartE
|
||||
{ $$ = new AstEnumItem($<fl>1, *$1, $2, $3); }
|
||||
;
|
||||
|
||||
enumNameRangeE<nodep>: // IEEE: second part of enum_name_declaration
|
||||
enumNameRangeE<rangep>: // IEEE: second part of enum_name_declaration
|
||||
/* empty */
|
||||
{ $$ = nullptr; }
|
||||
| '[' intnumAsConst ']'
|
||||
|
|
@ -2472,7 +2474,7 @@ continuous_assign<nodep>: // IEEE: continuous_assign
|
|||
if ($3)
|
||||
for (auto* nodep = $$; nodep; nodep = nodep->nextp()) {
|
||||
auto* const assignp = VN_AS(nodep, NodeAssign);
|
||||
assignp->addTimingControlp(nodep == $$ ? $3 : $3->cloneTree(false));
|
||||
assignp->timingControlp(nodep == $$ ? $3 : $3->cloneTree(false));
|
||||
}
|
||||
}
|
||||
;
|
||||
|
|
@ -2634,7 +2636,7 @@ loop_generate_construct<nodep>: // ==IEEE: loop_generate_construct
|
|||
}
|
||||
// Statements are under 'genforp' as cells under this
|
||||
// for loop won't get an extra layer of hierarchy tacked on
|
||||
blkp->addGenforp(new AstGenFor($1, initp, $5, $7, lowerNoBegp));
|
||||
blkp->genforp(new AstGenFor($1, initp, $5, $7, lowerNoBegp));
|
||||
$$ = blkp;
|
||||
VL_DO_DANGLING(lowerBegp->deleteTree(), lowerBegp);
|
||||
}
|
||||
|
|
@ -2679,12 +2681,12 @@ genvar_iteration<nodep>: // ==IEEE: genvar_iteration
|
|||
new AstConst{$2, AstConst::StringToParse{}, "'b1"}}}; }
|
||||
;
|
||||
|
||||
case_generate_itemListE<nodep>: // IEEE: [{ case_generate_itemList }]
|
||||
case_generate_itemListE<caseItemp>: // IEEE: [{ case_generate_itemList }]
|
||||
/* empty */ { $$ = nullptr; }
|
||||
| case_generate_itemList { $$ = $1; }
|
||||
;
|
||||
|
||||
case_generate_itemList<nodep>: // IEEE: { case_generate_itemList }
|
||||
case_generate_itemList<caseItemp>: // IEEE: { case_generate_itemList }
|
||||
~c~case_generate_item { $$ = $1; }
|
||||
| ~c~case_generate_itemList ~c~case_generate_item { $$ = $1; $1->addNext($2); }
|
||||
;
|
||||
|
|
@ -2693,7 +2695,7 @@ case_generate_itemList<nodep>: // IEEE: { case_generate_itemList }
|
|||
//UNSUP BISONPRE_COPY(case_generate_itemList,{s/~c~/c_/g}) // {copied}
|
||||
//UNSUP ;
|
||||
|
||||
case_generate_item<nodep>: // ==IEEE: case_generate_item
|
||||
case_generate_item<caseItemp>: // ==IEEE: case_generate_item
|
||||
caseCondList colon generate_block_or_null { $$ = new AstCaseItem{$2, $1, $3}; }
|
||||
| yDEFAULT colon generate_block_or_null { $$ = new AstCaseItem{$1, nullptr, $3}; }
|
||||
| yDEFAULT generate_block_or_null { $$ = new AstCaseItem{$1, nullptr, $2}; }
|
||||
|
|
@ -2768,7 +2770,7 @@ netSig<varp>: // IEEE: net_decl_assignment - one element from
|
|||
{ $$ = VARDONEA($<fl>1, *$1, nullptr, $2);
|
||||
auto* const assignp = new AstAssignW{$3, new AstVarRef{$<fl>1, *$1, VAccess::WRITE}, $4};
|
||||
if (GRAMMARP->m_netStrengthp) assignp->strengthSpecp(GRAMMARP->m_netStrengthp->cloneTree(false));
|
||||
if ($$->delayp()) assignp->addTimingControlp($$->delayp()->unlinkFrBack()); // IEEE 1800-2017 10.3.3
|
||||
if ($$->delayp()) assignp->timingControlp($$->delayp()->unlinkFrBack()); // IEEE 1800-2017 10.3.3
|
||||
AstNode::addNext<AstNode, AstNode>($$, assignp); } | netId variable_dimensionList sigAttrListE
|
||||
{ $$ = VARDONEA($<fl>1,*$1, $2, $3); }
|
||||
;
|
||||
|
|
@ -4110,19 +4112,19 @@ funcId<nodeFTaskp>: // IEEE: function_data_type_or_implicit
|
|||
// // function_data_type expanded here to prevent conflicts with implicit_type:empty vs data_type:ID
|
||||
/**/ fIdScoped
|
||||
{ $$ = $1;
|
||||
$$->addFvarp(new AstBasicDType($<fl>1, LOGIC_IMPLICIT));
|
||||
$$->fvarp(new AstBasicDType($<fl>1, LOGIC_IMPLICIT));
|
||||
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>1); }
|
||||
| signingE rangeList fIdScoped
|
||||
{ $$ = $3;
|
||||
$$->addFvarp(GRAMMARP->addRange(new AstBasicDType($<fl>3, LOGIC_IMPLICIT, $1), $2,true));
|
||||
$$->fvarp(GRAMMARP->addRange(new AstBasicDType($<fl>3, LOGIC_IMPLICIT, $1), $2,true));
|
||||
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>3); }
|
||||
| signing fIdScoped
|
||||
{ $$ = $2;
|
||||
$$->addFvarp(new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $1));
|
||||
$$->fvarp(new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $1));
|
||||
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>2); }
|
||||
| data_type fIdScoped
|
||||
{ $$ = $2;
|
||||
$$->addFvarp($1);
|
||||
$$->fvarp($1);
|
||||
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>2); }
|
||||
// // To verilator tasks are the same as void functions (we separately detect time passing)
|
||||
| yVOID taskId
|
||||
|
|
@ -4992,12 +4994,12 @@ combinational_body<nodep>: // IEEE: combinational_body + sequential_body
|
|||
yTABLE tableEntryList yENDTABLE { $$ = new AstUdpTable($1,$2); }
|
||||
;
|
||||
|
||||
tableEntryList<nodep>: // IEEE: { combinational_entry | sequential_entry }
|
||||
tableEntryList<udpTableLinep>: // IEEE: { combinational_entry | sequential_entry }
|
||||
tableEntry { $$ = $1; }
|
||||
| tableEntryList tableEntry { $$ = addNextNull($1, $2); }
|
||||
;
|
||||
|
||||
tableEntry<nodep>: // IEEE: combinational_entry + sequential_entry
|
||||
tableEntry<udpTableLinep>: // IEEE: combinational_entry + sequential_entry
|
||||
yaTABLELINE { $$ = new AstUdpTableLine($<fl>1,*$1); }
|
||||
| error { $$ = nullptr; }
|
||||
;
|
||||
|
|
@ -6227,14 +6229,14 @@ classVirtualE<cbool>:
|
|||
| yVIRTUAL__CLASS { $$ = true; }
|
||||
;
|
||||
|
||||
classExtendsE<nodep>: // IEEE: part of class_declaration
|
||||
classExtendsE<classExtendsp>: // IEEE: part of class_declaration
|
||||
// // The classExtendsE rule relys on classFront having the
|
||||
// // new class scope correct via classFront
|
||||
/* empty */ { $$ = nullptr; $<scp>$ = nullptr; }
|
||||
| yEXTENDS classExtendsList { $$ = $2; $<scp>$ = $<scp>2; }
|
||||
;
|
||||
|
||||
classExtendsList<nodep>: // IEEE: part of class_declaration
|
||||
classExtendsList<classExtendsp>: // IEEE: part of class_declaration
|
||||
classExtendsOne { $$ = $1; $<scp>$ = $<scp>1; }
|
||||
| classExtendsList ',' classExtendsOne
|
||||
{ $$ = $3; $<scp>$ = $<scp>3;
|
||||
|
|
@ -6242,7 +6244,7 @@ classExtendsList<nodep>: // IEEE: part of class_declaration
|
|||
"and unsupported for interface classes."); }
|
||||
;
|
||||
|
||||
classExtendsOne<nodep>: // IEEE: part of class_declaration
|
||||
classExtendsOne<classExtendsp>: // IEEE: part of class_declaration
|
||||
class_typeExtImpList
|
||||
{ $$ = new AstClassExtends($1->fileline(), $1);
|
||||
$<scp>$ = $<scp>1; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue