vpr/src/timing/timing_util.cpp
//Returns the worst (maximum) criticality of the set of slack tags specified. Requires the maximum
//required time and worst slack for all domain pairs represent by the slack tags
//
// Criticality (in [0., 1.]) represents how timing-critical something is,
// 0. is non-critical and 1. is most-critical.
//
// This returns 'relaxed per constraint' criticaly as defined in:
//
//     M. Wainberg and V. Betz, "Robust Optimization of Multiple Timing Constraints,"
//         IEEE CAD, vol. 34, no. 12, pp. 1942-1953, Dec. 2015. doi: 10.1109/TCAD.2015.2440316
//
// which handles the trade-off between different timing constraints in multi-clock circuits.
//
// Note that unlike in Wainberg, we calculate the relaxed criticality as a post-processing step.
Returns the worst (maximum) criticality of the set of slack tags specified. Requires the maximum
required time and worst slack for all domain pairs represent by the slack tags

Criticality (in [0., 1.]) represents how timing-critical something is,
0. is non-critical and 1. is most-critical.

This returns 'relaxed per constraint' criticaly as defined in.

M. Wainberg and V. Betz, "Robust Optimization of Multiple Timing Constraints,"
IEEE CAD, vol. 34, no. 12, pp.

which handles the trade-off between different timing constraints in multi-clock circuits.

Note that unlike in Wainberg, we calculate the relaxed criticality as a post-processing step.
Returns the worst ( maximum ) criticality of the set of slack tags specified . Requires the maximum required time and worst slack for all domain pairs represent by the slack tags Criticality ( in [ 0 . 1 . ] ) represents how timing - critical something is 0 . is non - critical and 1 . is most - critical . This returns ' relaxed per constraint ' criticaly as defined in . M . Wainberg and V . Betz " Robust Optimization of Multiple Timing Constraints " IEEE CAD vol . 34 no . 12 pp . which handles the trade - off between different timing constraints in multi - clock circuits . Note that unlike in Wainberg we calculate the relaxed criticality as a post - processing step .
float calc_relaxed_criticality(const std::map<DomainPair, float>& domains_max_req,
                               const std::map<DomainPair, float>& domains_worst_slack,
                               const tatum::TimingTags::tag_range tags) {
    constexpr float CRITICALITY_ROUND_OFF_TOLERANCE = 1e-4;
    float max_crit = 0.;
    for (const auto& tag : tags) {
        VTR_ASSERT_MSG(tag.type() == tatum::TagType::SLACK, "Tags must be slacks to calculate criticality");
        float slack = tag.time().value();
        auto domain_pair = DomainPair(tag.launch_clock_domain(), tag.capture_clock_domain());
        auto iter = domains_max_req.find(domain_pair);
        VTR_ASSERT_MSG(iter != domains_max_req.end(), "Require the maximum required time for clock domain pair");
        float max_req = iter->second;
        iter = domains_worst_slack.find(domain_pair);
        VTR_ASSERT_MSG(iter != domains_worst_slack.end(), "Require the worst slack for clock domain pair");
        float worst_slack = iter->second;
        if (worst_slack < 0.) {
            This corresponds to the 'relaxed' criticality from Wainberg et. al.
            float shift = -worst_slack;
            VTR_ASSERT(shift > 0.);
            slack += shift;
            max_req += shift;
        }
        float crit = std::numeric_limits<float>::quiet_NaN();
        if (max_req > 0.) {
            Standard case
            crit = 1. - (slack / max_req);
        } else if (max_req == 0. && slack == 0.) {
            Special case to avoid divide by zero
            crit = 1.;
        } else {
            std::string msg = vtr::string_fmt("Invalid maximum required time %g (expected >= 0). Shifted slack was %g.", max_req, slack);
            VPR_ERROR(VPR_ERROR_TIMING, msg.c_str());
        }
        Soft check for reasonable criticality values
        VTR_ASSERT_MSG(crit >= 0. - CRITICALITY_ROUND_OFF_TOLERANCE, "Criticality should never be negative");
        VTR_ASSERT_MSG(crit <= 1. + CRITICALITY_ROUND_OFF_TOLERANCE, "Criticality should never be greather than one");
        Clamp criticality to [0., 1.] to correct round-off
        crit = std::max(0.f, crit);
        crit = std::min(1.f, crit);
        max_crit = std::max(max_crit, crit);
    }
    VTR_ASSERT_MSG(max_crit >= 0., "Criticality should never be negative");
    VTR_ASSERT_MSG(max_crit <= 1., "Criticality should never be greather than one");
    return max_crit;
}
float calc_relaxed_criticality ( const std :: map < DomainPair , float > & domains_max_req , const std :: map < DomainPair , float > & domains_worst_slack , const tatum :: TimingTags :: tag_range tags ) { constexpr float CRITICALITY_ROUND_OFF_TOLERANCE = 1e-4 ; float max_crit = 0. ; for ( const auto & tag : tags ) { VTR_ASSERT_MSG ( tag . type ( ) == tatum :: TagType :: SLACK , " " ) ; float slack = tag . time ( ) . value ( ) ; auto domain_pair = DomainPair ( tag . launch_clock_domain ( ) , tag . capture_clock_domain ( ) ) ; auto iter = domains_max_req . find ( domain_pair ) ; VTR_ASSERT_MSG ( iter != domains_max_req . end ( ) , " " ) ; float max_req = iter -> second ; iter = domains_worst_slack . find ( domain_pair ) ; VTR_ASSERT_MSG ( iter != domains_worst_slack . end ( ) , " " ) ; float worst_slack = iter -> second ; if ( worst_slack < 0. ) { float shift = - worst_slack ; VTR_ASSERT ( shift > 0. ) ; slack += shift ; max_req += shift ; } float crit = std :: numeric_limits < float > :: quiet_NaN ( ) ; if ( max_req > 0. ) { crit = 1. - ( slack / max_req ) ; } else if ( max_req == 0. && slack == 0. ) { crit = 1. ; } else { std :: string msg = vtr :: string_fmt ( " " , max_req , slack ) ; VPR_ERROR ( VPR_ERROR_TIMING , msg . c_str ( ) ) ; } VTR_ASSERT_MSG ( crit >= 0. - CRITICALITY_ROUND_OFF_TOLERANCE , " " ) ; VTR_ASSERT_MSG ( crit <= 1. + CRITICALITY_ROUND_OFF_TOLERANCE , " " ) ; crit = std :: max ( 0.f , crit ) ; crit = std :: min ( 1.f , crit ) ; max_crit = std :: max ( max_crit , crit ) ; } VTR_ASSERT_MSG ( max_crit >= 0. , " " ) ; VTR_ASSERT_MSG ( max_crit <= 1. , " " ) ; return max_crit ; }
Returns the worst (maximum) criticality of the set of slack tags specified.
Returns the worst ( maximum ) criticality of the set of slack tags specified .
//Allowable round-off tolerance during criticality calculation //Record the maximum criticality over all the tags //We shift slacks and required time by the most negative slack //**in the domain**, to ensure criticality is bounded within [0., 1.] // //This corresponds to the 'relaxed' criticality from Wainberg et. al. //Standard case //Special case to avoid divide by zero //Soft check for reasonable criticality values //Clamp criticality to [0., 1.] to correct round-off