From e4c5eb5e69ddaf16f024d2b0939f706420466e89 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 1 Jan 2022 18:37:34 -0500 Subject: [PATCH] Fix spurious UNUSED by ignoring inout pin connections (#3242). --- Changes | 1 + src/V3Undriven.cpp | 14 +++++++++++++- test_regress/t/t_lint_unused_tri.pl | 18 ++++++++++++++++++ test_regress/t/t_lint_unused_tri.v | 26 ++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_lint_unused_tri.pl create mode 100644 test_regress/t/t_lint_unused_tri.v diff --git a/Changes b/Changes index e699ac150..1c8de8ffb 100644 --- a/Changes +++ b/Changes @@ -33,6 +33,7 @@ Verilator 4.217 devel * Fix associative array foreach loop (#3229). * Fix $fclose not accepting expressions (#3237). [Julie Schwartz] * Fix $random not updating seed (#3238). [Julie Schwartz] +* Fix spurious UNUSED by ignoring inout pin connections (#3242). [Julie Schwartz] * Fix splitting of _eval and other top level functions. [Geza Lore, Shunyao CAD] diff --git a/src/V3Undriven.cpp b/src/V3Undriven.cpp index be909a9e8..4618af23c 100644 --- a/src/V3Undriven.cpp +++ b/src/V3Undriven.cpp @@ -250,6 +250,7 @@ private: bool m_inBBox = false; // In black box; mark as driven+used bool m_inContAssign = false; // In continuous assignment bool m_inProcAssign = false; // In procedural assignment + bool m_inInoutPin = false; // Connected to pin that is inout const AstNodeFTask* m_taskp = nullptr; // Current task const AstAlways* m_alwaysCombp = nullptr; // Current always if combo, otherwise nullptr @@ -374,7 +375,13 @@ private: } entryp->drivenWhole(); } - if (m_inBBox || nodep->access().isReadOrRW() || fdrv) entryp->usedWhole(); + if (m_inBBox || nodep->access().isReadOrRW() + || fdrv + // Inouts have only isWrite set, as we don't have more + // information and operating on module boundry, treat as + // both read and writing + || m_inInoutPin) + entryp->usedWhole(); } } @@ -430,6 +437,11 @@ private: iterateChildren(nodep); } } + virtual void visit(AstPin* nodep) override { + VL_RESTORER(m_inInoutPin); + m_inInoutPin = nodep->modVarp()->isInoutish(); + iterateChildren(nodep); + } // Until we support tables, primitives will have undriven and unused I/Os virtual void visit(AstPrimitive*) override {} diff --git a/test_regress/t/t_lint_unused_tri.pl b/test_regress/t/t_lint_unused_tri.pl new file mode 100755 index 000000000..3679f5264 --- /dev/null +++ b/test_regress/t/t_lint_unused_tri.pl @@ -0,0 +1,18 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2008 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); + +lint( + verilator_flags2 => ["--lint-only -Wall -Wno-DECLFILENAME"], + ); + +ok(1); +1; diff --git a/test_regress/t/t_lint_unused_tri.v b/test_regress/t/t_lint_unused_tri.v new file mode 100644 index 000000000..4d2646a00 --- /dev/null +++ b/test_regress/t/t_lint_unused_tri.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2022 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module Receiver(in); + inout [31:0] in; + always @(in) $display(in); +endmodule + +module Sender(out); + inout [31:0] out; + assign out = 12; +endmodule + +module t; + // ports of submodule recv + tri [31 : 0] recvIn; + + // submodule recv + Receiver recv(.in(recvIn)); + + // submodule send + Sender send(.out(recvIn)); +endmodule