From b581f73843dec967cb695020bd8169d914d6838a Mon Sep 17 00:00:00 2001 From: Yilou Wang Date: Wed, 17 Jun 2026 13:17:39 +0200 Subject: [PATCH] Support $assertcontrol control_type from lock to kill (#7788) --- include/verilated.cpp | 46 +++++-- include/verilated.h | 11 ++ src/V3Assert.cpp | 151 +++++++++------------- test_regress/t/t_assert_ctl_arg_unsup.out | 4 - test_regress/t/t_assert_ctl_lock.py | 18 +++ test_regress/t/t_assert_ctl_lock.v | 66 ++++++++++ test_regress/t/t_assert_ctl_lock_noinl.py | 19 +++ test_regress/t/t_assert_ctl_unsup.out | 125 +++++++----------- test_regress/t/t_assert_ctl_unsup.v | 14 -- 9 files changed, 256 insertions(+), 198 deletions(-) create mode 100755 test_regress/t/t_assert_ctl_lock.py create mode 100644 test_regress/t/t_assert_ctl_lock.v create mode 100755 test_regress/t/t_assert_ctl_lock_noinl.py diff --git a/include/verilated.cpp b/include/verilated.cpp index a7d78f3bd..fcfbab58a 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -3050,24 +3050,44 @@ bool VerilatedContext::assertOnGet(VerilatedAssertType_t type, // Check if directive type bit is enabled in corresponding assertion type bits. return m_s.m_assertOn & (directive << (typeMaskPosition * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH)); } +uint32_t VerilatedContext::assertOnMask(VerilatedAssertType_t types, + VerilatedAssertDirectiveType_t directives) VL_PURE { + // Place the directive bits at each selected assertion type's 3-bit group. + uint32_t mask = 0; + for (int i = 0; i < std::numeric_limits::digits; ++i) { + if (VL_BITISSET_I(types, i)) mask |= directives << (i * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH); + } + return mask; +} void VerilatedContext::assertOnSet(VerilatedAssertType_t types, VerilatedAssertDirectiveType_t directives) VL_MT_SAFE { - // For each assertion type, set directive bits. - - // Iterate through all positions of assertion type bits. If bit for this assertion type is set, - // set directive type bits mask at this group index. - for (int i = 0; i < std::numeric_limits::digits; ++i) { - if (VL_BITISSET_I(types, i)) - m_s.m_assertOn |= directives << (i * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH); - } + m_s.m_assertOn |= assertOnMask(types, directives); } void VerilatedContext::assertOnClear(VerilatedAssertType_t types, VerilatedAssertDirectiveType_t directives) VL_MT_SAFE { - // Iterate through all positions of assertion type bits. If bit for this assertion type is set, - // clear directive type bits mask at this group index. - for (int i = 0; i < std::numeric_limits::digits; ++i) { - if (VL_BITISSET_I(types, i)) - m_s.m_assertOn &= ~(directives << (i * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH)); + m_s.m_assertOn &= ~assertOnMask(types, directives); +} +void VerilatedContext::assertCtl(uint32_t controlType, VerilatedAssertType_t types, + VerilatedAssertDirectiveType_t directives) VL_MT_SAFE { + // IEEE 1800-2023 Table 20-5 control_type. Lock freezes the On/Off state of the + // selected bits until Unlock; On/Off/Kill leave locked bits unchanged. + const uint32_t mask = assertOnMask(types, directives); + switch (controlType) { + case 1: // Lock + m_s.m_assertLock |= mask; + break; + case 2: // Unlock + m_s.m_assertLock &= ~mask; + break; + case 3: // On + m_s.m_assertOn |= mask & ~m_s.m_assertLock; + break; + case 4: // Off + case 5: // Kill + m_s.m_assertOn &= ~(mask & ~m_s.m_assertLock); + break; + default: // 6..11 (Pass/Fail/Vacuous action control) are not modeled; ignore + break; } } void VerilatedContext::calcUnusedSigs(bool flag) VL_MT_SAFE { diff --git a/include/verilated.h b/include/verilated.h index 707ede5ce..f8075567e 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -356,6 +356,9 @@ private: static constexpr size_t ASSERT_ON_WIDTH = ASSERT_DIRECTIVE_TYPE_MASK_WIDTH * std::numeric_limits::digits + 1; + // Build the m_assertOn/m_assertLock bit mask for the given assertion x directive types. + static uint32_t assertOnMask(VerilatedAssertType_t types, + VerilatedAssertDirectiveType_t directives) VL_PURE; protected: // TYPES @@ -375,6 +378,9 @@ protected: // for each VerilatedAssertType we store // 3-bits, one for each directive type. Last // bit guards internal directive types. + std::atomic m_assertLock{0}; // Locked assertion bits (IEEE 1800-2023 20.11 + // Lock/Unlock); same layout as m_assertOn. While + // a bit is locked, On/Off/Kill leave it unchanged. bool m_calcUnusedSigs = false; // Waves file on, need all signals calculated bool m_fatalOnError = true; // Fatal on $stop/non-fatal error bool m_fatalOnVpiError = true; // Fatal on vpi error/unsupported @@ -484,6 +490,11 @@ public: /// Clear enabled status for given assertion types void assertOnClear(VerilatedAssertType_t types, VerilatedAssertDirectiveType_t directives) VL_MT_SAFE; + /// Apply a $assertcontrol control_type (IEEE 1800-2023 Table 20-5) to the given + /// assertion and directive types: 1=Lock, 2=Unlock, 3=On, 4=Off, 5=Kill. Locked + /// bits are left unchanged by On/Off/Kill. Other control_type values are ignored. + void assertCtl(uint32_t controlType, VerilatedAssertType_t types, + VerilatedAssertDirectiveType_t directives) VL_MT_SAFE; /// Return if calculating of unused signals (for traces) bool calcUnusedSigs() const VL_MT_SAFE { return m_s.m_calcUnusedSigs; } /// Enable calculation of unused signals (for traces) diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 47c1874f3..18df21153 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -280,36 +280,12 @@ class AssertVisitor final : public VNVisitor { + cvtToStr(nodep->fileline()->lineno()) + ": %m" + ((message != "") ? ": " : "") + message + "\n"); } - static bool resolveAssertType(AstAssertCtl* nodep) { - if (!nodep->assertTypesp()) { - nodep->ctlAssertTypes(VAssertType{ALL_ASSERT_TYPES}); - return true; - } - if (const AstConst* const assertTypesp = VN_CAST(nodep->assertTypesp(), Const)) { - nodep->ctlAssertTypes(VAssertType{assertTypesp->toSInt()}); - return true; - } - return false; - } - static bool resolveControlType(AstAssertCtl* nodep) { - if (const AstConst* const constp = VN_CAST(nodep->controlTypep(), Const)) { - nodep->ctlType(constp->toSInt()); - return true; - } - return false; - } - static bool resolveDirectiveType(AstAssertCtl* nodep) { - if (!nodep->directiveTypesp()) { - nodep->ctlDirectiveTypes(VAssertDirectiveType::ASSERT | VAssertDirectiveType::ASSUME - | VAssertDirectiveType::COVER); - return true; - } - if (const AstConst* const directiveTypesp = VN_CAST(nodep->directiveTypesp(), Const)) { - nodep->ctlDirectiveTypes(VAssertDirectiveType{directiveTypesp->toSInt()}); - return true; - } - return false; - } + // Default assertion_type and directive_type when the argument is omitted + // (IEEE 1800-2023 20.11): assertion_type defaults to all types, directive_type + // to Assert|Cover|Assume. + static constexpr uint8_t DEFAULT_DIRECTIVE_TYPES = VAssertDirectiveType::ASSERT + | VAssertDirectiveType::COVER + | VAssertDirectiveType::ASSUME; void replaceDisplay(AstDisplay* nodep, const string& prefix) { nodep->fmtp()->text( assertDisplayMessage(nodep, prefix, nodep->fmtp()->text(), nodep->displayType())); @@ -1002,71 +978,66 @@ class AssertVisitor final : public VNVisitor { } void visit(AstAssertCtl* nodep) override { iterateChildren(nodep); - - if (!resolveAssertType(nodep)) { - nodep->v3warn(E_UNSUPPORTED, - "Unsupported: non-constant assert assertion-type expression"); - VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); - return; - } - if (nodep->ctlAssertTypes() != ALL_ASSERT_TYPES - && nodep->ctlAssertTypes().containsAny(VAssertType::EXPECT | VAssertType::UNIQUE - | VAssertType::UNIQUE0 - | VAssertType::PRIORITY)) { - nodep->v3warn(E_UNSUPPORTED, "Unsupported: assert control assertion_type"); - VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); - return; - } - if (!resolveControlType(nodep)) { - nodep->v3warn(E_UNSUPPORTED, "Unsupported: non-const assert control type expression"); - VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); - return; - } - if (!resolveDirectiveType(nodep)) { - nodep->v3warn(E_UNSUPPORTED, - "Unsupported: non-const assert directive type expression"); - VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); - return; - } - FileLine* const fl = nodep->fileline(); - switch (nodep->ctlType()) { - case VAssertCtlType::ON: - UINFO(9, "Generating assertctl for a module: " << m_modp); - nodep->replaceWith( - new AstCStmt{fl, "vlSymsp->_vm_contextp__->assertOnSet("s - + std::to_string(nodep->ctlAssertTypes()) + ", "s - + std::to_string(nodep->ctlDirectiveTypes()) + ");\n"s}); - break; - case VAssertCtlType::OFF: - case VAssertCtlType::KILL: { - UINFO(9, "Generating assertctl for a module: " << m_modp); - nodep->replaceWith( - new AstCStmt{fl, "vlSymsp->_vm_contextp__->assertOnClear("s - + std::to_string(nodep->ctlAssertTypes()) + " ,"s - + std::to_string(nodep->ctlDirectiveTypes()) + ");\n"s}); - break; + + // control_type, assertion_type and directive_type are integer expressions + // (IEEE 1800-2023 20.11) and may be non-constant; they are evaluated at runtime + // by VerilatedContext::assertCtl. The levels and scope/assertion-list arguments + // are not modeled -- control applies to the whole context. + // When control_type is a compile-time constant, reject the not-yet-modeled + // action-control codes (Table 20-5 values 6..11) and out-of-range values with a + // clear error rather than emitting a runtime no-op. + if (const AstConst* const controlp = VN_CAST(nodep->controlTypep(), Const)) { + const int32_t control = controlp->toSInt(); + if (control < VAssertCtlType::LOCK || control > VAssertCtlType::VACUOUS_OFF) { + nodep->unlinkFrBack(); + nodep->v3warn(EC_ERROR, "Bad $assertcontrol control_type '" + << control << "' (IEEE 1800-2023 Table 20-5)"); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + return; + } + if (control >= VAssertCtlType::PASS_ON) { + nodep->unlinkFrBack(); + nodep->v3warn(E_UNSUPPORTED, + "Unsupported: $assertcontrol control_type '" << control << "'"); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + return; + } } - case VAssertCtlType::LOCK: - case VAssertCtlType::UNLOCK: - case VAssertCtlType::PASS_ON: - case VAssertCtlType::PASS_OFF: - case VAssertCtlType::FAIL_ON: - case VAssertCtlType::FAIL_OFF: - case VAssertCtlType::NONVACUOUS_ON: - case VAssertCtlType::VACUOUS_OFF: { - nodep->unlinkFrBack(); - nodep->v3warn(E_UNSUPPORTED, "Unsupported: $assertcontrol control_type '" << cvtToStr( - static_cast(nodep->ctlType())) << "'"); - break; + + // When assertion_type is a compile-time constant, reject values that cannot be + // filtered at runtime because unique/priority violations use bare assertOn() rather + // than a per-type assertOnGet() call (IEEE 1800-2023 Table 20-6). + if (nodep->assertTypesp()) { + if (const AstConst* const typecp = VN_CAST(nodep->assertTypesp(), Const)) { + if (typecp->toUInt() + & (VAssertType::EXPECT | VAssertType::UNIQUE | VAssertType::UNIQUE0 + | VAssertType::PRIORITY)) { + nodep->unlinkFrBack(); + nodep->v3warn(E_UNSUPPORTED, "Unsupported: assert control assertion_type"); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + return; + } + } } - default: { - nodep->unlinkFrBack(); - nodep->v3warn(EC_ERROR, "Bad $assertcontrol control_type '" - << cvtToStr(static_cast(nodep->ctlType())) - << "' (IEEE 1800-2023 Table 20-5)"); + + UINFO(9, "Generating assertctl in module: " << m_modp); + AstCStmt* const callp = new AstCStmt{fl, "vlSymsp->_vm_contextp__->assertCtl("}; + callp->add(nodep->controlTypep()->unlinkFrBack()); + callp->add(", "); + if (AstNodeExpr* const typesp = nodep->assertTypesp()) { + callp->add(typesp->unlinkFrBack()); + } else { + callp->add(std::to_string(ALL_ASSERT_TYPES)); } + callp->add(", "); + if (AstNodeExpr* const directivesp = nodep->directiveTypesp()) { + callp->add(directivesp->unlinkFrBack()); + } else { + callp->add(std::to_string(DEFAULT_DIRECTIVE_TYPES)); } + callp->add(");\n"); + nodep->replaceWith(callp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } void visit(AstAssertIntrinsic* nodep) override { // diff --git a/test_regress/t/t_assert_ctl_arg_unsup.out b/test_regress/t/t_assert_ctl_arg_unsup.out index c9bad92c3..da5e1145d 100644 --- a/test_regress/t/t_assert_ctl_arg_unsup.out +++ b/test_regress/t/t_assert_ctl_arg_unsup.out @@ -1,18 +1,14 @@ %Error-UNSUPPORTED: t/t_assert_ctl_arg_unsup.v:15:5: Unsupported: assert control assertion_type - : ... note: In instance 't' 15 | $assertcontrol(OFF, EXPECT); | ^~~~~~~~~~~~~~ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest %Error-UNSUPPORTED: t/t_assert_ctl_arg_unsup.v:16:5: Unsupported: assert control assertion_type - : ... note: In instance 't' 16 | $assertcontrol(OFF, UNIQUE); | ^~~~~~~~~~~~~~ %Error-UNSUPPORTED: t/t_assert_ctl_arg_unsup.v:17:5: Unsupported: assert control assertion_type - : ... note: In instance 't' 17 | $assertcontrol(OFF, UNIQUE0); | ^~~~~~~~~~~~~~ %Error-UNSUPPORTED: t/t_assert_ctl_arg_unsup.v:18:5: Unsupported: assert control assertion_type - : ... note: In instance 't' 18 | $assertcontrol(OFF, PRIORITY); | ^~~~~~~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_assert_ctl_lock.py b/test_regress/t/t_assert_ctl_lock.py new file mode 100755 index 000000000..fdd1c0d4d --- /dev/null +++ b/test_regress/t/t_assert_ctl_lock.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# 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-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.compile(verilator_flags2=["--binary --assert"]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_assert_ctl_lock.v b/test_regress/t/t_assert_ctl_lock.v new file mode 100644 index 000000000..cc9ce8411 --- /dev/null +++ b/test_regress/t/t_assert_ctl_lock.v @@ -0,0 +1,66 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 PlanV GmbH +// SPDX-License-Identifier: CC0-1.0 + +`ifdef verilator + `define no_optimize(v) $c(v) +`else + `define no_optimize(v) (v) +`endif + +module t ( /*AUTOARG*/); + logic clk = 0; + int imm_fails = 0, conc_fails = 0; + logic a = 1'b1; // antecedent always true + logic b = 1'b0; // consequent always false -> assertion always violates + + always #5 clk = ~clk; + + // Immediate assertion: assertion_type SIMPLE_IMMEDIATE (mask value 2). + always @(posedge clk) + ia : + assert (b) + else imm_fails = imm_fails + 1; + + // Concurrent assertion: assertion_type CONCURRENT (mask value 1). + ca : + assert property (@(posedge clk) a |-> b) + else conc_fails = conc_fails + 1; + + int ctl; + + // posedge clk at t = 5, 15, 25, 35, 45, 55, 65, 75, 85, 95. + initial begin + // Phase A (t=0..): everything on. edge@5 -> imm+1, conc+1. + #6; // t=6 + // Phase B: lock the on state, then $assertoff must be ignored while locked. + $assertcontrol(1); // Lock, all types + $assertoff; // ignored -> edges @15,@25 still fire both + #24; // t=30 + // Phase C: unlock, then turn off only SIMPLE_IMMEDIATE via assertion_type filter. + $assertcontrol(2); // Unlock + $assertcontrol(4, 2); // Off, assertion_type = SIMPLE_IMMEDIATE only + #20; // t=50: edges @35,@45 -> imm off, conc still on + // Phase D: non-constant control_type and assertion_type re-enable the immediate. + ctl = `no_optimize(3); // On + $assertcontrol(ctl, `no_optimize(2)); // non-const On, SIMPLE_IMMEDIATE + #20; // t=70: edges @55,@65 -> both on + // Phase E: off everything, then a non-const action-control code (no runtime effect). + $assertcontrol(4); // Off all + ctl = `no_optimize(7); // Pass_Off (IEEE 1800-2023 Table 20-5 action control) + $assertcontrol(ctl); // non-const action-control: evaluated at runtime, ignored + #30; // t=100: edges @75,@85,@95 -> none + $finish; + end + + final begin + // Concrete counts cross-checked against Questa 2022.3: imm_fails=5 conc_fails=7. + if (imm_fails != 5 || conc_fails != 7) begin + $display("%%Error: imm_fails=%0d (exp 5) conc_fails=%0d (exp 7)", imm_fails, conc_fails); + $stop; + end + $write("*-* All Finished *-*\n"); + end +endmodule diff --git a/test_regress/t/t_assert_ctl_lock_noinl.py b/test_regress/t/t_assert_ctl_lock_noinl.py new file mode 100755 index 000000000..83440d018 --- /dev/null +++ b/test_regress/t/t_assert_ctl_lock_noinl.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# 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-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') +test.top_filename = "t_assert_ctl_lock.v" + +test.compile(verilator_flags2=["--binary --assert --fno-inline"]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_assert_ctl_unsup.out b/test_regress/t/t_assert_ctl_unsup.out index b00a2a58f..d0aaa3d7e 100644 --- a/test_regress/t/t_assert_ctl_unsup.out +++ b/test_regress/t/t_assert_ctl_unsup.out @@ -1,103 +1,74 @@ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:26:5: Unsupported: non-constant assert assertion-type expression - : ... note: In instance 't.unsupported_ctl_type' - 26 | $assertcontrol(Lock, a); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:23:5: Unsupported: $assertcontrol control_type '6' + 23 | $assertcontrol(PassOn); | ^~~~~~~~~~~~~~ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:28:5: Unsupported: $assertcontrol control_type '2' - 28 | $assertcontrol(Unlock); - | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:30:5: Unsupported: $assertcontrol control_type '6' - 30 | $assertcontrol(PassOn); - | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:31:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 31 | $assertpasson; +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:24:5: Unsupported: $assertcontrol control_type '6' + 24 | $assertpasson; | ^~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:32:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 32 | $assertpasson(a); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:25:5: Unsupported: $assertcontrol control_type '6' + 25 | $assertpasson(a); | ^~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:33:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 33 | $assertpasson(a, t); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:26:5: Unsupported: $assertcontrol control_type '6' + 26 | $assertpasson(a, t); | ^~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:35:5: Unsupported: $assertcontrol control_type '7' - 35 | $assertcontrol(PassOff); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:28:5: Unsupported: $assertcontrol control_type '7' + 28 | $assertcontrol(PassOff); | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:36:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 36 | $assertpassoff; +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:29:5: Unsupported: $assertcontrol control_type '7' + 29 | $assertpassoff; | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:37:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 37 | $assertpassoff(a); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:30:5: Unsupported: $assertcontrol control_type '7' + 30 | $assertpassoff(a); | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:38:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 38 | $assertpassoff(a, t); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:31:5: Unsupported: $assertcontrol control_type '7' + 31 | $assertpassoff(a, t); | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:40:5: Unsupported: $assertcontrol control_type '8' - 40 | $assertcontrol(FailOn); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:33:5: Unsupported: $assertcontrol control_type '8' + 33 | $assertcontrol(FailOn); | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:41:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 41 | $assertfailon; +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:34:5: Unsupported: $assertcontrol control_type '8' + 34 | $assertfailon; | ^~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:42:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 42 | $assertfailon(a); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:35:5: Unsupported: $assertcontrol control_type '8' + 35 | $assertfailon(a); | ^~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:43:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 43 | $assertfailon(a, t); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:36:5: Unsupported: $assertcontrol control_type '8' + 36 | $assertfailon(a, t); | ^~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:45:5: Unsupported: $assertcontrol control_type '9' - 45 | $assertcontrol(FailOff); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:38:5: Unsupported: $assertcontrol control_type '9' + 38 | $assertcontrol(FailOff); | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:46:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 46 | $assertfailoff; +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:39:5: Unsupported: $assertcontrol control_type '9' + 39 | $assertfailoff; | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:47:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 47 | $assertfailoff(a); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:40:5: Unsupported: $assertcontrol control_type '9' + 40 | $assertfailoff(a); | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:48:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 48 | $assertfailoff(a, t); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:41:5: Unsupported: $assertcontrol control_type '9' + 41 | $assertfailoff(a, t); | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:50:5: Unsupported: $assertcontrol control_type '10' - 50 | $assertcontrol(NonvacuousOn); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:43:5: Unsupported: $assertcontrol control_type '10' + 43 | $assertcontrol(NonvacuousOn); | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:51:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 51 | $assertnonvacuouson; +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:44:5: Unsupported: $assertcontrol control_type '10' + 44 | $assertnonvacuouson; | ^~~~~~~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:52:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 52 | $assertnonvacuouson(a); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:45:5: Unsupported: $assertcontrol control_type '10' + 45 | $assertnonvacuouson(a); | ^~~~~~~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:53:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 53 | $assertnonvacuouson(a, t); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:46:5: Unsupported: $assertcontrol control_type '10' + 46 | $assertnonvacuouson(a, t); | ^~~~~~~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:55:5: Unsupported: $assertcontrol control_type '11' - 55 | $assertcontrol(VacuousOff); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:48:5: Unsupported: $assertcontrol control_type '11' + 48 | $assertcontrol(VacuousOff); | ^~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:56:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 56 | $assertvacuousoff; +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:49:5: Unsupported: $assertcontrol control_type '11' + 49 | $assertvacuousoff; | ^~~~~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:57:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 57 | $assertvacuousoff(a); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:50:5: Unsupported: $assertcontrol control_type '11' + 50 | $assertvacuousoff(a); | ^~~~~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:58:5: Unsupported: assert control assertion_type - : ... note: In instance 't.unsupported_ctl_type' - 58 | $assertvacuousoff(a, t); +%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:51:5: Unsupported: $assertcontrol control_type '11' + 51 | $assertvacuousoff(a, t); | ^~~~~~~~~~~~~~~~~ -%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:65:5: Unsupported: non-const assert control type expression - : ... note: In instance 't.unsupported_ctl_type_expr' - 65 | $assertcontrol(ctl_type); - | ^~~~~~~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_assert_ctl_unsup.v b/test_regress/t/t_assert_ctl_unsup.v index 90d63e86c..027b4e824 100644 --- a/test_regress/t/t_assert_ctl_unsup.v +++ b/test_regress/t/t_assert_ctl_unsup.v @@ -8,25 +8,18 @@ module t ( input logic clk ); unsupported_ctl_type unsupported_ctl_type (clk ? 1 : 2); - unsupported_ctl_type_expr unsupported_ctl_type_expr (); endmodule module unsupported_ctl_type ( input int a ); initial begin - let Lock = 1; - let Unlock = 2; let PassOn = 6; let PassOff = 7; let FailOn = 8; let FailOff = 9; let NonvacuousOn = 10; let VacuousOff = 11; - $assertcontrol(Lock, a); - - $assertcontrol(Unlock); - $assertcontrol(PassOn); $assertpasson; $assertpasson(a); @@ -58,10 +51,3 @@ module unsupported_ctl_type ( $assertvacuousoff(a, t); end endmodule - -module unsupported_ctl_type_expr; - int ctl_type = 1; - initial begin - $assertcontrol(ctl_type); - end -endmodule