mirror of
https://github.com/verilator/verilator.git
synced 2025-01-05 22:27:35 +00:00
Put display scope tracking under special node type
git-svn-id: file://localhost/svn/verilator/trunk/verilator@936 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
5b620a8dc5
commit
c18f9da400
@ -63,6 +63,9 @@ private:
|
||||
AstNode* timesp = nodep->exprsp(); if (timesp) timesp->unlinkFrBack();
|
||||
timesp = timesp->addNext(new AstTime(nodep->fileline()));
|
||||
nodep->exprsp(timesp);
|
||||
if (!nodep->scopeNamep() && nodep->name().find("%m") != string::npos) {
|
||||
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
|
||||
}
|
||||
}
|
||||
|
||||
AstNode* newIfAssertOn(AstNode* nodep) {
|
||||
|
@ -1271,11 +1271,8 @@ public:
|
||||
bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display
|
||||
AstNode* filep() const { return op2p(); }
|
||||
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
||||
AstNode* scopeAttrp() const { return op3p(); }
|
||||
AstText* scopeTextp() const { return op3p()->castText(); }
|
||||
void scopeAttrp(AstNode* nodep) { addOp3p(nodep); }
|
||||
bool needScopeTracking() { return (displayType().needScopeTracking()
|
||||
|| name().find("%m") != string::npos); }
|
||||
AstScopeName* scopeNamep() const { return op3p()->castScopeName(); }
|
||||
void scopeNamep(AstNode* nodep) { setNOp3p(nodep); }
|
||||
};
|
||||
|
||||
struct AstFClose : public AstNodeStmt {
|
||||
@ -1726,6 +1723,22 @@ public:
|
||||
int dimension() const { return m_dimension; }
|
||||
};
|
||||
|
||||
struct AstScopeName : public AstNode {
|
||||
// For display %m
|
||||
// Parents: DISPLAY
|
||||
// Children: TEXT
|
||||
AstScopeName(FileLine* fl)
|
||||
: AstNode(fl) {}
|
||||
virtual ~AstScopeName() {}
|
||||
virtual AstType type() const { return AstType::SCOPENAME;}
|
||||
virtual AstNode* clone() { return new AstScopeName(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return true; }
|
||||
AstText* scopeAttrp() const { return op1p()->castText(); }
|
||||
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// non-ary ops
|
||||
|
||||
|
@ -131,10 +131,10 @@ private:
|
||||
nodep->replaceWith(newp);
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
}
|
||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||
// Similar code in V3Inline
|
||||
if (m_beginScope != "" && nodep->needScopeTracking()) {
|
||||
if (m_beginScope != "") {
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstNode* afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
|
@ -196,6 +196,9 @@ private:
|
||||
virtual void visit(AstText* nodep, AstNUser*) {
|
||||
setClean (nodep, true);
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||
setClean (nodep, true);
|
||||
}
|
||||
virtual void visit(AstSel* nodep, AstNUser*) {
|
||||
operandTriop(nodep);
|
||||
setClean (nodep, nodep->cleanOut());
|
||||
|
@ -1061,7 +1061,8 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
|
||||
case 'm': {
|
||||
emitDispState.pushFormat("%s");
|
||||
emitDispState.pushArg(NULL, "vlSymsp->name(");
|
||||
for (AstText* textp=nodep->scopeTextp(); textp; textp=textp->nextp()->castText()) {
|
||||
if (!nodep->scopeNamep()) nodep->v3fatalSrc("Display with %m but no AstScopeName");
|
||||
for (AstText* textp=nodep->scopeNamep()->scopeAttrp(); textp; textp=textp->nextp()->castText()) {
|
||||
emitDispState.pushFormat(textp->text());
|
||||
}
|
||||
break;
|
||||
|
@ -246,6 +246,8 @@ public:
|
||||
virtual void visit(AstText* nodep, AstNUser*) {
|
||||
ofp()->putsNoTracking(nodep->text());
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||
}
|
||||
virtual void visit(AstCStmt* nodep, AstNUser*) {
|
||||
putbs("$_CSTMT(");
|
||||
nodep->bodysp()->iterateAndNext(*this);
|
||||
|
@ -233,10 +233,10 @@ private:
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||
// Similar code in V3Begin
|
||||
if (m_cellp && nodep->needScopeTracking()) {
|
||||
if (m_cellp) {
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstNode* afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
|
@ -335,6 +335,10 @@ private:
|
||||
|| nodep->displayType() == AstDisplayType::FATAL)) {
|
||||
nodep->v3error(nodep->verilogKwd()+" only allowed under a assertion.");
|
||||
}
|
||||
if (nodep->displayType().needScopeTracking()
|
||||
|| nodep->name().find("%m") != string::npos) {
|
||||
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstScCtor* nodep, AstNUser*) {
|
||||
|
@ -198,19 +198,17 @@ private:
|
||||
nodep->taskp(NULL);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||
if (nodep->name().find("%m") != string::npos) {
|
||||
string prefix = (string)(".")+m_scopep->prettyName();
|
||||
// TOP and above will be the user's name().
|
||||
// Note 'TOP.'is stripped by prettyName, but not 'TOP'.
|
||||
if (prefix != ".TOP") {
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstNode* afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeAttrp(new AstText(nodep->fileline(), prefix));
|
||||
if (afterp) nodep->scopeAttrp(afterp);
|
||||
}
|
||||
string prefix = (string)(".")+m_scopep->prettyName();
|
||||
// TOP and above will be the user's name().
|
||||
// Note 'TOP.'is stripped by prettyName, but not 'TOP'.
|
||||
if (prefix != ".TOP") {
|
||||
// To keep correct visual order, must add before other Text's
|
||||
AstNode* afterp = nodep->scopeAttrp();
|
||||
if (afterp) afterp->unlinkFrBackWithNext();
|
||||
nodep->scopeAttrp(new AstText(nodep->fileline(), prefix));
|
||||
if (afterp) nodep->scopeAttrp(afterp);
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
@ -385,6 +385,9 @@ private:
|
||||
virtual void visit(AstText* nodep, AstNUser* vup) {
|
||||
// Only used in CStmts which don't care....
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep, AstNUser* vup) {
|
||||
// Only used in Displays which don't care....
|
||||
}
|
||||
virtual void visit(AstVar* nodep, AstNUser* vup) {
|
||||
//if (debug()) nodep->dumpTree(cout," InitPre: ");
|
||||
// Must have deterministic constant width
|
||||
|
Loading…
Reference in New Issue
Block a user