timing: Allow critical path traversal for shortest paths
This commit is contained in:
parent
2d542eb63a
commit
44665a9c4d
@ -203,7 +203,7 @@ enum TimingPortClass
|
||||
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) {
|
||||
case TMG_CLOCK_INPUT:
|
||||
|
@ -796,7 +796,8 @@ std::vector<CellPortKey> TimingAnalyser::get_worst_eps(domain_id_t domain_pair,
|
||||
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;
|
||||
|
||||
@ -846,11 +847,18 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
|
||||
std::vector<PortRef> crit_path_rev;
|
||||
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;
|
||||
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
|
||||
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))
|
||||
break;
|
||||
|
||||
cursor = ports.at(cursor).arrival.at(dp.key.launch).bwd_max;
|
||||
auto cell = cell_info(cursor);
|
||||
auto &port = port_info(cursor);
|
||||
cursor = next_cursor(ports.at(cursor).arrival.at(dp.key.launch));
|
||||
}
|
||||
|
||||
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_driver = front_port.net->driver;
|
||||
|
||||
int port_clocks;
|
||||
auto portClass = ctx->getPortTimingClass(front_driver.cell, front_driver.port, port_clocks);
|
||||
portClass = ctx->getPortTimingClass(front_driver.cell, front_driver.port, port_clocks);
|
||||
|
||||
const CellInfo *last_cell = front.cell;
|
||||
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].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);
|
||||
}
|
||||
@ -1015,7 +1020,7 @@ void TimingAnalyser::build_crit_path_reports()
|
||||
if (worst_endpoint.empty())
|
||||
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) {
|
||||
|
@ -119,7 +119,9 @@ struct TimingAnalyser
|
||||
void compute_criticality();
|
||||
|
||||
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_slack_histogram_report();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user