コード例 #1
0
ファイル: v3VrfMPDR.cpp プロジェクト: chengyinwu/V3
/* ---------------------------------------------------------------------------------------------------- *\
isIncKeepLastReachability(): If the last result is unsat, put the inductive invariant into the last frame.
isIncContinueOnLastSolver(): Reset the solver.
\* ---------------------------------------------------------------------------------------------------- */
void
V3VrfMPDR::startVerify(const uint32_t& p) {
vrfRestart: 
   // Check Shared Results
   if (_sharedBound && V3NtkUD == _sharedBound->getBound(p)) return;
   
   // Clear Verification Results
   clearResult(p); if (profileON()) _totalStat->start();
   
   // Consistency Check
   consistencyCheck(); assert (!_constr.size());
   if (!reportUnsupportedInitialState()) return;
   
   // Initialize Backup Frames
   for (uint32_t i = 0; i < _pdrBackup.size(); ++i) delete _pdrBackup[i]; _pdrBackup.clear();
   if (_pdrFrame.size()) {
      if (isIncKeepLastReachability()) {
         // Backup frames in the order: ..., 2, 1, INF
         assert (_pdrFrame.size() > 1); _pdrBackup.reserve(_pdrFrame.size() - 1);
         for (uint32_t i = _pdrFrame.size() - 2; i > 0; --i) _pdrBackup.push_back(_pdrFrame[i]);
         _pdrBackup.push_back(_pdrFrame.back()); delete _pdrFrame[0];
      }
      else { for (uint32_t i = 0; i < _pdrFrame.size(); ++i) delete _pdrFrame[i]; } _pdrFrame.clear();
   }

   // Initialize Other Members
   if (!isIncKeepLastReachability()) _pdrPriority.clear(); _pdrActCount = 0;
   if (_pdrBad) delete _pdrBad; _pdrBad = 0; if (_pdrGen) delete _pdrGen; _pdrGen = 0;
   if (dynamic_cast<V3BvNtk*>(_vrfNtk)) {
      _pdrGen = new V3AlgBvGeneralize(_handler); assert (_pdrGen);
      _pdrSim = dynamic_cast<V3AlgBvSimulate*>(_pdrGen); assert (_pdrSim);
   }
   else {
      _pdrGen = new V3AlgAigGeneralize(_handler); assert (_pdrGen);
      _pdrSim = dynamic_cast<V3AlgAigSimulate*>(_pdrGen); assert (_pdrSim);
   }
   V3NetVec simTargets(1, _vrfNtk->getOutput(p)); _pdrSim->reset(simTargets);

   // Initialize Pattern Input Size
   assert (p < _result.size()); assert (p < _vrfNtk->getOutputSize());
   const V3NetId& pId = _vrfNtk->getOutput(p); assert (V3NetUD != pId);
   _pdrSize = _vrfNtk->getInputSize() + _vrfNtk->getInoutSize();

   // Initialize Parameters
   const string flushSpace = string(100, ' ');
   uint32_t proved = V3NtkUD, fired = V3NtkUD;
   struct timeval inittime, curtime; gettimeofday(&inittime, NULL);
   
   // Initialize Signal Priority List
   if (_pdrPriority.size() != _vrfNtk->getLatchSize()) _pdrPriority.resize(_vrfNtk->getLatchSize(), 0);

   // Initialize Solver
   if (_pdrSvr && !isIncContinueOnLastSolver()) { delete _pdrSvr; _pdrSvr = 0; } initializeSolver();

   // Initialize Bad Cube
   _pdrBad = new V3MPDRCube(0); assert (_pdrBad); _pdrBad->setState(V3NetVec(1, pId));

   // Initialize Frame 0
   if (_vrfNtk->getLatchSize()) _pdrFrame.push_back(new V3MPDRFrame(_pdrSvr->setImplyInit()));  // R0 = I0
   else _pdrFrame.push_back(new V3MPDRFrame(_pdrSvr->reserveFormula()));
   assert (_pdrFrame.back()->getActivator()); assert (_pdrFrame.size() == 1);

   // Initialize Frame INF
   if (_pdrBackup.size()) { _pdrFrame.push_back(_pdrBackup.back()); _pdrBackup.pop_back(); addFrameInfoToSolver(1); }
   else _pdrFrame.push_back(new V3MPDRFrame(_pdrSvr->reserveFormula()));
   assert (_pdrFrame.back()->getActivator()); assert (_pdrFrame.size() == 2);

   // Check Shared Invariants
   if (_sharedInv) {
      V3NetTable sharedInv; _sharedInv->getInv(sharedInv);
      for (uint32_t i = 0; i < sharedInv.size(); ++i) {
         V3MPDRCube* const inv = new V3MPDRCube(0); assert (inv);
         inv->setState(sharedInv[i]); addBlockedCube(make_pair(getPDRFrame(), inv));
      }
   }

   // Continue on the Last Depth
   while (_pdrBackup.size() && (getIncLastDepthToKeepGoing() > getPDRFrame())) {
      _pdrFrame.push_back(_pdrFrame.back());  // Keep frame INF the last frame
      _pdrFrame[_pdrFrame.size() - 2] = _pdrBackup.back(); _pdrBackup.pop_back();
      addFrameInfoToSolver(_pdrFrame.size() - 2);
   }

   // Start PDR Based Verification
   V3MPDRCube* badCube = 0;
   while (true) {
      // Check Time Bounds
      gettimeofday(&curtime, NULL);
      if (_maxTime < getTimeUsed(inittime, curtime)) break;
      // Check Shared Results
      if (_sharedBound && (V3NtkUD == _sharedBound->getBound(p))) break;
      // Check Shared Networks
      if (_sharedNtk) {
         V3NtkHandler* const sharedNtk = _sharedNtk->getNtk(_handler);
         if (sharedNtk) {
            setIncKeepLastReachability(true); setIncContinueOnLastSolver(false); setIncLastDepthToKeepGoing(getPDRDepth());
            _handler = sharedNtk; _vrfNtk = sharedNtk->getNtk(); goto vrfRestart;
         }
      }
      // Find a Bad Cube as Initial Proof Obligation
      badCube = getInitialObligation();  // SAT(R ^ T ^ !p)
      if (!badCube) {
         if (!isIncKeepSilent() && intactON()) {
            if (!endLineON()) Msg(MSG_IFO) << "\r" + flushSpace + "\r";
            Msg(MSG_IFO) << setw(3) << left << getPDRDepth() << " :";
            const uint32_t j = (_pdrFrame.size() > 25) ? _pdrFrame.size() - 25 : 0; if (j) Msg(MSG_IFO) << " ...";
            for (uint32_t i = j; i < _pdrFrame.size(); ++i) 
               Msg(MSG_IFO) << " " << _pdrFrame[i]->getCubeList().size();
            if (svrInfoON()) { Msg(MSG_IFO) << "  ("; _pdrSvr->printInfo(); Msg(MSG_IFO) << ")"; }
            Msg(MSG_IFO) << endl;  // Always Endline At the End of Each Frame
         }
         if (_sharedBound) _sharedBound->updateBound(p, getPDRFrame());
         // Push New Frame
         _pdrFrame.push_back(_pdrFrame.back());  // Renders F Infinity to be the last in _pdrFrame
         if (_pdrBackup.size()) {
            _pdrFrame[_pdrFrame.size() - 2] = _pdrBackup.back(); _pdrBackup.pop_back();
            addFrameInfoToSolver(_pdrFrame.size() - 2);
         }
         else _pdrFrame[_pdrFrame.size() - 2] = new V3MPDRFrame(_pdrSvr->reserveFormula());  // New Frame
         if (propagateCubes()) { proved = getPDRDepth(); break; }
         if (_maxDepth <= (getPDRFrame() - 1)) break;
      }
      else {
         badCube = recursiveBlockCube(badCube);
         if (badCube) { fired = getPDRDepth(); break; }
         // Interactively Show the Number of Bad Cubes in Frames
         if (!isIncKeepSilent() && intactON()) {
            if (!endLineON()) Msg(MSG_IFO) << "\r" + flushSpace + "\r";
            Msg(MSG_IFO) << setw(3) << left << getPDRDepth() << " :";
            const uint32_t j = (_pdrFrame.size() > 25) ? _pdrFrame.size() - 25 : 0; if (j) Msg(MSG_IFO) << " ...";
            for (uint32_t i = j; i < _pdrFrame.size(); ++i) 
               Msg(MSG_IFO) << " " << _pdrFrame[i]->getCubeList().size();
            if (svrInfoON()) { Msg(MSG_IFO) << "  ("; _pdrSvr->printInfo(); Msg(MSG_IFO) << ")"; }
            if (endLineON()) Msg(MSG_IFO) << endl; else Msg(MSG_IFO) << flush;
         }
      }
   }

   // Report Verification Result
   if (!isIncKeepSilent() && reportON()) {
      if (intactON()) {
         if (endLineON()) Msg(MSG_IFO) << endl;
         else Msg(MSG_IFO) << "\r" << flushSpace << "\r";
      }
      if (V3NtkUD != proved) Msg(MSG_IFO) << "Inductive Invariant found at depth = " << ++proved;
      else if (V3NtkUD != fired) Msg(MSG_IFO) << "Counter-example found at depth = " << ++fired;
      else Msg(MSG_IFO) << "UNDECIDED at depth = " << _maxDepth;
      if (usageON()) {
         gettimeofday(&curtime, NULL);
         Msg(MSG_IFO) << "  (time = " << setprecision(5) << getTimeUsed(inittime, curtime) << "  sec)" << endl;
      }
      if (profileON()) {
         _totalStat->end();
         Msg(MSG_IFO) << *_initSvrStat << endl;
         Msg(MSG_IFO) << *_solveStat << endl;
         Msg(MSG_IFO) << *_generalStat << endl;
         Msg(MSG_IFO) << *_propagateStat << endl;
         Msg(MSG_IFO) << *_ternaryStat << endl;
         Msg(MSG_IFO) << *_totalStat << endl;
      }
   }

   // Record CounterExample Trace or Invariant
   if (V3NtkUD != fired) {  // Record Counter-Example
      // Compute PatternCount
      const V3MPDRCube* traceCube = badCube; assert (traceCube); assert (existInitial(traceCube->getState()));
      uint32_t patternCount = 0; while (_pdrBad != traceCube) { traceCube = traceCube->getNextCube(); ++patternCount; }
      V3CexTrace* const cex = new V3CexTrace(patternCount); assert (cex);
      _result[p].setCexTrace(cex); assert (_result[p].isCex());
      // Set Pattern Value
      traceCube = badCube; assert (traceCube); assert (existInitial(traceCube->getState()));
      while (_pdrBad != traceCube) {
         if (_pdrSize) cex->pushData(traceCube->getInputData());
         traceCube = traceCube->getNextCube(); assert (traceCube);
      }
      // Set Initial State Value
      if (_pdrInitValue.size()) {
         V3BitVecX initValue(_pdrInitValue.size());
         for (uint32_t i = 0; i < badCube->getState().size(); ++i) {
            assert (initValue.size() > badCube->getState()[i].id);
            if (badCube->getState()[i].cp) initValue.set0(badCube->getState()[i].id);
            else initValue.set1(badCube->getState()[i].id);
         }
         for (uint32_t i = 0; i < _pdrInitValue.size(); ++i)
            if (_pdrInitConst[i]) { if (_pdrInitValue[i]) initValue.set0(i); else initValue.set1(i); }
         cex->setInit(initValue);
      }
      // Delete Cubes on the Trace
      const V3MPDRCube* lastCube; traceCube = badCube;
      while (_pdrBad != traceCube) { lastCube = traceCube->getNextCube(); delete traceCube; traceCube = lastCube; }
      // Check Common Results
      if (isIncVerifyUsingCurResult()) checkCommonCounterexample(p, *cex);
   }
   else if (V3NtkUD != proved) {  // Record Inductive Invariant
      _result[p].setIndInv(_vrfNtk); assert (_result[p].isInv());
      // Put the Inductive Invariant to Frame INF
      uint32_t f = 1; for (; f < getPDRDepth(); ++f) if (!_pdrFrame[f]->getCubeList().size()) break;
      assert (f < getPDRDepth());
      for (uint32_t i = 1 + f; i < getPDRFrame(); ++i) {
         const V3MPDRCubeList& cubeList = _pdrFrame[i]->getCubeList(); V3MPDRCubeList::const_iterator it;
         for (it = cubeList.begin(); it != cubeList.end(); ++it) addBlockedCube(make_pair(getPDRFrame(), *it));
         _pdrFrame[i]->clearCubeList(); delete _pdrFrame[i];
      }
      // Remove Empty Frames
      _pdrFrame.back()->removeSelfSubsumed();
      _pdrFrame[f] = _pdrFrame.back(); while ((1 + f) != _pdrFrame.size()) _pdrFrame.pop_back();
      // Check Common Results
      if (isIncVerifyUsingCurResult()) {
         const V3MPDRCubeList& invCubeList = _pdrFrame.back()->getCubeList();
         V3NetTable invList; invList.clear(); invList.reserve(invCubeList.size());
         for (V3MPDRCubeList::const_iterator it = invCubeList.begin(); it != invCubeList.end(); ++it)
            invList.push_back((*it)->getState()); checkCommonProof(p, invList, false);
      }
   }
}
コード例 #2
0
ファイル: v3VrfUMC.cpp プロジェクト: ChunHungLiu/abc1234
// Private Verification Main Functions
void
V3VrfUMC::startVerify(const uint32_t& pIndex) {
   // Consistency Check
   if (_preDepth > _maxDepth) _maxDepth = _preDepth; assert (_maxDepth >= _preDepth);
   if (_incDepth && ((_maxDepth - _preDepth) % _incDepth)) _maxDepth -= (_maxDepth - _preDepth) % _incDepth;
   assert (!_incDepth || !((_maxDepth - _preDepth) % _incDepth)); assert (_maxDepth >= _preDepth);
   if ((_maxDepth > _preDepth) && !_incDepth) _maxDepth = _preDepth;

   // Initialize
   V3Ntk* const ntk = _handler->getNtk(); assert (ntk);
   if (_solver) delete _solver; _solver = allocSolver(getSolver(), ntk);
   assert (_solver); assert (_solver->totalSolves() == 0);
   assert (pIndex < _result.size()); assert (pIndex < ntk->getOutputSize());
   const V3NetId& pId = ntk->getOutput(pIndex); assert (V3NetUD != pId);
   const uint32_t logMaxWidth = (uint32_t)(ceil(log10(_maxDepth)));
   const string flushSpace = string(100, ' ');
   uint32_t proved = V3NtkUD, fired = V3NtkUD;
   double runtime = clock();
   uint32_t boundDepth = _preDepth ? _preDepth : _incDepth;
   
   // Solver Data
   V3SvrData pFormulaData; V3PtrVec pFormula;
   pFormula.reserve((_preDepth > _incDepth) ? _preDepth : _incDepth);

   // Start UMC Based Verification
   for (uint32_t i = 0, j = _maxDepth; i < j; ++i) {
      // Add time frame expanded circuit to SAT Solver
      _solver->addBoundedVerifyData(pId, i); pFormula.push_back(_solver->getFormula(pId, i));
      // Check if the bound is achieved
      if ((1 + i) < boundDepth) continue; assert ((1 + i) == boundDepth);
      assert ((1 + i) >= pFormula.size()); boundDepth += _incDepth;
      // Add assume for assumption solve only
      _solver->assumeRelease();
      if (1 == pFormula.size()) _solver->assumeProperty(pId, false, i);
      else {
         pFormulaData = _solver->setImplyUnion(pFormula);
         assert (pFormulaData); _solver->assumeProperty(pFormulaData);
      }
      _solver->simplify();
      // Report Verification Progress
      if (intactON()) {
         if (!endLineON()) Msg(MSG_IFO) << "\r" + flushSpace + "\r";
         Msg(MSG_IFO) << "Verification completed under depth = " << setw(logMaxWidth) << (i + 1);
         if (svrInfoON()) { Msg(MSG_IFO) << "  ("; _solver->printInfo(); Msg(MSG_IFO) << ")"; }
         if (endLineON()) Msg(MSG_IFO) << endl; else Msg(MSG_IFO) << flush;
      }
      // Assumption Solve : If UNSAT, proved!
      if (!isFireOnly() && !_solver->assump_solve()) {
         if (!isProveOnly()) {
            proved = i; break;
         }
      }
      // Assumption Solve : If SAT, disproved!
      if (!isProveOnly()) {
         _solver->assumeInit(); // Conjunction with initial condition
         if (_solver->assump_solve()) {
            for (uint32_t k = 0; k < pFormula.size(); ++k)
               if ('0' != _solver->getDataValue(pFormula[k])) {
                  fired = (1 + i + k - pFormula.size()); break;
               }
            assert (V3NtkUD != fired); break;
         }
      }
      // Add assert back to the property
      if (1 < pFormula.size()) { assert (pFormulaData); _solver->assertProperty(pFormulaData, true); }
      for (uint32_t k = i - pFormula.size(); k < i; ++k) _solver->assertProperty(pId, true, k);
      pFormula.clear(); pFormulaData = 0;
   }

   // Report Verification Result
   if (reportON()) {
      runtime = (clock() - runtime) / CLOCKS_PER_SEC;
      if (intactON()) {
         if (endLineON()) Msg(MSG_IFO) << endl;
         else Msg(MSG_IFO) << "\r" << flushSpace << "\r";
      }
      if (V3NtkUD != proved) Msg(MSG_IFO) << "Inductive Invariant found at depth = " << ++proved;
      else if (V3NtkUD != fired) Msg(MSG_IFO) << "Counter-example found at depth = " << ++fired;
      else Msg(MSG_IFO) << "UNDECIDED at depth = " << _maxDepth;
      if (usageON()) Msg(MSG_IFO) << "  (time = " << setprecision(5) << runtime << "  sec)" << endl;
      if (profileON()) { /* Report some profiling here ... */ }
   }
   else {
      if (V3NtkUD != proved) ++proved;
      else if (V3NtkUD != fired) ++fired;
   }

   // Record CounterExample Trace or Invariant
   if (V3NtkUD != fired) {  // Record Counter-Example
      V3CexTrace* const cex = new V3CexTrace(fired); assert (cex);
      _result[pIndex].setCexTrace(cex); assert (_result[pIndex].isCex());
      // Compute Pattern Size  (PI + PIO)
      uint32_t patternSize = 0;
      for (uint32_t i = 0; i < ntk->getInputSize(); ++i) patternSize += ntk->getNetWidth(ntk->getInput(i));
      for (uint32_t i = 0; i < ntk->getInoutSize(); ++i) patternSize += ntk->getNetWidth(ntk->getInout(i));
      // Set Pattern Value  (PI + PIO)
      V3BitVecX dataValue, patternValue(patternSize ? patternSize : 1);
      for (uint32_t i = 0; i < fired; ++i) {
         patternSize = 0; patternValue.clear();
         for (uint32_t j = 0; j < ntk->getInputSize(); ++j) {
            if (_solver->existVerifyData(ntk->getInput(j), i)) {
               dataValue = _solver->getDataValue(ntk->getInput(j), i);
               assert (dataValue.size() == ntk->getNetWidth(ntk->getInput(j)));
               for (uint32_t k = 0; k < dataValue.size(); ++k, ++patternSize) {
                  if ('0' == dataValue[k]) patternValue.set0(patternSize);
                  else if ('1' == dataValue[k]) patternValue.set1(patternSize);
               }
            }
            else patternSize += ntk->getNetWidth(ntk->getInput(j));
         }
         for (uint32_t j = 0; j < ntk->getInoutSize(); ++j) {
            if (_solver->existVerifyData(ntk->getInout(j), i)) {
               dataValue = _solver->getDataValue(ntk->getInout(j), i);
               assert (dataValue.size() == ntk->getNetWidth(ntk->getInout(j)));
               for (uint32_t k = 0; k < dataValue.size(); ++k, ++patternSize) {
                  if ('0' == dataValue[k]) patternValue.set0(patternSize);
                  else if ('1' == dataValue[k]) patternValue.set1(patternSize);
               }
            }
            else patternSize += ntk->getNetWidth(ntk->getInout(j));
         }
         assert (_solver->existVerifyData(pId, i));
         assert (!patternSize || patternSize == patternValue.size()); cex->pushData(patternValue);
      }
   }
   else if (V3NtkUD != proved) {  // Record Inductive Invariant
      _result[pIndex].setIndInv(ntk); assert (_result[pIndex].isInv());
   }
}