34 std::vector<std::string> &siteTypesToLegalize, std::map<std::string, std::string> &JSONCfg)
35 : legalizerName(legalizerName), placementInfo(placementInfo), deviceInfo(deviceInfo),
36 compatiblePlacementTable(placementInfo->getCompatiblePlacementTable()), siteTypesToLegalize(siteTypesToLegalize),
37 cellLoc(placementInfo->getCellId2location()), JSONCfg(JSONCfg)
47 if (curSiteType ==
"SLICEM")
51 if (curSiteType ==
"SLICEL")
98 if (exactLegalization)
101 print_status(
"CLBLegalizer Started Fixed-Column Legalization.");
175 float tmpAverageDisplacement = 0.0;
181 print_info(
"CLBLegalizer Macro Cell Average Final Legalization Displacement = " +
188 std::vector<std::deque<PlacementInfo::PlacementUnit *>> &Column2PUs)
201 float tmpTotalDisplacement = 0.0;
202 std::map<PlacementInfo::PlacementUnit *, std::vector<DeviceInfo::DeviceSite *>>
PU2Sites;
204 for (
auto &PUDeque : Column2PUs)
206 for (
auto tmpPU : PUDeque)
209 PU2Sites[tmpPU] = std::vector<DeviceInfo::DeviceSite *>();
213 #pragma omp parallel for
214 for (
int c = 0;
c < colNum;
c++)
216 int numPUs = Column2PUs[
c].size();
220 auto &curColSites = Column2Sites[
c];
221 auto &curColPU = Column2PUs[
c];
227 std::vector<std::vector<float>> f(numPUs, std::vector<float>(curColSites.size(), 1000000000.0));
228 std::vector<std::vector<bool>> fChoice(
229 numPUs, std::vector<bool>(curColSites.size(), 0));
231 int minLastPUTop = -1;
233 int totalMacroCellNum = 0;
235 totalMacroCellNum += heightPURow;
236 float minHPWLChange = 1100000000.0;
237 for (
unsigned int j = heightPURow - 1; j < curColSites.size(); j++)
239 float curHPWLChange =
getHPWLChange(curColPU[0], curColSites[j - heightPURow + 1]);
240 if (curColSites[j]->getSiteY() - curColSites[j - heightPURow + 1]->getSiteY() != heightPURow - 1)
243 curHPWLChange = 1100000000.0;
245 if (curHPWLChange < minHPWLChange)
247 minHPWLChange = curHPWLChange;
254 f[0][j] = minHPWLChange;
258 for (
int i = 1;
i < numPUs;
i++)
260 float minVal = 100000000.0;
262 totalMacroCellNum += heightPURow;
263 for (
unsigned int j = totalMacroCellNum - 1; j < curColSites.size();
266 float curHPWLChange =
getHPWLChange(curColPU[
i], curColSites[j - heightPURow + 1]);
267 if (curColSites[j]->getSiteY() - curColSites[j - heightPURow + 1]->getSiteY() != heightPURow - 1)
270 curHPWLChange = 1100000000.0;
272 if (f[
i][j - 1] > f[
i - 1][j - heightPURow] + curHPWLChange)
277 if (f[
i - 1][j - heightPURow] + curHPWLChange < minVal)
279 minVal = f[
i - 1][j - heightPURow] + curHPWLChange;
285 f[
i][j] = std::min(f[
i][j - 1], f[
i - 1][j - heightPURow] + curHPWLChange);
289 assert(minLastPUTop >= 0);
291 std::vector<DeviceInfo::DeviceSite *> PUBottom2Site_reverse(0);
293 for (
int i = numPUs - 1;
i >= 0;
i--)
295 assert(minLastPUTop >= 0);
297 while (!fChoice[
i][minLastPUTop])
300 assert(minLastPUTop >= 0);
302 auto curSite = curColSites[minLastPUTop - heightPURow + 1];
303 assert(
PU2Sites[curColPU[
i]].size() == 0);
305 PU2Sites[curColPU[
i]].push_back(curSite);
306 minLastPUTop -= heightPURow;
315 for (
auto &PUDeque : Column2PUs)
317 for (
auto tmpPU : PUDeque)
322 assert(
PU2X.find(tmpPU) ==
PU2X.end());
323 PU2X[tmpPU] = curSite->X();
324 PU2Y[tmpPU] = curSite->Y();
327 tmpTotalDisplacement += std::fabs(tmpPU->X() - curSite->X()) + std::fabs(tmpPU->Y() - curSite->Y());
333 return tmpTotalDisplacement;
344 if (!curPU->isLocked())
379 siteType2Sites[siteTypeToLegalize] = std::vector<DeviceInfo::DeviceSite *>(0);
381 for (
auto curSite : sitesInType)
383 if (!curSite->isOccupied() && !curSite->isMapped())
387 assert(!curSite->isMapped());
392 if (siteTypeToLegalize ==
"SLICEL")
396 std::string tmpSiteType =
"SLICEM";
398 for (
auto curSite : sitesInType)
400 if (!curSite->isOccupied() && !curSite->isMapped())
413 if (curSiteType ==
"SLICEM")
423 if (curSiteType ==
"SLICEL")
478 PU2Sites[curPU] = std::vector<DeviceInfo::DeviceSite *>(0);
483 #pragma omp parallel for
484 for (
int i = 0;
i < numPUs;
i++)
487 std::string curSiteType =
"";
489 curSiteType =
"SLICEL";
490 else if (curPU->isMCLB())
491 curSiteType =
"SLICEM";
493 assert(
false &&
"should be LogicCLB or RAMCLB");
496 std::vector<DeviceInfo::DeviceSite *> *candidateSite =
nullptr;
499 int targetSiteX = -1;
500 std::vector<std::vector<DeviceInfo::DeviceSite *>> *column2Sites;
513 assert(targetSiteX >= 0 &&
"undefine type");
515 for (
auto &tmpCol : *column2Sites)
517 if (tmpCol.size() == 0)
519 if (tmpCol[0]->getSiteX() == targetSiteX)
521 candidateSite = &tmpCol;
530 assert(candidateSite);
532 for (
auto curSite : *candidateSite)
562 float minCost = 10000000;
564 for (
unsigned int leftCellId = 0; leftCellId <
PUsToLegalize.size(); leftCellId++)
568 for (
auto curSite :
PU2Sites[curPU])
578 if (tmpCost < minCost)
587 if (minCost < 0.0001)
589 float compensation = 10 - minCost;
590 for (
unsigned int leftCellId = 0; leftCellId <
PUsToLegalize.size(); leftCellId++)
592 for (
unsigned int tmpId = 0; tmpId <
adjList[leftCellId].size(); tmpId++)
594 adjList[leftCellId][tmpId].second += compensation;
602 for (
unsigned int leftCellId = 0; leftCellId <
PUsToLegalize.size(); leftCellId++)
615 std::vector<PlacementInfo::PlacementUnit *> newPUsToLegalize;
616 newPUsToLegalize.clear();
617 for (
unsigned int leftCellId = 0; leftCellId <
PUsToLegalize.size(); leftCellId++)
622 newPUsToLegalize.push_back(curPU);
630 if (
JSONCfg.find(
"DumpCLBLegalization") !=
JSONCfg.end() || enforce)
632 std::string dumpFile =
"";
639 print_status(
"CLBLegalizer: dumping CLBLegalization archieve to: " + dumpFile);
643 std::stringstream outfile0;
646 auto matchedSite = matchedPair.second;
647 auto curPU = matchedPair.first;
648 outfile0 <<
"name: " << curPU->getName() <<
" locX:" << curPU->X() <<
" locY:" << curPU->Y() <<
"\n";
649 outfile0 <<
" macthed with: " << matchedSite->getName() <<
" locX:" << matchedSite->X()
650 <<
"\n locY:" << matchedSite->Y()
652 <<
"\n HPWLIncrease:" <<
getHPWLChange(curPU, matchedSite) <<
"\n";
660 for (
int j = 0; j < numPUs; j++)
663 outfile0 <<
"MCLB col#" <<
i <<
": " << PU->getName() <<
" PUY:" <<
PU2Y[PU]
664 <<
" numPUs:" <<
getPUSiteNum(PU) <<
" netNum:" << PU->getNetsSetPtr()->size() <<
"\n";
670 for (
int j = 0; j < numPUs; j++)
673 outfile0 <<
"LCLB col#" <<
i <<
": " << PU->getName() <<
" PUY:" <<
PU2Y[PU]
674 <<
" numPUs:" <<
getPUSiteNum(PU) <<
" netNum:" << PU->getNetsSetPtr()->size() <<
"\n";
680 print_status(
"CLBLegalizer: dumped CLBLegalization archieve to: " + dumpFile);
692 int numPUs = PUs.size();
693 for (
int i = 0;
i < numPUs;
i++)
694 for (
int j =
i + 1; j < numPUs; j++)
701 int numSites =
sites.size();
703 for (
int i = 1;
i < numSites;
i++)
713 for (
int i = 0;
i < numSites;
i++)
714 for (
int j =
i + 1; j < numSites; j++)
738 float tmpAverageDisplacement = 0.0;
742 auto matchedSite = matchedPair.second;
743 auto curPU = matchedPair.first;
763 actualPUX = matchedSite->X();
764 actualPUY = matchedSite->Y();
766 tmpAverageDisplacement += std::fabs(curPU->X() - matchedSite->X()) + std::fabs(curPU->Y() - matchedSite->Y());
767 assert(isRoughLegalization ||
PU2SiteX[curPU] == -1 ||
PU2SiteX[curPU] == matchedSite->getSiteX());
768 PU2SiteX[curPU] = matchedSite->getSiteX();
769 PU2X[curPU] += actualPUX;
770 PU2Y[curPU] += actualPUY;
775 PU2Columns[curPU].push_back(matchedSite->getSiteX());
781 print_info(
"CLBLegalizer Macro Cell Average Displacement = " + std::to_string(tmpAverageDisplacement));
783 if (updateDisplacement)
785 if (isRoughLegalization)
791 for (
auto pairPU2X :
PU2X)
794 assert(numCells == 1);
795 PU2X[pairPU2X.first] /= numCells;
796 PU2Y[pairPU2X.first] /= numCells;
799 #pragma omp parallel for
803 #pragma omp parallel for
811 std::vector<std::vector<DeviceInfo::DeviceSite *>> &column2Sites,
812 std::vector<std::deque<PlacementInfo::PlacementUnit *>> &column2PUs,
813 std::map<PlacementInfo::PlacementUnit *, int> &cell2Column)
817 int overflowColId = -1;
818 std::vector<int> accumulationUtil(columnNum, 0), accumulationCapacity(columnNum, 0);
819 accumulationUtil[0] = columnUntilization[0];
820 accumulationCapacity[0] = column2Sites[0].size();
821 for (
int colId = 1; colId < columnNum; colId++)
823 accumulationUtil[colId] = accumulationUtil[colId - 1] + columnUntilization[colId];
824 accumulationCapacity[colId] = accumulationCapacity[colId - 1] + column2Sites[colId].size();
827 for (
int colId = 0; colId < columnNum; colId++)
829 if (column2Sites[colId].size() < (
unsigned int)columnUntilization[colId])
831 overflowColId = colId;
835 if (overflowColId < 0)
841 int leftAvaliableCapacity = 0;
842 int rightAvaliableCapacity = 0;
846 if (overflowColId > 0)
848 leftAvaliableCapacity += accumulationCapacity[overflowColId - 1];
849 leftUtil += accumulationUtil[overflowColId - 1];
851 if (overflowColId < columnNum - 1)
853 rightAvaliableCapacity += accumulationCapacity[columnNum - 1] - accumulationCapacity[overflowColId];
854 rightUtil += accumulationUtil[columnNum - 1] - accumulationUtil[overflowColId];
857 int overflowNum = (
unsigned int)columnUntilization[overflowColId] - column2Sites[overflowColId].size();
860 int totalAvailableCapacity = rightAvaliableCapacity + leftAvaliableCapacity - leftUtil - rightUtil;
861 assert(totalAvailableCapacity > 0);
862 float toLeftRatio = (float)(leftAvaliableCapacity - leftUtil) / totalAvailableCapacity;
863 int toLeftNum = int((overflowNum * toLeftRatio) + 0.4999);
864 int toRightNum = overflowNum - toLeft;
866 if (leftAvaliableCapacity - leftUtil > 0)
868 while (toLeftNum > 0 && column2PUs[overflowColId].size() > 0)
870 column2PUs[overflowColId - 1].push_back(column2PUs[overflowColId][0]);
871 int macroSize =
getPUSiteNum(column2PUs[overflowColId][0]);
872 columnUntilization[overflowColId - 1] += macroSize;
873 columnUntilization[overflowColId] -= macroSize;
874 toLeftNum -= macroSize;
875 column2PUs[overflowColId].pop_front();
878 if (rightAvaliableCapacity - rightUtil > 0)
880 while (toRightNum > 0 && column2PUs[overflowColId].size() > 0)
882 column2PUs[overflowColId + 1].push_front(
883 column2PUs[overflowColId][column2PUs[overflowColId].size() - 1]);
884 int macroSize =
getPUSiteNum(column2PUs[overflowColId][column2PUs[overflowColId].size() - 1]);
885 columnUntilization[overflowColId + 1] += macroSize;
886 columnUntilization[overflowColId] -= macroSize;
887 toRightNum -= macroSize;
888 column2PUs[overflowColId].pop_back();
894 for (
unsigned int colId = 0; colId < column2PUs.size(); colId++)
896 auto PUs = column2PUs[colId];
897 for (
auto curPU : PUs)
899 cell2Column[curPU] = colId;
919 int maxRecurence = 0;
920 assert(ids.size() > 0);
921 for (
int i = minId;
i <= maxId;
i++)
929 if (
cnt > maxRecurence)
953 auto tmpMacroUnit = PUCol_pair.first;
976 auto tmpMacroUnit = PUCol_pair.first;
993 auto targetPU = matchedPair.first;
996 assert(!curSite->isMapped());
997 curSite->setMapped();
1007 auto targetPU = matchedPair.first;
1010 assert(curSite->isMapped());
1011 curSite->resetMapped();