diff --git a/bin/verilator b/bin/verilator index 7d4c84bd4..dff24c375 100755 --- a/bin/verilator +++ b/bin/verilator @@ -362,7 +362,7 @@ detailed descriptions of these arguments. +incdir+ Directory to search for includes --inline-mult Tune module inlining --instr-count-dpi Assumed dynamic instruction count of DPI imports - -j Parallelism for --build (alias to --build-jobs) + -j Parallelism for --build-jobs/--verilate-jobs --l2-name Verilog scope name of the top module --language Default language standard to parse -LDFLAGS Linker pre-object arguments for makefile @@ -445,6 +445,7 @@ detailed descriptions of these arguments. --unused-regexp Tune UNUSED lint signals -V Verbose version and config -v Verilog library + --verilate-jobs Job threads for Verilation stage --no-verilate Skip Verilation and just compile previously Verilated code +verilog1995ext+ Synonym for +1364-1995ext+ +verilog2001ext+ Synonym for +1364-2001ext+ diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index e610fa926..52017c50d 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -707,9 +707,10 @@ Summary: .. option:: -j [] Specify the level of parallelism for :vlopt:`--build` if - :vlopt:`--build-jobs` isn't provided. If zero, uses the number of threads - in the current hardware. Otherwise, the must be a positive - integer specifying the maximum number of parallel build jobs. + :vlopt:`--build-jobs` isn't provided, and the internal compilation steps + of Verilator if :vlopt:`--verilate-jobs` isn't provided. If zero, uses + the number of threads in the current hardware. Otherwise, must be a + positive integer specifying the maximum number of parallel build jobs. .. option:: --l2-name @@ -1429,6 +1430,15 @@ Summary: execute only the build. This can be useful for rebuilding the Verilated code produced by a previous invocation of Verilator. +.. option:: --verilate-jobs [] + + Specify the level of parallelism for the internal compilation steps of + Verilator. If zero, uses the number of threads in the current hardware. + Otherwise, must be a positive integer specifying the maximum number of + parallel build jobs. + + See also :vlopt:`-j`. + .. option:: +verilog1995ext+ Synonym for :vlopt:`+1364-1995ext+\`. diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 2785a939b..8ea9d7aab 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1505,6 +1505,17 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char DECL_OPTION("-v", CbVal, [this, &optdir](const char* valp) { V3Options::addLibraryFile(parseFileArg(optdir, valp)); }); + DECL_OPTION("-verilate-jobs", CbVal, [this, fl](const char* valp) { + int val = std::atoi(valp); + if (val < 0) { + fl->v3error("--verilate-jobs requires a non-negative integer, but '" + << valp << "' was passed"); + val = 1; + } else if (val == 0) { + val = std::thread::hardware_concurrency(); + } + m_verilateJobs = val; + }); DECL_OPTION("-verilate", OnOff, &m_verilate); DECL_OPTION("-version", CbCall, [this]() { showVersion(false); @@ -1628,6 +1639,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char ++i; } if (m_buildJobs == -1) m_buildJobs = val; + if (m_verilateJobs == -1) m_verilateJobs = val; } else if (argv[i][0] == '-' || argv[i][0] == '+') { const char* argvNoDashp = (argv[i][1] == '-') ? (argv[i] + 2) : (argv[i] + 1); if (const int consumed = parser.parse(i, argc, argv)) { @@ -1660,6 +1672,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char } } if (m_buildJobs == -1) m_buildJobs = 1; + if (m_verilateJobs == -1) m_verilateJobs = 1; } //====================================================================== diff --git a/src/V3Options.h b/src/V3Options.h index 27e4f5036..b6c169561 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -317,6 +317,7 @@ private: int m_traceThreads = 0; // main switch: --trace-threads int m_unrollCount = 64; // main switch: --unroll-count int m_unrollStmts = 30000; // main switch: --unroll-stmts + int m_verilateJobs = -1; // main switch: --verilate-jobs int m_compLimitBlocks = 0; // compiler selection; number of nested blocks int m_compLimitMembers = 64; // compiler selection; number of members in struct before make anon array @@ -544,6 +545,7 @@ public: } int unrollCount() const { return m_unrollCount; } int unrollStmts() const { return m_unrollStmts; } + int verilateJobs() const { return m_verilateJobs; } int compLimitBlocks() const { return m_compLimitBlocks; } int compLimitMembers() const { return m_compLimitMembers; } diff --git a/src/V3StatsReport.cpp b/src/V3StatsReport.cpp index 72123b2df..d72f13c1c 100644 --- a/src/V3StatsReport.cpp +++ b/src/V3StatsReport.cpp @@ -47,6 +47,7 @@ class StatsReport final { os << " " << V3Options::version() << '\n'; os << " Arguments: " << v3Global.opt.allArgsString() << '\n'; os << " Build jobs: " << v3Global.opt.buildJobs() << '\n'; + os << " Verilate jobs: " << v3Global.opt.verilateJobs() << '\n'; os << '\n'; } diff --git a/test_regress/t/t_flag_verilate_threads_bad.out b/test_regress/t/t_flag_verilate_threads_bad.out new file mode 100644 index 000000000..f26bfdd19 --- /dev/null +++ b/test_regress/t/t_flag_verilate_threads_bad.out @@ -0,0 +1,2 @@ +%Error: --verilate-jobs requires a non-negative integer, but '-1' was passed +%Error: Exiting due to diff --git a/test_regress/t/t_flag_verilate_threads_bad.pl b/test_regress/t/t_flag_verilate_threads_bad.pl new file mode 100755 index 000000000..8743294da --- /dev/null +++ b/test_regress/t/t_flag_verilate_threads_bad.pl @@ -0,0 +1,22 @@ +#!/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(vlt => 1); + +top_filename("t/t_flag_werror.v"); + +lint( + fails => 1, + verilator_flags => [qw(--verilate-jobs -1)], + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_vthread.pl b/test_regress/t/t_vthread.pl new file mode 100755 index 000000000..5a360513a --- /dev/null +++ b/test_regress/t/t_vthread.pl @@ -0,0 +1,58 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2023 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 +use IO::File; + +scenarios(vlt => 1); + +sub gen { + my $filename = shift; + my $n = shift; + + my $fh = IO::File->new(">$filename"); + $fh->print("// Generated by t_vthread.pl\n"); + $fh->print("module genmod #(int val = 0)(clk, o);\n"); + $fh->print(" input clk;\n"); + $fh->print(" output int o;\n"); + $fh->print(" always @ (posedge clk) begin\n"); + $fh->print(" o <= val;\n"); + $fh->print(" end\n"); + $fh->print("endmodule\n"); + $fh->print("module t (clk, o);\n"); + $fh->print(" input clk;\n"); + $fh->print(" output int o;\n"); + for (my $i = 0; $i < ($n + 1); ++$i) { + $fh->print(" int r$i;\n"); + $fh->print(" genmod #(.val($i)) rm$i (.clk(clk), .o(r$i));\n"); + } + $fh->print(" always @ (posedge clk) begin\n"); + $fh->print(" o <= r$n;\n"); + $fh->print(' $write("*-* All Finished *-*\n");', "\n"); + $fh->print(' $finish;', "\n"); + $fh->print(" end\n"); + $fh->print("endmodule\n"); +} + +top_filename("$Self->{obj_dir}/t_vthread.v"); + +gen($Self->{top_filename}, 6000); + +compile( + # use --trace to generate trace files that can be parallelized + verilator_flags2=>["--stats --trace --verilate-jobs 2"], + ); + +execute( + check_finished => 1, + ); + +file_grep($Self->{stats}, qr/Verilate jobs: 2/); + +ok(1); +1;