AMF-Placer
2.0
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
|
Go to the documentation of this file.
26 #ifndef _PARALLELCLBPACKER_
27 #define _PARALLELCLBPACKER_
31 #include "KDTree/KDTree.h"
32 #include "MaximalCardinalityMatching/MaximalCardinalityMatching.h"
147 assert((anotherControlSet.
getSize() > 0 || anotherControlSet.
getCSId() < 0) &&
148 "the other one control set should not be empty.");
154 SR = anotherControlSet.
getSR();
155 CE = anotherControlSet.
getCE();
175 assert((anotherControlSet.
getSize() > 0 || anotherControlSet.
getCSId() < 0) &&
176 "the other one control set should not be empty.");
182 SR = anotherControlSet.
getSR();
183 CE = anotherControlSet.
getCE();
212 inline const std::vector<DesignInfo::DesignCell *> &
getFFs()
const
223 assert(
FFs.size() == 0);
256 FFs.push_back(curFF);
258 return a->getCellId() > b->getCellId();
269 assert(
i < (
int)
FFs.size());
277 bool allVirtual =
true;
278 for (
unsigned int i = 0;
i <
FFs.size();
i++)
280 if (!
FFs[
i]->isVirtualCell())
304 for (
unsigned int i = 0;
i <
FFs.size();
i++)
369 if (
CSId == -1 || inputCSId == -1)
371 return inputCSId ==
CSId;
390 std::vector<DesignInfo::DesignCell *>
FFs;
461 assert(
false &&
"PackingCLBCluster should not initialize without parameters \"parentPackingCLB\". This "
462 "problem might be caused by resizing vector to a longer one");
479 id = anotherPackingCLBCluster->
getId();
483 PUs = anotherPackingCLBCluster->
getPUs();
535 if (!tmpPin->isUnconnected())
537 netIds[pinNumA] = tmpPin->getNet()->getElementIdInType();
544 if (!tmpPin->isUnconnected())
546 bool matched =
false;
547 for (
int i = 0;
i < pinNumA;
i++)
549 if (netIds[
i] >= 0 && netIds[
i] == tmpPin->getNet()->getElementIdInType())
634 bool addToFFSet(std::vector<DesignInfo::DesignCell *> curFFs,
int halfCLB);
663 bool addFFGroup(std::vector<DesignInfo::DesignCell *> curFFs,
int enforceHalfCLB,
bool enforceMainFFSlot,
697 std::vector<bool> foundMuxFF(4,
false);
701 for (
auto FF : CSFF.getFFs())
705 foundMuxFF[
i] =
true;
715 std::set<DesignInfo::DesignCell *> movedFFs;
717 for (
auto FF : CSFF.getFFs())
719 if (!
isMuxMacro(FF) && FF && FF->getControlSetInfo())
723 if (k ==
i || foundMuxFF[k])
725 int CSId = FF->getControlSetInfo()->getId();
729 int anotherSetId = k - 1 + ((k % 2 == 0) ? 2 : 0);
732 assert(
addFF(FF, k));
740 assert(movedFFs.size() < 4);
742 for (
auto movedFF : movedFFs)
744 int movedId = CSFF.findFF(movedFF);
745 assert(movedId >= 0);
746 CSFF.removeXthFF(movedId);
747 if (CSFF.getSize() == 0)
774 std::vector<bool> foundCarryFF(4,
false);
778 for (
auto FF : CSFF.getFFs())
782 foundCarryFF[
i] =
true;
789 std::set<DesignInfo::DesignCell *> movedFFs;
791 if (foundCarryFF[FFSetId])
794 for (
auto FF : CSFF.getFFs())
800 if (k == FFSetId || foundCarryFF[k])
802 int CSId = FF->getControlSetInfo()->getId();
806 int anotherSetId = k - 1 + ((k % 2 == 0) ? 2 : 0);
809 assert(
addFF(FF, k));
817 assert(movedFFs.size() < 4);
819 for (
auto movedFF : movedFFs)
821 int movedId = CSFF.findFF(movedFF);
822 assert(movedId >= 0);
823 CSFF.removeXthFF(movedId);
824 if (CSFF.getSize() == 0)
830 return movedFFs.size() > 0;
847 if (LUTPair.first == curLUT)
853 else if (LUTPair.second == curLUT)
860 assert(
false &&
"should be erased successfully");
884 assert(
false &&
"should not reach here");
895 assert(
PUs.find(tmpPU) !=
PUs.end());
896 std::vector<DesignInfo::DesignCell *> cellsToRemove(0);
899 cellsToRemove.push_back(unpackCell->getCell());
903 for (
auto tmpCell : curMacro->getCells())
904 cellsToRemove.push_back(tmpCell);
907 for (
auto curCell : cellsToRemove)
909 if (curCell->isLUT())
913 else if (curCell->isFF())
919 assert(curCell->isMux());
982 if (fakeCluster->
addPU(tmpPU,
false))
1001 if (fakeCluster->
addPU(tmpPU,
false))
1029 return PUs.find(tmpPU) !=
PUs.end();
1032 inline const std::set<PlacementInfo::PlacementUnit *, Packing_PUcompare> &
getPUs()
const
1039 std::set<DesignInfo::DesignCell *> res;
1044 for (
auto FF : cs.getFFs())
1064 res.insert(LUTPair.first);
1068 res.insert(LUTPair.second);
1093 for (
auto cell : tmpMacro->getCells())
1100 for (
auto cell : tmpMacro->getCells())
1123 res.insert(LUTPair.first);
1127 res.insert(LUTPair.second);
1157 std::vector<DesignInfo::DesignCell *> LUTs;
1160 LUTs.push_back(tmpLUT);
1162 return a->getCellId() > b->getCellId();
1209 if (tmpLUT == pair.first)
1215 if (tmpLUT == pair.second)
1237 if (tmpLUTA == pair.first)
1239 assert(pair.second == tmpLUTB);
1243 if (tmpLUTA == pair.second)
1245 assert(pair.first == tmpLUTB);
1258 inline const std::set<std::pair<DesignInfo::DesignCell *, DesignInfo::DesignCell *>> &
getPairedLUTs()
const
1270 std::vector<std::pair<DesignInfo::DesignCell *, DesignInfo::DesignCell *>> pairedLUTs_new;
1271 pairedLUTs_new.clear();
1273 pairedLUTs_new.push_back(tmpLUTs);
1275 std::sort(pairedLUTs_new.begin(), pairedLUTs_new.end(),
1276 [](std::pair<DesignInfo::DesignCell *, DesignInfo::DesignCell *> &a,
1277 std::pair<DesignInfo::DesignCell *, DesignInfo::DesignCell *> &b) ->
bool {
1278 return a.first->getCellId() > b.first->getCellId();
1281 return pairedLUTs_new;
1296 for (
auto tmpPU :
PUs)
1368 for (
auto tmpPU :
PUs)
1373 unpackCell->getCell()->getCellId();
1378 for (
auto tmpCell : curMacro->getCells())
1381 tmpCell->getCellId();
1399 int clusterHashId =
getHash();
1405 unpackCell->getCell()->getCellId();
1406 clusterHashId %= 10001777;
1410 for (
auto tmpCell : curMacro->getCells())
1413 tmpCell->getCellId();
1414 clusterHashId %= 10001777;
1418 return clusterHashId;
1441 std::vector<DesignInfo::DesignCell *> cellsToCheck(0);
1442 for (
auto tmpPU :
PUs)
1446 hashId += 28901 * unpackCell->getCell()->getCellId();
1451 for (
auto tmpCell : curMacro->getCells())
1453 hashId += 28901 * tmpCell->getCellId();
1540 float totalCellWeight = 0;
1555 for (
auto curCell : CS.getFFs())
1561 return totalCellWeight;
1626 if (unpacked->getCell()->isVirtualCell())
1628 return timingNodes[unpacked->getCell()->getCellId()]->getLongestPathLength();
1633 for (
auto tmpCell : tmpMacro->getCells())
1635 if (tmpCell->isVirtualCell())
1637 int len = timingNodes[tmpCell->getCellId()]->getLongestPathLength();
1662 if (unpacked->getCell()->isVirtualCell() ||
1663 timingNodes[unpacked->getCell()->getCellId()]->checkIsRegister())
1665 return (timingNodes[unpacked->getCell()->getCellId()]->getLatestInputArrival() -
1666 timingNodes[unpacked->getCell()->getCellId()]->getRequiredArrivalTime());
1670 float maxNegativeSlack = 0;
1671 for (
auto tmpCell : tmpMacro->getCells())
1673 if (tmpCell->isVirtualCell())
1676 if (timingNodes[tmpCell->getCellId()]->checkIsRegister())
1678 float negativeSlack = (timingNodes[tmpCell->getCellId()]->getLatestInputArrival() -
1679 timingNodes[tmpCell->getCellId()]->getRequiredArrivalTime());
1680 if (negativeSlack > maxNegativeSlack)
1681 maxNegativeSlack = negativeSlack;
1683 return maxNegativeSlack;
1732 std::set<PlacementInfo::PlacementUnit *, Packing_PUcompare>
PUs;
1799 std::set<std::pair<DesignInfo::DesignCell *, DesignInfo::DesignCell *>>
pairedLUTs;
1814 for (
auto tmpPU : qTop->getPUs())
1841 std::set<PlacementInfo::PlacementUnit *, Packing_PUcompare> *
1843 float displacementLowerbound,
float displacementUpperbound,
int PUNumThreshold,
1845 std::set<PlacementInfo::PlacementUnit *, Packing_PUcompare> *res =
nullptr,
1946 float changeHPWL = 0;
1949 if (tmpNet->getUnits().size() > 64)
1952 float oriHPWL = tmpNet->getHPWL(
y2xRatio);
1953 if (std::isnan(newHPWL) || std::isnan(oriHPWL))
1955 #pragma omp critical
1959 std::cout <<
"curPU === \n" << tmpPU <<
"\n";
1960 std::cout <<
"CLBSite->X()=" <<
CLBSite->
X() <<
" CLBSite->Y()=" <<
CLBSite->
Y()
1961 <<
" y2xRatio=" <<
y2xRatio <<
"\n";
1962 for (
auto tmpPU0 : tmpNet->getUnits())
1964 auto tmpPinOffset = tmpNet->getPinOffsetsInUnit()[o];
1965 std::cout <<
"PUXoffset=" << tmpPinOffset.x <<
" PUYoffset=" << tmpPinOffset.y <<
"\n";
1966 std::cout <<
"PU=" << tmpPU0 <<
"\n";
1970 float oriHPWL1 = tmpNet->getHPWL(
y2xRatio);
1971 std::cout <<
"newHPWL1=" << newHPWL1 <<
" oriHPWL1=" << oriHPWL1 <<
"\n";
1975 changeHPWL += newHPWL - oriHPWL;
2005 for (
int i = 0;
i < 2;
i++)
2007 for (
int j = 0; j < 2; j++)
2009 for (
int k = 0; k < 4; k++)
2018 std::cout <<
CARRYChain <<
" \n =====================================\n targetFF:"
2020 std::cout <<
"slotMapping.FFs[i][j][k].CS=\n";
2026 std::cout <<
"currentCluster:\n";
2028 std::cout <<
"FF-FFSet:\n";
2032 std::cout <<
"FF-FF:\n";
2036 std::cout <<
"i,j,k: " <<
i <<
", " << j <<
", " << k <<
"\n";
2064 assert(_NonCLBCell);
2146 if (!tmpPin->isUnconnected())
2148 netIds[pinNumA] = tmpPin->getNet()->getElementIdInType();
2155 if (!tmpPin->isUnconnected())
2157 bool matched =
false;
2158 for (
int i = 0;
i < pinNumA;
i++)
2160 if (netIds[
i] >= 0 && netIds[
i] == tmpPin->getNet()->getElementIdInType())
2189 for (
int i = 0;
i < 2;
i++)
2192 for (
int j = 0; j < 2; j++)
2195 for (
int k = 0; k < 4; k++)
2197 LUTs[
i][j][k] =
nullptr;
2198 FFs[
i][j][k] =
nullptr;
2206 for (
int i = 0;
i < 2;
i++)
2209 for (
int j = 0; j < 2; j++)
2212 for (
int k = 0; k < 4; k++)
2214 LUTs[
i][j][k] = anotherMapping.
LUTs[
i][j][k];
2215 FFs[
i][j][k] = anotherMapping.
FFs[
i][j][k];
2225 for (
int i = 0;
i < 2;
i++)
2227 for (
int j = 0; j < 2; j++)
2229 bool compatible =
true;
2230 if (targetLUT->
isLUT6() && j == 1)
2232 for (
int k = 0; k < 4; k++)
2236 if (
FFs[
i][j][k]->getControlSetInfo())
2238 if (
FFs[
i][j][k]->getControlSetInfo()->getId() !=
2246 for (
int k = 0; k < 4; k++)
2248 if (
FFs[
i][1 - j][k])
2250 if (
FFs[
i][1 - j][k]->getControlSetInfo())
2252 if (
FFs[
i][1 - j][k]->getControlSetInfo()->getCLK() !=
2264 for (
int k = 0; k < 4; k++)
2281 for (
int i = 0;
i < 2;
i++)
2283 for (
int j = 0; j < 2; j++)
2285 bool compatible =
true;
2286 if (targetLUT->
isLUT6() && j == 1)
2288 for (
int k = 0; k < 4; k++)
2292 if (
FFs[
i][j][k]->getControlSetInfo())
2294 if (
FFs[
i][j][k]->getControlSetInfo()->getId() !=
2302 for (
int k = 0; k < 4; k++)
2304 if (
FFs[
i][1 - j][k])
2306 if (
FFs[
i][1 - j][k]->getControlSetInfo())
2308 if (
FFs[
i][1 - j][k]->getControlSetInfo()->getCLK() !=
2320 for (
int k = 0; k < 4; k++)
2326 LUTs[
i][j][k] = targetLUT;
2327 FFs[
i][j][k] = targetFF;
2334 assert(
false &&
"the LUT-FF pair should be assigned to a slot");
2340 for (
int i = 0;
i < 2;
i++)
2342 for (
int j = 0; j < 2; j++)
2344 for (
int k = 0; k < 4; k++)
2346 if (
LUTs[
i][j][k] == targetLUT)
2348 LUTs[
i][j][k] =
nullptr;
2350 if (
FFs[
i][j][k] == targetFF)
2352 FFs[
i][j][k] =
nullptr;
2365 {{
nullptr,
nullptr,
nullptr,
nullptr}, {
nullptr,
nullptr,
nullptr,
nullptr}},
2366 {{
nullptr,
nullptr,
nullptr,
nullptr},
2367 {
nullptr,
nullptr,
nullptr,
nullptr}}};
2369 {{
nullptr,
nullptr,
nullptr,
nullptr}, {
nullptr,
nullptr,
nullptr,
nullptr}},
2370 {{
nullptr,
nullptr,
nullptr,
nullptr},
2371 {
nullptr,
nullptr,
nullptr,
nullptr}}};
2373 {
nullptr,
nullptr}};
2378 const std::string
MuxF7SlotNames[2][2] = {{
"F7MUX_AB",
"F7MUX_CD"}, {
"F7MUX_EF",
"F7MUX_GH"}};
2410 if (FFControlSets[halfCLB].getCSId() < 0 || FFControlSets[anotherHalfCLB].getCSId() < 0)
2414 else if (FFControlSets[anotherHalfCLB].getCLK() == FFControlSets[halfCLB].getCLK() &&
2415 FFControlSets[anotherHalfCLB].getSR() == FFControlSets[halfCLB].getSR() &&
2417 FFControlSets[halfCLB].getFFType()))
2596 if (!tmpFF || !tmpLUT)
2598 if (FF2LUT.find(tmpFF) == FF2LUT.end())
2602 return FF2LUT[tmpFF] == tmpLUT;
2619 if (!tmpFF || !tmpLUT)
2621 if (FF2LUT.find(tmpFF) == FF2LUT.end())
2626 if (FF2LUT[tmpFF] != tmpLUT)
2629 auto srcCell = tmpLUT;
2630 unsigned int srcCellId = srcCell->
getCellId();
2631 auto srcNode = timingNodes[srcCellId];
2633 float slack = (srcNode->getLatestInputArrival() - srcNode->getRequiredArrivalTime()) / clockPeriod + 20;
2644 assert(targetCell->
isLUT());
2645 for (
int i = 0;
i < 2;
i++)
2647 for (
int j = 0; j < 2; j++)
2649 for (
int k = 0; k < 4; k++)
2653 return std::array<int, 3>{
i, j, k};
2658 assert(
false &&
"the LUT should be found in slots.");
2659 return std::array<int, 3>{-1, -1, -1};
2663 assert(targetCell->
isFF());
2664 for (
int i = 0;
i < 2;
i++)
2666 for (
int j = 0; j < 2; j++)
2668 for (
int k = 0; k < 4; k++)
2672 return std::array<int, 3>{
i, j, k};
2677 assert(
false &&
"the FF should be found in slots.");
2678 return std::array<int, 3>{-1, -1, -1};
2742 std::set<PlacementInfo::PlacementUnit *, Packing_PUcompare>
neighborPUs;
2746 std::map<PlacementInfo::PlacementUnit *, int, Packing_PUcompare>
PU2TopCnt;
2820 (*this)[0] = tmpPU->
X();
2821 (*this)[1] = tmpPU->
Y();
2825 (*this)[0] = anotherPULocation[0];
2826 (*this)[1] = anotherPULocation[1];
2827 PU = anotherPULocation.
getPU();
2865 void packCLBs(
int packIterNum,
bool doExceptionHandling,
bool debug =
false);
2895 float targetX,
float targetY,
2896 float displacementLowerbound,
2897 float displacementUpperbound,
float y2xRatio,
2900 std::vector<DeviceInfo::DeviceSite *> *
2902 float displacementLowerbound,
float displacementUpperbound,
float y2xRatio,
2903 bool clockRegionAware,
float v1x,
float v1y,
float v2x,
float v2y,
int numLimit);
2933 std::map<PackingCLBSite *, PackingCLBSite::PackingCLBCluster *> &packingSite2DeterminedCluster,
bool verbose);
2954 void updatePackedMacro(
bool setPUPseudoNetToCLBSite =
false,
bool setCLBFixed =
false);
3034 std::set<PlacementInfo::PlacementUnit *, Packing_PUcompare>
packedPUs;
3035 std::set<PlacementInfo::PlacementUnit *, Packing_PUcompare>
unpackedPUs;
void dumpCLBPlacementTcl(std::ofstream &outfileTcl, bool packingRelatedToLUT6_2)
std::ostream & operator<<(std::ostream &os, const ParallelCLBPacker::PackingCLBSite::PackingCLBCluster *tmpCluster)
float getY2xRatio() const
bool clockRegionAware
whether make clock region become constraints
Placement net, compared to design net, includes information related to placement.
bool addFFGroup(std::vector< DesignInfo::DesignCell * > curFFs, int enforceHalfCLB, bool enforceMainFFSlot, bool isMuxMacro)
try to add a given list of FFs into this cluster
bool checkNumMuxCompatibleInFFSet(int i, int addNum)
check whether a specific number of Muxes can be compatible with a specific FFset for packing
void setNonCLBCell(DesignInfo::DesignCell *_NonCLBCell)
int numNeighbor
the threshold number of cells for site
float y2xRatio
a factor to tune the weights of the net spanning in Y-coordinate relative to the net spanning in X-co...
void exceptionHandling(bool verbose=false)
handle the PlacementUnits that cannot be packed during the parallel procedure
float getTotalCellWeight() const
Get the total weights of cells in the cluster (each cell will have different weight in the placement)
void removeClustersIncompatibleWithDetClusterFromPQ()
remove clusters incompatible with determined cluster from PQ
std::set< DesignInfo::DesignCell * > & cellInMacros
float totalConnectivityScore
the connectivity score for this cluster
bool containFF(DesignInfo::DesignCell *curFF)
check whether the cluster contains a specific FF cell
DesignInfo::DesignNet * CLK
PlacementInfo::PlacementUnit * getPU() const
bool addFF(DesignInfo::DesignCell *curFF, int enforceHalfCLB=-1, bool enforceMainFFSlot=false)
try to add a given FF into this cluster
float getHPWLChange() const
Get the HWPL change term in the cluster score object.
PlacementInfo::PlacementMacro * LUTRAMMacro
const std::vector< PackingCLBSite * > & PUId2PackingCLBSite
ParallelCLBPacker(DesignInfo *designInfo, DeviceInfo *deviceInfo, PlacementInfo *placementInfo, std::map< std::string, std::string > &JSONCfg, int unchangedIterationThr, int numNeighbor, float deltaD, float curD, float maxD, int PQSize, float HPWLWeight, std::string packerName, PlacementTimingOptimizer *timingOptimizer, WirelengthOptimizer *WLOptimizer=nullptr)
Construct a new Parallel CLB Packer object.
void printMyself()
a API to print the information of cluster
bool contains(PlacementInfo::PlacementUnit *tmpPU)
check whether the cluster contains a specific PlacementUnit
DesignInfo::DesignCell * MuxF7[2][2]
std::vector< std::vector< PackingCLBSite * > > clockColumns2PackingSites
void recoverFFControlSets()
void dumpPlacementTcl(std::string dumpTclFile)
void updateStep(bool initial, bool debug=false)
a iteration to pack PlacementUnit into a CLB site
void addPUFailReason(PlacementInfo::PlacementUnit *tmpPU)
find/print the reason why the PlacementUnit fails to be added into this cluster
bool compatibleInOneHalfCLB(int halfCLB, int anotherHalfCLB)
check whether two half CLB can be packed togather
DesignInfo::DesignCell * FFs[2][2][4]
std::set< DesignInfo::DesignCell * > conflictLUTs
void dumpAllCellsCoordinate()
int id
the unique id for each cluster
PackedControlSet(const PackedControlSet &anotherControlSet)
Construct a new Packed Control Set object by cloning another one.
bool tryRemoveSingleLUTFromPairs(DesignInfo::DesignCell *tmpLUT)
try to remove a LUT from the set of paired LUTs
void refreshId()
refresh the Id of the PackingCLBCluster so we can know it is changed.
This header file contains the definitions of GlobalPlacer class and its internal modules and APIs whi...
bool exceptionPULegalize(PlacementInfo::PlacementUnit *curPU, float displacementThreshold, bool verbose)
try to find a legal location for the given PlacementUnit when most of PlacementUnits are packed into ...
WirelengthOptimizer * WLOptimizer
bool compatibleInOneHalfCLB(DesignInfo::ControlSetInfo *CSPtr, int anotherHalfCLB)
check whether a control set can be placed in a given half CLB
std::set< DesignInfo::DesignCell * > mappedCells
std::set< DesignInfo::DesignCell * > fixedLUTsInPairs
a fixed group of multiple standard cells with constraints of their relative locations
int unchangedIterationThr
specify how many iterations a PlacementUnit should stay at the top priority of a site before we final...
SiteBELMapping slotMapping
int totalNetNum
the cell number term in the cluster score
int timingDrivenDetailedPlacement_swap(int iterId)
a DesignCell in design netlist, DesignPin objects of which might connect to DesignNet objects
bool checkClockColumnLegalization(PlacementInfo::PlacementUnit *curPU, DeviceInfo::DeviceSite *curSite)
check whether the given PlacementUnit can be mapped to the site considering the half-column clock leg...
const PackingCLBCluster * getPriorityQueueTop()
std::vector< PackingCLBSite * > PUId2PackingCLBSiteCandidate
bool tryRemoveSingleLUT(DesignInfo::DesignCell *tmpLUT)
try to remove a single LUT from the single LUT set
a design net (hyperedge) defined in the design, connecting to pins of cells
const unsigned int MaxNum_LUTSite
const int HiFPlacer_hashprimes[300]
const std::set< DesignInfo::DesignCell * > & getSingleLUTs() const
Get the set of single LUTs in this cluster (some other LUTs have been paired for packing)
PlacementInfo * placementInfo
the paraent CLB site for this cluster
int getInternalPinsNum(PlacementInfo::PlacementNet *curNet)
Get the number of pins within this site for a given net (more pins are located in ont site will reduc...
float getPlacementUnitMaxPathNegativeSlack(PlacementInfo::PlacementUnit *curPU)
Get the max length of paths involving a given PlacementUnit.
void addNonCLBPackingSites()
bool ripUpAndLegalizae(PackingCLBSite *curTargetPackingSite, PlacementInfo::PlacementUnit *curPU, float displacementThreshold, std::map< PackingCLBSite *, PackingCLBSite::PackingCLBCluster * > &packingSite2DeterminedCluster, bool verbose)
try to rip up the packing for a given CLB site and pack the given PlacementUnit in the site....
@ PlacementMacroType_LCLB
std::array< int, 3 > getLUTSlot(DesignInfo::DesignCell *targetCell)
float checkDirectLUTFFConnect_slack(std::map< DesignInfo::DesignCell *, DesignInfo::DesignCell * > &FF2LUT, DesignInfo::DesignCell *tmpLUT, DesignInfo::DesignCell *tmpFF)
check whether the FF/LUT are directly connected and calculate the slack
std::set< PlacementInfo::PlacementUnit *, Packing_PUcompare > packedPUs
std::vector< PlacementNet * > * getNetsSetPtr()
Get the Nets Set Ptr object which records the nets connecting to the PlacementUnit.
void dumpDSPBRAMPlacementTcl(std::ofstream &outfileTcl)
float maxD
the maximum constraint of the neighbor search diameter
void finalMapToSlotsForCommonLUTFFInSite()
finally map LUTs/FFs to the exact slots in the sites
@ PlacementMacroType_CARRY
float HPWLChange
the HPWL term for the wirelength optimization
float getScoreInSite() const
Get the score if this cluster is mapped the site.
DesignInfo::DesignNet * getCE() const
void setDeterminedClusterInSite(PackingCLBCluster *tmpCluster)
DesignInfo::DesignCell * MuxF8[2]
PackingCLBSite(PlacementInfo *placementInfo, DeviceInfo::DeviceSite *CLBSite, int unchangedIterationThr, int numNeighbor, float deltaD, float curD, float maxD, unsigned int PQSize, float y2xRatio, float HPWLWeight, std::vector< PackingCLBSite * > &PUId2PackingCLBSite)
Construct a new Packing CLB Site object.
DesignInfo::DesignCell * getCarryCell()
PULocation & operator=(const PULocation &anotherPULocation)
DesignCellType
design cell types
std::vector< PlacementInfo::PlacementUnit * > & placementUnits
void prePackLegalizedMacros(PlacementInfo::PlacementMacro *tmpMacro)
Load the information of some packed macros like LUTRAM/Crossing-Clock-Domain FFs/Carry Chains have be...
bool operator()(PlacementInfo::PlacementUnit *lhs, PlacementInfo::PlacementUnit *rhs) const
void finalMapToSlots()
finally map the elements (CARRY/MUX/LUT/FF) packed in this site into the slots in the site
PlacementInfo * placementInfo
float getHPWLChangeForPU(PlacementInfo::PlacementUnit *tmpPU)
float getClockPeriod()
Get the clock period.
@ PlacementMacroType_MUX8
void finalMapToSlotsForCarrySite()
find the slots in the site for Carry by enumeration
float deltaD
the increase step of the neighbor search diameter
std::set< DesignInfo::DesignCell * > mappedFFs
void removePUToConstructDetCluster(PlacementInfo::PlacementUnit *tmpPU)
remove some PlacementInfo::PlacementUnit from the cluster for later determined cluster construction o...
void reset()
clear the control set information in this PackedControlSet (only when there is no FF in this set)
void clusterHash()
we use a hash function to encode the cluster to easily check duplicated clusters in the candidates
PackedControlSet stores the data of a combination of FFs within one control set (clock enable/preset-...
std::set< std::pair< DesignInfo::DesignCell *, DesignInfo::DesignCell * > > pairedLUTs
the paired LUTs in the cluster
int getTotalNetNum() const
Get the total number of cells in this cluster.
std::map< DeviceInfo::DeviceSite *, PackingCLBSite * > deviceSite2PackingSite
const std::vector< DesignInfo::DesignCell * > & getFFs() const
get the FFs in this PackedControlSet
static bool FFSRCompatible(DesignCellType typeA, DesignCellType typeB)
bool operator()(PlacementInfo::PlacementNet *lhs, PlacementInfo::PlacementNet *rhs) const
std::vector< DeviceInfo::DeviceSite * > * findNeiborSitesFromBinGrid(DesignInfo::DesignCellType curCellType, float targetX, float targetY, float displacementLowerbound, float displacementUpperbound, float y2xRatio, bool clockRegionAware)
find the neighbors of specific cell type with given coordinate center
int PQSize
the size of priority queue (the low-priority candidates will be removed)
This header file contains the classes of data for a standalone design netlist.
unsigned int numNeighbor
the threshold number of cells for site
DesignInfo::DesignCell * Carry
DesignInfo::DesignCell * LUTs[2][2][4]
void addCarry()
add CARRY-related PlacementUnit into this CLB site
int getPlacementUnitMaxPathLen(PlacementInfo::PlacementUnit *curPU)
Get the max length of paths involving a given PlacementUnit.
PlacementInfo * getPlacementInfo() const
SiteBELMapping is a contain recording the mapping between cells and BELs.
DesignInfo::DesignNet * getCLK() const
PackingCLBCluster * getDeterminedClusterInSite()
std::map< int, PlacementInfo::PlacementUnit * > & cellId2PlacementUnit
This header file contains the classes of data for a standalone device.
PackingCLBCluster(PackingCLBCluster *anotherPackingCLBCluster)
@ PlacementMacroType_MUX7
std::set< PlacementInfo::PlacementUnit *, Packing_PUcompare > PUs
PlacementInfo * placementInfo
bool conflictLUTsContain(DesignInfo::DesignCell *tmpCell)
check whether a given cell is unpackable
int getHashConst() const
Get the hash code of this cluster without changing the class variables of this cluster.
int hashId
a hash id to record the elements in this cluster
_PUWithScore(PlacementInfo::PlacementUnit *PU, float score)
DesignCellType getOriCellType()
Get the Original Cell Type object defined in the design netlist.
float getActualOccupationByCellId(int id)
Get the Actual Occupation By Cell Id.
void updateScoreInSite()
update the score of this cluster by considering HPWL, interconnection density, timing and etc
float deltaD
the increase step of the neighbor search diameter
void findNewClustersWithNeighborPUs()
extend the clusters in the priority queue with the neighbor PlacementUnits
struct ParallelCLBPacker::_siteWithScore siteWithScore
helper struct for candidate site sorting
std::vector< DesignInfo::DesignCell * > FFs
bool checkCellCorrectness(PlacementInfo::PlacementUnit *tmpPU, bool isAddPU)
a verification function to check whether the cells in this cluster are REALLY LEGAL.
DesignInfo::DesignNet * getCE() const
DesignInfo::DesignCell * getNonCLBCell()
const std::vector< PackedControlSet > & getFFControlSets() const
a utility struct for the comparison between PlacementInfo::PlacementUnit according to PU ID
bool isMuxMacro(DesignInfo::DesignCell *cell)
std::vector< PackedControlSet > FFControlSets
the control set information for this cluster
int findFF(DesignInfo::DesignCell *curFF) const
find the index in the list for a given FF cell pointer
void setPUsToBePacked()
set the packed attribute for the packed PlacementUnits
A control set is a combination of CLK, CE and SR signal. It could be nullptr (not related to control ...
struct ParallelCLBPacker::_PUWithScore PUWithScore
helper struct for candidate site sorting
int getId() const
Get the Id of the PackingCLBCluster (just for debug information don't use it in algorithm)
Site class for site on device.
int totalLen
the term of timing (paths) in the packing score
DesignInfo::DesignNet * getSR() const
void greedyMapMuxForCommonLUTFFInSite()
find the slots in the site for Muxes by enumeration
PackedControlSet & operator=(const PackedControlSet &anotherControlSet)
undate a new Packed Control Set object by cloning another one
int unchangedIterationThr
specify how many iterations a PlacementUnit should stay at the top priority of a site before we final...
unsigned int getPairPinNum(DesignInfo::DesignCell *LUTA, DesignInfo::DesignCell *LUTB)
check how many input pins will be needed if the two LUTs are packed.
std::vector< PackingCLBCluster * > seedClusters
void addFF(DesignInfo::DesignCell *curFF)
add a FF into this PackedControlSet and check the compatibility
void removeLUTFFPair(DesignInfo::DesignCell *targetLUT, DesignInfo::DesignCell *targetFF)
void removeFF(DesignInfo::DesignCell *curFF)
remove a specific FF from this candidate cluster
PlacementInfo::PlacementMacro * CARRYChain
std::set< DesignInfo::DesignCell * > getCellSet()
std::set< DesignInfo::DesignCell * > best_mappedFFs
void removeSingleLUT(DesignInfo::DesignCell *tmpLUT)
remove a single LUT from the set of single LUTs in this cluster
unsigned int getSize() const
Get the the number of FFs in this control set.
bool addLUT(DesignInfo::DesignCell *curLUT)
try to add a given LUT into this cluster
std::set< DesignInfo::DesignCell * > singleLUTs
the set of LUTs have not been paired with other LUTs in the clutser
bool clockRegionAware
whether make clock region become constraints
std::set< PlacementInfo::PlacementUnit *, Packing_PUcompare > & getNeighborPUs()
float HPWLWeight
the factor of HPWL overhead in packing evaluation for a cell
void removeLUT(DesignInfo::DesignCell *curLUT)
remove a specific LUT from this candidate cluster
PackingCLBCluster * determinedClusterInSite
int getCSId() const
get the control set id of this PackedControlSet.
PackingCLBCluster is a container of cells/PlacementUnits which can be packed in the corresponding CLB...
float HPWLWeight
the factor of HPWL overhead in packing evaluation for a cell
void checkPackedPUsAndUnpackedPUs()
check the packing status for all the PlacementUnits
DeviceInfo::DeviceSite * CLBSite
bool addPU(PlacementInfo::PlacementUnit *tmpPU, bool allowOverlap=false)
try to add a given PlacementUnit into this cluster
bool isCarryMacro(DesignInfo::DesignCell *cell)
helper struct for candidate site sorting
std::set< DesignInfo::DesignCell * > mappedLUTs
int timingDrivenDetailedPlacement_shortestPath_intermediate()
int getHash()
Get the hash code for this cluster.
const std::set< PlacementInfo::PlacementUnit *, Packing_PUcompare > & getPUs() const
std::vector< PlacementInfo::PlacementUnit * > unpackedPUsVec
a movement unit in placement with information of location and resource demand
PackingCLBSite * getParentPackingCLB() const
Get the Parent Packing CLB site of this cluster (this can be used to get more device information)
int getTotalLen() const
Get the maximum length of the paths which involve this cluster.
std::vector< PackingCLBSite * > cellId2PackingSite
void setCSId(int _CSId)
set the control set id of this PackedControlSet.
void packCLBs(int packIterNum, bool doExceptionHandling, bool debug=false)
packing the PlacementUnits (which are compatible to CLB sites) into CLB sites
int getCellId()
Get the Cell Id in the cell list.
PackingCLBCluster(PackingCLBSite *parentPackingCLB)
void updatePackedMacro(bool setPUPseudoNetToCLBSite=false, bool setCLBFixed=false)
Update the macros in PlacementInfo by regarding those elements in one CLB site as a macro.
PackingCLBSite * parentPackingCLB
the paraent CLB site for this cluster
std::string & getSiteType()
const unsigned int MaxNum_ControlSet
float curD
current neighbor search diameter
ControlSetInfo * getControlSetInfo()
Get the Control Set Info object of this cell.
PlacementInfo::PlacementMacro * getLUTRAMMacro()
bool tryRemoveLUTPairFromPairs(DesignInfo::DesignCell *tmpLUTA, DesignInfo::DesignCell *tmpLUTB)
try to remove a pair of LUTs from the set of paired LUTs
DesignInfo::DesignCellType FFType
bool checkIsPrePackedSite()
PlacementTimingInfo * getTimingInfo()
int timingDrivenDetailedPlacement_shortestPath(int iterId, float displacementRatio)
bool addToFFSet(DesignInfo::DesignCell *curFF, int halfCLB)
try to add a given FF into a specific half CLB in this cluster
void evictFFsFromMuxHalfCLB()
try to move FFs in Mux slot to other controlSet
void addLUTFFPair(DesignInfo::DesignCell *targetLUT, DesignInfo::DesignCell *targetFF)
PULocation(PlacementInfo::PlacementUnit *tmpPU)
bool isPQTopCompletelyAccptedByCells()
check whether all the PlacementUnit in the top cluster in the priority queue have been assigned to th...
void removeInvalidClustersFromPQ()
remove invalid clusters from the priority queue
std::set< std::pair< DesignInfo::DesignCell *, DesignInfo::DesignCell * > > & getFixedPairedLUTs()
Get the fixed pairs of LUTs which should NOT be broken.
std::map< std::string, std::string > & JSONCfg
PlacementInfo::PlacementUnit * PU
void mapLUTRAMRelatedCellsToSlots(PlacementInfo::PlacementMacro *_LUTRAMMacro)
DeviceInfo::DeviceSite * getCLBSite()
void addLUTRAMMacro()
add LUTRAM-related PlacementUnit into this CLB site
std::vector< DesignInfo::DesignCell * > getSortedSingleLUTs()
Get the sorted list of single LUTs in this cluster (some other LUTs have been paired for packing)
std::set< PlacementInfo::PlacementUnit *, Packing_PUcompare > * findNeiborPUsFromBinGrid(DesignInfo::DesignCellType curCellType, float targetX, float targetY, float displacementLowerbound, float displacementUpperbound, int PUNumThreshold, const std::vector< PackingCLBSite * > &PUId2PackingCLBSite, float y2xRatio, std::set< PlacementInfo::PlacementUnit *, Packing_PUcompare > *res=nullptr, bool clockRegionAware=true)
find neighbor PlacementUnit around targetX/Y from the bin grid
DesignInfo::DesignNet * getSR() const
float HPWLWeight
the configurable weight for the wirelength in the cluster score
DesignInfo::DesignNet * SR
std::set< PlacementInfo::PlacementUnit *, Packing_PUcompare > unpackedPUs
const SiteBELMapping & getSlotMapping() const
Get the slot(BEL) mapping of the cells.
float getHPWLChangeForPU(PlacementInfo::PlacementUnit *tmpPU)
get the HPWL change if a given PlacementUnit is moved to this site
std::vector< TimingGraph< DesignInfo::DesignCell >::TimingNode * > & getSimplePlacementTimingInfo()
Get the Simple Timing Info object which regard design cells as timing nodes.
std::set< PlacementInfo::PlacementUnit *, Packing_PUcompare > neighborPUs
Information class related to FPGA device, including the details of BEL/Site/Tile/ClockRegion.
std::vector< std::pair< DesignInfo::DesignCell *, DesignInfo::DesignCell * > > getSortedPairedLUTs()
Get the sorted list of the paired LUTs.
SiteBELMapping best_SlotMapping
void incrementalUpdateScoreInSite(PlacementInfo::PlacementUnit *tmpPU)
incrementally update the score of this cluster by considering that only a given PlacementUnit will be...
void mapMuxF7Macro(int halfCLBOffset, PlacementInfo::PlacementMacro *MUXF7Macro)
map cells in MUXF7 macro to CLB slot
std::set< DesignInfo::DesignCell * > best_mappedCells
void setClockRegionAwareTo(bool _clockRegionAware)
the smallest, indivisible, representable component. It will include only one standard cell
std::map< PackingCLBSite *, PlacementInfo::PlacementUnit * > involvedPackingSite2PU
const unsigned int MaxNum_FFinControlSet
std::vector< PULocation > PUPoints
std::set< std::pair< DesignInfo::DesignCell *, DesignInfo::DesignCell * > > fixedPairedLUTs
int getId()
Get the Id of the net in current placement procedure.
bool compatibleWith(int inputCSId) const
check whether this PackedControlSet can be compatible with a given control set ID
void mapCarryRelatedCellsToSlots(PlacementInfo::PlacementMacro *_CARRYChain, float siteOffset)
bool isPUTypeCompatibleWithSiteType(PlacementInfo::PlacementUnit *tmpPU)
check whether the type of the given PlacementUnit is compatible with the site type
bool isMuxMacro(DesignInfo::DesignCell *cell)
int clusterHashWithAdditionalPU(PlacementInfo::PlacementUnit *tmpPU)
incrementally update the hash function with an additional PlacementUnit. This hash will be used to en...
std::vector< DesignInfo::DesignCell * > & getCells()
float maxD
the maximum constraint of the neighbor search diameter
DesignInfo::DesignCell * nonCLBCell
bool areAllPUsValidForThisSite(const std::vector< PackingCLBSite * > &PUId2PackingCLBSite, PackingCLBSite *parentPackingCLBSite)
check whether all the PlacementUnit in this cluster are valid (not bound to other sites) for this sit...
SiteBELMapping & operator=(const SiteBELMapping &anotherMapping)
ParallelCLBPacker will finally pack LUT/FF/MUX/CARRY elements into legal CLB sites in a parallel appr...
const int getId() const
Get the Id of the control set (each control set will have a unique Id)
bool isCarryMacro(DesignInfo::DesignCell *cell)
bool tryAddPU(PlacementInfo::PlacementUnit *tmpPU)
without modifying the original cluster container, try to add a given PlacementUnit into this cluster
PackingCLBCluster()
Construct a new Packing CLB Cluster object (it should not be called.)
std::vector< PackedControlSet > FFControlSets_backup
bool evictFFsFromCarryHalfCLB(unsigned int FFSetId)
try to move FFs in Mux slot to other controlSet
DesignInfo::DesignCell * carryCell
float getTotalConnectivityScore() const
Get the connectivity term in the cluster score object.
PlacementUnit * getPlacementUnitByCell(DesignInfo::DesignCell *curCell)
float scoreInSite
the evaluation score of packing for this cluster
float curD
current neighbor search diameter
std::vector< PlacementInfo::PlacementUnpackedCell * > & placementUnpackedCells
unsigned int getPairPinNum(DesignInfo::DesignCell *LUTA, DesignInfo::DesignCell *LUTB)
check how many input pins will be needed if the two LUTs are packed.
void moveFFFromCS1ToCS0(DesignInfo::DesignCell *targetFF, int CSGroupId1, int CSGroupId0)
_siteWithScore(PackingCLBSite *site, float score)
void removeInvalidPUsFromNeighborPUs()
remove invalid clusters from neighbor PlacementUnits
int getTotalCellNum() const
Get the total number of cells in this cluster.
void packCLBsIteration(bool initial, bool debug=false)
update the packing cluster candidates for each CLB site and determine some mapping from elements to s...
void mapMuxF8Macro(int muxF8Offset, PlacementInfo::PlacementMacro *MUXF8Macro)
map cells in MUXF8 macro to CLB slot
This header file mainly contains the definition of class PlacementInfo, including information related...
std::vector< DesignPin * > & getInputPins()
int findMuxFromHalfCLB(PlacementInfo::PlacementMacro *MUXF8Macro)
find the correspdnding FF control set id for a given Mux macro (this mux macro should have been mappe...
void setPULocationToPackedSite()
update the location of PlacementUnits according to the packing result
std::vector< PackingCLBSite * > packingSites
void refreshPrioryQueue()
sort the elements in the priority queue
const std::string MuxF8SlotNames[2]
void updateConsistentPUsInTop()
update the information of consistent PUs at the top of priority queue
std::vector< PlacementInfo::PlacementMacro * > & placementMacros
PULocation is a helper class to find the neighbor PlacementUnits with KD-Tree.
std::vector< PackingCLBCluster * > priorityQueue
bool checkAddPU(PlacementInfo::PlacementUnit *tmpPU)
std::vector< PackingCLBSite * > PUId2PackingCLBSite
int timingDrivenDetailedPlacement_LUTFFPairReloacationAfterSlotMapping()
PlacementTimingOptimizer * timingOptimizer
void removeXthFF(int i)
remove a specify i-th FF from this PackedControlSet
bool canDirectConnectInSlot(DesignInfo::DesignCell *targetLUT, DesignInfo::DesignCell *targetFF) const
Information related to FPGA designs, including design cells and their interconnections.
helper struct for candidate site sorting
void maxCardinalityMatching(bool verbose=false)
conduct maximun cardinality matching algorithm to pair LUTs
const std::string MuxF7SlotNames[2][2]
const std::set< std::pair< DesignInfo::DesignCell *, DesignInfo::DesignCell * > > & getPairedLUTs() const
Get the set of the paired LUTs.
PackingCLBSite is a container for the packing information (parameters, candidates and packing status)...
WirelengthOptimizer builds numerical models based on the element locations and calls solvers to find ...
unsigned int PQSize
the size of priority queue (the low-priority candidates will be removed)
DesignInfo::DesignNet * CE
SiteBELMapping & getSlotMappingRef()
int checkDirectLUTFFConnect(std::map< DesignInfo::DesignCell *, DesignInfo::DesignCell * > &FF2LUT, DesignInfo::DesignCell *tmpLUT, DesignInfo::DesignCell *tmpFF)
check whether the FF/LUT are directly connected
PlacementInfo::PlacementMacro * getCarryMacro()
DesignInfo::DesignCellType getFFType() const
PlacementInfo::PlacementUnit * PU
std::set< DesignInfo::DesignCell * > & getConflictLUTs()
Get the LUTs which CANNOT be paired.
Information related to FPGA placement (wirelength optimization, cell spreading, legalization,...
TimingGraph< DesignInfo::DesignCell > * getSimplePlacementTimingGraph()
Get the Simple Placement Timing Graph object.
int getNumMuxes() const
Get the total number of MUX cells in this cluster.
std::array< int, 3 > getFFSlot(DesignInfo::DesignCell *targetCell)
DesignInfo::DesignNet * getCLK() const
std::map< PlacementInfo::PlacementUnit *, int, Packing_PUcompare > PU2TopCnt
std::set< DesignInfo::DesignCell * > best_mappedLUTs