AMF-Placer  2.0
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
PlacementTimingInfo.cc
Go to the documentation of this file.
1 
25 #include "PlacementTimingInfo.h"
26 #include "PlacementInfo.h"
27 #include "stringCheck.h"
28 #include <algorithm>
29 #include <cmath>
30 #include <codecvt>
31 #include <queue>
32 #include <set>
33 #include <stack>
34 
36  std::map<std::string, std::string> &JSONCfg)
37  : designInfo(designInfo), deviceInfo(deviceInfo), JSONCfg(JSONCfg)
38 {
39  if (JSONCfg.find("PlacementTimingInfoVerbose") != JSONCfg.end())
40  verbose = JSONCfg["PlacementTimingInfoVerbose"] == "true";
41 
42  if (JSONCfg.find("ClockPeriod") != JSONCfg.end())
43  clockPeriod = std::stof(JSONCfg["ClockPeriod"]);
44 
45  if (JSONCfg.find("DSPCritical") != JSONCfg.end())
46  DSPCritical = JSONCfg["DSPCritical"] == "true";
47 
48  clockNet2Period.clear();
49  cellId2Period.clear();
50  for (auto pair : JSONCfg)
51  {
52  if (pair.first.find("ClockPeriod:") != std::string::npos)
53  {
54  auto clockDriver = pair.first;
55  std::string from = "ClockPeriod:";
56  std::string to = "";
57  replaceAll(clockDriver, from, to);
58  auto driverNet = designInfo->getNet(clockDriver);
59  float tmpClkPeriod = std::stof(pair.second);
60 
61  clockNet2Period[driverNet] = tmpClkPeriod;
62  for (auto succPin : driverNet->getPinsBeDriven())
63  {
64  auto cell = succPin->getCell();
65  if (cell)
66  {
67  cellId2Period[cell->getCellId()] = tmpClkPeriod;
68  }
69  }
70  }
71  }
72 }
73 
75 {
76  if (!DSPCritical)
77  return;
78  auto &nodes = simpleTimingGraph->getNodes();
79  for (auto curCell : designInfo->getCells())
80  {
81 
82  if (curCell->isDSP())
83  {
84  auto newNode = nodes[curCell->getCellId()];
85  newNode->setInnerDelay(1.3);
86  }
87  }
88 
89  print_status("PlacementTimingInfo: set DSP inner delay");
90 }
91 
93 {
94  print_status("PlacementTimingInfo: building simple timing graph (TimingNode is DesignCell)");
97 
98  for (auto curCell : designInfo->getCells())
99  {
100  auto newNode =
102 
103  if (curCell->isTimingEndPoint())
104  {
105  if (!curCell->isDSP())
106  {
107  newNode->setIsRegister();
108  if (cellId2Period.find(curCell->getCellId()) != cellId2Period.end())
109  {
110  newNode->setClockPeriod(cellId2Period[curCell->getCellId()]);
111  }
112  else
113  {
114  newNode->setClockPeriod(clockPeriod);
115  }
116  }
117  else if (!DSPCritical || curCell->checkHasDSPReg())
118  {
119  newNode->setIsRegister();
120  if (cellId2Period.find(curCell->getCellId()) != cellId2Period.end())
121  {
122  newNode->setClockPeriod(cellId2Period[curCell->getCellId()]);
123  }
124  else
125  {
126  newNode->setClockPeriod(clockPeriod);
127  }
128  }
129  }
131  }
132 
133  float defaultNetDelay = 1;
134  for (auto curCell : designInfo->getCells())
135  {
136  assert(curCell);
137  int curId = curCell->getCellId();
138  for (auto srcPin : curCell->getOutputPins())
139  {
140  assert(srcPin);
141  auto curNet = srcPin->getNet();
142  if (!curNet)
143  continue;
144  if (curNet->checkIsGlobalClock() || curNet->checkIsPowerNet())
145  continue;
146  for (auto pinBeDriven : curNet->getPinsBeDriven())
147  {
148  if (auto cellBeDriven = pinBeDriven->getCell())
149  {
150  assert(srcPin);
151  assert(pinBeDriven);
152  simpleTimingGraph->addEdgeBetween(curId, cellBeDriven->getCellId(), srcPin, pinBeDriven, curNet,
153  defaultNetDelay);
154  }
155  }
156  }
157  }
158 
162 
163  // std::string cellName = "chip/tile0/g_ariane_core.core/ariane/id_stage_i/operand_a_q[21]_i_8";
164  // auto debugCell = designInfo->getCell(cellName);
165  // std::cout << debugCell << "\n";
166  // assert(!simpleTimingGraph->getNodes()[debugCell->getCellId()]->checkIsRegister());
167  // auto listA = simpleTimingGraph->traceBackFromNode(debugCell->getCellId());
168  // auto listB = simpleTimingGraph->traceForwardFromNode(debugCell->getCellId());
169  // std::cout << "\n\n";
170  // for (auto id : listA)
171  // {
172  // std::cout << " " << designInfo->getCells()[id]->getName()
173  // << " level:" << simpleTimingGraph->getNodes()[id]->getForwardLevel()
174  // << " path:" << simpleTimingGraph->getNodes()[id]->getLongestPathLength() << "\n";
175  // }
176  // std::cout << "\n\n";
177  // for (auto id : listB)
178  // {
179  // std::cout << " " << designInfo->getCells()[id]->getName()
180  // << " level:" << simpleTimingGraph->getNodes()[id]->getForwardLevel()
181  // << " path:" << simpleTimingGraph->getNodes()[id]->getLongestPathLength() << "\n";
182  // }
183  print_status("PlacementTimingInfo: built simple timing graph");
184 }
185 
187 {
188  print_status("PlacementTimingInfo: Timing graph starts forward levalization");
189  forwardlevel2NodeIds.clear();
190 
191  std::vector<int> curLevelIds;
192  curLevelIds.clear();
193  for (unsigned int i = 0; i < nodes.size(); i++)
194  {
195  if (nodes[i]->checkIsRegister())
196  {
197  curLevelIds.push_back(i);
198  nodes[i]->setForwardLevel(0);
199  }
200  }
201 
202  int curLevel = 0;
203  while (curLevelIds.size())
204  {
205  // print_info("level#" + std::to_string(curLevel) + " has " + std::to_string(curLevelIds.size()) + " nodes");
206  forwardlevel2NodeIds.push_back(curLevelIds);
207 
208  curLevelIds.clear();
209 
210  int nextLevel = curLevel + 1;
211  for (auto curId : forwardlevel2NodeIds[curLevel])
212  {
213  for (auto outEdge : nodes[curId]->getOutEdges())
214  {
215  int nextId = outEdge->getSink()->getId();
216 
217  if (!nodes[nextId]->checkIsRegister())
218  {
219  if (nodes[nextId]->getForwardLevel() < nextLevel)
220  {
221  nodes[nextId]->setForwardLevel(nextLevel);
222  curLevelIds.push_back(nextId);
223  }
224  }
225  }
226  }
227  curLevel++;
228 
229  if (curLevel > 100)
230  {
231  print_warning("Reach level#" + std::to_string(curLevel) + " has " + std::to_string(curLevelIds.size()) +
232  " nodes. It might mean that there are loops in timing graph.");
233  std::vector<int> nodeInPath;
234  for (auto tmpId : curLevelIds)
235  {
236  nodeInPath.clear();
237  nodeInPath.push_back(tmpId);
238  findALoopFromNode(nodeInPath, tmpId, tmpId, 0);
239  }
240  }
241  }
242 
243  // some nodes are duplicated in some lower levels, remove them
244  for (unsigned int level = 0; level < forwardlevel2NodeIds.size(); level++)
245  {
246  std::vector<int> filteredList;
247  filteredList.clear();
248  for (auto id : forwardlevel2NodeIds[level])
249  {
250  assert(nodes[id]->getForwardLevel() >= 0);
251  if ((unsigned int)nodes[id]->getForwardLevel() == level)
252  filteredList.push_back(id);
253  }
254  forwardlevel2NodeIds[level] = filteredList;
255  }
256 
257  // set the destination level of the nodes, in reversed topological order
258  for (int level = forwardlevel2NodeIds.size() - 2; level >= 0; level--)
259  {
260  for (auto curId : forwardlevel2NodeIds[level])
261  {
262  for (auto outEdge : nodes[curId]->getOutEdges())
263  {
264  int nextId = outEdge->getSink()->getId();
265 
266  if (!nodes[nextId]->checkIsRegister())
267  {
268  if (nodes[nextId]->getDestLevel() > nodes[curId]->getDestLevel())
269  {
270  nodes[curId]->setDestLevel(nodes[nextId]->getDestLevel());
271  }
272  }
273  }
274  }
275  }
276 
277  longPathThresholdLevel = 1;
278 
279  int thresholdLevelNum = nodes.size() * longPathThrRatio;
280  int mediumThresholdLevelNum = nodes.size() * mediumPathThrRatio;
281  int cntNodes = 0;
282  std::string levelInfoStr = " details: ";
283  for (unsigned int i = 0; i < forwardlevel2NodeIds.size(); i++)
284  {
285  if (cntNodes < thresholdLevelNum)
286  {
287  longPathThresholdLevel = i;
288  }
289  if (cntNodes < mediumThresholdLevelNum)
290  {
291  mediumPathThresholdLevel = i;
292  }
293  cntNodes += forwardlevel2NodeIds[i].size();
294  levelInfoStr += std::to_string(i) + "(" + std::to_string(forwardlevel2NodeIds[i].size()) + ", " +
295  std::to_string((float)cntNodes / nodes.size()) + "), ";
296  }
297 
298  for (unsigned int i = 0; i < nodes.size(); i++)
299  {
300  nodes[i]->sortInEdgesByForwardLevel();
301  }
302 
303  print_info("PlacementTimingInfo: total level = " + std::to_string(forwardlevel2NodeIds.size()) + levelInfoStr);
304  print_info("PlacementTimingInfo: long path threshold level = " + std::to_string(longPathThresholdLevel));
305  print_info("PlacementTimingInfo: medium path threshold level = " + std::to_string(mediumPathThresholdLevel));
306  print_status("PlacementTimingInfo: Timing graph finished forward levalization");
307 }
308 
310 {
311  print_status("PlacementTimingInfo: Timing graph starts backward levalization");
312  backwardlevel2NodeIds.clear();
313 
314  std::vector<int> curLevelIds;
315  curLevelIds.clear();
316  for (unsigned int i = 0; i < nodes.size(); i++)
317  {
318  if (nodes[i]->checkIsRegister())
319  {
320  curLevelIds.push_back(i);
321  nodes[i]->setBackwardLevel(0);
322  }
323  }
324 
325  int curLevel = 0;
326  while (curLevelIds.size())
327  {
328  // print_info("level#" + std::to_string(curLevel) + " has " + std::to_string(curLevelIds.size()) + " nodes");
329  backwardlevel2NodeIds.push_back(curLevelIds);
330 
331  curLevelIds.clear();
332 
333  int nextLevel = curLevel + 1;
334  for (auto curId : backwardlevel2NodeIds[curLevel])
335  {
336  for (auto inEdge : nodes[curId]->getInEdges())
337  {
338  int nextId = inEdge->getSource()->getId();
339 
340  if (!nodes[nextId]->checkIsRegister())
341  {
342  if (nodes[nextId]->getBackwardLevel() < nextLevel)
343  {
344  nodes[nextId]->setBackwardLevel(nextLevel);
345  curLevelIds.push_back(nextId);
346  }
347  }
348  }
349  }
350  curLevel++;
351  }
352 
353  // some nodes are duplicated in some lower levels, remove them
354  for (unsigned int level = 0; level < backwardlevel2NodeIds.size(); level++)
355  {
356  std::vector<int> filteredList;
357  filteredList.clear();
358  for (auto id : backwardlevel2NodeIds[level])
359  {
360  assert(nodes[id]->getBackwardLevel() >= 0);
361  if ((unsigned int)nodes[id]->getBackwardLevel() == level)
362  filteredList.push_back(id);
363  }
364  backwardlevel2NodeIds[level] = filteredList;
365  }
366 
367  for (unsigned int level = 0; level < backwardlevel2NodeIds.size() - 1; level++)
368  {
369  for (auto curId : backwardlevel2NodeIds[level])
370  {
371  assert(curId < nodes.size());
372  float curClockPeriod = nodes[curId]->getClockPeriod();
373  if (curClockPeriod < 0)
374  {
375  continue;
376  }
377  for (auto inEdge : nodes[curId]->getInEdges())
378  {
379  int nextId = inEdge->getSource()->getId();
380 
381  assert(nextId < nodes.size());
382  if (!nodes[nextId]->checkIsRegister())
383  {
384  nodes[nextId]->setClockPeriod(curClockPeriod);
385  }
386  }
387  }
388  }
389 
390  for (unsigned int i = 0; i < nodes.size(); i++)
391  {
392  nodes[i]->sortOutEdgesByBackwardLevel();
393  }
394 
395  print_status("PlacementTimingInfo: Timing graph finished backward levalization");
396 }
397 
398 template <typename nodeType>
400 {
401  std::vector<int> resPath;
402  resPath.clear();
403  resPath.push_back(targetId);
404 
405  int curId = targetId;
406  while (nodes[curId]->getForwardLevel() != 0)
407  {
408  int maxLevelInLastId = -1;
409  int cellInMaxLevelInLastId = -1;
410  for (auto inEdge : nodes[curId]->getInEdges())
411  {
412  int lastId = inEdge->getSource()->getId();
413 
414  if (nodes[lastId]->getForwardLevel() > maxLevelInLastId && !nodes[lastId]->checkIsRegister())
415  {
416  maxLevelInLastId = nodes[lastId]->getForwardLevel();
417  cellInMaxLevelInLastId = lastId;
418  }
419  }
420  if (cellInMaxLevelInLastId < 0)
421  break;
422  curId = cellInMaxLevelInLastId;
423  resPath.push_back(curId);
424  }
425  return resPath;
426 }
427 
428 template <typename nodeType>
430 {
431  std::vector<int> resPath;
432  resPath.clear();
433  resPath.push_back(targetId);
434 
435  int targetPathLength = nodes[targetId]->getLongestPathLength();
436  int curId = targetId;
437  while (curId >= 0)
438  {
439  int maxLevelInLastId = -1;
440  int cellInMaxLevelInLastId = -1;
441  for (auto outEdge : nodes[curId]->getOutEdges())
442  {
443  int lastId = outEdge->getSink()->getId();
444  if (nodes[lastId]->getBackwardLevel() > maxLevelInLastId &&
445  nodes[lastId]->getLongestPathLength() >= targetPathLength && !nodes[lastId]->checkIsRegister())
446  {
447  maxLevelInLastId = nodes[lastId]->getBackwardLevel();
448  cellInMaxLevelInLastId = lastId;
449  }
450  }
451  if (cellInMaxLevelInLastId < 0)
452  break;
453  curId = cellInMaxLevelInLastId;
454  resPath.push_back(curId);
455  }
456  return resPath;
457 }
458 
459 template <typename nodeType>
460 std::vector<int> PlacementTimingInfo::TimingGraph<nodeType>::DFSFromNode(int startNodeId, int pathLenThr,
461  unsigned int sizeThr,
462  std::set<int> &exceptionCells, int fanoutThr)
463 {
464  std::vector<int> resSucessors;
465  std::stack<int> nodeStack;
466  std::set<int> nodeSet;
467  nodeSet.clear();
468  resSucessors.clear();
469  nodeSet.insert(startNodeId);
470  resSucessors.push_back(startNodeId);
471  nodeStack.push(startNodeId);
472  int targetPathLen = nodes[startNodeId]->getLongestPathLength();
473 
474  if (nodes[startNodeId]->getForwardLevel() > targetPathLen * 0.2)
475  {
476  return resSucessors;
477  }
478 
479  resSucessors.push_back(startNodeId);
480  while (nodeStack.size() && nodeSet.size() < sizeThr)
481  {
482  int curNode = nodeStack.top();
483  nodeStack.pop();
484 
485  for (auto outEdge : nodes[curNode]->getOutEdges())
486  {
487  int nextId = outEdge->getSink()->getId();
488 
489  if (!nodes[nextId]->checkIsRegister() && nodes[nextId]->getLongestPathLength() > pathLenThr)
490  {
491  if (nodeSet.find(nextId) == nodeSet.end())
492  {
493  resSucessors.push_back(nextId);
494  nodeSet.insert(nextId);
495  nodeStack.push(nextId);
496  }
497  }
498  }
499 
500  for (auto inEdge : nodes[curNode]->getInEdges())
501  {
502  int nextId = inEdge->getSource()->getId();
503 
504  if (!nodes[nextId]->checkIsRegister() && nodes[nextId]->getLongestPathLength() > pathLenThr)
505  {
506  if (nodeSet.find(nextId) == nodeSet.end())
507  {
508  resSucessors.push_back(nextId);
509  nodeSet.insert(nextId);
510  nodeStack.push(nextId);
511  }
512  }
513  }
514  }
515  return resSucessors;
516 }
517 
518 template <typename nodeType>
519 std::vector<int> PlacementTimingInfo::TimingGraph<nodeType>::BFSFromNode(int startNodeId, int pathLenThr,
520  unsigned int sizeThr,
521  std::set<int> &exceptionCells)
522 {
523  std::vector<int> resSucessors;
524  std::queue<int> nodeQ;
525  std::set<int> nodeSet;
526  nodeSet.clear();
527  resSucessors.clear();
528  resSucessors.push_back(startNodeId);
529  nodeSet.insert(startNodeId);
530  nodeQ.push(startNodeId);
531  // int targetPathLen = nodes[startNodeId]->getLongestPathLength();
532 
533  int targetPathLen = nodes[startNodeId]->getLongestPathLength();
534 
535  if (nodes[startNodeId]->getForwardLevel() > targetPathLen * 0.2)
536  {
537  return resSucessors;
538  }
539 
540  while (nodeQ.size() && nodeSet.size() < sizeThr)
541  {
542  int curNode = nodeQ.front();
543  nodeQ.pop();
544 
545  for (auto outEdge : nodes[curNode]->getOutEdges())
546  {
547  int nextId = outEdge->getSink()->getId();
548 
549  if (!nodes[nextId]->checkIsRegister() && nodes[nextId]->getLongestPathLength() > pathLenThr)
550  {
551  if (nodeSet.find(nextId) == nodeSet.end() && exceptionCells.find(nextId) == exceptionCells.end())
552  {
553  resSucessors.push_back(nextId);
554  nodeSet.insert(nextId);
555  nodeQ.push(nextId);
556  }
557  }
558  }
559 
560  for (auto inEdge : nodes[curNode]->getInEdges())
561  {
562  int nextId = inEdge->getSource()->getId();
563 
564  if (!nodes[nextId]->checkIsRegister() && nodes[nextId]->getLongestPathLength() > pathLenThr)
565  {
566  if (nodeSet.find(nextId) == nodeSet.end() && exceptionCells.find(nextId) == exceptionCells.end())
567  {
568  resSucessors.push_back(nextId);
569  nodeSet.insert(nextId);
570  nodeQ.push(nextId);
571  }
572  }
573  }
574  }
575  return resSucessors;
576 }
577 
579 {
580  int nodeNum = nodes.size();
581 #pragma omp parallel for
582  for (int j = 0; j < nodeNum; j++)
583  {
584  auto curNode = nodes[j];
585  curNode->setLatestInputArrival(0.0);
586  curNode->setLatestOutputArrival(0.0);
587  curNode->setSlowestPredecessorId(-1);
588  }
589  for (unsigned int i = 1; i < forwardlevel2NodeIds.size(); i++)
590  {
591  int numNodeInLayer = forwardlevel2NodeIds[i].size();
592 #pragma omp parallel for
593  for (int j = 0; j < numNodeInLayer; j++)
594  {
595  auto curNodeId = forwardlevel2NodeIds[i][j];
596  auto curNode = nodes[curNodeId];
597  for (auto inEdge : curNode->getInEdges())
598  {
599  int predId = inEdge->getSource()->getId();
600  float predDelay = inEdge->getSource()->getLatestInputArrival();
601  float edgeDelay = inEdge->getDelay();
602  float newDelay;
603 
604  if (inEdge->getSource()->getInnerDelay() < 1.0 || inEdge->getSource()->getForwardLevel() > 0)
605  newDelay = predDelay + edgeDelay + inEdge->getSource()->getInnerDelay();
606  else
607  newDelay = predDelay + edgeDelay;
608  if (newDelay > curNode->getLatestInputArrival())
609  {
610  curNode->setLatestInputArrival(newDelay);
611  curNode->setSlowestPredecessorId(predId);
612  // curNode->setLatestOutputArrival(newDelay + curNode->getInnerDelay());
613  curNode->setLatestOutputArrival(newDelay);
614  }
615  }
616  }
617  }
618 
619  int numNodeInLayer = forwardlevel2NodeIds[0].size();
620 #pragma omp parallel for
621  for (int j = 0; j < numNodeInLayer; j++)
622  {
623  auto curNodeId = forwardlevel2NodeIds[0][j];
624  assert(curNodeId < nodes.size());
625  auto curNode = nodes[curNodeId];
626  if (curNode->getDesignNode()->isVirtualCell())
627  continue;
628 
629  for (auto inEdge : curNode->getInEdges())
630  {
631  if (inEdge->getSource())
632  {
633  if (inEdge->getSource()->getForwardLevel() > 0)
634  {
635  int predId = inEdge->getSource()->getId();
636  float predDelay = inEdge->getSource()->getLatestInputArrival();
637  float edgeDelay = inEdge->getDelay();
638  float newDelay = predDelay + edgeDelay + inEdge->getSource()->getInnerDelay();
639  if (newDelay > curNode->getLatestInputArrival())
640  {
641  curNode->setLatestInputArrival(newDelay);
642  curNode->setSlowestPredecessorId(predId);
643  }
644  }
645  }
646  }
647  }
648 }
649 
651 {
652  int nodeNum = nodes.size();
653 #pragma omp parallel for
654  for (int j = 0; j < nodeNum; j++)
655  {
656  auto curNode = nodes[j];
657  curNode->setInitialRequiredArrivalTime(clockPeriod);
658  curNode->setEarlestSuccessorId(-1);
659  }
660  for (unsigned int i = 1; i < backwardlevel2NodeIds.size(); i++)
661  {
662  int numNodeInLayer = backwardlevel2NodeIds[i].size();
663 #pragma omp parallel for
664  for (int j = 0; j < numNodeInLayer; j++)
665  {
666  auto curNodeId = backwardlevel2NodeIds[i][j];
667  auto curNode = nodes[curNodeId];
668  for (auto outEdge : curNode->getOutEdges())
669  {
670  int succId = outEdge->getSink()->getId();
671  float succRequiredArrival = outEdge->getSink()->getRequiredArrivalTime();
672  float edgeDelay = outEdge->getDelay();
673  float newRequiredArrival = succRequiredArrival - edgeDelay - outEdge->getSink()->getInnerDelay();
674  if (newRequiredArrival < curNode->getRequiredArrivalTime())
675  {
676  curNode->setRequiredArrivalTime(newRequiredArrival);
677  curNode->setEarlestSuccessorId(succId);
678  }
679  }
680  }
681  }
682 }
683 
684 template <typename nodeType>
686 {
687  int slowestPredecessorId = curNodeId;
688  std::vector<int> resPath;
689  resPath.clear();
690  resPath.push_back(slowestPredecessorId);
691  while (slowestPredecessorId != -1)
692  {
693  slowestPredecessorId = nodes[slowestPredecessorId]->getSlowestPredecessorId();
694  resPath.push_back(slowestPredecessorId);
695 
696  if (slowestPredecessorId == -1 || nodes[slowestPredecessorId]->getForwardLevel() == 0)
697  break;
698  }
699  return resPath;
700 }
701 
702 template <typename nodeType>
704  std::vector<int> &isCovered,
705  std::vector<int> &resPath,
706  int converThr)
707 {
708  int slowestPredecessorId = curNodeId;
709  resPath.clear();
710  resPath.push_back(slowestPredecessorId);
711  while (slowestPredecessorId != -1)
712  {
713  slowestPredecessorId = nodes[slowestPredecessorId]->getSlowestPredecessorId();
714  resPath.push_back(slowestPredecessorId);
715 
716  if (isCovered[slowestPredecessorId] > 30 && nodes[slowestPredecessorId]->getForwardLevel() > 5 &&
717  nodes[slowestPredecessorId]->getOutEdges().size() > 1)
718  {
719  // if (nodes[slowestPredecessorId]->getDesignNode()->isDSP() ||
720  // nodes[slowestPredecessorId]->getDesignNode()->isBRAM() ||
721  // nodes[slowestPredecessorId]->getDesignNode()->isCarry())
722  // {
723  // if (isCovered[slowestPredecessorId] > 60)
724  // return false;
725  // }
726  // else
727  {
728  return false;
729  }
730  }
731  if (slowestPredecessorId == -1 || nodes[slowestPredecessorId]->getForwardLevel() == 0)
732  break;
733  }
734  return true;
735 }
736 
PlacementTimingInfo::clockPeriod
float clockPeriod
Definition: PlacementTimingInfo.h:882
PlacementTimingInfo::designInfo
DesignInfo * designInfo
Definition: PlacementTimingInfo.h:873
PlacementTimingInfo::TimingGraph::traceBackFromNode
std::vector< int > traceBackFromNode(int targetId)
find the longest path from a register to the target node (id)
Definition: PlacementTimingInfo.cc:399
PlacementTimingInfo::TimingGraph::getNodes
std::vector< TimingNode * > & getNodes()
Definition: PlacementTimingInfo.h:537
PlacementTimingInfo::TimingGraph::setClockPeriod
void setClockPeriod(float _clockPeriod)
Set the clock period.
Definition: PlacementTimingInfo.h:789
PlacementTimingInfo::clockNet2Period
std::map< DesignInfo::DesignNet *, float > clockNet2Period
Definition: PlacementTimingInfo.h:885
PlacementTimingInfo::TimingGraph::setLongestPathLength
void setLongestPathLength()
Set the Longest Path Length for each TimingNode in the TimingGraph and get a sorted vector of TimingN...
Definition: PlacementTimingInfo.h:668
PlacementTimingInfo::TimingGraph::DFSFromNode
std::vector< int > DFSFromNode(int startNodeId, int pathLenThr, unsigned sizeThr, std::set< int > &exceptionCells, int fanoutThr=10000000)
DFS the sucessors(predecessors) of a node in the long paths.
Definition: PlacementTimingInfo.cc:460
PlacementTimingInfo::TimingGraph::backwardLevelization
void backwardLevelization()
propogate the backward level of each TimingNode backward level of a TimingNode is the distance toward...
Definition: PlacementTimingInfo.cc:309
DesignInfo::getNet
DesignNet * getNet(std::string &tmpName)
Definition: DesignInfo.h:1644
PlacementTimingInfo.h
This header file contains the classes of data which record the timing information related to placemen...
PlacementTimingInfo::TimingGraph::backTraceDelayLongestPathFromNode
std::vector< int > backTraceDelayLongestPathFromNode(int curNodeId)
backtrace the longest delay path from the node
Definition: PlacementTimingInfo.cc:685
stringCheck.h
print_status
void print_status(std::string tmp_string)
Definition: strPrint.cc:44
PlacementTimingInfo::TimingGraph::forwardLevelization
void forwardLevelization()
propogate the forward level of each TimingNode forward level of a TimingNode is the distance toward t...
Definition: PlacementTimingInfo.cc:186
PlacementTimingInfo::TimingGraph::propogateArrivalTime
void propogateArrivalTime()
propogate the timing delay along the TimingEdge
Definition: PlacementTimingInfo.cc:578
print_warning
void print_warning(std::string tmp_string)
Definition: strPrint.cc:57
PlacementTimingInfo::TimingGraph::addEdgeBetween
void addEdgeBetween(int idA, int idB, DesignInfo::DesignPin *srcPin, DesignInfo::DesignPin *sinkPin, DesignInfo::DesignNet *net=nullptr, float delay=0.0)
add a TimingEdge into TimingGraph based on some related information
Definition: PlacementTimingInfo.h:557
PlacementTimingInfo::cellId2Period
std::map< int, float > cellId2Period
Definition: PlacementTimingInfo.h:886
PlacementTimingInfo::TimingGraph< DesignInfo::DesignCell >
PlacementTimingInfo::verbose
bool verbose
Definition: PlacementTimingInfo.h:880
DesignInfo::getCells
std::vector< DesignCell * > & getCells()
Definition: DesignInfo.h:1609
PlacementTimingInfo::DSPCritical
bool DSPCritical
Definition: PlacementTimingInfo.h:883
DeviceInfo
Information class related to FPGA device, including the details of BEL/Site/Tile/ClockRegion.
Definition: DeviceInfo.h:43
print_info
void print_info(std::string tmp_string)
Definition: strPrint.cc:39
checkHalfColumn.i
int i
Definition: checkHalfColumn.py:5
PlacementTimingInfo::PlacementTimingInfo
PlacementTimingInfo(DesignInfo *designInfo, DeviceInfo *deviceInfo, std::map< std::string, std::string > &JSONCfg)
Construct a new Placement Timing Info object based on the information of design and device.
Definition: PlacementTimingInfo.cc:35
PlacementInfo.h
This header file mainly contains the definition of class PlacementInfo, including information related...
PlacementTimingInfo::setDSPInnerDelay
void setDSPInnerDelay()
Definition: PlacementTimingInfo.cc:74
PlacementTimingInfo::TimingGraph::traceForwardFromNode
std::vector< int > traceForwardFromNode(int targetId)
find the longest path from the target node (id) to a register
Definition: PlacementTimingInfo.cc:429
PlacementTimingInfo::TimingGraph::insertTimingNode
void insertTimingNode(TimingNode *timingNode)
insert a TimingNode into this TimingGraph
Definition: PlacementTimingInfo.h:532
PlacementTimingInfo::JSONCfg
std::map< std::string, std::string > & JSONCfg
Definition: PlacementTimingInfo.h:877
replaceAll
void replaceAll(std::string &str, const std::string from, const std::string to)
Definition: stringCheck.cc:50
DesignInfo
Information related to FPGA designs, including design cells and their interconnections.
Definition: DesignInfo.h:51
PlacementTimingInfo::buildSimpleTimingGraph
void buildSimpleTimingGraph()
build a simple timing graph, where the inner delay between pin paris for an element will be identical
Definition: PlacementTimingInfo.cc:92
PlacementTimingInfo::TimingGraph::backPropogateRequiredArrivalTime
void backPropogateRequiredArrivalTime()
back propogate the required arrival time
Definition: PlacementTimingInfo.cc:650
PlacementTimingInfo::simpleTimingGraph
TimingGraph< DesignInfo::DesignCell > * simpleTimingGraph
Definition: PlacementTimingInfo.h:879
PlacementTimingInfo::TimingGraph::BFSFromNode
std::vector< int > BFSFromNode(int startNodeId, int pathLenThr, unsigned sizeThr, std::set< int > &exceptionCells)
BFS the sucessors(predecessors) of a node in the long paths.
Definition: PlacementTimingInfo.cc:519