Internals: Rename AstSenTree pointers to sentreep. No functional change intended except JSON.
This commit is contained in:
parent
dbdf235115
commit
88046c8063
|
|
@ -240,7 +240,7 @@ public:
|
|||
// Make a new AstActive sensitive to the given sentree and return it
|
||||
AstActive* makeActive(FileLine* const fl, AstSenTree* const senTreep) {
|
||||
AstActive* const activep = new AstActive{fl, "", senTreep};
|
||||
activep->sensesStorep(activep->sensesp());
|
||||
activep->senTreeStorep(activep->sentreep());
|
||||
addActive(activep);
|
||||
return activep;
|
||||
}
|
||||
|
|
@ -261,17 +261,17 @@ public:
|
|||
}
|
||||
|
||||
// Return an AstActive that is sensitive to a SenTree equivalent to the given sentreep.
|
||||
AstActive* getActive(FileLine* fl, AstSenTree* sensesp) {
|
||||
UASSERT(sensesp, "Must be non-null");
|
||||
AstActive* getActive(FileLine* fl, AstSenTree* sentreep) {
|
||||
UASSERT(sentreep, "Must be non-null");
|
||||
|
||||
auto it = m_activeMap.find(*sensesp);
|
||||
auto it = m_activeMap.find(*sentreep);
|
||||
// If found matching AstActive, return it
|
||||
if (it != m_activeMap.end()) return it->second;
|
||||
|
||||
// No such AstActive yet, creat it, and add to map.
|
||||
AstSenTree* const newsenp = sensesp->cloneTree(false);
|
||||
AstSenTree* const newsenp = sentreep->cloneTree(false);
|
||||
AstActive* const activep = new AstActive{fl, "sequent", newsenp};
|
||||
activep->sensesStorep(activep->sensesp());
|
||||
activep->senTreeStorep(activep->sentreep());
|
||||
addActive(activep);
|
||||
m_activeMap.emplace(*newsenp, activep);
|
||||
return activep;
|
||||
|
|
@ -441,11 +441,11 @@ class ActiveVisitor final : public VNVisitor {
|
|||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
|
||||
void visitAlways(AstNode* nodep, AstSenTree* oldsensesp, VAlwaysKwd kwd) {
|
||||
void visitAlways(AstNode* nodep, AstSenTree* oldsentreep, VAlwaysKwd kwd) {
|
||||
// Move always to appropriate ACTIVE based on its sense list
|
||||
if (oldsensesp && oldsensesp->sensesp() && oldsensesp->sensesp()->isNever()) {
|
||||
if (oldsentreep && oldsentreep->sensesp() && oldsentreep->sensesp()->isNever()) {
|
||||
// Never executing. Kill it.
|
||||
UASSERT_OBJ(!oldsensesp->sensesp()->nextp(), nodep,
|
||||
UASSERT_OBJ(!oldsentreep->sensesp()->nextp(), nodep,
|
||||
"Never senitem should be alone, else the never should be eliminated.");
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
|
|
@ -457,9 +457,9 @@ class ActiveVisitor final : public VNVisitor {
|
|||
// Walk sensitivity list
|
||||
m_clockedProcess = false;
|
||||
m_allChanged = true;
|
||||
if (oldsensesp) {
|
||||
oldsensesp->unlinkFrBack();
|
||||
iterateChildrenConst(oldsensesp);
|
||||
if (oldsentreep) {
|
||||
oldsentreep->unlinkFrBack();
|
||||
iterateChildrenConst(oldsentreep);
|
||||
}
|
||||
|
||||
// If all SenItems are ET_CHANGE, then walk the body to determine if this process
|
||||
|
|
@ -476,9 +476,9 @@ class ActiveVisitor final : public VNVisitor {
|
|||
|
||||
AstActive* const wantactivep
|
||||
= !m_clockedProcess ? m_namer.getSpecialActive<AstSenItem::Combo>(nodep->fileline())
|
||||
: oldsensesp ? m_namer.getActive(nodep->fileline(), oldsensesp)
|
||||
// Clocked, no sensitivity lists, it's a suspendable, put it in initial
|
||||
: m_namer.getSpecialActive<AstSenItem::Initial>(nodep->fileline());
|
||||
: oldsentreep ? m_namer.getActive(nodep->fileline(), oldsentreep)
|
||||
// Clocked, no sensitivity lists, it's a suspendable, put it in initial
|
||||
: m_namer.getSpecialActive<AstSenItem::Initial>(nodep->fileline());
|
||||
|
||||
// Move node to new active
|
||||
nodep->unlinkFrBack();
|
||||
|
|
@ -487,12 +487,12 @@ class ActiveVisitor final : public VNVisitor {
|
|||
// Warn and convert any delayed assignments
|
||||
{
|
||||
ActiveDlyVisitor{nodep, !m_clockedProcess ? ActiveDlyVisitor::CT_COMB
|
||||
: oldsensesp ? ActiveDlyVisitor::CT_SEQ
|
||||
: oldsentreep ? ActiveDlyVisitor::CT_SEQ
|
||||
: ActiveDlyVisitor::CT_SUSPENDABLE};
|
||||
}
|
||||
|
||||
// Delete sensitivity list
|
||||
if (oldsensesp) VL_DO_DANGLING(oldsensesp->deleteTree(), oldsensesp);
|
||||
if (oldsentreep) VL_DO_DANGLING(oldsentreep->deleteTree(), oldsentreep);
|
||||
|
||||
// check combinational processes for latches
|
||||
if (!m_clockedProcess || kwd == VAlwaysKwd::ALWAYS_LATCH) {
|
||||
|
|
@ -534,7 +534,7 @@ class ActiveVisitor final : public VNVisitor {
|
|||
return;
|
||||
}
|
||||
visitSenItems(nodep);
|
||||
visitAlways(nodep, nodep->sensesp(), nodep->keyword());
|
||||
visitAlways(nodep, nodep->sentreep(), nodep->keyword());
|
||||
}
|
||||
void visit(AstAlwaysPostponed* nodep) override {
|
||||
// Might be empty with later optimizations, so this assertion can be removed,
|
||||
|
|
@ -545,23 +545,23 @@ class ActiveVisitor final : public VNVisitor {
|
|||
activep->addStmtsp(nodep->unlinkFrBack());
|
||||
}
|
||||
void visit(AstAlwaysObserved* nodep) override {
|
||||
UASSERT_OBJ(nodep->sensesp(), nodep, "Should have a sentree");
|
||||
AstSenTree* const sensesp = nodep->sensesp();
|
||||
sensesp->unlinkFrBack();
|
||||
UASSERT_OBJ(nodep->sentreep(), nodep, "Should have a sentree");
|
||||
AstSenTree* const sentreep = nodep->sentreep();
|
||||
sentreep->unlinkFrBack();
|
||||
// Make a new active for it, needs to be the only item under the active for V3Sched
|
||||
AstActive* const activep = m_namer.makeActive(nodep->fileline(), sensesp);
|
||||
AstActive* const activep = m_namer.makeActive(nodep->fileline(), sentreep);
|
||||
activep->addStmtsp(nodep->unlinkFrBack());
|
||||
}
|
||||
void visit(AstAlwaysReactive* nodep) override {
|
||||
UASSERT_OBJ(nodep->sensesp(), nodep, "Should have a sentree");
|
||||
AstSenTree* const sensesp = nodep->sensesp();
|
||||
sensesp->unlinkFrBack();
|
||||
UASSERT_OBJ(nodep->sentreep(), nodep, "Should have a sentree");
|
||||
AstSenTree* const sentreep = nodep->sentreep();
|
||||
sentreep->unlinkFrBack();
|
||||
// Make a new active for it, needs to be the only item under the active for V3Sched
|
||||
AstActive* const activep = m_namer.makeActive(nodep->fileline(), sensesp);
|
||||
AstActive* const activep = m_namer.makeActive(nodep->fileline(), sentreep);
|
||||
activep->addStmtsp(nodep->unlinkFrBack());
|
||||
}
|
||||
void visit(AstAlwaysPublic* nodep) override {
|
||||
visitAlways(nodep, nodep->sensesp(), VAlwaysKwd::ALWAYS);
|
||||
visitAlways(nodep, nodep->sentreep(), VAlwaysKwd::ALWAYS);
|
||||
}
|
||||
void visit(AstCFunc* nodep) override { visitSenItems(nodep); }
|
||||
void visit(AstSenItem* nodep) override {
|
||||
|
|
|
|||
|
|
@ -68,11 +68,11 @@ class ActiveTopVisitor final : public VNVisitor {
|
|||
UINFO(4, " ACTIVE " << nodep);
|
||||
// Remove duplicate clocks and such; sensesp() may change!
|
||||
V3Const::constifyExpensiveEdit(nodep);
|
||||
AstSenTree* sensesp = nodep->sensesp();
|
||||
UASSERT_OBJ(sensesp, nodep, "nullptr");
|
||||
if (sensesp->sensesp() && sensesp->sensesp()->isNever()) {
|
||||
AstSenTree* sentreep = nodep->sentreep();
|
||||
UASSERT_OBJ(sentreep, nodep, "nullptr");
|
||||
if (sentreep->sensesp() && sentreep->sensesp()->isNever()) {
|
||||
// Never executing. Kill it.
|
||||
UASSERT_OBJ(!sensesp->sensesp()->nextp(), nodep,
|
||||
UASSERT_OBJ(!sentreep->sensesp()->nextp(), nodep,
|
||||
"Never senitem should be alone, else the never should be eliminated.");
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
|
|
@ -94,21 +94,21 @@ class ActiveTopVisitor final : public VNVisitor {
|
|||
|
||||
// Move the SENTREE for each active up to the global level.
|
||||
// This way we'll easily see what clock domains are identical
|
||||
AstSenTree* const wantp = m_finder.getSenTree(sensesp);
|
||||
AstSenTree* const wantp = m_finder.getSenTree(sentreep);
|
||||
UINFO(4, " lookdone");
|
||||
if (wantp != sensesp) {
|
||||
if (wantp != sentreep) {
|
||||
// Move the active's contents to the other active
|
||||
UINFO(4, " merge active " << sensesp << " into " << wantp);
|
||||
if (nodep->sensesStorep()) {
|
||||
UASSERT_OBJ(sensesp == nodep->sensesStorep(), nodep,
|
||||
UINFO(4, " merge active " << sentreep << " into " << wantp);
|
||||
if (nodep->senTreeStorep()) {
|
||||
UASSERT_OBJ(sentreep == nodep->senTreeStorep(), nodep,
|
||||
"sensesStore should have been deleted earlier if different");
|
||||
sensesp->unlinkFrBack();
|
||||
sentreep->unlinkFrBack();
|
||||
// There may be other references to same sense tree,
|
||||
// we'll be removing all references when we get to them,
|
||||
// but don't dangle our pointer yet!
|
||||
VL_DO_DANGLING(pushDeletep(sensesp), sensesp);
|
||||
VL_DO_DANGLING(pushDeletep(sentreep), sentreep);
|
||||
}
|
||||
nodep->sensesp(wantp);
|
||||
nodep->sentreep(wantp);
|
||||
}
|
||||
|
||||
// If this is combinational logic that does not read any variables, then it really is an
|
||||
|
|
@ -116,7 +116,7 @@ class ActiveTopVisitor final : public VNVisitor {
|
|||
// prune these otherwise.
|
||||
// TODO: we should warn for these if they were 'always @*' as some (including strictly
|
||||
// compliant) simulators will never execute these.
|
||||
if (nodep->sensesp()->hasCombo()) {
|
||||
if (nodep->sentreep()->hasCombo()) {
|
||||
FileLine* const flp = nodep->fileline();
|
||||
AstActive* initialp = nullptr;
|
||||
for (AstNode *logicp = nodep->stmtsp(), *nextp; logicp; logicp = nextp) {
|
||||
|
|
|
|||
|
|
@ -438,8 +438,8 @@ private:
|
|||
}
|
||||
}
|
||||
void visit(AstAlways* nodep) override {
|
||||
iterateAndNextNull(nodep->sensesp());
|
||||
if (nodep->sensesp()) m_seniAlwaysp = nodep->sensesp()->sensesp();
|
||||
iterateAndNextNull(nodep->sentreep());
|
||||
if (nodep->sentreep()) m_seniAlwaysp = nodep->sentreep()->sensesp();
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
m_seniAlwaysp = nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,8 +148,8 @@ bool AstBasicDType::ascending() const {
|
|||
return (rangep() ? rangep()->ascending() : m.m_nrange.ascending());
|
||||
}
|
||||
|
||||
bool AstActive::hasClocked() const { return m_sensesp->hasClocked(); }
|
||||
bool AstActive::hasCombo() const { return m_sensesp->hasCombo(); }
|
||||
bool AstActive::hasClocked() const { return m_sentreep->hasClocked(); }
|
||||
bool AstActive::hasCombo() const { return m_sentreep->hasCombo(); }
|
||||
|
||||
AstElabDisplay::AstElabDisplay(FileLine* fl, VDisplayType dispType, AstNodeExpr* exprsp)
|
||||
: ASTGEN_SUPER_ElabDisplay(fl) {
|
||||
|
|
|
|||
|
|
@ -4945,17 +4945,17 @@ class AstCAwait final : public AstNodeUniop {
|
|||
// Emit C++'s co_await expression
|
||||
// @astgen alias op1 := exprp
|
||||
//
|
||||
// @astgen ptr := m_sensesp : Optional[AstSenTree] // Sentree related to this await
|
||||
// @astgen ptr := m_sentreep : Optional[AstSenTree] // Sentree related to this await
|
||||
public:
|
||||
AstCAwait(FileLine* fl, AstNodeExpr* exprp, AstSenTree* sensesp = nullptr)
|
||||
AstCAwait(FileLine* fl, AstNodeExpr* exprp, AstSenTree* sentreep = nullptr)
|
||||
: ASTGEN_SUPER_CAwait(fl, exprp)
|
||||
, m_sensesp{sensesp} {}
|
||||
, m_sentreep{sentreep} {}
|
||||
ASTGEN_MEMBERS_AstCAwait;
|
||||
bool isTimingControl() const override { return true; }
|
||||
void dump(std::ostream& str) const override;
|
||||
void dumpJson(std::ostream& str) const override;
|
||||
AstSenTree* sensesp() const { return m_sensesp; }
|
||||
void clearSensesp() { m_sensesp = nullptr; }
|
||||
AstSenTree* sentreep() const { return m_sentreep; }
|
||||
void clearSentreep() { m_sentreep = nullptr; }
|
||||
void numberOperate(V3Number& out, const V3Number& lhs) override { V3ERROR_NA; }
|
||||
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
||||
string emitC() override { V3ERROR_NA_RETURN(""); }
|
||||
|
|
|
|||
|
|
@ -386,26 +386,26 @@ public:
|
|||
class AstActive final : public AstNode {
|
||||
// Block of code with sensitivity activation
|
||||
// Parents: MODULE | CFUNC
|
||||
// @astgen op1 := sensesStorep : Optional[AstSenTree] // Moved into m_sensesp in V3Active
|
||||
// @astgen op1 := senTreeStorep : Optional[AstSenTree] // Moved into m_sensesp in V3Active
|
||||
// @astgen op2 := stmtsp : List[AstNode] // Logic
|
||||
//
|
||||
// @astgen ptr := m_sensesp : Optional[AstSenTree] // Sensitivity list for this process
|
||||
// @astgen ptr := m_sentreep : Optional[AstSenTree] // Sensitivity list for this process
|
||||
string m_name;
|
||||
|
||||
public:
|
||||
AstActive(FileLine* fl, const string& name, AstSenTree* sensesp)
|
||||
AstActive(FileLine* fl, const string& name, AstSenTree* sentreep)
|
||||
: ASTGEN_SUPER_Active(fl)
|
||||
, m_name{name}
|
||||
, m_sensesp{sensesp} {
|
||||
UASSERT(sensesp, "Sensesp required arg");
|
||||
, m_sentreep{sentreep} {
|
||||
UASSERT(sentreep, "Sentreep required arg");
|
||||
}
|
||||
ASTGEN_MEMBERS_AstActive;
|
||||
void dump(std::ostream& str = std::cout) const override;
|
||||
void dumpJson(std::ostream& str = std::cout) const override;
|
||||
string name() const override VL_MT_STABLE { return m_name; }
|
||||
// Statements are broken into pieces, as some must come before others.
|
||||
void sensesp(AstSenTree* nodep) { m_sensesp = nodep; }
|
||||
AstSenTree* sensesp() const { return m_sensesp; }
|
||||
void sentreep(AstSenTree* nodep) { m_sentreep = nodep; }
|
||||
AstSenTree* sentreep() const { return m_sentreep; }
|
||||
// METHODS
|
||||
inline bool hasClocked() const;
|
||||
inline bool hasCombo() const;
|
||||
|
|
@ -2498,14 +2498,14 @@ public:
|
|||
|
||||
// === AstNodeProcedure ===
|
||||
class AstAlways final : public AstNodeProcedure {
|
||||
// @astgen op1 := sensesp : Optional[AstSenTree] // Sensitivity list iff clocked
|
||||
// @astgen op1 := sentreep : Optional[AstSenTree] // Sensitivity list iff clocked
|
||||
const VAlwaysKwd m_keyword;
|
||||
|
||||
public:
|
||||
AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sensesp, AstNode* stmtsp)
|
||||
AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sentreep, AstNode* stmtsp)
|
||||
: ASTGEN_SUPER_Always(fl, stmtsp)
|
||||
, m_keyword{keyword} {
|
||||
this->sensesp(sensesp);
|
||||
this->sentreep(sentreep);
|
||||
}
|
||||
ASTGEN_MEMBERS_AstAlways;
|
||||
//
|
||||
|
|
@ -2515,12 +2515,12 @@ public:
|
|||
};
|
||||
class AstAlwaysObserved final : public AstNodeProcedure {
|
||||
// Like always but Observed scheduling region
|
||||
// @astgen op1 := sensesp : Optional[AstSenTree] // Sensitivity list, removed in V3Active
|
||||
// @astgen op1 := sentreep : Optional[AstSenTree] // Sensitivity list, removed in V3Active
|
||||
|
||||
public:
|
||||
AstAlwaysObserved(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp)
|
||||
AstAlwaysObserved(FileLine* fl, AstSenTree* sentreep, AstNode* bodysp)
|
||||
: ASTGEN_SUPER_AlwaysObserved(fl, bodysp) {
|
||||
this->sensesp(sensesp);
|
||||
this->sentreep(sentreep);
|
||||
}
|
||||
ASTGEN_MEMBERS_AstAlwaysObserved;
|
||||
};
|
||||
|
|
@ -2542,12 +2542,12 @@ public:
|
|||
};
|
||||
class AstAlwaysReactive final : public AstNodeProcedure {
|
||||
// Like always but Reactive scheduling region
|
||||
// @astgen op1 := sensesp : Optional[AstSenTree] // Sensitivity list, removed in V3Active
|
||||
// @astgen op1 := sentreep : Optional[AstSenTree] // Sensitivity list, removed in V3Active
|
||||
|
||||
public:
|
||||
AstAlwaysReactive(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp)
|
||||
AstAlwaysReactive(FileLine* fl, AstSenTree* sentreep, AstNode* bodysp)
|
||||
: ASTGEN_SUPER_AlwaysReactive(fl, bodysp) {
|
||||
this->sensesp(sensesp);
|
||||
this->sentreep(sentreep);
|
||||
}
|
||||
ASTGEN_MEMBERS_AstAlwaysReactive;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -268,12 +268,12 @@ public:
|
|||
class AstAlwaysPublic final : public AstNodeStmt {
|
||||
// "Fake" sensitivity created by /*verilator public_flat_rw @(edgelist)*/
|
||||
// Body statements are just AstVarRefs to the public signals
|
||||
// @astgen op1 := sensesp : List[AstSenTree]
|
||||
// @astgen op1 := sentreep : Optional[AstSenTree]
|
||||
// @astgen op2 := stmtsp : List[AstNode]
|
||||
public:
|
||||
AstAlwaysPublic(FileLine* fl, AstSenTree* sensesp, AstNode* stmtsp)
|
||||
AstAlwaysPublic(FileLine* fl, AstSenTree* sentreep, AstNode* stmtsp)
|
||||
: ASTGEN_SUPER_AlwaysPublic(fl) {
|
||||
addSensesp(sensesp);
|
||||
this->sentreep(sentreep);
|
||||
addStmtsp(stmtsp);
|
||||
}
|
||||
ASTGEN_MEMBERS_AstAlwaysPublic;
|
||||
|
|
@ -605,12 +605,12 @@ public:
|
|||
};
|
||||
class AstEventControl final : public AstNodeStmt {
|
||||
// Parents: stmtlist
|
||||
// @astgen op1 := sensesp : Optional[AstSenTree]
|
||||
// @astgen op1 := sentreep : Optional[AstSenTree]
|
||||
// @astgen op2 := stmtsp : List[AstNode]
|
||||
public:
|
||||
AstEventControl(FileLine* fl, AstSenTree* sensesp, AstNode* stmtsp)
|
||||
AstEventControl(FileLine* fl, AstSenTree* sentreep, AstNode* stmtsp)
|
||||
: ASTGEN_SUPER_EventControl(fl) {
|
||||
this->sensesp(sensesp);
|
||||
this->sentreep(sentreep);
|
||||
addStmtsp(stmtsp);
|
||||
}
|
||||
ASTGEN_MEMBERS_AstEventControl;
|
||||
|
|
|
|||
|
|
@ -2814,8 +2814,8 @@ void AstDot::dumpJson(std::ostream& str) const {
|
|||
void AstActive::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
str << " => ";
|
||||
if (sensesp()) {
|
||||
sensesp()->dump(str);
|
||||
if (sentreep()) {
|
||||
sentreep()->dump(str);
|
||||
} else {
|
||||
str << "UNLINKED";
|
||||
}
|
||||
|
|
@ -3069,9 +3069,9 @@ void AstCFunc::dumpJson(std::ostream& str) const {
|
|||
}
|
||||
void AstCAwait::dump(std::ostream& str) const {
|
||||
this->AstNodeUniop::dump(str);
|
||||
if (sensesp()) {
|
||||
if (sentreep()) {
|
||||
str << " => ";
|
||||
sensesp()->dump(str);
|
||||
sentreep()->dump(str);
|
||||
}
|
||||
}
|
||||
void AstCAwait::dumpJson(std::ostream& str) const { dumpJsonGen(str); }
|
||||
|
|
|
|||
|
|
@ -85,10 +85,10 @@ class ClockVisitor final : public VNVisitor {
|
|||
}
|
||||
return senEqnp;
|
||||
}
|
||||
AstIf* makeActiveIf(AstSenTree* sensesp) {
|
||||
AstNodeExpr* const senEqnp = createSenseEquation(sensesp->sensesp());
|
||||
UASSERT_OBJ(senEqnp, sensesp, "No sense equation, shouldn't be in sequent activation.");
|
||||
AstIf* const newifp = new AstIf{sensesp->fileline(), senEqnp};
|
||||
AstIf* makeActiveIf(AstSenTree* sentreep) {
|
||||
AstNodeExpr* const senEqnp = createSenseEquation(sentreep->sensesp());
|
||||
UASSERT_OBJ(senEqnp, sentreep, "No sense equation, shouldn't be in sequent activation.");
|
||||
AstIf* const newifp = new AstIf{sentreep->fileline(), senEqnp};
|
||||
return newifp;
|
||||
}
|
||||
void clearLastSen() {
|
||||
|
|
@ -133,11 +133,11 @@ class ClockVisitor final : public VNVisitor {
|
|||
AstNode* const stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
|
||||
|
||||
// Create 'if' statement, if needed
|
||||
if (!m_lastSenp || !nodep->sensesp()->sameTree(m_lastSenp)) {
|
||||
if (!m_lastSenp || !nodep->sentreep()->sameTree(m_lastSenp)) {
|
||||
VNRelinker relinker;
|
||||
nodep->unlinkFrBack(&relinker);
|
||||
clearLastSen();
|
||||
m_lastSenp = nodep->sensesp();
|
||||
m_lastSenp = nodep->sentreep();
|
||||
// Make a new if statement
|
||||
m_lastIfp = makeActiveIf(m_lastSenp);
|
||||
relinker.relink(m_lastIfp);
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ class DelayedVisitor final : public VNVisitor {
|
|||
vscpInfo.shadowVariableKit().vscp = shadowVscp;
|
||||
// Create the AstActive for the Pre/Post logic
|
||||
AstActive* const activep = new AstActive{flp, "nba-shadow-variable", vscpInfo.senTreep()};
|
||||
activep->sensesStorep(vscpInfo.senTreep());
|
||||
activep->senTreeStorep(vscpInfo.senTreep());
|
||||
scopep->addBlocksp(activep);
|
||||
// Add 'Pre' scheduled 'shadowVariable = originalVariable' assignment
|
||||
activep->addStmtsp(new AstAssignPre{flp, new AstVarRef{flp, shadowVscp, VAccess::WRITE},
|
||||
|
|
@ -622,7 +622,7 @@ class DelayedVisitor final : public VNVisitor {
|
|||
// Create the AstActive for the Post logic
|
||||
AstActive* const activep
|
||||
= new AstActive{flp, "nba-shadow-var-masked", vscpInfo.senTreep()};
|
||||
activep->sensesStorep(vscpInfo.senTreep());
|
||||
activep->senTreeStorep(vscpInfo.senTreep());
|
||||
scopep->addBlocksp(activep);
|
||||
// Add 'Post' scheduled process for the commit and mask clear
|
||||
AstAlwaysPost* const postp = new AstAlwaysPost{flp};
|
||||
|
|
@ -676,7 +676,7 @@ class DelayedVisitor final : public VNVisitor {
|
|||
AstScope* const scopep = vscp->scopep();
|
||||
// Create the AstActive for the Pre/Post logic
|
||||
AstActive* const activep = new AstActive{flp, "nba-flag-shared", vscpInfo.senTreep()};
|
||||
activep->sensesStorep(vscpInfo.senTreep());
|
||||
activep->senTreeStorep(vscpInfo.senTreep());
|
||||
scopep->addBlocksp(activep);
|
||||
vscpInfo.flagSharedKit().activep = activep;
|
||||
// Add 'Post' scheduled process to be populated later
|
||||
|
|
@ -773,7 +773,7 @@ class DelayedVisitor final : public VNVisitor {
|
|||
AstScope* const scopep = vscp->scopep();
|
||||
// Create the AstActive for the Pre/Post logic
|
||||
AstActive* const activep = new AstActive{flp, "nba-flag-unique", vscpInfo.senTreep()};
|
||||
activep->sensesStorep(vscpInfo.senTreep());
|
||||
activep->senTreeStorep(vscpInfo.senTreep());
|
||||
scopep->addBlocksp(activep);
|
||||
// Add 'Post' scheduled process to be populated later
|
||||
AstAlwaysPost* const postp = new AstAlwaysPost{flp};
|
||||
|
|
@ -837,7 +837,7 @@ class DelayedVisitor final : public VNVisitor {
|
|||
// Create the AstActive for the Post logic
|
||||
AstActive* const activep
|
||||
= new AstActive{flp, "nba-value-queue-whole", vscpInfo.senTreep()};
|
||||
activep->sensesStorep(vscpInfo.senTreep());
|
||||
activep->senTreeStorep(vscpInfo.senTreep());
|
||||
scopep->addBlocksp(activep);
|
||||
// Add 'Post' scheduled process for the commit
|
||||
AstAlwaysPost* const postp = new AstAlwaysPost{flp};
|
||||
|
|
@ -1085,7 +1085,7 @@ class DelayedVisitor final : public VNVisitor {
|
|||
VL_RESTORER(m_ignoreBlkAndNBlk);
|
||||
VL_RESTORER(m_inNonCombLogic);
|
||||
m_activep = nodep;
|
||||
AstSenTree* const senTreep = nodep->sensesp();
|
||||
AstSenTree* const senTreep = nodep->sentreep();
|
||||
m_ignoreBlkAndNBlk = senTreep->hasStatic() || senTreep->hasInitial();
|
||||
m_inNonCombLogic = senTreep->hasClocked();
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -1131,7 +1131,7 @@ class DelayedVisitor final : public VNVisitor {
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstCAwait* nodep) override {
|
||||
if (nodep->sensesp()) m_timingDomains.insert(nodep->sensesp());
|
||||
if (nodep->sentreep()) m_timingDomains.insert(nodep->sentreep());
|
||||
}
|
||||
void visit(AstFireEvent* nodep) override {
|
||||
UASSERT_OBJ(v3Global.hasEvents(), nodep, "Inconsistent");
|
||||
|
|
@ -1166,7 +1166,7 @@ class DelayedVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
UASSERT_OBJ(m_activep, nodep, "No active to handle FireEvent");
|
||||
AstActive* const activep = new AstActive{flp, "nba-event", m_activep->sensesp()};
|
||||
AstActive* const activep = new AstActive{flp, "nba-event", m_activep->sentreep()};
|
||||
m_activep->addNextHere(activep);
|
||||
activep->addStmtsp(prep);
|
||||
activep->addStmtsp(postp);
|
||||
|
|
@ -1238,7 +1238,7 @@ class DelayedVisitor final : public VNVisitor {
|
|||
vscpInfo.m_inLoop |= m_inLoop;
|
||||
vscpInfo.m_inSuspOrFork |= m_inSuspendableOrFork;
|
||||
// Sensitivity might be non-clocked, in a suspendable process, which are handled elsewhere
|
||||
if (m_activep->sensesp()->hasClocked()) {
|
||||
if (m_activep->sentreep()->hasClocked()) {
|
||||
if (vscpInfo.m_fistActivep != m_activep) {
|
||||
AstVar* const varp = vscp->varp();
|
||||
if (!varp->user1SetOnce()
|
||||
|
|
@ -1255,7 +1255,7 @@ class DelayedVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
// Add this sensitivity to the variable
|
||||
vscpInfo.addSensitivity(m_activep->sensesp());
|
||||
vscpInfo.addSensitivity(m_activep->sentreep());
|
||||
}
|
||||
|
||||
// Record the NBA for later processing
|
||||
|
|
|
|||
|
|
@ -492,7 +492,7 @@ public:
|
|||
bool convert(AstAlways* nodep) {
|
||||
// Ignore sequential logic
|
||||
const VAlwaysKwd kwd = nodep->keyword();
|
||||
if (nodep->sensesp() || (kwd != VAlwaysKwd::ALWAYS && kwd != VAlwaysKwd::ALWAYS_COMB)) {
|
||||
if (nodep->sentreep() || (kwd != VAlwaysKwd::ALWAYS && kwd != VAlwaysKwd::ALWAYS_COMB)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ class DfgToAstVisitor final : DfgVisitor {
|
|||
AstSenTree* const senTreep
|
||||
= new AstSenTree{flp, new AstSenItem{flp, AstSenItem::Combo{}}};
|
||||
AstActive* const activep = new AstActive{flp, "", senTreep};
|
||||
activep->sensesStorep(senTreep);
|
||||
activep->senTreeStorep(senTreep);
|
||||
scopep->addBlocksp(activep);
|
||||
scopep->user2p(activep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ class DataflowExtractVisitor final : public VNVisitor {
|
|||
void visit(AstAlways* nodep) override {
|
||||
VL_RESTORER(m_candidatesp);
|
||||
// Only extract from combinational logic under proper modules
|
||||
const bool isComb = !nodep->sensesp()
|
||||
const bool isComb = !nodep->sentreep()
|
||||
&& (nodep->keyword() == VAlwaysKwd::ALWAYS
|
||||
|| nodep->keyword() == VAlwaysKwd::ALWAYS_COMB
|
||||
|| nodep->keyword() == VAlwaysKwd::ALWAYS_LATCH);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
|
|||
const bool m_suppressUnknown; // Do not error on unknown node
|
||||
|
||||
// STATE - for current visit position (use VL_RESTORER)
|
||||
AstSenTree* m_sensesp = nullptr; // Domain for printing one a ALWAYS under a ACTIVE
|
||||
AstSenTree* m_sentreep = nullptr; // Domain for printing one a ALWAYS under a ACTIVE
|
||||
bool m_suppressSemi = false; // Non-statement, don't print ;
|
||||
bool m_suppressVarSemi = false; // Suppress emitting semicolon for AstVars
|
||||
bool m_arrayPost = false; // Print array information that goes after identifier (vs after)
|
||||
|
|
@ -122,11 +122,11 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
|
|||
void visit(AstInitialStatic* nodep) override { iterateChildrenConst(nodep); }
|
||||
void visit(AstAlways* nodep) override {
|
||||
putfs(nodep, "always ");
|
||||
if (m_sensesp) {
|
||||
iterateAndNextConstNull(m_sensesp);
|
||||
if (m_sentreep) {
|
||||
iterateAndNextConstNull(m_sentreep);
|
||||
} // In active
|
||||
else {
|
||||
iterateAndNextConstNull(nodep->sensesp());
|
||||
iterateAndNextConstNull(nodep->sentreep());
|
||||
}
|
||||
putbs(" begin\n");
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
|
|
@ -134,11 +134,11 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
|
|||
}
|
||||
void visit(AstAlwaysPublic* nodep) override {
|
||||
putfs(nodep, "/*verilator public_flat_rw ");
|
||||
if (m_sensesp) {
|
||||
iterateAndNextConstNull(m_sensesp);
|
||||
if (m_sentreep) {
|
||||
iterateAndNextConstNull(m_sentreep);
|
||||
} // In active
|
||||
else {
|
||||
iterateAndNextConstNull(nodep->sensesp());
|
||||
iterateAndNextConstNull(nodep->sentreep());
|
||||
}
|
||||
putqs(nodep, " ");
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
|
|
@ -923,8 +923,8 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
|
|||
puts(m_suppressVarSemi ? "\n" : ";\n");
|
||||
}
|
||||
void visit(AstActive* nodep) override {
|
||||
VL_RESTORER(m_sensesp);
|
||||
m_sensesp = nodep->sensesp();
|
||||
VL_RESTORER(m_sentreep);
|
||||
m_sentreep = nodep->sentreep();
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
}
|
||||
void visit(AstDelay* nodep) override {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public:
|
|||
AstActive* const activep = new AstActive{
|
||||
flp, "force-init",
|
||||
new AstSenTree{flp, new AstSenItem{flp, AstSenItem::Static{}}}};
|
||||
activep->sensesStorep(activep->sensesp());
|
||||
activep->senTreeStorep(activep->sentreep());
|
||||
|
||||
activep->addStmtsp(new AstInitial{flp, assignp});
|
||||
vscp->scopep()->addBlocksp(activep);
|
||||
|
|
@ -120,7 +120,7 @@ public:
|
|||
new AstSenItem{flp, VEdgeType::ET_CHANGED, origp->cloneTree(false)});
|
||||
AstActive* const activep
|
||||
= new AstActive{flp, "force-update", new AstSenTree{flp, itemsp}};
|
||||
activep->sensesStorep(activep->sensesp());
|
||||
activep->senTreeStorep(activep->sentreep());
|
||||
activep->addStmtsp(new AstAlways{flp, VAlwaysKwd::ALWAYS, nullptr,
|
||||
new AstAssign{flp, lhsp, rhsp}});
|
||||
vscp->scopep()->addBlocksp(activep);
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ class HasherVisitor final : public VNVisitorConst {
|
|||
}
|
||||
void visit(AstCAwait* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [this, nodep]() { //
|
||||
iterateConstNull(nodep->sensesp());
|
||||
iterateConstNull(nodep->sentreep());
|
||||
});
|
||||
}
|
||||
void visit(AstCLocalScope* nodep) override {
|
||||
|
|
@ -480,7 +480,7 @@ class HasherVisitor final : public VNVisitorConst {
|
|||
}
|
||||
void visit(AstActive* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [this, nodep]() { //
|
||||
iterateConstNull(nodep->sensesp());
|
||||
iterateConstNull(nodep->sentreep());
|
||||
});
|
||||
}
|
||||
void visit(AstCell* nodep) override {
|
||||
|
|
|
|||
|
|
@ -837,11 +837,11 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
"(IEEE 1800-2023 9.2.2.2.2)\n"
|
||||
<< nodep->warnMore() << "... Suggest use a normal 'always'");
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
} else if (alwaysp && !alwaysp->sensesp()) {
|
||||
} else if (alwaysp && !alwaysp->sentreep()) {
|
||||
// If the event control is at the top, move the sentree to the always
|
||||
if (AstSenTree* const sensesp = nodep->sensesp()) {
|
||||
sensesp->unlinkFrBackWithNext();
|
||||
alwaysp->sensesp(sensesp);
|
||||
if (AstSenTree* const sentreep = nodep->sentreep()) {
|
||||
sentreep->unlinkFrBackWithNext();
|
||||
alwaysp->sentreep(sentreep);
|
||||
}
|
||||
if (nodep->stmtsp()) alwaysp->addStmtsp(nodep->stmtsp()->unlinkFrBackWithNext());
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ public:
|
|||
// When profCFuncs, create a new function for each logic vertex
|
||||
if (v3Global.opt.profCFuncs()) forceNewFunction();
|
||||
// If the new domain is different, force a new function as it needs to be called separately
|
||||
if (!m_activeps.empty() && m_activeps.back()->sensesp() != domainp) forceNewFunction();
|
||||
if (!m_activeps.empty() && m_activeps.back()->sentreep() != domainp) forceNewFunction();
|
||||
|
||||
// Process procedures per statement, so we can split CFuncs within procedures.
|
||||
// Everything else is handled as a unit.
|
||||
|
|
@ -146,7 +146,7 @@ public:
|
|||
AstCCall* const callp = new AstCCall{flp, m_funcp};
|
||||
callp->dtypeSetVoid();
|
||||
// Call it under an AstActive with the same sensitivity
|
||||
if (m_activeps.empty() || m_activeps.back()->sensesp() != domainp) {
|
||||
if (m_activeps.empty() || m_activeps.back()->sentreep() != domainp) {
|
||||
m_activeps.emplace_back(new AstActive{flp, name, domainp});
|
||||
}
|
||||
m_activeps.back()->addStmtsp(callp->makeStmt());
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ class OrderGraphBuilder final : public VNVisitor {
|
|||
|
||||
// VISITORS
|
||||
void visit(AstActive* nodep) override {
|
||||
UASSERT_OBJ(!nodep->sensesStorep(), nodep,
|
||||
UASSERT_OBJ(!nodep->senTreeStorep(), nodep,
|
||||
"AstSenTrees should have been made global in V3ActiveTop");
|
||||
UASSERT_OBJ(m_scopep, nodep, "AstActive not under AstScope");
|
||||
UASSERT_OBJ(!m_logicVxp, nodep, "AstActive under logic");
|
||||
|
|
@ -138,8 +138,9 @@ class OrderGraphBuilder final : public VNVisitor {
|
|||
|
||||
// This is the original sensitivity of the block (i.e.: not the ref into the TRIGGERVEC)
|
||||
|
||||
const AstSenTree* const senTreep
|
||||
= nodep->sensesp()->hasCombo() ? nodep->sensesp() : m_trigToSen.at(nodep->sensesp());
|
||||
const AstSenTree* const senTreep = nodep->sentreep()->hasCombo()
|
||||
? nodep->sentreep()
|
||||
: m_trigToSen.at(nodep->sentreep());
|
||||
|
||||
m_inClocked = senTreep->hasClocked();
|
||||
|
||||
|
|
@ -149,11 +150,11 @@ class OrderGraphBuilder final : public VNVisitor {
|
|||
|
||||
// Combinational and hybrid logic will have it's domain assigned based on the driver
|
||||
// domains. For clocked logic, we already know its domain.
|
||||
if (!senTreep->hasCombo() && !senTreep->hasHybrid()) m_domainp = nodep->sensesp();
|
||||
if (!senTreep->hasCombo() && !senTreep->hasHybrid()) m_domainp = nodep->sentreep();
|
||||
|
||||
// Hybrid logic also includes additional sensitivities
|
||||
if (senTreep->hasHybrid()) {
|
||||
m_hybridp = nodep->sensesp();
|
||||
m_hybridp = nodep->sentreep();
|
||||
// Mark AstVarScopes that are explicit sensitivities
|
||||
AstNode::user3ClearTree();
|
||||
senTreep->foreach([](const AstVarRef* refp) { //
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ std::vector<const AstSenTree*> getSenTreesUsedBy(const std::vector<const LogicBy
|
|||
for (const LogicByScope* const lbsp : lbsps) {
|
||||
for (const auto& pair : *lbsp) {
|
||||
AstActive* const activep = pair.second;
|
||||
AstSenTree* const senTreep = activep->sensesp();
|
||||
AstSenTree* const senTreep = activep->sentreep();
|
||||
if (senTreep->user1SetOnce()) continue;
|
||||
if (senTreep->hasClocked() || senTreep->hasHybrid()) result.push_back(senTreep);
|
||||
}
|
||||
|
|
@ -92,9 +92,9 @@ void remapSensitivities(const LogicByScope& lbs,
|
|||
std::unordered_map<const AstSenTree*, AstSenTree*> senTreeMap) {
|
||||
for (const auto& pair : lbs) {
|
||||
AstActive* const activep = pair.second;
|
||||
AstSenTree* const senTreep = activep->sensesp();
|
||||
AstSenTree* const senTreep = activep->sentreep();
|
||||
if (senTreep->hasCombo()) continue;
|
||||
activep->sensesp(senTreeMap.at(senTreep));
|
||||
activep->sentreep(senTreeMap.at(senTreep));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -368,7 +368,7 @@ LogicClasses gatherLogicClasses(AstNetlist* netlistp) {
|
|||
|
||||
netlistp->foreach([&](AstScope* scopep) {
|
||||
scopep->foreach([&](AstActive* activep) {
|
||||
AstSenTree* const senTreep = activep->sensesp();
|
||||
AstSenTree* const senTreep = activep->sentreep();
|
||||
if (senTreep->hasStatic()) {
|
||||
UASSERT_OBJ(!senTreep->sensesp()->nextp(), activep,
|
||||
"static initializer with additional sensitivities");
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ struct LogicByScope final : public std::vector<std::pair<AstScope*, AstActive*>>
|
|||
// Add logic
|
||||
void add(AstScope* scopep, AstSenTree* senTreep, AstNode* logicp) {
|
||||
UASSERT_OBJ(!logicp->backp(), logicp, "Already linked");
|
||||
if (empty() || back().first != scopep || back().second->sensesp() != senTreep) {
|
||||
if (empty() || back().first != scopep || back().second->sentreep() != senTreep) {
|
||||
emplace_back(scopep, new AstActive{logicp->fileline(), "", senTreep});
|
||||
}
|
||||
back().second->addStmtsp(logicp);
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ class SchedGraphBuilder final : public VNVisitor {
|
|||
|
||||
// VISIT methods
|
||||
void visit(AstActive* nodep) override {
|
||||
AstSenTree* const senTreep = nodep->sensesp();
|
||||
AstSenTree* const senTreep = nodep->sentreep();
|
||||
UASSERT_OBJ(senTreep->hasClocked() || senTreep->hasCombo() || senTreep->hasHybrid(), nodep,
|
||||
"Unhandled");
|
||||
UASSERT_OBJ(!m_senTreep, nodep, "Should not nest");
|
||||
|
|
@ -369,7 +369,7 @@ LogicRegions partition(LogicByScope& clockedLogic, LogicByScope& combinationalLo
|
|||
|
||||
for (const auto& pair : result.m_act) {
|
||||
AstActive* const activep = pair.second;
|
||||
markVars(activep->sensesp());
|
||||
markVars(activep->sentreep());
|
||||
markVars(activep);
|
||||
}
|
||||
|
||||
|
|
@ -394,12 +394,12 @@ LogicRegions partition(LogicByScope& clockedLogic, LogicByScope& combinationalLo
|
|||
});
|
||||
LogicByScope& lbs = toActiveRegion ? result.m_pre : result.m_nba;
|
||||
logicp->unlinkFrBack();
|
||||
lbs.add(scopep, activep->sensesp(), logicp);
|
||||
lbs.add(scopep, activep->sentreep(), logicp);
|
||||
} else {
|
||||
UASSERT_OBJ(VN_IS(nodep, AssignPost) || VN_IS(nodep, AlwaysPost), nodep,
|
||||
"Unexpected node type " << nodep->typeName());
|
||||
nodep->unlinkFrBack();
|
||||
result.m_nba.add(scopep, activep->sensesp(), nodep);
|
||||
result.m_nba.add(scopep, activep->sentreep(), nodep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ std::unique_ptr<Graph> buildGraph(const LogicRegions& logicRegions) {
|
|||
};
|
||||
|
||||
const auto addLogic = [&](RegionFlags region, AstScope* scopep, AstActive* activep) {
|
||||
AstSenTree* const senTreep = activep->sensesp();
|
||||
AstSenTree* const senTreep = activep->sentreep();
|
||||
|
||||
// Predicate for whether a read of the given variable triggers this block
|
||||
std::function<bool(AstVarScope*)> readTriggersThisLogic;
|
||||
|
|
|
|||
|
|
@ -115,15 +115,15 @@ AstCCall* TimingKit::createCommit(AstNetlist* const netlistp) {
|
|||
m_commitFuncp->declPrivate(true);
|
||||
scopeTopp->addBlocksp(m_commitFuncp);
|
||||
}
|
||||
AstSenTree* const sensesp = activep->sensesp();
|
||||
FileLine* const flp = sensesp->fileline();
|
||||
AstSenTree* const sentreep = activep->sentreep();
|
||||
FileLine* const flp = sentreep->fileline();
|
||||
// Negate the sensitivity. We will commit only if the event wasn't triggered on the
|
||||
// current iteration
|
||||
auto* const negSensesp = sensesp->cloneTree(false);
|
||||
negSensesp->sensesp()->sensp(
|
||||
new AstLogNot{flp, negSensesp->sensesp()->sensp()->unlinkFrBack()});
|
||||
sensesp->addNextHere(negSensesp);
|
||||
auto* const newactp = new AstActive{flp, "", negSensesp};
|
||||
auto* const negSentreep = sentreep->cloneTree(false);
|
||||
negSentreep->sensesp()->sensp(
|
||||
new AstLogNot{flp, negSentreep->sensesp()->sensp()->unlinkFrBack()});
|
||||
sentreep->addNextHere(negSentreep);
|
||||
auto* const newactp = new AstActive{flp, "", negSentreep};
|
||||
// Create the commit call and put it in the commit function
|
||||
auto* const commitp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, schedulerp, VAccess::READWRITE}, "commit"};
|
||||
|
|
@ -180,8 +180,8 @@ TimingKit prepareTiming(AstNetlist* const netlistp) {
|
|||
void createResumeActive(AstCAwait* const awaitp) {
|
||||
auto* const methodp = VN_AS(awaitp->exprp(), CMethodHard);
|
||||
AstVarScope* const schedulerp = VN_AS(methodp->fromp(), VarRef)->varScopep();
|
||||
AstSenTree* const sensesp = awaitp->sensesp();
|
||||
FileLine* const flp = sensesp->fileline();
|
||||
AstSenTree* const sentreep = awaitp->sentreep();
|
||||
FileLine* const flp = sentreep->fileline();
|
||||
// Create a resume() call on the timing scheduler
|
||||
auto* const resumep = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, schedulerp, VAccess::READWRITE}, "resume"};
|
||||
|
|
@ -201,7 +201,7 @@ TimingKit prepareTiming(AstNetlist* const netlistp) {
|
|||
m_postUpdatesr = AstNode::addNext(m_postUpdatesr, postp->makeStmt());
|
||||
}
|
||||
// Put it in an active and put that in the global resume function
|
||||
auto* const activep = new AstActive{flp, "_timing", sensesp};
|
||||
auto* const activep = new AstActive{flp, "_timing", sentreep};
|
||||
activep->addStmtsp(resumep->makeStmt());
|
||||
m_lbs.emplace_back(m_scopeTopp, activep);
|
||||
}
|
||||
|
|
@ -232,10 +232,10 @@ TimingKit prepareTiming(AstNetlist* const netlistp) {
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstCAwait* nodep) override {
|
||||
if (AstSenTree* const sensesp = nodep->sensesp()) {
|
||||
if (!sensesp->user1SetOnce()) createResumeActive(nodep);
|
||||
nodep->clearSensesp(); // Clear as these sentrees will get deleted later
|
||||
if (m_inProcess) m_processDomains.insert(sensesp);
|
||||
if (AstSenTree* const sentreep = nodep->sentreep()) {
|
||||
if (!sentreep->user1SetOnce()) createResumeActive(nodep);
|
||||
nodep->clearSentreep(); // Clear as these sentrees will get deleted later
|
||||
if (m_inProcess) m_processDomains.insert(sentreep);
|
||||
}
|
||||
}
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
|
|
|
|||
|
|
@ -473,16 +473,16 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
|||
void visit(AstNodeStmt* nodep) override { setContextAndIterateChildren(nodep); }
|
||||
void visit(AstCell* nodep) override { setContextAndIterateChildren(nodep); }
|
||||
void visit(AstAlways* nodep) override {
|
||||
if (nodep->sensesp()) { // When visiting sensitivity list, always is the context
|
||||
setContextAndIterate(nodep, nodep->sensesp());
|
||||
if (nodep->sentreep()) { // When visiting sensitivity list, always is the context
|
||||
setContextAndIterate(nodep, nodep->sentreep());
|
||||
}
|
||||
for (AstNode* bodysp = nodep->stmtsp(); bodysp; bodysp = bodysp->nextp()) {
|
||||
iterate(bodysp);
|
||||
}
|
||||
};
|
||||
void visit(AstAlwaysPublic* nodep) override {
|
||||
if (nodep->sensesp()) { // When visiting sensitivity list, always is the context
|
||||
setContextAndIterate(nodep, nodep->sensesp());
|
||||
if (nodep->sentreep()) { // When visiting sensitivity list, always is the context
|
||||
setContextAndIterate(nodep, nodep->sentreep());
|
||||
}
|
||||
for (AstNode* bodysp = nodep->stmtsp(); bodysp; bodysp = bodysp->nextp()) {
|
||||
iterate(bodysp);
|
||||
|
|
|
|||
|
|
@ -506,9 +506,9 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
stmtp->replaceWith(delayp->unlinkFrBack());
|
||||
delayp->addStmtsp(stmtp);
|
||||
stmtp = delayp;
|
||||
} else if (AstSenTree* const sensesp = VN_CAST(controlp, SenTree)) {
|
||||
} else if (AstSenTree* const sentreep = VN_CAST(controlp, SenTree)) {
|
||||
AstEventControl* const eventControlp
|
||||
= new AstEventControl{sensesp->fileline(), sensesp->unlinkFrBack(), nullptr};
|
||||
= new AstEventControl{sentreep->fileline(), sentreep->unlinkFrBack(), nullptr};
|
||||
stmtp->replaceWith(eventControlp);
|
||||
eventControlp->addStmtsp(stmtp);
|
||||
stmtp = eventControlp;
|
||||
|
|
@ -619,8 +619,8 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
});
|
||||
}
|
||||
// Creates a trigger scheduler variable
|
||||
AstVarScope* getCreateTriggerSchedulerp(AstSenTree* const sensesp) {
|
||||
if (!sensesp->user1p()) {
|
||||
AstVarScope* getCreateTriggerSchedulerp(AstSenTree* const sentreep) {
|
||||
if (!sentreep->user1p()) {
|
||||
if (!m_trigSchedDtp) {
|
||||
m_trigSchedDtp
|
||||
= new AstBasicDType{m_scopeTopp->fileline(), VBasicDTypeKwd::TRIGGER_SCHEDULER,
|
||||
|
|
@ -628,27 +628,27 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
m_netlistp->typeTablep()->addTypesp(m_trigSchedDtp);
|
||||
}
|
||||
AstVarScope* const trigSchedp
|
||||
= m_scopeTopp->createTemp(m_trigSchedNames.get(sensesp), m_trigSchedDtp);
|
||||
sensesp->user1p(trigSchedp);
|
||||
= m_scopeTopp->createTemp(m_trigSchedNames.get(sentreep), m_trigSchedDtp);
|
||||
sentreep->user1p(trigSchedp);
|
||||
}
|
||||
return VN_AS(sensesp->user1p(), VarScope);
|
||||
return VN_AS(sentreep->user1p(), VarScope);
|
||||
}
|
||||
// Creates a string describing the sentree
|
||||
AstCExpr* createEventDescription(AstSenTree* const sensesp) const {
|
||||
if (!sensesp->user2p()) {
|
||||
AstCExpr* createEventDescription(AstSenTree* const sentreep) const {
|
||||
if (!sentreep->user2p()) {
|
||||
std::stringstream ss;
|
||||
ss << '"';
|
||||
V3EmitV::verilogForTree(sensesp, ss);
|
||||
V3EmitV::verilogForTree(sentreep, ss);
|
||||
ss << '"';
|
||||
// possibly a multiline string
|
||||
std::string comment = ss.str();
|
||||
std::replace(comment.begin(), comment.end(), '\n', ' ');
|
||||
AstCExpr* const commentp = new AstCExpr{sensesp->fileline(), comment, 0};
|
||||
AstCExpr* const commentp = new AstCExpr{sentreep->fileline(), comment, 0};
|
||||
commentp->dtypeSetString();
|
||||
sensesp->user2p(commentp);
|
||||
sentreep->user2p(commentp);
|
||||
return commentp;
|
||||
}
|
||||
return VN_AS(sensesp->user2p(), CExpr)->cloneTree(false);
|
||||
return VN_AS(sentreep->user2p(), CExpr)->cloneTree(false);
|
||||
}
|
||||
// Adds debug info to a hardcoded method call
|
||||
void addDebugInfo(AstCMethodHard* const methodp) const {
|
||||
|
|
@ -662,9 +662,9 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
methodp->addPinsp(bp);
|
||||
}
|
||||
// Adds debug info to a trigSched.trigger() call
|
||||
void addEventDebugInfo(AstCMethodHard* const methodp, AstSenTree* const sensesp) const {
|
||||
void addEventDebugInfo(AstCMethodHard* const methodp, AstSenTree* const sentreep) const {
|
||||
if (v3Global.opt.protectIds()) return;
|
||||
methodp->addPinsp(createEventDescription(sensesp));
|
||||
methodp->addPinsp(createEventDescription(sentreep));
|
||||
addDebugInfo(methodp);
|
||||
}
|
||||
// Adds process pointer to a hardcoded method call
|
||||
|
|
@ -812,17 +812,17 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
if (!hasFlags(nodep, T_SUSPENDEE)) return;
|
||||
nodep->setSuspendable();
|
||||
FileLine* const flp = nodep->fileline();
|
||||
AstSenTree* const sensesp = m_activep->sensesp();
|
||||
if (sensesp->hasClocked()) {
|
||||
AstSenTree* const sentreep = m_activep->sentreep();
|
||||
if (sentreep->hasClocked()) {
|
||||
AstNode* const bodysp = nodep->stmtsp()->unlinkFrBackWithNext();
|
||||
auto* const controlp = new AstEventControl{flp, sensesp->cloneTree(false), bodysp};
|
||||
auto* const controlp = new AstEventControl{flp, sentreep->cloneTree(false), bodysp};
|
||||
nodep->addStmtsp(controlp);
|
||||
iterate(controlp);
|
||||
}
|
||||
// Note: The 'while (true)' outer loop will be added in V3Sched
|
||||
auto* const activep = new AstActive{
|
||||
flp, "", new AstSenTree{flp, new AstSenItem{flp, AstSenItem::Initial{}}}};
|
||||
activep->sensesStorep(activep->sensesp());
|
||||
activep->senTreeStorep(activep->sentreep());
|
||||
activep->addStmtsp(nodep->unlinkFrBack());
|
||||
m_activep->addNextHere(activep);
|
||||
}
|
||||
|
|
@ -905,11 +905,12 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
void visit(AstEventControl* nodep) override {
|
||||
// Do not allow waiting on local named events, as they get enqueued for clearing, but can
|
||||
// go out of scope before that happens
|
||||
if (!nodep->sensesp()) nodep->v3warn(E_UNSUPPORTED, "Unsupported: no sense equation (@*)");
|
||||
if (!nodep->sentreep())
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: no sense equation (@*)");
|
||||
FileLine* const flp = nodep->fileline();
|
||||
// Relink child statements after the event control
|
||||
if (nodep->stmtsp()) nodep->addNextHere(nodep->stmtsp()->unlinkFrBackWithNext());
|
||||
if (needDynamicTrigger(nodep->sensesp())) {
|
||||
if (needDynamicTrigger(nodep->sentreep())) {
|
||||
// Create the trigger variable and init it with 0
|
||||
AstVarScope* const trigvscp
|
||||
= createTemp(flp, m_dynTrigNames.get(nodep), nodep->findBitDType(), nodep);
|
||||
|
|
@ -923,8 +924,8 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
"evaluation"};
|
||||
evalMethodp->dtypeSetVoid();
|
||||
addProcessInfo(evalMethodp);
|
||||
auto* const sensesp = nodep->sensesp();
|
||||
addEventDebugInfo(evalMethodp, sensesp);
|
||||
auto* const sentreep = nodep->sentreep();
|
||||
addEventDebugInfo(evalMethodp, sentreep);
|
||||
// Create the co_await
|
||||
AstCAwait* const awaitEvalp
|
||||
= new AstCAwait{flp, evalMethodp, getCreateDynamicTriggerSenTree()};
|
||||
|
|
@ -932,7 +933,7 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
// Construct the sen expression for this sentree
|
||||
UASSERT_OBJ(m_senExprBuilderp, nodep, "No SenExprBuilder for this scope");
|
||||
auto* const assignp = new AstAssign{flp, new AstVarRef{flp, trigvscp, VAccess::WRITE},
|
||||
m_senExprBuilderp->build(sensesp).first};
|
||||
m_senExprBuilderp->build(sentreep).first};
|
||||
// Get the SenExprBuilder results
|
||||
const SenExprBuilder::Results senResults = m_senExprBuilderp->getAndClearResults();
|
||||
// Put all and inits before the trigger eval loop
|
||||
|
|
@ -957,7 +958,7 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
loopp->addStmtsp(anyTriggeredMethodp->makeStmt());
|
||||
// If the post update is destructive (e.g. event vars are cleared), create an await for
|
||||
// the post update step
|
||||
if (destructivePostUpdate(sensesp)) {
|
||||
if (destructivePostUpdate(sentreep)) {
|
||||
AstCAwait* const awaitPostUpdatep = awaitEvalp->cloneTree(false);
|
||||
VN_AS(awaitPostUpdatep->exprp(), CMethodHard)->name("postUpdate");
|
||||
loopp->addStmtsp(awaitPostUpdatep->makeStmt());
|
||||
|
|
@ -971,21 +972,21 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
// Replace the event control with the loop
|
||||
nodep->replaceWith(loopp);
|
||||
} else {
|
||||
auto* const sensesp = m_finder.getSenTree(nodep->sensesp());
|
||||
nodep->sensesp()->unlinkFrBack()->deleteTree();
|
||||
auto* const sentreep = m_finder.getSenTree(nodep->sentreep());
|
||||
nodep->sentreep()->unlinkFrBack()->deleteTree();
|
||||
// Get this sentree's trigger scheduler
|
||||
// Replace self with a 'co_await trigSched.trigger()'
|
||||
auto* const triggerMethodp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, getCreateTriggerSchedulerp(sensesp), VAccess::WRITE},
|
||||
flp, new AstVarRef{flp, getCreateTriggerSchedulerp(sentreep), VAccess::WRITE},
|
||||
"trigger"};
|
||||
triggerMethodp->dtypeSetVoid();
|
||||
// If it should be committed immediately, pass true, otherwise false
|
||||
triggerMethodp->addPinsp(nodep->user2() ? new AstConst{flp, AstConst::BitTrue{}}
|
||||
: new AstConst{flp, AstConst::BitFalse{}});
|
||||
addProcessInfo(triggerMethodp);
|
||||
addEventDebugInfo(triggerMethodp, sensesp);
|
||||
addEventDebugInfo(triggerMethodp, sentreep);
|
||||
// Create the co_await
|
||||
AstCAwait* const awaitp = new AstCAwait{flp, triggerMethodp, sensesp};
|
||||
AstCAwait* const awaitp = new AstCAwait{flp, triggerMethodp, sentreep};
|
||||
awaitp->dtypeSetVoid();
|
||||
nodep->replaceWith(awaitp->makeStmt());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,10 +147,10 @@
|
|||
"lhsp": [
|
||||
{"type":"PARSEREF","name":"result","addr":"(RC)","loc":"e,33:16,33:22","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []}
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ALWAYS","name":"","addr":"(SC)","loc":"e,36:4,36:10","keyword":"always","isSuspendable":false,"needProcess":false,"sensesp": [],
|
||||
{"type":"ALWAYS","name":"","addr":"(SC)","loc":"e,36:4,36:10","keyword":"always","isSuspendable":false,"needProcess":false,"sentreep": [],
|
||||
"stmtsp": [
|
||||
{"type":"EVENTCONTROL","name":"","addr":"(TC)","loc":"e,36:11,36:12",
|
||||
"sensesp": [
|
||||
"sentreep": [
|
||||
{"type":"SENTREE","name":"","addr":"(UC)","loc":"e,36:11,36:12","isMulti":false,
|
||||
"sensesp": [
|
||||
{"type":"SENITEM","name":"","addr":"(VC)","loc":"e,36:14,36:21","edgeType":"POS",
|
||||
|
|
@ -466,10 +466,10 @@
|
|||
]}
|
||||
]}
|
||||
],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"ALWAYS","name":"","addr":"(PH)","loc":"e,82:4,82:10","keyword":"always","isSuspendable":false,"needProcess":false,"sensesp": [],
|
||||
{"type":"ALWAYS","name":"","addr":"(PH)","loc":"e,82:4,82:10","keyword":"always","isSuspendable":false,"needProcess":false,"sentreep": [],
|
||||
"stmtsp": [
|
||||
{"type":"EVENTCONTROL","name":"","addr":"(QH)","loc":"e,82:11,82:12",
|
||||
"sensesp": [
|
||||
"sentreep": [
|
||||
{"type":"SENTREE","name":"","addr":"(RH)","loc":"e,82:11,82:12","isMulti":false,
|
||||
"sensesp": [
|
||||
{"type":"SENITEM","name":"","addr":"(SH)","loc":"e,82:13,82:20","edgeType":"POS",
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
{"type":"CONST","name":"32'sh1","addr":"(OB)","loc":"d,39:25,39:26","dtypep":"(LB)"}
|
||||
],"attrsp": []},
|
||||
{"type":"ALWAYS","name":"","addr":"(PB)","loc":"d,41:4,41:10","keyword":"always","isSuspendable":false,"needProcess":false,
|
||||
"sensesp": [
|
||||
"sentreep": [
|
||||
{"type":"SENTREE","name":"","addr":"(QB)","loc":"d,41:11,41:12","isMulti":false,
|
||||
"sensesp": [
|
||||
{"type":"SENITEM","name":"","addr":"(RB)","loc":"d,41:13,41:20","edgeType":"POS",
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@
|
|||
{"type":"VARREF","name":"t.cell1.q","addr":"(HC)","loc":"d,36:30,36:31","dtypep":"(H)","access":"WR","varp":"(U)","varScopep":"(LB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ALWAYS","name":"","addr":"(IC)","loc":"d,41:4,41:10","keyword":"always","isSuspendable":false,"needProcess":false,
|
||||
"sensesp": [
|
||||
"sentreep": [
|
||||
{"type":"SENTREE","name":"","addr":"(JC)","loc":"d,41:11,41:12","isMulti":false,
|
||||
"sensesp": [
|
||||
{"type":"SENITEM","name":"","addr":"(KC)","loc":"d,41:13,41:20","edgeType":"POS",
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@
|
|||
"lhsp": [
|
||||
{"type":"VARREF","name":"vlvbound_test.o_b","addr":"(BC)","loc":"d,12:25,12:28","dtypep":"(K)","access":"WR","varp":"(P)","varScopep":"(Y)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ALWAYS","name":"","addr":"(CC)","loc":"d,24:14,24:15","keyword":"always","isSuspendable":false,"needProcess":false,"sensesp": [],
|
||||
{"type":"ALWAYS","name":"","addr":"(CC)","loc":"d,24:14,24:15","keyword":"always","isSuspendable":false,"needProcess":false,"sentreep": [],
|
||||
"stmtsp": [
|
||||
{"type":"COMMENT","name":"Function: foo","addr":"(DC)","loc":"d,24:16,24:19"},
|
||||
{"type":"ASSIGN","name":"","addr":"(EC)","loc":"d,24:20,24:23","dtypep":"(H)",
|
||||
|
|
@ -170,7 +170,7 @@
|
|||
{"type":"VARREF","name":"o_a","addr":"(XD)","loc":"d,24:10,24:13","dtypep":"(K)","access":"WR","varp":"(J)","varScopep":"(T)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []}
|
||||
]},
|
||||
{"type":"ALWAYS","name":"","addr":"(YD)","loc":"d,25:14,25:15","keyword":"always","isSuspendable":false,"needProcess":false,"sensesp": [],
|
||||
{"type":"ALWAYS","name":"","addr":"(YD)","loc":"d,25:14,25:15","keyword":"always","isSuspendable":false,"needProcess":false,"sentreep": [],
|
||||
"stmtsp": [
|
||||
{"type":"COMMENT","name":"Function: foo","addr":"(ZD)","loc":"d,25:16,25:19"},
|
||||
{"type":"ASSIGN","name":"","addr":"(AE)","loc":"d,25:20,25:23","dtypep":"(H)",
|
||||
|
|
|
|||
Loading…
Reference in New Issue