forked from github/verilator
Fix foreach on dotted reference.
This commit is contained in:
parent
0a94ea5386
commit
f775feb7f0
@ -1726,6 +1726,7 @@ public:
|
||||
virtual bool same(const AstNode* samep) const override { return true; }
|
||||
virtual bool maybePointedTo() const override { return false; }
|
||||
AstNode* fromp() const { return op1p(); }
|
||||
void fromp(AstNode* nodep) { setOp1p(nodep); }
|
||||
AstNode* elementsp() const { return op2p(); }
|
||||
};
|
||||
|
||||
@ -3137,6 +3138,7 @@ public:
|
||||
}
|
||||
virtual void dump(std::ostream& str) const override;
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
void rhsp(AstNode* nodep) { setOp2p(nodep); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
bool colon() const { return m_colon; }
|
||||
};
|
||||
|
@ -1280,16 +1280,25 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
||||
m_curSymp = m_statep->insertBlock(m_curSymp, "__Vforeach" + cvtToStr(m_modWithNum),
|
||||
nodep, m_classOrPackagep);
|
||||
m_curSymp->fallbackp(oldCurSymp);
|
||||
|
||||
// DOT(x, SELLOOPVARS(var, loops)) -> SELLOOPVARS(DOT(x, var), loops)
|
||||
if (AstDot* const dotp = VN_CAST(nodep->arrayp(), Dot)) {
|
||||
if (AstSelLoopVars* const loopvarsp = VN_CAST(dotp->rhsp(), SelLoopVars)) {
|
||||
AstNode* const fromp = loopvarsp->fromp()->unlinkFrBack();
|
||||
loopvarsp->unlinkFrBack();
|
||||
dotp->replaceWith(loopvarsp);
|
||||
dotp->rhsp(fromp);
|
||||
loopvarsp->fromp(dotp);
|
||||
}
|
||||
}
|
||||
const auto loopvarsp = VN_CAST(nodep->arrayp(), SelLoopVars);
|
||||
if (!loopvarsp) {
|
||||
AstNode* const warnp = nodep->arrayp() ? nodep->arrayp() : nodep;
|
||||
warnp->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported (or syntax error): Foreach on this array's construct");
|
||||
nodep->dumpTree(cout, "-FIXME-us ");
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
}
|
||||
|
||||
for (AstNode *nextp, *argp = loopvarsp->elementsp(); argp; argp = nextp) {
|
||||
nextp = argp->nextp();
|
||||
AstVar* argrefp = nullptr;
|
||||
@ -1310,6 +1319,7 @@ class LinkDotFindVisitor final : public AstNVisitor {
|
||||
argp->v3error("'foreach' loop variable expects simple variable name");
|
||||
}
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -444,6 +444,7 @@ private:
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
|
@ -1,8 +1,4 @@
|
||||
%Error: t/t_foreach_bad.v:14:7: Syntax error; foreach missing bracketed loop variable (IEEE 1800-2017 12.7.3)
|
||||
14 | foreach (array);
|
||||
| ^~~~~~~
|
||||
%Error-UNSUPPORTED: t/t_foreach_bad.v:16:21: Unsupported (or syntax error): Foreach on this array's construct
|
||||
16 | foreach (array.array[a]);
|
||||
| ^
|
||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||
%Error: Exiting due to
|
||||
|
21
test_regress/t/t_foreach_class.pl
Executable file
21
test_regress/t/t_foreach_class.pl
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
46
test_regress/t/t_foreach_class.v
Normal file
46
test_regress/t/t_foreach_class.v
Normal file
@ -0,0 +1,46 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2016 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
|
||||
|
||||
class Cls;
|
||||
int q[$];
|
||||
function new();
|
||||
q.push_back(1);
|
||||
q.push_back(2);
|
||||
q.push_back(3);
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
|
||||
int two[5:6];
|
||||
|
||||
if (1) begin : named
|
||||
Cls c;
|
||||
end
|
||||
|
||||
function [63:0] crc(input [63:0] sum, input [31:0] a, input [31:0] b, input [31:0] c, input [31:0] d);
|
||||
crc = {sum[62:0],sum[63]} ^ {20'b0,a[7:0], 4'h0,b[7:0], 4'h0,c[7:0], 4'h0,d[7:0]};
|
||||
endfunction
|
||||
|
||||
bit [63:0] sum;
|
||||
|
||||
initial begin
|
||||
named.c = new;
|
||||
sum = 0;
|
||||
foreach (named.c.q[i]) begin
|
||||
foreach (two[j]) begin
|
||||
// $display(i, j);
|
||||
sum = crc(sum, i, named.c.q[i], j, 0);
|
||||
end
|
||||
end
|
||||
`checkh(sum, 64'h000000a02d0fc000);
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user