Support $assertcontrol lock, assertion-type, and non-constant args
This commit is contained in:
parent
969a775ae5
commit
e91d8d4f8d
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
137
src/V3Assert.cpp
137
src/V3Assert.cpp
|
|
@ -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 { //
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue