diff --git a/Changes b/Changes index 0d2803490..97b65dc0d 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks! * Verilator 3.81*** +**** Report errors on duplicated pins, bug321. [Christian Leber] + **** Throw UNUSED/UNDRIVEN only once per net in a parametrized module. **** Fix false BLKSEQ on non-unrolled for loop indexes. [Jeff Winston] diff --git a/TODO b/TODO index adaf3a994..222e4de25 100644 --- a/TODO +++ b/TODO @@ -67,6 +67,10 @@ Usability: #### non-comment lines, ##### ops, ### KB model size * Default the --l2name to remove extra "v" level of hierarchy (flag to make "top") +Lint: + * CDCRSTLOGIC should allow filtering with paths + "waive CDCRSTLOGIC --from a.b.sig --to a.c.sig --via OR" + Internal Code: * Eliminate the AstNUser* passed to all visitors; its only needed in V3Width, and removing it will speed up and simplify all the other code. diff --git a/src/V3Link.cpp b/src/V3Link.cpp index a76619bdd..72152f781 100644 --- a/src/V3Link.cpp +++ b/src/V3Link.cpp @@ -55,9 +55,11 @@ private: // AstNodeModule::user4p() // V3SymTable* Module's Symbol table // AstNodeFTask::user4p() // V3SymTable* Local Symbol table // AstBegin::user4p() // V3SymTable* Local Symbol table + // AstVar::user5p() // AstPin* True if port attached to a pin AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; AstUser4InUse m_inuser4; + AstUser5InUse m_inuser5; // ENUMS enum IdState { // Which loop through the tree @@ -551,6 +553,7 @@ private: virtual void visit(AstCell* nodep, AstNUser*) { // Cell: Resolve its filename. If necessary, parse it. m_cellp = nodep; + AstNode::user5ClearTree(); if (m_idState==ID_FIND) { // Add to list of all cells, for error checking and defparam's findAndInsertAndCheck(nodep, nodep->name()); @@ -635,6 +638,12 @@ private: nodep->v3error("Pin is not an in/out/inout/param: "<prettyName()); } else { nodep->modVarp(refp); + if (refp->user5p() && refp->user5p()->castNode()!=nodep) { + nodep->v3error("Duplicate pin connection: "<prettyName()); + refp->user5p()->castNode()->v3error("... Location of original pin connection"); + } else { + refp->user5p(nodep); + } } nodep->iterateChildren(*this); } diff --git a/test_regress/t/t_lint_pindup_bad.pl b/test_regress/t/t_lint_pindup_bad.pl new file mode 100755 index 000000000..4c453fad1 --- /dev/null +++ b/test_regress/t/t_lint_pindup_bad.pl @@ -0,0 +1,25 @@ +#!/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 ( + v_flags2 => ["--lint-only"], + fails=>1, + verilator_make_gcc => 0, + make_top_shell => 0, + make_main => 0, + expect=> +'%Error: t/t_lint_pindup_bad.v:\d+: Duplicate pin connection: i +%Error: t/t_lint_pindup_bad.v:\d+: ... Location of original pin connection +%Error: t/t_lint_pindup_bad.v:\d+: Duplicate pin connection: P +%Error: t/t_lint_pindup_bad.v:\d+: ... Location of original pin connection +%Error: Exiting due to.*', + ) if $Self->{v3}; + +ok(1); +1; diff --git a/test_regress/t/t_lint_pindup_bad.v b/test_regress/t/t_lint_pindup_bad.v new file mode 100644 index 000000000..167627b99 --- /dev/null +++ b/test_regress/t/t_lint_pindup_bad.v @@ -0,0 +1,31 @@ +// 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 + ( + output wire o, + input wire i, + input wire i2 + ); + + sub + #(.P(2), .P(3)) + sub (.o(o), + .i(i), + .i(i2), + ); + +endmodule + +module sub + #(parameter P=1) + ( + output wire o, + input wire i + ); + + assign o = ~i; + +endmodule