Example #1
0
// 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;
}
Example #2
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;
}
Example #3
0
// 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);
      }
   }
}
Example #4
0
// 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);
      }
   }
}
Example #5
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 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;
}