Fix extra evaluation of pure combo blocks in SystemC output.
This commit is contained in:
parent
500dc2170f
commit
3463080a71
2
Changes
2
Changes
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue