diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index ea5dd9713..ac8d96a42 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -43,6 +43,7 @@ private: AstVar* m_monitorOffVarp = nullptr; // $monitoroff variable unsigned m_modPastNum = 0; // Module past numbering unsigned m_modStrobeNum = 0; // Module $strobe numbering + const AstNodeProcedure* m_procedurep = nullptr; // Current procedure VDouble0 m_statCover; // Statistic tracking VDouble0 m_statAsNotImm; // Statistic tracking VDouble0 m_statAsImm; // Statistic tracking @@ -145,6 +146,11 @@ private: } else { UASSERT_OBJ(sentreep, nodep, "Concurrent assertions must have sensitivity"); sentreep->unlinkFrBack(); + if (m_procedurep) { + // To support this need queue of asserts to activate + nodep->v3error("Unsupported: Procedural concurent assertion with" + " clocking event inside always (IEEE 1800-2917 16.14.6)"); + } } // AstNode* bodysp = nullptr; @@ -495,6 +501,11 @@ private: iterateChildren(nodep); } } + void visit(AstNodeProcedure* nodep) override { + VL_RESTORER(m_procedurep); + m_procedurep = nodep; + iterateChildren(nodep); + } void visit(AstBegin* nodep) override { // This code is needed rather than a visitor in V3Begin, // because V3Assert is called before V3Begin diff --git a/test_regress/t/t_assert_procedural_clk.out b/test_regress/t/t_assert_procedural_clk.out new file mode 100644 index 000000000..8d930ad07 --- /dev/null +++ b/test_regress/t/t_assert_procedural_clk.out @@ -0,0 +1,9 @@ +%Error: t/t_assert_procedural_clk.v:21:13: Unsupported: Procedural concurent assertion with clocking event inside always (IEEE 1800-2917 16.14.6) + : ... In instance t + 21 | assume property (@(posedge clk) cyc == 9); + | ^~~~~~ +%Error: t/t_assert_procedural_clk.v:22:13: Unsupported: Procedural concurent assertion with clocking event inside always (IEEE 1800-2917 16.14.6) + : ... In instance t + 22 | assume property (@(negedge clk) cyc == 9); + | ^~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_assert_procedural_clk.pl b/test_regress/t/t_assert_procedural_clk.pl new file mode 100755 index 000000000..d188a4276 --- /dev/null +++ b/test_regress/t/t_assert_procedural_clk.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2022 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}, + verilator_flags2 => ['--assert'], + fails => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_assert_procedural_clk.v b/test_regress/t/t_assert_procedural_clk.v new file mode 100644 index 000000000..ef2220d7f --- /dev/null +++ b/test_regress/t/t_assert_procedural_clk.v @@ -0,0 +1,31 @@ +// 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*/ + // Inputs + clk + ); + + input clk; + + integer cyc; initial cyc=1; + wire [7:0] cyc_copy = cyc[7:0]; + + always @ (posedge clk) begin + if (cyc!=0) begin + cyc <= cyc + 1; + if (cyc==9) begin + assume property (@(posedge clk) cyc == 9); + assume property (@(negedge clk) cyc == 9); + end + if (cyc==10) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + end + +endmodule