From 7f49b6c1020680eb323875b68c8a449f0c15c750 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 16 Apr 2023 17:23:16 -0400 Subject: [PATCH] Parse 'let' as unsupported --- src/verilog.l | 2 +- src/verilog.y | 50 +++++++++++++++++++++++++++++++++--- test_regress/t/t_let.out | 41 +++++++++++++++++++++++++++++ test_regress/t/t_let.pl | 23 +++++++++++++++++ test_regress/t/t_let.v | 36 ++++++++++++++++++++++++++ test_regress/t/t_let_bad.out | 11 ++++++++ test_regress/t/t_let_bad.pl | 19 ++++++++++++++ test_regress/t/t_let_bad.v | 20 +++++++++++++++ 8 files changed, 198 insertions(+), 4 deletions(-) create mode 100644 test_regress/t/t_let.out create mode 100755 test_regress/t/t_let.pl create mode 100644 test_regress/t/t_let.v create mode 100644 test_regress/t/t_let_bad.out create mode 100755 test_regress/t/t_let_bad.pl create mode 100644 test_regress/t/t_let_bad.v diff --git a/src/verilog.l b/src/verilog.l index 985f89b6a..eec6be4ed 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -599,7 +599,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "eventually" { FL; return yEVENTUALLY; } "global" { FL; return yGLOBAL__LEX; } "implies" { FL; return yIMPLIES; } - "let" { ERROR_RSVD_WORD("SystemVerilog 2009"); } + "let" { FL; return yLET; } "nexttime" { FL; return yNEXTTIME; } "reject_on" { FL; return yREJECT_ON; } "s_always" { FL; return yS_ALWAYS; } diff --git a/src/verilog.y b/src/verilog.y index a7c3c70ff..844853f10 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -645,7 +645,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) %token yJOIN "join" %token yJOIN_ANY "join_any" %token yJOIN_NONE "join_none" -//UNSUP %token yLET "let" +%token yLET "let" %token yLOCALPARAM "localparam" %token yLOCAL__COLONCOLON "local-then-::" %token yLOCAL__ETC "local" @@ -1815,6 +1815,7 @@ modportSimplePortOrTFPort:// IEEE: modport_simple_port or modport_tf_port, | '.' idAny '(' ')' { $$ = $2; BBUNSUP($1, "Unsupported: Modport dotted port name"); } | '.' idAny '(' expr ')' { $$ = $2; BBUNSUP($1, "Unsupported: Modport dotted port name"); } ; + //************************************************ // Variable Declarations @@ -3450,7 +3451,7 @@ block_item_declarationList: // IEEE: [ block_item_declaration ] block_item_declaration: // ==IEEE: block_item_declaration data_declaration { $$ = $1; } | parameter_declaration ';' { $$ = $1; } - //UNSUP let_declaration { $$ = $1; } + | let_declaration { $$ = $1; } ; stmtList: @@ -5151,6 +5152,49 @@ stream_expressionOrDataType: // IEEE: from streaming_concatenation { $$ = $1; BBUNSUP($2, "Unsupported: with[] stream expression"); } ; +//************************************************ +// Let + +letId: // IEEE: pert of let_declaration + idAny/*let_identifieer*/ + { $$ = $1; + $$ = nullptr; + // No unsupported message as caller has one, for now just use a func + $$ = new AstFunc{$$, *$1, nullptr, nullptr}; + SYMP->pushNewUnderNodeOrCurrent($$, $$); } + ; + +let_declaration: // IEEE: let_declaration + yLET letId '=' expr ';' + { $$ = nullptr; + SYMP->popScope($2); + BBUNSUP($1, "Unsupported: let"); } + | yLET letId '(' let_port_listE ')' '=' expr ';' + { $$ = nullptr; + SYMP->popScope($2); + BBUNSUP($1, "Unsupported: let"); } + ; + +let_port_listE: // IEEE: [ let_port_list ] + /*empty*/ { $$ = nullptr; } + | let_port_list { $$ = $1; } + ; + +let_port_list: // IEEE: let_port_list + let_port_item { $$ = $1; } + | let_port_list ',' let_port_item { $$ = addNextNull($1, $3); } + ; + +let_port_item: // IEEE: let_port_Item + // // IEEE: Expanded let_formal_type + yUNTYPED idAny/*formal_port_identifier*/ variable_dimensionListE exprEqE + { $$ = nullptr; BBUNSUP($1, "Unsupported: let untyped ports"); } + | data_type id/*formal_port_identifier*/ variable_dimensionListE exprEqE + { $$ = nullptr; BBUNSUP($1, "Unsupported: let ports"); } + | implicit_typeE id/*formal_port_identifier*/ variable_dimensionListE exprEqE + { $$ = nullptr; BBUNSUP($1, "Unsupported: let ports"); } + ; + //************************************************ // Gate declarations @@ -5697,7 +5741,7 @@ cycle_delay: // IEEE: cycle_delay assertion_item_declaration: // ==IEEE: assertion_item_declaration property_declaration { $$ = $1; } | sequence_declaration { $$ = $1; } - //UNSUP let_declaration { $$ = $1; } + | let_declaration { $$ = $1; } ; assertion_item: // ==IEEE: assertion_item diff --git a/test_regress/t/t_let.out b/test_regress/t/t_let.out new file mode 100644 index 000000000..aca0f5993 --- /dev/null +++ b/test_regress/t/t_let.out @@ -0,0 +1,41 @@ +%Error-UNSUPPORTED: t/t_let.v:8:4: Unsupported: let + 8 | let P = 11; + | ^~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_let.v:13:4: Unsupported: let + 13 | let A = 10; + | ^~~ +%Error-UNSUPPORTED: t/t_let.v:14:4: Unsupported: let + 14 | let B() = 20; + | ^~~ +%Error-UNSUPPORTED: t/t_let.v:13:14: Unsupported: let ports + 13 | let A = 10; + | ^ +%Error-UNSUPPORTED: t/t_let.v:15:4: Unsupported: let + 15 | let C(a) = 30 + a; + | ^~~ +%Error-UNSUPPORTED: t/t_let.v:15:13: Unsupported: let ports + 15 | let C(a) = 30 + a; + | ^ +%Error-UNSUPPORTED: t/t_let.v:16:4: Unsupported: let + 16 | let D(a, b) = 30 + a + b; + | ^~~ +%Error-UNSUPPORTED: t/t_let.v:16:16: Unsupported: let ports + 16 | let D(a, b) = 30 + a + b; + | ^ +%Error-UNSUPPORTED: t/t_let.v:17:4: Unsupported: let + 17 | let E(a, b=7) = 30 + a + b; + | ^~~ +%Error-UNSUPPORTED: t/t_let.v:18:10: Unsupported: let untyped ports + 18 | let F(untyped a) = 30 + a; + | ^~~~~~~ +%Error-UNSUPPORTED: t/t_let.v:18:4: Unsupported: let + 18 | let F(untyped a) = 30 + a; + | ^~~ +%Error-UNSUPPORTED: t/t_let.v:19:10: Unsupported: let ports + 19 | let G(int a) = 30 + a; + | ^~~ +%Error-UNSUPPORTED: t/t_let.v:19:4: Unsupported: let + 19 | let G(int a) = 30 + a; + | ^~~ +%Error: Exiting due to diff --git a/test_regress/t/t_let.pl b/test_regress/t/t_let.pl new file mode 100755 index 000000000..c18ffc8f0 --- /dev/null +++ b/test_regress/t/t_let.pl @@ -0,0 +1,23 @@ +#!/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(vlt => 1); + +compile( + expect_filename => $Self->{golden_filename}, + fails => 1, + ); + +#execute( +# check_finished => 1, +# ); + +ok(1); +1; diff --git a/test_regress/t/t_let.v b/test_regress/t/t_let.v new file mode 100644 index 000000000..b8d010fb3 --- /dev/null +++ b/test_regress/t/t_let.v @@ -0,0 +1,36 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +package Pkg; + let P = 11; +endpackage + +module t(/*AUTOARG*/); + + let A = 10; + let B() = 20; + let C(a) = 30 + a; + let D(a, b) = 30 + a + b; + let E(a, b=7) = 30 + a + b; + let F(untyped a) = 30 + a; + let G(int a) = 30 + a; + + initial begin + if (A != 10) $stop; + if (A() != 10) $stop; + if (B != 20) $stop; + if (B() != 20) $stop; + if (C(1) != (30 + 1)) $stop; + if (D(1, 2) != (30 + 1 + 2)) $stop; + if (E(1) != (30 + 1 + 7)) $stop; + if (F(1) != (30 + 1)) $stop; + if (G(1) != (30 + 1)) $stop; + if (Pkg::P != 11) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_let_bad.out b/test_regress/t/t_let_bad.out new file mode 100644 index 000000000..ce76ac770 --- /dev/null +++ b/test_regress/t/t_let_bad.out @@ -0,0 +1,11 @@ +%Error-UNSUPPORTED: t/t_let_bad.v:9:4: Unsupported: let + 9 | let NO_ARG = 10; + | ^~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_let_bad.v:9:19: Unsupported: let ports + 9 | let NO_ARG = 10; + | ^ +%Error-UNSUPPORTED: t/t_let_bad.v:10:4: Unsupported: let + 10 | let ONE_ARG(a) = 10; + | ^~~ +%Error: Exiting due to diff --git a/test_regress/t/t_let_bad.pl b/test_regress/t/t_let_bad.pl new file mode 100755 index 000000000..882bc2418 --- /dev/null +++ b/test_regress/t/t_let_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 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(linter => 1); + +compile( + expect_filename => $Self->{golden_filename}, + fails => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_let_bad.v b/test_regress/t/t_let_bad.v new file mode 100644 index 000000000..816b46651 --- /dev/null +++ b/test_regress/t/t_let_bad.v @@ -0,0 +1,20 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/); + + let NO_ARG = 10; + let ONE_ARG(a) = 10; + + initial begin + if (NO_ARG(10) != 10) $stop; // BAD + if (ONE_ARG() != 10) $stop; // BAD + if (ONE_ARG(10, 20) != 10) $stop; // BAD + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule