forked from github/verilator
Assign unique names for blocks in do..while loop (#4019)
This commit is contained in:
parent
2c62714a30
commit
1d0a06438c
@ -2651,17 +2651,13 @@ public:
|
||||
bool addNewline() const { return displayType().addNewline(); }
|
||||
};
|
||||
class AstDoWhile final : public AstNodeStmt {
|
||||
// @astgen op1 := precondsp : List[AstNode]
|
||||
// @astgen op2 := condp : AstNodeExpr
|
||||
// @astgen op3 := stmtsp : List[AstNode]
|
||||
// @astgen op4 := incsp : List[AstNode]
|
||||
// @astgen op1 := condp : AstNodeExpr
|
||||
// @astgen op2 := stmtsp : List[AstNode]
|
||||
public:
|
||||
AstDoWhile(FileLine* fl, AstNodeExpr* conditionp, AstNode* stmtsp = nullptr,
|
||||
AstNode* incsp = nullptr)
|
||||
AstDoWhile(FileLine* fl, AstNodeExpr* conditionp, AstNode* stmtsp = nullptr)
|
||||
: ASTGEN_SUPER_DoWhile(fl) {
|
||||
condp(conditionp);
|
||||
addStmtsp(stmtsp);
|
||||
addIncsp(incsp);
|
||||
}
|
||||
ASTGEN_MEMBERS_AstDoWhile;
|
||||
bool isGateOptimizable() const override { return false; }
|
||||
|
@ -128,6 +128,19 @@ private:
|
||||
return labelp;
|
||||
}
|
||||
}
|
||||
void addPrefixToBlocksRecurse(AstNode* nodep) {
|
||||
// Add do_while_ prefix to blocks
|
||||
// Used to not have blocks with duplicated names
|
||||
if (AstBegin* const beginp = VN_CAST(nodep, Begin)) {
|
||||
if (beginp->name() != "") beginp->name("__Vdo_while_" + beginp->name());
|
||||
}
|
||||
|
||||
if (nodep->op1p()) addPrefixToBlocksRecurse(nodep->op1p());
|
||||
if (nodep->op2p()) addPrefixToBlocksRecurse(nodep->op2p());
|
||||
if (nodep->op3p()) addPrefixToBlocksRecurse(nodep->op3p());
|
||||
if (nodep->op4p()) addPrefixToBlocksRecurse(nodep->op4p());
|
||||
if (nodep->nextp()) addPrefixToBlocksRecurse(nodep->nextp());
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
@ -200,23 +213,21 @@ private:
|
||||
void visit(AstDoWhile* nodep) override {
|
||||
// It is converted to AstWhile in this visit method
|
||||
VL_RESTORER(m_loopp);
|
||||
VL_RESTORER(m_loopInc);
|
||||
{
|
||||
m_loopp = nodep;
|
||||
m_loopInc = false;
|
||||
iterateAndNextNull(nodep->precondsp());
|
||||
iterateAndNextNull(nodep->condp());
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
m_loopInc = true;
|
||||
iterateAndNextNull(nodep->incsp());
|
||||
}
|
||||
AstNodeExpr* const condp = nodep->condp() ? nodep->condp()->unlinkFrBack() : nullptr;
|
||||
AstNode* const bodyp = nodep->stmtsp() ? nodep->stmtsp()->unlinkFrBack() : nullptr;
|
||||
AstNode* const incsp = nodep->incsp() ? nodep->incsp()->unlinkFrBack() : nullptr;
|
||||
AstWhile* const whilep = new AstWhile{nodep->fileline(), condp, bodyp, incsp};
|
||||
AstWhile* const whilep = new AstWhile{nodep->fileline(), condp, bodyp};
|
||||
nodep->replaceWith(whilep);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
if (bodyp) whilep->addHereThisAsNext(bodyp->cloneTree(false));
|
||||
if (bodyp) {
|
||||
AstNode* const copiedBodyp = bodyp->cloneTree(false);
|
||||
addPrefixToBlocksRecurse(copiedBodyp);
|
||||
whilep->addHereThisAsNext(copiedBodyp);
|
||||
}
|
||||
}
|
||||
void visit(AstForeach* nodep) override {
|
||||
VL_RESTORER(m_loopp);
|
||||
|
21
test_regress/t/t_do_while.pl
Executable file
21
test_regress/t/t_do_while.pl
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2020 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(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
58
test_regress/t/t_do_while.v
Normal file
58
test_regress/t/t_do_while.v
Normal file
@ -0,0 +1,58 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2023 by Antmicro Ltd.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
function automatic int get_1;
|
||||
int a = 0;
|
||||
do begin
|
||||
int x = 1;
|
||||
a += x;
|
||||
end while (a < 0);
|
||||
return a;
|
||||
endfunction
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
int a;
|
||||
initial begin
|
||||
if (get_1() != 1) $stop;
|
||||
|
||||
a = 0;
|
||||
do begin
|
||||
int x = 1;
|
||||
a += x;
|
||||
if (a == 1) begin
|
||||
a = 2;
|
||||
end
|
||||
end while (a < 0);
|
||||
if (a != 2) $stop;
|
||||
|
||||
a = 1;
|
||||
do begin
|
||||
if (a == 1) begin
|
||||
a = 2;
|
||||
end
|
||||
if (a == 2) begin
|
||||
a = 3;
|
||||
end
|
||||
end while (a < 0);
|
||||
if (a != 3) $stop;
|
||||
|
||||
a = 1;
|
||||
do begin
|
||||
if (a == 1) begin
|
||||
do begin
|
||||
a++;
|
||||
end while (a < 5);
|
||||
end
|
||||
if (a == 2) begin
|
||||
a = 3;
|
||||
end
|
||||
end while (a < 0);
|
||||
if (a != 5) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user