blob: 427a6b62887f1c82a77ff7addb16e8fd56c9c051 [file] [log] [blame]
#ifndef VPR_TIMING_INFO_H
#define VPR_TIMING_INFO_H
#include <memory>
#include "timing_info_fwd.h"
#include "tatum/analyzer_factory.hpp"
#include "tatum/timing_paths.hpp"
#include "timing_util.h"
//Create a SetupTimingInfo for the given delay calculator
template<class DelayCalc>
std::unique_ptr<SetupTimingInfo> make_setup_timing_info(std::shared_ptr<DelayCalc> delay_calculator);
//Create a HoldTimingInfo for the given delay calculator
template<class DelayCalc>
std::unique_ptr<HoldTimingInfo> make_hold_timing_info(std::shared_ptr<DelayCalc> delay_calculator);
//Create a SetupHoldTimingInfo for the given delay calculator
template<class DelayCalc>
std::unique_ptr<SetupHoldTimingInfo> make_setup_hold_timing_info(std::shared_ptr<DelayCalc> delay_calculator);
//Create a timing info object which does no timing analysis, and returns
//place-holder values. This is useful to running timing driven algorithms
//with timing disabled
std::unique_ptr<SetupHoldTimingInfo> make_no_op_timing_info();
//Generic inteface which provides functionality to update (but not
//access) timing information.
//
//This is useful for algorithms which know they need to update timing
//information (e.g. because they have made a change to the implementation)
//but do not care *what* timing information is updated (e.g. setup vs hold)
class TimingInfo {
public:
//Constructors
virtual ~TimingInfo() = default;
public:
//Mutators
//Update all timing information
virtual void update() = 0;
//Return the underlying timing analyzer
virtual std::shared_ptr<const tatum::TimingAnalyzer> analyzer() const = 0;
//Return the underlying timing graph
virtual std::shared_ptr<const tatum::TimingGraph> timing_graph() const = 0;
//Return the underlying timing constraints
virtual std::shared_ptr<const tatum::TimingConstraints> timing_constraints() const = 0;
//Enable/disable warnings about unconstrained startpoints/endpoints during timing analysis
virtual void set_warn_unconstrained(bool val) = 0;
};
//Generic interface which provides setup-related timing information
//
//This is useful for algorithms which need to access setup timing related
//information (e.g. to optimize critical path delay)
class SetupTimingInfo : public virtual TimingInfo {
public:
//Accessors
//Return the critical path with the least slack
virtual tatum::TimingPathInfo least_slack_critical_path() const = 0;
//Return the critical path the the longest absolute delay
virtual tatum::TimingPathInfo longest_critical_path() const = 0;
//Return the set of critical paths between all clock domain pairs
virtual std::vector<tatum::TimingPathInfo> critical_paths() const = 0;
//Return the total negative slack w.r.t. setup constraints
virtual float setup_total_negative_slack() const = 0;
//Return the worst negative slack w.r.t. setup constraints
virtual float setup_worst_negative_slack() const = 0;
//Return the worst setup slack of all paths passing through pin
virtual float setup_pin_slack(AtomPinId pin) const = 0;
//Return the setup criticality of the worst connection passing through pin
virtual float setup_pin_criticality(AtomPinId pin) const = 0;
//Return the underlying timing analyzer
virtual std::shared_ptr<const tatum::SetupTimingAnalyzer> setup_analyzer() const = 0;
public:
//Mutators
virtual void update_setup() = 0;
};
//Generic interface which provides setup-related timing information
//
//This is useful for algorithms which need to access hold timing related
//information (e.g. to fix hold timing)
class HoldTimingInfo : public virtual TimingInfo {
public:
//Accessors
//Return the total negative slack w.r.t. hold constraints
virtual float hold_total_negative_slack() const = 0;
//Return the worst negative slack w.r.t. hold constraints
virtual float hold_worst_negative_slack() const = 0;
//Return the worst slack of all paths passing through pin
virtual float hold_pin_slack(AtomPinId pin) const = 0;
//Return the hold criticality of the worst connection passing through pin
virtual float hold_pin_criticality(AtomPinId pin) const = 0;
//Return the underlying timing analyzer
virtual std::shared_ptr<const tatum::HoldTimingAnalyzer> hold_analyzer() const = 0;
public:
//Mutators
virtual void update_hold() = 0;
};
//Generic interface which provides both setup and hold related timing information
//
//This is useful for algorithms which require access to both setup and hold timing
//information (e.g. simulatneously optimizing setup and hold)
//
//This class supports both the SetupTimingInfo and HoldTimingInfo interfaces and
//can be used in place of them in any algorithm requiring setup or hold related
//information.
//
//Implementation Note:
// This class uses multiple inheritence, which is OK in this case for the following reasons:
// * The inheritance is virtual avoiding the diamon problem (i.e. there is only
// one base TimingInfo class instance)
// * Both SetupTimingInfo and HoldTimingInfo are purely abstract classes so there
// is no data to be duplicated
class SetupHoldTimingInfo : public SetupTimingInfo, public HoldTimingInfo {
public:
virtual std::shared_ptr<const tatum::SetupHoldTimingAnalyzer> setup_hold_analyzer() const = 0;
};
#include "concrete_timing_info.h"
template<class DelayCalc>
std::unique_ptr<SetupTimingInfo> make_setup_timing_info(std::shared_ptr<DelayCalc> delay_calculator) {
auto& timing_ctx = g_vpr_ctx.timing();
std::shared_ptr<tatum::SetupTimingAnalyzer> analyzer = tatum::AnalyzerFactory<tatum::SetupAnalysis, tatum::ParallelWalker>::make(*timing_ctx.graph, *timing_ctx.constraints, *delay_calculator);
return std::make_unique<ConcreteSetupTimingInfo<DelayCalc>>(timing_ctx.graph, timing_ctx.constraints, delay_calculator, analyzer);
}
template<class DelayCalc>
std::unique_ptr<HoldTimingInfo> make_hold_timing_info(std::shared_ptr<DelayCalc> delay_calculator) {
auto& timing_ctx = g_vpr_ctx.timing();
std::shared_ptr<tatum::HoldTimingAnalyzer> analyzer = tatum::AnalyzerFactory<tatum::HoldAnalysis, tatum::ParallelWalker>::make(*timing_ctx.graph, *timing_ctx.constraints, *delay_calculator);
return std::make_unique<ConcreteHoldTimingInfo<DelayCalc>>(timing_ctx.graph, timing_ctx.constraints, delay_calculator, analyzer);
}
template<class DelayCalc>
std::unique_ptr<SetupHoldTimingInfo> make_setup_hold_timing_info(std::shared_ptr<DelayCalc> delay_calculator) {
auto& timing_ctx = g_vpr_ctx.timing();
std::shared_ptr<tatum::SetupHoldTimingAnalyzer> analyzer = tatum::AnalyzerFactory<tatum::SetupHoldAnalysis, tatum::ParallelWalker>::make(*timing_ctx.graph, *timing_ctx.constraints, *delay_calculator);
return std::make_unique<ConcreteSetupHoldTimingInfo<DelayCalc>>(timing_ctx.graph, timing_ctx.constraints, delay_calculator, analyzer);
}
inline std::unique_ptr<SetupHoldTimingInfo> make_constant_timing_info(const float criticality) {
return std::make_unique<ConstantTimingInfo>(criticality);
}
#endif