From 5547833dde013047482a2a4b611c00f41b474380 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 28 Jan 2026 19:14:10 -0500 Subject: [PATCH] Add UNSUPPORTED error on IEEE complex ports (#2844 partial) --- src/verilog.y | 21 +++++- test_regress/t/t_inst_port_complex_unsup.out | 47 ++++++++++++ test_regress/t/t_inst_port_complex_unsup.py | 16 ++++ test_regress/t/t_inst_port_complex_unsup.v | 78 ++++++++++++++++++++ 4 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 test_regress/t/t_inst_port_complex_unsup.out create mode 100755 test_regress/t/t_inst_port_complex_unsup.py create mode 100644 test_regress/t/t_inst_port_complex_unsup.v diff --git a/src/verilog.y b/src/verilog.y index ef5c5bfa7..d6a4008ce 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1397,9 +1397,9 @@ port: // ==IEEE: port // // IEEE: ansi_port_declaration, with [port_direction] removed // // IEEE: [ net_port_header | interface_port_header ] // // port_identifier { unpacked_dimension } [ '=' constant_expression ] - // // IEEE: [ net_port_header | variable_port_header ] '.' port_identifier '(' [ expression ] ')' // // IEEE: [ variable_port_header ] port_identifier // // { variable_dimension } [ '=' constant_expression ] + // // IEEE: '.' port_identifier '(' [ expression ] ')' // // Substitute net_port_header = [ port_direction ] net_port_type // // Substitute variable_port_header = [ port_direction ] variable_port_type // // Substitute net_port_type = [ net_type ] data_type_or_implicit @@ -1474,6 +1474,13 @@ port: // ==IEEE: port | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr { $$ = $2; /*VARDTYPE-same*/ if (AstVar* vp = VARDONEP($$, $3, $4)) { addNextNull($$, vp); vp->valuep($6); } } + // // IEEE: '.' port_identifier '(' [ expression ] ')' + | portDirNetE /*implicit*/ '.' portSig '(' expr ')' + { $$ = $3; DEL($5); + BBUNSUP($2, "Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2)"); } + // // IEEE: part of (non-ansi) port_reference + | '{' port_expressionList '}' + { $$ = $2; } ; portDirNetE: // IEEE: part of port, optional net type and/or direction @@ -1497,6 +1504,18 @@ portSig: { $$ = new AstPort{$1, PINNUMINC(), *$1}; } ; +port_expressionList: // IEEE: part of (non-ansi) port_reference + port_reference { $$ = $1; } + | port_expressionList ',' port_reference { $$ = addNextNull($1, $3); } + ; + +port_reference: // IEEE: (non-ansi) port-reference + // // IEEE: port_identifier constant_select + // // constant_select ::= [ '[' constant_part_select_range ']' ] + id/*port_identifier*/ { $$ = nullptr; } // UNSUP above here + | id/*port_identifier*/ part_select_range { $$ = nullptr; DEL($2); } // UNSUP above here + ; + //********************************************************************** // Interface headers diff --git a/test_regress/t/t_inst_port_complex_unsup.out b/test_regress/t/t_inst_port_complex_unsup.out new file mode 100644 index 000000000..e2f245c5f --- /dev/null +++ b/test_regress/t/t_inst_port_complex_unsup.out @@ -0,0 +1,47 @@ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:9:9: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 9 | input .ai_rename(ai), .bi_rename(b), + | ^ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:9:26: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 9 | input .ai_rename(ai), .bi_rename(b), + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:10:15: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 10 | output wire .ao_rename(ao), .bo_rename(bo) + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:10:32: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 10 | output wire .ao_rename(ao), .bo_rename(bo) + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:17:3: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 17 | .ai_rename(ai), .bi_rename(bi), + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:17:19: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 17 | .ai_rename(ai), .bi_rename(bi), + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:18:3: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 18 | .ao_rename(ao), .bo_rename(bo) + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:18:19: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 18 | .ao_rename(ao), .bo_rename(bo) + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:30:9: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 30 | input .ci_30(ci[3:0]), .ci_74(ci[7:4]), + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:30:26: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 30 | input .ci_30(ci[3:0]), .ci_74(ci[7:4]), + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:31:15: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 31 | output wire .co_30(co[3:0]), .co_74(co[7:4]) + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:31:33: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 31 | output wire .co_30(co[3:0]), .co_74(co[7:4]) + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:56:3: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 56 | .abi({ai, bi}), + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:57:3: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 57 | .abo({ao, bo}) + | ^ +%Error-UNSUPPORTED: t/t_inst_port_complex_unsup.v:70:30: Unsupported: complex ports (IEEE 1800-2017 23.2.2.1/2) + 70 | module nansi_mixed_direction(.aio({ai, ao})); + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_inst_port_complex_unsup.py b/test_regress/t/t_inst_port_complex_unsup.py new file mode 100755 index 000000000..e842d48f7 --- /dev/null +++ b/test_regress/t/t_inst_port_complex_unsup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2026 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_inst_port_complex_unsup.v b/test_regress/t/t_inst_port_complex_unsup.v new file mode 100644 index 000000000..9b9162f65 --- /dev/null +++ b/test_regress/t/t_inst_port_complex_unsup.v @@ -0,0 +1,78 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +// No simulator supporting this was found +module ansi_rename ( + input .ai_rename(ai), .bi_rename(b), + output wire .ao_rename(ao), .bo_rename(bo) +); + assign ao = ai; + assign bo = bi; +endmodule + +module nansi_rename ( + .ai_rename(ai), .bi_rename(bi), + .ao_rename(ao), .bo_rename(bo) +); + input ai; + input bi; + output ao; + output bo; + assign ao = ai; + assign bo = bi; +endmodule + +// No simulator supporting this was found +module ansi_split ( + input .ci_30(ci[3:0]), .ci_74(ci[7:4]), + output wire .co_30(co[3:0]), .co_74(co[7:4]) +); + assign co = ci; +endmodule + +module nansi_split ( + ci[3:0], ci[7:4], + co[3:0], co[7:4] +); + input [7:0] ci; + output [7:0] co; + assign co = ci; +endmodule + +module nansi_concat ( + {ai, bi}, + {ao, bo} +); + input [1:0] ai, bi; + output [1:0] ao, bo; + assign ao = ai; + assign bo = bi; +endmodule + +module nansi_concat_named ( + .abi({ai, bi}), + .abo({ao, bo}) +); + input [1:0] ai, bi; + output [1:0] ao, bo; + assign ao = ai; + assign bo = bi; +endmodule + +module nansi_same_input(aa, aa); + input aa; +endmodule + +// Some simulators don't support aggregated ports with different directions +module nansi_mixed_direction(.aio({ai, ao})); + input ai; + output ao; +endmodule + +module t; + // TODO make self checking + initial $finish; +endmodule