Formatting and display async path in json report
This commit is contained in:
parent
cfd3a52a3c
commit
b0820eeaaa
@ -48,9 +48,12 @@ TimingAnalyser::TimingAnalyser(Context *ctx) : ctx(ctx)
|
|||||||
domain_to_id.emplace(key, 0);
|
domain_to_id.emplace(key, 0);
|
||||||
domains.emplace_back(key);
|
domains.emplace_back(key);
|
||||||
async_clock_id = 0;
|
async_clock_id = 0;
|
||||||
|
|
||||||
|
domain_pair_id(async_clock_id, async_clock_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
void TimingAnalyser::setup(bool update_net_timings, bool update_histogram, bool update_crit_paths, bool update_route_delays)
|
void TimingAnalyser::setup(bool update_net_timings, bool update_histogram, bool update_crit_paths,
|
||||||
|
bool update_route_delays)
|
||||||
{
|
{
|
||||||
init_ports();
|
init_ports();
|
||||||
get_cell_delays();
|
get_cell_delays();
|
||||||
@ -60,7 +63,8 @@ void TimingAnalyser::setup(bool update_net_timings, bool update_histogram, bool
|
|||||||
run(update_net_timings, update_histogram, update_crit_paths, update_route_delays);
|
run(update_net_timings, update_histogram, update_crit_paths, update_route_delays);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimingAnalyser::run(bool update_net_timings, bool update_histogram, bool update_crit_paths, bool update_route_delays)
|
void TimingAnalyser::run(bool update_net_timings, bool update_histogram, bool update_crit_paths,
|
||||||
|
bool update_route_delays)
|
||||||
{
|
{
|
||||||
reset_times();
|
reset_times();
|
||||||
if (update_route_delays)
|
if (update_route_delays)
|
||||||
@ -757,21 +761,11 @@ void TimingAnalyser::build_detailed_net_timing_report()
|
|||||||
auto &capture = domains.at(req.first).key;
|
auto &capture = domains.at(req.first).key;
|
||||||
|
|
||||||
NetSinkTiming sink_timing;
|
NetSinkTiming sink_timing;
|
||||||
sink_timing.clock_pair = ClockPair {
|
sink_timing.clock_pair = ClockPair{.start = ClockEvent{.clock = launch.clock, .edge = launch.edge},
|
||||||
.start = ClockEvent {
|
.end = ClockEvent{.clock = capture.clock, .edge = capture.edge}};
|
||||||
.clock = launch.clock,
|
|
||||||
.edge = launch.edge
|
|
||||||
},
|
|
||||||
.end = ClockEvent {
|
|
||||||
.clock = capture.clock,
|
|
||||||
.edge = capture.edge
|
|
||||||
}
|
|
||||||
};
|
|
||||||
sink_timing.cell_port = std::make_pair(pd.cell_port.cell, pd.cell_port.port);
|
sink_timing.cell_port = std::make_pair(pd.cell_port.cell, pd.cell_port.port);
|
||||||
sink_timing.delay = arr.second.value.max_delay;
|
sink_timing.delay = arr.second.value.max_delay;
|
||||||
|
|
||||||
log_info("update net_timings: %s: %f\n", net->name.c_str(ctx), (float) sink_timing.delay);
|
|
||||||
|
|
||||||
net_timings[net->name].push_back(sink_timing);
|
net_timings[net->name].push_back(sink_timing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -806,6 +800,32 @@ std::vector<CellPortKey> TimingAnalyser::get_worst_eps(domain_id_t domain_pair,
|
|||||||
return worst_eps;
|
return worst_eps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string tgp_to_string(TimingPortClass c)
|
||||||
|
{
|
||||||
|
switch (c) {
|
||||||
|
case TMG_CLOCK_INPUT:
|
||||||
|
return "TMG_CLOCK_INPUT";
|
||||||
|
case TMG_GEN_CLOCK:
|
||||||
|
return "TMG_GEN_CLOCK";
|
||||||
|
case TMG_REGISTER_INPUT:
|
||||||
|
return "TMG_REGISTER_INPUT";
|
||||||
|
case TMG_REGISTER_OUTPUT:
|
||||||
|
return "TMG_REGISTER_OUTPUT";
|
||||||
|
case TMG_COMB_INPUT:
|
||||||
|
return "TMG_COMB_INPUT";
|
||||||
|
case TMG_COMB_OUTPUT:
|
||||||
|
return "TMG_COMB_OUTPUT";
|
||||||
|
case TMG_STARTPOINT:
|
||||||
|
return "TMG_STARTPOINT";
|
||||||
|
case TMG_ENDPOINT:
|
||||||
|
return "TMG_ENDPOINT";
|
||||||
|
case TMG_IGNORE:
|
||||||
|
return "TMG_IGNORE";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
CriticalPath report;
|
CriticalPath report;
|
||||||
@ -814,16 +834,8 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
|
|||||||
auto &launch = domains.at(dp.key.launch).key;
|
auto &launch = domains.at(dp.key.launch).key;
|
||||||
auto &capture = domains.at(dp.key.capture).key;
|
auto &capture = domains.at(dp.key.capture).key;
|
||||||
|
|
||||||
report.clock_pair = ClockPair {
|
report.clock_pair = ClockPair{.start = ClockEvent{.clock = launch.clock, .edge = launch.edge},
|
||||||
.start = ClockEvent {
|
.end = ClockEvent{.clock = capture.clock, .edge = capture.edge}};
|
||||||
.clock = launch.clock,
|
|
||||||
.edge = launch.edge
|
|
||||||
},
|
|
||||||
.end = ClockEvent {
|
|
||||||
.clock = capture.clock,
|
|
||||||
.edge = capture.edge
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
report.period = ctx->getDelayFromNS(1.0e9 / ctx->setting<float>("target_freq"));
|
report.period = ctx->getDelayFromNS(1.0e9 / ctx->setting<float>("target_freq"));
|
||||||
if (launch.edge != capture.edge) {
|
if (launch.edge != capture.edge) {
|
||||||
@ -842,6 +854,8 @@ 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;
|
||||||
|
|
||||||
|
log_info("Analyzing %s -> %s\n", clock_event_name(ctx, launch).c_str(), clock_event_name(ctx, capture).c_str());
|
||||||
while (cursor != CellPortKey()) {
|
while (cursor != CellPortKey()) {
|
||||||
auto cell = cell_info(cursor);
|
auto cell = cell_info(cursor);
|
||||||
auto &port = port_info(cursor);
|
auto &port = port_info(cursor);
|
||||||
@ -849,11 +863,10 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
|
|||||||
int port_clocks;
|
int port_clocks;
|
||||||
auto portClass = ctx->getPortTimingClass(cell, port.name, port_clocks);
|
auto portClass = ctx->getPortTimingClass(cell, port.name, port_clocks);
|
||||||
|
|
||||||
if (portClass != TMG_CLOCK_INPUT &&
|
log_info("\tcursor at %s.%s tmg: %s, port dir: %s\n", cell->name.c_str(ctx), port.name.c_str(ctx),
|
||||||
portClass != TMG_ENDPOINT &&
|
tgp_to_string(portClass).c_str(), port.type == PortType::PORT_IN ? "PORT_IN" : "PORT_X");
|
||||||
portClass != TMG_IGNORE &&
|
|
||||||
port.type == PortType::PORT_IN)
|
if (portClass != TMG_CLOCK_INPUT && portClass != TMG_IGNORE && port.type == PortType::PORT_IN) {
|
||||||
{
|
|
||||||
crit_path_rev.emplace_back(PortRef{cell, port.name});
|
crit_path_rev.emplace_back(PortRef{cell, port.name});
|
||||||
}
|
}
|
||||||
if (!ports.at(cursor).arrival.count(dp.key.launch))
|
if (!ports.at(cursor).arrival.count(dp.key.launch))
|
||||||
@ -959,15 +972,8 @@ void TimingAnalyser::build_crit_path_reports()
|
|||||||
|
|
||||||
auto delay_by_domain = max_delay_by_domain_pairs();
|
auto delay_by_domain = max_delay_by_domain_pairs();
|
||||||
|
|
||||||
auto uq_doms = ctx->timing_result.empty_paths;
|
for (int i = 0; i < int(domains.size()); i++) {
|
||||||
auto clock_pairs = std::vector<std::pair<ClockDomainKey, ClockDomainKey>>();
|
empty_clocks.insert(domains.at(i).key.clock);
|
||||||
|
|
||||||
for (int i = 0; i < int(domain_pairs.size()); i++) {
|
|
||||||
auto &dp = domain_pairs.at(i);
|
|
||||||
auto &launch = domains.at(dp.key.launch).key;
|
|
||||||
auto &capture = domains.at(dp.key.capture).key;
|
|
||||||
|
|
||||||
clock_pairs.emplace_back(std::make_pair(launch, capture));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < int(domain_pairs.size()); i++) {
|
for (int i = 0; i < int(domain_pairs.size()); i++) {
|
||||||
@ -1005,9 +1011,15 @@ void TimingAnalyser::build_crit_path_reports()
|
|||||||
auto &launch = domains.at(dp.key.launch).key;
|
auto &launch = domains.at(dp.key.launch).key;
|
||||||
auto &capture = domains.at(dp.key.capture).key;
|
auto &capture = domains.at(dp.key.capture).key;
|
||||||
|
|
||||||
if (launch.clock == capture.clock)
|
log_info("testin testing %s -> %s\n", clock_event_name(ctx, launch).c_str(),
|
||||||
|
clock_event_name(ctx, capture).c_str());
|
||||||
|
|
||||||
|
if (launch.clock == capture.clock && !launch.is_async())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
log_info("testin testing2 %s -> %s\n", clock_event_name(ctx, launch).c_str(),
|
||||||
|
clock_event_name(ctx, capture).c_str());
|
||||||
|
|
||||||
auto worst_endpoint = get_worst_eps(i, 1).at(0);
|
auto worst_endpoint = get_worst_eps(i, 1).at(0);
|
||||||
xclock_reports.emplace_back(build_critical_path_report(i, worst_endpoint));
|
xclock_reports.emplace_back(build_critical_path_report(i, worst_endpoint));
|
||||||
}
|
}
|
||||||
|
@ -411,8 +411,6 @@ struct Timing
|
|||||||
for (auto crit_pair : crit_nets) {
|
for (auto crit_pair : crit_nets) {
|
||||||
NetInfo *crit_net = crit_pair.second.second;
|
NetInfo *crit_net = crit_pair.second.second;
|
||||||
auto &cp_ports = (*crit_path)[crit_pair.first].ports;
|
auto &cp_ports = (*crit_path)[crit_pair.first].ports;
|
||||||
log_info("// Walk backwards from the most critical net, start point: %s.%s\n",
|
|
||||||
cp_ports.at(0)->cell->name.c_str(ctx), cp_ports.at(0)->port.c_str(ctx));
|
|
||||||
while (crit_net) {
|
while (crit_net) {
|
||||||
const PortInfo *crit_ipin = nullptr;
|
const PortInfo *crit_ipin = nullptr;
|
||||||
delay_t max_arrival = std::numeric_limits<delay_t>::min();
|
delay_t max_arrival = std::numeric_limits<delay_t>::min();
|
||||||
@ -454,9 +452,7 @@ struct Timing
|
|||||||
break;
|
break;
|
||||||
// Now convert PortInfo* into a PortRef*
|
// Now convert PortInfo* into a PortRef*
|
||||||
for (auto &usr : crit_ipin->net->users) {
|
for (auto &usr : crit_ipin->net->users) {
|
||||||
log_info("critical pin user: %s.%s\n", usr.cell->name.c_str(ctx), usr.port.c_str(ctx));
|
|
||||||
if (usr.cell->name == crit_net->driver.cell->name && usr.port == crit_ipin->name) {
|
if (usr.cell->name == crit_net->driver.cell->name && usr.port == crit_ipin->name) {
|
||||||
log_info("Adding %s.%s to critical path\n", usr.cell->name.c_str(ctx), usr.port.c_str(ctx));
|
|
||||||
cp_ports.push_back(&usr);
|
cp_ports.push_back(&usr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -470,32 +466,6 @@ struct Timing
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string tgp_to_string(TimingPortClass c)
|
|
||||||
{
|
|
||||||
switch (c) {
|
|
||||||
case TMG_CLOCK_INPUT:
|
|
||||||
return "TMG_CLOCK_INPUT";
|
|
||||||
case TMG_GEN_CLOCK:
|
|
||||||
return "TMG_GEN_CLOCK";
|
|
||||||
case TMG_REGISTER_INPUT:
|
|
||||||
return "TMG_REGISTER_INPUT";
|
|
||||||
case TMG_REGISTER_OUTPUT:
|
|
||||||
return "TMG_REGISTER_OUTPUT";
|
|
||||||
case TMG_COMB_INPUT:
|
|
||||||
return "TMG_COMB_INPUT";
|
|
||||||
case TMG_COMB_OUTPUT:
|
|
||||||
return "TMG_COMB_OUTPUT";
|
|
||||||
case TMG_STARTPOINT:
|
|
||||||
return "TMG_STARTPOINT";
|
|
||||||
case TMG_ENDPOINT:
|
|
||||||
return "TMG_ENDPOINT";
|
|
||||||
case TMG_IGNORE:
|
|
||||||
return "TMG_IGNORE";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
|
||||||
|
|
||||||
CriticalPath build_critical_path_report(Context *ctx, ClockPair &clocks, const PortRefVector &crit_path)
|
CriticalPath build_critical_path_report(Context *ctx, ClockPair &clocks, const PortRefVector &crit_path)
|
||||||
{
|
{
|
||||||
CriticalPath report;
|
CriticalPath report;
|
||||||
@ -524,9 +494,6 @@ CriticalPath build_critical_path_report(Context *ctx, ClockPair &clocks, const P
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("building critical path report for clocks: %s -> %s\n", clocks.start.clock.c_str(ctx),
|
|
||||||
clocks.end.clock.c_str(ctx));
|
|
||||||
|
|
||||||
for (auto sink : crit_path) {
|
for (auto sink : crit_path) {
|
||||||
|
|
||||||
auto sink_cell = sink->cell;
|
auto sink_cell = sink->cell;
|
||||||
@ -645,7 +612,6 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
|
|||||||
const ClockEvent &b = path.first.end;
|
const ClockEvent &b = path.first.end;
|
||||||
empty_clocks.insert(a.clock);
|
empty_clocks.insert(a.clock);
|
||||||
empty_clocks.insert(b.clock);
|
empty_clocks.insert(b.clock);
|
||||||
log_info("timing_old: clock pair: %s -> %s\n", a.clock.c_str(ctx), b.clock.c_str(ctx));
|
|
||||||
}
|
}
|
||||||
for (auto path : crit_paths) {
|
for (auto path : crit_paths) {
|
||||||
const ClockEvent &a = path.first.start;
|
const ClockEvent &a = path.first.start;
|
||||||
@ -1018,14 +984,6 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
|
|||||||
(bins[i] * bar_width) % max_freq > 0 ? '+' : ' ');
|
(bins[i] * bar_width) % max_freq > 0 ? '+' : ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("segments");
|
|
||||||
for (auto &r : clock_reports) {
|
|
||||||
log_info("clock: %s\n", r.first.c_str(ctx));
|
|
||||||
for (const auto &segment : r.second.segments) {
|
|
||||||
log_info("processing segment %s\n", segment.net.c_str(ctx));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update timing results in the context
|
// Update timing results in the context
|
||||||
if (update_results) {
|
if (update_results) {
|
||||||
auto &results = ctx->timing_result;
|
auto &results = ctx->timing_result;
|
||||||
|
@ -79,8 +79,7 @@ static void log_crit_paths(const Context *ctx)
|
|||||||
segment.type == CriticalPath::Segment::Type::SETUP) {
|
segment.type == CriticalPath::Segment::Type::SETUP) {
|
||||||
logic_total += segment.delay;
|
logic_total += segment.delay;
|
||||||
|
|
||||||
const std::string type_name =
|
const std::string type_name = (segment.type == CriticalPath::Segment::Type::SETUP) ? "Setup" : "Source";
|
||||||
(segment.type == CriticalPath::Segment::Type::SETUP) ? "Setup" : "Source";
|
|
||||||
|
|
||||||
log_info("%4.1f %4.1f %s %s.%s\n", ctx->getDelayNS(segment.delay), ctx->getDelayNS(total),
|
log_info("%4.1f %4.1f %s %s.%s\n", ctx->getDelayNS(segment.delay), ctx->getDelayNS(total),
|
||||||
type_name.c_str(), segment.to.first.c_str(ctx), segment.to.second.c_str(ctx));
|
type_name.c_str(), segment.to.first.c_str(ctx), segment.to.second.c_str(ctx));
|
||||||
@ -94,8 +93,8 @@ static void log_crit_paths(const Context *ctx)
|
|||||||
auto sink_loc = ctx->getBelLocation(sink->bel);
|
auto sink_loc = ctx->getBelLocation(sink->bel);
|
||||||
|
|
||||||
log_info("%4.1f %4.1f Net %s (%d,%d) -> (%d,%d)\n", ctx->getDelayNS(segment.delay),
|
log_info("%4.1f %4.1f Net %s (%d,%d) -> (%d,%d)\n", ctx->getDelayNS(segment.delay),
|
||||||
ctx->getDelayNS(total), segment.net.c_str(ctx),
|
ctx->getDelayNS(total), segment.net.c_str(ctx), driver_loc.x, driver_loc.y, sink_loc.x,
|
||||||
driver_loc.x, driver_loc.y, sink_loc.x, sink_loc.y);
|
sink_loc.y);
|
||||||
log_info(" Sink %s.%s\n", segment.to.first.c_str(ctx), segment.to.second.c_str(ctx));
|
log_info(" Sink %s.%s\n", segment.to.first.c_str(ctx), segment.to.second.c_str(ctx));
|
||||||
|
|
||||||
const NetInfo *net = ctx->nets.at(segment.net).get();
|
const NetInfo *net = ctx->nets.at(segment.net).get();
|
||||||
@ -139,8 +138,8 @@ static void log_crit_paths(const Context *ctx)
|
|||||||
// Single domain paths
|
// Single domain paths
|
||||||
for (auto &clock : ctx->timing_result.clock_paths) {
|
for (auto &clock : ctx->timing_result.clock_paths) {
|
||||||
log_break();
|
log_break();
|
||||||
std::string start = clock.second.clock_pair.start.edge == FALLING_EDGE ? std::string("negedge")
|
std::string start =
|
||||||
: std::string("posedge");
|
clock.second.clock_pair.start.edge == FALLING_EDGE ? std::string("negedge") : std::string("posedge");
|
||||||
std::string end =
|
std::string end =
|
||||||
clock.second.clock_pair.end.edge == FALLING_EDGE ? std::string("negedge") : std::string("posedge");
|
clock.second.clock_pair.end.edge == FALLING_EDGE ? std::string("negedge") : std::string("posedge");
|
||||||
log_info("Critical path report for clock '%s' (%s -> %s):\n", clock.first.c_str(ctx), start.c_str(),
|
log_info("Critical path report for clock '%s' (%s -> %s):\n", clock.first.c_str(ctx), start.c_str(),
|
||||||
@ -176,18 +175,17 @@ static void log_fmax(Context *ctx, bool warn_on_failure)
|
|||||||
bool passed = target < fmax;
|
bool passed = target < fmax;
|
||||||
|
|
||||||
if (!warn_on_failure || passed)
|
if (!warn_on_failure || passed)
|
||||||
log_info("Max frequency for clock %*s'%s': %.02f MHz (%s at %.02f MHz)\n", width, "",
|
log_info("Max frequency for clock %*s'%s': %.02f MHz (%s at %.02f MHz)\n", width, "", clock_name.c_str(),
|
||||||
clock_name.c_str(), fmax, passed ? "PASS" : "FAIL", target);
|
fmax, passed ? "PASS" : "FAIL", target);
|
||||||
else if (bool_or_default(ctx->settings, ctx->id("timing/allowFail"), false))
|
else if (bool_or_default(ctx->settings, ctx->id("timing/allowFail"), false))
|
||||||
log_warning("Max frequency for clock %*s'%s': %.02f MHz (%s at %.02f MHz)\n", width, "",
|
log_warning("Max frequency for clock %*s'%s': %.02f MHz (%s at %.02f MHz)\n", width, "", clock_name.c_str(),
|
||||||
clock_name.c_str(), fmax, passed ? "PASS" : "FAIL", target);
|
fmax, passed ? "PASS" : "FAIL", target);
|
||||||
else
|
else
|
||||||
log_nonfatal_error("Max frequency for clock %*s'%s': %.02f MHz (%s at %.02f MHz)\n", width, "",
|
log_nonfatal_error("Max frequency for clock %*s'%s': %.02f MHz (%s at %.02f MHz)\n", width, "",
|
||||||
clock_name.c_str(), fmax, passed ? "PASS" : "FAIL", target);
|
clock_name.c_str(), fmax, passed ? "PASS" : "FAIL", target);
|
||||||
}
|
}
|
||||||
log_break();
|
log_break();
|
||||||
|
|
||||||
|
|
||||||
// Clock to clock delays for xpaths
|
// Clock to clock delays for xpaths
|
||||||
dict<ClockPair, delay_t> xclock_delays;
|
dict<ClockPair, delay_t> xclock_delays;
|
||||||
for (auto &report : ctx->timing_result.xclock_paths) {
|
for (auto &report : ctx->timing_result.xclock_paths) {
|
||||||
@ -256,12 +254,12 @@ static void log_fmax(Context *ctx, bool warn_on_failure)
|
|||||||
auto ev_b = clock_event_name(ctx, report.clock_pair.end, max_width_xcb);
|
auto ev_b = clock_event_name(ctx, report.clock_pair.end, max_width_xcb);
|
||||||
|
|
||||||
if (!warn_on_failure || passed)
|
if (!warn_on_failure || passed)
|
||||||
log_info("Max frequency for %s -> %s: %.02f MHz (%s at %.02f MHz)\n", ev_a.c_str(), ev_b.c_str(),
|
log_info("Max frequency for %s -> %s: %.02f MHz (%s at %.02f MHz)\n", ev_a.c_str(), ev_b.c_str(), fmax,
|
||||||
fmax, passed ? "PASS" : "FAIL", target);
|
passed ? "PASS" : "FAIL", target);
|
||||||
else if (bool_or_default(ctx->settings, ctx->id("timing/allowFail"), false) ||
|
else if (bool_or_default(ctx->settings, ctx->id("timing/allowFail"), false) ||
|
||||||
bool_or_default(ctx->settings, ctx->id("timing/ignoreRelClk"), false))
|
bool_or_default(ctx->settings, ctx->id("timing/ignoreRelClk"), false))
|
||||||
log_warning("Max frequency for %s -> %s: %.02f MHz (%s at %.02f MHz)\n", ev_a.c_str(),
|
log_warning("Max frequency for %s -> %s: %.02f MHz (%s at %.02f MHz)\n", ev_a.c_str(), ev_b.c_str(),
|
||||||
ev_b.c_str(), fmax, passed ? "PASS" : "FAIL", target);
|
fmax, passed ? "PASS" : "FAIL", target);
|
||||||
else
|
else
|
||||||
log_nonfatal_error("Max frequency for %s -> %s: %.02f MHz (%s at %.02f MHz)\n", ev_a.c_str(),
|
log_nonfatal_error("Max frequency for %s -> %s: %.02f MHz (%s at %.02f MHz)\n", ev_a.c_str(),
|
||||||
ev_b.c_str(), fmax, passed ? "PASS" : "FAIL", target);
|
ev_b.c_str(), fmax, passed ? "PASS" : "FAIL", target);
|
||||||
@ -280,8 +278,7 @@ static void log_fmax(Context *ctx, bool warn_on_failure)
|
|||||||
delay /= 2;
|
delay /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("Clock to clock delay %s -> %s: %0.02f ns\n", ev_a.c_str(), ev_b.c_str(),
|
log_info("Clock to clock delay %s -> %s: %0.02f ns\n", ev_a.c_str(), ev_b.c_str(), ctx->getDelayNS(delay));
|
||||||
ctx->getDelayNS(delay));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log_break();
|
log_break();
|
||||||
@ -312,7 +309,16 @@ static void log_fmax(Context *ctx, bool warn_on_failure)
|
|||||||
log_break();
|
log_break();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_histogram(Context *ctx) {
|
static void log_histogram(Context *ctx)
|
||||||
|
{
|
||||||
|
log_break();
|
||||||
|
log_info("Slack histogram:\n");
|
||||||
|
|
||||||
|
if (ctx->timing_result.slack_histogram.empty()) {
|
||||||
|
log_info(" No slack figures available\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned num_bins = 20;
|
unsigned num_bins = 20;
|
||||||
unsigned bar_width = 60;
|
unsigned bar_width = 60;
|
||||||
|
|
||||||
@ -341,8 +347,6 @@ static void log_histogram(Context *ctx) {
|
|||||||
}
|
}
|
||||||
bar_width = std::min(bar_width, max_freq);
|
bar_width = std::min(bar_width, max_freq);
|
||||||
|
|
||||||
log_break();
|
|
||||||
log_info("Slack histogram:\n");
|
|
||||||
log_info(" legend: * represents %d endpoint(s)\n", max_freq / bar_width);
|
log_info(" legend: * represents %d endpoint(s)\n", max_freq / bar_width);
|
||||||
log_info(" + represents [1,%d) endpoint(s)\n", max_freq / bar_width);
|
log_info(" + represents [1,%d) endpoint(s)\n", max_freq / bar_width);
|
||||||
for (unsigned i = 0; i < num_bins; ++i)
|
for (unsigned i = 0; i < num_bins; ++i)
|
||||||
|
Loading…
Reference in New Issue
Block a user