diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index 14dab380..5f10462c 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -423,6 +423,8 @@ public: void setIsMemory(bool is_memory); bool isPad() const { return is_pad_; } void setIsPad(bool is_pad); + bool isClockCell() const { return is_clock_cell_; } + void setIsClockCell(bool is_clock_cell); bool isLevelShifter() const { return is_level_shifter_; } void setIsLevelShifter(bool is_level_shifter); LevelShifterType levelShifterType() const { return level_shifter_type_; } @@ -564,6 +566,7 @@ protected: bool is_macro_; bool is_memory_; bool is_pad_; + bool is_clock_cell_; bool is_level_shifter_; LevelShifterType level_shifter_type_; bool is_isolation_cell_; diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 6e8a91c0..1878f113 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -925,6 +925,7 @@ LibertyCell::LibertyCell(LibertyLibrary *library, is_macro_(false), is_memory_(false), is_pad_(false), + is_clock_cell_(false), is_level_shifter_(false), level_shifter_type_(LevelShifterType::HL_LH), is_isolation_cell_(false), @@ -1077,6 +1078,12 @@ LibertyCell::LibertyCell::setIsPad(bool is_pad) is_pad_ = is_pad; } +void +LibertyCell::LibertyCell::setIsClockCell(bool is_clock_cell) +{ + is_clock_cell_ = is_clock_cell; +} + void LibertyCell::setIsLevelShifter(bool is_level_shifter) { diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 7cf3491d..f25cc79f 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -298,6 +298,7 @@ LibertyReader::defineVisitors() defineAttrVisitor("is_macro", &LibertyReader::visitIsMacro); defineAttrVisitor("is_memory", &LibertyReader::visitIsMemory); defineAttrVisitor("is_pad", &LibertyReader::visitIsPad); + defineAttrVisitor("is_clock_cell", &LibertyReader::visitIsClockCell); defineAttrVisitor("is_level_shifter", &LibertyReader::visitIsLevelShifter); defineAttrVisitor("level_shifter_type", &LibertyReader::visitLevelShifterType); defineAttrVisitor("is_isolation_cell", &LibertyReader::visitIsIsolationCell); @@ -2819,6 +2820,17 @@ LibertyReader::visitIsPad(LibertyAttr *attr) } } +void +LibertyReader::visitIsClockCell(LibertyAttr *attr) +{ + if (cell_) { + bool is_clock_cell, exists; + getAttrBool(attr, is_clock_cell, exists); + if (exists) + cell_->setIsClockCell(is_clock_cell); + } +} + void LibertyReader::visitIsLevelShifter(LibertyAttr *attr) { diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index f99fa1f1..6c7ea2d1 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -188,6 +188,7 @@ public: virtual void visitIsMacro(LibertyAttr *attr); virtual void visitIsMemory(LibertyAttr *attr); virtual void visitIsPad(LibertyAttr *attr); + virtual void visitIsClockCell(LibertyAttr *attr); virtual void visitIsLevelShifter(LibertyAttr *attr); virtual void visitLevelShifterType(LibertyAttr *attr); virtual void visitIsIsolationCell(LibertyAttr *attr); diff --git a/liberty/Units.cc b/liberty/Units.cc index ecd17846..c21f24f1 100644 --- a/liberty/Units.cc +++ b/liberty/Units.cc @@ -17,7 +17,6 @@ #include "Units.hh" #include // abs -#include #include "StringUtil.hh" #include "MinMax.hh" // INF diff --git a/network/ConcreteLibrary.cc b/network/ConcreteLibrary.cc index 379fb093..154efaa5 100644 --- a/network/ConcreteLibrary.cc +++ b/network/ConcreteLibrary.cc @@ -17,6 +17,7 @@ #include "ConcreteLibrary.hh" #include +#include #include "PatternMatch.hh" #include "PortDirection.hh" @@ -26,6 +27,10 @@ namespace sta { using std::map; +using std::min; +using std::max; +using std::abs; +using std::swap; static constexpr char escape_ = '\\'; @@ -289,67 +294,47 @@ ConcreteCell::portBitIterator() const //////////////////////////////////////////////////////////////// +// Helper class for ConcreteCell::groupBusPorts. class BusPort { public: - BusPort(const char *name, - int from, - PortDirection *direction); - ~BusPort(); - const char *name() const { return name_; } - void pushMember(ConcretePort *port); - void setFrom(int from); - void setTo(int to); + BusPort(); + void addBusBit(ConcretePort *port, + int index); int from() const { return from_; } int to() const { return to_; } - ConcretePortSeq *members() { return members_; } + ConcretePortSeq &members() { return members_; } + void setDirection(PortDirection *direction); PortDirection *direction() { return direction_; } private: - const char *name_; int from_; int to_; PortDirection *direction_; - ConcretePortSeq *members_; + ConcretePortSeq members_; }; -BusPort::BusPort(const char *name, - int from, - PortDirection *direction) : - name_(stringCopy(name)), - from_(from), - to_(from), - direction_(direction), - members_(new ConcretePortSeq) +BusPort::BusPort() : + from_(std::numeric_limits::max()), + to_(std::numeric_limits::min()) { } -BusPort::~BusPort() -{ - // members_ ownership is transfered to bus port. - stringDelete(name_); -} - void -BusPort::pushMember(ConcretePort *port) +BusPort::setDirection(PortDirection *direction) { - members_->push_back(port); + direction_ = direction; } void -BusPort::setFrom(int from) +BusPort::addBusBit(ConcretePort *port, + int index) { - from_ = from; + from_ = min(from_, index); + to_ = max(to_, index); + members_.push_back(port); } -void -BusPort::setTo(int to) -{ - to_ = to; -} - -typedef Map BusPortMap; - void ConcreteCell::groupBusPorts(const char bus_brkt_left, const char bus_brkt_right, @@ -357,7 +342,7 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left, { const char bus_brkts_left[2]{bus_brkt_left, '\0'}; const char bus_brkts_right[2]{bus_brkt_right, '\0'}; - map port_map; + map bus_map; // Find ungrouped bus ports. // Remove bus bit ports from the ports_ vector during the scan by // keeping an index to the next insertion index and skipping over @@ -373,64 +358,35 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left, is_bus, bus_name, index); if (is_bus) { if (!port->isBusBit()) { - auto name_bus_port = port_map.find(bus_name); - BusPort *bus_port; - if (name_bus_port == port_map.end()) { - bus_port = new BusPort(bus_name.c_str(), index, port->direction()); - port_map[bus_name] = bus_port; - } - else - bus_port = name_bus_port->second; - bus_port->pushMember(port); + BusPort &bus_port = bus_map[bus_name]; + bus_port.addBusBit(port, index); + port->setBusBitIndex(index); + bus_port.setDirection(port->direction()); } - else - ports_.push_back(port); } else ports_.push_back(port); } // Make the bus ports. - for (auto name_bus : port_map) { - const string &bus_name = name_bus.first; - BusPort *bus_port = name_bus.second; + for (auto name_bus : bus_map) { + string bus_name = name_bus.first; + BusPort &bus_port = name_bus.second; + int from = bus_port.from(); + int to = bus_port.to(); + size_t size = to - from + 1; bool msb_first = port_msb_first(bus_name.c_str()); - ConcretePortSeq *members = bus_port->members(); - sort(members, [&](ConcretePort *port1, - ConcretePort *port2) { - bool is_bus; - string bus_name; - int index1, index2; - parseBusName(port1->name(), bus_brkts_left, bus_brkts_right, escape_, - is_bus, bus_name, index1); - parseBusName(port2->name(), bus_brkts_left, bus_brkts_right, escape_, - is_bus, bus_name, index2); - return msb_first ? index1 > index2 : index1 < index2; - }); - - bool is_bus1; - string bus_name1; - int from_index, to_index; - parseBusName((*members)[0]->name(), - bus_brkts_left, bus_brkts_right, escape_, - is_bus1, bus_name1, from_index); - parseBusName((*members)[members->size() - 1]->name(), - bus_brkts_left, bus_brkts_right, escape_, - is_bus1, bus_name1, to_index); - - ConcretePort *port = makeBusPort(bus_name.c_str(), from_index, - to_index, members); - port->setDirection(bus_port->direction()); - delete bus_port; - - for (ConcretePort *port : *members) { - bool is_bus; - string bus_name; - int index; - parseBusName(port->name(), bus_brkts_left, bus_brkts_right, escape_, - is_bus, bus_name, index); - port->setBusBitIndex(index); + ConcretePortSeq *members = new ConcretePortSeq(size); + // Index the bus bit ports. + for (ConcretePort *bus_bit : bus_port.members()) { + int bit_index = bus_bit->busBitIndex(); + int member_index = msb_first ? to - bit_index : bit_index - from; + (*members)[member_index] = bus_bit; } + if (msb_first) + swap(from, to); + ConcretePort *port = makeBusPort(bus_name.c_str(), from, to, members); + port->setDirection(bus_port.direction()); } } @@ -546,7 +502,8 @@ ConcretePort::setDirection(PortDirection *dir) ConcretePortMemberIterator *member_iter = memberIterator(); while (member_iter->hasNext()) { ConcretePort *port_bit = member_iter->next(); - port_bit->setDirection(dir); + if (port_bit) + port_bit->setDirection(dir); } delete member_iter; } diff --git a/network/ConcreteNetwork.cc b/network/ConcreteNetwork.cc index 18e2df18..8c141511 100644 --- a/network/ConcreteNetwork.cc +++ b/network/ConcreteNetwork.cc @@ -853,21 +853,24 @@ ConcreteNetwork::hasMembers(const Port *port) const //////////////////////////////////////////////////////////////// +// This has to skip over missing bus bits in the members. class ConcretePortMemberIterator1 : public PortMemberIterator { public: explicit ConcretePortMemberIterator1(const ConcretePort *port); ~ConcretePortMemberIterator1(); - virtual bool hasNext() { return iter_->hasNext(); } + virtual bool hasNext(); virtual Port *next(); private: ConcretePortMemberIterator *iter_; + ConcretePort *next_; }; ConcretePortMemberIterator1::ConcretePortMemberIterator1(const ConcretePort * port) : - iter_(port->memberIterator()) + iter_(port->memberIterator()), + next_(nullptr) { } @@ -876,10 +879,21 @@ ConcretePortMemberIterator1::~ConcretePortMemberIterator1() delete iter_; } +bool +ConcretePortMemberIterator1::hasNext() +{ + while (next_ == nullptr + && iter_->hasNext()) + next_ = iter_->next(); + return next_ != nullptr; +} + Port * ConcretePortMemberIterator1::next() { - return reinterpret_cast(iter_->next()); + ConcretePort *next = next_; + next_ = nullptr; + return reinterpret_cast(next); } PortMemberIterator * diff --git a/parasitics/ConcreteParasitics.cc b/parasitics/ConcreteParasitics.cc index 2ab1086a..4de6827f 100644 --- a/parasitics/ConcreteParasitics.cc +++ b/parasitics/ConcreteParasitics.cc @@ -16,7 +16,6 @@ #include "ConcreteParasitics.hh" -#include #include // max #include "Report.hh" diff --git a/parasitics/SpefReader.cc b/parasitics/SpefReader.cc index 476dbe86..99e4bd57 100644 --- a/parasitics/SpefReader.cc +++ b/parasitics/SpefReader.cc @@ -16,8 +16,6 @@ #include "SpefReader.hh" -#include - #include "Zlib.hh" #include "Report.hh" #include "Debug.hh" diff --git a/power/ReadVcdActivities.cc b/power/ReadVcdActivities.cc index dbc2e784..3abaf594 100644 --- a/power/ReadVcdActivities.cc +++ b/power/ReadVcdActivities.cc @@ -16,6 +16,8 @@ #include "ReadVcdActivities.hh" +#include + #include "VcdReader.hh" #include "Debug.hh" #include "Network.hh" @@ -212,7 +214,7 @@ ReadVcdActivities::findVarActivity(const VcdValues &var_values, for (const VcdValue &var_value : var_values) { VcdTime time = var_value.time(); char value = var_value.value(value_bit); - debugPrint(debug_, "read_vcd_activities", 3, " %ld %c", time, value); + debugPrint(debug_, "read_vcd_activities", 3, " %" PRId64 " %c", time, value); if (prev_value == '1') high_time += time - prev_time; if (value != prev_value)