From a4813ec67768a15a46955579618407e61a08ee18 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 1 Mar 2024 17:28:12 -0500 Subject: [PATCH] Add warning on TOP-named modules (#4935). --- Changes | 1 + src/V3LinkParse.cpp | 5 +++++ test_regress/t/t_lint_top_bad.out | 5 +++++ test_regress/t/t_lint_top_bad.pl | 20 +++++++++++++++++++ test_regress/t/t_lint_top_bad.v | 33 +++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+) create mode 100644 test_regress/t/t_lint_top_bad.out create mode 100755 test_regress/t/t_lint_top_bad.pl create mode 100644 test_regress/t/t_lint_top_bad.v diff --git a/Changes b/Changes index 180a6bc05..c795078c2 100644 --- a/Changes +++ b/Changes @@ -13,6 +13,7 @@ Verilator 5.023 devel **Minor:** +* Add warning on 'TOP'-named modules (#4935). [Yanglin Xun] * Fix invalid cast on string structure creation (#4921). [esynr3z] diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 275608f98..38848e5cf 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -642,6 +642,11 @@ class LinkParseVisitor final : public VNVisitor { if (m_lifetime.isNone()) { m_lifetime = VN_IS(nodep, Class) ? VLifetime::AUTOMATIC : VLifetime::STATIC; } + if (nodep->name() == "TOP") { + // May mess up scope resolution and cause infinite loop + nodep->v3warn(E_UNSUPPORTED, "Module cannot be named 'TOP' as conflicts with " + "Verilator top-level internals"); + } iterateChildren(nodep); } m_valueModp = nodep; diff --git a/test_regress/t/t_lint_top_bad.out b/test_regress/t/t_lint_top_bad.out new file mode 100644 index 000000000..a0c6fa716 --- /dev/null +++ b/test_regress/t/t_lint_top_bad.out @@ -0,0 +1,5 @@ +%Error-UNSUPPORTED: t/t_lint_top_bad.v:14:8: Module cannot be named 'TOP' as conflicts with Verilator top-level internals + 14 | module TOP( + | ^~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_lint_top_bad.pl b/test_regress/t/t_lint_top_bad.pl new file mode 100755 index 000000000..b1d44e6a9 --- /dev/null +++ b/test_regress/t/t_lint_top_bad.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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(vlt => 1); + +compile( + verilator_flags2 => ['-O0 --trace-fst'], + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_lint_top_bad.v b/test_regress/t/t_lint_top_bad.v new file mode 100644 index 000000000..9b35bc7e1 --- /dev/null +++ b/test_regress/t/t_lint_top_bad.v @@ -0,0 +1,33 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module sub(input wire clk, cpu_reset); + reg reset_r; + always @(posedge clk) begin + reset_r <= cpu_reset; // The problematic one + end +endmodule + +module TOP(/*AUTOARG*/ + // Inputs + clk, reset_l + ); + + input clk; + input reset_l; + + reg sync_0, sync_1, sync_2; + wire _cpu_reset_chain_io_q = sync_0; + + sub sub (.clk(clk), + .cpu_reset(_cpu_reset_chain_io_q | !reset_l)); + + always @(posedge clk) begin + sync_0 <= sync_1; + sync_1 <= sync_2; + sync_2 <= !reset_l; + end +endmodule