aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorSergiusz Bazanski <q3k@q3k.org>2018-07-14 18:52:56 +0100
committerSergiusz Bazanski <q3k@q3k.org>2018-07-14 18:52:56 +0100
commit447ed83638ef35967adae801430f24e92acb6010 (patch)
treef52c89571a97363052c1655137c0392e7588e6a4 /common
parent09ca9ea39edbb33bfb23119786a3fa2792785e87 (diff)
downloadnextpnr-447ed83638ef35967adae801430f24e92acb6010.tar.gz
nextpnr-447ed83638ef35967adae801430f24e92acb6010.tar.bz2
nextpnr-447ed83638ef35967adae801430f24e92acb6010.zip
Revert "Introduce proxies for locked access to ctx"
This reverts commit 89809a8b810dd57f50f365d70a0ce547705f8dbb.
Diffstat (limited to 'common')
-rw-r--r--common/place_common.cc95
-rw-r--r--common/place_common.h83
-rw-r--r--common/placer1.cc181
-rw-r--r--common/router1.cc108
4 files changed, 220 insertions, 247 deletions
diff --git a/common/place_common.cc b/common/place_common.cc
index 48416370..281e40a2 100644
--- a/common/place_common.cc
+++ b/common/place_common.cc
@@ -2,7 +2,6 @@
* nextpnr -- Next Generation Place and Route
*
* Copyright (C) 2018 David Shah <david@symbioticeda.com>
- * Copyright (C) 2018 Serge Bazanski <q3k@symbioticeda.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -25,8 +24,84 @@
NEXTPNR_NAMESPACE_BEGIN
+// Get the total estimated wirelength for a net
+wirelen_t get_net_wirelength(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 = ctx->getWireBelPinUnlocked(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 = ctx->getWireBelPinUnlocked(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;
+}
+
+// Get the total wirelength for a cell
+wirelen_t get_cell_wirelength(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(ctx, ctx->nets.at(n).get(), tns);
+ }
+ return wirelength;
+}
+
+wirelen_t get_cell_wirelength_at_bel(const Context *ctx, CellInfo *cell, BelId bel)
+{
+ BelId oldBel = cell->bel;
+ cell->bel = bel;
+ wirelen_t wirelen = get_cell_wirelength(ctx, cell);
+ cell->bel = oldBel;
+ return wirelen;
+}
+
// Placing a single cell
-bool place_single_cell(ArchRWProxy &proxy, Context *ctx, CellInfo *cell, bool require_legality)
+bool place_single_cell(Context *ctx, CellInfo *cell, bool require_legality)
{
bool all_placed = false;
int iters = 25;
@@ -37,13 +112,13 @@ bool place_single_cell(ArchRWProxy &proxy, Context *ctx, CellInfo *cell, bool re
CellInfo *ripup_target = nullptr;
BelId ripup_bel = BelId();
if (cell->bel != BelId()) {
- proxy.unbindBel(cell->bel);
+ ctx->unbindBelUnlocked(cell->bel);
}
BelType targetType = ctx->belTypeFromId(cell->type);
for (auto bel : ctx->getBels()) {
- if (ctx->getBelType(bel) == targetType && (!require_legality || proxy.isValidBelForCell(cell, bel))) {
- if (proxy.checkBelAvail(bel)) {
- wirelen_t wirelen = get_cell_wirelength_at_bel(proxy, ctx, cell, bel);
+ if (ctx->getBelType(bel) == targetType && (!require_legality || ctx->isValidBelForCell(cell, bel))) {
+ if (ctx->checkBelAvailUnlocked(bel)) {
+ wirelen_t wirelen = get_cell_wirelength_at_bel(ctx, cell, bel);
if (iters >= 4)
wirelen += ctx->rng(25);
if (wirelen <= best_wirelen) {
@@ -51,11 +126,11 @@ bool place_single_cell(ArchRWProxy &proxy, Context *ctx, CellInfo *cell, bool re
best_bel = bel;
}
} else {
- wirelen_t wirelen = get_cell_wirelength_at_bel(proxy, ctx, cell, bel);
+ wirelen_t wirelen = get_cell_wirelength_at_bel(ctx, cell, bel);
if (iters >= 4)
wirelen += ctx->rng(25);
if (wirelen <= best_ripup_wirelen) {
- ripup_target = proxy.getCell(proxy.getBoundBelCell(bel));
+ ripup_target = ctx->cells.at(ctx->getBoundBelCellUnlocked(bel)).get();
if (ripup_target->belStrength < STRENGTH_STRONG) {
best_ripup_wirelen = wirelen;
ripup_bel = bel;
@@ -73,12 +148,12 @@ bool place_single_cell(ArchRWProxy &proxy, Context *ctx, CellInfo *cell, bool re
log_error("failed to place cell '%s' of type '%s'\n", cell->name.c_str(ctx), cell->type.c_str(ctx));
}
--iters;
- proxy.unbindBel(ripup_target->bel);
+ ctx->unbindBelUnlocked(ripup_target->bel);
best_bel = ripup_bel;
} else {
all_placed = true;
}
- proxy.bindBel(best_bel, cell->name, STRENGTH_WEAK);
+ ctx->bindBelUnlocked(best_bel, cell->name, STRENGTH_WEAK);
cell = ripup_target;
}
diff --git a/common/place_common.h b/common/place_common.h
index 57e82510..67956072 100644
--- a/common/place_common.h
+++ b/common/place_common.h
@@ -22,94 +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(ArchRWProxy &proxy, Context *ctx, CellInfo *cell, bool require_legality);
+bool place_single_cell(Context *ctx, CellInfo *cell, bool require_legality);
NEXTPNR_NAMESPACE_END
diff --git a/common/placer1.cc b/common/placer1.cc
index 0e3a84f7..05f760a3 100644
--- a/common/placer1.cc
+++ b/common/placer1.cc
@@ -3,7 +3,6 @@
*
* Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com>
* Copyright (C) 2018 David Shah <david@symbioticeda.com>
- * Copyright (C) 2018 Serge Bazanski <q3k@symbioticeda.com>
*
* Simulated annealing implementation based on arachne-pnr
* Copyright (C) 2015-2018 Cotton Seed
@@ -80,33 +79,30 @@ class SAPlacer
log_break();
size_t placed_cells = 0;
- {
- auto &&proxy = ctx->rwproxy();
- // Initial constraints placer
- for (auto &cell_entry : ctx->cells) {
- CellInfo *cell = cell_entry.second.get();
- auto loc = cell->attrs.find(ctx->id("BEL"));
- if (loc != cell->attrs.end()) {
- std::string loc_name = loc->second;
- BelId bel = proxy.getBelByName(ctx->id(loc_name));
- if (bel == BelId()) {
- log_error("No Bel named \'%s\' located for "
- "this chip (processing BEL attribute on \'%s\')\n",
- loc_name.c_str(), cell->name.c_str(ctx));
- }
-
- BelType bel_type = ctx->getBelType(bel);
- if (bel_type != ctx->belTypeFromId(cell->type)) {
- log_error("Bel \'%s\' of type \'%s\' does not match cell "
- "\'%s\' of type \'%s\'",
- loc_name.c_str(), ctx->belTypeToId(bel_type).c_str(ctx), cell->name.c_str(ctx),
- cell->type.c_str(ctx));
- }
+ // Initial constraints placer
+ for (auto &cell_entry : ctx->cells) {
+ CellInfo *cell = cell_entry.second.get();
+ auto loc = cell->attrs.find(ctx->id("BEL"));
+ if (loc != cell->attrs.end()) {
+ std::string loc_name = loc->second;
+ BelId bel = ctx->getBelByNameUnlocked(ctx->id(loc_name));
+ if (bel == BelId()) {
+ log_error("No Bel named \'%s\' located for "
+ "this chip (processing BEL attribute on \'%s\')\n",
+ loc_name.c_str(), cell->name.c_str(ctx));
+ }
- proxy.bindBel(bel, cell->name, STRENGTH_USER);
- locked_bels.insert(bel);
- placed_cells++;
+ BelType bel_type = ctx->getBelType(bel);
+ if (bel_type != ctx->belTypeFromId(cell->type)) {
+ log_error("Bel \'%s\' of type \'%s\' does not match cell "
+ "\'%s\' of type \'%s\'",
+ loc_name.c_str(), ctx->belTypeToId(bel_type).c_str(ctx), cell->name.c_str(ctx),
+ cell->type.c_str(ctx));
}
+
+ ctx->bindBelUnlocked(bel, cell->name, STRENGTH_USER);
+ locked_bels.insert(bel);
+ placed_cells++;
}
}
int constr_placed_cells = placed_cells;
@@ -126,15 +122,12 @@ class SAPlacer
// Place cells randomly initially
log_info("Creating initial placement for remaining %d cells.\n", int(autoplaced.size()));
- {
- auto &&proxy = ctx->rwproxy();
- for (auto cell : autoplaced) {
- place_initial(proxy, cell);
- placed_cells++;
- if ((placed_cells - constr_placed_cells) % 500 == 0)
- log_info(" initial placement placed %d/%d cells\n", int(placed_cells - constr_placed_cells),
- int(autoplaced.size()));
- }
+ for (auto cell : autoplaced) {
+ place_initial(cell);
+ placed_cells++;
+ if ((placed_cells - constr_placed_cells) % 500 == 0)
+ log_info(" initial placement placed %d/%d cells\n", int(placed_cells - constr_placed_cells),
+ int(autoplaced.size()));
}
if ((placed_cells - constr_placed_cells) % 500 != 0)
log_info(" initial placement placed %d/%d cells\n", int(placed_cells - constr_placed_cells),
@@ -145,13 +138,10 @@ class SAPlacer
// Calculate wirelength after initial placement
curr_wirelength = 0;
curr_tns = 0;
- {
- auto &&proxy = ctx->rproxy();
- for (auto &net : ctx->nets) {
- wirelen_t wl = get_net_wirelength(proxy, ctx, net.second.get(), curr_tns);
- wirelengths[net.first] = wl;
- curr_wirelength += wl;
- }
+ for (auto &net : ctx->nets) {
+ wirelen_t wl = get_net_wirelength(ctx, net.second.get(), curr_tns);
+ wirelengths[net.first] = wl;
+ curr_wirelength += wl;
}
int n_no_progress = 0;
@@ -168,18 +158,15 @@ class SAPlacer
"%.0f, est tns = %.02fns\n",
iter, temp, double(curr_wirelength), curr_tns);
- {
- auto &&proxy = ctx->rwproxy();
- for (int m = 0; m < 15; ++m) {
- // Loop through all automatically placed cells
- for (auto cell : autoplaced) {
- // Find another random Bel for this cell
- BelId try_bel = random_bel_for_cell(cell);
- // If valid, try and swap to a new position and see if
- // the new position is valid/worthwhile
- if (try_bel != BelId() && try_bel != cell->bel)
- try_swap_position(proxy, cell, try_bel);
- }
+ for (int m = 0; m < 15; ++m) {
+ // Loop through all automatically placed cells
+ for (auto cell : autoplaced) {
+ // Find another random Bel for this cell
+ BelId try_bel = random_bel_for_cell(cell);
+ // If valid, try and swap to a new position and see if
+ // the new position is valid/worthwhile
+ if (try_bel != BelId() && try_bel != cell->bel)
+ try_swap_position(cell, try_bel);
}
}
// Heuristic to improve placement on the 8k
@@ -240,33 +227,27 @@ class SAPlacer
// accumulating over time
curr_wirelength = 0;
curr_tns = 0;
- {
- auto &&proxy = ctx->rproxy();
- for (auto &net : ctx->nets) {
- wirelen_t wl = get_net_wirelength(proxy, ctx, net.second.get(), curr_tns);
- wirelengths[net.first] = wl;
- curr_wirelength += wl;
- }
+ for (auto &net : ctx->nets) {
+ wirelen_t wl = get_net_wirelength(ctx, net.second.get(), curr_tns);
+ wirelengths[net.first] = wl;
+ curr_wirelength += wl;
}
}
- {
- // Final post-pacement validitiy check
- auto &&proxy = ctx->rproxy();
- for (auto bel : ctx->getBels()) {
- IdString cell = proxy.getBoundBelCell(bel);
- if (!proxy.isBelLocationValid(bel)) {
- std::string cell_text = "no cell";
- if (cell != IdString())
- cell_text = std::string("cell '") + cell.str(ctx) + "'";
- if (ctx->force) {
- log_warning("post-placement validity check failed for Bel '%s' "
- "(%s)\n",
- ctx->getBelName(bel).c_str(ctx), cell_text.c_str());
- } else {
- log_error("post-placement validity check failed for Bel '%s' "
- "(%s)\n",
- ctx->getBelName(bel).c_str(ctx), cell_text.c_str());
- }
+ // Final post-pacement validitiy check
+ for (auto bel : ctx->getBels()) {
+ IdString cell = ctx->getBoundBelCellUnlocked(bel);
+ if (!ctx->isBelLocationValid(bel)) {
+ std::string cell_text = "no cell";
+ if (cell != IdString())
+ cell_text = std::string("cell '") + cell.str(ctx) + "'";
+ if (ctx->force) {
+ log_warning("post-placement validity check failed for Bel '%s' "
+ "(%s)\n",
+ ctx->getBelName(bel).c_str(ctx), cell_text.c_str());
+ } else {
+ log_error("post-placement validity check failed for Bel '%s' "
+ "(%s)\n",
+ ctx->getBelName(bel).c_str(ctx), cell_text.c_str());
}
}
}
@@ -275,7 +256,7 @@ class SAPlacer
private:
// Initial random placement
- void place_initial(ArchRWProxy &proxy, CellInfo *cell)
+ void place_initial(CellInfo *cell)
{
bool all_placed = false;
int iters = 25;
@@ -286,12 +267,12 @@ class SAPlacer
CellInfo *ripup_target = nullptr;
BelId ripup_bel = BelId();
if (cell->bel != BelId()) {
- proxy.unbindBel(cell->bel);
+ ctx->unbindBelUnlocked(cell->bel);
}
BelType targetType = ctx->belTypeFromId(cell->type);
for (auto bel : ctx->getBels()) {
- if (ctx->getBelType(bel) == targetType && (proxy.isValidBelForCell(cell, bel) || !require_legal)) {
- if (proxy.checkBelAvail(bel)) {
+ if (ctx->getBelType(bel) == targetType && (ctx->isValidBelForCell(cell, bel) || !require_legal)) {
+ if (ctx->checkBelAvailUnlocked(bel)) {
uint64_t score = ctx->rng64();
if (score <= best_score) {
best_score = score;
@@ -301,7 +282,7 @@ class SAPlacer
uint64_t score = ctx->rng64();
if (score <= best_ripup_score) {
best_ripup_score = score;
- ripup_target = ctx->cells.at(proxy.getBoundBelCell(bel)).get();
+ ripup_target = ctx->cells.at(ctx->getBoundBelCellUnlocked(bel)).get();
ripup_bel = bel;
}
}
@@ -311,12 +292,12 @@ class SAPlacer
if (iters == 0 || ripup_bel == BelId())
log_error("failed to place cell '%s' of type '%s'\n", cell->name.c_str(ctx), cell->type.c_str(ctx));
--iters;
- proxy.unbindBel(ripup_target->bel);
+ ctx->unbindBelUnlocked(ripup_target->bel);
best_bel = ripup_bel;
} else {
all_placed = true;
}
- proxy.bindBel(best_bel, cell->name, STRENGTH_WEAK);
+ ctx->bindBelUnlocked(best_bel, cell->name, STRENGTH_WEAK);
// Back annotate location
cell->attrs[ctx->id("BEL")] = ctx->getBelName(cell->bel).str(ctx);
@@ -325,14 +306,14 @@ class SAPlacer
}
// Attempt a SA position swap, return true on success or false on failure
- bool try_swap_position(ArchRWProxy &proxy, CellInfo *cell, BelId newBel)
+ bool try_swap_position(CellInfo *cell, BelId newBel)
{
static std::unordered_set<NetInfo *> update;
static std::vector<std::pair<IdString, wirelen_t>> new_lengths;
new_lengths.clear();
update.clear();
BelId oldBel = cell->bel;
- IdString other = proxy.getBoundBelCell(newBel);
+ IdString other = ctx->getBoundBelCellUnlocked(newBel);
CellInfo *other_cell = nullptr;
if (other != IdString()) {
other_cell = ctx->cells[other].get();
@@ -340,9 +321,9 @@ class SAPlacer
return false;
}
wirelen_t new_wirelength = 0, delta;
- proxy.unbindBel(oldBel);
+ ctx->unbindBelUnlocked(oldBel);
if (other != IdString()) {
- proxy.unbindBel(newBel);
+ ctx->unbindBelUnlocked(newBel);
}
for (const auto &port : cell->ports)
@@ -355,16 +336,16 @@ class SAPlacer
update.insert(port.second.net);
}
- proxy.bindBel(newBel, cell->name, STRENGTH_WEAK);
+ ctx->bindBelUnlocked(newBel, cell->name, STRENGTH_WEAK);
if (other != IdString()) {
- proxy.bindBel(oldBel, other_cell->name, STRENGTH_WEAK);
+ ctx->bindBelUnlocked(oldBel, other_cell->name, STRENGTH_WEAK);
}
if (require_legal) {
- if (!proxy.isBelLocationValid(newBel) || ((other != IdString() && !proxy.isBelLocationValid(oldBel)))) {
- proxy.unbindBel(newBel);
+ if (!ctx->isBelLocationValid(newBel) || ((other != IdString() && !ctx->isBelLocationValid(oldBel)))) {
+ ctx->unbindBelUnlocked(newBel);
if (other != IdString())
- proxy.unbindBel(oldBel);
+ ctx->unbindBelUnlocked(oldBel);
goto swap_fail;
}
}
@@ -375,7 +356,7 @@ class SAPlacer
for (auto net : update) {
new_wirelength -= wirelengths.at(net->name);
float temp_tns = 0;
- wirelen_t net_new_wl = get_net_wirelength<>(proxy, ctx, net, temp_tns);
+ wirelen_t net_new_wl = get_net_wirelength(ctx, net, temp_tns);
new_wirelength += net_new_wl;
new_lengths.push_back(std::make_pair(net->name, net_new_wl));
}
@@ -388,8 +369,8 @@ class SAPlacer
improved = true;
} else {
if (other != IdString())
- proxy.unbindBel(oldBel);
- proxy.unbindBel(newBel);
+ ctx->unbindBelUnlocked(oldBel);
+ ctx->unbindBelUnlocked(newBel);
goto swap_fail;
}
curr_wirelength = new_wirelength;
@@ -398,9 +379,9 @@ class SAPlacer
return true;
swap_fail:
- proxy.bindBel(oldBel, cell->name, STRENGTH_WEAK);
+ ctx->bindBelUnlocked(oldBel, cell->name, STRENGTH_WEAK);
if (other != IdString()) {
- proxy.bindBel(newBel, other, STRENGTH_WEAK);
+ ctx->bindBelUnlocked(newBel, other, STRENGTH_WEAK);
}
return false;
}
diff --git a/common/router1.cc b/common/router1.cc
index 0d26a36d..cbaf773d 100644
--- a/common/router1.cc
+++ b/common/router1.cc
@@ -2,7 +2,6 @@
* nextpnr -- Next Generation Place and Route
*
* Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com>
- * Copyright (C) 2018 Serge Bazanski <q3k@symbioticeda.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -74,7 +73,7 @@ struct RipupScoreboard
std::unordered_map<std::pair<IdString, PipId>, int, hash_id_pip> netPipScores;
};
-void ripup_net(ArchRWProxy &proxy, Context *ctx, IdString net_name)
+void ripup_net(Context *ctx, IdString net_name)
{
auto net_info = ctx->nets.at(net_name).get();
std::vector<PipId> pips;
@@ -91,10 +90,10 @@ void ripup_net(ArchRWProxy &proxy, Context *ctx, IdString net_name)
}
for (auto pip : pips)
- proxy.unbindPip(pip);
+ ctx->unbindPipUnlocked(pip);
for (auto wire : wires)
- proxy.unbindWire(wire);
+ ctx->unbindWireUnlocked(wire);
NPNR_ASSERT(net_info->wires.empty());
}
@@ -115,7 +114,7 @@ struct Router
delay_t maxDelay = 0.0;
WireId failedDest;
- void route(ArchRWProxy &proxy, const std::unordered_map<WireId, delay_t> &src_wires, WireId dst_wire)
+ void route(const std::unordered_map<WireId, delay_t> &src_wires, WireId dst_wire)
{
std::priority_queue<QueuedWire, std::vector<QueuedWire>, QueuedWire::Greater> queue;
@@ -136,7 +135,6 @@ struct Router
int thisVisitCnt = 0;
int thisVisitCntLimit = 0;
-
while (!queue.empty() && (thisVisitCntLimit == 0 || thisVisitCnt < thisVisitCntLimit)) {
QueuedWire qw = queue.top();
queue.pop();
@@ -150,10 +148,10 @@ struct Router
bool foundRipupNet = false;
thisVisitCnt++;
- if (!proxy.checkWireAvail(next_wire)) {
+ if (!ctx->checkWireAvailUnlocked(next_wire)) {
if (!ripup)
continue;
- IdString ripupWireNet = proxy.getConflictingWireNet(next_wire);
+ IdString ripupWireNet = ctx->getConflictingWireNetUnlocked(next_wire);
if (ripupWireNet == net_name || ripupWireNet == IdString())
continue;
@@ -168,10 +166,10 @@ struct Router
foundRipupNet = true;
}
- if (!proxy.checkPipAvail(pip)) {
+ if (!ctx->checkPipAvailUnlocked(pip)) {
if (!ripup)
continue;
- IdString ripupPipNet = proxy.getConflictingPipNet(pip);
+ IdString ripupPipNet = ctx->getConflictingPipNetUnlocked(pip);
if (ripupPipNet == net_name || ripupPipNet == IdString())
continue;
@@ -229,10 +227,7 @@ struct Router
{
std::unordered_map<WireId, delay_t> src_wires;
src_wires[src_wire] = 0;
- {
- auto &&proxy = ctx->rwproxy();
- route(proxy, src_wires, dst_wire);
- }
+ route(src_wires, dst_wire);
routedOkay = visited.count(dst_wire);
if (ctx->debug) {
@@ -277,7 +272,7 @@ struct Router
if (driver_port_it != net_info->driver.cell->pins.end())
driver_port = driver_port_it->second;
- auto src_wire = ctx->rproxy().getWireBelPin(src_bel, ctx->portPinFromId(driver_port));
+ auto src_wire = ctx->getWireBelPinUnlocked(src_bel, ctx->portPinFromId(driver_port));
if (src_wire == WireId())
log_error("No wire found for port %s (pin %s) on source cell %s "
@@ -291,10 +286,8 @@ struct Router
std::unordered_map<WireId, delay_t> src_wires;
src_wires[src_wire] = 0;
- auto &&proxy = ctx->rwproxy();
-
- ripup_net(proxy, ctx, net_name);
- proxy.bindWire(src_wire, net_name, STRENGTH_WEAK);
+ ripup_net(ctx, net_name);
+ ctx->bindWireUnlocked(src_wire, net_name, STRENGTH_WEAK);
std::vector<PortRef> users_array = net_info->users;
ctx->shuffle(users_array);
@@ -319,7 +312,7 @@ struct Router
if (user_port_it != user_it.cell->pins.end())
user_port = user_port_it->second;
- auto dst_wire = proxy.getWireBelPin(dst_bel, ctx->portPinFromId(user_port));
+ auto dst_wire = ctx->getWireBelPinUnlocked(dst_bel, ctx->portPinFromId(user_port));
if (dst_wire == WireId())
log_error("No wire found for port %s (pin %s) on destination "
@@ -332,7 +325,7 @@ struct Router
log(" Path delay estimate: %.2f\n", float(ctx->estimateDelay(src_wire, dst_wire)));
}
- route(proxy, src_wires, dst_wire);
+ route(src_wires, dst_wire);
if (visited.count(dst_wire) == 0) {
if (ctx->debug)
@@ -341,7 +334,7 @@ struct Router
else if (ripup)
log_info("Failed to route %s -> %s.\n", ctx->getWireName(src_wire).c_str(ctx),
ctx->getWireName(dst_wire).c_str(ctx));
- ripup_net(proxy, ctx, net_name);
+ ripup_net(ctx, net_name);
failedDest = dst_wire;
return;
}
@@ -362,15 +355,15 @@ struct Router
if (src_wires.count(cursor))
break;
- IdString conflicting_wire_net = proxy.getConflictingWireNet(cursor);
+ IdString conflicting_wire_net = ctx->getConflictingWireNetUnlocked(cursor);
if (conflicting_wire_net != IdString()) {
NPNR_ASSERT(ripup);
NPNR_ASSERT(conflicting_wire_net != net_name);
- proxy.unbindWire(cursor);
- if (!proxy.checkWireAvail(cursor))
- ripup_net(proxy, ctx, conflicting_wire_net);
+ ctx->unbindWireUnlocked(cursor);
+ if (!ctx->checkWireAvailUnlocked(cursor))
+ ripup_net(ctx, conflicting_wire_net);
rippedNets.insert(conflicting_wire_net);
scores.wireScores[cursor]++;
@@ -379,15 +372,15 @@ struct Router
}
PipId pip = visited[cursor].pip;
- IdString conflicting_pip_net = proxy.getConflictingPipNet(pip);
+ IdString conflicting_pip_net = ctx->getConflictingPipNetUnlocked(pip);
if (conflicting_pip_net != IdString()) {
NPNR_ASSERT(ripup);
NPNR_ASSERT(conflicting_pip_net != net_name);
- proxy.unbindPip(pip);
- if (!proxy.checkPipAvail(pip))
- ripup_net(proxy, ctx, conflicting_pip_net);
+ ctx->unbindPipUnlocked(pip);
+ if (!ctx->checkPipAvailUnlocked(pip))
+ ripup_net(ctx, conflicting_pip_net);
rippedNets.insert(conflicting_pip_net);
scores.pipScores[visited[cursor].pip]++;
@@ -395,7 +388,7 @@ struct Router
scores.netPipScores[std::make_pair(conflicting_pip_net, visited[cursor].pip)]++;
}
- proxy.bindPip(visited[cursor].pip, net_name, STRENGTH_WEAK);
+ ctx->bindPipUnlocked(visited[cursor].pip, net_name, STRENGTH_WEAK);
src_wires[cursor] = visited[cursor].delay;
cursor = ctx->getPipSrcWire(visited[cursor].pip);
}
@@ -444,48 +437,45 @@ bool router1(Context *ctx)
delay_t estimatedTotalDelay = 0.0;
int estimatedTotalDelayCnt = 0;
- {
- auto &&proxy = ctx->rproxy();
- for (auto net_name : netsQueue) {
- auto net_info = ctx->nets.at(net_name).get();
+ for (auto net_name : netsQueue) {
+ auto net_info = ctx->nets.at(net_name).get();
- auto src_bel = net_info->driver.cell->bel;
+ auto src_bel = net_info->driver.cell->bel;
- if (src_bel == BelId())
- continue;
+ if (src_bel == BelId())
+ continue;
- IdString driver_port = net_info->driver.port;
+ IdString driver_port = net_info->driver.port;
- auto driver_port_it = net_info->driver.cell->pins.find(driver_port);
- if (driver_port_it != net_info->driver.cell->pins.end())
- driver_port = driver_port_it->second;
+ auto driver_port_it = net_info->driver.cell->pins.find(driver_port);
+ if (driver_port_it != net_info->driver.cell->pins.end())
+ driver_port = driver_port_it->second;
- auto src_wire = proxy.getWireBelPin(src_bel, ctx->portPinFromId(driver_port));
+ auto src_wire = ctx->getWireBelPinUnlocked(src_bel, ctx->portPinFromId(driver_port));
- if (src_wire == WireId())
- continue;
+ if (src_wire == WireId())
+ continue;
- for (auto &user_it : net_info->users) {
- auto dst_bel = user_it.cell->bel;
+ for (auto &user_it : net_info->users) {
+ auto dst_bel = user_it.cell->bel;
- if (dst_bel == BelId())
- continue;
+ if (dst_bel == BelId())
+ continue;
- IdString user_port = user_it.port;
+ IdString user_port = user_it.port;
- auto user_port_it = user_it.cell->pins.find(user_port);
+ auto user_port_it = user_it.cell->pins.find(user_port);
- if (user_port_it != user_it.cell->pins.end())
- user_port = user_port_it->second;
+ if (user_port_it != user_it.cell->pins.end())
+ user_port = user_port_it->second;
- auto dst_wire = proxy.getWireBelPin(dst_bel, ctx->portPinFromId(user_port));
+ auto dst_wire = ctx->getWireBelPinUnlocked(dst_bel, ctx->portPinFromId(user_port));
- if (dst_wire == WireId())
- continue;
+ if (dst_wire == WireId())
+ continue;
- estimatedTotalDelay += ctx->estimateDelay(src_wire, dst_wire);
- estimatedTotalDelayCnt++;
- }
+ estimatedTotalDelay += ctx->estimateDelay(src_wire, dst_wire);
+ estimatedTotalDelayCnt++;
}
}