36 std::map<std::string, std::string> &JSONCfg)
37 : designInfo(designInfo), deviceInfo(deviceInfo), JSONCfg(JSONCfg)
52 if (pair.first.find(
"ClockPeriod:") != std::string::npos)
54 auto clockDriver = pair.first;
55 std::string from =
"ClockPeriod:";
59 float tmpClkPeriod = std::stof(pair.second);
62 for (
auto succPin : driverNet->getPinsBeDriven())
64 auto cell = succPin->getCell();
84 auto newNode = nodes[curCell->getCellId()];
85 newNode->setInnerDelay(1.3);
89 print_status(
"PlacementTimingInfo: set DSP inner delay");
94 print_status(
"PlacementTimingInfo: building simple timing graph (TimingNode is DesignCell)");
103 if (curCell->isTimingEndPoint())
105 if (!curCell->isDSP())
107 newNode->setIsRegister();
110 newNode->setClockPeriod(
cellId2Period[curCell->getCellId()]);
117 else if (!
DSPCritical || curCell->checkHasDSPReg())
119 newNode->setIsRegister();
122 newNode->setClockPeriod(
cellId2Period[curCell->getCellId()]);
133 float defaultNetDelay = 1;
137 int curId = curCell->getCellId();
138 for (
auto srcPin : curCell->getOutputPins())
141 auto curNet = srcPin->getNet();
144 if (curNet->checkIsGlobalClock() || curNet->checkIsPowerNet())
146 for (
auto pinBeDriven : curNet->getPinsBeDriven())
148 if (
auto cellBeDriven = pinBeDriven->getCell())
183 print_status(
"PlacementTimingInfo: built simple timing graph");
188 print_status(
"PlacementTimingInfo: Timing graph starts forward levalization");
189 forwardlevel2NodeIds.clear();
191 std::vector<int> curLevelIds;
193 for (
unsigned int i = 0;
i < nodes.size();
i++)
195 if (nodes[
i]->checkIsRegister())
197 curLevelIds.push_back(
i);
198 nodes[
i]->setForwardLevel(0);
203 while (curLevelIds.size())
206 forwardlevel2NodeIds.push_back(curLevelIds);
210 int nextLevel = curLevel + 1;
211 for (
auto curId : forwardlevel2NodeIds[curLevel])
213 for (
auto outEdge : nodes[curId]->getOutEdges())
215 int nextId = outEdge->getSink()->getId();
217 if (!nodes[nextId]->checkIsRegister())
219 if (nodes[nextId]->getForwardLevel() < nextLevel)
221 nodes[nextId]->setForwardLevel(nextLevel);
222 curLevelIds.push_back(nextId);
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)
237 nodeInPath.push_back(tmpId);
238 findALoopFromNode(nodeInPath, tmpId, tmpId, 0);
244 for (
unsigned int level = 0; level < forwardlevel2NodeIds.size(); level++)
246 std::vector<int> filteredList;
247 filteredList.clear();
248 for (
auto id : forwardlevel2NodeIds[level])
250 assert(nodes[
id]->getForwardLevel() >= 0);
251 if ((
unsigned int)nodes[
id]->getForwardLevel() == level)
252 filteredList.push_back(
id);
254 forwardlevel2NodeIds[level] = filteredList;
258 for (
int level = forwardlevel2NodeIds.size() - 2; level >= 0; level--)
260 for (
auto curId : forwardlevel2NodeIds[level])
262 for (
auto outEdge : nodes[curId]->getOutEdges())
264 int nextId = outEdge->getSink()->getId();
266 if (!nodes[nextId]->checkIsRegister())
268 if (nodes[nextId]->getDestLevel() > nodes[curId]->getDestLevel())
270 nodes[curId]->setDestLevel(nodes[nextId]->getDestLevel());
277 longPathThresholdLevel = 1;
279 int thresholdLevelNum = nodes.size() * longPathThrRatio;
280 int mediumThresholdLevelNum = nodes.size() * mediumPathThrRatio;
282 std::string levelInfoStr =
" details: ";
283 for (
unsigned int i = 0;
i < forwardlevel2NodeIds.size();
i++)
285 if (cntNodes < thresholdLevelNum)
287 longPathThresholdLevel =
i;
289 if (cntNodes < mediumThresholdLevelNum)
291 mediumPathThresholdLevel =
i;
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()) +
"), ";
298 for (
unsigned int i = 0;
i < nodes.size();
i++)
300 nodes[
i]->sortInEdgesByForwardLevel();
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");
311 print_status(
"PlacementTimingInfo: Timing graph starts backward levalization");
312 backwardlevel2NodeIds.clear();
314 std::vector<int> curLevelIds;
316 for (
unsigned int i = 0;
i < nodes.size();
i++)
318 if (nodes[
i]->checkIsRegister())
320 curLevelIds.push_back(
i);
321 nodes[
i]->setBackwardLevel(0);
326 while (curLevelIds.size())
329 backwardlevel2NodeIds.push_back(curLevelIds);
333 int nextLevel = curLevel + 1;
334 for (
auto curId : backwardlevel2NodeIds[curLevel])
336 for (
auto inEdge : nodes[curId]->getInEdges())
338 int nextId = inEdge->getSource()->getId();
340 if (!nodes[nextId]->checkIsRegister())
342 if (nodes[nextId]->getBackwardLevel() < nextLevel)
344 nodes[nextId]->setBackwardLevel(nextLevel);
345 curLevelIds.push_back(nextId);
354 for (
unsigned int level = 0; level < backwardlevel2NodeIds.size(); level++)
356 std::vector<int> filteredList;
357 filteredList.clear();
358 for (
auto id : backwardlevel2NodeIds[level])
360 assert(nodes[
id]->getBackwardLevel() >= 0);
361 if ((
unsigned int)nodes[
id]->getBackwardLevel() == level)
362 filteredList.push_back(
id);
364 backwardlevel2NodeIds[level] = filteredList;
367 for (
unsigned int level = 0; level < backwardlevel2NodeIds.size() - 1; level++)
369 for (
auto curId : backwardlevel2NodeIds[level])
371 assert(curId < nodes.size());
372 float curClockPeriod = nodes[curId]->getClockPeriod();
373 if (curClockPeriod < 0)
377 for (
auto inEdge : nodes[curId]->getInEdges())
379 int nextId = inEdge->getSource()->getId();
381 assert(nextId < nodes.size());
382 if (!nodes[nextId]->checkIsRegister())
384 nodes[nextId]->setClockPeriod(curClockPeriod);
390 for (
unsigned int i = 0;
i < nodes.size();
i++)
392 nodes[
i]->sortOutEdgesByBackwardLevel();
395 print_status(
"PlacementTimingInfo: Timing graph finished backward levalization");
398 template <
typename nodeType>
401 std::vector<int> resPath;
403 resPath.push_back(targetId);
405 int curId = targetId;
406 while (nodes[curId]->getForwardLevel() != 0)
408 int maxLevelInLastId = -1;
409 int cellInMaxLevelInLastId = -1;
410 for (
auto inEdge : nodes[curId]->getInEdges())
412 int lastId = inEdge->getSource()->getId();
414 if (nodes[lastId]->getForwardLevel() > maxLevelInLastId && !nodes[lastId]->checkIsRegister())
416 maxLevelInLastId = nodes[lastId]->getForwardLevel();
417 cellInMaxLevelInLastId = lastId;
420 if (cellInMaxLevelInLastId < 0)
422 curId = cellInMaxLevelInLastId;
423 resPath.push_back(curId);
428 template <
typename nodeType>
431 std::vector<int> resPath;
433 resPath.push_back(targetId);
435 int targetPathLength = nodes[targetId]->getLongestPathLength();
436 int curId = targetId;
439 int maxLevelInLastId = -1;
440 int cellInMaxLevelInLastId = -1;
441 for (
auto outEdge : nodes[curId]->getOutEdges())
443 int lastId = outEdge->getSink()->getId();
444 if (nodes[lastId]->getBackwardLevel() > maxLevelInLastId &&
445 nodes[lastId]->getLongestPathLength() >= targetPathLength && !nodes[lastId]->checkIsRegister())
447 maxLevelInLastId = nodes[lastId]->getBackwardLevel();
448 cellInMaxLevelInLastId = lastId;
451 if (cellInMaxLevelInLastId < 0)
453 curId = cellInMaxLevelInLastId;
454 resPath.push_back(curId);
459 template <
typename nodeType>
461 unsigned int sizeThr,
462 std::set<int> &exceptionCells,
int fanoutThr)
464 std::vector<int> resSucessors;
465 std::stack<int> nodeStack;
466 std::set<int> nodeSet;
468 resSucessors.clear();
469 nodeSet.insert(startNodeId);
470 resSucessors.push_back(startNodeId);
471 nodeStack.push(startNodeId);
472 int targetPathLen = nodes[startNodeId]->getLongestPathLength();
474 if (nodes[startNodeId]->getForwardLevel() > targetPathLen * 0.2)
479 resSucessors.push_back(startNodeId);
480 while (nodeStack.size() && nodeSet.size() < sizeThr)
482 int curNode = nodeStack.top();
485 for (
auto outEdge : nodes[curNode]->getOutEdges())
487 int nextId = outEdge->getSink()->getId();
489 if (!nodes[nextId]->checkIsRegister() && nodes[nextId]->getLongestPathLength() > pathLenThr)
491 if (nodeSet.find(nextId) == nodeSet.end())
493 resSucessors.push_back(nextId);
494 nodeSet.insert(nextId);
495 nodeStack.push(nextId);
500 for (
auto inEdge : nodes[curNode]->getInEdges())
502 int nextId = inEdge->getSource()->getId();
504 if (!nodes[nextId]->checkIsRegister() && nodes[nextId]->getLongestPathLength() > pathLenThr)
506 if (nodeSet.find(nextId) == nodeSet.end())
508 resSucessors.push_back(nextId);
509 nodeSet.insert(nextId);
510 nodeStack.push(nextId);
518 template <
typename nodeType>
520 unsigned int sizeThr,
521 std::set<int> &exceptionCells)
523 std::vector<int> resSucessors;
524 std::queue<int> nodeQ;
525 std::set<int> nodeSet;
527 resSucessors.clear();
528 resSucessors.push_back(startNodeId);
529 nodeSet.insert(startNodeId);
530 nodeQ.push(startNodeId);
533 int targetPathLen = nodes[startNodeId]->getLongestPathLength();
535 if (nodes[startNodeId]->getForwardLevel() > targetPathLen * 0.2)
540 while (nodeQ.size() && nodeSet.size() < sizeThr)
542 int curNode = nodeQ.front();
545 for (
auto outEdge : nodes[curNode]->getOutEdges())
547 int nextId = outEdge->getSink()->getId();
549 if (!nodes[nextId]->checkIsRegister() && nodes[nextId]->getLongestPathLength() > pathLenThr)
551 if (nodeSet.find(nextId) == nodeSet.end() && exceptionCells.find(nextId) == exceptionCells.end())
553 resSucessors.push_back(nextId);
554 nodeSet.insert(nextId);
560 for (
auto inEdge : nodes[curNode]->getInEdges())
562 int nextId = inEdge->getSource()->getId();
564 if (!nodes[nextId]->checkIsRegister() && nodes[nextId]->getLongestPathLength() > pathLenThr)
566 if (nodeSet.find(nextId) == nodeSet.end() && exceptionCells.find(nextId) == exceptionCells.end())
568 resSucessors.push_back(nextId);
569 nodeSet.insert(nextId);
580 int nodeNum = nodes.size();
581 #pragma omp parallel for
582 for (
int j = 0; j < nodeNum; j++)
584 auto curNode = nodes[j];
585 curNode->setLatestInputArrival(0.0);
586 curNode->setLatestOutputArrival(0.0);
587 curNode->setSlowestPredecessorId(-1);
589 for (
unsigned int i = 1;
i < forwardlevel2NodeIds.size();
i++)
591 int numNodeInLayer = forwardlevel2NodeIds[
i].size();
592 #pragma omp parallel for
593 for (
int j = 0; j < numNodeInLayer; j++)
595 auto curNodeId = forwardlevel2NodeIds[
i][j];
596 auto curNode = nodes[curNodeId];
597 for (
auto inEdge : curNode->getInEdges())
599 int predId = inEdge->getSource()->getId();
600 float predDelay = inEdge->getSource()->getLatestInputArrival();
601 float edgeDelay = inEdge->getDelay();
604 if (inEdge->getSource()->getInnerDelay() < 1.0 || inEdge->getSource()->getForwardLevel() > 0)
605 newDelay = predDelay + edgeDelay + inEdge->getSource()->getInnerDelay();
607 newDelay = predDelay + edgeDelay;
608 if (newDelay > curNode->getLatestInputArrival())
610 curNode->setLatestInputArrival(newDelay);
611 curNode->setSlowestPredecessorId(predId);
613 curNode->setLatestOutputArrival(newDelay);
619 int numNodeInLayer = forwardlevel2NodeIds[0].size();
620 #pragma omp parallel for
621 for (
int j = 0; j < numNodeInLayer; j++)
623 auto curNodeId = forwardlevel2NodeIds[0][j];
624 assert(curNodeId < nodes.size());
625 auto curNode = nodes[curNodeId];
626 if (curNode->getDesignNode()->isVirtualCell())
629 for (
auto inEdge : curNode->getInEdges())
631 if (inEdge->getSource())
633 if (inEdge->getSource()->getForwardLevel() > 0)
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())
641 curNode->setLatestInputArrival(newDelay);
642 curNode->setSlowestPredecessorId(predId);
652 int nodeNum = nodes.size();
653 #pragma omp parallel for
654 for (
int j = 0; j < nodeNum; j++)
656 auto curNode = nodes[j];
657 curNode->setInitialRequiredArrivalTime(clockPeriod);
658 curNode->setEarlestSuccessorId(-1);
660 for (
unsigned int i = 1;
i < backwardlevel2NodeIds.size();
i++)
662 int numNodeInLayer = backwardlevel2NodeIds[
i].size();
663 #pragma omp parallel for
664 for (
int j = 0; j < numNodeInLayer; j++)
666 auto curNodeId = backwardlevel2NodeIds[
i][j];
667 auto curNode = nodes[curNodeId];
668 for (
auto outEdge : curNode->getOutEdges())
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())
676 curNode->setRequiredArrivalTime(newRequiredArrival);
677 curNode->setEarlestSuccessorId(succId);
684 template <
typename nodeType>
687 int slowestPredecessorId = curNodeId;
688 std::vector<int> resPath;
690 resPath.push_back(slowestPredecessorId);
691 while (slowestPredecessorId != -1)
693 slowestPredecessorId = nodes[slowestPredecessorId]->getSlowestPredecessorId();
694 resPath.push_back(slowestPredecessorId);
696 if (slowestPredecessorId == -1 || nodes[slowestPredecessorId]->getForwardLevel() == 0)
702 template <
typename nodeType>
704 std::vector<int> &isCovered,
705 std::vector<int> &resPath,
708 int slowestPredecessorId = curNodeId;
710 resPath.push_back(slowestPredecessorId);
711 while (slowestPredecessorId != -1)
713 slowestPredecessorId = nodes[slowestPredecessorId]->getSlowestPredecessorId();
714 resPath.push_back(slowestPredecessorId);
716 if (isCovered[slowestPredecessorId] > 30 && nodes[slowestPredecessorId]->getForwardLevel() > 5 &&
717 nodes[slowestPredecessorId]->getOutEdges().size() > 1)
731 if (slowestPredecessorId == -1 || nodes[slowestPredecessorId]->getForwardLevel() == 0)