Skip to content

Commit

Permalink
get_ports bus range
Browse files Browse the repository at this point in the history
Signed-off-by: James Cherry <[email protected]>
  • Loading branch information
jjcherry56 committed Jun 4, 2023
1 parent 3c70c9b commit 7514224
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 86 deletions.
2 changes: 0 additions & 2 deletions include/sta/ConcreteNetwork.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion include/sta/Network.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
41 changes: 23 additions & 18 deletions include/sta/ParseBus.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions liberty/LibertyReader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down
26 changes: 0 additions & 26 deletions network/ConcreteLibrary.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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*>(port_bit));
}
delete member_iter;
}
else if (pattern->match(port->name()))
matches.push_back(reinterpret_cast<Port*>(port));
}
delete port_iter;
return matches;
}

ConcreteCellPortIterator *
ConcreteCell::portIterator() const
{
Expand Down
8 changes: 0 additions & 8 deletions network/ConcreteNetwork.cc
Original file line number Diff line number Diff line change
Expand Up @@ -605,14 +605,6 @@ ConcreteNetwork::findPort(const Cell *cell,
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
ConcreteNetwork::isLeaf(const Cell *cell) const
{
Expand Down
58 changes: 58 additions & 0 deletions network/Network.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "Liberty.hh"
#include "PortDirection.hh"
#include "Corner.hh"
#include "ParseBus.hh"

namespace sta {

Expand Down Expand Up @@ -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
{
Expand Down
60 changes: 37 additions & 23 deletions network/ParseBus.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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);
}
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions power/ReadVcdActivities.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down

0 comments on commit 7514224

Please sign in to comment.