diff options
author | David Shah <davey1576@gmail.com> | 2018-06-09 19:38:37 +0200 |
---|---|---|
committer | David Shah <davey1576@gmail.com> | 2018-06-09 19:38:37 +0200 |
commit | 72f5e640af8bdccb641bb561757021c0a3d83edb (patch) | |
tree | 9456f4d6f0ea2e6303200320129d3f2fe57535fd /common | |
parent | e15620ccd4e5062a999f51bc5f3ee53739586561 (diff) | |
download | nextpnr-72f5e640af8bdccb641bb561757021c0a3d83edb.tar.gz nextpnr-72f5e640af8bdccb641bb561757021c0a3d83edb.tar.bz2 nextpnr-72f5e640af8bdccb641bb561757021c0a3d83edb.zip |
Adding basic placement constraints
Specify the attribute (* LOC="bel_name" *) on any cell to constrain its
placement to that bel.
Signed-off-by: David Shah <davey1576@gmail.com>
Diffstat (limited to 'common')
-rw-r--r-- | common/place.cc | 40 | ||||
-rw-r--r-- | common/route.cc | 2 |
2 files changed, 40 insertions, 2 deletions
diff --git a/common/place.cc b/common/place.cc index 42e366c6..8f174478 100644 --- a/common/place.cc +++ b/common/place.cc @@ -38,8 +38,38 @@ void place_design(Design *design) std::set<IdString>::iterator not_found, element; std::set<BelType> used_bels; + // Initial constraints placer for (auto cell_entry : design->cells) { CellInfo *cell = cell_entry.second; + auto loc = cell->attrs.find("LOC"); + if (loc != cell->attrs.end()) { + std::string loc_name = loc->second; + BelId bel = design->chip.getBelByName(IdString(loc_name)); + if (bel == BelId()) { + log_error("No Bel named \'%s\' located for " + "this chip (processing LOC on \'%s\')\n", + loc_name.c_str(), cell->name.c_str()); + } + + BelType bel_type = design->chip.getBelType(bel); + if (bel_type != belTypeFromId(cell->type)) { + log_error("Bel \'%s\' of type \'%s\' does not match cell " + "\'%s\' of type \'%s\'", + loc_name.c_str(), belTypeToId(bel_type).c_str(), + cell->name.c_str(), cell->type.c_str()); + } + + cell->bel = bel; + design->chip.bindBel(bel, cell->name); + } + } + + for (auto cell_entry : design->cells) { + CellInfo *cell = cell_entry.second; + // Ignore already placed cells + if (cell->bel != BelId()) + continue; + BelType bel_type; element = types_used.find(cell->type); @@ -64,17 +94,25 @@ void place_design(Design *design) for (auto cell_entry : design->cells) { CellInfo *cell = cell_entry.second; + // Ignore already placed cells + if (cell->bel != BelId()) + continue; // Only place one type of Bel at a time if (cell->type.compare(bel_type_name) != 0) continue; while ((bi != blist.end()) && - (design->chip.getBelType(*bi) != bel_type)) + ((design->chip.getBelType(*bi) != bel_type || + !design->chip.checkBelAvail(*bi)))) bi++; if (bi == blist.end()) log_error("Too many \'%s\' used in design\n", cell->type.c_str()); cell->bel = *bi++; + design->chip.bindBel(cell->bel, cell->name); + + // Back annotate location + cell->attrs["LOC"] = design->chip.getBelName(cell->bel); } } } diff --git a/common/route.cc b/common/route.cc index 28a51bc6..b57bc29f 100644 --- a/common/route.cc +++ b/common/route.cc @@ -37,7 +37,7 @@ template <> struct greater<QueuedWire> return lhs.delay.avgDelay() > rhs.delay.avgDelay(); } }; -} +} // namespace std void route_design(Design *design) { |