aboutsummaryrefslogtreecommitdiffstats
path: root/common/place/placer_heap.cc
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2022-06-23 18:48:31 +0100
committergatecat <gatecat@ds0.me>2022-07-08 14:30:57 +0200
commit09e388f453d9cf998391495349c88e5478b62e34 (patch)
tree004f2b14ed5a3b0584c4998d9f0a5598cc52ab28 /common/place/placer_heap.cc
parent86396c41d64d2583ec1dffca4298e83d927f0762 (diff)
downloadnextpnr-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.cc24
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)))