aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/timing.cc13
-rw-r--r--common/timing_opt.cc40
2 files changed, 30 insertions, 23 deletions
diff --git a/common/timing.cc b/common/timing.cc
index 000a36b7..18caa989 100644
--- a/common/timing.cc
+++ b/common/timing.cc
@@ -531,6 +531,10 @@ struct Timing
bool is_path = ctx->getCellDelay(drv.cell, port.first, drv.port, comb_delay);
if (!is_path)
continue;
+ int cc;
+ auto pclass = ctx->getPortTimingClass(drv.cell, port.first, cc);
+ if (pclass != TMG_COMB_INPUT)
+ continue;
NetInfo *sink_net = port.second.net;
if (net_data.count(sink_net) && net_data.at(sink_net).count(startdomain.first)) {
auto &sink_nd = net_data.at(sink_net).at(startdomain.first);
@@ -562,15 +566,24 @@ struct Timing
auto &nc = (*net_crit)[net->name];
if (nc.slack.empty())
nc.slack.resize(net->users.size(), std::numeric_limits<delay_t>::max());
+ if (ctx->debug)
+ log_info("Net %s cd %s\n", net->name.c_str(ctx), startdomain.first.clock.c_str(ctx));
for (size_t i = 0; i < net->users.size(); i++) {
delay_t slack = nd.min_required.at(i) -
(nd.max_arrival + ctx->getNetinfoRouteDelay(net, net->users.at(i)));
+ if (ctx->debug)
+ log_info(" user %s.%s required %.02fns arrival %.02f route %.02f slack %.02f\n",
+ net->users.at(i).cell->name.c_str(ctx), net->users.at(i).port.c_str(ctx),
+ ctx->getDelayNS(nd.min_required.at(i)), ctx->getDelayNS(nd.max_arrival),
+ ctx->getDelayNS(ctx->getNetinfoRouteDelay(net, net->users.at(i))), ctx->getDelayNS(slack));
if (worst_slack.count(startdomain.first))
worst_slack.at(startdomain.first) = std::min(worst_slack.at(startdomain.first), slack);
else
worst_slack[startdomain.first] = slack;
nc.slack.at(i) = std::min(nc.slack.at(i), slack);
}
+ if (ctx->debug)
+ log_break();
}
}
// Assign criticality values
diff --git a/common/timing_opt.cc b/common/timing_opt.cc
index 300ca06f..ed1618da 100644
--- a/common/timing_opt.cc
+++ b/common/timing_opt.cc
@@ -90,7 +90,7 @@ class TimingOptimiser
log_info(" Iteration %d...\n", i);
get_criticalities(ctx, &net_crit);
setup_delay_limits();
- auto crit_paths = find_crit_paths(0.92, 1000);
+ auto crit_paths = find_crit_paths(0.95, 1000);
for (auto &path : crit_paths)
optimise_path(path);
#if 1
@@ -438,25 +438,12 @@ class TimingOptimiser
return;
}
IdString last_cell;
- const int d = 3; // FIXME: how to best determine d
+ const int d = 4; // FIXME: how to best determine d
for (auto cell : path_cells) {
// FIXME: when should we allow swapping due to a lack of candidates
find_neighbours(ctx->cells[cell].get(), last_cell, d, false);
last_cell = cell;
}
- // Map cells that we will actually modify to the arc we will use for cost
- // calculation
- // for delay calc purposes
- std::unordered_map<IdString, std::pair<PortRef *, PortRef *>> cost_ports;
- PortRef *last_port = nullptr;
- auto pcell = path_cells.begin();
- for (auto port : path) {
- if (port->cell->name == *pcell) {
- cost_ports[*pcell] = std::make_pair(last_port, port);
- pcell++;
- }
- last_port = port;
- }
// Actual BFS path optimisation algorithm
std::unordered_map<IdString, std::unordered_map<BelId, delay_t>> cumul_costs;
@@ -501,8 +488,6 @@ class TimingOptimiser
move.push_back(std::make_pair(cell, origBel));
}
- delay_t cdelay = cumul_costs[cellname][entry.second];
-
// Have a look at where we can travel from here
for (auto neighbour : cell_neighbour_bels.at(path_cells.at(entry.first + 1))) {
// Edges between overlapping bels are deleted
@@ -514,12 +499,21 @@ class TimingOptimiser
BelId origBel = cell_swap_bel(next_cell, neighbour);
move.push_back(std::make_pair(next_cell, origBel));
- // Check the new cumulative delay
- auto port_pair = cost_ports.at(ncname);
- delay_t edge_delay =
- ctx->estimateDelay(ctx->getBelPinWire(port_pair.first->cell->bel, port_pair.first->port),
- ctx->getBelPinWire(port_pair.second->cell->bel, port_pair.second->port));
- delay_t total_delay = cdelay + edge_delay;
+ delay_t total_delay = 0;
+
+ for (size_t i = 0; i < path.size(); i++) {
+ NetInfo *pn = path.at(i)->cell->ports.at(path.at(i)->port).net;
+ for (size_t j = 0; j < pn->users.size(); j++) {
+ auto & usr = pn->users.at(j);
+ if (usr.cell == path.at(i)->cell && usr.port == path.at(i)->port) {
+ total_delay += ctx->predictDelay(pn, usr);
+ break;
+ }
+ }
+ if (path.at(i)->cell == next_cell)
+ break;
+ }
+
// First, check if the move is actually worthwhile from a delay point of view before the expensive
// legality check
if (!cumul_costs.count(ncname) || !cumul_costs.at(ncname).count(neighbour) ||