void V3SVrfIPDR::generalizeSimulation2(const uint32_t& d, V3SIPDRCube* const cube, const V3SIPDRCube* const nextCube) { assert (d < _pdrSvr.size()); assert (cube); assert (nextCube); assert (nextCube == cube->getNextCube()); assert (_pdrSim); // Set Values for Simulator for (uint32_t i = 0; i < _vrfNtk->getInputSize(); ++i) { if (!_pdrSvr[d]->existVerifyData(_vrfNtk->getInput(i), 0)) _pdrSim->clearSource(_vrfNtk->getInput(i), true); else _pdrSim->setSource(_vrfNtk->getInput(i), _pdrSvr[d]->getDataValue(_vrfNtk->getInput(i), 0)); } for (uint32_t i = 0; i < _vrfNtk->getLatchSize(); ++i) { if (!_pdrSvr[d]->existVerifyData(_vrfNtk->getLatch(i), 0)) _pdrSim->clearSource(_vrfNtk->getLatch(i), true); else _pdrSim->setSource(_vrfNtk->getLatch(i), _pdrSvr[d]->getDataValue(_vrfNtk->getLatch(i), 0)); } _pdrSim->simulate(); // Perform SAT Generalization if (_pdrBad != nextCube) _pdrGen->setTargetNets2(V3NetVec(), nextCube->getState(), _decompDepth); else { V3NetVec constrCube(1, nextCube->getState()[0]); assert (1 == nextCube->getState().size()); _pdrGen->setTargetNets(constrCube); } // Set Priority V3UI32Vec prioNets; prioNets.clear(); prioNets.reserve(_pdrPriority.size()); for (uint32_t i = 0; i < _pdrPriority.size(); ++i) if (!_pdrPriority[i]) prioNets.push_back(i); for (uint32_t i = 0; i < _pdrPriority.size(); ++i) if ( _pdrPriority[i]) prioNets.push_back(i); //_pdrGen->_tem = true; _pdrGen->performSetXForNotCOIVars(false); _pdrGen->performXPropForExtensibleVars(prioNets,false); cube->setState(_pdrGen->getGeneralizationResult()); }
void computeFanout(V3Ntk* const ntk, V3NetTable& outputTable, const V3NetVec& targetNets) { assert (ntk); outputTable.clear(); outputTable.reserve(ntk->getNetSize()); for (uint32_t i = 0; i < ntk->getNetSize(); ++i) outputTable.push_back(V3NetVec()); V3BoolVec m(ntk->getNetSize(), false); // Set Latest Misc Data on (Pseudo) PI / PIO / Const for (uint32_t i = 0; i < ntk->getInputSize(); ++i) m[ntk->getInput(i).id] = true; for (uint32_t i = 0; i < ntk->getInoutSize(); ++i) m[ntk->getInout(i).id] = true; for (uint32_t i = 0; i < ntk->getLatchSize(); ++i) m[ntk->getLatch(i).id] = true; for (uint32_t i = 0; i < ntk->getConstSize(); ++i) m[ntk->getConst(i).id] = true; // DFS Compute Fanout List From (Pseudo) PO / PIO for (uint32_t i = 0; i < ntk->getLatchSize(); ++i) { dfsComputeFanout(ntk, ntk->getInputNetId(ntk->getLatch(i), 0), m, outputTable); dfsComputeFanout(ntk, ntk->getInputNetId(ntk->getLatch(i), 1), m, outputTable); } for (uint32_t i = 0; i < ntk->getInoutSize(); ++i) dfsComputeFanout(ntk, ntk->getInputNetId(ntk->getInout(i), 0), m, outputTable); if (targetNets.size()) for (uint32_t i = 0; i < targetNets.size(); ++i) dfsComputeFanout(ntk, targetNets[i], m, outputTable); else for (uint32_t i = 0; i < ntk->getOutputSize(); ++i) dfsComputeFanout(ntk, ntk->getOutput(i), m, outputTable); }
void V3SVrfIPDR::startVerify2(const uint32_t& p) { // Initialize Parameters cerr << "Multi-Step PDR\n"; uint32_t proved = V3NtkUD, fired = V3NtkUD; struct timeval inittime, curtime; gettimeofday(&inittime, NULL); clearResult(p); if (profileON()) _totalStat->start(); assert (!_constr.size()); const string flushSpace = string(100, ' '); setEndline(true); _maxTime = 900; // Clear Verification Results if(_tem_decomp == false) _decompDepth = 1; if (!reportUnsupportedInitialState()) return; //printNetlist(_vrfNtk); V3NtkExpand2* const pNtk = new V3NtkExpand2(_handler, _decompDepth+1, true); assert (pNtk); _handler->_ntk = pNtk->getNtk(); _vrfNtk = pNtk->getNtk(); //_handler->_latchMap = V3NetTable(_cycle, V3NetVec(parentNets, V3NetUD)); _handler->_latchMap = &(pNtk->_latchMap); if(_decompDepth >1) _handler->_decDep = _decompDepth; v3Handler.pushAndSetCurHandler(_handler); //printNetlist(pNtk->getNtk()); /*for (unsigned i = 0; i < 3; ++i){ for (unsigned j = 0; j < 6; ++j){ cout << _handler->_latchMap->at(i)[j].id << ":" << _handler->_latchMap->at(i)[j].cp << endl; } }*/ _pdrGen = new V3AlgAigGeneralize(_handler); assert (_pdrGen); _pdrSim = dynamic_cast<V3AlgAigSimulate*>(_pdrGen); assert (_pdrSim); V3NetVec simTargets(1, _vrfNtk->getOutput(p)); _pdrSim->reset2(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 Signal Priority List if (_pdrPriority.size() != _vrfNtk->getLatchSize()) _pdrPriority.resize(_vrfNtk->getLatchSize()); // Initialize Bad Cube _pdrBad = new V3SIPDRCube(0); assert (_pdrBad); _pdrBad->setState(V3NetVec(1, pId)); // Initialize Frame 0, Solver 0 _pdrFrame.push_back(new V3SIPDRFrame()); assert (_pdrFrame.size() == 1); initializeSolver2(0); assert (_pdrSvr.size() == 1); assert (_pdrSvr.back()); if (_vrfNtk->getLatchSize()) _pdrSvr.back()->assertInit(); // R0 = I0 // Start PDR Based Verification V3SIPDRCube* badCube = 0; while (true) { // Check Time Bounds gettimeofday(&curtime, NULL); if (_maxTime < getTimeUsed(inittime, curtime)) break; // Find a Bad Cube as Initial Proof Obligation badCube = getInitialObligation(); // SAT(R ^ T ^ !p) if(heavy_debug){ if(!badCube) cerr << "the Cube is NULL\n"; if(badCube){ cerr << "the Cube is NOT NULL\n"; printState(badCube->getState()); } } if (!badCube) { if (!isIncKeepSilent() && intactON() && frame_info ) { 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(); Msg(MSG_IFO) << endl; // Always Endline At the End of Each Frame } // Set p to the Last Frame _pdrSvr.back()->assertProperty(pId, true, 0); // Push New Frame _pdrFrame.push_back(new V3SIPDRFrame()); initializeSolver2(getPDRDepth()); assert (_pdrSvr.back()); assert (_pdrSvr.size() == _pdrFrame.size()); if (propagateCubes()) { proved = getPDRDepth(); break; } } else { badCube = recursiveBlockCube2(badCube); if (badCube) { fired = getPDRDepth(); break; } // Interactively Show the Number of Bad Cubes in Frames if (!isIncKeepSilent() && intactON() && frame_info) { 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 (endLineON()) Msg(MSG_IFO) << endl; else Msg(MSG_IFO) << flush; } } } // Report Verification Result if (!isIncKeepSilent() && reportON()) { uint32_t c_size = 0; for (uint32_t i = 0; i < _pdrFrame.size(); ++i) c_size += _pdrFrame[i]->getCubeList().size(); cout << "CubeSize : " << c_size << endl; 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) << *_BMCStat << 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 V3SIPDRCube* traceCube = badCube; assert (traceCube); 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 (existInitial2(traceCube->getState())); while (_pdrBad != traceCube) { if (_pdrSize) cex->pushData(traceCube->getInputData()); traceCube = traceCube->getNextCube(); assert (traceCube); } const V3SIPDRCube* lastCube; traceCube = badCube; while (_pdrBad != traceCube) { lastCube = traceCube->getNextCube(); delete traceCube; traceCube = lastCube; } } else if (V3NtkUD != proved) { // Record Inductive Invariant _result[p].setIndInv(_vrfNtk); assert (_result[p].isInv()); // Put the Inductive Invariant to the Last Frame uint32_t f = 1; for (; f < getPDRDepth(); ++f) if (!_pdrFrame[f]->getCubeList().size()) break; assert (f < getPDRDepth()); for (uint32_t i = 1 + f; i < getPDRDepth(); ++i) { const V3SIPDRCubeList& cubeList = _pdrFrame[i]->getCubeList(); V3SIPDRCubeList::const_iterator it; for (it = cubeList.begin(); it != cubeList.end(); ++it) _pdrFrame.back()->pushCube(*it); _pdrFrame[i]->clearCubeList(); delete _pdrFrame[i]; delete _pdrSvr[i]; } // Remove Empty Frames _pdrFrame[f] = _pdrFrame.back(); while ((1 + f) != _pdrFrame.size()) _pdrFrame.pop_back(); _pdrFrame.back()->removeSelfSubsumed(); delete _pdrSvr.back(); while ((1 + f) != _pdrSvr.size()) _pdrSvr.pop_back(); } }
/* ---------------------------------------------------------------------------------------------------- *\ 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); } } }
// Transformation Functions void V3NtkExpand2::performNtkTransformation(const bool& init) { V3Ntk* const ntk = _handler->getNtk(); assert (ntk); const uint32_t parentNets = ntk->getNetSize(); assert (parentNets); // Initialize Mappers From Parent Ntk (Index) to Current Ntk (V3NetId) _p2cMap = V3NetTable(_cycle, V3NetVec(parentNets, V3NetUD)); _latchMap = V3NetTable(_cycle, V3NetVec(parentNets, V3NetUD)); for (uint32_t cycle = 0; cycle < _cycle; ++cycle) _p2cMap[cycle][0] = V3NetId::makeNetId(0); // Compute DFS Order for Transformation V3NetVec orderMap; orderMap.clear(); dfsNtkForGeneralOrder(ntk, orderMap); assert (orderMap.size() <= parentNets); assert (!orderMap[0].id); V3NetId id; V3InputVec inputs; inputs.reserve(3); inputs.clear(); // Expand Network for (uint32_t cycle = 0; cycle < _cycle; ++cycle) { V3NetVec& p2cMap = _p2cMap[cycle]; assert (parentNets == p2cMap.size()); // Construct PI / PIO in Consistent Order uint32_t i = 1; for (uint32_t j = i + ntk->getInputSize(); i < j; ++i) { assert (parentNets > orderMap[i].id); assert (V3NetUD == p2cMap[orderMap[i].id]); p2cMap[orderMap[i].id] = _ntk->createNet(ntk->getNetWidth(orderMap[i])); assert (V3_PI == ntk->getGateType(orderMap[i])); _ntk->createInput(p2cMap[orderMap[i].id]); //cout << "PI " << orderMap[i].id << endl; //cout << "PI " << p2cMap[orderMap[i].id].id << endl; } for (uint32_t j = i + ntk->getInoutSize(); i < j; ++i) { assert (parentNets > orderMap[i].id); assert (V3NetUD == p2cMap[orderMap[i].id]); p2cMap[orderMap[i].id] = _ntk->createNet(ntk->getNetWidth(orderMap[i])); assert (V3_PIO == ntk->getGateType(orderMap[i])); _ntk->createInout(p2cMap[orderMap[i].id]); } // Construct Latches in Consistent Order for (uint32_t j = i + ntk->getLatchSize(); i < j; ++i) { assert (parentNets > orderMap[i].id); assert (V3NetUD == p2cMap[orderMap[i].id]); assert (V3_FF == ntk->getGateType(orderMap[i])); if (cycle) { // Connect FF with the Last Frame id = ntk->getInputNetId(orderMap[i], 0); assert (V3NetUD != _p2cMap[cycle - 1][id.id]); p2cMap[orderMap[i].id] = V3NetId::makeNetId(_p2cMap[cycle - 1][id.id].id, _p2cMap[cycle - 1][id.id].cp ^ id.cp); _latchMap[cycle][i-1-(ntk->getInputSize())] = p2cMap[orderMap[i].id]; //cout << "FF " << orderMap[i].id << endl; //cout << "FF " << p2cMap[orderMap[i].id].id << endl; } else { // Set Latches as Free Inputs (which will be appended after PI / PIO) p2cMap[orderMap[i].id] = _ntk->createNet(1); _ntk->createLatch(p2cMap[orderMap[i].id]); _latchMap[cycle][i-1-(ntk->getInputSize())] = p2cMap[orderMap[i].id]; } } // Construct Nets and Connections for (; i < orderMap.size(); ++i) { assert (parentNets > orderMap[i].id); assert (V3NetUD == p2cMap[orderMap[i].id]); const V3GateType& type = ntk->getGateType(orderMap[i]); assert (V3_XD > type); p2cMap[orderMap[i].id] = _ntk->createNet(ntk->getNetWidth(orderMap[i])); //cout << "AIG " << orderMap[i].id << endl; //cout << "AIG " << p2cMap[orderMap[i].id].id << endl; if (AIG_NODE == type) { id = ntk->getInputNetId(orderMap[i], 0); assert (V3NetUD != p2cMap[id.id]); inputs.push_back(V3NetId::makeNetId(p2cMap[id.id].id, p2cMap[id.id].cp ^ id.cp)); id = ntk->getInputNetId(orderMap[i], 1); assert (V3NetUD != p2cMap[id.id]); inputs.push_back(V3NetId::makeNetId(p2cMap[id.id].id, p2cMap[id.id].cp ^ id.cp)); } else { _ntk->createConst(p2cMap[orderMap[i].id]); continue; } _ntk->setInput(p2cMap[orderMap[i].id], inputs); inputs.clear(); _ntk->createGate(ntk->getGateType(orderMap[i]), p2cMap[orderMap[i].id]); } // Construct PO in Consistent Order for (i = 0; i < ntk->getOutputSize(); ++i) { id = ntk->getOutput(i); assert (V3NetUD != p2cMap[id.id]); _ntk->createOutput(V3NetId::makeNetId(p2cMap[id.id].id, p2cMap[id.id].cp ^ id.cp)); } } // Set Latches in Consistent Order as Primary Inputs uint32_t i = 1; for (uint32_t j = i + ntk->getInputSize(); i < j; ++i) {} for (uint32_t j = i + ntk->getLatchSize(); i < j; ++i) { id = ntk->getInputNetId( orderMap[i], 0 ); inputs.push_back(V3NetId::makeNetId(_p2cMap[0][id.id].id, _p2cMap[0][id.id].cp ^ id.cp)); id = ntk->getInputNetId( orderMap[i], 1 ); inputs.push_back(V3NetId::makeNetId(id.id, id.cp)); //cerr << "id.id:" << id.id << "id.cp:" << id.cp << endl; _ntk->setInput(_p2cMap[0][orderMap[i].id], inputs); inputs.clear(); //cout << "FF " << orderMap[i].id << endl; //cout << "FF " << p2cMap[orderMap[i].id].id << endl; } // Complete Mapping Table from Current Ntk to Parent Ntk _c2pMap = V3NetVec(_ntk->getNetSize(), V3NetUD); _c2pMap[0] = V3NetId::makeNetId(0); for (uint32_t cycle = 0; cycle < _cycle; ++cycle) { V3NetVec& p2cMap = _p2cMap[cycle]; assert (_c2pMap[0] == p2cMap[0]); for (uint32_t i = 0; i < p2cMap.size(); ++i) { if (V3NetUD == p2cMap[i] || V3NetUD != _c2pMap[p2cMap[i].id]) continue; else _c2pMap[p2cMap[i].id] = V3NetId::makeNetId(i, p2cMap[i].cp); } } }
// Transformation Functions void V3NtkExpand::performNtkTransformation(const bool& init) { V3Ntk* const ntk = _handler->getNtk(); assert (ntk); const uint32_t parentNets = ntk->getNetSize(); assert (parentNets); const bool isBvNtk = dynamic_cast<V3BvNtk*>(ntk); // Initialize Mappers From Parent Ntk (Index) to Current Ntk (V3NetId) _p2cMap = V3NetTable(_cycle, V3NetVec(parentNets, V3NetUD)); for (uint32_t cycle = 0; cycle < _cycle; ++cycle) _p2cMap[cycle][0] = V3NetId::makeNetId(0); // Compute DFS Order for Transformation V3NetVec orderMap; orderMap.clear(); dfsNtkForGeneralOrder(ntk, orderMap); assert (orderMap.size() <= parentNets); assert (!orderMap[0].id); V3NetId id; V3InputVec inputs; inputs.reserve(3); inputs.clear(); // Expand Network for (uint32_t cycle = 0; cycle < _cycle; ++cycle) { V3NetVec& p2cMap = _p2cMap[cycle]; assert (parentNets == p2cMap.size()); // Construct PI / PIO in Consistent Order uint32_t i = 1; for (uint32_t j = i + ntk->getInputSize(); i < j; ++i) { assert (parentNets > orderMap[i].id); assert (V3NetUD == p2cMap[orderMap[i].id]); p2cMap[orderMap[i].id] = _ntk->createNet(ntk->getNetWidth(orderMap[i])); assert (V3_PI == ntk->getGateType(orderMap[i])); _ntk->createInput(p2cMap[orderMap[i].id]); //cout << "PI " << orderMap[i].id << endl; //cout << "PI " << p2cMap[orderMap[i].id].id << endl; } for (uint32_t j = i + ntk->getInoutSize(); i < j; ++i) { assert (parentNets > orderMap[i].id); assert (V3NetUD == p2cMap[orderMap[i].id]); p2cMap[orderMap[i].id] = _ntk->createNet(ntk->getNetWidth(orderMap[i])); assert (V3_PIO == ntk->getGateType(orderMap[i])); _ntk->createInout(p2cMap[orderMap[i].id]); } // Construct Latches in Consistent Order for (uint32_t j = i + ntk->getLatchSize(); i < j; ++i) { assert (parentNets > orderMap[i].id); assert (V3NetUD == p2cMap[orderMap[i].id]); assert (V3_FF == ntk->getGateType(orderMap[i])); if (cycle) { // Connect FF with the Last Frame id = ntk->getInputNetId(orderMap[i], 0); assert (V3NetUD != _p2cMap[cycle - 1][id.id]); p2cMap[orderMap[i].id] = V3NetId::makeNetId(_p2cMap[cycle - 1][id.id].id, _p2cMap[cycle - 1][id.id].cp ^ id.cp); //cout << "FF0 " << orderMap[i].id << endl; //cout << "FF0 " << p2cMap[orderMap[i].id].id << endl; } else { // Set Latches as Free Inputs (which will be appended after PI / PIO) if (!init) p2cMap[orderMap[i].id] = _ntk->createNet(ntk->getNetWidth(orderMap[i])); else { const V3NetId id1 = ntk->getInputNetId(orderMap[i], 1); assert (id1.id < ntk->getNetSize()); if (!id1.id) p2cMap[orderMap[i].id] = id1; else if (id1 == orderMap[i]) p2cMap[orderMap[i].id] = _ntk->createNet(ntk->getNetWidth(orderMap[i])); else p2cMap[orderMap[i].id] = V3NetId::makeNetId(p2cMap[id1.id].id, p2cMap[id1.id].cp ^ id1.cp); //cout << "FF " << orderMap[i].id << endl; //cout << "FF " << p2cMap[orderMap[i].id].id << endl; } } } // Construct Nets and Connections for (; i < orderMap.size(); ++i) { assert (parentNets > orderMap[i].id); assert (V3NetUD == p2cMap[orderMap[i].id]); const V3GateType& type = ntk->getGateType(orderMap[i]); assert (V3_XD > type); p2cMap[orderMap[i].id] = _ntk->createNet(ntk->getNetWidth(orderMap[i])); //cout << "AIG " << orderMap[i].id << endl; //cout << "AIG " << p2cMap[orderMap[i].id].id << endl; if (isBvNtk) { assert (AIG_FALSE < type); if (BV_CONST == type) { inputs.push_back(ntk->getInputNetId(orderMap[i], 0)); _ntk->setInput(p2cMap[orderMap[i].id], inputs); inputs.clear(); _ntk->createConst(p2cMap[orderMap[i].id]); continue; } else if (BV_SLICE == type) { id = ntk->getInputNetId(orderMap[i], 0); assert (V3NetUD != p2cMap[id.id]); inputs.push_back(V3NetId::makeNetId(p2cMap[id.id].id, p2cMap[id.id].cp ^ id.cp)); inputs.push_back(ntk->getInputNetId(orderMap[i], 1)); } else { for (uint32_t j = 0; j < ntk->getInputNetSize(orderMap[i]); ++j) { id = ntk->getInputNetId(orderMap[i], j); assert (V3NetUD != p2cMap[id.id]); inputs.push_back(V3NetId::makeNetId(p2cMap[id.id].id, p2cMap[id.id].cp ^ id.cp)); } } } else { if (AIG_NODE == type) { id = ntk->getInputNetId(orderMap[i], 0); assert (V3NetUD != p2cMap[id.id]); inputs.push_back(V3NetId::makeNetId(p2cMap[id.id].id, p2cMap[id.id].cp ^ id.cp)); id = ntk->getInputNetId(orderMap[i], 1); assert (V3NetUD != p2cMap[id.id]); inputs.push_back(V3NetId::makeNetId(p2cMap[id.id].id, p2cMap[id.id].cp ^ id.cp)); } else { _ntk->createConst(p2cMap[orderMap[i].id]); continue; } } /*for (unsigned ii = 0, s = inputs.size(); ii < s; ++ii){ cout << inputs[ii].id.id << " "; } cout << endl;*/ //cout << "?? " << (_ntk->getGateType(p2cMap[orderMap[i].id]) == V3_PI) << endl; _ntk->setInput(p2cMap[orderMap[i].id], inputs); inputs.clear(); _ntk->createGate(ntk->getGateType(orderMap[i]), p2cMap[orderMap[i].id]); } // Construct PO in Consistent Order for (i = 0; i < ntk->getOutputSize(); ++i) { id = ntk->getOutput(i); assert (V3NetUD != p2cMap[id.id]); _ntk->createOutput(V3NetId::makeNetId(p2cMap[id.id].id, p2cMap[id.id].cp ^ id.cp)); } } // Set Latches in Consistent Order as Primary Inputs for (uint32_t i = 0; i < ntk->getLatchSize(); ++i) { id = ntk->getLatch(i); assert (V3NetUD != _p2cMap[0][id.id]); //cout << id.id << endl; //cout << V3GateTypeStr[_ntk->getGateType(id)] << endl; //cout << V3GateTypeStr[_ntk->getGateType(_p2cMap[0][id.id])] << endl; if (V3_PI == _ntk->getGateType(_p2cMap[0][id.id]))_ntk->createInput(_p2cMap[0][id.id]); } // Complete Mapping Table from Current Ntk to Parent Ntk _c2pMap = V3NetVec(_ntk->getNetSize(), V3NetUD); _c2pMap[0] = V3NetId::makeNetId(0); for (uint32_t cycle = 0; cycle < _cycle; ++cycle) { V3NetVec& p2cMap = _p2cMap[cycle]; assert (_c2pMap[0] == p2cMap[0]); for (uint32_t i = 0; i < p2cMap.size(); ++i) { if (V3NetUD == p2cMap[i] || V3NetUD != _c2pMap[p2cMap[i].id]) continue; else _c2pMap[p2cMap[i].id] = V3NetId::makeNetId(i, p2cMap[i].cp); } } }