Fix 's with array select followed by wide AND. [David Hewson]

git-svn-id: file://localhost/svn/verilator/trunk/verilator@882 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
Wilson Snyder 2007-01-31 15:44:36 +00:00
parent ecb938f20e
commit 5dbae27f01
5 changed files with 14 additions and 7 deletions

View File

@ -11,6 +11,8 @@ indicates the contributor was also the author of the fix; Thanks!
**** Fix isolate_assignments across task/func temporaries. [Mike Shinkarovsky]
**** Fix $display's with array select followed by wide AND. [David Hewson]
* Verilator 3.632 1/17/2007
*** Add /*verilator isolate_assignments*/ attribute. [Mike Shinkarovsky]

View File

@ -505,6 +505,7 @@ public:
AstNode* op3p() const { return m_op3p; }
AstNode* op4p() const { return m_op4p; }
AstNode* clonep() const { return ((m_cloneCnt==s_cloneCntGbl)?m_clonep:NULL); }
AstNode* firstAbovep() const { return ((backp() && backp()->nextp()!=this) ? backp() : NULL); } // Returns NULL when second or later in list
bool brokeExists() const;
// CONSTRUCTORS

View File

@ -71,14 +71,18 @@ private:
// ASSIGN(CONST*here*, VARREF(!sc))
// ARRAYSEL(*here*, ...) (No wides can be in any argument but first, so we don't check which arg is wide)
// ASSIGN(x, SEL*HERE*(ARRAYSEL()...) (m_assignLhs==true handles this.)
//UINFO(9, " Check: "<<nodep<<endl);
//UINFO(9, " Detail stmtp="<<(m_stmtp?"Y":"N")<<" U="<<(nodep->user()?"Y":"N")<<" IW "<<(nodep->isWide()?"Y":"N")<<endl);
if (m_stmtp
&& !nodep->user()) { // Not already done
if (nodep->isWide()) { // Else might be cell interconnect or something
if (m_assignLhs) {
} else if (nodep->backp()->castNodeAssign()
&& assignNoTemp(nodep->backp()->castNodeAssign())) {
} else if (nodep->firstAbovep()
&& nodep->firstAbovep()->castNodeAssign()
&& assignNoTemp(nodep->firstAbovep()->castNodeAssign())) {
// Not much point if it's just a direct assignment to a constant
} else if (nodep->backp()->castArraySel()) { // ArraySel's are pointer refs, ignore
} else if (nodep->firstAbovep()
&& nodep->firstAbovep()->castArraySel()) { // ArraySel's are pointer refs, ignore
} else {
UINFO(4,"Cre Temp: "<<nodep<<endl);
createDeepTemp(nodep);
@ -140,6 +144,7 @@ private:
virtual void visit(AstCFunc* nodep, AstNUser*) {
m_funcp = nodep;
nodep->iterateChildren(*this);
m_funcp = NULL;
}
void startStatement(AstNode* nodep) {
m_assignLhs = false;

View File

@ -428,7 +428,7 @@ private:
AstNode* firstp = nodep; // We may reorder, and nodep is no longer first.
void* oldBlockUser3 = nodep->user3p(); // May be overloaded in below loop, save it
nodep->user3p(NULL);
if (nodep->backp()->nextp()==nodep) nodep->v3fatalSrc("Node passed is in next list; should have processed all list at oncen");
if (!nodep->firstAbovep()) nodep->v3fatalSrc("Node passed is in next list; should have processed all list at once");
// Process it
if (!nodep->nextp()) {
// Just one, so can't reorder. Just look for more blocks/statements.

View File

@ -63,9 +63,8 @@ private:
m_instrs += nodep->instrCount();
if (m_counting) {
++m_statTypeCount[nodep->type()];
if (nodep->backp() && nodep->backp()->nextp()!=nodep) {
// Grab only those above, not those "back"
++m_statAbove[nodep->backp()->type()][nodep->type()];
if (nodep->firstAbovep()) { // Grab only those above, not those "back"
++m_statAbove[nodep->firstAbovep()->type()][nodep->type()];
}
m_statInstr += nodep->instrCount();
if (m_cfuncp && !m_cfuncp->slow()) m_statInstrFast += nodep->instrCount();