diff --git a/Changes b/Changes index c0a4e143e..ad96861a0 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,8 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Add +verilator+seed, bug1396. [Stan Sokorac] +**** Report PORTSHORT errors on concat constants, bug 1400. [Will Korteland] + **** Fix VERILATOR_GDB being ignored, msg2860. [Yu Sheng Lin] **** Fix $value$plus$args missing verilated_heavy.h. [Yi-Chung Chen] diff --git a/src/V3Error.h b/src/V3Error.h index 1289aae78..a2761299d 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -49,8 +49,9 @@ public: I_DEF_NETTYPE_WIRE, // `default_nettype is WIRE (false=NONE) // Error codes: E_DETECTARRAY, // Error: Unsupported: Can't detect changes on arrayed variable - E_MULTITOP, // Error: Multiple top level modules - E_TASKNSVAR, // Error: Task I/O not simple + E_MULTITOP, // Error: Multiple top level modules + E_PORTSHORT, // Error: Output port is connected to a constant, electrical short + E_TASKNSVAR, // Error: Task I/O not simple // // Warning codes: EC_FIRST_WARN, // Just a code so the program knows where to start warnings @@ -128,9 +129,9 @@ public: " MIN", " INFO", " FATAL", " FATALSRC", " ERROR", // Boolean " I_COVERAGE", " I_TRACING", " I_LINT", " I_DEF_NETTYPE_WIRE", - // Errors - "DETECTARRAY", "MULTITOP", "TASKNSVAR", - // Warnings + // Errors + "DETECTARRAY", "MULTITOP", "PORTSHORT", "TASKNSVAR", + // Warnings " EC_FIRST_WARN", "ALWCOMBORDER", "ASSIGNDLY", "ASSIGNIN", "BLKANDNBLK", "BLKLOOPINIT", "BLKSEQ", "BSSPACE", diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index d92b9eaa7..0b19e6443 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -550,14 +550,11 @@ private: AstVar* pinNewVarp = pinOldVarp->clonep(); if (!pinNewVarp) pinOldVarp->v3fatalSrc("Cloning failed"); - AstNode* connectRefp = pinp->exprp(); + AstNode* connectRefp = pinp->exprp(); if (!VN_IS(connectRefp, Const) && !VN_IS(connectRefp, VarRef)) { pinp->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up"); } - if (pinNewVarp->direction() == VDirection::OUTPUT - && VN_IS(connectRefp, Const)) { - pinp->v3error("Output port is connected to a constant pin, electrical short"); - } + V3Inst::checkOutputShort(pinp); // Propagate any attributes across the interconnect pinNewVarp->propagateAttrFrom(pinOldVarp); diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index 549ca10bc..4e1bf4c7e 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -68,10 +68,7 @@ private: UINFO(4," PIN "<exprp()) return; // No-connect if (debug()>=9) nodep->dumpTree(cout," Pin_oldb: "); - if (nodep->modVarp()->direction() == VDirection::OUTPUT - && VN_IS(nodep->exprp(), Const)) { - nodep->v3error("Output port is connected to a constant pin, electrical short"); - } + V3Inst::checkOutputShort(nodep); // Use user1p on the PIN to indicate we created an assign for this pin if (!nodep->user1SetOnce()) { // Simplify it @@ -513,8 +510,9 @@ public: // Done. Constant. } else { // Make a new temp wire - //if (1||debug()>=9) { pinp->dumpTree(cout,"-in_pin:"); } - AstNode* pinexprp = pinp->exprp()->unlinkFrBack(); + //if (1||debug()>=9) { pinp->dumpTree(cout,"-in_pin:"); } + V3Inst::checkOutputShort(pinp); + AstNode* pinexprp = pinp->exprp()->unlinkFrBack(); string newvarname = (string(pinVarp->isWritable() ? "__Vcellout" : "__Vcellinp") // Prevent name conflict if both tri & non-tri add signals +(forTristate?"t":"") @@ -555,10 +553,23 @@ public: // Inst class functions AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, - bool forTristate, bool alwaysCvt) { + bool forTristate, bool alwaysCvt) { return InstStatic::pinReconnectSimple(pinp, cellp, forTristate, alwaysCvt); } +void V3Inst::checkOutputShort(AstPin* nodep) { + if (nodep->modVarp()->direction() == VDirection::OUTPUT) { + if (VN_IS(nodep->exprp(), Const) + || VN_IS(nodep->exprp(), Extend) + || (VN_IS(nodep->exprp(), Concat) + && (VN_IS(VN_CAST(nodep->exprp(), Concat)->lhsp(), Const)))) { + // Uses v3warn for error, as might be found multiple times + nodep->v3warn(E_PORTSHORT, "Output port is connected to a constant pin," + " electrical short"); + } + } +} + //###################################################################### // Inst class visitor diff --git a/src/V3Inst.h b/src/V3Inst.h index 56b6374d4..0ee6e3528 100644 --- a/src/V3Inst.h +++ b/src/V3Inst.h @@ -35,6 +35,7 @@ public: static void dearrayAll(AstNetlist* nodep); static AstAssignW* pinReconnectSimple(AstPin* pinp, AstCell* cellp, bool forTristate, bool alwaysCvt=false); + static void checkOutputShort(AstPin* nodep); }; #endif // Guard diff --git a/test_regress/t/t_lint_setout_bad.out b/test_regress/t/t_lint_setout_bad.out new file mode 100644 index 000000000..aa43238fb --- /dev/null +++ b/test_regress/t/t_lint_setout_bad.out @@ -0,0 +1,2 @@ +%Error-PORTSHORT: t/t_lint_setout_bad.v:16: Output port is connected to a constant pin, electrical short +%Error: Exiting due to diff --git a/test_regress/t/t_lint_setout_bad.pl b/test_regress/t/t_lint_setout_bad.pl index a59e415d5..022fe59ea 100755 --- a/test_regress/t/t_lint_setout_bad.pl +++ b/test_regress/t/t_lint_setout_bad.pl @@ -15,9 +15,7 @@ compile( verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, - expect => -'%Error: t/t_lint_setout_bad.v:\d+: Output port is connected to a constant pin, electrical short -.*', + expect_filename => $Self->{golden_filename}, ); ok(1); diff --git a/test_regress/t/t_lint_setout_bad_noinl.out b/test_regress/t/t_lint_setout_bad_noinl.out new file mode 100644 index 000000000..aa43238fb --- /dev/null +++ b/test_regress/t/t_lint_setout_bad_noinl.out @@ -0,0 +1,2 @@ +%Error-PORTSHORT: t/t_lint_setout_bad.v:16: Output port is connected to a constant pin, electrical short +%Error: Exiting due to diff --git a/test_regress/t/t_lint_setout_bad_noinl.pl b/test_regress/t/t_lint_setout_bad_noinl.pl index f1d9328ed..d9722d132 100755 --- a/test_regress/t/t_lint_setout_bad_noinl.pl +++ b/test_regress/t/t_lint_setout_bad_noinl.pl @@ -17,9 +17,7 @@ compile( verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, - expect => -'%Error: t/t_lint_setout_bad.v:\d+: Output port is connected to a constant pin, electrical short -.*', + expect_filename => $Self->{golden_filename}, ); ok(1); diff --git a/test_regress/t/t_lint_subout_bad.out b/test_regress/t/t_lint_subout_bad.out new file mode 100644 index 000000000..635de2efc --- /dev/null +++ b/test_regress/t/t_lint_subout_bad.out @@ -0,0 +1,4 @@ +%Error-PORTSHORT: t/t_lint_subout_bad.v:11: Output port is connected to a constant pin, electrical short +%Error-PORTSHORT: t/t_lint_subout_bad.v:12: Output port is connected to a constant pin, electrical short +%Error-PORTSHORT: t/t_lint_subout_bad.v:10: Output port is connected to a constant pin, electrical short +%Error: Exiting due to diff --git a/test_regress/t/t_lint_subout_bad.pl b/test_regress/t/t_lint_subout_bad.pl new file mode 100755 index 000000000..fb4e1de76 --- /dev/null +++ b/test_regress/t/t_lint_subout_bad.pl @@ -0,0 +1,21 @@ +#!/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. + +scenarios(vlt_all => 1); + +compile( + # No --lint-only as got compile error + verilator_flags2 => ["--trace"], + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; + diff --git a/test_regress/t/t_lint_subout_bad.v b/test_regress/t/t_lint_subout_bad.v new file mode 100644 index 000000000..475803de8 --- /dev/null +++ b/test_regress/t/t_lint_subout_bad.v @@ -0,0 +1,16 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2019 by Wilson Snyder. + +// verilator lint_off UNDRIVEN + +module t(); + wire sig; + sub sub0(.out(33'b0)); + sub sub1(.out({32'b0, sig})); + sub sub2(.out({32'b1, sig})); +endmodule + +module sub(output reg [32 : 0] out); +endmodule