From 55d1b87b347938673ef48c4c8fc9d6b8ecd96421 Mon Sep 17 00:00:00 2001 From: Anthony Donlon <4056887+donlon@users.noreply.github.com> Date: Sun, 7 Jan 2024 23:59:56 +0800 Subject: [PATCH] Support parsing anonymous primitive instantiations (#4809) --- src/V3LinkParse.cpp | 16 ++++++++++++++++ src/verilog.y | 6 ++---- test_regress/t/t_inst_noname_bad.out | 7 +++++++ test_regress/t/t_inst_noname_bad.pl | 19 +++++++++++++++++++ test_regress/t/t_inst_noname_bad.v | 13 +++++++++++++ test_regress/t/t_preproc_inc_bad.out | 2 +- test_regress/t/t_udp_noname.out | 4 ---- test_regress/t/t_udp_noname.pl | 8 +++----- test_regress/t/t_udp_noname.v | 13 ++++++++----- test_regress/t/t_vams_kwd_bad.out | 2 +- 10 files changed, 70 insertions(+), 20 deletions(-) create mode 100644 test_regress/t/t_inst_noname_bad.out create mode 100755 test_regress/t/t_inst_noname_bad.pl create mode 100644 test_regress/t/t_inst_noname_bad.v delete mode 100644 test_regress/t/t_udp_noname.out diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 5d3e36da8..7980a7336 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -56,6 +56,7 @@ class LinkParseVisitor final : public VNVisitor { AstNodeDType* m_dtypep = nullptr; // Current data type AstNodeExpr* m_defaultInSkewp = nullptr; // Current default input skew AstNodeExpr* m_defaultOutSkewp = nullptr; // Current default output skew + int m_anonUdpId = 0; // Counter for anonymous UDP instances int m_genblkAbove = 0; // Begin block number of if/case/for above int m_genblkNum = 0; // Begin block number, 0=none seen int m_beginDepth = 0; // How many begin blocks above current node within current AstNodeModule @@ -621,6 +622,7 @@ class LinkParseVisitor final : public VNVisitor { V3Config::applyModule(nodep); VL_RESTORER(m_modp); + VL_RESTORER(m_anonUdpId); VL_RESTORER(m_genblkAbove); VL_RESTORER(m_genblkNum); VL_RESTORER(m_beginDepth); @@ -631,6 +633,7 @@ class LinkParseVisitor final : public VNVisitor { // Classes inherit from upper package if (m_modp && nodep->timeunit().isNone()) nodep->timeunit(m_modp->timeunit()); m_modp = nodep; + m_anonUdpId = 0; m_genblkAbove = 0; m_genblkNum = 0; m_beginDepth = 0; @@ -700,6 +703,19 @@ class LinkParseVisitor final : public VNVisitor { iterateChildren(nodep); } } + void visit(AstCell* nodep) override { + if (nodep->origName().empty()) { + if (!VN_IS(nodep->modp(), Primitive)) { // Module/Program/Iface + nodep->modNameFileline()->v3error("Instance of " << nodep->modp()->verilogKwd() + << " must be named"); + } + // UDPs can have empty instance names. Assigning unique names for them to prevent any + // conflicts + const string newName = "$unnamedudp" + cvtToStr(++m_anonUdpId); + nodep->name(newName); + nodep->origName(newName); + } + } void visit(AstGenCase* nodep) override { ++m_genblkNum; cleanFileline(nodep); diff --git a/src/verilog.y b/src/verilog.y index b83b953bc..ad0b9bc61 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -3203,10 +3203,8 @@ instnameParen: { $$ = GRAMMARP->createCellOrIfaceRef($1, *$1, $4, $2, true); } | id instRangeListE { $$ = GRAMMARP->createCellOrIfaceRef($1, *$1, nullptr, $2, false); } - //UNSUP instRangeListE '(' cellpinListE ')' { UNSUP } // UDP - // // Adding above and switching to the Verilog-Perl syntax - // // causes a shift conflict due to use of idClassSel inside exprScope. - // // It also breaks allowing "id foo;" instantiation syntax. + | '(' cellpinListE ')' // When UDP has empty name, unpacked dimensions must not be used + { $$ = GRAMMARP->createCellOrIfaceRef($1, "", $2, nullptr, true); } ; instRangeListE: diff --git a/test_regress/t/t_inst_noname_bad.out b/test_regress/t/t_inst_noname_bad.out new file mode 100644 index 000000000..8f555c3aa --- /dev/null +++ b/test_regress/t/t_inst_noname_bad.out @@ -0,0 +1,7 @@ +%Error: t/t_inst_noname_bad.v:8:5: Instance of module must be named + 8 | m (); + | ^ +%Error: t/t_inst_noname_bad.v:9:5: Instance of module must be named + 9 | m (); + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_inst_noname_bad.pl b/test_regress/t/t_inst_noname_bad.pl new file mode 100755 index 000000000..a60503a1f --- /dev/null +++ b/test_regress/t/t_inst_noname_bad.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 2003 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_inst_noname_bad.v b/test_regress/t/t_inst_noname_bad.v new file mode 100644 index 000000000..ca179b788 --- /dev/null +++ b/test_regress/t/t_inst_noname_bad.v @@ -0,0 +1,13 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Anthony Donlon. +// SPDX-License-Identifier: CC0-1.0 + +module t; + m (); + m (); +endmodule + +module m; +endmodule diff --git a/test_regress/t/t_preproc_inc_bad.out b/test_regress/t/t_preproc_inc_bad.out index 006f0ec09..2f46dacbd 100644 --- a/test_regress/t/t_preproc_inc_bad.out +++ b/test_regress/t/t_preproc_inc_bad.out @@ -1,4 +1,4 @@ -%Error: t/t_preproc_inc_inc_bad.vh:11:1: syntax error, unexpected endmodule, expecting IDENTIFIER or randomize +%Error: t/t_preproc_inc_inc_bad.vh:11:1: syntax error, unexpected endmodule, expecting IDENTIFIER or '(' or randomize 11 | endmodule | ^~~~~~~~~ t/t_preproc_inc_bad.v:10:1: ... note: In file included from 't_preproc_inc_bad.v' diff --git a/test_regress/t/t_udp_noname.out b/test_regress/t/t_udp_noname.out deleted file mode 100644 index 14eb3efdb..000000000 --- a/test_regress/t/t_udp_noname.out +++ /dev/null @@ -1,4 +0,0 @@ -%Error: t/t_udp_noname.v:15:8: syntax error, unexpected '(', expecting IDENTIFIER or randomize - 15 | udp (o, a); - | ^ -%Error: Exiting due to diff --git a/test_regress/t/t_udp_noname.pl b/test_regress/t/t_udp_noname.pl index b4e56a7d2..b46d46042 100755 --- a/test_regress/t/t_udp_noname.pl +++ b/test_regress/t/t_udp_noname.pl @@ -11,13 +11,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(simulator => 1); compile( - expect_filename => $Self->{golden_filename}, - fails => $Self->{vlt_all}, # Verilator unsupported, bug468" ); -#execute( -# check_finished => 1, -# ); +execute( + check_finished => 1, + ); ok(1); 1; diff --git a/test_regress/t/t_udp_noname.v b/test_regress/t/t_udp_noname.v index 1ce45f043..862a57e86 100644 --- a/test_regress/t/t_udp_noname.v +++ b/test_regress/t/t_udp_noname.v @@ -10,20 +10,23 @@ module t (/*AUTOARG*/ ); input clk; - reg a; - wire o; - udp (o, a); + reg a1; + wire a2 = ~a1; + wire o1, o2; + udp (o1, a1); + udp (o2, a2); integer cyc; initial cyc = 0; // Test loop always @ (posedge clk) begin cyc <= cyc + 1; - a <= cyc[0]; + a1 <= cyc[0]; if (cyc==0) begin end else if (cyc<90) begin - if (a != !cyc[0]) $stop; + if (o1 != cyc[0]) $stop; + if (o2 != !cyc[0]) $stop; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); diff --git a/test_regress/t/t_vams_kwd_bad.out b/test_regress/t/t_vams_kwd_bad.out index 0d6fac32e..9e3a97617 100644 --- a/test_regress/t/t_vams_kwd_bad.out +++ b/test_regress/t/t_vams_kwd_bad.out @@ -2,7 +2,7 @@ 12 | int above; | ^~~~~ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Error: t/t_vams_kwd_bad.v:12:13: syntax error, unexpected ';', expecting IDENTIFIER or randomize +%Error: t/t_vams_kwd_bad.v:12:13: syntax error, unexpected ';', expecting IDENTIFIER or '(' or randomize 12 | int above; | ^ %Error-UNSUPPORTED: t/t_vams_kwd_bad.v:13:8: Unsupported: AMS reserved word not implemented: 'abs'