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

View File

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

View File

@ -149,8 +149,8 @@ public:
}; };
const char* verilogKwd() const { const char* verilogKwd() const {
static const char* names[] = { static const char* names[] = {
"%E-edge", "", "[both]", "posedge", "negedge", "[high]","[low]", "%E-edge", "[any]", "[both]", "posedge", "negedge", "[high]","[low]",
"/*AS*/","[initial]","[settle]","[never]" "*","[initial]","[settle]","[never]"
}; };
return names[m_e]; return names[m_e];
}; };
@ -924,6 +924,17 @@ struct AstNodeCase : public AstNodeStmt {
void addNotParallelp(AstNode* nodep) { setOp3p(nodep); } 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 { class AstNodeVarRef : public AstNodeMath {
// A AstVarRef or AstVarXRef // A AstVarRef or AstVarXRef
private: private:

View File

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

View File

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

View File

@ -106,48 +106,57 @@ private:
m_scopep->addVarp(newvscp); m_scopep->addVarp(newvscp);
return 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* createSenseEquation(AstSenTree* nodep) {
AstNode* senEqnp = NULL; AstNode* senEqnp = NULL;
for (AstSenItem* senp = nodep->sensesp(); senp; senp=senp->nextp()->castSenItem()) { for (AstNodeSenItem* senp = nodep->sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
// 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();
AstNode* senOnep = NULL; AstNode* senOnep = NULL;
if (senp->edgeType()==AstEdgeType::POSEDGE) { if (AstSenItem* itemp = senp->castSenItem()) {
if (!lastVscp) senp->v3fatalSrc("No last var ptr?\n"); senOnep = createSenItemEquation(itemp);
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));
} else { } else {
senp->v3fatalSrc("Bad edge type"); senp->v3fatalSrc("Strange node under sentree");
} }
if (senEqnp) { if (senEqnp) {
// Add new OR to the sensitivity list equation // Add new OR to the sensitivity list equation
@ -159,13 +168,6 @@ private:
return senEqnp; return senEqnp;
} }
AstIf* makeActiveIf(AstSenTree* sensesp) { 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); AstNode* senEqnp = createSenseEquation(sensesp);
if (!senEqnp) sensesp->v3fatalSrc("No sense equation, shouldn't be in sequent activation."); if (!senEqnp) sensesp->v3fatalSrc("No sense equation, shouldn't be in sequent activation.");
AstIf* newifp = new AstIf (sensesp->fileline(), AstIf* newifp = new AstIf (sensesp->fileline(),

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -66,7 +66,7 @@ private:
virtual void visit(AstTopScope* nodep, AstNUser*) { virtual void visit(AstTopScope* nodep, AstNUser*) {
m_topscopep = nodep; m_topscopep = nodep;
nodep->iterateChildren(*this); 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*) { virtual void visit(AstScope* nodep, AstNUser*) {
// But no SenTrees under TopScope's scope // But no SenTrees under TopScope's scope

View File

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