Fix pre/postincrement operations (#3744) (#3756)

This commit is contained in:
Ryszard Rozak 2022-11-17 19:26:45 +01:00 committed by GitHub
parent 3c77c7bb92
commit d41efb189d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 14 deletions

View File

@ -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

View File

@ -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 {

22
test_regress/t/t_delay_incr.pl Executable file
View File

@ -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;

View File

@ -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

View File

@ -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;