report_clock_min_period

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2021-10-04 17:49:19 -07:00
parent 26ada326ce
commit 72dece4117
5 changed files with 132 additions and 0 deletions

Binary file not shown.

View File

@ -964,6 +964,12 @@ public:
const RiseFall *rf,
const MinMax *min_max);
// Find the min clock period for rise/rise and fall/fall paths of a clock
// using the slack. This does NOT correctly predict min period when there
// are paths between different clocks.
float findClkMinPeriod(const Clock *clk,
bool include_port_paths);
// The following arrival/required/slack functions incrementally
// update timing to the level of the vertex. They do NOT do multiple
// passes required propagate arrivals around latch loops.

View File

@ -67,10 +67,13 @@
#include "Genclks.hh"
#include "ClkNetwork.hh"
#include "Power.hh"
#include "VisitPathEnds.hh"
#include "PathExpanded.hh"
namespace sta {
using std::min;
using std::max;
static const ClockEdge *clk_edge_wildcard = reinterpret_cast<ClockEdge*>(1);
@ -3030,6 +3033,91 @@ Sta::vertexSlacks(Vertex *vertex,
}
}
////////////////////////////////////////////////////////////////
class MinPeriodEndVisitor : public PathEndVisitor
{
public:
MinPeriodEndVisitor(const Clock *clk,
bool include_port_paths,
StaState *sta);
virtual PathEndVisitor *copy();
virtual void visit(PathEnd *path_end);
float minPeriod() const { return min_period_; }
private:
bool pathIsFromInputPort(PathEnd *path_end);
const Clock *clk_;
bool include_port_paths_;
StaState *sta_;
float min_period_;
};
MinPeriodEndVisitor::MinPeriodEndVisitor(const Clock *clk,
bool include_port_paths,
StaState *sta) :
clk_(clk),
include_port_paths_(include_port_paths),
sta_(sta),
min_period_(0)
{
}
PathEndVisitor *
MinPeriodEndVisitor::copy()
{
return new MinPeriodEndVisitor(clk_, include_port_paths_, sta_);
}
void
MinPeriodEndVisitor::visit(PathEnd *path_end)
{
Path *path = path_end->path();
ClockEdge *src_edge = path_end->sourceClkEdge(sta_);
ClockEdge *tgt_edge = path_end->targetClkEdge(sta_);
if (path->minMax(sta_) == MinMax::max()
&& src_edge->clock() == clk_
&& tgt_edge->clock() == clk_
// Only consider rise/rise and fall/fall paths.
&& src_edge->transition() == tgt_edge->transition()
&& (include_port_paths_
|| !(path_end->isOutputDelay()
|| pathIsFromInputPort(path_end)))) {
Slack slack = path_end->slack(sta_);
float period = clk_->period() - slack;
min_period_ = max(min_period_, period);
}
}
bool
MinPeriodEndVisitor::pathIsFromInputPort(PathEnd *path_end)
{
PathExpanded expanded(path_end->path(), sta_);
PathRef *start = expanded.startPath();
Graph *graph = sta_->graph();
const Pin *first_pin = start->pin(graph);
Network *network = sta_->network();
return network->isTopLevelPort(first_pin);
}
float
Sta::findClkMinPeriod(const Clock *clk,
bool include_port_paths)
{
searchPreamble();
search_->findArrivals();
VisitPathEnds visit_ends(this);
MinPeriodEndVisitor min_period_visitor(clk, include_port_paths, this);
for (Vertex *vertex : *search_->endpoints()) {
findRequired(vertex);
visit_ends.visitPathEnds(vertex, &min_period_visitor);
}
return min_period_visitor.minPeriod();
}
////////////////////////////////////////////////////////////////
void
Sta::findRequired(Vertex *vertex)
{

View File

@ -1075,5 +1075,34 @@ proc define_report_path_fields {} {
set_report_path_field_properties "case" " " 11 0
}
################################################################
define_cmd_args "report_clock_min_period" \
{ [-clocks clocks] [-include_port_paths] }
proc report_clock_min_period { args } {
parse_key_args "report_min_clock_period" args \
keys {-clocks} flags {-include_port_paths} 0
if { [info exists keys(-clocks)] } {
set clks [get_clocks $keys(-clocks)]
} else {
set clks [all_clocks]
}
set include_port_paths [info exists flags(-include_port_paths)]
foreach clk $clks {
set min_period [sta::find_clk_min_period $clk $include_port_paths]
if { $min_period == 0.0 } {
set min_period 0
set fmax "INF"
} else {
# max frequency in MHz
set fmax [expr 1.0e-6 / $min_period]
}
puts "[get_name $clk] period_min = [sta::format_time $min_period 2] fmax = [format %.2f $fmax]"
}
}
# sta namespace end.
}

View File

@ -4702,6 +4702,15 @@ vertex_worst_slack_path(Vertex *vertex,
return nullptr;
}
Slack
find_clk_min_period(const Clock *clk,
bool ignore_port_paths)
{
cmdLinkedNetwork();
Sta *sta = Sta::sta();
return sta->findClkMinPeriod(clk, ignore_port_paths);
}
TmpString *
report_delay_calc_cmd(Edge *edge,
TimingArc *arc,