mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Internals: Refactor AstNodeBlock representation (#6280) AstNodeBlock now has 2 child lists: 'declsp' to hold declarations within the block, and 'stmtsp' to hold the procedural statements. AstBegin is then just a simple subtype of AstNodeBlock. AstFork is a proper superset of AstNodeBlock (and also AstBegin), and adds 'forksp' which hold the parallel statements. Having the sequential 'stmtsp' in AstFork is required to properly implement variable initializers in fork blocks (IEEE 1800-2023 9.3.2), this makes that clear, while also separating the non AstNodeStmt declarations (for #6280). The actual fork branches in 'AstFork::forkps()' are all AstBegin nodes. This is required as lowering stages will introduce additional statements in each parallel branch. (We used to wrap AstFork statements into AstBegin in 3 different places, now they always are AstBegin and this is enforced via the type checker/V3Broken). Also fixes incorrect disabling of forked processes from within the `fork`.
This commit is contained in:
+19
-13
@@ -1258,20 +1258,26 @@ class LinkDotFindVisitor final : public VNVisitor {
|
||||
// unnamed#'s would just confuse tracing variables in
|
||||
// places such as tasks, where "task ...; begin ... end"
|
||||
// are common.
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (VN_IS(stmtp, Var) || VN_IS(stmtp, Foreach)) {
|
||||
std::string name;
|
||||
const std::string stepStr = m_statep->forPrimary()
|
||||
? ""
|
||||
: std::to_string(m_statep->stepNumber()) + "_";
|
||||
do {
|
||||
++m_modBlockNum;
|
||||
name = "unnamedblk" + stepStr + cvtToStr(m_modBlockNum);
|
||||
// Increment again if earlier pass of V3LinkDot claimed this name
|
||||
} while (m_curSymp->findIdFlat(name));
|
||||
nodep->name(name);
|
||||
break;
|
||||
const auto containsDecl = [](const AstNode* nodesp) -> bool {
|
||||
for (const AstNode* np = nodesp; np; np = np->nextp()) {
|
||||
if (VN_IS(np, Var) || VN_IS(np, Foreach)) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
bool needName = nodep->declsp() || containsDecl(nodep->stmtsp());
|
||||
if (const AstFork* const forkp = VN_CAST(nodep, Fork)) {
|
||||
needName = needName || containsDecl(forkp->forksp());
|
||||
}
|
||||
if (needName) {
|
||||
const std::string stepStr
|
||||
= m_statep->forPrimary() ? "" : std::to_string(m_statep->stepNumber()) + "_";
|
||||
std::string name;
|
||||
do {
|
||||
++m_modBlockNum;
|
||||
name = "unnamedblk" + stepStr + cvtToStr(m_modBlockNum);
|
||||
// Increment again if earlier pass of V3LinkDot claimed this name
|
||||
} while (m_curSymp->findIdFlat(name));
|
||||
nodep->name(name);
|
||||
}
|
||||
}
|
||||
if (nodep->name() == "") {
|
||||
|
||||
Reference in New Issue
Block a user