diff --git a/src/verilog.y b/src/verilog.y index 08cd48cdc..076ea09fa 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -4254,11 +4254,13 @@ system_f_call_or_t: // IEEE: part of system_tf_call (can be task | yD_ONEHOT '(' expr ')' { $$ = new AstOneHot{$1, $3}; } | yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0{$1, $3}; } | yD_PAST '(' expr ')' { $$ = new AstPast{$1, $3, nullptr}; } - | yD_PAST '(' expr ',' expr ')' { $$ = new AstPast{$1, $3, $5}; } - | yD_PAST '(' expr ',' expr ',' expr ')' - { $$ = $3; BBUNSUP($1, "Unsupported: $past expr2 and clock arguments"); } - | yD_PAST '(' expr ',' expr ',' expr ',' expr')' - { $$ = $3; BBUNSUP($1, "Unsupported: $past expr2 and clock arguments"); } + | yD_PAST '(' expr ',' exprE ')' { $$ = new AstPast{$1, $3, $5}; } + | yD_PAST '(' expr ',' exprE ',' exprE ')' + { if ($7) BBUNSUP($1, "Unsupported: $past expr2 and/or clock arguments"); + $$ = new AstPast{$1, $3, $5}; } + | yD_PAST '(' expr ',' exprE ',' exprE ',' clocking_eventE ')' + { if ($7 || $9) BBUNSUP($1, "Unsupported: $past expr2 and/or clock arguments"); + $$ = new AstPast{$1, $3, $5}; } | yD_POW '(' expr ',' expr ')' { $$ = new AstPowD{$1, $3, $5}; } | yD_RANDOM '(' expr ')' { $$ = new AstRand{$1, $3, false}; } | yD_RANDOM parenE { $$ = new AstRand{$1, nullptr, false}; } @@ -4683,6 +4685,11 @@ constExpr: expr { $$ = $1; } ; +exprE: // IEEE: optional expression + /*empty*/ { $$ = nullptr; } + | expr { $$ = $1; } + ; + expr: // IEEE: part of expression/constant_expression/primary // *SEE BELOW* // IEEE: primary/constant_primary // @@ -5665,6 +5672,11 @@ clocking_declaration: // IEEE: clocking_declaration { $$ = new AstClocking{$3, *$3, $4, $6, false, true}; } ; +clocking_eventE: // IEEE: optional clocking_event + /* empty */ { $$ = nullptr; } + | clocking_event { $$ = $1; } + ; + clocking_event: // IEEE: clocking_event '@' id { $$ = new AstSenItem{$2, VEdgeType::ET_CHANGED, new AstParseRef{$2, VParseRefExp::PX_TEXT, *$2, nullptr, nullptr}}; } diff --git a/test_regress/t/t_past.v b/test_regress/t/t_past.v index 250810185..24b82ad92 100644 --- a/test_regress/t/t_past.v +++ b/test_regress/t/t_past.v @@ -74,8 +74,10 @@ module Test (/*AUTOARG*/ // $past(expression, ticks, expression, clocking) // In clock expression if (dly0 != $past(in)) $stop; - if (dly0 != $past(in,1)) $stop; - if (dly1 != $past(in,2)) $stop; + if (dly0 != $past(in,)) $stop; + if (dly1 != $past(in, 2)) $stop; + if (dly1 != $past(in, 2, )) $stop; + if (dly1 != $past(in, 2, , )) $stop; // $sampled(expression) -> expression if (in != $sampled(in)) $stop; end diff --git a/test_regress/t/t_past_unsup.out b/test_regress/t/t_past_unsup.out new file mode 100644 index 000000000..888dec662 --- /dev/null +++ b/test_regress/t/t_past_unsup.out @@ -0,0 +1,11 @@ +%Error-UNSUPPORTED: t/t_past_unsup.v:16:11: Unsupported: $past expr2 and/or clock arguments + 16 | if ($past(d, 1, 1)) $stop; + | ^~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_past_unsup.v:17:11: Unsupported: $past expr2 and/or clock arguments + 17 | if ($past(d, 1, 1, )) $stop; + | ^~~~~ +%Error-UNSUPPORTED: t/t_past_unsup.v:18:11: Unsupported: $past expr2 and/or clock arguments + 18 | if ($past(d, 1, 1, @(posedge clk))) $stop; + | ^~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_past_unsup.pl b/test_regress/t/t_past_unsup.pl new file mode 100755 index 000000000..a5846c699 --- /dev/null +++ b/test_regress/t/t_past_unsup.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(vlt => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_past_unsup.v b/test_regress/t/t_past_unsup.v new file mode 100644 index 000000000..58cbc84c5 --- /dev/null +++ b/test_regress/t/t_past_unsup.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, 2018 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/ + // Inputs + d, clk, num + ); + input d; + input clk; + input int num; + + always @ (posedge clk) begin + if ($past(d, 1, 1)) $stop; // Unsup + if ($past(d, 1, 1, )) $stop; // Unsup + if ($past(d, 1, 1, @(posedge clk))) $stop; // Unsup + end +endmodule