aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2018-12-01 13:22:57 +0000
committerDavid Shah <dave@ds0.me>2018-12-06 10:53:01 +0000
commit83e32775775cc06d0f70a18e2a18089c38ff3c35 (patch)
tree1cc78704329758d8a3b543d41588b141e7e2b477 /common
parent9a42b64a6853a3802a6d934a1ca251e84ddb7e07 (diff)
downloadnextpnr-83e32775775cc06d0f70a18e2a18089c38ff3c35.tar.gz
nextpnr-83e32775775cc06d0f70a18e2a18089c38ff3c35.tar.bz2
nextpnr-83e32775775cc06d0f70a18e2a18089c38ff3c35.zip
timing_opt: Implement neighbour Bel finder
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'common')
-rw-r--r--common/timing.cc2
-rw-r--r--common/timing_opt.cc77
-rw-r--r--common/timing_opt.h4
3 files changed, 83 insertions, 0 deletions
diff --git a/common/timing.cc b/common/timing.cc
index 55d3a46f..ebe3a177 100644
--- a/common/timing.cc
+++ b/common/timing.cc
@@ -91,6 +91,7 @@ struct NetCriticalityInfo
// One each per user
std::vector<delay_t> slack;
std::vector<float> criticality;
+ unsigned max_path_length = 0;
};
typedef std::unordered_map<ClockPair, CriticalPath> CriticalPathMap;
@@ -597,6 +598,7 @@ struct Timing
float criticality = 1.0 - ((nc.slack.at(i) - worst_slack.at(startdomain.first)) / dmax);
nc.criticality.at(i) = std::max(nc.criticality.at(i), criticality);
}
+ nc.max_path_length = std::max(nc.max_path_length, nd.max_path_length);
}
}
}
diff --git a/common/timing_opt.cc b/common/timing_opt.cc
index b33c2db0..de8e00a5 100644
--- a/common/timing_opt.cc
+++ b/common/timing_opt.cc
@@ -34,6 +34,83 @@ class TimingOptimiser
bool optimise() {}
private:
+ // Ratio of available to already-candidates to begin borrowing
+ const float borrow_thresh = 0.2;
+
+ bool check_cell_delay_limits(CellInfo *cell) {
+
+ }
+
+ bool acceptable_bel_candidate(CellInfo *cell, BelId newBel) {
+ bool result = true;
+ // At the moment we have to actually do the swap to get an accurate legality result
+ // Switching to macro swaps might help with this
+ BelId oldBel = cell->bel;
+ CellInfo *other_cell = ctx->getBoundBelCell(newBel);
+ if (other_cell != nullptr && other_cell->belStrength > STRENGTH_WEAK) {
+ return false;
+ }
+
+ ctx->bindBel(newBel, cell, STRENGTH_WEAK);
+ if (other_cell != nullptr) {
+ ctx->bindBel(oldBel, other_cell, STRENGTH_WEAK);
+ }
+ if (!ctx->isBelLocationValid(newBel) || ((other_cell != nullptr && !ctx->isBelLocationValid(oldBel)))) {
+ result = false;
+ goto unbind;
+ }
+
+
+
+unbind:
+ ctx->unbindBel(newBel);
+ if (other_cell != nullptr)
+ ctx->unbindBel(oldBel);
+ // Undo the swap
+ ctx->bindBel(oldBel, cell, STRENGTH_WEAK);
+ if (other_cell != nullptr) {
+ ctx->bindBel(newBel, other_cell, STRENGTH_WEAK);
+ }
+ return result;
+ }
+
+ void find_neighbours(CellInfo *cell, int d) {
+ BelId curr = cell->bel;
+ Loc curr_loc = ctx->getBelLocation(curr);
+ for (int dy = -d; dy <= d; dy++) {
+ for (int dx = -d; dx <= d; dx++) {
+ if (dx == 0 && dy == 0)
+ continue;
+ // Go through all the Bels at this location
+ // First, find all bels of the correct type that are either unbound or bound normally
+ // Strongly bound bels are ignored
+ // FIXME: This means that we cannot touch carry chains or similar relatively constrained macros
+ std::vector<BelId> free_bels_at_loc;
+ std::vector<BelId> bound_bels_at_loc;
+ for (auto bel : ctx->getBelsByTile(curr_loc.x + dx, curr_loc.y + dy)) {
+ if (ctx->getBelType(bel) != cell->type)
+ continue;
+ CellInfo *bound = ctx->getBoundBelCell(bel);
+ if (bound == nullptr) {
+ free_bels_at_loc.push_back(bel);
+ } else if (bound->belStrength <= STRENGTH_WEAK) {
+ bound_bels_at_loc.push_back(bel);
+ }
+ }
+ bool found = false;
+
+ if (found)
+ continue;
+ }
+ }
+ }
+
+ // Current candidate Bels for cells (linked in both direction>
+ std::vector<IdString> path_cells;
+ std::unordered_map<IdString, std::unordered_set<BelId>> cell_neighbour_bels;
+ std::unordered_map<BelId, std::unordered_set<IdString>> bel_candidate_cells;
+ // Map net users to net delay limit
+ std::unordered_map<IdString, std::vector<delay_t>> max_net_delay;
Context *ctx;
};
diff --git a/common/timing_opt.h b/common/timing_opt.h
index 60df7df9..746294bb 100644
--- a/common/timing_opt.h
+++ b/common/timing_opt.h
@@ -23,6 +23,10 @@ NEXTPNR_NAMESPACE_BEGIN
struct TimingOptCfg : public Settings
{
+ // The timing optimiser will *only* optimise cells of these types
+ // Normally these would only be logic cells (or tiles if applicable), the algorithm makes little sense
+ // for other cell types
+ std::unordered_set<IdString> cellTypes;
};
extern bool timing_opt(Context *ctx, TimingOptCfg cfg);