void CircuitBuilder::levelize() { bool processed[cir_->nGates()]; bool levelized[cir_->nGates()]; memset(processed, false, sizeof(bool) * cir_->nGates()); memset(levelized, false, sizeof(bool) * cir_->nGates()); for (size_t i = 0; i < cir_->nGates(); ++i) cir_->getGate(i)->setId(i); queue<Gate *> que; for (size_t i = 0; i < cir_->nPis() + cir_->nSeqs(); ++i) que.push(cir_->getGate(i)); while (!que.empty()) { Gate *g = que.front(); que.pop(); int maxlvl = -1; bool ready = true; // determine level only if all fanins are levelized // 1. PPI is set to level zero // 2. PPI has input PPO // 3. Skip PPI directly if(g->getType() != Gate::PPI){ for (size_t i = 0; i < g->nFis(); ++i) { Gate *fi = g->getFi(i); if (!levelized[fi->getId()]) { ready = false; break; } if (fi->getLvl() > maxlvl) maxlvl = fi->getLvl(); } } // put back to queue if not ready if (!ready) { que.push(g); continue; } // set level g->setLvl(maxlvl + 1); levelized[g->getId()] = true; // determine circuit level if ((g->getType() == Gate::PO || g->getType() == Gate::PPO) && g->getLvl() > cir_->getLvl()) cir_->setLvl(g->getLvl()); // put fanouts into queue for (size_t i = 0; i < g->nFos(); ++i) { Gate *fo = g->getFo(i); if (processed[fo->getId()]) continue; processed[fo->getId()] = true; que.push(fo); } } // set all POs to highest level for (size_t i = 0; i < cir_->nPos(); ++i) cir_->getPo(i)->setLvl(cir_->getLvl()); for (size_t i = 0; i < cir_->nSeqs(); ++i) cir_->getPpo(i)->setLvl(cir_->getLvl()); cir_->setLvl(cir_->getLvl() + 1); // sort gates by their level stable_sort(cir_->getGates()->begin() , cir_->getGates()->end() , cmpGateLvl); // set gate id for (size_t i = 0; i < cir_->nGates(); ++i) cir_->getGate(i)->setId(i); }