Support [#] in dotted cell names
git-svn-id: file://localhost/svn/verilator/trunk/verilator@863 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
58b1ad1439
commit
5a65f6debb
3
Changes
3
Changes
|
|
@ -5,6 +5,9 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
* Verilator 3.63*
|
||||
|
||||
** Support standard NAME[#] for cells created by arraying or generate for.
|
||||
This replaces the non-standard name__# syntax used in earlier versions.
|
||||
|
||||
**** Fix again dotted references into generate cells. [David Hewson]
|
||||
Verilator no longer accepts duplicated variables inside unique
|
||||
generate blocks as this is illegal according to the specification.
|
||||
|
|
|
|||
|
|
@ -1169,24 +1169,22 @@ always @* to prevent these issues.)
|
|||
|
||||
Verilator supports dotted references to variables, functions and tasks in
|
||||
different modules. However, references into named blocks and function-local
|
||||
variables are not supported. References into arrayed and generated
|
||||
instances work, but still require some work-arounds in the Verilog code:
|
||||
variables are not supported. The portion before the dot must have a
|
||||
constant value; for example a[2].b is acceptable, while a[x].b is not.
|
||||
|
||||
References into arrayed instances use different names from the Verilog
|
||||
standard; arrayed instances are named {cellName}__{instanceNumber}. For
|
||||
example a[2] is instead a__2. Thus you cannot use a parameter or variable
|
||||
to select the index number; expand it into a case statement manually.
|
||||
|
||||
References into generate statements should match the names from the Verilog
|
||||
standard; subject to converting generate-for a[#] to a__# as described
|
||||
above. When a dotted signal cannot be resolved, Verilator will print a
|
||||
list of known scopes to help debugging.
|
||||
References into generated and arrayed instances use the instance names
|
||||
specified in the Verilog standard; arrayed instances are named
|
||||
{cellName}[{instanceNumber}] in Verilog, which becomes
|
||||
{cellname}__BRA__{instanceNumber}__KET__ inside the generated C++ code.
|
||||
|
||||
Verilator creates numbered "genblk" when a begin: name is not specified
|
||||
around a block inside a generate statement. These numbers may differ
|
||||
between other simulators, but the Verilog specification does not allow
|
||||
users to use these names, so it should not matter.
|
||||
|
||||
If you are having trouble determining where a dotted path goes wrong, note
|
||||
that Verilator will print a list of known scopes to help your debugging.
|
||||
|
||||
=head2 Latches
|
||||
|
||||
Verilator is optimized for edge sensitive (flop based) designs. It will
|
||||
|
|
@ -1626,6 +1624,12 @@ create a SpTraceFile object as you would create a normal SystemC trace
|
|||
file. For an example, see the call to SpTraceFile in the
|
||||
test_sp/sc_main.cpp file of the distribution.
|
||||
|
||||
=item How do I view waveforms (traces)?
|
||||
|
||||
Verilator makes standard VCD (Value Change Dump) files. They are viewable
|
||||
with the public domain Dinotrace or GtkWave programs, or any of the many
|
||||
commercial offerings.
|
||||
|
||||
=item Where is the translate_off command? (How do I ignore a construct?)
|
||||
|
||||
Translate on/off pragmas are generally a bad idea, as it's easy to have
|
||||
|
|
|
|||
|
|
@ -92,12 +92,19 @@ string AstNode::shortName() const {
|
|||
return pretty;
|
||||
}
|
||||
|
||||
string AstNode::prettyName(const string& namein) {
|
||||
string AstNode::dedotName(const string& namein) {
|
||||
string pretty = namein;
|
||||
string::size_type pos;
|
||||
while ((pos=pretty.find("__DOT__")) != string::npos) {
|
||||
pretty.replace(pos, 7, ".");
|
||||
}
|
||||
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
|
||||
return pretty;
|
||||
}
|
||||
|
||||
string AstNode::prettyName(const string& namein) {
|
||||
string pretty = namein;
|
||||
string::size_type pos;
|
||||
while ((pos=pretty.find("__BRA__")) != string::npos) {
|
||||
pretty.replace(pos, 7, "[");
|
||||
}
|
||||
|
|
@ -107,8 +114,7 @@ string AstNode::prettyName(const string& namein) {
|
|||
while ((pos=pretty.find("__PVT__")) != string::npos) {
|
||||
pretty.replace(pos, 7, "");
|
||||
}
|
||||
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
|
||||
return pretty;
|
||||
return AstNode::dedotName(pretty);
|
||||
}
|
||||
|
||||
int AstNode::widthPow2() const {
|
||||
|
|
|
|||
|
|
@ -523,6 +523,7 @@ public:
|
|||
virtual string name() const { return ""; }
|
||||
virtual string verilogKwd() const { return ""; }
|
||||
string shortName() const; // Name with __PVT__ removed for concatenating scopes
|
||||
static string dedotName(const string& namein); // Name with dots removed
|
||||
static string prettyName(const string& namein); // Name for printing out to the user
|
||||
string prettyName() const { return prettyName(name()); }
|
||||
FileLine* fileline() const { return m_fileline; }
|
||||
|
|
|
|||
|
|
@ -163,8 +163,8 @@ private:
|
|||
// Somewhat illogically, we need to rename the orignal name of the cell too.
|
||||
// as that is the name users expect for dotting
|
||||
// The spec says we add [x], but that won't work in C...
|
||||
newp->name(newp->name()+"__"+cvtToStr(m_instNum));
|
||||
newp->origName(newp->origName()+"__"+cvtToStr(m_instNum));
|
||||
newp->name(newp->name()+"__BRA__"+cvtToStr(m_instNum)+"__KET__");
|
||||
newp->origName(newp->origName()+"__BRA__"+cvtToStr(m_instNum)+"__KET__");
|
||||
// Fixup pins
|
||||
newp->pinsp()->iterateAndNext(*this);
|
||||
if (debug()==9) { newp->dumpTree(cout,"newcell: "); cout<<endl; }
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ private:
|
|||
typedef std::multimap<string,LinkDotCellVertex*> NameScopeMap;
|
||||
// MEMBERS
|
||||
LinkDotGraph m_graph; // Graph of hiearchy
|
||||
NameScopeMap m_nameScopeMap; // Hash of scope referenced by textual name
|
||||
NameScopeMap m_nameScopeMap; // Hash of scope referenced by non-pretty textual name
|
||||
bool m_forPrearray; // Compress cell__[array] refs
|
||||
bool m_forScopeCreation; // Remove VarXRefs for V3Scope
|
||||
public:
|
||||
|
|
@ -298,7 +298,7 @@ public:
|
|||
string altIdent = "";
|
||||
if (m_forPrearray) {
|
||||
// Cell foo__[array] before we've expanded arrays is just foo.
|
||||
if ((pos = ident.find("__")) != string::npos) {
|
||||
if ((pos = ident.find("__BRA__")) != string::npos) {
|
||||
altIdent = ident.substr(0,pos);
|
||||
}
|
||||
}
|
||||
|
|
@ -415,7 +415,7 @@ private:
|
|||
LinkDotBaseVertex* oldInlineVxp = m_inlineVxp;
|
||||
// Where do we add it?
|
||||
LinkDotBaseVertex* aboveVxp = m_inlineVxp;
|
||||
string origname = nodep->prettyName();
|
||||
string origname = AstNode::dedotName(nodep->name());
|
||||
string::size_type pos;
|
||||
if ((pos = origname.rfind(".")) != string::npos) {
|
||||
// Flattened, find what CellInline it should live under
|
||||
|
|
@ -616,7 +616,7 @@ private:
|
|||
LinkDotBaseVertex* okVxp;
|
||||
LinkDotBaseVertex* dotVxp = m_cellVxp; // Start search at current scope
|
||||
if (nodep->inlinedDots()!="") { // Correct for current scope
|
||||
string inl = AstNode::prettyName(nodep->inlinedDots());
|
||||
string inl = AstNode::dedotName(nodep->inlinedDots());
|
||||
dotVxp = m_statep->findDotted(dotVxp, inl, baddot, okVxp);
|
||||
if (!dotVxp) nodep->v3fatalSrc("Couldn't resolve inlined scope '"<<baddot<<"' in: "<<nodep->inlinedDots());
|
||||
}
|
||||
|
|
@ -663,10 +663,13 @@ private:
|
|||
LinkDotBaseVertex* okVxp;
|
||||
LinkDotBaseVertex* dotVxp = m_cellVxp; // Start search at current scope
|
||||
if (nodep->inlinedDots()!="") { // Correct for current scope
|
||||
string inl = AstNode::prettyName(nodep->inlinedDots());
|
||||
string inl = AstNode::dedotName(nodep->inlinedDots());
|
||||
UINFO(8,"\t\tInlined "<<inl<<endl);
|
||||
dotVxp = m_statep->findDotted(dotVxp, inl, baddot, okVxp);
|
||||
if (!dotVxp) nodep->v3fatalSrc("Couldn't resolve inlined scope '"<<baddot<<"' in: "<<nodep->inlinedDots());
|
||||
if (!dotVxp) {
|
||||
okVxp->errorScopes(nodep);
|
||||
nodep->v3fatalSrc("Couldn't resolve inlined scope '"<<baddot<<"' in: "<<nodep->inlinedDots());
|
||||
}
|
||||
}
|
||||
dotVxp = m_statep->findDotted(dotVxp, nodep->dotted(), baddot, okVxp); // Maybe NULL
|
||||
|
||||
|
|
|
|||
|
|
@ -348,10 +348,7 @@ private:
|
|||
// V3Begin sees these DOTs and makes CellInlines for us.
|
||||
string nname = (string)"genfor"+cvtToStr(m_varValuep->asInt())+"__DOT__"+nodep->name();
|
||||
// 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.
|
||||
// (Fixing parsing to allow hardcoded numbers then leads to shift/reduce conflicts.)
|
||||
nname = nodep->name() + "__" + cvtToStr(m_varValuep->asInt());
|
||||
nname = nodep->name() + "__BRA__" + cvtToStr(m_varValuep->asInt()) + "__KET__";
|
||||
//UINFO(8," Rename begin "<<nname<<" "<<nodep<<endl);
|
||||
nodep->name(nname);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,11 +98,7 @@ module Genit (clk, value, result);
|
|||
Test tt (clk, value, result);
|
||||
`endif
|
||||
|
||||
`ifdef verilator
|
||||
wire Result2 = t.g.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
|
||||
|
|
|
|||
|
|
@ -51,13 +51,8 @@ module Genit (
|
|||
|
||||
// ARRAY
|
||||
One cellarray1[1:0] (); //cellarray[0..1][0..1]
|
||||
`ifdef verilator
|
||||
always @ (posedge clk) if (cellarray1__0.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (cellarray1__1.one !== 1'b1) $stop;
|
||||
`else
|
||||
always @ (posedge clk) if (cellarray1[0].one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (cellarray1[1].one !== 1'b1) $stop;
|
||||
`endif
|
||||
|
||||
// IF
|
||||
generate
|
||||
|
|
@ -122,8 +117,8 @@ module Genit (
|
|||
One cellfor20 (); // genblk5[0..1].cellfor20
|
||||
endgenerate
|
||||
`ifdef verilator
|
||||
always @ (posedge clk) if (genblk4__0.cellfor20.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (genblk4__1.cellfor20.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (genblk4[0].cellfor20.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (genblk4[1].cellfor20.one !== 1'b1) $stop;
|
||||
//`else // NOT SUPPORTED accoring to spec - generic block references
|
||||
`endif
|
||||
|
||||
|
|
@ -134,13 +129,8 @@ module Genit (
|
|||
One cellfor21 (); // namedfor21[0..1].cellfor21
|
||||
end
|
||||
endgenerate
|
||||
`ifdef verilator
|
||||
always @ (posedge clk) if (namedfor21__0.cellfor21.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (namedfor21__1.cellfor21.one !== 1'b1) $stop;
|
||||
`else
|
||||
always @ (posedge clk) if (namedfor21[0].cellfor21.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (namedfor21[1].cellfor21.one !== 1'b1) $stop;
|
||||
`endif
|
||||
|
||||
generate
|
||||
for (i = 0; i < 2; i = i + 1)
|
||||
|
|
@ -162,15 +152,13 @@ module Genit (
|
|||
end
|
||||
end
|
||||
endgenerate
|
||||
`ifdef verilator
|
||||
always @ (posedge clk) if (namedfor30__0.forb30__0.forif30.cellfor30a.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (namedfor30__0.forb30__1.forif30b.cellfor30b.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (namedfor30__1.forb30__0.forif30.cellfor30a.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (namedfor30__1.forb30__1.forif30b.cellfor30b.one !== 1'b1) $stop;
|
||||
`else
|
||||
always @ (posedge clk) if (namedfor30[0].forb30[0].forif30.cellfor30a.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (namedfor30[0].forb30[1].forif30.cellfor30b.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (namedfor30[1].forb30[0].forif30.cellfor30a.one !== 1'b1) $stop;
|
||||
`ifdef verilator
|
||||
always @ (posedge clk) if (namedfor30[0].forb30[1].forif30b.cellfor30b.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (namedfor30[1].forb30[1].forif30b.cellfor30b.one !== 1'b1) $stop;
|
||||
`else
|
||||
always @ (posedge clk) if (namedfor30[0].forb30[1].forif30.cellfor30b.one !== 1'b1) $stop;
|
||||
always @ (posedge clk) if (namedfor30[1].forb30[1].forif30.cellfor30b.one !== 1'b1) $stop;
|
||||
`endif
|
||||
|
||||
|
|
|
|||
|
|
@ -36,12 +36,9 @@ module t (/*AUTOARG*/
|
|||
end
|
||||
if (cyc==3) begin
|
||||
if (bitout !== 8'h41) $stop;
|
||||
`ifdef verilator // Hacky array subscripting
|
||||
if (sub__0.bitout !== 1'b1) $stop;
|
||||
if (sub__1.bitout !== 1'b0) $stop;
|
||||
`else
|
||||
if (sub[0].bitout !== 1'b1) $stop;
|
||||
if (sub[1].bitout !== 1'b0) $stop;
|
||||
`ifndef verilator // Hacky array subscripting
|
||||
if (sub[ONE].bitout !== 1'b0) $stop;
|
||||
`endif
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue