timing_opt: Fix criticality and cost calculations
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
f3adf5a576
commit
a990a1576c
@ -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
|
||||
|
@ -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) ||
|
||||
|
Loading…
Reference in New Issue
Block a user