diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index d91761f7e..25c395139 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -331,7 +331,10 @@ private: FileLine* const flp = nodep->fileline(); AstNodeExpr* valuep = V3Const::constifyEdit(nodep->lhsp()->unlinkFrBack()); const AstConst* const constp = VN_CAST(valuep, Const); - if (constp->isZero()) { + if (!constp) { + nodep->v3error( + "Delay value is not an elaboration-time constant (IEEE 1800-2023 16.7)"); + } else if (constp->isZero()) { nodep->v3warn(E_UNSUPPORTED, "Unsupported: ##0 delays"); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(valuep->deleteTree(), valuep); diff --git a/src/verilog.y b/src/verilog.y index 5abcdb0dc..a94a9046f 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -6690,11 +6690,9 @@ cycle_delay_range: // IEEE: ==cycle_delay_range yP_POUNDPOUND intnumAsConst { $$ = new AstDelay{$1, $2, true}; } | yP_POUNDPOUND idAny - { $$ = new AstDelay{$1, new AstConst{$1, AstConst::BitFalse{}}, true}; - BBUNSUP($1, "Unsupported: ## id cycle delay range expression"); } + { $$ = new AstDelay{$1, new AstParseRef{$2, *$2}, true}; } | yP_POUNDPOUND '(' constExpr ')' - { $$ = new AstDelay{$1, new AstConst{$1, AstConst::BitFalse{}}, true}; - BBUNSUP($1, "Unsupported: ## () cycle delay range expression"); } + { $$ = new AstDelay{$1, $3, true}; } // // In 1800-2009 ONLY: // // IEEE: yP_POUNDPOUND constant_primary // // UNSUP: This causes a big grammar ambiguity diff --git a/test_regress/t/t_property_sexpr2_bad.out b/test_regress/t/t_property_sexpr2_bad.out new file mode 100644 index 000000000..c19645e7d --- /dev/null +++ b/test_regress/t/t_property_sexpr2_bad.out @@ -0,0 +1,10 @@ +%Error: t/t_property_sexpr2_bad.v:20:35: Delay value is not an elaboration-time constant (IEEE 1800-2023 16.7) + : ... note: In instance 't' + 20 | assert property (@(posedge clk) ##clk val); + | ^~ + ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. +%Error: t/t_property_sexpr2_bad.v:21:35: Delay value is not an elaboration-time constant (IEEE 1800-2023 16.7) + : ... note: In instance 't' + 21 | assert property (@(posedge clk) ##(1 + clk) val); + | ^~ +%Error: Exiting due to diff --git a/test_regress/t/t_property_sexpr2_bad.py b/test_regress/t/t_property_sexpr2_bad.py new file mode 100755 index 000000000..5562c90e9 --- /dev/null +++ b/test_regress/t/t_property_sexpr2_bad.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 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, + verilator_flags2=['--assert', '--timing'], + expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_property_sexpr2_bad.v b/test_regress/t/t_property_sexpr2_bad.v new file mode 100644 index 000000000..96e6bd67c --- /dev/null +++ b/test_regress/t/t_property_sexpr2_bad.v @@ -0,0 +1,22 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2025 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +module t ( /*AUTOARG*/ + // Inputs + clk +); + + input clk; + bit val; + + always @(posedge clk) begin + $write("*-* All Finished *-*\n"); + $finish; + end + + assert property (@(posedge clk) ##clk val); + assert property (@(posedge clk) ##(1 + clk) val); +endmodule diff --git a/test_regress/t/t_property_sexpr_multi.v b/test_regress/t/t_property_sexpr_multi.v index 45586fb01..283ccb42e 100644 --- a/test_regress/t/t_property_sexpr_multi.v +++ b/test_regress/t/t_property_sexpr_multi.v @@ -156,7 +156,7 @@ module t ( /*AUTOARG*/ else results[cyc].fails = 1; - assert property (@(e3) ##1 val == 1 ##2 val == 3 ##3 val == 2) + assert property (@(e3) ##1 val == 1 ##2 val == 3 ##(1+2) val == 2) results[cyc].passs = 1; else results[cyc].fails = 1; diff --git a/test_regress/t/t_sequence_sexpr_unsup.out b/test_regress/t/t_sequence_sexpr_unsup.out index a74f6a345..6f1065b80 100644 --- a/test_regress/t/t_sequence_sexpr_unsup.out +++ b/test_regress/t/t_sequence_sexpr_unsup.out @@ -38,15 +38,9 @@ %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:55:4: Unsupported: sequence 55 | sequence s_uni_cycdelay_id; | ^~~~~~~~ -%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:56:7: Unsupported: ## id cycle delay range expression - 56 | ## DELAY b; - | ^~ %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:58:4: Unsupported: sequence 58 | sequence s_uni_cycdelay_pid; | ^~~~~~~~ -%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:59:7: Unsupported: ## () cycle delay range expression - 59 | ## ( DELAY ) b; - | ^~ %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:61:4: Unsupported: sequence 61 | sequence s_uni_cycdelay_range; | ^~~~~~~~ @@ -68,15 +62,9 @@ %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:71:4: Unsupported: sequence 71 | sequence s_cycdelay_id; | ^~~~~~~~ -%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:72:9: Unsupported: ## id cycle delay range expression - 72 | a ## DELAY b; - | ^~ %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:74:4: Unsupported: sequence 74 | sequence s_cycdelay_pid; | ^~~~~~~~ -%Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:75:9: Unsupported: ## () cycle delay range expression - 75 | a ## ( DELAY ) b; - | ^~ %Error-UNSUPPORTED: t/t_sequence_sexpr_unsup.v:77:4: Unsupported: sequence 77 | sequence s_cycdelay_range; | ^~~~~~~~