// V3 Verification Result Report Functions void reportAigerCex(const uint32_t& inputSize, const uint32_t& latchSize, const V3CexTrace& cex, const string& prefix) { assert (cex.getTraceSize()); assert (prefix.size()); // Store Output for Each Cycle into String V3BitVecX initValue(latchSize ? latchSize : 1); V3BitVecX patternValue(inputSize ? inputSize : 1); // Report Cex in AIGER 1.9 Format V3VrfShared::printLock(); Msg(MSG_IFO) << "1" << endl; Msg(MSG_IFO) << prefix << endl; // Report Initial State if (latchSize) { if (cex.getInit()) initValue = cex.getInit()->bv_slice(latchSize - 1, 0); for (uint32_t k = 0; k < latchSize; ++k) Msg(MSG_IFO) << ('1' == initValue[k] ? '1' : '0'); } Msg(MSG_IFO) << endl; // Report Pattern Values for (uint32_t i = 0; i < cex.getTraceSize(); ++i) { if (inputSize) { patternValue = cex.getData(i).bv_slice(inputSize - 1, 0); for (uint32_t k = 0; k < inputSize; ++k) Msg(MSG_IFO) << ('1' == patternValue[k] ? '1' : '0'); } Msg(MSG_IFO) << endl; } Msg(MSG_IFO) << "." << endl; V3VrfShared::printUnlock(); }
// Functions for Checking Common Results void V3VrfBase::checkCommonCounterexample(const uint32_t& p, const V3CexTrace& cex) { assert (_result[p].isCex()); assert (cex.getTraceSize()); // Collect Unsolved Properties V3UI32Vec unsolved; unsolved.clear(); unsolved.reserve(_result.size()); for (uint32_t i = 0; i < _result.size(); ++i) if (!(_result[i].isCex() || _result[i].isInv())) unsolved.push_back(i); if (!unsolved.size()) return; assert (!_constr.size()); V3UI32Vec firedIndex, firedDepth; firedIndex.clear(); firedDepth.clear(); // Check Same Property const V3NetId pId = _vrfNtk->getOutput(p); for (uint32_t i = 0; i < unsolved.size(); ++i) { if (pId != _vrfNtk->getOutput(unsolved[i])) continue; firedIndex.push_back(unsolved[i]); firedDepth.push_back(cex.getTraceSize()); unsolved.erase(unsolved.begin() + i); --i; } // Create Simulator V3AlgSimulate* simulator = 0; V3BitVecX pattern; if (dynamic_cast<V3BvNtk*>(_vrfNtk)) simulator = new V3AlgBvSimulate(_handler); else simulator = new V3AlgAigSimulate(_handler); assert (simulator); // For each time-frame, set pattern from counter-example for (uint32_t i = 0, k; i < cex.getTraceSize(); ++i) { if (!unsolved.size()) break; // Update FF Next State Values simulator->updateNextStateValue(); // Set Initial State Values if (!i && cex.getInit()) { V3BitVecX* const initValue = cex.getInit(); k = 0; for (uint32_t j = 0; j < _vrfNtk->getLatchSize(); ++j, ++k) simulator->setSource(_vrfNtk->getLatch(j), initValue->bv_slice(k, k)); } // Set PI Values if (cex.getTraceDataSize()) pattern = cex.getData(i); k = 0; for (uint32_t j = 0; j < _vrfNtk->getInputSize(); ++j, ++k) simulator->setSource(_vrfNtk->getInput(j), pattern.bv_slice(k, k)); for (uint32_t j = 0; j < _vrfNtk->getInoutSize(); ++j, ++k) simulator->setSource(_vrfNtk->getInout(j), pattern.bv_slice(k, k)); // Simulate Ntk for a Cycle simulator->simulate(); // Check Property Assertion for (uint32_t j = 0; j < unsolved.size(); ++j) { if ('1' == simulator->getSimValue(_vrfNtk->getOutput(unsolved[j])).bv_slice(0, 0)[0]) { firedIndex.push_back(unsolved[j]); firedDepth.push_back(1 + i); unsolved.erase(unsolved.begin() + j); --j; } } } delete simulator; simulator = 0; assert (firedIndex.size() == firedDepth.size()); // Set Sub-Traces for Cex to Fired Properties for (uint32_t i = 0; i < firedIndex.size(); ++i) { V3CexTrace* const subTrace = new V3CexTrace(firedDepth[i]); assert (subTrace); if (cex.getTraceDataSize()) for (uint32_t j = 0; j < firedDepth[i]; ++j) subTrace->pushData(cex.getData(j)); if (cex.getInit()) subTrace->setInit(*(cex.getInit())); _result[firedIndex[i]].setCexTrace(subTrace); } }
// Simulation-Based Checker const int cycleSimulateResult(const V3CexTrace& cex, const V3NetVec& constrList, const V3NetVec& fairList, const bool& safe, const V3NtkHandler* const handler, const uint32_t& index) { // Check Counterexample Directly on Input Ntk assert (cex.getTraceSize()); assert (handler); assert (!safe || !fairList.size()); V3Ntk* const ntk = handler->getNtk(); assert (ntk); // Create Simulator V3AlgSimulate* simulator = 0; if (dynamic_cast<V3BvNtk*>(ntk)) simulator = new V3AlgBvSimulate(handler); else simulator = new V3AlgAigSimulate(handler); assert (simulator); // Add Constraints to Simulator V3NetVec targetNets; targetNets.clear(); targetNets.reserve(constrList.size() + fairList.size() + 1); for (uint32_t i = 0; i < constrList.size(); ++i) targetNets.push_back(constrList[i]); for (uint32_t i = 0; i < fairList.size(); ++i) targetNets.push_back(fairList[i]); targetNets.push_back(ntk->getOutput(index)); simulator->reset(targetNets); // Storage for Liveness Properties V3Vec<V3BitVec>::Vec fairVec(fairList.size() ? fairList.size() : 1, V3BitVec(cex.getTraceSize())); V3Vec<V3BitVecX>::Vec stateVec; stateVec.clear(); // For each time-frame, set pattern from counter-example V3BitVecX pattern, value; for (uint32_t i = 0, k; i < cex.getTraceSize(); ++i) { // Update FF Next State Values simulator->updateNextStateValue(); // Set Initial State Values if (!i && cex.getInit()) { V3BitVecX* const initValue = cex.getInit(); k = 0; for (uint32_t j = 0; j < ntk->getLatchSize(); ++j) { pattern = simulator->getSimValue(ntk->getLatch(j)).bv_slice(ntk->getNetWidth(ntk->getLatch(j)) - 1, 0); value = initValue->bv_slice(k + ntk->getNetWidth(ntk->getLatch(j)) - 1, k); if (!pattern.bv_cover(value)) { reportUnexpectedState(1, j, value, pattern); return -1; } simulator->setSource(ntk->getLatch(j), value); k += ntk->getNetWidth(ntk->getLatch(j)); assert (k <= initValue->size()); } } // Set PI Values if (cex.getTraceDataSize()) pattern = cex.getData(i); k = 0; for (uint32_t j = 0; j < ntk->getInputSize(); ++j) { simulator->setSource(ntk->getInput(j), pattern.bv_slice(k + ntk->getNetWidth(ntk->getInput(j)) - 1, k)); k += ntk->getNetWidth(ntk->getInput(j)); assert (k <= pattern.size()); } for (uint32_t j = 0; j < ntk->getInoutSize(); ++j) { simulator->setSource(ntk->getInout(j), pattern.bv_slice(k + ntk->getNetWidth(ntk->getInout(j)) - 1, k)); k += ntk->getNetWidth(ntk->getInout(j)); assert (k <= pattern.size()); } // Simulate Ntk for a Cycle simulator->simulate(); // Check Invariant Constraints for (uint32_t j = 0; j < constrList.size(); ++j) { assert (1 == ntk->getNetWidth(constrList[j])); value = simulator->getSimValue(constrList[j]).bv_slice(0, 0); if ('1' != value[0]) { reportUnsatisfiedConstraint(1 + i, j, value); return -1; } } // Check Property Assertion value = simulator->getSimValue(ntk->getOutput(index)).bv_slice(0, 0); if (safe) { if ((i < (cex.getTraceSize() - 1)) && ('1' == value[0])) reportShorterTrace(1 + i, value[0]); } else if ('1' != value[0]) { Msg(MSG_IFO) << "Cycle = " << i << ", Root Constraint has unexpected value = " << value << endl; return -1; } // Record Data for Liveness Checking if (!safe) { for (uint32_t j = 0; j < fairList.size(); ++j) { assert (1 == ntk->getNetWidth(fairList[j])); value = simulator->getSimValue(fairList[j]).bv_slice(0, 0); if ('1' == value[0]) fairVec[j].set1(i); } for (uint32_t j = 0; j < ntk->getLatchSize(); ++j) { const uint32_t width = ntk->getNetWidth(ntk->getLatch(j)); if (!j) value = simulator->getSimValue(ntk->getLatch(j)).bv_slice(width - 1, 0); else value = value.bv_concat(simulator->getSimValue(ntk->getLatch(j)).bv_slice(width - 1, 0)); } stateVec.push_back(value); } } delete simulator; simulator = 0; if (!safe) { // Check the Existence of Loop uint32_t looped = stateVec.size() - 1; assert (stateVec.size()); while (looped--) { if (stateVec.back() != stateVec[looped]) continue; // Check Fairness Constraints uint32_t i = 0, j; for (; i < fairList.size(); ++i) { for (j = looped; j < stateVec.size(); ++j) if (fairVec[i][j]) break; if (stateVec.size() == j) break; } if (fairList.size() == i) return 1; } return -1; } else return ('1' == value[0]) ? 1 : -1; }
const int expandSimulateResult(const V3CexTrace& cex, const V3NetVec& constrList, const V3NetVec& fairList, const bool& safe, const V3NtkHandler* const handler) { // Check Counterexample on Time-Frame Expanded Input Ntk assert (cex.getTraceSize()); assert (handler); assert (!safe || !fairList.size()); V3Ntk* const ntk = handler->getNtk(); assert (ntk); return 0; }