AMF-Placer  2.0
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
InitialPacker.cc
Go to the documentation of this file.
1 
26 #include "InitialPacker.h"
27 
29 {
30  cellId2PlacementUnit.clear();
31  placementUnits.clear();
32  placementMacros.clear();
33  cellInMacros.clear();
34  placementUnpackedCells.clear();
35 
36  print_status("InitialPacker Finding Macros");
38  findMuxMacros();
40  findDSPMacros();
41 
42  if (JSONCfg.find("unpredictable macro file") != JSONCfg.end())
43  {
44  loadOtherCLBMacros(JSONCfg["unpredictable macro file"]);
45  }
46 
48 
49  LUTFFPairing();
50 
51  print_status("InitialPacker Finding unpacked units");
53 
54  if (JSONCfg.find("fixed units file") != JSONCfg.end())
55  {
56  loadFixedPlacementUnits(JSONCfg["fixed units file"]);
57  }
58  else
59  {
61  "No fixed cell in the design. Floating placement is not allowed temporarily."); // this can be disabled but
62  // might lead to
63  // unpredictable placement.
64  assert(false && "No fixed cell in the design. Floating placement is not allowed temporarily.");
65  }
66 
67  print_info("#Cells In Macro = " + std::to_string(cellInMacros.size()));
68 
70 
71  // since new placement units might be generated, we need to update the net information
72  print_status("InitialPacker Loading Nets");
74 
75  // update the BEL information for all the cells (including those virtual cells)
77 
78  // for each FF, check/record its control set
81 
82  // enhanceIONets();
83  // std::string dumpFile = "netNumDisribution.gz";
84  // print_status("ParallelCLBPacker: dumping unpackable PUs archieve to: " + dumpFile);
85  // std::stringstream outfile1;
86 
87  // for (auto tmpPU : placementInfo->getPlacementUnits())
88  // {
89  // outfile1 << tmpPU->getNetsSetPtr()->size() << " " << tmpPU->getName() << "\n";
90  // }
91  // writeStrToGZip(dumpFile, outfile1);
92 
94 }
95 
97 {
98  for (auto net : placementInfo->getPlacementNets())
99  {
100  if (net->getDriverUnits().size() == 1)
101  {
102  if (net->getDriverUnits()[0]->isFixed())
103  {
104  net->getDesignNet()->enhanceOverallClusterNetEnhancement(1.5);
105  }
106  }
107  else if (net->getUnitsBeDriven().size() == 1)
108  {
109  if (net->getUnitsBeDriven()[0]->isFixed())
110  {
111  net->getDesignNet()->enhanceOverallClusterNetEnhancement(1.5);
112  }
113  }
114  }
115 }
116 
117 std::vector<DesignInfo::DesignCell *>
118 InitialPacker::BFSExpandViaSpecifiedPorts(std::string portPattern, DesignInfo::DesignCell *startCell, bool exactMatch)
119 {
120  std::set<DesignInfo::DesignCell *> tmpCellInMacros;
121  std::vector<DesignInfo::DesignCell *> res;
122  res.clear();
123  tmpCellInMacros.clear();
124  tmpCellInMacros.insert(startCell);
125  res.push_back(startCell);
126 
127  std::queue<DesignInfo::DesignCell *> cellToBFS;
128  while (!cellToBFS.empty())
129  cellToBFS.pop();
130  cellToBFS.push(startCell);
131 
132  while (!cellToBFS.empty())
133  {
134  DesignInfo::DesignCell *curCell = cellToBFS.front();
135  cellToBFS.pop();
136 
137  for (DesignInfo::DesignNet *curOutputNet : curCell->getOutputNets())
138  {
139  for (DesignInfo::DesignPin *pinBeDriven : curOutputNet->getPinsBeDriven())
140  {
141  if ((exactMatch && pinBeDriven->getRefPinName() == portPattern) ||
142  (!exactMatch && pinBeDriven->getRefPinName().find(portPattern) == 0))
143  {
144  DesignInfo::DesignCell *tmpCell = pinBeDriven->getCell();
145  if (startCell->getCellType() != tmpCell->getCellType())
146  continue;
147  if (tmpCellInMacros.find(tmpCell) == tmpCellInMacros.end())
148  {
149  tmpCellInMacros.insert(tmpCell);
150  cellToBFS.push(tmpCell);
151  res.push_back(tmpCell);
152  }
153  }
154  }
155  }
156  }
157  return res;
158 }
159 
160 std::vector<DesignInfo::DesignCell *> InitialPacker::BFSExpandViaSpecifiedPorts(std::vector<std::string> portPatterns,
161  DesignInfo::DesignCell *startCell,
162  bool exactMatch)
163 {
164  std::set<DesignInfo::DesignCell *> tmpCellInMacros;
165  std::vector<DesignInfo::DesignCell *> res;
166  res.clear();
167  tmpCellInMacros.clear();
168  tmpCellInMacros.insert(startCell);
169  res.push_back(startCell);
170 
171  std::queue<DesignInfo::DesignCell *> cellToBFS;
172  while (!cellToBFS.empty())
173  cellToBFS.pop();
174  cellToBFS.push(startCell);
175 
176  while (!cellToBFS.empty())
177  {
178  DesignInfo::DesignCell *curCell = cellToBFS.front();
179  cellToBFS.pop();
180 
181  for (DesignInfo::DesignNet *curOutputNet : curCell->getOutputNets())
182  {
183  for (DesignInfo::DesignPin *pinBeDriven : curOutputNet->getPinsBeDriven())
184  {
185  bool isCAS = false;
186  for (auto portPattern : portPatterns)
187  {
188  if ((exactMatch && pinBeDriven->getRefPinName() == portPattern) ||
189  (!exactMatch && pinBeDriven->getRefPinName().find(portPattern) == 0))
190  {
191  isCAS = true;
192  break;
193  }
194  }
195 
196  if (isCAS)
197  {
198  DesignInfo::DesignCell *tmpCell = pinBeDriven->getCell();
199  if (startCell->getCellType() != tmpCell->getCellType())
200  continue;
201  if (tmpCellInMacros.find(tmpCell) == tmpCellInMacros.end())
202  {
203  tmpCellInMacros.insert(tmpCell);
204  cellToBFS.push(tmpCell);
205  res.push_back(tmpCell);
206  }
207  }
208  }
209  }
210  }
211  return res;
212 }
213 
214 // DSP with ACIN*/BCIN*/PCIN* connected to other DSP should be a Macro
216 {
217  float DSPHeight = 2.5;
218  std::vector<PlacementInfo::PlacementMacro *> res;
219  res.clear();
220 
221  std::vector<DesignInfo::DesignCell *> &curCellsInDesign = designInfo->getCells();
222  int curNumCells = designInfo->getNumCells();
223 
224  std::vector<DesignInfo::DesignCell *> DSPTailsToBeCheckedRegisterAttr;
225  DSPTailsToBeCheckedRegisterAttr.clear();
226 
227  for (int curCellId = 0; curCellId < curNumCells; curCellId++)
228  {
229  auto curCell = curCellsInDesign[curCellId];
230  if (!curCell->isDSP())
231  continue;
232 
233  if (cellInMacros.find(curCell) != cellInMacros.end())
234  continue;
235 
236  bool noCASInput = true;
237 
238  for (DesignInfo::DesignPin *pinBeDriven : curCell->getInputPins())
239  {
240  if (pinBeDriven->getRefPinName().find("ACIN[") == 0 || pinBeDriven->getRefPinName().find("BCIN[") == 0 ||
241  pinBeDriven->getRefPinName().find("PCIN[") == 0 ||
242  pinBeDriven->getRefPinName().find("CARRYCASCIN") == 0)
243  {
244  if (pinBeDriven->getDriverPin())
245  {
246  noCASInput = false;
247  break;
248  }
249  }
250  }
251 
252  if (!noCASInput)
253  continue;
254 
255  std::vector<std::string> portPatterns{"ACIN[", "BCIN[", "PCIN[", "CARRYCASCIN"};
256  std::vector<DesignInfo::DesignCell *> curMacroCores = BFSExpandViaSpecifiedPorts(portPatterns, curCell, false);
257 
258  if (curMacroCores.size())
259  DSPTailsToBeCheckedRegisterAttr.push_back(curMacroCores[curMacroCores.size() - 1]);
260  if (curMacroCores.size() <= 1)
261  continue;
262 
264  curMacroCores[0]->getName(), placementUnits.size(), PlacementInfo::PlacementMacro::PlacementMacroType_DSP);
265 
266  float coreOffset = 0;
267  for (unsigned int i = 0; i < curMacroCores.size(); i++)
268  {
269  curMacro->addOccupiedSite(coreOffset, 1);
270  curMacro->addCell(curMacroCores[i], curMacroCores[i]->getCellType(), 0, coreOffset);
271  coreOffset += DSPHeight / 2;
272  }
273  int totalWeight = 0;
274  for (auto tmpCell : curMacro->getCells())
275  {
276  assert(cellInMacros.find(tmpCell) == cellInMacros.end());
277  cellId2PlacementUnit[tmpCell->getElementIdInType()] = curMacro;
278  cellInMacros.insert(tmpCell);
279  totalWeight += compatiblePlacementTable->cellType2sharedBELTypeOccupation[tmpCell->getCellType()];
280  }
281  curMacro->setWeight(totalWeight * 16);
282  res.push_back(curMacro);
283  placementMacros.push_back(curMacro);
284  placementUnits.push_back(curMacro);
285  }
286 
287  int cellInDSPMacrosCnt = 0;
288  for (auto macro : res)
289  cellInDSPMacrosCnt += macro->getCells().size();
290 
291  if (DSPCritical)
292  {
293  setDSPRegs(DSPTailsToBeCheckedRegisterAttr);
294  }
295 
296  // std::cout << "highlight_objects -color yellow [get_cells { ";
297  // for (auto macro : res)
298  // for (auto cell : macro->getCells())
299  // std::cout << " " << cell->getName();
300  // std::cout << "}]\n";
301 
302  print_info("#DSP Macro: " + std::to_string(res.size()));
303  print_info("#DSP Macro Cells: " + std::to_string(cellInDSPMacrosCnt));
304  print_status("DSP Macro Extracted.");
305 }
306 
307 void InitialPacker::setDSPRegs(std::vector<DesignInfo::DesignCell *> &DSPTailsToBeCheckedRegisterAttr)
308 {
309  int DSPRegCount = 0;
310 
311  for (auto startCell : DSPTailsToBeCheckedRegisterAttr)
312  {
313  std::queue<DesignInfo::DesignCell *> nodeQ;
314  std::set<DesignInfo::DesignCell *> nodeSet;
315  nodeSet.clear();
316  nodeSet.insert(startCell);
317  nodeQ.push(startCell);
318  bool found = false;
319 
320  while (nodeQ.size() && !found)
321  {
322  auto curNode = nodeQ.front();
323  nodeQ.pop();
324 
325  for (auto outNet : curNode->getOutputNets())
326  {
327  if (!outNet)
328  continue;
329  for (auto pin : outNet->getPinsBeDriven())
330  {
331  auto nextCell = pin->getCell();
332  if (nextCell)
333  {
334  if (nodeSet.find(nextCell) == nodeSet.end())
335  {
336  nodeSet.insert(nextCell);
337 
338  if (!nextCell->isTimingEndPoint())
339  nodeQ.push(nextCell);
340  if (nextCell->isDSP())
341  {
342  if (cellId2PlacementUnit[nextCell->getCellId()] !=
343  cellId2PlacementUnit[startCell->getCellId()])
344  {
345  startCell->setHasDSPReg(true);
346  DSPRegCount++;
347  found = true;
348  break;
349  }
350  }
351  }
352  }
353  }
354  }
355  }
356  }
357 
358  print_warning(std::to_string(DSPRegCount) + " DSPs have set registered.\n");
359  return;
360 }
361 
363 {
364  std::vector<PlacementInfo::PlacementMacro *> res;
365  res.clear();
366 
367  std::vector<DesignInfo::DesignCell *> &curCellsInDesign = designInfo->getCells();
368  int curNumCells = designInfo->getNumCells();
369  for (int curCellId = 0; curCellId < curNumCells; curCellId++)
370  {
371  auto curCell = curCellsInDesign[curCellId];
372  if (!curCell->originallyIsLUTRAM())
373  continue;
374 
375  if (cellInMacros.find(curCell) != cellInMacros.end())
376  continue;
377 
380 
381  curMacro->addOccupiedSite(0, 1);
382  curMacro->addCell(curCell, curCell->getCellType(), 0, 0);
383  assert(cellInMacros.find(curCell) == cellInMacros.end());
384  cellInMacros.insert(curCell);
385  cellId2PlacementUnit[curCell->getElementIdInType()] = curMacro;
386  curMacro->setWeight(16);
387  res.push_back(curMacro);
388  placementMacros.push_back(curMacro);
389  placementUnits.push_back(curMacro);
390  }
391 
392  int cellInLUTRAMMacrosCnt = 0;
393  for (auto macro : res)
394  cellInLUTRAMMacrosCnt += macro->getCells().size();
395 
396  // std::cout << "highlight_objects -color yellow [get_cells { ";
397  // for (auto macro : res)
398  // for (auto cell : macro->getCells())
399  // std::cout << " " << cell->getName();
400  // std::cout << "}]\n";
401 
402  print_info("#LUTRAM Predictable Macro: " + std::to_string(res.size()));
403  print_info("#LUTRAM Predictable Macro Cells: " + std::to_string(cellInLUTRAMMacrosCnt));
404  print_status("LUTRAM Predictable Macro Extracted.");
405 }
406 
407 // BRAM with CAS* connected to other BRAM should be a Macro
409 {
410  float BRAM36Height = 5;
411  float BRAM18Height = 2.5;
412  std::vector<PlacementInfo::PlacementMacro *> res;
413  res.clear();
414 
415  std::vector<DesignInfo::DesignCell *> &curCellsInDesign = designInfo->getCells();
416  int curNumCells = designInfo->getNumCells();
417  for (int curCellId = 0; curCellId < curNumCells; curCellId++)
418  {
419  auto curCell = curCellsInDesign[curCellId];
420  if (!curCell->isBRAM())
421  continue;
422 
423  if (cellInMacros.find(curCell) != cellInMacros.end())
424  continue;
425 
426  bool noCASInput = true;
427 
428  for (DesignInfo::DesignPin *pinBeDriven : curCell->getInputPins())
429  {
430  if (pinBeDriven->getRefPinName().find("CASDI") == 0)
431  {
432  if (pinBeDriven->getDriverPin())
433  {
434  noCASInput = false;
435  break;
436  }
437  }
438  }
439 
440  if (!noCASInput)
441  continue;
442  std::vector<DesignInfo::DesignCell *> curMacroCores = BFSExpandViaSpecifiedPorts("CASDI", curCell, false);
443 
444  if (curMacroCores.size() <= 1 && curCell->getCellType() != DesignInfo::CellType_RAMB36E2 &&
445  curCell->getCellType() != DesignInfo::CellType_FIFO36E2)
446  continue;
447 
449  curMacroCores[0]->getName(), placementUnits.size(), PlacementInfo::PlacementMacro::PlacementMacroType_BRAM);
450 
451  float coreOffset = 0;
452  for (unsigned int i = 0; i < curMacroCores.size(); i++)
453  {
454  if (curMacroCores[i]->getCellType() == DesignInfo::CellType_RAMB36E2 ||
455  curMacroCores[i]->getCellType() == DesignInfo::CellType_FIFO36E2)
456  {
457  curMacro->addOccupiedSite(coreOffset, 1.0);
458  curMacro->addCell(curMacroCores[i], curMacroCores[i]->getCellType(), 0, coreOffset);
459  curMacro->addOccupiedSite(coreOffset + BRAM18Height, 1.0);
460  curMacro->addVirtualCell(curMacroCores[i]->getName(), designInfo, DesignInfo::CellType_RAMB18E2, 0,
461  coreOffset + BRAM18Height);
462  }
463  else if (curMacroCores[i]->getCellType() == DesignInfo::CellType_RAMB18E2 ||
464  curMacroCores[i]->getCellType() == DesignInfo::CellType_FIFO18E2)
465  {
466  curMacro->addOccupiedSite(coreOffset, 1.0);
467  curMacro->addCell(curMacroCores[i], curMacroCores[i]->getCellType(), 0, coreOffset);
468  }
469  else
470  {
471  assert(false);
472  }
473 
474  if (i < curMacroCores.size() - 1)
475  {
476  if (curMacroCores[i]->getCellType() == DesignInfo::CellType_RAMB36E2 ||
477  curMacroCores[i]->getCellType() == DesignInfo::CellType_FIFO36E2)
478  coreOffset += BRAM36Height;
479  else
480  coreOffset += BRAM18Height;
481  }
482  }
483  int totalWeight = 0;
484  for (auto tmpCell : curMacro->getCells())
485  {
486  assert(cellInMacros.find(tmpCell) == cellInMacros.end());
487  cellId2PlacementUnit[tmpCell->getElementIdInType()] = curMacro;
488  cellInMacros.insert(tmpCell);
489  totalWeight += compatiblePlacementTable->cellType2sharedBELTypeOccupation[tmpCell->getCellType()];
490  }
491  curMacro->setWeight(totalWeight * 16);
492  res.push_back(curMacro);
493  placementMacros.push_back(curMacro);
494  placementUnits.push_back(curMacro);
495  }
496 
497  int cellInBRAMMacrosCnt = 0;
498  for (auto macro : res)
499  cellInBRAMMacrosCnt += macro->getCells().size();
500 
501  print_info("#BRAM Macro: " + std::to_string(res.size()));
502  print_info("#BRAM Macro Cells: " + std::to_string(cellInBRAMMacrosCnt));
503  print_status("BRAM Macro Extracted.");
504 }
505 
507 {
508  std::set<DesignInfo::DesignPin *> driverPins;
509  driverPins.clear();
510  assert(ALUT->isLUT() && BLUT->isLUT());
511  for (DesignInfo::DesignPin *pinBeDriven : ALUT->getInputPins())
512  {
513  if (pinBeDriven->isUnconnected())
514  continue;
515  if (!pinBeDriven->getDriverPin()) // pin connect to GND/VCC which has no specifc driver pin
516  {
517  continue;
518  }
519  driverPins.insert(pinBeDriven->getDriverPin());
520  }
521  for (DesignInfo::DesignPin *pinBeDriven : BLUT->getInputPins())
522  {
523  if (pinBeDriven->isUnconnected())
524  continue;
525  if (!pinBeDriven->getDriverPin()) // pin connect to GND/VCC which has no specifc driver pin
526  {
527  continue;
528  }
529  driverPins.insert(pinBeDriven->getDriverPin());
530  }
531  return driverPins.size() <= 5;
532 }
533 
534 std::vector<DesignInfo::DesignCell *> InitialPacker::checkCompatibleFFs(std::vector<DesignInfo::DesignCell *> FFs)
535 {
536  std::vector<PackedControlSet> FFControlSets;
537  const int MaxNum_ControlSet = 4;
538 
539  for (auto curFF : FFs)
540  {
541  assert(curFF->getControlSetInfo());
542  bool added = false;
543  for (unsigned int i = 0; i < FFControlSets.size(); i++)
544  {
545  if (FFControlSets[i].getCSId() == curFF->getControlSetInfo()->getId() &&
546  FFControlSets[i].getFFs().size() < MaxNum_ControlSet)
547  {
548  FFControlSets[i].addFF(curFF);
549  added = true;
550  break;
551  }
552  }
553  if (!added)
554  {
555  FFControlSets.emplace_back(curFF);
556  }
557  }
558 
559  std::sort(FFControlSets.begin(), FFControlSets.end(),
560  [](const PackedControlSet &a, const PackedControlSet &b) -> bool {
561  return a.getFFs().size() > b.getFFs().size();
562  });
563 
564  typedef struct _CLKSRCombination
565  {
566  DesignInfo::DesignNet *CLK = nullptr;
567  DesignInfo::DesignNet *SR = nullptr;
568  unsigned int cnt = 0;
569  } CLKSRCombination;
570  CLKSRCombination halfCLBSettings[1];
571  std::vector<DesignInfo::DesignCell *> resFF;
572 
573  for (auto &FFCS : FFControlSets)
574  {
575  auto curFF = FFCS.getFFs()[0];
576  assert(curFF->getControlSetInfo());
577  if (halfCLBSettings[0].cnt == 0 || (halfCLBSettings[0].cnt < MaxNum_ControlSet / 2 &&
578  halfCLBSettings[0].CLK == curFF->getControlSetInfo()->getCLK() &&
579  halfCLBSettings[0].SR == curFF->getControlSetInfo()->getSR()))
580  {
581  halfCLBSettings[0].CLK = curFF->getControlSetInfo()->getCLK();
582  halfCLBSettings[0].SR = curFF->getControlSetInfo()->getSR();
583  halfCLBSettings[0].cnt++;
584  for (auto tmpFF : FFCS.getFFs())
585  resFF.push_back(tmpFF);
586  }
587  }
588 
589  return resFF;
590 }
591 
593  DesignInfo::DesignCell *coreCell, float CARRYChainSiteOffset)
594 {
595  SiteBELMapping slotMapping;
596  std::set<DesignInfo::DesignCell *> mappedCells;
597  std::set<DesignInfo::DesignCell *> mappedLUTs;
598  std::set<DesignInfo::DesignCell *> mappedFFs;
599 
600  mappedCells.clear();
601  mappedLUTs.clear();
602  mappedFFs.clear();
603 
604  float siteHeight = 1.0;
605  float lowerBound = siteHeight * CARRYChainSiteOffset - (1e-2);
606  float uppwerBound = siteHeight * CARRYChainSiteOffset + (1e-2);
607  for (auto curCell : CARRYChain->getCells())
608  {
609  float offsetY = CARRYChain->getCellOffsetYInMacro(curCell);
610  if (offsetY > lowerBound && offsetY < uppwerBound)
611  {
612  if (curCell->isCarry())
613  {
614  auto curCarry = curCell;
615  slotMapping.Carry = curCarry;
616  mappedCells.insert(curCarry);
617  for (DesignInfo::DesignPin *pinBeDriven : curCarry->getInputPins())
618  {
619  if (pinBeDriven->isUnconnected())
620  continue;
621  if (!pinBeDriven->getDriverPin()) // pin connect to GND/VCC which has no specifc driver pin
622  continue;
623 
624  if (pinBeDriven->getRefPinName().find("S[") == 0)
625  {
626  if (CARRYChain->hasCell(pinBeDriven->getDriverPin()->getCell()) &&
627  pinBeDriven->getDriverPin()->getCell()->isLUT())
628  {
629  char SPinCellId =
630  pinBeDriven->getRefPinName()[pinBeDriven->getRefPinName().find("[") + 1] - '0';
631  slotMapping.LUTs[SPinCellId / 4][0][SPinCellId % 4] =
632  pinBeDriven->getDriverPin()->getCell();
633  mappedCells.insert(pinBeDriven->getDriverPin()->getCell());
634  mappedLUTs.insert(pinBeDriven->getDriverPin()->getCell());
635  // char LUTCode = SPinCellId + 'A';
636  // std::string LUTSiteName = std::string(1, LUTCode) + "6LUT";
637  // outfile0 << " " << pinBeDriven->getDriverPin()->getCell()->getName() << " "
638  // << CLBSite->getName() << "/" + LUTSiteName << "\n";
639  }
640  }
641  else if (pinBeDriven->getRefPinName().find("DI[") == 0)
642  {
643  if (CARRYChain->hasCell(pinBeDriven->getDriverPin()->getCell()) &&
644  pinBeDriven->getDriverPin()->getCell()->isLUT())
645  {
646  char DIPinCellId =
647  pinBeDriven->getRefPinName()[pinBeDriven->getRefPinName().find("[") + 1] - '0';
648  slotMapping.LUTs[DIPinCellId / 4][1][DIPinCellId % 4] =
649  pinBeDriven->getDriverPin()->getCell();
650  mappedCells.insert(pinBeDriven->getDriverPin()->getCell());
651  mappedLUTs.insert(pinBeDriven->getDriverPin()->getCell());
652  // char LUTCode = DIPinCellId + 'A';
653  // std::string LUTSiteName = std::string(1, LUTCode) + "5LUT";
654  // outfile0 << " " << pinBeDriven->getDriverPin()->getCell()->getName() << " "
655  // << CLBSite->getName() << "/" + LUTSiteName << "\n";
656  }
657  }
658  }
659  std::vector<std::string> checkFFRefPins{"O[", "CO["};
660  for (DesignInfo::DesignPin *driverPin : curCarry->getOutputPins())
661  {
662  if (driverPin->isUnconnected())
663  continue;
664  DesignInfo::DesignNet *curOutputNet = driverPin->getNet();
665  bool findMatchedInputPin = false;
666  for (auto patternPin : checkFFRefPins)
667  {
668  if (driverPin->getRefPinName().find(patternPin) == 0)
669  {
670  findMatchedInputPin = true;
671  break;
672  }
673  }
674 
675  if (findMatchedInputPin)
676  {
677  int FFcnt = 0;
678  DesignInfo::DesignCell *theFF = nullptr;
679  for (auto pinBeDriven : curOutputNet->getPinsBeDriven())
680  {
681  if (pinBeDriven->getCell()->isFF())
682  {
683  FFcnt++;
684  if (pinBeDriven->getRefPinName().find("D") != std::string::npos)
685  {
686  if (CARRYChain->hasCell(pinBeDriven->getCell()))
687  theFF = pinBeDriven->getCell();
688  }
689  }
690  }
691  if (FFcnt == 1 && theFF)
692  {
693  char FFPinCellId =
694  driverPin->getRefPinName()[driverPin->getRefPinName().find("[") + 1] - '0';
695  if (driverPin->getRefPinName().find("CO[") != std::string::npos)
696  {
697  slotMapping.FFs[FFPinCellId / 4][1][FFPinCellId % 4] = theFF;
698  mappedCells.insert(theFF);
699  mappedFFs.insert(theFF);
700  // std::string FFSiteName = std::string(1, FFCode) + "FF2";
701  // outfile0 << " " << theFF->getName() << " " << CLBSite->getName() << "/" + FFSiteName
702  // << "\n";
703  }
704  else if (driverPin->getRefPinName().find("O[") != std::string::npos)
705  {
706  slotMapping.FFs[FFPinCellId / 4][0][FFPinCellId % 4] = theFF;
707  mappedCells.insert(theFF);
708  mappedFFs.insert(theFF);
709  // std::string FFSiteName = std::string(1, FFCode) + "FF";
710  // outfile0 << " " << theFF->getName() << " " << CLBSite->getName() << "/" + FFSiteName
711  // << "\n";
712  }
713  }
714  }
715  }
716  }
717 
718  if (curCell->isVirtualCell())
719  {
720  assert(mappedCells.find(curCell) == mappedCells.end());
721  if (curCell->isLUT())
722  {
723  assert(curCell->isLUT6());
724  assert(curCell->getName().find('(') != std::string::npos);
725  int slotId = curCell->getName()[curCell->getName().find('(') - 1] - '0';
726  assert(slotId < 8 && slotId >= 0);
727  assert(!slotMapping.LUTs[slotId / 4][0][slotId % 4]);
728  mappedCells.insert(curCell);
729  mappedLUTs.insert(curCell);
730  slotMapping.LUTs[slotId / 4][0][slotId % 4] = curCell;
731  }
732  else
733  {
734  assert(curCell->isFF());
735  assert(curCell->getName().find('(') != std::string::npos);
736  int strOffset = curCell->getName().find('(');
737  int slotId = curCell->getName()[strOffset - 1] - '0';
738  assert(curCell->getName()[strOffset - 2] == '2' || curCell->getName()[strOffset - 2] == 'F');
739  int oddCLB = curCell->getName()[strOffset - 2] == '2';
740  assert(slotId < 8 && slotId >= 0);
741  assert(!slotMapping.FFs[slotId / 4][oddCLB][slotId % 4]);
742  mappedCells.insert(curCell);
743  mappedFFs.insert(curCell);
744  slotMapping.FFs[slotId / 4][oddCLB][slotId % 4] = curCell;
745  }
746  }
747  }
748  }
749 
750  for (int i = 0; i < 2; i++)
751  {
752  for (int k = 0; k < 4; k++)
753  {
754  if (slotMapping.FFs[i][0][k] && slotMapping.FFs[i][1][k])
755  {
756  if (slotMapping.FFs[i][0][k]->isVirtualCell() && slotMapping.FFs[i][1][k]->isVirtualCell())
757  {
758  for (int jj = 0; jj < 2; jj++)
759  {
760  for (int kk = 0; kk < 4; kk++)
761  {
762  if (!slotMapping.FFs[i][jj][kk])
763  {
764  if (jj == 0)
765  slotMapping.FFs[i][jj][kk] = CARRYChain->addVirtualCell(
766  coreCell->getName() + "__FF" + std::to_string(i * 4 + kk), designInfo,
767  DesignInfo::CellType_FDCE, 0, CARRYChainSiteOffset);
768  else
769  slotMapping.FFs[i][jj][kk] = CARRYChain->addVirtualCell(
770  coreCell->getName() + "__FF2" + std::to_string(i * 4 + kk), designInfo,
771  DesignInfo::CellType_FDCE, 0, CARRYChainSiteOffset);
772  }
773  }
774  }
775  break;
776  }
777  }
778  }
779  }
780 
781  for (int i = 0; i < 2; i++)
782  for (int k = 0; k < 4; k++)
783  {
784  if (slotMapping.LUTs[i][0][k] && !slotMapping.FFs[i][0][k])
785  {
786  if (slotMapping.LUTs[i][0][k]->isLUT6())
787  {
788  slotMapping.FFs[i][0][k] =
789  CARRYChain->addVirtualCell(coreCell->getName() + "__FF" + std::to_string(i * 4 + k), designInfo,
790  DesignInfo::CellType_FDCE, 0, CARRYChainSiteOffset);
791  if (!slotMapping.FFs[i][1][k])
792  {
793  slotMapping.FFs[i][1][k] =
794  CARRYChain->addVirtualCell(coreCell->getName() + "__FF2" + std::to_string(i * 4 + k),
795  designInfo, DesignInfo::CellType_FDCE, 0, CARRYChainSiteOffset);
796  }
797  }
798  }
799  if (slotMapping.LUTs[i][1][k] && !slotMapping.FFs[i][1][k])
800  {
801  if (slotMapping.LUTs[i][1][k]->isLUT6())
802  {
803  if (slotMapping.LUTs[i][1][k]->getOriCellType() != DesignInfo::CellType_LUT6_2)
804  {
805  std::cout << slotMapping.LUTs[i][1][k] << "\n";
806  assert(!slotMapping.LUTs[i][1][k]->isLUT6()); // this slot cannot handle LUT6
807  }
808  }
809  }
810  }
811 }
812 
813 // CARRY with CIN connected to other DSP should be a Macro. CARRY with external input from outside of CLB will occupy
814 // specific LUT too.
816 {
817  std::vector<PlacementInfo::PlacementMacro *> res;
818  res.clear();
819 
820  std::vector<DesignInfo::DesignCell *> &curCellsInDesign = designInfo->getCells();
821  int curNumCells = designInfo->getNumCells();
822  for (int curCellId = 0; curCellId < curNumCells; curCellId++)
823  {
824  auto curCell = curCellsInDesign[curCellId];
825  if (curCell->getCellType() != DesignInfo::CellType_CARRY8)
826  continue;
827 
828  if (cellInMacros.find(curCell) != cellInMacros.end())
829  continue;
830 
831  bool noCASInput = true;
832  bool AXUsed = false;
833 
834  for (DesignInfo::DesignPin *pinBeDriven : curCell->getInputPins())
835  {
836  if (pinBeDriven->getRefPinName() == "CI")
837  {
838  if (pinBeDriven->getDriverPin())
839  {
840  if (pinBeDriven->getDriverPin()->getCell()->getCellType() == DesignInfo::CellType_CARRY8)
841  noCASInput = false;
842  else
843  AXUsed = true; // non-CARRY CI will use AX
844  }
845  break;
846  }
847  }
848 
849  if (!noCASInput)
850  continue;
851 
852  std::vector<DesignInfo::DesignCell *> curMacroCores = BFSExpandViaSpecifiedPorts("CI", curCell, true);
853 
854  if (curMacroCores.size() < 1)
855  continue;
856 
857  // expand CARRY MACRO with input LUT / output FF / external input occupying
859  new PlacementInfo::PlacementMacro(curMacroCores[0]->getName(), placementUnits.size(),
861 
862  std::vector<std::string> checkLUTRefPins{"S["}; //"DI[",
863  std::vector<std::string> checkFFRefPins{"O[", "CO["};
864 
865  int coreOffset = 0;
866  for (auto coreCell : curMacroCores)
867  {
868  curMacro->addOccupiedSite(coreOffset, 1.0);
869  curMacro->addCell(coreCell, coreCell->getCellType(), 0, coreOffset);
870  coreOffset++;
871  }
872 
873  coreOffset = 0;
874  for (auto coreCell : curMacroCores)
875  {
876 
877  std::vector<std::pair<DesignInfo::DesignPin *, DesignInfo::DesignCell *>> SPinCell(0);
878  SPinCell.resize(8, std::pair<DesignInfo::DesignPin *, DesignInfo::DesignCell *>(nullptr, nullptr));
879  std::vector<std::pair<DesignInfo::DesignPin *, DesignInfo::DesignCell *>> DIPinCell(0);
880  DIPinCell.resize(8, std::pair<DesignInfo::DesignPin *, DesignInfo::DesignCell *>(nullptr, nullptr));
881  std::vector<bool> externalSignal(0);
882  externalSignal.resize(8, false);
883 
884  for (DesignInfo::DesignPin *pinBeDriven : coreCell->getInputPins())
885  {
886  if (pinBeDriven->isUnconnected())
887  continue;
888  if (!pinBeDriven->getDriverPin()) // pin connect to GND/VCC which has no specifc driver pin
889  {
890  if (pinBeDriven->getRefPinName().find("DI[") == 0)
891  {
892  char DIPinCellId =
893  pinBeDriven->getRefPinName()[pinBeDriven->getRefPinName().find("[") + 1] - '0';
894  DIPinCell[DIPinCellId] =
895  std::pair<DesignInfo::DesignPin *, DesignInfo::DesignCell *>(pinBeDriven, nullptr);
896  }
897  continue;
898  }
899 
900  if (pinBeDriven->getRefPinName().find("DI[") == 0)
901  {
902  char DIPinCellId = pinBeDriven->getRefPinName()[pinBeDriven->getRefPinName().find("[") + 1] - '0';
903  DIPinCell[DIPinCellId] = std::pair<DesignInfo::DesignPin *, DesignInfo::DesignCell *>(
904  pinBeDriven, pinBeDriven->getDriverPin()->getCell());
905  }
906  }
907 
908  for (DesignInfo::DesignPin *pinBeDriven : coreCell->getInputPins())
909  {
910  if (pinBeDriven->isUnconnected())
911  continue;
912  if (!pinBeDriven->getDriverPin()) // pin connect to GND/VCC which has no specifc driver pin
913  {
914  if (pinBeDriven->getRefPinName().find("S[") == 0)
915  {
916  char SPinCellId =
917  pinBeDriven->getRefPinName()[pinBeDriven->getRefPinName().find("[") + 1] - '0';
918  SPinCell[SPinCellId] =
919  std::pair<DesignInfo::DesignPin *, DesignInfo::DesignCell *>(pinBeDriven, nullptr);
920  }
921  continue;
922  }
923 
924  if (pinBeDriven->getRefPinName().find("S[") == 0)
925  {
926  char SPinCellId = pinBeDriven->getRefPinName()[pinBeDriven->getRefPinName().find("[") + 1] - '0';
927  SPinCell[SPinCellId] = std::pair<DesignInfo::DesignPin *, DesignInfo::DesignCell *>(
928  pinBeDriven, pinBeDriven->getDriverPin()->getCell());
929  }
930  }
931 
932  for (unsigned int i = 0; i < 8; i++)
933  {
934  if (AXUsed && i == 0 && coreOffset < 0.005)
935  {
936  if (DIPinCell[i].second && SPinCell[i].second)
937  {
938  bool DICanBeInSlice = DIPinCell[i].second->isLUT() && !DIPinCell[i].second->isLUT6() &&
939  DIPinCell[i].first->getNet()->getPinsBeDriven().size() == 1;
940  bool SCanBeInSlice =
941  SPinCell[i].second->isLUT() && SPinCell[i].first->getNet()->getPinsBeDriven().size() == 1;
942  if (DICanBeInSlice && SCanBeInSlice)
943  {
944  if (canLUTPacked(DIPinCell[i].second, SPinCell[i].second))
945  {
946  curMacro->addCell(DIPinCell[i].second, DIPinCell[i].second->getCellType(), 0,
947  coreOffset);
948  curMacro->addCell(SPinCell[i].second, SPinCell[i].second->getCellType(), 0, coreOffset);
949  }
950  else
951  {
952  curMacro->addVirtualCell(coreCell->getName() + "__" + std::to_string(i), designInfo,
953  DesignInfo::CellType_LUT6, 0, coreOffset);
954  }
955  }
956  else if (SCanBeInSlice)
957  {
958  curMacro->addVirtualCell(coreCell->getName() + "__" + std::to_string(i), designInfo,
959  DesignInfo::CellType_LUT6, 0, coreOffset);
960  }
961  else
962  {
963  curMacro->addVirtualCell(coreCell->getName() + "__" + std::to_string(i), designInfo,
964  DesignInfo::CellType_LUT6, 0, coreOffset);
965  }
966  }
967  else if (SPinCell[i].second && !DIPinCell[i].first)
968  {
969  bool SCanBeInSlice =
970  SPinCell[i].second->isLUT() && SPinCell[i].first->getNet()->getPinsBeDriven().size() == 1;
971  if (SCanBeInSlice && !SPinCell[i].second->isLUT6())
972  {
973  curMacro->addCell(SPinCell[i].second, DesignInfo::CellType_LUT6, 0, coreOffset);
974  }
975  else
976  {
977  curMacro->addVirtualCell(coreCell->getName() + "__" + std::to_string(i), designInfo,
978  DesignInfo::CellType_LUT6, 0, coreOffset);
979  }
980  }
981  else
982  {
983  curMacro->addVirtualCell(coreCell->getName() + "__" + std::to_string(i), designInfo,
984  DesignInfo::CellType_LUT6, 0, coreOffset);
985  }
986  }
987  else if (DIPinCell[i].second && SPinCell[i].second)
988  {
989  bool DICanBeInSlice = DIPinCell[i].second->isLUT() && !DIPinCell[i].second->isLUT6() &&
990  DIPinCell[i].first->getNet()->getPinsBeDriven().size() == 1;
991  bool SCanBeInSlice =
992  SPinCell[i].second->isLUT() && SPinCell[i].first->getNet()->getPinsBeDriven().size() == 1;
993  if (DICanBeInSlice && SCanBeInSlice)
994  {
995  if (canLUTPacked(DIPinCell[i].second, SPinCell[i].second))
996  {
997  curMacro->addCell(DIPinCell[i].second, DIPinCell[i].second->getCellType(), 0, coreOffset);
998  curMacro->addCell(SPinCell[i].second, SPinCell[i].second->getCellType(), 0, coreOffset);
999  }
1000  else
1001  {
1002  curMacro->addCell(SPinCell[i].second, DesignInfo::CellType_LUT6, 0, coreOffset);
1003  }
1004  }
1005  else if (SCanBeInSlice)
1006  {
1007  curMacro->addCell(SPinCell[i].second, DesignInfo::CellType_LUT6, 0, coreOffset);
1008  }
1009  else
1010  {
1011  curMacro->addVirtualCell(coreCell->getName() + "__" + std::to_string(i), designInfo,
1012  DesignInfo::CellType_LUT6, 0, coreOffset);
1013  }
1014  }
1015  else if (DIPinCell[i].second && !SPinCell[i].first)
1016  {
1017  bool DICanBeInSlice = DIPinCell[i].second->isLUT() && !DIPinCell[i].second->isLUT6() &&
1018  DIPinCell[i].first->getNet()->getPinsBeDriven().size() == 1;
1019  if (DICanBeInSlice)
1020  {
1021  curMacro->addCell(DIPinCell[i].second, DIPinCell[i].second->getCellType(), 0, coreOffset);
1022  }
1023  }
1024  else if (SPinCell[i].second)
1025  {
1026  bool SCanBeInSlice =
1027  SPinCell[i].second->isLUT() && SPinCell[i].first->getNet()->getPinsBeDriven().size() == 1;
1028  if (SCanBeInSlice)
1029  {
1030  curMacro->addCell(SPinCell[i].second, DesignInfo::CellType_LUT6, 0, coreOffset);
1031  }
1032  else
1033  {
1034  curMacro->addVirtualCell(coreCell->getName() + "__" + std::to_string(i), designInfo,
1035  DesignInfo::CellType_LUT6, 0, coreOffset);
1036  }
1037  }
1038  else if (DIPinCell[i].first || SPinCell[i].first)
1039  {
1040  curMacro->addVirtualCell(coreCell->getName() + "__" + std::to_string(i), designInfo,
1041  DesignInfo::CellType_LUT6, 0, coreOffset);
1042  }
1043  }
1044 
1045  std::vector<DesignInfo::DesignCell *> drivenTopFFs;
1046  std::vector<DesignInfo::DesignCell *> drivenBottomFFs;
1047  for (DesignInfo::DesignPin *driverPin : coreCell->getOutputPins())
1048  {
1049  if (driverPin->isUnconnected())
1050  continue;
1051  DesignInfo::DesignNet *curOutputNet = driverPin->getNet();
1052  bool findMatchedInputPin = false;
1053  for (auto patternPin : checkFFRefPins)
1054  {
1055  if (driverPin->getRefPinName().find(patternPin) == 0)
1056  {
1057  findMatchedInputPin = true;
1058  break;
1059  }
1060  }
1061 
1062  if (findMatchedInputPin)
1063  {
1064  int FFcnt = 0;
1065  DesignInfo::DesignCell *theFF = nullptr;
1066  for (auto pinBeDriven : curOutputNet->getPinsBeDriven())
1067  {
1068  if (pinBeDriven->getCell()->isFF())
1069  {
1070  FFcnt++;
1071  if (pinBeDriven->getRefPinName().find("D") != std::string::npos)
1072  theFF = pinBeDriven->getCell();
1073  }
1074  }
1075  if (FFcnt == 1 && theFF)
1076  {
1077  char FFPinCellId = driverPin->getRefPinName()[driverPin->getRefPinName().find("[") + 1] - '0';
1078  if (FFPinCellId < 4)
1079  drivenBottomFFs.push_back(theFF);
1080  else
1081  drivenTopFFs.push_back(theFF);
1082  // curMacro->addCell(theFF, theFF->getCellType(), 0, coreOffset);
1083  }
1084  }
1085  }
1086 
1087  std::set<DesignInfo::DesignCell *> addedFFs;
1088  addedFFs.clear();
1089  drivenBottomFFs = checkCompatibleFFs(drivenBottomFFs);
1090  for (auto theFF : drivenBottomFFs)
1091  {
1092  curMacro->addCell(theFF, theFF->getCellType(), 0, coreOffset);
1093  addedFFs.insert(theFF);
1094  }
1095  drivenTopFFs = checkCompatibleFFs(drivenTopFFs);
1096  for (auto theFF : drivenTopFFs)
1097  {
1098  curMacro->addCell(theFF, theFF->getCellType(), 0, coreOffset);
1099  addedFFs.insert(theFF);
1100  }
1101 
1102  for (DesignInfo::DesignPin *driverPin : coreCell->getOutputPins())
1103  {
1104  if (driverPin->isUnconnected())
1105  continue;
1106  DesignInfo::DesignNet *curOutputNet = driverPin->getNet();
1107  bool findMatchedInputPin = false;
1108  for (auto patternPin : checkFFRefPins)
1109  {
1110  if (driverPin->getRefPinName().find(patternPin) == 0)
1111  {
1112  findMatchedInputPin = true;
1113  break;
1114  }
1115  }
1116 
1117  if (findMatchedInputPin)
1118  {
1119  int FFcnt = 0;
1120  DesignInfo::DesignCell *theFF = nullptr;
1121  for (auto pinBeDriven : curOutputNet->getPinsBeDriven())
1122  {
1123  if (pinBeDriven->getCell()->isFF())
1124  {
1125  FFcnt++;
1126  if (pinBeDriven->getRefPinName().find("D") != std::string::npos)
1127  {
1128  if (addedFFs.find(pinBeDriven->getCell()) != addedFFs.end())
1129  theFF = pinBeDriven->getCell();
1130  }
1131  }
1132  }
1133  if (FFcnt == 1 && theFF)
1134  {
1135  // char FFPinCellId = driverPin->getRefPinName()[driverPin->getRefPinName().find("[") + 1] -
1136  // '0'; if (driverPin->getRefPinName().find("CO[") != std::string::npos)
1137  // {
1138  // slotMapping.FFs[FFPinCellId / 4][1][FFPinCellId % 4] = theFF;
1139  // // std::string FFSiteName = std::string(1, FFCode) + "FF2";
1140  // // outfile0 << " " << theFF->getName() << " " << CLBSite->getName() << "/" + FFSiteName
1141  // // << "\n";
1142  // }
1143  // else if (driverPin->getRefPinName().find("O[") != std::string::npos)
1144  // {
1145  // slotMapping.FFs[FFPinCellId / 4][0][FFPinCellId % 4] = theFF;
1146  // // std::string FFSiteName = std::string(1, FFCode) + "FF";
1147  // // outfile0 << " " << theFF->getName() << " " << CLBSite->getName() << "/" + FFSiteName
1148  // // << "\n";
1149  // }
1150  }
1151  else
1152  {
1153  char FFPinCellId = driverPin->getRefPinName()[driverPin->getRefPinName().find("[") + 1] - '0';
1154  if (driverPin->getRefPinName().find("CO[") != std::string::npos)
1155  {
1156  curMacro->addVirtualCell(coreCell->getName() + "__FF2" + std::to_string(FFPinCellId),
1157  designInfo, DesignInfo::CellType_FDCE, 0, coreOffset);
1158  // std::string FFSiteName = std::string(1, FFCode) + "FF2";
1159  // outfile0 << " " << theFF->getName() << " " << CLBSite->getName() << "/" + FFSiteName
1160  // << "\n";
1161  }
1162  else if (driverPin->getRefPinName().find("O[") != std::string::npos)
1163  {
1164  curMacro->addVirtualCell(coreCell->getName() + "__FF" + std::to_string(FFPinCellId),
1165  designInfo, DesignInfo::CellType_FDCE, 0, coreOffset);
1166  // std::string FFSiteName = std::string(1, FFCode) + "FF";
1167  // outfile0 << " " << theFF->getName() << " " << CLBSite->getName() << "/" + FFSiteName
1168  // << "\n";
1169  }
1170  }
1171  }
1172  }
1173  mapCarryRelatedRouteThru(curMacro, coreCell, coreOffset);
1174  coreOffset++;
1175  }
1176  int totalWeight = 0;
1177  for (auto tmpCell : curMacro->getCells())
1178  {
1179  assert(cellInMacros.find(tmpCell) == cellInMacros.end());
1180  cellId2PlacementUnit[tmpCell->getElementIdInType()] = curMacro;
1181  cellInMacros.insert(tmpCell);
1182  if (tmpCell->isCarry())
1183  totalWeight += 8;
1184  else
1185  totalWeight += compatiblePlacementTable->cellType2sharedBELTypeOccupation[tmpCell->getCellType()];
1186  }
1187  curMacro->setWeight(totalWeight);
1188  res.push_back(curMacro);
1189  placementMacros.push_back(curMacro);
1190  placementUnits.push_back(curMacro);
1191  }
1192 
1193  int cellInCarryMacrosCnt = 0;
1194  for (auto macro : res)
1195  cellInCarryMacrosCnt += macro->getCells().size();
1196  print_info("#CARRY Macro: " + std::to_string(res.size()));
1197  print_info("#CARRY Macro Cells: " + std::to_string(cellInCarryMacrosCnt));
1198  print_status("CARRY Macro Extracted.");
1199 }
1200 
1201 // LUTs and Muxs connected are Macros
1203 {
1204  // TODO: consider F9MUX
1205 
1206  std::vector<PlacementInfo::PlacementMacro *> res;
1207  res.clear();
1208  std::vector<DesignInfo::DesignCell *> &curCellsInDesign = designInfo->getCells();
1209  int curNumCells = designInfo->getNumCells();
1210  for (int curCellId = 0; curCellId < curNumCells; curCellId++)
1211  {
1212  auto curCell = curCellsInDesign[curCellId];
1213  if (curCell->getCellType() != DesignInfo::CellType_MUXF8)
1214  continue;
1215 
1216  if (cellInMacros.find(curCell) != cellInMacros.end())
1217  continue;
1218 
1219  std::vector<DesignInfo::DesignCell *> curMacroCores;
1220  curMacroCores.clear();
1221  curMacroCores.push_back(curCell);
1222 
1224  curMacroCores[0]->getName(), placementUnits.size(), PlacementInfo::PlacementMacro::PlacementMacroType_MUX8);
1225 
1226  curMacro->addCell(curCell, curCell->getCellType(), 0, 0);
1227  bool muxF8HasDirectFF =
1228  false; // chipset/chipset_impl/mc_top/i_ddr4_0/inst/u_ddr4_mem_intfc/u_ddr_cal_riu/mcs0/inst/microblaze_I/U0/MicroBlaze_Core_I/Performance.Core/Data_Flow_I/Operand_Select_I/Gen_Bit[3].MUXF7_I1
1229  for (DesignInfo::DesignPin *driverPin : curCell->getOutputPins())
1230  {
1231  if (driverPin->getRefPinName() == "O")
1232  {
1233  auto curOutputNet = driverPin->getNet();
1234  if (curOutputNet->getPinsBeDriven().size() != 1)
1235  continue;
1236  auto pinBeDriven = curOutputNet->getPinsBeDriven()[0];
1237  if (pinBeDriven->getCell()->isFF())
1238  {
1239  if (pinBeDriven->getRefPinName().find("D") != std::string::npos)
1240  {
1241  muxF8HasDirectFF = true;
1242  curMacro->addCell(pinBeDriven->getCell(), pinBeDriven->getCell()->getCellType(), 0, 0);
1243  }
1244  }
1245  }
1246  }
1247  if (!muxF8HasDirectFF)
1248  curMacro->addVirtualCell(curCell->getName() + "__FFF8", designInfo, DesignInfo::CellType_FDCE, 0, 0);
1249  curMacro->addOccupiedSite(0.0, 0.5);
1250 
1251  for (DesignInfo::DesignPin *pinBeDriven : curCell->getInputPins())
1252  {
1253  if (pinBeDriven->getRefPinName() == "I0" || pinBeDriven->getRefPinName() == "I1")
1254  {
1255  if (!pinBeDriven->getDriverPin())
1256  {
1257  auto tmpMuxf7 =
1258  curMacro->addVirtualCell(curCell->getName() + "__MUXF7" + pinBeDriven->getRefPinName(),
1260 
1261  curMacro->addVirtualCell(curCell->getName() + "__FFF7", designInfo, DesignInfo::CellType_FDCE, 0,
1262  0);
1263  curMacro->addVirtualCell(tmpMuxf7->getName() + "__I0" + pinBeDriven->getRefPinName(), designInfo,
1265  curMacro->addVirtualCell(tmpMuxf7->getName() + "__I1" + pinBeDriven->getRefPinName(), designInfo,
1267  }
1268  else
1269  {
1270  assert(pinBeDriven->getDriverPin());
1271  assert(pinBeDriven->getDriverPin()->getCell()->getCellType() == DesignInfo::CellType_MUXF7);
1272  curMacro->addVirtualCell(pinBeDriven->getDriverPin()->getCell()->getName() + "__FFF7", designInfo,
1274  curMacro->addCell(pinBeDriven->getDriverPin()->getCell(),
1275  pinBeDriven->getDriverPin()->getCell()->getCellType(), 0, 0);
1276  }
1277  }
1278  }
1279 
1280  unsigned int lastMux = 0;
1281  assert(curMacro->getCells().size() >= 4);
1282  DesignInfo::DesignCell *tmpCell = nullptr;
1283  for (unsigned int i = lastMux + 1; i < curMacro->getCells().size(); i++)
1284  {
1285  if (curMacro->getCells()[i]->isMux())
1286  {
1287  lastMux = i;
1288  tmpCell = curMacro->getCells()[i];
1289  break;
1290  }
1291  }
1292  assert(tmpCell);
1293  assert(tmpCell->isMux());
1294  for (DesignInfo::DesignPin *pinBeDriven : tmpCell->getInputPins())
1295  {
1296  if (pinBeDriven->getRefPinName() == "I0" || pinBeDriven->getRefPinName() == "I1")
1297  {
1298  if (pinBeDriven->isUnconnected())
1299  {
1300  curMacro->addVirtualCell(tmpCell->getName() + "__" + pinBeDriven->getRefPinName(), designInfo,
1302  }
1303  else
1304  {
1305  assert(pinBeDriven->getDriverPin()->getCell()->isLUT() &&
1306  "just a guess assert. maybe just to use a if-else branch");
1307  curMacro->addCell(pinBeDriven->getDriverPin()->getCell(), DesignInfo::CellType_LUT6, 0, 0);
1308  }
1309  }
1310  }
1311 
1312  assert(curMacro->getCells().size() >= 7);
1313  tmpCell = nullptr;
1314  for (unsigned int i = lastMux + 1; i < curMacro->getCells().size(); i++)
1315  {
1316  if (curMacro->getCells()[i]->isMux())
1317  {
1318  lastMux = i;
1319  tmpCell = curMacro->getCells()[i];
1320  break;
1321  }
1322  }
1323  assert(tmpCell);
1324  assert(tmpCell->isMux());
1325  if (tmpCell->isMux())
1326  {
1327  for (DesignInfo::DesignPin *pinBeDriven : tmpCell->getInputPins())
1328  {
1329  if (pinBeDriven->getRefPinName() == "I0" || pinBeDriven->getRefPinName() == "I1")
1330  {
1331  if (pinBeDriven->isUnconnected())
1332  {
1333  curMacro->addVirtualCell(tmpCell->getName() + "__" + pinBeDriven->getRefPinName(), designInfo,
1335  }
1336  else
1337  {
1338  assert(pinBeDriven->getDriverPin()->getCell()->isLUT() &&
1339  "just a guess assert. maybe just to use a if-else branch");
1340  curMacro->addCell(pinBeDriven->getDriverPin()->getCell(), DesignInfo::CellType_LUT6, 0, 0);
1341  }
1342  }
1343  }
1344  }
1345 
1346  assert(curMacro->getCells().size() == 10);
1347  int totalWeight = 0;
1348  for (auto tmpCell : curMacro->getCells())
1349  {
1350  assert(cellInMacros.find(tmpCell) == cellInMacros.end());
1351  cellId2PlacementUnit[tmpCell->getElementIdInType()] = curMacro;
1352  cellInMacros.insert(tmpCell);
1354  }
1355  curMacro->setWeight(totalWeight);
1356  res.push_back(curMacro);
1357  placementMacros.push_back(curMacro);
1358  placementUnits.push_back(curMacro);
1359  }
1360 
1361  curNumCells = designInfo->getNumCells();
1362  for (int curCellId = 0; curCellId < curNumCells; curCellId++)
1363  {
1364  auto curCell = curCellsInDesign[curCellId];
1365  if (curCell->getCellType() != DesignInfo::CellType_MUXF7)
1366  continue;
1367 
1368  if (cellInMacros.find(curCell) != cellInMacros.end())
1369  continue;
1370 
1371  std::vector<DesignInfo::DesignCell *> curMacroCores;
1372  curMacroCores.clear();
1373  curMacroCores.push_back(curCell);
1375  curMacroCores[0]->getName(), placementUnits.size(), PlacementInfo::PlacementMacro::PlacementMacroType_MUX7);
1376  curMacro->addOccupiedSite(0.0, 0.25);
1377  curMacro->addCell(curCell, curCell->getCellType(), 0, 0);
1378 
1379  for (DesignInfo::DesignPin *driverPin : curCell->getOutputPins())
1380  {
1381  if (driverPin->getRefPinName() == "O")
1382  {
1383  auto curOutputNet = driverPin->getNet();
1384  if (curOutputNet->getPinsBeDriven().size() != 1)
1385  continue;
1386  auto pinBeDriven = curOutputNet->getPinsBeDriven()[0];
1387  if (pinBeDriven->getCell()->isFF())
1388  {
1389  if (pinBeDriven->getRefPinName().find("D") != std::string::npos)
1390  {
1391  curMacro->addCell(pinBeDriven->getCell(), pinBeDriven->getCell()->getCellType(), 0, 0);
1392  }
1393  }
1394  }
1395  }
1396  curMacro->addVirtualCell(curCell->getName() + "__FFF7", designInfo, DesignInfo::CellType_FDCE, 0, 0);
1397 
1398  for (DesignInfo::DesignPin *pinBeDriven : curMacroCores[0]->getInputPins())
1399  {
1400  if (pinBeDriven->getRefPinName() == "I0" || pinBeDriven->getRefPinName() == "I1")
1401  {
1402  if (pinBeDriven->isUnconnected())
1403  {
1404  curMacro->addVirtualCell(curCell->getName() + "__" + pinBeDriven->getRefPinName(), designInfo,
1406  }
1407  else
1408  {
1409  if (pinBeDriven->getDriverPin())
1410  {
1411  assert(pinBeDriven->getDriverPin()->getCell()->isLUT() &&
1412  "just a guess assert. maybe just to use a if-else branch");
1413  curMacro->addCell(pinBeDriven->getDriverPin()->getCell(), DesignInfo::CellType_LUT6, 0, 0);
1414  }
1415  else
1416  {
1417  curMacro->addVirtualCell(curCell->getName() + "__" + pinBeDriven->getRefPinName(), designInfo,
1419  }
1420  }
1421  }
1422  }
1423  assert(curMacro->getCells().size() >= 4);
1424  int totalWeight = 0;
1425  for (auto tmpCell : curMacro->getCells())
1426  {
1427  assert(cellInMacros.find(tmpCell) == cellInMacros.end());
1428  cellId2PlacementUnit[tmpCell->getElementIdInType()] = curMacro;
1429  cellInMacros.insert(tmpCell);
1430  totalWeight += compatiblePlacementTable->cellType2sharedBELTypeOccupation[tmpCell->getCellType()];
1431  }
1432  curMacro->setWeight(totalWeight);
1433  res.push_back(curMacro);
1434  placementMacros.push_back(curMacro);
1435  placementUnits.push_back(curMacro);
1436  }
1437 
1438  int cellInMuxMacrosCnt = 0;
1439  for (auto macro : res)
1440  cellInMuxMacrosCnt += macro->getCells().size();
1441 
1442  print_info("#Mux Macro: " + std::to_string(res.size()));
1443  print_info("#Mux Macro Cells: " + std::to_string(cellInMuxMacrosCnt));
1444  print_status("Mux Macro Extracted.");
1445 }
1446 
1447 // LUTs and Muxs connected are Macros
1448 void InitialPacker::loadOtherCLBMacros(std::string RAMMacroListFromVivadoFileName)
1449 {
1450  // currently, some macros of distributed RAMs is difficult. However, the good news is that the number of the
1451  // unpredictable macros is very small. Therefore, temporarily, we load this information extracted from Vivado.
1452 
1453  std::vector<PlacementInfo::PlacementMacro *> res;
1454  res.clear();
1455 
1456  std::ifstream infile(RAMMacroListFromVivadoFileName.c_str());
1457  assert(infile.good() && "Unpredictable Macro file does not exist and please check your path settings");
1458 
1459  std::string line;
1460  std::getline(infile, line);
1461  std::string cellName, siteName, BELName, fill0, fill1, fill2;
1462  std::istringstream iss(line);
1463 
1464  std::map<std::string, std::vector<std::string>> siteName2Cells;
1465  std::map<std::string, std::string> cellName2BELLoc;
1466  while (std::getline(infile, line))
1467  {
1468  std::istringstream iss(line);
1469  iss >> fill0 >> cellName >> fill1 >> siteName >> fill2 >> BELName;
1470  if (strContains(fill0, "name=>"))
1471  {
1472  if (siteName2Cells.find(siteName) == siteName2Cells.end())
1473  {
1474  siteName2Cells[siteName] = std::vector<std::string>();
1475  }
1476  siteName2Cells[siteName].push_back(cellName);
1477  cellName2BELLoc[cellName] = BELName;
1478  }
1479  }
1480 
1481  for (auto it = siteName2Cells.begin(); it != siteName2Cells.end(); it++)
1482  {
1483  auto curSiteName = it->first;
1484  auto curSite = deviceInfo->getSiteWithName(curSiteName);
1485  std::set<DesignInfo::DesignCell *> macroCells;
1486  std::set<char> BELset;
1487  macroCells.clear();
1488  BELset.clear();
1489 
1490  for (auto cellName : it->second)
1491  {
1492  macroCells.insert(designInfo->getCell(cellName));
1493  BELset.insert(cellName2BELLoc[cellName][6]);
1494  }
1495 
1496  PlacementInfo::PlacementMacro *curMacro = nullptr;
1497 
1498  if (curSite->getSiteType() == "SLICEM") // is LUTRAM macro
1499  {
1500  curMacro = new PlacementInfo::PlacementMacro((*macroCells.begin())->getName(), placementUnits.size(),
1502  curMacro->addOccupiedSite(0.0, 1.0);
1503  for (DesignInfo::DesignCell *cell : macroCells)
1504  {
1505  std::vector<std::string> splited;
1506  strSplit(cellName2BELLoc[cell->getName()], splited, ".");
1507  curMacro->addFixedCellInfo(cell, splited[0], splited[1]);
1508  if (cell->isLUT() || cell->isLUTRAM())
1509  {
1510  if (compatiblePlacementTable->getOccupation(cell->getCellType()) == 2)
1511  curMacro->addCell(cell, DesignInfo::CellType_LUT6, 0, 0);
1512  else
1513  curMacro->addCell(cell, DesignInfo::CellType_LUT5, 0, 0);
1514  }
1515  else
1516  {
1517  curMacro->addCell(cell, cell->getCellType(), 0, 0);
1518  curMacro->addLUTRAM(); // just let it be a fake LUTRAM so it can be mapped to SLICEM
1519  }
1520 
1521  // curMacro->setLocInMacro(cell, 0, 0);
1522  }
1523  }
1524  else
1525  {
1526  curMacro = new PlacementInfo::PlacementMacro((*macroCells.begin())->getName(), placementUnits.size(),
1528  curMacro->addOccupiedSite(0.0, 1.0);
1529  for (DesignInfo::DesignCell *cell : macroCells)
1530  {
1531  curMacro->addCell(cell, cell->getCellType(), 0, 0);
1532  }
1533  }
1534 
1535  // int factor = macroCells[0]->getCellType() == DesignInfo::CellType_RAM32X1D ? 2 : 1;
1536  // for (unsigned int i = 0; i < BELset.size() * factor; i++)
1537  // {
1538  // curMacro->addVirtualCell(designInfo, DesignInfo::CellType_LUT6, 0, 0);
1539  // }
1540  int totalWeight = 0;
1541  for (auto tmpCell : curMacro->getCells())
1542  {
1543  assert(cellInMacros.find(tmpCell) == cellInMacros.end());
1544  cellId2PlacementUnit[tmpCell->getElementIdInType()] = curMacro;
1545  cellInMacros.insert(tmpCell);
1546  totalWeight += compatiblePlacementTable->cellType2sharedBELTypeOccupation[tmpCell->getCellType()];
1547  }
1548 
1549  curMacro->setWeight(totalWeight);
1550  res.push_back(curMacro);
1551  placementMacros.push_back(curMacro);
1552  placementUnits.push_back(curMacro);
1553  }
1554 
1555  int cellInMuxMacrosCnt = 0;
1556  for (auto macro : res)
1557  cellInMuxMacrosCnt += macro->getCells().size();
1558 
1559  print_info("#CLB Macro: " + std::to_string(res.size()));
1560  print_info("#CLB Macro Cells: " + std::to_string(cellInMuxMacrosCnt));
1561  print_status("CLB Macro Extracted.");
1562 }
1563 
1565 {
1566  print_status("InitialPacker Pairing LUTs and FFs.");
1567 
1568  std::vector<std::pair<DesignInfo::DesignCell *, DesignInfo::DesignCell *>> LUTFFPairs;
1569  LUTFFPairs.clear();
1570  std::vector<bool> packed(placementUnpackedCells.size(), false);
1571  std::vector<PlacementInfo::PlacementUnpackedCell *> oriPlacementUnpackedCells = placementUnpackedCells;
1572 
1573  placementUnits.resize(placementMacros.size());
1574 
1575  int LUTTO1FFPackedCnt = 0;
1576 
1577  std::vector<DesignInfo::DesignCell *> &curCellsInDesign = designInfo->getCells();
1578  int curNumCells = designInfo->getNumCells();
1579  for (int curCellId = 0; curCellId < curNumCells; curCellId++)
1580  {
1581  auto curCell = curCellsInDesign[curCellId];
1582 
1583  if (cellInMacros.find(curCell) != cellInMacros.end())
1584  continue;
1585 
1586  if (curCell->isLUT())
1587  {
1588  assert(curCell->getOutputPins().size() > 0);
1589  if (curCell->getOutputPins().size() == 1)
1590  {
1591  if (curCell->getOutputPins()[0]
1592  ->isUnconnected()) // interestingly, some LUTs generated by Vivado might have no output
1593  continue;
1594  assert(curCell->getOutputPins()[0]->getNet());
1595  if (curCell->getOutputPins()[0]->getNet()->getPinsBeDriven().size() == 1)
1596  {
1597  auto pinBeDriven = curCell->getOutputPins()[0]->getNet()->getPinsBeDriven()[0];
1598  assert(pinBeDriven->getCell());
1599  auto FFBeDriven = pinBeDriven->getCell();
1600  if (FFBeDriven->isFF() && cellInMacros.find(FFBeDriven) == cellInMacros.end())
1601  {
1602  LUTFFPairs.emplace_back(curCell, FFBeDriven);
1603 
1605  curCell->getName(), placementUnits.size(),
1607 
1608  curMacro->addOccupiedSite(0.0, 0.0625);
1609  curMacro->addCell(curCell, curCell->getCellType(), 0, 0.0);
1610  curMacro->addCell(FFBeDriven, FFBeDriven->getCellType(), 0, 0.0);
1611 
1612  curMacro->setWeight(
1613  compatiblePlacementTable->cellType2sharedBELTypeOccupation[FFBeDriven->getCellType()] +
1615  placementMacros.push_back(curMacro);
1616  placementUnits.push_back(curMacro);
1617 
1618  cellId2PlacementUnit[curCell->getCellId()] = curMacro;
1619  cellId2PlacementUnit[FFBeDriven->getCellId()] = curMacro;
1620 
1621  cellInMacros.insert(curCell);
1622  cellInMacros.insert(FFBeDriven);
1623 
1624  LUTTO1FFPackedCnt++;
1625  }
1626  }
1627  }
1628  else
1629  {
1630  // this is a LUT6_2, has two output pins and we don't pack them temporarily.
1631  }
1632  }
1633  }
1634 
1635  print_info("InitialPacker: LUTTO1FFPackedCnt=" + std::to_string(LUTTO1FFPackedCnt));
1636 
1637  print_status("InitialPacker Paired LUTs and FFs (#Pairs = " + std::to_string(LUTFFPairs.size()) + ")");
1638 }
1639 
1641 {
1642  // const char *celltypestr[] = {CELLTYPESTRS};
1643  for (DesignInfo::DesignCell *cell : designInfo->getCells())
1644  {
1645  if (cellInMacros.find(cell) == cellInMacros.end())
1646  {
1647  assert(!cell->isVirtualCell());
1648  PlacementInfo::PlacementUnpackedCell *curUnpackedCell =
1649  new PlacementInfo::PlacementUnpackedCell(cell->getName(), placementUnits.size(), cell);
1650  curUnpackedCell->setWeight(compatiblePlacementTable->cellType2sharedBELTypeOccupation[cell->getCellType()]);
1651 
1652  cellId2PlacementUnit[cell->getElementIdInType()] = curUnpackedCell;
1653  placementUnits.push_back(curUnpackedCell);
1654  placementUnpackedCells.push_back(curUnpackedCell);
1655  }
1656  }
1657 }
1658 
1659 void packerUtil_StrReplaceAll(std::string &str, const std::string from, const std::string to)
1660 {
1661  if (from.empty())
1662  return;
1663  std::string::size_type start_pos = 0;
1664  while ((start_pos = str.find(from, start_pos)) != std::string::npos)
1665  {
1666  str.replace(start_pos, from.length(), to);
1667  start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
1668  }
1669 }
1670 
1671 void InitialPacker::loadFixedPlacementUnits(std::string fixedPlacementUnitsFromVivadoFileName)
1672 {
1673  fixedPlacementUnits.clear();
1674  std::ifstream infile(fixedPlacementUnitsFromVivadoFileName.c_str());
1675  assert(infile.good() && "Fixed Element file does not exist and please check your path settings");
1676 
1677  std::string line;
1678  std::getline(infile, line);
1679  std::string cellName, siteName, BELName, fill0, fill1, fill2;
1680  std::istringstream iss(line);
1681 
1682  while (std::getline(infile, line))
1683  {
1684  std::istringstream iss(line);
1685  iss >> fill0 >> cellName >> fill1 >> siteName >> fill2 >> BELName;
1686  if (strContains(fill0, "name=>"))
1687  {
1688  auto curCell = designInfo->getCell(cellName);
1689  for (auto tmpPin : curCell->getPins())
1690  {
1691  tmpPin->setFixed();
1692  if (tmpPin->getNet())
1693  {
1694  tmpPin->getNet()->setContainFixedPins();
1695  }
1696  }
1698  cellId2PlacementUnit[curCell->getElementIdInType()]))
1699  {
1700  unpackedPU->setLockedAt(siteName, BELName, deviceInfo);
1701  fixedPlacementUnits.push_back(unpackedPU);
1702  }
1703  else if (PlacementInfo::PlacementMacro *curMacro = dynamic_cast<PlacementInfo::PlacementMacro *>(
1704  cellId2PlacementUnit[curCell->getElementIdInType()]))
1705  {
1706  // We can only handle BRAM36 currently
1707  assert(curCell->getCellType() == DesignInfo::CellType_RAMB36E2);
1708  assert(curMacro->getCells().size() == 2);
1709  assert(curMacro->getCells()[0]->getCellType() == DesignInfo::CellType_RAMB36E2);
1710  assert(curMacro->getCells()[1]->getCellType() == DesignInfo::CellType_RAMB18E2 &&
1711  curMacro->getCells()[1]->isVirtualCell());
1712 
1713  // 12
1714  // 012345678901
1715  // RAMB18_X16Y2 bel=> RAMB180.RAMB18E2_L
1716  int locY = std::stoi(siteName.substr(siteName.find('Y') + 1, siteName.size() - siteName.find('Y') - 1));
1717  std::string newSiteName = siteName.substr(0, siteName.find('Y') + 1);
1718  std::string oriS = "RAMB36_";
1719  std::string newS = "RAMB18_";
1720  packerUtil_StrReplaceAll(newSiteName, oriS, newS);
1721  std::string newSiteNameA = newSiteName + std::to_string(locY * 2);
1722  std::string newSiteNameB = newSiteName + std::to_string(locY * 2 + 1);
1723  std::string newBELNameA = "RAMB180.RAMB18E2_L";
1724  std::string newBELNameB = "RAMB181.RAMB18E2_U";
1725 
1726  curMacro->addFixedCellInfo(curMacro->getCells()[0], newSiteNameA, newBELNameA);
1727  curMacro->addFixedCellInfo(curMacro->getCells()[1], newSiteNameB, newBELNameB);
1728  deviceInfo->getSite(newSiteNameA)->setOccupied();
1729  deviceInfo->getSite(newSiteNameB)->setOccupied();
1730  curMacro->setAnchorLocation(deviceInfo->getSite(newSiteNameA)->X(),
1731  deviceInfo->getSite(newSiteNameA)->Y());
1732 
1733  curMacro->setFixed();
1734  curMacro->setPlaced();
1735  curMacro->setLocked();
1736 
1737  fixedPlacementUnits.push_back(curMacro);
1738  // assert(false && "unimplemented.");
1739  }
1740  }
1741  }
1742 }
1743 
1745 {
1746  std::ofstream tmpColorFile(JSONCfg["dumpDirectory"] + "/color.tcl");
1747  assert(tmpColorFile.is_open() && tmpColorFile.good() &&
1748  "The path for dumping elements' highlight colors does not exist and please check your path settings");
1749  // 2 -> carry
1750  // 1 -> DSP
1751  // 3 -> BRAM
1752  // 4 -> LUTRAM
1753  // 7 -> MUX
1754 
1755  tmpColorFile << "highlight -color_index 2 [ get_cells { \n";
1756  for (auto tmpMacro : placementInfo->getPlacementMacros())
1757  {
1758  if (tmpMacro->getMacroType() == PlacementInfo::PlacementMacro::PlacementMacroType_CARRY)
1759  {
1760  if (tmpMacro->getCells().size() == 1)
1761  continue;
1762  for (auto tmpCell : tmpMacro->getCells())
1763  {
1764  if (!tmpCell->isVirtualCell())
1765  {
1766  tmpColorFile << tmpCell->getName() << "\n";
1767  }
1768  }
1769  }
1770  }
1771  tmpColorFile << "}]\n";
1772 
1773  tmpColorFile << "highlight -color_index 1 [ get_cells { \n";
1774  for (auto tmpMacro : placementInfo->getPlacementMacros())
1775  {
1776  if (tmpMacro->getMacroType() == PlacementInfo::PlacementMacro::PlacementMacroType_DSP)
1777  {
1778  if (tmpMacro->getCells().size() == 1)
1779  continue;
1780  for (auto tmpCell : tmpMacro->getCells())
1781  {
1782  if (!tmpCell->isVirtualCell())
1783  {
1784  tmpColorFile << tmpCell->getName() << "\n";
1785  }
1786  }
1787  }
1788  }
1789  tmpColorFile << "}]\n";
1790 
1791  tmpColorFile << "highlight -color_index 3 [ get_cells { \n";
1792  for (auto tmpMacro : placementInfo->getPlacementMacros())
1793  {
1794  if (tmpMacro->getMacroType() == PlacementInfo::PlacementMacro::PlacementMacroType_BRAM)
1795  {
1796  if (tmpMacro->getCells().size() == 1)
1797  continue;
1798  for (auto tmpCell : tmpMacro->getCells())
1799  {
1800  if (!tmpCell->isVirtualCell())
1801  {
1802  tmpColorFile << tmpCell->getName() << "\n";
1803  }
1804  }
1805  }
1806  }
1807  tmpColorFile << "}]\n";
1808 
1809  tmpColorFile << "highlight -color_index 4 [ get_cells { \n";
1810  for (auto tmpMacro : placementInfo->getPlacementMacros())
1811  {
1812  if (tmpMacro->getMacroType() == PlacementInfo::PlacementMacro::PlacementMacroType_MCLB)
1813  {
1814  if (tmpMacro->getCells().size() == 1)
1815  continue;
1816  for (auto tmpCell : tmpMacro->getCells())
1817  {
1818  if (!tmpCell->isVirtualCell())
1819  {
1820  tmpColorFile << tmpCell->getName() << "\n";
1821  }
1822  }
1823  }
1824  }
1825  tmpColorFile << "}]\n";
1826 
1827  tmpColorFile << "highlight -color_index 7 [ get_cells { \n";
1828  for (auto tmpMacro : placementInfo->getPlacementMacros())
1829  {
1830  if (tmpMacro->getMacroType() == PlacementInfo::PlacementMacro::PlacementMacroType_MUX7 ||
1831  tmpMacro->getMacroType() == PlacementInfo::PlacementMacro::PlacementMacroType_MUX8 ||
1832  tmpMacro->getMacroType() == PlacementInfo::PlacementMacro::PlacementMacroType_MUX9)
1833  {
1834  if (tmpMacro->getCells().size() == 1)
1835  continue;
1836  for (auto tmpCell : tmpMacro->getCells())
1837  {
1838  if (!tmpCell->isVirtualCell())
1839  {
1840  tmpColorFile << tmpCell->getName() << "\n";
1841  }
1842  }
1843  }
1844  }
1845  tmpColorFile << "}]\n";
1846  tmpColorFile.close();
1847 }
DesignInfo::DesignCell::isVirtualCell
bool isVirtualCell()
Definition: DesignInfo.h:1042
InitialPacker::dumpMacroHighLight
void dumpMacroHighLight()
Definition: InitialPacker.cc:1744
PlacementInfo::CompatiblePlacementTable::cellType2sharedBELTypeOccupation
std::map< DesignInfo::DesignCellType, int > cellType2sharedBELTypeOccupation
the resource demand of specific types. (cost how many slot/BELs)
Definition: PlacementInfo.h:144
InitialPacker::JSONCfg
std::map< std::string, std::string > & JSONCfg
Definition: InitialPacker.h:364
PlacementInfo::calculateNetNumDistributionOfPUs
void calculateNetNumDistributionOfPUs()
calculate the proportion of the PlacementUnit objects with high interconnection density
Definition: PlacementInfo.h:4176
DesignInfo::getNumCells
int getNumCells()
Definition: DesignInfo.h:1600
DesignInfo::DesignCell::isMux
bool isMux()
Definition: DesignInfo.h:959
DesignInfo::CellType_LUT6_2
@ CellType_LUT6_2
Definition: DesignInfo.h:80
paintPlacement.cnt
int cnt
Definition: paintPlacement.py:155
DesignInfo::CellType_RAMB36E2
@ CellType_RAMB36E2
Definition: DesignInfo.h:111
InitialPacker::cellId2PlacementUnit
std::map< int, PlacementInfo::PlacementUnit * > & cellId2PlacementUnit
Definition: InitialPacker.h:362
InitialPacker::placementInfo
PlacementInfo * placementInfo
Definition: InitialPacker.h:353
InitialPacker::placementMacros
std::vector< PlacementInfo::PlacementMacro * > & placementMacros
Definition: InitialPacker.h:358
InitialPacker::loadOtherCLBMacros
void loadOtherCLBMacros(std::string RAMMacroListFromVivadoFileName)
load the special macros from the design file. vendors might allow users to specify some primitive mac...
Definition: InitialPacker.cc:1448
PlacementInfo::PlacementUnit::addLUTRAM
void addLUTRAM()
Definition: PlacementInfo.h:1280
PlacementInfo::PlacementMacro
a fixed group of multiple standard cells with constraints of their relative locations
Definition: PlacementInfo.h:1525
InitialPacker::compatiblePlacementTable
PlacementInfo::CompatiblePlacementTable * compatiblePlacementTable
Definition: InitialPacker.h:354
DesignInfo::DesignCell::isLUT6
bool isLUT6()
Definition: DesignInfo.h:923
InitialPacker::designInfo
DesignInfo * designInfo
Definition: InitialPacker.h:351
PlacementInfo::PlacementUnit::setWeight
void setWeight(int numCell)
Definition: PlacementInfo.h:1196
DesignInfo::DesignCell
a DesignCell in design netlist, DesignPin objects of which might connect to DesignNet objects
Definition: DesignInfo.h:782
DesignInfo::CellType_FIFO18E2
@ CellType_FIFO18E2
Definition: DesignInfo.h:109
InitialPacker::loadFixedPlacementUnits
void loadFixedPlacementUnits(std::string fixedPlacementUnitsFromVivadoFileName)
load the fixed elements (e.g., IOs) from the design file.
Definition: InitialPacker.cc:1671
DeviceInfo::getSiteWithName
DeviceSite * getSiteWithName(std::string &siteName)
Get a site based on a given name.
Definition: DeviceInfo.h:1031
removeFailurePartFromTcl.line
line
Definition: removeFailurePartFromTcl.py:32
DesignInfo::DesignNet
a design net (hyperedge) defined in the design, connecting to pins of cells
Definition: DesignInfo.h:525
PlacementInfo::PlacementMacro::getCellOffsetYInMacro
float getCellOffsetYInMacro(DesignInfo::DesignCell *cell)
Definition: PlacementInfo.h:1762
PlacementInfo::PlacementMacro::PlacementMacroType_LCLB
@ PlacementMacroType_LCLB
Definition: PlacementInfo.h:1533
InitialPacker::SiteBELMapping::Carry
DesignInfo::DesignCell * Carry
Definition: InitialPacker.h:348
DesignInfo::getCell
DesignCell * getCell(std::string &tmpName)
Definition: DesignInfo.h:1634
PlacementInfo::PlacementMacro::PlacementMacroType_CARRY
@ PlacementMacroType_CARRY
Definition: PlacementInfo.h:1537
InitialPacker::findDSPMacros
void findDSPMacros()
detects DSP macros and clusters the related cells into PlacementInfo::PlacementMacro
Definition: InitialPacker.cc:215
InitialPacker::placementUnits
std::vector< PlacementInfo::PlacementUnit * > & placementUnits
Definition: InitialPacker.h:356
PlacementInfo::PlacementMacro::PlacementMacroType_MUX8
@ PlacementMacroType_MUX8
Definition: PlacementInfo.h:1541
PlacementInfo::PlacementMacro::PlacementMacroType_MUX9
@ PlacementMacroType_MUX9
Definition: PlacementInfo.h:1542
DesignInfo::DesignPin
A design pin on a design cell connected to a net.
Definition: DesignInfo.h:277
PlacementInfo::PlacementMacro::PlacementMacroType_MCLB
@ PlacementMacroType_MCLB
Definition: PlacementInfo.h:1535
DesignInfo::DesignCell::getCellType
DesignCellType getCellType()
Definition: DesignInfo.h:881
InitialPacker::checkCompatibleFFs
std::vector< DesignInfo::DesignCell * > checkCompatibleFFs(std::vector< DesignInfo::DesignCell * > FFs)
check the control set of the candidate FFs and select the control set with the most FFs to be packed ...
Definition: InitialPacker.cc:534
PlacementInfo::updateCells2PlacementUnits
void updateCells2PlacementUnits()
update the mapping from Cells to PlacementUnits, since sometime, PlacementUnits might change
Definition: PlacementInfo.cc:1683
DesignInfo::updateFFControlSets
void updateFFControlSets()
go through the FF cells to extract control sets for later processing
Definition: DesignInfo.cc:425
PlacementInfo::getPlacementMacros
std::vector< PlacementMacro * > & getPlacementMacros()
Definition: PlacementInfo.h:2814
InitialPacker::findLUTRAMMacros
void findLUTRAMMacros()
detects LUTRAM macros and clusters the related cells into PlacementInfo::PlacementMacro
Definition: InitialPacker.cc:362
PlacementInfo::PlacementMacro::PlacementMacroType_MUX7
@ PlacementMacroType_MUX7
Definition: PlacementInfo.h:1540
strContains
bool strContains(std::string target, std::string substring)
Definition: stringCheck.cc:30
InitialPacker.h
This header file contains the definitions of InitialPacker class and its internal modules and APIs wh...
PlacementInfo::CompatiblePlacementTable::getOccupation
float getOccupation(DesignInfo::DesignCellType cellType)
Get the theoratical occupation of a specific cell type.
Definition: PlacementInfo.h:227
DesignInfo::DesignCell::getOriCellType
DesignCellType getOriCellType()
Get the Original Cell Type object defined in the design netlist.
Definition: DesignInfo.h:1089
PlacementInfo::PlacementMacro::PlacementMacroType_DSP
@ PlacementMacroType_DSP
Definition: PlacementInfo.h:1538
PlacementInfo::PlacementMacro::addVirtualCell
DesignInfo::DesignCell * addVirtualCell(std::string virtualCellName, DesignInfo *designInfo, DesignInfo::DesignCellType cellType, float x, float y)
add a virtual cell with a given name into the macro with its offsets in the macro....
Definition: PlacementInfo.h:1634
InitialPacker::SiteBELMapping::LUTs
DesignInfo::DesignCell * LUTs[2][2][4]
Definition: InitialPacker.h:338
PlacementInfo::reloadNets
void reloadNets()
update PlacementNet objects when there are some updates of PlacementUnit objects (e....
Definition: PlacementInfo.cc:507
DesignInfo::CellType_RAMB18E2
@ CellType_RAMB18E2
Definition: DesignInfo.h:110
DesignInfo::DesignNet::getPinsBeDriven
std::vector< DesignPin * > & getPinsBeDriven()
Get the vector reference of the pins driven by the net.
Definition: DesignInfo.h:581
DesignInfo::CellType_FIFO36E2
@ CellType_FIFO36E2
Definition: DesignInfo.h:108
InitialPacker::setDSPRegs
void setDSPRegs(std::vector< DesignInfo::DesignCell * > &DSPTailsToBeCheckedRegisterAttr)
Definition: InitialPacker.cc:307
InitialPacker::cellInMacros
std::set< DesignInfo::DesignCell * > & cellInMacros
Definition: InitialPacker.h:361
DeviceInfo::getSite
DeviceSite * getSite(std::string &Name)
Definition: DeviceInfo.h:1111
print_status
void print_status(std::string tmp_string)
Definition: strPrint.cc:44
InitialPacker::fixedPlacementUnits
std::vector< PlacementInfo::PlacementUnit * > & fixedPlacementUnits
Definition: InitialPacker.h:359
PlacementInfo::PlacementMacro::PlacementMacroType_LUTFFPair
@ PlacementMacroType_LUTFFPair
Definition: PlacementInfo.h:1529
DesignInfo::DesignElement::getName
const std::string & getName() const
Definition: DesignInfo.h:243
print_error
void print_error(std::string tmp_string)
Definition: strPrint.cc:52
DesignInfo::CellType_LUT5
@ CellType_LUT5
Definition: DesignInfo.h:78
print_warning
void print_warning(std::string tmp_string)
Definition: strPrint.cc:57
InitialPacker::deviceInfo
DeviceInfo * deviceInfo
Definition: InitialPacker.h:352
InitialPacker::pack
void pack()
extract the macros from the netlist to construction PlacmentMacro
Definition: InitialPacker.cc:28
PlacementInfo::CompatiblePlacementTable::setBELTypeForCells
void setBELTypeForCells(DesignInfo *designInfo)
set the mapping from cells in design netlist to BEL type ID for later processing.
Definition: PlacementInfo.cc:217
InitialPacker::findUnpackedUnits
void findUnpackedUnits()
other non-Macro elements will be instantiated as PlacementInfo::PlacementUnpackedCell
Definition: InitialPacker.cc:1640
DesignInfo::DesignCell::isLUT
bool isLUT()
Definition: DesignInfo.h:927
InitialPacker::LUTFFPairing
void LUTFFPairing()
directly pack some LUTs/FFs if the LUT has only one fan-out.
Definition: InitialPacker.cc:1564
InitialPacker::findMuxMacros
void findMuxMacros()
detects Mux macros and clusters the related cells into PlacementInfo::PlacementMacro
Definition: InitialPacker.cc:1202
DeviceInfo::DeviceSite::setOccupied
void setOccupied()
Definition: DeviceInfo.h:316
PlacementInfo::PlacementMacro::addOccupiedSite
void addOccupiedSite(float siteOffset, float occ)
for site-level cell spreading
Definition: PlacementInfo.h:1827
DesignInfo::CellType_MUXF8
@ CellType_MUXF8
Definition: DesignInfo.h:93
InitialPacker::BFSExpandViaSpecifiedPorts
std::vector< DesignInfo::DesignCell * > BFSExpandViaSpecifiedPorts(std::string portPattern, DesignInfo::DesignCell *startCell, bool exactMatch=false)
BFS to find the core cells of a macro based on some pre-defined patterns of cascaded cells.
Definition: InitialPacker.cc:118
strSplit
void strSplit(const std::string &s, std::vector< std::string > &sv, const char *delim)
Definition: stringCheck.cc:35
DesignInfo::DesignElement::getElementIdInType
int getElementIdInType()
Definition: DesignInfo.h:255
InitialPacker::placementUnpackedCells
std::vector< PlacementInfo::PlacementUnpackedCell * > & placementUnpackedCells
Definition: InitialPacker.h:357
canLUTPacked
bool canLUTPacked(DesignInfo::DesignCell *ALUT, DesignInfo::DesignCell *BLUT)
Definition: InitialPacker.cc:506
DesignInfo::getCells
std::vector< DesignCell * > & getCells()
Definition: DesignInfo.h:1609
PlacementInfo::PlacementMacro::hasCell
bool hasCell(DesignInfo::DesignCell *curCell)
Definition: PlacementInfo.h:1562
InitialPacker::mapCarryRelatedRouteThru
void mapCarryRelatedRouteThru(PlacementInfo::PlacementMacro *CARRYChain, DesignInfo::DesignCell *coreCell, float CARRYChainSiteOffset)
Definition: InitialPacker.cc:592
DeviceInfo::DeviceSite::X
float X()
Definition: DeviceInfo.h:288
DesignInfo::CellType_CARRY8
@ CellType_CARRY8
Definition: DesignInfo.h:89
PlacementInfo::getPlacementNets
std::vector< PlacementNet * > & getPlacementNets()
Definition: PlacementInfo.h:2822
DesignInfo::CellType_LUT6
@ CellType_LUT6
Definition: DesignInfo.h:79
InitialPacker::SiteBELMapping
SiteBELMapping is a contain recording the mapping between cells and BELs.
Definition: InitialPacker.h:314
packerUtil_StrReplaceAll
void packerUtil_StrReplaceAll(std::string &str, const std::string from, const std::string to)
Definition: InitialPacker.cc:1659
PlacementInfo::PlacementMacro::addCell
void addCell(DesignInfo::DesignCell *curCell, DesignInfo::DesignCellType cellType, float x, float y)
add a real cell into the macro with its offsets in the macro
Definition: PlacementInfo.h:1576
PlacementInfo::PlacementUnpackedCell
the smallest, indivisible, representable component. It will include only one standard cell
Definition: PlacementInfo.h:1447
DesignInfo::CellType_FDCE
@ CellType_FDCE
Definition: DesignInfo.h:82
print_info
void print_info(std::string tmp_string)
Definition: strPrint.cc:39
InitialPacker::PackedControlSet
control set information container used during initial packing.
Definition: InitialPacker.h:197
PlacementInfo::PlacementMacro::getCells
std::vector< DesignInfo::DesignCell * > & getCells()
Definition: PlacementInfo.h:1724
checkHalfColumn.i
int i
Definition: checkHalfColumn.py:5
InitialPacker::DSPCritical
bool DSPCritical
Definition: InitialPacker.h:365
InitialPacker::SiteBELMapping::FFs
DesignInfo::DesignCell * FFs[2][2][4]
Definition: InitialPacker.h:342
DesignInfo::DesignCell::getInputPins
std::vector< DesignPin * > & getInputPins()
Definition: DesignInfo.h:918
InitialPacker::enhanceIONets
void enhanceIONets()
enhance the nets connected to the IO ports
Definition: InitialPacker.cc:96
PlacementInfo::PlacementMacro::addFixedCellInfo
void addFixedCellInfo(DesignInfo::DesignCell *cell, std::string siteName, std::string BELName)
add information of a fixed cell
Definition: PlacementInfo.h:1751
DesignInfo::DesignCell::getOutputNets
std::vector< DesignNet * > & getOutputNets()
Definition: DesignInfo.h:906
PlacementInfo::PlacementMacro::PlacementMacroType_BRAM
@ PlacementMacroType_BRAM
Definition: PlacementInfo.h:1539
InitialPacker::findBRAMMacros
void findBRAMMacros()
detects BRAM macros and clusters the related cells into PlacementInfo::PlacementMacro
Definition: InitialPacker.cc:408
DeviceInfo::DeviceSite::Y
float Y()
Definition: DeviceInfo.h:292
DesignInfo::CellType_MUXF7
@ CellType_MUXF7
Definition: DesignInfo.h:92
InitialPacker::findCARRYMacros
void findCARRYMacros()
detects CARRY macros and clusters the related cells into PlacementInfo::PlacementMacro
Definition: InitialPacker.cc:815