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:
Wilson Snyder 2006-12-22 15:06:13 +00:00
parent 58b1ad1439
commit 5a65f6debb
10 changed files with 48 additions and 53 deletions

View File

@ -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.

View File

@ -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

View File

@ -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 {

View File

@ -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; }

View File

@ -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; }

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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");