diff options
Diffstat (limited to 'common/place_common.h')
-rw-r--r-- | common/place_common.h | 81 |
1 files changed, 5 insertions, 76 deletions
diff --git a/common/place_common.h b/common/place_common.h index dac2e607..67956072 100644 --- a/common/place_common.h +++ b/common/place_common.h @@ -22,92 +22,21 @@ #include "nextpnr.h" -#include <set> - NEXTPNR_NAMESPACE_BEGIN typedef int64_t wirelen_t; -// Get the total estimated wirelength for a net -template <typename T> wirelen_t get_net_wirelength(const T &proxy, const Context *ctx, const NetInfo *net, float &tns) -{ - wirelen_t wirelength = 0; - int driver_x, driver_y; - bool driver_gb; - CellInfo *driver_cell = net->driver.cell; - if (!driver_cell) - return 0; - if (driver_cell->bel == BelId()) - return 0; - ctx->estimatePosition(driver_cell->bel, driver_x, driver_y, driver_gb); - WireId drv_wire = proxy.getWireBelPin(driver_cell->bel, ctx->portPinFromId(net->driver.port)); - if (driver_gb) - return 0; - float worst_slack = 1000; - int xmin = driver_x, xmax = driver_x, ymin = driver_y, ymax = driver_y; - for (auto load : net->users) { - if (load.cell == nullptr) - continue; - CellInfo *load_cell = load.cell; - if (load_cell->bel == BelId()) - continue; - if (ctx->timing_driven) { - WireId user_wire = proxy.getWireBelPin(load_cell->bel, ctx->portPinFromId(load.port)); - delay_t raw_wl = ctx->estimateDelay(drv_wire, user_wire); - float slack = ctx->getDelayNS(load.budget) - ctx->getDelayNS(raw_wl); - if (slack < 0) - tns += slack; - worst_slack = std::min(slack, worst_slack); - } - - int load_x, load_y; - bool load_gb; - ctx->estimatePosition(load_cell->bel, load_x, load_y, load_gb); - if (load_gb) - continue; - xmin = std::min(xmin, load_x); - ymin = std::min(ymin, load_y); - xmax = std::max(xmax, load_x); - ymax = std::max(ymax, load_y); - } - if (ctx->timing_driven) { - wirelength = wirelen_t((((ymax - ymin) + (xmax - xmin)) * std::min(5.0, (1.0 + std::exp(-worst_slack / 5))))); - } else { - wirelength = wirelen_t((ymax - ymin) + (xmax - xmin)); - } - - return wirelength; -} +// Return the wirelength of a net +wirelen_t get_net_wirelength(const Context *ctx, const NetInfo *net, float &tns); // Return the wirelength of all nets connected to a cell -template <typename T> wirelen_t get_cell_wirelength(const T &proxy, const Context *ctx, const CellInfo *cell) -{ - std::set<IdString> nets; - for (auto p : cell->ports) { - if (p.second.net) - nets.insert(p.second.net->name); - } - wirelen_t wirelength = 0; - float tns = 0; - for (auto n : nets) { - wirelength += get_net_wirelength(proxy, ctx, ctx->nets.at(n).get(), tns); - } - return wirelength; -} +wirelen_t get_cell_wirelength(const Context *ctx, const CellInfo *cell); // Return the wirelength of all nets connected to a cell, when the cell is at a given bel -template <typename T> -wirelen_t get_cell_wirelength_at_bel(const T &proxy, const Context *ctx, CellInfo *cell, BelId bel) -{ - BelId oldBel = cell->bel; - cell->bel = bel; - wirelen_t wirelen = get_cell_wirelength(proxy, ctx, cell); - cell->bel = oldBel; - return wirelen; -} +wirelen_t get_cell_wirelength_at_bel(const Context *ctx, CellInfo *cell, BelId bel); // Place a single cell in the lowest wirelength Bel available, optionally requiring validity check -bool place_single_cell(MutateContext &proxy, Context *ctx, CellInfo *cell, bool require_legality); +bool place_single_cell(Context *ctx, CellInfo *cell, bool require_legality); NEXTPNR_NAMESPACE_END |