timing: Slack and criticality computation
Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
parent
296e6d10c2
commit
e681e0f14c
@ -40,6 +40,8 @@ void TimingAnalyser::setup()
|
||||
reset_times();
|
||||
walk_forward();
|
||||
walk_backward();
|
||||
compute_slack();
|
||||
compute_criticality();
|
||||
print_fmax();
|
||||
}
|
||||
|
||||
@ -266,6 +268,7 @@ void TimingAnalyser::reset_times()
|
||||
dp.second.criticality = 0;
|
||||
dp.second.budget = 0;
|
||||
}
|
||||
port.second.worst_crit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -417,6 +420,43 @@ void TimingAnalyser::print_fmax()
|
||||
}
|
||||
}
|
||||
|
||||
void TimingAnalyser::compute_slack()
|
||||
{
|
||||
for (auto &dp : domain_pairs) {
|
||||
dp.worst_setup_slack = std::numeric_limits<delay_t>::max();
|
||||
dp.worst_hold_slack = std::numeric_limits<delay_t>::max();
|
||||
}
|
||||
for (auto p : topological_order) {
|
||||
auto &pd = ports.at(p);
|
||||
for (auto &pdp : pd.domain_pairs) {
|
||||
auto &dp = domain_pairs.at(pdp.first);
|
||||
auto &arr = pd.arrival.at(dp.key.launch);
|
||||
auto &req = pd.required.at(dp.key.capture);
|
||||
pdp.second.setup_slack = dp.period.minDelay() - (arr.value.maxDelay() - req.value.minDelay());
|
||||
if (!setup_only)
|
||||
pdp.second.hold_slack = arr.value.minDelay() - req.value.maxDelay();
|
||||
pdp.second.max_path_length = arr.path_length + req.path_length;
|
||||
dp.worst_setup_slack = std::min(dp.worst_setup_slack, pdp.second.setup_slack);
|
||||
if (!setup_only)
|
||||
dp.worst_hold_slack = std::min(dp.worst_hold_slack, pdp.second.hold_slack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimingAnalyser::compute_criticality()
|
||||
{
|
||||
for (auto p : topological_order) {
|
||||
auto &pd = ports.at(p);
|
||||
for (auto &pdp : pd.domain_pairs) {
|
||||
auto &dp = domain_pairs.at(pdp.first);
|
||||
pdp.second.criticality =
|
||||
1.0f - (float(pdp.second.setup_slack) - float(dp.worst_setup_slack)) / float(-dp.worst_setup_slack);
|
||||
NPNR_ASSERT(pdp.second.criticality >= -0.00001f && pdp.second.criticality <= 1.00001f);
|
||||
pd.worst_crit = std::max(pd.worst_crit, pdp.second.criticality);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
domain_id_t TimingAnalyser::domain_id(IdString cell, IdString clock_port, ClockEdge edge)
|
||||
{
|
||||
return domain_id(ctx->cells.at(cell)->ports.at(clock_port).net, edge);
|
||||
|
@ -141,6 +141,9 @@ struct TimingAnalyser
|
||||
void walk_forward();
|
||||
void walk_backward();
|
||||
|
||||
void compute_slack();
|
||||
void compute_criticality();
|
||||
|
||||
void print_fmax();
|
||||
|
||||
const DelayPair init_delay{std::numeric_limits<delay_t>::max(), std::numeric_limits<delay_t>::lowest()};
|
||||
@ -207,6 +210,8 @@ struct TimingAnalyser
|
||||
std::vector<CellArc> cell_arcs;
|
||||
// routing delay into this port (input ports only)
|
||||
DelayPair route_delay;
|
||||
// worst criticality across domain pairs
|
||||
float worst_crit;
|
||||
};
|
||||
|
||||
struct PerDomain
|
||||
@ -221,6 +226,8 @@ struct TimingAnalyser
|
||||
{
|
||||
PerDomainPair(ClockDomainPairKey key) : key(key){};
|
||||
ClockDomainPairKey key;
|
||||
DelayPair period;
|
||||
delay_t worst_setup_slack, worst_hold_slack;
|
||||
};
|
||||
|
||||
CellInfo *cell_info(const CellPortKey &key);
|
||||
|
Loading…
Reference in New Issue
Block a user