diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index b5bbedba..ae5b33fb 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -48,6 +48,7 @@ class StaState; typedef Set LibrarySet; typedef Map TableTemplateMap; +typedef Vector TableTemplateSeq; typedef Map BusDclMap; typedef Map ScaleFactorsMap; typedef Map WireloadMap; @@ -133,6 +134,7 @@ public: TableTemplateType type); TableTemplate *findTableTemplate(const char *name, TableTemplateType type); + TableTemplateSeq tableTemplates() const; float nominalProcess() const { return nominal_process_; } void setNominalProcess(float process); float nominalVoltage() const { return nominal_voltage_; } diff --git a/include/sta/TableModel.hh b/include/sta/TableModel.hh index 0b79b405..08878388 100644 --- a/include/sta/TableModel.hh +++ b/include/sta/TableModel.hh @@ -141,6 +141,7 @@ public: bool pocv_enabled, int digits, string *result) const; + const TableModel *model() const { return model_; } // Check the axes before making the model. // Return true if the model axes are supported. @@ -188,15 +189,20 @@ class TableModel { public: TableModel(Table *table, + TableTemplate *tbl_template, ScaleFactorType scale_factor_type, RiseFall *rf); ~TableModel(); void setScaleFactorType(ScaleFactorType type); int order() const; + TableTemplate *tblTemplate() const { return tbl_template_; } TableAxis *axis1() const; TableAxis *axis2() const; TableAxis *axis3() const; void setIsScaled(bool is_scaled); + float value(size_t index1, + size_t index2, + size_t index3) const; // Table interpolated lookup. float findValue(float value1, float value2, @@ -232,6 +238,7 @@ protected: string *result) const; Table *table_; + TableTemplate *tbl_template_; // ScaleFactorType gcc barfs if this is dcl'd. unsigned scale_factor_type_:scale_factor_bits; unsigned tr_index_:RiseFall::index_bit_count; @@ -250,6 +257,9 @@ public: virtual TableAxis *axis2() const { return nullptr; } virtual TableAxis *axis3() const { return nullptr; } void setIsScaled(bool is_scaled); + virtual float value(size_t axis_idx1, + size_t axis_idx2, + size_t axis_idx3) const = 0; // Table interpolated lookup. virtual float findValue(float value1, float value2, @@ -281,6 +291,9 @@ class Table0 : public Table public: Table0(float value); virtual int order() const { return 0; } + virtual float value(size_t index1, + size_t index2, + size_t index3) const; virtual float findValue(float value1, float value2, float value3) const; @@ -312,7 +325,10 @@ public: virtual ~Table1(); virtual int order() const { return 1; } virtual TableAxis *axis1() const { return axis1_; } - float tableValue(size_t index1) const; + virtual float value(size_t index1, + size_t index2, + size_t index3) const; + float value(size_t index1) const; virtual float findValue(float value1, float value2, float value3) const; @@ -349,8 +365,11 @@ public: virtual int order() const { return 2; } TableAxis *axis1() const { return axis1_; } TableAxis *axis2() const { return axis2_; } - float tableValue(size_t index1, - size_t index2) const; + virtual float value(size_t index1, + size_t index2, + size_t index3) const; + float value(size_t index1, + size_t index2) const; virtual float findValue(float value1, float value2, float value3) const; @@ -392,9 +411,9 @@ public: virtual ~Table3(); virtual int order() const { return 3; } TableAxis *axis3() const { return axis3_; } - float tableValue(size_t index1, - size_t index2, - size_t index3) const; + virtual float value(size_t index1, + size_t index2, + size_t index3) const; virtual float findValue(float value1, float value2, float value3) const; diff --git a/include/sta/TimingArc.hh b/include/sta/TimingArc.hh index 0b5c8d88..8489c6f5 100644 --- a/include/sta/TimingArc.hh +++ b/include/sta/TimingArc.hh @@ -154,7 +154,8 @@ public: void arcsFrom(const RiseFall *from_rf, // Return values. TimingArc *&arc1, - TimingArc *&arc2); + TimingArc *&arc2) const; + TimingArc *arcTo(const RiseFall *to_rf) const; const TimingArcSeq &arcs() const { return arcs_; } // Use the TimingArcSetArcIterator(arc_set) constructor instead. TimingArcSetArcIterator *timingArcIterator() __attribute__ ((deprecated)); @@ -215,6 +216,7 @@ protected: bool is_disabled_constraint_; TimingArc *from_arc1_[RiseFall::index_count]; TimingArc *from_arc2_[RiseFall::index_count]; + TimingArc *to_arc_[RiseFall::index_count]; static TimingArcSet *wire_timing_arc_set_; }; diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index d525e050..76041d99 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -192,6 +192,19 @@ LibertyLibrary::findTableTemplate(const char *name, return template_maps_[int(type)][name]; } +TableTemplateSeq +LibertyLibrary::tableTemplates() const +{ + TableTemplateSeq tbl_templates; + for (int type = 0; type < table_template_type_count; type++) { + for (auto name_template : template_maps_[type]) { + TableTemplate *tbl_template = name_template.second; + tbl_templates.push_back(tbl_template); + } + } + return tbl_templates; +} + void LibertyLibrary::setNominalProcess(float process) { diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index aaf6667e..5eb249b5 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -3721,7 +3721,8 @@ LibertyReader::endCellRiseFall(LibertyGroup *group) { if (table_) { if (GateTableModel::checkAxes(table_)) { - TableModel *table_model = new TableModel(table_, scale_factor_type_, rf_); + TableModel *table_model = new TableModel(table_, tbl_template_, + scale_factor_type_, rf_); timing_->setCell(rf_, table_model); } else { @@ -3749,7 +3750,8 @@ LibertyReader::endRiseFallTransition(LibertyGroup *group) { if (table_) { if (GateTableModel::checkAxes(table_)) { - TableModel *table_model = new TableModel(table_, scale_factor_type_, rf_); + TableModel *table_model = new TableModel(table_, tbl_template_, + scale_factor_type_, rf_); timing_->setTransition(rf_, table_model); } else { @@ -3779,7 +3781,8 @@ LibertyReader::endRiseFallConstraint(LibertyGroup *group) { if (table_) { if (CheckTableModel::checkAxes(table_)) { - TableModel *table_model = new TableModel(table_, scale_factor_type_, rf_); + TableModel *table_model = new TableModel(table_, tbl_template_, + scale_factor_type_, rf_); timing_->setConstraint(rf_, table_model); } else { @@ -3815,7 +3818,8 @@ LibertyReader::endRiseFallTransitionDegredation(LibertyGroup *group) { if (table_) { if (LibertyLibrary::checkSlewDegradationAxes(table_)) { - TableModel *table_model = new TableModel(table_, scale_factor_type_, rf_); + TableModel *table_model = new TableModel(table_, tbl_template_, + scale_factor_type_, rf_); library_->setWireSlewDegradationTable(table_model, rf_); } else { @@ -3911,7 +3915,7 @@ LibertyReader::visitValues(LibertyAttr *attr) void LibertyReader::makeTable(LibertyAttr *attr, - float scale) + float scale) { if (attr->isComplex()) { makeTableAxis(0); @@ -4540,7 +4544,8 @@ void LibertyReader::endRiseFallPower(LibertyGroup *) { if (table_) { - TableModel *table_model = new TableModel(table_, scale_factor_type_, rf_); + TableModel *table_model = new TableModel(table_, tbl_template_, + scale_factor_type_, rf_); internal_power_->setModel(rf_, new InternalPowerModel(table_model)); } endTableModel(); @@ -4550,7 +4555,8 @@ void LibertyReader::endPower(LibertyGroup *) { if (table_) { - TableModel *table_model = new TableModel(table_, scale_factor_type_, rf_); + TableModel *table_model = new TableModel(table_, tbl_template_, + scale_factor_type_, rf_); // Share the model for rise/fall. InternalPowerModel *power_model = new InternalPowerModel(table_model); internal_power_->setModel(RiseFall::rise(), power_model); @@ -4735,7 +4741,8 @@ LibertyReader::endOcvSigmaCell(LibertyGroup *group) { if (table_) { if (GateTableModel::checkAxes(table_)) { - TableModel *table_model = new TableModel(table_, scale_factor_type_, rf_); + TableModel *table_model = new TableModel(table_, tbl_template_, + scale_factor_type_, rf_); if (sigma_type_ == EarlyLateAll::all()) { timing_->setDelaySigma(rf_, EarlyLate::min(), table_model); timing_->setDelaySigma(rf_, EarlyLate::max(), table_model); @@ -4768,7 +4775,8 @@ LibertyReader::endOcvSigmaTransition(LibertyGroup *group) { if (table_) { if (GateTableModel::checkAxes(table_)) { - TableModel *table_model = new TableModel(table_, scale_factor_type_, rf_); + TableModel *table_model = new TableModel(table_, tbl_template_, + scale_factor_type_, rf_); if (sigma_type_ == EarlyLateAll::all()) { timing_->setSlewSigma(rf_, EarlyLate::min(), table_model); timing_->setSlewSigma(rf_, EarlyLate::max(), table_model); @@ -4801,7 +4809,8 @@ LibertyReader::endOcvSigmaConstraint(LibertyGroup *group) { if (table_) { if (CheckTableModel::checkAxes(table_)) { - TableModel *table_model = new TableModel(table_, scale_factor_type_, rf_); + TableModel *table_model = new TableModel(table_, tbl_template_, + scale_factor_type_, rf_); if (sigma_type_ == EarlyLateAll::all()) { timing_->setConstraintSigma(rf_, EarlyLate::min(), table_model); timing_->setConstraintSigma(rf_, EarlyLate::max(), table_model); diff --git a/liberty/LibertyWriter.cc b/liberty/LibertyWriter.cc index 45b9fe36..733a819e 100644 --- a/liberty/LibertyWriter.cc +++ b/liberty/LibertyWriter.cc @@ -24,6 +24,8 @@ #include "Liberty.hh" #include "TimingRole.hh" #include "TimingArc.hh" +#include "TimingModel.hh" +#include "TableModel.hh" #include "StaState.hh" namespace sta { @@ -40,9 +42,20 @@ public: protected: void writeHeader(); void writeFooter(); + void writeTableTemplates(); + void writeTableTemplate(TableTemplate *tbl_template); + void writeCells(); void writeCell(const LibertyCell *cell); void writePort(const LibertyPort *port); void writeTimingArcSet(const TimingArcSet *arc_set); + void writeTimingModels(const TimingArc *arc, + RiseFall *rf); + void writeTableModel(const TableModel *model); + void writeTableModel0(const TableModel *model); + void writeTableModel2(const TableModel *model); + void writeTableAxis(TableAxis *axis, + int index); + const char *asString(bool value); const char *asString(const PortDirection *dir); const char *timingTypeString(const TimingArcSet *arc_set); @@ -87,11 +100,10 @@ void LibertyWriter::writeLibrary() { writeHeader(); - LibertyCellIterator cell_iter(library_); - while (cell_iter.hasNext()) { - const LibertyCell *cell = cell_iter.next(); - writeCell(cell); - } + fprintf(stream_, "\n"); + writeTableTemplates(); + fprintf(stream_, "\n"); + writeCells(); writeFooter(); } @@ -174,6 +186,64 @@ LibertyWriter::writeHeader() library_->nominalVoltage()); } +void +LibertyWriter::writeTableTemplates() +{ + for (TableTemplate *tbl_template : library_->tableTemplates()) + writeTableTemplate(tbl_template); +} + +void +LibertyWriter::writeTableTemplate(TableTemplate *tbl_template) +{ + fprintf(stream_, " lu_table_template(%s) {\n", tbl_template->name()); + TableAxis *axis1 = tbl_template->axis1(); + TableAxis *axis2 = tbl_template->axis2(); + TableAxis *axis3 = tbl_template->axis3(); + if (axis1) + fprintf(stream_, " variable_1 : %s;\n", + tableVariableString(axis1->variable())); + if (axis2) + fprintf(stream_, " variable_2 : %s;\n", + tableVariableString(axis2->variable())); + if (axis3) + fprintf(stream_, " variable_3 : %s;\n", + tableVariableString(axis3->variable())); + if (axis1) + writeTableAxis(axis1, 1); + if (axis2) + writeTableAxis(axis2, 2); + if (axis3) + writeTableAxis(axis3, 3); + fprintf(stream_, " }\n"); +} + +void +LibertyWriter::writeTableAxis(TableAxis *axis, + int index) +{ + fprintf(stream_, " index_%d (\"", index); + const Unit *unit = tableVariableUnit(axis->variable(), library_->units()); + bool first = true; + for (size_t i = 0; i < axis->size(); i++) { + if (!first) + fprintf(stream_, ", "); + fprintf(stream_, "%s", unit->asString(axis->axisValue(i), 5)); + first = false; + } + fprintf(stream_, "\");\n"); +} + +void +LibertyWriter::writeCells() +{ + LibertyCellIterator cell_iter(library_); + while (cell_iter.hasNext()) { + const LibertyCell *cell = cell_iter.next(); + writeCell(cell); + } +} + void LibertyWriter::writeCell(const LibertyCell *cell) { @@ -196,10 +266,10 @@ void LibertyWriter::writePort(const LibertyPort *port) { fprintf(stream_, " pin(\"%s\") {\n", port->name()); + fprintf(stream_, " direction : %s;\n" , asString(port->direction())); auto func = port->function(); if (func) fprintf(stream_, " function : \"%s\";\n", func->asString()); - fprintf(stream_, " direction : %s;\n" , asString(port->direction())); if (port->isClock()) fprintf(stream_, " clock : true;\n"); fprintf(stream_, " capacitance : %s;\n", @@ -237,9 +307,96 @@ LibertyWriter::writeTimingArcSet(const TimingArcSet *arc_set) const char *timing_type = timingTypeString(arc_set); if (timing_type) fprintf(stream_, " timing_type : %s;\n", timing_type); + + for (RiseFall *rf : RiseFall::range()) { + TimingArc *arc = arc_set->arcTo(rf); + if (arc) + writeTimingModels(arc, rf); + } + fprintf(stream_, " }\n"); } +void +LibertyWriter::writeTimingModels(const TimingArc *arc, + RiseFall *rf) +{ + TimingModel *model = arc->model(); + const GateTableModel *gate_model = dynamic_cast(model); + const CheckTableModel *check_model = dynamic_cast(model); + if (gate_model) { + const TableModel *delay_model = gate_model->delayModel(); + const char *template_name = delay_model->tblTemplate()->name(); + fprintf(stream_, " cell_%s(%s) {\n", rf->name(), template_name); + writeTableModel(delay_model); + fprintf(stream_, " }\n"); + + const TableModel *slew_model = gate_model->slewModel(); + template_name = slew_model->tblTemplate()->name(); + fprintf(stream_, " %s_transition(%s) {\n", rf->name(), template_name); + writeTableModel(slew_model); + fprintf(stream_, " }\n"); + } else if (check_model) { + const TableModel *model = check_model->model(); + const char *template_name = model->tblTemplate()->name(); + fprintf(stream_, " %s_constraint(%s) {\n", rf->name(), template_name); + writeTableModel(model); + fprintf(stream_, " }\n"); + } + else + criticalError(701, "timing model not supported."); +} + +void +LibertyWriter::writeTableModel(const TableModel *model) +{ + switch (model->order()) { + case 0: + writeTableModel0(model); + break; + case 1: + break; + case 2: + writeTableModel2(model); + break; + case 3: + criticalError(701, "3 axis table models not supported."); + break; + } +} + +void +LibertyWriter::writeTableModel0(const TableModel *model) +{ + float value = model->value(0, 0, 0); + fprintf(stream_, " values(\"%s\");\n", + time_unit_->asString(value, 5)); +} + +void +LibertyWriter::writeTableModel2(const TableModel *model) +{ + fprintf(stream_, " values(\""); + bool first_row = true; + for (size_t index1 = 0; index1 < model->axis1()->size(); index1++) { + if (!first_row) { + fprintf(stream_, "\\\n"); + fprintf(stream_, " \""); + } + bool first_col = true; + for (size_t index2 = 0; index2 < model->axis2()->size(); index2++) { + float value = model->value(index1, index2, 0); + if (!first_col) + fprintf(stream_, ","); + fprintf(stream_, "%s", time_unit_->asString(value, 5)); + first_col = false; + } + fprintf(stream_, "\""); + first_row = false; + } + fprintf(stream_, ");\n"); +} + void LibertyWriter::writeFooter() { diff --git a/liberty/TableModel.cc b/liberty/TableModel.cc index f49bc9d7..c039b76b 100644 --- a/liberty/TableModel.cc +++ b/liberty/TableModel.cc @@ -556,9 +556,11 @@ CheckTableModel::checkAxis(TableAxis *axis) //////////////////////////////////////////////////////////////// TableModel::TableModel(Table *table, + TableTemplate *tbl_template, ScaleFactorType scale_factor_type, RiseFall *rf) : table_(table), + tbl_template_(tbl_template), scale_factor_type_(int(scale_factor_type)), tr_index_(rf->index()), is_scaled_(false) @@ -606,6 +608,14 @@ TableModel::axis3() const return table_->axis3(); } +float +TableModel::value(size_t index1, + size_t index2, + size_t index3) const +{ + return table_->value(index1, index2, index3); +} + float TableModel::findValue(const LibertyLibrary *library, const LibertyCell *cell, @@ -702,6 +712,14 @@ Table0::Table0(float value) : { } +float +Table0::value(size_t, + size_t, + size_t) const +{ + return value_; +} + float Table0::findValue(float, float, @@ -761,7 +779,15 @@ Table1::~Table1() } float -Table1::tableValue(size_t index1) const +Table1::value(size_t index1, + size_t, + size_t) const +{ + return value(index1); +} + +float +Table1::value(size_t index1) const { return (*values_)[index1]; } @@ -772,14 +798,14 @@ Table1::findValue(float value1, float) const { if (axis1_->size() == 1) - return tableValue(value1); + return value(value1); else { size_t index1 = axis1_->findAxisIndex(value1); float x1 = value1; float x1l = axis1_->axisValue(index1); float x1u = axis1_->axisValue(index1 + 1); - float y1 = tableValue(index1); - float y2 = tableValue(index1 + 1); + float y1 = value(index1); + float y2 = value(index1 + 1); float dx1 = (x1 - x1l) / (x1u - x1l); return (1 - dx1) * y1 + dx1 * y2; } @@ -821,9 +847,9 @@ Table1::reportValue(const char *result_name, const *result += " --------------------\n"; *result += "| "; - *result += table_unit->asString(tableValue(index1), digits); + *result += table_unit->asString(value(index1), digits); *result += " "; - *result += table_unit->asString(tableValue(index1 + 1), + *result += table_unit->asString(value(index1 + 1), digits); *result += '\n'; } @@ -852,7 +878,7 @@ Table1::report(const Units *units, line.clear(); for (size_t index1 = 0; index1 < axis1_->size(); index1++) { - line += table_unit->asString(tableValue(index1), digits); + line += table_unit->asString(value(index1), digits); line += " "; } report->reportLineString(line); @@ -885,8 +911,16 @@ Table2::~Table2() } float -Table2::tableValue(size_t index1, - size_t index2) const +Table2::value(size_t index1, + size_t index2, + size_t) const +{ + return value(index1, index2); +} + +float +Table2::value(size_t index1, + size_t index2) const { FloatSeq *row = (*values_)[index1]; return (*row)[index2]; @@ -902,15 +936,15 @@ Table2::findValue(float value1, size_t size2 = axis2_->size(); if (size1 == 1) { if (size2 == 1) - return tableValue(0, 0); + return value(0, 0); else { size_t index2 = axis2_->findAxisIndex(value2); float x2 = value2; - float y00 = tableValue(0, index2); + float y00 = value(0, index2); float x2l = axis2_->axisValue(index2); float x2u = axis2_->axisValue(index2 + 1); float dx2 = (x2 - x2l) / (x2u - x2l); - float y01 = tableValue(0, index2 + 1); + float y01 = value(0, index2 + 1); float tbl_value = (1 - dx2) * y00 + dx2 * y01; @@ -920,11 +954,11 @@ Table2::findValue(float value1, else if (size2 == 1) { size_t index1 = axis1_->findAxisIndex(value1); float x1 = value1; - float y00 = tableValue(index1, 0); + float y00 = value(index1, 0); float x1l = axis1_->axisValue(index1); float x1u = axis1_->axisValue(index1 + 1); float dx1 = (x1 - x1l) / (x1u - x1l); - float y10 = tableValue(index1 + 1, 0); + float y10 = value(index1 + 1, 0); float tbl_value = (1 - dx1) * y00 + dx1 * y10; @@ -935,16 +969,16 @@ Table2::findValue(float value1, size_t index2 = axis2_->findAxisIndex(value2); float x1 = value1; float x2 = value2; - float y00 = tableValue(index1, index2); + float y00 = value(index1, index2); float x1l = axis1_->axisValue(index1); float x1u = axis1_->axisValue(index1 + 1); float dx1 = (x1 - x1l) / (x1u - x1l); - float y10 = tableValue(index1 + 1, index2); - float y11 = tableValue(index1 + 1, index2 + 1); + float y10 = value(index1 + 1, index2); + float y11 = value(index1 + 1, index2 + 1); float x2l = axis2_->axisValue(index2); float x2u = axis2_->axisValue(index2 + 1); float dx2 = (x2 - x2l) / (x2u - x2l); - float y01 = tableValue(index1, index2 + 1); + float y01 = value(index1, index2 + 1); float tbl_value = (1 - dx1) * (1 - dx2) * y00 + dx1 * (1 - dx2) * y10 @@ -1000,20 +1034,20 @@ Table2::reportValue(const char *result_name, *result += unit1->asString(axis1_->axisValue(index1), digits); *result += " | "; - *result += table_unit->asString(tableValue(index1, index2), digits); + *result += table_unit->asString(value(index1, index2), digits); if (axis2_->size() != 1) { *result += " "; - *result += table_unit->asString(tableValue(index1, index2 + 1), digits); + *result += table_unit->asString(value(index1, index2 + 1), digits); } *result += '\n'; if (axis1_->size() != 1) { *result += unit1->asString(axis1_->axisValue(index1 + 1), digits); *result += " | "; - *result += table_unit->asString(tableValue(index1 + 1, index2), digits); + *result += table_unit->asString(value(index1 + 1, index2), digits); if (axis2_->size() != 1) { *result += " "; - *result +=table_unit->asString(tableValue(index1 + 1, index2 + 1),digits); + *result +=table_unit->asString(value(index1 + 1, index2 + 1),digits); } } *result += '\n'; @@ -1045,7 +1079,7 @@ Table2::report(const Units *units, line = unit1->asString(axis1_->axisValue(index1), digits); line += " |"; for (size_t index2 = 0; index2 < axis2_->size(); index2++) { - line += table_unit->asString(tableValue(index1, index2), digits); + line += table_unit->asString(value(index1, index2), digits); line += " "; } report->reportLineString(line); @@ -1074,9 +1108,9 @@ Table3::~Table3() } float -Table3::tableValue(size_t index1, - size_t index2, - size_t index3) const +Table3::value(size_t index1, + size_t index2, + size_t index3) const { size_t row = index1 * axis2_->size() + index2; return values_->operator[](row)->operator[](index3); @@ -1097,7 +1131,7 @@ Table3::findValue(float value1, float dx1 = 0.0; float dx2 = 0.0; float dx3 = 0.0; - float y000 = tableValue(index1, index2, index3); + float y000 = value(index1, index2, index3); float y001 = 0.0; float y010 = 0.0; float y011 = 0.0; @@ -1110,28 +1144,28 @@ Table3::findValue(float value1, float x1l = axis1_->axisValue(index1); float x1u = axis1_->axisValue(index1 + 1); dx1 = (x1 - x1l) / (x1u - x1l); - y100 = tableValue(index1 + 1, index2, index3); + y100 = value(index1 + 1, index2, index3); if (axis3_->size() != 1) - y101 = tableValue(index1 + 1, index2, index3 + 1); + y101 = value(index1 + 1, index2, index3 + 1); if (axis2_->size() != 1) { - y110 = tableValue(index1 + 1, index2 + 1, index3); + y110 = value(index1 + 1, index2 + 1, index3); if (axis3_->size() != 1) - y111 = tableValue(index1 + 1, index2 + 1, index3 + 1); + y111 = value(index1 + 1, index2 + 1, index3 + 1); } } if (axis2_->size() != 1) { float x2l = axis2_->axisValue(index2); float x2u = axis2_->axisValue(index2 + 1); dx2 = (x2 - x2l) / (x2u - x2l); - y010 = tableValue(index1, index2 + 1, index3); + y010 = value(index1, index2 + 1, index3); if (axis3_->size() != 1) - y011 = tableValue(index1, index2 + 1, index3 + 1); + y011 = value(index1, index2 + 1, index3 + 1); } if (axis3_->size() != 1) { float x3l = axis3_->axisValue(index3); float x3u = axis3_->axisValue(index3 + 1); dx3 = (x3 - x3l) / (x3u - x3l); - y001 = tableValue(index1, index2, index3 + 1); + y001 = value(index1, index2, index3 + 1); } float tbl_value @@ -1216,11 +1250,11 @@ Table3::reportValue(const char *result_name, *result += " "; *result += unit1->asString(axis1_->axisValue(index1+1), digits); *result += " v / "; - *result += table_unit->asString(tableValue(index1+1,index2,index3), + *result += table_unit->asString(value(index1+1,index2,index3), digits); if (axis3_->size() != 1) { *result += " "; - *result += table_unit->asString(tableValue(index1+1,index2,index3+1), + *result += table_unit->asString(value(index1+1,index2,index3+1), digits); } } @@ -1234,10 +1268,10 @@ Table3::reportValue(const char *result_name, *result += " "; *result += unit2->asString(axis2_->axisValue(index2), digits); *result += " | "; - *result += table_unit->asString(tableValue(index1, index2, index3), digits); + *result += table_unit->asString(value(index1, index2, index3), digits); if (axis3_->size() != 1) { *result += " "; - *result += table_unit->asString(tableValue(index1, index2, index3+1), + *result += table_unit->asString(value(index1, index2, index3+1), digits); } *result += '\n'; @@ -1245,11 +1279,11 @@ Table3::reportValue(const char *result_name, *result += " |/ "; if (axis1_->size() != 1 && axis2_->size() != 1) { - *result += table_unit->asString(tableValue(index1+1,index2+1,index3), + *result += table_unit->asString(value(index1+1,index2+1,index3), digits); if (axis3_->size() != 1) { *result += " "; - *result +=table_unit->asString(tableValue(index1+1,index2+1,index3+1), + *result +=table_unit->asString(value(index1+1,index2+1,index3+1), digits); } } @@ -1259,11 +1293,11 @@ Table3::reportValue(const char *result_name, *result += unit2->asString(axis2_->axisValue(index2 + 1), digits); *result += " | "; if (axis2_->size() != 1) { - *result += table_unit->asString(tableValue(index1, index2+1, index3), + *result += table_unit->asString(value(index1, index2+1, index3), digits); if (axis3_->size() != 1) { *result += " "; - *result +=table_unit->asString(tableValue(index1, index2+1,index3+1), + *result +=table_unit->asString(value(index1, index2+1,index3+1), digits); } } @@ -1309,7 +1343,7 @@ Table3::report(const Units *units, line = unit2->asString(axis2_->axisValue(index2),digits); line += " |"; for (size_t index3 = 0; index3 < axis3_->size(); index3++) { - line += table_unit->asString(tableValue(index1, index2, index3), digits); + line += table_unit->asString(value(index1, index2, index3), digits); line += " "; } report->reportLineString(line); diff --git a/liberty/TimingArc.cc b/liberty/TimingArc.cc index ef498a3d..39d35fdf 100644 --- a/liberty/TimingArc.cc +++ b/liberty/TimingArc.cc @@ -219,6 +219,7 @@ TimingArcSet::init(LibertyCell *cell) for (auto tr_index : RiseFall::rangeIndex()) { from_arc1_[tr_index] = nullptr; from_arc2_[tr_index] = nullptr; + to_arc_[tr_index] = nullptr; } } @@ -263,6 +264,9 @@ TimingArcSet::addTimingArc(TimingArc *arc) else if (from_arc2_[from_rf_index] == nullptr) from_arc2_[from_rf_index] = arc; + int to_rf_index = arc->toEdge()->asRiseFall()->index(); + to_arc_[to_rf_index] = arc; + return arc_index; } @@ -309,13 +313,19 @@ void TimingArcSet::arcsFrom(const RiseFall *from_rf, // Return values. TimingArc *&arc1, - TimingArc *&arc2) + TimingArc *&arc2) const { int tr_index = from_rf->index(); arc1 = from_arc1_[tr_index]; arc2 = from_arc2_[tr_index]; } +TimingArc * +TimingArcSet::arcTo(const RiseFall *to_rf) const +{ + return to_arc_[to_rf->index()]; +} + TimingSense TimingArcSet::sense() const { diff --git a/messages.txt b/messages.txt index 4d9e6a11..d1cb2749 100644 --- a/messages.txt +++ b/messages.txt @@ -1,9 +1,9 @@ 0001 DmpCeff.cc:1595 cell %s delay model not supported on SPF parasitics by DMP delay calculator -0002 Liberty.cc:728 cell %s/%s port %s not found in cell %s/%s. -0003 Liberty.cc:751 cell %s/%s %s -> %s timing group %s not found in cell %s/%s. -0004 Liberty.cc:1646 cell %s/%s %s -> %s latch enable %s_edge timing arc is inconsistent with %s -> %s setup_%s check. -0005 Liberty.cc:1661 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function positive sense. -0006 Liberty.cc:1669 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function negative sense. +0002 Liberty.cc:739 cell %s/%s port %s not found in cell %s/%s. +0003 Liberty.cc:762 cell %s/%s %s -> %s timing group %s not found in cell %s/%s. +0004 Liberty.cc:1657 cell %s/%s %s -> %s latch enable %s_edge timing arc is inconsistent with %s -> %s setup_%s check. +0005 Liberty.cc:1672 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function positive sense. +0006 Liberty.cc:1680 cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function negative sense. 0007 LibertyExpr.cc:78 %s references unknown port %s. 0008 ConcreteNetwork.cc:1855 cell type %s can not be linked. 0009 CycleAccting.cc:87 No common period was found between clocks %s and %s. @@ -110,58 +110,58 @@ 0115 LibertyReader.cc:3647 mode name is not a string. 0116 LibertyReader.cc:3650 mode missing values. 0117 LibertyReader.cc:3653 mode missing mode name and value. -0118 LibertyReader.cc:3728 unsupported model axis. -0119 LibertyReader.cc:3756 unsupported model axis. -0120 LibertyReader.cc:3786 unsupported model axis. -0121 LibertyReader.cc:3822 unsupported model axis. -0122 LibertyReader.cc:3874 table template %s not found. -0123 LibertyReader.cc:3961 %s is missing values. -0124 LibertyReader.cc:3986 %s is not a list of floats. -0125 LibertyReader.cc:3988 table row has %u columns but axis has %d. -0126 LibertyReader.cc:3998 table has %u rows but axis has %d. -0127 LibertyReader.cc:4052 lut output is not a string. -0128 LibertyReader.cc:4090 mode definition missing name. -0129 LibertyReader.cc:4107 mode value missing name. -0130 LibertyReader.cc:4121 when attribute inside table model. -0131 LibertyReader.cc:4170 %s attribute is not a string. -0132 LibertyReader.cc:4173 %s is not a simple attribute. -0133 LibertyReader.cc:4196 %s is not a simple attribute. -0134 LibertyReader.cc:4209 %s is not a simple attribute. -0135 LibertyReader.cc:4233 %s value %s is not a float. -0136 LibertyReader.cc:4262 %s missing values. -0137 LibertyReader.cc:4266 %s missing values. -0138 LibertyReader.cc:4269 %s is not a complex attribute. -0139 LibertyReader.cc:4295 %s is not a float. -0140 LibertyReader.cc:4314 %s is missing values. -0141 LibertyReader.cc:4317 %s has more than one string. -0142 LibertyReader.cc:4326 %s is missing values. -0143 LibertyReader.cc:4351 %s attribute is not boolean. -0144 LibertyReader.cc:4354 %s attribute is not boolean. -0145 LibertyReader.cc:4357 %s is not a simple attribute. -0146 LibertyReader.cc:4373 attribute %s value %s not recognized. -0147 LibertyReader.cc:4403 unknown early/late value. -0148 LibertyReader.cc:4627 OCV derate group named %s not found. -0149 LibertyReader.cc:4643 ocv_derate missing name. -0150 LibertyReader.cc:4696 unknown rise/fall. -0151 LibertyReader.cc:4716 unknown derate type. -0152 LibertyReader.cc:4747 unsupported model axis. -0153 LibertyReader.cc:4780 unsupported model axis. -0154 LibertyReader.cc:4813 unsupported model axis. -0155 LibertyReader.cc:4886 unknown pg_type. -0156 LibertyReader.cc:5263 port %s subscript out of range. -0157 LibertyReader.cc:5267 port range %s of non-bus port %s. -0158 LibertyReader.cc:5281 port %s not found. -0159 LibertyReader.cc:5351 port %s not found. +0118 LibertyReader.cc:3729 unsupported model axis. +0119 LibertyReader.cc:3758 unsupported model axis. +0120 LibertyReader.cc:3789 unsupported model axis. +0121 LibertyReader.cc:3826 unsupported model axis. +0122 LibertyReader.cc:3878 table template %s not found. +0123 LibertyReader.cc:3965 %s is missing values. +0124 LibertyReader.cc:3990 %s is not a list of floats. +0125 LibertyReader.cc:3992 table row has %u columns but axis has %d. +0126 LibertyReader.cc:4002 table has %u rows but axis has %d. +0127 LibertyReader.cc:4056 lut output is not a string. +0128 LibertyReader.cc:4094 mode definition missing name. +0129 LibertyReader.cc:4111 mode value missing name. +0130 LibertyReader.cc:4125 when attribute inside table model. +0131 LibertyReader.cc:4174 %s attribute is not a string. +0132 LibertyReader.cc:4177 %s is not a simple attribute. +0133 LibertyReader.cc:4200 %s is not a simple attribute. +0134 LibertyReader.cc:4213 %s is not a simple attribute. +0135 LibertyReader.cc:4237 %s value %s is not a float. +0136 LibertyReader.cc:4266 %s missing values. +0137 LibertyReader.cc:4270 %s missing values. +0138 LibertyReader.cc:4273 %s is not a complex attribute. +0139 LibertyReader.cc:4299 %s is not a float. +0140 LibertyReader.cc:4318 %s is missing values. +0141 LibertyReader.cc:4321 %s has more than one string. +0142 LibertyReader.cc:4330 %s is missing values. +0143 LibertyReader.cc:4355 %s attribute is not boolean. +0144 LibertyReader.cc:4358 %s attribute is not boolean. +0145 LibertyReader.cc:4361 %s is not a simple attribute. +0146 LibertyReader.cc:4377 attribute %s value %s not recognized. +0147 LibertyReader.cc:4407 unknown early/late value. +0148 LibertyReader.cc:4633 OCV derate group named %s not found. +0149 LibertyReader.cc:4649 ocv_derate missing name. +0150 LibertyReader.cc:4702 unknown rise/fall. +0151 LibertyReader.cc:4722 unknown derate type. +0152 LibertyReader.cc:4754 unsupported model axis. +0153 LibertyReader.cc:4788 unsupported model axis. +0154 LibertyReader.cc:4822 unsupported model axis. +0155 LibertyReader.cc:4895 unknown pg_type. +0156 LibertyReader.cc:5272 port %s subscript out of range. +0157 LibertyReader.cc:5276 port range %s of non-bus port %s. +0158 LibertyReader.cc:5290 port %s not found. +0159 LibertyReader.cc:5360 port %s not found. 0160 LibertyReader.cc:981 default_max_transition is 0.0. 0161 LibertyReader.cc:3092 max_transition is 0.0. -0162 LibertyReader.cc:4193 %s attribute is not an integer. +0162 LibertyReader.cc:4197 %s attribute is not an integer. 0163 LibertyReader.cc:1086 default_fanout_load is 0.0. 0179 SpefReader.cc:728 %s. 0190 VerilogReader.cc:1728 %s is not a verilog module. 0191 VerilogReader.cc:1733 %s is not a verilog module. -0201 StaTcl.i:128 no network has been linked. -0202 StaTcl.i:142 network does not support edits. -0204 StaTcl.i:4174 POCV support requires compilation with SSTA=1. +0201 StaTcl.i:129 no network has been linked. +0202 StaTcl.i:143 network does not support edits. +0204 StaTcl.i:4182 POCV support requires compilation with SSTA=1. 0206 LibertyExpr.cc:171 %s %s. 0207 GraphDelayCalc1.cc:742 port not found in cell 0208 Graph.cc:795 arc_delay_annotated array bounds exceeded @@ -191,8 +191,8 @@ 0265 TagGroup.cc:297 tag group missing tag 0266 Sta.cc:2080 '%s' is not a valid endpoint. 0267 Sta.cc:2004 '%s' is not a valid startpoint. -0272 StaTcl.i:4160 unknown common clk pessimism mode. -0273 StaTcl.i:5168 unknown clock sense +0272 StaTcl.i:4168 unknown common clk pessimism mode. +0273 StaTcl.i:5176 unknown clock sense 0300 Util.tcl:218 no commands match '$pattern'. 0301 Power.tcl:215 activity should be 0.0 to 1.0 or 2.0 0302 Power.tcl:223 duty should be 0.0 to 1.0 @@ -461,8 +461,8 @@ 0604 Sdc.tcl:272 unknown $unit prefix '$prefix'. 0605 Sdc.tcl:3064 wire load model '$model_name' not found. 0606 Sta.tcl:1136 get_property unsupported object type $object_type. -0607 StaTcl.i:4410 unknown report path field %s -0608 StaTcl.i:4422 unknown report path field %s +0607 StaTcl.i:4418 unknown report path field %s +0608 StaTcl.i:4430 unknown report path field %s 0609 Search.tcl:427 -all_violators is deprecated. Use -violators 0610 Search.tcl:507 -max_transition deprecated. Use -max_slew. 0611 Search.tcl:512 -min_transition deprecated. Use -min_slew. @@ -476,4 +476,3 @@ 0622 PathVertex.cc:279 missing requireds. 0623 PathVertexRep.cc:153 missing arrivals. 0624 PathVertexRep.cc:150 missing arrivals -700