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; }
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; }