Support $assertcontrol lock, assertion-type, and non-constant args

This commit is contained in:
Yilou Wang 2026-06-15 22:18:56 +02:00
parent 969a775ae5
commit e91d8d4f8d
10 changed files with 219 additions and 235 deletions

View File

@ -3050,24 +3050,44 @@ bool VerilatedContext::assertOnGet(VerilatedAssertType_t type,
// Check if directive type bit is enabled in corresponding assertion type bits. // Check if directive type bit is enabled in corresponding assertion type bits.
return m_s.m_assertOn & (directive << (typeMaskPosition * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH)); 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<VerilatedAssertType_t>::digits; ++i) {
if (VL_BITISSET_I(types, i)) mask |= directives << (i * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH);
}
return mask;
}
void VerilatedContext::assertOnSet(VerilatedAssertType_t types, void VerilatedContext::assertOnSet(VerilatedAssertType_t types,
VerilatedAssertDirectiveType_t directives) VL_MT_SAFE { VerilatedAssertDirectiveType_t directives) VL_MT_SAFE {
// For each assertion type, set directive bits. m_s.m_assertOn |= assertOnMask(types, directives);
// 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<VerilatedAssertType_t>::digits; ++i) {
if (VL_BITISSET_I(types, i))
m_s.m_assertOn |= directives << (i * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH);
}
} }
void VerilatedContext::assertOnClear(VerilatedAssertType_t types, void VerilatedContext::assertOnClear(VerilatedAssertType_t types,
VerilatedAssertDirectiveType_t directives) VL_MT_SAFE { VerilatedAssertDirectiveType_t directives) VL_MT_SAFE {
// Iterate through all positions of assertion type bits. If bit for this assertion type is set, m_s.m_assertOn &= ~assertOnMask(types, directives);
// clear directive type bits mask at this group index. }
for (int i = 0; i < std::numeric_limits<VerilatedAssertType_t>::digits; ++i) { void VerilatedContext::assertCtl(uint32_t controlType, VerilatedAssertType_t types,
if (VL_BITISSET_I(types, i)) VerilatedAssertDirectiveType_t directives) VL_MT_SAFE {
m_s.m_assertOn &= ~(directives << (i * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH)); // 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 { void VerilatedContext::calcUnusedSigs(bool flag) VL_MT_SAFE {

View File

@ -356,6 +356,9 @@ private:
static constexpr size_t ASSERT_ON_WIDTH static constexpr size_t ASSERT_ON_WIDTH
= ASSERT_DIRECTIVE_TYPE_MASK_WIDTH * std::numeric_limits<VerilatedAssertType_t>::digits = ASSERT_DIRECTIVE_TYPE_MASK_WIDTH * std::numeric_limits<VerilatedAssertType_t>::digits
+ 1; + 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: protected:
// TYPES // TYPES
@ -375,6 +378,9 @@ protected:
// for each VerilatedAssertType we store // for each VerilatedAssertType we store
// 3-bits, one for each directive type. Last // 3-bits, one for each directive type. Last
// bit guards internal directive types. // bit guards internal directive types.
std::atomic<uint32_t> 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_calcUnusedSigs = false; // Waves file on, need all signals calculated
bool m_fatalOnError = true; // Fatal on $stop/non-fatal error bool m_fatalOnError = true; // Fatal on $stop/non-fatal error
bool m_fatalOnVpiError = true; // Fatal on vpi error/unsupported bool m_fatalOnVpiError = true; // Fatal on vpi error/unsupported
@ -484,6 +490,11 @@ public:
/// Clear enabled status for given assertion types /// Clear enabled status for given assertion types
void assertOnClear(VerilatedAssertType_t types, void assertOnClear(VerilatedAssertType_t types,
VerilatedAssertDirectiveType_t directives) VL_MT_SAFE; 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) /// Return if calculating of unused signals (for traces)
bool calcUnusedSigs() const VL_MT_SAFE { return m_s.m_calcUnusedSigs; } bool calcUnusedSigs() const VL_MT_SAFE { return m_s.m_calcUnusedSigs; }
/// Enable calculation of unused signals (for traces) /// Enable calculation of unused signals (for traces)

View File

@ -280,36 +280,12 @@ class AssertVisitor final : public VNVisitor {
+ cvtToStr(nodep->fileline()->lineno()) + ": %m" + ((message != "") ? ": " : "") + cvtToStr(nodep->fileline()->lineno()) + ": %m" + ((message != "") ? ": " : "")
+ message + "\n"); + message + "\n");
} }
static bool resolveAssertType(AstAssertCtl* nodep) { // Default assertion_type and directive_type when the argument is omitted
if (!nodep->assertTypesp()) { // (IEEE 1800-2023 20.11): assertion_type defaults to all types, directive_type
nodep->ctlAssertTypes(VAssertType{ALL_ASSERT_TYPES}); // to Assert|Cover|Assume.
return true; static constexpr uint8_t DEFAULT_DIRECTIVE_TYPES = VAssertDirectiveType::ASSERT
} | VAssertDirectiveType::COVER
if (const AstConst* const assertTypesp = VN_CAST(nodep->assertTypesp(), Const)) { | VAssertDirectiveType::ASSUME;
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;
}
void replaceDisplay(AstDisplay* nodep, const string& prefix) { void replaceDisplay(AstDisplay* nodep, const string& prefix) {
nodep->fmtp()->text( nodep->fmtp()->text(
assertDisplayMessage(nodep, prefix, nodep->fmtp()->text(), nodep->displayType())); assertDisplayMessage(nodep, prefix, nodep->fmtp()->text(), nodep->displayType()));
@ -1002,71 +978,50 @@ class AssertVisitor final : public VNVisitor {
} }
void visit(AstAssertCtl* nodep) override { void visit(AstAssertCtl* nodep) override {
iterateChildren(nodep); 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(); FileLine* const fl = nodep->fileline();
switch (nodep->ctlType()) {
case VAssertCtlType::ON: // control_type, assertion_type and directive_type are integer expressions
UINFO(9, "Generating assertctl for a module: " << m_modp); // (IEEE 1800-2023 20.11) and may be non-constant; they are evaluated at runtime
nodep->replaceWith( // by VerilatedContext::assertCtl. The levels and scope/assertion-list arguments
new AstCStmt{fl, "vlSymsp->_vm_contextp__->assertOnSet("s // are not modeled -- control applies to the whole context.
+ std::to_string(nodep->ctlAssertTypes()) + ", "s // When control_type is a compile-time constant, reject the not-yet-modeled
+ std::to_string(nodep->ctlDirectiveTypes()) + ");\n"s}); // action-control codes (Table 20-5 values 6..11) and out-of-range values with a
break; // clear error rather than emitting a runtime no-op.
case VAssertCtlType::OFF: if (const AstConst* const controlp = VN_CAST(nodep->controlTypep(), Const)) {
case VAssertCtlType::KILL: { const int32_t control = controlp->toSInt();
UINFO(9, "Generating assertctl for a module: " << m_modp); if (control < VAssertCtlType::LOCK || control > VAssertCtlType::VACUOUS_OFF) {
nodep->replaceWith( nodep->unlinkFrBack();
new AstCStmt{fl, "vlSymsp->_vm_contextp__->assertOnClear("s nodep->v3warn(EC_ERROR, "Bad $assertcontrol control_type '"
+ std::to_string(nodep->ctlAssertTypes()) + " ,"s << control << "' (IEEE 1800-2023 Table 20-5)");
+ std::to_string(nodep->ctlDirectiveTypes()) + ");\n"s}); VL_DO_DANGLING(pushDeletep(nodep), nodep);
break; 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: UINFO(9, "Generating assertctl in module: " << m_modp);
case VAssertCtlType::PASS_ON: AstCStmt* const callp = new AstCStmt{fl, "vlSymsp->_vm_contextp__->assertCtl("};
case VAssertCtlType::PASS_OFF: callp->add(nodep->controlTypep()->unlinkFrBack());
case VAssertCtlType::FAIL_ON: callp->add(", ");
case VAssertCtlType::FAIL_OFF: if (AstNodeExpr* const typesp = nodep->assertTypesp()) {
case VAssertCtlType::NONVACUOUS_ON: callp->add(typesp->unlinkFrBack());
case VAssertCtlType::VACUOUS_OFF: { } else {
nodep->unlinkFrBack(); callp->add(std::to_string(ALL_ASSERT_TYPES));
nodep->v3warn(E_UNSUPPORTED, "Unsupported: $assertcontrol control_type '" << cvtToStr(
static_cast<int>(nodep->ctlType())) << "'");
break;
}
default: {
nodep->unlinkFrBack();
nodep->v3warn(EC_ERROR, "Bad $assertcontrol control_type '"
<< cvtToStr(static_cast<int>(nodep->ctlType()))
<< "' (IEEE 1800-2023 Table 20-5)");
} }
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); VL_DO_DANGLING(pushDeletep(nodep), nodep);
} }
void visit(AstAssertIntrinsic* nodep) override { // void visit(AstAssertIntrinsic* nodep) override { //

View File

@ -1,18 +0,0 @@
%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

View File

@ -1,20 +0,0 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain
// SPDX-FileCopyrightText: 2024 Antmicro
// SPDX-License-Identifier: CC0-1.0
module t;
let OFF = 4;
let EXPECT = 16;
let UNIQUE = 32;
let UNIQUE0 = 64;
let PRIORITY = 128;
initial begin
$assertcontrol(OFF, EXPECT);
$assertcontrol(OFF, UNIQUE);
$assertcontrol(OFF, UNIQUE0);
$assertcontrol(OFF, PRIORITY);
end
endmodule

View File

@ -4,13 +4,15 @@
# This program is free software; you can redistribute it and/or modify it # 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 # under the terms of either the GNU Lesser General Public License Version 3
# or the Perl Artistic License Version 2.0. # or the Perl Artistic License Version 2.0.
# SPDX-FileCopyrightText: 2024 Wilson Snyder # SPDX-FileCopyrightText: 2026 Wilson Snyder
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap import vltest_bootstrap
test.scenarios('vlt') test.scenarios('vlt')
test.lint(fails=True, expect_filename=test.golden_filename) test.compile(verilator_flags2=["--binary --assert"])
test.execute()
test.passes() test.passes()

View File

@ -0,0 +1,58 @@
// 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
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 re-enables the immediate assertion.
ctl = 3; // On
$assertcontrol(ctl, 2); // non-const On, SIMPLE_IMMEDIATE
#20; // t=70: edges @55,@65 -> both on
// Phase E: off everything.
$assertcontrol(4); // Off all
#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

View File

@ -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()

View File

@ -1,103 +1,74 @@
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:26:5: Unsupported: non-constant assert assertion-type expression %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:23:5: Unsupported: $assertcontrol control_type '6'
: ... note: In instance 't.unsupported_ctl_type' 23 | $assertcontrol(PassOn);
26 | $assertcontrol(Lock, a);
| ^~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest ... 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' %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:24:5: Unsupported: $assertcontrol control_type '6'
28 | $assertcontrol(Unlock); 24 | $assertpasson;
| ^~~~~~~~~~~~~~
%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:32:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:25:5: Unsupported: $assertcontrol control_type '6'
: ... note: In instance 't.unsupported_ctl_type' 25 | $assertpasson(a);
32 | $assertpasson(a);
| ^~~~~~~~~~~~~ | ^~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:33:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:26:5: Unsupported: $assertcontrol control_type '6'
: ... note: In instance 't.unsupported_ctl_type' 26 | $assertpasson(a, t);
33 | $assertpasson(a, t);
| ^~~~~~~~~~~~~ | ^~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:35:5: Unsupported: $assertcontrol control_type '7' %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:28:5: Unsupported: $assertcontrol control_type '7'
35 | $assertcontrol(PassOff); 28 | $assertcontrol(PassOff);
| ^~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:36:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:29:5: Unsupported: $assertcontrol control_type '7'
: ... note: In instance 't.unsupported_ctl_type' 29 | $assertpassoff;
36 | $assertpassoff;
| ^~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:37:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:30:5: Unsupported: $assertcontrol control_type '7'
: ... note: In instance 't.unsupported_ctl_type' 30 | $assertpassoff(a);
37 | $assertpassoff(a);
| ^~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:38:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:31:5: Unsupported: $assertcontrol control_type '7'
: ... note: In instance 't.unsupported_ctl_type' 31 | $assertpassoff(a, t);
38 | $assertpassoff(a, t);
| ^~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:40:5: Unsupported: $assertcontrol control_type '8' %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:33:5: Unsupported: $assertcontrol control_type '8'
40 | $assertcontrol(FailOn); 33 | $assertcontrol(FailOn);
| ^~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:41:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:34:5: Unsupported: $assertcontrol control_type '8'
: ... note: In instance 't.unsupported_ctl_type' 34 | $assertfailon;
41 | $assertfailon;
| ^~~~~~~~~~~~~ | ^~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:42:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:35:5: Unsupported: $assertcontrol control_type '8'
: ... note: In instance 't.unsupported_ctl_type' 35 | $assertfailon(a);
42 | $assertfailon(a);
| ^~~~~~~~~~~~~ | ^~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:43:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:36:5: Unsupported: $assertcontrol control_type '8'
: ... note: In instance 't.unsupported_ctl_type' 36 | $assertfailon(a, t);
43 | $assertfailon(a, t);
| ^~~~~~~~~~~~~ | ^~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:45:5: Unsupported: $assertcontrol control_type '9' %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:38:5: Unsupported: $assertcontrol control_type '9'
45 | $assertcontrol(FailOff); 38 | $assertcontrol(FailOff);
| ^~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:46:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:39:5: Unsupported: $assertcontrol control_type '9'
: ... note: In instance 't.unsupported_ctl_type' 39 | $assertfailoff;
46 | $assertfailoff;
| ^~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:47:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:40:5: Unsupported: $assertcontrol control_type '9'
: ... note: In instance 't.unsupported_ctl_type' 40 | $assertfailoff(a);
47 | $assertfailoff(a);
| ^~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:48:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:41:5: Unsupported: $assertcontrol control_type '9'
: ... note: In instance 't.unsupported_ctl_type' 41 | $assertfailoff(a, t);
48 | $assertfailoff(a, t);
| ^~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:50:5: Unsupported: $assertcontrol control_type '10' %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:43:5: Unsupported: $assertcontrol control_type '10'
50 | $assertcontrol(NonvacuousOn); 43 | $assertcontrol(NonvacuousOn);
| ^~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:51:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:44:5: Unsupported: $assertcontrol control_type '10'
: ... note: In instance 't.unsupported_ctl_type' 44 | $assertnonvacuouson;
51 | $assertnonvacuouson;
| ^~~~~~~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:52:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:45:5: Unsupported: $assertcontrol control_type '10'
: ... note: In instance 't.unsupported_ctl_type' 45 | $assertnonvacuouson(a);
52 | $assertnonvacuouson(a);
| ^~~~~~~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:53:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:46:5: Unsupported: $assertcontrol control_type '10'
: ... note: In instance 't.unsupported_ctl_type' 46 | $assertnonvacuouson(a, t);
53 | $assertnonvacuouson(a, t);
| ^~~~~~~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:55:5: Unsupported: $assertcontrol control_type '11' %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:48:5: Unsupported: $assertcontrol control_type '11'
55 | $assertcontrol(VacuousOff); 48 | $assertcontrol(VacuousOff);
| ^~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:56:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:49:5: Unsupported: $assertcontrol control_type '11'
: ... note: In instance 't.unsupported_ctl_type' 49 | $assertvacuousoff;
56 | $assertvacuousoff;
| ^~~~~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:57:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:50:5: Unsupported: $assertcontrol control_type '11'
: ... note: In instance 't.unsupported_ctl_type' 50 | $assertvacuousoff(a);
57 | $assertvacuousoff(a);
| ^~~~~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:58:5: Unsupported: assert control assertion_type %Error-UNSUPPORTED: t/t_assert_ctl_unsup.v:51:5: Unsupported: $assertcontrol control_type '11'
: ... note: In instance 't.unsupported_ctl_type' 51 | $assertvacuousoff(a, t);
58 | $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 %Error: Exiting due to

View File

@ -8,25 +8,18 @@ module t (
input logic clk input logic clk
); );
unsupported_ctl_type unsupported_ctl_type (clk ? 1 : 2); unsupported_ctl_type unsupported_ctl_type (clk ? 1 : 2);
unsupported_ctl_type_expr unsupported_ctl_type_expr ();
endmodule endmodule
module unsupported_ctl_type ( module unsupported_ctl_type (
input int a input int a
); );
initial begin initial begin
let Lock = 1;
let Unlock = 2;
let PassOn = 6; let PassOn = 6;
let PassOff = 7; let PassOff = 7;
let FailOn = 8; let FailOn = 8;
let FailOff = 9; let FailOff = 9;
let NonvacuousOn = 10; let NonvacuousOn = 10;
let VacuousOff = 11; let VacuousOff = 11;
$assertcontrol(Lock, a);
$assertcontrol(Unlock);
$assertcontrol(PassOn); $assertcontrol(PassOn);
$assertpasson; $assertpasson;
$assertpasson(a); $assertpasson(a);
@ -58,10 +51,3 @@ module unsupported_ctl_type (
$assertvacuousoff(a, t); $assertvacuousoff(a, t);
end end
endmodule endmodule
module unsupported_ctl_type_expr;
int ctl_type = 1;
initial begin
$assertcontrol(ctl_type);
end
endmodule