From 23c243bb8293daa8e84ea6667fa9145d62f01827 Mon Sep 17 00:00:00 2001 From: Udi Finkelstein Date: Fri, 9 Apr 2021 17:39:46 +0300 Subject: [PATCH] Add support for null ports (#2875) --- bin/verilator | 11 +++ src/V3Error.h | 3 +- src/verilog.y | 26 ++++++- test_regress/t/t_lint_nullport.out | 107 +++++++++++++++++++++++++++++ test_regress/t/t_lint_nullport.pl | 19 +++++ test_regress/t/t_lint_nullport.v | 80 +++++++++++++++++++++ 6 files changed, 243 insertions(+), 3 deletions(-) create mode 100644 test_regress/t/t_lint_nullport.out create mode 100755 test_regress/t/t_lint_nullport.pl create mode 100644 test_regress/t/t_lint_nullport.v diff --git a/bin/verilator b/bin/verilator index 7b51a3d18..75d4bc395 100755 --- a/bin/verilator +++ b/bin/verilator @@ -4729,6 +4729,17 @@ using a regular always may be more appropriate. Ignoring this warning will only suppress the lint check, it will simulate correctly. +=item NULLPORT + +Warns that a null port was detected in the module definition port list. Null +ports are empty placeholders, i.e. either one ore more commas at the beginning +or the end of a module port list, or two or more consecutive commas in the +middle of a module port list. A null port cannot be accessed within the module, +but when instantiating the module by port order, it is treated like a regular +port and any wire connected to it is left unconnected. +This is considered a warning because this feature is rarely used, and is mostly +the result of a typing error such as a dangling comma at the end of a port list. + =item PINCONNECTEMPTY Warns that an instance has a pin which is connected to .pin_name(), diff --git a/src/V3Error.h b/src/V3Error.h index 1eec450e0..a312fe6e9 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -101,6 +101,7 @@ public: MULTIDRIVEN, // Driven from multiple blocks MULTITOP, // Multiple top level modules NOLATCH, // No latch detected in always_latch block + NULLPORT, // Null port detected in module definition PINCONNECTEMPTY,// Cell pin connected by name with empty reference PINMISSING, // Cell pin not specified PINNOCONNECT, // Cell pin not connected @@ -167,7 +168,7 @@ public: "IMPERFECTSCH", "IMPLICIT", "IMPORTSTAR", "IMPURE", "INCABSPATH", "INFINITELOOP", "INITIALDLY", "INSECURE", "LATCH", "LITENDIAN", "MODDUP", - "MULTIDRIVEN", "MULTITOP","NOLATCH", "PINCONNECTEMPTY", + "MULTIDRIVEN", "MULTITOP","NOLATCH", "NULLPORT", "PINCONNECTEMPTY", "PINMISSING", "PINNOCONNECT", "PINNOTFOUND", "PKGNODECL", "PROCASSWIRE", "RANDC", "REALCVT", "REDEFMACRO", "SELRANGE", "SHORTREAL", "SPLITVAR", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET", diff --git a/src/verilog.y b/src/verilog.y index e887c3a3d..d5bb07096 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1284,9 +1284,31 @@ portsStarE: // IEEE: .* + list_of_ports + list_of_port_declarations + em | '(' {VARRESET_LIST(PORT);} list_of_ports ')' { $$ = $3; VARRESET_NONLIST(UNKNOWN); } ; +list_of_portsE: // IEEE: list_of_ports + list_of_port_declarations + portAndTagE { $$ = $1; } + | list_of_portsE ',' portAndTagE { $$ = $1->addNextNull($3); } + ; + list_of_ports: // IEEE: list_of_ports + list_of_port_declarations - portAndTag { $$ = $1; } - | list_of_ports ',' portAndTag { $$ = $1->addNextNull($3); } + portAndTag { $$ = $1; } + | list_of_portsE ',' portAndTagE { $$ = $1->addNextNull($3); } + ; + +portAndTagE: + /* empty */ + { int p = PINNUMINC(); + const string name = "__pinNumber" + cvtToStr(p); + $$ = new AstPort{CRELINE(), p, name}; + AstVar* varp = new AstVar{CRELINE(), AstVarType::PORT, name, VFlagChildDType{}, + new AstBasicDType{CRELINE(), LOGIC_IMPLICIT}}; + varp->declDirection(VDirection::INPUT); + varp->direction(VDirection::INPUT); + varp->ansi(false); + varp->declTyped(true); + varp->trace(false); + $$ = $$->addNext(varp); + $$->v3warn(NULLPORT, "Null port on module (perhaps extraneous comma)"); } + | portAndTag { $$ = $1; } ; portAndTag: diff --git a/test_regress/t/t_lint_nullport.out b/test_regress/t/t_lint_nullport.out new file mode 100644 index 000000000..f35a775cd --- /dev/null +++ b/test_regress/t/t_lint_nullport.out @@ -0,0 +1,107 @@ +%Warning-NULLPORT: t/t_lint_nullport.v:23:13: Null port on module (perhaps extraneous comma) + 23 | module t5(a,); + | ^ + ... Use "/* verilator lint_off NULLPORT */" and lint_on around source to disable this message. +%Warning-NULLPORT: t/t_lint_nullport.v:27:13: Null port on module (perhaps extraneous comma) + 27 | module t6(a,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:27:14: Null port on module (perhaps extraneous comma) + 27 | module t6(a,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:31:15: Null port on module (perhaps extraneous comma) + 31 | module t7(a,b,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:35:15: Null port on module (perhaps extraneous comma) + 35 | module t8(a,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:35:16: Null port on module (perhaps extraneous comma) + 35 | module t8(a,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:39:13: Null port on module (perhaps extraneous comma) + 39 | module t9(a,,b); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:43:14: Null port on module (perhaps extraneous comma) + 43 | module t10(a,,b,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:43:17: Null port on module (perhaps extraneous comma) + 43 | module t10(a,,b,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:47:14: Null port on module (perhaps extraneous comma) + 47 | module t11(a,,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:47:17: Null port on module (perhaps extraneous comma) + 47 | module t11(a,,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:47:18: Null port on module (perhaps extraneous comma) + 47 | module t11(a,,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:51:12: Null port on module (perhaps extraneous comma) + 51 | module t12(,a,,b); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:51:15: Null port on module (perhaps extraneous comma) + 51 | module t12(,a,,b); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:55:12: Null port on module (perhaps extraneous comma) + 55 | module t13(,a,,b,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:55:15: Null port on module (perhaps extraneous comma) + 55 | module t13(,a,,b,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:55:18: Null port on module (perhaps extraneous comma) + 55 | module t13(,a,,b,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:59:12: Null port on module (perhaps extraneous comma) + 59 | module t14(,a,,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:59:15: Null port on module (perhaps extraneous comma) + 59 | module t14(,a,,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:59:18: Null port on module (perhaps extraneous comma) + 59 | module t14(,a,,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:59:19: Null port on module (perhaps extraneous comma) + 59 | module t14(,a,,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:63:12: Null port on module (perhaps extraneous comma) + 63 | module t15(,,a,,b); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:63:13: Null port on module (perhaps extraneous comma) + 63 | module t15(,,a,,b); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:63:16: Null port on module (perhaps extraneous comma) + 63 | module t15(,,a,,b); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:67:12: Null port on module (perhaps extraneous comma) + 67 | module t16(,,a,,b,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:67:13: Null port on module (perhaps extraneous comma) + 67 | module t16(,,a,,b,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:67:16: Null port on module (perhaps extraneous comma) + 67 | module t16(,,a,,b,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:67:19: Null port on module (perhaps extraneous comma) + 67 | module t16(,,a,,b,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:71:12: Null port on module (perhaps extraneous comma) + 71 | module t17(,,a,,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:71:13: Null port on module (perhaps extraneous comma) + 71 | module t17(,,a,,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:71:16: Null port on module (perhaps extraneous comma) + 71 | module t17(,,a,,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:71:19: Null port on module (perhaps extraneous comma) + 71 | module t17(,,a,,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:71:20: Null port on module (perhaps extraneous comma) + 71 | module t17(,,a,,b,,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:75:12: Null port on module (perhaps extraneous comma) + 75 | module t18(,); + | ^ +%Warning-NULLPORT: t/t_lint_nullport.v:75:13: Null port on module (perhaps extraneous comma) + 75 | module t18(,); + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_lint_nullport.pl b/test_regress/t/t_lint_nullport.pl new file mode 100755 index 000000000..4f29861db --- /dev/null +++ b/test_regress/t/t_lint_nullport.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2021 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); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_lint_nullport.v b/test_regress/t/t_lint_nullport.v new file mode 100644 index 000000000..5b42dc176 --- /dev/null +++ b/test_regress/t/t_lint_nullport.v @@ -0,0 +1,80 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2021 by Udi Finkelstein. +// SPDX-License-Identifier: CC0-1.0 + +/* verilator lint_off MULTITOP */ +// First, test we haven't broken normal ports +module t1(); +endmodule + +module t2; +endmodule + +module t3(a); +input a; +endmodule + +module t4(a, b); +input a, b; +endmodule + +module t5(a,); +input a; +endmodule + +module t6(a,,); +input a; +endmodule + +module t7(a,b,); +input a, b; +endmodule + +module t8(a,b,,); +input a, b; +endmodule + +module t9(a,,b); +input a, b; +endmodule + +module t10(a,,b,); +input a, b; +endmodule + +module t11(a,,b,,); +input a, b; +endmodule + +module t12(,a,,b); +input a, b; +endmodule + +module t13(,a,,b,); +input a, b; +endmodule + +module t14(,a,,b,,); +input a, b; +endmodule + +module t15(,,a,,b); +input a, b; +endmodule + +module t16(,,a,,b,); +input a, b; +endmodule + +module t17(,,a,,b,,); +input a, b; +endmodule + +module t18(,); +endmodule + +/* verilator lint_off NULLPORT */ +module t19(,,); +endmodule