Exemple #1
0
// 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);
   }
}
Exemple #2
0
// Verification Main Functions
void
V3VrfSIM::startVerify(const uint32_t& pIndex) {
   // Initialize
   V3Ntk* const ntk = _handler->getNtk(); assert (ntk);
   V3AlgSimulate* simulator = 0;
   if (dynamic_cast<V3BvNtk*>(ntk)) simulator = new V3AlgBvSimulate(_handler);
   else simulator = new V3AlgAigSimulate(_handler); assert (simulator);
   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 cycle = V3NtkUD, cycleReached = 0;
   double runtime = clock(), timeBound = clock() + (CLOCKS_PER_SEC * _maxTime);
   
   // Start SIM Based Verification
   const uint32_t Cycle = 10000;
   uint32_t i = 0, j = 0;
   for (uint32_t k = 0, n = (uint32_t)(ceil(_maxDepth / Cycle)); k < n; ++k) {
      j = Cycle + i; if (j > _maxDepth) j = _maxDepth;
      for (i = Cycle * k; i < j; ++i) {
         // Update FF Next State Values
         simulator->updateNextStateValue();
         // Purely Random Simulation
         simulator->setSourceFree(V3_PI, true);
         simulator->setSourceFree(V3_PIO, true);
         // Simulate for One Cycle
         simulator->simulate();
         // Record Simulation Data
         simulator->recordSimValue();
         // Check if Property Asserted
         if (simulator->getSimValue(pId).exist1()) { cycle = i; break; }
      }
      if (V3NtkUD != cycle) break;
      // Report Verification Progress
      if (intactON()) {
         if (!endLineON()) Msg(MSG_IFO) << "\r" + flushSpace + "\r";
         Msg(MSG_IFO) << "Simulation completed under cycle = " << setw(logMaxWidth) << i;
         if (endLineON()) Msg(MSG_IFO) << endl; else Msg(MSG_IFO) << flush;
         // Check if Time Bound Reached
         if (clock() >= timeBound) { cycleReached = i; break; }
      }
   }

   // 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 != cycle) Msg(MSG_IFO) << "Counter-example found at cycle = " << ++cycle;
      else Msg(MSG_IFO) << "UNDECIDED at cycle = " << ((clock() >= timeBound) ? cycleReached : _maxDepth);
      if (usageON()) Msg(MSG_IFO) << "  (time = " << setprecision(5) << runtime << "  sec)" << endl;
      if (profileON()) { /* Report some profiling here ... */ }
   }

   // Record CounterExample Trace
   if (V3NtkUD == cycle) return;
   // Compute Pattern Size and Initialize Trace
   V3CexTrace* const cex = new V3CexTrace(cycle); assert (cex);
   _result[pIndex].setCexTrace(cex); assert (_result[pIndex].isCex());
   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));
   if (!patternSize) return;
   // Record Counter-Example
   V3SimTrace pattern(ntk->getInputSize()); V3BitVecX trace(patternSize);
   if (dynamic_cast<V3BvNtk*>(ntk)) {
      for (uint32_t i = 0; i < cycle; ++i) {
         simulator->getSimRecordData(i, pattern);
         uint32_t k = 0;
         for (uint32_t j = 0; j < ntk->getInputSize(); ++j) {
            assert (pattern[j].size() == ntk->getNetWidth(ntk->getInput(j)));
            for (uint32_t x = 0; x < pattern[j].size(); ++x, ++k)
               if ('1' == pattern[j][x]) trace.set1(k);
               else if ('0' == pattern[j][x]) trace.set0(k);
         }
         for (uint32_t j = 0; j < ntk->getInoutSize(); ++j) {
            assert (pattern[j].size() == ntk->getNetWidth(ntk->getInout(j)));
            for (uint32_t x = 0; x < pattern[j].size(); ++x, ++k)
               if ('1' == pattern[j][x]) trace.set1(k);
               else if ('0' == pattern[j][x]) trace.set0(k);
         }
         cex->pushData(trace); trace.clear();
      }
   }
   else {
      const uint32_t p = simulator->getSimValue(pId).first1(); assert (p < simulator->getSimValue(pId).size());
      assert (pattern.size() == trace.size());
      for (uint32_t i = 0; i < cycle; ++i) {
         simulator->getSimRecordData(i, pattern);
         for (uint32_t j = 0; j < pattern.size(); ++j)
            if ('1' == pattern[j][p]) trace.set1(j);
            else if ('0' == pattern[j][p]) trace.set0(j);
         cex->pushData(trace); trace.clear();
      }
   }
}
Exemple #3
0
// 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;
}