37 std::map<std::string, std::string> &JSONCfg)
38 : designInfo(designInfo), deviceInfo(deviceInfo), JSONCfg(JSONCfg)
73 for (
auto curClockRegion : curClockRegionRow)
75 for (
auto curColRows : curClockRegion->getClockColumns())
77 for (
auto curCol : curColRows)
91 std::string cellType2sharedCellTypeFileName,
92 std::string sharedCellType2BELtypeFileName,
94 : designInfo(designInfo), deviceInfo(deviceInfo)
108 std::set<std::string>::iterator typeIt;
117 assert(infile0.good() &&
"cellType2fixedAmoFile file does not exist and please check your path settings");
121 std::string cellTypeStr;
123 std::string CompatiblePlacementTableLoading =
"CompatiblePlacementTableLoading";
125 while (std::getline(infile0,
line))
127 std::istringstream iss(
line);
128 iss >> cellTypeStr >> occupationAmo;
138 std::cout <<
"cellType: " << tmppair.first
139 <<
" is not defined with resource demand. Check your compatibale table setting.\n";
142 "each type should be defined with resource demand.");
147 assert(infile1.good() &&
"cellType2sharedCellType file does not exist and please check your path settings");
148 std::string cell2BELType;
150 std::set<std::string> involvedSharedBELStr;
151 involvedSharedBELStr.clear();
153 while (std::getline(infile1,
line))
155 std::istringstream iss(
line);
156 iss >> cellTypeStr >> cell2BELType;
157 std::vector<std::string> cellTypeStrVec;
158 strSplit(cellTypeStr, cellTypeStrVec,
",");
159 std::vector<std::string> BELTypeStrVec;
160 strSplit(cell2BELType, BELTypeStrVec,
",");
162 for (
auto tmpCellTypeStr : cellTypeStrVec)
169 for (
auto tmpSharedBELStr : BELTypeStrVec)
171 involvedSharedBELStr.insert(tmpSharedBELStr);
178 for (
auto tmpCellTypeStr : cellTypeStrVec)
185 for (
auto tmpSharedBELStr : BELTypeStrVec)
193 assert(infile2.good() &&
"sharedCellType2BELtype file does not exist and please check your path settings");
194 std::string compatibleBELTypeStrs, sharedCellTypeStr, siteTypeStr;
196 while (std::getline(infile2,
line))
198 std::istringstream iss(
line);
199 iss >> sharedCellTypeStr >> siteTypeStr >> compatibleBELTypeStrs;
200 std::vector<std::string> CompatibleBELStrVec;
201 strSplit(compatibleBELTypeStrs, CompatibleBELStrVec,
",");
205 print_info(
"There are " + std::to_string(CompatibleBELStrVec.size()) +
" slot(s) in a site for cell type : (" +
206 sharedCellTypeStr +
"). They are :" + compatibleBELTypeStrs);
209 for (
auto it = involvedSharedBELStr.begin(); it != involvedSharedBELStr.end(); it++)
224 assert(cellId2SharedCellBELTypeID[cell->getCellId()].size() == 0);
226 cellId2Occupation[cell->getCellId()] = cellType2sharedBELTypeOccupation[cell->getCellType()];
227 cellId2InfationRatio[cell->getCellId()] = 1.0;
228 for (
auto sharedBELTypeStr : cellType2sharedBELTypes[cell->getCellType()])
232 cellId2SharedCellBELTypeID[cell->getCellId()].push_back(sharedBELTypeID);
235 assert(cellId2SharedCellBELTypeID[cell->getCellId()].size() != 0);
237 defaultCellId2Occupation = cellId2Occupation;
243 cellId2Occupation = defaultCellId2Occupation;
244 for (
unsigned int i = 0;
i < cellId2Occupation.size();
i++)
246 cellId2InfationRatio[
i] = 1.0;
253 for (
auto curSite :
sites)
255 if (curSite->X() < minX)
264 for (
auto curSite :
sites)
266 if (curSite->Y() < minY)
274 float maxX = -100000;
275 for (
auto curSite :
sites)
277 if (curSite->X() > maxX)
285 float maxY = -100000;
286 for (
auto curSite :
sites)
288 if (curSite->Y() > maxY)
302 print_info(
"Total Macro Placement Unit(s): " +
310 if (inRange(curSite->
X(), curSite->
Y()))
312 correspondingSites.push_back(curSite);
318 print_error(
"leftX: " + std::to_string(leftX) +
"rightX: " + std::to_string(rightX) +
319 "topY: " + std::to_string(topY) +
"bottomY: " + std::to_string(bottomY));
321 assert(
false &&
"some sites are out of the scope");
339 for (
auto &tmpRow : tmpBinGrid)
340 for (
auto &curBin : tmpRow)
349 for (
auto &curBin : tmpRow)
357 for (
auto &curBin : tmpRow)
367 float curBottomY, curLeftX;
370 std::vector<std::vector<PlacementBinInfo *>> tmpSharedBELGrid;
371 tmpSharedBELGrid.clear();
374 std::vector<PlacementBinInfo *> tmpBELGridRow;
375 tmpBELGridRow.clear();
380 tmpBELGridRow.push_back(newBin);
382 tmpSharedBELGrid.push_back(tmpBELGridRow);
392 std::vector<PlacementBinInfo *> tmpBELGridRow;
393 tmpBELGridRow.clear();
394 std::vector<PlacementBinInfo *> tmpGlobalBELGridRow;
395 tmpGlobalBELGridRow.clear();
404 tmpBELGridRow.push_back(newBin);
405 tmpGlobalBELGridRow.push_back(globalNewBin);
411 std::set<DeviceInfo::DeviceSite *> countedSites;
412 countedSites.clear();
419 print_error(sharedBELStr +
" is not found in sharedCellType2SiteType.");
423 print_error(
"sharedCellType2SiteType Key: " + it->first);
436 unsigned int siteIndex = 0;
444 sitesInType[siteIndex]->
Y()))
448 if (actualSharedBELTypeId != targetSharedBELTypeId)
450 countedSites.insert(sitesInType[siteIndex]);
452 if (siteIndex >= sitesInType.size())
455 if (siteIndex >= sitesInType.size())
458 if (siteIndex >= sitesInType.size())
461 if (siteIndex >= sitesInType.size())
479 std::set<std::string> siteTypeNotMapped;
484 if (countedSites.find(site) == countedSites.end() &&
485 siteTypeNotMapped.find(site->getSiteType()) == siteTypeNotMapped.end())
487 print_warning(
"Site Type (" + site->getSiteType() +
") is not mapped to bin grid. e.g. [" +
489 "]. It might be not critical if the design will not utilize this kind of sites. Please "
490 "check the compatible table you defined.");
491 siteTypeNotMapped.insert(site->getSiteType());
497 std::string SLICEL_LUT_STR =
"SLICEL_LUT";
499 "Bin Grid Size: Y: " +
523 bool isInternalNet =
true;
524 for (
auto tmpPU : newPNet->
getUnits())
530 if (PUInNet != tmpPU)
532 isInternalNet =
false;
547 std::vector<std::set<PlacementNet *>> placementUnitId2NetSet;
548 placementUnitId2NetSet.clear();
549 placementUnitId2NetSet.resize(
placementUnits.size(), std::set<PlacementNet *>());
555 for (
auto curPU : curNet->getUnits())
557 if (placementUnitId2NetSet[curPU->getId()].find(curNet) == placementUnitId2NetSet[curPU->getId()].end())
559 placementUnitId2NetSet[curPU->getId()].insert(curNet);
575 if (curPU->hasRegister())
585 for (
int i = 0;
i <= 7;
i++)
590 bool overflow =
true;
592 for (
i = 0;
i < 7;
i++)
607 std::string outputStr =
"net interconnection density: ";
608 for (
int i = 0;
i <= 7;
i++)
638 std::set<PlacementUnit *> visitedPUs;
643 int restartNum = 1000000;
644 int pathMexLen = 100;
646 for (
int restartIter = 0; restartIter < restartNum; restartIter++)
653 std::vector<PlacementUnit *> curPath(0);
654 curPath.push_back(curPU);
657 for (
int pathEleId = 0; pathEleId < pathMexLen; pathEleId++)
659 std::vector<PlacementNet *> outputNets;
663 if (curNet->getDriverUnits().size() == 1)
665 if (curNet->getDriverUnits()[0] == curPU && curNet->getUnitsBeDriven().size() > 0)
667 outputNets.push_back(curNet);
673 if (outputNets.size())
678 auto selectedNet = outputNets[random() % outputNets.size()];
681 selectedNet->getUnitsBeDriven()[random() * random() % selectedNet->getUnitsBeDriven().size()];
683 if (curPU == nextPU || !nextPU->
hasLogic() || visitedPUs.find(nextPU) != visitedPUs.end())
696 curPath.push_back(nextPU);
703 if (curPath.size() > 5)
706 for (
unsigned int i = 1;
i < curPath.size() - 1;
i++)
708 visitedPUs.insert(curPath[
i]);
714 [](
const std::vector<PlacementUnit *> &a,
const std::vector<PlacementUnit *> &b) ->
bool {
715 return a.size() > b.size();
728 float totalWeight = 0;
731 for (
auto tmpPU : path)
734 if (tmpPU->checkHasBRAM() || tmpPU->checkHasCARRY() || tmpPU->checkHasDSP())
744 totalX += tmpPU->X() * curWeight;
745 totalY += tmpPU->Y() * curWeight;
747 float avgX = totalX / totalWeight;
748 float avgY = totalY / totalWeight;
749 for (
auto tmpPU : path)
751 if (tmpPU->checkHasDSP() || tmpPU->checkHasBRAM())
753 tmpPU->setAnchorLocationAndForgetTheOriginalOne(avgX, avgY);
762 std::vector<std::pair<float, float>> nodexy;
763 std::vector<std::pair<int, int>>
lines;
764 for (
unsigned int pinId_net = 0; pinId_net < unitsOfNetPins.size(); pinId_net++)
766 auto tmpPU = unitsOfNetPins[pinId_net];
767 auto tmpPinOffset = pinOffsetsInUnit[pinId_net];
768 float curX = tmpPU->X() + tmpPinOffset.x;
769 float curY = tmpPU->Y() + tmpPinOffset.y;
770 nodexy.push_back(std::pair<float, float>(curX, curY));
772 lines.push_back(std::pair<int, int>(leftPinId_net, rightPinId_net));
773 lines.push_back(std::pair<int, int>(bottomPinId_net, bottomPinId_net));
775 for (
unsigned int pinId_net = 0; pinId_net < unitsOfNetPins.size(); pinId_net++)
777 if (pinId_net != leftPinId_net && pinId_net != rightPinId_net)
779 lines.push_back(std::pair<int, int>(leftPinId_net, pinId_net));
780 lines.push_back(std::pair<int, int>(rightPinId_net, pinId_net));
782 if (pinId_net != topPinId_net && pinId_net != bottomPinId_net)
784 lines.push_back(std::pair<int, int>(bottomPinId_net, pinId_net));
785 lines.push_back(std::pair<int, int>(topPinId_net, pinId_net));
797 "all cells in the design should be placable in the device.");
799 print_status(
"Device Information Verified for Design Information");
815 os <<
"Macro: " << curMacro->
getId() <<
" " << curMacro->
getName() <<
"\n";
818 os <<
" macroType: PlacementMacroType_LUTFFPair\n";
820 os <<
" macroType: PlacementMacroType_FFFFPair\n";
822 os <<
" macroType: PlacementMacroType_HALFCLB\n";
824 os <<
" macroType: PlacementMacroType_LCLB\n";
826 os <<
" macroType: PlacementMacroType_MCLB\n";
828 os <<
" macroType: PlacementMacroType_CARRY\n";
830 os <<
" macroType: PlacementMacroType_DSP\n";
832 os <<
" macroType: PlacementMacroType_BRAM\n";
834 os <<
" macroType: PlacementMacroType_MUX7\n";
836 os <<
" macroType: PlacementMacroType_MUX8\n";
838 os <<
" macroType: PlacementMacroType_LUTLUTSeires\n";
840 assert(
false &&
"undefined macro type.");
842 os <<
" placedAt: " << curMacro->
X() <<
" " << curMacro->
Y() <<
"\n";
843 os <<
" isPlaced: " << curMacro->
isPlaced() <<
"\n";
844 os <<
" isFixed: " << curMacro->
isFixed() <<
"\n";
845 os <<
" isLocked: " << curMacro->
isLocked() <<
"\n";
849 os <<
" numCell: " << curMacro->
getCells().size() <<
"\n";
850 for (
unsigned int i = 0;
i < curMacro->
getCells().size();
i++)
871 os <<
"UnpackedCell: " << curUnpackedCell->
getId() <<
" " << curUnpackedCell->
getName() <<
"\n";
874 os <<
" placedAt: " << curUnpackedCell->
X() <<
" " << curUnpackedCell->
Y() <<
"\n";
875 os <<
" isPlaced: " << curUnpackedCell->
isPlaced() <<
"\n";
876 os <<
" isFixed: " << curUnpackedCell->
isFixed() <<
"\n";
877 os <<
" isLocked: " << curUnpackedCell->
isLocked() <<
"\n";
878 if (curUnpackedCell->
isFixed())
894 assert(
false &&
"placement unit type error.");
901 for (
auto &curRow : typeGrid)
902 for (
auto curBin : curRow)
916 float cellX = curUnpackedCell->X();
917 float cellY = curUnpackedCell->Y();
925 assert(num_cellOccupationBELs >= 0);
927 bool nonOverflow =
false;
932 assert((
unsigned int)binIdY <
getBinGrid(SharedBELID).size());
933 assert((
unsigned int)binIdX <
getBinGrid(SharedBELID)[binIdY].size());
934 if (!
getBinGrid(SharedBELID)[binIdY][binIdX]->inRange(cellX, cellY))
936 std::cout <<
"cellX=" << cellX <<
"\n";
937 std::cout <<
"cellY=" << cellY <<
"\n";
938 std::cout <<
"left=" <<
getBinGrid(SharedBELID)[binIdY][binIdX]->left() <<
"\n";
939 std::cout <<
"right=" <<
getBinGrid(SharedBELID)[binIdY][binIdX]->right() <<
"\n";
940 std::cout <<
"top=" <<
getBinGrid(SharedBELID)[binIdY][binIdX]->top() <<
"\n";
941 std::cout <<
"bottom=" <<
getBinGrid(SharedBELID)[binIdY][binIdX]->bottom() <<
"\n";
944 assert(
getBinGrid(SharedBELID)[binIdY][binIdX]->inRange(cellX, cellY));
945 if (
getBinGrid(SharedBELID)[binIdY][binIdX]->canAddMore(num_cellOccupationBELs))
947 getBinGrid(SharedBELID)[binIdY][binIdX]->addCell(curCell, num_cellOccupationBELs);
956 num_cellOccupationBELs);
958 num_cellOccupationBELs);
963 for (
int vId = 0; vId < curMacro->getNumOfCells(); vId++)
965 float offsetX_InMacro, offsetY_InMacro;
967 curMacro->getVirtualCellInfo(vId, offsetX_InMacro, offsetY_InMacro, cellType);
971 float cellX = curMacro->X() + offsetX_InMacro;
972 float cellY = curMacro->Y() + offsetY_InMacro;
977 assert(num_cellOccupationBELs >= 0);
978 bool nonOverflow =
false;
987 assert((
unsigned int)binIdY <
getBinGrid(SharedBELID).size());
988 assert((
unsigned int)binIdX <
getBinGrid(SharedBELID)[binIdY].size());
989 assert(
getBinGrid(SharedBELID)[binIdY][binIdX]->inRange(cellX, cellY));
990 if (
getBinGrid(SharedBELID)[binIdY][binIdX]->canAddMore(num_cellOccupationBELs))
993 getBinGrid(SharedBELID)[binIdY][binIdX]->addCell(curCell, num_cellOccupationBELs);
1003 num_cellOccupationBELs);
1005 num_cellOccupationBELs);
1018 for (
auto &curBin : tmpRow)
1030 float cellX = curUnpackedCell->X();
1031 float cellY = curUnpackedCell->Y();
1034 if (curCell->
isLUT() || curCell->
isFF())
1036 getGridXY(cellX, cellY, binIdX, binIdY);
1037 assert(
globalBinGrid[binIdY][binIdX]->inRange(cellX, cellY));
1038 assert(binIdY >= 0);
1039 assert(binIdX >= 0);
1041 assert((
unsigned int)binIdX <
globalBinGrid[binIdY].size());
1047 for (
int vId = 0; vId < curMacro->getNumOfCells(); vId++)
1049 float offsetX_InMacro, offsetY_InMacro;
1051 curMacro->getVirtualCellInfo(vId, offsetX_InMacro, offsetY_InMacro, cellType);
1053 if (curCell->
isLUT() || curCell->
isFF())
1056 float cellX = curMacro->X() + offsetX_InMacro;
1057 float cellY = curMacro->Y() + offsetY_InMacro;
1059 getGridXY(cellX, cellY, binIdX, binIdY);
1060 assert(
globalBinGrid[binIdY][binIdX]->inRange(cellX, cellY));
1062 assert(binIdY >= 0);
1063 assert(binIdX >= 0);
1065 assert((
unsigned int)binIdX <
globalBinGrid[binIdY].size());
1077 bool doUpdate =
false;
1091 print_status(
"PlacementInfo: adjusting LUT/FF utilization based on Packablity");
1093 for (
auto curBin : curRow)
1101 float cellX = curUnpackedCell->X();
1102 float cellY = curUnpackedCell->Y();
1105 if (curCell->
isLUT() || curCell->
isFF())
1107 getGridXY(cellX, cellY, binIdX, binIdY);
1108 assert(
LUTFFBinGrid[binIdY][binIdX]->inRange(cellX, cellY));
1109 assert(binIdY >= 0);
1110 assert(binIdX >= 0);
1112 assert((
unsigned int)binIdX <
LUTFFBinGrid[binIdY].size());
1121 for (
int vId = 0; vId < curMacro->getNumOfCells(); vId++)
1123 float offsetX_InMacro, offsetY_InMacro;
1125 curMacro->getVirtualCellInfo(vId, offsetX_InMacro, offsetY_InMacro, cellType);
1127 if (curCell->
isLUT() || curCell->
isFF())
1130 float cellX = curMacro->X() + offsetX_InMacro;
1131 float cellY = curMacro->Y() + offsetY_InMacro;
1133 getGridXY(cellX, cellY, binIdX, binIdY);
1134 assert(
LUTFFBinGrid[binIdY][binIdX]->inRange(cellX, cellY));
1136 assert(binIdY >= 0);
1137 assert(binIdX >= 0);
1139 assert((
unsigned int)binIdX <
LUTFFBinGrid[binIdY].size());
1149 unsigned int cellNum =
getCells().size();
1151 #pragma omp parallel for schedule(dynamic)
1152 for (
unsigned int cellId = 0; cellId < cellNum; cellId++)
1155 int cellRealId = curCell->getCellId();
1157 if (curCell->isLUT())
1159 std::vector<DesignInfo::DesignCell *> *neighborCells =
1161 assert(neighborCells->size());
1162 int pairableCnt = 0;
1163 float tmpRatio = -1;
1165 if (deteminted >= 0)
1167 compatiblePlacementTable_cellId2Occupation[curCell->getCellId()] = deteminted;
1171 if (curCell->getInputPins().size() <= 5 && !curCell->isLUT6())
1173 int totalNumNeighborCells = neighborCells->size();
1174 for (
auto neighborLUT : *neighborCells)
1178 totalNumNeighborCells--;
1181 if (neighborLUT->getInputPins().size() <= 5 && !neighborLUT->isLUT6() && curCell != neighborLUT)
1189 assert(totalNumNeighborCells > 0);
1190 if (totalNumNeighborCells == 1 || pairableCnt == 0)
1193 tmpRatio = std::pow((
float)pairableCnt / (
float)(totalNumNeighborCells - 1), 0.3);
1194 assert(tmpRatio <= 1 && tmpRatio >= 0);
1200 float areaDemand = (float)(1 * tmpRatio + 2 * (1 - tmpRatio));
1201 compatiblePlacementTable_cellId2Occupation[cellRealId] = areaDemand * 1.15;
1205 compatiblePlacementTable_cellId2Occupation[cellRealId] = 2.2;
1208 assert(compatiblePlacementTable_cellId2Occupation[cellRealId] >= 0);
1209 delete neighborCells;
1211 else if (curCell->isFF())
1213 if (!curCell->getControlSetInfo())
1215 assert(curCell->isVirtualCell());
1216 compatiblePlacementTable_cellId2Occupation[cellRealId] = 1;
1219 assert(!curCell->isVirtualCell());
1220 std::vector<DesignInfo::DesignCell *> *neighborCells =
1222 assert(neighborCells->size());
1223 std::map<int, int> CSId2Cnt;
1224 int targetControlSetId = curCell->getControlSetInfo()->getId();
1225 for (
auto neighborFF : *neighborCells)
1227 if (neighborFF->isVirtualCell())
1229 if (neighborFF->getControlSetInfo()->getCLK() == curCell->getControlSetInfo()->getCLK() &&
1230 neighborFF->getControlSetInfo()->getSR() == curCell->getControlSetInfo()->getSR())
1231 CSId2Cnt[neighborFF->getControlSetInfo()->getId()] = 0;
1233 for (
auto neighborFF : *neighborCells)
1235 if (neighborFF->isVirtualCell())
1240 if (neighborFF->getControlSetInfo()->getCLK() == curCell->getControlSetInfo()->getCLK() &&
1241 neighborFF->getControlSetInfo()->getSR() == curCell->getControlSetInfo()->getSR())
1242 CSId2Cnt[neighborFF->getControlSetInfo()->getId()]++;
1244 int totalDemand = 0;
1245 int targetFFNum = CSId2Cnt[targetControlSetId];
1246 int targetDemand = (1 + ((targetFFNum - 1) / 4));
1247 for (
auto CSIdCntpair : CSId2Cnt)
1249 totalDemand += (1 + ((CSIdCntpair.second - 1) / 4));
1251 int factor = (1 + ((totalDemand - 1) / 2));
1252 const float alpha = 1.3;
1253 assert(totalDemand > 0);
1254 assert(targetFFNum > 0);
1257 alpha * 8.0 * ((float)targetDemand) / ((float)totalDemand) * (float)factor / (
float)(targetFFNum);
1258 if (areaDemand > 1.5)
1264 compatiblePlacementTable_cellId2Occupation[cellRealId] = areaDemand;
1265 assert(compatiblePlacementTable_cellId2Occupation[cellRealId] >= 0);
1266 delete neighborCells;
1269 print_status(
"PlacementInfo: adjusted LUT/FF utilization based on Packablity");
1275 print_status(
"PlacementInfo: adjusting LUT/FF utilization based on Routability");
1282 int leftBinX, rightBinX, topBinY, bottomBinY;
1283 getGridXY(tmpNet->getLeftPinX(), tmpNet->getBottomPinY(), leftBinX, bottomBinY);
1284 getGridXY(tmpNet->getRightPinX(), tmpNet->getTopPinY(), rightBinX, topBinY);
1286 assert(bottomBinY >= 0);
1287 assert(leftBinX >= 0);
1289 assert((
unsigned int)leftBinX <
globalBinGrid[bottomBinY].size());
1290 assert(topBinY >= 0);
1291 assert(rightBinX >= 0);
1293 assert((
unsigned int)rightBinX <
globalBinGrid[topBinY].size());
1295 float totW = tmpNet->getHPWL(
y2xRatio) + 0.5;
1296 unsigned int nPins = tmpNet->getPinOffsetsInUnit().size();
1299 else if (nPins < 20)
1301 else if (nPins < 30)
1303 else if (nPins < 50)
1305 else if (nPins < 100)
1307 else if (nPins < 200)
1312 int numGCell = (rightBinX - leftBinX + 1) * (topBinY - bottomBinY + 1) *
binHeight *
binWidth;
1313 float indW = totW / numGCell;
1314 for (
int x = leftBinX;
x <= rightBinX; ++
x)
1315 for (
int y = bottomBinY;
y <= topBinY; ++
y)
1319 std::vector<float> &compatiblePlacementTable_cellId2InfationRatio =
1322 std::vector<std::vector<PlacementInfo::PlacementBinInfo *>> &LUTBinGrid =
getBinGrid(LUTTypeBELIds[0]);
1324 std::vector<std::vector<PlacementInfo::PlacementBinInfo *>> &FFBinGrid =
getBinGrid(FFTypeBELIds[0]);
1326 for (
unsigned int i = 0;
i <
getCells().size();
i++)
1328 compatiblePlacementTable_cellId2InfationRatio[
i] = std::sqrt(compatiblePlacementTable_cellId2InfationRatio[
i]);
1331 std::vector<PlacementInfo::PlacementBinInfo *> bins;
1334 for (
auto &curBin : tmpRow)
1337 bins.push_back(curBin);
1340 std::sort(bins.begin(), bins.end(),
1342 return a->getSwitchDemandForNets() > b->getSwitchDemandForNets();
1346 for (
auto &curBin : bins)
1350 if (curBin->getSwitchDemandForNets() > 80 && binOrderId < bins.size() * 0.3)
1352 float infateRatio = 2 * (curBin->getSwitchDemandForNets() / 80);
1353 if (infateRatio > 4)
1355 for (
auto tmpCell : curBin->getCells())
1357 assert(tmpCell->isLUT() || tmpCell->isFF());
1358 compatiblePlacementTable_cellId2InfationRatio[tmpCell->getCellId()] = infateRatio;
1360 float LUTSupplyRatio = LUTBinGrid[curBin->Y()][curBin->X()]->getRequiredBinShrinkRatio() * 0.9;
1361 float FFSupplyRatio = FFBinGrid[curBin->Y()][curBin->X()]->getRequiredBinShrinkRatio() * 0.9;
1362 if (LUTSupplyRatio > 0.7)
1363 LUTBinGrid[curBin->Y()][curBin->X()]->setRequiredBinShrinkRatio(LUTSupplyRatio);
1364 if (FFSupplyRatio > 0.7)
1365 FFBinGrid[curBin->Y()][curBin->X()]->setRequiredBinShrinkRatio(FFSupplyRatio);
1369 else if (curBin->getSwitchDemandForNets() < 50 || binOrderId > bins.size() * 0.5)
1371 if (LUTBinGrid[curBin->Y()][curBin->X()]->getRequiredBinShrinkRatio() < 0.999)
1373 LUTBinGrid[curBin->Y()][curBin->X()]->setRequiredBinShrinkRatio(1);
1374 FFBinGrid[curBin->Y()][curBin->X()]->setRequiredBinShrinkRatio(1);
1377 else if (curBin->getSwitchDemandForNets() < 55)
1379 if (LUTBinGrid[curBin->Y()][curBin->X()]->getRequiredBinShrinkRatio() < 0.999)
1381 float LUTSupplyRatio = LUTBinGrid[curBin->Y()][curBin->X()]->getRequiredBinShrinkRatio() * 1.05;
1382 if (LUTSupplyRatio > 1)
1384 float FFSupplyRatio = FFBinGrid[curBin->Y()][curBin->X()]->getRequiredBinShrinkRatio() * 1.05;
1385 if (FFSupplyRatio > 1)
1387 LUTBinGrid[curBin->Y()][curBin->X()]->setRequiredBinShrinkRatio(LUTSupplyRatio);
1388 FFBinGrid[curBin->Y()][curBin->X()]->setRequiredBinShrinkRatio(FFSupplyRatio);
1391 else if (curBin->getSwitchDemandForNets() < 70)
1393 if (LUTBinGrid[curBin->Y()][curBin->X()]->getRequiredBinShrinkRatio() < 0.999)
1395 float LUTSupplyRatio = LUTBinGrid[curBin->Y()][curBin->X()]->getRequiredBinShrinkRatio() * 1.025;
1396 if (LUTSupplyRatio > 1)
1398 float FFSupplyRatio = FFBinGrid[curBin->Y()][curBin->X()]->getRequiredBinShrinkRatio() * 1.025;
1399 if (FFSupplyRatio > 1)
1401 LUTBinGrid[curBin->Y()][curBin->X()]->setRequiredBinShrinkRatio(LUTSupplyRatio);
1402 FFBinGrid[curBin->Y()][curBin->X()]->setRequiredBinShrinkRatio(FFSupplyRatio);
1406 print_status(
"PlacementInfo: adjusted LUT/FF utilization based on Routability");
1411 print_status(
"PlacementInfo: adjusting FF utilization based on Clock Utilization");
1413 float infateRatio = 1.5;
1414 std::vector<float> &compatiblePlacementTable_cellId2InfationRatio =
1419 std::set<int> addedCells;
1424 std::vector<std::vector<PlacementInfo::PlacementBinInfo *>> &FFBinGrid =
getBinGrid(FFTypeBELIds[0]);
1426 std::vector<std::vector<PlacementInfo::PlacementBinInfo *>> &LUTBinGrid =
getBinGrid(LUTTypeBELIds[0]);
1428 std::set<std::pair<int, int>> clockRegion2Inflat;
1429 clockRegion2Inflat.clear();
1435 for (
auto &row : clockRegions[
i][j]->getClockColumns())
1437 for (
auto clockColumn : row)
1442 for (
auto &pair : clockColumn->getClockNetId2CellIds())
1444 for (
auto cellId : pair.second)
1446 assert(cellId < (
int)cells.size());
1447 if (cells[cellId]->isFF())
1449 if (addedCells.find(cellId) == addedCells.end())
1451 if (compatiblePlacementTable_cellId2InfationRatio[cellId] < 4)
1452 compatiblePlacementTable_cellId2InfationRatio[cellId] *= infateRatio;
1453 addedCells.insert(cellId);
1454 std::pair<int, int> rloc(
i, j);
1455 clockRegion2Inflat.insert(rloc);
1469 for (
auto &tmpRow : FFBinGrid)
1471 for (
auto curBin : tmpRow)
1473 int clockRegionX, clockRegionY;
1475 (curBin->top() + curBin->bottom()) / 2, clockRegionX,
1477 std::pair<int, int> rloc(clockRegionY, clockRegionX);
1478 if (clockRegion2Inflat.find(rloc) != clockRegion2Inflat.end())
1481 if (curBin->getRequiredBinShrinkRatio() > 0.75)
1483 curBin->setRequiredBinShrinkRatio(curBin->getRequiredBinShrinkRatio() * 0.75);
1488 for (
auto &tmpRow : LUTBinGrid)
1490 for (
auto curBin : tmpRow)
1492 int clockRegionX, clockRegionY;
1494 (curBin->top() + curBin->bottom()) / 2, clockRegionX,
1496 std::pair<int, int> rloc(clockRegionY, clockRegionX);
1497 if (clockRegion2Inflat.find(rloc) != clockRegion2Inflat.end())
1499 if (curBin->getRequiredBinShrinkRatio() > 0.75)
1501 curBin->setRequiredBinShrinkRatio(curBin->getRequiredBinShrinkRatio() * 0.85);
1506 print_status(
"PlacementInfo: adjusted FF utilization based on Clock Utilization. " + std::to_string(
cnt) +
1507 " bins have been shrinked.");
1514 std::vector<float> &compatiblePlacementTable_cellId2InfationRatio =
1517 std::vector<std::vector<PlacementInfo::PlacementBinInfo *>> &LUTBinGrid =
getBinGrid(LUTTypeBELIds[0]);
1519 std::vector<std::vector<PlacementInfo::PlacementBinInfo *>> &FFBinGrid =
getBinGrid(FFTypeBELIds[0]);
1521 for (
unsigned int i = 0;
i <
getCells().size();
i++)
1523 compatiblePlacementTable_cellId2InfationRatio[
i] = 1.0;
1525 for (
auto &tmpRow : LUTBinGrid)
1527 for (
auto &curBin : tmpRow)
1530 curBin->setRequiredBinShrinkRatio(1);
1533 for (
auto &tmpRow : FFBinGrid)
1535 for (
auto &curBin : tmpRow)
1538 curBin->setRequiredBinShrinkRatio(1);
1541 print_status(
"PlacementInfo: Routability-oriented area adjustion is reset.");
1546 if (neighborDisplacementUpperbound > 0)
1548 print_status(
"PlacementInfo: adjusting LUT/FF Utilization");
1550 print_status(
"PlacementInfo: adjusted LUT/FF Utilization");
1564 dumpFileName = dumpFileName;
1565 print_status(
"PlacementInfo: dumping congestion rate to: " + dumpFileName);
1566 std::vector<std::vector<PlacementInfo::PlacementBinInfo *>> &curBinGrid =
globalBinGrid;
1568 std::ofstream outfile0(dumpFileName.c_str());
1569 assert(outfile0.is_open() && outfile0.good() &&
1570 "The path for congestion dumping does not exist and please check your path settings");
1571 for (
auto &row : curBinGrid)
1573 for (
auto curBin : row)
1575 outfile0 << curBin->getSwitchDemandForNets() <<
" ";
1585 std::vector<std::string> checkSiteNameList{
"SLICEL",
"SLICEM"};
1589 float curBottomY, curLeftX;
1593 std::vector<PlacementSiteBinInfo *> tmpBELGridRow;
1594 tmpBELGridRow.clear();
1599 tmpBELGridRow.push_back(newBin);
1604 for (std::string targetSiteType : checkSiteNameList)
1608 unsigned int siteIndex = 0;
1615 while (
siteGridForMacros[
i][j]->inRange(sitesInType[siteIndex]->
X(), sitesInType[siteIndex]->
Y()))
1619 if (siteIndex >= sitesInType.size())
1622 if (siteIndex >= sitesInType.size())
1625 if (siteIndex >= sitesInType.size())
1628 if (siteIndex >= sitesInType.size())
1636 if (inRange(curSite->
X(), curSite->
Y()))
1638 correspondingSites.push_back(curSite);
1643 print_error(
"leftX: " + std::to_string(leftX) +
"rightX: " + std::to_string(rightX) +
1644 "topY: " + std::to_string(topY) +
"bottomY: " + std::to_string(bottomY));
1646 assert(
false &&
"some sites are out of the scope");
1653 for (
auto curBin : curRow)
1659 assert(
false &&
"unimplemented");
1698 print_status(
"PlacementInfo: dumping placment Tcl commands archieve to: " + dumpFile);
1726 print_status(
"PlacementInfo: dumping PU information archieve to: " + dumpFile);
1730 std::stringstream outfile0;
1740 outfile0 <<
"PULegalization: " << PUSitePair.first->getId() <<
" ";
1741 std::vector<DeviceInfo::DeviceSite *> tmpSites = PUSitePair.second;
1742 for (
unsigned int tmpId = 0; tmpId < tmpSites.size() - 1; tmpId++)
1743 outfile0 << tmpSites[tmpId]->getName() <<
",";
1744 outfile0 << tmpSites[tmpSites.size() - 1]->getName() <<
"\n";
1747 print_status(
"PlacementInfo: dumped PU information archieve to: " + dumpFile);
1754 print_status(
"loading PU coordinate archieve from: " + locFile);
1755 print_warning(
"Please note that the loaded PU location information should be compatible with the other"
1756 "information in the placer! Otherwise, there could be potential errors");
1758 "E.g., the initial packing which creates virtual cells should be done. The bin grid for all cell types "
1759 "should be created.");
1764 std::string unzipCmnd =
"gzip -c -d " + locFile;
1766 struct stat checkbuf;
1767 assert(stat(locFile.c_str(), &checkbuf) != -1);
1769 FILEbuf sbuf(popen(unzipCmnd.c_str(),
"r"));
1770 std::istream infile(&sbuf);
1773 std::string
line, PUName, macroTypeStr, cellName, siteName, BELName;
1775 std::string fill0, fill1, fill2, fill3, fill4, fill5, fill6;
1776 unsigned int PUId, numCells, cellId;
1796 std::getline(infile,
line);
1797 std::istringstream iss(
line);
1799 assert(fill0 ==
"GlobalPlacerPseudoNetWeight:");
1800 std::getline(infile,
line);
1801 iss = std::istringstream(
line);
1803 assert(fill0 ==
"GlobalPlacerMacroPseudoNetEnhanceCnt:");
1804 std::getline(infile,
line);
1805 iss = std::istringstream(
line);
1807 assert(fill0 ==
"GlobalPlacerMacroLegalizationWeight:");
1809 while (std::getline(infile,
line))
1811 std::istringstream iss(
line);
1812 iss >> fill0 >> PUId >> PUName;
1813 if (fill0.find(
"Macro") != std::string::npos)
1828 assert(
placementUnits.size() == PUId &&
"PlacementUnit should be dumped according to the PU id order.");
1829 std::getline(infile,
line);
1830 iss = std::istringstream(
line);
1831 iss >> fill0 >> macroTypeStr;
1833 if (macroTypeStr ==
"PlacementMacroType_LUTFFPair")
1835 else if (macroTypeStr ==
"PlacementMacroType_FFFFPair")
1837 else if (macroTypeStr ==
"PlacementMacroType_HALFCLB")
1839 else if (macroTypeStr ==
"PlacementMacroType_LCLB")
1841 else if (macroTypeStr ==
"PlacementMacroType_MCLB")
1843 else if (macroTypeStr ==
"PlacementMacroType_CARRY")
1845 else if (macroTypeStr ==
"PlacementMacroType_DSP")
1847 else if (macroTypeStr ==
"PlacementMacroType_BRAM")
1849 else if (macroTypeStr ==
"PlacementMacroType_MUX7")
1851 else if (macroTypeStr ==
"PlacementMacroType_MUX8")
1853 if (macroTypeStr ==
"PlacementMacroType_LUTLUTSeires")
1856 assert(
false &&
"undefined macro type.");
1862 std::getline(infile,
line);
1863 iss = std::istringstream(
line);
1864 iss >> fill0 >>
X >>
Y;
1867 std::getline(infile,
line);
1868 iss = std::istringstream(
line);
1869 iss >> fill0 >> booleanValue;
1873 std::getline(infile,
line);
1874 iss = std::istringstream(
line);
1875 iss >> fill0 >> booleanValue;
1882 std::getline(infile,
line);
1883 iss = std::istringstream(
line);
1884 iss >> fill0 >> booleanValue;
1888 std::getline(infile,
line);
1889 std::getline(infile,
line);
1890 iss = std::istringstream(
line);
1891 iss >> fill0 >> numCells;
1893 int totalWeight = 0;
1896 std::getline(infile,
line);
1897 iss = std::istringstream(
line);
1898 int virtualCellTypeId;
1899 iss >> fill0 >> cellId >> fill1 >> virtualCellTypeId >> fill2 >> cellName >>
X >>
Y;
1900 assert(cellId <
getCells().size());
1901 assert(
getCells()[cellId]->getName() == cellName);
1913 std::getline(infile,
line);
1914 iss = std::istringstream(
line);
1915 iss >> fill0 >> numCells;
1919 std::getline(infile,
line);
1920 iss = std::istringstream(
line);
1922 iss >> fill0 >> cellId >> fill1 >> siteName >> fill2 >> BELName;
1923 assert(cellId <
getCells().size());
1927 else if (fill0.find(
"UnpackedCell") != std::string::npos)
1937 assert(
placementUnits.size() == PUId &&
"PlacementUnit should be dumped according to the PU id order.");
1938 std::getline(infile,
line);
1939 iss = std::istringstream(
line);
1940 iss >> fill0 >> cellId >> fill1 >> cellName;
1942 assert(
getCells()[cellId]->getName() == cellName);
1951 std::getline(infile,
line);
1952 iss = std::istringstream(
line);
1953 iss >> fill0 >>
X >>
Y;
1956 std::getline(infile,
line);
1957 iss = std::istringstream(
line);
1958 iss >> fill0 >> booleanValue;
1962 std::getline(infile,
line);
1963 iss = std::istringstream(
line);
1964 iss >> fill0 >> booleanValue;
1971 bool shouldLock =
false;
1972 std::getline(infile,
line);
1973 iss = std::istringstream(
line);
1974 iss >> fill0 >> booleanValue;
1982 std::getline(infile,
line);
1983 iss = std::istringstream(
line);
1984 iss >> fill0 >> fill1 >> siteName >> fill2 >> BELName;
1991 else if (fill0.find(
"PULegalization:") != std::string::npos)
1993 std::vector<std::string> tmpSiteNames;
1994 tmpSiteNames.clear();
1995 strSplit(PUName, tmpSiteNames,
",");
1998 for (
auto siteName : tmpSiteNames)
2009 std::cout <<
"This line : (" << std::string(
line) <<
") cannot be parsed.\n";
2023 if (
auto curNet = curPNet->getDesignNet())
2025 if (!curNet->checkIsGlobalClock() && !curNet->checkIsGlobalClock() && curNet->getPins().size() < 10000 &&
2028 curNet->enhanceOverallTimingNetEnhancement(1.2);
2038 int leftId, rightId, topId, bottomId;
2042 assert(leftId >= 0 && leftId < deviceInfo->getClockRegionNumX());
2043 assert(rightId >= 0 && rightId < deviceInfo->getClockRegionNumX());
2044 assert(topId >= 0 && topId < deviceInfo->getClockRegionNumY());
2045 assert(bottomId >= 0 && bottomId < deviceInfo->getClockRegionNumY());
2047 bool enhanced =
false;
2048 for (
int i = bottomId;
i <= topId && !enhanced;
i++)
2050 for (
int j = leftId; j <= rightId && !enhanced; j++)
2054 if ((rightId - leftId + 1) * (topId - bottomId + 1) < 15)
2056 if (curClockNet->getPinOffsetsInUnit().size() < 5000)
2058 curClockNet->getDesignNet()->setOverallTimingNetEnhancement(1.2);
2066 if (curClockNet->getDesignNet()->getName().find(
"_ddr") != std::string::npos)
2068 curClockNet->getDesignNet()->setOverallTimingNetEnhancement(1.1);
2077 if (
auto curNet = curPNet->getDesignNet())
2079 if (curNet->getName().find(
"_ddr") != std::string::npos)
2081 curNet->setOverallTimingNetEnhancement(1.2);
2099 clockRegions[
i][j]->resetClockUtilizationInfo();
2105 int leftId, rightId, topId, bottomId;
2109 assert(leftId >= 0 && leftId < deviceInfo->getClockRegionNumX());
2110 assert(rightId >= 0 && rightId < deviceInfo->getClockRegionNumX());
2111 assert(topId >= 0 && topId < deviceInfo->getClockRegionNumY());
2112 assert(bottomId >= 0 && bottomId < deviceInfo->getClockRegionNumY());
2113 for (
int i = bottomId;
i <= topId;
i++)
2115 for (
int j = leftId; j <= rightId; j++)
2124 auto designNet = curClockNet->getDesignNet();
2125 for (
auto curPin : designNet->getPins())
2127 auto curCell = curPin->getCell();
2129 int regionX, regionY;
2132 designNet->getElementIdInType());
2136 bool isLegal =
true;
2148 print_info(
"Clock column rough max untilization in each clock region:");
2154 std::cout << std::left << std::setw(4) << halfColumnUtil;
2155 isLegal &= (halfColumnUtil <= 12);
2170 std::cout <<
"clock region " <<
i <<
" " << j
2171 <<
" ===================================================================\n";
2173 if (curClockRegion->getMaxUtilizationOfClockColumns() > 12)
2175 auto curColumn = curClockRegion->getMaxUtilizationClockColumnsPtr();
2179 auto designNet = curClockNet->getDesignNet();
2180 std::vector<DesignInfo::DesignCell *> cellsInColumn;
2181 cellsInColumn.clear();
2182 for (
auto curPin : designNet->getPins())
2184 auto curCell = curPin->getCell();
2186 if (loc.X <= curColumn->getRight() && loc.X >= curColumn->getLeft() &&
2187 loc.Y <= curColumn->getTop() && loc.Y >= curColumn->getBottom())
2189 cellsInColumn.push_back(curCell);
2193 if (cellsInColumn.size())
2195 std::cout <<
"clockSrcPin: " << curClockNet->getDesignNet()->getName() <<
" has "
2196 << cellsInColumn.size() <<
" cell in the targetColumn:\n";
2197 for (
auto tmpCell : cellsInColumn)
2199 std::cout <<
" " << tmpCell->getName() <<
"\n";
2201 std::cout <<
"packing record:=========================================================\n";
2204 std::cout <<
"design net is found in packing record.";
2208 std::cout <<
"design net is not found in packing record.";
2210 std::cout <<
"===================================================================\n";
2211 std::cout <<
"===================================================================\n";
2226 std::vector<std::string> cellNames;
2228 for (
int i = 0;
i < cells.size();
i++)
2233 if (cells[
i]->isLUT())
2235 else if (cells[
i]->isFF())
2237 else if (cells[
i]->isMux())
2239 else if (cells[
i]->isCarry())
2241 else if (cells[
i]->isDSP())
2243 else if (cells[
i]->isBRAM())
2247 cellNames.push_back(cells[
i]->getName());
2254 std::vector<int> isCovered(timingGraph->getNodes().size(), 0);
2255 std::vector<std::vector<int>> resPaths;
2263 for (
auto curEndpoint : timingGraph->getSortedTimingEndpoints())
2265 if (isCovered[curEndpoint->getId()])
2267 std::vector<int> resPath;
2268 bool findSuccessfully =
2269 timingGraph->backTraceDelayLongestPathFromNode(curEndpoint->getId(), isCovered, resPath, 10);
2270 if (findSuccessfully)
2276 bool containNegativeIndex =
false;
2277 for (
auto cellId : resPath)
2281 containNegativeIndex =
true;
2287 isCovered[unpackedCell->getCell()->getCellId()]++;
2291 for (
auto cell : macro->getCells())
2293 isCovered[cell->getCellId()]++;
2297 if (!containNegativeIndex)
2298 resPaths.push_back(resPath);
2301 if (resPaths.size() > pathNumThr)