timing: Allow critical path traversal for shortest paths

This commit is contained in:
Rowan Goemans 2024-09-06 23:23:04 +02:00 committed by myrtle
parent 2d542eb63a
commit 44665a9c4d
3 changed files with 19 additions and 12 deletions

View File

@ -203,7 +203,7 @@ enum TimingPortClass
TMG_IGNORE, // Asynchronous to all clocks, "don't care", and should be ignored (false path) for analysis TMG_IGNORE, // Asynchronous to all clocks, "don't care", and should be ignored (false path) for analysis
}; };
std::string tmgPortClass_to_str(TimingPortClass tmg_class) static std::string tmgPortClass_to_str(TimingPortClass tmg_class)
{ {
switch (tmg_class) { switch (tmg_class) {
case TMG_CLOCK_INPUT: case TMG_CLOCK_INPUT:

View File

@ -796,7 +796,8 @@ std::vector<CellPortKey> TimingAnalyser::get_worst_eps(domain_id_t domain_pair,
return worst_eps; return worst_eps;
} }
CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair, CellPortKey endpoint) CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair, CellPortKey endpoint,
bool longest_path)
{ {
CriticalPath report; CriticalPath report;
@ -846,11 +847,18 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
std::vector<PortRef> crit_path_rev; std::vector<PortRef> crit_path_rev;
auto cursor = endpoint; auto cursor = endpoint;
while (cursor != CellPortKey()) { auto next_cursor = [longest_path](ArrivReqTime &arrival) {
if (longest_path) {
return arrival.bwd_max;
}
return arrival.bwd_min;
};
while (cursor != CellPortKey()) {
auto cell = cell_info(cursor);
auto &port = port_info(cursor);
int port_clocks; int port_clocks;
auto portClass = ctx->getPortTimingClass(cell, port.name, port_clocks); auto portClass = ctx->getPortTimingClass(cell, port.name, port_clocks);
printf("%s.%s %s\n", cell->name.c_str(ctx), port.name.c_str(ctx), tmgPortClass_to_str(portClass));
// combinational loop // combinational loop
if (!visited.insert(std::make_pair(cell->name, port.name)).second) if (!visited.insert(std::make_pair(cell->name, port.name)).second)
@ -862,9 +870,7 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
if (!ports.at(cursor).arrival.count(dp.key.launch)) if (!ports.at(cursor).arrival.count(dp.key.launch))
break; break;
cursor = ports.at(cursor).arrival.at(dp.key.launch).bwd_max; cursor = next_cursor(ports.at(cursor).arrival.at(dp.key.launch));
auto cell = cell_info(cursor);
auto &port = port_info(cursor);
} }
auto crit_path = boost::adaptors::reverse(crit_path_rev); auto crit_path = boost::adaptors::reverse(crit_path_rev);
@ -873,8 +879,7 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
auto &front_port = front.cell->ports.at(front.port); auto &front_port = front.cell->ports.at(front.port);
auto &front_driver = front_port.net->driver; auto &front_driver = front_port.net->driver;
int port_clocks; portClass = ctx->getPortTimingClass(front_driver.cell, front_driver.port, port_clocks);
auto portClass = ctx->getPortTimingClass(front_driver.cell, front_driver.port, port_clocks);
const CellInfo *last_cell = front.cell; const CellInfo *last_cell = front.cell;
IdString last_port = front_driver.port; IdString last_port = front_driver.port;
@ -997,7 +1002,7 @@ void TimingAnalyser::build_crit_path_reports()
clock_fmax[launch.clock].achieved = Fmax; clock_fmax[launch.clock].achieved = Fmax;
clock_fmax[launch.clock].constraint = target; clock_fmax[launch.clock].constraint = target;
clock_reports[launch.clock] = build_critical_path_report(i, worst_endpoint.at(0)); clock_reports[launch.clock] = build_critical_path_report(i, worst_endpoint.at(0), true);
empty_clocks.erase(launch.clock); empty_clocks.erase(launch.clock);
} }
@ -1015,7 +1020,7 @@ void TimingAnalyser::build_crit_path_reports()
if (worst_endpoint.empty()) if (worst_endpoint.empty())
continue; continue;
xclock_reports.emplace_back(build_critical_path_report(i, worst_endpoint.at(0))); xclock_reports.emplace_back(build_critical_path_report(i, worst_endpoint.at(0), true));
} }
auto cmp_crit_path = [&](const CriticalPath &ra, const CriticalPath &rb) { auto cmp_crit_path = [&](const CriticalPath &ra, const CriticalPath &rb) {

View File

@ -119,7 +119,9 @@ struct TimingAnalyser
void compute_criticality(); void compute_criticality();
void build_detailed_net_timing_report(); void build_detailed_net_timing_report();
CriticalPath build_critical_path_report(domain_id_t domain_pair, CellPortKey endpoint); // longest_path indicate whether to follow the longest or shortest path from endpoint to startpoint
// longest paths are interesting for setup violations and shortest paths are interesting for hold violations
CriticalPath build_critical_path_report(domain_id_t domain_pair, CellPortKey endpoint, bool longest_path);
void build_crit_path_reports(); void build_crit_path_reports();
void build_slack_histogram_report(); void build_slack_histogram_report();