diff --git a/Changes b/Changes index 6f07c10f1..84fda223b 100644 --- a/Changes +++ b/Changes @@ -37,6 +37,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Add --bbox-unsup option to black-box unsupported UDP tables. +**** Add -Wno-MODDUP option to allow duplicate modules. + **** Fix creating implicit variables for expressions, bug196. [Byron Bradley] **** Fix tracing with --pins-bv 1, bug195. [Michael S] diff --git a/bin/verilator b/bin/verilator index 0b72a26f1..1b3368287 100755 --- a/bin/verilator +++ b/bin/verilator @@ -2102,6 +2102,13 @@ intent. Ignoring this warning will only suppress the lint check, it will simulate correctly. +=item MODDUP + +Error that a module has multiple definitions. Generally this indicates a +coding error, or a mistake in a library file and it's good practice to have +one module per file to avoid these issues. For some gate level netlists +duplicates are unavoidable, and this error may be disabled. + =item MULTIDRIVEN Warns that the specified signal comes from multiple always blocks. This is diff --git a/src/V3Error.h b/src/V3Error.h index ab0f150f0..8303adb1b 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -66,6 +66,7 @@ public: IMPLICIT, // Implicit wire IMPURE, // Impure function not being inlined LITENDIAN, // Little bit endian vector + MODDUP, // Duplicate module MULTIDRIVEN, // Driven from multiple blocks REDEFMACRO, // Redefining existing define macro UNDRIVEN, // No drivers @@ -98,7 +99,7 @@ public: "BLKANDNBLK", "CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CMPCONST", "COMBDLY", "STMTDLY", "SYMRSVDWORD", "GENCLK", "IMPERFECTSCH", "IMPLICIT", "IMPURE", - "LITENDIAN", + "LITENDIAN", "MODDUP", "MULTIDRIVEN", "REDEFMACRO", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED", "VARHIDDEN", "WIDTH", "WIDTHCONCAT", @@ -112,7 +113,7 @@ public: bool dangerous() const { return ( m_e==COMBDLY ); } // Warnings we'll present to the user as errors // Later -Werror- options may make more of these. - bool pretendError() const { return ( m_e==BLKANDNBLK || m_e==IMPURE || m_e==SYMRSVDWORD); } + bool pretendError() const { return ( m_e==BLKANDNBLK || m_e==IMPURE || m_e==MODDUP || m_e==SYMRSVDWORD); } // Warnings to mention manual bool mentionManual() const { return ( m_e==FATALSRC || pretendError() ); } diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 29fb0d46d..fc45ee4b7 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -250,11 +250,15 @@ private: // METHODS void readModNames() { // Look at all modules, and store pointers to all module names - for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) { + for (AstNodeModule* nextp,* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nextp) { + nextp = nodep->nextp()->castNodeModule(); AstNode* foundp = m_mods.findIdUpward(nodep->name()); if (foundp && foundp != nodep) { - nodep->v3error("Duplicate declaration of module: "<prettyName()); - foundp->v3error("... Location of original declaration"); + if (!(foundp->fileline()->warnIsOff(V3ErrorCode::MODDUP) || nodep->fileline()->warnIsOff(V3ErrorCode::MODDUP))) { + nodep->v3warn(MODDUP,"Duplicate declaration of module: "<prettyName()); + foundp->v3warn(MODDUP,"... Location of original declaration"); + } + nodep->unlinkFrBack()->deleteTree(); } else if (!foundp) { m_mods.insert(nodep->name(), nodep); } diff --git a/test_regress/t/t_mod_dup_bad.pl b/test_regress/t/t_mod_dup_bad.pl index 7f4b57004..de99944e2 100755 --- a/test_regress/t/t_mod_dup_bad.pl +++ b/test_regress/t/t_mod_dup_bad.pl @@ -11,8 +11,8 @@ compile ( fails=>$Self->{v3}, nc=>0, # Need to get it not to give the prompt expect=> -'%Error: t/t_mod_dup_bad.v:\d+: Duplicate declaration of module: a -%Error: t/t_mod_dup_bad.v:\d+: ... Location of original declaration +'%Error-MODDUP: t/t_mod_dup_bad.v:\d+: Duplicate declaration of module: a +%Error-MODDUP: t/t_mod_dup_bad.v:\d+: ... Location of original declaration .* %Error: Exiting due to.*', ) if $Self->{v3}; diff --git a/test_regress/t/t_mod_dup_ign.pl b/test_regress/t/t_mod_dup_ign.pl new file mode 100755 index 000000000..acfee1103 --- /dev/null +++ b/test_regress/t/t_mod_dup_ign.pl @@ -0,0 +1,18 @@ +#!/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 ( + make_top_shell => 0, + make_main => 0, + v_flags2 => ["--lint-only"], + verilator_make_gcc => 0, + ); + +ok(1); +1; diff --git a/test_regress/t/t_mod_dup_ign.v b/test_regress/t/t_mod_dup_ign.v new file mode 100644 index 000000000..7283d0889 --- /dev/null +++ b/test_regress/t/t_mod_dup_ign.v @@ -0,0 +1,23 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2010 by Wilson Snyder. + +module t; + sub sub (); +endmodule + +module sub; + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule + +// verilator lint_off MODDUP +module sub; + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule