diff --git a/Changes b/Changes index 30d299c1f..d7923afde 100644 --- a/Changes +++ b/Changes @@ -21,6 +21,7 @@ Verilator 4.201 devel * Fix false $dumpfile warning on model save (#2834). [Yinan Xu] * Fix --timescale-override not suppressing TIMESCALEMOD (#2838). [Kaleb Barrett] * Fix false TIMESCALEMOD on generate-ignored instances (#2838). [Kaleb Barrett] +* Fix --output-split with class extends (#2839). [Iru Cai] Verilator 4.200 2021-03-12 diff --git a/include/verilated.cpp b/include/verilated.cpp index 0ee5a46e6..06c632e2e 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -2403,6 +2403,8 @@ void VerilatedContextImp::commandArgVl(const std::string& arg) { VL_PRINTF_MT("For help, please see 'verilator --help'\n"); VL_FATAL_MT("COMMAND_LINE", 0, "", "Exiting due to command line argument (not an error)"); + } else if (arg == "+verilator+noassert") { + assertOn(false); } else if (commandArgVlValue(arg, "+verilator+prof+threads+start+", value /*ref*/)) { profThreadsStart(atoll(value.c_str())); } else if (commandArgVlValue(arg, "+verilator+prof+threads+window+", value /*ref*/)) { @@ -2413,8 +2415,6 @@ void VerilatedContextImp::commandArgVl(const std::string& arg) { randReset(atoi(value.c_str())); } else if (commandArgVlValue(arg, "+verilator+seed+", value /*ref*/)) { randSeed(atoi(value.c_str())); - } else if (arg == "+verilator+noassert") { - assertOn(false); } else if (arg == "+verilator+V") { VerilatedImp::versionDump(); // Someday more info too VL_FATAL_MT("COMMAND_LINE", 0, "", diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 0ea41997c..a83efb16b 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -1853,7 +1853,7 @@ class EmitCImp final : EmitCStmts { void emitTextSection(AstType type); // High level void emitImpTop(AstNodeModule* modp); - void emitImp(AstNodeModule* modp); + void emitImp(AstNodeModule* fileModp, AstNodeModule* modp); void emitSettleLoop(const std::string& eval_call, bool initial); void emitWrapEval(AstNodeModule* modp); void emitWrapFast(AstNodeModule* modp); @@ -3351,7 +3351,7 @@ void EmitCImp::emitImpTop(AstNodeModule* fileModp) { emitTextSection(AstType::atScImpHdr); } -void EmitCImp::emitImp(AstNodeModule* modp) { +void EmitCImp::emitImp(AstNodeModule* fileModp, AstNodeModule* modp) { puts("\n//==========\n"); if (m_slow) { string section; @@ -3374,7 +3374,7 @@ void EmitCImp::emitImp(AstNodeModule* modp) { // Blocks for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstCFunc* funcp = VN_CAST(nodep, CFunc)) { - maybeSplit(modp); + maybeSplit(fileModp); mainDoFunc(funcp); } } @@ -3427,14 +3427,14 @@ void EmitCImp::mainImp(AstNodeModule* modp, bool slow) { m_ofp = newOutCFile(fileModp, !m_fast, true /*source*/); emitImpTop(fileModp); - emitImp(modp); + emitImp(fileModp, modp); if (AstClassPackage* packagep = VN_CAST(modp, ClassPackage)) { // Put the non-static class implementation in same C++ files as // often optimizations are possible when both are seen by the // compiler together m_modp = packagep->classp(); - emitImp(packagep->classp()); + emitImp(fileModp, packagep->classp()); m_modp = modp; } @@ -3447,7 +3447,7 @@ void EmitCImp::mainImp(AstNodeModule* modp, bool slow) { vxp = vxp->verticesNextp()) { const ExecMTask* mtaskp = dynamic_cast(vxp); if (mtaskp->threadRoot()) { - maybeSplit(modp); + maybeSplit(fileModp); // Only define one function for all the mtasks packed on // a given thread. We'll name this function after the // root mtask though it contains multiple mtasks' worth diff --git a/test_regress/t/t_class_split.pl b/test_regress/t/t_class_split.pl new file mode 100755 index 000000000..2dd83547c --- /dev/null +++ b/test_regress/t/t_class_split.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 2020 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(simulator => 1); + +compile( + verilator_flags2 => ['--output-split 10'], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_class_split.v b/test_regress/t/t_class_split.v new file mode 100644 index 000000000..7c6a6b8e8 --- /dev/null +++ b/test_regress/t/t_class_split.v @@ -0,0 +1,34 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2021 by Iru Cai. +// SPDX-License-Identifier: CC0-1.0 + +class Cls1; + int ctr; + task run(); + $display("%d", ctr); + ctr = ctr + 1; + endtask: run +endclass; + +class Cls2 extends Cls1; + task runtask(); + run(); + run(); + run(); + run(); + run(); + run(); + endtask: runtask +endclass + +module top; + Cls2 o; + initial begin + o = new; + o.runtask(); + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule