diff --git a/include/verilated.cpp b/include/verilated.cpp index cfd88c5a7..ecfb98881 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -3128,32 +3128,16 @@ VerilatedContext::Serialized::Serialized() { bool VerilatedContext::assertOn() const VL_MT_SAFE { return m_s.m_assertOn; } void VerilatedContext::assertOn(bool flag) VL_MT_SAFE { - if (assertCtlsLocked()) return; + if (m_ns.m_assertCtlsLocked) return; // Set all assert and directive types when true, clear otherwise. m_s.m_assertOn = VL_MASK_I(ASSERT_ON_WIDTH) * flag; } -bool VerilatedContext::assertOnGet(VerilatedAssertType_t type, - VerilatedAssertDirectiveType_t directive) const VL_MT_SAFE { - return assertCtlGet(VerilatedAssertCtlQuery::ASSERT_CTL_ON, type, directive); -} -void VerilatedContext::assertOnSet(VerilatedAssertType_t types, - VerilatedAssertDirectiveType_t directives) VL_MT_SAFE { - if (assertCtlsLocked()) return; - m_s.m_assertOn |= assertOnMask(types, directives); -} -void VerilatedContext::assertOnClear(VerilatedAssertType_t types, - VerilatedAssertDirectiveType_t directives) VL_MT_SAFE { - if (assertCtlsLocked()) return; - m_s.m_assertOn &= ~assertOnMask(types, directives); -} -bool VerilatedContext::assertCtlsLocked() const VL_MT_SAFE { return m_ns.m_assertCtlsLocked; } -void VerilatedContext::assertCtlsLocked(bool flag) VL_MT_SAFE { m_ns.m_assertCtlsLocked = flag; } 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. // +verilator+assert+lock freezes everything, including Lock/Unlock itself. - if (assertCtlsLocked()) return; + if (m_ns.m_assertCtlsLocked) return; const uint32_t mask = assertOnMask(types, directives); const uint32_t lockedMask = mask & ~m_s.m_assertLock; switch (controlType) { @@ -3598,7 +3582,7 @@ void VerilatedContextImp::commandArgVl(const std::string& arg) { std::string str; uint64_t u64; if (arg == "+verilator+assert+lock") { - assertCtlsLocked(true); + m_ns.m_assertCtlsLocked = true; } else if (commandArgVlString(arg, "+verilator+coverage+file+", str)) { coverageFilename(str); } else if (arg == "+verilator+debug") { diff --git a/include/verilated.h b/include/verilated.h index 1ffdced3e..7c311b52c 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -510,8 +510,8 @@ private: = ASSERT_DIRECTIVE_TYPE_MASK_WIDTH * std::numeric_limits::digits + 1; // Build the assertion-control bit mask for the given assertion x directive types. - static inline uint32_t assertOnMask(VerilatedAssertType_t types, - VerilatedAssertDirectiveType_t directives) VL_PURE; + static constexpr uint32_t assertOnMask(VerilatedAssertType_t types, + VerilatedAssertDirectiveType_t directives) VL_PURE; static constexpr size_t ASSERT_CONTROL_SLOT_COUNT = ASSERT_ON_WIDTH - 1; // No termination request has stamped m_finishPendingTime yet static constexpr uint64_t TIME_UNSET = ~0ULL; @@ -651,28 +651,9 @@ public: bool assertOn() const VL_MT_SAFE; /// Enable all assertion types void assertOn(bool flag) VL_MT_SAFE; - /// Get enabled status for given assertion types - bool assertOnGet(VerilatedAssertType_t type, - VerilatedAssertDirectiveType_t directive) const VL_MT_SAFE; - /// Set enabled status for given assertion types - void assertOnSet(VerilatedAssertType_t types, - VerilatedAssertDirectiveType_t directives) VL_MT_SAFE; - /// Clear enabled status for given assertion types - void assertOnClear(VerilatedAssertType_t types, - VerilatedAssertDirectiveType_t directives) VL_MT_SAFE; - /// Return if assertion-control updates are locked. When locked, RTL assert - // control statements ($asserton/$assertoff/$assertcontrol) are ignored, as - // are updates from the C++ API. - bool assertCtlsLocked() const VL_MT_SAFE; - /// Lock/unlock assertion-control updates. - void assertCtlsLocked(bool flag) VL_MT_SAFE; /// Apply assertion control for given control, assertion, and directive types void assertCtl(uint32_t controlType, VerilatedAssertType_t types, VerilatedAssertDirectiveType_t directives) VL_MT_SAFE; - /// Get assertion-control runtime state. Boolean queries return 0/1, Kill returns - /// the generation count. - inline uint32_t assertCtlGet(VerilatedAssertCtlQuery query, VerilatedAssertType_t type, - VerilatedAssertDirectiveType_t directive) const 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) @@ -848,6 +829,10 @@ public: bool stopRequestReserve(bool maybe) VL_MT_SAFE; void stopRequestRelease() VL_MT_SAFE; + // Internal: assertCtlGet() for generated code, with constant type and directive + template + VL_ATTR_ALWINLINE uint32_t assertCtlGet(VerilatedAssertCtlQuery query) const VL_MT_SAFE; + // Internal: access to implementation class VerilatedContextImp* impp() VL_MT_SAFE { return reinterpret_cast(this); } const VerilatedContextImp* impp() const VL_MT_SAFE { @@ -1356,8 +1341,9 @@ void VerilatedContext::timeprecision(int value) VL_MT_SAFE { } // Defined here, not in-class: VL_CLOG2_I / VL_FATAL_MT (verilated_funcs.h) are not yet in scope -uint32_t VerilatedContext::assertOnMask(VerilatedAssertType_t types, - VerilatedAssertDirectiveType_t directives) VL_PURE { +constexpr 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) { @@ -1365,21 +1351,24 @@ uint32_t VerilatedContext::assertOnMask(VerilatedAssertType_t types, } return mask; } -uint32_t -VerilatedContext::assertCtlGet(VerilatedAssertCtlQuery query, VerilatedAssertType_t type, - VerilatedAssertDirectiveType_t directive) const VL_MT_SAFE { - const uint32_t mask = assertOnMask(type, directive); +template +uint32_t VerilatedContext::assertCtlGet(VerilatedAssertCtlQuery query) const VL_MT_SAFE { + // A constexpr local forces compile-time evaluation of the mask, which a plain + // assertOnMask() call does not get from GCC at -Os + constexpr uint32_t mask = assertOnMask(T_Type, T_Directive); if (!mask) return 0; + // Explicit load(): G++ -Os inlines it but not the implicit conversion. switch (query) { // LCOV_EXCL_BR_LINE - case VerilatedAssertCtlQuery::ASSERT_CTL_ON: return (m_s.m_assertOn & mask) != 0; + case VerilatedAssertCtlQuery::ASSERT_CTL_ON: return (m_s.m_assertOn.load() & mask) != 0; case VerilatedAssertCtlQuery::ASSERT_CTL_KILL: assert(mask && (mask & (mask - 1)) == 0); - return m_s.m_assertKill[VL_CLOG2_I(mask)]; + return m_s.m_assertKill[VL_CLOG2_I(mask)].load(); case VerilatedAssertCtlQuery::ASSERT_CTL_PASS_ON_VACUOUS: - return (m_s.m_assertPassOnVacuous & mask) != 0; + return (m_s.m_assertPassOnVacuous.load() & mask) != 0; case VerilatedAssertCtlQuery::ASSERT_CTL_PASS_ON_NONVACUOUS: - return (m_s.m_assertPassOnNonvacuous & mask) != 0; - case VerilatedAssertCtlQuery::ASSERT_CTL_FAIL_ON: return (m_s.m_assertFailOn & mask) != 0; + return (m_s.m_assertPassOnNonvacuous.load() & mask) != 0; + case VerilatedAssertCtlQuery::ASSERT_CTL_FAIL_ON: + return (m_s.m_assertFailOn.load() & mask) != 0; default: // LCOV_EXCL_START VL_FATAL_MT("", 0, "", "Internal: Bad assertCtlGet query"); VL_UNREACHABLE; diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index a04ac05fa..9dc01cbc9 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -154,6 +154,13 @@ void V3AssertCommon::lowerSequenceEvents(AstNetlist* nodep) { V3Global::dumpCheckGlobalTree("assertseqevent", 0, dumpTreeEitherLevel() >= 3); } +string V3AssertCommon::assertCtlGetCall(const char* query, VAssertType type, + VAssertDirectiveType directiveType) { + // Template arguments let the runtime build the type/directive mask at C++ compile time + return "vlSymsp->_vm_contextp__->assertCtlGet<"s + std::to_string(type) + ", "s + + std::to_string(directiveType) + ">(VerilatedAssertCtlQuery::"s + query + ")"s; +} + //###################################################################### // AssertDeFutureVisitor // If any AstFuture, then move all non-future varrefs to be one cycle behind, @@ -335,11 +342,6 @@ class AssertVisitor final : public VNVisitor { std::unordered_map m_delayedAlways2TickTimep; // METHODS - static string assertCtlGetCall(const char* query, VAssertType type, - VAssertDirectiveType directiveType) { - return "vlSymsp->_vm_contextp__->assertCtlGet(VerilatedAssertCtlQuery::"s + query + ", "s - + std::to_string(type) + ", "s + std::to_string(directiveType) + ")"s; - } static const char* assertPassOnQuery(bool vacuous) { static constexpr const char* queries[2] = {"ASSERT_CTL_PASS_ON_NONVACUOUS", "ASSERT_CTL_PASS_ON_VACUOUS"}; @@ -363,8 +365,9 @@ class AssertVisitor final : public VNVisitor { case VAssertDirectiveType::COVER: case VAssertDirectiveType::ASSUME: { if (v3Global.opt.assertOn()) { - return new AstCExpr{fl, AstCExpr::Pure{}, - assertCtlGetCall("ASSERT_CTL_ON", type, directiveType), 1}; + return new AstCExpr{ + fl, AstCExpr::Pure{}, + V3AssertCommon::assertCtlGetCall("ASSERT_CTL_ON", type, directiveType), 1}; } return new AstConst{fl, AstConst::BitFalse{}}; } @@ -391,15 +394,17 @@ class AssertVisitor final : public VNVisitor { VAssertDirectiveType directiveType, bool vacuous) { if (!isControlled(directiveType)) return new AstConst{fl, AstConst::BitTrue{}}; if (!v3Global.opt.assertOn()) return new AstConst{fl, AstConst::BitFalse{}}; - return new AstCExpr{fl, AstCExpr::Pure{}, - assertCtlGetCall(assertPassOnQuery(vacuous), type, directiveType), 1}; + return new AstCExpr{ + fl, AstCExpr::Pure{}, + V3AssertCommon::assertCtlGetCall(assertPassOnQuery(vacuous), type, directiveType), 1}; } static AstNodeExpr* assertFailOnCond(FileLine* fl, VAssertType type, VAssertDirectiveType directiveType) { if (!isControlled(directiveType)) return new AstConst{fl, AstConst::BitTrue{}}; if (!v3Global.opt.assertOn()) return new AstConst{fl, AstConst::BitFalse{}}; - return new AstCExpr{fl, AstCExpr::Pure{}, - assertCtlGetCall("ASSERT_CTL_FAIL_ON", type, directiveType), 1}; + return new AstCExpr{ + fl, AstCExpr::Pure{}, + V3AssertCommon::assertCtlGetCall("ASSERT_CTL_FAIL_ON", type, directiveType), 1}; } string assertDisplayMessage(const AstNode* nodep, const string& prefix, const string& message, VDisplayType severity) { diff --git a/src/V3Assert.h b/src/V3Assert.h index 3bda2528e..81a9e8877 100644 --- a/src/V3Assert.h +++ b/src/V3Assert.h @@ -28,6 +28,8 @@ class V3AssertCommon final { public: static void collectDefaultDisable(AstNetlist* nodep) VL_MT_DISABLED; static void lowerSequenceEvents(AstNetlist* nodep) VL_MT_DISABLED; + static string assertCtlGetCall(const char* query, VAssertType type, + VAssertDirectiveType directiveType) VL_MT_DISABLED; }; class V3Assert final { diff --git a/src/V3AssertNfa.cpp b/src/V3AssertNfa.cpp index 6e3c19d1e..1bfe2427c 100644 --- a/src/V3AssertNfa.cpp +++ b/src/V3AssertNfa.cpp @@ -243,12 +243,6 @@ static AstNodeExpr* sampled(AstNodeExpr* exprp) { return new AstSampled{exprp->fileline(), exprp, exprp->dtypep(), true}; } -static string assertCtlGetCall(const char* query, VAssertType type, - VAssertDirectiveType directiveType) { - return "vlSymsp->_vm_contextp__->assertCtlGet(VerilatedAssertCtlQuery::"s + query + ", "s - + std::to_string(type) + ", "s + std::to_string(directiveType) + ")"s; -} - static const char* assertPassOnQuery(bool vacuous) { static constexpr const char* queries[2] = {"ASSERT_CTL_PASS_ON_NONVACUOUS", "ASSERT_CTL_PASS_ON_VACUOUS"}; @@ -259,13 +253,14 @@ static AstNodeExpr* assertOnCond(FileLine* flp, VAssertType type, VAssertDirectiveType directiveType) { if (!v3Global.opt.assertOn()) { return new AstConst{flp, AstConst::BitFalse{}}; } return new AstCExpr{flp, AstCExpr::Pure{}, - assertCtlGetCall("ASSERT_CTL_ON", type, directiveType), 1}; + V3AssertCommon::assertCtlGetCall("ASSERT_CTL_ON", type, directiveType), 1}; } static AstNodeExpr* assertKillGet(FileLine* flp, VAssertType type, VAssertDirectiveType directiveType) { return new AstCExpr{flp, AstCExpr::Pure{}, - assertCtlGetCall("ASSERT_CTL_KILL", type, directiveType), 32}; + V3AssertCommon::assertCtlGetCall("ASSERT_CTL_KILL", type, directiveType), + 32}; } static string assertActionControlPrefix(VAssertDirectiveType directiveType) { @@ -280,19 +275,21 @@ static string assertActionControlPrefix(VAssertDirectiveType directiveType) { static AstNodeExpr* assertPassOnCond(FileLine* flp, VAssertType type, VAssertDirectiveType directiveType, bool vacuous) { - return new AstCExpr{flp, AstCExpr::Pure{}, - assertActionControlPrefix(directiveType) - + assertCtlGetCall(assertPassOnQuery(vacuous), type, directiveType) - + "))"s, - 1}; + return new AstCExpr{ + flp, AstCExpr::Pure{}, + assertActionControlPrefix(directiveType) + + V3AssertCommon::assertCtlGetCall(assertPassOnQuery(vacuous), type, directiveType) + + "))"s, + 1}; } static AstNodeExpr* assertFailOnCond(FileLine* flp, VAssertType type, VAssertDirectiveType directiveType) { - return new AstCExpr{flp, AstCExpr::Pure{}, - assertActionControlPrefix(directiveType) - + assertCtlGetCall("ASSERT_CTL_FAIL_ON", type, directiveType) + "))"s, - 1}; + return new AstCExpr{ + flp, AstCExpr::Pure{}, + assertActionControlPrefix(directiveType) + + V3AssertCommon::assertCtlGetCall("ASSERT_CTL_FAIL_ON", type, directiveType) + "))"s, + 1}; } static AstIf* newPassOnIf(FileLine* flp, AstNodeExpr* firep, AstNode* bodyp, VAssertType type, diff --git a/test_regress/t/t_assert_ctl_arg.cpp b/test_regress/t/t_assert_ctl_arg.cpp index 128d7be25..d5e26f5d0 100644 --- a/test_regress/t/t_assert_ctl_arg.cpp +++ b/test_regress/t/t_assert_ctl_arg.cpp @@ -27,140 +27,15 @@ void verilatedTest() { TEST_CHECK_NZ(contextp->assertOn()); contextp->assertOn(false); TEST_CHECK_Z(contextp->assertOn()); - TEST_CHECK_Z(contextp->assertOnGet(1, 1)); - - // Setting one type - contextp->assertOnSet(1, 1); - TEST_CHECK_NZ(contextp->assertOnGet(1, 1)); - TEST_CHECK_NZ(contextp->assertOn()); - TEST_CHECK_Z(contextp->assertOnGet(2, 2)); - - // Setting types - contextp->assertOn(false); - contextp->assertOnSet(1, 3); - TEST_CHECK_NZ(contextp->assertOnGet(1, 3)); - TEST_CHECK_NZ(contextp->assertOnGet(1, 2)); - TEST_CHECK_NZ(contextp->assertOnGet(1, 1)); - TEST_CHECK_Z(contextp->assertOnGet(1, 0)); - TEST_CHECK_Z(contextp->assertOnGet(2, 0)); - TEST_CHECK_Z(contextp->assertOnGet(0, 0)); - - // Setting multiple types separately - contextp->assertOn(false); - contextp->assertOnSet(0, 1); - contextp->assertOnSet(1, 2); - contextp->assertOnSet(2, 3); - TEST_CHECK_NZ(contextp->assertOn()); - TEST_CHECK_Z(contextp->assertOnGet(0, 1)); - TEST_CHECK_Z(contextp->assertOnGet(1, 1)); - TEST_CHECK_NZ(contextp->assertOnGet(1, 2)); - TEST_CHECK_NZ(contextp->assertOnGet(2, 1)); - TEST_CHECK_NZ(contextp->assertOnGet(2, 2)); - TEST_CHECK_NZ(contextp->assertOnGet(2, 3)); - TEST_CHECK_Z(contextp->assertOnGet(0, 2)); - TEST_CHECK_Z(contextp->assertOnGet(4, 1)); - TEST_CHECK_Z(contextp->assertOnGet(8, 7)); - - // Clearing selected types - contextp->assertOn(true); - contextp->assertOnClear(1, 3); - contextp->assertOnClear(1, 4); - TEST_CHECK_Z(contextp->assertOnGet(1, 1)); - TEST_CHECK_Z(contextp->assertOnGet(1, 2)); - TEST_CHECK_Z(contextp->assertOnGet(1, 4)); - contextp->assertOnClear(4, 4); - TEST_CHECK_Z(contextp->assertOnGet(4, 4)); - TEST_CHECK_NZ(contextp->assertOnGet(4, 1)); - TEST_CHECK_NZ(contextp->assertOnGet(4, 2)); - TEST_CHECK_NZ(contextp->assertOn()); - - // Clearing all assert types - contextp->assertOn(true); - contextp->assertOnClear(255, 7); - // Everything is disabled except internal asserts - TEST_CHECK_NZ(contextp->assertOn()); - contextp->assertOn(false); - // Now everything is disabled - TEST_CHECK_Z(contextp->assertOn()); - - // Unified runtime query getter - using Query = VerilatedAssertCtlQuery; - constexpr uint32_t LOCK = 1; - constexpr uint32_t UNLOCK = 2; - constexpr uint32_t ON = 3; - constexpr uint32_t OFF = 4; - constexpr uint32_t KILL = 5; - constexpr uint32_t PASS_ON = 6; - constexpr uint32_t PASS_OFF = 7; - constexpr uint32_t FAIL_ON = 8; - constexpr uint32_t FAIL_OFF = 9; - constexpr uint32_t NONVACUOUS_ON = 10; - constexpr uint32_t VACUOUS_OFF = 11; - constexpr uint32_t TYPE = 1; - constexpr uint32_t DIRECTIVE = 1; - - TEST_CHECK_Z(contextp->assertCtlGet(Query::ASSERT_CTL_ON, TYPE, DIRECTIVE)); - TEST_CHECK_Z(contextp->assertCtlGet(Query::ASSERT_CTL_ON, 0, DIRECTIVE)); - - contextp->assertCtl(LOCK, TYPE, DIRECTIVE); - contextp->assertCtl(ON, TYPE, DIRECTIVE); - TEST_CHECK_Z(contextp->assertCtlGet(Query::ASSERT_CTL_ON, TYPE, DIRECTIVE)); - contextp->assertCtl(UNLOCK, TYPE, DIRECTIVE); - contextp->assertCtl(ON, TYPE, DIRECTIVE); - TEST_CHECK_NZ(contextp->assertCtlGet(Query::ASSERT_CTL_ON, TYPE, DIRECTIVE)); - contextp->assertCtl(OFF, TYPE, DIRECTIVE); - TEST_CHECK_Z(contextp->assertCtlGet(Query::ASSERT_CTL_ON, TYPE, DIRECTIVE)); - - const uint32_t killBefore = contextp->assertCtlGet(Query::ASSERT_CTL_KILL, TYPE, DIRECTIVE); - contextp->assertCtl(KILL, TYPE, DIRECTIVE); - TEST_CHECK_EQ(contextp->assertCtlGet(Query::ASSERT_CTL_KILL, TYPE, DIRECTIVE), killBefore + 1); - TEST_CHECK_Z(contextp->assertCtlGet(Query::ASSERT_CTL_ON, TYPE, DIRECTIVE)); - - TEST_CHECK_NZ(contextp->assertCtlGet(Query::ASSERT_CTL_PASS_ON_NONVACUOUS, TYPE, DIRECTIVE)); - TEST_CHECK_NZ(contextp->assertCtlGet(Query::ASSERT_CTL_PASS_ON_VACUOUS, TYPE, DIRECTIVE)); - contextp->assertCtl(PASS_OFF, TYPE, DIRECTIVE); - TEST_CHECK_Z(contextp->assertCtlGet(Query::ASSERT_CTL_PASS_ON_NONVACUOUS, TYPE, DIRECTIVE)); - TEST_CHECK_Z(contextp->assertCtlGet(Query::ASSERT_CTL_PASS_ON_VACUOUS, TYPE, DIRECTIVE)); - - contextp->assertCtl(NONVACUOUS_ON, TYPE, DIRECTIVE); - TEST_CHECK_NZ(contextp->assertCtlGet(Query::ASSERT_CTL_PASS_ON_NONVACUOUS, TYPE, DIRECTIVE)); - TEST_CHECK_Z(contextp->assertCtlGet(Query::ASSERT_CTL_PASS_ON_VACUOUS, TYPE, DIRECTIVE)); - contextp->assertCtl(PASS_ON, TYPE, DIRECTIVE); - TEST_CHECK_NZ(contextp->assertCtlGet(Query::ASSERT_CTL_PASS_ON_NONVACUOUS, TYPE, DIRECTIVE)); - TEST_CHECK_NZ(contextp->assertCtlGet(Query::ASSERT_CTL_PASS_ON_VACUOUS, TYPE, DIRECTIVE)); - contextp->assertCtl(VACUOUS_OFF, TYPE, DIRECTIVE); - TEST_CHECK_NZ(contextp->assertCtlGet(Query::ASSERT_CTL_PASS_ON_NONVACUOUS, TYPE, DIRECTIVE)); - TEST_CHECK_Z(contextp->assertCtlGet(Query::ASSERT_CTL_PASS_ON_VACUOUS, TYPE, DIRECTIVE)); - - TEST_CHECK_NZ(contextp->assertCtlGet(Query::ASSERT_CTL_FAIL_ON, TYPE, DIRECTIVE)); - contextp->assertCtl(FAIL_OFF, TYPE, DIRECTIVE); - TEST_CHECK_Z(contextp->assertCtlGet(Query::ASSERT_CTL_FAIL_ON, TYPE, DIRECTIVE)); - contextp->assertCtl(FAIL_ON, TYPE, DIRECTIVE); - TEST_CHECK_NZ(contextp->assertCtlGet(Query::ASSERT_CTL_FAIL_ON, TYPE, DIRECTIVE)); } void verilatedLockedTest() { // With +verilator+assert+lock, every assertion-control update is a no-op const std::unique_ptr contextp{new VerilatedContext}; - - // Clear some bits to test assertOnSet - contextp->assertOnClear(2, 3); const char* argsp[] = {"+verilator+assert+lock"}; contextp->commandArgsAdd(1, argsp); - TEST_CHECK_EQ(contextp->assertCtlsLocked(), true); - - // Validate each assert control API call is a no-op contextp->assertOn(false); TEST_CHECK_NZ(contextp->assertOn()); - - contextp->assertOnSet(2, 3); - TEST_CHECK_Z(contextp->assertOnGet(2, 3)); - - contextp->assertOnClear(1, 1); - TEST_CHECK_NZ(contextp->assertOnGet(1, 1)); - - contextp->assertCtl(4, 4, 1); - TEST_CHECK_NZ(contextp->assertOnGet(4, 1)); } int main(int argc, char** argv) {