From 5dbae27f01f4442fe5744a4bb0eebc5bbc7421dc Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 31 Jan 2007 15:44:36 +0000 Subject: [PATCH] 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 --- Changes | 2 ++ src/V3Ast.h | 1 + src/V3Premit.cpp | 11 ++++++++--- src/V3Split.cpp | 2 +- src/V3Stats.cpp | 5 ++--- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Changes b/Changes index 003312343..78c5b3c5d 100644 --- a/Changes +++ b/Changes @@ -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] diff --git a/src/V3Ast.h b/src/V3Ast.h index 6c15182a4..60c80a8a5 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -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 diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index 2d30fba37..25efb636b 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -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: "<isWide()?"Y":"N")<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: "<iterateChildren(*this); + m_funcp = NULL; } void startStatement(AstNode* nodep) { m_assignLhs = false; diff --git a/src/V3Split.cpp b/src/V3Split.cpp index abffaa7e5..3753965e8 100644 --- a/src/V3Split.cpp +++ b/src/V3Split.cpp @@ -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. diff --git a/src/V3Stats.cpp b/src/V3Stats.cpp index 94048ef9b..472f4a636 100644 --- a/src/V3Stats.cpp +++ b/src/V3Stats.cpp @@ -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();