void V3NtkElaborate::elaborateFairnessL2S(V3Constraint* const constr, V3NetVec& constrList) { assert (V3NetUD != _saved); assert (V3NetUD != _1stSave); assert (V3NetUD != _inLoop); assert (V3NetUD != _looped); assert (constr); assert (!constr->isFSMConstr()); constrList.clear(); elaboratePOConstraints(constr->getStart(), constr->getEnd(), constrList); // Create Latches for Fairness Constraints (f) V3BvNtk* const bvNtk = dynamic_cast<V3BvNtk*>(_ntk); V3NetId id; V3GateType type; V3InputVec inputs(2); if (bvNtk) { for (uint32_t i = 0; i < constrList.size(); ++i) { // Create Input of Latch (F) : "F || (f && _inLoop)" inputs.clear(); inputs.push_back(_inLoop); inputs.push_back(constrList[i]); type = BV_AND; id = elaborateBvGate(bvNtk, type, inputs, _netHash); constrList[i] = _ntk->createNet(1); assert (V3NetUD != constrList[i]); inputs.clear(); inputs.push_back(~constrList[i]); inputs.push_back(~id); type = BV_AND; id = elaborateBvGate(bvNtk, type, inputs, _netHash); inputs.clear(); inputs.push_back(~id); inputs.push_back(0); _ntk->setInput(constrList[i], inputs); _ntk->createLatch(constrList[i]); } } else { for (uint32_t i = 0; i < constrList.size(); ++i) { // Create Input of Latch (F) : "F || (f && _inLoop)" inputs.clear(); inputs.push_back(_inLoop); inputs.push_back(constrList[i]); type = AIG_NODE; id = elaborateAigGate(_ntk, type, inputs, _netHash); constrList[i] = _ntk->createNet(1); assert (V3NetUD != constrList[i]); inputs.clear(); inputs.push_back(~constrList[i]); inputs.push_back(~id); type = AIG_NODE; id = elaborateAigGate(_ntk, type, inputs, _netHash); inputs.clear(); inputs.push_back(~id); inputs.push_back(0); _ntk->setInput(constrList[i], inputs); _ntk->createLatch(constrList[i]); } } }
const V3NetId V3NtkElaborate::elaborateFSMState(const V3NetVec& stateNets, const bool& nextState) { assert (stateNets.size()); V3InputVec inputs(2, V3NetUD); V3NetId id; V3BvNtk* const bvNtk = dynamic_cast<V3BvNtk*>(_ntk); if (!nextState) { for (uint32_t k = 0; k < stateNets.size(); ++k) { assert (1 == _handler->getNtk()->getNetWidth(stateNets[k])); id = getCurrentNetId(V3NetId::makeNetId(stateNets[k].id)); inputs[1] = (stateNets[k].cp) ? ~id : id; if (!k) { inputs[0] = inputs[1]; continue; } inputs[0] = bvNtk ? elaborateBvGate(bvNtk, BV_AND, inputs, _netHash) : elaborateAigGate(_ntk, AIG_NODE, inputs, _netHash); } } else { V3UI32Hash::const_iterator is; V3InputVec ffInputs(2, 0); if (V3NetUD == _nextOpId) { _nextOpId = _ntk->createNet(1); assert (V3NetUD != _nextOpId); ffInputs[0] = V3NetId::makeNetId(0, 1); ffInputs[1] = V3NetId::makeNetId(0); _ntk->setInput(_nextOpId, ffInputs); _ntk->createLatch(_nextOpId); } for (uint32_t k = 0; k < stateNets.size(); ++k) { assert (1 == _handler->getNtk()->getNetWidth(stateNets[k])); is = _mirror.find(_p2cMap[stateNets[k].id].id); if (_mirror.end() == is) { id = _ntk->createNet(1); _mirror.insert(make_pair((uint32_t)(_p2cMap[stateNets[k].id].id), id)); ffInputs[0] = V3NetId::makeNetId(_p2cMap[stateNets[k].id].id); ffInputs[1] = V3NetId::makeNetId(0); _ntk->setInput(id, ffInputs); _ntk->createLatch(id); } else id = is->second; inputs[1] = (_p2cMap[stateNets[k].id].cp ^ stateNets[k].cp) ? ~id : id; if (!k) { inputs[0] = inputs[1]; continue; } inputs[0] = bvNtk ? elaborateBvGate(bvNtk, BV_AND, inputs, _netHash) : elaborateAigGate(_ntk, AIG_NODE, inputs, _netHash); } } assert (V3NetUD != inputs[0].id); return inputs[0].id; }
const V3NetId V3NtkElaborate::combineConstraints(const V3NetVec& constrList) { assert (constrList.size()); V3InputVec inputs(2, 0); V3BvNtk* const bvNtk = dynamic_cast<V3BvNtk*>(_ntk); // Combine All Constraints for (uint32_t i = 0; i < constrList.size(); ++i) { assert (constrList[i].id < _ntk->getNetSize()); assert (1 == _ntk->getNetWidth(constrList[i])); if (!i) inputs[0] = constrList[i]; else { inputs[1] = constrList[i]; inputs[0] = bvNtk ? elaborateBvGate(bvNtk, BV_AND, inputs, _netHash) : elaborateAigGate(_ntk, AIG_NODE, inputs, _netHash); } } return inputs[0].id; }
void V3NtkElaborate::combineConstraintsToOutputs(const uint32_t& pIndex, const V3NetVec& constrList) { assert (pIndex < _ntk->getOutputSize()); assert (constrList.size()); // Combine All Constraints V3NetId id = combineConstraints(constrList); V3InputVec inputs(2, 0); // Combine Constraints with the Property Output V3BvNtk* const bvNtk = dynamic_cast<V3BvNtk*>(_ntk); const V3NetId latchId = _ntk->createNet(); assert (V3NetUD != latchId); inputs[0] = ~latchId; inputs[1] = id; id = bvNtk ? ~elaborateBvGate(bvNtk, BV_AND, inputs, _netHash) : ~elaborateAigGate(_ntk, AIG_NODE, inputs, _netHash); inputs[0] = id; inputs[1] = V3NetId::makeNetId(0); _ntk->setInput(latchId, inputs); _ntk->createLatch(latchId); inputs[0] = ~id; inputs[1] = _ntk->getOutput(pIndex); id = bvNtk ? elaborateBvGate(bvNtk, BV_AND, inputs, _netHash) : elaborateAigGate(_ntk, AIG_NODE, inputs, _netHash); _ntk->replaceOutput(pIndex, id); }
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; }