Fix extra evaluation of pure combo blocks in SystemC output.

This commit is contained in:
Wilson Snyder 2008-08-06 17:09:33 -04:00
parent 500dc2170f
commit 3463080a71
6 changed files with 83 additions and 6 deletions

View File

@ -12,6 +12,8 @@ indicates the contributor was also the author of the fix; Thanks!
*** Add by-design and by-module subtotals to verilator_profcfunc.
*** Fix extra evaluation of pure combo blocks in SystemC output.
**** Add IMPERFECTSCH warning, disabled by default.
* Verilator 3.670 2008/07/23

View File

@ -417,3 +417,7 @@ void AstCCall::dump(ostream& str) {
funcp()->dump(str);
}
}
void AstCFunc::dump(ostream& str) {
this->AstNode::dump(str);
if (slow()) str<<" [SLOW]";
}

View File

@ -3143,6 +3143,7 @@ public:
virtual string name() const { return m_name; }
virtual bool broken() const { return ( (m_scopep && !m_scopep->brokeExists())); }
virtual bool maybePointedTo() const { return true; }
virtual void dump(ostream& str=cout);
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return ((funcType()==samep->castCFunc()->funcType())
&& (rtnTypeVoid()==samep->castCFunc()->rtnTypeVoid())

View File

@ -256,7 +256,7 @@ private:
AstSenTree* m_deleteDomainp;// Delete this from tree
AstSenTree* m_settleDomainp;// Initial activation tree
OrderInputsVertex* m_inputsVxp; // Top level vertex all inputs point from
OrderSettleVertex* m_settleVxp; // Top level vertex all inputs point from
OrderSettleVertex* m_settleVxp; // Top level vertex all settlement vertexes point from
OrderLogicVertex* m_logicVxp; // Current statement being tracked, NULL=ignored
AstTopScope* m_topScopep; // Current top scope being processed
AstScope* m_scopetopp; // Scope under TOPSCOPE
@ -341,6 +341,8 @@ private:
OrderVarVertex* processInsLoopNewVar(OrderVarVertex* oldVertexp, bool& createdr);
void processBrokeLoop();
void processCircular();
void processInputs();
void processInputsIterate(OrderEitherVertex* vertexp);
void processSensitive();
void processDomains();
void processDomainsIterate(OrderEitherVertex* vertexp);
@ -927,6 +929,39 @@ void OrderVisitor::processBrokeLoop() {
}
}
//######################################################################
// Clock propagation
void OrderVisitor::processInputs() {
m_graph.userClearVertices(); // Vertex::user() // true if added as begin/end
processInputsIterate(m_inputsVxp);
}
void OrderVisitor::processInputsIterate(OrderEitherVertex* vertexp) {
// Propagate PrimaryIn through simple assignments
if (vertexp->user()) return; // Already processed
//UINFO(9," InIt "<<vertexp<<endl);
vertexp->user(true);
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(vertexp)) {
vvertexp->isFromInput(true);
}
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
OrderEitherVertex* toVertexp = (OrderEitherVertex*)edgep->top();
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(toVertexp)) {
processInputsIterate(vvertexp);
}
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(toVertexp)) {
if (AstNodeAssign* nodep = vvertexp->nodep()->castNodeAssign()) {
if (nodep->lhsp()->castVarRef()
&& nodep->rhsp()->castVarRef()) {
UINFO(9," Input reassignment: "<<vvertexp<<endl);
processInputsIterate(vvertexp);
}
}
}
}
}
//######################################################################
// Circular detection
@ -936,7 +971,7 @@ void OrderVisitor::processCircular() {
// The change detect code will use this to force changedets
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) {
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(itp)) {
if (vvertexp->isClock() && !vvertexp->varScp()->varp()->isPrimaryIn()) {
if (vvertexp->isClock() && !vvertexp->isFromInput()) {
// If a clock is generated internally, we need to do another loop
// through the entire evaluation. This fixes races; see t_clk_dpulse test.
UINFO(5,"Circular Clock "<<vvertexp<<endl);
@ -947,6 +982,7 @@ void OrderVisitor::processCircular() {
if (edgep->weight()==0) { // was cut
OrderEdge* oedgep = dynamic_cast<OrderEdge*>(edgep);
if (!oedgep) vvertexp->varScp()->v3fatalSrc("Cuttable edge not of proper type");
UINFO(6," CutCircularO: "<<vvertexp->name()<<endl);
nodeMarkCircular(vvertexp, oedgep);
}
}
@ -954,6 +990,7 @@ void OrderVisitor::processCircular() {
if (edgep->weight()==0) { // was cut
OrderEdge* oedgep = dynamic_cast<OrderEdge*>(edgep);
if (!oedgep) vvertexp->varScp()->v3fatalSrc("Cuttable edge not of proper type");
UINFO(6," CutCircularI: "<<vvertexp->name()<<endl);
nodeMarkCircular(vvertexp, oedgep);
}
}
@ -1542,6 +1579,9 @@ void OrderVisitor::process() {
m_graph.order();
m_graph.dumpDotFilePrefixed("orderg_order");
UINFO(2," Process Clocks...\n");
processInputs(); // must be before processCircular
#ifndef NEW_ORDERING
UINFO(2," Process Circulars...\n");
processCircular(); // must be before processDomains

View File

@ -18,6 +18,30 @@
// GNU General Public License for more details.
//
//*************************************************************************
// OrderGraph Class Hiearchy:
//
// V3GraphVertex
// OrderMoveVertex
// OrderEitherVertex
// OrderInputsVertex
// OrderSettleVertex
// OrderLogicVertex
// OrderLoopBeginVertex
// OrderLoopEndVertex
// OrderVarVertex
// OrderVarStdVertex
// OrderVarPreVertex
// OrderVarPostVertex
// OrderVarPordVertex
// OrderVarSettleVertex
//
// V3GraphEdge
// OrderEdge
// OrderChangeDetEdge
// OrderComboCutEdge
// OrderPostCutEdge
// OrderPreCutEdge
//*************************************************************************
#include "config_build.h"
#include "verilatedos.h"
@ -168,20 +192,23 @@ public:
class OrderVarVertex : public OrderEitherVertex {
AstVarScope* m_varScp;
bool m_isClock; // Used as clock
OrderVarVertex* m_pilNewVertexp; // for processInsLoopNewVar
bool m_isClock; // Used as clock
bool m_isFromInput; // From input, or derrived therefrom (conservatively false)
public:
OrderVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
: OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp), m_isClock(false)
, m_pilNewVertexp(NULL)
: OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp)
, m_pilNewVertexp(NULL), m_isClock(false), m_isFromInput(false)
{}
virtual ~OrderVarVertex() {}
virtual OrderVarVertex* clone (V3Graph* graphp) const = 0;
virtual OrderVEdgeType type() const = 0;
// Accessors
AstVarScope* varScp() const { return m_varScp; }
void isClock(bool clk) { m_isClock=clk; }
void isClock(bool flag) { m_isClock=flag; }
bool isClock() const { return m_isClock; }
void isFromInput(bool flag) { m_isFromInput=flag; }
bool isFromInput() const { return m_isFromInput; }
OrderVarVertex* pilNewVertexp() const { return m_pilNewVertexp; }
void pilNewVertexp (OrderVarVertex* vertexp) { m_pilNewVertexp = vertexp; }
};

View File

@ -3,6 +3,9 @@
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2003 by Wilson Snyder.
// Also check that SystemC is ordering properly
// verilator lint_on IMPERFECTSCH
module t (/*AUTOARG*/
// Inputs
clk