blob: 1569aa6d704014a3171cad8a0c77e447a3d36783 [file]
#ifndef TATUM_TIMING_REPORTER_HPP
#define TATUM_TIMING_REPORTER_HPP
#include <iosfwd>
#include "tatum/TimingGraphFwd.hpp"
#include "tatum/TimingConstraintsFwd.hpp"
#include "tatum/timing_analyzers.hpp"
#include "tatum/TimingGraphNameResolver.hpp"
#include "tatum/report/TimingPath.hpp"
#include "tatum/report/TimingPathCollector.hpp"
#include "tatum/report/TimingReportTagRetriever.hpp"
namespace tatum { namespace detail {
float convert_to_printable_units(float value, float unit_scale);
std::string to_printable_string(tatum::Time val, float unit_scale, size_t precision);
//Helper class to track path state and formatting while writing timing path reports
class ReportTimingPathHelper {
public:
ReportTimingPathHelper(float unit_scale, size_t precision, size_t point_width=60, size_t incr_width=10, size_t path_width=10)
: unit_scale_(unit_scale)
, precision_(precision)
, point_width_(point_width)
, incr_width_(incr_width)
, path_width_(path_width) {}
void update_print_path(std::ostream& os, std::string point, tatum::Time path);
void update_print_path_no_incr(std::ostream& os, std::string point, tatum::Time path);
void reset_path();
void print_path_line_no_incr(std::ostream& os, std::string point, tatum::Time path) const;
void print_path_line(std::ostream& os, std::string point, std::string incr, std::string path) const;
void print_divider(std::ostream& os) const;
private:
float unit_scale_;
size_t precision_;
size_t point_width_;
size_t incr_width_;
size_t path_width_;
tatum::Time prev_path_ = tatum::Time(0.);
};
}} //namespace
namespace tatum {
constexpr size_t REPORT_TIMING_DEFAULT_NPATHS=100;
//A class for generating timing reports
class TimingReporter {
public:
TimingReporter(const TimingGraphNameResolver& name_resolver,
const tatum::TimingGraph& timing_graph,
const tatum::TimingConstraints& timing_constraints,
float unit_scale=1e-9,
size_t precision=3);
public:
void report_timing_setup(std::string filename, const tatum::SetupTimingAnalyzer& setup_analyzer, size_t npaths=REPORT_TIMING_DEFAULT_NPATHS) const;
void report_timing_setup(std::ostream& os, const tatum::SetupTimingAnalyzer& setup_analyzer, size_t npaths=REPORT_TIMING_DEFAULT_NPATHS) const;
void report_timing_hold(std::string filename, const tatum::HoldTimingAnalyzer& hold_analyzer, size_t npaths=REPORT_TIMING_DEFAULT_NPATHS) const;
void report_timing_hold(std::ostream& os, const tatum::HoldTimingAnalyzer& hold_analyzer, size_t npaths=REPORT_TIMING_DEFAULT_NPATHS) const;
void report_skew_setup(std::string filename, const tatum::SetupTimingAnalyzer& setup_analyzer, size_t nworst=REPORT_TIMING_DEFAULT_NPATHS) const;
void report_skew_setup(std::ostream& os, const tatum::SetupTimingAnalyzer& setup_analyzer, size_t nworst=REPORT_TIMING_DEFAULT_NPATHS) const;
void report_skew_hold(std::string filename, const tatum::HoldTimingAnalyzer& hold_analyzer, size_t nworst=REPORT_TIMING_DEFAULT_NPATHS) const;
void report_skew_hold(std::ostream& os, const tatum::HoldTimingAnalyzer& hold_analyzer, size_t nworst=REPORT_TIMING_DEFAULT_NPATHS) const;
void report_unconstrained_setup(std::string filename, const tatum::SetupTimingAnalyzer& setup_analyzer) const;
void report_unconstrained_setup(std::ostream& os, const tatum::SetupTimingAnalyzer& setup_analyzer) const;
void report_unconstrained_hold(std::string filename, const tatum::HoldTimingAnalyzer& hold_analyzer) const;
void report_unconstrained_hold(std::ostream& os, const tatum::HoldTimingAnalyzer& hold_analyzer) const;
private:
struct PathSkew {
NodeId launch_node;
NodeId capture_node;
DomainId launch_domain;
DomainId capture_domain;
Time clock_launch;
Time clock_capture;
Time clock_capture_normalized;
Time clock_constraint;
Time clock_skew;
};
private:
void report_timing(std::ostream& os, const std::vector<TimingPath>& paths) const;
void report_timing_path(std::ostream& os, const TimingPath& path) const;
void report_unconstrained(std::ostream& os, const NodeType type, const detail::TagRetriever& tag_retriever) const;
void report_skew(std::ostream& os, const std::vector<SkewPath>& paths, TimingType timing_type) const;
void report_skew_path(std::ostream& os, const SkewPath& skew_path, TimingType timing_type) const;
Time report_timing_clock_launch_subpath(std::ostream& os,
detail::ReportTimingPathHelper& path_helper,
const TimingSubPath& subpath,
DomainId domain,
TimingType timing_type) const;
Time report_timing_clock_capture_subpath(std::ostream& os,
detail::ReportTimingPathHelper& path_helper,
const TimingSubPath& subpath,
DomainId launch_domain,
DomainId capture_domain,
NodeId capture_node,
TimingType timing_type) const;
Time report_timing_data_arrival_subpath(std::ostream& os,
detail::ReportTimingPathHelper& path_helper,
const TimingSubPath& subpath,
DomainId domain,
TimingType timing_type,
Time path) const;
Time report_timing_data_required_element(std::ostream& os,
detail::ReportTimingPathHelper& path_helper,
const TimingPathElem& data_required_elem,
DomainId capture_domain,
TimingType timing_type,
Time path) const;
//Reports clock latency and path (caller should handle rising edge)
Time report_timing_clock_subpath(std::ostream& os,
detail::ReportTimingPathHelper& path_helper,
const TimingSubPath& subpath,
DomainId domain,
TimingType timing_type,
Time path,
Time offset) const;
bool nearly_equal(const tatum::Time& lhs, const tatum::Time& rhs) const;
size_t estimate_point_print_width(const TimingPath& path) const;
private:
const TimingGraphNameResolver& name_resolver_;
const TimingGraph& timing_graph_;
const TimingConstraints& timing_constraints_;
float unit_scale_ = 1e-9;
size_t precision_ = 3;
float relative_error_tolerance_ = 1.e-5;
float absolute_error_tolerance_ = 1e-13; //Sub pico-second
TimingPathCollector path_collector_;
};
} //namespace
#endif