Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanG077 committed Sep 20, 2024
1 parent 2550b14 commit 9b9e1ac
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 27 deletions.
8 changes: 3 additions & 5 deletions common/kernel/nextpnr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -451,16 +451,14 @@ struct CriticalPath
// To cell.port
std::pair<IdString, IdString> to;
// Segment delay
DelayPair delay;
delay_t delay;
};

// Clock pair
ClockPair clock_pair;
// Total path delay
// if sum < 0 this is a hold/min violation
// if delay.maxDelay() >= max_delay this is a setup/max violation
DelayPair delay;

// if sum(segments.delay) < 0 this is a hold/min violation
// if sum(segments.delay) >= max_delay this is a setup/max violation
delay_t max_delay;

// Individual path segments
Expand Down
31 changes: 21 additions & 10 deletions common/kernel/timing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -650,17 +650,15 @@ void TimingAnalyser::walk_backward()
// Input port: propagate delay back through net, subtracting route delay
NetInfo *net = port_info(p).net;
if (net != nullptr && net->driver.cell != nullptr)
set_required_time(CellPortKey(net->driver), req.first,
req.second.value - DelayPair(pd.route_delay.maxDelay()), req.second.path_length,
p);
set_required_time(CellPortKey(net->driver), req.first, req.second.value - pd.route_delay,
req.second.path_length, p);
} else if (pd.type == PORT_OUT) {
// Output port : propagate delay back through cell, subtracting combinational delay
for (auto &fanin : pd.cell_arcs) {
if (fanin.type != CellArc::COMBINATIONAL)
continue;
set_required_time(CellPortKey(p.cell, fanin.other_port), req.first,
req.second.value - DelayPair(fanin.value.maxDelay()), req.second.path_length + 1,
p);
req.second.value - fanin.value.delayPair(), req.second.path_length + 1, p);
}
}
}
Expand Down Expand Up @@ -895,8 +893,6 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
const auto &launch = domains.at(dp.key.launch).key;
const auto &capture = domains.at(dp.key.capture).key;

report.delay = DelayPair(0);

report.clock_pair.start.clock = launch.clock;
report.clock_pair.start.edge = launch.edge;
report.clock_pair.end.clock = capture.clock;
Expand Down Expand Up @@ -998,7 +994,7 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
if (!is_zero_delay(clock_skew)) {
CriticalPath::Segment seg_skew;
seg_skew.type = CriticalPath::Segment::Type::CLK_SKEW;
seg_skew.delay = DelayPair(clock_skew);
seg_skew.delay = DelayPair(clock_delay_launch);
seg_skew.from = std::make_pair(sp_cell->name, sp_clk_info.clock_port);
seg_skew.to = std::make_pair(ep_cell->name, ep_clk_info.clock_port);
if (same_clock) {
Expand All @@ -1007,6 +1003,18 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
seg_skew.net = IdString();
}
report.segments.push_back(seg_skew);

CriticalPath::Segment seg_skew2;
seg_skew2.type = CriticalPath::Segment::Type::CLK_SKEW;
seg_skew2.delay = DelayPair(-clock_delay_capture);
seg_skew2.from = std::make_pair(sp_cell->name, sp_clk_info.clock_port);
seg_skew2.to = std::make_pair(ep_cell->name, ep_clk_info.clock_port);
if (same_clock) {
seg_skew2.net = launch.clock;
} else {
seg_skew2.net = IdString();
}
report.segments.push_back(seg_skew2);
}
}

Expand Down Expand Up @@ -1236,9 +1244,12 @@ std::vector<CriticalPath> TimingAnalyser::get_min_delay_violations()
}

auto hold_slack = arr.value.minDelay() - req.value.maxDelay() + clock_to_clock;
auto violated = hold_slack <= 0;
if (hold_slack <= 0) {
printf("%s.%s, arr: %f, req: %f, c2c: %f, hold_slack: %f\n", ep.first.cell.c_str(ctx),
ep.first.port.c_str(ctx), ctx->getDelayNS(arr.value.minDelay()),
ctx->getDelayNS(req.value.maxDelay()), ctx->getDelayNS(clock_to_clock),
ctx->getDelayNS(hold_slack));

if (violated) {
const auto dom_pair_id = domain_pair_id(launch_id, capture_id);
violations.emplace_back(build_critical_path_report(dom_pair_id, ep.first, false));
}
Expand Down
23 changes: 11 additions & 12 deletions common/kernel/timing_log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,17 @@ static void log_crit_paths(const Context *ctx, TimingResult &result)

// A helper function for reporting one critical path
auto print_path_report = [ctx](const CriticalPath &path) {
DelayPair total(0), logic_total(0), route_total(0);
delay_t total(0), logic_total(0), route_total(0);

// We print out the max delay since that's usually the interesting case
// But if we know this critical path has violated hold time we print the
// min delay instead
bool min_delay_violation = path.delay.minDelay() < 0;
auto get_delay_ns = [min_delay_violation, ctx](const DelayPair &d) {
if (min_delay_violation) {
ctx->getDelayNS(d.minDelay());
}
return ctx->getDelayNS(d.maxDelay());
};
delay_t total_delay = 0;
for (const auto &segment : path.segments) {
total_delay += segment.delay;
}

bool min_delay_violation = total_delay < 0;

log_info(" type curr total name\n");
for (const auto &segment : path.segments) {
Expand All @@ -95,7 +94,7 @@ static void log_crit_paths(const Context *ctx, TimingResult &result)
logic_total += segment.delay;

log_info("%10s % 5.2f % 5.2f Source %s.%s\n", CriticalPath::Segment::type_to_str(segment.type).c_str(),
get_delay_ns(segment.delay), get_delay_ns(total), segment.to.first.c_str(ctx),
ctx->getDelayNS(segment.delay), ctx->getDelayNS(total), segment.to.first.c_str(ctx),
segment.to.second.c_str(ctx));
} else if (segment.type == CriticalPath::Segment::Type::ROUTING ||
segment.type == CriticalPath::Segment::Type::CLK_TO_CLK ||
Expand All @@ -109,8 +108,8 @@ static void log_crit_paths(const Context *ctx, TimingResult &result)
auto sink_loc = ctx->getBelLocation(sink->bel);

log_info("%10s % 5.2f % 5.2f Net %s (%d,%d) -> (%d,%d)\n",
CriticalPath::Segment::type_to_str(segment.type).c_str(), get_delay_ns(segment.delay),
get_delay_ns(total), segment.net.c_str(ctx), driver_loc.x, driver_loc.y, sink_loc.x,
CriticalPath::Segment::type_to_str(segment.type).c_str(), ctx->getDelayNS(segment.delay),
ctx->getDelayNS(total), segment.net.c_str(ctx), driver_loc.x, driver_loc.y, sink_loc.x,
sink_loc.y);
log_info(" Sink %s.%s\n", segment.to.first.c_str(ctx),
segment.to.second.c_str(ctx));
Expand Down Expand Up @@ -150,7 +149,7 @@ static void log_crit_paths(const Context *ctx, TimingResult &result)
}
}
}
log_info("%.2f ns logic, %.2f ns routing\n", get_delay_ns(logic_total), get_delay_ns(route_total));
log_info("%.2f ns logic, %.2f ns routing\n", ctx->getDelayNS(logic_total), ctx->getDelayNS(route_total));
};

// Single domain paths
Expand Down

0 comments on commit 9b9e1ac

Please sign in to comment.