Ejemplo n.º 1
0
// PDR Initialization Functions
void
V3VrfMPDR::initializeSolver() {
   if (profileON()) _initSvrStat->start();
   const bool isNewSolver = !_pdrSvr;
   if (!_pdrSvr) { _pdrSvr = allocSolver(getSolver(), _vrfNtk); assert (_pdrSvr->totalSolves() == 0); }
   else _pdrSvr->reset(); _pdrActCount = _pdrRecycle;
   // Set Initial State to Solver
   for (uint32_t i = 0; i < _vrfNtk->getLatchSize(); ++i) _pdrSvr->addBoundedVerifyData(_vrfNtk->getLatch(i), 0);
   if (isNewSolver) _pdrSvr->simplify();
   if (profileON()) _initSvrStat->end();
}
Ejemplo n.º 2
0
void
V3SVrfIPDR::initializeSolver2(const uint32_t& d, const bool& isReuse) {
   //cerr << "initializeSolver depth: " << d << endl;
   if (profileON()) _initSvrStat->start();
   if(!d){
      _pdrSvr.push_back(allocSolver(getSolver(), _vrfNtk));
   }
   else{
      assert (d == _pdrSvr.size());
      _pdrSvr.push_back(d ? referenceSolver(_pdrSvr[0]) : allocSolver(getSolver(), _vrfNtk));
   }
   for (uint32_t i = 0; i < _vrfNtk->getLatchSize(); ++i)
      _pdrSvr[d]->addBoundedVerifyData(_vrfNtk->getLatch(i), 0);
   _pdrSvr[d]->addBoundedVerifyData(_pdrBad->getState()[0], 0);

    if (d != getPDRDepth()) _pdrSvr[d]->assertProperty(_pdrBad->getState()[0], true, 0);

    // Consistency Check
    assert (_pdrFrame.size() == _pdrSvr.size());
    _pdrSvr[d]->simplify();
   if (profileON()) _initSvrStat->end();
   _pdrSvr[d]->printVerbose();
}
Ejemplo n.º 3
0
void
V3VrfBase::checkCommonProof(const uint32_t& p, const V3NetTable& invList, const bool& checkInitial) {
   assert (_result[p].isInv());
   // 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);
   // 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;
      _result[unsolved[i]].setIndInv(_vrfNtk);
      unsolved.erase(unsolved.begin() + i); --i;
   }
   if (!unsolved.size()) return; assert (!_constr.size());
   // Create Solver
   V3SvrBase* const solver = allocSolver(getSolver(), _vrfNtk); assert (solver);
   V3SvrDataVec formula; formula.clear(); V3NetId id; uint32_t d = 0;
   // Set Inductive Invariant
   for (uint32_t i = 0; i < invList.size(); ++i) {
      formula.clear(); formula.reserve(invList[i].size());
      for (uint32_t j = 0; j < invList[i].size(); ++j) {
         id = invList[i][j]; assert (_vrfNtk->getLatchSize() > id.id); assert (!d);
         if (!solver->existVerifyData(_vrfNtk->getLatch(id.id), d)) 
            solver->addBoundedVerifyData(_vrfNtk->getLatch(id.id), d);
         assert (solver->existVerifyData(_vrfNtk->getLatch(id.id), d));
         formula.push_back(solver->getFormula(_vrfNtk->getLatch(id.id), 0, d));
         if (!id.cp) formula.back() = solver->getNegFormula(formula.back());
      }
      solver->assertImplyUnion(formula);
   }
   if (checkInitial) {
      solver->assumeRelease(); solver->assumeInit();
      if (solver->assump_solve()) { delete solver; return; }
   }
   // Check if the bad State Signal is Inconsistent with the Inductive Invariant
   for (uint32_t i = 0, j = 0; i < unsolved.size(); ++i) {
      solver->assumeRelease(); assert (!d);
      if (!solver->existVerifyData(_vrfNtk->getOutput(unsolved[i]), d))
         solver->addBoundedVerifyData(_vrfNtk->getOutput(unsolved[i]), d);
      assert (solver->existVerifyData(_vrfNtk->getOutput(unsolved[i]), d));
      solver->assumeProperty(_vrfNtk->getOutput(unsolved[i]), false, d);
      if (!solver->assump_solve()) { _result[unsolved[i]].setIndInv(_vrfNtk); j = 0; }
      else if (++j > 100) break;  // Avoid Spending Too Much Effort on the Check
   }
   delete solver;
}
Ejemplo n.º 4
0
// 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());
   }
}
Ejemplo n.º 5
0
// Private Verification Main Functions
void
V3SVrfBMC::startVerify(const uint32_t& p) {

   // Clear Verification Results
   clearResult(p);

   // Initialize Parameters
   const string flushSpace = string(100, ' ');
   uint32_t fired = V3NtkUD;
   struct timeval inittime, curtime; gettimeofday(&inittime, NULL);
   uint32_t lastDepth = getIncLastDepthToKeepGoing(); if (10000000 < lastDepth) lastDepth = 0;
   uint32_t boundDepth = lastDepth ? lastDepth : 0;

   // Start BMC Based Verification
   V3Ntk* simpNtk = 0; V3SvrBase* solver = 0;
   while (boundDepth < _maxDepth) {
      // Check Time Bounds
      gettimeofday(&curtime, NULL);
      if (_maxTime < getTimeUsed(inittime, curtime)) break;

      boundDepth += 1;

      // Expand Network and Set Initial States
      V3NtkExpand* const pNtk = new V3NtkExpand(_handler, boundDepth, true); assert (pNtk);

      //printNetlist(pNtk);

      V3NetId id; V3NetVec p2cMap, c2pMap; V3RepIdHash repIdHash; repIdHash.clear();
      simpNtk = duplicateNtk(pNtk, p2cMap, c2pMap); assert (simpNtk);

      //printNetlist(simpNtk);


      // Create Outputs for the Unrolled Property Signals
      for (uint32_t i = boundDepth - 1, j = 0; j < 1; ++i, ++j) {
         id = pNtk->getNtk()->getOutput(p + (_vrfNtk->getOutputSize() * i));
         simpNtk->createOutput(V3NetId::makeNetId(p2cMap[id.id].id, p2cMap[id.id].cp ^ id.cp));
      }

      // Set CONST 0 to Proven Property Signals
      for (uint32_t i = 0, j = boundDepth - 1, k = p; i < j; ++i, k += _vrfNtk->getOutputSize()) {
         id = pNtk->getNtk()->getOutput(k); id = V3NetId::makeNetId(p2cMap[id.id].id, p2cMap[id.id].cp ^ id.cp);
         repIdHash.insert(make_pair(id.id, V3NetId::makeNetId(0, id.cp)));
      }

      if (repIdHash.size()) simpNtk->replaceFanin(repIdHash); delete pNtk; p2cMap.clear(); c2pMap.clear();



      // Initialize Solver
      solver = allocSolver(getSolver(), simpNtk); assert (solver);
      solver->addBoundedVerifyData(simpNtk->getOutput(0), 0); solver->simplify();
      solver->assumeRelease(); solver->assumeProperty(simpNtk->getOutput(0), false, 0);
      if (solver->assump_solve()) { fired = boundDepth; break; }
      solver->assertProperty(simpNtk->getOutput(0), true, 0);

      if (!endLineON()) Msg(MSG_IFO) << "\r" + flushSpace + "\r";
      Msg(MSG_IFO) << "Verification completed under depth = "  << boundDepth;

      if (V3NtkUD != fired) break; delete solver; delete simpNtk;

   }

   // Report Verification Result

   if (V3NtkUD != fired) Msg(MSG_IFO) << "Counter-example found at depth = " << fired;
   else Msg(MSG_IFO) << "UNDECIDED at depth = " << _maxDepth;


   // Record CounterExample Trace or Invariant
   if (V3NtkUD != fired) {  // Record Counter-Example
      V3CexTrace* const cex = new V3CexTrace(fired); assert (cex);
      // Set Pattern Value
      uint32_t patternSize = _vrfNtk->getInputSize() + _vrfNtk->getInoutSize();
      V3BitVecX dataValue, patternValue(patternSize ? patternSize : 1);
      for (uint32_t i = 0, inSize = 0, ioSize = 0; i < fired; ++i) {
         patternSize = 0; patternValue.clear();
         for (uint32_t j = 0; j < _vrfNtk->getInputSize(); ++j, ++patternSize, ++inSize) {
            if (!solver->existVerifyData(simpNtk->getInput(inSize), 0)) continue;
            dataValue = solver->getDataValue(simpNtk->getInput(inSize), 0);
            if ('0' == dataValue[0]) patternValue.set0(patternSize);
            else if ('1' == dataValue[0]) patternValue.set1(patternSize);
         }
         for (uint32_t j = 0; j < _vrfNtk->getInoutSize(); ++j, ++patternSize, ++ioSize) {
            if (!solver->existVerifyData(simpNtk->getInout(ioSize), 0)) continue;
            dataValue = solver->getDataValue(simpNtk->getInout(ioSize), 0);
            if ('0' == dataValue[0]) patternValue.set0(patternSize);
            else if ('1' == dataValue[0]) patternValue.set1(patternSize);
         }
         assert (!patternSize || patternSize == patternValue.size()); cex->pushData(patternValue);
      }
      // Set Initial State Value
      if (_vrfNtk->getLatchSize()) {
         const uint32_t piSize = boundDepth * _vrfNtk->getInputSize();
         patternValue.resize(_vrfNtk->getLatchSize());
         patternValue.clear(); V3NetId id; uint32_t k = 0;
         for (uint32_t j = 0; j < _vrfNtk->getLatchSize(); ++j) {
            id = _vrfNtk->getInputNetId(_vrfNtk->getLatch(j), 1);
            if (!id.id) { if (id.cp) patternValue.set1(j); else patternValue.set0(j); }
            else {
               if (solver->existVerifyData(simpNtk->getInput(piSize + k), 0)) {
                  dataValue = solver->getDataValue(simpNtk->getInput(piSize + k), 0);
                  if ('0' == dataValue[0]) patternValue.set0(j);
                  else if ('1' == dataValue[0]) patternValue.set1(j);
               }
               ++k;
            }
         }
         cex->setInit(patternValue);
      }
      delete solver; delete simpNtk;
      _result[p].setCexTrace(cex);

   }
}