void CircuitBuilder::build(Design * const design, const size_t &f) { delete cir_; cir_ = new Circuit; cir_->setFrame(f); cir_->setOccRoot(design->getOcc()); cir_->setModRoot(design->getTop()); map<string,Gate*> FFMap; // flip-flop map, used to connecte PPI & PPO // create PI // ignore CK, test_si, and test_so for (size_t i = 0; i < design->getTop()->nModTerms(); ++i) { ModTerm *term = design->getTop()->getModTerm(i); if (term->getType() != ModTerm::INPUT || strcmp(term->getName(),"test_si") == 0 || strcmp(term->getName(),"test_se") == 0 || strcmp(term->getName(),"CK") == 0 ) continue; Gate *g = new PiGate; g->setOcc(design->getOcc()); cir_->addPi(g); } // create PPI for (size_t i = 0; i < design->getOcc()->nChildren(); ++i) { Occ *occ = design->getOcc()->getChild(i); string modName(occ->getModInst()->getModName()); if (modName.size() < 4 || modName.substr(0,4) != "SDFF") continue; Gate *g = new PpiGate; g->setOcc(occ); cir_->addPpi(g); cir_->setOccToGate(occ, g); FFMap[occ->getModInst()->getName()] = g; } // create combinational gates for (size_t i = 0; i < design->getOcc()->nChildren(); ++i) { Occ *occ = design->getOcc()->getChild(i); string modName(occ->getModInst()->getModName()); if (modName.size() > 3 && modName.substr(0,4) == "SDFF") continue; Gate *g = createGate(occ); g->setOcc(occ); cir_->addComb(g); cir_->setOccToGate(occ, g); } // create PO for (size_t i = 0; i < design->getTop()->nModTerms(); ++i) { ModTerm *term = design->getTop()->getModTerm(i); if (term->getType() != ModTerm::OUTPUT) continue; Gate *g = new PoGate; g->setOcc(design->getOcc()); cir_->addPo(g); } // create PPO for (size_t i = 0; i < design->getOcc()->nChildren(); ++i) { Occ *occ = design->getOcc()->getChild(i); string modName(occ->getModInst()->getModName()); if (modName.size() < 4 || modName.substr(0,4) != "SDFF") continue; Gate *g = new PpoGate; g->setOcc(occ); cir_->addPpo(g); FFMap[occ->getModInst()->getName()]->addFi(g); } // connect gates for (size_t i = cir_->nPis() + cir_->nSeqs(); i < cir_->nGates(); ++i) { Gate *g = cir_->getGate(i); Occ *occ = g->getOcc(); size_t nTerm = 0; if (g->getType() == Gate::PO || g->getType() == Gate::PPO) nTerm = 1; else nTerm = occ->getModInst()->nModInstTerms() - 1; for (size_t j = 0; j < nTerm; ++j) { ModTerm *term = NULL; ModInstTerm *instTerm = NULL; ModNet *net = NULL; if (g->getType() == Gate::PO) { // because we ignore 3 inputs(CK,test_si,test_so) // we have to add 3 in idx to match id in ModTerm size_t id = i - cir_->nCombs() - cir_->nSeqs() + 3; term = design->getTop()->getModTerm(id); net = term->getModNet(); } else if (g->getType() == Gate::PPO) { instTerm = occ->getModInst()->getModInstTerm("D"); net = instTerm->getModNet(); } else { instTerm = occ->getModInst()->getModInstTerm(j); net = instTerm->getModNet(); } // find fanin Gate *fi = NULL; for (size_t k = 0; k < net->nModTerms(); ++k) { if (net->getModTerm(k) == term || net->getModTerm(k)->getType() == ModTerm::OUTPUT) continue; // because we ignore 3 inputs(CK,test_si,test_so) // we have to minus 3 in idx to match id in ModTerm size_t id = net->getModTerm(k)->getPos()-3; fi = cir_->getGate(id); break; } if (!fi) { for (size_t k = 0; k < net->nModInstTerms(); ++k) { ModInst *inst = net->getModInstTerm(k)->getModInst(); if (net->getModInstTerm(k) == instTerm || inst->getModule()->getModTerm(net->getModInstTerm(k)->getName())->getType() == ModTerm::INPUT) continue; const char *name = net->getModInstTerm(k)->getModInst()->getName(); fi = cir_->getGate(design->getOcc()->getChild(name)); break; } } // connect gates g->addFi(fi); fi->addFo(g); } } levelize(); setTimeFrame(f); }