// Restricted Copy Functions V3Formula* const V3Formula::createSuccessor(V3NtkHandler* const handler) const { assert (handler); if (_handler != handler->getHandler()) { Msg(MSG_ERR) << "Require handler to be the Immediate Sucessor of formula's Handler !!" << endl; return 0; } V3Formula* const formula = new V3Formula(handler); assert (formula); formula->_formula.clear(); formula->_formula.reserve(_formula.size()); formula->_rootId = _rootId; V3NetId id; V3InputVec inputs; inputs.clear(); for (uint32_t i = 0; i < _formula.size(); ++i) if (isLeaf(i)) { id = getNetId(i); assert (V3NetUD != id); id = handler->getCurrentNetId(id); inputs.push_back(id); if (V3NetUD == id) { Msg(MSG_ERR) << "Unresolvable Formula Found !!" << endl; delete formula; return 0; } else formula->_formula.push_back(make_pair(_formula[i].first, inputs)); inputs.clear(); } else formula->_formula.push_back(_formula[i]); assert (formula); return formula; }
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; }
// 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); } } }
void V3Ntk::setInput(const V3NetId& id, const V3InputVec& inputs) { assert (validNetId(id)); //assert (V3_PI == getGateType(id)); V3InputVec& fanInVec = _inputData[id.id]; assert (!fanInVec.size()); for (uint32_t i = 0; i < inputs.size(); ++i) fanInVec.push_back(inputs[i]); }
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 Exists V3BvNtk* const bvNtk = dynamic_cast<V3BvNtk*>(_ntk); V3InputVec inputs; inputs.clear(); inputs.reserve(4); V3GateType type; if ((V3NetUD == _saved) || (V3NetUD == _1stSave)) { assert ((V3NetUD == _saved) && (V3NetUD == _1stSave)); _saved = _ntk->createNet(1); _1stSave = _ntk->createNet(1); 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); // Set Inputs of _1stSave inputs.push_back(oracle); inputs.push_back(~_saved); _ntk->setInput(_1stSave, inputs); _ntk->createGate((bvNtk ? BV_AND : AIG_NODE), _1stSave); inputs.clear(); } // Create Equivalence Logic and Shadow FF if NOT Exists for (uint32_t i = 0; i < _shadow.size(); ++i) { if (V3NetUD == _shadow[i] && V3NetUD != _p2cMap[_handler->getNtk()->getLatch(i).id]) { assert (V3_FF == _ntk->getGateType(_p2cMap[_handler->getNtk()->getLatch(i).id])); _shadow[i] = _ntk->createNet(_ntk->getNetWidth(_p2cMap[_handler->getNtk()->getLatch(i).id])); // Create Input MUX of Shadow FF V3NetId shadowMux = V3NetUD; if (bvNtk) { inputs.push_back(_p2cMap[_handler->getNtk()->getLatch(i).id]); inputs.push_back(_shadow[i]); inputs.push_back(~_1stSave); type = BV_MUX; shadowMux = elaborateBvGate(bvNtk, type, inputs, _netHash); } else { inputs.push_back(_1stSave); inputs.push_back(_p2cMap[_handler->getNtk()->getLatch(i).id]); inputs.push_back(~_1stSave); inputs.push_back(_shadow[i]); type = AIG_NODE; shadowMux = elaborateAigAndOrAndGate(_ntk, inputs, _netHash); } assert (V3NetUD != shadowMux); inputs.clear(); // Create Shadow FF inputs.clear(); inputs.push_back(shadowMux); const uint32_t width = (bvNtk) ? _ntk->getNetWidth(_p2cMap[_handler->getNtk()->getLatch(i).id]) : 1; if (width > 1) { V3InputVec constInputs(1, bvNtk->hashV3ConstBitVec(v3Int2Str(width) + "'d0")); type = BV_CONST; inputs.push_back(elaborateBvGate(bvNtk, type, constInputs, _netHash)); } else inputs.push_back(0); _ntk->setInput(_shadow[i], inputs); _ntk->createLatch(_shadow[i]); inputs.clear(); // Create Equivalence Gate and Update _shadow if (bvNtk) { inputs.push_back(_p2cMap[_handler->getNtk()->getLatch(i).id]); inputs.push_back(_shadow[i]); type = BV_EQUALITY; _shadow[i] = elaborateBvGate(bvNtk, type, inputs, _netHash); } else { inputs.push_back(_p2cMap[_handler->getNtk()->getLatch(i).id]); inputs.push_back(_shadow[i]); inputs.push_back(~_shadow[i]); inputs.push_back(~_p2cMap[_handler->getNtk()->getLatch(i).id]); _shadow[i] = elaborateAigAndOrAndGate(_ntk, inputs, _netHash); } inputs.clear(); assert (V3NetUD != _shadow[i]); } } // Build LTL Formula Output Logic 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(); // Build LTL Formula Output V3NetId pId = V3NetUD; inputs.push_back(_saved); inputs.push_back(~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(); // Build LTL Formula Output with Related Latches Only _ntk->newMiscData(); dfsRecurMarkFaninCone(_ntk, id); for (uint32_t i = 0; i < _shadow.size(); ++i) { if (V3NetUD == _shadow[i]) continue; if (!_ntk->isLatestMiscData(_p2cMap[_handler->getNtk()->getLatch(i).id])) continue; inputs.push_back(pId); inputs.push_back(_shadow[i]); 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; }