diff --git a/include/sta/Bfs.hh b/include/sta/Bfs.hh index bf198cf5..89080010 100644 --- a/include/sta/Bfs.hh +++ b/include/sta/Bfs.hh @@ -75,7 +75,7 @@ public: // Notify iterator that vertex will be deleted. void deleteVertexBefore(Vertex *vertex); void remove(Vertex *vertex); - void reportEntries(); + void reportEntries() const; virtual bool hasNext(); bool hasNext(Level to_level); @@ -103,7 +103,7 @@ protected: Level level2) const = 0; virtual bool levelLessOrEqual(Level level1, Level level2) const = 0; - virtual void incrLevel(Level &level) = 0; + virtual void incrLevel(Level &level) const = 0; void findNext(Level to_level); void deleteEntries(); @@ -139,7 +139,7 @@ protected: Level level2) const; virtual bool levelLess(Level level1, Level level2) const; - virtual void incrLevel(Level &level); + virtual void incrLevel(Level &level) const; }; class BfsBkwdIterator : public BfsIterator @@ -159,7 +159,7 @@ protected: Level level2) const; virtual bool levelLess(Level level1, Level level2) const; - virtual void incrLevel(Level &level); + virtual void incrLevel(Level &level) const; }; } // namespace diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index c921ffd8..e7d64bcc 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -26,6 +26,7 @@ #include #include +#include #include "EnumNameMap.hh" #include "Report.hh" @@ -875,8 +876,23 @@ LibertyReader::visitCapacitiveLoadUnit(LibertyAttr *attr) LibertyAttrValueIterator value_iter(attr->values()); if (value_iter.hasNext()) { LibertyAttrValue *value = value_iter.next(); + bool valid = false; + float scale; if (value->isFloat()) { - float scale = value->floatValue(); + scale = value->floatValue(); + valid = true; + } + else if (value->isString()) { + try { + scale = std::stof(value->stringValue()); + valid = true; + } + catch (...) { + valid = false; + } + } + + if (valid) { if (value_iter.hasNext()) { value = value_iter.next(); if (value->isString()) { @@ -970,10 +986,24 @@ LibertyReader::visitVoltageMap(LibertyAttr *attr) const char *supply_name = value->stringValue(); if (value_iter.hasNext()) { value = value_iter.next(); + bool valid = false; + float voltage; if (value->isFloat()) { - float voltage = value->floatValue(); - library_->addSupplyVoltage(supply_name, voltage); + voltage = value->floatValue(); + valid = true; } + else if (value->isString()) { + try { + voltage = std::stof(value->stringValue()); + valid = true; + } + catch (...) { + valid = false; + } + } + + if (valid) + library_->addSupplyVoltage(supply_name, voltage); else libWarn(1166, attr, "voltage_map voltage is not a float."); } diff --git a/search/Bfs.cc b/search/Bfs.cc index 26472622..42cb4885 100644 --- a/search/Bfs.cc +++ b/search/Bfs.cc @@ -89,19 +89,16 @@ BfsIterator::clear() } void -BfsIterator::reportEntries() +BfsIterator::reportEntries() const { - Level level = first_level_; - while (levelLessOrEqual(level, last_level_)) { - VertexSeq &level_vertices = queue_[level]; + for (Level level=first_level_; levelLessOrEqual(level, last_level_);incrLevel(level)){ + const VertexSeq &level_vertices = queue_[level]; if (!level_vertices.empty()) { report_->reportLine("Level %d", level); - for (Vertex *vertex : level_vertices) { - if (vertex) - report_->reportLine(" %s", vertex->to_string(this).c_str()); - } + for (Vertex *vertex : level_vertices) + report_->reportLine(" %s", + vertex ? vertex->to_string(this).c_str() : "NULL"); } - incrLevel(level); } } @@ -255,9 +252,18 @@ void BfsIterator::findNext(Level to_level) { while (levelLessOrEqual(first_level_, last_level_) - && levelLessOrEqual(first_level_, to_level) - && queue_[first_level_].empty()) + && levelLessOrEqual(first_level_, to_level)) { + VertexSeq &level_vertices = queue_[first_level_]; + // Skip null entries from deleted vertices. + while (!level_vertices.empty()) { + Vertex *vertex = level_vertices.back(); + if (vertex == nullptr) + level_vertices.pop_back(); + else + return; + } incrLevel(first_level_); + } } void @@ -283,7 +289,7 @@ BfsIterator::enqueue(Vertex *vertex) bool BfsIterator::inQueue(Vertex *vertex) { - // checkInQueue(vertex); + // checkInQueue(vertex); return vertex->bfsInQueue(bfs_index_); } @@ -319,6 +325,9 @@ BfsIterator::remove(Vertex *vertex) Level level = vertex->level(); if (vertex->bfsInQueue(bfs_index_) && static_cast(queue_.size()) > level) { + debugPrint(debug_, "bfs", 2, "remove %s", + vertex->to_string(this).c_str()); + printf("bfs remove %s\n", vertex->to_string(this).c_str()); for (Vertex *&v : queue_[level]) { if (v == vertex) { v = nullptr; @@ -346,7 +355,7 @@ BfsFwdIterator::~BfsFwdIterator() } void -BfsFwdIterator::incrLevel(Level &level) +BfsFwdIterator::incrLevel(Level &level) const { level++; } @@ -400,7 +409,7 @@ BfsBkwdIterator::~BfsBkwdIterator() } void -BfsBkwdIterator::incrLevel(Level &level) +BfsBkwdIterator::incrLevel(Level &level) const { level--; } diff --git a/search/Levelize.cc b/search/Levelize.cc index 7adef739..9effdad0 100644 --- a/search/Levelize.cc +++ b/search/Levelize.cc @@ -602,7 +602,7 @@ void Levelize::relevelizeFrom(Vertex *vertex) { if (levelized_) { - debugPrint(debug_, "levelize", 1, "relevelize from %s", + debugPrint(debug_, "levelize", 1, "level invalid from %s", vertex->to_string(this).c_str()); relevelize_from_.insert(vertex); levels_valid_ = false; @@ -649,8 +649,6 @@ Levelize::relevelize() ensureLatchLevels(); levels_valid_ = true; relevelize_from_.clear(); - - checkLevels(); } void diff --git a/search/Levelize.hh b/search/Levelize.hh index 68eece66..f0e5667b 100644 --- a/search/Levelize.hh +++ b/search/Levelize.hh @@ -70,9 +70,10 @@ public: // Set the observer for level changes. void setObserver(LevelizeObserver *observer); void checkLevels(); + // Public for regression testing. + void levelize(); protected: - void levelize(); void findRoots(); VertexSeq sortedRootsWithFanout(); VertexSeq findTopologicalOrder(); diff --git a/search/Search.i b/search/Search.i index 57b6fc2f..73f4761a 100644 --- a/search/Search.i +++ b/search/Search.i @@ -32,6 +32,7 @@ #include "search/Levelize.hh" #include "search/ReportPath.hh" #include "PathExpanded.hh" +#include "Bfs.hh" #include "Sta.hh" using namespace sta; @@ -1128,6 +1129,32 @@ set_use_default_arrival_clock(bool enable) Sta::sta()->setUseDefaultArrivalClock(enable); } +// For regression tests. +void +report_arrival_entries() +{ + Sta *sta = Sta::sta(); + Search *search = sta->search(); + search->arrivalIterator()->reportEntries(); +} + +// For regression tests. +void +report_required_entries() +{ + Sta *sta = Sta::sta(); + Search *search = sta->search(); + search->requiredIterator()->reportEntries(); +} + +// For regression tests. +void +levelize() +{ + Sta *sta = Sta::sta(); + sta->levelize()->levelize(); +} + %} // inline //////////////////////////////////////////////////////////////// diff --git a/search/Sta.cc b/search/Sta.cc index b7c28bbc..a766d927 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -4486,7 +4486,7 @@ Sta::disconnectPinBefore(const Pin *pin) void Sta::deleteEdge(Edge *edge) { - debugPrint(debug_, "network_edit", 1, "delete edge %s -> %s", + debugPrint(debug_, "network_edit", 2, "delete edge %s -> %s", edge->from(graph_)->name(sdc_network_), edge->to(graph_)->name(sdc_network_)); Vertex *to = edge->to(graph_); @@ -4568,6 +4568,8 @@ void Sta::deletePinBefore(const Pin *pin) { if (graph_) { + debugPrint(debug_, "network_edit", 1, "delete pin %s", + sdc_network_->pathName(pin)); if (network_->isLoad(pin)) { Vertex *vertex = graph_->pinLoadVertex(pin); if (vertex) { diff --git a/test/liberty_float_as_str.lib b/test/liberty_float_as_str.lib new file mode 100644 index 00000000..659f4ec4 --- /dev/null +++ b/test/liberty_float_as_str.lib @@ -0,0 +1,55 @@ +library (liberty_float_as_str) { + delay_model : "table_lookup"; + simulation : false; + capacitive_load_unit ("1","fF"); + leakage_power_unit : "1pW"; + current_unit : "1A"; + pulling_resistance_unit : "1kohm"; + time_unit : "1ns"; + voltage_unit : "1v"; + library_features : "report_delay_calculation"; + input_threshold_pct_rise : 50; + input_threshold_pct_fall : 50; + output_threshold_pct_rise : 50; + output_threshold_pct_fall : 50; + slew_lower_threshold_pct_rise : 30; + slew_lower_threshold_pct_fall : 30; + slew_upper_threshold_pct_rise : 70; + slew_upper_threshold_pct_fall : 70; + slew_derate_from_library : 1.0; + nom_process : 1.0; + nom_temperature : 85.0; + nom_voltage : 0.75; + voltage_map ("VDD", "0.65"); + voltage_map ("VSS", "0"); + voltage_map ("VCC", "-0.1"); + voltage_map ("VBB", 0.1); + voltage_map ("GND", 0); + + cell (my_inv) { + pin (A) { + capacitance : 1; + direction : "input"; + } + pin (Y) { + function : "!A"; + direction : "output"; + timing () { + related_pin : "A"; + timing_sense : "negative_unate"; + cell_rise (scalar) { + values ("1"); + } + cell_fall (scalar) { + values ("1"); + } + rise_transition (scalar) { + values ("1"); + } + fall_transition (scalar) { + values ("1"); + } + } + } + } +} diff --git a/test/liberty_float_as_str.ok b/test/liberty_float_as_str.ok new file mode 100644 index 00000000..8d63396d --- /dev/null +++ b/test/liberty_float_as_str.ok @@ -0,0 +1,7 @@ + time 1ns + capacitance 1fF + resistance 1kohm + voltage 1v + current 1A + power 1pW + distance 1um diff --git a/test/liberty_float_as_str.tcl b/test/liberty_float_as_str.tcl new file mode 100644 index 00000000..b3aeae01 --- /dev/null +++ b/test/liberty_float_as_str.tcl @@ -0,0 +1,3 @@ +# liberty with float as string in voltage_map and capacitive_load_unit +read_liberty liberty_float_as_str.lib +report_units diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index 2d71a1ac..9dcfd8f4 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -147,6 +147,7 @@ record_sta_tests { liberty_arcs_one2one_2 liberty_backslash_eol liberty_ccsn + liberty_float_as_str liberty_latch3 path_group_names prima3