From 9cc218db3eaa1b275f89714c0e8e371b96e500ca Mon Sep 17 00:00:00 2001 From: Adrien Le Masle <14968086+adrienlemasle@users.noreply.github.com> Date: Thu, 1 Jun 2023 13:43:17 +0100 Subject: [PATCH] Fix incorrect multi-driven lint warning (#4231) (#4248) --- src/V3DfgAstToDfg.cpp | 25 +++++----- test_regress/t/t_incorrect_multi_driven.pl | 21 ++++++++ test_regress/t/t_incorrect_multi_driven.v | 56 ++++++++++++++++++++++ 3 files changed, 91 insertions(+), 11 deletions(-) create mode 100755 test_regress/t/t_incorrect_multi_driven.pl create mode 100644 test_regress/t/t_incorrect_multi_driven.v diff --git a/src/V3DfgAstToDfg.cpp b/src/V3DfgAstToDfg.cpp index 78a598742..da265a1ff 100644 --- a/src/V3DfgAstToDfg.cpp +++ b/src/V3DfgAstToDfg.cpp @@ -334,17 +334,20 @@ class AstToDfgVisitor final : public VNVisitor { const uint32_t bEnd = b.m_lsb + bWidth; const uint32_t overlapEnd = std::min(aEnd, bEnd) - 1; - varp->varp()->v3warn( // - MULTIDRIVEN, - "Bits [" // - << overlapEnd << ":" << b.m_lsb << "] of signal " - << varp->varp()->prettyNameQ() - << " have multiple combinational drivers\n" - << a.m_fileline->warnOther() << "... Location of first driver\n" - << a.m_fileline->warnContextPrimary() << '\n' - << b.m_fileline->warnOther() << "... Location of other driver\n" - << b.m_fileline->warnContextSecondary() << varp->varp()->warnOther() - << "... Only the first driver will be respected"); + if (a.m_fileline->operatorCompare(*b.m_fileline) != 0) { + varp->varp()->v3warn( // + MULTIDRIVEN, + "Bits [" // + << overlapEnd << ":" << b.m_lsb << "] of signal " + << varp->varp()->prettyNameQ() + << " have multiple combinational drivers\n" + << a.m_fileline->warnOther() << "... Location of first driver\n" + << a.m_fileline->warnContextPrimary() << '\n' + << b.m_fileline->warnOther() << "... Location of other driver\n" + << b.m_fileline->warnContextSecondary() + << varp->varp()->warnOther() + << "... Only the first driver will be respected"); + } // If the first driver completely covers the range of the second driver, // we can just delete the second driver completely, otherwise adjust the diff --git a/test_regress/t/t_incorrect_multi_driven.pl b/test_regress/t/t_incorrect_multi_driven.pl new file mode 100755 index 000000000..0fc71f8e9 --- /dev/null +++ b/test_regress/t/t_incorrect_multi_driven.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 2023 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(linter => 1); + +top_filename("t/t_incorrect_multi_driven.v"); + +lint( + fails => 0 + ); + +ok(1); +1; diff --git a/test_regress/t/t_incorrect_multi_driven.v b/test_regress/t/t_incorrect_multi_driven.v new file mode 100644 index 000000000..3020398db --- /dev/null +++ b/test_regress/t/t_incorrect_multi_driven.v @@ -0,0 +1,56 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2023 by Adrien Le Masle. +// SPDX-License-Identifier: CC0-1.0 + +interface test_if #(parameter int AA = 2, BB=5); + + logic [AA-1 : 0] a; + logic [BB-1 : 0] b; + logic c; + logic d; + + modport slave (input a, + input b, + input c, + input d); + + modport master (output a, + output b, + output c, + output d); + +endinterface : test_if + +module test + (input logic [28:0] a, + output logic [28:0] b); + + always_comb begin + b = a; + end +endmodule + +module multi_driven + ( + input logic [20-1 : 0] data_in, + output logic [20-1 : 0] data_out, + test_if.slave test_if_in, + test_if.master test_if_out + ); + + test test_inst + ( + .a({data_in, + test_if_in.a, + test_if_in.b, + test_if_in.c, + test_if_in.d}), + .b({data_out, + test_if_out.a, + test_if_out.b, + test_if_out.c, + test_if_out.d})); + +endmodule;