rm tmp string uses

commit 2d0a4f8e9a8b46faa2ba91e1be636c3c3ad95a7f
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Mar 25 21:25:37 2023 -0700

    leaks

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 5514910a91707d615bac0bbed3a29f579eca8de2
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Mar 25 18:21:54 2023 -0700

    foo

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 076a51d5816444e883232933c2ded7309291d0bc
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Mar 25 16:38:42 2023 -0700

    parse bus string

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 2b80e563cbbb6563a6b716431f391bbb6639f816
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Mar 25 15:57:05 2023 -0700

    rm tmp string

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 9e4f2308658232d0b1ee9efcd948bb19ae5dd30f
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Mar 25 14:37:35 2023 -0700

    rm tmp string

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit ebad3afd49b08e7194452dd082c3c7c05767f875
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Mar 25 10:59:11 2023 -0700

    rm tmp string

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 69647913932312a04ca06e7a04cca17ed50d4daf
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Mar 24 21:02:20 2023 -0700

    rm tmp string

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 55e67996a7b0651dbb5ee06cb89fe0410648c3c1
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Mar 25 10:42:43 2023 -0700

    rm tmp string

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 73cee43925c0d32940989c616440b4da18640121
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Mar 25 09:55:17 2023 -0700

    rm tmp string

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit eba6d1413b8d87a64a90141e5263a56eede1df51
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Mar 25 09:40:16 2023 -0700

    rm tmp string

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 95d6ed78144512a37fd7c1d3d8a62fc4c8965818
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Mar 25 08:18:46 2023 -0700

    rm tmp string

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit faf82464d7be7fd6c958a21d401fa48ece4ac341
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Mar 25 07:49:11 2023 -0700

    rm tmp string

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit cfc9064496cb6f46ec562b104bc7fff2fbc1b32e
Author: James Cherry <cherry@parallaxsw.com>
Date:   Sat Mar 25 07:37:12 2023 -0700

    rm tmp string

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 057933a6ac356a7541883aa64b5109c7a0e8b8d1
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Mar 24 21:02:20 2023 -0700

    rm tmp string

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit fdeb6436a72413356a627dd1de1d8cec7fca4c4a
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Mar 24 19:53:44 2023 -0700

    rm TmpString uses

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2023-03-26 06:34:36 -07:00
parent 2b8fd17ca7
commit 94a93bd4ae
24 changed files with 621 additions and 588 deletions

View File

@ -1106,7 +1106,7 @@ private:
LibertyCell *cell_; LibertyCell *cell_;
}; };
const char * string
portLibertyToSta(const char *port_name); portLibertyToSta(const char *port_name);
} // namespace } // namespace

View File

@ -16,8 +16,12 @@
#pragma once #pragma once
#include <string>
namespace sta { namespace sta {
using std::string;
// Return true if name is a bus. // Return true if name is a bus.
bool bool
isBusName(const char *name, isBusName(const char *name,
@ -38,7 +42,8 @@ parseBusName(const char *name,
const char brkt_right, const char brkt_right,
char escape, char escape,
// Return values. // Return values.
char *&bus_name, bool &is_bus,
string &bus_name,
int &index); int &index);
// Allow multiple different left/right bus brackets. // Allow multiple different left/right bus brackets.
void void
@ -47,7 +52,8 @@ parseBusName(const char *name,
const char *brkts_right, const char *brkts_right,
char escape, char escape,
// Return values. // Return values.
char *&bus_name, bool &is_bus,
string &bus_name,
int &index); int &index);
// Parse a bus range, such as BUS[4:0]. // Parse a bus range, such as BUS[4:0].
@ -59,7 +65,8 @@ parseBusRange(const char *name,
const char brkt_right, const char brkt_right,
char escape, char escape,
// Return values. // Return values.
char *&bus_name, bool &is_bus,
string &bus_name,
int &from, int &from,
int &to); int &to);
// brkt_lefts and brkt_rights are corresponding strings of legal // brkt_lefts and brkt_rights are corresponding strings of legal
@ -70,12 +77,13 @@ parseBusRange(const char *name,
const char *brkts_right, const char *brkts_right,
const char escape, const char escape,
// Return values. // Return values.
char *&bus_name, bool &is_bus,
string &bus_name,
int &from, int &from,
int &to); int &to);
// Insert escapes before ch1 and ch2 in token. // Insert escapes before ch1 and ch2 in token.
const char * string
escapeChars(const char *token, escapeChars(const char *token,
const char ch1, const char ch1,
const char ch2, const char ch2,

View File

@ -44,7 +44,10 @@ public:
PatternMatch(const char *pattern); PatternMatch(const char *pattern);
PatternMatch(const char *pattern, PatternMatch(const char *pattern,
const PatternMatch *inherit_from); const PatternMatch *inherit_from);
PatternMatch(string pattern,
const PatternMatch *inherit_from);
bool match(const char *str) const; bool match(const char *str) const;
bool match(const string &str) const;
bool matchNoCase(const char *str) const; bool matchNoCase(const char *str) const;
const char *pattern() const { return pattern_; } const char *pattern() const { return pattern_; }
bool isRegexp() const { return is_regexp_; } bool isRegexp() const { return is_regexp_; }

View File

@ -16,25 +16,29 @@
#pragma once #pragma once
#include <string>
namespace sta { namespace sta {
const char * using std::string;
string
instanceVerilogName(const char *sta_name, instanceVerilogName(const char *sta_name,
const char escape); const char escape);
const char * string
netVerilogName(const char *sta_name, netVerilogName(const char *sta_name,
const char escape); const char escape);
const char * string
portVerilogName(const char *sta_name, portVerilogName(const char *sta_name,
const char escape); const char escape);
const char * string
moduleVerilogToSta(const char *sta_name); moduleVerilogToSta(const char *sta_name);
const char * string
instanceVerilogToSta(const char *sta_name); instanceVerilogToSta(const char *sta_name);
const char * string
netVerilogToSta(const char *sta_name); netVerilogToSta(const char *sta_name);
const char * string
portVerilogToSta(const char *sta_name); portVerilogToSta(const char *sta_name);
} // namespace } // namespace

View File

@ -2520,23 +2520,20 @@ LibertyPort::setReceiverModel(ReceiverModelPtr receiver_model)
receiver_model_ = receiver_model; receiver_model_ = receiver_model;
} }
const char * string
portLibertyToSta(const char *port_name) portLibertyToSta(const char *port_name)
{ {
constexpr char bus_brkt_left = '['; constexpr char bus_brkt_left = '[';
constexpr char bus_brkt_right = ']'; constexpr char bus_brkt_right = ']';
size_t name_length = strlen(port_name); size_t name_length = strlen(port_name);
char *sta_name = makeTmpString(name_length * 2); string sta_name;
//char *sta_name = new char[name_length * 2];//makeTmpString(name_length * 2);
char *p = sta_name;
for (size_t i = 0; i < name_length; i++) { for (size_t i = 0; i < name_length; i++) {
char ch = port_name[i]; char ch = port_name[i];
if (ch == bus_brkt_left if (ch == bus_brkt_left
|| ch == bus_brkt_right) || ch == bus_brkt_right)
*p++ = '\\'; sta_name += '\\';
*p++ = ch; sta_name += ch;
} }
*p++ = '\0';
return sta_name; return sta_name;
} }

View File

@ -41,8 +41,8 @@ LibertyPort *
LibertyBuilder::makePort(LibertyCell *cell, LibertyBuilder::makePort(LibertyCell *cell,
const char *port_name) const char *port_name)
{ {
const char *sta_name = portLibertyToSta(port_name); string sta_name = portLibertyToSta(port_name);
LibertyPort *port = new LibertyPort(cell, sta_name, false, nullptr, LibertyPort *port = new LibertyPort(cell, sta_name.c_str(), false, nullptr,
-1, -1, false, nullptr); -1, -1, false, nullptr);
cell->addPort(port); cell->addPort(port);
return port; return port;
@ -89,12 +89,13 @@ LibertyBuilder::makeBusPortBit(ConcreteLibrary *library,
const char *bus_name, const char *bus_name,
int bit_index) int bit_index)
{ {
char *bit_name = stringPrintTmp("%s%c%d%c", string bit_name;
bus_name, stringPrint(bit_name, "%s%c%d%c",
library->busBrktLeft(), bus_name,
bit_index, library->busBrktLeft(),
library->busBrktRight()); bit_index,
LibertyPort *port = makePort(cell, bit_name, bit_index); library->busBrktRight());
LibertyPort *port = makePort(cell, bit_name.c_str(), bit_index);
bus_port->addPortBit(port); bus_port->addPortBit(port);
cell->addPortBit(port); cell->addPortBit(port);
} }

View File

@ -523,38 +523,42 @@ LibertyReader::defineScalingFactorVisitors()
if (scaleFactorTypeRiseFallSuffix(type)) { if (scaleFactorTypeRiseFallSuffix(type)) {
for (auto tr : RiseFall::range()) { for (auto tr : RiseFall::range()) {
const char *tr_name = (tr == RiseFall::rise()) ? "rise":"fall"; const char *tr_name = (tr == RiseFall::rise()) ? "rise":"fall";
const char *attr_name = stringPrintTmp("k_%s_%s_%s", string attr_name;
pvt_name, stringPrint(attr_name, "k_%s_%s_%s",
type_name, pvt_name,
tr_name); type_name,
defineAttrVisitor(attr_name,&LibertyReader::visitScaleFactorSuffix); tr_name);
defineAttrVisitor(attr_name.c_str() ,&LibertyReader::visitScaleFactorSuffix);
} }
} }
else if (scaleFactorTypeRiseFallPrefix(type)) { else if (scaleFactorTypeRiseFallPrefix(type)) {
for (auto tr : RiseFall::range()) { for (auto tr : RiseFall::range()) {
const char *tr_name = (tr == RiseFall::rise()) ? "rise":"fall"; const char *tr_name = (tr == RiseFall::rise()) ? "rise":"fall";
const char *attr_name = stringPrintTmp("k_%s_%s_%s", string attr_name;
pvt_name, stringPrint(attr_name, "k_%s_%s_%s",
tr_name, pvt_name,
type_name); tr_name,
defineAttrVisitor(attr_name,&LibertyReader::visitScaleFactorPrefix); type_name);
defineAttrVisitor(attr_name.c_str(),&LibertyReader::visitScaleFactorPrefix);
} }
} }
else if (scaleFactorTypeLowHighSuffix(type)) { else if (scaleFactorTypeLowHighSuffix(type)) {
for (auto tr : RiseFall::range()) { for (auto tr : RiseFall::range()) {
const char *tr_name = (tr == RiseFall::rise()) ? "high":"low"; const char *tr_name = (tr == RiseFall::rise()) ? "high":"low";
const char *attr_name = stringPrintTmp("k_%s_%s_%s", string attr_name;
pvt_name, stringPrint(attr_name, "k_%s_%s_%s",
tr_name, pvt_name,
type_name); tr_name,
defineAttrVisitor(attr_name,&LibertyReader::visitScaleFactorHiLow); type_name);
defineAttrVisitor(attr_name.c_str(),&LibertyReader::visitScaleFactorHiLow);
} }
} }
else { else {
const char *attr_name = stringPrintTmp("k_%s_%s", string attr_name;
pvt_name, stringPrint(attr_name, "k_%s_%s",
type_name); pvt_name,
defineAttrVisitor(attr_name,&LibertyReader::visitScaleFactor); type_name);
defineAttrVisitor(attr_name.c_str(),&LibertyReader::visitScaleFactor);
} }
} }
} }
@ -770,39 +774,32 @@ LibertyReader::parseUnits(LibertyAttr *attr,
float &scale_var, float &scale_var,
Unit *unit) Unit *unit)
{ {
const char *unit_str = getAttrString(attr); string units = getAttrString(attr);
if (unit_str) { if (!units.empty()) {
unsigned unit_str_length = strlen(unit_str);
// Unit format is <multipler_digits><scale_suffix_char><unit_suffix>. // Unit format is <multipler_digits><scale_suffix_char><unit_suffix>.
// Find the multiplier digits. // Find the multiplier digits.
char *mult_str = makeTmpString(unit_str_length); string units = getAttrString(attr);
const char *s = unit_str; size_t mult_end = units.find_first_not_of("01234567890");
char *m = mult_str;
for (; *s; s++) {
char ch = *s;
if (isdigit(ch))
*m++ = ch;
else
break;
}
*m = '\0';
float mult = 1.0F; float mult = 1.0F;
if (*mult_str != '\0') { string scale_suffix;
if (stringEq(mult_str, "1")) if (mult_end != units.npos) {
string unit_mult = units.substr(0, mult_end);
scale_suffix = units.substr(mult_end);
if (unit_mult == "1")
mult = 1.0F; mult = 1.0F;
else if (stringEq(mult_str, "10")) else if (unit_mult == "10")
mult = 10.0F; mult = 10.0F;
else if (stringEq(mult_str, "100")) else if (unit_mult == "100")
mult = 100.0F; mult = 100.0F;
else else
libWarn(38, attr, "unknown unit multiplier %s.", mult_str); libWarn(38, attr, "unknown unit multiplier %s.", unit_mult.c_str());
} }
else
scale_suffix = units;
float scale_mult = 1.0F; float scale_mult = 1.0F;
if (*s && stringEqual(s + 1, unit_suffix)) { if (scale_suffix.size() >= 2 && scale_suffix.substr(1) == unit_suffix) {
char scale_char = tolower(*s); char scale_char = tolower(scale_suffix[0]);
if (scale_char == 'k') if (scale_char == 'k')
scale_mult = 1E+3F; scale_mult = 1E+3F;
else if (scale_char == 'm') else if (scale_char == 'm')
@ -818,8 +815,8 @@ LibertyReader::parseUnits(LibertyAttr *attr,
else else
libWarn(39, attr, "unknown unit scale %c.", scale_char); libWarn(39, attr, "unknown unit scale %c.", scale_char);
} }
else if (!stringEqual(s, unit_suffix)) else if (!stringEqual(scale_suffix.c_str(), unit_suffix))
libWarn(40, attr, "unknown unit suffix %s.", s + 1); libWarn(40, attr, "unknown unit suffix %s.", scale_suffix.c_str());
scale_var = scale_mult * mult; scale_var = scale_mult * mult;
unit->setScale(scale_var); unit->setScale(scale_var);
@ -3192,8 +3189,8 @@ libertyReaderFindPort(LibertyCell *cell,
char brkt_right = library->busBrktRight(); char brkt_right = library->busBrktRight();
const char escape = '\\'; const char escape = '\\';
// Pins at top level with bus names have escaped brackets. // Pins at top level with bus names have escaped brackets.
port_name = escapeChars(port_name, brkt_left, brkt_right, escape); string escaped_port_name = escapeChars(port_name, brkt_left, brkt_right, escape);
port = cell->findLibertyPort(port_name); port = cell->findLibertyPort(escaped_port_name.c_str());
} }
return port; return port;
} }
@ -4771,11 +4768,12 @@ LibertyReader::parseFunc(const char *func,
const char *attr_name, const char *attr_name,
int line) int line)
{ {
const char *error_msg = stringPrintTmp("%s, line %d %s", string error_msg;
filename_, stringPrint(error_msg, "%s, line %d %s",
line, filename_,
attr_name); line,
return parseFuncExpr(func, cell_, error_msg, report_); attr_name);
return parseFuncExpr(func, cell_, error_msg.c_str(), report_);
} }
EarlyLateAll * EarlyLateAll *
@ -5628,7 +5626,6 @@ PortNameBitIterator::PortNameBitIterator(LibertyCell *cell,
port_(nullptr), port_(nullptr),
bit_iterator_(nullptr), bit_iterator_(nullptr),
range_bus_port_(nullptr), range_bus_port_(nullptr),
range_bus_name_(nullptr),
range_name_next_(nullptr), range_name_next_(nullptr),
size_(0) size_(0)
{ {
@ -5649,11 +5646,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;
string bus_name;
int from, to; int from, to;
char *bus_name; parseBusRange(port_name, library->busBrktLeft(),
parseBusRange(port_name, library->busBrktLeft(), library->busBrktRight(), library->busBrktRight(), '\\',
'\\', bus_name, from, to); is_bus, bus_name, from, to);
if (bus_name) { if (is_bus) {
port = visitor_->findPort(port_name); port = visitor_->findPort(port_name);
if (port) { if (port) {
if (port->isBus()) { if (port->isBus()) {
@ -5663,7 +5662,6 @@ PortNameBitIterator::init(const char *port_name)
range_from_ = from; range_from_ = from;
range_to_ = to; range_to_ = to;
range_bit_ = from; range_bit_ = from;
delete [] bus_name;
} }
else else
visitor_->libWarn(156, line_, "port %s subscript out of range.", visitor_->libWarn(156, line_, "port %s subscript out of range.",
@ -5672,7 +5670,7 @@ PortNameBitIterator::init(const char *port_name)
else else
visitor_->libWarn(157, line_, "port range %s of non-bus port %s.", visitor_->libWarn(157, line_, "port range %s of non-bus port %s.",
port_name, port_name,
bus_name); bus_name.c_str());
} }
else { else {
range_bus_name_ = bus_name; range_bus_name_ = bus_name;
@ -5690,7 +5688,6 @@ PortNameBitIterator::init(const char *port_name)
PortNameBitIterator::~PortNameBitIterator() PortNameBitIterator::~PortNameBitIterator()
{ {
stringDelete(range_bus_name_);
delete bit_iterator_; delete bit_iterator_;
} }
@ -5703,7 +5700,7 @@ PortNameBitIterator::hasNext()
&& ((range_from_ > range_to_) && ((range_from_ > range_to_)
? range_bit_ >= range_to_ ? range_bit_ >= range_to_
: range_bit_ <= range_from_)) : range_bit_ <= range_from_))
|| (range_bus_name_ || (!range_bus_name_.empty()
&& range_name_next_); && range_name_next_);
} }
@ -5725,7 +5722,7 @@ PortNameBitIterator::next()
range_bit_++; range_bit_++;
return next; return next;
} }
else if (range_bus_name_) { else if (!range_bus_name_.empty()) {
LibertyPort *next = range_name_next_; LibertyPort *next = range_name_next_;
findRangeBusNameNext(); findRangeBusNameNext();
return next; return next;
@ -5741,12 +5738,13 @@ PortNameBitIterator::findRangeBusNameNext()
? range_bit_ >= range_to_ ? range_bit_ >= range_to_
: range_bit_ <= range_to_) { : range_bit_ <= range_to_) {
LibertyLibrary *library = visitor_->library(); LibertyLibrary *library = visitor_->library();
const char *bus_bit_name = stringPrintTmp("%s%c%d%c", string bus_bit_name;
range_bus_name_, stringPrint(bus_bit_name, "%s%c%d%c",
library->busBrktLeft(), range_bus_name_.c_str(),
range_bit_, library->busBrktLeft(),
library->busBrktRight()); range_bit_,
range_name_next_ = visitor_->findPort(bus_bit_name); library->busBrktRight());
range_name_next_ = visitor_->findPort(bus_bit_name.c_str());
if (range_name_next_) { if (range_name_next_) {
if (range_from_ > range_to_) if (range_from_ > range_to_)
range_bit_--; range_bit_--;
@ -5754,7 +5752,7 @@ PortNameBitIterator::findRangeBusNameNext()
range_bit_++; range_bit_++;
} }
else else
visitor_->libWarn(159, line_, "port %s not found.", bus_bit_name); visitor_->libWarn(159, line_, "port %s not found.", bus_bit_name.c_str());
} }
else else
range_name_next_ = nullptr; range_name_next_ = nullptr;

View File

@ -861,7 +861,7 @@ protected:
LibertyPort *port_; LibertyPort *port_;
LibertyPortMemberIterator *bit_iterator_; LibertyPortMemberIterator *bit_iterator_;
LibertyPort *range_bus_port_; LibertyPort *range_bus_port_;
const char *range_bus_name_; string range_bus_name_;
LibertyPort *range_name_next_; LibertyPort *range_name_next_;
int range_from_; int range_from_;
int range_to_; int range_to_;

View File

@ -25,6 +25,8 @@
namespace sta { namespace sta {
using std::map;
static constexpr char escape_ = '\\'; static constexpr char escape_ = '\\';
ConcreteLibrary::ConcreteLibrary(const char *name, ConcreteLibrary::ConcreteLibrary(const char *name,
@ -381,7 +383,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'};
BusPortMap port_map; map<string, BusPort*> port_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
@ -390,19 +392,21 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left,
ports_.clear(); ports_.clear();
for (ConcretePort *port : ports) { for (ConcretePort *port : ports) {
const char *port_name = port->name(); const char *port_name = port->name();
char *bus_name; bool is_bus;
string bus_name;
int index; int index;
parseBusName(port_name, bus_brkts_left, bus_brkts_right, escape_, parseBusName(port_name, bus_brkts_left, bus_brkts_right, escape_,
bus_name, index); is_bus, bus_name, index);
if (bus_name) { if (is_bus) {
if (!port->isBusBit()) { if (!port->isBusBit()) {
BusPort *bus_port = port_map.findKey(bus_name); auto name_bus_port = port_map.find(bus_name);
if (bus_port) BusPort *bus_port;
stringDelete(bus_name); if (name_bus_port == port_map.end()) {
else { bus_port = new BusPort(bus_name.c_str(), index, port->direction());
bus_port = new BusPort(bus_name, index, port->direction());
port_map[bus_name] = bus_port; port_map[bus_name] = bus_port;
} }
else
bus_port = name_bus_port->second;
bus_port->pushMember(port); bus_port->pushMember(port);
} }
else else
@ -413,47 +417,45 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left,
} }
// Make the bus ports. // Make the bus ports.
BusPortMap::Iterator bus_iter(port_map); for (auto name_bus : port_map) {
while (bus_iter.hasNext()) { const string &bus_name = name_bus.first;
BusPort *bus_port = bus_iter.next(); BusPort *bus_port = name_bus.second;
const char *bus_name = bus_port->name(); bool msb_first = port_msb_first(bus_name.c_str());
bool msb_first = port_msb_first(bus_name);
ConcretePortSeq *members = bus_port->members(); ConcretePortSeq *members = bus_port->members();
sort(members, [&](ConcretePort *port1, sort(members, [&](ConcretePort *port1,
ConcretePort *port2) { ConcretePort *port2) {
char *bus_name; bool is_bus;
int index1, index2; string bus_name;
parseBusName(port1->name(), bus_brkts_left, bus_brkts_right, escape_, int index1, index2;
bus_name, index1); parseBusName(port1->name(), bus_brkts_left, bus_brkts_right, escape_,
stringDelete(bus_name); is_bus, bus_name, index1);
parseBusName(port2->name(), bus_brkts_left, bus_brkts_right, escape_, parseBusName(port2->name(), bus_brkts_left, bus_brkts_right, escape_,
bus_name, index2); is_bus, bus_name, index2);
stringDelete(bus_name); return msb_first ? index1 > index2 : index1 < index2;
return msb_first ? index1 > index2 : index1 < index2; });
});
char *bus_name1; bool is_bus1;
string bus_name1;
int from_index, to_index; int from_index, to_index;
parseBusName((*members)[0]->name(), parseBusName((*members)[0]->name(),
bus_brkts_left, bus_brkts_right, escape_, bus_brkts_left, bus_brkts_right, escape_,
bus_name1, from_index); is_bus1, bus_name1, from_index);
stringDelete(bus_name1);
parseBusName((*members)[members->size() - 1]->name(), parseBusName((*members)[members->size() - 1]->name(),
bus_brkts_left, bus_brkts_right, escape_, bus_brkts_left, bus_brkts_right, escape_,
bus_name1, to_index); is_bus1, bus_name1, to_index);
stringDelete(bus_name1);
ConcretePort *port = makeBusPort(bus_name, from_index, to_index, members); ConcretePort *port = makeBusPort(bus_name.c_str(), from_index,
to_index, members);
port->setDirection(bus_port->direction()); port->setDirection(bus_port->direction());
delete bus_port; delete bus_port;
for (ConcretePort *port : *members) { for (ConcretePort *port : *members) {
char *bus_name; bool is_bus;
string bus_name;
int index; int index;
parseBusName(port->name(), bus_brkts_left, bus_brkts_right, escape_, parseBusName(port->name(), bus_brkts_left, bus_brkts_right, escape_,
bus_name, index); is_bus, bus_name, index);
port->setBusBitIndex(index); port->setBusBitIndex(index);
stringDelete(bus_name);
} }
} }
} }

View File

@ -51,12 +51,14 @@ parseBusName(const char *name,
const char brkt_right, const char brkt_right,
const char escape, const char escape,
// Return values. // Return values.
char *&bus_name, bool &is_bus,
string &bus_name,
int &index) int &index)
{ {
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'};
parseBusName(name, brkts_left, brkts_right, escape, bus_name, index); parseBusName(name, brkts_left, brkts_right, escape,
is_bus, bus_name, index);
} }
void void
@ -65,10 +67,11 @@ parseBusName(const char *name,
const char *brkts_right, const char *brkts_right,
char escape, char escape,
// Return values. // Return values.
char *&bus_name, bool &is_bus,
string &bus_name,
int &index) int &index)
{ {
bus_name = nullptr; is_bus = false;
size_t len = strlen(name); size_t len = strlen(name);
// Shortest bus name is a[0]. // Shortest bus name is a[0].
if (len >= 4 if (len >= 4
@ -81,10 +84,9 @@ parseBusName(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;
size_t bus_name_len = left - name; size_t bus_name_len = left - name;
bus_name = new char[bus_name_len + 1]; bus_name.append(name, bus_name_len);
strncpy(bus_name, name, bus_name_len);
bus_name[bus_name_len] = '\0';
// Simple bus subscript. // Simple bus subscript.
index = atoi(left + 1); index = atoi(left + 1);
} }
@ -98,13 +100,15 @@ parseBusRange(const char *name,
const char brkt_right, const char brkt_right,
char escape, char escape,
// Return values. // Return values.
char *&bus_name, bool &is_bus,
string &bus_name,
int &from, int &from,
int &to) int &to)
{ {
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, bus_name, from, to); parseBusRange(name, brkts_left, brkts_right, escape,
is_bus, bus_name, from, to);
} }
void void
@ -113,11 +117,12 @@ parseBusRange(const char *name,
const char *brkts_right, const char *brkts_right,
char escape, char escape,
// Return values. // Return values.
char *&bus_name, bool &is_bus,
string &bus_name,
int &from, int &from,
int &to) int &to)
{ {
bus_name = nullptr; is_bus = false;
size_t len = strlen(name); size_t len = strlen(name);
// Shortest bus range is a[1:0]. // Shortest bus range is a[1:0].
if (len >= 6 if (len >= 6
@ -134,10 +139,8 @@ parseBusRange(const char *name,
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) {
size_t bus_name_len = left - name; is_bus = true;
bus_name = new char[bus_name_len + 1]; bus_name.append(name, left - name);
strncpy(bus_name, name, bus_name_len);
bus_name[bus_name_len] = '\0';
// 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);
@ -148,54 +151,32 @@ parseBusRange(const char *name,
} }
} }
const char * string
escapeChars(const char *token, escapeChars(const char *token,
const char ch1, const char ch1,
const char ch2, const char ch2,
const char escape) const char escape)
{ {
int result_length = 0; string escaped;
bool need_escapes = false;
for (const char *s = token; *s; s++) { for (const char *s = token; *s; s++) {
char ch = *s; char ch = *s;
if (ch == escape) { if (ch == escape) {
char next_ch = s[1]; char next_ch = s[1];
// Make sure we don't skip the null if escape is the last char. // Make sure we don't skip the null if escape is the last char.
if (next_ch != '\0') if (next_ch != '\0') {
result_length++; escaped += ch;
escaped += next_ch;
s++;
}
} }
else if (ch == ch1 || ch == ch2) { else if (ch == ch1 || ch == ch2) {
result_length++; escaped += escape;
need_escapes = true; escaped += ch;
} }
result_length++; else
escaped += ch;
} }
if (need_escapes) { return escaped;
char *result = makeTmpString(result_length + 1);
char *r = result;
for (const char *s = token; *s; s++) {
char ch = *s;
if (ch == escape) {
char next_ch = s[1];
// Make sure we don't skip the null if escape is the last char.
if (next_ch != '\0') {
*r++ = ch;
*r++ = next_ch;
s++;
}
}
else if (ch == ch1 || ch == ch2) {
*r++ = escape;
*r++ = ch;
}
else
*r++ = ch;
}
*r++ = '\0';
return result;
}
else
return token;
} }
} // namespace } // namespace

View File

@ -22,10 +22,10 @@
namespace sta { namespace sta {
static const char * static string
escapeDividers(const char *token, escapeDividers(const char *token,
const Network *network); const Network *network);
static const char * static string
escapeBrackets(const char *token, escapeBrackets(const char *token,
const Network *network); const Network *network);
@ -631,21 +631,22 @@ SdcNetwork::findPort(const Cell *cell,
Port *port = network_->findPort(cell, name); Port *port = network_->findPort(cell, name);
if (port == nullptr) { if (port == nullptr) {
// Look for matches after escaping brackets. // Look for matches after escaping brackets.
char *bus_name; bool is_bus;
string bus_name;
int index; int index;
parseBusName(name, '[', ']', pathEscape(), bus_name, index); parseBusName(name, '[', ']', pathEscape(), is_bus, bus_name, index);
if (bus_name) { if (is_bus) {
const char *escaped1 = escapeBrackets(name, this); string escaped1 = escapeBrackets(name, this);
port = network_->findPort(cell, escaped1); port = network_->findPort(cell, escaped1.c_str());
if (port == nullptr if (port == nullptr) {
&& bus_name[strlen(bus_name) - 1] == ']') {
// Try escaping base foo\[0\][1] // Try escaping base foo\[0\][1]
const char *escaped2 = stringPrintTmp("%s[%d]", string escaped2;
escapeBrackets(bus_name, this), string escaped_bus_name = escapeBrackets(bus_name.c_str(), this);
index); stringPrint(escaped2, "%s[%d]",
port = network_->findPort(cell, escaped2); escaped_bus_name.c_str(),
index);
port = network_->findPort(cell, escaped2.c_str());
} }
stringDelete(bus_name);
} }
} }
return port; return port;
@ -658,23 +659,25 @@ SdcNetwork::findPortsMatching(const Cell *cell,
PortSeq matches = network_->findPortsMatching(cell, pattern); PortSeq matches = network_->findPortsMatching(cell, pattern);
if (matches.empty()) { if (matches.empty()) {
// Look for matches after escaping brackets. // Look for matches after escaping brackets.
char *bus_name; bool is_bus;
string bus_name;
int index; int index;
parseBusName(pattern->pattern(), '[', ']', pathEscape(), bus_name, index); parseBusName(pattern->pattern(), '[', ']', pathEscape(),
if (bus_name) { is_bus, bus_name, index);
const char *escaped1 = escapeBrackets(pattern->pattern(), this); if (is_bus) {
PatternMatch escaped_pattern1(escaped1, pattern); string escaped1 = escapeBrackets(pattern->pattern(), this);
PatternMatch escaped_pattern1(escaped1.c_str(), pattern);
matches = network_->findPortsMatching(cell, &escaped_pattern1); matches = network_->findPortsMatching(cell, &escaped_pattern1);
if (matches.empty() if (matches.empty()) {
&& bus_name[strlen(bus_name) - 1] == ']') {
// Try escaping base foo\[0\][1] // Try escaping base foo\[0\][1]
const char *escaped2 = stringPrintTmp("%s[%d]", string escaped2;
escapeBrackets(bus_name, this), string escaped_bus_name = escapeBrackets(bus_name.c_str(), this);
index); stringPrint(escaped2, "%s[%d]",
PatternMatch escaped_pattern2(escaped2, pattern); escaped_bus_name.c_str(),
index);
PatternMatch escaped_pattern2(escaped2.c_str(), pattern);
matches = network_->findPortsMatching(cell, &escaped_pattern2); matches = network_->findPortsMatching(cell, &escaped_pattern2);
} }
stringDelete(bus_name);
} }
} }
return matches; return matches;
@ -739,8 +742,10 @@ SdcNetwork::findInstance(const char *path_name) const
if (parent == nullptr) if (parent == nullptr)
parent = network_->topInstance(); parent = network_->topInstance();
Instance *child = findChild(parent, child_name); Instance *child = findChild(parent, child_name);
if (child == nullptr) if (child == nullptr) {
child = findChild(parent, escapeDividers(child_name, this)); string escaped_name = escapeDividers(child_name, this);
child = findChild(parent, escaped_name.c_str());
}
return child; return child;
} }
@ -774,8 +779,8 @@ SdcNetwork::findChild(const Instance *parent,
{ {
Instance *child = network_->findChild(parent, name); Instance *child = network_->findChild(parent, name);
if (child == nullptr) { if (child == nullptr) {
const char *escaped = escapeBrackets(name, this); string escaped = escapeBrackets(name, this);
child = network_->findChild(parent, escaped); child = network_->findChild(parent, escaped.c_str());
} }
return child; return child;
} }
@ -799,8 +804,8 @@ SdcNetwork::findNet(const Instance *instance,
{ {
Net *net = network_->findNet(instance, net_name); Net *net = network_->findNet(instance, net_name);
if (net == nullptr) { if (net == nullptr) {
const char *net_name_ = escapeBrackets(net_name, this); string net_name1 = escapeBrackets(net_name, this);
net = network_->findNet(instance, net_name_); net = network_->findNet(instance, net_name1.c_str());
} }
return net; return net;
} }
@ -829,14 +834,13 @@ SdcNetwork::findInstNetsMatching(const Instance *instance,
network_->findInstNetsMatching(instance, pattern, matches); network_->findInstNetsMatching(instance, pattern, matches);
if (matches.empty()) { if (matches.empty()) {
// Look for matches after escaping path dividers. // Look for matches after escaping path dividers.
const PatternMatch escaped_dividers(escapeDividers(pattern->pattern(), string escaped_pattern = escapeDividers(pattern->pattern(), this);
this), const PatternMatch escaped_dividers(escaped_pattern.c_str(), pattern);
pattern);
network_->findInstNetsMatching(instance, &escaped_dividers, matches); network_->findInstNetsMatching(instance, &escaped_dividers, matches);
if (matches.empty()) { if (matches.empty()) {
// Look for matches after escaping brackets. // Look for matches after escaping brackets.
const PatternMatch escaped_brkts(escapeBrackets(pattern->pattern(),this), string escaped_pattern2 = escapeBrackets(pattern->pattern(),this);
pattern); const PatternMatch escaped_brkts(escaped_pattern2.c_str(), pattern);
network_->findInstNetsMatching(instance, &escaped_brkts, matches); network_->findInstNetsMatching(instance, &escaped_brkts, matches);
} }
} }
@ -862,21 +866,21 @@ SdcNetwork::findPin(const Instance *instance,
Pin *pin = network_->findPin(instance, port_name); Pin *pin = network_->findPin(instance, port_name);
if (pin == nullptr) { if (pin == nullptr) {
// Look for match after escaping brackets. // Look for match after escaping brackets.
char *bus_name; bool is_bus;
string bus_name;
int index; int index;
parseBusName(port_name, '[', ']', pathEscape(), bus_name, index); parseBusName(port_name, '[', ']', pathEscape(),
if (bus_name) { is_bus, bus_name, index);
const char *escaped1 = escapeBrackets(port_name, this); if (is_bus) {
pin = network_->findPin(instance, escaped1); string escaped1 = escapeBrackets(port_name, this);
if (pin == nullptr pin = network_->findPin(instance, escaped1.c_str());
&& bus_name[strlen(bus_name) - 1] == ']') { if (pin == nullptr) {
// Try escaping base foo\[0\][1] // Try escaping base foo\[0\][1]
const char *escaped2 = stringPrintTmp("%s[%d]", string escaped_bus_name = escapeBrackets(bus_name.c_str(), this);
escapeBrackets(bus_name, this), string escaped2;
index); stringPrint(escaped2, "%s[%d]", escaped_bus_name.c_str(), index);
pin = network_->findPin(instance, escaped2); pin = network_->findPin(instance, escaped2.c_str());
} }
stringDelete(bus_name);
} }
} }
return pin; return pin;
@ -967,16 +971,16 @@ SdcNetwork::makeInstance(LibertyCell *cell,
const char *name, const char *name,
Instance *parent) Instance *parent)
{ {
const char *escaped_name = escapeDividers(name, this); string escaped_name = escapeDividers(name, this);
return network_edit_->makeInstance(cell, escaped_name, parent); return network_edit_->makeInstance(cell, escaped_name.c_str(), parent);
} }
Net * Net *
SdcNetwork::makeNet(const char *name, SdcNetwork::makeNet(const char *name,
Instance *parent) Instance *parent)
{ {
const char *escaped_name = escapeDividers(name, this); string escaped_name = escapeDividers(name, this);
return network_edit_->makeNet(escaped_name, parent); return network_edit_->makeNet(escaped_name.c_str(), parent);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -1154,10 +1158,9 @@ SdcNetwork::visitMatches(const Instance *parent,
found_match |= visit_tail(parent, &tail_pattern); found_match |= visit_tail(parent, &tail_pattern);
if (!found_match && has_brkts) { if (!found_match && has_brkts) {
// Look for matches after escaping brackets. // Look for matches after escaping brackets.
char *escaped_path = stringCopy(escapeBrackets(inst_path, this)); string escaped_path = escapeBrackets(inst_path, this);
const PatternMatch escaped_tail(escaped_path, pattern); const PatternMatch escaped_tail(escaped_path, pattern);
found_match |= visit_tail(parent, &escaped_tail); found_match |= visit_tail(parent, &escaped_tail);
stringDelete(escaped_path);
} }
} }
stringDelete(inst_path); stringDelete(inst_path);
@ -1166,7 +1169,7 @@ SdcNetwork::visitMatches(const Instance *parent,
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
static const char * static string
escapeDividers(const char *token, escapeDividers(const char *token,
const Network *network) const Network *network)
{ {
@ -1174,7 +1177,7 @@ escapeDividers(const char *token,
network->pathEscape()); network->pathEscape());
} }
static const char * static string
escapeBrackets(const char *token, escapeBrackets(const char *token,
const Network *network) const Network *network)
{ {

View File

@ -23,72 +23,63 @@
namespace sta { namespace sta {
static const char * static string
staToVerilog(const char *sta_name, staToVerilog(const char *sta_name,
const char escape); const char escape);
static const char * static string
staToVerilog2(const char *sta_name, staToVerilog2(const char *sta_name,
const char escape); const char escape);
static const char * static string
verilogToSta(const char *verilog_name); verilogToSta(const char *verilog_name);
static inline void
vstringAppend(char *&str,
char *&str_end,
char *&insert,
char ch);
const char * string
instanceVerilogName(const char *sta_name, instanceVerilogName(const char *sta_name,
const char escape) const char escape)
{ {
return staToVerilog(sta_name, escape); return staToVerilog(sta_name, escape);
} }
const char * string
netVerilogName(const char *sta_name, netVerilogName(const char *sta_name,
const char escape) const char escape)
{ {
char *bus_name; bool is_bus;
string bus_name;
int index; int index;
parseBusName(sta_name, '[', ']', escape, bus_name, index); parseBusName(sta_name, '[', ']', escape, is_bus, bus_name, index);
if (bus_name) { if (is_bus) {
const char *vname = stringPrintTmp("%s[%d]", string bus_vname = staToVerilog(bus_name.c_str(), escape);
staToVerilog(bus_name, escape), string vname;
index); stringPrint(vname, "%s[%d]", bus_vname.c_str(), index);
stringDelete(bus_name);
return vname; return vname;
} }
else else
return staToVerilog2(sta_name, escape); return staToVerilog2(sta_name, escape);
} }
const char * string
portVerilogName(const char *sta_name, portVerilogName(const char *sta_name,
const char escape) const char escape)
{ {
return staToVerilog2(sta_name, escape); return staToVerilog2(sta_name, escape);
} }
static const char * static string
staToVerilog(const char *sta_name, staToVerilog(const char *sta_name,
const char escape) const char escape)
{ {
// Leave room for leading escape and trailing space if the name // Leave room for leading escape and trailing space if the name
// needs to be escaped. // needs to be escaped.
size_t verilog_name_length = strlen(sta_name) + 3;
char *verilog_name = makeTmpString(verilog_name_length);
char *verilog_name_end = &verilog_name[verilog_name_length];
char *v = verilog_name;
// Assume the name has to be escaped and start copying while scanning. // Assume the name has to be escaped and start copying while scanning.
string escaped_name = "\\";
bool escaped = false; bool escaped = false;
*v++ = '\\';
for (const char *s = sta_name; *s ; s++) { for (const char *s = sta_name; *s ; s++) {
char ch = s[0]; char ch = s[0];
if (ch == escape) { if (ch == escape) {
char next_ch = s[1]; char next_ch = s[1];
if (next_ch == escape) { if (next_ch == escape) {
vstringAppend(verilog_name, verilog_name_end, v, ch); escaped_name += ch;
vstringAppend(verilog_name, verilog_name_end, v, next_ch); escaped_name += next_ch;
s++; s++;
} }
else else
@ -98,20 +89,19 @@ staToVerilog(const char *sta_name,
else { else {
if ((!(isalnum(ch) || ch == '_'))) if ((!(isalnum(ch) || ch == '_')))
escaped = true; escaped = true;
vstringAppend(verilog_name, verilog_name_end, v, ch); escaped_name += ch;
} }
} }
if (escaped) { if (escaped) {
// Add a terminating space. // Add a terminating space.
vstringAppend(verilog_name, verilog_name_end, v, ' '); escaped_name += ' ';
vstringAppend(verilog_name, verilog_name_end, v, '\0'); return escaped_name;
return verilog_name;
} }
else else
return sta_name; return string(sta_name);
} }
static const char * static string
staToVerilog2(const char *sta_name, staToVerilog2(const char *sta_name,
const char escape) const char escape)
{ {
@ -119,20 +109,16 @@ staToVerilog2(const char *sta_name,
constexpr char bus_brkt_right = ']'; constexpr char bus_brkt_right = ']';
// Leave room for leading escape and trailing space if the name // Leave room for leading escape and trailing space if the name
// needs to be escaped. // needs to be escaped.
size_t verilog_name_length = strlen(sta_name) + 3; string escaped_name = "\\";
char *verilog_name = makeTmpString(verilog_name_length);
char *verilog_name_end = &verilog_name[verilog_name_length];
char *v = verilog_name;
// Assume the name has to be escaped and start copying while scanning. // Assume the name has to be escaped and start copying while scanning.
bool escaped = false; bool escaped = false;
*v++ = '\\';
for (const char *s = sta_name; *s ; s++) { for (const char *s = sta_name; *s ; s++) {
char ch = s[0]; char ch = s[0];
if (ch == escape) { if (ch == escape) {
char next_ch = s[1]; char next_ch = s[1];
if (next_ch == escape) { if (next_ch == escape) {
vstringAppend(verilog_name, verilog_name_end, v, ch); escaped_name += ch;
vstringAppend(verilog_name, verilog_name_end, v, next_ch); escaped_name += next_ch;
s++; s++;
} }
else else
@ -144,46 +130,45 @@ staToVerilog2(const char *sta_name,
if ((!(isalnum(ch) || ch == '_') && !is_brkt) if ((!(isalnum(ch) || ch == '_') && !is_brkt)
|| is_brkt) || is_brkt)
escaped = true; escaped = true;
vstringAppend(verilog_name, verilog_name_end, v, ch); escaped_name += ch;
} }
} }
if (escaped) { if (escaped) {
// Add a terminating space. // Add a terminating space.
vstringAppend(verilog_name, verilog_name_end, v, ' '); escaped_name += ' ';
vstringAppend(verilog_name, verilog_name_end, v, '\0'); return escaped_name;
return verilog_name;
} }
else else
return sta_name; return string(sta_name);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
const char * string
moduleVerilogToSta(const char *module_name) moduleVerilogToSta(const char *module_name)
{ {
return verilogToSta(module_name); return verilogToSta(module_name);
} }
const char * string
instanceVerilogToSta(const char *inst_name) instanceVerilogToSta(const char *inst_name)
{ {
return verilogToSta(inst_name); return verilogToSta(inst_name);
} }
const char * string
netVerilogToSta(const char *net_name) netVerilogToSta(const char *net_name)
{ {
return verilogToSta(net_name); return verilogToSta(net_name);
} }
const char * string
portVerilogToSta(const char *port_name) portVerilogToSta(const char *port_name)
{ {
return verilogToSta(port_name); return verilogToSta(port_name);
} }
static const char * static string
verilogToSta(const char *verilog_name) verilogToSta(const char *verilog_name)
{ {
if (verilog_name && verilog_name[0] == '\\') { if (verilog_name && verilog_name[0] == '\\') {
@ -197,11 +182,7 @@ verilogToSta(const char *verilog_name)
size_t verilog_name_length = strlen(verilog_name); size_t verilog_name_length = strlen(verilog_name);
if (verilog_name[verilog_name_length - 1] == ' ') if (verilog_name[verilog_name_length - 1] == ' ')
verilog_name_length--; verilog_name_length--;
// +1 for \0, +2 for escaping brackets. string sta_name;
size_t sta_name_length = verilog_name_length + 1;
char *sta_name = makeTmpString(sta_name_length);
char *sta_name_end = &sta_name[sta_name_length];
char *s = sta_name;
for (size_t i = 0; i < verilog_name_length; i++) { for (size_t i = 0; i < verilog_name_length; i++) {
char ch = verilog_name[i]; char ch = verilog_name[i];
if (ch == bus_brkt_left if (ch == bus_brkt_left
@ -209,33 +190,13 @@ verilogToSta(const char *verilog_name)
|| ch == divider || ch == divider
|| ch == escape) || ch == escape)
// Escape bus brackets, dividers and escapes. // Escape bus brackets, dividers and escapes.
vstringAppend(sta_name, sta_name_end, s, escape); sta_name += escape;
vstringAppend(sta_name, sta_name_end, s, ch); sta_name += ch;
} }
vstringAppend(sta_name, sta_name_end, s, '\0');
return sta_name; return sta_name;
} }
else else
return verilog_name; return string(verilog_name);
}
// Append ch to str at insert. Resize str if necessary.
static inline void
vstringAppend(char *&str,
char *&str_end,
char *&insert,
char ch)
{
if (insert == str_end) {
size_t length = str_end - str;
size_t length2 = length * 2;
char *new_str = makeTmpString(length2);
strncpy(new_str, str, length);
str = new_str;
str_end = &str[length2];
insert = &str[length];
}
*insert++ = ch;
} }
} // namespace } // namespace

View File

@ -131,14 +131,15 @@ ReadVcdActivities::setVarActivity(VcdVar *var,
string &var_name, string &var_name,
const VcdValues &var_values) const VcdValues &var_values)
{ {
const char *sta_name = netVerilogToSta(var_name.c_str()); string sta_name = netVerilogToSta(var_name.c_str());
if (var->width() == 1) if (var->width() == 1)
setVarActivity(sta_name, var_values, 0); setVarActivity(sta_name.c_str(), var_values, 0);
else { else {
char *bus_name; bool is_bus;
string bus_name;
int from, to; int from, to;
parseBusRange(sta_name, '[', ']', '\\', parseBusRange(sta_name.c_str(), '[', ']', '\\',
bus_name, from, to); is_bus, bus_name, from, to);
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++) {
@ -160,7 +161,6 @@ ReadVcdActivities::setVarActivity(VcdVar *var,
value_bit++; value_bit++;
} }
} }
stringDelete(bus_name);
} }
} }

View File

@ -128,8 +128,10 @@ celltype:
; ;
cell_instance: cell_instance:
'(' INSTANCE ')' { sta::sdf_reader->setInstance(NULL); } '(' INSTANCE ')'
| '(' INSTANCE '*' ')' { sta::sdf_reader->setInstanceWildcard(); } { sta::sdf_reader->setInstance(NULL); }
| '(' INSTANCE '*' ')'
{ sta::sdf_reader->setInstanceWildcard(); }
| '(' INSTANCE path ')' | '(' INSTANCE path ')'
{ sta::sdf_reader->setInstance($3); } { sta::sdf_reader->setInstance($3); }
; ;
@ -266,7 +268,10 @@ port:
ID ID
{ $$ = sta::sdf_reader->unescaped($1); } { $$ = sta::sdf_reader->unescaped($1); }
| ID '[' DNUMBER ']' | ID '[' DNUMBER ']'
{ $$ = sta::stringPrint("%s[%d]", sta::sdf_reader->unescaped($1), $3); } { const char *bus_name = sta::sdf_reader->unescaped($1);
$$ = sta::stringPrint("%s[%d]", bus_name, $3);
sta::stringDelete(bus_name);
}
; ;
port_instance: port_instance:
@ -292,7 +297,7 @@ port_tchk:
| '(' COND EXPR_ID_CLOSE | '(' COND EXPR_ID_CLOSE
{ $$ = sta::sdf_reader->makeCondPortSpec($3); } { $$ = sta::sdf_reader->makeCondPortSpec($3); }
| '(' COND EXPR_OPEN port_transition port_instance ')' ')' | '(' COND EXPR_OPEN port_transition port_instance ')' ')'
{ $$ = sta::sdf_reader->makePortSpec($4, $5, $3); sta::stringDelete($3); } { $$ = sta::sdf_reader->makePortSpec($4, $5, $3); }
; ;
value: value:

View File

@ -210,6 +210,8 @@ SdfReader::interconnect(const char *from_pin_name,
sdfWarn(186, "pin %s not found.", to_pin_name); sdfWarn(186, "pin %s not found.", to_pin_name);
} }
} }
stringDelete(from_pin_name);
stringDelete(to_pin_name);
deleteTripleSeq(triples); deleteTripleSeq(triples);
} }
@ -234,6 +236,7 @@ SdfReader::port(const char *to_pin_name,
} }
} }
} }
stringDelete(to_pin_name);
deleteTripleSeq(triples); deleteTripleSeq(triples);
} }
@ -312,6 +315,7 @@ SdfReader::setInstance(const char *instance_name)
} }
else else
instance_ = nullptr; instance_ = nullptr;
stringDelete(instance_name);
} }
void void
@ -399,6 +403,7 @@ SdfReader::iopath(SdfPortSpec *from_edge,
} }
} }
} }
stringDelete(to_port_name);
deletePortSpec(from_edge); deletePortSpec(from_edge);
deleteTripleSeq(triples); deleteTripleSeq(triples);
stringDelete(cond); stringDelete(cond);
@ -688,6 +693,7 @@ SdfReader::device(const char *to_port_name,
setDevicePinDelays(to_pin, triples); setDevicePinDelays(to_pin, triples);
} }
} }
stringDelete(to_port_name);
deleteTripleSeq(triples); deleteTripleSeq(triples);
} }
@ -822,7 +828,10 @@ SdfReader::makePortSpec(Transition *tr,
const char *port, const char *port,
const char *cond) const char *cond)
{ {
return new SdfPortSpec(tr, port, cond); SdfPortSpec *port_spec = new SdfPortSpec(tr, port, cond);
stringDelete(port);
stringDelete(cond);
return port_spec;
} }
SdfPortSpec * SdfPortSpec *
@ -837,9 +846,9 @@ SdfReader::makeCondPortSpec(const char *cond_port)
auto cond_end = cond_port1.find_last_not_of(" ", port_idx); auto cond_end = cond_port1.find_last_not_of(" ", port_idx);
if (cond_end != cond_port1.npos) { if (cond_end != cond_port1.npos) {
string cond1 = cond_port1.substr(0, cond_end + 1); string cond1 = cond_port1.substr(0, cond_end + 1);
SdfPortSpec *port_spec = makePortSpec(Transition::riseFall(), SdfPortSpec *port_spec = new SdfPortSpec(Transition::riseFall(),
port1.c_str(), port1.c_str(),
cond1.c_str()); cond1.c_str());
stringDelete(cond_port); stringDelete(cond_port);
return port_spec; return port_spec;
} }
@ -919,7 +928,7 @@ SdfReader::unescaped(const char *token)
{ {
char path_escape = network_->pathEscape(); char path_escape = network_->pathEscape();
char path_divider = network_->pathDivider(); char path_divider = network_->pathDivider();
char *unescaped = makeTmpString(strlen(token) + 1); char *unescaped = new char[strlen(token) + 1];
char *u = unescaped; char *u = unescaped;
size_t token_length = strlen(token); size_t token_length = strlen(token);
@ -962,10 +971,12 @@ char *
SdfReader::makePath(const char *head, SdfReader::makePath(const char *head,
const char *tail) const char *tail)
{ {
char *path = stringPrintTmp("%s%c%s", char *path = stringPrint("%s%c%s",
head, head,
network_->pathDivider(), network_->pathDivider(),
tail); tail);
sta::stringDelete(head);
sta::stringDelete(tail);
return path; return path;
} }

View File

@ -100,10 +100,10 @@ protected:
void writeSdfTriple(float min, void writeSdfTriple(float min,
float max); float max);
void writeSdfDelay(double delay); void writeSdfDelay(double delay);
char *sdfPortName(const Pin *pin); string sdfPortName(const Pin *pin);
char *sdfPathName(const Pin *pin); string sdfPathName(const Pin *pin);
char *sdfPathName(const Instance *inst); string sdfPathName(const Instance *inst);
char *sdfName(const Instance *inst); string sdfName(const Instance *inst);
private: private:
char sdf_divider_; char sdf_divider_;
@ -310,9 +310,11 @@ SdfWriter::writeInterconnectFromPin(Pin *drvr_pin)
Edge *edge = edge_iter.next(); Edge *edge = edge_iter.next();
if (edge->isWire()) { if (edge->isWire()) {
Pin *load_pin = edge->to(graph_)->pin(); Pin *load_pin = edge->to(graph_)->pin();
string drvr_pin_name = sdfPathName(drvr_pin);
string load_pin_name = sdfPathName(load_pin);
gzprintf(stream_, " (INTERCONNECT %s %s ", gzprintf(stream_, " (INTERCONNECT %s %s ",
sdfPathName(drvr_pin), drvr_pin_name.c_str(),
sdfPathName(load_pin)); load_pin_name.c_str());
writeArcDelays(edge); writeArcDelays(edge);
gzprintf(stream_, ")\n"); gzprintf(stream_, ")\n");
} }
@ -340,7 +342,8 @@ SdfWriter::writeInstHeader(const Instance *inst)
{ {
gzprintf(stream_, " (CELL\n"); gzprintf(stream_, " (CELL\n");
gzprintf(stream_, " (CELLTYPE \"%s\")\n", network_->cellName(inst)); gzprintf(stream_, " (CELLTYPE \"%s\")\n", network_->cellName(inst));
gzprintf(stream_, " (INSTANCE %s)\n", sdfPathName(inst)); string inst_name = sdfPathName(inst);
gzprintf(stream_, " (INSTANCE %s)\n", inst_name.c_str());
} }
void void
@ -384,9 +387,11 @@ SdfWriter::writeIopaths(const Instance *inst,
gzprintf(stream_, " (COND %s\n", sdf_cond); gzprintf(stream_, " (COND %s\n", sdf_cond);
gzprintf(stream_, " "); gzprintf(stream_, " ");
} }
gzprintf(stream_, " (IOPATH %s %s ", string from_pin_name = sdfPortName(from_pin);
sdfPortName(from_pin), string to_pin_name = sdfPortName(to_pin);
sdfPortName(to_pin)); gzprintf(stream_, " (IOPATH %s %s ",
from_pin_name.c_str(),
to_pin_name.c_str());
writeArcDelays(edge); writeArcDelays(edge);
if (sdf_cond) if (sdf_cond)
gzprintf(stream_, ")"); gzprintf(stream_, ")");
@ -651,12 +656,14 @@ SdfWriter::writeCheck(Edge *edge,
if (sdf_cond_start) if (sdf_cond_start)
gzprintf(stream_, "(COND %s ", sdf_cond_start); gzprintf(stream_, "(COND %s ", sdf_cond_start);
if (use_data_edge) string to_pin_name = sdfPortName(to_pin);
if (use_data_edge) {
gzprintf(stream_, "(%s %s)", gzprintf(stream_, "(%s %s)",
sdfEdge(arc->toEdge()), sdfEdge(arc->toEdge()),
sdfPortName(to_pin)); to_pin_name.c_str());
}
else else
gzprintf(stream_, "%s", sdfPortName(to_pin)); gzprintf(stream_, "%s", to_pin_name.c_str());
if (sdf_cond_start) if (sdf_cond_start)
gzprintf(stream_, ")"); gzprintf(stream_, ")");
@ -666,12 +673,13 @@ SdfWriter::writeCheck(Edge *edge,
if (sdf_cond_end) if (sdf_cond_end)
gzprintf(stream_, "(COND %s ", sdf_cond_end); gzprintf(stream_, "(COND %s ", sdf_cond_end);
string from_pin_name = sdfPortName(from_pin);
if (use_clk_edge) if (use_clk_edge)
gzprintf(stream_, "(%s %s)", gzprintf(stream_, "(%s %s)",
sdfEdge(arc->fromEdge()), sdfEdge(arc->fromEdge()),
sdfPortName(from_pin)); from_pin_name.c_str());
else else
gzprintf(stream_, "%s", sdfPortName(from_pin)); gzprintf(stream_, "%s", from_pin_name.c_str());
if (sdf_cond_end) if (sdf_cond_end)
gzprintf(stream_, ")"); gzprintf(stream_, ")");
@ -691,9 +699,10 @@ SdfWriter::writeWidthCheck(const Pin *pin,
float min_width, float min_width,
float max_width) float max_width)
{ {
string pin_name = sdfPortName(pin);
gzprintf(stream_, " (WIDTH (%s %s) ", gzprintf(stream_, " (WIDTH (%s %s) ",
sdfEdge(hi_low->asTransition()), sdfEdge(hi_low->asTransition()),
sdfPortName(pin)); pin_name.c_str());
writeSdfTriple(min_width, max_width); writeSdfTriple(min_width, max_width);
gzprintf(stream_, ")\n"); gzprintf(stream_, ")\n");
} }
@ -702,8 +711,8 @@ void
SdfWriter::writePeriodCheck(const Pin *pin, SdfWriter::writePeriodCheck(const Pin *pin,
float min_period) float min_period)
{ {
gzprintf(stream_, " (PERIOD %s ", string pin_name = sdfPortName(pin);
sdfPortName(pin)); gzprintf(stream_, " (PERIOD %s ", pin_name.c_str());
writeSdfTriple(min_period, min_period); writeSdfTriple(min_period, min_period);
gzprintf(stream_, ")\n"); gzprintf(stream_, ")\n");
} }
@ -720,81 +729,68 @@ SdfWriter::sdfEdge(const Transition *tr)
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
char * string
SdfWriter::sdfPathName(const Pin *pin) SdfWriter::sdfPathName(const Pin *pin)
{ {
Instance *inst = network_->instance(pin); Instance *inst = network_->instance(pin);
if (network_->isTopInstance(inst)) if (network_->isTopInstance(inst))
return sdfPortName(pin); return sdfPortName(pin);
else { else {
char *inst_path = sdfPathName(inst); string inst_path = sdfPathName(inst);
const char *port_name = sdfPortName(pin); string port_name = sdfPortName(pin);
size_t length = strlen(inst_path) + 1 + strlen(port_name) + 1; string sdf_name = inst_path;
char *sdf_name = makeTmpString(length); sdf_name += sdf_divider_;
snprintf(sdf_name, length, "%s%c%s", inst_path, sdf_divider_, port_name); sdf_name += port_name;
return sdf_name; return sdf_name;
} }
} }
// Based on Network::pathName. // Based on Network::pathName.
char * string
SdfWriter::sdfPathName(const Instance *instance) SdfWriter::sdfPathName(const Instance *instance)
{ {
InstanceSeq inst_path; InstanceSeq inst_path;
network_->path(instance, inst_path); network_->path(instance, inst_path);
size_t name_length = 0;
InstanceSeq::Iterator path_iter1(inst_path); InstanceSeq::Iterator path_iter1(inst_path);
while (path_iter1.hasNext()) { string path_name;
const Instance *inst = path_iter1.next(); while (!inst_path.empty()) {
name_length += strlen(sdfName(inst)) + 1;
}
char *path_name = makeTmpString(name_length);
char *path_ptr = path_name;
// Top instance has null string name, so terminate the string here.
*path_name = '\0';
while (inst_path.size()) {
const Instance *inst = inst_path.back(); const Instance *inst = inst_path.back();
const char *inst_name = sdfName(inst); string inst_name = sdfName(inst);
strcpy(path_ptr, inst_name); path_name += inst_name;
path_ptr += strlen(inst_name);
inst_path.pop_back(); inst_path.pop_back();
if (inst_path.size()) if (!inst_path.empty())
*path_ptr++ = sdf_divider_; path_name += sdf_divider_;
*path_ptr = '\0';
} }
return path_name; return path_name;
} }
// Escape for non-alpha numeric characters. // Escape for non-alpha numeric characters.
char * string
SdfWriter::sdfName(const Instance *inst) SdfWriter::sdfName(const Instance *inst)
{ {
const char *name = network_->name(inst); const char *name = network_->name(inst);
char *sdf_name = makeTmpString(strlen(name) * 2 + 1); string sdf_name;
const char *p = name; const char *p = name;
char *s = sdf_name;
while (*p) { while (*p) {
char ch = *p; char ch = *p;
// Ignore sta escapes. // Ignore sta escapes.
if (ch != network_escape_) { if (ch != network_escape_) {
if (!(isalnum(ch) || ch == '_')) if (!(isalnum(ch) || ch == '_'))
// Insert escape. // Insert escape.
*s++ = sdf_escape_; sdf_name += sdf_escape_;
*s++ = ch; sdf_name += ch;
} }
p++; p++;
} }
*s = '\0';
return sdf_name; return sdf_name;
} }
char * string
SdfWriter::sdfPortName(const Pin *pin) SdfWriter::sdfPortName(const Pin *pin)
{ {
const char *name = network_->portName(pin); const char *name = network_->portName(pin);
size_t name_length = strlen(name); size_t name_length = strlen(name);
char *sdf_name = makeTmpString(name_length * 2 + 1); string sdf_name;
char *s = sdf_name;
constexpr char bus_brkt_left = '['; constexpr char bus_brkt_left = '[';
constexpr char bus_brkt_right = ']'; constexpr char bus_brkt_right = ']';
@ -809,18 +805,17 @@ SdfWriter::sdfPortName(const Pin *pin)
char ch = name[i]; char ch = name[i];
if (ch == network_escape_) { if (ch == network_escape_) {
// Copy escape and escaped char. // Copy escape and escaped char.
*s++ = sdf_escape_; sdf_name += sdf_escape_;
*s++ = name[++i]; sdf_name += name[++i];
} }
else { else {
if (!(isalnum(ch) || ch == '_') if (!(isalnum(ch) || ch == '_')
&& !(i >= bus_index && (ch == bus_brkt_right || ch == bus_brkt_left))) && !(i >= bus_index && (ch == bus_brkt_right || ch == bus_brkt_left)))
// Insert escape. // Insert escape.
*s++ = sdf_escape_; sdf_name += sdf_escape_;
*s++ = ch; sdf_name += ch;
} }
} }
*s = '\0';
return sdf_name; return sdf_name;
} }

View File

@ -113,34 +113,35 @@ ClkInfo::asString(const StaState *sta) const
{ {
Network *network = sta->network(); Network *network = sta->network();
Corners *corners = sta->corners(); Corners *corners = sta->corners();
string str; string result;
PathAnalysisPt *path_ap = corners->findPathAnalysisPt(path_ap_index_); PathAnalysisPt *path_ap = corners->findPathAnalysisPt(path_ap_index_);
str += stringPrintTmp("%s/%d ", result += path_ap->pathMinMax()->asString();
path_ap->pathMinMax()->asString(), result += "/";
path_ap_index_); result += std::to_string(path_ap_index_);
if (clk_edge_) if (clk_edge_)
str += clk_edge_->name(); result += clk_edge_->name();
else else
str += "unclocked"; result += "unclocked";
if (clk_src_) { if (clk_src_) {
str += " clk_src "; result += " clk_src ";
str += network->pathName(clk_src_); result += network->pathName(clk_src_);
} }
if (!crpr_clk_path_.isNull()) { if (!crpr_clk_path_.isNull()) {
const Pin *crpr_clk_pin = crpr_clk_path_.vertex(sta)->pin(); const Pin *crpr_clk_pin = crpr_clk_path_.vertex(sta)->pin();
str += " crpr_pin "; result += " crpr_pin ";
str += network->pathName(crpr_clk_pin); result += network->pathName(crpr_clk_pin);
} }
if (is_gen_clk_src_path_) if (is_gen_clk_src_path_)
str += " genclk"; result += " genclk";
char *result = makeTmpString(str.size() + 1); char *tmp = makeTmpString(result.size() + 1);
strcpy(result, str.c_str()); strcpy(tmp, result.c_str());
return result; return tmp;
} }
const Clock * const Clock *

View File

@ -1028,7 +1028,9 @@ getProperty(Edge *edge,
auto graph = sta->graph(); auto graph = sta->graph();
const char *from = edge->from(graph)->name(network); const char *from = edge->from(graph)->name(network);
const char *to = edge->to(graph)->name(network); const char *to = edge->to(graph)->name(network);
return PropertyValue(stringPrintTmp("%s -> %s", from, to)); string full_name;
stringPrint(full_name, "%s -> %s", from, to);
return PropertyValue(full_name);
} }
if (stringEqual(property, "delay_min_fall")) if (stringEqual(property, "delay_min_fall"))
return edgeDelayProperty(edge, RiseFall::fall(), MinMax::min(), sta); return edgeDelayProperty(edge, RiseFall::fall(), MinMax::min(), sta);

View File

@ -94,83 +94,84 @@ Tag::asString(bool report_index,
{ {
const Network *network = sta->network(); const Network *network = sta->network();
const Corners *corners = sta->corners(); const Corners *corners = sta->corners();
string str; string result;
if (report_index) if (report_index)
str += stringPrintTmp("%4d ", index_); result += std::to_string(index_);
if (report_rf_min_max) { if (report_rf_min_max) {
const RiseFall *rf = transition(); const RiseFall *rf = transition();
PathAnalysisPt *path_ap = corners->findPathAnalysisPt(path_ap_index_); PathAnalysisPt *path_ap = corners->findPathAnalysisPt(path_ap_index_);
str += stringPrintTmp("%s %s/%d ", result += rf->asString();
rf->asString(), result += " ";
path_ap->pathMinMax()->asString(), result += path_ap->pathMinMax()->asString();
path_ap_index_); result += "/";
result += std::to_string(path_ap_index_);
} }
const ClockEdge *clk_edge = clkEdge(); const ClockEdge *clk_edge = clkEdge();
if (clk_edge) if (clk_edge)
str += clk_edge->name(); result += clk_edge->name();
else else
str += "unclocked"; result += "unclocked";
bool is_genclk_src = clk_info_->isGenClkSrcPath(); bool is_genclk_src = clk_info_->isGenClkSrcPath();
if (is_clk_ || is_genclk_src) { if (is_clk_ || is_genclk_src) {
str += " ("; result += " (";
if (is_clk_) { if (is_clk_) {
str += "clock"; result += "clock";
if (clk_info_->isPropagated()) if (clk_info_->isPropagated())
str += " prop"; result += " prop";
else else
str += " ideal"; result += " ideal";
if (is_genclk_src) if (is_genclk_src)
str += " "; result += " ";
} }
if (clk_info_->isGenClkSrcPath()) if (clk_info_->isGenClkSrcPath())
str += "genclk"; result += "genclk";
str += ")"; result += ")";
} }
const Pin *clk_src = clkSrc(); const Pin *clk_src = clkSrc();
if (clk_src) { if (clk_src) {
str += " clk_src "; result += " clk_src ";
str += network->pathName(clk_src); result += network->pathName(clk_src);
} }
const PathVertex crpr_clk_path(clk_info_->crprClkPath(), sta); const PathVertex crpr_clk_path(clk_info_->crprClkPath(), sta);
if (!crpr_clk_path.isNull()) { if (!crpr_clk_path.isNull()) {
str += " crpr_pin "; result += " crpr_pin ";
str += network->pathName(crpr_clk_path.pin(sta)); result += network->pathName(crpr_clk_path.pin(sta));
} }
if (input_delay_) { if (input_delay_) {
str += " input "; result += " input ";
str += network->pathName(input_delay_->pin()); result += network->pathName(input_delay_->pin());
} }
if (is_segment_start_) if (is_segment_start_)
str += " segment_start"; result += " segment_start";
if (states_) { if (states_) {
for (ExceptionState *state : *states_) { for (ExceptionState *state : *states_) {
ExceptionPath *exception = state->exception(); ExceptionPath *exception = state->exception();
str += " "; result += " ";
str += exception->asString(network); result += exception->asString(network);
if (state->nextThru()) { if (state->nextThru()) {
str += " (next thru "; result += " (next thru ";
str += state->nextThru()->asString(network); result += state->nextThru()->asString(network);
str += ")"; result += ")";
} }
else { else {
if (exception->thrus() != nullptr) if (exception->thrus() != nullptr)
str += " (thrus complete)"; result += " (thrus complete)";
} }
} }
} }
char *result = makeTmpString(str.size() + 1); char *tmp = makeTmpString(result.size() + 1);
strcpy(result, str.c_str()); strcpy(tmp, result.c_str());
return result; return tmp;
} }
const RiseFall * const RiseFall *

View File

@ -57,6 +57,18 @@ PatternMatch::PatternMatch(const char *pattern,
compileRegexp(); compileRegexp();
} }
PatternMatch::PatternMatch(string pattern,
const PatternMatch *inherit_from) :
pattern_(pattern.c_str()),
is_regexp_(inherit_from->is_regexp_),
nocase_(inherit_from->nocase_),
interp_(inherit_from->interp_),
regexp_(nullptr)
{
if (is_regexp_)
compileRegexp();
}
void void
PatternMatch::compileRegexp() PatternMatch::compileRegexp()
{ {
@ -89,6 +101,12 @@ PatternMatch::hasWildcards() const
return patternWildcards(pattern_); return patternWildcards(pattern_);
} }
bool
PatternMatch::match(const string &str) const
{
return match(str.c_str());
}
bool bool
PatternMatch::match(const char *str) const PatternMatch::match(const char *str) const
{ {

View File

@ -394,7 +394,7 @@ inst_named_pins:
inst_named_pin: inst_named_pin:
// Scalar port. // Scalar port.
'.' ID '(' ')' '.' ID '(' ')'
{ $$ = sta::verilog_reader->makeNetNamedPortRefScalarNet($2, NULL); } { $$ = sta::verilog_reader->makeNetNamedPortRefScalarNet($2); }
| '.' ID '(' ID ')' | '.' ID '(' ID ')'
{ $$ = sta::verilog_reader->makeNetNamedPortRefScalarNet($2, $4); } { $$ = sta::verilog_reader->makeNetNamedPortRefScalarNet($2, $4); }
| '.' ID '(' ID '[' INT ']' ')' | '.' ID '(' ID '[' INT ']' ')'

View File

@ -36,9 +36,9 @@ namespace sta {
VerilogReader *verilog_reader; VerilogReader *verilog_reader;
static const char *unconnected_net_name = reinterpret_cast<const char*>(1); static const char *unconnected_net_name = reinterpret_cast<const char*>(1);
static const char * static string
verilogBusBitNameTmp(const char *bus_name, verilogBusBitName(const char *bus_name,
int index); int index);
static int static int
hierarchyLevel(Net *net, hierarchyLevel(Net *net,
Network *network); Network *network);
@ -255,17 +255,18 @@ VerilogReader::makeModule(const char *module_vname,
VerilogStmtSeq *stmts, VerilogStmtSeq *stmts,
int line) int line)
{ {
const char *module_name = moduleVerilogToSta(module_vname); string module_name = moduleVerilogToSta(module_vname);
Cell *cell = network_->findCell(library_, module_name); Cell *cell = network_->findCell(library_, module_name.c_str());
if (cell) { if (cell) {
VerilogModule *module = module_map_[cell]; VerilogModule *module = module_map_[cell];
delete module; delete module;
module_map_.erase(cell); module_map_.erase(cell);
network_->deleteCell(cell); network_->deleteCell(cell);
} }
VerilogModule *module = new VerilogModule(module_name, ports, stmts, VerilogModule *module = new VerilogModule(module_name.c_str(),
ports, stmts,
filename_, line, this); filename_, line, this);
cell = network_->makeCell(library_, module_name, false, filename_); cell = network_->makeCell(library_, module_name.c_str(), false, filename_);
module_map_[cell] = module; module_map_[cell] = module;
makeCellPorts(cell, module, ports); makeCellPorts(cell, module, ports);
module_count_++; module_count_++;
@ -300,26 +301,25 @@ VerilogReader::makeCellPorts(Cell *cell,
VerilogModule *module, VerilogModule *module,
VerilogNetSeq *ports) VerilogNetSeq *ports)
{ {
StringSet port_names; set<string> port_names;
for (VerilogNet *mod_port : *ports) { for (VerilogNet *mod_port : *ports) {
const char *port_name = mod_port->name(); const string &port_name = mod_port->name();
if (port_names.findKey(port_name) == nullptr) { if (port_names.find(port_name) == port_names.end()) {
port_names.insert(stringCopy(port_name)); port_names.insert(port_name);
if (mod_port->isNamed()) { if (mod_port->isNamed()) {
if (mod_port->isNamedPortRef()) if (mod_port->isNamedPortRef())
makeNamedPortRefCellPorts(cell, module, mod_port, port_names); makeNamedPortRefCellPorts(cell, module, mod_port, port_names);
else else
makeCellPort(cell, module, mod_port->name()); makeCellPort(cell, module, mod_port->name().c_str());
} }
} }
else else
warn(165, module->filename(), module->line(), warn(165, module->filename(), module->line(),
"module %s repeated port name %s.", "module %s repeated port name %s.",
module->name(), module->name(),
port_name); port_name.c_str());
} }
checkModuleDcls(module, port_names); checkModuleDcls(module, port_names);
deleteContents(&port_names);
} }
Port * Port *
@ -351,25 +351,25 @@ void
VerilogReader::makeNamedPortRefCellPorts(Cell *cell, VerilogReader::makeNamedPortRefCellPorts(Cell *cell,
VerilogModule *module, VerilogModule *module,
VerilogNet *mod_port, VerilogNet *mod_port,
StringSet &port_names) set<string> &port_names)
{ {
PortSeq *member_ports = new PortSeq; PortSeq *member_ports = new PortSeq;
VerilogNetNameIterator *net_name_iter = mod_port->nameIterator(module,this); VerilogNetNameIterator *net_name_iter = mod_port->nameIterator(module,this);
while (net_name_iter->hasNext()) { while (net_name_iter->hasNext()) {
const char *net_name = net_name_iter->next(); const char *net_name = net_name_iter->next();
port_names.insert(stringCopy(net_name)); port_names.insert(net_name);
Port *port = makeCellPort(cell, module, net_name); Port *port = makeCellPort(cell, module, net_name);
member_ports->push_back(port); member_ports->push_back(port);
} }
delete net_name_iter; delete net_name_iter;
// Note that the bundle does NOT have a port declaration. // Note that the bundle does NOT have a port declaration.
network_->makeBundlePort(cell, mod_port->name(), member_ports); network_->makeBundlePort(cell, mod_port->name().c_str(), member_ports);
} }
// Make sure each declaration appears in the module port list. // Make sure each declaration appears in the module port list.
void void
VerilogReader::checkModuleDcls(VerilogModule *module, VerilogReader::checkModuleDcls(VerilogModule *module,
StringSet &port_names) set<string> &port_names)
{ {
VerilogDclMap::ConstIterator dcl_iter(module->declarationMap()); VerilogDclMap::ConstIterator dcl_iter(module->declarationMap());
while (dcl_iter.hasNext()) { while (dcl_iter.hasNext()) {
@ -380,7 +380,7 @@ VerilogReader::checkModuleDcls(VerilogModule *module,
if (dir->isInput() if (dir->isInput()
|| dir->isOutput() || dir->isOutput()
|| dir->isBidirect()) { || dir->isBidirect()) {
if (port_names.findKey(port_name) == nullptr) if (port_names.find(port_name) == port_names.end())
linkWarn(197, module->filename(), module->line(), linkWarn(197, module->filename(), module->line(),
"module %s declared signal %s is not in the port list.", "module %s declared signal %s is not in the port list.",
module->name(), module->name(),
@ -457,10 +457,10 @@ VerilogDclArg *
VerilogReader::makeDclArg(const char *net_vname) VerilogReader::makeDclArg(const char *net_vname)
{ {
dcl_arg_count_++; dcl_arg_count_++;
const char *net_name = netVerilogToSta(net_vname); string net_name = netVerilogToSta(net_vname);
VerilogDclArg *dcl =new VerilogDclArg(net_name); VerilogDclArg *dcl =new VerilogDclArg(net_name.c_str());
stringDelete(net_vname); stringDelete(net_vname);
return dcl; return dcl;
} }
VerilogDclArg * VerilogDclArg *
@ -478,8 +478,9 @@ VerilogReader::makeNetPartSelect(const char *net_vname,
net_part_select_count_++; net_part_select_count_++;
if (report_stmt_stats_) if (report_stmt_stats_)
net_bus_names_ += strlen(net_vname) + 1; net_bus_names_ += strlen(net_vname) + 1;
const char *net_name = netVerilogToSta(net_vname); string net_name = netVerilogToSta(net_vname);
VerilogNetPartSelect *select = new VerilogNetPartSelect(net_name, from_index, VerilogNetPartSelect *select = new VerilogNetPartSelect(net_name.c_str(),
from_index,
to_index); to_index);
stringDelete(net_vname); stringDelete(net_vname);
return select; return select;
@ -498,8 +499,8 @@ VerilogReader::makeNetScalar(const char *net_vname)
net_scalar_count_++; net_scalar_count_++;
if (report_stmt_stats_) if (report_stmt_stats_)
net_scalar_names_ += strlen(net_vname) + 1; net_scalar_names_ += strlen(net_vname) + 1;
const char *net_name = netVerilogToSta(net_vname); string net_name = netVerilogToSta(net_vname);
VerilogNetScalar *scalar = new VerilogNetScalar(net_name); VerilogNetScalar *scalar = new VerilogNetScalar(net_name.c_str());
stringDelete(net_vname); stringDelete(net_vname);
return scalar; return scalar;
} }
@ -511,8 +512,8 @@ VerilogReader::makeNetBitSelect(const char *net_vname,
net_bit_select_count_++; net_bit_select_count_++;
if (report_stmt_stats_) if (report_stmt_stats_)
net_bus_names_ += strlen(net_vname) + 1; net_bus_names_ += strlen(net_vname) + 1;
const char *net_name = netVerilogToSta(net_vname); string net_name = netVerilogToSta(net_vname);
VerilogNetBitSelect *select = new VerilogNetBitSelect(net_name, index); VerilogNetBitSelect *select = new VerilogNetBitSelect(net_name.c_str(), index);
stringDelete(net_vname); stringDelete(net_vname);
return select; return select;
} }
@ -532,9 +533,9 @@ VerilogReader::makeModuleInst(const char *module_vname,
VerilogNetSeq *pins, VerilogNetSeq *pins,
const int line) const int line)
{ {
const char *module_name = moduleVerilogToSta(module_vname); string module_name = moduleVerilogToSta(module_vname);
const char *inst_name = instanceVerilogToSta(inst_vname); string inst_name = instanceVerilogToSta(inst_vname);
Cell *cell = network_->findAnyCell(module_name); Cell *cell = network_->findAnyCell(module_name.c_str());
LibertyCell *liberty_cell = nullptr; LibertyCell *liberty_cell = nullptr;
if (cell) if (cell)
liberty_cell = network_->libertyCell(cell); liberty_cell = network_->libertyCell(cell);
@ -549,7 +550,7 @@ VerilogReader::makeModuleInst(const char *module_vname,
for (VerilogNet *vnet : *pins) { for (VerilogNet *vnet : *pins) {
VerilogNetPortRefScalarNet *vpin = VerilogNetPortRefScalarNet *vpin =
dynamic_cast<VerilogNetPortRefScalarNet*>(vnet); dynamic_cast<VerilogNetPortRefScalarNet*>(vnet);
const char *port_name = vpin->name(); const char *port_name = vpin->name().c_str();
const char *net_name = vpin->netName(); const char *net_name = vpin->netName();
// Steal the net name string. // Steal the net name string.
vpin->setNetName(nullptr); vpin->setNetName(nullptr);
@ -569,11 +570,11 @@ VerilogReader::makeModuleInst(const char *module_vname,
delete vpin; delete vpin;
net_port_ref_scalar_net_count_--; net_port_ref_scalar_net_count_--;
} }
VerilogInst *inst = new VerilogLibertyInst(liberty_cell, inst_name, VerilogInst *inst = new VerilogLibertyInst(liberty_cell, inst_name.c_str(),
net_names, line); net_names, line);
delete pins; delete pins;
if (report_stmt_stats_) { if (report_stmt_stats_) {
inst_names_ += strlen(inst_name) + 1; inst_names_ += inst_name.size() + 1;
inst_lib_count_++; inst_lib_count_++;
inst_lib_net_arrays_ += port_count; inst_lib_net_arrays_ += port_count;
} }
@ -582,10 +583,12 @@ VerilogReader::makeModuleInst(const char *module_vname,
return inst; return inst;
} }
else { else {
VerilogInst *inst = new VerilogModuleInst(module_name, inst_name, pins, line); VerilogInst *inst = new VerilogModuleInst(module_name.c_str(),
inst_name.c_str(),
pins, line);
if (report_stmt_stats_) { if (report_stmt_stats_) {
inst_module_names_ += strlen(module_name) + 1; inst_module_names_ += module_name.size() + 1;
inst_names_ += strlen(inst_name) + 1; inst_names_ += inst_name.size() + 1;
inst_mod_count_++; inst_mod_count_++;
} }
stringDelete(module_vname); stringDelete(module_vname);
@ -602,7 +605,7 @@ VerilogReader::hasScalarNamedPortRefs(LibertyCell *liberty_cell,
&& pins->size() > 0 && pins->size() > 0
&& (*pins)[0]->isNamedPortRef()) { && (*pins)[0]->isNamedPortRef()) {
for (VerilogNet *vpin : *pins) { for (VerilogNet *vpin : *pins) {
const char *port_name = vpin->name(); const char *port_name = vpin->name().c_str();
LibertyPort *port = liberty_cell->findLibertyPort(port_name); LibertyPort *port = liberty_cell->findLibertyPort(port_name);
if (port) { if (port) {
if (!(port->size() == 1 if (!(port->size() == 1
@ -618,6 +621,18 @@ VerilogReader::hasScalarNamedPortRefs(LibertyCell *liberty_cell,
return false; return false;
} }
VerilogNetPortRef *
VerilogReader::makeNetNamedPortRefScalarNet(const char *port_vname)
{
net_port_ref_scalar_net_count_++;
if (report_stmt_stats_)
port_names_ += strlen(port_vname) + 1;
string port_name = portVerilogToSta(port_vname);
VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name.c_str());
stringDelete(port_vname);
return ref;
}
VerilogNetPortRef * VerilogNetPortRef *
VerilogReader::makeNetNamedPortRefScalarNet(const char *port_vname, VerilogReader::makeNetNamedPortRefScalarNet(const char *port_vname,
const char *net_vname) const char *net_vname)
@ -628,9 +643,10 @@ VerilogReader::makeNetNamedPortRefScalarNet(const char *port_vname,
net_scalar_names_ += strlen(net_vname) + 1; net_scalar_names_ += strlen(net_vname) + 1;
port_names_ += strlen(port_vname) + 1; port_names_ += strlen(port_vname) + 1;
} }
const char *port_name = portVerilogToSta(port_vname); string port_name = portVerilogToSta(port_vname);
const char *net_name = netVerilogToSta(net_vname); string net_name = netVerilogToSta(net_vname);
VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name, net_name); VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name.c_str(),
net_name.c_str());
stringDelete(port_vname); stringDelete(port_vname);
stringDelete(net_vname); stringDelete(net_vname);
return ref; return ref;
@ -642,14 +658,15 @@ VerilogReader::makeNetNamedPortRefBitSelect(const char *port_vname,
int index) int index)
{ {
net_port_ref_scalar_net_count_++; net_port_ref_scalar_net_count_++;
const char *bus_name = portVerilogToSta(bus_vname); string bus_name = portVerilogToSta(bus_vname);
const char *net_name = verilogBusBitNameTmp(bus_name, index); string net_name = verilogBusBitName(bus_name.c_str(), index);
if (report_stmt_stats_) { if (report_stmt_stats_) {
net_scalar_names_ += strlen(net_name) + 1; net_scalar_names_ += net_name.length() + 1;
port_names_ += strlen(port_vname) + 1; port_names_ += strlen(port_vname) + 1;
} }
const char *port_name = portVerilogToSta(port_vname); string port_name = portVerilogToSta(port_vname);
VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name, net_name); VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name.c_str(),
net_name.c_str());
stringDelete(port_vname); stringDelete(port_vname);
stringDelete(bus_vname); stringDelete(bus_vname);
return ref; return ref;
@ -662,8 +679,8 @@ VerilogReader::makeNetNamedPortRefScalar(const char *port_vname,
net_port_ref_scalar_count_++; net_port_ref_scalar_count_++;
if (report_stmt_stats_) if (report_stmt_stats_)
port_names_ += strlen(port_vname) + 1; port_names_ += strlen(port_vname) + 1;
const char *port_name = portVerilogToSta(port_vname); string port_name = portVerilogToSta(port_vname);
VerilogNetPortRef *ref = new VerilogNetPortRefScalar(port_name, net); VerilogNetPortRef *ref = new VerilogNetPortRefScalar(port_name.c_str(), net);
stringDelete(port_vname); stringDelete(port_vname);
return ref; return ref;
} }
@ -674,8 +691,9 @@ VerilogReader::makeNetNamedPortRefBit(const char *port_vname,
VerilogNet *net) VerilogNet *net)
{ {
net_port_ref_bit_count_++; net_port_ref_bit_count_++;
const char *port_name = portVerilogToSta(port_vname); string port_name = portVerilogToSta(port_vname);
VerilogNetPortRef *ref = new VerilogNetPortRefBit(port_name, index, net); VerilogNetPortRef *ref = new VerilogNetPortRefBit(port_name.c_str(),
index, net);
stringDelete(port_vname); stringDelete(port_vname);
return ref; return ref;
} }
@ -687,8 +705,9 @@ VerilogReader::makeNetNamedPortRefPart(const char *port_vname,
VerilogNet *net) VerilogNet *net)
{ {
net_port_ref_part_count_++; net_port_ref_part_count_++;
const char *port_name = portVerilogToSta(port_vname); string port_name = portVerilogToSta(port_vname);
VerilogNetPortRef *ref = new VerilogNetPortRefPart(port_name, from_index, VerilogNetPortRef *ref = new VerilogNetPortRefPart(port_name.c_str(),
from_index,
to_index, net); to_index, net);
stringDelete(port_vname); stringDelete(port_vname);
return ref; return ref;
@ -776,20 +795,20 @@ VerilogReader::warn(int id,
va_end(args); va_end(args);
} }
const char * string
VerilogReader::verilogName(VerilogModuleInst *mod_inst) VerilogReader::verilogName(VerilogModuleInst *mod_inst)
{ {
return sta::instanceVerilogName(mod_inst->instanceName(), return sta::instanceVerilogName(mod_inst->instanceName(),
network_->pathEscape()); network_->pathEscape());
} }
const char * string
VerilogReader::instanceVerilogName(const char *inst_name) VerilogReader::instanceVerilogName(const char *inst_name)
{ {
return sta::netVerilogName(inst_name, network_->pathEscape()); return sta::netVerilogName(inst_name, network_->pathEscape());
} }
const char * string
VerilogReader::netVerilogName(const char *net_name) VerilogReader::netVerilogName(const char *net_name)
{ {
return sta::netVerilogName(net_name, network_->pathEscape()); return sta::netVerilogName(net_name, network_->pathEscape());
@ -862,11 +881,13 @@ VerilogModule::parseDcl(VerilogDcl *dcl,
// supply0/supply1 dcl can be used as modifier for // supply0/supply1 dcl can be used as modifier for
// input/output/inout dcls. // input/output/inout dcls.
dcl_map_[net_name] = dcl; dcl_map_[net_name] = dcl;
else if (!dcl->direction()->isInternal()) else if (!dcl->direction()->isInternal()) {
string net_vname = reader->netVerilogName(net_name);
reader->warn(18, filename_, dcl->line(), reader->warn(18, filename_, dcl->line(),
"signal %s previously declared on line %d.", "signal %s previously declared on line %d.",
reader->netVerilogName(net_name), net_vname.c_str(),
existing_dcl->line()); existing_dcl->line());
}
} }
else else
dcl_map_[net_name] = dcl; dcl_map_[net_name] = dcl;
@ -890,9 +911,10 @@ VerilogModule::checkInstanceName(VerilogInst *inst,
stringDelete(replacement_name); stringDelete(replacement_name);
replacement_name = stringPrint("%s_%d", inst_name, i); replacement_name = stringPrint("%s_%d", inst_name, i);
} while (inst_names.findKey(replacement_name)); } while (inst_names.findKey(replacement_name));
string inst_vname = reader->instanceVerilogName(inst_name);
reader->warn(19, filename_, inst->line(), reader->warn(19, filename_, inst->line(),
"instance name %s duplicated - renamed to %s.", "instance name %s duplicated - renamed to %s.",
reader->instanceVerilogName(inst_name), inst_vname.c_str(),
replacement_name); replacement_name);
inst_name = replacement_name; inst_name = replacement_name;
inst->setInstanceName(inst_name); inst->setInstanceName(inst_name);
@ -1078,7 +1100,7 @@ VerilogDclArg::netName()
if (net_name_) if (net_name_)
return net_name_; return net_name_;
else if (assign_) else if (assign_)
return assign_->lhs()->name(); return assign_->lhs()->name().c_str();
else else
return nullptr; return nullptr;
} }
@ -1112,6 +1134,7 @@ class VerilogOneNetNameIterator : public VerilogNetNameIterator
{ {
public: public:
explicit VerilogOneNetNameIterator(const char *name); explicit VerilogOneNetNameIterator(const char *name);
explicit VerilogOneNetNameIterator(string name);
virtual bool hasNext(); virtual bool hasNext();
virtual const char *next(); virtual const char *next();
@ -1152,6 +1175,7 @@ protected:
int from_index_; int from_index_;
int to_index_; int to_index_;
int index_; int index_;
string bit_name_;
}; };
VerilogBusNetNameIterator::VerilogBusNetNameIterator(const char *bus_name, VerilogBusNetNameIterator::VerilogBusNetNameIterator(const char *bus_name,
@ -1176,19 +1200,21 @@ VerilogBusNetNameIterator::hasNext()
const char * const char *
VerilogBusNetNameIterator::next() VerilogBusNetNameIterator::next()
{ {
const char *bit_name = verilogBusBitNameTmp(bus_name_, index_); bit_name_ = verilogBusBitName(bus_name_, index_);
if (to_index_ > from_index_) if (to_index_ > from_index_)
index_++; index_++;
else else
index_--; index_--;
return bit_name; return bit_name_.c_str();
} }
static const char * static string
verilogBusBitNameTmp(const char *bus_name, verilogBusBitName(const char *bus_name,
int index) int index)
{ {
return stringPrintTmp("%s[%d]", bus_name, index); string bus_bit_name;
stringPrint(bus_bit_name, "%s[%d]", bus_name, index);
return bus_bit_name;
} }
class VerilogConstantNetNameIterator : public VerilogNetNameIterator class VerilogConstantNetNameIterator : public VerilogNetNameIterator
@ -1291,21 +1317,27 @@ VerilogNetConcatNameIterator::next()
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
const string VerilogNetUnnamed::null_;
VerilogNetNamed::VerilogNetNamed(const char *name) : VerilogNetNamed::VerilogNetNamed(const char *name) :
VerilogNet(), VerilogNet(),
name_(stringCopy(name)) name_(name)
{
}
VerilogNetNamed::VerilogNetNamed(const string &name) :
VerilogNet(),
name_(name)
{ {
} }
VerilogNetNamed::~VerilogNetNamed() VerilogNetNamed::~VerilogNetNamed()
{ {
stringDelete(name_);
} }
void void
VerilogNetNamed::setName(const char *name) VerilogNetNamed::setName(const char *name)
{ {
stringDelete(name_);
name_ = name; name_ = name;
} }
@ -1329,7 +1361,7 @@ verilogNetScalarSize(const char *name,
int int
VerilogNetScalar::size(VerilogModule *module) VerilogNetScalar::size(VerilogModule *module)
{ {
return verilogNetScalarSize(name_, module); return verilogNetScalarSize(name_.c_str(), module);
} }
static VerilogNetNameIterator * static VerilogNetNameIterator *
@ -1354,22 +1386,16 @@ VerilogNetNameIterator *
VerilogNetScalar::nameIterator(VerilogModule *module, VerilogNetScalar::nameIterator(VerilogModule *module,
VerilogReader *) VerilogReader *)
{ {
return verilogNetScalarNameIterator(name_, module); return verilogNetScalarNameIterator(name_.c_str(), module);
} }
VerilogNetBitSelect::VerilogNetBitSelect(const char *name, VerilogNetBitSelect::VerilogNetBitSelect(const char *name,
int index) : int index) :
VerilogNetNamed(name), VerilogNetNamed(verilogBusBitName(name, index)),
index_(index) index_(index)
{ {
} }
const char *
VerilogNetBitSelect::name()
{
return verilogBusBitNameTmp(name_, index_);
}
int int
VerilogNetBitSelect::size(VerilogModule *) VerilogNetBitSelect::size(VerilogModule *)
{ {
@ -1380,7 +1406,7 @@ VerilogNetNameIterator *
VerilogNetBitSelect::nameIterator(VerilogModule *, VerilogNetBitSelect::nameIterator(VerilogModule *,
VerilogReader *) VerilogReader *)
{ {
return new VerilogOneNetNameIterator(verilogBusBitNameTmp(name_, index_)); return new VerilogOneNetNameIterator(name_.c_str());
} }
VerilogNetPartSelect::VerilogNetPartSelect(const char *name, VerilogNetPartSelect::VerilogNetPartSelect(const char *name,
@ -1405,7 +1431,7 @@ VerilogNetNameIterator *
VerilogNetPartSelect::nameIterator(VerilogModule *, VerilogNetPartSelect::nameIterator(VerilogModule *,
VerilogReader *) VerilogReader *)
{ {
return new VerilogBusNetNameIterator(name_, from_index_, to_index_); return new VerilogBusNetNameIterator(name_.c_str(), from_index_, to_index_);
} }
VerilogNetConstant::VerilogNetConstant(const char *constant, VerilogNetConstant::VerilogNetConstant(const char *constant,
@ -1583,6 +1609,12 @@ VerilogNetPortRef::VerilogNetPortRef(const char *name) :
{ {
} }
VerilogNetPortRefScalarNet::VerilogNetPortRefScalarNet(const char *name) :
VerilogNetPortRef(name),
net_name_(nullptr)
{
}
VerilogNetPortRefScalarNet::VerilogNetPortRefScalarNet(const char *name, VerilogNetPortRefScalarNet::VerilogNetPortRefScalarNet(const char *name,
const char *net_name) : const char *net_name) :
VerilogNetPortRef(name), VerilogNetPortRef(name),
@ -1651,16 +1683,10 @@ VerilogNetPortRefBit::VerilogNetPortRefBit(const char *name,
int index, int index,
VerilogNet *net) : VerilogNet *net) :
VerilogNetPortRefScalar(name, net), VerilogNetPortRefScalar(name, net),
index_(index) bit_name_(verilogBusBitName(name, index))
{ {
} }
const char *
VerilogNetPortRefBit::name()
{
return verilogBusBitNameTmp(name_, index_);
}
VerilogNetPortRefPart::VerilogNetPortRefPart(const char *name, VerilogNetPortRefPart::VerilogNetPortRefPart(const char *name,
int from_index, int from_index,
int to_index, int to_index,
@ -1670,8 +1696,8 @@ VerilogNetPortRefPart::VerilogNetPortRefPart(const char *name,
{ {
} }
const char * const string &
VerilogNetPortRefPart::name() VerilogNetPortRefPart::name() const
{ {
return name_; return name_;
} }
@ -1813,18 +1839,19 @@ VerilogReader::makeModuleInstNetwork(VerilogModuleInst *mod_inst,
const char *module_name = mod_inst->moduleName(); const char *module_name = mod_inst->moduleName();
Cell *cell = network_->findAnyCell(module_name); Cell *cell = network_->findAnyCell(module_name);
if (cell == nullptr) { if (cell == nullptr) {
string inst_vname = verilogName(mod_inst);
if (make_black_boxes) { if (make_black_boxes) {
cell = makeBlackBox(mod_inst, parent_module); cell = makeBlackBox(mod_inst, parent_module);
linkWarn(198, parent_module->filename(), mod_inst->line(), linkWarn(198, parent_module->filename(), mod_inst->line(),
"module %s not found. Creating black box for %s.", "module %s not found. Creating black box for %s.",
mod_inst->moduleName(), mod_inst->moduleName(),
verilogName(mod_inst)); inst_vname.c_str());
} }
else else
linkError(199, parent_module->filename(), mod_inst->line(), linkError(199, parent_module->filename(), mod_inst->line(),
"module %s not found for instance %s.", "module %s not found for instance %s.",
mod_inst->moduleName(), mod_inst->moduleName(),
verilogName(mod_inst)); inst_vname.c_str());
} }
if (cell) { if (cell) {
LibertyCell *lib_cell = network_->libertyCell(cell); LibertyCell *lib_cell = network_->libertyCell(cell);
@ -1868,20 +1895,22 @@ VerilogReader::makeNamedInstPins(Cell *cell,
VerilogBindingTbl *parent_bindings, VerilogBindingTbl *parent_bindings,
bool is_leaf) bool is_leaf)
{ {
string inst_vname = verilogName(mod_inst);
VerilogNetSeq::Iterator pin_iter(mod_inst->pins()); VerilogNetSeq::Iterator pin_iter(mod_inst->pins());
while (pin_iter.hasNext()) { while (pin_iter.hasNext()) {
VerilogNetPortRef *vpin = dynamic_cast<VerilogNetPortRef*>(pin_iter.next()); VerilogNetPortRef *vpin = dynamic_cast<VerilogNetPortRef*>(pin_iter.next());
const char *port_name = vpin->name(); const char *port_name = vpin->name().c_str();
Port *port = network_->findPort(cell, port_name); Port *port = network_->findPort(cell, port_name);
if (port) { if (port) {
if (vpin->hasNet() if (vpin->hasNet()
&& network_->size(port) != vpin->size(parent_module)) && network_->size(port) != vpin->size(parent_module)) {
linkWarn(200, parent_module->filename(), mod_inst->line(), linkWarn(200, parent_module->filename(), mod_inst->line(),
"instance %s port %s size %d does not match net size %d.", "instance %s port %s size %d does not match net size %d.",
verilogName(mod_inst), inst_vname.c_str(),
network_->name(port), network_->name(port),
network_->size(port), network_->size(port),
vpin->size(parent_module)); vpin->size(parent_module));
}
else { else {
VerilogNetNameIterator *net_name_iter = VerilogNetNameIterator *net_name_iter =
vpin->nameIterator(parent_module, this); vpin->nameIterator(parent_module, this);
@ -1907,11 +1936,12 @@ VerilogReader::makeNamedInstPins(Cell *cell,
if (lib_cell) if (lib_cell)
pg_port = lib_cell->findPgPort(port_name); pg_port = lib_cell->findPgPort(port_name);
// Do not warn about connections to pg ports (which are ignored). // Do not warn about connections to pg ports (which are ignored).
if (pg_port == nullptr) if (pg_port == nullptr) {
linkWarn(201, parent_module->filename(), mod_inst->line(), linkWarn(201, parent_module->filename(), mod_inst->line(),
"instance %s port %s not found.", "instance %s port %s not found.",
verilogName(mod_inst), inst_vname.c_str(),
port_name); port_name);
}
} }
} }
} }
@ -1931,13 +1961,15 @@ VerilogReader::makeOrderedInstPins(Cell *cell,
while (pin_iter.hasNext() && port_iter->hasNext()) { while (pin_iter.hasNext() && port_iter->hasNext()) {
VerilogNet *net = pin_iter.next(); VerilogNet *net = pin_iter.next();
Port *port = port_iter->next(); Port *port = port_iter->next();
if (network_->size(port) != net->size(parent_module)) if (network_->size(port) != net->size(parent_module)) {
string inst_vname = verilogName(mod_inst);
linkWarn(202, parent_module->filename(), mod_inst->line(), linkWarn(202, parent_module->filename(), mod_inst->line(),
"instance %s port %s size %d does not match net size %d.", "instance %s port %s size %d does not match net size %d.",
verilogName(mod_inst), inst_vname.c_str(),
network_->name(port), network_->name(port),
network_->size(port), network_->size(port),
net->size(parent_module)); net->size(parent_module));
}
else { else {
VerilogNetNameIterator *net_name_iter=net->nameIterator(parent_module, VerilogNetNameIterator *net_name_iter=net->nameIterator(parent_module,
this); this);
@ -2027,9 +2059,8 @@ VerilogReader::makeLibertyInst(VerilogLibertyInst *lib_inst,
if (dcl && dcl->isBus()) { if (dcl && dcl->isBus()) {
VerilogDclBus *dcl_bus = dynamic_cast<VerilogDclBus *>(dcl); VerilogDclBus *dcl_bus = dynamic_cast<VerilogDclBus *>(dcl);
// Bus is only 1 bit wide. // Bus is only 1 bit wide.
const char *bus_name = verilogBusBitNameTmp(net_name, string bus_name = verilogBusBitName(net_name, dcl_bus->fromIndex());
dcl_bus->fromIndex()); net = parent_bindings->ensureNetBinding(bus_name.c_str(), parent, network_);
net = parent_bindings->ensureNetBinding(bus_name, parent, network_);
} }
else else
net = parent_bindings->ensureNetBinding(net_name, parent, network_); net = parent_bindings->ensureNetBinding(net_name, parent, network_);
@ -2066,7 +2097,7 @@ VerilogReader::makeBlackBoxNamedPorts(Cell *cell,
VerilogNetSeq::Iterator pin_iter(mod_inst->pins()); VerilogNetSeq::Iterator pin_iter(mod_inst->pins());
while (pin_iter.hasNext()) { while (pin_iter.hasNext()) {
VerilogNetNamed *vpin = dynamic_cast<VerilogNetNamed*>(pin_iter.next()); VerilogNetNamed *vpin = dynamic_cast<VerilogNetNamed*>(pin_iter.next());
const char *port_name = vpin->name(); const char *port_name = vpin->name().c_str();
size_t size = vpin->size(parent_module); size_t size = vpin->size(parent_module);
Port *port = (size == 1) Port *port = (size == 1)
? network_->makePort(cell, port_name) ? network_->makePort(cell, port_name)

View File

@ -32,6 +32,9 @@ VerilogParse_error(const char *msg);
namespace sta { namespace sta {
using std::string;
using std::set;
class Debug; class Debug;
class Report; class Report;
class VerilogReader; class VerilogReader;
@ -117,6 +120,7 @@ public:
VerilogNet *rhs, VerilogNet *rhs,
int line); int line);
VerilogNetScalar *makeNetScalar(const char *name); VerilogNetScalar *makeNetScalar(const char *name);
VerilogNetPortRef *makeNetNamedPortRefScalarNet(const char *port_vname);
VerilogNetPortRef *makeNetNamedPortRefScalarNet(const char *port_name, VerilogNetPortRef *makeNetNamedPortRefScalarNet(const char *port_name,
const char *net_name); const char *net_name);
VerilogNetPortRef *makeNetNamedPortRefBitSelect(const char *port_name, VerilogNetPortRef *makeNetNamedPortRefBitSelect(const char *port_name,
@ -160,11 +164,11 @@ public:
void reportStmtCounts(); void reportStmtCounts();
const char *constant10Max() const { return constant10_max_; } const char *constant10Max() const { return constant10_max_; }
size_t constant10MaxLength() const { return constant10_max_length_; } size_t constant10MaxLength() const { return constant10_max_length_; }
const char * string
verilogName(VerilogModuleInst *inst); verilogName(VerilogModuleInst *inst);
const char * string
instanceVerilogName(const char *inst_name); instanceVerilogName(const char *inst_name);
const char * string
netVerilogName(const char *net_name); netVerilogName(const char *net_name);
protected: protected:
@ -178,9 +182,9 @@ protected:
void makeNamedPortRefCellPorts(Cell *cell, void makeNamedPortRefCellPorts(Cell *cell,
VerilogModule *module, VerilogModule *module,
VerilogNet *mod_port, VerilogNet *mod_port,
StringSet &port_names); set<string> &port_names);
void checkModuleDcls(VerilogModule *module, void checkModuleDcls(VerilogModule *module,
StringSet &port_names); set<string> &port_names);
void makeModuleInstBody(VerilogModule *module, void makeModuleInstBody(VerilogModule *module,
Instance *inst, Instance *inst,
VerilogBindingTbl *bindings, VerilogBindingTbl *bindings,
@ -488,8 +492,8 @@ class VerilogNet
public: public:
VerilogNet() {} VerilogNet() {}
virtual ~VerilogNet() {} virtual ~VerilogNet() {}
virtual bool isNamed() = 0; virtual bool isNamed() const = 0;
virtual const char *name() = 0; virtual const string &name() const = 0;
virtual bool isNamedPortRef() { return false; } virtual bool isNamedPortRef() { return false; }
virtual bool isNamedPortRefScalarNet() const { return false; } virtual bool isNamedPortRefScalarNet() const { return false; }
virtual int size(VerilogModule *module) = 0; virtual int size(VerilogModule *module) = 0;
@ -503,23 +507,27 @@ class VerilogNetUnnamed : public VerilogNet
{ {
public: public:
VerilogNetUnnamed() {} VerilogNetUnnamed() {}
virtual bool isNamed() { return false; } bool isNamed() const override { return false; }
virtual const char *name() { return nullptr; } const string &name() const override { return null_; }
private:
static const string null_;
}; };
class VerilogNetNamed : public VerilogNet class VerilogNetNamed : public VerilogNet
{ {
public: public:
explicit VerilogNetNamed(const char *name); explicit VerilogNetNamed(const char *name);
explicit VerilogNetNamed(const string &name);
virtual ~VerilogNetNamed(); virtual ~VerilogNetNamed();
virtual bool isNamed() { return true; } bool isNamed() const override { return true; }
virtual bool isScalar() const = 0; virtual bool isScalar() const = 0;
virtual const char *name() { return name_; } const string &name() const override { return name_; }
const char *baseName() { return name_; } const string baseName() const { return name_; }
void setName(const char *name); void setName(const char *name);
protected: protected:
const char *name_; string name_;
}; };
// Named net reference, which could be the name of a scalar or bus signal. // Named net reference, which could be the name of a scalar or bus signal.
@ -538,7 +546,6 @@ class VerilogNetBitSelect : public VerilogNetNamed
public: public:
VerilogNetBitSelect(const char *name, VerilogNetBitSelect(const char *name,
int index); int index);
virtual const char *name();
int index() { return index_; } int index() { return index_; }
virtual bool isScalar() const { return false; } virtual bool isScalar() const { return false; }
virtual int size(VerilogModule *module); virtual int size(VerilogModule *module);
@ -620,6 +627,7 @@ public:
class VerilogNetPortRefScalarNet : public VerilogNetPortRef class VerilogNetPortRefScalarNet : public VerilogNetPortRef
{ {
public: public:
VerilogNetPortRefScalarNet(const char *name);
VerilogNetPortRefScalarNet(const char *name, VerilogNetPortRefScalarNet(const char *name,
const char *net_name); const char *net_name);
virtual ~VerilogNetPortRefScalarNet(); virtual ~VerilogNetPortRefScalarNet();
@ -658,10 +666,10 @@ public:
VerilogNetPortRefBit(const char *name, VerilogNetPortRefBit(const char *name,
int index, int index,
VerilogNet *net); VerilogNet *net);
virtual const char *name(); const string &name() const override { return bit_name_; }
private: private:
int index_; string bit_name_;
}; };
class VerilogNetPortRefPart : public VerilogNetPortRefBit class VerilogNetPortRefPart : public VerilogNetPortRefBit
@ -671,7 +679,7 @@ public:
int from_index, int from_index,
int to_index, int to_index,
VerilogNet *net); VerilogNet *net);
virtual const char *name(); const string &name() const override;
int toIndex() const { return to_index_; } int toIndex() const { return to_index_; }
private: private:

View File

@ -159,8 +159,9 @@ VerilogWriter::writePorts(Cell *cell)
|| !network_->direction(port)->isPowerGround()) { || !network_->direction(port)->isPowerGround()) {
if (!first) if (!first)
fprintf(stream_, ",\n "); fprintf(stream_, ",\n ");
fprintf(stream_, "%s", portVerilogName(network_->name(port), string verillg_name = portVerilogName(network_->name(port),
network_->pathEscape())); network_->pathEscape());
fprintf(stream_, "%s", verillg_name.c_str());
first = false; first = false;
} }
} }
@ -177,8 +178,8 @@ VerilogWriter::writePortDcls(Cell *cell)
PortDirection *dir = network_->direction(port); PortDirection *dir = network_->direction(port);
if (include_pwr_gnd_ if (include_pwr_gnd_
|| !network_->direction(port)->isPowerGround()) { || !network_->direction(port)->isPowerGround()) {
const char *port_name = portVerilogName(network_->name(port), string port_vname = portVerilogName(network_->name(port),
network_->pathEscape()); network_->pathEscape());
const char *vtype = verilogPortDir(dir); const char *vtype = verilogPortDir(dir);
if (vtype) { if (vtype) {
fprintf(stream_, " %s", vtype); fprintf(stream_, " %s", vtype);
@ -186,14 +187,14 @@ VerilogWriter::writePortDcls(Cell *cell)
fprintf(stream_, " [%d:%d]", fprintf(stream_, " [%d:%d]",
network_->fromIndex(port), network_->fromIndex(port),
network_->toIndex(port)); network_->toIndex(port));
fprintf(stream_, " %s;\n", port_name); fprintf(stream_, " %s;\n", port_vname.c_str());
if (dir->isTristate()) { if (dir->isTristate()) {
fprintf(stream_, " tri"); fprintf(stream_, " tri");
if (network_->isBus(port)) if (network_->isBus(port))
fprintf(stream_, " [%d:%d]", fprintf(stream_, " [%d:%d]",
network_->fromIndex(port), network_->fromIndex(port),
network_->toIndex(port)); network_->toIndex(port));
fprintf(stream_, " %s;\n", port_name); fprintf(stream_, " %s;\n", port_vname.c_str());
} }
} }
} }
@ -238,16 +239,18 @@ VerilogWriter::writeWireDcls(Instance *inst)
const char *net_name = network_->name(net); const char *net_name = network_->name(net);
if (network_->findPort(cell, net_name) == nullptr) { if (network_->findPort(cell, net_name) == nullptr) {
if (isBusName(net_name, '[', ']', escape)) { if (isBusName(net_name, '[', ']', escape)) {
char *bus_name; bool is_bus;
string bus_name;
int index; int index;
parseBusName(net_name, '[', ']', escape, bus_name, index); parseBusName(net_name, '[', ']', escape, is_bus, bus_name, index);
BusIndexRange &range = bus_ranges[bus_name]; BusIndexRange &range = bus_ranges[bus_name.c_str()];
range.first = max(range.first, index); range.first = max(range.first, index);
range.second = min(range.second, index); range.second = min(range.second, index);
} }
else else {
fprintf(stream_, " wire %s;\n", string net_vname = netVerilogName(net_name, network_->pathEscape());
netVerilogName(net_name, network_->pathEscape()));; fprintf(stream_, " wire %s;\n", net_vname.c_str());;
}
} }
} }
delete net_iter; delete net_iter;
@ -255,10 +258,11 @@ VerilogWriter::writeWireDcls(Instance *inst)
for (auto name_range : bus_ranges) { for (auto name_range : bus_ranges) {
const char *bus_name = name_range.first; const char *bus_name = name_range.first;
const BusIndexRange &range = name_range.second; const BusIndexRange &range = name_range.second;
string net_vname = netVerilogName(bus_name, network_->pathEscape());
fprintf(stream_, " wire [%d:%d] %s;\n", fprintf(stream_, " wire [%d:%d] %s;\n",
range.first, range.first,
range.second, range.second,
netVerilogName(bus_name, network_->pathEscape()));; net_vname.c_str());;
} }
// Wire net dcls for writeInstBusPinBit. // Wire net dcls for writeInstBusPinBit.
@ -297,11 +301,10 @@ VerilogWriter::writeChild(Instance *child)
Cell *child_cell = network_->cell(child); Cell *child_cell = network_->cell(child);
if (!remove_cells_.hasKey(child_cell)) { if (!remove_cells_.hasKey(child_cell)) {
const char *child_name = network_->name(child); const char *child_name = network_->name(child);
const char *child_vname = instanceVerilogName(child_name, string child_vname = instanceVerilogName(child_name, network_->pathEscape());
network_->pathEscape());
fprintf(stream_, " %s %s (", fprintf(stream_, " %s %s (",
network_->name(child_cell), network_->name(child_cell),
child_vname); child_vname.c_str());
bool first_port = true; bool first_port = true;
CellPortIterator *port_iter = network_->portIterator(child_cell); CellPortIterator *port_iter = network_->portIterator(child_cell);
while (port_iter->hasNext()) { while (port_iter->hasNext()) {
@ -329,14 +332,14 @@ VerilogWriter::writeInstPin(Instance *inst,
Net *net = network_->net(pin); Net *net = network_->net(pin);
if (net) { if (net) {
const char *net_name = network_->name(net); const char *net_name = network_->name(net);
const char *net_vname = netVerilogName(net_name, network_->pathEscape()); string net_vname = netVerilogName(net_name, network_->pathEscape());
if (!first_port) if (!first_port)
fprintf(stream_, ",\n "); fprintf(stream_, ",\n ");
const char *port_name = portVerilogName(network_->name(port), string port_vname = portVerilogName(network_->name(port),
network_->pathEscape()); network_->pathEscape());
fprintf(stream_, ".%s(%s)", fprintf(stream_, ".%s(%s)",
port_name, port_vname.c_str(),
net_vname); net_vname.c_str());
first_port = false; first_port = false;
} }
} }
@ -382,19 +385,17 @@ VerilogWriter::writeInstBusPinBit(Instance *inst,
bool &first_member) bool &first_member)
{ {
Pin *pin = network_->findPin(inst, port); Pin *pin = network_->findPin(inst, port);
const char *net_name = nullptr; Net *net = pin ? network_->net(pin) : nullptr;
if (pin) { string net_name;
Net *net = network_->net(pin); if (net)
if (net) net_name = network_->name(net);
net_name = network_->name(net); else
}
if (net_name == nullptr)
// There is no verilog syntax to "skip" a bit in the concatentation. // There is no verilog syntax to "skip" a bit in the concatentation.
net_name = stringPrintTmp("_NC%d", unconnected_net_index_++); stringPrint(net_name, "_NC%d", unconnected_net_index_++);
const char *net_vname = netVerilogName(net_name, network_->pathEscape()); string net_vname = netVerilogName(net_name.c_str(), network_->pathEscape());
if (!first_member) if (!first_member)
fprintf(stream_, ",\n "); fprintf(stream_, ",\n ");
fprintf(stream_, "%s", net_vname); fprintf(stream_, "%s", net_vname.c_str());
first_member = false; first_member = false;
} }
@ -414,11 +415,13 @@ VerilogWriter::writeAssigns(Instance *inst)
&& network_->direction(port)->isAnyOutput() && network_->direction(port)->isAnyOutput()
&& !stringEqual(network_->name(port), network_->name(net))) { && !stringEqual(network_->name(port), network_->name(net))) {
// Port name is different from net name. // Port name is different from net name.
string port_vname = netVerilogName(network_->name(port),
network_->pathEscape());
string net_vname = netVerilogName(network_->name(net),
network_->pathEscape());
fprintf(stream_, " assign %s = %s;\n", fprintf(stream_, " assign %s = %s;\n",
netVerilogName(network_->name(port), port_vname.c_str(),
network_->pathEscape()), net_vname.c_str());
netVerilogName(network_->name(net),
network_->pathEscape()));
} }
} }
delete pin_iter; delete pin_iter;