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();
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) {

View File

@ -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

View File

@ -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();

View File

@ -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());

View File

@ -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;

View File

@ -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);

View File

@ -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();

View File

@ -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*) {

View File

@ -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);
}

View File

@ -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