Skip to content

Commit

Permalink
timing: minor cleanup and stupid mistake fixups
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanG077 committed Sep 17, 2024
1 parent c73c327 commit 3aedaf1
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 23 deletions.
6 changes: 3 additions & 3 deletions common/kernel/nextpnr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -447,11 +447,11 @@ struct CriticalPath
// 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 delay.minDelay() < bound.minDelay() then this is a hold violation
// if delay.maxDelay() > bound.maxDelay() then this is a setup violation
DelayPair bound;
delay_t max_delay;

// Individual path segments
std::vector<Segment> segments;
Expand Down
20 changes: 6 additions & 14 deletions common/kernel/timing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -911,22 +911,21 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
report.clock_pair.end.clock = capture.clock;
report.clock_pair.end.edge = capture.edge;

report.bound = DelayPair(0, ctx->getDelayFromNS(1.0e9 / ctx->setting<float>("target_freq")));
report.max_delay = ctx->getDelayFromNS(1.0e9 / ctx->setting<float>("target_freq"));
if (launch.edge != capture.edge) {
report.bound.max_delay = report.bound.max_delay / 2;
report.max_delay = report.max_delay / 2;
}

if (!launch.is_async() && ctx->nets.at(launch.clock)->clkconstr) {
if (launch.edge == capture.edge) {
report.bound.max_delay = ctx->nets.at(launch.clock)->clkconstr->period.minDelay();
report.max_delay = ctx->nets.at(launch.clock)->clkconstr->period.minDelay();
} else if (capture.edge == RISING_EDGE) {
report.bound.max_delay = ctx->nets.at(launch.clock)->clkconstr->low.minDelay();
report.max_delay = ctx->nets.at(launch.clock)->clkconstr->low.minDelay();
} else if (capture.edge == FALLING_EDGE) {
report.bound.max_delay = ctx->nets.at(launch.clock)->clkconstr->high.minDelay();
report.max_delay = ctx->nets.at(launch.clock)->clkconstr->high.minDelay();
}
}

// Walk the min or max path backwards to find a single crit path
auto crit_path_rev = walk_crit_path(domain_pair, endpoint, longest_path);
auto crit_path = boost::adaptors::reverse(crit_path_rev);

Expand Down Expand Up @@ -997,8 +996,6 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
}
}

// Calculate clock skew only if start- and endpoint are registered
// and either the clock domains are the same or related clock
if (with_clock_skew && register_start && register_end && (same_clock || related_clock)) {

auto clock_delay_launch =
Expand Down Expand Up @@ -1070,8 +1067,6 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
is_startpoint = false;
}

// Add setup/hold time as final segment
// And add hold time as min bound
if (register_end) {
CriticalPath::Segment seg_logic;
seg_logic.delay = DelayPair(0);
Expand All @@ -1086,8 +1081,6 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
seg_logic.to = seg_logic.from;
seg_logic.net = IdString();
report.segments.push_back(seg_logic);

report.bound.min_delay = ep_clk_info.hold.min_delay;
}

return report;
Expand Down Expand Up @@ -1244,8 +1237,7 @@ std::vector<CriticalPath> TimingAnalyser::get_min_delay_violations()
auto clocks = std::make_pair(launch_clock, capture_clock);
auto related_clocks = clock_delays.count(clocks) > 0;

// Don't consider async paths and clocks without known relationships
if (launch_id == async_clock_id && launch_id != capture_id && !related_clocks) {
if (launch_id == async_clock_id || (launch_id != capture_id && !related_clocks)) {
continue;
}

Expand Down
12 changes: 6 additions & 6 deletions common/kernel/timing_log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ static void log_crit_paths(const Context *ctx, TimingResult &result)
// 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 hold_violation = path.delay.minDelay() < path.bound.minDelay();
auto get_delay_ns = [hold_violation, ctx](const DelayPair &d) {
if (hold_violation) {
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());
Expand Down Expand Up @@ -180,16 +180,16 @@ static void log_crit_paths(const Context *ctx, TimingResult &result)
auto num_min_violations = result.min_delay_violations.size();
if (num_min_violations > 0) {
log_break();
log_info("Hold time/min time violation:\n");
log_info("Hold time/min time violations:\n");
for (size_t i = 0; i < std::min((size_t)10, num_min_violations); ++i) {
auto &report = result.min_delay_violations.at(i);
log_break();
std::string start = clock_event_name(ctx, report.clock_pair.start);
std::string end = clock_event_name(ctx, report.clock_pair.end);
if (report.clock_pair.start == report.clock_pair.end) {
log_nonfatal_error("Hold time violations for clock '%s':\n", start.c_str());
log_nonfatal_error("Hold time violation for clock '%s':\n", start.c_str());
} else {
log_nonfatal_error("Hold time violations for path '%s' -> '%s':\n", start.c_str(), end.c_str());
log_nonfatal_error("Hold time violation for path '%s' -> '%s':\n", start.c_str(), end.c_str());
}
print_path_report(report);
}
Expand Down

0 comments on commit 3aedaf1

Please sign in to comment.