From d41efb189d82b4344f4ca0a828ca6decca55c1a3 Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Thu, 17 Nov 2022 19:26:45 +0100 Subject: [PATCH] Fix pre/postincrement operations (#3744) (#3756) --- src/V3LinkInc.cpp | 19 ++++++---------- src/V3Width.cpp | 4 ++-- test_regress/t/t_delay_incr.pl | 22 ++++++++++++++++++ test_regress/t/t_delay_incr.v | 27 ++++++++++++++++++++++ test_regress/t/t_delay_incr_timing.pl | 32 +++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 14 deletions(-) create mode 100755 test_regress/t/t_delay_incr.pl create mode 100644 test_regress/t/t_delay_incr.v create mode 100755 test_regress/t/t_delay_incr_timing.pl diff --git a/src/V3LinkInc.cpp b/src/V3LinkInc.cpp index 6f1fe68f0..d4b486e67 100644 --- a/src/V3LinkInc.cpp +++ b/src/V3LinkInc.cpp @@ -85,8 +85,6 @@ private: } else { nodep->v3fatalSrc("Unknown InsertMode"); } - m_insMode = IM_AFTER; - m_insStmtp = newp; } // VISITORS @@ -259,21 +257,18 @@ private: if (VN_IS(nodep, PreAdd) || VN_IS(nodep, PreSub)) { // PreAdd/PreSub operations // Immediately after declaration - increment it by one - m_insStmtp->addHereThisAsNext( - new AstAssign(fl, new AstVarRef(fl, varp, VAccess::WRITE), operp)); + varp->addNextHere(new AstAssign{fl, new AstVarRef{fl, varrefp->varp(), VAccess::WRITE}, + new AstVarRef{fl, varp, VAccess::READ}}); // Immediately after incrementing - assign it to the original variable - m_insStmtp->addHereThisAsNext( - new AstAssign(fl, new AstVarRef(fl, varrefp->varp(), VAccess::WRITE), - new AstVarRef(fl, varp, VAccess::READ))); + varp->addNextHere(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, operp}); } else { // PostAdd/PostSub operations // assign the original variable to the temporary one - m_insStmtp->addHereThisAsNext( - new AstAssign(fl, new AstVarRef(fl, varp, VAccess::WRITE), - new AstVarRef(fl, varrefp->varp(), VAccess::READ))); + varp->addNextHere( + new AstAssign{fl, new AstVarRef{fl, varrefp->varp(), VAccess::WRITE}, operp}); // Increment the original variable by one - m_insStmtp->addHereThisAsNext( - new AstAssign(fl, new AstVarRef(fl, varrefp->varp(), VAccess::WRITE), operp)); + varp->addNextHere(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, + new AstVarRef{fl, varrefp->varp(), VAccess::READ}}); } // Replace the node with the temporary diff --git a/src/V3Width.cpp b/src/V3Width.cpp index fff0970b9..2fb61d8c0 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -614,7 +614,7 @@ private: if (nodep->fileline()->timingOn()) { if (v3Global.opt.timing().isSetTrue()) { userIterate(nodep->lhsp(), WidthVP{nullptr, BOTH}.p()); - iterateNull(nodep->stmtsp()); + iterateAndNextNull(nodep->stmtsp()); return; } else if (v3Global.opt.timing().isSetFalse()) { nodep->v3warn(STMTDLY, "Ignoring delay on this statement due to --no-timing"); @@ -624,7 +624,7 @@ private: "Use --timing or --no-timing to specify how delays should be handled"); } } - if (nodep->stmtsp()) nodep->addNextHere(nodep->stmtsp()->unlinkFrBack()); + if (nodep->stmtsp()) nodep->addNextHere(nodep->stmtsp()->unlinkFrBackWithNext()); VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); } void visit(AstFork* nodep) override { diff --git a/test_regress/t/t_delay_incr.pl b/test_regress/t/t_delay_incr.pl new file mode 100755 index 000000000..3e8a3c919 --- /dev/null +++ b/test_regress/t/t_delay_incr.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 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 + +scenarios(simulator => 1); + +compile( + verilator_flags2 => ['-Wno-STMTDLY -Wno-ASSIGNDLY --no-timing'], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_delay_incr.v b/test_regress/t/t_delay_incr.v new file mode 100644 index 000000000..2ba72abea --- /dev/null +++ b/test_regress/t/t_delay_incr.v @@ -0,0 +1,27 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2003 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`timescale 100ns/1ns + +module t; + int ia; + int ib; + + initial begin + ia = 0; + #1 ib = ++ia; + #1 + if (ia !== ib) $stop; + + #1 ib = ia++; + #1 + if (ia == ib) $stop; + #10; + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_delay_incr_timing.pl b/test_regress/t/t_delay_incr_timing.pl new file mode 100755 index 000000000..6b78f49a3 --- /dev/null +++ b/test_regress/t/t_delay_incr_timing.pl @@ -0,0 +1,32 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2022 by Antmicro Ltd. 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); + +$Self->{main_time_multiplier} = 10e-7 / 10e-9; + +if (!$Self->have_coroutines) { + skip("No coroutine support"); +} +else { + top_filename("t/t_delay_incr.v"); + + compile( + timing_loop => 1, + verilator_flags2 => ['--timing -Wno-ZERODLY'], + ); + + execute( + check_finished => 1, + ); +} + +ok(1); +1;