make timing model setup/hold
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
f2c6b49d07
commit
55ec1973d0
|
|
@ -59,6 +59,14 @@ public:
|
||||||
LeakagePower *makeLeakagePower(LibertyCell *cell,
|
LeakagePower *makeLeakagePower(LibertyCell *cell,
|
||||||
LeakagePowerAttrs *attrs);
|
LeakagePowerAttrs *attrs);
|
||||||
|
|
||||||
|
TimingArcSet *makeFromTransitionArcs(LibertyCell *cell,
|
||||||
|
LibertyPort *from_port,
|
||||||
|
LibertyPort *to_port,
|
||||||
|
LibertyPort *related_out,
|
||||||
|
RiseFall *from_rf,
|
||||||
|
TimingRole *role,
|
||||||
|
TimingArcAttrs *attrs);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ConcretePort *makeBusPort(const char *name,
|
ConcretePort *makeBusPort(const char *name,
|
||||||
int from_index,
|
int from_index,
|
||||||
|
|
@ -111,13 +119,6 @@ protected:
|
||||||
LibertyPort *related_out,
|
LibertyPort *related_out,
|
||||||
RiseFall *from_rf,
|
RiseFall *from_rf,
|
||||||
TimingArcAttrs *attrs);
|
TimingArcAttrs *attrs);
|
||||||
TimingArcSet *makeFromTransitionArcs(LibertyCell *cell,
|
|
||||||
LibertyPort *from_port,
|
|
||||||
LibertyPort *to_port,
|
|
||||||
LibertyPort *related_out,
|
|
||||||
RiseFall *from_rf,
|
|
||||||
TimingRole *role,
|
|
||||||
TimingArcAttrs *attrs);
|
|
||||||
TimingArcSet *makePresetClrArcs(LibertyCell *cell,
|
TimingArcSet *makePresetClrArcs(LibertyCell *cell,
|
||||||
LibertyPort *from_port,
|
LibertyPort *from_port,
|
||||||
LibertyPort *to_port,
|
LibertyPort *to_port,
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,7 @@ CheckTableModel::CheckTableModel(TableModel *model,
|
||||||
model_(model)
|
model_(model)
|
||||||
{
|
{
|
||||||
for (auto el_index : EarlyLate::rangeIndex())
|
for (auto el_index : EarlyLate::rangeIndex())
|
||||||
sigma_models_[el_index] = sigma_models[el_index];
|
sigma_models_[el_index] = sigma_models ? sigma_models[el_index] : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckTableModel::~CheckTableModel()
|
CheckTableModel::~CheckTableModel()
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
#include "Units.hh"
|
#include "Units.hh"
|
||||||
#include "Transition.hh"
|
#include "Transition.hh"
|
||||||
#include "Liberty.hh"
|
#include "Liberty.hh"
|
||||||
|
#include "TimingArc.hh"
|
||||||
|
#include "TableModel.hh"
|
||||||
#include "liberty/LibertyBuilder.hh"
|
#include "liberty/LibertyBuilder.hh"
|
||||||
#include "LibertyWriter.hh"
|
#include "LibertyWriter.hh"
|
||||||
#include "Network.hh"
|
#include "Network.hh"
|
||||||
|
|
@ -29,6 +31,7 @@
|
||||||
#include "dcalc/GraphDelayCalc1.hh"
|
#include "dcalc/GraphDelayCalc1.hh"
|
||||||
#include "Sdc.hh"
|
#include "Sdc.hh"
|
||||||
#include "StaState.hh"
|
#include "StaState.hh"
|
||||||
|
#include "PathEnd.hh"
|
||||||
#include "Sta.hh"
|
#include "Sta.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
@ -89,6 +92,7 @@ MakeTimingModel::makeTimingModel(const char *cell_name,
|
||||||
findClkedOutputPaths();
|
findClkedOutputPaths();
|
||||||
#endif
|
#endif
|
||||||
findInputSetupHolds();
|
findInputSetupHolds();
|
||||||
|
cell_->finish(false, report_, debug_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -190,41 +194,64 @@ MakeTimingModel::findInputSetupHolds()
|
||||||
Pin *input_pin = input_iter->next();
|
Pin *input_pin = input_iter->next();
|
||||||
if (network_->direction(input_pin)->isInput()
|
if (network_->direction(input_pin)->isInput()
|
||||||
&& !sta_->isClockSrc(input_pin)) {
|
&& !sta_->isClockSrc(input_pin)) {
|
||||||
|
LibertyPort *input_port = modelPort(input_pin);
|
||||||
for (Clock *clk : *sdc_->clocks()) {
|
for (Clock *clk : *sdc_->clocks()) {
|
||||||
for (RiseFall *clk_rf : RiseFall::range()) {
|
for (const Pin *clk_pin : clk->pins()) {
|
||||||
for (MinMax *min_max : MinMax::range()) {
|
LibertyPort *clk_port = modelPort(clk_pin);
|
||||||
MinMaxAll *min_max2 = min_max->asMinMaxAll();
|
for (RiseFall *clk_rf : RiseFall::range()) {
|
||||||
bool setup = min_max == MinMax::max();
|
for (MinMax *min_max : MinMax::range()) {
|
||||||
bool hold = !setup;
|
MinMaxAll *min_max2 = min_max->asMinMaxAll();
|
||||||
for (RiseFall *input_rf : RiseFall::range()) {
|
bool setup = min_max == MinMax::max();
|
||||||
sdc_->setInputDelay(input_pin, RiseFallBoth::riseFall(), clk, clk_rf,
|
bool hold = !setup;
|
||||||
nullptr, false, false, min_max2, false, 0.0);
|
TimingRole *role = setup ? TimingRole::setup() : TimingRole::hold();
|
||||||
|
TimingArcAttrs *attrs = nullptr;
|
||||||
|
for (RiseFall *input_rf : RiseFall::range()) {
|
||||||
|
sdc_->setInputDelay(input_pin, RiseFallBoth::riseFall(), clk, clk_rf,
|
||||||
|
nullptr, false, false, min_max2, false, 0.0);
|
||||||
|
|
||||||
PinSet *from_pins = new PinSet;
|
PinSet *from_pins = new PinSet;
|
||||||
from_pins->insert(input_pin);
|
from_pins->insert(input_pin);
|
||||||
ExceptionFrom *from = sta_->makeExceptionFrom(from_pins, nullptr, nullptr,
|
ExceptionFrom *from = sta_->makeExceptionFrom(from_pins, nullptr, nullptr,
|
||||||
input_rf->asRiseFallBoth());
|
input_rf->asRiseFallBoth());
|
||||||
|
|
||||||
ClockSet *to_clks = new ClockSet;
|
ClockSet *to_clks = new ClockSet;
|
||||||
to_clks->insert(clk);
|
to_clks->insert(clk);
|
||||||
ExceptionTo *to = sta_->makeExceptionTo(nullptr, to_clks, nullptr,
|
ExceptionTo *to = sta_->makeExceptionTo(nullptr, to_clks, nullptr,
|
||||||
clk_rf->asRiseFallBoth(),
|
clk_rf->asRiseFallBoth(),
|
||||||
RiseFallBoth::riseFall());
|
RiseFallBoth::riseFall());
|
||||||
PathEndSeq *ends = sta_->findPathEnds(from, nullptr, to, false, corner_,
|
PathEndSeq *ends = sta_->findPathEnds(from, nullptr, to, false, corner_,
|
||||||
min_max2,
|
min_max2,
|
||||||
1, 1, false,
|
1, 1, false,
|
||||||
-INF, INF, false, nullptr,
|
-INF, INF, false, nullptr,
|
||||||
setup, hold, setup, hold, setup, hold);
|
setup, hold, setup, hold, setup, hold);
|
||||||
if (!ends->empty()) {
|
if (!ends->empty()) {
|
||||||
debugPrint(debug_, "timing_model", 1, "%s %s %s -> clock %s %s",
|
PathEnd *end = (*ends)[0];
|
||||||
setup ? "setup" : "hold",
|
debugPrint(debug_, "timing_model", 1, "%s %s %s -> clock %s %s",
|
||||||
network_->pathName(input_pin),
|
setup ? "setup" : "hold",
|
||||||
input_rf->asString(),
|
network_->pathName(input_pin),
|
||||||
clk->name(),
|
input_rf->asString(),
|
||||||
clk_rf->asString());
|
clk->name(),
|
||||||
PathEnd *end = (*ends)[0];
|
clk_rf->asString());
|
||||||
sta_->reportPathEnd(end);
|
if (debug_->check("timing_model", 2))
|
||||||
|
sta_->reportPathEnd(end);
|
||||||
|
Arrival data_arrival = end->path()->arrival(sta_);
|
||||||
|
Delay clk_latency = end->targetClkDelay(sta_);
|
||||||
|
ArcDelay check_setup = end->margin(sta_);
|
||||||
|
float margin = data_arrival - clk_latency + check_setup;
|
||||||
|
|
||||||
|
ScaleFactorType scale_type = setup
|
||||||
|
? ScaleFactorType::setup
|
||||||
|
: ScaleFactorType::hold;
|
||||||
|
TimingModel *check_model = makeScalarCheckModel(margin, scale_type, input_rf);
|
||||||
|
if (attrs == nullptr)
|
||||||
|
attrs = new TimingArcAttrs();
|
||||||
|
attrs->setModel(input_rf, check_model);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (attrs)
|
||||||
|
lib_builder_->makeFromTransitionArcs(cell_, clk_port,
|
||||||
|
input_port, nullptr,
|
||||||
|
clk_rf, role, attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -273,4 +300,24 @@ MakeTimingModel::findClkedOutputPaths()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LibertyPort *
|
||||||
|
MakeTimingModel::modelPort(const Pin *pin)
|
||||||
|
{
|
||||||
|
return cell_->findLibertyPort(network_->name(network_->port(pin)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TimingModel *
|
||||||
|
MakeTimingModel::makeScalarCheckModel(float value,
|
||||||
|
ScaleFactorType scale_factor_type,
|
||||||
|
RiseFall *rf)
|
||||||
|
{
|
||||||
|
Table *table = new Table0(value);
|
||||||
|
TableTemplate *tbl_template =
|
||||||
|
library_->findTableTemplate("scalar", TableTemplateType::delay);
|
||||||
|
TableModel *table_model = new TableModel(table, tbl_template,
|
||||||
|
scale_factor_type, rf);
|
||||||
|
CheckTableModel *check_model = new CheckTableModel(table_model, nullptr);
|
||||||
|
return check_model;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,11 @@ private:
|
||||||
void findInputSetupHolds();
|
void findInputSetupHolds();
|
||||||
void findClkedOutputPaths();
|
void findClkedOutputPaths();
|
||||||
|
|
||||||
|
LibertyPort *modelPort(const Pin *pin);
|
||||||
|
TimingModel *makeScalarCheckModel(float value,
|
||||||
|
ScaleFactorType scale_factor_type,
|
||||||
|
RiseFall *rf);
|
||||||
|
|
||||||
Sta *sta_;
|
Sta *sta_;
|
||||||
LibertyLibrary *library_;
|
LibertyLibrary *library_;
|
||||||
LibertyCell *cell_;
|
LibertyCell *cell_;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue