diff --git a/include/verilated.cpp b/include/verilated.cpp index c992d8cf7..180cc8d76 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -2482,12 +2482,12 @@ void Verilated::endOfEvalGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE { // VerilatedImp:: Constructors // verilated.o may exist both in protect-lib and main module. -// Both the main module and the protec-lib refer the same instance of +// Both the main module and the protect-lib refer the same instance of // static variables such as Verilated or VerilatedImplData. // This is important to share the state such as Verilated::gotFinish. // But the sharing may cause double-free error when shutting down because destructors // are called twice. -// 1st time:From protec-lib shared object on the way of unloading after exitting main() +// 1st time:From protect-lib shared object on the way of unloading after exiting main() // 2nd time:From main executable. // // To avoid the trouble, all member variables are enclosed in VerilatedImpU union. diff --git a/include/verilated.h b/include/verilated.h index c0cddeaec..657313e0f 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -564,22 +564,23 @@ public: static int dpiLineno() VL_MT_SAFE { return t_s.t_dpiLineno; } static int exportFuncNum(const char* namep) VL_MT_SAFE; + // Internal: Serialization setup static constexpr size_t serialized1Size() VL_PURE { return sizeof(s_s); } static constexpr void* serialized1Ptr() VL_MT_UNSAFE { return &s_s; } // For Serialize only static size_t serialized2Size() VL_PURE; static void* serialized2Ptr() VL_MT_UNSAFE; #ifdef VL_THREADED - /// Set the mtaskId, called when an mtask starts + /// Internal: Set the mtaskId, called when an mtask starts static void mtaskId(vluint32_t id) VL_MT_SAFE { t_s.t_mtaskId = id; } static vluint32_t mtaskId() VL_MT_SAFE { return t_s.t_mtaskId; } static void endOfEvalReqdInc() VL_MT_SAFE { ++t_s.t_endOfEvalReqd; } static void endOfEvalReqdDec() VL_MT_SAFE { --t_s.t_endOfEvalReqd; } - /// Called at end of each thread mtask, before finishing eval + /// Internal: Called at end of each thread mtask, before finishing eval static void endOfThreadMTask(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE { if (VL_UNLIKELY(t_s.t_endOfEvalReqd)) endOfThreadMTaskGuts(evalMsgQp); } - /// Called at end of eval loop + /// Internal: Called at end of eval loop static void endOfEval(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE { // It doesn't work to set endOfEvalReqd on the threadpool thread // and then check it on the eval thread since it's thread local. diff --git a/test_regress/t/t_verilated_legacy.cpp b/test_regress/t/t_verilated_legacy.cpp new file mode 100644 index 000000000..5536d586d --- /dev/null +++ b/test_regress/t/t_verilated_legacy.cpp @@ -0,0 +1,105 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2020 by Wilson Snyder and Marlon James. 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 +// +//************************************************************************* + +#include VM_PREFIX_INCLUDE + +#include +#include +#include +#include + +bool got_error = false; + +// Use cout to avoid issues with %d/%lx etc +#define CHECK_RESULT(got, exp) \ + if ((got) != (exp)) { \ + std::cout << std::dec << "%Error: " << __FILE__ << ":" << __LINE__ << ": GOT = " << (got) \ + << " EXP = " << (exp) << std::endl; \ + got_error = true; \ + } +#define CHECK_RESULT_CSTR(got, exp) \ + if (strcmp((got), (exp))) { \ + printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", __FILE__, __LINE__, \ + (got) ? (got) : "", (exp) ? (exp) : ""); \ + return __LINE__; \ + } + +vluint64_t main_time = 0; + +#ifdef T_VERILATED_LEGACY_TIME64 +vluint64_t vl_time_stamp64() { return main_time; } +#endif +#ifdef T_VERILATED_LEGACY +double sc_time_stamp() { return main_time; } +#endif + +int main(int argc, char** argv, char** env) { + // Test that the old non-context Verilated:: calls all work + // (This test should never get updated to use context) + + // Many used only by git@github.com:djg/verilated-rs.git + + Verilated::commandArgs(argc, argv); // Commonly used + CHECK_RESULT_CSTR(Verilated::commandArgsPlusMatch("not-matching"), ""); + + Verilated::assertOn(true); + CHECK_RESULT(Verilated::assertOn(), true); + + Verilated::calcUnusedSigs(true); + CHECK_RESULT(Verilated::calcUnusedSigs(), true); + + Verilated::debug(9); // Commonly used + CHECK_RESULT(Verilated::debug(), 9); + Verilated::debug(0); + + Verilated::fatalOnVpiError(true); + CHECK_RESULT(Verilated::fatalOnVpiError(), true); + + Verilated::gotFinish(false); + CHECK_RESULT(Verilated::gotFinish(), false); // Commonly used + + Verilated::mkdir(VL_STRINGIFY(TEST_OBJ_DIR) "/mkdired"); + + Verilated::randReset(0); + CHECK_RESULT(Verilated::randReset(), 0); + + Verilated::traceEverOn(true); // Commonly used + + CHECK_RESULT_CSTR(Verilated::productName(), Verilated::productName()); + CHECK_RESULT_CSTR(Verilated::productVersion(), Verilated::productVersion()); + + VM_PREFIX* topp = new VM_PREFIX(); + + topp->eval(); + topp->clk = 0; + + VL_PRINTF("Starting\n"); + + vluint64_t sim_time = 100; + while (vl_time_stamp64() < sim_time && !Verilated::gotFinish()) { + CHECK_RESULT(VL_TIME_Q(), main_time); + CHECK_RESULT(VL_TIME_D(), main_time); + main_time += 1; + topp->clk = !topp->clk; + topp->eval(); + } + + topp->final(); + Verilated::flushCall(); + Verilated::runFlushCallbacks(); + + Verilated::internalsDump(); + Verilated::scopesDump(); + + VL_DO_DANGLING(delete topp, topp); + Verilated::runExitCallbacks(); + return got_error ? 10 : 0; +} diff --git a/test_regress/t/t_verilated_legacy.pl b/test_regress/t/t_verilated_legacy.pl new file mode 100755 index 000000000..293973bb4 --- /dev/null +++ b/test_regress/t/t_verilated_legacy.pl @@ -0,0 +1,24 @@ +#!/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 and Marlon James. 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_all => 1); + +compile( + make_top_shell => 0, + make_main => 0, + verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_verilated_legacy.v b/test_regress/t/t_verilated_legacy.v new file mode 100644 index 000000000..c6fd4a2e0 --- /dev/null +++ b/test_regress/t/t_verilated_legacy.v @@ -0,0 +1,24 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2021 Wilson Snyder and Marlon James. +// SPDX-License-Identifier: CC0-1.0 + + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + int count; + + always @(posedge clk) begin + count <= count + 1; + if (count == 10) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + +endmodule : t diff --git a/test_regress/t/t_verilated_legacy_time64.pl b/test_regress/t/t_verilated_legacy_time64.pl new file mode 100755 index 000000000..7319ca391 --- /dev/null +++ b/test_regress/t/t_verilated_legacy_time64.pl @@ -0,0 +1,27 @@ +#!/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 and Marlon James. 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_all => 1); + +top_filename("t/t_verilated_legacy.v"); + +compile( + make_top_shell => 0, + make_main => 0, + verilator_flags2 => ["--exe $Self->{t_dir}/t_verilated_legacy.cpp"], + make_flags => 'CPPFLAGS_ADD=-DVL_TIME_STAMP64', + ); + +execute( + check_finished => 1, + ); + +ok(1); +1;