forked from github/verilator
Fix genblk naming with directly nested generate blocks, #2176.
This commit is contained in:
parent
4c438bbc67
commit
68b6a0b667
2
Changes
2
Changes
@ -9,6 +9,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
|||||||
|
|
||||||
*** Add check for assertOn for asserts, #2162. [Tobias Wölfel]
|
*** Add check for assertOn for asserts, #2162. [Tobias Wölfel]
|
||||||
|
|
||||||
|
*** Fix genblk naming with directly nested generate blocks, #2176. [Alexander Grobman]
|
||||||
|
|
||||||
**** Fix undeclared VL_SHIFTR_WWQ, #2114. [Alex Solomatnikov]
|
**** Fix undeclared VL_SHIFTR_WWQ, #2114. [Alex Solomatnikov]
|
||||||
|
|
||||||
|
|
||||||
|
@ -1282,6 +1282,7 @@ void AstBegin::dump(std::ostream& str) const {
|
|||||||
if (unnamed()) str<<" [UNNAMED]";
|
if (unnamed()) str<<" [UNNAMED]";
|
||||||
if (generate()) str<<" [GEN]";
|
if (generate()) str<<" [GEN]";
|
||||||
if (genforp()) str<<" [GENFOR]";
|
if (genforp()) str<<" [GENFOR]";
|
||||||
|
if (implied()) str<<" [IMPLIED]";
|
||||||
}
|
}
|
||||||
void AstCoverDecl::dump(std::ostream& str) const {
|
void AstCoverDecl::dump(std::ostream& str) const {
|
||||||
this->AstNode::dump(str);
|
this->AstNode::dump(str);
|
||||||
|
@ -3736,16 +3736,19 @@ class AstBegin : public AstNode {
|
|||||||
// Children: statements
|
// Children: statements
|
||||||
private:
|
private:
|
||||||
string m_name; // Name of block
|
string m_name; // Name of block
|
||||||
bool m_unnamed; // Originally unnamed
|
bool m_unnamed; // Originally unnamed (name change does not affect this)
|
||||||
bool m_generate; // Underneath a generate
|
bool m_generate; // Underneath a generate
|
||||||
|
bool m_implied; // Not inserted by user
|
||||||
public:
|
public:
|
||||||
// Node that simply puts name into the output stream
|
// Node that simply puts name into the output stream
|
||||||
AstBegin(FileLine* fl, const string& name, AstNode* stmtsp, bool generate=false)
|
AstBegin(FileLine* fl, const string& name, AstNode* stmtsp, bool generate = false,
|
||||||
|
bool implied = false)
|
||||||
: ASTGEN_SUPER(fl)
|
: ASTGEN_SUPER(fl)
|
||||||
, m_name(name) {
|
, m_name(name) {
|
||||||
addNOp1p(stmtsp);
|
addNOp1p(stmtsp);
|
||||||
m_unnamed = (name=="");
|
m_unnamed = (name == "");
|
||||||
m_generate = generate;
|
m_generate = generate;
|
||||||
|
m_implied = implied;
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(Begin)
|
ASTNODE_NODE_FUNCS(Begin)
|
||||||
virtual void dump(std::ostream& str) const;
|
virtual void dump(std::ostream& str) const;
|
||||||
@ -3760,6 +3763,7 @@ public:
|
|||||||
bool unnamed() const { return m_unnamed; }
|
bool unnamed() const { return m_unnamed; }
|
||||||
void generate(bool flag) { m_generate = flag; }
|
void generate(bool flag) { m_generate = flag; }
|
||||||
bool generate() const { return m_generate; }
|
bool generate() const { return m_generate; }
|
||||||
|
bool implied() const { return m_implied; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class AstInitial : public AstNode {
|
class AstInitial : public AstNode {
|
||||||
|
@ -125,7 +125,7 @@ private:
|
|||||||
while ((pos=dottedname.find("__DOT__")) != string::npos) {
|
while ((pos=dottedname.find("__DOT__")) != string::npos) {
|
||||||
string ident = dottedname.substr(0, pos);
|
string ident = dottedname.substr(0, pos);
|
||||||
dottedname = dottedname.substr(pos+strlen("__DOT__"));
|
dottedname = dottedname.substr(pos+strlen("__DOT__"));
|
||||||
if (!nodep->unnamed()) {
|
if (nodep->name() != "") {
|
||||||
if (m_namedScope=="") m_namedScope = ident;
|
if (m_namedScope=="") m_namedScope = ident;
|
||||||
else m_namedScope = m_namedScope + "__DOT__"+ident;
|
else m_namedScope = m_namedScope + "__DOT__"+ident;
|
||||||
}
|
}
|
||||||
|
@ -914,20 +914,24 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int oldNum = m_beginNum;
|
if (nodep->name() == "") {
|
||||||
AstBegin* oldbegin = m_beginp;
|
|
||||||
VSymEnt* oldCurSymp = m_curSymp;
|
|
||||||
{
|
|
||||||
m_beginNum = 0;
|
|
||||||
m_beginp = nodep;
|
|
||||||
m_curSymp = m_statep->insertBlock(m_curSymp, nodep->name(), nodep, m_packagep);
|
|
||||||
m_curSymp->fallbackp(oldCurSymp);
|
|
||||||
// Iterate
|
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
|
} else {
|
||||||
|
int oldNum = m_beginNum;
|
||||||
|
AstBegin* oldbegin = m_beginp;
|
||||||
|
VSymEnt* oldCurSymp = m_curSymp;
|
||||||
|
{
|
||||||
|
m_beginNum = 0;
|
||||||
|
m_beginp = nodep;
|
||||||
|
m_curSymp = m_statep->insertBlock(m_curSymp, nodep->name(), nodep, m_packagep);
|
||||||
|
m_curSymp->fallbackp(oldCurSymp);
|
||||||
|
// Iterate
|
||||||
|
iterateChildren(nodep);
|
||||||
|
}
|
||||||
|
m_curSymp = oldCurSymp;
|
||||||
|
m_beginp = oldbegin;
|
||||||
|
m_beginNum = oldNum;
|
||||||
}
|
}
|
||||||
m_curSymp = oldCurSymp;
|
|
||||||
m_beginp = oldbegin;
|
|
||||||
m_beginNum = oldNum;
|
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeFTask* nodep) VL_OVERRIDE {
|
virtual void visit(AstNodeFTask* nodep) VL_OVERRIDE {
|
||||||
// NodeTask: Remember its name for later resolution
|
// NodeTask: Remember its name for later resolution
|
||||||
@ -2449,8 +2453,10 @@ private:
|
|||||||
checkNoDot(nodep);
|
checkNoDot(nodep);
|
||||||
VSymEnt* oldCurSymp = m_curSymp;
|
VSymEnt* oldCurSymp = m_curSymp;
|
||||||
{
|
{
|
||||||
m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep);
|
if (nodep->name() != "") {
|
||||||
UINFO(5," cur=se"<<cvtToHex(m_curSymp)<<endl);
|
m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep);
|
||||||
|
UINFO(5," cur=se"<<cvtToHex(m_curSymp)<<endl);
|
||||||
|
}
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
}
|
}
|
||||||
m_ds.m_dotSymp = m_curSymp = oldCurSymp;
|
m_ds.m_dotSymp = m_curSymp = oldCurSymp;
|
||||||
|
@ -435,7 +435,7 @@ private:
|
|||||||
new AstConst(fl, 1),
|
new AstConst(fl, 1),
|
||||||
new AstConst(fl, -1))));
|
new AstConst(fl, -1))));
|
||||||
stmtsp->addNext(new AstWhile(fl, condp, newp, incp));
|
stmtsp->addNext(new AstWhile(fl, condp, newp, incp));
|
||||||
newp = new AstBegin(nodep->fileline(), "", stmtsp);
|
newp = new AstBegin(nodep->fileline(), "", stmtsp, false, true);
|
||||||
dimension--;
|
dimension--;
|
||||||
}
|
}
|
||||||
//newp->dumpTree(cout, "-foreach-new:");
|
//newp->dumpTree(cout, "-foreach-new:");
|
||||||
@ -488,6 +488,21 @@ private:
|
|||||||
virtual void visit(AstBegin* nodep) VL_OVERRIDE {
|
virtual void visit(AstBegin* nodep) VL_OVERRIDE {
|
||||||
V3Config::applyCoverageBlock(m_modp, nodep);
|
V3Config::applyCoverageBlock(m_modp, nodep);
|
||||||
cleanFileline(nodep);
|
cleanFileline(nodep);
|
||||||
|
AstNode* backp = nodep->backp();
|
||||||
|
// IEEE says directly nested item is not a new block
|
||||||
|
bool nestedIf = (nodep->implied() // User didn't provide begin/end
|
||||||
|
&& (VN_IS(nodep->stmtsp(), GenIf)
|
||||||
|
|| VN_IS(nodep->stmtsp(), GenCase)) // Has an if/case
|
||||||
|
&& !nodep->stmtsp()->nextp()); // Has only one item
|
||||||
|
// It's not FOR(BEGIN(...)) but we earlier changed it to BEGIN(FOR(...))
|
||||||
|
if (nodep->genforp() && nodep->name() == "") {
|
||||||
|
nodep->name("genblk");
|
||||||
|
}
|
||||||
|
else if (nodep->generate() && nodep->name() == ""
|
||||||
|
&& (VN_IS(backp, CaseItem) || VN_IS(backp, GenIf))
|
||||||
|
&& !nestedIf) {
|
||||||
|
nodep->name("genblk");
|
||||||
|
}
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
}
|
}
|
||||||
virtual void visit(AstCase* nodep) VL_OVERRIDE {
|
virtual void visit(AstCase* nodep) VL_OVERRIDE {
|
||||||
|
@ -2047,18 +2047,18 @@ generate_block_or_null<nodep>: // IEEE: generate_block_or_null (called from genc
|
|||||||
// ';' // is included in
|
// ';' // is included in
|
||||||
// // IEEE: generate_block
|
// // IEEE: generate_block
|
||||||
// // Must always return a BEGIN node, or NULL - see GenFor construction
|
// // Must always return a BEGIN node, or NULL - see GenFor construction
|
||||||
generate_item { $$ = $1 ? (new AstBegin($1->fileline(),"genblk",$1,true)) : NULL; }
|
generate_item { $$ = $1 ? (new AstBegin($1->fileline(),"",$1,true,true)) : NULL; }
|
||||||
| genItemBegin { $$ = $1; }
|
| genItemBegin { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
genItemBegin<nodep>: // IEEE: part of generate_block
|
genItemBegin<nodep>: // IEEE: part of generate_block
|
||||||
yBEGIN ~c~genItemList yEND { $$ = new AstBegin($1,"genblk",$2,true); }
|
yBEGIN ~c~genItemList yEND { $$ = new AstBegin($1,"",$2,true,false); }
|
||||||
| yBEGIN yEND { $$ = NULL; }
|
| yBEGIN yEND { $$ = NULL; }
|
||||||
| id ':' yBEGIN ~c~genItemList yEND endLabelE
|
| id ':' yBEGIN ~c~genItemList yEND endLabelE
|
||||||
{ $$ = new AstBegin($<fl>1,*$1,$4,true); GRAMMARP->endLabel($<fl>6,*$1,$6); }
|
{ $$ = new AstBegin($<fl>1,*$1,$4,true,false); GRAMMARP->endLabel($<fl>6,*$1,$6); }
|
||||||
| id ':' yBEGIN yEND endLabelE { $$ = NULL; GRAMMARP->endLabel($<fl>5,*$1,$5); }
|
| id ':' yBEGIN yEND endLabelE { $$ = NULL; GRAMMARP->endLabel($<fl>5,*$1,$5); }
|
||||||
| yBEGIN ':' idAny ~c~genItemList yEND endLabelE
|
| yBEGIN ':' idAny ~c~genItemList yEND endLabelE
|
||||||
{ $$ = new AstBegin($<fl>3,*$3,$4,true); GRAMMARP->endLabel($<fl>6,*$3,$6); }
|
{ $$ = new AstBegin($<fl>3,*$3,$4,true,false); GRAMMARP->endLabel($<fl>6,*$3,$6); }
|
||||||
| yBEGIN ':' idAny yEND endLabelE { $$ = NULL; GRAMMARP->endLabel($<fl>5,*$3,$5); }
|
| yBEGIN ':' idAny yEND endLabelE { $$ = NULL; GRAMMARP->endLabel($<fl>5,*$3,$5); }
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -2116,11 +2116,11 @@ loop_generate_construct<nodep>: // ==IEEE: loop_generate_construct
|
|||||||
{ // Convert BEGIN(...) to BEGIN(GENFOR(...)), as we need the BEGIN to hide the local genvar
|
{ // Convert BEGIN(...) to BEGIN(GENFOR(...)), as we need the BEGIN to hide the local genvar
|
||||||
AstBegin* lowerBegp = VN_CAST($9, Begin);
|
AstBegin* lowerBegp = VN_CAST($9, Begin);
|
||||||
UASSERT_OBJ(!($9 && !lowerBegp), $9, "Child of GENFOR should have been begin");
|
UASSERT_OBJ(!($9 && !lowerBegp), $9, "Child of GENFOR should have been begin");
|
||||||
if (!lowerBegp) lowerBegp = new AstBegin($1,"genblk",NULL,true); // Empty body
|
if (!lowerBegp) lowerBegp = new AstBegin($1, "genblk", NULL, true, true); // Empty body
|
||||||
AstNode* lowerNoBegp = lowerBegp->stmtsp();
|
AstNode* lowerNoBegp = lowerBegp->stmtsp();
|
||||||
if (lowerNoBegp) lowerNoBegp->unlinkFrBackWithNext();
|
if (lowerNoBegp) lowerNoBegp->unlinkFrBackWithNext();
|
||||||
//
|
//
|
||||||
AstBegin* blkp = new AstBegin($1,lowerBegp->name(),NULL,true);
|
AstBegin* blkp = new AstBegin($1, lowerBegp->name(), NULL, true, true);
|
||||||
// V3LinkDot detects BEGIN(GENFOR(...)) as a special case
|
// V3LinkDot detects BEGIN(GENFOR(...)) as a special case
|
||||||
AstNode* initp = $3; AstNode* varp = $3;
|
AstNode* initp = $3; AstNode* varp = $3;
|
||||||
if (VN_IS(varp, Var)) { // Genvar
|
if (VN_IS(varp, Var)) { // Genvar
|
||||||
@ -2793,10 +2793,10 @@ statement_item<nodep>: // IEEE: statement_item
|
|||||||
|
|
||||||
statementFor<beginp>: // IEEE: part of statement
|
statementFor<beginp>: // IEEE: part of statement
|
||||||
yFOR '(' for_initialization expr ';' for_stepE ')' stmtBlock
|
yFOR '(' for_initialization expr ';' for_stepE ')' stmtBlock
|
||||||
{ $$ = new AstBegin($1,"",$3);
|
{ $$ = new AstBegin($1, "", $3, false, true);
|
||||||
$$->addStmtsp(new AstWhile($1, $4,$8,$6)); }
|
$$->addStmtsp(new AstWhile($1, $4,$8,$6)); }
|
||||||
| yFOR '(' for_initialization ';' for_stepE ')' stmtBlock
|
| yFOR '(' for_initialization ';' for_stepE ')' stmtBlock
|
||||||
{ $$ = new AstBegin($1,"",$3);
|
{ $$ = new AstBegin($1, "", $3, false, true);
|
||||||
$$->addStmtsp(new AstWhile($1, new AstConst($1,AstConst::LogicTrue()),$7,$5)); }
|
$$->addStmtsp(new AstWhile($1, new AstConst($1,AstConst::LogicTrue()),$7,$5)); }
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -4473,7 +4473,7 @@ assertion_item<nodep>: // ==IEEE: assertion_item
|
|||||||
deferred_immediate_assertion_item<nodep>: // ==IEEE: deferred_immediate_assertion_item
|
deferred_immediate_assertion_item<nodep>: // ==IEEE: deferred_immediate_assertion_item
|
||||||
deferred_immediate_assertion_statement { $$ = $1; }
|
deferred_immediate_assertion_statement { $$ = $1; }
|
||||||
| id/*block_identifier*/ ':' deferred_immediate_assertion_statement
|
| id/*block_identifier*/ ':' deferred_immediate_assertion_statement
|
||||||
{ $$ = new AstBegin($<fl>1, *$1, $3); }
|
{ $$ = new AstBegin($<fl>1, *$1, $3, false, true); }
|
||||||
;
|
;
|
||||||
|
|
||||||
procedural_assertion_statement<nodep>: // ==IEEE: procedural_assertion_statement
|
procedural_assertion_statement<nodep>: // ==IEEE: procedural_assertion_statement
|
||||||
@ -4528,7 +4528,8 @@ deferred_immediate_assertion_statement<nodep>: // ==IEEE: deferred_immediate_ass
|
|||||||
|
|
||||||
concurrent_assertion_item<nodep>: // IEEE: concurrent_assertion_item
|
concurrent_assertion_item<nodep>: // IEEE: concurrent_assertion_item
|
||||||
concurrent_assertion_statement { $$ = $1; }
|
concurrent_assertion_statement { $$ = $1; }
|
||||||
| id/*block_identifier*/ ':' concurrent_assertion_statement { $$ = new AstBegin($<fl>1, *$1, $3); }
|
| id/*block_identifier*/ ':' concurrent_assertion_statement
|
||||||
|
{ $$ = new AstBegin($<fl>1, *$1, $3, false, true); }
|
||||||
// // IEEE: checker_instantiation
|
// // IEEE: checker_instantiation
|
||||||
// // identical to module_instantiation; see etcInst
|
// // identical to module_instantiation; see etcInst
|
||||||
;
|
;
|
||||||
|
6
test_regress/t/t_gen_genblk.out
Normal file
6
test_regress/t/t_gen_genblk.out
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
010: exp=top.t.show0 got=top.t.show0
|
||||||
|
014: exp=top.t.genblk1.show1 got=top.t.genblk1.show1
|
||||||
|
018: exp=top.t.genblk2.show2 got=top.t.genblk2.show2
|
||||||
|
023: exp=top.t.genblk3.genblk1.show3 got=top.t.genblk3.genblk1.show3
|
||||||
|
029: exp=top.t.x1.x3.show4 got=top.t.x1.x3.show4
|
||||||
|
*-* All Finished *-*
|
20
test_regress/t/t_gen_genblk.pl
Executable file
20
test_regress/t/t_gen_genblk.pl
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
|
compile(
|
||||||
|
);
|
||||||
|
|
||||||
|
execute(
|
||||||
|
expect_filename => $Self->{golden_filename},
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
51
test_regress/t/t_gen_genblk.v
Normal file
51
test_regress/t/t_gen_genblk.v
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
module t (/*AUTOARG*/
|
||||||
|
// Inputs
|
||||||
|
clk, reset_l
|
||||||
|
);
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input reset_l;
|
||||||
|
|
||||||
|
generate
|
||||||
|
show #(`__LINE__, "top.t.show0") show0();
|
||||||
|
|
||||||
|
if (0) ;
|
||||||
|
else if (0) ;
|
||||||
|
else if (1) show #(`__LINE__, "top.t.genblk1.show1") show1();
|
||||||
|
|
||||||
|
if (0) begin end
|
||||||
|
else if (0) begin end
|
||||||
|
else if (1) begin show #(`__LINE__, "top.t.genblk2.show2") show2(); end
|
||||||
|
|
||||||
|
if (0) ;
|
||||||
|
else begin
|
||||||
|
if (0) begin end
|
||||||
|
else if (1) begin show #(`__LINE__, "top.t.genblk3.genblk1.show3") show3(); end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (0) ;
|
||||||
|
else begin : x1
|
||||||
|
if (0) begin : x2 end
|
||||||
|
else if (1) begin : x3 show #(`__LINE__, "top.t.x1.x3.show4") show4(); end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
int cyc;
|
||||||
|
|
||||||
|
always @ (posedge clk) begin
|
||||||
|
cyc <= cyc + 1;
|
||||||
|
if (cyc == 99) begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module show #(parameter LINE=0, parameter string EXPT) ();
|
||||||
|
always @ (posedge t.clk) begin
|
||||||
|
if (t.cyc == LINE) begin
|
||||||
|
$display("%03d: exp=%s got=%m", LINE, EXPT);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
23
test_regress/t/t_gen_genblk_noinl.pl
Executable file
23
test_regress/t/t_gen_genblk_noinl.pl
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
top_filename("t_gen_genblk.v");
|
||||||
|
|
||||||
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
|
compile(
|
||||||
|
v_flags2 => ["-Oi"],
|
||||||
|
);
|
||||||
|
|
||||||
|
execute(
|
||||||
|
expect_filename => "t/t_gen_genblk.out",
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
@ -24,7 +24,7 @@ module t();
|
|||||||
|
|
||||||
generate
|
generate
|
||||||
genvar the_genvar;
|
genvar the_genvar;
|
||||||
begin
|
begin : ia
|
||||||
for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf
|
for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf
|
||||||
begin
|
begin
|
||||||
assign my_intf[the_genvar].val = '1;
|
assign my_intf[the_genvar].val = '1;
|
||||||
@ -36,7 +36,7 @@ module t();
|
|||||||
|
|
||||||
generate
|
generate
|
||||||
genvar the_second_genvar;
|
genvar the_second_genvar;
|
||||||
begin
|
begin : ib
|
||||||
intf #(.PARAM(1)) my_intf [1:0] ();
|
intf #(.PARAM(1)) my_intf [1:0] ();
|
||||||
for (the_second_genvar = 0; the_second_genvar < 2; the_second_genvar++) begin : TestIf
|
for (the_second_genvar = 0; the_second_genvar < 2; the_second_genvar++) begin : TestIf
|
||||||
begin
|
begin
|
||||||
@ -49,7 +49,7 @@ module t();
|
|||||||
|
|
||||||
generate
|
generate
|
||||||
genvar the_third_genvar;
|
genvar the_third_genvar;
|
||||||
begin
|
begin : ic
|
||||||
for (the_third_genvar = 0; the_third_genvar < 2; the_third_genvar++) begin : TestIf
|
for (the_third_genvar = 0; the_third_genvar < 2; the_third_genvar++) begin : TestIf
|
||||||
begin
|
begin
|
||||||
intf #(.PARAM(1)) my_intf [1:0] ();
|
intf #(.PARAM(1)) my_intf [1:0] ();
|
||||||
|
131
test_regress/t/t_var_dotted2.v
Normal file
131
test_regress/t/t_var_dotted2.v
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty 2020 by Wilson Snyder.
|
||||||
|
|
||||||
|
`ifdef USE_INLINE
|
||||||
|
`define INLINE_MODULE /*verilator inline_module*/
|
||||||
|
`else
|
||||||
|
`define INLINE_MODULE /*verilator public_module*/
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module t (/*AUTOARG*/);
|
||||||
|
|
||||||
|
`define DRAM1(bank) mem.mem_bank[bank].dccm.dccm_bank.ram_core
|
||||||
|
`define DRAM2(bank) mem.mem_bank2[bank].dccm.dccm_bank.ram_core
|
||||||
|
`define DRAM3(bank) mem.mem_bank3[bank].dccm.dccm_bank.ram_core
|
||||||
|
`define DRAM4(bank) mem.sub4.mem_bank4[bank].dccm.dccm_bank.ram_core
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
`DRAM1(0)[3] = 130;
|
||||||
|
`DRAM1(1)[3] = 131;
|
||||||
|
`DRAM2(0)[3] = 230;
|
||||||
|
`DRAM2(1)[3] = 231;
|
||||||
|
`DRAM3(0)[3] = 330;
|
||||||
|
`DRAM3(1)[3] = 331;
|
||||||
|
`DRAM4(0)[3] = 430;
|
||||||
|
`DRAM4(1)[3] = 431;
|
||||||
|
if (`DRAM1(0)[3] !== 130) $stop;
|
||||||
|
if (`DRAM1(1)[3] !== 131) $stop;
|
||||||
|
if (`DRAM2(0)[3] !== 230) $stop;
|
||||||
|
if (`DRAM2(1)[3] !== 231) $stop;
|
||||||
|
if (`DRAM3(0)[3] !== 330) $stop;
|
||||||
|
if (`DRAM3(1)[3] !== 331) $stop;
|
||||||
|
if (`DRAM4(0)[3] !== 430) $stop;
|
||||||
|
if (`DRAM4(1)[3] !== 431) $stop;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
eh2_lsu_dccm_mem mem (/*AUTOINST*/);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module eh2_lsu_dccm_mem
|
||||||
|
#(
|
||||||
|
DCCM_INDEX_DEPTH = 8192,
|
||||||
|
DCCM_NUM_BANKS = 2
|
||||||
|
)(
|
||||||
|
);
|
||||||
|
`INLINE_MODULE
|
||||||
|
|
||||||
|
// 8 Banks, 16KB each (2048 x 72)
|
||||||
|
for (genvar i=0; i<DCCM_NUM_BANKS; i++) begin: mem_bank
|
||||||
|
if (DCCM_INDEX_DEPTH == 16384) begin : dccm
|
||||||
|
eh2_ram
|
||||||
|
#(.depth(16384), .width(32))
|
||||||
|
dccm_bank (.*);
|
||||||
|
end
|
||||||
|
else if (DCCM_INDEX_DEPTH == 8192) begin : dccm
|
||||||
|
eh2_ram
|
||||||
|
#(.depth(8192), .width(32))
|
||||||
|
dccm_bank (.*);
|
||||||
|
end
|
||||||
|
else if (DCCM_INDEX_DEPTH == 4096) begin : dccm
|
||||||
|
eh2_ram
|
||||||
|
#(.depth(4096), .width(32))
|
||||||
|
dccm_bank (.*);
|
||||||
|
end
|
||||||
|
end : mem_bank
|
||||||
|
|
||||||
|
// Check that generate doesn't also add a genblk
|
||||||
|
generate
|
||||||
|
for (genvar i=0; i<DCCM_NUM_BANKS; i++) begin: mem_bank2
|
||||||
|
if (DCCM_INDEX_DEPTH == 8192) begin : dccm
|
||||||
|
eh2_ram
|
||||||
|
#(.depth(8192), .width(32))
|
||||||
|
dccm_bank (.*);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// Nor this
|
||||||
|
generate
|
||||||
|
begin
|
||||||
|
for (genvar i=0; i<DCCM_NUM_BANKS; i++) begin: mem_bank3
|
||||||
|
if (DCCM_INDEX_DEPTH == 8192) begin : dccm
|
||||||
|
eh2_ram
|
||||||
|
#(.depth(8192), .width(32))
|
||||||
|
dccm_bank (.*);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// This does
|
||||||
|
generate
|
||||||
|
begin : sub4
|
||||||
|
for (genvar i=0; i<DCCM_NUM_BANKS; i++) begin: mem_bank4
|
||||||
|
if (DCCM_INDEX_DEPTH == 8192) begin : dccm
|
||||||
|
eh2_ram
|
||||||
|
#(.depth(8192), .width(32))
|
||||||
|
dccm_bank (.*);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// This is an error (previously declared)
|
||||||
|
//generate
|
||||||
|
// begin
|
||||||
|
// eh2_ram
|
||||||
|
// #(.depth(8192), .width(32))
|
||||||
|
// dccm_bank (.*);
|
||||||
|
// end
|
||||||
|
// begin
|
||||||
|
// eh2_ram
|
||||||
|
// #(.depth(8192), .width(32))
|
||||||
|
// dccm_bank (.*);
|
||||||
|
// end
|
||||||
|
//endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module eh2_ram #(depth=4096, width=39)
|
||||||
|
();
|
||||||
|
|
||||||
|
`INLINE_MODULE
|
||||||
|
|
||||||
|
reg [(width-1):0] ram_core [(depth-1):0];
|
||||||
|
|
||||||
|
endmodule
|
23
test_regress/t/t_var_dotted2_inl0.pl
Executable file
23
test_regress/t/t_var_dotted2_inl0.pl
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
|
top_filename("t/t_var_dotted2.v");
|
||||||
|
|
||||||
|
compile(
|
||||||
|
v_flags2 => ['+define+NOUSE_INLINE',],
|
||||||
|
);
|
||||||
|
|
||||||
|
execute(
|
||||||
|
check_finished => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
23
test_regress/t/t_var_dotted2_inl1.pl
Executable file
23
test_regress/t/t_var_dotted2_inl1.pl
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
|
top_filename("t/t_var_dotted2.v");
|
||||||
|
|
||||||
|
compile(
|
||||||
|
v_flags2 => ['+define+USE_INLINE',],
|
||||||
|
);
|
||||||
|
|
||||||
|
execute(
|
||||||
|
check_finished => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
7
test_regress/t/t_var_dotted_dup_bad.out
Normal file
7
test_regress/t/t_var_dotted_dup_bad.out
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
%Error: t/t_var_dotted_dup_bad.v:13: Duplicate declaration of cell: 'dccm_bank'
|
||||||
|
eh2_ram dccm_bank (.*);
|
||||||
|
^~~~~~~~~
|
||||||
|
t/t_var_dotted_dup_bad.v:10: ... Location of original declaration
|
||||||
|
eh2_ram dccm_bank (.*);
|
||||||
|
^~~~~~~~~
|
||||||
|
%Error: Exiting due to
|
18
test_regress/t/t_var_dotted_dup_bad.pl
Executable file
18
test_regress/t/t_var_dotted_dup_bad.pl
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2005 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
scenarios(vlt => 1);
|
||||||
|
|
||||||
|
lint(
|
||||||
|
fails => 1,
|
||||||
|
expect_filename => $Self->{golden_filename},
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
20
test_regress/t/t_var_dotted_dup_bad.v
Normal file
20
test_regress/t/t_var_dotted_dup_bad.v
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty 2020 by Wilson Snyder.
|
||||||
|
|
||||||
|
module t (/*AUTOARG*/);
|
||||||
|
|
||||||
|
generate
|
||||||
|
begin
|
||||||
|
eh2_ram dccm_bank (.*);
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
eh2_ram dccm_bank (.*); // Error: duplicate
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module eh2_ram ();
|
||||||
|
endmodule
|
@ -1,9 +1,9 @@
|
|||||||
ingen: {mod}.genblk1 top.t.genblk1
|
ingen: {mod}.genblk1 top.t.genblk1
|
||||||
d3a: {mod}.d3nameda top.t.d3nameda
|
d3a: {mod}.d3nameda top.t.unnamedblk1.d3nameda
|
||||||
b2: {mod} top.t
|
b2: {mod} top.t.unnamedblk2
|
||||||
b3n: {mod}.b3named: top.t.b3named
|
b3n: {mod}.b3named: top.t.unnamedblk2.b3named
|
||||||
b3: {mod} top.t
|
b3: {mod} top.t.unnamedblk2.unnamedblk3
|
||||||
b4: {mod} top.t
|
b4: {mod} top.t.unnamedblk2.unnamedblk3.unnamedblk4
|
||||||
t1 {mod}.tsk top.t
|
t1 {mod}.tsk top.t
|
||||||
t2 {mod}.tsk top.t
|
t2 {mod}.tsk top.t.unnamedblk7
|
||||||
*-* All Finished *-*
|
*-* All Finished *-*
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
: ... Suggested alternative: 'notfuncs'
|
: ... Suggested alternative: 'notfuncs'
|
||||||
i = sub.nofuncs();
|
i = sub.nofuncs();
|
||||||
^~~~~~~
|
^~~~~~~
|
||||||
... Known scopes under 'nofuncs': <no cells found>
|
... Known scopes under 'nofuncs': sub
|
||||||
%Error: t/t_var_notfound_bad.v:21: Can't find definition of task/function: 'notask'
|
%Error: t/t_var_notfound_bad.v:21: Can't find definition of task/function: 'notask'
|
||||||
: ... Suggested alternative: 'nottask'
|
: ... Suggested alternative: 'nottask'
|
||||||
notask();
|
notask();
|
||||||
|
Loading…
Reference in New Issue
Block a user