timing: minor cleanup and stupid mistake fixups
This commit is contained in:
parent
bca6f6394a
commit
a7f79fd681
@ -447,11 +447,11 @@ struct CriticalPath
|
|||||||
// Clock pair
|
// Clock pair
|
||||||
ClockPair clock_pair;
|
ClockPair clock_pair;
|
||||||
// Total path delay
|
// 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;
|
DelayPair delay;
|
||||||
|
|
||||||
// if delay.minDelay() < bound.minDelay() then this is a hold violation
|
delay_t max_delay;
|
||||||
// if delay.maxDelay() > bound.maxDelay() then this is a setup violation
|
|
||||||
DelayPair bound;
|
|
||||||
|
|
||||||
// Individual path segments
|
// Individual path segments
|
||||||
std::vector<Segment> segments;
|
std::vector<Segment> segments;
|
||||||
|
@ -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.clock = capture.clock;
|
||||||
report.clock_pair.end.edge = capture.edge;
|
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) {
|
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.is_async() && ctx->nets.at(launch.clock)->clkconstr) {
|
||||||
if (launch.edge == capture.edge) {
|
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) {
|
} 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) {
|
} 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_rev = walk_crit_path(domain_pair, endpoint, longest_path);
|
||||||
auto crit_path = boost::adaptors::reverse(crit_path_rev);
|
auto crit_path = boost::adaptors::reverse(crit_path_rev);
|
||||||
|
|
||||||
@ -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)) {
|
if (with_clock_skew && register_start && register_end && (same_clock || related_clock)) {
|
||||||
|
|
||||||
auto clock_delay_launch =
|
auto clock_delay_launch =
|
||||||
@ -1070,8 +1067,6 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
|
|||||||
is_startpoint = false;
|
is_startpoint = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add setup/hold time as final segment
|
|
||||||
// And add hold time as min bound
|
|
||||||
if (register_end) {
|
if (register_end) {
|
||||||
CriticalPath::Segment seg_logic;
|
CriticalPath::Segment seg_logic;
|
||||||
seg_logic.delay = DelayPair(0);
|
seg_logic.delay = DelayPair(0);
|
||||||
@ -1086,8 +1081,6 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
|
|||||||
seg_logic.to = seg_logic.from;
|
seg_logic.to = seg_logic.from;
|
||||||
seg_logic.net = IdString();
|
seg_logic.net = IdString();
|
||||||
report.segments.push_back(seg_logic);
|
report.segments.push_back(seg_logic);
|
||||||
|
|
||||||
report.bound.min_delay = ep_clk_info.hold.min_delay;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return report;
|
return report;
|
||||||
@ -1244,8 +1237,7 @@ std::vector<CriticalPath> TimingAnalyser::get_min_delay_violations()
|
|||||||
auto clocks = std::make_pair(launch_clock, capture_clock);
|
auto clocks = std::make_pair(launch_clock, capture_clock);
|
||||||
auto related_clocks = clock_delays.count(clocks) > 0;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
// 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
|
// But if we know this critical path has violated hold time we print the
|
||||||
// min delay instead
|
// min delay instead
|
||||||
bool hold_violation = path.delay.minDelay() < path.bound.minDelay();
|
bool min_delay_violation = path.delay.minDelay() < 0;
|
||||||
auto get_delay_ns = [hold_violation, ctx](const DelayPair &d) {
|
auto get_delay_ns = [min_delay_violation, ctx](const DelayPair &d) {
|
||||||
if (hold_violation) {
|
if (min_delay_violation) {
|
||||||
ctx->getDelayNS(d.minDelay());
|
ctx->getDelayNS(d.minDelay());
|
||||||
}
|
}
|
||||||
return ctx->getDelayNS(d.maxDelay());
|
return ctx->getDelayNS(d.maxDelay());
|
||||||
@ -180,16 +180,16 @@ static void log_crit_paths(const Context *ctx, TimingResult &result)
|
|||||||
auto num_min_violations = result.min_delay_violations.size();
|
auto num_min_violations = result.min_delay_violations.size();
|
||||||
if (num_min_violations > 0) {
|
if (num_min_violations > 0) {
|
||||||
log_break();
|
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) {
|
for (size_t i = 0; i < std::min((size_t)10, num_min_violations); ++i) {
|
||||||
auto &report = result.min_delay_violations.at(i);
|
auto &report = result.min_delay_violations.at(i);
|
||||||
log_break();
|
log_break();
|
||||||
std::string start = clock_event_name(ctx, report.clock_pair.start);
|
std::string start = clock_event_name(ctx, report.clock_pair.start);
|
||||||
std::string end = clock_event_name(ctx, report.clock_pair.end);
|
std::string end = clock_event_name(ctx, report.clock_pair.end);
|
||||||
if (report.clock_pair.start == 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 {
|
} 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);
|
print_path_report(report);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user