get_ports bus range

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2023-06-04 09:34:29 -07:00
parent 3c70c9bee1
commit 7514224f6c
9 changed files with 127 additions and 86 deletions

View File

@ -82,8 +82,6 @@ public:
const char *filename(const Cell *cell) override; const char *filename(const Cell *cell) override;
Port *findPort(const Cell *cell, Port *findPort(const Cell *cell,
const char *name) const override; const char *name) const override;
PortSeq findPortsMatching(const Cell *cell,
const PatternMatch *pattern) const override;
bool isLeaf(const Cell *cell) const override; bool isLeaf(const Cell *cell) const override;
CellPortIterator *portIterator(const Cell *cell) const override; CellPortIterator *portIterator(const Cell *cell) const override;
CellPortBitIterator *portBitIterator(const Cell *cell) const override; CellPortBitIterator *portBitIterator(const Cell *cell) const override;

View File

@ -148,7 +148,7 @@ public:
virtual Port *findPort(const Cell *cell, virtual Port *findPort(const Cell *cell,
const char *name) const = 0; const char *name) const = 0;
virtual PortSeq findPortsMatching(const Cell *cell, virtual PortSeq findPortsMatching(const Cell *cell,
const PatternMatch *pattern) const = 0; const PatternMatch *pattern) const;
virtual bool isLeaf(const Cell *cell) const = 0; virtual bool isLeaf(const Cell *cell) const = 0;
virtual CellPortIterator *portIterator(const Cell *cell) const = 0; virtual CellPortIterator *portIterator(const Cell *cell) const = 0;
// Iterate over port bits (expanded buses). // Iterate over port bits (expanded buses).

View File

@ -60,27 +60,32 @@ parseBusName(const char *name,
// bus_name is set to null if name is not a range. // bus_name is set to null if name is not a range.
// Caller must delete returned bus_name string. // Caller must delete returned bus_name string.
void void
parseBusRange(const char *name, parseBusName(const char *name,
const char brkt_left, const char brkt_left,
const char brkt_right, const char brkt_right,
char escape, char escape,
// Return values. // Return values.
bool &is_bus, bool &is_bus,
string &bus_name, bool &is_range,
int &from, string &bus_name,
int &to); int &from,
int &to,
bool &subscript_wild);
// brkt_lefts and brkt_rights are corresponding strings of legal // brkt_lefts and brkt_rights are corresponding strings of legal
// bus brackets such as "[(<" and "])>". // bus brackets such as "[(<" and "])>".
void void
parseBusRange(const char *name, parseBusName(const char *name,
const char *brkts_left, const char *brkts_left,
const char *brkts_right, const char *brkts_right,
const char escape, const char escape,
// Return values. // Return values.
bool &is_bus, bool &is_bus,
string &bus_name, bool &is_range,
int &from, string &bus_name,
int &to); int &from,
int &to,
bool &subscript_wild);
// Insert escapes before ch1 and ch2 in token. // Insert escapes before ch1 and ch2 in token.
string string

View File

@ -5637,13 +5637,13 @@ PortNameBitIterator::init(const char *port_name)
else { else {
// Check for bus range. // Check for bus range.
LibertyLibrary *library = visitor_->library(); LibertyLibrary *library = visitor_->library();
bool is_bus; bool is_bus, is_range, subscript_wild;
string bus_name; string bus_name;
int from, to; int from, to;
parseBusRange(port_name, library->busBrktLeft(), parseBusName(port_name, library->busBrktLeft(),
library->busBrktRight(), '\\', library->busBrktRight(), '\\',
is_bus, bus_name, from, to); is_bus, is_range, bus_name, from, to, subscript_wild);
if (is_bus) { if (is_range) {
port = visitor_->findPort(port_name); port = visitor_->findPort(port_name);
if (port) { if (port) {
if (port->isBus()) { if (port->isBus()) {

View File

@ -275,32 +275,6 @@ ConcreteCell::portCount() const
return ports_.size(); 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*>(port_bit));
}
delete member_iter;
}
else if (pattern->match(port->name()))
matches.push_back(reinterpret_cast<Port*>(port));
}
delete port_iter;
return matches;
}
ConcreteCellPortIterator * ConcreteCellPortIterator *
ConcreteCell::portIterator() const ConcreteCell::portIterator() const
{ {

View File

@ -605,14 +605,6 @@ ConcreteNetwork::findPort(const Cell *cell,
return reinterpret_cast<Port*>(ccell->findPort(name)); return reinterpret_cast<Port*>(ccell->findPort(name));
} }
PortSeq
ConcreteNetwork::findPortsMatching(const Cell *cell,
const PatternMatch *pattern) const
{
const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
return ccell->findPortsMatching(pattern);
}
bool bool
ConcreteNetwork::isLeaf(const Cell *cell) const ConcreteNetwork::isLeaf(const Cell *cell) const
{ {

View File

@ -22,6 +22,7 @@
#include "Liberty.hh" #include "Liberty.hh"
#include "PortDirection.hh" #include "PortDirection.hh"
#include "Corner.hh" #include "Corner.hh"
#include "ParseBus.hh"
namespace sta { namespace sta {
@ -56,6 +57,63 @@ Network::libertyLibrary(const Cell *cell) const
return libertyCell(cell)->libertyLibrary(); 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 * LibertyLibrary *
Network::libertyLibrary(const Instance *instance) const Network::libertyLibrary(const Instance *instance) const
{ {

View File

@ -95,37 +95,43 @@ parseBusName(const char *name,
} }
void void
parseBusRange(const char *name, parseBusName(const char *name,
const char brkt_left, const char brkt_left,
const char brkt_right, const char brkt_right,
char escape, char escape,
// Return values. // Return values.
bool &is_bus, bool &is_bus,
string &bus_name, bool &is_range,
int &from, string &bus_name,
int &to) int &from,
int &to,
bool &subscript_wild)
{ {
const char brkts_left[2] = {brkt_left, '\0'}; const char brkts_left[2] = {brkt_left, '\0'};
const char brkts_right[2] = {brkt_right, '\0'}; const char brkts_right[2] = {brkt_right, '\0'};
parseBusRange(name, brkts_left, brkts_right, escape, parseBusName(name, brkts_left, brkts_right, escape,
is_bus, bus_name, from, to); is_bus, is_range, bus_name, from, to, subscript_wild);
} }
void void
parseBusRange(const char *name, parseBusName(const char *name,
const char *brkts_left, const char *brkts_left,
const char *brkts_right, const char *brkts_right,
char escape, char escape,
// Return values. // Return values.
bool &is_bus, bool &is_bus,
string &bus_name, bool &is_range,
int &from, string &bus_name,
int &to) int &from,
int &to,
bool &subscript_wild)
{ {
is_bus = false; is_bus = false;
is_range = false;
subscript_wild = false;
size_t len = strlen(name); size_t len = strlen(name);
// Shortest bus range is a[1:0]. // Shortest bus is a[0].
if (len >= 6 if (len >= 4
// Escaped bus brackets are not buses. // Escaped bus brackets are not buses.
&& name[len - 2] != escape) { && name[len - 2] != escape) {
char last_ch = name[len - 1]; char last_ch = name[len - 1];
@ -135,17 +141,25 @@ parseBusRange(const char *name,
char brkt_left = brkts_left[brkt_index]; char brkt_left = brkts_left[brkt_index];
const char *left = strrchr(name, brkt_left); const char *left = strrchr(name, brkt_left);
if (left) { if (left) {
is_bus = true;
// Check for bus range. // Check for bus range.
const char range_sep = ':'; const char range_sep = ':';
const char *range = strchr(name, range_sep); const char *range = strchr(name, range_sep);
if (range) { if (range) {
is_bus = true; is_range = true;
bus_name.append(name, left - name); bus_name.append(name, left - name);
// No need to terminate bus subscript because atoi stops // No need to terminate bus subscript because atoi stops
// scanning at first non-digit character. // scanning at first non-digit character.
from = atoi(left + 1); from = atoi(left + 1);
to = atoi(range + 1); to = atoi(range + 1);
} }
else {
bus_name.append(name, left - name);
if (left[1] == '*')
subscript_wild = true;
else
from = to = atoi(left + 1);
}
} }
} }
} }

View File

@ -135,11 +135,11 @@ ReadVcdActivities::setVarActivity(VcdVar *var,
if (var->width() == 1) if (var->width() == 1)
setVarActivity(sta_name.c_str(), var_values, 0); setVarActivity(sta_name.c_str(), var_values, 0);
else { else {
bool is_bus; bool is_bus, is_range, subscript_wild;
string bus_name; string bus_name;
int from, to; int from, to;
parseBusRange(sta_name.c_str(), '[', ']', '\\', parseBusName(sta_name.c_str(), '[', ']', '\\',
is_bus, bus_name, from, to); is_bus, is_range, bus_name, from, to, subscript_wild);
int value_bit = 0; int value_bit = 0;
if (to < from) { if (to < from) {
for (int bus_bit = to; bus_bit <= from; bus_bit++) { for (int bus_bit = to; bus_bit <= from; bus_bit++) {