Internals: Create AstNodeSelItem in prep for future commits.

No real functional change, outside of minor debug dump differences.
This commit is contained in:
Wilson Snyder 2008-11-20 07:55:54 -05:00
parent ab668b066f
commit ddbfc176b6
15 changed files with 186 additions and 153 deletions

View File

@ -255,7 +255,10 @@ private:
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
return;
}
if (nodep->sensesp() && nodep->sensesp()->sensesp() && nodep->sensesp()->sensesp()->isNever()) {
if (nodep->sensesp()
&& nodep->sensesp()->sensesp()
&& nodep->sensesp()->sensesp()->castSenItem()
&& nodep->sensesp()->sensesp()->castSenItem()->isNever()) {
// Never executing. Kill it.
if (nodep->sensesp()->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
@ -266,18 +269,22 @@ private:
bool combo = false;
bool sequent = false;
if (nodep->sensesp()) {
for (AstSenItem* nextp, *senp = nodep->sensesp()->sensesp(); senp; senp=nextp) {
nextp = senp->nextp()->castSenItem();
if (senp->edgeType() == AstEdgeType::ANYEDGE) {
combo = true;
// Delete the sensitivity
// We'll add it as a generic COMBO SenItem in a moment.
senp->unlinkFrBack()->deleteTree(); senp=NULL;
} else if (senp->varrefp()) {
if (senp->varrefp()->width()>1) senp->v3error("Unsupported: Non-single bit wide signal pos/negedge sensitivity: "
<<senp->varrefp()->prettyName());
sequent = true;
senp->varrefp()->varp()->usedClock(true);
for (AstNodeSenItem* nextp, *senp = nodep->sensesp()->sensesp(); senp; senp=nextp) {
nextp = senp->nextp()->castNodeSenItem();
if (AstSenItem* itemp = senp->castSenItem()) {
if (itemp->edgeType() == AstEdgeType::ANYEDGE) {
combo = true;
// Delete the sensitivity
// We'll add it as a generic COMBO SenItem in a moment.
itemp->unlinkFrBack()->deleteTree(); itemp=NULL; senp=NULL;
} else if (itemp->varrefp()) {
if (itemp->varrefp()->width()>1) itemp->v3error("Unsupported: Non-single bit wide signal pos/negedge sensitivity: "
<<itemp->varrefp()->prettyName());
sequent = true;
itemp->varrefp()->varp()->usedClock(true);
}
} else {
senp->v3fatalSrc("Strange node under sentree");
}
}
}

View File

@ -71,7 +71,9 @@ private:
AstSenTree* sensesp = nodep->sensesp();
if (!sensesp) nodep->v3fatalSrc("NULL");
sensesp->sortSenses(); // Remove duplicate clocks and such
if (sensesp->sensesp() && sensesp->sensesp()->isNever()) {
if (sensesp->sensesp()
&& sensesp->sensesp()->castSenItem()
&& sensesp->sensesp()->castSenItem()->isNever()) {
// Never executing. Kill it.
if (sensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;

View File

@ -44,9 +44,9 @@ private:
// NODE STATE/TYPES
// STATE
// Reset each module:
AstSenItem* m_seniDefaultp; // Default sensitivity (from AstDefClock)
AstNodeSenItem* m_seniDefaultp; // Default sensitivity (from AstDefClock)
// Reset each assertion:
AstSenItem* m_senip; // Last sensitivity
AstNodeSenItem* m_senip; // Last sensitivity
int debug() { return 0; }
@ -55,7 +55,7 @@ private:
// Create sentree based on clocked or default clock
// Return NULL for always
AstSenTree* newp = NULL;
AstSenItem* senip = m_senip ? m_senip : m_seniDefaultp;
AstNodeSenItem* senip = m_senip ? m_senip : m_seniDefaultp;
if (!senip) {
nodep->v3error("Unsupported: Unclocked assertion");
newp = new AstSenTree(nodep->fileline(), NULL);

View File

@ -149,8 +149,8 @@ public:
};
const char* verilogKwd() const {
static const char* names[] = {
"%E-edge", "", "[both]", "posedge", "negedge", "[high]","[low]",
"/*AS*/","[initial]","[settle]","[never]"
"%E-edge", "[any]", "[both]", "posedge", "negedge", "[high]","[low]",
"*","[initial]","[settle]","[never]"
};
return names[m_e];
};
@ -924,6 +924,17 @@ struct AstNodeCase : public AstNodeStmt {
void addNotParallelp(AstNode* nodep) { setOp3p(nodep); }
};
struct AstNodeSenItem : public AstNode {
// A AstSenItem under
AstNodeSenItem(FileLine* fl) : AstNode(fl) {}
ASTNODE_BASE_FUNCS(NodeSenItem)
virtual bool isClocked() const = 0;
virtual bool isCombo() const = 0;
virtual bool isInitial() const = 0;
virtual bool isSettle() const = 0;
virtual bool isNever() const = 0;
};
class AstNodeVarRef : public AstNodeMath {
// A AstVarRef or AstVarXRef
private:

View File

@ -186,15 +186,16 @@ void AstSenTree::sortSenses() {
// Also, remove duplicate assignments, and fold POS&NEGs into ANYEDGEs
//cout<<endl; this->dumpTree(cout,"ssin: ");
AstSenItem* nextp;
if (sensesp() && !sensesp()->castSenItem()) v3fatalSrc("Unsupported node type under sentree");
// Make things a little faster; check first if we need a sort
for (AstSenItem* senp = sensesp(); senp; senp=senp->nextp()->castSenItem()) {
for (AstSenItem* senp = sensesp()->castSenItem(); senp; senp=senp->nextp()->castSenItem()) {
nextp=senp->nextp()->castSenItem();
AstSenItemCmp cmp;
if (nextp && !cmp(senp, nextp)) {
// Something's out of order, sort it
senp = NULL;
vector<AstSenItem*> vec;
for (AstSenItem* senp = sensesp(); senp; senp=senp->nextp()->castSenItem()) {
for (AstSenItem* senp = sensesp()->castSenItem(); senp; senp=senp->nextp()->castSenItem()) {
vec.push_back(senp);
}
sort(vec.begin(), vec.end(), AstSenItemCmp());
@ -209,7 +210,7 @@ void AstSenTree::sortSenses() {
}
// Pass2, remove dup edges
for (AstSenItem* senp = sensesp(); senp; senp=nextp) {
for (AstSenItem* senp = sensesp()->castSenItem(); senp; senp=nextp) {
nextp=senp->nextp()->castSenItem();
AstSenItem* cmpp = nextp;
if (cmpp
@ -236,7 +237,7 @@ void AstSenTree::sortSenses() {
// Pass3, remove nevers
if (sensesp()->nextp()) { // Else only one never, can't remove it
for (AstSenItem* senp = sensesp(); senp; senp=nextp) {
for (AstSenItem* senp = sensesp()->castSenItem(); senp; senp=nextp) {
nextp=senp->nextp()->castSenItem();
if (senp->isNever()) {
senp->unlinkFrBack()->deleteTree(); senp=NULL;
@ -248,28 +249,28 @@ void AstSenTree::sortSenses() {
bool AstSenTree::hasClocked() {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
for (AstSenItem* senp = sensesp(); senp; senp=senp->nextp()->castSenItem()) {
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
if (senp->isClocked()) return true;
}
return false;
}
bool AstSenTree::hasSettle() {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
for (AstSenItem* senp = sensesp(); senp; senp=senp->nextp()->castSenItem()) {
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
if (senp->isSettle()) return true;
}
return false;
}
bool AstSenTree::hasInitial() {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
for (AstSenItem* senp = sensesp(); senp; senp=senp->nextp()->castSenItem()) {
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
if (senp->isInitial()) return true;
}
return false;
}
bool AstSenTree::hasCombo() {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
for (AstSenItem* senp = sensesp(); senp; senp=senp->nextp()->castSenItem()) {
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
if (senp->isCombo()) return true;
}
return false;

View File

@ -799,7 +799,7 @@ struct AstFuncRef : public AstNodeFTaskRef {
//######################################################################
struct AstSenItem : public AstNode {
struct AstSenItem : public AstNodeSenItem {
// Parents: SENTREE
// Children: (optional) VARREF
private:
@ -810,27 +810,27 @@ public:
class Settle {}; // for creator type-overload selection
class Never {}; // for creator type-overload selection
AstSenItem(FileLine* fl, AstEdgeType edgeType, AstNodeVarRef* varrefp)
: AstNode(fl), m_edgeType(edgeType) {
: AstNodeSenItem(fl), m_edgeType(edgeType) {
setOp1p(varrefp);
}
AstSenItem(FileLine* fl, AstEdgeType edgeType, AstParseRef* varrefp)
: AstNode(fl), m_edgeType(edgeType) {
: AstNodeSenItem(fl), m_edgeType(edgeType) {
setOp1p(varrefp);
}
AstSenItem(FileLine* fl, Combo)
: AstNode(fl) {
: AstNodeSenItem(fl) {
m_edgeType = AstEdgeType::COMBO;
}
AstSenItem(FileLine* fl, Initial)
: AstNode(fl) {
: AstNodeSenItem(fl) {
m_edgeType = AstEdgeType::INITIAL;
}
AstSenItem(FileLine* fl, Settle)
: AstNode(fl) {
: AstNodeSenItem(fl) {
m_edgeType = AstEdgeType::SETTLE;
}
AstSenItem(FileLine* fl, Never)
: AstNode(fl) {
: AstNodeSenItem(fl) {
m_edgeType = AstEdgeType::NEVER;
}
ASTNODE_NODE_FUNCS(SenItem, SENITEM)
@ -843,11 +843,11 @@ public:
AstNode* sensp() const { return op1p(); } // op1 = Signal sensitized
AstNodeVarRef* varrefp() const { return op1p()->castNodeVarRef(); } // op1 = Signal sensitized
//
bool isClocked() const { return edgeType().clockedStmt(); }
bool isCombo() const { return edgeType()==AstEdgeType::COMBO; }
bool isInitial() const { return edgeType()==AstEdgeType::INITIAL; }
bool isSettle() const { return edgeType()==AstEdgeType::SETTLE; }
bool isNever() const { return edgeType()==AstEdgeType::NEVER; }
virtual bool isClocked() const { return edgeType().clockedStmt(); }
virtual bool isCombo() const { return edgeType()==AstEdgeType::COMBO; }
virtual bool isInitial() const { return edgeType()==AstEdgeType::INITIAL; }
virtual bool isSettle() const { return edgeType()==AstEdgeType::SETTLE; }
virtual bool isNever() const { return edgeType()==AstEdgeType::NEVER; }
bool hasVar() const { return !(isCombo()||isInitial()||isSettle()||isNever()); }
};
@ -858,7 +858,7 @@ struct AstSenTree : public AstNode {
private:
bool m_multi; // Created from combo logic by ORing multiple clock domains
public:
AstSenTree(FileLine* fl, AstSenItem* sensesp)
AstSenTree(FileLine* fl, AstNodeSenItem* sensesp)
: AstNode(fl), m_multi(false) {
addNOp1p(sensesp);
}
@ -866,8 +866,8 @@ public:
virtual void dump(ostream& str);
virtual bool maybePointedTo() const { return true; }
bool isMulti() const { return m_multi; }
AstSenItem* sensesp() const { return op1p()->castSenItem(); } // op1 = Sensitivity list
void addSensesp(AstSenItem* nodep) { addOp1p(nodep); }
AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list
void addSensesp(AstNodeSenItem* nodep) { addOp1p(nodep); }
void multi(bool flag) { m_multi = true; }
// METHODS
void sortSenses(); // Sort senitems in standard way
@ -2450,13 +2450,13 @@ struct AstClocking : public AstNode {
// Parents: MODULE
// Children: Assertions
public:
AstClocking(FileLine* fl, AstSenItem* sensesp, AstNode* bodysp)
AstClocking(FileLine* fl, AstNodeSenItem* sensesp, AstNode* bodysp)
: AstNode(fl) {
addOp1p(sensesp);
addNOp2p(bodysp);
}
ASTNODE_NODE_FUNCS(Clocking, CLOCKING)
AstSenItem* sensesp() const { return op1p()->castSenItem(); } // op1 = Sensitivity list
AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list
AstNode* bodysp() const { return op2p(); } // op2 = Body
};
@ -2468,12 +2468,12 @@ struct AstPslDefClock : public AstNode {
// Parents: MODULE
// Children: SENITEM
public:
AstPslDefClock(FileLine* fl, AstSenItem* sensesp)
AstPslDefClock(FileLine* fl, AstNodeSenItem* sensesp)
: AstNode(fl) {
addNOp1p(sensesp);
}
ASTNODE_NODE_FUNCS(PslDefClock, PSLDEFCLOCK)
AstSenItem* sensesp() const { return op1p()->castSenItem(); } // op1 = Sensitivity list
AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list
};
struct AstPslClocked : public AstNode {
@ -2481,14 +2481,14 @@ struct AstPslClocked : public AstNode {
// Parents: ASSERT|COVER (property)
// Children: SENITEM, Properties
public:
AstPslClocked(FileLine* fl, AstSenItem* sensesp, AstNode* disablep, AstNode* propp)
AstPslClocked(FileLine* fl, AstNodeSenItem* sensesp, AstNode* disablep, AstNode* propp)
: AstNode(fl) {
addNOp1p(sensesp);
addNOp2p(disablep);
addOp3p(propp);
}
ASTNODE_NODE_FUNCS(PslClocked, PSLCLOCKED)
AstSenItem* sensesp() const { return op1p()->castSenItem(); } // op1 = Sensitivity list
AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list
AstNode* disablep() const { return op2p(); } // op2 = disable
AstNode* propp() const { return op3p(); } // op3 = property
};

View File

@ -106,48 +106,57 @@ private:
m_scopep->addVarp(newvscp);
return newvscp;
}
AstNode* createSenItemEquation(AstSenItem* nodep) {
// We know the var is clean, and one bit, so we use binary ops
// for speed instead of logical ops.
// POSEDGE: var & ~var_last
// NEGEDGE: ~var & var_last
// BOTHEDGE: var ^ var_last
// HIGHEDGE: var
// LOWEDGE: ~var
AstNode* newp = NULL;
AstVarScope* clkvscp = nodep->varrefp()->varScopep();
if (nodep->edgeType()==AstEdgeType::POSEDGE) {
AstVarScope* lastVscp = getCreateLastClk(clkvscp);
newp = new AstAnd(nodep->fileline(),
new AstVarRef(nodep->fileline(),
nodep->varrefp()->varScopep(), false),
new AstNot(nodep->fileline(),
new AstVarRef(nodep->fileline(),
lastVscp, false)));
} else if (nodep->edgeType()==AstEdgeType::NEGEDGE) {
AstVarScope* lastVscp = getCreateLastClk(clkvscp);
newp = new AstAnd(nodep->fileline(),
new AstNot(nodep->fileline(),
new AstVarRef(nodep->fileline(),
nodep->varrefp()->varScopep(), false)),
new AstVarRef(nodep->fileline(), lastVscp, false));
} else if (nodep->edgeType()==AstEdgeType::BOTHEDGE) {
AstVarScope* lastVscp = getCreateLastClk(clkvscp);
newp = new AstXor(nodep->fileline(),
new AstVarRef(nodep->fileline(),
nodep->varrefp()->varScopep(), false),
new AstVarRef(nodep->fileline(), lastVscp, false));
} else if (nodep->edgeType()==AstEdgeType::HIGHEDGE) {
newp = new AstVarRef(nodep->fileline(),
clkvscp, false);
} else if (nodep->edgeType()==AstEdgeType::LOWEDGE) {
newp = new AstNot(nodep->fileline(),
new AstVarRef(nodep->fileline(),
clkvscp, false));
} else {
nodep->v3fatalSrc("Bad edge type");
}
return newp;
}
AstNode* createSenseEquation(AstSenTree* nodep) {
AstNode* senEqnp = NULL;
for (AstSenItem* senp = nodep->sensesp(); senp; senp=senp->nextp()->castSenItem()) {
// We know the var is clean, and one bit, so we use binary ops
// for speed instead of logical ops.
// POSEDGE: var & ~var_last
// NEGEDGE: ~var & var_last
// BOTHEDGE: var ^ var_last
// HIGHEDGE: var
// LOWEDGE: ~var
AstVarScope* lastVscp = senp->varrefp()->varScopep()->userp()->castNode()->castVarScope();
for (AstNodeSenItem* senp = nodep->sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
AstNode* senOnep = NULL;
if (senp->edgeType()==AstEdgeType::POSEDGE) {
if (!lastVscp) senp->v3fatalSrc("No last var ptr?\n");
senOnep = new AstAnd(senp->fileline(),
new AstVarRef(senp->fileline(),
senp->varrefp()->varScopep(), false),
new AstNot(senp->fileline(),
new AstVarRef(senp->fileline(),
lastVscp, false)));
} else if (senp->edgeType()==AstEdgeType::NEGEDGE) {
if (!lastVscp) senp->v3fatalSrc("No last var ptr?\n");
senOnep = new AstAnd(senp->fileline(),
new AstNot(senp->fileline(),
new AstVarRef(senp->fileline(),
senp->varrefp()->varScopep(), false)),
new AstVarRef(senp->fileline(), lastVscp, false));
} else if (senp->edgeType()==AstEdgeType::BOTHEDGE) {
if (!lastVscp) senp->v3fatalSrc("No last var ptr?\n");
senOnep = new AstXor(senp->fileline(),
new AstVarRef(senp->fileline(),
senp->varrefp()->varScopep(), false),
new AstVarRef(senp->fileline(), lastVscp, false));
} else if (senp->edgeType()==AstEdgeType::HIGHEDGE) {
senOnep = new AstVarRef(senp->fileline(),
senp->varrefp()->varScopep(), false);
} else if (senp->edgeType()==AstEdgeType::LOWEDGE) {
senOnep = new AstNot(senp->fileline(),
new AstVarRef(senp->fileline(),
senp->varrefp()->varScopep(), false));
if (AstSenItem* itemp = senp->castSenItem()) {
senOnep = createSenItemEquation(itemp);
} else {
senp->v3fatalSrc("Bad edge type");
senp->v3fatalSrc("Strange node under sentree");
}
if (senEqnp) {
// Add new OR to the sensitivity list equation
@ -159,13 +168,6 @@ private:
return senEqnp;
}
AstIf* makeActiveIf(AstSenTree* sensesp) {
for (AstSenItem* senp = sensesp->sensesp(); senp; senp=senp->nextp()->castSenItem()) {
if (senp->edgeType() != AstEdgeType::HIGHEDGE
&& senp->varrefp()) {
AstVarScope* oldvscp = senp->varrefp()->varScopep();
getCreateLastClk(oldvscp);
}
}
AstNode* senEqnp = createSenseEquation(sensesp);
if (!senEqnp) sensesp->v3fatalSrc("No sense equation, shouldn't be in sequent activation.");
AstIf* newifp = new AstIf (sensesp->fileline(),

View File

@ -370,8 +370,8 @@ private:
UINFO(4," Act: "<<m_activep<<endl);
UINFO(4," Act: "<<oldactivep<<endl);
// Make a new sensitivity list, which is the combination of both blocks
AstSenItem* sena = m_activep->sensesp()->sensesp()->cloneTree(true);
AstSenItem* senb = oldactivep->sensesp()->sensesp()->cloneTree(true);
AstNodeSenItem* sena = m_activep->sensesp()->sensesp()->cloneTree(true);
AstNodeSenItem* senb = oldactivep->sensesp()->sensesp()->cloneTree(true);
AstSenTree* treep = new AstSenTree(m_activep->fileline(), sena);
if (senb) treep->addSensesp(senb);
if (AstSenTree* storep = oldactivep->sensesStorep()) {

View File

@ -78,9 +78,9 @@ public:
virtual void putsIntTopInclude() { puts("#include \"systemperl.h\"\n"); }
};
class V3OutVFile : public V3OutCFile {
class V3OutVFile : public V3OutFile {
public:
V3OutVFile(const string& filename) : V3OutCFile(filename) {}
V3OutVFile(const string& filename) : V3OutFile(filename) {}
virtual ~V3OutVFile() {};
virtual void putsHeader() { puts("// Verilated -*- Verilog -*-\n"); }
};

View File

@ -35,25 +35,24 @@
//######################################################################
// Emit statements and math operators
class EmitVImp : public EmitCBaseVisitor {
private:
class EmitVBaseVisitor : public EmitCBaseVisitor {
// MEMBERS
bool m_suppressSemi;
AstModule* m_modp;
public:
//int debug() { return 9; }
// METHODS
virtual void puts(const string& str) = 0;
virtual void putbs(const string& str) = 0;
virtual void putsNoTracking(const string& str) = 0;
// VISITORS
virtual void visit(AstNetlist* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
virtual void visit(AstModule* nodep, AstNUser*) {
m_modp = nodep;
putbs("module "+modClassName(nodep)+";\n");
nodep->iterateChildren(*this);
puts("endmodule\n");
m_modp = NULL;
}
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
putbs(nodep->castTask() ? "task ":"function ");
@ -87,7 +86,7 @@ public:
virtual void visit(AstAlways* nodep, AstNUser*) {
putbs("always ");
nodep->sensesp()->iterateAndNext(*this);
putbs("begin\n");
putbs(" begin\n");
nodep->bodysp()->iterateAndNext(*this);
puts("end\n");
}
@ -118,17 +117,17 @@ public:
if (!m_suppressSemi) puts(";\n");
}
virtual void visit(AstSenTree* nodep, AstNUser*) {
// AstSenItem is called for dumping in isolation by V3Order
putbs("@(");
nodep->iterateChildren(*this);
puts(") ");
puts(")");
}
virtual void visit(AstSenItem* nodep, AstNUser*) {
putbs("");
if (nodep->backp()->castSenItem()) puts(" or ");
if (!nodep->backp()->castSenTree()) puts(" or ");
puts(nodep->edgeType().verilogKwd());
puts(" ");
if (nodep->sensp()) puts(" ");
nodep->iterateChildren(*this);
puts(" ");
}
virtual void visit(AstNodeCase* nodep, AstNUser*) {
putbs(nodep->verilogKwd());
@ -170,7 +169,7 @@ public:
putbs(" (");
if (filep) { filep->iterateAndNext(*this); putbs(","); }
puts("\"");
ofp()->putsNoTracking(text);
putsNoTracking(text);
puts("\"");
for (AstNode* expp=exprsp; expp; expp = expp->nextp()) {
puts(",");
@ -261,7 +260,7 @@ public:
putbs("$finish;\n");
}
virtual void visit(AstText* nodep, AstNUser*) {
ofp()->putsNoTracking(nodep->text());
putsNoTracking(nodep->text());
}
virtual void visit(AstScopeName* nodep, AstNUser*) {
}
@ -434,21 +433,50 @@ public:
}
public:
EmitVImp() {
EmitVBaseVisitor() {
m_suppressSemi = false;
m_modp = NULL;
}
void main(AstNode* nodep, V3OutCFile* ofp);
virtual ~EmitVImp() {}
virtual ~EmitVBaseVisitor() {}
};
//######################################################################
// Emit to an output file
void EmitVImp::main(AstNode* modp, V3OutCFile* ofp) {
// Output a module, or overall netlist
m_ofp = ofp;
modp->accept(*this);
}
class EmitVFileVisitor : public EmitVBaseVisitor {
// MEMBERS
V3OutFile* m_ofp;
// METHODS
V3OutFile* ofp() const { return m_ofp; };
void puts(const string& str) { ofp()->puts(str); }
void putbs(const string& str) { ofp()->putbs(str); }
void putsNoTracking(const string& str) { ofp()->putsNoTracking(str); }
public:
EmitVFileVisitor(AstNode* nodep, V3OutFile* ofp) {
m_ofp = ofp;
nodep->accept(*this);
}
virtual ~EmitVFileVisitor() {}
};
//######################################################################
// Emit to a stream (perhaps stringstream)
class EmitVStreamVisitor : public EmitVBaseVisitor {
// MEMBERS
ostream& m_os;
// METHODS
void puts(const string& str) { m_os<<str; }
void putbs(const string& str) { m_os<<str; }
void putsNoTracking(const string& str) { m_os<<str; }
public:
EmitVStreamVisitor(AstNode* nodep, ostream& os)
: m_os(os) {
nodep->accept(*this);
}
virtual ~EmitVStreamVisitor() {}
};
//######################################################################
// EmitV class functions
@ -459,15 +487,18 @@ void V3EmitV::emitv() {
// All-in-one file
V3OutVFile of (v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__Vout.v");
of.putsHeader();
EmitVImp imp;
imp.main(v3Global.rootp(), &of);
EmitVFileVisitor visitor (v3Global.rootp(), &of);
} else {
// Process each module in turn
for (AstModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castModule()) {
EmitVImp imp;
V3OutVFile of (v3Global.opt.makeDir()+"/"+imp.modClassName(modp)+"__Vout.v");
V3OutVFile of (v3Global.opt.makeDir()
+"/"+EmitCBaseVisitor::modClassName(modp)+"__Vout.v");
of.putsHeader();
imp.main(modp, &of);
EmitVFileVisitor visitor (modp, &of);
}
}
}
void V3EmitV::verilogForTree(AstNode* nodep, ostream& os) {
EmitVStreamVisitor(nodep, os);
}

View File

@ -31,6 +31,7 @@
class V3EmitV {
public:
static void emitv();
static void verilogForTree(AstNode* nodep, ostream& os=cout);
};
#endif // Guard

View File

@ -356,7 +356,7 @@ private:
virtual void visit(AstCFunc* nodep, AstNUser*) {
iterateNewStmt(nodep, "User C Function", "User C Function");
}
virtual void visit(AstSenItem* nodep, AstNUser*) {
virtual void visit(AstNodeSenItem* nodep, AstNUser*) {
m_inSenItem = true;
iterateNewStmt(nodep, NULL, NULL);
m_inSenItem = false;

View File

@ -110,6 +110,7 @@
#include "V3Order.h"
#include "V3OrderGraph.h"
#include "V3EmitV.h"
class OrderMoveDomScope;
@ -239,7 +240,6 @@ private:
// Forming graph:
// Entire Netlist:
// AstVarScope::userp -> OrderUser* for usage var
// AstActive::user3() -> uint clocks hash of sensitivity list
// {statement}Node::userp-> AstModule* statement is under
// USER5 Cleared on each Logic stmt
// AstVarScope::user5() -> VarUsage(gen/con/both). Where already encountered signal
@ -480,17 +480,6 @@ private:
m_activep = nodep;
m_activeSenVxp = NULL;
m_inClocked = nodep->hasClocked();
// Compute hash of sensitivity list
V3Hash clocks;
if (nodep->sensesp()) {
for (AstSenItem* senp = nodep->sensesp()->sensesp(); senp; senp=senp->nextp()->castSenItem()) {
clocks = V3Hash(clocks, V3Hash(senp->edgeType()));
if (senp->varrefp()) {
clocks = V3Hash(clocks, V3Hash(senp->varrefp()->varScopep()));
}
}
}
nodep->user3(clocks.hshval());
// Grab the sensitivity list
if (nodep->sensesStorep()) nodep->v3fatalSrc("Senses should have been activeTop'ed to be global!");
nodep->sensesp()->accept(*this);
@ -1086,7 +1075,7 @@ void OrderVisitor::processDomainsIterate(OrderEitherVertex* vertexp) {
fromVertexp->domainp()->dumpTree(cout);
}
AstSenTree* newtreep = domainp->cloneTree(false);
AstSenItem* newtree2p = fromVertexp->domainp()->sensesp()->cloneTree(true);
AstNodeSenItem* newtree2p = fromVertexp->domainp()->sensesp()->cloneTree(true);
if (!newtree2p) fromVertexp->domainp()->v3fatalSrc("No senitem found under clocked domain");
newtreep->addSensesp(newtree2p);
newtreep->sortSenses(); // Remove duplicates
@ -1143,18 +1132,7 @@ void OrderVisitor::processEdgeReport() {
os.setf(ios::left);
os<<" "<<setw(50)<<name<<" ";
AstSenTree* sentreep = vvertexp->domainp();
if (sentreep) {
bool first = true;
for (AstSenItem* itemp=sentreep->sensesp(); itemp; itemp=itemp->nextp()->castSenItem()) {
if (first) os<<"@( "; else os<<", ";
first = false;
os<<itemp->edgeType().verilogKwd();
if (itemp->varrefp()) {
os<<" "+itemp->varrefp()->prettyName();
}
}
if (!first) os<<" )";
}
if (sentreep) V3EmitV::verilogForTree(sentreep, os);
report.push_back(os.str());
}
}

View File

@ -66,7 +66,7 @@ private:
virtual void visit(AstTopScope* nodep, AstNUser*) {
m_topscopep = nodep;
nodep->iterateChildren(*this);
// Don't clear scopep, the namer persists beyond this visit
// Don't clear topscopep, the namer persists beyond this visit
}
virtual void visit(AstScope* nodep, AstNUser*) {
// But no SenTrees under TopScope's scope

View File

@ -124,7 +124,7 @@ class AstSenTree;
AstParseRef* parserefp;
AstPin* pinp;
AstRange* rangep;
AstSenItem* senitemp;
AstNodeSenItem* senitemp;
AstSenTree* sentreep;
AstVar* varp;
AstVarRef* varrefp;