From 7514224f6c63176ddba7b72bcdc88105908f575e Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sun, 4 Jun 2023 09:34:29 -0700 Subject: [PATCH] get_ports bus range Signed-off-by: James Cherry --- include/sta/ConcreteNetwork.hh | 2 -- include/sta/Network.hh | 2 +- include/sta/ParseBus.hh | 41 +++++++++++++---------- liberty/LibertyReader.cc | 10 +++--- network/ConcreteLibrary.cc | 26 --------------- network/ConcreteNetwork.cc | 8 ----- network/Network.cc | 58 ++++++++++++++++++++++++++++++++ network/ParseBus.cc | 60 +++++++++++++++++++++------------- power/ReadVcdActivities.cc | 6 ++-- 9 files changed, 127 insertions(+), 86 deletions(-) diff --git a/include/sta/ConcreteNetwork.hh b/include/sta/ConcreteNetwork.hh index a07c4082..7bd9014a 100644 --- a/include/sta/ConcreteNetwork.hh +++ b/include/sta/ConcreteNetwork.hh @@ -82,8 +82,6 @@ public: const char *filename(const Cell *cell) override; Port *findPort(const Cell *cell, const char *name) const override; - PortSeq findPortsMatching(const Cell *cell, - const PatternMatch *pattern) const override; bool isLeaf(const Cell *cell) const override; CellPortIterator *portIterator(const Cell *cell) const override; CellPortBitIterator *portBitIterator(const Cell *cell) const override; diff --git a/include/sta/Network.hh b/include/sta/Network.hh index 62a42b24..7a87d3e7 100644 --- a/include/sta/Network.hh +++ b/include/sta/Network.hh @@ -148,7 +148,7 @@ public: virtual Port *findPort(const Cell *cell, const char *name) const = 0; virtual PortSeq findPortsMatching(const Cell *cell, - const PatternMatch *pattern) const = 0; + const PatternMatch *pattern) const; virtual bool isLeaf(const Cell *cell) const = 0; virtual CellPortIterator *portIterator(const Cell *cell) const = 0; // Iterate over port bits (expanded buses). diff --git a/include/sta/ParseBus.hh b/include/sta/ParseBus.hh index 66021a2a..395cd1f0 100644 --- a/include/sta/ParseBus.hh +++ b/include/sta/ParseBus.hh @@ -60,27 +60,32 @@ parseBusName(const char *name, // bus_name is set to null if name is not a range. // Caller must delete returned bus_name string. void -parseBusRange(const char *name, - const char brkt_left, - const char brkt_right, - char escape, - // Return values. - bool &is_bus, - string &bus_name, - int &from, - int &to); +parseBusName(const char *name, + const char brkt_left, + const char brkt_right, + char escape, + // Return values. + bool &is_bus, + bool &is_range, + string &bus_name, + int &from, + int &to, + bool &subscript_wild); + // brkt_lefts and brkt_rights are corresponding strings of legal // bus brackets such as "[(<" and "])>". void -parseBusRange(const char *name, - const char *brkts_left, - const char *brkts_right, - const char escape, - // Return values. - bool &is_bus, - string &bus_name, - int &from, - int &to); +parseBusName(const char *name, + const char *brkts_left, + const char *brkts_right, + const char escape, + // Return values. + bool &is_bus, + bool &is_range, + string &bus_name, + int &from, + int &to, + bool &subscript_wild); // Insert escapes before ch1 and ch2 in token. string diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index ad0947eb..d48dc95f 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -5637,13 +5637,13 @@ PortNameBitIterator::init(const char *port_name) else { // Check for bus range. LibertyLibrary *library = visitor_->library(); - bool is_bus; + bool is_bus, is_range, subscript_wild; string bus_name; int from, to; - parseBusRange(port_name, library->busBrktLeft(), - library->busBrktRight(), '\\', - is_bus, bus_name, from, to); - if (is_bus) { + parseBusName(port_name, library->busBrktLeft(), + library->busBrktRight(), '\\', + is_bus, is_range, bus_name, from, to, subscript_wild); + if (is_range) { port = visitor_->findPort(port_name); if (port) { if (port->isBus()) { diff --git a/network/ConcreteLibrary.cc b/network/ConcreteLibrary.cc index d4547bfe..9ec963f8 100644 --- a/network/ConcreteLibrary.cc +++ b/network/ConcreteLibrary.cc @@ -275,32 +275,6 @@ ConcreteCell::portCount() const return ports_.size(); } -PortSeq -ConcreteCell::findPortsMatching(const PatternMatch *pattern) const -{ - PortSeq matches; - char bus_brkt_right = library_->busBrktRight(); - const char *pattern1 = pattern->pattern(); - bool bus_pattern = (pattern1[strlen(pattern1) - 1] == bus_brkt_right); - ConcreteCellPortIterator *port_iter = portIterator(); - while (port_iter->hasNext()) { - ConcretePort *port = port_iter->next(); - if (port->isBus() && bus_pattern) { - ConcretePortMemberIterator *member_iter = port->memberIterator(); - while (member_iter->hasNext()) { - ConcretePort *port_bit = member_iter->next(); - if (pattern->match(port_bit->name())) - matches.push_back(reinterpret_cast(port_bit)); - } - delete member_iter; - } - else if (pattern->match(port->name())) - matches.push_back(reinterpret_cast(port)); - } - delete port_iter; - return matches; -} - ConcreteCellPortIterator * ConcreteCell::portIterator() const { diff --git a/network/ConcreteNetwork.cc b/network/ConcreteNetwork.cc index c6e4856f..12668e87 100644 --- a/network/ConcreteNetwork.cc +++ b/network/ConcreteNetwork.cc @@ -605,14 +605,6 @@ ConcreteNetwork::findPort(const Cell *cell, return reinterpret_cast(ccell->findPort(name)); } -PortSeq -ConcreteNetwork::findPortsMatching(const Cell *cell, - const PatternMatch *pattern) const -{ - const ConcreteCell *ccell = reinterpret_cast(cell); - return ccell->findPortsMatching(pattern); -} - bool ConcreteNetwork::isLeaf(const Cell *cell) const { diff --git a/network/Network.cc b/network/Network.cc index 2811aadf..c26f38fe 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -22,6 +22,7 @@ #include "Liberty.hh" #include "PortDirection.hh" #include "Corner.hh" +#include "ParseBus.hh" namespace sta { @@ -56,6 +57,63 @@ Network::libertyLibrary(const Cell *cell) const return libertyCell(cell)->libertyLibrary(); } +PortSeq +Network::findPortsMatching(const Cell *cell, + const PatternMatch *pattern) const +{ + PortSeq matches; + bool is_bus, is_range, subscript_wild; + string bus_name; + int from, to; + parseBusName(pattern->pattern(), '[', ']', '\\', + is_bus, is_range, bus_name, from, to, subscript_wild); + if (is_bus) { + PatternMatch bus_pattern(bus_name.c_str(), pattern); + CellPortIterator *port_iter = portIterator(cell); + while (port_iter->hasNext()) { + Port *port = port_iter->next(); + if (isBus(port) + && bus_pattern.match(name(port))) { + if (is_range) { + // bus[8:0] + if (from > to) + std::swap(from, to); + for (int bit = from; bit <= to; bit++) { + Port *port_bit = findBusBit(port, bit); + matches.push_back(port_bit); + } + } + else { + if (subscript_wild) { + PortMemberIterator *member_iter = memberIterator(port); + while (member_iter->hasNext()) { + Port *port_bit = member_iter->next(); + matches.push_back(port_bit); + } + delete member_iter; + } + else { + // bus[0] + Port *port_bit = findBusBit(port, from); + matches.push_back(port_bit); + } + } + } + } + delete port_iter; + } + else { + CellPortIterator *port_iter = portIterator(cell); + while (port_iter->hasNext()) { + Port *port = port_iter->next(); + if (pattern->match(name(port))) + matches.push_back(port); + } + delete port_iter; + } + return matches; +} + LibertyLibrary * Network::libertyLibrary(const Instance *instance) const { diff --git a/network/ParseBus.cc b/network/ParseBus.cc index 0920daac..400e5ff1 100644 --- a/network/ParseBus.cc +++ b/network/ParseBus.cc @@ -95,37 +95,43 @@ parseBusName(const char *name, } void -parseBusRange(const char *name, - const char brkt_left, - const char brkt_right, - char escape, - // Return values. - bool &is_bus, - string &bus_name, - int &from, - int &to) +parseBusName(const char *name, + const char brkt_left, + const char brkt_right, + char escape, + // Return values. + bool &is_bus, + bool &is_range, + string &bus_name, + int &from, + int &to, + bool &subscript_wild) { const char brkts_left[2] = {brkt_left, '\0'}; const char brkts_right[2] = {brkt_right, '\0'}; - parseBusRange(name, brkts_left, brkts_right, escape, - is_bus, bus_name, from, to); + parseBusName(name, brkts_left, brkts_right, escape, + is_bus, is_range, bus_name, from, to, subscript_wild); } void -parseBusRange(const char *name, - const char *brkts_left, - const char *brkts_right, - char escape, - // Return values. - bool &is_bus, - string &bus_name, - int &from, - int &to) +parseBusName(const char *name, + const char *brkts_left, + const char *brkts_right, + char escape, + // Return values. + bool &is_bus, + bool &is_range, + string &bus_name, + int &from, + int &to, + bool &subscript_wild) { is_bus = false; + is_range = false; + subscript_wild = false; size_t len = strlen(name); - // Shortest bus range is a[1:0]. - if (len >= 6 + // Shortest bus is a[0]. + if (len >= 4 // Escaped bus brackets are not buses. && name[len - 2] != escape) { char last_ch = name[len - 1]; @@ -135,17 +141,25 @@ parseBusRange(const char *name, char brkt_left = brkts_left[brkt_index]; const char *left = strrchr(name, brkt_left); if (left) { + is_bus = true; // Check for bus range. const char range_sep = ':'; const char *range = strchr(name, range_sep); if (range) { - is_bus = true; + is_range = true; bus_name.append(name, left - name); // No need to terminate bus subscript because atoi stops // scanning at first non-digit character. from = atoi(left + 1); to = atoi(range + 1); } + else { + bus_name.append(name, left - name); + if (left[1] == '*') + subscript_wild = true; + else + from = to = atoi(left + 1); + } } } } diff --git a/power/ReadVcdActivities.cc b/power/ReadVcdActivities.cc index 9e2706c4..8f53da0e 100644 --- a/power/ReadVcdActivities.cc +++ b/power/ReadVcdActivities.cc @@ -135,11 +135,11 @@ ReadVcdActivities::setVarActivity(VcdVar *var, if (var->width() == 1) setVarActivity(sta_name.c_str(), var_values, 0); else { - bool is_bus; + bool is_bus, is_range, subscript_wild; string bus_name; int from, to; - parseBusRange(sta_name.c_str(), '[', ']', '\\', - is_bus, bus_name, from, to); + parseBusName(sta_name.c_str(), '[', ']', '\\', + is_bus, is_range, bus_name, from, to, subscript_wild); int value_bit = 0; if (to < from) { for (int bus_bit = to; bus_bit <= from; bus_bit++) {