diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 39ef36202..30c0e86dc 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -33,6 +33,7 @@ Garrett Smith Geza Lore Gianfranco Costamagna Glen Gibb +Gökçe Aydos Graham Rushton Guokai Chen Gustav Svensk diff --git a/src/verilog.y b/src/verilog.y index 02d00cb37..c6b3ccfdc 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -96,6 +96,8 @@ public: bool m_tracingParse = true; // Tracing disable for parser bool m_insideProperty = false; // Is inside property declaration bool m_typedPropertyPort = false; // True if typed property port occurred on port lists + bool m_modportImpExpActive = false; // Standalone ID is a tf_identifier instead of port_identifier + bool m_modportImpExpLastIsExport = false; // Last import_export statement in modportPortsDecl is an export int m_pinNum = -1; // Pin number currently parsing std::stack m_pinStack; // Queue of pin numbers being parsed @@ -1744,30 +1746,40 @@ modportPortsDeclList: // We track the type as with the V2k series of defines, then create as each ID is seen. modportPortsDecl: // // IEEE: modport_simple_ports_declaration - port_direction modportSimplePort { $$ = new AstModportVarRef{$2, *$2, GRAMMARP->m_varIO}; } + port_direction modportSimplePortOrTFPort { $$ = new AstModportVarRef{$2, *$2, GRAMMARP->m_varIO}; + GRAMMARP->m_modportImpExpActive = false;} // // IEEE: modport_clocking_declaration | yCLOCKING idAny/*clocking_identifier*/ { $$ = nullptr; BBUNSUP($1, "Unsupported: Modport clocking"); } // // IEEE: yIMPORT modport_tf_port // // IEEE: yEXPORT modport_tf_port // // modport_tf_port expanded here - | yIMPORT id/*tf_identifier*/ { $$ = new AstModportFTaskRef{$2, *$2, false}; } - | yEXPORT id/*tf_identifier*/ { $$ = new AstModportFTaskRef{$2, *$2, true}; } + | yIMPORT id/*tf_identifier*/ { $$ = new AstModportFTaskRef{$2, *$2, false}; + GRAMMARP->m_modportImpExpActive = true; + GRAMMARP->m_modportImpExpLastIsExport = false; } + | yEXPORT id/*tf_identifier*/ { $$ = new AstModportFTaskRef{$2, *$2, true}; + GRAMMARP->m_modportImpExpActive = true; + GRAMMARP->m_modportImpExpLastIsExport = true; } | yIMPORT method_prototype { $$ = nullptr; BBUNSUP($1, "Unsupported: Modport import with prototype"); } | yEXPORT method_prototype { $$ = nullptr; BBUNSUP($1, "Unsupported: Modport export with prototype"); } // Continuations of above after a comma. // // IEEE: modport_simple_ports_declaration - | modportSimplePort { $$ = new AstModportVarRef{$1, *$1, GRAMMARP->m_varIO}; } + | modportSimplePortOrTFPort { $$ = GRAMMARP->m_modportImpExpActive ? + static_cast( + new AstModportFTaskRef( + $1, *$1, GRAMMARP->m_modportImpExpLastIsExport) ) : + static_cast( + new AstModportVarRef( + $1, *$1, GRAMMARP->m_varIO) ); } ; -modportSimplePort: // IEEE: modport_simple_port or modport_tf_port, depending what keyword was earlier +modportSimplePortOrTFPort:// IEEE: modport_simple_port or modport_tf_port, depending what keyword was earlier id { $$ = $1; } //UNSUP '.' idAny '(' ')' { } //UNSUP '.' idAny '(' expr ')' { } ; - //************************************************ // Variable Declarations diff --git a/test_regress/t/t_interface_modport_import_export_list.pl b/test_regress/t/t_interface_modport_import_export_list.pl new file mode 100755 index 000000000..5412e6e24 --- /dev/null +++ b/test_regress/t/t_interface_modport_import_export_list.pl @@ -0,0 +1,18 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2023 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(simulator => 1); + +compile( + fails=>0, +); + +ok(1); +1; diff --git a/test_regress/t/t_interface_modport_import_export_list.v b/test_regress/t/t_interface_modport_import_export_list.v new file mode 100644 index 000000000..ddefa9700 --- /dev/null +++ b/test_regress/t/t_interface_modport_import_export_list.v @@ -0,0 +1,54 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Modport import export list test +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Goekce Aydos. +// SPDX-License-Identifier: CC0-1.0 + +interface intf; + logic l; + function void f1(); + endfunction + function void f2(); + endfunction + function void f3(); + endfunction + function void f4(); + endfunction + + modport mpi ( + import f1, f2, + input l, + import f3, f4 + ); + modport mpo ( + output l, + import f1, f2, f3, f4 + ); +endinterface + +module mo (intf.mpo intf0); + function void ef1(); + intf0.f1(); + intf0.f2(); + endfunction + function void ef2(); + intf0.f3(); + intf0.f4(); + endfunction + +initial begin + ef1(); + ef2(); +end +endmodule + +module mi (intf.mpi intf0); +endmodule + +module t; + intf intf0(); + mi mi(.*); + mo mo(.*); +endmodule