AMF-Placer  2.0
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
PlacementTimingOptimizer.cc
Go to the documentation of this file.
1 
26 
27 #include <cmath>
28 #include <codecvt>
29 
31  std::map<std::string, std::string> &JSONCfg)
32  : placementInfo(placementInfo), timingInfo(placementInfo->getTimingInfo()), JSONCfg(JSONCfg)
33 {
34  if (JSONCfg.find("PlacementTimingOptimizerVerbose") != JSONCfg.end())
35  verbose = JSONCfg["PlacementTimingOptimizerVerbose"] == "true";
36  if (JSONCfg.find("y2xRatio") != JSONCfg.end())
37  y2xRatio = std::stof(JSONCfg["y2xRatio"]);
38  if (JSONCfg.find("DSPCritical") != JSONCfg.end())
39  DSPCritical = JSONCfg["DSPCritical"] == "true";
40 
43  initPois();
44 }
45 
47 {
48  auto &cellLoc = placementInfo->getCellId2location();
49  auto &pinLoc = placementInfo->getPinId2location();
50  pinLoc = std::vector<PlacementInfo::Location>(designInfo->getPins().size());
51  for (auto tmpCell : placementInfo->getCells())
52  {
53  int cellId = tmpCell->getCellId();
54  auto tmpCellLoc = cellLoc[cellId];
55  for (auto tmpPin : tmpCell->getPins())
56  {
57  float pinX = tmpCellLoc.X + tmpPin->getOffsetXInCell();
58  float pinY = tmpCellLoc.Y + tmpPin->getOffsetYInCell();
59  assert((unsigned int)tmpPin->getElementIdInType() < pinLoc.size());
60  pinLoc[tmpPin->getElementIdInType()].X = pinX;
61  pinLoc[tmpPin->getElementIdInType()].Y = pinY;
62  }
63  }
64 }
65 
67 {
69  auto &cellLoc = placementInfo->getCellId2location();
70 
71  unsigned int srcCellId = srcCell->getCellId();
72  auto srcNode = timingNodes[srcCellId];
73  auto srcLoc = cellLoc[srcCellId];
74 
75  float worstSlack = 100;
76  for (auto outputNet : srcCell->getOutputNets())
77  {
78  for (auto pinBeDriven : outputNet->getPinsBeDriven())
79  {
80  // get the sinkPin information
81  auto sinkCell = pinBeDriven->getCell();
82  unsigned int sinkCellId = sinkCell->getCellId();
83  auto sinkNode = timingNodes[sinkCellId];
84  auto sinkLoc = cellLoc[sinkCellId];
85  int succPathLen = sinkNode->getLongestPathLength();
86  float netDelay = getDelayByModel(sinkNode, srcNode, sinkLoc.X, sinkLoc.Y, srcLoc.X, srcLoc.Y);
87  float slack = sinkNode->getRequiredArrivalTime() - srcNode->getLatestOutputArrival() - netDelay;
88 
89  if (slack < worstSlack)
90  worstSlack = slack;
91  }
92  }
93 
94  return worstSlack;
95 }
96 
98 {
99 
100  assert(timingInfo);
101  auto timingGraph = timingInfo->getSimplePlacementTimingGraph();
102  float maxDelay = 0;
103  int maxDelayId = -1;
104  for (unsigned int i = 0; i < timingGraph->getNodes().size(); i++)
105  {
106  if (timingGraph->getNodes()[i]->getLatestInputArrival() > maxDelay)
107  {
108  maxDelay = timingGraph->getNodes()[i]->getLatestInputArrival();
109  maxDelayId = i;
110  }
111  }
112 
113  std::vector<std::vector<int>> resPaths;
114  auto resPath = timingGraph->backTraceDelayLongestPathFromNode(maxDelayId);
115 
116  return resPath;
117 }
118 
119 std::vector<std::vector<int>> PlacementTimingOptimizer::findCriticalPaths(float criticalRatio, bool checkOverlap,
120  int pathNumThr, int converThr)
121 {
122 
123  assert(timingInfo);
124  auto timingGraph = timingInfo->getSimplePlacementTimingGraph();
125  timingGraph->sortedEndpointByDelay();
126  std::vector<int> isCovered(timingGraph->getNodes().size(), 0);
127  std::vector<std::vector<int>> resPaths;
128 
129  for (auto curEndpoint : timingGraph->getSortedTimingEndpoints())
130  {
131  if (isCovered[curEndpoint->getId()])
132  continue;
133  if (curEndpoint->getLatestInputArrival() / timingGraph->getClockPeriod() < criticalRatio)
134  break;
135  std::vector<int> resPath;
136  bool findSuccessfully =
137  timingGraph->backTraceDelayLongestPathFromNode(curEndpoint->getId(), isCovered, resPath, converThr);
138  if (findSuccessfully)
139  {
140  // std::cout << "find endpoint [" << curEndpoint->getDesignNode()
141  // << "] delay=" << curEndpoint->getLatestInputArrival() << " with " << resPath.size()
142  // << " nodes in path.\n";
143  resPaths.push_back(resPath);
144  if (checkOverlap)
145  {
146  for (auto cellId : resPath)
147  {
148  auto PU = placementInfo->getPlacementUnitByCellId(cellId);
149  if (auto unpackedCell = dynamic_cast<PlacementInfo::PlacementUnpackedCell *>(PU))
150  {
151  isCovered[unpackedCell->getCell()->getCellId()]++;
152  }
153  else if (auto macro = dynamic_cast<PlacementInfo::PlacementMacro *>(PU))
154  {
155  for (auto cell : macro->getCells())
156  {
157  isCovered[cell->getCellId()]++;
158  }
159  }
160  }
161  }
162  }
163 
164  if (resPaths.size() > pathNumThr)
165  break;
166  }
167 
168  return resPaths;
169 }
170 
171 std::vector<std::vector<int>>
172 PlacementTimingOptimizer::findCriticalPaths(float criticalRatio, std::vector<bool> &FFDirectlyDrivenButNotInOneSlot)
173 {
174 
175  assert(timingInfo);
176  auto timingGraph = timingInfo->getSimplePlacementTimingGraph();
177  timingGraph->sortedEndpointByDelay();
178  std::vector<int> isCovered(timingGraph->getNodes().size(), 0);
179  std::vector<std::vector<int>> resPaths;
180 
181  for (auto curEndpoint : timingGraph->getSortedTimingEndpoints())
182  {
183  if (isCovered[curEndpoint->getId()] || !FFDirectlyDrivenButNotInOneSlot[curEndpoint->getId()])
184  continue;
185  if (curEndpoint->getLatestInputArrival() / timingGraph->getClockPeriod() < criticalRatio)
186  break;
187  std::vector<int> resPath;
188  bool findSuccessfully =
189  timingGraph->backTraceDelayLongestPathFromNode(curEndpoint->getId(), isCovered, resPath, 100);
190  if (findSuccessfully)
191  {
192  // std::cout << "find endpoint [" << curEndpoint->getDesignNode()
193  // << "] delay=" << curEndpoint->getLatestInputArrival() << " with " << resPath.size()
194  // << " nodes in path.\n";
195  resPath.resize(2);
196  resPaths.push_back(resPath);
197  for (auto cellId : resPath)
198  {
199  auto PU = placementInfo->getPlacementUnitByCellId(cellId);
200  if (auto unpackedCell = dynamic_cast<PlacementInfo::PlacementUnpackedCell *>(PU))
201  {
202  isCovered[unpackedCell->getCell()->getCellId()] = 1;
203  }
204  else if (auto macro = dynamic_cast<PlacementInfo::PlacementMacro *>(PU))
205  {
206  for (auto cell : macro->getCells())
207  {
208  isCovered[cell->getCellId()] = 1;
209  }
210  }
211  }
212  }
213  }
214 
215  return resPaths;
216 }
217 
218 float PlacementTimingOptimizer::conductStaticTimingAnalysis(bool disableOptimisticTiming)
219 {
220  print_status("PlacementTimingOptimizer: conducting Static Timing Analysis");
221 
222  unsigned int highFanoutThr = 10000;
223 
225  {
226  highFanoutThr = 1000;
227  print_warning("highFanoutThr is set to 1000");
228  }
229 
230  if (enableCounter)
231  STA_Cnt++;
232 
233  increaseLowDelayVal = false;
234  if (disableOptimisticTiming)
235  increaseLowDelayVal = true;
236 
237  effectFactor = (STA_Cnt / 30.0);
238  if (effectFactor < 1)
239  effectFactor = std::pow(effectFactor, 1);
240  else
241  effectFactor = (effectFactor - 1) * 0.3 + 1;
242 
243  bool printOut = false;
244  std::string dumpFileName = "optNetDelayInfo.txt";
245  std::ofstream outfile0;
246  if (JSONCfg.find("PlacementTimingOptimizer_EdgesDelayLog") != JSONCfg.end())
247  {
248  printOut = true;
249  std::string dumpFileName = JSONCfg["PlacementTimingOptimizer_EdgesDelayLog"];
250  print_status("PlacementTimingOptimizer: dumping PlacementTimingOptimizer_EdgesDelayLog to: " + dumpFileName);
251  outfile0.open(dumpFileName.c_str());
252  assert(outfile0.is_open() && outfile0.good() &&
253  "The path for PlacementTimingOptimizer_EdgesDelayLog does not exist and please check "
254  "your path settings");
255  }
256 
257  // std::string cellName =
258  // "chip/tile0/g_ariane_core.core/ariane/ex_stage_i/i_mult/i_div/mem_q[4][sbe][result][55]_i_8"; int targetCellId =
259  // placementInfo->getDesignInfo()->getCell(cellName)->getCellId(); auto targetCellLoc =
260  // placementInfo->getCellId2location()[targetCellId]; print_warning("targetCellLoc X:" +
261  // std::to_string(targetCellLoc.X) + " Y:" + std::to_string(targetCellLoc.Y));
262 
263  assert(timingInfo);
264  auto timingGraph = timingInfo->getSimplePlacementTimingGraph();
265  setPinsLocation();
266 
267  auto &pinLoc = placementInfo->getPinId2location();
268  auto &cellLoc = placementInfo->getCellId2location();
269 
270  auto &edges = timingGraph->getEdges();
271  int numEdges = edges.size();
272 
273 #pragma omp parallel for
274  for (int i = 0; i < numEdges; i++)
275  {
276  auto edge = edges[i];
277  auto &pin1Loc = pinLoc[edge->getSourcePin()->getElementIdInType()];
278  auto &pin2Loc = pinLoc[edge->getSinkPin()->getElementIdInType()];
279  if (pin1Loc.X < -5 && pin1Loc.Y < -5)
280  continue;
281  if (pin2Loc.X < -5 && pin2Loc.Y < -5)
282  continue;
283 
284  edge->setDelay(getDelayByModel(edge->getSink(), edge->getSource(), pin1Loc.X, pin1Loc.Y, pin2Loc.X, pin2Loc.Y));
285  }
286 
287  timingGraph->propogateArrivalTime();
288  timingGraph->backPropogateRequiredArrivalTime();
289  timingGraph->updateCriticalPath();
290 
291  auto resPath = timingGraph->backTraceDelayLongestPathFromNode(timingGraph->getCriticalEndPoint());
292 
293  std::cout << "An example of long delay path for the current placement:\n";
294  for (auto id : resPath)
295  {
296  std::cout << designInfo->getCells()[id] << " X:" << cellLoc[id].X << " Y:" << cellLoc[id].Y
297  << " [delay]: " << timingGraph->getNodes()[id]->getLatestInputArrival()
298  << " [required]: " << timingGraph->getNodes()[id]->getRequiredArrivalTime() << "\n";
299  }
300 
301  // // important::: chip/tile1/g_ariane_core.core/ariane/id_stage_i/operand_b_q[63]_i_31__0
302  // print_warning("===========================================================================\n");
303  // std::string cellNames[24] = {"design_1_i/DigitRec_0/inst/ap_CS_fsm_reg[9]_replica_1",
304  // "design_1_i/DigitRec_0/inst/knn_set_311_0_reg_21661[31]_i_2",
305  // "design_1_i/DigitRec_0/inst/knn_set_307_3_reg_21799[31]_i_84",
306  // "design_1_i/DigitRec_0/inst/knn_set_307_3_reg_21799[31]_i_18",
307  // "design_1_i/DigitRec_0/inst/knn_set_307_3_reg_21799_reg[31]_i_8",
308  // "design_1_i/DigitRec_0/inst/knn_set_307_3_reg_21799[31]_i_132",
309  // "design_1_i/DigitRec_0/inst/knn_set_307_3_reg_21799[31]_i_37",
310  // "design_1_i/DigitRec_0/inst/knn_set_307_3_reg_21799_reg[31]_i_9",
311  // "design_1_i/DigitRec_0/inst/knn_set_307_3_reg_21799[31]_i_182",
312  // "design_1_i/DigitRec_0/inst/knn_set_307_3_reg_21799[31]_i_55",
313  // "design_1_i/DigitRec_0/inst/knn_set_307_3_reg_21799_reg[31]_i_10",
314  // "design_1_i/DigitRec_0/inst/ap_phi_reg_pp2_iter25_knn_set_310_1_reg_22001[31]_i_66",
315  // "design_1_i/DigitRec_0/inst/ap_phi_reg_pp2_iter25_knn_set_310_1_reg_22001[31]_i_14",
316  // "design_1_i/DigitRec_0/inst/ap_phi_reg_pp2_iter25_knn_set_310_1_reg_22001_reg[31]_i_4",
317  // "design_1_i/DigitRec_0/inst/ap_phi_reg_pp2_iter25_knn_set_314_1_reg_22175[31]_i_40",
318  // "design_1_i/DigitRec_0/inst/ap_phi_reg_pp2_iter25_knn_set_314_1_reg_22175[31]_i_28",
319  // "design_1_i/DigitRec_0/inst/ap_phi_reg_pp2_iter25_knn_set_314_1_reg_22175_reg[31]_i_5",
320  // "design_1_i/DigitRec_0/inst/ap_phi_reg_pp2_iter25_knn_set_314_1_reg_22175_reg[31]_i_3",
321  // "design_1_i/DigitRec_0/inst/knn_set_307_3_reg_21799[31]_i_5",
322  // "design_1_i/DigitRec_0/inst/ap_phi_reg_pp2_iter25_knn_set_310_1_reg_22001[31]_i_1",
323  // "design_1_i/DigitRec_0/inst/knn_set_306_343_reg_21841[8]_i_5",
324  // "design_1_i/DigitRec_0/inst/ap_phi_reg_pp2_iter25_knn_set_316_1_reg_21919[31]_i_3",
325  // "design_1_i/DigitRec_0/inst/ap_phi_reg_pp2_iter25_knn_set_316_1_reg_21919[31]_i_1",
326  // "design_1_i/DigitRec_0/inst/ap_phi_reg_pp2_iter25_knn_set_316_1_reg_21919_reg[1]"};
327 
328  // std::vector<std::string> cellNameVec(cellNames, cellNames + 24);
329  // float totalDelay = 0;
330  // for (int i = 0; i < cellNameVec.size() - 1; i++)
331  // {
332  // auto id = designInfo->getCell(cellNameVec[i])->getCellId();
333  // auto curNode = timingGraph->getNodes()[id];
334  // for (auto edge : curNode->getOutEdges())
335  // {
336  // auto &pin1Loc = pinLoc[edge->getSourcePin()->getElementIdInType()];
337  // auto &pin2Loc = pinLoc[edge->getSinkPin()->getElementIdInType()];
338  // if (pin1Loc.X < -5 && pin1Loc.Y < -5)
339  // continue;
340  // if (pin2Loc.X < -5 && pin2Loc.Y < -5)
341  // continue;
342  // float delay = getDelayByModel(pin1Loc.X, pin1Loc.Y, pin2Loc.X, pin2Loc.Y);
343  // if (edge->getSinkPin()->getCell()->getName() == cellNameVec[i + 1])
344  // {
345  // std::cout << edge->getSinkPin()->getCell() << "X:" << pin1Loc.X << " Y:" << pin1Loc.Y
346  // << " [InputTotalDelay]: " << totalDelay << " [ToNextDelay]: " << delay << "\n";
347  // totalDelay += curNode->getInnerDelay() + delay;
348  // break;
349  // }
350  // }
351  // }
352  if (printOut)
353  {
354  for (auto node : timingInfo->getSimplePlacementTimingInfo())
355  {
356  if (node->getOutEdges().size() > 32)
357  continue;
358  for (auto edge : node->getOutEdges())
359  {
360  outfile0 << " src:" << edge->getSourcePin()->getName() << " sink:" << edge->getSinkPin()->getName()
361  << " delay:" << edge->getDelay() << "\n";
362  }
363  }
364  outfile0.close();
365  }
366 
367  return timingGraph->getCriticalPathDelay();
368 }
369 
371 {
372  assert(placementInfo->getTimingInfo());
373 
374  // float maxEnhanceRatio = 0;
376  auto &cellLoc = placementInfo->getCellId2location();
377  assert(cellLoc.size() == timingNodes.size());
378 
379  // std::ofstream outfile0("timingOptProc.log");
380 
381  // auto deviceInfo = placementInfo->getDeviceInfo();
382 
383  std::vector<int> slackCntVec(200, 0);
384  int totalSlackChecked = 0;
385 
386  netActualSlackPinNum.clear();
387 
388  for (auto curNet : placementInfo->getPlacementNets())
389  {
390  auto designNet = curNet->getDesignNet();
391  if (designNet->checkIsPowerNet() || designNet->checkIsGlobalClock())
392  continue;
393 
394  if (curNet->getDriverUnits().size() != 1 || curNet->getUnits().size() <= 1 || curNet->getUnits().size() >= 1000)
395  continue;
396  auto &pins = designNet->getPins();
397  int pinNum = pins.size();
398 
399  assert(curNet->getUnits().size() == (unsigned int)pinNum);
400 
401  int driverPinInNet = -1;
402 
403  for (int i = 0; i < pinNum; i++)
404  {
405  if (pins[i]->isOutputPort())
406  {
407  driverPinInNet = i;
408  break;
409  }
410  }
411 
412  assert(driverPinInNet >= 0);
413 
414  // get the srcPin information
415  auto srcCell = pins[driverPinInNet]->getCell();
416  unsigned int srcCellId = srcCell->getCellId();
417  auto srcNode = timingNodes[srcCellId];
418  auto srcLoc = cellLoc[srcCellId];
419  // iterate the sinkPin for evaluation and enhancement
420 
421  netActualSlackPinNum[curNet] = 0;
422  for (int pinBeDriven = 0; pinBeDriven < pinNum; pinBeDriven++)
423  {
424  if (pinBeDriven == driverPinInNet)
425  continue;
426 
427  // get the sinkPin information
428  auto sinkCell = pins[pinBeDriven]->getCell();
429  unsigned int sinkCellId = sinkCell->getCellId();
430  auto sinkNode = timingNodes[sinkCellId];
431  auto sinkLoc = cellLoc[sinkCellId];
432  float netDelay = getDelayByModel(sinkNode, srcNode, sinkLoc.X, sinkLoc.Y, srcLoc.X, srcLoc.Y);
433  float slack = sinkNode->getRequiredArrivalTime() - srcNode->getLatestOutputArrival() - netDelay;
434 
435  if (slack > 0)
436  continue;
437 
438  netActualSlackPinNum[curNet]++;
439  int slotId = (int)(-slack / 0.1);
440  if (slotId >= 100)
441  slotId = 100;
442  if (slotId < 0)
443  slotId = 0;
444  slackCntVec[slotId] += 1;
445  totalSlackChecked++;
446  }
447  }
448 
449  float slackThr = 0;
450  int slackUnderThrCnt = 0;
451  float careRatio = 0.333;
452 
453  if (careRatio <= 0.9 && totalSlackChecked > 0)
454  {
455  for (unsigned int i = 0; i < slackCntVec.size(); i++)
456  {
457  slackUnderThrCnt += slackCntVec[i];
458  if (slackUnderThrCnt > totalSlackChecked * (1 - careRatio))
459  break;
460  slackThr -= 0.1;
461  }
462  }
463 
464  std::string outputStr = "";
465  for (unsigned int i = 0; i < slackCntVec.size(); i++)
466  {
467  outputStr += " " + std::to_string(slackCntVec[i]);
468  }
469  print_info("Slack distribution:" + outputStr);
470  print_info("slackThr = " + std::to_string(slackThr));
471  return slackThr;
472 }
473 
475  float targetX, float targetY)
476 {
477  print_status("PlacementTimingOptimizer: conducting incremental Static Timing Analysis");
478 
479  assert(timingInfo);
480  auto timingGraph = timingInfo->getSimplePlacementTimingGraph();
481  setPinsLocation();
482 
483  auto &pinLoc = placementInfo->getPinId2location();
484 
485  auto &edges = timingGraph->getEdges();
486  int numEdges = edges.size();
487 
488 #pragma omp parallel for
489  for (int i = 0; i < numEdges; i++)
490  {
491  auto edge = edges[i];
492  auto &pin1Loc = pinLoc[edge->getSourcePin()->getElementIdInType()];
493  auto &pin2Loc = pinLoc[edge->getSinkPin()->getElementIdInType()];
494  if (pin1Loc.X < -5 && pin1Loc.Y < -5)
495  continue;
496  if (pin2Loc.X < -5 && pin2Loc.Y < -5)
497  continue;
498 
499  edge->setDelay(getDelayByModel(edge->getSink(), edge->getSource(), pin1Loc.X, pin1Loc.Y, pin2Loc.X, pin2Loc.Y));
500  }
501 
502  timingGraph->propogateArrivalTime();
503  timingGraph->backPropogateRequiredArrivalTime();
504  float maxDelay = 0;
505  int maxDelayId = -1;
506  for (unsigned int i = 0; i < timingGraph->getNodes().size(); i++)
507  {
508  if (timingGraph->getNodes()[i]->getLatestInputArrival() > maxDelay)
509  {
510  maxDelay = timingGraph->getNodes()[i]->getLatestInputArrival();
511  maxDelayId = i;
512  }
513  }
514 
515  auto resPath = timingGraph->backTraceDelayLongestPathFromNode(maxDelayId);
516 
517  std::cout << "An example of long delay path for the current placement:\n";
518  for (auto id : resPath)
519  {
520  std::cout << designInfo->getCells()[id]
521  << " [delay]: " << timingGraph->getNodes()[id]->getLatestInputArrival()
522  << " [required]: " << timingGraph->getNodes()[id]->getRequiredArrivalTime() << "\n";
523  }
524 }
525 
526 void PlacementTimingOptimizer::clusterLongPathInOneClockRegion(int pathLenThr, float clusterThrRatio)
527 {
528  // if (DSPCritical)
529  // return;
532  print_warning("PlacementTimingOptimizer: clustering long path in one clock region");
535  auto simpleTimingGraph = placementInfo->getTimingInfo()->getSimplePlacementTimingGraph();
536  auto &cellLoc = placementInfo->getCellId2location();
538  auto YX2ClockRegion = deviceInfo->getClockRegions();
539  auto &PU2ClockRegionCenter = placementInfo->getPU2ClockRegionCenters();
540  auto &PU2ClockRegionColumn = placementInfo->getPU2ClockRegionColumn();
541 
542  PU2ClockRegionCenter.clear();
543  PU2ClockRegionColumn.clear();
544 
545  std::set<int> extractedCellIds;
546  std::set<PlacementInfo::PlacementUnit *> extractedPUs;
547 
548  extractedCellIds.clear();
549  extractedPUs.clear();
550  clockRegionclusters.clear();
551 
552  unsigned int fanoutThr = 512; // placementInfo->getHighFanOutThr();
553  int sizeThr = 20000;
555  sizeThr = 2000;
556  for (unsigned int nodeId = 0; nodeId < timingNodes.size() * 0.1; nodeId++)
557  {
558  auto timingNode = timingNodes[nodeId];
559  if (timingNode->getLongestPathLength() > pathLenThr)
560  {
561  if (extractedCellIds.find(nodeId) != extractedCellIds.end())
562  continue;
563  auto candidateCellIds =
564  simpleTimingGraph->DFSFromNode(timingNode->getId(), pathLenThr, sizeThr, extractedCellIds, 1000000);
565 
566  if (candidateCellIds.size() >= pathLenThr * 0.8)
567  {
568  std::set<PlacementInfo::PlacementUnit *> PUsInLongPaths;
569  PUsInLongPaths.clear();
570 
571  float totalWeight = 0;
572  for (auto &candidateCellId : candidateCellIds)
573  {
574  auto PUInPath = placementInfo->getPlacementUnitByCellId(candidateCellId);
575  if (extractedPUs.find(PUInPath) == extractedPUs.end() &&
576  PUsInLongPaths.find(PUInPath) == PUsInLongPaths.end())
577  {
578  PUsInLongPaths.insert(PUInPath);
579  totalWeight += PUInPath->getWeight();
580  }
581  }
582 
583  if (totalWeight >= pathLenThr)
584  {
585  std::map<std::pair<int, int>, float> clockRegionYX2Cnt;
586  clockRegionYX2Cnt.clear();
587 
588  float maxClockRegionWeight = 0;
589  float totalClockRegionWeight = 0;
590  std::pair<int, int> optClockLocYX;
591 
592  for (auto tmpPU : PUsInLongPaths)
593  {
594  if (auto unpackedCell = dynamic_cast<PlacementInfo::PlacementUnpackedCell *>(tmpPU))
595  {
596  int cellId = unpackedCell->getCell()->getCellId();
597  int clockRegionX, clockRegionY;
598  auto tmpLoc = cellLoc[cellId];
599  deviceInfo->getClockRegionByLocation(tmpLoc.X, tmpLoc.Y, clockRegionX, clockRegionY);
600  std::pair<int, int> tmpClockLocYX(-1, clockRegionX);
601  // if (clockRegionX < 2)
602  // clockRegionX = 1;
603  // if (clockRegionX > 2)
604  // clockRegionX = 3;
605  if (clockRegionYX2Cnt.find(tmpClockLocYX) == clockRegionYX2Cnt.end())
606  {
607  clockRegionYX2Cnt[tmpClockLocYX] = 0;
608  }
609  clockRegionYX2Cnt[tmpClockLocYX] += 1;
610  totalClockRegionWeight += 1;
611 
612  if (clockRegionYX2Cnt[tmpClockLocYX] > maxClockRegionWeight)
613  {
614  maxClockRegionWeight = clockRegionYX2Cnt[tmpClockLocYX];
615  optClockLocYX = tmpClockLocYX;
616  }
617  }
618  else if (auto curMacro = dynamic_cast<PlacementInfo::PlacementMacro *>(tmpPU))
619  {
620  for (auto tmpCell : curMacro->getCells())
621  {
622  int cellId = tmpCell->getCellId();
623  int clockRegionX, clockRegionY;
624  auto tmpLoc = cellLoc[cellId];
625  deviceInfo->getClockRegionByLocation(tmpLoc.X, tmpLoc.Y, clockRegionX, clockRegionY);
626 
627  std::pair<int, int> tmpClockLocYX(-1, clockRegionX);
628  if (clockRegionYX2Cnt.find(tmpClockLocYX) == clockRegionYX2Cnt.end())
629  {
630  clockRegionYX2Cnt[tmpClockLocYX] = 0;
631  }
632  clockRegionYX2Cnt[tmpClockLocYX] += 1;
633  totalClockRegionWeight += 1;
634 
635  if (clockRegionYX2Cnt[tmpClockLocYX] > maxClockRegionWeight)
636  {
637  maxClockRegionWeight = clockRegionYX2Cnt[tmpClockLocYX];
638  optClockLocYX = tmpClockLocYX;
639  }
640  }
641  }
642  }
643 
644  if ((maxClockRegionWeight > totalClockRegionWeight * clusterThrRatio) &&
645  maxClockRegionWeight >= pathLenThr * 0.333)
646  {
647  // if (optClockLocYX.second < 2)
648  // optClockLocYX.second = 1;
649  // if (optClockLocYX.second > 2)
650  // optClockLocYX.second = 3;
651  auto optClockRegion = YX2ClockRegion[0][optClockLocYX.second];
652  float cX = (optClockRegion->getLeft() + optClockRegion->getRight()) / 2;
653  std::vector<int> PUIdsInLongPaths;
654  PUIdsInLongPaths.clear();
655  bool abandon = false;
656  for (auto curPU : PUsInLongPaths)
657  {
658  if (curPU->checkHasDSP())
659  abandon = true;
660  }
661  if (abandon)
662  break;
663  for (auto curPU : PUsInLongPaths)
664  {
665  if (!curPU->isFixed() && !curPU->checkHasBRAM() && !curPU->checkHasDSP())
666  {
667  float fX = cX;
668  float fY = curPU->Y();
669  placementInfo->legalizeXYInArea(curPU, fX, fY);
670  // curPU->setAnchorLocationAndForgetTheOriginalOne(fX, fY);
671  extractedPUs.insert(curPU);
672 
673  PU2ClockRegionCenter[curPU] = std::pair<float, float>(fX, fY);
674  PU2ClockRegionColumn[curPU] = optClockLocYX.second;
675 
676  if (auto unpackedCell = dynamic_cast<PlacementInfo::PlacementUnpackedCell *>(curPU))
677  {
678  int cellId = unpackedCell->getCell()->getCellId();
679  if (timingNodes[cellId]->getOutEdges().size() < fanoutThr)
680  extractedCellIds.insert(cellId);
681  }
682  else if (auto curMacro = dynamic_cast<PlacementInfo::PlacementMacro *>(curPU))
683  {
684  for (auto tmpCell : curMacro->getCells())
685  {
686  int cellId = tmpCell->getCellId();
687  if (timingNodes[cellId]->getOutEdges().size() < fanoutThr)
688  extractedCellIds.insert(cellId);
689  }
690  }
691  PUIdsInLongPaths.push_back(curPU->getId());
692  }
693  }
694 
695  clockRegionclusters.push_back(PUIdsInLongPaths);
696  std::cout << "maxClockRegionWeight: " << maxClockRegionWeight
697  << " totalClockRegionWeight:" << totalClockRegionWeight
698  << " #extractedCellIds=" << extractedCellIds.size()
699  << " #extractedPUs=" << extractedPUs.size()
700  << " pathLength=" << timingNode->getLongestPathLength() << "\n";
701  }
702 
703  else if (totalClockRegionWeight >= 20000)
704  {
705  for (auto tmpCellId : candidateCellIds)
706  {
707  if (timingNodes[tmpCellId]->getOutEdges().size() < fanoutThr)
708  extractedCellIds.insert(tmpCellId);
709  }
710  }
711  }
712  }
713  }
714 
715  if (extractedCellIds.size() > timingNodes.size() * 0.2 && sizeThr > 20000)
716  {
717  PU2ClockRegionCenter.clear();
718  PU2ClockRegionColumn.clear();
719 
720  extractedCellIds.clear();
721  extractedPUs.clear();
722  clockRegionclusters.clear();
723 
724  sizeThr = 2000;
726  }
727  }
729  // if (!placementInfo->isDensePlacement())
731 }
732 
734 {
735  auto &binGrid = placementInfo->getGlobalBinGrid();
736  auto &PU2ClockRegionColumn = placementInfo->getPU2ClockRegionColumn();
737  auto YX2ClockRegion = deviceInfo->getClockRegions();
738  int clockRegionXNum = YX2ClockRegion[0].size();
739  std::vector<int> curClockRegionX2cellNum(clockRegionXNum, 0);
740  std::vector<std::vector<PlacementInfo::PlacementUnit *>> clockRegionX2PUs(
741  clockRegionXNum, std::vector<PlacementInfo::PlacementUnit *>(0));
742  std::vector<float> curClockRegionX2MinY(clockRegionXNum, placementInfo->getGlobalBinMaxLocY());
743  std::vector<float> curClockRegionX2MaxY(clockRegionXNum, placementInfo->getGlobalBinMinLocY());
744 
745  for (auto PU : placementInfo->getPlacementUnits())
746  {
747  int clockRegionX, clockRegionY;
748  deviceInfo->getClockRegionByLocation(PU->X(), PU->X(), clockRegionX, clockRegionY);
749  curClockRegionX2cellNum[clockRegionX] += PU->getWeight();
750  clockRegionX2PUs[clockRegionX].push_back(PU);
751 
752  int binIdX, binIdY;
753  placementInfo->getGridXY(PU->X(), PU->Y(), binIdX, binIdY);
754 
755  if (binGrid[binIdY][binIdX]->getCells().size() > 16)
756  {
757  if (PU->Y() > curClockRegionX2MaxY[clockRegionX])
758  {
759  curClockRegionX2MaxY[clockRegionX] = PU->Y();
760  }
761  if (PU->Y() < curClockRegionX2MinY[clockRegionX])
762  {
763  curClockRegionX2MinY[clockRegionX] = PU->Y();
764  }
765  }
766  }
767 
768  std::vector<int> newClockRegionX2cellNum = curClockRegionX2cellNum;
769  for (auto pair : PU2ClockRegionColumn)
770  {
771  auto PU = pair.first;
772  int oriClockRegionX, oriClockRegionY;
773  deviceInfo->getClockRegionByLocation(PU->X(), PU->X(), oriClockRegionX, oriClockRegionY);
774  newClockRegionX2cellNum[oriClockRegionX] -= PU->getWeight();
775  newClockRegionX2cellNum[pair.second] += PU->getWeight();
776  }
777 
778  for (unsigned int colX = 0; colX < curClockRegionX2cellNum.size(); colX++)
779  {
780  float stretchRatio = (float)newClockRegionX2cellNum[colX] / (float)curClockRegionX2cellNum[colX];
781 
782  float bottomLimit = placementInfo->getGlobalBinMinLocY();
783  float topLimit = placementInfo->getGlobalBinMaxLocY();
784  float completeH = topLimit - bottomLimit;
785  float oriTopY = curClockRegionX2MaxY[colX];
786  float oriBottomY = curClockRegionX2MinY[colX];
787  float oriH = std::abs(oriTopY - oriBottomY);
788  bool maybeCongestion =
789  completeH * 0.625 > oriH && (oriBottomY < 0.075 * completeH || oriTopY > 0.925 * completeH);
790 
791  if (oriBottomY < 0.075 * completeH)
792  bottomLimit = std::max(std::max(oriBottomY, bottomLimit), (float)0.05 * completeH);
793  if (oriTopY > 0.925 * completeH)
794  topLimit = std::min(std::min(oriTopY, topLimit), (float)0.95 * completeH);
795 
796  if (std::abs(oriTopY - oriBottomY) < 0.1)
797  continue;
798  if (stretchRatio > 1 || (maybeCongestion && stretchRatio > 0.95))
799  {
800  if (maybeCongestion)
801  {
802  print_warning("PlacementTimingOptimizer: " + std::to_string(colX) +
803  "th column is stretched more to avoid potential congestion");
804  stretchRatio *= 1.1;
805  }
806  else
807  stretchRatio *= 1.05;
808  float newH = stretchRatio * oriH;
809  float deltaH = newH - oriH;
810  float newTopY = oriTopY + deltaH / 2;
811  float newBottomY = oriBottomY - deltaH / 2;
812 
813  if (newBottomY < bottomLimit)
814  {
815  newTopY += (bottomLimit - newBottomY);
816  newBottomY = bottomLimit;
817  }
818 
819  if (newTopY > topLimit)
820  {
821  newBottomY = std::max(bottomLimit, newBottomY - (newTopY - topLimit));
822  newTopY = topLimit;
823  }
824  newH = newTopY - newBottomY;
825  if (oriH < 0.01)
826  continue;
827  stretchRatio = newH / oriH;
828  for (auto PU : clockRegionX2PUs[colX])
829  {
830  if (!PU->isFixed())
831  {
832  float fY = (PU->Y() - oriBottomY) * stretchRatio + newBottomY;
833  float fX = PU->X();
834  placementInfo->legalizeXYInArea(PU, fX, fY);
835  PU->setAnchorLocationAndForgetTheOriginalOne(fX, fY);
836  }
837  }
838  print_warning("PlacementTimingOptimizer: " + std::to_string(colX) + "th column is stretched by " +
839  std::to_string(stretchRatio) + " oriBottomY=" + std::to_string(oriBottomY) +
840  " oriTopY=" + std::to_string(oriTopY) + " newBottomY=" + std::to_string(newBottomY) +
841  " newTopY=" + std::to_string(newTopY));
842  }
843  }
844 
846 }
847 
849 {
850  std::string dumpClockRegionClustersFile = JSONCfg["Dump Cluster file"] + "-clockRegion";
851  if (dumpClockRegionClustersFile != "")
852  {
853  print_status("dumping cluster information to " + dumpClockRegionClustersFile);
854  std::ofstream outfile0((dumpClockRegionClustersFile + ".tcl").c_str());
855  assert(outfile0.is_open() && outfile0.good() &&
856  "The path for cluster result dumping does not exist and please check your path settings");
857  for (unsigned int cluster_id = 0; cluster_id < clockRegionclusters.size(); cluster_id++)
858  {
859  outfile0 << "highlight -color_index " << (cluster_id) % 20 + 1 << " [get_cells {";
860  for (int id : clockRegionclusters[cluster_id])
861  {
862  if (auto tmpMacro =
864  {
865  for (auto cell : tmpMacro->getCells())
866  {
867  outfile0 << cell->getName() << " ";
868  }
869  }
870  else if (auto tmpUnpacked = dynamic_cast<PlacementInfo::PlacementUnpackedCell *>(
872  {
873  outfile0 << tmpUnpacked->getName() << " ";
874  }
875  else
876  {
877  assert(false);
878  }
879  }
880  outfile0 << "}]\n";
881  }
882  outfile0.close();
883  }
884 }
885 
887 {
888  assert(timingInfo);
889  // auto timingGraph = timingInfo->getSimplePlacementTimingGraph();
890 }
891 
892 std::vector<float> &PlacementTimingOptimizer::getPUId2Slack(bool update)
893 {
894  if (update)
895  {
897  // float clockPeriod = placementInfo->getTimingInfo()->getSimplePlacementTimingGraph()->getClockPeriod();
898  auto &cellLoc = placementInfo->getCellId2location();
899  assert(cellLoc.size() == timingNodes.size());
900 
901  unsigned int highFanoutThr = 1000;
902 
903  int PUNum = placementInfo->getPlacementUnits().size();
904  PUId2Slack.clear();
905  PUId2Slack.resize(PUNum, 0);
906 
907 #pragma omp parallel for
908  for (int PUId = 0; PUId < PUNum; PUId++)
909  {
910  auto &curPU = placementInfo->getPlacementUnits()[PUId];
911 
912  for (auto curNet : *(curPU->getNetsSetPtr()))
913  {
914  if (curNet->getDriverUnits().size() == 0)
915  continue;
916  if (curNet->getDriverUnits()[0] != curPU)
917  continue;
918 
919  auto designNet = curNet->getDesignNet();
920  assert(designNet);
921  if (designNet->checkIsPowerNet() || designNet->checkIsGlobalClock())
922  continue;
923 
924  if (curNet->getDriverUnits().size() != 1 || curNet->getUnits().size() <= 1 ||
925  curNet->getUnits().size() >= highFanoutThr)
926  continue;
927  auto &PUs = curNet->getUnits();
928  auto &pins = designNet->getPins();
929  int pinNum = pins.size();
930 
931  assert(curNet->getUnits().size() == (unsigned int)pinNum);
932 
933  int driverPinInNet = -1;
934 
935  for (int i = 0; i < pinNum; i++)
936  {
937  if (pins[i]->isOutputPort())
938  {
939  driverPinInNet = i;
940  break;
941  }
942  }
943 
944  assert(driverPinInNet >= 0);
945 
946  // get the srcPin information
947  auto srcCell = pins[driverPinInNet]->getCell();
948  unsigned int srcCellId = srcCell->getCellId();
949  auto srcNode = timingNodes[srcCellId];
950  auto srcLoc = cellLoc[srcCellId];
951 
952  for (int pinBeDriven = 0; pinBeDriven < pinNum; pinBeDriven++)
953  {
954  if (pinBeDriven == driverPinInNet)
955  continue;
956 
957  // get the sinkPin information
958  auto sinkCell = pins[pinBeDriven]->getCell();
959  unsigned int sinkCellId = sinkCell->getCellId();
960  auto sinkNode = timingNodes[sinkCellId];
961  auto sinkLoc = cellLoc[sinkCellId];
962 
963  float netDelay = getDelayByModel(sinkNode, srcNode, sinkLoc.X, sinkLoc.Y, srcLoc.X, srcLoc.Y);
964  float slack = sinkNode->getRequiredArrivalTime() - srcNode->getLatestOutputArrival() - netDelay;
965  if (slack < 0)
966  {
967  if (slack < PUId2Slack[PUId])
968  PUId2Slack[PUId] = slack;
969  }
970  }
971  }
972  }
973  }
974  return PUId2Slack;
975 }
PlacementTimingOptimizer::DSPCritical
bool DSPCritical
Definition: PlacementTimingOptimizer.h:206
PlacementInfo::PlacementUnit::getWeight
int getWeight()
Definition: PlacementInfo.h:1201
PlacementInfo::getGlobalBinMinLocY
float getGlobalBinMinLocY()
get bottom boundary of the bin grid
Definition: PlacementInfo.h:2922
PlacementTimingOptimizer::getWorstSlackOfCell
float getWorstSlackOfCell(DesignInfo::DesignCell *srcCell)
Definition: PlacementTimingOptimizer.cc:66
PlacementTimingOptimizer::effectFactor
float effectFactor
Definition: PlacementTimingOptimizer.h:219
PlacementTimingOptimizer::initPois
void initPois()
Definition: PlacementTimingOptimizer.h:68
PlacementTimingOptimizer::getDelayByModel
float getDelayByModel(PlacementTimingInfo::TimingGraph< DesignInfo::DesignCell >::TimingNode *node1, PlacementTimingInfo::TimingGraph< DesignInfo::DesignCell >::TimingNode *node2, float X1, float Y1, float X2, float Y2)
Definition: PlacementTimingOptimizer.h:103
PlacementInfo::getNetDistributionByDensity
int getNetDistributionByDensity(int density)
Definition: PlacementInfo.h:4404
PlacementInfo::getPlacementUnits
std::vector< PlacementUnit * > & getPlacementUnits()
Definition: PlacementInfo.h:2810
PlacementInfo::getCells
std::vector< DesignInfo::DesignCell * > & getCells()
Definition: PlacementInfo.h:3898
PlacementTimingInfo::getSimplePlacementTimingInfo_PathLenSorted
std::vector< TimingGraph< DesignInfo::DesignCell >::TimingNode * > & getSimplePlacementTimingInfo_PathLenSorted()
Definition: PlacementTimingInfo.h:840
PlacementTimingOptimizer.h
PlacementTimingInfo::TimingGraph::getNodes
std::vector< TimingNode * > & getNodes()
Definition: PlacementTimingInfo.h:537
PlacementTimingOptimizer::clusterLongPathInOneClockRegion
void clusterLongPathInOneClockRegion(int pathLenThr, float clusterThrRatio)
Definition: PlacementTimingOptimizer.cc:526
PlacementInfo::PlacementMacro
a fixed group of multiple standard cells with constraints of their relative locations
Definition: PlacementInfo.h:1525
DesignInfo::DesignCell
a DesignCell in design netlist, DesignPin objects of which might connect to DesignNet objects
Definition: DesignInfo.h:782
PlacementTimingOptimizer::stretchClockRegionColumns
void stretchClockRegionColumns()
Definition: PlacementTimingOptimizer.cc:733
PlacementInfo::getGridXY
void getGridXY(float cellX, float cellY, int &binIdX, int &binIdY)
Get the Grid row/column based on given location X,Y.
Definition: PlacementInfo.h:3344
PlacementTimingOptimizer::findCriticalPaths
std::vector< std::vector< int > > findCriticalPaths(float criticalRatio, bool checkOverlap=true, int pathNumThr=1000, int converThr=30)
Definition: PlacementTimingOptimizer.cc:119
PlacementTimingOptimizer::PUId2Slack
std::vector< float > PUId2Slack
Definition: PlacementTimingOptimizer.h:224
PlacementTimingOptimizer::incrementalStaticTimingAnalysis_forPUWithLocation
void incrementalStaticTimingAnalysis_forPUWithLocation(PlacementInfo::PlacementUnit *curPU, float targetX, float targetY)
Definition: PlacementTimingOptimizer.cc:474
PlacementInfo::getPinId2location
std::vector< Location > & getPinId2location()
Definition: PlacementInfo.h:3605
PlacementInfo::getCellId2location
std::vector< Location > & getCellId2location()
Definition: PlacementInfo.h:3600
DeviceInfo::getClockRegionByLocation
void getClockRegionByLocation(float locX, float locY, int &clockRegionX, int &clockRegionY)
Get the clock region ID (X/Y) by a given location (X/Y)
Definition: DeviceInfo.h:1183
PlacementTimingOptimizer::verbose
bool verbose
Definition: PlacementTimingOptimizer.h:204
PlacementTimingOptimizer::y2xRatio
float y2xRatio
Definition: PlacementTimingOptimizer.h:205
PlacementTimingOptimizer::designInfo
DesignInfo * designInfo
Definition: PlacementTimingOptimizer.h:198
PlacementInfo::getDeviceInfo
DeviceInfo * getDeviceInfo()
Definition: PlacementInfo.h:3308
PlacementInfo::getGlobalBinMaxLocY
float getGlobalBinMaxLocY()
get top boundary of the bin grid
Definition: PlacementInfo.h:2902
PlacementTimingOptimizer::deviceInfo
DeviceInfo * deviceInfo
Definition: PlacementTimingOptimizer.h:199
PlacementTimingOptimizer::dumpClockRegionClusters
void dumpClockRegionClusters()
Definition: PlacementTimingOptimizer.cc:848
PlacementTimingOptimizer::netActualSlackPinNum
std::map< PlacementInfo::PlacementNet *, int > netActualSlackPinNum
Definition: PlacementTimingOptimizer.h:223
PlacementTimingOptimizer::timingInfo
PlacementTimingInfo * timingInfo
Definition: PlacementTimingOptimizer.h:197
PlacementTimingOptimizer::findCriticalPath
std::vector< int > findCriticalPath()
Definition: PlacementTimingOptimizer.cc:97
PlacementInfo::updateElementBinGrid
void updateElementBinGrid()
map design cells to the bins in the bin grid.
Definition: PlacementInfo.cc:906
PlacementTimingOptimizer::STA_Cnt
int STA_Cnt
Definition: PlacementTimingOptimizer.h:218
print_status
void print_status(std::string tmp_string)
Definition: strPrint.cc:44
PlacementTimingOptimizer::increaseLowDelayVal
bool increaseLowDelayVal
Definition: PlacementTimingOptimizer.h:225
print_warning
void print_warning(std::string tmp_string)
Definition: strPrint.cc:57
PlacementInfo::isDensePlacement
bool isDensePlacement()
Definition: PlacementInfo.h:4388
PlacementInfo::getPlacementUnitByCellId
PlacementUnit * getPlacementUnitByCellId(int cellId)
Definition: PlacementInfo.h:3127
PlacementInfo::PlacementUnit
a movement unit in placement with information of location and resource demand
Definition: PlacementInfo.h:1010
DesignInfo::DesignCell::getCellId
int getCellId()
Get the Cell Id in the cell list.
Definition: DesignInfo.h:1037
PlacementTimingOptimizer::placementInfo
PlacementInfo * placementInfo
Definition: PlacementTimingOptimizer.h:196
PlacementInfo::legalizeXYInArea
void legalizeXYInArea(PlacementUnit *curPU, float &fX, float &fY)
move the PlacementUnit to ensure the cells in it are within the device area.
Definition: PlacementInfo.h:3364
PlacementInfo::getTimingInfo
PlacementTimingInfo * getTimingInfo()
Definition: PlacementInfo.h:3313
PlacementTimingOptimizer::PlacementTimingOptimizer
PlacementTimingOptimizer(PlacementInfo *placementInfo, std::map< std::string, std::string > &JSONCfg)
Definition: PlacementTimingOptimizer.cc:30
DesignInfo::getCells
std::vector< DesignCell * > & getCells()
Definition: DesignInfo.h:1609
PlacementInfo::getPU2ClockRegionColumn
std::map< PlacementUnit *, int > & getPU2ClockRegionColumn()
get the PlacementUnit Mapping to clock region column for timing optimzation
Definition: PlacementInfo.h:4353
PlacementTimingInfo::getSimplePlacementTimingInfo
std::vector< TimingGraph< DesignInfo::DesignCell >::TimingNode * > & getSimplePlacementTimingInfo()
Get the Simple Timing Info object which regard design cells as timing nodes.
Definition: PlacementTimingInfo.h:835
PlacementTimingOptimizer::conductStaticTimingAnalysis
float conductStaticTimingAnalysis(bool enforeOptimisticTiming=false)
Definition: PlacementTimingOptimizer.cc:218
PlacementTimingOptimizer::clockRegionclusters
std::vector< std::vector< int > > clockRegionclusters
Definition: PlacementTimingOptimizer.h:222
PlacementInfo::getPlacementNets
std::vector< PlacementNet * > & getPlacementNets()
Definition: PlacementInfo.h:2822
PlacementTimingOptimizer::getSlackThr
float getSlackThr()
Definition: PlacementTimingOptimizer.cc:370
PlacementInfo::getGlobalBinGrid
std::vector< std::vector< PlacementBinInfo * > > & getGlobalBinGrid()
Definition: PlacementInfo.h:4373
PlacementInfo::PlacementUnpackedCell
the smallest, indivisible, representable component. It will include only one standard cell
Definition: PlacementInfo.h:1447
PlacementTimingOptimizer::getPUId2Slack
std::vector< float > & getPUId2Slack(bool update=false)
Definition: PlacementTimingOptimizer.cc:892
PlacementTimingOptimizer::propogateArrivalTime
void propogateArrivalTime()
Definition: PlacementTimingOptimizer.cc:886
print_info
void print_info(std::string tmp_string)
Definition: strPrint.cc:39
checkHalfColumn.i
int i
Definition: checkHalfColumn.py:5
PlacementInfo::getDesignInfo
DesignInfo * getDesignInfo()
Definition: PlacementInfo.h:3303
PlacementTimingOptimizer::enableCounter
bool enableCounter
Definition: PlacementTimingOptimizer.h:226
PlacementTimingOptimizer::setPinsLocation
void setPinsLocation()
Definition: PlacementTimingOptimizer.cc:46
PlacementTimingOptimizer::clockRegionClusterTooLarge
bool clockRegionClusterTooLarge
Definition: PlacementTimingOptimizer.h:220
PlacementTimingOptimizer::JSONCfg
std::map< std::string, std::string > & JSONCfg
Definition: PlacementTimingOptimizer.h:202
PlacementInfo::getPU2ClockRegionCenters
std::map< PlacementUnit *, std::pair< float, float > > & getPU2ClockRegionCenters()
get the PlacementUnit Mapping to clock region centers for timing optimzation
Definition: PlacementInfo.h:4343
DesignInfo::DesignCell::getOutputNets
std::vector< DesignNet * > & getOutputNets()
Definition: DesignInfo.h:906
DeviceInfo::getClockRegions
std::vector< std::vector< ClockRegion * > > & getClockRegions()
Get the Clock Regions in an 2D array clockregion[Y][X].
Definition: DeviceInfo.h:1261
DesignInfo::getPins
std::vector< DesignPin * > & getPins()
Definition: DesignInfo.h:1617
PlacementTimingInfo::TimingGraph::sortedEndpointByDelay
void sortedEndpointByDelay()
Definition: PlacementTimingInfo.h:684
PlacementInfo
Information related to FPGA placement (wirelength optimization, cell spreading, legalization,...
Definition: PlacementInfo.h:59
PlacementTimingInfo::getSimplePlacementTimingGraph
TimingGraph< DesignInfo::DesignCell > * getSimplePlacementTimingGraph()
Get the Simple Placement Timing Graph object.
Definition: PlacementTimingInfo.h:850