diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index 05b5afd3..0b0f3174 100644 Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ diff --git a/liberty/LibertyWriter.cc b/liberty/LibertyWriter.cc index 00ecc0ae..e14b5792 100644 --- a/liberty/LibertyWriter.cc +++ b/liberty/LibertyWriter.cc @@ -52,6 +52,7 @@ protected: RiseFall *rf); void writeTableModel(const TableModel *model); void writeTableModel0(const TableModel *model); + void writeTableModel1(const TableModel *model); void writeTableModel2(const TableModel *model); void writeTableAxis(TableAxis *axis, int index); @@ -373,6 +374,7 @@ LibertyWriter::writeTableModel(const TableModel *model) writeTableModel0(model); break; case 1: + writeTableModel1(model); break; case 2: writeTableModel2(model); @@ -391,6 +393,21 @@ LibertyWriter::writeTableModel0(const TableModel *model) time_unit_->asString(value, 5)); } +void +LibertyWriter::writeTableModel1(const TableModel *model) +{ + fprintf(stream_, " values(\""); + bool first_col = true; + for (size_t index1 = 0; index1 < model->axis1()->size(); index1++) { + float value = model->value(index1, 0, 0); + if (!first_col) + fprintf(stream_, ","); + fprintf(stream_, "%s", time_unit_->asString(value, 5)); + first_col = false; + } + fprintf(stream_, "\");\n"); +} + void LibertyWriter::writeTableModel2(const TableModel *model) { diff --git a/liberty/TableModel.cc b/liberty/TableModel.cc index 6ae924d8..e5a6f7ee 100644 --- a/liberty/TableModel.cc +++ b/liberty/TableModel.cc @@ -46,8 +46,8 @@ GateTableModel::GateTableModel(TableModel *delay_model, slew_model_(slew_model) { for (auto el_index : EarlyLate::rangeIndex()) { - slew_sigma_models_[el_index] = slew_sigma_models[el_index]; - delay_sigma_models_[el_index] = delay_sigma_models[el_index]; + slew_sigma_models_[el_index] = slew_sigma_models ? slew_sigma_models[el_index] : nullptr; + delay_sigma_models_[el_index] = delay_sigma_models ? delay_sigma_models[el_index] : nullptr; } } diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index cb0015ec..8c3c9eff 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -23,7 +23,6 @@ #include "TimingArc.hh" #include "TableModel.hh" #include "liberty/LibertyBuilder.hh" -#include "LibertyWriter.hh" #include "Network.hh" #include "PortDirection.hh" #include "Corner.hh" @@ -36,16 +35,6 @@ namespace sta { -void -writeTimingModel(const char *cell_name, - const char *filename, - const Corner *corner, - Sta *sta) -{ - MakeTimingModel writer(corner, sta); - writer.writeTimingModel(cell_name, filename); -} - MakeTimingModel::MakeTimingModel(const Corner *corner, Sta *sta) : StaState(sta), @@ -61,21 +50,7 @@ MakeTimingModel::~MakeTimingModel() delete lib_builder_; } -void -MakeTimingModel::writeTimingModel(const char *cell_name, - const char *filename) -{ - makeTimingModel(cell_name, filename); - writeLibertyFile(filename); -} - -void -MakeTimingModel::writeLibertyFile(const char *filename) -{ - writeLiberty(library_, filename, this); -} - -void +LibertyLibrary * MakeTimingModel::makeTimingModel(const char *cell_name, const char *filename) { @@ -86,13 +61,11 @@ MakeTimingModel::makeTimingModel(const char *cell_name, for (Clock *clk : *sdc_->clocks()) sta_->setPropagatedClock(clk); -#if 0 findInputToOutputPaths(); findInputSetupHolds(); findClkedOutputPaths(); -#endif - findClkedOutputPaths(); cell_->finish(false, report_, debug_); + return library_; } void @@ -269,37 +242,52 @@ MakeTimingModel::findClkedOutputPaths() while (output_iter->hasNext()) { Pin *output_pin = output_iter->next(); if (network_->direction(output_pin)->isOutput()) { + LibertyPort *output_port = modelPort(output_pin); for (Clock *clk : *sdc_->clocks()) { - for (RiseFall *clk_rf : RiseFall::range()) { - for (RiseFall *output_rf : RiseFall::range()) { - RiseFallBoth *output_rf1 = output_rf->asRiseFallBoth(); - MinMax *min_max = MinMax::max(); - MinMaxAll *min_max1 = min_max->asMinMaxAll(); - sta_->setOutputDelay(output_pin, output_rf1, clk, clk_rf, - nullptr, false, false, min_max1, false, 0.0); + for (const Pin *clk_pin : clk->pins()) { + LibertyPort *clk_port = modelPort(clk_pin); + for (RiseFall *clk_rf : RiseFall::range()) { + TimingArcAttrs *attrs = nullptr; + for (RiseFall *output_rf : RiseFall::range()) { + RiseFallBoth *output_rf1 = output_rf->asRiseFallBoth(); + MinMax *min_max = MinMax::max(); + MinMaxAll *min_max1 = min_max->asMinMaxAll(); + sta_->setOutputDelay(output_pin, output_rf1, clk, clk_rf, + nullptr, false, false, min_max1, false, 0.0); - ClockSet *from_clks = new ClockSet; - from_clks->insert(clk); - ExceptionFrom *from = sta_->makeExceptionFrom(nullptr, from_clks, nullptr, - clk_rf->asRiseFallBoth()); - PinSet *to_pins = new PinSet; - to_pins->insert(output_pin); - ExceptionTo *to = sta_->makeExceptionTo(to_pins, nullptr, nullptr, - output_rf1, output_rf1); + ClockSet *from_clks = new ClockSet; + from_clks->insert(clk); + ExceptionFrom *from = sta_->makeExceptionFrom(nullptr, from_clks, nullptr, + clk_rf->asRiseFallBoth()); + PinSet *to_pins = new PinSet; + to_pins->insert(output_pin); + ExceptionTo *to = sta_->makeExceptionTo(to_pins, nullptr, nullptr, + output_rf1, output_rf1); - PathEndSeq *ends = sta_->findPathEnds(from, nullptr, to, false, corner_, min_max1, - 1, 1, false, -INF, INF, false, nullptr, - true, false, false, false, false, false); - if (!ends->empty()) { - debugPrint(debug_, "make_timing_model", 1, "clock %s -> output %s", - clk->name(), - network_->pathName(output_pin)); - PathEnd *end = (*ends)[0]; - if (debug_->check("make_timing_model", 2)) - sta_->reportPathEnd(end); + PathEndSeq *ends = sta_->findPathEnds(from, nullptr, to, false, corner_, min_max1, + 1, 1, false, -INF, INF, false, nullptr, + true, false, false, false, false, false); + if (!ends->empty()) { + debugPrint(debug_, "make_timing_model", 1, "clock %s -> output %s", + clk->name(), + network_->pathName(output_pin)); + PathEnd *end = (*ends)[0]; + if (debug_->check("make_timing_model", 2)) + sta_->reportPathEnd(end); + Arrival delay = end->path()->arrival(sta_); + Slew slew = end->path()->slew(sta_); + TimingModel *check_model = makeScalarGateModel(delay, slew, output_rf); + if (attrs == nullptr) + attrs = new TimingArcAttrs(); + attrs->setModel(output_rf, check_model); + } + sta_->removeOutputDelay(output_pin, output_rf1, clk, clk_rf, MinMaxAll::max()); } - sta_->removeOutputDelay(output_pin, RiseFallBoth::riseFall(), - clk, clk_rf, MinMaxAll::max()); + if (attrs) + lib_builder_->makeFromTransitionArcs(cell_, clk_port, + output_port, nullptr, + clk_rf, TimingRole::regClkToQ(), + attrs); } } } @@ -327,4 +315,22 @@ MakeTimingModel::makeScalarCheckModel(float value, return check_model; } +TimingModel * +MakeTimingModel::makeScalarGateModel(Delay delay, + Slew slew, + RiseFall *rf) +{ + Table *delay_table = new Table0(delay); + Table *slew_table = new Table0(slew); + TableTemplate *tbl_template = + library_->findTableTemplate("scalar", TableTemplateType::delay); + TableModel *delay_model = new TableModel(delay_table, tbl_template, + ScaleFactorType::cell, rf); + TableModel *slew_model = new TableModel(slew_table, tbl_template, + ScaleFactorType::cell, rf); + GateTableModel *gate_model = new GateTableModel(delay_model, nullptr, + slew_model, nullptr); + return gate_model; +} + } // namespace diff --git a/search/MakeTimingModel.hh b/search/MakeTimingModel.hh index ac284a2b..53b041cd 100644 --- a/search/MakeTimingModel.hh +++ b/search/MakeTimingModel.hh @@ -31,11 +31,8 @@ public: MakeTimingModel(const Corner *corner, Sta *sta); ~MakeTimingModel(); - void writeTimingModel(const char *cell_name, - const char *filename); - void makeTimingModel(const char *cell_name, - const char *filename); - void writeLibertyFile(const char *filename); + LibertyLibrary *makeTimingModel(const char *cell_name, + const char *filename); private: void makeLibrary(const char *cell_name, @@ -51,6 +48,9 @@ private: TimingModel *makeScalarCheckModel(float value, ScaleFactorType scale_factor_type, RiseFall *rf); + TimingModel *makeScalarGateModel(Delay delay, + Slew slew, + RiseFall *rf); Sta *sta_; LibertyLibrary *library_; diff --git a/search/Sta.cc b/search/Sta.cc index d56036e7..0d3d0217 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -28,6 +28,7 @@ #include "EquivCells.hh" #include "Liberty.hh" #include "liberty/LibertyReader.hh" +#include "LibertyWriter.hh" #include "SdcNetwork.hh" #include "MakeConcreteNetwork.hh" #include "PortDirection.hh" @@ -5572,7 +5573,9 @@ Sta::writeTimingModel(const char *cell_name, const char *filename, const Corner *corner) { - sta::writeTimingModel(cell_name, filename, corner, this); + MakeTimingModel maker(corner, this); + LibertyLibrary *library = maker.makeTimingModel(cell_name, filename); + writeLiberty(library, filename, this); } ////////////////////////////////////////////////////////////////