From ec0815e9acc67ee78b55e7338e1dc497c93e0f64 Mon Sep 17 00:00:00 2001 From: Krzysztof Bieganski Date: Thu, 8 Aug 2024 23:12:00 +0200 Subject: [PATCH] Fix NBAs in suspendables (#5348) Signed-off-by: Krzysztof Bieganski --- src/V3Delayed.cpp | 16 ++----- .../t/{t_timing_nba.pl => t_timing_nba_1.pl} | 0 .../t/{t_timing_nba.v => t_timing_nba_1.v} | 0 test_regress/t/t_timing_nba_2.pl | 22 ++++++++++ test_regress/t/t_timing_nba_2.v | 44 +++++++++++++++++++ 5 files changed, 70 insertions(+), 12 deletions(-) rename test_regress/t/{t_timing_nba.pl => t_timing_nba_1.pl} (100%) rename test_regress/t/{t_timing_nba.v => t_timing_nba_1.v} (100%) create mode 100755 test_regress/t/t_timing_nba_2.pl create mode 100644 test_regress/t/t_timing_nba_2.v diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 2e6cd67c2..59749239b 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -120,8 +120,6 @@ class DelayedVisitor final : public VNVisitor { AstVarScope* delayVscp = nullptr; // Points to AstActive block of the shadow variable 'delayVscp/post block 'postp' AstActive* activep = nullptr; - // Post block for this variable used in suspendable processes - AstAlwaysPost* suspPostp = nullptr; // Post block for this variable AstAlwaysPost* postp = nullptr; // First reference encountered to the VarScope @@ -386,17 +384,11 @@ class DelayedVisitor final : public VNVisitor { } // Get/Create 'Post' ordered block to commit the delayed value - AstAlwaysPost* postp = m_vscpAux(vscp).suspPostp; - if (!postp) { - postp = new AstAlwaysPost{flp}; - if (!m_procp->user2p()) { - m_procp->user2p(createActiveLike(lhsComponents.refp->fileline(), m_activep)); - // TODO: Somebody needs to explain me how it makes sense to set this - // inside this 'if'. Shouldn't it be outside this 'if'? See #5084 - m_vscpAux(vscp).suspPostp = postp; - } - VN_AS(m_procp->user2p(), Active)->addStmtsp(postp); + AstAlwaysPost* postp = new AstAlwaysPost{flp}; + if (!m_procp->user2p()) { + m_procp->user2p(createActiveLike(lhsComponents.refp->fileline(), m_activep)); } + VN_AS(m_procp->user2p(), Active)->addStmtsp(postp); // Create the flag denoting an update is pending - no reuse here AstVarScope* const setVscp = createNewVarScope(vscp, "__VdlySet" + baseName, 1); diff --git a/test_regress/t/t_timing_nba.pl b/test_regress/t/t_timing_nba_1.pl similarity index 100% rename from test_regress/t/t_timing_nba.pl rename to test_regress/t/t_timing_nba_1.pl diff --git a/test_regress/t/t_timing_nba.v b/test_regress/t/t_timing_nba_1.v similarity index 100% rename from test_regress/t/t_timing_nba.v rename to test_regress/t/t_timing_nba_1.v diff --git a/test_regress/t/t_timing_nba_2.pl b/test_regress/t/t_timing_nba_2.pl new file mode 100755 index 000000000..929ae897c --- /dev/null +++ b/test_regress/t/t_timing_nba_2.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 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 + +scenarios(simulator => 1); + +compile( + verilator_flags2 => ["--exe --main --timing"], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_timing_nba_2.v b/test_regress/t/t_timing_nba_2.v new file mode 100644 index 000000000..9f09d4c76 --- /dev/null +++ b/test_regress/t/t_timing_nba_2.v @@ -0,0 +1,44 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +module t; + logic clk1 = 0, clk2 = 0, clk3 = 0, clk4 = 0; + always #2 clk1 = ~clk1; + assign #1 clk2 = clk1; + assign #1 clk3 = clk2; + assign #1 clk4 = clk3; + + int x = 0; + int cyc = 0; + + always @(posedge clk1) begin + if (x != 0) $stop; +`ifdef TEST_VERBOSE + $display("[%0t] clk1 | x=%0d cyc=%0d", $realtime, x, cyc); +`endif + @(posedge clk2); +`ifdef TEST_VERBOSE + $display("[%0t] clk2 | x=%0d cyc=%0d", $realtime, x, cyc); +`endif + x <= x + 1; + cyc <= cyc + 1; + if (cyc == 10) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + + always @(posedge clk3) begin +`ifdef TEST_VERBOSE + $display("[%0t] clk3 | x=%0d cyc=%0d", $realtime, x, cyc); +`endif + @(posedge clk4); +`ifdef TEST_VERBOSE + $display("[%0t] clk4 | x=%0d cyc=%0d", $realtime, x, cyc); +`endif + x <= x - 1; + end +endmodule