Fix genvar check to be more strict about generate-for usage only
This commit is contained in:
parent
309129ebcf
commit
f106c1eaec
|
|
@ -52,7 +52,7 @@ class LinkResolveVisitor final : public VNVisitor {
|
|||
AstNodeFTask* m_ftaskp = nullptr; // Function or task we're inside
|
||||
AstNodeCoverOrAssert* m_assertp = nullptr; // Current assertion
|
||||
int m_senitemCvtNum = 0; // Temporary signal counter
|
||||
bool m_underGenFor = false; // Under GenFor
|
||||
std::deque<AstGenFor*> m_underGenFors; // Stack of GenFor underneath
|
||||
bool m_underGenerate = false; // Under GenFor/GenIf
|
||||
|
||||
// VISITORS
|
||||
|
|
@ -139,9 +139,16 @@ class LinkResolveVisitor final : public VNVisitor {
|
|||
if (nodep->varp()) { // Else due to dead code, might not have var pointer
|
||||
// VarRef: Resolve its reference
|
||||
nodep->varp()->usedParam(true);
|
||||
// TODO should look for where genvar is valid, but for now catch
|
||||
// just gross errors of using genvar outside any generate
|
||||
if (nodep->varp()->isGenVar() && !m_underGenFor) {
|
||||
// Look for where genvar is valid
|
||||
bool ok = false;
|
||||
for (AstGenFor* forp : m_underGenFors) {
|
||||
if (ok) break;
|
||||
if (forp->initsp())
|
||||
forp->initsp()->foreach([&](AstVarRef* refp) { //
|
||||
if (refp->varp() == nodep->varp()) ok = true;
|
||||
});
|
||||
}
|
||||
if (nodep->varp()->isGenVar() && !ok) {
|
||||
nodep->v3error("Genvar "
|
||||
<< nodep->prettyNameQ()
|
||||
<< " used outside generate for loop (IEEE 1800-2023 27.4)");
|
||||
|
|
@ -503,11 +510,12 @@ class LinkResolveVisitor final : public VNVisitor {
|
|||
// We keep Modport's themselves around for XML dump purposes
|
||||
|
||||
void visit(AstGenFor* nodep) override {
|
||||
VL_RESTORER(m_underGenFor);
|
||||
VL_RESTORER(m_underGenerate);
|
||||
m_underGenFor = true;
|
||||
m_underGenerate = true;
|
||||
m_underGenFors.emplace_back(nodep);
|
||||
iterateChildren(nodep);
|
||||
UASSERT_OBJ(!m_underGenFors.empty(), nodep, "Underflow");
|
||||
m_underGenFors.pop_back();
|
||||
}
|
||||
void visit(AstGenIf* nodep) override {
|
||||
VL_RESTORER(m_underGenerate);
|
||||
|
|
|
|||
|
|
@ -124,10 +124,10 @@ class UnrollVisitor final : public VNVisitor {
|
|||
if (VN_IS(nodep, GenFor) && !m_forVarp->isGenVar()) {
|
||||
nodep->v3error("Non-genvar used in generate for: " << m_forVarp->prettyNameQ());
|
||||
} else if (!VN_IS(nodep, GenFor) && m_forVarp->isGenVar()) {
|
||||
nodep->v3error("Genvar not legal in non-generate for (IEEE 1800-2023 27.4): "
|
||||
<< m_forVarp->prettyNameQ() << '\n'
|
||||
<< nodep->warnMore()
|
||||
<< "... Suggest move for loop upwards to generate-level scope.");
|
||||
// Likely impossible as V3LinkResolve will earlier throw bad genvar use error
|
||||
nodep->v3error("Genvar not legal in non-generate for" // LCOV_EXCL_LINE
|
||||
" (IEEE 1800-2023 27.4): "
|
||||
<< m_forVarp->prettyNameQ());
|
||||
}
|
||||
if (m_generate) V3Const::constifyParamsEdit(initAssp->rhsp()); // rhsp may change
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,20 @@
|
|||
%Error: t/t_genvar_for_bad.v:25:13: Genvar not legal in non-generate for (IEEE 1800-2023 27.4): 't.i'
|
||||
: ... Suggest move for loop upwards to generate-level scope.
|
||||
25 | for (i=0; i<N; i=i+1) begin
|
||||
| ^~~
|
||||
%Error: t/t_genvar_for_bad.v:23:12: Genvar 'i' used outside generate for loop (IEEE 1800-2023 27.4)
|
||||
23 | for (i = 0; i < N; i = i + 1) begin
|
||||
| ^
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_genvar_for_bad.v:23:19: Genvar 'i' used outside generate for loop (IEEE 1800-2023 27.4)
|
||||
23 | for (i = 0; i < N; i = i + 1) begin
|
||||
| ^
|
||||
%Error: t/t_genvar_for_bad.v:24:21: Genvar 'i' used outside generate for loop (IEEE 1800-2023 27.4)
|
||||
24 | ov[i] <= iv[i];
|
||||
| ^
|
||||
%Error: t/t_genvar_for_bad.v:24:12: Genvar 'i' used outside generate for loop (IEEE 1800-2023 27.4)
|
||||
24 | ov[i] <= iv[i];
|
||||
| ^
|
||||
%Error: t/t_genvar_for_bad.v:23:30: Genvar 'i' used outside generate for loop (IEEE 1800-2023 27.4)
|
||||
23 | for (i = 0; i < N; i = i + 1) begin
|
||||
| ^
|
||||
%Error: t/t_genvar_for_bad.v:23:26: Genvar 'i' used outside generate for loop (IEEE 1800-2023 27.4)
|
||||
23 | for (i = 0; i < N; i = i + 1) begin
|
||||
| ^
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -4,28 +4,25 @@
|
|||
// any use, without warranty, 2020 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
ov,
|
||||
// Inputs
|
||||
clk, iv
|
||||
);
|
||||
module t ( /*AUTOARG*/
|
||||
// Outputs
|
||||
ov,
|
||||
// Inputs
|
||||
clk, iv
|
||||
);
|
||||
|
||||
parameter N = 4;
|
||||
parameter N = 4;
|
||||
|
||||
input clk;
|
||||
input [63:0] iv[N-1:0];
|
||||
output logic [63:0] ov[N-1:0];
|
||||
input clk;
|
||||
input [63:0] iv[N-1:0];
|
||||
output logic [63:0] ov[N-1:0];
|
||||
|
||||
genvar j; // Bypass first genvar check
|
||||
genvar i;
|
||||
generate
|
||||
for (j=0; j<1; j=j+1) begin
|
||||
always @(posedge clk) begin
|
||||
for (i=0; i<N; i=i+1) begin
|
||||
ov[i] <= iv[i];
|
||||
end
|
||||
end
|
||||
genvar i;
|
||||
generate
|
||||
always @(posedge clk) begin
|
||||
for (i = 0; i < N; i = i + 1) begin
|
||||
ov[i] <= iv[i];
|
||||
end
|
||||
endgenerate
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
%Error: t/t_genvar_misuse_bad.v:16:31: Genvar 'i' used outside generate for loop (IEEE 1800-2023 27.4)
|
||||
16 | assign q[i] = d[i];
|
||||
| ^
|
||||
%Error: t/t_genvar_misuse_bad.v:15:19: Genvar 'i' used outside generate for loop (IEEE 1800-2023 27.4)
|
||||
15 | assign q[i] = d[i];
|
||||
| ^
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_genvar_misuse_bad.v:16:24: Genvar 'i' used outside generate for loop (IEEE 1800-2023 27.4)
|
||||
16 | assign q[i] = d[i];
|
||||
| ^
|
||||
%Error: t/t_genvar_misuse_bad.v:15:12: Genvar 'i' used outside generate for loop (IEEE 1800-2023 27.4)
|
||||
15 | assign q[i] = d[i];
|
||||
| ^
|
||||
%Error: t/t_genvar_misuse_bad.v:22:11: Genvar 'c' used outside generate for loop (IEEE 1800-2023 27.4)
|
||||
22 | if (c);
|
||||
| ^
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -5,13 +5,22 @@
|
|||
// SPDX-License-Identifier: CC0-1.0
|
||||
// See bug408
|
||||
|
||||
module top
|
||||
(
|
||||
output logic [1:0] q,
|
||||
input logic [1:0] d,
|
||||
input logic clk
|
||||
);
|
||||
module top (
|
||||
output logic [1:0] q,
|
||||
input logic [1:0] d,
|
||||
input logic clk
|
||||
);
|
||||
|
||||
genvar i;
|
||||
assign q[i] = d[i]; // <--- Error: Misusing genvar i
|
||||
genvar a, b, c;
|
||||
for (a = 0; a < 2; ++a) begin
|
||||
if (a);
|
||||
for (b = 0; b < 2; ++b) begin
|
||||
if (a);
|
||||
if (b);
|
||||
if (c); // <--- Error: Misusing genvar c
|
||||
end
|
||||
end
|
||||
|
||||
genvar i;
|
||||
assign q[i] = d[i];
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue