Fix dotted references into generate fors
git-svn-id: file://localhost/svn/verilator/trunk/verilator@840 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
4100417f83
commit
8848469bf9
|
|
@ -98,6 +98,12 @@ string AstNode::prettyName(const string& namein) {
|
||||||
while ((pos=pretty.find("__DOT__")) != string::npos) {
|
while ((pos=pretty.find("__DOT__")) != string::npos) {
|
||||||
pretty.replace(pos, 7, ".");
|
pretty.replace(pos, 7, ".");
|
||||||
}
|
}
|
||||||
|
while ((pos=pretty.find("__BRA__")) != string::npos) {
|
||||||
|
pretty.replace(pos, 7, "[");
|
||||||
|
}
|
||||||
|
while ((pos=pretty.find("__KET__")) != string::npos) {
|
||||||
|
pretty.replace(pos, 7, "]");
|
||||||
|
}
|
||||||
while ((pos=pretty.find("__PVT__")) != string::npos) {
|
while ((pos=pretty.find("__PVT__")) != string::npos) {
|
||||||
pretty.replace(pos, 7, "");
|
pretty.replace(pos, 7, "");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ public:
|
||||||
string scopes;
|
string scopes;
|
||||||
for (NameVtxMap::iterator it = m_nameToVtxMap.begin(); it!=m_nameToVtxMap.end(); ++it) {
|
for (NameVtxMap::iterator it = m_nameToVtxMap.begin(); it!=m_nameToVtxMap.end(); ++it) {
|
||||||
if (scopes != "") scopes += ", ";
|
if (scopes != "") scopes += ", ";
|
||||||
scopes += it->second->cellName();
|
scopes += AstNode::prettyName(it->second->cellName());
|
||||||
}
|
}
|
||||||
cerr<<V3Error::msgPrefix()<<" Known scopes under '"<<cellName()<<"': "
|
cerr<<V3Error::msgPrefix()<<" Known scopes under '"<<cellName()<<"': "
|
||||||
<<scopes<<endl;
|
<<scopes<<endl;
|
||||||
|
|
@ -145,6 +145,27 @@ public:
|
||||||
virtual string dotColor() const { return "yellow"; }
|
virtual string dotColor() const { return "yellow"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LinkDotBeginVertex : public LinkDotBaseVertex {
|
||||||
|
// A fake point in the hierarchy, corresponding to a begin block
|
||||||
|
// After we remove begins these will go away
|
||||||
|
// Note we use the symbol table of the parent, as we want to find variables there
|
||||||
|
// However, cells walk the graph, so cells will appear under the begin itself
|
||||||
|
AstBegin* m_nodep; // Relevant node
|
||||||
|
LinkDotCellVertex* m_symVxp; // Above cell so we can find real symbol table
|
||||||
|
// // (Could walk graph to find it, but that's much slower.)
|
||||||
|
public:
|
||||||
|
LinkDotBeginVertex(V3Graph* graphp, AstBegin* nodep, LinkDotCellVertex* symVxp)
|
||||||
|
: LinkDotBaseVertex(graphp, nodep->name()+"__DOT__")
|
||||||
|
, m_nodep(nodep), m_symVxp(symVxp) {}
|
||||||
|
virtual ~LinkDotBeginVertex() {}
|
||||||
|
// Search up through tree to find the real symbol table.
|
||||||
|
virtual V3SymTable& syms() { return m_symVxp->syms(); }
|
||||||
|
virtual string modName() const { return m_nodep->name(); }
|
||||||
|
virtual string cellName() const { return m_nodep->name(); }
|
||||||
|
virtual string name() const { return (string)("BEG C:")+cellName(); }
|
||||||
|
virtual string dotColor() const { return "blue"; }
|
||||||
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// LinkDot state, as a visitor of each AstNode
|
// LinkDot state, as a visitor of each AstNode
|
||||||
|
|
||||||
|
|
@ -214,6 +235,14 @@ public:
|
||||||
}
|
}
|
||||||
return vxp;
|
return vxp;
|
||||||
}
|
}
|
||||||
|
LinkDotBeginVertex* insertBegin(LinkDotBaseVertex* abovep, LinkDotCellVertex* cellVxp,
|
||||||
|
AstBegin* nodep) {
|
||||||
|
UINFO(9," INSERTbeg "<<nodep<<endl);
|
||||||
|
LinkDotBeginVertex* vxp = new LinkDotBeginVertex(&m_graph, nodep, cellVxp);
|
||||||
|
new V3GraphEdge(&m_graph, abovep, vxp, 1, false);
|
||||||
|
abovep->insertSubcellName(nodep->name(), vxp);
|
||||||
|
return vxp;
|
||||||
|
}
|
||||||
void insertSym(LinkDotCellVertex* abovep, const string& name, AstNode* nodep) {
|
void insertSym(LinkDotCellVertex* abovep, const string& name, AstNode* nodep) {
|
||||||
UINFO(9," INSERTsym "<<name<<" "<<nodep<<endl);
|
UINFO(9," INSERTsym "<<name<<" "<<nodep<<endl);
|
||||||
abovep->syms().insert(name, nodep);
|
abovep->syms().insert(name, nodep);
|
||||||
|
|
@ -382,8 +411,9 @@ private:
|
||||||
string oldscope = m_scope;
|
string oldscope = m_scope;
|
||||||
AstBegin* oldbeginp = m_beginp;
|
AstBegin* oldbeginp = m_beginp;
|
||||||
LinkDotCellVertex* oldVxp = m_cellVxp;
|
LinkDotCellVertex* oldVxp = m_cellVxp;
|
||||||
|
LinkDotBaseVertex* oldInlineVxp = m_inlineVxp;
|
||||||
// Where do we add it?
|
// Where do we add it?
|
||||||
LinkDotBaseVertex* aboveVxp = m_cellVxp;
|
LinkDotBaseVertex* aboveVxp = m_inlineVxp;
|
||||||
string origname = nodep->prettyName();
|
string origname = nodep->prettyName();
|
||||||
string::size_type pos;
|
string::size_type pos;
|
||||||
if ((pos = origname.rfind(".")) != string::npos) {
|
if ((pos = origname.rfind(".")) != string::npos) {
|
||||||
|
|
@ -404,7 +434,7 @@ private:
|
||||||
m_scope = oldscope;
|
m_scope = oldscope;
|
||||||
m_beginp = oldbeginp;
|
m_beginp = oldbeginp;
|
||||||
m_cellVxp = oldVxp;
|
m_cellVxp = oldVxp;
|
||||||
m_inlineVxp = m_cellVxp;
|
m_inlineVxp = oldInlineVxp;
|
||||||
}
|
}
|
||||||
virtual void visit(AstCellInline* nodep, AstNUser*) {
|
virtual void visit(AstCellInline* nodep, AstNUser*) {
|
||||||
UINFO(5," CELLINLINE under "<<m_scope<<" is "<<nodep<<endl);
|
UINFO(5," CELLINLINE under "<<m_scope<<" is "<<nodep<<endl);
|
||||||
|
|
@ -426,10 +456,16 @@ private:
|
||||||
}
|
}
|
||||||
virtual void visit(AstBegin* nodep, AstNUser*) {
|
virtual void visit(AstBegin* nodep, AstNUser*) {
|
||||||
UINFO(5," "<<nodep<<endl);
|
UINFO(5," "<<nodep<<endl);
|
||||||
// We don't pickup variables, but do need to find cells
|
|
||||||
AstBegin* oldbegin = m_beginp;
|
AstBegin* oldbegin = m_beginp;
|
||||||
m_beginp = nodep;
|
LinkDotBaseVertex* oldVxp = m_inlineVxp;
|
||||||
nodep->iterateChildren(*this);
|
{
|
||||||
|
m_beginp = nodep;
|
||||||
|
// Ignore begin names
|
||||||
|
m_inlineVxp = m_statep->insertBegin(m_inlineVxp, m_cellVxp, nodep);
|
||||||
|
// We don't pickup variables, but do need to find cells
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
m_inlineVxp = oldVxp;
|
||||||
m_beginp = oldbegin;
|
m_beginp = oldbegin;
|
||||||
}
|
}
|
||||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||||
|
|
|
||||||
|
|
@ -346,6 +346,13 @@ private:
|
||||||
// Rename it, as otherwise we may get a conflict
|
// Rename it, as otherwise we may get a conflict
|
||||||
// V3Begin sees these DOTs and makes CellInlines for us.
|
// V3Begin sees these DOTs and makes CellInlines for us.
|
||||||
string nname = (string)"genfor"+cvtToStr(m_varValuep->asInt())+"__DOT__"+nodep->name();
|
string nname = (string)"genfor"+cvtToStr(m_varValuep->asInt())+"__DOT__"+nodep->name();
|
||||||
|
if (nodep->name() != "genblk"
|
||||||
|
&& nodep->name().find("__DOT__") == string::npos) {
|
||||||
|
// Verilog seems to drop the for loop name and tack on [#]
|
||||||
|
//nname = nodep->name() + "__BRA__" + cvtToStr(m_varValuep->asInt()) + "__KET__";
|
||||||
|
// However we don't parse [#]'s correctly, so just use __ for now.
|
||||||
|
nname = nodep->name() + "__" + cvtToStr(m_varValuep->asInt());
|
||||||
|
}
|
||||||
//UINFO(8," Rename begin "<<nname<<" "<<nodep<<endl);
|
//UINFO(8," Rename begin "<<nname<<" "<<nodep<<endl);
|
||||||
nodep->name(nname);
|
nodep->name(nname);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,14 @@ module t (/*AUTOARG*/
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
//`define WAVES
|
||||||
|
`ifdef WAVES
|
||||||
|
initial begin
|
||||||
|
$dumpfile("obj_dir/t_gen_intdot.vcd");
|
||||||
|
$dumpvars(12, t);
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module Generate (clk, value, result);
|
module Generate (clk, value, result);
|
||||||
|
|
@ -82,12 +90,22 @@ module Genit (clk, value, result);
|
||||||
genvar i;
|
genvar i;
|
||||||
generate
|
generate
|
||||||
for (i = 0; i < 1; i = i + 1)
|
for (i = 0; i < 1; i = i + 1)
|
||||||
begin : gen
|
begin : foo
|
||||||
Test t (clk, value, result);
|
Test tt (clk, value, result);
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
`else
|
`else
|
||||||
Test t (clk, value, result);
|
Test tt (clk, value, result);
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
`ifdef verilator
|
||||||
|
wire Result2 = t.g.genblk.foo__0.tt.gen.Internal;
|
||||||
|
`else
|
||||||
|
wire Result2 = t.g.foo[0].tt.gen.Internal; // Works - Do not change!
|
||||||
|
`endif
|
||||||
|
always @ (posedge clk) begin
|
||||||
|
$write("[%0t] Result2 = %x\n", $time, Result2);
|
||||||
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue