timing_opt: Fix criticality and cost calculations

Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
David Shah 2018-12-02 14:14:44 +00:00
parent f3adf5a576
commit a990a1576c
2 changed files with 30 additions and 23 deletions

View File

@ -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

View File

@ -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) ||