From 38988c005c89d9f4f0dd9f014f49733f6b13f79c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 14 Nov 2017 20:10:25 -0500 Subject: [PATCH] Fix false unused warning on interfaces, bug1241. --- Changes | 2 + src/V3Undriven.cpp | 12 +++-- test_regress/t/t_lint_unused_iface.pl | 20 ++++++++ test_regress/t/t_lint_unused_iface.v | 59 +++++++++++++++++++++++ test_regress/t/t_lint_unused_iface_bad.pl | 27 +++++++++++ test_regress/t/t_lint_unused_iface_bad.v | 28 +++++++++++ 6 files changed, 144 insertions(+), 4 deletions(-) create mode 100755 test_regress/t/t_lint_unused_iface.pl create mode 100644 test_regress/t/t_lint_unused_iface.v create mode 100755 test_regress/t/t_lint_unused_iface_bad.pl create mode 100644 test_regress/t/t_lint_unused_iface_bad.v diff --git a/Changes b/Changes index df91dd47a..9c30a88e2 100644 --- a/Changes +++ b/Changes @@ -12,6 +12,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Add error when driving input-only modport. +**** Fix false unused warning on interfaces, bug1241. [Laurens van Dam] + * Verilator 3.914 2017-10-14 diff --git a/src/V3Undriven.cpp b/src/V3Undriven.cpp index da4072b4c..e4787a81a 100644 --- a/src/V3Undriven.cpp +++ b/src/V3Undriven.cpp @@ -175,7 +175,11 @@ public: if (allU) m_usedWhole = true; if (allD) m_drivenWhole = true; // Test results - if (allU && allD) { + if (nodep->isIfaceRef()) { + // For interface top level we don't do any tracking + // Ideally we'd report unused instance cells, but presumably a signal inside one + // would get reported as unused + } else if (allU && allD) { // It's fine } else if (!anyD && !anyU) { // UNDRIVEN is considered more serious - as is more likely a bug, @@ -258,7 +262,7 @@ private: } } - void warnAlwCombOrder(AstVarRef* nodep) { + void warnAlwCombOrder(AstNodeVarRef* nodep) { AstVar* varp = nodep->varp(); if (!varp->isParam() && !varp->isGenVar() && !varp->isUsedLoopIdx() && !m_inBBox // We may have falsely considered a SysIgnore as a driver @@ -292,7 +296,7 @@ private: nodep->iterateChildren(*this); } virtual void visit(AstSel* nodep) { - AstVarRef* varrefp = nodep->fromp()->castVarRef(); + AstNodeVarRef* varrefp = nodep->fromp()->castNodeVarRef(); AstConst* constp = nodep->lsbp()->castConst(); if (varrefp && constp && !constp->num().isFourState()) { for (int usr=1; usr<(m_alwaysp?3:2); ++usr) { @@ -313,7 +317,7 @@ private: nodep->iterateChildren(*this); } } - virtual void visit(AstVarRef* nodep) { + virtual void visit(AstNodeVarRef* nodep) { // Any variable for (int usr=1; usr<(m_alwaysp?3:2); ++usr) { UndrivenVarEntry* entryp = getEntryp (nodep->varp(), usr); diff --git a/test_regress/t/t_lint_unused_iface.pl b/test_regress/t/t_lint_unused_iface.pl new file mode 100755 index 000000000..6fff7520d --- /dev/null +++ b/test_regress/t/t_lint_unused_iface.pl @@ -0,0 +1,20 @@ +#!/usr/bin/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. + +compile ( + verilator_flags2 => ["--lint-only -Wall -Wno-DECLFILENAME"], + fails=>0, + verilator_make_gcc => 0, + make_top_shell => 0, + make_main => 0, + ); + +ok(1); +1; + diff --git a/test_regress/t/t_lint_unused_iface.v b/test_regress/t/t_lint_unused_iface.v new file mode 100644 index 000000000..cef438658 --- /dev/null +++ b/test_regress/t/t_lint_unused_iface.v @@ -0,0 +1,59 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2017 by Wilson Snyder. + +interface dummy_if (); + logic signal; + + modport slave + ( + input signal + ); + + modport master + ( + output signal + ); +endinterface: dummy_if + +module sub + ( + input wire signal_i, + output wire signal_o, + + dummy_if.master dummy_in, + dummy_if.slave dummy_out + ); + + assign dummy_in.signal = signal_i; + assign signal_o = dummy_out.signal; +endmodule + + +module t (/*AUTOARG*/ + // Outputs + signal_o, + // Inputs + signal_i + ); + input signal_i; + output signal_o; + + // verila tor lint_off UUSD + // verila tor lint_off UNDRIVEN + dummy_if dummy_if (); + // verila tor lint_on UUSD + // verila tor lint_on UNDRIVEN + + dummy_if uusd_if (); + + sub sub + ( + .signal_i(signal_i), + .signal_o(signal_o), + .dummy_in(dummy_if), + .dummy_out(dummy_if) + ); + +endmodule diff --git a/test_regress/t/t_lint_unused_iface_bad.pl b/test_regress/t/t_lint_unused_iface_bad.pl new file mode 100755 index 000000000..0b7b75685 --- /dev/null +++ b/test_regress/t/t_lint_unused_iface_bad.pl @@ -0,0 +1,27 @@ +#!/usr/bin/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. + +$Self->{vlt} or $Self->skip("Verilator only test"); + +compile ( + verilator_flags2 => ["--lint-only -Wall -Wno-DECLFILENAME"], + fails=>1, + verilator_make_gcc => 0, + make_top_shell => 0, + make_main => 0, + expect => +'%Warning-UNDRIVEN: t/t_lint_unused_iface_bad.v:\d+: Signal is not driven: sig_udrv +%Warning-UNDRIVEN: Use .* +%Warning-UNUSED: t/t_lint_unused_iface_bad.v:\d+: Signal is not used: sig_uusd +%Error: Exiting due to .*', + ); + +ok(1); +1; + diff --git a/test_regress/t/t_lint_unused_iface_bad.v b/test_regress/t/t_lint_unused_iface_bad.v new file mode 100644 index 000000000..92edeee1a --- /dev/null +++ b/test_regress/t/t_lint_unused_iface_bad.v @@ -0,0 +1,28 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2017 by Wilson Snyder. + +interface dummy_if (); + logic sig_udrv; + logic sig_uusd; +endinterface: dummy_if + +module sub + ( + dummy_if dummy + ); + + assign dummy.sig_uusd = 1'b0 | dummy.sig_udrv; +endmodule + + +module t (/*AUTOARG*/); + + dummy_if dummy (); + + sub sub + (.dummy(dummy) + ); + +endmodule