Example #1
0
const bool createBvPairGate(V3BvNtk* const ntk, const V3GateType& type, const V3NetId& id, 
                                                const V3NetId& id1, const V3NetId& id2) {
   assert (isV3PairType(type) || isV3ExtendType(type));
   if (ntk->reportMultipleDrivenNet(type, id)) return false;
   // Extended Gate Type
   if (isV3ExtendType(type)) {
      V3NetId ext1 = id1, ext2 = id2;
      if (isV3ExtendSwapIn(type)) { V3NetId t = ext2; ext2 = ext1; ext1 = t; }
      if (isV3ExtendInvIn(type)) { ext1.cp ^= 1; ext2.cp ^= 1; }
      V3NetId id_new = isV3ExtendInvOut(type) ? ntk->createNet(ntk->getNetWidth(id)) : id;
      assert (V3NetUD != id_new); assert (isV3ExtendInvOut(type) ^ (id == id_new));
      if (!createBvPairGate(ntk, getV3ExtendNormal(type), id_new, ext1, ext2)) return false;
      if (id != id_new) { id_new.cp ^= 1; return createV3BufGate(ntk, id, id_new); } return true;
   }
   else {
      if (type != BV_SHL && type != BV_SHR && type != BV_MERGE)
         if (ntk->reportNetWidthInconsistency(id1, id2, V3GateTypeStr[type] + " I/O")) return false;
      if (type == BV_EQUALITY || type == BV_GEQ) {
         if (ntk->reportUnexpectedNetWidth(id, 1, V3GateTypeStr[type] + " Output")) return false;
      }
      else if (type != BV_MERGE) {
         if (ntk->reportNetWidthInconsistency(id, id1, V3GateTypeStr[type] + " I/O")) return false;
         if (type != BV_SHL && type != BV_SHR) 
            if (ntk->reportNetWidthInconsistency(id, id2, V3GateTypeStr[type] + " I/O")) return false;
      }
      else if (ntk->reportUnexpectedNetWidth(id, ntk->getNetWidth(id1) + ntk->getNetWidth(id2), "BV_MERGE Output")) 
         return false;
      V3InputVec v3InputVec; v3InputVec.clear(); v3InputVec.push_back(V3NetType(id1));
      v3InputVec.push_back(V3NetType(id2)); ntk->setInput(id, v3InputVec);
      ntk->createGate(type, id); return true;
   }
}
Example #2
0
void
V3NtkHandler::printNetlist() const {
   assert (_ntk); V3NetId id = V3NetId::makeNetId(1); V3GateType type;
   for (uint32_t i = 1; i < _ntk->getNetSize(); ++i, ++id.id) {
      assert (i == id.id); Msg(MSG_IFO) << "[" << getNetNameOrFormedWithId(id) << "]";
      type = _ntk->getGateType(id); Msg(MSG_IFO) << " = " << V3GateTypeStr[type];
      if (V3_FF == type || AIG_NODE == type || isV3PairType(type))
         Msg(MSG_IFO) << "(.A(" << getNetNameOrFormedWithId(_ntk->getInputNetId(id, 0)) << ")," 
                      << " .B(" << getNetNameOrFormedWithId(_ntk->getInputNetId(id, 1)) << "))" << endl;
      else if (V3_PIO == type || isV3ReducedType(type))
         Msg(MSG_IFO) << "(.A(" << getNetNameOrFormedWithId(_ntk->getInputNetId(id, 0)) << "))" << endl;
      else if (BV_MUX == type)
         Msg(MSG_IFO) << "(.F(" << getNetNameOrFormedWithId(_ntk->getInputNetId(id, 0)) << "),"
                      << " .T(" << getNetNameOrFormedWithId(_ntk->getInputNetId(id, 1)) << "),"
                      << " .S(" << getNetNameOrFormedWithId(_ntk->getInputNetId(id, 2)) << "))" << endl;
      else if (BV_SLICE == type)
         Msg(MSG_IFO) << "(.A(" << getNetNameOrFormedWithId(_ntk->getInputNetId(id, 0)) << "[" 
                      << dynamic_cast<V3BvNtk*>(_ntk)->getInputSliceBit(id, true) << " : " 
                      << dynamic_cast<V3BvNtk*>(_ntk)->getInputSliceBit(id, false) << "))" << endl;
      else if (BV_CONST == type)
         Msg(MSG_IFO) << "(.A(" << (dynamic_cast<V3BvNtk*>(_ntk)->getInputConstValue(id)) << "))" << endl;
      else if (V3_MODULE == type)
         Msg(MSG_IFO) << "(" << _ntk->getModule(id)->getNtkRef()->getNtkName() << ")" << endl;
      else Msg(MSG_IFO) << endl;
   }
}
Example #3
0
// Ntk Reconstruction Functions
void
V3Ntk::replaceFanin(const V3RepIdHash& repIdHash) {
   //cerr << "called replaceFanin" << endl;
   assert (repIdHash.size());
   uint32_t i, inSize; V3GateType type;
   V3RepIdHash::const_iterator it;
   for (V3NetId id = V3NetId::makeNetId(1); id.id < _inputData.size(); ++id.id) {
      type = getGateType(id);
      if (V3_MODULE == type) {
         V3NtkModule* const module = getModule(_inputData[id.id][0].value); assert (module);
         for (i = 0; i < module->getInputList().size(); ++i) {
            it = repIdHash.find(module->getInputList()[i].id); if (repIdHash.end() == it) continue;
            module->updateInput(i, module->getInputList()[i].cp ? ~(it->second) : it->second);
         }
      }
      else {
         inSize = (AIG_NODE == type || isV3PairType(type)) ? 2 : (BV_MUX == type) ? 3 : 
                  (V3_FF == type || BV_SLICE == type || isV3ReducedType(type)) ? 1 : 0;
         for (i = 0; i < inSize; ++i) {
            it = repIdHash.find(_inputData[id.id][i].id.id); if (repIdHash.end() == it) continue;
            //cout << "replacing : " << id.id << "'s input\n";
            _inputData[id.id][i] = V3NetType(_inputData[id.id][i].id.cp ? ~(it->second) : it->second);
         }
      }
   }
}
Example #4
0
const bool
V3Ntk::reportUnexpectedFaninSize(const V3GateType& type, const V3NetId& id) const {
   assert (type < V3_XD); assert (validNetId(id));
   if (((isV3ReducedType(type) || BV_CONST == type || V3_PIO == type) && (getInputNetSize(id) != 1)) || 
       ((isV3PairType(type) || AIG_NODE == type || V3_FF == type || BV_SLICE == type) && (getInputNetSize(id) != 2)) || 
       ((BV_MUX == type) && (getInputNetSize(id) != 3)) || ((V3_MODULE == type) && (getInputNetSize(id) != 1)))
      Msg(MSG_ERR) << "Expecting Fanin Size is One while " << getInputNetSize(id) 
                   << " is Found @ " << id.id << " for Gate Type = " << V3GateTypeStr[type] << endl;
   else return false;
   return true;
}
Example #5
0
const uint32_t reportCombinationalLoops(V3Ntk* const ntk) {
   assert (ntk); V3UI32Vec levelData; computeLevel(ntk, levelData);
   V3Vec<V3PairType>::Vec netLoop; netLoop.clear(); V3GateType type; uint32_t j = 0;
   for (V3NetId id = V3NetId::makeNetId(0); id.id < ntk->getNetSize(); ++id.id) {
      type = ntk->getGateType(id); assert (V3_XD > type);
      if (V3NtkUD == levelData[id.id]) continue;  // Unreachable net
      else if (V3_MODULE >= type || BV_CONST == type || AIG_FALSE == type) continue;
      const uint32_t inSize = (type == AIG_NODE || isV3PairType(type)) ? 2 : (BV_MUX == type) ? 3 : 
                              (isV3ReducedType(type) || BV_SLICE == type) ? 1 : 0;
      for (uint32_t i = 0; i < inSize; ++i) {
         if (levelData[id.id] > levelData[ntk->getInputNetId(id, i).id]) continue;
         // Report Combinational Loops
         netLoop.clear(); netLoop.push_back(V3PairType(id.id, i)); ++j;
         if (reportCombinationalLoops(ntk, ntk->getInputNetId(id, i), levelData, netLoop)) {
            Msg(MSG_IFO) << "Combinational Loop " << j << " : " << endl; uint32_t k = netLoop.size();
            while (k--) { Msg(MSG_IFO) << netLoop[k].bus[0] << "[" << netLoop[k].bus[1] << "] --> "; }
            Msg(MSG_IFO) << netLoop.back().bus[0] << endl;
         }
         else Msg(MSG_ERR) << "Unknown Combinational Loop Starting from " << id.id << "[" << i << "] ..." << endl;
      }
   }
   return j;
}
Example #6
0
// General Ntk Topology Validation Functions for V3 Ntk
const bool reportCombinationalLoops(V3Ntk* const ntk, const V3NetId& id, const V3UI32Vec levelData, V3Vec<V3PairType>::Vec& netLoop) {
   assert (ntk); assert (1 == netLoop.size()); assert (id.id < ntk->getNetSize());
   if (id.id == netLoop[0].bus[0]) return true; assert (V3NtkUD != levelData[id.id]);
   const V3GateType type = ntk->getGateType(id); assert (V3_XD > type);
   if (V3_MODULE > type || BV_CONST == type || AIG_FALSE == type) return false;
   else if (V3_MODULE == type) {
      V3NtkModule* const moduleNtk = ntk->getModule(id); assert (moduleNtk);
      const V3NetVec& inputs = moduleNtk->getInputList();
      for (uint32_t i = 0; i < inputs.size(); ++i) {
         if (!reportCombinationalLoops(ntk, inputs[i], levelData, netLoop)) continue;
         netLoop.push_back(V3PairType(id.id, i)); return true;
      }
   }
   else {
      const uint32_t inSize = (type == AIG_NODE || isV3PairType(type)) ? 2 : (BV_MUX == type) ? 3 : 
         (isV3ReducedType(type) || BV_SLICE == type) ? 1 : 0;
      for (uint32_t i = 0; i < inSize; ++i) {
         if (levelData[id.id] <= levelData[ntk->getInputNetId(id, i).id]) continue;
         if (!reportCombinationalLoops(ntk, ntk->getInputNetId(id, i), levelData, netLoop)) continue;
         netLoop.push_back(V3PairType(id.id, i)); return true;
      }
   }
   return false;
}
Example #7
0
const V3NetId dfsBuildNtkFromQuteRTL(V3NtkInput* const quteHandler, CktOutPin* const OutPin, const bool& a2s) {
   assert (quteHandler); assert (OutPin);
   // Check if OutPin Already Exists
   const string name = quteGetOutPinName(OutPin); assert (name.size());
   V3NetId id = quteHandler->getNetId(name); if (V3NetUD != id) return id;
   // Get OutPin Info
   CktCell* const cell = quteGetCellFromPin(OutPin); assert (cell);
   const QuteRTL_API_CellType type = quteGetCellType(cell); assert (type < QUTE_TOTAL_CELL);
   assert (type != QUTE_PI_CELL && type != QUTE_PO_CELL && type != QUTE_PIO_CELL && type != QUTE_DFF_CELL);
   // Create V3NetId for OutPin
   if (QUTE_MODULE_CELL != type) {
      id = quteHandler->createNet(name, getOutPinWidthFromQuteRTL(name, OutPin));
      if (V3NetUD == id) return id;
   }
   // Compute V3 Gate Type According to QuteRTL Cell Type
   V3BvNtk* const ntk = dynamic_cast<V3BvNtk*>(quteHandler->getNtk()); assert (ntk);
   bool invert = false, exactTwo = false;
   V3GateType v3Type;
   switch (type) {
      // Single Input : Reduced
      case QUTE_RED_AND_CELL  : v3Type = BV_RED_AND;                   break;
      case QUTE_RED_OR_CELL   : v3Type = BV_RED_OR;                    break;
      case QUTE_RED_NAND_CELL : v3Type = BV_RED_AND;  invert = true;   break;
      case QUTE_RED_NOR_CELL  : v3Type = BV_RED_OR;   invert = true;   break;
      case QUTE_RED_XOR_CELL  : v3Type = BV_RED_XOR;                   break;
      case QUTE_RED_XNOR_CELL : v3Type = BV_RED_XOR;  invert = true;   break;
      // Single Input : Logic
      case QUTE_BUF_CELL      : v3Type = BV_BUF;                       break;
      case QUTE_INV_CELL      : v3Type = BV_BUF;      invert = true;   break;
      // One+ Input : Logic
      case QUTE_AND_CELL      : v3Type = BV_AND;                       break;
      case QUTE_OR_CELL       : v3Type = BV_OR;                        break;
      case QUTE_NAND_CELL     : v3Type = BV_AND;      invert = true;   break;
      case QUTE_NOR_CELL      : v3Type = BV_OR;       invert = true;   break;
      case QUTE_XOR_CELL      : v3Type = BV_XOR;                       break;
      case QUTE_XNOR_CELL     : v3Type = BV_XOR;      invert = true;   break;
      // One+ Input : Arithmetic
      case QUTE_ADD_CELL      : v3Type = BV_ADD;                       break;
      case QUTE_SUB_CELL      : v3Type = BV_SUB;                       break;
      case QUTE_MULT_CELL     : v3Type = BV_MULT;                      break;
      case QUTE_DIV_CELL      : v3Type = BV_DIV;                       break;
      case QUTE_MODULO_CELL   : v3Type = BV_MODULO;                    break;
      // One+ Input : Model
      case QUTE_MERGE_CELL    : v3Type = BV_MERGE;                     break;
      // Two Inputs : Arithmetic
      case QUTE_SHL_CELL      : v3Type = BV_SHL;                       break;
      case QUTE_SHR_CELL      : v3Type = BV_SHR;                       break;
      // Two Inputs : Comparator
      case QUTE_EQUALITY_CELL : v3Type = BV_EQUALITY; exactTwo = true; break;
      case QUTE_GEQ_CELL      : v3Type = BV_GEQ;      exactTwo = true; break;
      case QUTE_GREATER_CELL  : v3Type = BV_GREATER;  exactTwo = true; break;
      case QUTE_LEQ_CELL      : v3Type = BV_LEQ;      exactTwo = true; break;
      case QUTE_LESS_CELL     : v3Type = BV_LESS;     exactTwo = true; break;
      // Multiplexer
      case QUTE_MUX_CELL      : v3Type = BV_MUX;                       break;
      // Model
      case QUTE_CONST_CELL    : v3Type = BV_CONST;                     break;
      case QUTE_SPLIT_CELL    : v3Type = BV_SLICE;                     break;
      // Unsupported : Model
      case QUTE_MEMORY_CELL   : Msg(MSG_ERR) << "Memory Exists in RTL Design !!" << endl; return V3NetUD;
      // Unsupported : Module Instance
      case QUTE_MODULE_CELL   : v3Type = V3_MODULE;                    break;
      // Unsupported : Latch
      case QUTE_DLAT_CELL     : Msg(MSG_ERR) << "Latch Exists in RTL Design !!" << endl; return V3NetUD;
      default                 : Msg(MSG_ERR) << "Unexpected QuteRTL Cell Type : " << type << endl; return V3NetUD;
   }
   // Build V3 Gate
   V3NetId id1, id2, id3, id4;
   if (isV3ReducedType(v3Type)) {  // REDUCED
      assert (quteGetCellInputSize(cell) == 1); assert (V3NetUD != id);
      id1 = dfsBuildNtkFromQuteRTL(quteHandler, quteGetCellInputPin(cell, 0), a2s); if (V3NetUD == id1) return id1;
      id2 = ntk->createNet(1); if (V3NetUD == id2) return id2;
      if (!createBvReducedGate(ntk, v3Type, id2, id1)) return V3NetUD;
      // Matching Output and Input Bit-widths
      if (ntk->getNetWidth(id) == ntk->getNetWidth(id2)) {
         if (!createV3BufGate(ntk, id, (invert ? getV3InvertNet(id2) : id2))) return V3NetUD; }
      else {
         id3 = ntk->createNet(1); if (V3NetUD == id3) return id3;
         if (!createV3BufGate(ntk, id3, (invert ? getV3InvertNet(id2) : id2))) return V3NetUD;
         if (!createIOExtensionGate(ntk, id, id3)) return V3NetUD;
      }
   }
   else if (exactTwo) {  // TWO INPUTS
      assert (quteGetCellInputSize(cell) == 2); assert (V3NetUD != id); assert (!invert);
      id1 = dfsBuildNtkFromQuteRTL(quteHandler, quteGetCellInputPin(cell, 0), a2s); if (V3NetUD == id1) return id1;
      id2 = dfsBuildNtkFromQuteRTL(quteHandler, quteGetCellInputPin(cell, 1), a2s); if (V3NetUD == id2) return id2;
      // Matching Input Bit-widths
      if (ntk->getNetWidth(id1) > ntk->getNetWidth(id2)) {
         id2 = createNetExtensionGate(ntk, id2, ntk->getNetWidth(id1)); if (V3NetUD == id2) return id2; }
      else if (ntk->getNetWidth(id1) < ntk->getNetWidth(id2)) {
         id1 = createNetExtensionGate(ntk, id1, ntk->getNetWidth(id2)); if (V3NetUD == id1) return id1; }
      // Matching Output and Input Bit-widths
      if (1 == ntk->getNetWidth(id)) {
         if (!createBvPairGate(ntk, v3Type, id, id1, id2)) return V3NetUD; }
      else {
         id3 = ntk->createNet(1); if (V3NetUD == id3) return id3;
         if (!createBvPairGate(ntk, v3Type, id3, id1, id2)) return V3NetUD;
         if (!createIOExtensionGate(ntk, id, id3)) return V3NetUD;
      }
   }
   else if (BV_MUX == v3Type) {  // MULTIPLEXER
      assert (quteGetCellInputSize(cell) == 3); assert (V3NetUD != id); assert (!invert);
      id1 = dfsBuildNtkFromQuteRTL(quteHandler, quteGetCellInputPin(cell, 0), a2s); if (V3NetUD == id1) return id1;
      id2 = dfsBuildNtkFromQuteRTL(quteHandler, quteGetCellInputPin(cell, 1), a2s); if (V3NetUD == id2) return id2;
      // Matching Input Bit-widths
      if (ntk->getNetWidth(id1) > ntk->getNetWidth(id2)) {
         id2 = createNetExtensionGate(ntk, id2, ntk->getNetWidth(id1)); if (V3NetUD == id2) return id2; }
      else if (ntk->getNetWidth(id1) < ntk->getNetWidth(id2)) {
         id1 = createNetExtensionGate(ntk, id1, ntk->getNetWidth(id2)); if (V3NetUD == id1) return id1; }
      id3 = dfsBuildNtkFromQuteRTL(quteHandler, quteGetCellInputPin(cell, 2), a2s); if (V3NetUD == id3) return id3;
      // Matching Output and Input Bit-widths
      if (ntk->getNetWidth(id) == ntk->getNetWidth(id1)) {
         if (!createBvMuxGate(ntk, id, id1, id2, id3)) return V3NetUD; }
      else {
         id4 = ntk->createNet(ntk->getNetWidth(id1)); if (V3NetUD == id4) return id4;
         if (!createBvMuxGate(ntk, id4, id1, id2, id3)) return V3NetUD;
         if (!createIOExtensionGate(ntk, id, id4)) return V3NetUD;
      }
   }
   else if (BV_SLICE == v3Type) {  // SLICE
      assert (quteGetCellInputSize(cell) == 1); assert (V3NetUD != id); assert (!invert);
      CktOutPin* inOutPin = quteGetCellInputPin(cell, 0); assert (inOutPin);
      id1 = dfsBuildNtkFromQuteRTL(quteHandler, inOutPin, a2s); if (V3NetUD == id1) return id1;
      const uint32_t sliceEnd = quteGetSplitOutPinEnd(OutPin), sliceBegin = quteGetSplitOutPinBegin(OutPin);
      const uint32_t end = quteGetPinEnd(inOutPin), begin = quteGetPinBegin(inOutPin);
      if (end >= begin) {
         assert (sliceEnd <= end); assert (sliceBegin >= begin);
         // Matching Output and Input Bit-widths
         if (ntk->getNetWidth(id) == (1 + sliceEnd - sliceBegin)) {
            if (!createBvSliceGate(ntk, id, id1, sliceEnd - begin, sliceBegin - begin)) return V3NetUD; }
         else {
            id2 = ntk->createNet(1 + sliceEnd - sliceBegin); if (V3NetUD == id2) return id2;
            if (!createBvSliceGate(ntk, id2, id1, sliceEnd - begin, sliceBegin - begin)) return V3NetUD;
            if (!createIOExtensionGate(ntk, id, id2)) return V3NetUD;
         }
      }
      else {
         assert (sliceEnd >= end); assert (sliceBegin <= begin);
         // Matching Output and Input Bit-widths
         if (ntk->getNetWidth(id) == (1 + sliceBegin - sliceEnd)) {
            if (!createBvSliceGate(ntk, id, id1, begin - sliceEnd, begin - sliceBegin)) return V3NetUD;
         }
         else {
            id2 = ntk->createNet(1 + sliceBegin - sliceEnd); if (V3NetUD == id2) return id2;
            if (!createBvSliceGate(ntk, id2, id1, begin - sliceEnd, begin - sliceBegin)) return V3NetUD;
            if (!createIOExtensionGate(ntk, id, id2)) return V3NetUD;
         }
      }
   }
   else if (BV_CONST == v3Type) {  // CONST
      assert (quteGetCellInputSize(cell) == 0); assert (V3NetUD != id); assert (!invert);
      const string value = quteGetConstCellValue(cell); assert (value.size());
      // Matching Output and Input Bit-widths
      V3BitVec bvValue(value.c_str());
      if (ntk->getNetWidth(id) == bvValue.size()) {
         if (!createBvConstGate(ntk, id, value)) return V3NetUD; }
      else {
         id2 = ntk->createNet(bvValue.size()); if (V3NetUD == id2) return id2;
         if (!createBvConstGate(ntk, id2, value)) return V3NetUD;
         if (!createIOExtensionGate(ntk, id, id2)) return V3NetUD;
      }
   }
   else if (BV_BUF == v3Type) {  // BUF / INV
      assert (quteGetCellInputSize(cell) == 1); assert (V3NetUD != id);
      id1 = dfsBuildNtkFromQuteRTL(quteHandler, quteGetCellInputPin(cell, 0), a2s); if (V3NetUD == id1) return id1;
      // Matching Output and Input Bit-widths
      if (ntk->getNetWidth(id) == ntk->getNetWidth(id1)) {
         if (!createV3BufGate(ntk, id, (invert ? getV3InvertNet(id1) : id1))) return V3NetUD; }
      else {
         id2 = ntk->createNet(ntk->getNetWidth(id1)); if (V3NetUD == id2) return id2;
         if (!createV3BufGate(ntk, id2, (invert ? getV3InvertNet(id1) : id1))) return V3NetUD;
         if (!createIOExtensionGate(ntk, id, id2)) return V3NetUD;
      }
   }
   else if (BV_MERGE == v3Type) {  // MERGE
      assert (quteGetCellInputSize(cell) >= 1); assert (V3NetUD != id); id1 = V3NetUD;
      uint32_t merge_width = 0;
      for (uint32_t i = 0, j = quteGetCellInputSize(cell); i < j; ++i) {
         id2 = dfsBuildNtkFromQuteRTL(quteHandler, quteGetCellInputPin(cell, i), a2s); if (V3NetUD == id2) return id2;
         merge_width += ntk->getNetWidth(id2); assert (merge_width);
         if (V3NetUD == id1) { id1 = id2; continue; }
         id3 = ntk->createNet(merge_width); if (V3NetUD == id3) return id3;
         if (!createBvPairGate(ntk, v3Type, id3, id1, id2)) return V3NetUD; id1 = id3;
      }
      // Matching Output and Input Bit-widths
      if (ntk->getNetWidth(id) == ntk->getNetWidth(id1)) {
         if (!createV3BufGate(ntk, id, id1)) return V3NetUD; }
      else {
         id2 = ntk->createNet(ntk->getNetWidth(id1)); if (V3NetUD == id2) return id2;
         if (!createV3BufGate(ntk, id2, id1)) return V3NetUD;
         if (!createIOExtensionGate(ntk, id, id2)) return V3NetUD;
      }
   }
   else if (V3_MODULE == v3Type) {  // MODULE
      // Get Module Instance
      CktModule* const module = quteGetModuleInstance(cell); assert (module);
      // Create Output Nets for Module Instance
      V3NetVec outputs(quteGetCellOutputSize(cell), V3NetUD); assert (V3NetUD == id);
      assert (outputs.size() == quteGetDesignIoSize(module, QUTE_PO_CELL));
      for (uint32_t i = 0; i < outputs.size(); ++i) {
         CktOutPin* const outputPin = quteGetCellOutputPin(cell, i);
         if (outputPin) {  // Non-Floating Output
            const string outputName = quteGetOutPinName(outputPin); assert (outputName.size());
            assert (V3NetUD == quteHandler->getNetId(outputName));
            outputs[i] = quteHandler->createNet(outputName, getOutPinWidthFromQuteRTL(outputName, outputPin));
            if (V3NetUD == outputs[i]) return outputs[i]; if (OutPin == outputPin) id = outputs[i];
            // Matching Module Output Bit-widths
            CktCell* const outputCell = quteGetDesignIoCell(module, QUTE_PO_CELL, i); assert (outputCell);
            assert (1 == quteGetCellOutputSize(outputCell)); assert (quteGetCellOutputPin(outputCell, 0));
            if (quteGetPinWidth(quteGetCellOutputPin(outputCell, 0)) != ntk->getNetWidth(outputs[i])) {
               id1 = ntk->createNet(quteGetPinWidth(quteGetCellOutputPin(outputCell, 0))); if (V3NetUD == id1) return id1;
               if (!createIOExtensionGate(ntk, outputs[i], id1)) return V3NetUD; outputs[i] = id1;
            }
         }
         else {  // Floating Output
            CktCell* const outputCell = quteGetDesignIoCell(module, QUTE_PO_CELL, i); assert (outputCell);
            assert (1 == quteGetCellOutputSize(outputCell)); assert (quteGetCellOutputPin(outputCell, 0));
            outputs[i] = quteHandler->createNet("", quteGetPinWidth(quteGetCellOutputPin(outputCell, 0)));
            if (V3NetUD == outputs[i]) return outputs[i];
         }
      }
      // Collect Input Nets for Module Instance
      V3NetVec inputs(quteGetCellInputSize(cell), V3NetUD);
      assert (inputs.size() == quteGetDesignIoSize(module, QUTE_PI_CELL));
      for (uint32_t i = 0; i < inputs.size(); ++i) {
         inputs[i] = dfsBuildNtkFromQuteRTL(quteHandler, quteGetCellInputPin(cell, i), a2s);
         if (V3NetUD == inputs[i]) return inputs[i];
         // Matching Module Input Bit-widths
         CktCell* const inputCell = quteGetDesignIoCell(module, QUTE_PI_CELL, i); assert (inputCell);
         assert (1 == quteGetCellOutputSize(inputCell)); assert (quteGetCellOutputPin(inputCell, 0));
         if (quteGetPinWidth(quteGetCellOutputPin(inputCell, 0)) != ntk->getNetWidth(inputs[i])) {
            id1 = ntk->createNet(quteGetPinWidth(quteGetCellOutputPin(inputCell, 0))); if (V3NetUD == id1) return id1;
            if (!createIOExtensionGate(ntk, id1, inputs[i])) return V3NetUD; inputs[i] = id1;
         }
      }
      // Create Module Instance
      const V3NetVec oInputs = inputs;  // Backup for Clock Signal Identification
      V3NtkHandler* const moduleHandler = V3QuteRTLHandler(module, a2s, inputs, quteGetModuleInstanceName(cell));
      if (!moduleHandler) return V3NetUD; assert (moduleHandler->getNtk());
      // Set Clock From Module Instance
      for (uint32_t i = 0; i < inputs.size(); ++i) {
         if (V3NetUD != inputs[i]) continue; inputs.erase(inputs.begin() + i);  // Remove Clock Signal
         if (V3NetUD == ntk->getClock()) ntk->createClock(oInputs[i]);
         else if (oInputs[i] != ntk->getClock()) 
            Msg(MSG_WAR) << "Multiple Clock Domains Found in RTL Design \"" << quteHandler->getNtkName() << "\" !!" << endl;
         break;
      }
      createModule(ntk, inputs, outputs, moduleHandler, false);
   }
   else {  // ONE+ INPUT
      assert (quteGetCellInputSize(cell) >= 1); assert (V3NetUD != id);
      assert (isV3PairType(v3Type) || (BV_OR == v3Type)); id1 = V3NetUD;
      for (uint32_t i = 0, j = quteGetCellInputSize(cell); i < j; ++i) {
         id2 = dfsBuildNtkFromQuteRTL(quteHandler, quteGetCellInputPin(cell, i), a2s); if (V3NetUD == id2) return id2;
         //if (BV_ADD == v3Type || BV_SUB == v3Type) {
         //   id2 = createNetExtensionGate(ntk, id2, 1 + ntk->getNetWidth(id2)); if (V3NetUD == id2) return id2; }
         //else if (BV_MULT == v3Type) {
         //   id2 = createNetExtensionGate(ntk, id2, ntk->getNetWidth(id2) << 1); if (V3NetUD == id2) return id2; }
         if (V3NetUD == id1) { id1 = id2; continue; }
         // Matching Input Bit-widths
         if (ntk->getNetWidth(id1) > ntk->getNetWidth(id2)) {
            id2 = createNetExtensionGate(ntk, id2, ntk->getNetWidth(id1)); if (V3NetUD == id2) return id2; }
         else if (ntk->getNetWidth(id1) < ntk->getNetWidth(id2)) {
            id1 = createNetExtensionGate(ntk, id1, ntk->getNetWidth(id2)); if (V3NetUD == id1) return id1; }
         //if (BV_SHL == v3Type) {
         //   id1 = createNetExtensionGate(ntk, id1, ntk->getNetWidth(id1) + ntk->getNetWidth(id2));
         //   if (V3NetUD == id1) return id1;
         //   id2 = createNetExtensionGate(ntk, id2, ntk->getNetWidth(id1));
         //   if (V3NetUD == id2) return id2;
         //}
         id3 = ntk->createNet(ntk->getNetWidth(id1)); if (V3NetUD == id3) return id3;
         if (!createBvPairGate(ntk, v3Type, id3, id1, id2)) return V3NetUD; id1 = id3;
      }
      if (invert) {
         id3 = ntk->createNet(1); if (V3NetUD == id3) return id3;
         if (!createV3BufGate(ntk, id3, ~id1)) return V3NetUD; id1 = id3;
      }
      // Reset Bit-Width for Internal Output Signal
      if (quteIsInternalName(name)) ntk->resetNetWidth(id, ntk->getNetWidth(id1));
      // Matching Output and Input Bit-widths
      if (ntk->getNetWidth(id) == ntk->getNetWidth(id1)) {
         if (!createV3BufGate(ntk, id, id1)) return V3NetUD; }
      else {
         id2 = ntk->createNet(ntk->getNetWidth(id1)); if (V3NetUD == id2) return id2;
         if (!createV3BufGate(ntk, id2, id1)) return V3NetUD;
         if (!createIOExtensionGate(ntk, id, id2)) return V3NetUD;
      }
   }
   // Return V3NetId for OutPin
   return id;
}
Example #8
0
const string
V3NtkHandler::getNetRecurExpression(const V3NetId& id) const {
   assert (_ntk); assert (id.id < _ntk->getNetSize()); string name = "";
   const V3GateType& type = _ntk->getGateType(id); assert (V3_XD > type);
   if (V3_FF >= type) return (id.cp ? V3AuxNameInvPrefix : "") + v3Int2Str(id.id);
   else if (V3_MODULE == type) {
      Msg(MSG_WAR) << "Currently Expression Over Module Instances has NOT Been Implemented !!" << endl;
   }
   else {
      if (dynamic_cast<V3BvNtk*>(_ntk)) {
         assert (AIG_FALSE < type);
         if (isV3PairType(type)) {
            const string name1 = getNetExpression(_ntk->getInputNetId(id, 0)); assert (name1.size());
            const string name2 = getNetExpression(_ntk->getInputNetId(id, 1)); assert (name2.size());
            if (BV_MERGE == type) name = "{" + name1 + ", " + name2 + "}";
            else {
               switch (type) {
                  case BV_AND      : name = "(" + name1 + " & "  + name2 + ")"; break;
                  case BV_XOR      : name = "(" + name1 + " ^ "  + name2 + ")"; break;
                  case BV_ADD      : name = "(" + name1 + " + "  + name2 + ")"; break;
                  case BV_SUB      : name = "(" + name1 + " - "  + name2 + ")"; break;
                  case BV_MULT     : name = "(" + name1 + " * "  + name2 + ")"; break;
                  case BV_SHL      : name = "(" + name1 + " << " + name2 + ")"; break;
                  case BV_SHR      : name = "(" + name1 + " >> " + name2 + ")"; break;
                  case BV_DIV      : name = "(" + name1 + " / "  + name2 + ")"; break;
                  case BV_MODULO   : name = "(" + name1 + " % "  + name2 + ")"; break;
                  case BV_EQUALITY : return "(" + name1 + (id.cp ? " != " : " == ") + name2 + ")";
                  case BV_GEQ      : return "(" + name1 + (id.cp ? " < "  : " >= ") + name2 + ")";
                  default          : assert (0);
               }
            }
         }
         else if (isV3ReducedType(type)) {
            const string name1 = getNetExpression(_ntk->getInputNetId(id, 0)); assert (name1.size());
            switch (type) {
               case BV_RED_AND : name = "(&(" + name1 + "))"; break;
               case BV_RED_OR  : name = "(|(" + name1 + "))"; break;
               case BV_RED_XOR : name = "(^(" + name1 + "))"; break;
               default         : assert (0);
            }
         }
         else if (BV_MUX == type) {
            const string fName = getNetExpression(_ntk->getInputNetId(id, 0)); assert (fName.size());
            const string tName = getNetExpression(_ntk->getInputNetId(id, 1)); assert (tName.size());
            const string sName = getNetExpression(_ntk->getInputNetId(id, 2)); assert (sName.size());
            name = "(" + sName + " ? " + tName + " : " + fName + ")";
         }
         else if (BV_SLICE == type) {
            const string name1 = getNetExpression(_ntk->getInputNetId(id, 0)); assert (name1.size());
            const uint32_t msb = dynamic_cast<V3BvNtk*>(_ntk)->getInputSliceBit(id, true);
            const uint32_t lsb = dynamic_cast<V3BvNtk*>(_ntk)->getInputSliceBit(id, false);
            const uint32_t width = _ntk->getNetWidth(_ntk->getInputNetId(id, 0)); assert (width);
            name = ((msb >= lsb) && (width == (1 + msb - lsb))) ? name1 : 
                   (msb == lsb) ? ("(" + name1 + ")[" + v3Int2Str(msb) + "]") : 
                   ("(" + name1 + ")[" + v3Int2Str(msb) + ":" + v3Int2Str(lsb) + "]");
         }
         else {
            assert (BV_CONST == type);
            const V3BitVecX value = dynamic_cast<V3BvNtk*>(_ntk)->getInputConstValue(id);
            return v3Int2Str(value.size()) + "'b" + value.regEx();
         }
      }
      else {
         assert (AIG_FALSE >= type);
         if (AIG_NODE == type) {
            const string name1 = getNetExpression(_ntk->getInputNetId(id, 0)); assert (name1.size());
            const string name2 = getNetExpression(_ntk->getInputNetId(id, 1)); assert (name2.size());
            name = "(" + name1 + " && " + name2 + ")";
         }
         else {
            assert (AIG_FALSE == type);
            return (id.cp ? "AIGER_TRUE" : "AIGER_FALSE");
         }
      }
   }
   return (id.cp ? V3AuxNameInvPrefix : "") + name;
}