diff options
author | gatecat <gatecat@ds0.me> | 2022-06-23 18:48:31 +0100 |
---|---|---|
committer | gatecat <gatecat@ds0.me> | 2022-07-08 14:30:57 +0200 |
commit | 09e388f453d9cf998391495349c88e5478b62e34 (patch) | |
tree | 004f2b14ed5a3b0584c4998d9f0a5598cc52ab28 /common/place/placer_heap.cc | |
parent | 86396c41d64d2583ec1dffca4298e83d927f0762 (diff) | |
download | nextpnr-09e388f453d9cf998391495349c88e5478b62e34.tar.gz nextpnr-09e388f453d9cf998391495349c88e5478b62e34.tar.bz2 nextpnr-09e388f453d9cf998391495349c88e5478b62e34.zip |
netlist: Add PseudoCell API
When implementing concepts such as partition pins or deliberately split
nets, there's a need for something that looks like a cell (starts/ends
routing with pins on nets, has timing data) but isn't mapped to a fixed
bel in the architecture, but instead can have pin mappings defined at
runtime.
The PseudoCell allows this by providing an alternate, virtual-function
based API for such cells. When a cell has `pseudo_cell` used, instead of
calling functions such as getBelPinWire, getBelLocation or getCellDelay
in the Arch API; such data is provided by the cell itself, fully
flexible at runtime regardless of arch, via methods on the PseudoCell
implementation.
Diffstat (limited to 'common/place/placer_heap.cc')
-rw-r--r-- | common/place/placer_heap.cc | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/common/place/placer_heap.cc b/common/place/placer_heap.cc index 4c9ffb23..bd8cd37d 100644 --- a/common/place/placer_heap.cc +++ b/common/place/placer_heap.cc @@ -147,7 +147,7 @@ class HeAPPlacer tmg.setup(); for (auto &cell : ctx->cells) - if (cell.second->cluster != ClusterId()) + if (!cell.second->isPseudo() && cell.second->cluster != ClusterId()) cluster2cells[cell.second->cluster].push_back(cell.second.get()); } @@ -284,6 +284,8 @@ class HeAPPlacer // Save solution solution.clear(); for (auto &cell : ctx->cells) { + if (cell.second->isPseudo()) + continue; solution.emplace_back(cell.second.get(), cell.second->bel, cell.second->belStrength); } } else { @@ -312,6 +314,8 @@ class HeAPPlacer } for (auto &cell : ctx->cells) { + if (cell.second->isPseudo()) + continue; if (cell.second->bel == BelId()) log_error("Found unbound cell %s\n", cell.first.c_str(ctx)); if (ctx->getBoundBelCell(cell.second->bel) != cell.second.get()) @@ -411,7 +415,8 @@ class HeAPPlacer // Initial constraints placer for (auto &cell_entry : ctx->cells) { CellInfo *cell = cell_entry.second.get(); - + if (cell->isPseudo()) + continue; auto loc = cell->attrs.find(ctx->id("BEL")); if (loc != cell->attrs.end()) { std::string loc_name = loc->second.as_string(); @@ -461,6 +466,8 @@ class HeAPPlacer pool<IdString> cell_types_in_use; pool<BelBucketId> buckets_in_use; for (auto &cell : ctx->cells) { + if (cell.second->isPseudo()) + continue; IdString cell_type = cell.second->type; cell_types_in_use.insert(cell_type); BelBucketId bucket = ctx->getBelBucketForCellType(cell_type); @@ -527,6 +534,8 @@ class HeAPPlacer { pool<IdString> cell_types; for (const auto &cell : ctx->cells) { + if (cell.second->isPseudo()) + continue; cell_types.insert(cell.second->type); } @@ -551,6 +560,14 @@ class HeAPPlacer for (auto &cell : ctx->cells) { CellInfo *ci = cell.second.get(); + if (ci->isPseudo()) { + Loc loc = ci->pseudo_cell->getLocation(); + cell_locs[cell.first].x = loc.x; + cell_locs[cell.first].y = loc.y; + cell_locs[cell.first].locked = true; + cell_locs[cell.first].global = false; + continue; + } if (ci->bel != BelId()) { Loc loc = ctx->getBelLocation(ci->bel); cell_locs[cell.first].x = loc.x; @@ -627,8 +644,9 @@ class HeAPPlacer int row = 0; solve_cells.clear(); // First clear the udata of all cells - for (auto &cell : ctx->cells) + for (auto &cell : ctx->cells) { cell.second->udata = dont_solve; + } // Then update cells to be placed, which excludes cell children for (auto cell : place_cells) { if (buckets && !buckets->count(ctx->getBelBucketForCellType(cell->type))) |