31 std::map<PlacementInfo::PlacementUnit *, std::vector<DeviceInfo::DeviceSite *>> &PULegalSite =
35 assert(PULegalSite.find(tmpMacro) != PULegalSite.end());
36 std::vector<DeviceInfo::DeviceSite *> &legalSites = PULegalSite[tmpMacro];
37 for (
unsigned int i = 0;
i < legalSites.size();
i++)
46 assert(PULegalSite.find(tmpMacro) != PULegalSite.end());
47 std::vector<DeviceInfo::DeviceSite *> &legalSites = PULegalSite[tmpMacro];
48 for (
unsigned int i = 0;
i < legalSites.size();
i++)
58 std::map<std::string, std::string> &JSONCfg,
int unchangedIterationThr,
59 int numNeighbor,
float deltaD,
float curD,
float maxD,
int PQSize,
60 float HPWLWeight, std::string packerName,
62 : designInfo(designInfo), deviceInfo(deviceInfo), placementInfo(placementInfo), JSONCfg(JSONCfg),
63 unchangedIterationThr(unchangedIterationThr), numNeighbor(numNeighbor), deltaD(deltaD), curD(curD), maxD(maxD),
64 PQSize(PQSize), HPWLWeight(HPWLWeight), packerName(packerName), timingOptimizer(timingOptimizer),
65 WLOptimizer(WLOptimizer), PUId2PackingCLBSite(placementInfo->getPlacementUnits().size(), nullptr),
66 PUId2PackingCLBSiteCandidate(placementInfo->getPlacementUnits().size(), nullptr),
67 placementUnits(placementInfo->getPlacementUnits()),
68 placementUnpackedCells(placementInfo->getPlacementUnpackedCells()),
69 placementMacros(placementInfo->getPlacementMacros()), cellInMacros(placementInfo->getCellInMacros()),
70 cellId2PlacementUnit(placementInfo->getCellId2PlacementUnit())
82 std::vector<std::vector<PackingCLBSite *>>(numClockCols, std::vector<PackingCLBSite *>());
84 std::string targetSiteType =
"SLICEL";
88 if (curSite->isOccupied())
97 targetSiteType =
"SLICEM";
100 if (curSite->isOccupied())
115 print_status(
"ParallelCLBPacker: CARRY macros are mapped to sites.");
118 for (
int i = 0;
i < numPackingSites;
i++)
121 if (tmpPackingSite->getDeterminedClusterInSite())
123 assert(tmpPackingSite->checkIsPrePackedSite());
132 #pragma omp parallel for schedule(dynamic, 16)
133 for (
int i = 0;
i < numClockCols;
i++)
138 tmpPackingSite->updateStep(initial, debug);
158 if (packingSite->getDeterminedClusterInSite())
160 for (
auto tmpPU : packingSite->getDeterminedClusterInSite()->getPUs())
179 if (tmpPackingSite->hasValidPQTop())
182 for (
auto tmpPU : tmpTop->
getPUs())
224 float oriDeltaScore =
227 float newDeltaScore =
228 tmpPackingSite->getPriorityQueueTop()->getScoreInSite() - tmpPackingSite->getDetScore();
229 if (newDeltaScore > oriDeltaScore)
294 std::ofstream debugFile;
295 debugFile.open(
"OpenPitonSLICE_SLICE_X38Y213");
299 print_status(
"ParallelCLBPacker: initial packCLBsIteration done.");
302 bool noValidPQTop =
true;
305 if (tmpPackingSite->hasValidPQTop())
307 noValidPQTop =
false;
322 print_status(
"ParallelCLBPacker: iter#" + std::to_string(iterCnt) +
323 " #Mapped PU=" + std::to_string(mappedPUCnt));
325 int deteminedCnt = 0;
326 std::map<int, int> sliceSize2SliceCnt;
327 sliceSize2SliceCnt.clear();
332 if (packingSite->getDeterminedClusterInSite())
334 if (packingSite->getDeterminedClusterInSite()->getPUs().size())
338 for (
auto tmpPU : packingSite->getDeterminedClusterInSite()->getPUs())
344 tmpSize += tmpPU->getWeight();
345 assert((
unsigned int)tmpPU->getWeight() >= curMacro->getCells().size());
353 if (sliceSize2SliceCnt.find(tmpSize) == sliceSize2SliceCnt.end())
355 sliceSize2SliceCnt[tmpSize] = 1;
359 sliceSize2SliceCnt[tmpSize]++;
372 if (fixedRatio > 0.25 &&
WLOptimizer && iterCnt < 32)
378 print_status(
"ParallelCLBPacker: Move unfixed elements with WLOptimizer");
385 print_status(
"ParallelCLBPacker: iter#" + std::to_string(iterCnt) +
386 " #determined Slice=" + std::to_string(deteminedCnt));
388 std::string distibution =
"";
389 for (
auto tmpPair : sliceSize2SliceCnt)
391 distibution += (
"(" + std::to_string(tmpPair.first) +
"," + std::to_string(tmpPair.second) +
"), ");
393 print_status(
"ParallelCLBPacker: iter#" + std::to_string(iterCnt) +
" Distribution: " + distibution);
395 if (iterCnt > packIterNum)
410 if (packingSite->getDeterminedClusterInSite())
412 assert(packingSite->getDeterminedClusterInSite()->areAllPUsValidForThisSite(
PUId2PackingCLBSite,
419 print_status(
"ParallelCLBPacker: finish iterative packing");
420 if (doExceptionHandling)
430 int replaceCnt = 1000;
433 for (
int i = 0; (i < 120 || replaceCnt > 60) &&
i < 150;
i++)
442 if (packingSite->getDeterminedClusterInSite())
444 auto cellSet = packingSite->getDeterminedClusterInSite()->getCellSet();
445 for (
auto cell : cellSet)
452 else if (packingSite->checkIsNonCLBSite())
471 for (
int i = 0; i < 40 && replaceCnt > 5;
i++)
480 if (packingSite->getDeterminedClusterInSite())
482 auto cellSet = packingSite->getDeterminedClusterInSite()->getCellSet();
483 for (
auto cell : cellSet)
490 else if (packingSite->checkIsNonCLBSite())
503 #pragma omp parallel for schedule(dynamic)
504 for (
int i = 0;
i < packNum;
i++)
516 if (packingSite->getDeterminedClusterInSite())
518 assert(packingSite->getDeterminedClusterInSite()->checkCellCorrectness(
nullptr,
true));
525 inline float getAngle(
float v1x,
float v1y,
float v2x,
float v2y)
527 float angle = atan2(v2y, v2x) - atan2(v1y, v1x);
532 else if (angle <= -M_PI)
541 print_status(
"ParallelCLBPacker: conducting timing-driven detailed placement based on shortest path.");
543 std::set<PlacementInfo::PlacementUnit *> PUsTouched;
545 std::ofstream outfileTcl(
"./DetailedPlacementRecord");
547 for (
auto oriCellIdsInCriticalPath : oriCellIdsInCriticalPaths)
549 std::map<int, std::vector<PackingCLBSite *>> cellId2CandidateSites;
550 std::set<PackingCLBSite *> sitesCandidates;
551 std::map<PackingCLBSite *, PackingCLBSite::PackingCLBCluster *> site2TrialCluster;
552 cellId2CandidateSites.clear();
554 std::vector<int> cellIdsInCriticalPath;
556 std::set<PlacementInfo::PlacementUnit *> PUsInCriticalPathSet;
557 for (
auto cellId : oriCellIdsInCriticalPath)
560 PUsInCriticalPathSet.end())
563 cellIdsInCriticalPath.push_back(cellId);
569 bool CellUnmapped =
false;
570 for (
auto cellId : cellIdsInCriticalPath)
581 assert(curPackingSite);
582 cellId2CandidateSites[cellId] = std::vector<PackingCLBSite *>(1, curPackingSite);
583 sitesCandidates.insert(curPackingSite);
584 if (!curPackingSite->checkIsNonCLBSite())
585 site2TrialCluster[curPackingSite] =
592 for (
int siteCandidateLimit = 1; siteCandidateLimit <= 10; siteCandidateLimit++)
594 float displacementThr = 5.0 * displacementRatio;
595 if (displacementThr < 1)
597 for (
int orderI = cellIdsInCriticalPath.size() - 1; orderI >= 0; orderI--)
599 auto cellId = cellIdsInCriticalPath[orderI];
601 if (PUsTouched.find(curPU) != PUsTouched.end())
607 if (!curPU->isLocked() && !curPU->checkHasCARRY() && !curPU->checkHasLUTRAM() &&
608 !curPU->checkHasBRAM() && !curPU->checkHasDSP())
610 float v1x = 0, v1y = 0, v2x = 0, v2y = 0;
611 if (orderI > 0 && orderI < cellIdsInCriticalPath.size() - 1)
614 int predSiteOrderId = orderI - 1;
617 int succSiteOrderId = orderI + 1;
618 assert(predSite && curSite && succSite);
629 v1x = predSite->getCLBSite()->X() - curSite->getCLBSite()->X();
630 v1y = predSite->getCLBSite()->Y() - curSite->getCLBSite()->Y();
631 v2x = succSite->getCLBSite()->X() - curSite->getCLBSite()->X();
632 v2y = succSite->getCLBSite()->Y() - curSite->getCLBSite()->Y();
634 else if (orderI == 0)
638 assert(curSite && succSite);
639 int succSiteOrderId = orderI + 1;
640 while (curSite == succSite && succSiteOrderId + 1 <= cellIdsInCriticalPath.size() - 1)
645 v1x = v2x = succSite->getCLBSite()->X() - curSite->getCLBSite()->X();
646 v1y = v2y = succSite->getCLBSite()->Y() - curSite->getCLBSite()->Y();
652 assert(predSite && curSite);
653 int predSiteOrderId = orderI - 1;
654 while (curSite == predSite && predSiteOrderId - 1 >= 0)
659 v1x = v2x = predSite->getCLBSite()->X() - curSite->getCLBSite()->X();
660 v1y = v2y = predSite->getCLBSite()->Y() - curSite->getCLBSite()->Y();
662 if (std::fabs(v1x) + std::fabs(v1y) + std::fabs(v2x) + std::fabs(v2y) < 0.1)
664 if (std::fabs(
getAngle(v1x, v1y, v2x, v2y)) < M_PI / 2)
670 v1x, v1y, v2x, v2y, 20);
672 for (
auto curDeviceSite : *candidateSitesToPlaceTheCell_cone)
677 if (cellId2CandidateSites[cellId].size() >= siteCandidateLimit)
679 bool duplicate =
false;
680 for (
auto existCandidate : cellId2CandidateSites[cellId])
682 if (existCandidate == candidatePackingSite)
688 if (sitesCandidates.find(candidatePackingSite) == sitesCandidates.end())
692 auto determinedClusterInSite =
698 site2TrialCluster[candidatePackingSite] = trialCluster;
702 trialCluster = site2TrialCluster[candidatePackingSite];
707 assert(trialCluster->
addPU(curPU));
708 cellId2CandidateSites[cellId].push_back(candidatePackingSite);
709 sitesCandidates.insert(candidatePackingSite);
715 delete candidateSitesToPlaceTheCell_cone;
720 for (
int orderI = cellIdsInCriticalPath.size() - 1; orderI >= 0; orderI--)
722 auto cellId = cellIdsInCriticalPath[orderI];
725 if (PUsTouched.find(curPU) != PUsTouched.end())
730 if (!curPU->isLocked() && !curPU->checkHasCARRY() && !curPU->checkHasLUTRAM() &&
731 !curPU->checkHasBRAM() && !curPU->checkHasDSP())
737 if (cellId2CandidateSites[cellId].size() >= siteCandidateLimit + 1)
741 for (
auto curDeviceSite : *candidateSitesToPlaceTheCell)
746 bool duplicate =
false;
747 for (
auto existCandidate : cellId2CandidateSites[cellId])
749 if (existCandidate == candidatePackingSite)
755 if (sitesCandidates.find(candidatePackingSite) == sitesCandidates.end())
759 auto determinedClusterInSite =
765 site2TrialCluster[candidatePackingSite] = trialCluster;
769 trialCluster = site2TrialCluster[candidatePackingSite];
774 assert(trialCluster->
addPU(curPU));
775 cellId2CandidateSites[cellId].push_back(candidatePackingSite);
776 sitesCandidates.insert(candidatePackingSite);
780 delete candidateSitesToPlaceTheCell;
791 std::vector<std::vector<float>> shortestPath_LayerSite;
792 std::vector<std::vector<int>> shortestPath_LayerSite_backtrace;
793 shortestPath_LayerSite.push_back(
794 std::vector<float>(cellId2CandidateSites[cellIdsInCriticalPath[0]].size(), 0.0));
795 shortestPath_LayerSite_backtrace.push_back(
796 std::vector<int>(cellId2CandidateSites[cellIdsInCriticalPath[0]].size(), -1));
800 outfileTcl <<
"<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>\nCellsCandidate:\n";
801 for (
int i = 0;
i < cellIdsInCriticalPath.size();
i++)
803 auto curCellId = cellIdsInCriticalPath[
i];
805 auto &curCandidates = cellId2CandidateSites[curCellId];
806 outfileTcl <<
"cell: " << curCell <<
"\n";
807 for (
int k = 0; k < curCandidates.size(); k++)
809 outfileTcl <<
" " << cellId2CandidateSites[curCellId][k]->getCLBSite()->getName() <<
"\n";
814 int bestEndChoice = -1;
815 float bestChoiceDelay = 100000;
816 for (
int i = 1;
i < cellIdsInCriticalPath.size();
i++)
818 auto predCell = cellIdsInCriticalPath[
i - 1];
819 auto curCell = cellIdsInCriticalPath[
i];
820 auto &predCandidates = cellId2CandidateSites[predCell];
821 auto &curCandidates = cellId2CandidateSites[curCell];
822 shortestPath_LayerSite.push_back(std::vector<float>(cellId2CandidateSites[curCell].size(), 100000.0));
823 shortestPath_LayerSite_backtrace.push_back(std::vector<int>(cellId2CandidateSites[curCell].size(), -1));
825 for (
int j = 0; j < predCandidates.size(); j++)
827 for (
int k = 0; k < curCandidates.size(); k++)
830 predCandidates[j]->getCLBSite()->
X(), predCandidates[j]->getCLBSite()->
Y(),
831 curCandidates[k]->getCLBSite()->
X(), curCandidates[k]->getCLBSite()->
Y());
833 if (shortestPath_LayerSite[
i][k] > shortestPath_LayerSite[
i - 1][j] +
delay)
835 shortestPath_LayerSite[
i][k] = shortestPath_LayerSite[
i - 1][j] +
delay;
836 shortestPath_LayerSite_backtrace[
i][k] = j;
838 if (
i == cellIdsInCriticalPath.size() - 1)
840 if (shortestPath_LayerSite[
i][k] < bestChoiceDelay)
842 bestChoiceDelay = shortestPath_LayerSite[
i][k];
851 for (
int i = shortestPath_LayerSite.size() - 1;
i >= 0;
i--)
853 assert(bestEndChoice >= 0);
854 if (bestEndChoice > 0)
856 auto curCellId = cellIdsInCriticalPath[
i];
859 auto &curCandidates = cellId2CandidateSites[curCellId];
861 auto targetPackingSite = cellId2CandidateSites[curCellId][bestEndChoice];
862 if (!targetPackingSite->getDeterminedClusterInSite()->checkAddPU(curPU))
864 bestEndChoice = shortestPath_LayerSite_backtrace[
i][bestEndChoice];
868 cellId2CandidateSites[curCellId][0]->getDeterminedClusterInSite()->removePUToConstructDetCluster(curPU);
870 assert(bestEndChoice < cellId2CandidateSites[curCellId].size());
871 assert(targetPackingSite->getDeterminedClusterInSite()->addPU(curPU));
874 auto cellSet = targetPackingSite->getDeterminedClusterInSite()->getCellSet();
875 for (
auto cell : cellSet)
881 bestEndChoice = shortestPath_LayerSite_backtrace[
i][bestEndChoice];
884 for (
int i = 0;
i < shortestPath_LayerSite.size() - 1;
i++)
886 auto curCellId = cellIdsInCriticalPath[
i];
888 auto nextCellId = cellIdsInCriticalPath[
i + 1];
890 if (curPU->checkHasCARRY() || curPU->checkHasLUTRAM() || curPU->checkHasBRAM() || curPU->checkHasDSP() ||
891 nextPU->checkHasCARRY() || nextPU->checkHasLUTRAM() || nextPU->checkHasBRAM() ||
892 nextPU->checkHasDSP() || PUsTouched.find(curPU) != PUsTouched.end() ||
893 PUsTouched.find(nextPU) != PUsTouched.end() || curPU == nextPU || curPU->isLocked() ||
915 auto prevCellId = cellIdsInCriticalPath[
i - 1];
923 if (
i < shortestPath_LayerSite.size() - 1)
925 auto succCellId = cellIdsInCriticalPath[
i + 1];
935 auto trialClusterWithCurPU =
937 auto trialClusterWithNextPU =
939 assert(trialClusterWithCurPU->contains(curPU));
940 trialClusterWithCurPU->removePUToConstructDetCluster(curPU);
941 assert(trialClusterWithNextPU->contains(nextPU));
942 trialClusterWithNextPU->removePUToConstructDetCluster(nextPU);
943 if (trialClusterWithCurPU->addPU(nextPU))
945 if (trialClusterWithNextPU->addPU(curPU))
947 curPackingSite->getDeterminedClusterInSite()->removePUToConstructDetCluster(curPU);
948 assert(curPackingSite->getDeterminedClusterInSite()->addPU(nextPU));
949 nextPackingSite->getDeterminedClusterInSite()->removePUToConstructDetCluster(nextPU);
950 assert(nextPackingSite->getDeterminedClusterInSite()->addPU(curPU));
954 auto cellSet = nextPackingSite->getDeterminedClusterInSite()->getCellSet();
955 for (
auto cell : cellSet)
962 cellSet = curPackingSite->getDeterminedClusterInSite()->getCellSet();
963 for (
auto cell : cellSet)
970 delete trialClusterWithCurPU;
971 delete trialClusterWithNextPU;
975 for (
int orderI = cellIdsInCriticalPath.size() - 1; orderI >= 0; orderI--)
977 auto cellId = cellIdsInCriticalPath[orderI];
979 PUsTouched.insert(curPU);
981 for (
auto pair : site2TrialCluster)
987 print_status(
"ParallelCLBPacker: conducted timing-driven detailed placement (shortest path) and " +
988 std::to_string(replaceCnt) +
" PlacementUnits are replaced.");
995 print_status(
"ParallelCLBPacker: re-place some LUT-FF pairs since they are not connected via internal nets.");
1028 std::set<PlacementInfo::PlacementUnit *> PUsTouched;
1031 for (
auto oriCellIdsInCriticalPath : oriCellIdsInCriticalPaths)
1033 std::map<int, std::vector<PackingCLBSite *>> cellId2CandidateSites;
1034 std::set<PackingCLBSite *> sitesCandidates;
1035 std::map<PackingCLBSite *, PackingCLBSite::PackingCLBCluster *> site2TrialCluster;
1036 cellId2CandidateSites.clear();
1038 std::vector<int> cellIdsInCriticalPath;
1040 std::set<PlacementInfo::PlacementUnit *> PUsInCriticalPathSet;
1041 for (
auto cellId : oriCellIdsInCriticalPath)
1044 PUsInCriticalPathSet.end())
1047 cellIdsInCriticalPath.push_back(cellId);
1051 bool shouldRelocateLUTFFPair =
false;
1062 targetLUT = LUTFFPair->getCells()[0];
1063 targetFF = LUTFFPair->getCells()[1];
1064 auto LUTLoc = curPackingSite->getLUTSlot(targetLUT);
1065 auto FFLoc = curPackingSite->getFFSlot(targetFF);
1066 shouldRelocateLUTFFPair = !(LUTLoc[0] == FFLoc[0] && LUTLoc[1] == FFLoc[1] && LUTLoc[2] == FFLoc[2]);
1067 srcSite = curPackingSite;
1071 if (!shouldRelocateLUTFFPair)
1075 int siteCandidateLimit = 9;
1077 float displacementThr = 1.5;
1079 auto cellId = cellIdsInCriticalPath[orderI];
1081 if (PUsTouched.find(curPU) != PUsTouched.end())
1086 PUsTouched.insert(curPU);
1087 if (!curPU->isLocked() && !curPU->checkHasCARRY() && !curPU->checkHasLUTRAM() && !curPU->checkHasBRAM() &&
1088 !curPU->checkHasDSP())
1090 float v1x = 0, v1y = 0, v2x = 0, v2y = 0;
1094 assert(curSite && succSite);
1095 int succSiteOrderId = orderI + 1;
1096 while (curSite == succSite && succSiteOrderId + 1 <= cellIdsInCriticalPath.size() - 1)
1101 v1x = v2x = succSite->getCLBSite()->X() - curSite->getCLBSite()->X();
1102 v1y = v2y = succSite->getCLBSite()->Y() - curSite->getCLBSite()->Y();
1104 if (std::fabs(v1x) + std::fabs(v1y) + std::fabs(v2x) + std::fabs(v2y) < 0.1)
1106 if (std::fabs(
getAngle(v1x, v1y, v2x, v2y)) < M_PI / 2)
1114 for (
auto curDeviceSite : *candidateSitesToPlaceTheCell_cone)
1119 if (cellId2CandidateSites[cellId].size() >= siteCandidateLimit)
1121 bool duplicate =
false;
1122 for (
auto existCandidate : cellId2CandidateSites[cellId])
1124 if (existCandidate == candidatePackingSite)
1130 if (sitesCandidates.find(candidatePackingSite) == sitesCandidates.end())
1139 site2TrialCluster[candidatePackingSite] = trialCluster;
1143 trialCluster = site2TrialCluster[candidatePackingSite];
1148 assert(trialCluster->
addPU(curPU));
1149 cellId2CandidateSites[cellId].push_back(candidatePackingSite);
1150 sitesCandidates.insert(candidatePackingSite);
1155 delete candidateSitesToPlaceTheCell_cone;
1160 if (!curPU->isLocked() && !curPU->checkHasCARRY() && !curPU->checkHasLUTRAM() && !curPU->checkHasBRAM() &&
1161 !curPU->checkHasDSP())
1166 if (cellId2CandidateSites[cellId].size() >= siteCandidateLimit + 1)
1170 for (
auto curDeviceSite : *candidateSitesToPlaceTheCell)
1175 bool duplicate =
false;
1176 for (
auto existCandidate : cellId2CandidateSites[cellId])
1178 if (existCandidate == candidatePackingSite)
1184 if (sitesCandidates.find(candidatePackingSite) == sitesCandidates.end())
1193 site2TrialCluster[candidatePackingSite] = trialCluster;
1197 trialCluster = site2TrialCluster[candidatePackingSite];
1202 assert(trialCluster->
addPU(curPU));
1203 cellId2CandidateSites[cellId].push_back(candidatePackingSite);
1204 sitesCandidates.insert(candidatePackingSite);
1208 delete candidateSitesToPlaceTheCell;
1212 int bestEndChoice = -1;
1213 float bestChoiceDelay = 100000;
1215 int predCell = cellIdsInCriticalPath[1];
1216 auto &curCandidates = cellId2CandidateSites[cellId];
1219 for (
int k = 0; k < curCandidates.size(); k++)
1222 if (curCandidates[k] == srcSite)
1225 predCandidate->getCLBSite()->X(), predCandidate->getCLBSite()->Y(), curCandidates[k]->getCLBSite()->X(),
1226 curCandidates[k]->getCLBSite()->Y());
1228 if (bestChoiceDelay >
delay)
1231 if (curCandidates[k]->getSlotMapping().canDirectConnectInSlot(targetLUT, targetFF))
1233 bestChoiceDelay =
delay;
1240 if (bestEndChoice > 0)
1244 assert(curCandidates[bestEndChoice]->getDeterminedClusterInSite()->addPU(LUTFFPair));
1245 curCandidates[bestEndChoice]->getSlotMappingRef().addLUTFFPair(targetLUT, targetFF);
1251 for (
auto pair : site2TrialCluster)
1257 print_status(
"ParallelCLBPacker: conducted timing-driven detailed placement (LUT-FF pairs) and " +
1258 std::to_string(replaceCnt) +
" PlacementUnits are replaced.");
1265 print_status(
"ParallelCLBPacker: conducting timing-driven detailed placement based on shortest path.");
1267 std::set<PlacementInfo::PlacementUnit *> PUsTouched;
1272 for (
auto oriCellIdsInCriticalPath : oriCellIdsInCriticalPaths)
1274 std::map<int, std::vector<PlacementInfo::Location>> cellId2CandidateLocation;
1275 cellId2CandidateLocation.clear();
1277 std::vector<int> cellIdsInCriticalPath;
1279 std::set<PlacementInfo::PlacementUnit *> PUsInCriticalPathSet;
1280 for (
auto cellId : oriCellIdsInCriticalPath)
1283 PUsInCriticalPathSet.end())
1286 cellIdsInCriticalPath.push_back(cellId);
1290 bool CellUnmapped =
false;
1291 for (
auto cellId : cellIdsInCriticalPath)
1297 cellId2CandidateLocation[cellId] = std::vector<PlacementInfo::Location>(1, cellLoc[cellId]);
1300 for (
int orderI = cellIdsInCriticalPath.size() - 1; orderI >= 0; orderI--)
1302 auto cellId = cellIdsInCriticalPath[orderI];
1308 if (PUsTouched.find(curPU) != PUsTouched.end())
1313 if (!curPU->isLocked() && !curPU->isFixed() && !curPU->checkHasCARRY() && !curPU->checkHasLUTRAM() &&
1314 !curPU->checkHasBRAM() && !curPU->checkHasDSP())
1316 auto curX = cellLoc[cellId].X;
1317 auto curY = cellLoc[cellId].Y;
1318 for (
float cX = curX - 1.0; cX < curX + 1.1; cX += 0.5)
1320 for (
float cY = curY - 1.0; cY < curY + 1.1; cY += 0.5)
1322 if (std::fabs(cX - curX) + std::fabs(cY - curY) < 0.1)
1327 cellId2CandidateLocation[cellId].push_back(newLoc);
1332 for (
int orderI = cellIdsInCriticalPath.size() - 1; orderI >= 0; orderI--)
1334 auto cellId = cellIdsInCriticalPath[orderI];
1336 PUsTouched.insert(curPU);
1339 std::vector<std::vector<float>> shortestPath_LayerSite;
1340 std::vector<std::vector<int>> shortestPath_LayerSite_backtrace;
1341 shortestPath_LayerSite.push_back(
1342 std::vector<float>(cellId2CandidateLocation[cellIdsInCriticalPath[0]].size(), 0.0));
1343 shortestPath_LayerSite_backtrace.push_back(
1344 std::vector<int>(cellId2CandidateLocation[cellIdsInCriticalPath[0]].size(), -1));
1346 int bestEndChoice = -1;
1347 float bestChoiceDelay = 100000;
1349 for (
int i = 1;
i < cellIdsInCriticalPath.size();
i++)
1351 auto predCell = cellIdsInCriticalPath[
i - 1];
1352 auto curCell = cellIdsInCriticalPath[
i];
1353 auto &predCandidates = cellId2CandidateLocation[predCell];
1354 auto &curCandidates = cellId2CandidateLocation[curCell];
1355 shortestPath_LayerSite.push_back(std::vector<float>(cellId2CandidateLocation[curCell].size(), 100000.0));
1356 shortestPath_LayerSite_backtrace.push_back(std::vector<int>(cellId2CandidateLocation[curCell].size(), -1));
1358 for (
int j = 0; j < predCandidates.size(); j++)
1360 for (
int k = 0; k < curCandidates.size(); k++)
1362 float predX = predCandidates[j].
X, predY = predCandidates[j].Y;
1363 float curX = curCandidates[k].X, curY = curCandidates[k].Y;
1367 if (shortestPath_LayerSite[
i][k] > shortestPath_LayerSite[
i - 1][j] +
delay)
1369 shortestPath_LayerSite[
i][k] = shortestPath_LayerSite[
i - 1][j] +
delay;
1370 shortestPath_LayerSite_backtrace[
i][k] = j;
1372 if (
i == cellIdsInCriticalPath.size() - 1)
1374 if (shortestPath_LayerSite[
i][k] < bestChoiceDelay)
1376 bestChoiceDelay = shortestPath_LayerSite[
i][k];
1385 for (
int i = shortestPath_LayerSite.size() - 1;
i >= 0;
i--)
1389 auto curCellId = cellIdsInCriticalPath[
i];
1392 auto &curCandidates = cellId2CandidateLocation[curCellId];
1393 if (!curPU->isLocked() && !curPU->isFixed() && !curPU->checkHasCARRY() && !curPU->checkHasLUTRAM() &&
1394 !curPU->checkHasBRAM() && !curPU->checkHasDSP())
1397 curCandidates[bestEndChoice].
Y);
1401 bestEndChoice = shortestPath_LayerSite_backtrace[
i][bestEndChoice];
1405 print_status(
"ParallelCLBPacker: conducted timing-driven detailed placement (shortest path) and " +
1406 std::to_string(replaceCnt) +
" PlacementUnits are replaced.");
1412 print_status(
"ParallelCLBPacker: conducting timing-driven detailed placement based on swaping.");
1414 std::set<PlacementInfo::PlacementUnit *> PUsTouched;
1415 std::set<PlacementInfo::PlacementUnit *> PUsDontTouch;
1417 PUsDontTouch.clear();
1418 for (
auto oriCellIdsInCriticalPath : oriCellIdsInCriticalPaths)
1420 for (
int orderI = oriCellIdsInCriticalPath.size() - 1; orderI >= 0; orderI--)
1422 auto cellId = oriCellIdsInCriticalPath[orderI];
1424 PUsDontTouch.insert(curPU);
1429 for (
auto oriCellIdsInCriticalPath : oriCellIdsInCriticalPaths)
1431 std::map<int, std::vector<PackingCLBSite *>> cellId2CandidateSites;
1432 std::set<PackingCLBSite *> sitesCandidates;
1433 std::map<PackingCLBSite *, PackingCLBSite::PackingCLBCluster *> site2TrialCluster;
1434 cellId2CandidateSites.clear();
1436 std::vector<int> cellIdsInCriticalPath;
1438 std::set<PlacementInfo::PlacementUnit *> PUsInCriticalPathSet;
1439 for (
auto cellId : oriCellIdsInCriticalPath)
1442 PUsInCriticalPathSet.end())
1445 cellIdsInCriticalPath.push_back(cellId);
1449 bool CellUnmapped =
false;
1450 for (
auto cellId : cellIdsInCriticalPath)
1454 if (!curPackingSite)
1456 CellUnmapped =
true;
1459 assert(curPackingSite);
1468 for (
int orderI = 1; orderI <= cellIdsInCriticalPath.size() - 2; orderI++)
1470 auto cellId = cellIdsInCriticalPath[orderI];
1477 if (PUsTouched.find(curPU) != PUsTouched.end())
1482 if (curCell->isLUT())
1484 float v1x = 0, v1y = 0, v2x = 0, v2y = 0;
1487 int predSiteOrderId = orderI - 1;
1490 int succSiteOrderId = orderI + 1;
1491 assert(predSite && curSite && succSite);
1495 predSite->getCLBSite()->X(), predSite->getCLBSite()->Y()) +
1497 succSite->getCLBSite()->X(), succSite->getCLBSite()->Y());
1502 v1x = predSite->getCLBSite()->X() - curSite->getCLBSite()->X();
1503 v1y = predSite->getCLBSite()->Y() - curSite->getCLBSite()->Y();
1504 v2x = succSite->getCLBSite()->X() - curSite->getCLBSite()->X();
1505 v2y = succSite->getCLBSite()->Y() - curSite->getCLBSite()->Y();
1509 if (std::fabs(v1x) + std::fabs(v1y) < 0.1 || std::fabs(v2x) + std::fabs(v2y) < 0.1)
1518 float bestOverheadSlack = -1000000;
1521 for (
auto curDeviceSite : *candidateSitesToPlaceTheCell_cone)
1526 if (curSite == candidatePackingSite)
1537 predSite->getCLBSite()->X(), predSite->getCLBSite()->Y()) +
1540 succSite->getCLBSite()->X(), succSite->getCLBSite()->Y());
1545 if (newDelay > oriDelay - 0.05)
1551 if (tmpPU->isLocked() || PUsDontTouch.find(tmpPU) != PUsDontTouch.end())
1555 auto targetCell = unpackedCell->getCell();
1558 if (targetCell->isLUT())
1562 trialTargetCluster->removePUToConstructDetCluster(tmpPU);
1563 if (trialTargetCluster->addPU(curPU))
1567 trialCurrentCluster->removePUToConstructDetCluster(curPU);
1568 if (trialCurrentCluster->addPU(tmpPU))
1575 if (overhead > oriOverhead + 0.2)
1577 if (overhead > bestOverheadSlack)
1579 bestOverheadSlack = overhead;
1580 bestCandidatePackingSite = candidatePackingSite;
1581 bestSwapCandidatePU = tmpPU;
1585 delete trialCurrentCluster;
1587 delete trialTargetCluster;
1593 if (bestCandidatePackingSite)
1597 assert(trialTargetCluster->addPU(curPU));
1598 auto trialCurrentCluster =
PUId2PackingCLBSite[curPU->getId()]->getDeterminedClusterInSite();
1599 trialCurrentCluster->removePUToConstructDetCluster(curPU);
1600 assert(trialCurrentCluster->addPU(bestSwapCandidatePU));
1602 auto unpackedCell_bestSwapCandidatePU =
1604 cellId2PackingSite[unpackedCell_curPU->getCell()->getCellId()] = bestCandidatePackingSite;
1613 delete candidateSitesToPlaceTheCell_cone;
1617 for (
int i = 0;
i < cellIdsInCriticalPath.size() - 1;
i++)
1619 auto curCellId = cellIdsInCriticalPath[
i];
1621 auto nextCellId = cellIdsInCriticalPath[
i + 1];
1623 if (curPU->checkHasCARRY() || curPU->checkHasLUTRAM() || curPU->checkHasBRAM() || curPU->checkHasDSP() ||
1624 nextPU->checkHasCARRY() || nextPU->checkHasLUTRAM() || nextPU->checkHasBRAM() ||
1625 nextPU->checkHasDSP() || PUsTouched.find(curPU) != PUsTouched.end() ||
1626 PUsTouched.find(nextPU) != PUsTouched.end() || curPU == nextPU || curPU->isLocked() ||
1648 auto prevCellId = cellIdsInCriticalPath[
i - 1];
1656 if (
i < cellIdsInCriticalPath.size() - 1)
1658 auto succCellId = cellIdsInCriticalPath[
i + 1];
1666 if (newDis < oriDis)
1668 auto trialClusterWithCurPU =
1670 auto trialClusterWithNextPU =
1672 assert(trialClusterWithCurPU->contains(curPU));
1673 trialClusterWithCurPU->removePUToConstructDetCluster(curPU);
1675 assert(trialClusterWithNextPU->contains(nextPU));
1676 trialClusterWithNextPU->removePUToConstructDetCluster(nextPU);
1677 if (trialClusterWithCurPU->addPU(nextPU))
1679 if (trialClusterWithNextPU->addPU(curPU))
1681 curPackingSite->getDeterminedClusterInSite()->removePUToConstructDetCluster(curPU);
1682 assert(curPackingSite->getDeterminedClusterInSite()->addPU(nextPU));
1683 nextPackingSite->getDeterminedClusterInSite()->removePUToConstructDetCluster(nextPU);
1684 assert(nextPackingSite->getDeterminedClusterInSite()->addPU(curPU));
1688 auto cellSet = nextPackingSite->getDeterminedClusterInSite()->getCellSet();
1689 for (
auto cell : cellSet)
1696 cellSet = curPackingSite->getDeterminedClusterInSite()->getCellSet();
1697 for (
auto cell : cellSet)
1704 delete trialClusterWithCurPU;
1705 delete trialClusterWithNextPU;
1709 for (
int orderI = cellIdsInCriticalPath.size() - 1; orderI >= 0; orderI--)
1711 auto cellId = cellIdsInCriticalPath[orderI];
1713 PUsTouched.insert(curPU);
1717 print_status(
"ParallelCLBPacker: conducted timing-driven detailed placement (swaping) and " +
1718 std::to_string(replaceCnt) +
" PlacementUnits are replaced.");
1729 if (packingSite->getDeterminedClusterInSite())
1731 for (
auto tmpPU : packingSite->getDeterminedClusterInSite()->getPUs())
1744 if (tmpCell->isLUT() || tmpCell->isFF())
1769 print_status(
"ParallelCLBPacker: start exceptionHandling.");
1773 float Dc =
maxD * 0.5;
1777 std::set<PlacementInfo::PlacementUnit *, Packing_PUcompare> processedPUs;
1778 processedPUs.clear();
1781 for (
auto PU : inputUnpackedPUsVec)
1783 if (!PU->isLocked())
1792 processedPUs.clear();
1793 print_status(
"ParallelCLBPacker: starting parallel ripping up for " + std::to_string(
PUPoints.size()) +
1794 " PUs and current displacement threshold for ripping up is " + std::to_string(Dc));
1796 while (processedPUs.size() <
PUPoints.size())
1798 std::vector<PlacementInfo::PlacementUnit *> noRipUpOverlapPUs;
1799 std::set<PlacementInfo::PlacementUnit *, Packing_PUcompare> coveredPUs;
1800 noRipUpOverlapPUs.clear();
1808 if (coveredPUs.find(tmpPUPoint.getPU()) != coveredPUs.end())
1810 if (processedPUs.find(tmpPUPoint.getPU()) != processedPUs.end())
1812 if (isLegalizedPU[tmpPUPoint.getPU()->getId()])
1814 noRipUpOverlapPUs.push_back(tmpPUPoint.getPU());
1815 coveredPUs.insert(tmpPUPoint.getPU());
1816 processedPUs.insert(tmpPUPoint.getPU());
1817 std::vector<int> indices = kdtree.radiusSearch(tmpPUPoint, 4 * Dc + 2);
1818 for (
auto tmpInd : indices)
1820 assert(std::fabs(
PUPoints[tmpInd].getPU()->
X() - tmpPUPoint.getPU()->X()) +
1821 y2xRatio * std::fabs(
PUPoints[tmpInd].getPU()->Y() - tmpPUPoint.getPU()->Y()) <=
1823 coveredPUs.insert(
PUPoints[tmpInd].getPU());
1831 unsigned int numNoRipUpOverlapPUs = noRipUpOverlapPUs.size();
1834 #pragma omp parallel for schedule(dynamic)
1835 for (
unsigned int i = 0;
i < numNoRipUpOverlapPUs;
i++)
1837 isLegalizedPU[noRipUpOverlapPUs[
i]->getId()] =
exceptionPULegalize(noRipUpOverlapPUs[
i], Dc, verbose);
1841 for (
unsigned int i = 0;
i < numNoRipUpOverlapPUs;
i++)
1843 successCnt += isLegalizedPU[noRipUpOverlapPUs[
i]->getId()];
1849 int unprocessedCnt = 0;
1850 for (
unsigned int i = 0;
i <
PUPoints.size();
i++)
1852 if (!isLegalizedPU[
PUPoints[
i].getPU()->getId()])
1866 Dc =
maxD * 0.5 - 1;
1867 for (
unsigned int i = 0;
i <
PUPoints.size();
i++)
1869 std::cout <<
PUPoints[
i].getPU() <<
"\n=================================================\n";
1871 assert(
"fail to handle exceptions" &&
false);
1876 print_status(
"ParallelCLBPacker: there are " + std::to_string(unprocessedCnt) +
1877 " PUs left to be legalized and current displacement threshold for ripping up is " +
1878 std::to_string(Dc));
1879 int tmpFFCnt = 0, tmpLUTCnt = 0;
1880 float avgFFWeight = 0, avgLUTWeight = 0;
1881 for (
unsigned int i = 0;
i <
PUPoints.size();
i++)
1886 if (unpackCell->getCell()->isFF())
1891 else if (unpackCell->getCell()->isLUT())
1901 assert(!curMacro->isPacked());
1902 for (
auto tmpCell : curMacro->getCells())
1904 if (tmpCell->isFF())
1909 else if (tmpCell->isLUT())
1917 avgFFWeight /= tmpFFCnt;
1918 avgLUTWeight /= tmpLUTCnt;
1919 print_info(
"there are " + std::to_string(tmpFFCnt) +
" FFs(avgW=" + std::to_string(avgFFWeight) +
") and " +
1920 std::to_string(tmpLUTCnt) +
" LUTs(avgW=" + std::to_string(avgLUTWeight) +
") ");
1927 print_status(
"ParallelCLBPacker::exceptionHandling done!");
1935 std::vector<DeviceInfo::DeviceSite *> *candidateSitesToPlaceThePU =
nullptr;
1936 if (displacementThreshold < 4)
1940 candidateSitesToPlaceThePU =
1943 std::vector<siteWithScore> sitesToRipUp;
1944 sitesToRipUp.clear();
1945 for (
auto tmpSite : *candidateSitesToPlaceThePU)
1947 float lambda1 = 0.02;
1948 float lambda2 = 1.0;
1949 float lambda3 = 4.0;
1969 float changeHPWL = 0;
1972 if (tmpNet->getUnits().size() > 64)
1974 changeHPWL += tmpNet->getNewHPWLByTrying(curPU, tmpSite->
X(), tmpSite->Y(),
y2xRatio);
1975 changeHPWL -= tmpNet->getHPWL(
y2xRatio);
1976 assert(!std::isnan(changeHPWL));
1979 float packedScore = 0;
1980 float score = -lambda1 * changeHPWL;
1992 sitesToRipUp.emplace_back(packingSite, score);
1995 return a.score == b.score
1996 ? (a.site->getCLBSite()->getElementIdInParent() > b.site->getCLBSite()->getElementIdInParent())
1997 : (a.score > b.score);
2010 delete candidateSitesToPlaceThePU;
2014 for (
auto pair : sitesToRipUp)
2018 std::map<PackingCLBSite *, PackingCLBSite::PackingCLBCluster *> packingSite2DeterminedCluster;
2019 packingSite2DeterminedCluster.clear();
2022 if (
ripUpAndLegalizae(packingSite, curPU, displacementThreshold, packingSite2DeterminedCluster, verbose))
2029 for (
auto pair : packingSite2DeterminedCluster)
2031 if (pair.first->getDeterminedClusterInSite())
2032 delete pair.first->getDeterminedClusterInSite();
2033 pair.first->setDeterminedClusterInSite(pair.second);
2052 std::map<PackingCLBSite *, PackingCLBSite::PackingCLBCluster *> &packingSite2DeterminedCluster,
bool verbose)
2059 backup_determinedCluster =
2073 packingSite2DeterminedCluster[curTargetPackingSite] = backup_determinedCluster;
2105 if (backup_determinedCluster)
2108 std::set<PlacementInfo::PlacementUnit *, Packing_PUcompare> evictedPUs = backup_determinedCluster->
getPUs();
2109 std::set<PlacementInfo::PlacementUnit *, Packing_PUcompare> notEvictedPUs;
2110 notEvictedPUs.clear();
2113 std::vector<PUWithScore> PUsWithSlack;
2114 PUsWithSlack.clear();
2115 for (
auto evictedPU : evictedPUs)
2117 PUsWithSlack.emplace_back(evictedPU, PUId2Slack[evictedPU->getId()]);
2119 std::sort(PUsWithSlack.begin(), PUsWithSlack.end(), [](
const PUWithScore &a,
const PUWithScore &b) ->
bool {
2120 return a.score == b.score ? (a.PU->getId() > b.PU->getId()) : (a.score < b.score);
2123 for (
auto evictedPU_scorePair : PUsWithSlack)
2125 auto evictedPU = evictedPU_scorePair.PU;
2133 assert(notEvictedPUs.find(evictedPU) == notEvictedPUs.end());
2149 notEvictedPUs.insert(evictedPU);
2161 for (
auto evictedPU : evictedPUs)
2163 if (notEvictedPUs.find(evictedPU) != notEvictedPUs.end())
2166 std::vector<DeviceInfo::DeviceSite *> *candidateSitesToPlaceThePU =
nullptr;
2167 if (displacementThreshold < 4)
2172 candidateSitesToPlaceThePU =
2174 curTargetPackingSite->
getCLBSite()->
Y(), displacementThreshold - 3,
2177 float highestScoreIncrease = -1e5;
2179 for (
auto tmpSite : *candidateSitesToPlaceThePU)
2214 if (tmpCluster->
addPU(evictedPU))
2221 if (!bestClusterToPack)
2223 bestClusterToPack = tmpCluster;
2224 highestScoreIncrease = newScore - oriScore;
2229 if (highestScoreIncrease < newScore - oriScore)
2231 delete bestClusterToPack;
2232 bestClusterToPack = tmpCluster;
2233 highestScoreIncrease = newScore - oriScore;
2249 delete candidateSitesToPlaceThePU;
2250 if (bestClusterToPack)
2253 if (packingSite2DeterminedCluster.find(evictPUToPackingSite) ==
2254 packingSite2DeterminedCluster.end())
2262 packingSite2DeterminedCluster[evictPUToPackingSite] =
2269 packingSite2DeterminedCluster[evictPUToPackingSite] =
2303 std::vector<DeviceInfo::DeviceSite *> *
2305 float displacementLowerbound,
float displacementUpperbound,
2306 float y2xRatio,
bool clockRegionAware,
float v1x,
float v1y,
float v2x,
2307 float v2y,
int numLimit)
2309 assert(displacementLowerbound < displacementUpperbound);
2311 std::vector<DeviceInfo::DeviceSite *> *res =
new std::vector<DeviceInfo::DeviceSite *>();
2319 int clockRegionX, clockRegionY;
2326 for (
auto sharedTypeId : sharedTypeIds)
2328 std::vector<std::vector<PlacementInfo::PlacementBinInfo *>> &curBinGrid =
2330 assert(binIdY >= 0);
2331 assert((
unsigned int)binIdY < curBinGrid.size());
2332 assert(binIdX >= 0);
2333 assert((
unsigned int)binIdX < curBinGrid[binIdY].size());
2335 std::queue<std::pair<int, int>> binXYqueue;
2336 std::set<std::pair<int, int>> reachedBinXYs;
2337 binXYqueue.emplace(binIdX, binIdY);
2338 reachedBinXYs.emplace(binIdX, binIdY);
2340 while (binXYqueue.size() > 0)
2342 std::pair<int, int> curXY = binXYqueue.front();
2344 int curbinIdX = curXY.first, curbinIdY = curXY.second;
2348 if (bin2TargetXYDistance > displacementUpperbound)
2352 float vx = tmpSite->X() - targetX;
2353 float vy = tmpSite->Y() - targetY;
2354 float tmpPUDis = fabs(vx) +
y2xRatio * fabs(vy);
2355 if (tmpPUDis > displacementLowerbound && tmpPUDis <= displacementUpperbound &&
2356 std::fabs(
getAngle(vx, vy, vxCom, vyCom)) < 0.42 * M_PI)
2358 int siteClockRegionX, siteClockRegionY;
2364 res->push_back(tmpSite);
2368 if (res->size() > numLimit)
2371 for (
int nextY = curbinIdY - 1; nextY <= curbinIdY + 1; nextY++)
2373 for (
int nextX = curbinIdX - 1; nextX <= curbinIdX + 1; nextX++)
2377 if (!((
unsigned int)nextY < curBinGrid.size()))
2381 if (!((
unsigned int)nextX < curBinGrid[binIdY].size()))
2386 if (nextBin2TargetXYDistance > displacementUpperbound)
2389 std::pair<int, int> nextXY(nextX, nextY);
2390 if (reachedBinXYs.find(nextXY) != reachedBinXYs.end())
2395 std::vector<float> binXB;
2396 binXB.push_back(nextBin->
left());
2397 binXB.push_back(nextBin->
right());
2399 std::vector<float> binYB;
2400 binYB.push_back(nextBin->
top());
2401 binYB.push_back(nextBin->
bottom());
2403 bool overlap =
false;
2404 for (
auto bX : binXB)
2406 for (
auto bY : binYB)
2408 float vx = bX - targetX;
2409 float vy = bY - targetY;
2410 if (std::fabs(
getAngle(vx, vy, vxCom, vyCom)) < 0.42 * M_PI)
2417 if (reachedBinXYs.find(nextXY) == reachedBinXYs.end())
2419 reachedBinXYs.insert(nextXY);
2421 binXYqueue.push(nextXY);
2431 std::vector<DeviceInfo::DeviceSite *> *
2433 float displacementLowerbound,
float displacementUpperbound,
2434 float y2xRatio,
bool clockRegionAware)
2436 assert(displacementLowerbound < displacementUpperbound);
2438 std::vector<DeviceInfo::DeviceSite *> *res =
new std::vector<DeviceInfo::DeviceSite *>();
2446 int clockRegionX, clockRegionY;
2449 for (
auto sharedTypeId : sharedTypeIds)
2451 std::vector<std::vector<PlacementInfo::PlacementBinInfo *>> &curBinGrid =
2453 assert(binIdY >= 0);
2454 assert((
unsigned int)binIdY < curBinGrid.size());
2455 assert(binIdX >= 0);
2456 assert((
unsigned int)binIdX < curBinGrid[binIdY].size());
2458 std::queue<std::pair<int, int>> binXYqueue;
2459 std::set<std::pair<int, int>> reachedBinXYs;
2460 binXYqueue.emplace(binIdX, binIdY);
2461 reachedBinXYs.emplace(binIdX, binIdY);
2463 while (binXYqueue.size() > 0)
2465 std::pair<int, int> curXY = binXYqueue.front();
2467 int curbinIdX = curXY.first, curbinIdY = curXY.second;
2471 if (bin2TargetXYDistance > displacementUpperbound)
2475 float tmpPUDis = fabs(targetX - tmpSite->X()) +
y2xRatio * fabs(targetY - tmpSite->Y());
2476 if (tmpPUDis > displacementLowerbound && tmpPUDis <= displacementUpperbound)
2478 int siteClockRegionX, siteClockRegionY;
2484 res->push_back(tmpSite);
2488 for (
int nextY = curbinIdY - 1; nextY <= curbinIdY + 1; nextY++)
2490 for (
int nextX = curbinIdX - 1; nextX <= curbinIdX + 1; nextX++)
2494 if (!((
unsigned int)nextY < curBinGrid.size()))
2498 if (!((
unsigned int)nextX < curBinGrid[binIdY].size()))
2502 if (nextBin2TargetXYDistance > displacementUpperbound)
2504 std::pair<int, int> nextXY(nextX, nextY);
2505 if (reachedBinXYs.find(nextXY) == reachedBinXYs.end())
2507 reachedBinXYs.insert(nextXY);
2508 binXYqueue.push(nextXY);
2524 if (packingSite->getDeterminedClusterInSite())
2526 if (packingSite->getDeterminedClusterInSite()->getPUs().size())
2528 for (
auto tmpPU : packingSite->getDeterminedClusterInSite()->getPUs())
2530 tmpPU->setAnchorLocationAndForgetTheOriginalOne(packingSite->getCLBSite()->X(),
2531 packingSite->getCLBSite()->Y());
2548 if (packingSite->getDeterminedClusterInSite())
2550 if (packingSite->getDeterminedClusterInSite()->getPUs().size())
2552 for (
auto tmpPU : packingSite->getDeterminedClusterInSite()->getPUs())
2564 std::vector<PlacementInfo::PlacementUnit *>
packedPUs;
2566 std::map<PlacementInfo::PlacementUnit *, float> PU2X, PU2Y;
2567 std::map<PlacementInfo::PlacementUnit *, std::vector<DeviceInfo::DeviceSite *>> PU2Sites;
2575 if (packingSite->getDeterminedClusterInSite())
2577 if (packingSite->getDeterminedClusterInSite()->getPUs().size() >= 1)
2579 std::vector<DesignInfo::DesignCellType> cellsToAdd_cellType(0);
2580 std::vector<DesignInfo::DesignCell *> cellsToAdd(0);
2581 for (
auto tmpPU : packingSite->getDeterminedClusterInSite()->getPUs())
2585 cellsToAdd.push_back(unpackCell->getCell());
2586 cellsToAdd_cellType.push_back(unpackCell->getCell()->getCellType());
2590 assert(curMacro->getMacroType() !=
2593 assert(!curMacro->isPacked());
2594 int cellIdInMacro = 0;
2595 for (
auto tmpCell : curMacro->getCells())
2597 cellsToAdd.push_back(tmpCell);
2598 cellsToAdd_cellType.push_back(curMacro->getVirtualCellType(cellIdInMacro));
2606 assert(cellsToAdd.size() >= 1);
2610 packingSite->getCLBSite()->Y());
2611 int totalWeight = 0;
2612 for (
unsigned int tmpId = 0; tmpId < cellsToAdd.size(); tmpId++)
2614 curMacro->
addCell(cellsToAdd[tmpId], cellsToAdd_cellType[tmpId], 0, 0.0);
2615 cellLoc[cellsToAdd[tmpId]->getCellId()].X = packingSite->getCLBSite()->X();
2616 cellLoc[cellsToAdd[tmpId]->getCellId()].Y = packingSite->getCLBSite()->Y();
2631 if (setPUPseudoNetToCLBSite)
2633 PU2X[curMacro] = packingSite->getCLBSite()->X();
2634 PU2Y[curMacro] = packingSite->getCLBSite()->Y();
2635 PU2Sites[curMacro] = std::vector<DeviceInfo::DeviceSite *>();
2636 PU2Sites[curMacro].push_back(packingSite->getCLBSite());
2639 for (
auto LUTPair : packingSite->getDeterminedClusterInSite()->getPairedLUTs())
2645 if (cellsToAdd.size() > 8)
2647 for (
auto &tmpControlSet : packingSite->getDeterminedClusterInSite()->getFFControlSets())
2649 float estimatedFFUtil = 4.0 / (float)tmpControlSet.getSize();
2651 for (
auto tmpFF : tmpControlSet.getFFs())
2661 unsigned int validCnt = 0;
2664 for (
unsigned int tmpPUId = 0; tmpPUId <
placementUnits.size(); tmpPUId++)
2677 assert((
unsigned int)curMacro->getWeight() >= curMacro->getCells().size());
2684 print_status(
"ParallelCLBPacker Updating Cell-PlacementUnit Mapping");
2692 std::map<DesignInfo::DesignCell *, PlacementInfo::PlacementUnit *> cell2PUMap;
2698 assert(cell2PUMap.find(curCell) == cell2PUMap.end());
2699 cell2PUMap[curCell] = unpackedCell;
2704 for (
auto curCell : curMacro->getCells())
2706 if (cell2PUMap.find(curCell) != cell2PUMap.end())
2708 std::cout <<
"recorded PU:" << cell2PUMap[curCell] <<
"\n";
2709 std::cout <<
"another PU:" << curMacro <<
"\n";
2712 assert(cell2PUMap.find(curCell) == cell2PUMap.end());
2713 cell2PUMap[curCell] = curMacro;
2724 for (
int i = 0;
i < 2;
i++)
2726 for (
int k = 0; k < 4; k++)
2728 for (
int j = 0; j < 2; j++)
2730 if (slots.
LUTs[
i][j][k])
2751 assert(tmpMacro->getCells().size() == DSPBRAM_LegalSitePair.second.size());
2752 for (
unsigned int i = 0;
i < tmpMacro->getCells().size();
i++)
2754 auto curCell = tmpMacro->getCells()[
i];
2755 auto targetSite = DSPBRAM_LegalSitePair.second[
i];
2756 if (!curCell->isVirtualCell())
2761 assert(targetSite->getSiteY() % 2 == 0);
2781 assert(
false &&
"undefined situtation");
2786 assert(targetSite->getSiteY() % 2 == 1);
2792 assert(tmpMacro->getCells().size() == DSPBRAM_LegalSitePair.second.size());
2793 for (
unsigned int i = 0;
i < tmpMacro->getCells().size();
i++)
2795 auto curCell = tmpMacro->getCells()[
i];
2796 auto targetSite = DSPBRAM_LegalSitePair.second[
i];
2797 if (!curCell->isVirtualCell())
2808 assert(
false &&
"there should be no virtual DSP");
2817 else if (
auto tmpUnppackedCell =
2820 assert(1 == DSPBRAM_LegalSitePair.second.size());
2821 auto curCell = tmpUnppackedCell->getCell();
2822 auto targetSite = DSPBRAM_LegalSitePair.second[0];
2850 auto curCell = unpackedCell->getCell();
2851 if (curCell->isIO() && unpackedCell->isLocked())
2853 auto lockedSite = unpackedCell->getLockedSite();
2869 std::string placementStr =
"";
2874 assert(tmpMacro->getCells().size() == DSPBRAM_LegalSitePair.second.size());
2875 for (
unsigned int i = 0;
i < tmpMacro->getCells().size();
i++)
2877 auto curCell = tmpMacro->getCells()[
i];
2878 auto targetSite = DSPBRAM_LegalSitePair.second[
i];
2879 if (!curCell->isVirtualCell())
2884 assert(targetSite->getSiteY() % 2 == 0);
2885 placementStr +=
" " + curCell->getName() +
" RAMB36_X" +
2886 std::to_string(targetSite->getSiteX()) +
"Y" +
2887 std::to_string(targetSite->getSiteY() / 2) +
"\n";
2892 if (targetSite->getSiteY() % 2)
2895 " " + curCell->getName() +
" " + targetSite->getName() +
"/RAMB18E2_U" +
"\n";
2900 " " + curCell->getName() +
" " + targetSite->getName() +
"/RAMB18E2_L" +
"\n";
2905 assert(
false &&
"undefined situtation");
2910 assert(targetSite->getSiteY() % 2 == 1);
2916 assert(tmpMacro->getCells().size() == DSPBRAM_LegalSitePair.second.size());
2917 for (
unsigned int i = 0;
i < tmpMacro->getCells().size();
i++)
2919 auto curCell = tmpMacro->getCells()[
i];
2920 auto targetSite = DSPBRAM_LegalSitePair.second[
i];
2921 if (!curCell->isVirtualCell())
2923 placementStr +=
" " + curCell->getName() +
" " + targetSite->getName() +
"/DSP_ALU" +
"\n";
2927 assert(
false &&
"there should be no virtual DSP");
2936 else if (
auto tmpUnppackedCell =
2939 assert(1 == DSPBRAM_LegalSitePair.second.size());
2940 auto curCell = tmpUnppackedCell->getCell();
2941 auto targetSite = DSPBRAM_LegalSitePair.second[0];
2944 if (targetSite->getSiteY() % 2)
2946 placementStr +=
" " + curCell->getName() +
" " + targetSite->getName() +
"/RAMB18E2_U" +
"\n";
2950 placementStr +=
" " + curCell->getName() +
" " + targetSite->getName() +
"/RAMB18E2_L" +
"\n";
2955 placementStr +=
" " + curCell->getName() +
" " + targetSite->getName() +
"/DSP_ALU" +
"\n";
2962 if (placementStr !=
"")
2964 std::string oriBrace =
"[";
2965 std::string newBrace =
"\\[";
2966 outfileTcl <<
"set result "
2967 <<
"[catch {place_cell {" << placementStr <<
"}}]\n"
2968 <<
"if {$result} {\n incr errorNum \n";
2969 std::vector<std::string> splitItems;
2971 strSplit(placementStr, splitItems,
"\n");
2972 for (
auto item : splitItems)
2975 outfileTcl <<
"puts $fo \"" << item <<
" \"\n";
2977 outfileTcl <<
"\n}\n";
2987 return unpackedCell->getCell()->originallyIsLUTRAM();
2991 for (
auto tmpCell : curMacro->getCells())
2993 if (tmpCell->originallyIsLUTRAM())
3005 std::string placementStr =
"";
3009 auto slotMapping = tmpPackingSite->getSlotMapping();
3010 auto CLBSite = tmpPackingSite->getCLBSite();
3011 if ((packingRelatedToLUT6_2 && !
hasLUT62(slotMapping)) || (!packingRelatedToLUT6_2 &&
hasLUT62(slotMapping)))
3014 if (tmpPackingSite->getDeterminedClusterInSite())
3017 if (tmpPackingSite->checkIsCarrySite())
3020 placementStr += slotMapping.Carry->getName() +
" " + CLBSite->getName() +
"/CARRY8 \n";
3022 else if (tmpPackingSite->checkIsMuxSite())
3024 for (
int i = 0;
i < 2;
i++)
3026 if (slotMapping.MuxF8[
i])
3028 if (slotMapping.MuxF8[
i]->isVirtualCell())
3032 placementStr +=
" " + slotMapping.MuxF8[
i]->getName() +
" " + CLBSite->getName() +
"/" +
3033 slotMapping.MuxF8SlotNames[
i] +
" \n";
3035 for (
int j = 0; j < 2; j++)
3037 if (slotMapping.MuxF7[
i][j])
3039 if (slotMapping.MuxF7[
i][j]->isVirtualCell())
3042 placementStr +=
" " + slotMapping.MuxF7[
i][j]->getName() +
" " + CLBSite->getName() +
3043 "/" + slotMapping.MuxF7SlotNames[
i][j] +
" \n";
3048 else if (tmpPackingSite->checkIsLUTRAMSite())
3050 auto tmpMacro = tmpPackingSite->getLUTRAMMacro();
3053 if (tmpMacro->getFixedCellInfoVec().size() % 2 ==
3056 if (tmpMacro->getFixedCellInfoVec().size() > 0)
3058 for (
unsigned int i = 0;
i < tmpMacro->getFixedCellInfoVec().size();
i++)
3061 placementStr +=
" " + curCell->
getName() +
" " + CLBSite->getName() +
"/" +
3062 tmpMacro->getFixedCellInfoVec()[
i].BELName +
" \n";
3067 placementStr +=
" " + tmpMacro->getName() +
" " + CLBSite->getName() +
"/H6LUT \n";
3072 if (tmpMacro->getFixedCellInfoVec().size() == 1)
3074 placementStr +=
" " + tmpMacro->getName() +
" " + CLBSite->getName() +
"/H6LUT \n";
3080 for (
int i = 0;
i < 2;
i++)
3082 for (
int k = 0; k < 4; k++)
3084 for (
int j = 0; j < 2; j++)
3086 if (slotMapping.LUTs[
i][j][k])
3088 if (slotMapping.LUTs[
i][j][k]->isVirtualCell())
3090 assert(slotMapping.LUTs[
i][j][k]->isLUT());
3091 char LUTCode = (
i * 4 + k) +
'A';
3094 std::string LUTSiteName = std::string(1, LUTCode) +
"6LUT";
3096 placementStr +=
" " + slotMapping.LUTs[
i][j][k]->getName() +
" " + CLBSite->getName() +
3097 "/" + LUTSiteName +
"\n";
3104 std::string LUTSiteName = std::string(1, LUTCode) +
"5LUT";
3106 placementStr +=
" " + slotMapping.LUTs[
i][j][k]->getName() +
" " + CLBSite->getName() +
3107 "/" + LUTSiteName +
"\n";
3113 for (
int i = 0;
i < 2;
i++)
3115 for (
int k = 0; k < 4; k++)
3117 for (
int j = 0; j < 2; j++)
3119 if (slotMapping.FFs[
i][j][k])
3121 if (slotMapping.FFs[
i][j][k]->isVirtualCell())
3123 assert(slotMapping.FFs[
i][j][k]->isFF());
3127 if (tmpMacro->getMacroType() ==
3129 PlacementMacroType_LCLB)
3133 char FFCode = (
i * 4 + k) +
'A';
3136 std::string FFSiteName = std::string(1, FFCode) +
"FF";
3138 placementStr +=
" " + slotMapping.FFs[
i][j][k]->getName() +
" " + CLBSite->getName() +
3139 "/" + FFSiteName +
"\n";
3143 std::string FFSiteName = std::string(1, FFCode) +
"FF2";
3145 placementStr +=
" " + slotMapping.FFs[
i][j][k]->getName() +
" " + CLBSite->getName() +
3146 "/" + FFSiteName +
"\n";
3155 if (placementStr !=
"")
3157 std::string oriBrace =
"[";
3158 std::string newBrace =
"\\[";
3159 outfileTcl <<
"set result "
3160 <<
"[catch {place_cell {" << placementStr <<
"}}]\n"
3161 <<
"if {$result} {\n incr errorNum \n";
3162 std::vector<std::string> splitItems;
3164 strSplit(placementStr, splitItems,
"\n");
3165 for (
auto item : splitItems)
3168 outfileTcl <<
"puts $fo \"" << item <<
" \"\n";
3170 outfileTcl <<
"\n}\n";
3176 if (placementStr !=
"")
3178 outfileTcl <<
"set result "
3179 <<
"[catch {place_cell {" << placementStr <<
"}}]\n"
3180 <<
"if {$result} {\n incr errorNum \nputs $fo \"" << placementStr <<
"\"\n}\n";
3186 std::ofstream outfileTcl(dumpTclFile);
3187 assert(outfileTcl.is_open() && outfileTcl.good() &&
3188 "The path for placement Tcl dumping does not exist and please check your path settings");
3189 outfileTcl <<
"set script_path [ file dirname [ file normalize [ info script ] ] ]\n";
3191 <<
"set fo [open \"${script_path}/initialPlacementError\" \"w\"]\nplace_design -unplace\nset errorNum 0\n";
3195 outfileTcl <<
"set_property HLUTNM {} [get_cells -hierarchical *]\n";
3196 outfileTcl <<
"set_property SOFT_HLUTNM {} [get_cells -hierarchical *]\n";
3199 outfileTcl <<
"$errorNum\n";
3200 outfileTcl <<
"close $fo \n"
3201 "set a [open \"${script_path}/initialPlacementError\"]\n"
3202 "set lines [split [read $a] \"\\n\"]\n"
3204 "exec rm \"${script_path}/initialPlacementError\"\n"
3205 "set b [open \"${script_path}/placementError\" \"w\"]\n"
3207 "set placeBatch {}\n"
3208 "foreach line $lines {\n"
3210 " set placeBatch [concat $placeBatch $line]\n"
3211 " if {$lineCnt == 2 } {\n"
3212 " set result [catch {place_cell $placeBatch }]\n"
3214 " puts $b $placeBatch\n"
3217 " set placeBatch \"\"\n"
3221 outfileTcl <<
"place_design\nroute_design\n";
3229 std::string dumpTclFile =
3231 std::string dumpFile =
3234 print_status(
"ParallelCLBPacker: dumping CLBPacking archieve to: " + dumpFile);
3236 std::stringstream outfile0;
3240 if (tmpPackingSite->getDeterminedClusterInSite())
3242 outfile0 << tmpPackingSite->getDeterminedClusterInSite() <<
"\n";
3243 if (tmpPackingSite->checkIsCarrySite())
3245 outfile0 <<
"LUTSlots:\n";
3246 for (
int i = 0;
i < 2;
i++)
3248 for (
int k = 0; k < 4; k++)
3250 for (
int j = 0; j < 2; j++)
3252 if (tmpPackingSite->getSlotMapping().LUTs[
i][j][k])
3254 outfile0 <<
"i,j,k:" <<
i <<
"," << j <<
"," << k <<
" "
3255 << tmpPackingSite->getSlotMapping().LUTs[
i][j][k] <<
"\n";
3261 if (tmpPackingSite->checkIsCarrySite())
3263 outfile0 <<
"FFSlots:\n";
3264 for (
int i = 0;
i < 2;
i++)
3266 for (
int k = 0; k < 4; k++)
3268 for (
int j = 0; j < 2; j++)
3270 if (tmpPackingSite->getSlotMapping().FFs[
i][j][k])
3272 outfile0 <<
"i,j,k:" <<
i <<
"," << j <<
"," << k <<
" "
3273 << tmpPackingSite->getSlotMapping().FFs[
i][j][k] <<
"\n";
3283 print_status(
"ParallelCLBPacker: dumped CLBPacking archieve to: " + dumpFile);
3290 int mappedPUCnt = 0;
3295 if (packingSite->getDeterminedClusterInSite())
3297 for (
auto tmpPU : packingSite->getDeterminedClusterInSite()->getPUs())
3310 for (
auto tmpPU : packingSite->getNeighborPUs())
3314 if (!PUId2NeighborSite[tmpPU->getId()])
3316 PUId2NeighborSite[tmpPU->getId()] = packingSite->getCLBSite();
3320 float oriDis = std::abs(PUId2NeighborSite[tmpPU->getId()]->X() - tmpPU->X()) +
3321 y2xRatio * std::abs(PUId2NeighborSite[tmpPU->getId()]->Y() - tmpPU->Y());
3322 float newDis = std::abs(packingSite->getCLBSite()->X() - tmpPU->X()) +
3323 y2xRatio * std::abs(packingSite->getCLBSite()->Y() - tmpPU->Y());
3324 if (oriDis > newDis)
3326 PUId2NeighborSite[tmpPU->getId()] = packingSite->getCLBSite();
3333 print_info(
"#mappedPUCnt = " + std::to_string(mappedPUCnt));
3337 print_status(
"ParallelCLBPacker: dumping unpackable PUs archieve to: " + dumpFile);
3338 std::stringstream outfile1;
3340 int PUNeedMappingCnt = 0;
3341 std::set<PlacementInfo::PlacementUnit *, Packing_PUcompare> dumpedPUs;
3345 if (tmpCell->isLUT() || tmpCell->isFF())
3348 if (tmpPU->isPacked())
3358 if (dumpedPUs.find(tmpPU) != dumpedPUs.end())
3360 dumpedPUs.insert(tmpPU);
3365 if (PUId2NeighborSite[tmpPU->getId()])
3367 outfile1 <<
"candidate neighbor site: " << PUId2NeighborSite[tmpPU->getId()]->
getName()
3368 <<
" X:" << PUId2NeighborSite[tmpPU->getId()]->X()
3369 <<
" Y:" << PUId2NeighborSite[tmpPU->getId()]->Y() <<
"\n";
3376 std::vector<DeviceInfo::DeviceSite *> *candidateSites =
3378 if (candidateSites->size())
3380 for (
auto tmpSite : *candidateSites)
3382 if (!PUId2NeighborSite[tmpPU->getId()])
3384 PUId2NeighborSite[tmpPU->getId()] = tmpSite;
3388 float oriDis = std::abs(PUId2NeighborSite[tmpPU->getId()]->X() - tmpPU->X()) +
3389 y2xRatio * std::abs(PUId2NeighborSite[tmpPU->getId()]->Y() - tmpPU->Y());
3390 float newDis = std::abs(tmpSite->X() - tmpPU->X()) +
3391 y2xRatio * std::abs(tmpSite->Y() - tmpPU->Y());
3392 if (oriDis > newDis)
3394 PUId2NeighborSite[tmpPU->getId()] = tmpSite;
3399 delete candidateSites;
3400 outfile1 <<
"closed neighbor site: " << PUId2NeighborSite[tmpPU->getId()]->getName()
3401 <<
" X:" << PUId2NeighborSite[tmpPU->getId()]->X()
3402 <<
" Y:" << PUId2NeighborSite[tmpPU->getId()]->Y() <<
"\n";
3410 print_status(
"ParallelCLBPacker: dumped unpackable PUs archieve to: " + dumpFile);
3411 print_info(
"#PUNeedMappingCnt = " + std::to_string(PUNeedMappingCnt));
3413 print_status(
"ParallelCLBPacker: dumping placementTcl archieve to: " + dumpTclFile);
3415 print_status(
"ParallelCLBPacker: dumped placementTcl archieve to: " + dumpTclFile);
3424 std::string dumpFile =
3426 print_status(
"GlobalPlacer: dumping coordinate archieve to: " + dumpFile);
3430 std::stringstream outfile0;
3435 float cellX = curUnpackedCell->X();
3436 float cellY = curUnpackedCell->Y();
3438 outfile0 << cellX <<
" " << cellY <<
" " << curCell->
getName() <<
"\n";
3442 for (
int vId = 0; vId < curMacro->getNumOfCells(); vId++)
3444 float offsetX_InMacro, offsetY_InMacro;
3446 curMacro->getVirtualCellInfo(vId, offsetX_InMacro, offsetY_InMacro, cellType);
3447 float cellX = curMacro->X() + offsetX_InMacro;
3448 float cellY = curMacro->Y() + offsetY_InMacro;
3450 if (curMacro->getCell(vId))
3451 outfile0 << cellX <<
" " << cellY <<
" " << curMacro->getCell(vId)->getName() <<
"\n";
3453 outfile0 << cellX <<
" " << cellY <<
"\n";
3458 print_status(
"GlobalPlacer: dumped coordinate archieve to: " + dumpFile);