report_clock_min_period
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
26ada326ce
commit
72dece4117
BIN
doc/OpenSTA.odt
BIN
doc/OpenSTA.odt
Binary file not shown.
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue