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