Fix dotted generated array error, bug1005.
Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
parent
178028a70a
commit
f920b3945e
1
Changes
1
Changes
|
|
@ -27,6 +27,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||||
|
|
||||||
**** Fix array slicing of non-const indexes, bug1006. [Johan Bjork]
|
**** Fix array slicing of non-const indexes, bug1006. [Johan Bjork]
|
||||||
|
|
||||||
|
**** Fix dotted generated array error, bug1005. [Jeff Bush, Johan Bjork]
|
||||||
|
|
||||||
|
|
||||||
* Verilator 3.878 2015-11-01
|
* Verilator 3.878 2015-11-01
|
||||||
|
|
|
||||||
|
|
@ -1905,7 +1905,9 @@ private:
|
||||||
m_ds.m_dotp = NULL;
|
m_ds.m_dotp = NULL;
|
||||||
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
|
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
|
||||||
if (m_ds.m_unresolved && m_ds.m_unlinkedScope) {
|
if (m_ds.m_unresolved && m_ds.m_unlinkedScope) {
|
||||||
AstNode* newp = new AstUnlinkedRef(nodep->fileline(), nodep->cloneTree(false), nodep->name(), m_ds.m_unlinkedScope->unlinkFrBack());
|
AstNodeFTaskRef *newftaskp = nodep->cloneTree(false);
|
||||||
|
newftaskp->dotted(m_ds.m_dotText);
|
||||||
|
AstNode* newp = new AstUnlinkedRef(nodep->fileline(), newftaskp, nodep->name(), m_ds.m_unlinkedScope->unlinkFrBack());
|
||||||
m_ds.m_unlinkedScope = NULL;
|
m_ds.m_unlinkedScope = NULL;
|
||||||
m_ds.m_unresolved = false;
|
m_ds.m_unresolved = false;
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
|
|
|
||||||
|
|
@ -256,16 +256,22 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visit(AstUnlinkedRef* nodep, AstNUser*) {
|
virtual void visit(AstUnlinkedRef* nodep, AstNUser*) {
|
||||||
m_unlinkedTxt.clear();
|
|
||||||
nodep->cellrefp()->iterate(*this);
|
|
||||||
AstVarXRef* varxrefp = nodep->op1p()->castVarXRef();
|
AstVarXRef* varxrefp = nodep->op1p()->castVarXRef();
|
||||||
AstNodeFTaskRef* taskref = nodep->op1p()->castNodeFTaskRef();
|
AstNodeFTaskRef* taskrefp = nodep->op1p()->castNodeFTaskRef();
|
||||||
if (varxrefp) {
|
if (varxrefp) {
|
||||||
varxrefp->dotted(m_unlinkedTxt);
|
m_unlinkedTxt = varxrefp->dotted();
|
||||||
} else if (taskref) {
|
} else if (taskrefp) {
|
||||||
taskref->dotted(m_unlinkedTxt);
|
m_unlinkedTxt = taskrefp->dotted();
|
||||||
} else {
|
} else {
|
||||||
nodep->v3fatalSrc("Unexpected AstUnlinkedRef node");
|
nodep->v3fatalSrc("Unexpected AstUnlinkedRef node");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nodep->cellrefp()->iterate(*this);
|
||||||
|
|
||||||
|
if (varxrefp) {
|
||||||
|
varxrefp->dotted(m_unlinkedTxt);
|
||||||
|
} else {
|
||||||
|
taskrefp->dotted(m_unlinkedTxt);
|
||||||
}
|
}
|
||||||
nodep->replaceWith(nodep->op1p()->unlinkFrBack());
|
nodep->replaceWith(nodep->op1p()->unlinkFrBack());
|
||||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||||
|
|
@ -274,30 +280,18 @@ private:
|
||||||
V3Const::constifyParamsEdit(nodep->selp());
|
V3Const::constifyParamsEdit(nodep->selp());
|
||||||
if (AstConst* constp = nodep->selp()->castConst()) {
|
if (AstConst* constp = nodep->selp()->castConst()) {
|
||||||
string index = AstNode::encodeNumber(constp->toSInt());
|
string index = AstNode::encodeNumber(constp->toSInt());
|
||||||
m_unlinkedTxt += nodep->name() + "__BRA__"+index+"__KET__";
|
string replacestr = nodep->name() + "__BRA__??__KET__";
|
||||||
|
size_t pos = m_unlinkedTxt.find(replacestr);
|
||||||
|
if (pos == string::npos) {
|
||||||
|
nodep->v3error("Could not find array index in unlinked text: '" << m_unlinkedTxt << "' for node: " << nodep);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_unlinkedTxt.replace(pos, replacestr.length(), nodep->name() + "__BRA__"+index+"__KET__");
|
||||||
} else {
|
} else {
|
||||||
nodep->v3error("Could not expand constant selection inside dotted reference: "<<nodep->selp()->prettyName());
|
nodep->v3error("Could not expand constant selection inside dotted reference: "<<nodep->selp()->prettyName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void visit(AstCellRef* nodep, AstNUser*) {
|
|
||||||
// Children must be CellArrayRef, CellRef or ParseRef
|
|
||||||
if (nodep->cellp()->castCellArrayRef() || nodep->cellp()->castCellRef()) {
|
|
||||||
nodep->cellp()->iterate(*this);
|
|
||||||
} else if (nodep->cellp()->castParseRef()) {
|
|
||||||
m_unlinkedTxt += nodep->cellp()->name();
|
|
||||||
} else {
|
|
||||||
nodep->v3error("Could not elaborate dotted reference (LHS): "<<nodep->cellp()->prettyName());
|
|
||||||
}
|
|
||||||
m_unlinkedTxt += ".";
|
|
||||||
if (nodep->exprp()->castCellArrayRef() || nodep->exprp()->castCellRef()) {
|
|
||||||
nodep->exprp()->iterate(*this);
|
|
||||||
} else if (nodep->exprp()->castParseRef()) {
|
|
||||||
m_unlinkedTxt += nodep->exprp()->name();
|
|
||||||
} else {
|
|
||||||
nodep->v3error("Could not elaborate dotted reference (RHS): "<<nodep->exprp()->prettyName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate Statements
|
// Generate Statements
|
||||||
virtual void visit(AstGenerate* nodep, AstNUser*) {
|
virtual void visit(AstGenerate* nodep, AstNUser*) {
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ compile (
|
||||||
expect=>
|
expect=>
|
||||||
'%Error: t/t_interface_array_bad.v:\d+: Expecting expression to be constant, but variable isn\'t const: bar
|
'%Error: t/t_interface_array_bad.v:\d+: Expecting expression to be constant, but variable isn\'t const: bar
|
||||||
%Error: t/t_interface_array_bad.v:\d+: Could not expand constant selection inside dotted reference: bar
|
%Error: t/t_interface_array_bad.v:\d+: Could not expand constant selection inside dotted reference: bar
|
||||||
%Error: t/t_interface_array_bad.v:\d+: Can\'t find definition of \'a\' in dotted signal: .a
|
|
||||||
%Error: Known scopes under \'a\':.*
|
|
||||||
%Error: Exiting due to.*',
|
%Error: Exiting due to.*',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 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.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty.
|
||||||
|
|
||||||
|
// bug1005
|
||||||
|
|
||||||
|
module foo_module;
|
||||||
|
generate
|
||||||
|
for (genvar i = 0; i < 2; i = i + 1) begin : my_gen_block
|
||||||
|
logic baz;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module bar_module;
|
||||||
|
foo_module foo();
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t;
|
||||||
|
bar_module bar();
|
||||||
|
initial begin
|
||||||
|
bar.foo.my_gen_block[0].baz = 1;
|
||||||
|
if (bar.foo.my_gen_block[0].baz) begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue