Merge 2994d2cd70 into 3afb7e1a21
This commit is contained in:
commit
a2c85da54e
|
|
@ -932,7 +932,6 @@ class ConstVisitor final : public VNVisitor {
|
||||||
bool m_hasLoopTest = false; // Contains AstLoopTest
|
bool m_hasLoopTest = false; // Contains AstLoopTest
|
||||||
bool m_underRecFunc = false; // Under a recursive function
|
bool m_underRecFunc = false; // Under a recursive function
|
||||||
AstNodeModule* m_modp = nullptr; // Current module
|
AstNodeModule* m_modp = nullptr; // Current module
|
||||||
const AstArraySel* m_selp = nullptr; // Current select
|
|
||||||
const AstScope* m_scopep = nullptr; // Current scope
|
const AstScope* m_scopep = nullptr; // Current scope
|
||||||
const AstAttrOf* m_attrp = nullptr; // Current attribute
|
const AstAttrOf* m_attrp = nullptr; // Current attribute
|
||||||
VDouble0 m_statBitOpReduction; // Ops reduced in ConstBitOpTreeVisitor
|
VDouble0 m_statBitOpReduction; // Ops reduced in ConstBitOpTreeVisitor
|
||||||
|
|
@ -3284,34 +3283,12 @@ class ConstVisitor final : public VNVisitor {
|
||||||
|
|
||||||
void visit(AstArraySel* nodep) override {
|
void visit(AstArraySel* nodep) override {
|
||||||
iterateAndNextNull(nodep->bitp());
|
iterateAndNextNull(nodep->bitp());
|
||||||
if (VN_IS(nodep->bitp(), Const)
|
|
||||||
&& VN_IS(nodep->fromp(), VarRef)
|
|
||||||
// Need to make sure it's an array object so don't mis-allow a constant (bug509.)
|
|
||||||
&& VN_AS(nodep->fromp(), VarRef)->varp()
|
|
||||||
&& VN_IS(VN_AS(nodep->fromp(), VarRef)->varp()->valuep(), InitArray)) {
|
|
||||||
m_selp = nodep; // Ask visit(AstVarRef) to replace varref with const
|
|
||||||
}
|
|
||||||
iterateAndNextNull(nodep->fromp());
|
iterateAndNextNull(nodep->fromp());
|
||||||
if (VN_IS(nodep->fromp(), Const)) { // It did.
|
if (VN_IS(nodep->fromp(), Const)) {
|
||||||
if (!m_selp) {
|
nodep->v3error("Illegal assignment of constant to unpacked array");
|
||||||
nodep->v3error("Illegal assignment of constant to unpacked array");
|
} else if (m_required) {
|
||||||
} else {
|
replaceWithSimulation(nodep);
|
||||||
AstNode* const fromp = nodep->fromp()->unlinkFrBack();
|
|
||||||
nodep->replaceWithKeepDType(fromp);
|
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Handle ARRAYSEL directly on InitArray (not through VarRef)
|
|
||||||
else if (VN_IS(nodep->bitp(), Const) && VN_IS(nodep->fromp(), InitArray)) {
|
|
||||||
const AstInitArray* const initarp = VN_AS(nodep->fromp(), InitArray);
|
|
||||||
const uint32_t bit = VN_AS(nodep->bitp(), Const)->toUInt();
|
|
||||||
const AstNode* const itemp = initarp->getIndexDefaultedValuep(bit);
|
|
||||||
if (VN_IS(itemp, Const)) {
|
|
||||||
const V3Number& num = VN_AS(itemp, Const)->num();
|
|
||||||
VL_DO_DANGLING(replaceNum(nodep, num), nodep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_selp = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate a slice of an unpacked array. If constantification is
|
// Evaluate a slice of an unpacked array. If constantification is
|
||||||
|
|
@ -3374,21 +3351,8 @@ class ConstVisitor final : public VNVisitor {
|
||||||
= nodep->varp()->isParam() ? nodep->varp()->name() : "";
|
= nodep->varp()->isParam() ? nodep->varp()->name() : "";
|
||||||
VL_DO_DANGLING(replaceNum(nodep, num, origParamName), nodep);
|
VL_DO_DANGLING(replaceNum(nodep, num, origParamName), nodep);
|
||||||
did = true;
|
did = true;
|
||||||
} else if (m_selp && VN_IS(valuep, InitArray)) {
|
|
||||||
const AstInitArray* const initarp = VN_AS(valuep, InitArray);
|
|
||||||
const uint32_t bit = m_selp->bitConst();
|
|
||||||
const AstNode* const itemp = initarp->getIndexDefaultedValuep(bit);
|
|
||||||
if (VN_IS(itemp, Const)) {
|
|
||||||
const V3Number& num = VN_AS(itemp, Const)->num();
|
|
||||||
// UINFO(2, "constVisit " << cvtToHex(valuep) << " " << num);
|
|
||||||
VL_DO_DANGLING(replaceNum(nodep, num), nodep);
|
|
||||||
did = true;
|
|
||||||
}
|
|
||||||
} else if (m_params && VN_IS(valuep, InitArray)) {
|
} else if (m_params && VN_IS(valuep, InitArray)) {
|
||||||
// Allow parameters to pass arrays
|
// Allow parameters to pass arrays
|
||||||
// Earlier recursion of InitArray made sure each array value is constant
|
|
||||||
// This exception is fairly fragile, i.e. doesn't
|
|
||||||
// support arrays of arrays or other stuff
|
|
||||||
AstNode* const newp = valuep->cloneTree(false);
|
AstNode* const newp = valuep->cloneTree(false);
|
||||||
nodep->replaceWithKeepDType(newp);
|
nodep->replaceWithKeepDType(newp);
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# 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-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile()
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2020 Dustin Richmond
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
// Test: 2D array parameter passed to sub-modules via generate loops
|
||||||
|
|
||||||
|
module baz
|
||||||
|
#(
|
||||||
|
parameter integer type_p = '0
|
||||||
|
)
|
||||||
|
();
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t
|
||||||
|
#(
|
||||||
|
parameter integer n_x_p = 4
|
||||||
|
,parameter integer n_y_p = 4
|
||||||
|
,parameter integer twodim_p [0:n_y_p-1][0:n_x_p-1] = '{n_y_p{'{n_x_p{0}}}}
|
||||||
|
)
|
||||||
|
();
|
||||||
|
|
||||||
|
genvar r, c;
|
||||||
|
|
||||||
|
for (r = 0; r < n_y_p; r = r+1)
|
||||||
|
begin: y
|
||||||
|
for (c = 0; c < n_x_p; c=c+1)
|
||||||
|
begin: x
|
||||||
|
baz
|
||||||
|
#(.type_p(twodim_p[r][c]))
|
||||||
|
baz_i
|
||||||
|
();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# 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-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile()
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Greg Davill
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
`define stop $stop
|
||||||
|
`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);
|
||||||
|
|
||||||
|
module t ( /*AUTOARG*/);
|
||||||
|
|
||||||
|
// Test: 2D array localparam with pattern initialization
|
||||||
|
localparam logic [31:0] MATRIX[2][3] = '{'{32'hA0, 32'hA1, 32'hA2}, '{32'hB0, 32'hB1, 32'hB2}};
|
||||||
|
|
||||||
|
// Deriving a localparam from a 2D array element
|
||||||
|
localparam logic [31:0] DERIVED_A0 = MATRIX[0][0];
|
||||||
|
localparam logic [31:0] DERIVED_B2 = MATRIX[1][2];
|
||||||
|
|
||||||
|
// Use derived values as sub-module parameters to force elaboration-time resolution
|
||||||
|
sub #(.VAL(MATRIX[0][1])) u_sub ();
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
`checkh(DERIVED_A0, 32'hA0);
|
||||||
|
`checkh(DERIVED_B2, 32'hB2);
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module sub #(
|
||||||
|
parameter logic [31:0] VAL = 0
|
||||||
|
) ();
|
||||||
|
initial begin
|
||||||
|
if (VAL !== 32'hA1) begin
|
||||||
|
$display("%%Error: sub VAL='h%x expected 'hA1", VAL);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# 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-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.compile()
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Greg Davill
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
`define stop $stop
|
||||||
|
`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);
|
||||||
|
|
||||||
|
module t ( /*AUTOARG*/);
|
||||||
|
|
||||||
|
// Test: 3D array localparam with pattern initialization
|
||||||
|
localparam logic [31:0] CUBE[2][2][2] = '{
|
||||||
|
'{'{32'h00, 32'h01}, '{32'h10, 32'h11}},
|
||||||
|
'{'{32'h20, 32'h21}, '{32'h30, 32'h31}}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Deriving a localparam from a 3D array element
|
||||||
|
localparam logic [31:0] CUBE_VAL = CUBE[1][0][1];
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
`checkh(CUBE_VAL, 32'h21);
|
||||||
|
`checkh(CUBE[0][0][0], 32'h00);
|
||||||
|
`checkh(CUBE[0][1][1], 32'h11);
|
||||||
|
`checkh(CUBE[1][1][0], 32'h30);
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue