From 15ebbd309f72639cf0af0bf57e7adee410f5b1e6 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 2 May 2025 07:36:42 -0400 Subject: [PATCH] Fix always processes ignoring $finish (#5971). --- Changes | 1 + src/V3EmitCMain.cpp | 4 ++-- src/V3Sched.cpp | 10 ++++++-- test_regress/t/t_timing_debug1.out | 3 --- test_regress/t/t_timing_finish2.py | 18 ++++++++++++++ test_regress/t/t_timing_finish2.v | 33 ++++++++++++++++++++++++++ test_regress/t/t_timing_trace.out | 3 +-- test_regress/t/t_timing_trace_fst.out | 5 ++-- test_regress/t/t_timing_trace_saif.out | 4 ++-- test_regress/t/t_trace_timing1.out | 2 +- 10 files changed, 68 insertions(+), 15 deletions(-) create mode 100755 test_regress/t/t_timing_finish2.py create mode 100644 test_regress/t/t_timing_finish2.v diff --git a/Changes b/Changes index 786656ca0..5e407d7a1 100644 --- a/Changes +++ b/Changes @@ -18,6 +18,7 @@ Verilator 5.037 devel * Fix filename backslash escapes in C code (#5947). * Fix sign extension of signed compared with unsigned case items (#5968). * Fix constant propagation making upper bits Xs (#5969). +* Fix always processes ignoring $finish (#5971). [Hennadii Chernyshchyk] Verilator 5.036 2025-04-27 diff --git a/src/V3EmitCMain.cpp b/src/V3EmitCMain.cpp index 985a9cea9..2abdcd70b 100644 --- a/src/V3EmitCMain.cpp +++ b/src/V3EmitCMain.cpp @@ -77,7 +77,7 @@ private: puts("\n"); puts("// Simulate until $finish\n"); - puts("while (!contextp->gotFinish()) {\n"); + puts("while (VL_LIKELY(!contextp->gotFinish())) {\n"); puts(/**/ "// Evaluate model\n"); puts(/**/ "topp->eval();\n"); puts(/**/ "// Advance time\n"); @@ -93,7 +93,7 @@ private: puts("}\n"); puts("\n"); - puts("if (!contextp->gotFinish()) {\n"); + puts("if (VL_LIKELY(!contextp->gotFinish())) {\n"); puts(/**/ "VL_DEBUG_IF(VL_PRINTF(\"+ Exiting without $finish; no events left\\n\"););\n"); puts("}\n"); puts("\n"); diff --git a/src/V3Sched.cpp b/src/V3Sched.cpp index a0a7b82dd..8b2b12629 100644 --- a/src/V3Sched.cpp +++ b/src/V3Sched.cpp @@ -435,8 +435,14 @@ void orderSequentially(AstCFunc* funcp, const LogicByScope& lbs) { if (VN_IS(procp, Always)) { subFuncp->slow(false); FileLine* const flp = procp->fileline(); - bodyp - = new AstWhile{flp, new AstConst{flp, AstConst::BitTrue{}}, bodyp}; + bodyp = new AstWhile{ + flp, + // If we change to use exceptions to handle finish/stop, + // this can get removed + new AstCExpr{flp, + "VL_LIKELY(!vlSymsp->_vm_contextp__->gotFinish())", 1, + true}, + bodyp}; } } subFuncp->addStmtsp(bodyp); diff --git a/test_regress/t/t_timing_debug1.out b/test_regress/t/t_timing_debug1.out index 0d1f5f568..eefec27ca 100644 --- a/test_regress/t/t_timing_debug1.out +++ b/test_regress/t/t_timing_debug1.out @@ -2354,7 +2354,6 @@ *-* All Finished *-* -V{t#,#} Resuming: Process waiting at t/t_timing_sched.v:10 -V{t#,#} Resuming: Process waiting at t/t_timing_sched.v:50 --V{t#,#} Suspending process waiting for @(posedge t.clk2) at t/t_timing_sched.v:50 -V{t#,#}+ Vt_timing_debug1___024root___eval_act -V{t#,#}+ Vt_timing_debug1___024root___act_comb__TOP__0 -V{t#,#}+ Vt_timing_debug1___024root___eval_phase__act @@ -2362,8 +2361,6 @@ -V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act -V{t#,#} 'act' region trigger index 0 is active: @([hybrid] t.clk1) -V{t#,#}+ Vt_timing_debug1___024root___timing_commit --V{t#,#} Committing processes waiting for @(posedge t.clk2): --V{t#,#} - Process waiting at t/t_timing_sched.v:50 -V{t#,#}+ Vt_timing_debug1___024root___timing_resume -V{t#,#}+ Vt_timing_debug1___024root___eval_act -V{t#,#}+ Vt_timing_debug1___024root___act_sequent__TOP__0 diff --git a/test_regress/t/t_timing_finish2.py b/test_regress/t/t_timing_finish2.py new file mode 100755 index 000000000..bd059b0f2 --- /dev/null +++ b/test_regress/t/t_timing_finish2.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 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.compile(verilator_flags2=['--binary']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_timing_finish2.v b/test_regress/t/t_timing_finish2.v new file mode 100644 index 000000000..c252cf453 --- /dev/null +++ b/test_regress/t/t_timing_finish2.v @@ -0,0 +1,33 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); + +module tb2 (); + parameter CLK_PERIOD = 2; + + reg clk = 1'b0; + int messages; + + always #(CLK_PERIOD / 2) clk = ~clk; + + always begin + int counter = 0; + while (counter < 3) begin + counter += 1; + $display("[%0t] Running loop %0d", $time, counter); + messages += 1; + @(posedge clk); + end + + $write("[%0t] *-* All Finished *-*\n", $time); + $finish; + end + + final `checkd(messages, 3); + +endmodule diff --git a/test_regress/t/t_timing_trace.out b/test_regress/t/t_timing_trace.out index f5a47ca02..504e3a2bc 100644 --- a/test_regress/t/t_timing_trace.out +++ b/test_regress/t/t_timing_trace.out @@ -83,6 +83,5 @@ b00000000000000000000000000000101 + #95 1( #100 -1% -1' 0( +0) diff --git a/test_regress/t/t_timing_trace_fst.out b/test_regress/t/t_timing_trace_fst.out index b95eb3cdb..fe5088ccd 100644 --- a/test_regress/t/t_timing_trace_fst.out +++ b/test_regress/t/t_timing_trace_fst.out @@ -1,5 +1,5 @@ $date - Sun Sep 22 22:53:52 2024 + Fri May 2 07:32:42 2025 $end $version @@ -92,5 +92,4 @@ $end 1$ #100 0$ -1) -1' +0& diff --git a/test_regress/t/t_timing_trace_saif.out b/test_regress/t/t_timing_trace_saif.out index eacb5a045..8b2e73be3 100644 --- a/test_regress/t/t_timing_trace_saif.out +++ b/test_regress/t/t_timing_trace_saif.out @@ -77,8 +77,8 @@ (rst (T0 0) (T1 100) (TZ 0) (TX 0) (TB 0) (TC 1)) (clk (T0 50) (T1 50) (TZ 0) (TX 0) (TB 0) (TC 20)) (a (T0 100) (T1 0) (TZ 0) (TX 0) (TB 0) (TC 0)) - (b (T0 0) (T1 100) (TZ 0) (TX 0) (TB 0) (TC 1)) - (c (T0 50) (T1 50) (TZ 0) (TX 0) (TB 0) (TC 11)) + (b (T0 0) (T1 100) (TZ 0) (TX 0) (TB 0) (TC 2)) + (c (T0 50) (T1 50) (TZ 0) (TX 0) (TB 0) (TC 10)) (d (T0 100) (T1 0) (TZ 0) (TX 0) (TB 0) (TC 0)) (ev (T0 100) (T1 0) (TZ 0) (TX 0) (TB 0) (TC 0)) ) diff --git a/test_regress/t/t_trace_timing1.out b/test_regress/t/t_trace_timing1.out index b829e1aca..9aa36ef0b 100644 --- a/test_regress/t/t_trace_timing1.out +++ b/test_regress/t/t_trace_timing1.out @@ -22,4 +22,4 @@ b00000000000000000000000000001010 % #15 1$ #20 -1# +0$