aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorEddie Hung <e.hung@imperial.ac.uk>2018-07-24 22:20:10 -0700
committerEddie Hung <e.hung@imperial.ac.uk>2018-07-24 22:20:10 -0700
commit9382938661613b84e3ad3155e414aaae2fa87da2 (patch)
tree107c14811cf2e91c82ee4f9ea983260ee7acea8c /common
parent4920cf18fa1128758dac2ffd12bf88d194863f17 (diff)
parent32c7247785f48b2307e559a0af50d9387bda8b49 (diff)
downloadnextpnr-9382938661613b84e3ad3155e414aaae2fa87da2.tar.gz
nextpnr-9382938661613b84e3ad3155e414aaae2fa87da2.tar.bz2
nextpnr-9382938661613b84e3ad3155e414aaae2fa87da2.zip
Merge branch 'master' into redist_slack
Diffstat (limited to 'common')
-rw-r--r--common/archcheck.cc5
-rw-r--r--common/nextpnr.h11
-rw-r--r--common/place_common.cc22
-rw-r--r--common/placer1.cc26
-rw-r--r--common/timing.cc3
5 files changed, 38 insertions, 29 deletions
diff --git a/common/archcheck.cc b/common/archcheck.cc
index 5c4ef26c..5059066d 100644
--- a/common/archcheck.cc
+++ b/common/archcheck.cc
@@ -17,8 +17,8 @@
*
*/
-#include "nextpnr.h"
#include "log.h"
+#include "nextpnr.h"
#if 0
#define dbg(...) log(__VA_ARGS__)
@@ -84,8 +84,7 @@ void archcheck_locs(const Context *ctx)
log_info("Checking all locations..\n");
for (int x = 0; x < ctx->getGridDimX(); x++)
- for (int y = 0; y < ctx->getGridDimY(); y++)
- {
+ for (int y = 0; y < ctx->getGridDimY(); y++) {
dbg("> %d %d\n", x, y);
std::unordered_set<int> usedz;
diff --git a/common/nextpnr.h b/common/nextpnr.h
index 021772fe..4a1aaac1 100644
--- a/common/nextpnr.h
+++ b/common/nextpnr.h
@@ -147,6 +147,7 @@ struct GraphicElement
{
G_NONE,
G_LINE,
+ G_ARROW,
G_BOX,
G_CIRCLE,
G_LABEL
@@ -272,6 +273,16 @@ struct CellInfo : ArchCellInfo
// cell_port -> bel_pin
std::unordered_map<IdString, IdString> pins;
+
+ // placement constraints
+ CellInfo *constr_parent;
+ std::vector<CellInfo*> constr_children;
+ const int UNCONSTR = INT_MIN;
+ int constr_x = UNCONSTR; // this.x - parent.x
+ int constr_y = UNCONSTR; // this.y - parent.y
+ int constr_z = UNCONSTR; // this.z - parent.z
+ bool constr_abs_z = false; // parent.z := 0
+ // parent.[xyz] := 0 when (constr_parent == nullptr)
};
struct DeterministicRNG
diff --git a/common/place_common.cc b/common/place_common.cc
index 95b7b2aa..5673c847 100644
--- a/common/place_common.cc
+++ b/common/place_common.cc
@@ -28,19 +28,20 @@ NEXTPNR_NAMESPACE_BEGIN
wirelen_t get_net_metric(const Context *ctx, const NetInfo *net, MetricType type, float &tns)
{
wirelen_t wirelength = 0;
- int driver_x, driver_y;
+ Loc driver_loc;
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);
+ driver_gb = ctx->getBelGlobalBuf(driver_cell->bel);
+ driver_loc = ctx->getBelLocation(driver_cell->bel);
WireId drv_wire = ctx->getBelPinWire(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;
+ int xmin = driver_loc.x, xmax = driver_loc.x, ymin = driver_loc.y, ymax = driver_loc.y;
for (auto load : net->users) {
if (load.cell == nullptr)
continue;
@@ -56,15 +57,14 @@ wirelen_t get_net_metric(const Context *ctx, const NetInfo *net, MetricType type
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)
+ if (ctx->getBelGlobalBuf(load_cell->bel))
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);
+ Loc load_loc = ctx->getBelLocation(load_cell->bel);
+
+ xmin = std::min(xmin, load_loc.x);
+ ymin = std::min(ymin, load_loc.y);
+ xmax = std::max(xmax, load_loc.x);
+ ymax = std::max(ymax, load_loc.y);
}
if (ctx->timing_driven && type == MetricType::COST) {
wirelength = wirelen_t((((ymax - ymin) + (xmax - xmin)) * std::min(5.0, (1.0 + std::exp(-worst_slack / 5)))));
diff --git a/common/placer1.cc b/common/placer1.cc
index 77e33f5b..b7132254 100644
--- a/common/placer1.cc
+++ b/common/placer1.cc
@@ -50,9 +50,7 @@ class SAPlacer
{
int num_bel_types = 0;
for (auto bel : ctx->getBels()) {
- int x, y;
- bool gb;
- ctx->estimatePosition(bel, x, y, gb);
+ Loc loc = ctx->getBelLocation(bel);
BelType type = ctx->getBelType(bel);
int type_idx;
if (bel_types.find(type) == bel_types.end()) {
@@ -63,13 +61,13 @@ class SAPlacer
}
if (int(fast_bels.size()) < type_idx + 1)
fast_bels.resize(type_idx + 1);
- if (int(fast_bels.at(type_idx).size()) < (x + 1))
- fast_bels.at(type_idx).resize(x + 1);
- if (int(fast_bels.at(type_idx).at(x).size()) < (y + 1))
- fast_bels.at(type_idx).at(x).resize(y + 1);
- max_x = std::max(max_x, x);
- max_y = std::max(max_y, y);
- fast_bels.at(type_idx).at(x).at(y).push_back(bel);
+ if (int(fast_bels.at(type_idx).size()) < (loc.x + 1))
+ fast_bels.at(type_idx).resize(loc.x + 1);
+ if (int(fast_bels.at(type_idx).at(loc.x).size()) < (loc.y + 1))
+ fast_bels.at(type_idx).at(loc.x).resize(loc.y + 1);
+ max_x = std::max(max_x, loc.x);
+ max_y = std::max(max_y, loc.y);
+ fast_bels.at(type_idx).at(loc.x).at(loc.y).push_back(bel);
}
diameter = std::max(max_x, max_y) + 1;
}
@@ -411,12 +409,10 @@ class SAPlacer
BelId random_bel_for_cell(CellInfo *cell)
{
BelType targetType = ctx->belTypeFromId(cell->type);
- int x, y;
- bool gb;
- ctx->estimatePosition(cell->bel, x, y, gb);
+ Loc curr_loc = ctx->getBelLocation(cell->bel);
while (true) {
- int nx = ctx->rng(2 * diameter + 1) + std::max(x - diameter, 0);
- int ny = ctx->rng(2 * diameter + 1) + std::max(y - diameter, 0);
+ int nx = ctx->rng(2 * diameter + 1) + std::max(curr_loc.x - diameter, 0);
+ int ny = ctx->rng(2 * diameter + 1) + std::max(curr_loc.y - diameter, 0);
int beltype_idx = bel_types.at(targetType);
if (nx >= int(fast_bels.at(beltype_idx).size()))
continue;
diff --git a/common/timing.cc b/common/timing.cc
index ae164d20..814b0426 100644
--- a/common/timing.cc
+++ b/common/timing.cc
@@ -94,6 +94,9 @@ void assign_budget(Context *ctx)
IdString clock_domain = ctx->getPortClock(cell.second.get(), port.first);
if (clock_domain != IdString()) {
delay_t slack = delay_t(1.0e12 / ctx->target_freq); // TODO: clock constraints
+ delay_t clkToQ;
+ if (ctx->getCellDelay(cell.second.get(), clock_domain, port.first, clkToQ))
+ slack -= clkToQ;
if (port.second.net)
follow_net(ctx, port.second.net, 0, slack, updates);
}