parent
fe1a9e9ea7
commit
e2f5854088
|
|
@ -105,6 +105,7 @@ Jamey Hicks
|
||||||
Jamie Iles
|
Jamie Iles
|
||||||
Jan Van Winkel
|
Jan Van Winkel
|
||||||
Jean Berniolles
|
Jean Berniolles
|
||||||
|
Jens Yuechao Liu
|
||||||
Jeremy Bennett
|
Jeremy Bennett
|
||||||
Jesse Taube
|
Jesse Taube
|
||||||
Jevin Sweval
|
Jevin Sweval
|
||||||
|
|
|
||||||
|
|
@ -719,6 +719,11 @@ Summary:
|
||||||
automatically. Variables explicitly annotated with
|
automatically. Variables explicitly annotated with
|
||||||
:option:`/*verilator&32;split_var*/` are still split.
|
:option:`/*verilator&32;split_var*/` are still split.
|
||||||
|
|
||||||
|
.. option:: --fslice-element-limit
|
||||||
|
|
||||||
|
Rarely needed. Set the maximum array size (number of elements)
|
||||||
|
for slice optimization to avoid excessive memory usage.
|
||||||
|
|
||||||
.. option:: -future0 <option>
|
.. option:: -future0 <option>
|
||||||
|
|
||||||
Rarely needed. Suppress an unknown Verilator option for an option that
|
Rarely needed. Suppress an unknown Verilator option for an option that
|
||||||
|
|
|
||||||
|
|
@ -1458,13 +1458,16 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
||||||
DECL_OPTION("-freloop", FOnOff, &m_fReloop);
|
DECL_OPTION("-freloop", FOnOff, &m_fReloop);
|
||||||
DECL_OPTION("-freorder", FOnOff, &m_fReorder);
|
DECL_OPTION("-freorder", FOnOff, &m_fReorder);
|
||||||
DECL_OPTION("-fslice", FOnOff, &m_fSlice);
|
DECL_OPTION("-fslice", FOnOff, &m_fSlice);
|
||||||
|
DECL_OPTION("-fslice-element-limit", CbVal, [this, fl](const char* valp) {
|
||||||
|
m_fSliceElementLimit = std::atoi(valp);
|
||||||
|
if (m_fSliceElementLimit < 0) fl->v3fatal("--fslice-element-limit must be >= 0: " << valp);
|
||||||
|
});
|
||||||
DECL_OPTION("-fsplit", FOnOff, &m_fSplit);
|
DECL_OPTION("-fsplit", FOnOff, &m_fSplit);
|
||||||
DECL_OPTION("-fsubst", FOnOff, &m_fSubst);
|
DECL_OPTION("-fsubst", FOnOff, &m_fSubst);
|
||||||
DECL_OPTION("-fsubst-const", FOnOff, &m_fSubstConst);
|
DECL_OPTION("-fsubst-const", FOnOff, &m_fSubstConst);
|
||||||
DECL_OPTION("-ftable", FOnOff, &m_fTable);
|
DECL_OPTION("-ftable", FOnOff, &m_fTable);
|
||||||
DECL_OPTION("-ftaskify-all-forked", FOnOff, &m_fTaskifyAll).undocumented(); // Debug
|
DECL_OPTION("-ftaskify-all-forked", FOnOff, &m_fTaskifyAll).undocumented(); // Debug
|
||||||
DECL_OPTION("-fvar-split", FOnOff, &m_fVarSplit);
|
DECL_OPTION("-fvar-split", FOnOff, &m_fVarSplit);
|
||||||
|
|
||||||
DECL_OPTION("-G", CbPartialMatch, [this](const char* optp) { addParameter(optp, false); });
|
DECL_OPTION("-G", CbPartialMatch, [this](const char* optp) { addParameter(optp, false); });
|
||||||
DECL_OPTION("-gate-stmts", Set, &m_gateStmts);
|
DECL_OPTION("-gate-stmts", Set, &m_gateStmts);
|
||||||
DECL_OPTION("-gdb", CbCall, []() {}); // Processed only in bin/verilator shell
|
DECL_OPTION("-gdb", CbCall, []() {}); // Processed only in bin/verilator shell
|
||||||
|
|
|
||||||
|
|
@ -413,6 +413,7 @@ private:
|
||||||
bool m_fReloop; // main switch: -fno-reloop: reform loops
|
bool m_fReloop; // main switch: -fno-reloop: reform loops
|
||||||
bool m_fReorder; // main switch: -fno-reorder: reorder assignments in blocks
|
bool m_fReorder; // main switch: -fno-reorder: reorder assignments in blocks
|
||||||
bool m_fSlice = true; // main switch: -fno-slice: array assignment slicing
|
bool m_fSlice = true; // main switch: -fno-slice: array assignment slicing
|
||||||
|
int m_fSliceElementLimit = 256; // main switch: --fslice-element-limit
|
||||||
bool m_fSplit; // main switch: -fno-split: always assignment splitting
|
bool m_fSplit; // main switch: -fno-split: always assignment splitting
|
||||||
bool m_fSubst; // main switch: -fno-subst: substitute expression temp values
|
bool m_fSubst; // main switch: -fno-subst: substitute expression temp values
|
||||||
bool m_fSubstConst; // main switch: -fno-subst-const: final constant substitution
|
bool m_fSubstConst; // main switch: -fno-subst-const: final constant substitution
|
||||||
|
|
@ -726,6 +727,7 @@ public:
|
||||||
bool fReloop() const { return m_fReloop; }
|
bool fReloop() const { return m_fReloop; }
|
||||||
bool fReorder() const { return m_fReorder; }
|
bool fReorder() const { return m_fReorder; }
|
||||||
bool fSlice() const { return m_fSlice; }
|
bool fSlice() const { return m_fSlice; }
|
||||||
|
int fSliceElementLimit() const { return m_fSliceElementLimit; }
|
||||||
bool fSplit() const { return m_fSplit; }
|
bool fSplit() const { return m_fSplit; }
|
||||||
bool fSubst() const { return m_fSubst; }
|
bool fSubst() const { return m_fSubst; }
|
||||||
bool fSubstConst() const { return m_fSubstConst; }
|
bool fSubstConst() const { return m_fSubstConst; }
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ class SliceVisitor final : public VNVisitor {
|
||||||
|
|
||||||
// STATE - across all visitors
|
// STATE - across all visitors
|
||||||
VDouble0 m_statAssigns; // Statistic tracking
|
VDouble0 m_statAssigns; // Statistic tracking
|
||||||
|
VDouble0 m_statSliceElementSkips; // Statistic tracking
|
||||||
|
|
||||||
// STATE - for current visit position (use VL_RESTORER)
|
// STATE - for current visit position (use VL_RESTORER)
|
||||||
AstNode* m_assignp = nullptr; // Assignment we are under
|
AstNode* m_assignp = nullptr; // Assignment we are under
|
||||||
|
|
@ -248,6 +249,14 @@ class SliceVisitor final : public VNVisitor {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip optimization if array is too large
|
||||||
|
const int elements = arrayp->rangep()->elementsConst();
|
||||||
|
const int elementLimit = v3Global.opt.fSliceElementLimit();
|
||||||
|
if (elements > elementLimit && elementLimit > 0) {
|
||||||
|
++m_statSliceElementSkips;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
UINFO(4, "Slice optimizing " << nodep);
|
UINFO(4, "Slice optimizing " << nodep);
|
||||||
++m_statAssigns;
|
++m_statAssigns;
|
||||||
|
|
||||||
|
|
@ -256,7 +265,6 @@ class SliceVisitor final : public VNVisitor {
|
||||||
// Assign of an ascending range slice to a descending range one must reverse
|
// Assign of an ascending range slice to a descending range one must reverse
|
||||||
// the elements
|
// the elements
|
||||||
AstNodeAssign* newlistp = nullptr;
|
AstNodeAssign* newlistp = nullptr;
|
||||||
const int elements = arrayp->rangep()->elementsConst();
|
|
||||||
for (int elemIdx = 0; elemIdx < elements; ++elemIdx) {
|
for (int elemIdx = 0; elemIdx < elements; ++elemIdx) {
|
||||||
// Original node is replaced, so it is safe to copy it one time even if it is impure.
|
// Original node is replaced, so it is safe to copy it one time even if it is impure.
|
||||||
AstNodeAssign* const newp
|
AstNodeAssign* const newp
|
||||||
|
|
@ -383,6 +391,7 @@ public:
|
||||||
explicit SliceVisitor(AstNetlist* nodep) { iterate(nodep); }
|
explicit SliceVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||||
~SliceVisitor() override {
|
~SliceVisitor() override {
|
||||||
V3Stats::addStat("Optimizations, Slice array assignments", m_statAssigns);
|
V3Stats::addStat("Optimizations, Slice array assignments", m_statAssigns);
|
||||||
|
V3Stats::addStat("Optimizations, Slice array skips due to size limit", m_statSliceElementSkips);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2024 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
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.top_filename = "t/t_opt_slice_element_limit.v"
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--stats', '--fslice-element-limit', '10'])
|
||||||
|
|
||||||
|
test.file_grep(test.stats, r'Optimizations, Slice array skips due to size limit\s+(\d+)', 4)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2024 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t (
|
||||||
|
input logic [7:0] i1 [8],
|
||||||
|
input logic [7:0] i2 [16],
|
||||||
|
input logic [7:0] i3 [512],
|
||||||
|
output logic [7:0] o1 [8],
|
||||||
|
output logic [7:0] o2 [16],
|
||||||
|
output logic [7:0] o3 [256]
|
||||||
|
);
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2024 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
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.top_filename = "t/t_opt_slice_element_limit.v"
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--stats', '--fslice-element-limit', '0'])
|
||||||
|
|
||||||
|
test.file_grep(test.stats, r'Optimizations, Slice array skips due to size limit\s+(\d+)', 0)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
%Error: --fslice-element-limit must be >= 0: -100
|
||||||
|
... See the manual at https://verilator.org/verilator_doc.html?v=5.043 for more assistance.
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2024 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
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('linter')
|
||||||
|
|
||||||
|
test.top_filename = "t/t_opt_slice_element_limit.v"
|
||||||
|
test.golden_filename = "t/t_opt_slice_element_limit_bad.out"
|
||||||
|
|
||||||
|
test.lint(fails=True,
|
||||||
|
verilator_flags2=['--stats', '--fslice-element-limit', '-100'],
|
||||||
|
except_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2024 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
|
||||||
|
|
||||||
|
import vltest_bootstrap
|
||||||
|
|
||||||
|
test.scenarios('simulator')
|
||||||
|
|
||||||
|
test.top_filename = "t/t_opt_slice_element_limit.v"
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=['--stats'])
|
||||||
|
|
||||||
|
test.file_grep(test.stats, r'Optimizations, Slice array skips due to size limit\s+(\d+)', 1)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
Loading…
Reference in New Issue