diff --git a/Changes b/Changes index 9e233089b..20fc4b0db 100644 --- a/Changes +++ b/Changes @@ -30,6 +30,7 @@ Verilator 5.025 devel * Add parameterless assert control system tasks (#5010). [Bartłomiej Chmiel] * Add traceCapable indication to model header (#5053). [Vito Gamberini] * Add increasing of stack size when possible (#5071) (#5104). [Yinan Xu] +* Add assertion on reusing VerilatedContext (#5167). * Improve DFG regularization in cyclic graphs (#5142). [Geza Lore] * Improve VerilatedVpiPutHolder storage requirements (#5144). [Kaleb Barrett] * Fix missing flex include path variable (#4970) (#4971). [Christopher Taylor] diff --git a/include/verilated.cpp b/include/verilated.cpp index 3045d01d2..b6917aaf5 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -2664,8 +2664,16 @@ void VerilatedContext::addModel(VerilatedModel* modelp) { m_ns.m_cpuTimeStart.start(); m_ns.m_wallTimeStart.start(); } - threadPoolp(); // Ensure thread pool is created, so m_threads cannot change any more + // We look for time passing, as opposed to post-eval(), as embedded + // models might get added inside initial blocks. + if (VL_UNLIKELY(time())) + VL_FATAL_MT( + __FILE__, __LINE__, "", + "Adding model when time is non-zero. ... Suggest check time(), or for restarting" + " model use a new VerilatedContext"); + + threadPoolp(); // Ensure thread pool is created, so m_threads cannot change any more m_threadsInModels += modelp->threads(); if (VL_UNLIKELY(modelp->threads() > m_threads)) { std::ostringstream msg; diff --git a/include/verilated_trace_imp.h b/include/verilated_trace_imp.h index 9529a2b66..94549dc19 100644 --- a/include/verilated_trace_imp.h +++ b/include/verilated_trace_imp.h @@ -633,12 +633,13 @@ void VerilatedTrace::addModel(VerilatedModel* modelp) // Validate if (!newModel) { // LCOV_EXCL_START - VL_FATAL_MT(__FILE__, __LINE__, "", - "The same model has already been added to this trace file"); + VL_FATAL_MT( + __FILE__, __LINE__, "", + "The same model has already been added to this trace file or VerilatedContext"); } if (VL_UNCOVERABLE(m_contextp && contextp != m_contextp)) { VL_FATAL_MT(__FILE__, __LINE__, "", - "A trace file instance can only handle models from the same context"); + "A trace file instance can only handle models from the same VerilatedContext"); } if (VL_UNCOVERABLE(m_didSomeDump)) { VL_FATAL_MT(__FILE__, __LINE__, "", diff --git a/test_regress/t/t_leak.cpp b/test_regress/t/t_leak.cpp index eb15c060f..1d52d27f5 100644 --- a/test_regress/t/t_leak.cpp +++ b/test_regress/t/t_leak.cpp @@ -46,37 +46,20 @@ long long get_memory_usage() { } void make_and_destroy() { -#ifdef VL_NO_LEGACY VerilatedContext* contextp = new VerilatedContext; contextp->debug(0); VM_PREFIX* topp = new VM_PREFIX{contextp}; -#else - Verilated::debug(0); - VM_PREFIX* topp = new VM_PREFIX; -#endif topp->eval(); topp->clk = true; - while (! -#ifdef VL_NO_LEGACY - contextp->gotFinish() -#else - Verilated::gotFinish() -#endif - ) { -#ifdef VL_NO_LEGACY + while (!contextp->gotFinish()) { contextp->timeInc(5); -#else - main_time += 5; -#endif topp->clk = !topp->clk; topp->eval(); } VL_DO_DANGLING(delete topp, topp); -#ifdef VL_NO_LEGACY VL_DO_DANGLING(delete contextp, contextp); -#endif } int main(int argc, char* argv[]) { diff --git a/test_regress/t/t_leak_legacy.pl b/test_regress/t/t_leak_legacy.pl deleted file mode 100755 index 03166108f..000000000 --- a/test_regress/t/t_leak_legacy.pl +++ /dev/null @@ -1,33 +0,0 @@ -#!/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 - -if ($Self->{vltmt} && exists $ENV{TRAVIS_DIST} && - $ENV{TRAVIS_DIST} eq "trusty") -{ - skip("Multithreaded test does not work under CI w/ Ubuntu Trusty"); -} - -scenarios(vlt_all => 1); - -top_filename("t/t_leak.v"); - -compile( - make_top_shell => 0, - make_main => 0, - verilator_flags2 => ["--exe $Self->{t_dir}/t_leak.cpp"], - make_flags => 'CPPFLAGS_ADD=-UVL_NO_LEGACY', - ); - -execute( - check_finished => 1, - ); - -ok(1); -1; diff --git a/test_regress/t/t_timescale_parse.cpp b/test_regress/t/t_timescale_parse.cpp index 2a011930d..c3832e868 100644 --- a/test_regress/t/t_timescale_parse.cpp +++ b/test_regress/t/t_timescale_parse.cpp @@ -8,13 +8,14 @@ VM_PREFIX* tb = nullptr; -double sc_time_stamp() { - return 2 * 1e9; // e.g. 2 seconds in ns units -} +double s_time = 0.0; + +double sc_time_stamp() { return s_time; } int main() { tb = new VM_PREFIX{"tb"}; + s_time = 2 * 1e9; // e.g. 2 seconds in ns units tb->eval(); tb->eval(); tb->eval(); diff --git a/test_regress/t/t_wrapper_reuse_context_bad.cpp b/test_regress/t/t_wrapper_reuse_context_bad.cpp new file mode 100644 index 000000000..684fee858 --- /dev/null +++ b/test_regress/t/t_wrapper_reuse_context_bad.cpp @@ -0,0 +1,24 @@ +// +// DESCRIPTION: Verilator: Verilog Multiple Model 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 + +#include + +#include VM_PREFIX_INCLUDE + +int main(int argc, char** argv) { + // Create contexts + VerilatedContext* contextp{new VerilatedContext}; + + for (int i = 0; i < 2; ++i) { + std::unique_ptr topp{new VM_PREFIX{contextp, "TOP"}}; + topp->eval(); + contextp->timeInc(1); + topp->eval(); + } + + return 0; +} diff --git a/test_regress/t/t_wrapper_reuse_context_bad.out b/test_regress/t/t_wrapper_reuse_context_bad.out new file mode 100644 index 000000000..b27e39add --- /dev/null +++ b/test_regress/t/t_wrapper_reuse_context_bad.out @@ -0,0 +1,2 @@ +%Error: /svaha/wsnyder/SandBox/homecvs/v4/verilator/include/verilated.cpp:2672: Adding model when time is non-zero. ... Suggest check time(), or for restarting model use a new VerilatedContext +Aborting... diff --git a/test_regress/t/t_wrapper_reuse_context_bad.pl b/test_regress/t/t_wrapper_reuse_context_bad.pl new file mode 100755 index 000000000..2aedd72bc --- /dev/null +++ b/test_regress/t/t_wrapper_reuse_context_bad.pl @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +if (!$::Driver) { use strict; use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Multiple Model Test Module +# +# 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 + +scenarios(vlt => 1); + +compile( + make_top_shell => 0, + make_main => 0, + verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], + ); + +execute( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_wrapper_reuse_context_bad.v b/test_regress/t/t_wrapper_reuse_context_bad.v new file mode 100644 index 000000000..f4ae87f02 --- /dev/null +++ b/test_regress/t/t_wrapper_reuse_context_bad.v @@ -0,0 +1,9 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2022 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module top; + initial $finish; +endmodule