CDC: Fix columns mis-aligning when large filename paths
This commit is contained in:
parent
b6447a9032
commit
97adede70b
|
|
@ -110,15 +110,19 @@ public:
|
||||||
|
|
||||||
class CdcLogicVertex : public CdcEitherVertex {
|
class CdcLogicVertex : public CdcEitherVertex {
|
||||||
bool m_safe;
|
bool m_safe;
|
||||||
|
bool m_isFlop;
|
||||||
public:
|
public:
|
||||||
CdcLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstSenTree* sensenodep)
|
CdcLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstSenTree* sensenodep)
|
||||||
: CdcEitherVertex(graphp,scopep,nodep), m_safe(true) { srcDomainp(sensenodep); dstDomainp(sensenodep); }
|
: CdcEitherVertex(graphp,scopep,nodep), m_safe(true), m_isFlop(false)
|
||||||
|
{ srcDomainp(sensenodep); dstDomainp(sensenodep); }
|
||||||
virtual ~CdcLogicVertex() {}
|
virtual ~CdcLogicVertex() {}
|
||||||
// Accessors
|
// Accessors
|
||||||
virtual string name() const { return (cvtToStr((void*)nodep())+"@"+scopep()->prettyName()); }
|
virtual string name() const { return (cvtToStr((void*)nodep())+"@"+scopep()->prettyName()); }
|
||||||
virtual string dotColor() const { return safe() ? "black" : "yellow"; }
|
virtual string dotColor() const { return safe() ? "black" : "yellow"; }
|
||||||
bool safe() const { return m_safe; }
|
bool safe() const { return m_safe; }
|
||||||
void clearSafe(AstNode* nodep) { m_safe = false; nodep->user3(true); }
|
void clearSafe(AstNode* nodep) { m_safe = false; nodep->user3(true); }
|
||||||
|
bool isFlop() const { return m_isFlop; }
|
||||||
|
void isFlop(bool flag) { m_isFlop = flag; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
@ -158,6 +162,42 @@ public:
|
||||||
virtual ~CdcDumpVisitor() {}
|
virtual ~CdcDumpVisitor() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//######################################################################
|
||||||
|
|
||||||
|
class CdcWidthVisitor : public CdcBaseVisitor {
|
||||||
|
private:
|
||||||
|
int m_maxLineno;
|
||||||
|
int m_maxFilenameLen;
|
||||||
|
|
||||||
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
// Keeping line+filename lengths separate is much faster than calling ascii().length()
|
||||||
|
if (nodep->fileline()->lineno() >= m_maxLineno) {
|
||||||
|
m_maxLineno = nodep->fileline()->lineno()+1;
|
||||||
|
}
|
||||||
|
if (nodep->fileline()->filename().length() >= m_maxFilenameLen) {
|
||||||
|
m_maxFilenameLen = nodep->fileline()->filename().length()+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
// CONSTUCTORS
|
||||||
|
CdcWidthVisitor(AstNode* nodep) {
|
||||||
|
m_maxLineno = 0;
|
||||||
|
m_maxFilenameLen = 0;
|
||||||
|
nodep->accept(*this);
|
||||||
|
}
|
||||||
|
virtual ~CdcWidthVisitor() {}
|
||||||
|
// ACCESSORS
|
||||||
|
int maxWidth() {
|
||||||
|
int width=1;
|
||||||
|
width += m_maxFilenameLen;
|
||||||
|
width += 1; // The :
|
||||||
|
width += cvtToStr(m_maxLineno).length();
|
||||||
|
width += 1; // Final :
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// Cdc class functions
|
// Cdc class functions
|
||||||
|
|
||||||
|
|
@ -182,6 +222,7 @@ private:
|
||||||
string m_ofFilename; // Output filename
|
string m_ofFilename; // Output filename
|
||||||
ofstream* m_ofp; // Output file
|
ofstream* m_ofp; // Output file
|
||||||
uint32_t m_userGeneration; // Generation count to avoid slow userClearVertices
|
uint32_t m_userGeneration; // Generation count to avoid slow userClearVertices
|
||||||
|
int m_filelineWidth; // Characters in longest fileline
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
void iterateNewStmt(AstNode* nodep) {
|
void iterateNewStmt(AstNode* nodep) {
|
||||||
|
|
@ -189,6 +230,7 @@ private:
|
||||||
UINFO(4," STMT "<<nodep<<endl);
|
UINFO(4," STMT "<<nodep<<endl);
|
||||||
m_logicVertexp = new CdcLogicVertex(&m_graph, m_scopep, nodep, m_domainp);
|
m_logicVertexp = new CdcLogicVertex(&m_graph, m_scopep, nodep, m_domainp);
|
||||||
if (m_domainp && m_domainp->hasClocked()) { // To/from a flop
|
if (m_domainp && m_domainp->hasClocked()) { // To/from a flop
|
||||||
|
m_logicVertexp->isFlop(true);
|
||||||
m_logicVertexp->srcDomainp(m_domainp);
|
m_logicVertexp->srcDomainp(m_domainp);
|
||||||
m_logicVertexp->srcDomainSet(true);
|
m_logicVertexp->srcDomainSet(true);
|
||||||
m_logicVertexp->dstDomainp(m_domainp);
|
m_logicVertexp->dstDomainp(m_domainp);
|
||||||
|
|
@ -266,6 +308,14 @@ private:
|
||||||
analyzeReset();
|
analyzeReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int filelineWidth() {
|
||||||
|
if (!m_filelineWidth) {
|
||||||
|
CdcWidthVisitor visitor (v3Global.rootp());
|
||||||
|
m_filelineWidth = visitor.maxWidth();
|
||||||
|
}
|
||||||
|
return m_filelineWidth;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
// RESET REPORT
|
// RESET REPORT
|
||||||
|
|
||||||
|
|
@ -344,9 +394,15 @@ private:
|
||||||
*m_ofp<<"\n";
|
*m_ofp<<"\n";
|
||||||
*m_ofp<<"\n";
|
*m_ofp<<"\n";
|
||||||
CdcEitherVertex* targetp = vertexp; // One example destination flop (of possibly many)
|
CdcEitherVertex* targetp = vertexp; // One example destination flop (of possibly many)
|
||||||
if (V3GraphEdge* edgep = vertexp->outBeginp()) {
|
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||||
CdcEitherVertex* eToVertexp = (CdcEitherVertex*)edgep->top();
|
CdcEitherVertex* eToVertexp = (CdcEitherVertex*)edgep->top();
|
||||||
|
if (!eToVertexp) targetp = eToVertexp;
|
||||||
|
if (CdcLogicVertex* vvertexp = dynamic_cast<CdcLogicVertex*>(eToVertexp)) {
|
||||||
|
if (vvertexp->isFlop()) {
|
||||||
targetp = eToVertexp;
|
targetp = eToVertexp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // else it might be random logic that's not relevant
|
||||||
}
|
}
|
||||||
warnAndFile(markp->nodep(),V3ErrorCode::CDCRSTLOGIC,"Logic in path that feeds async reset, via signal: "+nodep->prettyName());
|
warnAndFile(markp->nodep(),V3ErrorCode::CDCRSTLOGIC,"Logic in path that feeds async reset, via signal: "+nodep->prettyName());
|
||||||
dumpAsyncRecurse(targetp, "", " ",0);
|
dumpAsyncRecurse(targetp, "", " ",0);
|
||||||
|
|
@ -372,19 +428,20 @@ private:
|
||||||
// Dump single variable/logic block
|
// Dump single variable/logic block
|
||||||
// See also OrderGraph::loopsVertexCb(V3GraphVertex* vertexp)
|
// See also OrderGraph::loopsVertexCb(V3GraphVertex* vertexp)
|
||||||
AstNode* nodep = vertexp->nodep();
|
AstNode* nodep = vertexp->nodep();
|
||||||
string front = pad(40,nodep->fileline()->ascii()+":")+" "+prefix+" +- ";
|
string front = pad(filelineWidth(),nodep->fileline()->ascii()+":")+" "+prefix+" +- ";
|
||||||
if (nodep->castVarScope()) {
|
if (nodep->castVarScope()) {
|
||||||
*m_ofp<<front<<"Variable: "<<nodep->prettyName()<<endl;
|
*m_ofp<<front<<"Variable: "<<nodep->prettyName()<<endl;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
V3EmitV::verilogPrefixedTree(nodep, *m_ofp, prefix+" +- ", vertexp->srcDomainp(), true);
|
V3EmitV::verilogPrefixedTree(nodep, *m_ofp, prefix+" +- ", filelineWidth(),
|
||||||
|
vertexp->srcDomainp(), true);
|
||||||
if (debug()) {
|
if (debug()) {
|
||||||
CdcDumpVisitor visitor (nodep, m_ofp, front+"DBG: ");
|
CdcDumpVisitor visitor (nodep, m_ofp, front+"DBG: ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nextsep = " | ";
|
nextsep = " | ";
|
||||||
if (level) *m_ofp<<V3OutFile::indentSpaces(40)<<" "<<prefix<<nextsep<<"\n";
|
if (level) *m_ofp<<V3OutFile::indentSpaces(filelineWidth())<<" "<<prefix<<nextsep<<"\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -428,7 +485,8 @@ private:
|
||||||
if (vvertexp->srcDomainp()) V3EmitV::verilogForTree(vvertexp->srcDomainp(), os);
|
if (vvertexp->srcDomainp()) V3EmitV::verilogForTree(vvertexp->srcDomainp(), os);
|
||||||
os<<" DST=";
|
os<<" DST=";
|
||||||
if (vvertexp->dstDomainp()) V3EmitV::verilogForTree(vvertexp->dstDomainp(), os);
|
if (vvertexp->dstDomainp()) V3EmitV::verilogForTree(vvertexp->dstDomainp(), os);
|
||||||
os<<"\n";
|
os<<setw(0);
|
||||||
|
os<<endl;
|
||||||
report.push_back(os.str());
|
report.push_back(os.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -627,6 +685,7 @@ public:
|
||||||
m_inDly = false;
|
m_inDly = false;
|
||||||
m_senNumber = 0;
|
m_senNumber = 0;
|
||||||
m_userGeneration = 0;
|
m_userGeneration = 0;
|
||||||
|
m_filelineWidth = 0;
|
||||||
|
|
||||||
// Make report of all signal names and what clock edges they have
|
// Make report of all signal names and what clock edges they have
|
||||||
string filename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__cdc.txt";
|
string filename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__cdc.txt";
|
||||||
|
|
@ -643,7 +702,7 @@ public:
|
||||||
analyze();
|
analyze();
|
||||||
//edgeReport(); // Not useful at the moment
|
//edgeReport(); // Not useful at the moment
|
||||||
|
|
||||||
if (0) { *m_ofp<<"\nDBG-test-dumper\n"; V3EmitV::verilogPrefixedTree(nodep, *m_ofp, "DBG ",NULL,true); *m_ofp<<endl; }
|
if (0) { *m_ofp<<"\nDBG-test-dumper\n"; V3EmitV::verilogPrefixedTree(nodep, *m_ofp, "DBG ",40,NULL,true); *m_ofp<<endl; }
|
||||||
}
|
}
|
||||||
virtual ~CdcVisitor() {
|
virtual ~CdcVisitor() {
|
||||||
if (m_ofp) { delete m_ofp; m_ofp = NULL; }
|
if (m_ofp) { delete m_ofp; m_ofp = NULL; }
|
||||||
|
|
|
||||||
|
|
@ -543,6 +543,7 @@ class EmitVStreamVisitor : public EmitVBaseVisitor {
|
||||||
class EmitVPrefixedFormatter : public V3OutFormatter {
|
class EmitVPrefixedFormatter : public V3OutFormatter {
|
||||||
ostream& m_os;
|
ostream& m_os;
|
||||||
string m_prefix; // What to print at beginning of each line
|
string m_prefix; // What to print at beginning of each line
|
||||||
|
int m_flWidth; // Padding of fileline
|
||||||
int m_column; // Rough location; need just zero or non-zero
|
int m_column; // Rough location; need just zero or non-zero
|
||||||
FileLine* m_prefixFl;
|
FileLine* m_prefixFl;
|
||||||
// METHODS
|
// METHODS
|
||||||
|
|
@ -554,7 +555,7 @@ class EmitVPrefixedFormatter : public V3OutFormatter {
|
||||||
if (m_column == 0) {
|
if (m_column == 0) {
|
||||||
m_column = 10;
|
m_column = 10;
|
||||||
m_os<<m_prefixFl->ascii()+":";
|
m_os<<m_prefixFl->ascii()+":";
|
||||||
m_os<<V3OutFile::indentSpaces(40-(m_prefixFl->ascii().length()+1));
|
m_os<<V3OutFile::indentSpaces(m_flWidth-(m_prefixFl->ascii().length()+1));
|
||||||
m_os<<" ";
|
m_os<<" ";
|
||||||
m_os<<m_prefix;
|
m_os<<m_prefix;
|
||||||
}
|
}
|
||||||
|
|
@ -566,8 +567,8 @@ public:
|
||||||
void prefixFl(FileLine* fl) { m_prefixFl = fl; }
|
void prefixFl(FileLine* fl) { m_prefixFl = fl; }
|
||||||
FileLine* prefixFl() const { return m_prefixFl; }
|
FileLine* prefixFl() const { return m_prefixFl; }
|
||||||
int column() const { return m_column; }
|
int column() const { return m_column; }
|
||||||
EmitVPrefixedFormatter(ostream& os, const string& prefix)
|
EmitVPrefixedFormatter(ostream& os, const string& prefix, int flWidth)
|
||||||
: V3OutFormatter("__STREAM", true), m_os(os), m_prefix(prefix) {
|
: V3OutFormatter("__STREAM", true), m_os(os), m_prefix(prefix), m_flWidth(flWidth) {
|
||||||
m_column = 0;
|
m_column = 0;
|
||||||
m_prefixFl = v3Global.rootp()->fileline(); // NETLIST's fileline instead of NULL to avoid NULL checks
|
m_prefixFl = v3Global.rootp()->fileline(); // NETLIST's fileline instead of NULL to avoid NULL checks
|
||||||
}
|
}
|
||||||
|
|
@ -598,9 +599,9 @@ class EmitVPrefixedVisitor : public EmitVBaseVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EmitVPrefixedVisitor(AstNode* nodep, ostream& os, const string& prefix,
|
EmitVPrefixedVisitor(AstNode* nodep, ostream& os, const string& prefix, int flWidth,
|
||||||
AstSenTree* domainp, bool user3mark)
|
AstSenTree* domainp, bool user3mark)
|
||||||
: EmitVBaseVisitor(domainp), m_formatter(os, prefix), m_user3mark(user3mark) {
|
: EmitVBaseVisitor(domainp), m_formatter(os, prefix, flWidth), m_user3mark(user3mark) {
|
||||||
if (user3mark) { AstUser3InUse::check(); }
|
if (user3mark) { AstUser3InUse::check(); }
|
||||||
nodep->accept(*this);
|
nodep->accept(*this);
|
||||||
}
|
}
|
||||||
|
|
@ -633,7 +634,7 @@ void V3EmitV::verilogForTree(AstNode* nodep, ostream& os) {
|
||||||
EmitVStreamVisitor(nodep, os);
|
EmitVStreamVisitor(nodep, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
void V3EmitV::verilogPrefixedTree(AstNode* nodep, ostream& os, const string& prefix,
|
void V3EmitV::verilogPrefixedTree(AstNode* nodep, ostream& os, const string& prefix, int flWidth,
|
||||||
AstSenTree* domainp, bool user3mark) {
|
AstSenTree* domainp, bool user3mark) {
|
||||||
EmitVPrefixedVisitor(nodep, os, prefix, domainp, user3mark);
|
EmitVPrefixedVisitor(nodep, os, prefix, flWidth, domainp, user3mark);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class V3EmitV {
|
||||||
public:
|
public:
|
||||||
static void emitv();
|
static void emitv();
|
||||||
static void verilogForTree(AstNode* nodep, ostream& os=cout);
|
static void verilogForTree(AstNode* nodep, ostream& os=cout);
|
||||||
static void verilogPrefixedTree(AstNode* nodep, ostream& os, const string& prefix,
|
static void verilogPrefixedTree(AstNode* nodep, ostream& os, const string& prefix, int flWidth,
|
||||||
AstSenTree* domainp, bool user3percent);
|
AstSenTree* domainp, bool user3percent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue