示例#1
0
// General Level Computation Functions for V3 Ntk
void dfsComputeLevel(V3Ntk* const ntk, V3NetVec& orderMap, V3UI32Vec& levelData) {
   assert (ntk); assert (orderMap.size() <= ntk->getNetSize());
   assert (levelData.size() == ntk->getNetSize());
   // Set Net Levels According to the DFS Order
   V3NetId id, id1; V3GateType type; uint32_t inSize;
   for (uint32_t i = 0; i < orderMap.size(); ++i) {
      id = orderMap[i]; assert (id.id < levelData.size());
      if (V3NtkUD != levelData[id.id]) continue; levelData[id.id] = 0;
      type = ntk->getGateType(id); assert (V3_XD > type); assert (V3_PI == type || V3_FF < type);
      if (V3_MODULE == type) {
         V3NtkModule* const moduleNtk = ntk->getModule(id); assert (moduleNtk);
         const V3NetVec& inputs = moduleNtk->getInputList(); inSize = inputs.size();
         while (inSize--) {
            id1 = inputs[inSize]; assert (V3NtkUD != levelData[id1.id]);
            if (levelData[id.id] < levelData[id1.id]) levelData[id.id] = levelData[id1.id];
         }
      }
      else {
         inSize = ntk->getInputNetSize(id); if (BV_SLICE == type || BV_CONST == type) --inSize;
         while (inSize--) {
            id1 = ntk->getInputNetId(id, inSize); assert (V3NtkUD != levelData[id1.id]);
            if (levelData[id.id] < levelData[id1.id]) levelData[id.id] = levelData[id1.id];
         }
      }
      ++levelData[id.id];
   }
}
示例#2
0
文件: v3VrfBase.cpp 项目: hschiang/V3
// 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);
   }
}
示例#3
0
V3Formula::V3Formula(V3NtkHandler* const handler, const uint32_t& constrSize, const uint32_t& maxCard, const V3GateType& gateType, const uint32_t& noPIorFF) : _handler(handler) {
   assert (handler); assert (constrSize); assert (maxCard); assert (!(noPIorFF & ~3ul));
   assert (BV_AND == gateType || BV_OR == gateType || BV_XOR == gateType || BV_XNOR == gateType);
   // Collect Leaf Candidates
   V3Ntk* const ntk = handler->getNtk(); assert (ntk);
   V3NetVec leafId; leafId.clear(); leafId.reserve(ntk->getInputSize() + ntk->getInoutSize() + ntk->getLatchSize());
   if (!(1ul & noPIorFF)) {
      for (uint32_t i = 0; i < ntk->getInputSize(); ++i) 
         if (1 == ntk->getNetWidth(ntk->getInput(i))) leafId.push_back(ntk->getInput(i));
      for (uint32_t i = 0; i < ntk->getInoutSize(); ++i) 
         if (1 == ntk->getNetWidth(ntk->getInout(i))) leafId.push_back(ntk->getInout(i));
   }
   if (!(2ul & noPIorFF)) {
      for (uint32_t i = 0; i < ntk->getLatchSize(); ++i) 
         if (1 == ntk->getNetWidth(ntk->getLatch(i))) leafId.push_back(ntk->getLatch(i));
   }
   V3UI32Vec constrId; constrId.clear(); constrId.reserve(constrSize); _formula.clear();
   // Create Constraints
   for (uint32_t i = 0; i < constrSize; ++i) {
      const uint32_t startId = _formula.size();
      // Create Leaf Nodes
      for (uint32_t j = 0; j < maxCard; ++j) {
         if (j && !(rand() % maxCard)) break;
         const V3NetId id = (rand() % 5) ? leafId[rand() % leafId.size()] : ~leafId[rand() % leafId.size()];
         _formula.push_back(make_pair(V3_PI, V3InputVec())); _formula.back().second.push_back(V3NetType(id));
      }
      assert (startId < _formula.size());
      // Link Leaf Nodes with the Specified GateType
      for (uint32_t j = 0, k = _formula.size() - startId; j < k; ++j) {
         if (!j) constrId.push_back(startId + j);
         else {
            _formula.push_back(make_pair(gateType, V3InputVec()));
            _formula.back().second.push_back(constrId.back());
            _formula.back().second.push_back(startId + j);
            constrId.back() = _formula.size() - 1;
         }
      }
      assert ((1 + i) == constrId.size());
   }
   // Combine Constraints
   for (uint32_t i = 0; i < constrId.size(); ++i) {
      if (!i) _rootId = constrId[i];
      else {
         _formula.push_back(make_pair(BV_AND, V3InputVec()));
         _formula.back().second.push_back(_rootId);
         _formula.back().second.push_back(constrId[i]);
         _rootId = _formula.size() - 1;
      }
   }
}
示例#4
0
void
V3NtkElaborate::elaborateFSMInvariants(V3FSM* const fsm, V3NetVec& constrList) {
   // NOTE: We add constraints follow the reachability, and
   //       For FSM with Milestones, we also add constraints follows the milestones.
   assert (fsm); assert (_handler == fsm->getNtkHandler());
   constrList.clear(); if (!_ntk || !_p2cMap.size()) return;
   // Omit FSM Without Invariants: Every milestone is reachable from any states
   if (!fsm->getStateSize()) return;
   uint32_t comb = 0, seq = 0;
   // Extract Combinational Invariants : G (state != some forward unreachable state)
   V3NetId id1; V3NetVec stateNets; V3UI32Vec reachStates; V3InputVec inputs(2);
   V3BvNtk* const bvNtk = dynamic_cast<V3BvNtk*>(_ntk);
   for (uint32_t j = 0; j < fsm->getStateSize(); ++j) {
      if (V3NtkUD != fsm->getStepFwdFromInit(j)) continue;
      stateNets.clear(); fsm->getStateNetId(j, stateNets); assert (stateNets.size());
      attachToNtk(_handler, _ntk, stateNets, _p2cMap, _c2pMap, _netHash); assert (_ntk);
      id1 = elaborateFSMState(stateNets, false); assert (id1.id < _ntk->getNetSize());
      constrList.push_back(~id1); ++comb;
   }
   // Elaborate Sequential Invariants : nextOpState -> (j -> Prev(OR (reachStates)))
   const bool hasMileStone = fsm->getMileStoneSize();
   if (hasMileStone) {
      for (uint32_t j = 0; j < fsm->getStateSize(); ++j) {
         if (!fsm->isMileStone(j)) continue;
         assert (V3NtkUD != fsm->getStepBwdFromTerm(j));
         fsm->getStateBwdReachable(j, reachStates, true);
         if (fsm->getStateSize() == reachStates.size()) continue;
         if (fsm->getStateSize() < (reachStates.size() << 2)) continue;
         stateNets.clear(); fsm->getStateNetId(j, stateNets); assert (stateNets.size());
         attachToNtk(_handler, _ntk, stateNets, _p2cMap, _c2pMap, _netHash); assert (_ntk);
         id1 = elaborateFSMState(stateNets, false); assert (id1.id < _ntk->getNetSize());
         inputs[0] = ~id1;
         for (uint32_t k = 0; k < reachStates.size(); ++k) {
            stateNets.clear(); fsm->getStateNetId(reachStates[k], stateNets); assert (stateNets.size());
            attachToNtk(_handler, _ntk, stateNets, _p2cMap, _c2pMap, _netHash); assert (_ntk);
            id1 = elaborateFSMState(stateNets, true); assert (id1.id < _ntk->getNetSize());
            inputs[0] = ~(inputs[0].id); inputs[1] = ~id1; ++seq;
            inputs[0] = bvNtk ? ~elaborateBvGate(bvNtk, BV_AND, inputs, _netHash) 
                              : ~elaborateAigGate(_ntk, AIG_NODE, inputs, _netHash);
         }
         // Record Invariants
         inputs[0] = ~(inputs[0].id); inputs[1] = _nextOpId; assert (V3NetUD != _nextOpId);
         inputs[0] = bvNtk ? ~elaborateBvGate(bvNtk, BV_AND, inputs, _netHash) 
                           : ~elaborateAigGate(_ntk, AIG_NODE, inputs, _netHash);
         constrList.push_back(inputs[0].id);
      }
   }
}
示例#5
0
文件: v3VrfBase.cpp 项目: hschiang/V3
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;
}
示例#6
0
void
V3Handler::setLastHandler() {
   assert (getHandlerCount()); if (_curHandlerId == _lastHandlerId) return;
   const uint32_t curHandlerId = _curHandlerId; assert (getHandler(curHandlerId));
   V3UI32Vec curRefIdVec = _curRefIdVec; assert (curRefIdVec.size());
   _curHandlerId = _lastHandlerId; _curRefIdVec = _lastRefIdVec;
   _lastHandlerId = curHandlerId; _lastRefIdVec = curRefIdVec;
}
示例#7
0
// Constructor for Random Formula
V3Formula::V3Formula(V3NtkHandler* const handler, const V3SimTraceVec& cexTrace, const double& strength) : _handler(handler) {
   assert (handler); assert (cexTrace.size()); assert (strength > 0 && strength <= 1.00);
   V3UI32Vec constrId; constrId.clear(); constrId.reserve(cexTrace.size()); _formula.clear();
   // Create Constraints
   V3Ntk* const ntk = handler->getNtk(); assert (ntk);
   for (uint32_t i = 0; i < cexTrace.size(); ++i) {
      const uint32_t startId = _formula.size(), end = 1 + (uint32_t)(strength * ntk->getLatchSize());
      assert (cexTrace[i].size()); assert (ntk->getLatchSize() == cexTrace[i].size());
      for (uint32_t j = 0; j < end; ++j) {
         const uint32_t index = rand() % cexTrace[i].size(); assert (1 == ntk->getNetWidth(ntk->getLatch(index)));
         const V3NetId id = ('0' == cexTrace[i][index][0]) ? ~(ntk->getLatch(index)) : ntk->getLatch(index);
         _formula.push_back(make_pair(V3_PI, V3InputVec())); _formula.back().second.push_back(V3NetType(id));
      }
      assert (startId <= _formula.size());
      // Conjunction of Leaf Nodes
      for (uint32_t j = 0, k = _formula.size() - startId; j < k; ++j) {
         if (!j) constrId.push_back(startId + j);
         else {
            _formula.push_back(make_pair(BV_AND, V3InputVec()));
            _formula.back().second.push_back(constrId.back());
            _formula.back().second.push_back(startId + j);
            constrId.back() = _formula.size() - 1;
         }
      }
   }
   // Disjunction of Constraints
   for (uint32_t i = 0; i < constrId.size(); ++i) {
      if (!i) _rootId = constrId[i];
      else {
         _formula.push_back(make_pair(BV_OR, V3InputVec()));
         _formula.back().second.push_back(_rootId);
         _formula.back().second.push_back(constrId[i]);
         _rootId = _formula.size() - 1;
      }
   }
}
示例#8
0
//----------------------------------------------------------------------
// MITer NTk <(unsigned ntkId1)> <(unsigned ntkId2)>
//           [-Name <(string miterNtkName)>] [| -SEC | -CEC] [-Merge]
//----------------------------------------------------------------------
V3CmdExecStatus
V3MiterNtkCmd::exec(const string& option) {
   vector<string> options;
   V3CmdExec::lexOptions(option, options);

   uint32_t id1 = V3NtkUD, id2 = V3NtkUD;
   bool miterName = false, miterNameON = false;
   bool sec = false, cec = false, merge = false;
   string miterNtkName = ""; int temp;
   
   size_t n = options.size();
   for (size_t i = 0; i < n; ++i) {
      const string& token = options[i];
      if (v3StrNCmp("-Name", token, 2) == 0) {
         if (miterName) return V3CmdExec::errorOption(CMD_OPT_EXTRA, token);
         else miterName = miterNameON = true;
      }
      else if (v3StrNCmp("-SEC", token, 4) == 0) {
         if (sec || cec) return V3CmdExec::errorOption(CMD_OPT_EXTRA, token);
         else sec = true;
      }
      else if (v3StrNCmp("-CEC", token, 4) == 0) {
         if (sec || cec) return V3CmdExec::errorOption(CMD_OPT_EXTRA, token);
         else cec = true;
      }
      else if (v3StrNCmp("-Merge", token, 2) == 0) {
         if (merge) return V3CmdExec::errorOption(CMD_OPT_EXTRA, token);
         else merge = true;
      }
      else if (miterNameON) { miterNameON = false; miterNtkName = token; }
      else if (V3NtkUD == id1) {
         if (!v3Str2Int(token, temp)) return V3CmdExec::errorOption(CMD_OPT_ILLEGAL, "(unsigned ntkId1)");
         else if (temp < 0) return V3CmdExec::errorOption(CMD_OPT_ILLEGAL, "(unsigned ntkId1)");
         id1 = (uint32_t)temp;
      }
      else if (V3NtkUD == id2) {
         if (!v3Str2Int(token, temp)) return V3CmdExec::errorOption(CMD_OPT_ILLEGAL, "(unsigned ntkId2)");
         else if (temp < 0) return V3CmdExec::errorOption(CMD_OPT_ILLEGAL, "(unsigned ntkId2)");
         id2 = (uint32_t)temp;
      }
      else return V3CmdExec::errorOption(CMD_OPT_ILLEGAL, token);
   }

   if (V3NtkUD == id1) return V3CmdExec::errorOption(CMD_OPT_MISSING, "(unsigned ntkId1)");
   if (V3NtkUD == id2) return V3CmdExec::errorOption(CMD_OPT_MISSING, "(unsigned ntkId2)");
   if (miterNameON) return V3CmdExec::errorOption(CMD_OPT_MISSING, "(string miterNtkName)");

   V3NtkHandler* const handler = v3Handler.getCurHandler();
   if (handler) {
      if (id1 >= v3Handler.getHandlerCount()) 
         Msg(MSG_ERR) << "Network with id = " << id1 << " Does NOT Exist !!" << endl;
      else if (id2 >= v3Handler.getHandlerCount()) 
         Msg(MSG_ERR) << "Network with id = " << id2 << " Does NOT Exist !!" << endl;
      else {
         V3NtkHandler* const handler1 = v3Handler.getHandler(id1); assert (handler);
         V3NtkHandler* const handler2 = v3Handler.getHandler(id2); assert (handler);
         if (!(reportIncompatibleModule(handler1, handler2) || reportIncompatibleModule(handler1, handler2))) {
            if (!cec) {
               V3NtkMiter* const miterHandler = new V3NtkMiter(handler1, handler2, merge, miterNtkName);
               assert (miterHandler); v3Handler.pushAndSetCurHandler(miterHandler);
            }
            else {
               // Compute Name Mapping for Latches Between Two Networks
               if (handler1->getNtk()->getLatchSize() == handler2->getNtk()->getLatchSize()) {
                  V3Map<string, uint32_t>::Map nameMap; nameMap.clear();
                  for (uint32_t i = 0; i < handler2->getNtk()->getLatchSize(); ++i)
                     nameMap.insert(make_pair(handler2->getNetName(handler2->getNtk()->getLatch(i)), i));
                  if (handler2->getNtk()->getLatchSize() == nameMap.size()) {
                     V3Map<string, uint32_t>::Map::const_iterator it; V3UI32Vec latchMap;
                     latchMap.clear(); latchMap.reserve(handler1->getNtk()->getLatchSize());
                     for (uint32_t i = 0; i < nameMap.size(); ++i) {
                        it = nameMap.find(handler1->getNetName(handler1->getNtk()->getLatch(i)));
                        if ((nameMap.end() == it) || 
                            (handler1->getNtk()->getNetWidth(handler1->getNtk()->getLatch(i)) != 
                             handler2->getNtk()->getNetWidth(handler2->getNtk()->getLatch(it->second)))) break;
                        else latchMap.push_back(it->second);
                     }
                     if (handler1->getNtk()->getLatchSize() == latchMap.size()) {
                        V3NtkMiter* const miterHandler = 
                           new V3NtkMiter(handler1, handler2, latchMap, merge, miterNtkName);
                        assert (miterHandler); v3Handler.pushAndSetCurHandler(miterHandler);
                     }
                     else Msg(MSG_ERR) << "Unmapped Latch " << latchMap.size() 
                                       << " Found in Network " << id1 << " !!" << endl;
                  }
                  else Msg(MSG_ERR) << "Repeated or Missing Latch Names Exist !!" << endl;
               }
               else Msg(MSG_ERR) << "Number of Latches in Networks NOT Matched : " << id1 << "(" 
                                 << handler1->getNtk()->getLatchSize() << ") != " << id2 << "(" 
                                 << handler2->getNtk()->getLatchSize() << ") !!" << endl;
            }
         }
      }
   }
   else Msg(MSG_ERR) << "Empty Ntk !!" << endl;
   return CMD_EXEC_DONE;
}
示例#9
0
void
V3Handler::setCurHandlerFromPath(const string& path) {
   assert (path.size());
   string curPath = path;
   uint32_t i;
   // Split Path by '/'
   V3Vec<string>::Vec idStr; idStr.clear();
   while (curPath.size()) {
      for (i = 0; i < curPath.size(); ++i) if ('/' == curPath[i]) break;
      if (!i) idStr.push_back("");
      else idStr.push_back(curPath.substr(0, i));
      if ((i + 1) >= curPath.size()) break;
      else curPath = curPath.substr(i + 1);
   }
   // Copy Current Handler and RefId
   const uint32_t curHandlerId = _curHandlerId; assert (getHandler(curHandlerId));
   V3UI32Vec curRefIdVec = _curRefIdVec; assert (curRefIdVec.size());
   V3NtkHandler* handler = 0;
   bool isRoot = false; int temp;
   for (i = 0; i < idStr.size(); ++i) {
      if (handler) {  // Expecting Sub-Module Index
         if (!idStr[i].size()) continue;
         if (v3Str2Int(idStr[i], temp)) {
            const uint32_t id = (uint32_t)temp;
            if (id < handler->getNtk()->getModuleSize()) {
               handler = handler->getNtk()->getModule(id)->getNtkRef();
               uint32_t j = 0; for (; j < _ntkHandlerList.size(); ++j) if (handler == _ntkHandlerList[j]) break;
               _curHandlerId = j; _curRefIdVec.push_back(id);
            }
            else {
               string recoverPath = "";
               for (uint32_t j = 0; j < _curRefIdVec.size(); ++j) recoverPath += ("/" + v3Int2Str(_curRefIdVec[j]));
               Msg(MSG_ERR) << "Sub-Module of " << recoverPath << " with Index = " 
                            << idStr[i] << " Does NOT Exist !!" << endl; return;
            }
         }
      }
      else {  // Expecting NtkID or Location Symbols (/, ./, ~/, .)
         if (!idStr[i].size()) isRoot = true;
         else {
            // Lex if current token is a SubModule Index
            if (v3Str2Int(idStr[i], temp)) {
               const uint32_t id = (uint32_t)temp;
               if (isRoot) {
                  if (id < getHandlerCount()) {
                     handler = getHandler(id); _curHandlerId = id;
                     _curRefIdVec.clear(); _curRefIdVec.push_back(id);
                  }
                  else {
                     Msg(MSG_ERR) << "Ntk with ID = " << idStr[i] << " Does NOT Exist !!" << endl; return;
                  }
               }
               else {
                  if (id < getCurHandler()->getNtk()->getModuleSize()) {
                     handler = getCurHandler()->getNtk()->getModule(id)->getNtkRef();
                     uint32_t j = 0; for (; j < _ntkHandlerList.size(); ++j) if (handler == _ntkHandlerList[j]) break;
                     _curHandlerId = j; _curRefIdVec.push_back(id);
                  }
                  else {
                     string recoverPath = "";
                     for (uint32_t j = 0; j < _curRefIdVec.size(); ++j) recoverPath += ("/" + v3Int2Str(_curRefIdVec[j]));
                     Msg(MSG_ERR) << "Sub-Module of " << recoverPath << " with Index = " 
                                  << idStr[i] << " Does NOT Exist !!" << endl; return;
                  }
               }
            }
            else if (idStr[i].size() > 1) {
               Msg(MSG_ERR) << "Unexpected Symbol \"" << idStr[i] << "\" in the Path !!" << endl; return;
            }
            else if ('~' == idStr[i][0]) {
               const uint32_t baseId = _curHandlerId = _curRefIdVec[0]; handler = getHandler(baseId);
               _curRefIdVec.clear(); _curRefIdVec.push_back(baseId);
            }
            else if ('.' == idStr[i][0]) handler = getCurHandler(); assert (handler);
         }
      }
   }
   // Copy Data for Last if Valid, Or Resume Data for Current
   if (_curHandlerId < _ntkHandlerList.size()) {
      _lastHandlerId = curHandlerId; _lastRefIdVec = curRefIdVec;
   }
   else {
      _curHandlerId = curHandlerId; _curRefIdVec = curRefIdVec;
      Msg(MSG_ERR) << "Network " << path << " was Implicitly Created and it is Currently Untraceable !!" << endl;
   }
}
示例#10
0
const V3NetId
V3NtkElaborate::elaborateL2S(const V3NetId& id) {
   assert (_ntk); assert (_p2cMap.size()); assert (id.id < _ntk->getNetSize());
   assert (isMutable()); assert (_shadow.size() == _handler->getNtk()->getLatchSize());
   // Create L2S Data Members if NOT Exist
   V3BvNtk* const bvNtk = dynamic_cast<V3BvNtk*>(_ntk);
   V3InputVec inputs; inputs.clear(); inputs.reserve(4);
   if (V3NetUD == _saved || V3NetUD == _1stSave || V3NetUD == _inLoop) {
      assert (V3NetUD == _saved && V3NetUD == _1stSave && V3NetUD == _inLoop);
      _saved = _ntk->createNet(1);  // Create Latch (_saved) for "In the Loop"
      const V3NetId oracle = _ntk->createNet(1), inSaved = _ntk->createNet(1);
      inputs.push_back(~_saved); inputs.push_back(~oracle); _ntk->setInput(inSaved, inputs);
      _ntk->createGate((bvNtk ? BV_AND : AIG_NODE), inSaved); inputs.clear();
      inputs.push_back(~inSaved); inputs.push_back(0); _ntk->setInput(_saved, inputs);
      _ntk->createLatch(_saved); inputs.clear(); _ntk->createInput(oracle);
      _1stSave = _ntk->createNet(1);  // Create Net (_1stSave) for "Loop Start"
      inputs.push_back(oracle); inputs.push_back(~_saved); _ntk->setInput(_1stSave, inputs);
      _ntk->createGate((bvNtk ? BV_AND : AIG_NODE), _1stSave); inputs.clear();
      _inLoop = _ntk->createNet(1);  // Create Net (_inLoop) for "_1stSave || _saved"
      inputs.push_back(~_1stSave); inputs.push_back(~_saved); _ntk->setInput(_inLoop, inputs);
      _ntk->createGate((bvNtk ? BV_AND : AIG_NODE), _inLoop); inputs.clear(); _inLoop = ~_inLoop;
   }
   // Create Equivalence Logic and Shadow FF if NOT Exist
   V3NetId ffId; V3GateType type; V3UI32Vec newShadow; newShadow.clear();
   for (uint32_t i = 0; i < _shadow.size(); ++i) {
      ffId = _p2cMap[_handler->getNtk()->getLatch(i).id]; assert (V3_FF == _ntk->getGateType(ffId));
      if (V3NetUD == ffId || V3NetUD != _shadow[i]) continue; newShadow.push_back(i);
      // Create Net for Shadow FF
      _shadow[i] = _ntk->createNet(_ntk->getNetWidth(ffId)); assert (V3NetUD != _shadow[i]);
      V3NetId shadowMux = V3NetUD;  // Create Input MUX of Shadow FF
      if (bvNtk) {
         inputs.push_back(_shadow[i]); inputs.push_back(ffId); inputs.push_back(_1stSave);
         type = BV_MUX; shadowMux = elaborateBvGate(bvNtk, type, inputs, _netHash);
      }
      else {
         inputs.push_back(_1stSave); inputs.push_back(ffId);
         inputs.push_back(~_1stSave); inputs.push_back(_shadow[i]);
         type = AIG_NODE; shadowMux = elaborateAigAndOrAndGate(_ntk, inputs, _netHash);
      }
      // Create Shadow FF
      assert (V3NetUD != shadowMux); inputs.clear(); inputs.push_back(shadowMux);
      if (_ntk->getNetWidth(ffId) == 1) inputs.push_back(0);
      else {
         V3InputVec constInputs(1, bvNtk->hashV3ConstBitVec(v3Int2Str(_ntk->getNetWidth(ffId)) + "'d0"));
         type = BV_CONST; inputs.push_back(elaborateBvGate(bvNtk, type, constInputs, _netHash));
      }
      _ntk->setInput(_shadow[i], inputs); _ntk->createLatch(_shadow[i]); inputs.clear();
      // Create Equivalence Gate and Update _shadow
      if (bvNtk) {
         inputs.push_back(ffId); inputs.push_back(_shadow[i]); type = BV_EQUALITY;
         _shadow[i] = elaborateBvGate(bvNtk, type, inputs, _netHash);
      }
      else {
         inputs.push_back(ffId); inputs.push_back(_shadow[i]);
         inputs.push_back(~ffId); inputs.push_back(~_shadow[i]);
         _shadow[i] = elaborateAigAndOrAndGate(_ntk, inputs, _netHash);
      }
      assert (V3NetUD != _shadow[i]); assert (1 == _ntk->getNetWidth(_shadow[i])); inputs.clear();
   }
   // Create or Update Net (_looped) for "Loop Found" if NOT Exist
   if (V3NetUD == _looped) _looped = _saved;
   for (uint32_t i = 0; i < newShadow.size(); ++i) {
      assert (V3NetUD != _p2cMap[_handler->getNtk()->getLatch(i).id]); assert (V3NetUD != _shadow[i]);
      inputs.push_back(_looped); inputs.push_back(_shadow[i]);
      if (bvNtk) { type = BV_AND; _looped = elaborateBvGate(bvNtk, type, inputs, _netHash); }
      else { type = AIG_NODE; _looped = elaborateAigGate(_ntk, type, inputs, _netHash); }
      assert (V3NetUD != _looped); inputs.clear();
   }
   if (V3NetId::makeNetId(0) == ~id) return _looped;
   // Create Latch (pLatch) for Recording Existence of Violation to id
   const V3NetId pLatch = _ntk->createNet(1), in_pLatch = _ntk->createNet(1);
   inputs.push_back(~pLatch); inputs.push_back(id); _ntk->setInput(in_pLatch, inputs);
   _ntk->createGate((bvNtk ? BV_AND : AIG_NODE), in_pLatch); inputs.clear();
   inputs.push_back(~in_pLatch); inputs.push_back(0); _ntk->setInput(pLatch, inputs);
   _ntk->createLatch(pLatch); inputs.clear();
   // Create L2S Property Output (to Witness "_looped && in_pLatch")
   V3NetId pId = V3NetUD; inputs.push_back(_looped); inputs.push_back(in_pLatch);
   if (bvNtk) { type = BV_AND; pId = elaborateBvGate(bvNtk, type, inputs, _netHash); }
   else { type = AIG_NODE; pId = elaborateAigGate(_ntk, type, inputs, _netHash); }
   assert (V3NetUD != pId); inputs.clear(); return pId;
}