diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index f81cc64f0..da0014dd5 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -719,7 +719,7 @@ Summary: automatically. Variables explicitly annotated with :option:`/*verilator&32;split_var*/` are still split. -.. option:: --fslice-opt-limit +.. option:: --fslice-element-limit Rarely needed. Set the maximum array size (number of elements) for slice optimization to avoid excessive memory usage. diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 0219e00bc..b22fb7c80 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1458,17 +1458,16 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-freloop", FOnOff, &m_fReloop); DECL_OPTION("-freorder", FOnOff, &m_fReorder); 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("-fsubst", FOnOff, &m_fSubst); DECL_OPTION("-fsubst-const", FOnOff, &m_fSubstConst); DECL_OPTION("-ftable", FOnOff, &m_fTable); DECL_OPTION("-ftaskify-all-forked", FOnOff, &m_fTaskifyAll).undocumented(); // Debug DECL_OPTION("-fvar-split", FOnOff, &m_fVarSplit); - DECL_OPTION("-fslice-opt-limit", CbVal, [this, fl](const char* valp) { - m_fSliceOptLimit = std::atoi(valp); - if (m_fSliceOptLimit < 1) fl->v3fatal("--fslice-opt-limit must be >= 1: " << valp); - }); - DECL_OPTION("-G", CbPartialMatch, [this](const char* optp) { addParameter(optp, false); }); DECL_OPTION("-gate-stmts", Set, &m_gateStmts); DECL_OPTION("-gdb", CbCall, []() {}); // Processed only in bin/verilator shell diff --git a/src/V3Options.h b/src/V3Options.h index 33a67a136..e5a584cf4 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -413,13 +413,13 @@ private: bool m_fReloop; // main switch: -fno-reloop: reform loops bool m_fReorder; // main switch: -fno-reorder: reorder assignments in blocks 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_fSubst; // main switch: -fno-subst: substitute expression temp values bool m_fSubstConst; // main switch: -fno-subst-const: final constant substitution bool m_fTable; // main switch: -fno-table: lookup table creation bool m_fTaskifyAll = false; // main switch: --ftaskify-all-forked bool m_fVarSplit; // main switch: -fno-var-split: automatic variable splitting - int m_fSliceOptLimit = 256; // main switch: --fslice-opt-limit // clang-format on bool m_available = false; // Set to true at the end of option parsing @@ -727,13 +727,13 @@ public: bool fReloop() const { return m_fReloop; } bool fReorder() const { return m_fReorder; } bool fSlice() const { return m_fSlice; } + int fSliceElementLimit() const { return m_fSliceElementLimit; } bool fSplit() const { return m_fSplit; } bool fSubst() const { return m_fSubst; } bool fSubstConst() const { return m_fSubstConst; } bool fTable() const { return m_fTable; } bool fTaskifyAll() const { return m_fTaskifyAll; } bool fVarSplit() const { return m_fVarSplit; } - int fSliceOptLimit() const { return m_fSliceOptLimit; } std::string traceClassBase() const VL_MT_SAFE; // Deprecated std::string traceClassLang() const VL_MT_SAFE; // Deprecated diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index d4ce038f1..cfadf7792 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -58,7 +58,7 @@ class SliceVisitor final : public VNVisitor { // STATE - across all visitors VDouble0 m_statAssigns; // Statistic tracking - VDouble0 m_statSliceLimitSkips; // Statistic tracking + VDouble0 m_statSliceElementSkips; // Statistic tracking // STATE - for current visit position (use VL_RESTORER) AstNode* m_assignp = nullptr; // Assignment we are under @@ -251,8 +251,9 @@ class SliceVisitor final : public VNVisitor { // Skip optimization if array is too large const int elements = arrayp->rangep()->elementsConst(); - if (elements > v3Global.opt.fSliceOptLimit()) { - ++m_statSliceLimitSkips; + const int elementLimit = v3Global.opt.fSliceElementLimit(); + if (elements > elementLimit && elementLimit > 0) { + ++m_statSliceElementSkips; return false; } @@ -390,7 +391,7 @@ public: explicit SliceVisitor(AstNetlist* nodep) { iterate(nodep); } ~SliceVisitor() override { V3Stats::addStat("Optimizations, Slice array assignments", m_statAssigns); - V3Stats::addStat("Optimizations, Slice array skips due to size limit", m_statSliceLimitSkips); + V3Stats::addStat("Optimizations, Slice array skips due to size limit", m_statSliceElementSkips); } }; diff --git a/test_regress/t/t_opt_slice_limit.py b/test_regress/t/t_opt_slice_element_limit.py similarity index 78% rename from test_regress/t/t_opt_slice_limit.py rename to test_regress/t/t_opt_slice_element_limit.py index 0f0a18a10..65eb02d55 100644 --- a/test_regress/t/t_opt_slice_limit.py +++ b/test_regress/t/t_opt_slice_element_limit.py @@ -11,10 +11,10 @@ import vltest_bootstrap test.scenarios('simulator') -test.top_filename = "t/t_opt_slice_limit.v" +test.top_filename = "t/t_opt_slice_element_limit.v" -test.compile(verilator_flags2=['--stats', '--fslice-opt-limit', '10']) +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() \ No newline at end of file +test.passes() diff --git a/test_regress/t/t_opt_slice_limit.v b/test_regress/t/t_opt_slice_element_limit.v similarity index 98% rename from test_regress/t/t_opt_slice_limit.v rename to test_regress/t/t_opt_slice_element_limit.v index cb89fe8a7..428dc1eec 100644 --- a/test_regress/t/t_opt_slice_limit.v +++ b/test_regress/t/t_opt_slice_element_limit.v @@ -17,4 +17,4 @@ module t ( $write("*-* All Finished *-*\n"); $finish; end -endmodule \ No newline at end of file +endmodule diff --git a/test_regress/t/t_opt_slice_element_limit_allow_all.py b/test_regress/t/t_opt_slice_element_limit_allow_all.py new file mode 100644 index 000000000..48a349457 --- /dev/null +++ b/test_regress/t/t_opt_slice_element_limit_allow_all.py @@ -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() diff --git a/test_regress/t/t_opt_slice_limit_bad.py b/test_regress/t/t_opt_slice_element_limit_bad.py similarity index 76% rename from test_regress/t/t_opt_slice_limit_bad.py rename to test_regress/t/t_opt_slice_element_limit_bad.py index 0c1c9d73d..57fcb2496 100644 --- a/test_regress/t/t_opt_slice_limit_bad.py +++ b/test_regress/t/t_opt_slice_element_limit_bad.py @@ -11,9 +11,9 @@ import vltest_bootstrap test.scenarios('simulator') -test.top_filename = "t/t_opt_slice_limit.v" +test.top_filename = "t/t_opt_slice_element_limit.v" test.lint(fails=True, - verilator_flags2=['--stats', '--fslice-opt-limit', '-100']) + verilator_flags2=['--stats', '--fslice-element-limit', '-100']) -test.passes() \ No newline at end of file +test.passes() diff --git a/test_regress/t/t_opt_slice_limit_default.py b/test_regress/t/t_opt_slice_element_limit_default.py similarity index 89% rename from test_regress/t/t_opt_slice_limit_default.py rename to test_regress/t/t_opt_slice_element_limit_default.py index 0e88e0223..31df49d90 100644 --- a/test_regress/t/t_opt_slice_limit_default.py +++ b/test_regress/t/t_opt_slice_element_limit_default.py @@ -11,10 +11,10 @@ import vltest_bootstrap test.scenarios('simulator') -test.top_filename = "t/t_opt_slice_limit.v" +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() \ No newline at end of file +test.passes()