or 4297 DEF missing bus ports

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2023-11-25 13:13:59 -08:00
parent 32fcba5166
commit ca11aa7be0
2 changed files with 62 additions and 91 deletions

View File

@ -17,6 +17,7 @@
#include "ConcreteLibrary.hh" #include "ConcreteLibrary.hh"
#include <cstdlib> #include <cstdlib>
#include <limits>
#include "PatternMatch.hh" #include "PatternMatch.hh"
#include "PortDirection.hh" #include "PortDirection.hh"
@ -26,6 +27,10 @@
namespace sta { namespace sta {
using std::map; using std::map;
using std::min;
using std::max;
using std::abs;
using std::swap;
static constexpr char escape_ = '\\'; static constexpr char escape_ = '\\';
@ -289,67 +294,47 @@ ConcreteCell::portBitIterator() const
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Helper class for ConcreteCell::groupBusPorts.
class BusPort class BusPort
{ {
public: public:
BusPort(const char *name, BusPort();
int from, void addBusBit(ConcretePort *port,
PortDirection *direction); int index);
~BusPort();
const char *name() const { return name_; }
void pushMember(ConcretePort *port);
void setFrom(int from);
void setTo(int to);
int from() const { return from_; } int from() const { return from_; }
int to() const { return to_; } int to() const { return to_; }
ConcretePortSeq *members() { return members_; } ConcretePortSeq &members() { return members_; }
void setDirection(PortDirection *direction);
PortDirection *direction() { return direction_; } PortDirection *direction() { return direction_; }
private: private:
const char *name_;
int from_; int from_;
int to_; int to_;
PortDirection *direction_; PortDirection *direction_;
ConcretePortSeq *members_; ConcretePortSeq members_;
}; };
BusPort::BusPort(const char *name, BusPort::BusPort() :
int from, from_(std::numeric_limits<int>::max()),
PortDirection *direction) : to_(std::numeric_limits<int>::min())
name_(stringCopy(name)),
from_(from),
to_(from),
direction_(direction),
members_(new ConcretePortSeq)
{ {
} }
BusPort::~BusPort()
{
// members_ ownership is transfered to bus port.
stringDelete(name_);
}
void void
BusPort::pushMember(ConcretePort *port) BusPort::setDirection(PortDirection *direction)
{ {
members_->push_back(port); direction_ = direction;
} }
void 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<const char*, BusPort*, CharPtrLess> BusPortMap;
void void
ConcreteCell::groupBusPorts(const char bus_brkt_left, ConcreteCell::groupBusPorts(const char bus_brkt_left,
const char bus_brkt_right, 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_left[2]{bus_brkt_left, '\0'};
const char bus_brkts_right[2]{bus_brkt_right, '\0'}; const char bus_brkts_right[2]{bus_brkt_right, '\0'};
map<string, BusPort*> port_map; map<string, BusPort> bus_map;
// Find ungrouped bus ports. // Find ungrouped bus ports.
// Remove bus bit ports from the ports_ vector during the scan by // Remove bus bit ports from the ports_ vector during the scan by
// keeping an index to the next insertion index and skipping over // 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); is_bus, bus_name, index);
if (is_bus) { if (is_bus) {
if (!port->isBusBit()) { if (!port->isBusBit()) {
auto name_bus_port = port_map.find(bus_name); BusPort &bus_port = bus_map[bus_name];
BusPort *bus_port; bus_port.addBusBit(port, index);
if (name_bus_port == port_map.end()) { port->setBusBitIndex(index);
bus_port = new BusPort(bus_name.c_str(), index, port->direction()); bus_port.setDirection(port->direction());
port_map[bus_name] = bus_port;
}
else
bus_port = name_bus_port->second;
bus_port->pushMember(port);
} }
else
ports_.push_back(port);
} }
else else
ports_.push_back(port); ports_.push_back(port);
} }
// Make the bus ports. // Make the bus ports.
for (auto name_bus : port_map) { for (auto name_bus : bus_map) {
const string &bus_name = name_bus.first; string bus_name = name_bus.first;
BusPort *bus_port = name_bus.second; 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()); bool msb_first = port_msb_first(bus_name.c_str());
ConcretePortSeq *members = bus_port->members(); ConcretePortSeq *members = new ConcretePortSeq(size);
sort(members, [&](ConcretePort *port1, // Index the bus bit ports.
ConcretePort *port2) { for (ConcretePort *bus_bit : bus_port.members()) {
bool is_bus; int bit_index = bus_bit->busBitIndex();
string bus_name; int member_index = msb_first ? to - bit_index : bit_index - from;
int index1, index2; (*members)[member_index] = bus_bit;
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);
} }
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(); ConcretePortMemberIterator *member_iter = memberIterator();
while (member_iter->hasNext()) { while (member_iter->hasNext()) {
ConcretePort *port_bit = member_iter->next(); ConcretePort *port_bit = member_iter->next();
port_bit->setDirection(dir); if (port_bit)
port_bit->setDirection(dir);
} }
delete member_iter; delete member_iter;
} }

View File

@ -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 class ConcretePortMemberIterator1 : public PortMemberIterator
{ {
public: public:
explicit ConcretePortMemberIterator1(const ConcretePort *port); explicit ConcretePortMemberIterator1(const ConcretePort *port);
~ConcretePortMemberIterator1(); ~ConcretePortMemberIterator1();
virtual bool hasNext() { return iter_->hasNext(); } virtual bool hasNext();
virtual Port *next(); virtual Port *next();
private: private:
ConcretePortMemberIterator *iter_; ConcretePortMemberIterator *iter_;
ConcretePort *next_;
}; };
ConcretePortMemberIterator1::ConcretePortMemberIterator1(const ConcretePort * ConcretePortMemberIterator1::ConcretePortMemberIterator1(const ConcretePort *
port) : port) :
iter_(port->memberIterator()) iter_(port->memberIterator()),
next_(nullptr)
{ {
} }
@ -876,10 +879,21 @@ ConcretePortMemberIterator1::~ConcretePortMemberIterator1()
delete iter_; delete iter_;
} }
bool
ConcretePortMemberIterator1::hasNext()
{
while (next_ == nullptr
&& iter_->hasNext())
next_ = iter_->next();
return next_ != nullptr;
}
Port * Port *
ConcretePortMemberIterator1::next() ConcretePortMemberIterator1::next()
{ {
return reinterpret_cast<Port*>(iter_->next()); ConcretePort *next = next_;
next_ = nullptr;
return reinterpret_cast<Port*>(next);
} }
PortMemberIterator * PortMemberIterator *