From 758264dc7729e7e270e38b34548f7a80acd10600 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 1 Nov 2021 08:59:00 -0400 Subject: [PATCH] Fix nested generate if genblk naming (#3189). --- Changes | 1 + src/V3LinkParse.cpp | 31 +++++++++++++++++++++++------- test_regress/t/t_gen_ifelse.pl | 21 ++++++++++++++++++++ test_regress/t/t_gen_ifelse.v | 35 ++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 7 deletions(-) create mode 100755 test_regress/t/t_gen_ifelse.pl create mode 100644 test_regress/t/t_gen_ifelse.v diff --git a/Changes b/Changes index 8f6484fc0..809d45d07 100644 --- a/Changes +++ b/Changes @@ -16,6 +16,7 @@ Verilator 4.215 devel * Internal code cleanups and improvements. [Geza Lore] * Fix array method names with parens (#3181) (#3183). [Teng Huang] * Fix split_var assign merging (#3177) (#3179). [Yutetsu TAKATSUKASA] +* Fix nested generate if genblk naming (#3189). [yanx21] Verilator 4.214 2021-10-17 diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 49c0c3e9d..be349ee45 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -105,6 +105,21 @@ private: } } + bool nestedIfBegin(AstBegin* nodep) { // Point at begin inside the GenIf + // IEEE says directly nested item is not a new block + // The genblk name will get attached to the if true/false LOWER begin block(s) + // 1: GENIF + // -> 1:3: BEGIN [GEN] [IMPLIED] // nodep passed to this function + // 1:3:1: GENIF + // 1:3:1:2: BEGIN genblk1 [GEN] [IMPLIED] + AstNode* const backp = nodep->backp(); + return (nodep->implied() // User didn't provide begin/end + && VN_IS(backp, GenIf) && VN_CAST(backp, GenIf)->elsesp() == nodep + && !nodep->nextp() // No other statements under upper genif else + && (VN_IS(nodep->stmtsp(), GenIf)) // Begin has if underneath + && !nodep->stmtsp()->nextp()); // Has only one item + } + // VISITs virtual void visit(AstNodeFTask* nodep) override { if (!nodep->user1SetOnce()) { // Process only once. @@ -539,12 +554,10 @@ private: virtual void visit(AstBegin* nodep) override { V3Config::applyCoverageBlock(m_modp, nodep); cleanFileline(nodep); - AstNode* backp = nodep->backp(); + AstNode* const backp = nodep->backp(); // IEEE says directly nested item is not a new block - const bool nestedIf = (nodep->implied() // User didn't provide begin/end - && (VN_IS(nodep->stmtsp(), GenIf) - || VN_IS(nodep->stmtsp(), GenCase)) // Has an if/case - && !nodep->stmtsp()->nextp()); // Has only one item + // The genblk name will get attached to the if true/false LOWER begin block(s) + const bool nestedIf = nestedIfBegin(nodep); // It's not FOR(BEGIN(...)) but we earlier changed it to BEGIN(FOR(...)) if (nodep->genforp()) { ++m_genblkNum; @@ -576,9 +589,13 @@ private: } } virtual void visit(AstGenIf* nodep) override { - ++m_genblkNum; cleanFileline(nodep); - { + bool nestedIf + = (VN_IS(nodep->backp(), Begin) && nestedIfBegin(VN_CAST(nodep->backp(), Begin))); + if (nestedIf) { + iterateChildren(nodep); + } else { + ++m_genblkNum; VL_RESTORER(m_genblkAbove); VL_RESTORER(m_genblkNum); m_genblkAbove = m_genblkNum; diff --git a/test_regress/t/t_gen_ifelse.pl b/test_regress/t/t_gen_ifelse.pl new file mode 100755 index 000000000..2cb5eeaff --- /dev/null +++ b/test_regress/t/t_gen_ifelse.pl @@ -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 2021 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; diff --git a/test_regress/t/t_gen_ifelse.v b/test_regress/t/t_gen_ifelse.v new file mode 100644 index 000000000..c23565d85 --- /dev/null +++ b/test_regress/t/t_gen_ifelse.v @@ -0,0 +1,35 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2021 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module s; + parameter A = 0; + generate + if (A == 1) + int i; + else if (A == 2) + int i; + else + int i; + endgenerate + generate + if (A == 1) + int i; + else if (A == 2) + int i; + else + int i; + endgenerate +endmodule + +module t; + s #(0) s0(); + s #(1) s1(); + s #(2) s2(); + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule