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:
Wilson Snyder 2007-06-14 16:41:32 +00:00
parent 5b620a8dc5
commit c18f9da400
10 changed files with 49 additions and 22 deletions

View File

@ -63,6 +63,9 @@ private:
AstNode* timesp = nodep->exprsp(); if (timesp) timesp->unlinkFrBack(); AstNode* timesp = nodep->exprsp(); if (timesp) timesp->unlinkFrBack();
timesp = timesp->addNext(new AstTime(nodep->fileline())); timesp = timesp->addNext(new AstTime(nodep->fileline()));
nodep->exprsp(timesp); nodep->exprsp(timesp);
if (!nodep->scopeNamep() && nodep->name().find("%m") != string::npos) {
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
}
} }
AstNode* newIfAssertOn(AstNode* nodep) { AstNode* newIfAssertOn(AstNode* nodep) {

View File

@ -1271,11 +1271,8 @@ public:
bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display
AstNode* filep() const { return op2p(); } AstNode* filep() const { return op2p(); }
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
AstNode* scopeAttrp() const { return op3p(); } AstScopeName* scopeNamep() const { return op3p()->castScopeName(); }
AstText* scopeTextp() const { return op3p()->castText(); } void scopeNamep(AstNode* nodep) { setNOp3p(nodep); }
void scopeAttrp(AstNode* nodep) { addOp3p(nodep); }
bool needScopeTracking() { return (displayType().needScopeTracking()
|| name().find("%m") != string::npos); }
}; };
struct AstFClose : public AstNodeStmt { struct AstFClose : public AstNodeStmt {
@ -1726,6 +1723,22 @@ public:
int dimension() const { return m_dimension; } 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 // non-ary ops

View File

@ -131,10 +131,10 @@ private:
nodep->replaceWith(newp); nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL; 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() // If there's a %m in the display text, we add a special node that will contain the name()
// Similar code in V3Inline // Similar code in V3Inline
if (m_beginScope != "" && nodep->needScopeTracking()) { if (m_beginScope != "") {
// To keep correct visual order, must add before other Text's // To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp(); AstNode* afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext(); if (afterp) afterp->unlinkFrBackWithNext();

View File

@ -196,6 +196,9 @@ private:
virtual void visit(AstText* nodep, AstNUser*) { virtual void visit(AstText* nodep, AstNUser*) {
setClean (nodep, true); setClean (nodep, true);
} }
virtual void visit(AstScopeName* nodep, AstNUser*) {
setClean (nodep, true);
}
virtual void visit(AstSel* nodep, AstNUser*) { virtual void visit(AstSel* nodep, AstNUser*) {
operandTriop(nodep); operandTriop(nodep);
setClean (nodep, nodep->cleanOut()); setClean (nodep, nodep->cleanOut());

View File

@ -1061,7 +1061,8 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
case 'm': { case 'm': {
emitDispState.pushFormat("%s"); emitDispState.pushFormat("%s");
emitDispState.pushArg(NULL, "vlSymsp->name("); 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()); emitDispState.pushFormat(textp->text());
} }
break; break;

View File

@ -246,6 +246,8 @@ public:
virtual void visit(AstText* nodep, AstNUser*) { virtual void visit(AstText* nodep, AstNUser*) {
ofp()->putsNoTracking(nodep->text()); ofp()->putsNoTracking(nodep->text());
} }
virtual void visit(AstScopeName* nodep, AstNUser*) {
}
virtual void visit(AstCStmt* nodep, AstNUser*) { virtual void visit(AstCStmt* nodep, AstNUser*) {
putbs("$_CSTMT("); putbs("$_CSTMT(");
nodep->bodysp()->iterateAndNext(*this); nodep->bodysp()->iterateAndNext(*this);

View File

@ -233,10 +233,10 @@ private:
} }
nodep->iterateChildren(*this); 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 there's a %m in the display text, we add a special node that will contain the name()
// Similar code in V3Begin // Similar code in V3Begin
if (m_cellp && nodep->needScopeTracking()) { if (m_cellp) {
// To keep correct visual order, must add before other Text's // To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp(); AstNode* afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext(); if (afterp) afterp->unlinkFrBackWithNext();

View File

@ -335,6 +335,10 @@ private:
|| nodep->displayType() == AstDisplayType::FATAL)) { || nodep->displayType() == AstDisplayType::FATAL)) {
nodep->v3error(nodep->verilogKwd()+" only allowed under a assertion."); 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*) { virtual void visit(AstScCtor* nodep, AstNUser*) {

View File

@ -198,19 +198,17 @@ private:
nodep->taskp(NULL); nodep->taskp(NULL);
nodep->iterateChildren(*this); 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 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();
string prefix = (string)(".")+m_scopep->prettyName(); // TOP and above will be the user's name().
// TOP and above will be the user's name(). // Note 'TOP.'is stripped by prettyName, but not 'TOP'.
// Note 'TOP.'is stripped by prettyName, but not 'TOP'. if (prefix != ".TOP") {
if (prefix != ".TOP") { // To keep correct visual order, must add before other Text's
// To keep correct visual order, must add before other Text's AstNode* afterp = nodep->scopeAttrp();
AstNode* afterp = nodep->scopeAttrp(); if (afterp) afterp->unlinkFrBackWithNext();
if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeAttrp(new AstText(nodep->fileline(), prefix));
nodep->scopeAttrp(new AstText(nodep->fileline(), prefix)); if (afterp) nodep->scopeAttrp(afterp);
if (afterp) nodep->scopeAttrp(afterp);
}
} }
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
} }

View File

@ -385,6 +385,9 @@ private:
virtual void visit(AstText* nodep, AstNUser* vup) { virtual void visit(AstText* nodep, AstNUser* vup) {
// Only used in CStmts which don't care.... // 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) { virtual void visit(AstVar* nodep, AstNUser* vup) {
//if (debug()) nodep->dumpTree(cout," InitPre: "); //if (debug()) nodep->dumpTree(cout," InitPre: ");
// Must have deterministic constant width // Must have deterministic constant width