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:
parent
2b8fd17ca7
commit
94a93bd4ae
|
|
@ -1106,7 +1106,7 @@ private:
|
|||
LibertyCell *cell_;
|
||||
};
|
||||
|
||||
const char *
|
||||
string
|
||||
portLibertyToSta(const char *port_name);
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -16,8 +16,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
|
||||
// Return true if name is a bus.
|
||||
bool
|
||||
isBusName(const char *name,
|
||||
|
|
@ -38,7 +42,8 @@ parseBusName(const char *name,
|
|||
const char brkt_right,
|
||||
char escape,
|
||||
// Return values.
|
||||
char *&bus_name,
|
||||
bool &is_bus,
|
||||
string &bus_name,
|
||||
int &index);
|
||||
// Allow multiple different left/right bus brackets.
|
||||
void
|
||||
|
|
@ -47,7 +52,8 @@ parseBusName(const char *name,
|
|||
const char *brkts_right,
|
||||
char escape,
|
||||
// Return values.
|
||||
char *&bus_name,
|
||||
bool &is_bus,
|
||||
string &bus_name,
|
||||
int &index);
|
||||
|
||||
// Parse a bus range, such as BUS[4:0].
|
||||
|
|
@ -59,7 +65,8 @@ parseBusRange(const char *name,
|
|||
const char brkt_right,
|
||||
char escape,
|
||||
// Return values.
|
||||
char *&bus_name,
|
||||
bool &is_bus,
|
||||
string &bus_name,
|
||||
int &from,
|
||||
int &to);
|
||||
// brkt_lefts and brkt_rights are corresponding strings of legal
|
||||
|
|
@ -70,12 +77,13 @@ parseBusRange(const char *name,
|
|||
const char *brkts_right,
|
||||
const char escape,
|
||||
// Return values.
|
||||
char *&bus_name,
|
||||
bool &is_bus,
|
||||
string &bus_name,
|
||||
int &from,
|
||||
int &to);
|
||||
|
||||
// Insert escapes before ch1 and ch2 in token.
|
||||
const char *
|
||||
string
|
||||
escapeChars(const char *token,
|
||||
const char ch1,
|
||||
const char ch2,
|
||||
|
|
|
|||
|
|
@ -44,7 +44,10 @@ public:
|
|||
PatternMatch(const char *pattern);
|
||||
PatternMatch(const char *pattern,
|
||||
const PatternMatch *inherit_from);
|
||||
PatternMatch(string pattern,
|
||||
const PatternMatch *inherit_from);
|
||||
bool match(const char *str) const;
|
||||
bool match(const string &str) const;
|
||||
bool matchNoCase(const char *str) const;
|
||||
const char *pattern() const { return pattern_; }
|
||||
bool isRegexp() const { return is_regexp_; }
|
||||
|
|
|
|||
|
|
@ -16,25 +16,29 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace sta {
|
||||
|
||||
const char *
|
||||
using std::string;
|
||||
|
||||
string
|
||||
instanceVerilogName(const char *sta_name,
|
||||
const char escape);
|
||||
const char *
|
||||
string
|
||||
netVerilogName(const char *sta_name,
|
||||
const char escape);
|
||||
const char *
|
||||
string
|
||||
portVerilogName(const char *sta_name,
|
||||
const char escape);
|
||||
|
||||
const char *
|
||||
string
|
||||
moduleVerilogToSta(const char *sta_name);
|
||||
const char *
|
||||
string
|
||||
instanceVerilogToSta(const char *sta_name);
|
||||
const char *
|
||||
string
|
||||
netVerilogToSta(const char *sta_name);
|
||||
const char *
|
||||
string
|
||||
portVerilogToSta(const char *sta_name);
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -2520,23 +2520,20 @@ LibertyPort::setReceiverModel(ReceiverModelPtr receiver_model)
|
|||
receiver_model_ = receiver_model;
|
||||
}
|
||||
|
||||
const char *
|
||||
string
|
||||
portLibertyToSta(const char *port_name)
|
||||
{
|
||||
constexpr char bus_brkt_left = '[';
|
||||
constexpr char bus_brkt_right = ']';
|
||||
size_t name_length = strlen(port_name);
|
||||
char *sta_name = makeTmpString(name_length * 2);
|
||||
//char *sta_name = new char[name_length * 2];//makeTmpString(name_length * 2);
|
||||
char *p = sta_name;
|
||||
string sta_name;
|
||||
for (size_t i = 0; i < name_length; i++) {
|
||||
char ch = port_name[i];
|
||||
if (ch == bus_brkt_left
|
||||
|| ch == bus_brkt_right)
|
||||
*p++ = '\\';
|
||||
*p++ = ch;
|
||||
sta_name += '\\';
|
||||
sta_name += ch;
|
||||
}
|
||||
*p++ = '\0';
|
||||
return sta_name;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ LibertyPort *
|
|||
LibertyBuilder::makePort(LibertyCell *cell,
|
||||
const char *port_name)
|
||||
{
|
||||
const char *sta_name = portLibertyToSta(port_name);
|
||||
LibertyPort *port = new LibertyPort(cell, sta_name, false, nullptr,
|
||||
string sta_name = portLibertyToSta(port_name);
|
||||
LibertyPort *port = new LibertyPort(cell, sta_name.c_str(), false, nullptr,
|
||||
-1, -1, false, nullptr);
|
||||
cell->addPort(port);
|
||||
return port;
|
||||
|
|
@ -89,12 +89,13 @@ LibertyBuilder::makeBusPortBit(ConcreteLibrary *library,
|
|||
const char *bus_name,
|
||||
int bit_index)
|
||||
{
|
||||
char *bit_name = stringPrintTmp("%s%c%d%c",
|
||||
string bit_name;
|
||||
stringPrint(bit_name, "%s%c%d%c",
|
||||
bus_name,
|
||||
library->busBrktLeft(),
|
||||
bit_index,
|
||||
library->busBrktRight());
|
||||
LibertyPort *port = makePort(cell, bit_name, bit_index);
|
||||
LibertyPort *port = makePort(cell, bit_name.c_str(), bit_index);
|
||||
bus_port->addPortBit(port);
|
||||
cell->addPortBit(port);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -523,38 +523,42 @@ LibertyReader::defineScalingFactorVisitors()
|
|||
if (scaleFactorTypeRiseFallSuffix(type)) {
|
||||
for (auto tr : RiseFall::range()) {
|
||||
const char *tr_name = (tr == RiseFall::rise()) ? "rise":"fall";
|
||||
const char *attr_name = stringPrintTmp("k_%s_%s_%s",
|
||||
string attr_name;
|
||||
stringPrint(attr_name, "k_%s_%s_%s",
|
||||
pvt_name,
|
||||
type_name,
|
||||
tr_name);
|
||||
defineAttrVisitor(attr_name,&LibertyReader::visitScaleFactorSuffix);
|
||||
defineAttrVisitor(attr_name.c_str() ,&LibertyReader::visitScaleFactorSuffix);
|
||||
}
|
||||
}
|
||||
else if (scaleFactorTypeRiseFallPrefix(type)) {
|
||||
for (auto tr : RiseFall::range()) {
|
||||
const char *tr_name = (tr == RiseFall::rise()) ? "rise":"fall";
|
||||
const char *attr_name = stringPrintTmp("k_%s_%s_%s",
|
||||
string attr_name;
|
||||
stringPrint(attr_name, "k_%s_%s_%s",
|
||||
pvt_name,
|
||||
tr_name,
|
||||
type_name);
|
||||
defineAttrVisitor(attr_name,&LibertyReader::visitScaleFactorPrefix);
|
||||
defineAttrVisitor(attr_name.c_str(),&LibertyReader::visitScaleFactorPrefix);
|
||||
}
|
||||
}
|
||||
else if (scaleFactorTypeLowHighSuffix(type)) {
|
||||
for (auto tr : RiseFall::range()) {
|
||||
const char *tr_name = (tr == RiseFall::rise()) ? "high":"low";
|
||||
const char *attr_name = stringPrintTmp("k_%s_%s_%s",
|
||||
string attr_name;
|
||||
stringPrint(attr_name, "k_%s_%s_%s",
|
||||
pvt_name,
|
||||
tr_name,
|
||||
type_name);
|
||||
defineAttrVisitor(attr_name,&LibertyReader::visitScaleFactorHiLow);
|
||||
defineAttrVisitor(attr_name.c_str(),&LibertyReader::visitScaleFactorHiLow);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const char *attr_name = stringPrintTmp("k_%s_%s",
|
||||
string attr_name;
|
||||
stringPrint(attr_name, "k_%s_%s",
|
||||
pvt_name,
|
||||
type_name);
|
||||
defineAttrVisitor(attr_name,&LibertyReader::visitScaleFactor);
|
||||
defineAttrVisitor(attr_name.c_str(),&LibertyReader::visitScaleFactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -770,39 +774,32 @@ LibertyReader::parseUnits(LibertyAttr *attr,
|
|||
float &scale_var,
|
||||
Unit *unit)
|
||||
{
|
||||
const char *unit_str = getAttrString(attr);
|
||||
if (unit_str) {
|
||||
unsigned unit_str_length = strlen(unit_str);
|
||||
|
||||
string units = getAttrString(attr);
|
||||
if (!units.empty()) {
|
||||
// Unit format is <multipler_digits><scale_suffix_char><unit_suffix>.
|
||||
// Find the multiplier digits.
|
||||
char *mult_str = makeTmpString(unit_str_length);
|
||||
const char *s = unit_str;
|
||||
char *m = mult_str;
|
||||
for (; *s; s++) {
|
||||
char ch = *s;
|
||||
if (isdigit(ch))
|
||||
*m++ = ch;
|
||||
else
|
||||
break;
|
||||
}
|
||||
*m = '\0';
|
||||
|
||||
string units = getAttrString(attr);
|
||||
size_t mult_end = units.find_first_not_of("01234567890");
|
||||
float mult = 1.0F;
|
||||
if (*mult_str != '\0') {
|
||||
if (stringEq(mult_str, "1"))
|
||||
string scale_suffix;
|
||||
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;
|
||||
else if (stringEq(mult_str, "10"))
|
||||
else if (unit_mult == "10")
|
||||
mult = 10.0F;
|
||||
else if (stringEq(mult_str, "100"))
|
||||
else if (unit_mult == "100")
|
||||
mult = 100.0F;
|
||||
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;
|
||||
if (*s && stringEqual(s + 1, unit_suffix)) {
|
||||
char scale_char = tolower(*s);
|
||||
if (scale_suffix.size() >= 2 && scale_suffix.substr(1) == unit_suffix) {
|
||||
char scale_char = tolower(scale_suffix[0]);
|
||||
if (scale_char == 'k')
|
||||
scale_mult = 1E+3F;
|
||||
else if (scale_char == 'm')
|
||||
|
|
@ -818,8 +815,8 @@ LibertyReader::parseUnits(LibertyAttr *attr,
|
|||
else
|
||||
libWarn(39, attr, "unknown unit scale %c.", scale_char);
|
||||
}
|
||||
else if (!stringEqual(s, unit_suffix))
|
||||
libWarn(40, attr, "unknown unit suffix %s.", s + 1);
|
||||
else if (!stringEqual(scale_suffix.c_str(), unit_suffix))
|
||||
libWarn(40, attr, "unknown unit suffix %s.", scale_suffix.c_str());
|
||||
|
||||
scale_var = scale_mult * mult;
|
||||
unit->setScale(scale_var);
|
||||
|
|
@ -3192,8 +3189,8 @@ libertyReaderFindPort(LibertyCell *cell,
|
|||
char brkt_right = library->busBrktRight();
|
||||
const char escape = '\\';
|
||||
// Pins at top level with bus names have escaped brackets.
|
||||
port_name = escapeChars(port_name, brkt_left, brkt_right, escape);
|
||||
port = cell->findLibertyPort(port_name);
|
||||
string escaped_port_name = escapeChars(port_name, brkt_left, brkt_right, escape);
|
||||
port = cell->findLibertyPort(escaped_port_name.c_str());
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
|
@ -4771,11 +4768,12 @@ LibertyReader::parseFunc(const char *func,
|
|||
const char *attr_name,
|
||||
int line)
|
||||
{
|
||||
const char *error_msg = stringPrintTmp("%s, line %d %s",
|
||||
string error_msg;
|
||||
stringPrint(error_msg, "%s, line %d %s",
|
||||
filename_,
|
||||
line,
|
||||
attr_name);
|
||||
return parseFuncExpr(func, cell_, error_msg, report_);
|
||||
return parseFuncExpr(func, cell_, error_msg.c_str(), report_);
|
||||
}
|
||||
|
||||
EarlyLateAll *
|
||||
|
|
@ -5628,7 +5626,6 @@ PortNameBitIterator::PortNameBitIterator(LibertyCell *cell,
|
|||
port_(nullptr),
|
||||
bit_iterator_(nullptr),
|
||||
range_bus_port_(nullptr),
|
||||
range_bus_name_(nullptr),
|
||||
range_name_next_(nullptr),
|
||||
size_(0)
|
||||
{
|
||||
|
|
@ -5649,11 +5646,13 @@ PortNameBitIterator::init(const char *port_name)
|
|||
else {
|
||||
// Check for bus range.
|
||||
LibertyLibrary *library = visitor_->library();
|
||||
bool is_bus;
|
||||
string bus_name;
|
||||
int from, to;
|
||||
char *bus_name;
|
||||
parseBusRange(port_name, library->busBrktLeft(), library->busBrktRight(),
|
||||
'\\', bus_name, from, to);
|
||||
if (bus_name) {
|
||||
parseBusRange(port_name, library->busBrktLeft(),
|
||||
library->busBrktRight(), '\\',
|
||||
is_bus, bus_name, from, to);
|
||||
if (is_bus) {
|
||||
port = visitor_->findPort(port_name);
|
||||
if (port) {
|
||||
if (port->isBus()) {
|
||||
|
|
@ -5663,7 +5662,6 @@ PortNameBitIterator::init(const char *port_name)
|
|||
range_from_ = from;
|
||||
range_to_ = to;
|
||||
range_bit_ = from;
|
||||
delete [] bus_name;
|
||||
}
|
||||
else
|
||||
visitor_->libWarn(156, line_, "port %s subscript out of range.",
|
||||
|
|
@ -5672,7 +5670,7 @@ PortNameBitIterator::init(const char *port_name)
|
|||
else
|
||||
visitor_->libWarn(157, line_, "port range %s of non-bus port %s.",
|
||||
port_name,
|
||||
bus_name);
|
||||
bus_name.c_str());
|
||||
}
|
||||
else {
|
||||
range_bus_name_ = bus_name;
|
||||
|
|
@ -5690,7 +5688,6 @@ PortNameBitIterator::init(const char *port_name)
|
|||
|
||||
PortNameBitIterator::~PortNameBitIterator()
|
||||
{
|
||||
stringDelete(range_bus_name_);
|
||||
delete bit_iterator_;
|
||||
}
|
||||
|
||||
|
|
@ -5703,7 +5700,7 @@ PortNameBitIterator::hasNext()
|
|||
&& ((range_from_ > range_to_)
|
||||
? range_bit_ >= range_to_
|
||||
: range_bit_ <= range_from_))
|
||||
|| (range_bus_name_
|
||||
|| (!range_bus_name_.empty()
|
||||
&& range_name_next_);
|
||||
}
|
||||
|
||||
|
|
@ -5725,7 +5722,7 @@ PortNameBitIterator::next()
|
|||
range_bit_++;
|
||||
return next;
|
||||
}
|
||||
else if (range_bus_name_) {
|
||||
else if (!range_bus_name_.empty()) {
|
||||
LibertyPort *next = range_name_next_;
|
||||
findRangeBusNameNext();
|
||||
return next;
|
||||
|
|
@ -5741,12 +5738,13 @@ PortNameBitIterator::findRangeBusNameNext()
|
|||
? range_bit_ >= range_to_
|
||||
: range_bit_ <= range_to_) {
|
||||
LibertyLibrary *library = visitor_->library();
|
||||
const char *bus_bit_name = stringPrintTmp("%s%c%d%c",
|
||||
range_bus_name_,
|
||||
string bus_bit_name;
|
||||
stringPrint(bus_bit_name, "%s%c%d%c",
|
||||
range_bus_name_.c_str(),
|
||||
library->busBrktLeft(),
|
||||
range_bit_,
|
||||
library->busBrktRight());
|
||||
range_name_next_ = visitor_->findPort(bus_bit_name);
|
||||
range_name_next_ = visitor_->findPort(bus_bit_name.c_str());
|
||||
if (range_name_next_) {
|
||||
if (range_from_ > range_to_)
|
||||
range_bit_--;
|
||||
|
|
@ -5754,7 +5752,7 @@ PortNameBitIterator::findRangeBusNameNext()
|
|||
range_bit_++;
|
||||
}
|
||||
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
|
||||
range_name_next_ = nullptr;
|
||||
|
|
|
|||
|
|
@ -861,7 +861,7 @@ protected:
|
|||
LibertyPort *port_;
|
||||
LibertyPortMemberIterator *bit_iterator_;
|
||||
LibertyPort *range_bus_port_;
|
||||
const char *range_bus_name_;
|
||||
string range_bus_name_;
|
||||
LibertyPort *range_name_next_;
|
||||
int range_from_;
|
||||
int range_to_;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::map;
|
||||
|
||||
static constexpr char escape_ = '\\';
|
||||
|
||||
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_right[2]{bus_brkt_right, '\0'};
|
||||
BusPortMap port_map;
|
||||
map<string, BusPort*> port_map;
|
||||
// Find ungrouped bus ports.
|
||||
// Remove bus bit ports from the ports_ vector during the scan by
|
||||
// keeping an index to the next insertion index and skipping over
|
||||
|
|
@ -390,19 +392,21 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left,
|
|||
ports_.clear();
|
||||
for (ConcretePort *port : ports) {
|
||||
const char *port_name = port->name();
|
||||
char *bus_name;
|
||||
bool is_bus;
|
||||
string bus_name;
|
||||
int index;
|
||||
parseBusName(port_name, bus_brkts_left, bus_brkts_right, escape_,
|
||||
bus_name, index);
|
||||
if (bus_name) {
|
||||
is_bus, bus_name, index);
|
||||
if (is_bus) {
|
||||
if (!port->isBusBit()) {
|
||||
BusPort *bus_port = port_map.findKey(bus_name);
|
||||
if (bus_port)
|
||||
stringDelete(bus_name);
|
||||
else {
|
||||
bus_port = new BusPort(bus_name, index, port->direction());
|
||||
auto name_bus_port = port_map.find(bus_name);
|
||||
BusPort *bus_port;
|
||||
if (name_bus_port == port_map.end()) {
|
||||
bus_port = new BusPort(bus_name.c_str(), index, port->direction());
|
||||
port_map[bus_name] = bus_port;
|
||||
}
|
||||
else
|
||||
bus_port = name_bus_port->second;
|
||||
bus_port->pushMember(port);
|
||||
}
|
||||
else
|
||||
|
|
@ -413,47 +417,45 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left,
|
|||
}
|
||||
|
||||
// Make the bus ports.
|
||||
BusPortMap::Iterator bus_iter(port_map);
|
||||
while (bus_iter.hasNext()) {
|
||||
BusPort *bus_port = bus_iter.next();
|
||||
const char *bus_name = bus_port->name();
|
||||
bool msb_first = port_msb_first(bus_name);
|
||||
for (auto name_bus : port_map) {
|
||||
const string &bus_name = name_bus.first;
|
||||
BusPort *bus_port = name_bus.second;
|
||||
bool msb_first = port_msb_first(bus_name.c_str());
|
||||
ConcretePortSeq *members = bus_port->members();
|
||||
sort(members, [&](ConcretePort *port1,
|
||||
ConcretePort *port2) {
|
||||
char *bus_name;
|
||||
bool is_bus;
|
||||
string bus_name;
|
||||
int index1, index2;
|
||||
parseBusName(port1->name(), bus_brkts_left, bus_brkts_right, escape_,
|
||||
bus_name, index1);
|
||||
stringDelete(bus_name);
|
||||
is_bus, bus_name, index1);
|
||||
parseBusName(port2->name(), bus_brkts_left, bus_brkts_right, escape_,
|
||||
bus_name, index2);
|
||||
stringDelete(bus_name);
|
||||
is_bus, bus_name, index2);
|
||||
return msb_first ? index1 > index2 : index1 < index2;
|
||||
});
|
||||
|
||||
char *bus_name1;
|
||||
bool is_bus1;
|
||||
string bus_name1;
|
||||
int from_index, to_index;
|
||||
parseBusName((*members)[0]->name(),
|
||||
bus_brkts_left, bus_brkts_right, escape_,
|
||||
bus_name1, from_index);
|
||||
stringDelete(bus_name1);
|
||||
is_bus1, bus_name1, from_index);
|
||||
parseBusName((*members)[members->size() - 1]->name(),
|
||||
bus_brkts_left, bus_brkts_right, escape_,
|
||||
bus_name1, to_index);
|
||||
stringDelete(bus_name1);
|
||||
is_bus1, bus_name1, to_index);
|
||||
|
||||
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());
|
||||
delete bus_port;
|
||||
|
||||
for (ConcretePort *port : *members) {
|
||||
char *bus_name;
|
||||
bool is_bus;
|
||||
string bus_name;
|
||||
int index;
|
||||
parseBusName(port->name(), bus_brkts_left, bus_brkts_right, escape_,
|
||||
bus_name, index);
|
||||
is_bus, bus_name, index);
|
||||
port->setBusBitIndex(index);
|
||||
stringDelete(bus_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,12 +51,14 @@ parseBusName(const char *name,
|
|||
const char brkt_right,
|
||||
const char escape,
|
||||
// Return values.
|
||||
char *&bus_name,
|
||||
bool &is_bus,
|
||||
string &bus_name,
|
||||
int &index)
|
||||
{
|
||||
const char brkts_left[2] = {brkt_left, '\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
|
||||
|
|
@ -65,10 +67,11 @@ parseBusName(const char *name,
|
|||
const char *brkts_right,
|
||||
char escape,
|
||||
// Return values.
|
||||
char *&bus_name,
|
||||
bool &is_bus,
|
||||
string &bus_name,
|
||||
int &index)
|
||||
{
|
||||
bus_name = nullptr;
|
||||
is_bus = false;
|
||||
size_t len = strlen(name);
|
||||
// Shortest bus name is a[0].
|
||||
if (len >= 4
|
||||
|
|
@ -81,10 +84,9 @@ parseBusName(const char *name,
|
|||
char brkt_left = brkts_left[brkt_index];
|
||||
const char *left = strrchr(name, brkt_left);
|
||||
if (left) {
|
||||
is_bus = true;
|
||||
size_t bus_name_len = left - name;
|
||||
bus_name = new char[bus_name_len + 1];
|
||||
strncpy(bus_name, name, bus_name_len);
|
||||
bus_name[bus_name_len] = '\0';
|
||||
bus_name.append(name, bus_name_len);
|
||||
// Simple bus subscript.
|
||||
index = atoi(left + 1);
|
||||
}
|
||||
|
|
@ -98,13 +100,15 @@ parseBusRange(const char *name,
|
|||
const char brkt_right,
|
||||
char escape,
|
||||
// Return values.
|
||||
char *&bus_name,
|
||||
bool &is_bus,
|
||||
string &bus_name,
|
||||
int &from,
|
||||
int &to)
|
||||
{
|
||||
const char brkts_left[2] = {brkt_left, '\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
|
||||
|
|
@ -113,11 +117,12 @@ parseBusRange(const char *name,
|
|||
const char *brkts_right,
|
||||
char escape,
|
||||
// Return values.
|
||||
char *&bus_name,
|
||||
bool &is_bus,
|
||||
string &bus_name,
|
||||
int &from,
|
||||
int &to)
|
||||
{
|
||||
bus_name = nullptr;
|
||||
is_bus = false;
|
||||
size_t len = strlen(name);
|
||||
// Shortest bus range is a[1:0].
|
||||
if (len >= 6
|
||||
|
|
@ -134,10 +139,8 @@ parseBusRange(const char *name,
|
|||
const char range_sep = ':';
|
||||
const char *range = strchr(name, range_sep);
|
||||
if (range) {
|
||||
size_t bus_name_len = left - name;
|
||||
bus_name = new char[bus_name_len + 1];
|
||||
strncpy(bus_name, name, bus_name_len);
|
||||
bus_name[bus_name_len] = '\0';
|
||||
is_bus = true;
|
||||
bus_name.append(name, left - name);
|
||||
// No need to terminate bus subscript because atoi stops
|
||||
// scanning at first non-digit character.
|
||||
from = atoi(left + 1);
|
||||
|
|
@ -148,54 +151,32 @@ parseBusRange(const char *name,
|
|||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
string
|
||||
escapeChars(const char *token,
|
||||
const char ch1,
|
||||
const char ch2,
|
||||
const char escape)
|
||||
{
|
||||
int result_length = 0;
|
||||
bool need_escapes = false;
|
||||
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')
|
||||
result_length++;
|
||||
}
|
||||
else if (ch == ch1 || ch == ch2) {
|
||||
result_length++;
|
||||
need_escapes = true;
|
||||
}
|
||||
result_length++;
|
||||
}
|
||||
if (need_escapes) {
|
||||
char *result = makeTmpString(result_length + 1);
|
||||
char *r = result;
|
||||
string escaped;
|
||||
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;
|
||||
escaped += ch;
|
||||
escaped += next_ch;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
else if (ch == ch1 || ch == ch2) {
|
||||
*r++ = escape;
|
||||
*r++ = ch;
|
||||
escaped += escape;
|
||||
escaped += ch;
|
||||
}
|
||||
else
|
||||
*r++ = ch;
|
||||
escaped += ch;
|
||||
}
|
||||
*r++ = '\0';
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return token;
|
||||
return escaped;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
static const char *
|
||||
static string
|
||||
escapeDividers(const char *token,
|
||||
const Network *network);
|
||||
static const char *
|
||||
static string
|
||||
escapeBrackets(const char *token,
|
||||
const Network *network);
|
||||
|
||||
|
|
@ -631,21 +631,22 @@ SdcNetwork::findPort(const Cell *cell,
|
|||
Port *port = network_->findPort(cell, name);
|
||||
if (port == nullptr) {
|
||||
// Look for matches after escaping brackets.
|
||||
char *bus_name;
|
||||
bool is_bus;
|
||||
string bus_name;
|
||||
int index;
|
||||
parseBusName(name, '[', ']', pathEscape(), bus_name, index);
|
||||
if (bus_name) {
|
||||
const char *escaped1 = escapeBrackets(name, this);
|
||||
port = network_->findPort(cell, escaped1);
|
||||
if (port == nullptr
|
||||
&& bus_name[strlen(bus_name) - 1] == ']') {
|
||||
parseBusName(name, '[', ']', pathEscape(), is_bus, bus_name, index);
|
||||
if (is_bus) {
|
||||
string escaped1 = escapeBrackets(name, this);
|
||||
port = network_->findPort(cell, escaped1.c_str());
|
||||
if (port == nullptr) {
|
||||
// Try escaping base foo\[0\][1]
|
||||
const char *escaped2 = stringPrintTmp("%s[%d]",
|
||||
escapeBrackets(bus_name, this),
|
||||
string escaped2;
|
||||
string escaped_bus_name = escapeBrackets(bus_name.c_str(), this);
|
||||
stringPrint(escaped2, "%s[%d]",
|
||||
escaped_bus_name.c_str(),
|
||||
index);
|
||||
port = network_->findPort(cell, escaped2);
|
||||
port = network_->findPort(cell, escaped2.c_str());
|
||||
}
|
||||
stringDelete(bus_name);
|
||||
}
|
||||
}
|
||||
return port;
|
||||
|
|
@ -658,23 +659,25 @@ SdcNetwork::findPortsMatching(const Cell *cell,
|
|||
PortSeq matches = network_->findPortsMatching(cell, pattern);
|
||||
if (matches.empty()) {
|
||||
// Look for matches after escaping brackets.
|
||||
char *bus_name;
|
||||
bool is_bus;
|
||||
string bus_name;
|
||||
int index;
|
||||
parseBusName(pattern->pattern(), '[', ']', pathEscape(), bus_name, index);
|
||||
if (bus_name) {
|
||||
const char *escaped1 = escapeBrackets(pattern->pattern(), this);
|
||||
PatternMatch escaped_pattern1(escaped1, pattern);
|
||||
parseBusName(pattern->pattern(), '[', ']', pathEscape(),
|
||||
is_bus, bus_name, index);
|
||||
if (is_bus) {
|
||||
string escaped1 = escapeBrackets(pattern->pattern(), this);
|
||||
PatternMatch escaped_pattern1(escaped1.c_str(), pattern);
|
||||
matches = network_->findPortsMatching(cell, &escaped_pattern1);
|
||||
if (matches.empty()
|
||||
&& bus_name[strlen(bus_name) - 1] == ']') {
|
||||
if (matches.empty()) {
|
||||
// Try escaping base foo\[0\][1]
|
||||
const char *escaped2 = stringPrintTmp("%s[%d]",
|
||||
escapeBrackets(bus_name, this),
|
||||
string escaped2;
|
||||
string escaped_bus_name = escapeBrackets(bus_name.c_str(), this);
|
||||
stringPrint(escaped2, "%s[%d]",
|
||||
escaped_bus_name.c_str(),
|
||||
index);
|
||||
PatternMatch escaped_pattern2(escaped2, pattern);
|
||||
PatternMatch escaped_pattern2(escaped2.c_str(), pattern);
|
||||
matches = network_->findPortsMatching(cell, &escaped_pattern2);
|
||||
}
|
||||
stringDelete(bus_name);
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
|
|
@ -739,8 +742,10 @@ SdcNetwork::findInstance(const char *path_name) const
|
|||
if (parent == nullptr)
|
||||
parent = network_->topInstance();
|
||||
Instance *child = findChild(parent, child_name);
|
||||
if (child == nullptr)
|
||||
child = findChild(parent, escapeDividers(child_name, this));
|
||||
if (child == nullptr) {
|
||||
string escaped_name = escapeDividers(child_name, this);
|
||||
child = findChild(parent, escaped_name.c_str());
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
|
|
@ -774,8 +779,8 @@ SdcNetwork::findChild(const Instance *parent,
|
|||
{
|
||||
Instance *child = network_->findChild(parent, name);
|
||||
if (child == nullptr) {
|
||||
const char *escaped = escapeBrackets(name, this);
|
||||
child = network_->findChild(parent, escaped);
|
||||
string escaped = escapeBrackets(name, this);
|
||||
child = network_->findChild(parent, escaped.c_str());
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
|
@ -799,8 +804,8 @@ SdcNetwork::findNet(const Instance *instance,
|
|||
{
|
||||
Net *net = network_->findNet(instance, net_name);
|
||||
if (net == nullptr) {
|
||||
const char *net_name_ = escapeBrackets(net_name, this);
|
||||
net = network_->findNet(instance, net_name_);
|
||||
string net_name1 = escapeBrackets(net_name, this);
|
||||
net = network_->findNet(instance, net_name1.c_str());
|
||||
}
|
||||
return net;
|
||||
}
|
||||
|
|
@ -829,14 +834,13 @@ SdcNetwork::findInstNetsMatching(const Instance *instance,
|
|||
network_->findInstNetsMatching(instance, pattern, matches);
|
||||
if (matches.empty()) {
|
||||
// Look for matches after escaping path dividers.
|
||||
const PatternMatch escaped_dividers(escapeDividers(pattern->pattern(),
|
||||
this),
|
||||
pattern);
|
||||
string escaped_pattern = escapeDividers(pattern->pattern(), this);
|
||||
const PatternMatch escaped_dividers(escaped_pattern.c_str(), pattern);
|
||||
network_->findInstNetsMatching(instance, &escaped_dividers, matches);
|
||||
if (matches.empty()) {
|
||||
// Look for matches after escaping brackets.
|
||||
const PatternMatch escaped_brkts(escapeBrackets(pattern->pattern(),this),
|
||||
pattern);
|
||||
string escaped_pattern2 = escapeBrackets(pattern->pattern(),this);
|
||||
const PatternMatch escaped_brkts(escaped_pattern2.c_str(), pattern);
|
||||
network_->findInstNetsMatching(instance, &escaped_brkts, matches);
|
||||
}
|
||||
}
|
||||
|
|
@ -862,21 +866,21 @@ SdcNetwork::findPin(const Instance *instance,
|
|||
Pin *pin = network_->findPin(instance, port_name);
|
||||
if (pin == nullptr) {
|
||||
// Look for match after escaping brackets.
|
||||
char *bus_name;
|
||||
bool is_bus;
|
||||
string bus_name;
|
||||
int index;
|
||||
parseBusName(port_name, '[', ']', pathEscape(), bus_name, index);
|
||||
if (bus_name) {
|
||||
const char *escaped1 = escapeBrackets(port_name, this);
|
||||
pin = network_->findPin(instance, escaped1);
|
||||
if (pin == nullptr
|
||||
&& bus_name[strlen(bus_name) - 1] == ']') {
|
||||
parseBusName(port_name, '[', ']', pathEscape(),
|
||||
is_bus, bus_name, index);
|
||||
if (is_bus) {
|
||||
string escaped1 = escapeBrackets(port_name, this);
|
||||
pin = network_->findPin(instance, escaped1.c_str());
|
||||
if (pin == nullptr) {
|
||||
// Try escaping base foo\[0\][1]
|
||||
const char *escaped2 = stringPrintTmp("%s[%d]",
|
||||
escapeBrackets(bus_name, this),
|
||||
index);
|
||||
pin = network_->findPin(instance, escaped2);
|
||||
string escaped_bus_name = escapeBrackets(bus_name.c_str(), this);
|
||||
string escaped2;
|
||||
stringPrint(escaped2, "%s[%d]", escaped_bus_name.c_str(), index);
|
||||
pin = network_->findPin(instance, escaped2.c_str());
|
||||
}
|
||||
stringDelete(bus_name);
|
||||
}
|
||||
}
|
||||
return pin;
|
||||
|
|
@ -967,16 +971,16 @@ SdcNetwork::makeInstance(LibertyCell *cell,
|
|||
const char *name,
|
||||
Instance *parent)
|
||||
{
|
||||
const char *escaped_name = escapeDividers(name, this);
|
||||
return network_edit_->makeInstance(cell, escaped_name, parent);
|
||||
string escaped_name = escapeDividers(name, this);
|
||||
return network_edit_->makeInstance(cell, escaped_name.c_str(), parent);
|
||||
}
|
||||
|
||||
Net *
|
||||
SdcNetwork::makeNet(const char *name,
|
||||
Instance *parent)
|
||||
{
|
||||
const char *escaped_name = escapeDividers(name, this);
|
||||
return network_edit_->makeNet(escaped_name, parent);
|
||||
string escaped_name = escapeDividers(name, this);
|
||||
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);
|
||||
if (!found_match && has_brkts) {
|
||||
// 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);
|
||||
found_match |= visit_tail(parent, &escaped_tail);
|
||||
stringDelete(escaped_path);
|
||||
}
|
||||
}
|
||||
stringDelete(inst_path);
|
||||
|
|
@ -1166,7 +1169,7 @@ SdcNetwork::visitMatches(const Instance *parent,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
static const char *
|
||||
static string
|
||||
escapeDividers(const char *token,
|
||||
const Network *network)
|
||||
{
|
||||
|
|
@ -1174,7 +1177,7 @@ escapeDividers(const char *token,
|
|||
network->pathEscape());
|
||||
}
|
||||
|
||||
static const char *
|
||||
static string
|
||||
escapeBrackets(const char *token,
|
||||
const Network *network)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,72 +23,63 @@
|
|||
|
||||
namespace sta {
|
||||
|
||||
static const char *
|
||||
static string
|
||||
staToVerilog(const char *sta_name,
|
||||
const char escape);
|
||||
static const char *
|
||||
static string
|
||||
staToVerilog2(const char *sta_name,
|
||||
const char escape);
|
||||
static const char *
|
||||
static string
|
||||
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,
|
||||
const char escape)
|
||||
{
|
||||
return staToVerilog(sta_name, escape);
|
||||
}
|
||||
|
||||
const char *
|
||||
string
|
||||
netVerilogName(const char *sta_name,
|
||||
const char escape)
|
||||
{
|
||||
char *bus_name;
|
||||
bool is_bus;
|
||||
string bus_name;
|
||||
int index;
|
||||
parseBusName(sta_name, '[', ']', escape, bus_name, index);
|
||||
if (bus_name) {
|
||||
const char *vname = stringPrintTmp("%s[%d]",
|
||||
staToVerilog(bus_name, escape),
|
||||
index);
|
||||
stringDelete(bus_name);
|
||||
parseBusName(sta_name, '[', ']', escape, is_bus, bus_name, index);
|
||||
if (is_bus) {
|
||||
string bus_vname = staToVerilog(bus_name.c_str(), escape);
|
||||
string vname;
|
||||
stringPrint(vname, "%s[%d]", bus_vname.c_str(), index);
|
||||
return vname;
|
||||
}
|
||||
else
|
||||
return staToVerilog2(sta_name, escape);
|
||||
}
|
||||
|
||||
const char *
|
||||
string
|
||||
portVerilogName(const char *sta_name,
|
||||
const char escape)
|
||||
{
|
||||
return staToVerilog2(sta_name, escape);
|
||||
}
|
||||
|
||||
static const char *
|
||||
static string
|
||||
staToVerilog(const char *sta_name,
|
||||
const char escape)
|
||||
{
|
||||
// Leave room for leading escape and trailing space if the name
|
||||
// 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.
|
||||
string escaped_name = "\\";
|
||||
bool escaped = false;
|
||||
*v++ = '\\';
|
||||
for (const char *s = sta_name; *s ; s++) {
|
||||
char ch = s[0];
|
||||
if (ch == escape) {
|
||||
char next_ch = s[1];
|
||||
if (next_ch == escape) {
|
||||
vstringAppend(verilog_name, verilog_name_end, v, ch);
|
||||
vstringAppend(verilog_name, verilog_name_end, v, next_ch);
|
||||
escaped_name += ch;
|
||||
escaped_name += next_ch;
|
||||
s++;
|
||||
}
|
||||
else
|
||||
|
|
@ -98,20 +89,19 @@ staToVerilog(const char *sta_name,
|
|||
else {
|
||||
if ((!(isalnum(ch) || ch == '_')))
|
||||
escaped = true;
|
||||
vstringAppend(verilog_name, verilog_name_end, v, ch);
|
||||
escaped_name += ch;
|
||||
}
|
||||
}
|
||||
if (escaped) {
|
||||
// Add a terminating space.
|
||||
vstringAppend(verilog_name, verilog_name_end, v, ' ');
|
||||
vstringAppend(verilog_name, verilog_name_end, v, '\0');
|
||||
return verilog_name;
|
||||
escaped_name += ' ';
|
||||
return escaped_name;
|
||||
}
|
||||
else
|
||||
return sta_name;
|
||||
return string(sta_name);
|
||||
}
|
||||
|
||||
static const char *
|
||||
static string
|
||||
staToVerilog2(const char *sta_name,
|
||||
const char escape)
|
||||
{
|
||||
|
|
@ -119,20 +109,16 @@ staToVerilog2(const char *sta_name,
|
|||
constexpr char bus_brkt_right = ']';
|
||||
// Leave room for leading escape and trailing space if the name
|
||||
// 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;
|
||||
string escaped_name = "\\";
|
||||
// Assume the name has to be escaped and start copying while scanning.
|
||||
bool escaped = false;
|
||||
*v++ = '\\';
|
||||
for (const char *s = sta_name; *s ; s++) {
|
||||
char ch = s[0];
|
||||
if (ch == escape) {
|
||||
char next_ch = s[1];
|
||||
if (next_ch == escape) {
|
||||
vstringAppend(verilog_name, verilog_name_end, v, ch);
|
||||
vstringAppend(verilog_name, verilog_name_end, v, next_ch);
|
||||
escaped_name += ch;
|
||||
escaped_name += next_ch;
|
||||
s++;
|
||||
}
|
||||
else
|
||||
|
|
@ -144,46 +130,45 @@ staToVerilog2(const char *sta_name,
|
|||
if ((!(isalnum(ch) || ch == '_') && !is_brkt)
|
||||
|| is_brkt)
|
||||
escaped = true;
|
||||
vstringAppend(verilog_name, verilog_name_end, v, ch);
|
||||
escaped_name += ch;
|
||||
}
|
||||
}
|
||||
if (escaped) {
|
||||
// Add a terminating space.
|
||||
vstringAppend(verilog_name, verilog_name_end, v, ' ');
|
||||
vstringAppend(verilog_name, verilog_name_end, v, '\0');
|
||||
return verilog_name;
|
||||
escaped_name += ' ';
|
||||
return escaped_name;
|
||||
}
|
||||
else
|
||||
return sta_name;
|
||||
return string(sta_name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
const char *
|
||||
string
|
||||
moduleVerilogToSta(const char *module_name)
|
||||
{
|
||||
return verilogToSta(module_name);
|
||||
}
|
||||
|
||||
const char *
|
||||
string
|
||||
instanceVerilogToSta(const char *inst_name)
|
||||
{
|
||||
return verilogToSta(inst_name);
|
||||
}
|
||||
|
||||
const char *
|
||||
string
|
||||
netVerilogToSta(const char *net_name)
|
||||
{
|
||||
return verilogToSta(net_name);
|
||||
}
|
||||
|
||||
const char *
|
||||
string
|
||||
portVerilogToSta(const char *port_name)
|
||||
{
|
||||
return verilogToSta(port_name);
|
||||
}
|
||||
|
||||
static const char *
|
||||
static string
|
||||
verilogToSta(const char *verilog_name)
|
||||
{
|
||||
if (verilog_name && verilog_name[0] == '\\') {
|
||||
|
|
@ -197,11 +182,7 @@ verilogToSta(const char *verilog_name)
|
|||
size_t verilog_name_length = strlen(verilog_name);
|
||||
if (verilog_name[verilog_name_length - 1] == ' ')
|
||||
verilog_name_length--;
|
||||
// +1 for \0, +2 for escaping brackets.
|
||||
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;
|
||||
string sta_name;
|
||||
for (size_t i = 0; i < verilog_name_length; i++) {
|
||||
char ch = verilog_name[i];
|
||||
if (ch == bus_brkt_left
|
||||
|
|
@ -209,33 +190,13 @@ verilogToSta(const char *verilog_name)
|
|||
|| ch == divider
|
||||
|| ch == escape)
|
||||
// Escape bus brackets, dividers and escapes.
|
||||
vstringAppend(sta_name, sta_name_end, s, escape);
|
||||
vstringAppend(sta_name, sta_name_end, s, ch);
|
||||
sta_name += escape;
|
||||
sta_name += ch;
|
||||
}
|
||||
vstringAppend(sta_name, sta_name_end, s, '\0');
|
||||
return sta_name;
|
||||
}
|
||||
else
|
||||
return 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;
|
||||
return string(verilog_name);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
|
|
@ -131,14 +131,15 @@ ReadVcdActivities::setVarActivity(VcdVar *var,
|
|||
string &var_name,
|
||||
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)
|
||||
setVarActivity(sta_name, var_values, 0);
|
||||
setVarActivity(sta_name.c_str(), var_values, 0);
|
||||
else {
|
||||
char *bus_name;
|
||||
bool is_bus;
|
||||
string bus_name;
|
||||
int from, to;
|
||||
parseBusRange(sta_name, '[', ']', '\\',
|
||||
bus_name, from, to);
|
||||
parseBusRange(sta_name.c_str(), '[', ']', '\\',
|
||||
is_bus, bus_name, from, to);
|
||||
int value_bit = 0;
|
||||
if (to < from) {
|
||||
for (int bus_bit = to; bus_bit <= from; bus_bit++) {
|
||||
|
|
@ -160,7 +161,6 @@ ReadVcdActivities::setVarActivity(VcdVar *var,
|
|||
value_bit++;
|
||||
}
|
||||
}
|
||||
stringDelete(bus_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -128,8 +128,10 @@ celltype:
|
|||
;
|
||||
|
||||
cell_instance:
|
||||
'(' INSTANCE ')' { sta::sdf_reader->setInstance(NULL); }
|
||||
| '(' INSTANCE '*' ')' { sta::sdf_reader->setInstanceWildcard(); }
|
||||
'(' INSTANCE ')'
|
||||
{ sta::sdf_reader->setInstance(NULL); }
|
||||
| '(' INSTANCE '*' ')'
|
||||
{ sta::sdf_reader->setInstanceWildcard(); }
|
||||
| '(' INSTANCE path ')'
|
||||
{ sta::sdf_reader->setInstance($3); }
|
||||
;
|
||||
|
|
@ -266,7 +268,10 @@ port:
|
|||
ID
|
||||
{ $$ = sta::sdf_reader->unescaped($1); }
|
||||
| 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:
|
||||
|
|
@ -292,7 +297,7 @@ port_tchk:
|
|||
| '(' COND EXPR_ID_CLOSE
|
||||
{ $$ = sta::sdf_reader->makeCondPortSpec($3); }
|
||||
| '(' 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:
|
||||
|
|
|
|||
|
|
@ -210,6 +210,8 @@ SdfReader::interconnect(const char *from_pin_name,
|
|||
sdfWarn(186, "pin %s not found.", to_pin_name);
|
||||
}
|
||||
}
|
||||
stringDelete(from_pin_name);
|
||||
stringDelete(to_pin_name);
|
||||
deleteTripleSeq(triples);
|
||||
}
|
||||
|
||||
|
|
@ -234,6 +236,7 @@ SdfReader::port(const char *to_pin_name,
|
|||
}
|
||||
}
|
||||
}
|
||||
stringDelete(to_pin_name);
|
||||
deleteTripleSeq(triples);
|
||||
}
|
||||
|
||||
|
|
@ -312,6 +315,7 @@ SdfReader::setInstance(const char *instance_name)
|
|||
}
|
||||
else
|
||||
instance_ = nullptr;
|
||||
stringDelete(instance_name);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -399,6 +403,7 @@ SdfReader::iopath(SdfPortSpec *from_edge,
|
|||
}
|
||||
}
|
||||
}
|
||||
stringDelete(to_port_name);
|
||||
deletePortSpec(from_edge);
|
||||
deleteTripleSeq(triples);
|
||||
stringDelete(cond);
|
||||
|
|
@ -688,6 +693,7 @@ SdfReader::device(const char *to_port_name,
|
|||
setDevicePinDelays(to_pin, triples);
|
||||
}
|
||||
}
|
||||
stringDelete(to_port_name);
|
||||
deleteTripleSeq(triples);
|
||||
}
|
||||
|
||||
|
|
@ -822,7 +828,10 @@ SdfReader::makePortSpec(Transition *tr,
|
|||
const char *port,
|
||||
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 *
|
||||
|
|
@ -837,7 +846,7 @@ SdfReader::makeCondPortSpec(const char *cond_port)
|
|||
auto cond_end = cond_port1.find_last_not_of(" ", port_idx);
|
||||
if (cond_end != cond_port1.npos) {
|
||||
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(),
|
||||
cond1.c_str());
|
||||
stringDelete(cond_port);
|
||||
|
|
@ -919,7 +928,7 @@ SdfReader::unescaped(const char *token)
|
|||
{
|
||||
char path_escape = network_->pathEscape();
|
||||
char path_divider = network_->pathDivider();
|
||||
char *unescaped = makeTmpString(strlen(token) + 1);
|
||||
char *unescaped = new char[strlen(token) + 1];
|
||||
char *u = unescaped;
|
||||
size_t token_length = strlen(token);
|
||||
|
||||
|
|
@ -962,10 +971,12 @@ char *
|
|||
SdfReader::makePath(const char *head,
|
||||
const char *tail)
|
||||
{
|
||||
char *path = stringPrintTmp("%s%c%s",
|
||||
char *path = stringPrint("%s%c%s",
|
||||
head,
|
||||
network_->pathDivider(),
|
||||
tail);
|
||||
sta::stringDelete(head);
|
||||
sta::stringDelete(tail);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
|
|
|||
103
sdf/SdfWriter.cc
103
sdf/SdfWriter.cc
|
|
@ -100,10 +100,10 @@ protected:
|
|||
void writeSdfTriple(float min,
|
||||
float max);
|
||||
void writeSdfDelay(double delay);
|
||||
char *sdfPortName(const Pin *pin);
|
||||
char *sdfPathName(const Pin *pin);
|
||||
char *sdfPathName(const Instance *inst);
|
||||
char *sdfName(const Instance *inst);
|
||||
string sdfPortName(const Pin *pin);
|
||||
string sdfPathName(const Pin *pin);
|
||||
string sdfPathName(const Instance *inst);
|
||||
string sdfName(const Instance *inst);
|
||||
|
||||
private:
|
||||
char sdf_divider_;
|
||||
|
|
@ -310,9 +310,11 @@ SdfWriter::writeInterconnectFromPin(Pin *drvr_pin)
|
|||
Edge *edge = edge_iter.next();
|
||||
if (edge->isWire()) {
|
||||
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 ",
|
||||
sdfPathName(drvr_pin),
|
||||
sdfPathName(load_pin));
|
||||
drvr_pin_name.c_str(),
|
||||
load_pin_name.c_str());
|
||||
writeArcDelays(edge);
|
||||
gzprintf(stream_, ")\n");
|
||||
}
|
||||
|
|
@ -340,7 +342,8 @@ SdfWriter::writeInstHeader(const Instance *inst)
|
|||
{
|
||||
gzprintf(stream_, " (CELL\n");
|
||||
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
|
||||
|
|
@ -384,9 +387,11 @@ SdfWriter::writeIopaths(const Instance *inst,
|
|||
gzprintf(stream_, " (COND %s\n", sdf_cond);
|
||||
gzprintf(stream_, " ");
|
||||
}
|
||||
string from_pin_name = sdfPortName(from_pin);
|
||||
string to_pin_name = sdfPortName(to_pin);
|
||||
gzprintf(stream_, " (IOPATH %s %s ",
|
||||
sdfPortName(from_pin),
|
||||
sdfPortName(to_pin));
|
||||
from_pin_name.c_str(),
|
||||
to_pin_name.c_str());
|
||||
writeArcDelays(edge);
|
||||
if (sdf_cond)
|
||||
gzprintf(stream_, ")");
|
||||
|
|
@ -651,12 +656,14 @@ SdfWriter::writeCheck(Edge *edge,
|
|||
if (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)",
|
||||
sdfEdge(arc->toEdge()),
|
||||
sdfPortName(to_pin));
|
||||
to_pin_name.c_str());
|
||||
}
|
||||
else
|
||||
gzprintf(stream_, "%s", sdfPortName(to_pin));
|
||||
gzprintf(stream_, "%s", to_pin_name.c_str());
|
||||
|
||||
if (sdf_cond_start)
|
||||
gzprintf(stream_, ")");
|
||||
|
|
@ -666,12 +673,13 @@ SdfWriter::writeCheck(Edge *edge,
|
|||
if (sdf_cond_end)
|
||||
gzprintf(stream_, "(COND %s ", sdf_cond_end);
|
||||
|
||||
string from_pin_name = sdfPortName(from_pin);
|
||||
if (use_clk_edge)
|
||||
gzprintf(stream_, "(%s %s)",
|
||||
sdfEdge(arc->fromEdge()),
|
||||
sdfPortName(from_pin));
|
||||
from_pin_name.c_str());
|
||||
else
|
||||
gzprintf(stream_, "%s", sdfPortName(from_pin));
|
||||
gzprintf(stream_, "%s", from_pin_name.c_str());
|
||||
|
||||
if (sdf_cond_end)
|
||||
gzprintf(stream_, ")");
|
||||
|
|
@ -691,9 +699,10 @@ SdfWriter::writeWidthCheck(const Pin *pin,
|
|||
float min_width,
|
||||
float max_width)
|
||||
{
|
||||
string pin_name = sdfPortName(pin);
|
||||
gzprintf(stream_, " (WIDTH (%s %s) ",
|
||||
sdfEdge(hi_low->asTransition()),
|
||||
sdfPortName(pin));
|
||||
pin_name.c_str());
|
||||
writeSdfTriple(min_width, max_width);
|
||||
gzprintf(stream_, ")\n");
|
||||
}
|
||||
|
|
@ -702,8 +711,8 @@ void
|
|||
SdfWriter::writePeriodCheck(const Pin *pin,
|
||||
float min_period)
|
||||
{
|
||||
gzprintf(stream_, " (PERIOD %s ",
|
||||
sdfPortName(pin));
|
||||
string pin_name = sdfPortName(pin);
|
||||
gzprintf(stream_, " (PERIOD %s ", pin_name.c_str());
|
||||
writeSdfTriple(min_period, min_period);
|
||||
gzprintf(stream_, ")\n");
|
||||
}
|
||||
|
|
@ -720,81 +729,68 @@ SdfWriter::sdfEdge(const Transition *tr)
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
char *
|
||||
string
|
||||
SdfWriter::sdfPathName(const Pin *pin)
|
||||
{
|
||||
Instance *inst = network_->instance(pin);
|
||||
if (network_->isTopInstance(inst))
|
||||
return sdfPortName(pin);
|
||||
else {
|
||||
char *inst_path = sdfPathName(inst);
|
||||
const char *port_name = sdfPortName(pin);
|
||||
size_t length = strlen(inst_path) + 1 + strlen(port_name) + 1;
|
||||
char *sdf_name = makeTmpString(length);
|
||||
snprintf(sdf_name, length, "%s%c%s", inst_path, sdf_divider_, port_name);
|
||||
string inst_path = sdfPathName(inst);
|
||||
string port_name = sdfPortName(pin);
|
||||
string sdf_name = inst_path;
|
||||
sdf_name += sdf_divider_;
|
||||
sdf_name += port_name;
|
||||
return sdf_name;
|
||||
}
|
||||
}
|
||||
|
||||
// Based on Network::pathName.
|
||||
char *
|
||||
string
|
||||
SdfWriter::sdfPathName(const Instance *instance)
|
||||
{
|
||||
InstanceSeq inst_path;
|
||||
network_->path(instance, inst_path);
|
||||
size_t name_length = 0;
|
||||
InstanceSeq::Iterator path_iter1(inst_path);
|
||||
while (path_iter1.hasNext()) {
|
||||
const Instance *inst = path_iter1.next();
|
||||
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()) {
|
||||
string path_name;
|
||||
while (!inst_path.empty()) {
|
||||
const Instance *inst = inst_path.back();
|
||||
const char *inst_name = sdfName(inst);
|
||||
strcpy(path_ptr, inst_name);
|
||||
path_ptr += strlen(inst_name);
|
||||
string inst_name = sdfName(inst);
|
||||
path_name += inst_name;
|
||||
inst_path.pop_back();
|
||||
if (inst_path.size())
|
||||
*path_ptr++ = sdf_divider_;
|
||||
*path_ptr = '\0';
|
||||
if (!inst_path.empty())
|
||||
path_name += sdf_divider_;
|
||||
}
|
||||
return path_name;
|
||||
}
|
||||
|
||||
// Escape for non-alpha numeric characters.
|
||||
char *
|
||||
string
|
||||
SdfWriter::sdfName(const Instance *inst)
|
||||
{
|
||||
const char *name = network_->name(inst);
|
||||
char *sdf_name = makeTmpString(strlen(name) * 2 + 1);
|
||||
string sdf_name;
|
||||
const char *p = name;
|
||||
char *s = sdf_name;
|
||||
while (*p) {
|
||||
char ch = *p;
|
||||
// Ignore sta escapes.
|
||||
if (ch != network_escape_) {
|
||||
if (!(isalnum(ch) || ch == '_'))
|
||||
// Insert escape.
|
||||
*s++ = sdf_escape_;
|
||||
*s++ = ch;
|
||||
sdf_name += sdf_escape_;
|
||||
sdf_name += ch;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
*s = '\0';
|
||||
return sdf_name;
|
||||
}
|
||||
|
||||
char *
|
||||
string
|
||||
SdfWriter::sdfPortName(const Pin *pin)
|
||||
{
|
||||
const char *name = network_->portName(pin);
|
||||
size_t name_length = strlen(name);
|
||||
char *sdf_name = makeTmpString(name_length * 2 + 1);
|
||||
char *s = sdf_name;
|
||||
string sdf_name;
|
||||
|
||||
constexpr char bus_brkt_left = '[';
|
||||
constexpr char bus_brkt_right = ']';
|
||||
|
|
@ -809,18 +805,17 @@ SdfWriter::sdfPortName(const Pin *pin)
|
|||
char ch = name[i];
|
||||
if (ch == network_escape_) {
|
||||
// Copy escape and escaped char.
|
||||
*s++ = sdf_escape_;
|
||||
*s++ = name[++i];
|
||||
sdf_name += sdf_escape_;
|
||||
sdf_name += name[++i];
|
||||
}
|
||||
else {
|
||||
if (!(isalnum(ch) || ch == '_')
|
||||
&& !(i >= bus_index && (ch == bus_brkt_right || ch == bus_brkt_left)))
|
||||
// Insert escape.
|
||||
*s++ = sdf_escape_;
|
||||
*s++ = ch;
|
||||
sdf_name += sdf_escape_;
|
||||
sdf_name += ch;
|
||||
}
|
||||
}
|
||||
*s = '\0';
|
||||
return sdf_name;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,34 +113,35 @@ ClkInfo::asString(const StaState *sta) const
|
|||
{
|
||||
Network *network = sta->network();
|
||||
Corners *corners = sta->corners();
|
||||
string str;
|
||||
string result;
|
||||
|
||||
PathAnalysisPt *path_ap = corners->findPathAnalysisPt(path_ap_index_);
|
||||
str += stringPrintTmp("%s/%d ",
|
||||
path_ap->pathMinMax()->asString(),
|
||||
path_ap_index_);
|
||||
result += path_ap->pathMinMax()->asString();
|
||||
result += "/";
|
||||
result += std::to_string(path_ap_index_);
|
||||
|
||||
if (clk_edge_)
|
||||
str += clk_edge_->name();
|
||||
result += clk_edge_->name();
|
||||
else
|
||||
str += "unclocked";
|
||||
result += "unclocked";
|
||||
|
||||
if (clk_src_) {
|
||||
str += " clk_src ";
|
||||
str += network->pathName(clk_src_);
|
||||
result += " clk_src ";
|
||||
result += network->pathName(clk_src_);
|
||||
}
|
||||
|
||||
if (!crpr_clk_path_.isNull()) {
|
||||
const Pin *crpr_clk_pin = crpr_clk_path_.vertex(sta)->pin();
|
||||
str += " crpr_pin ";
|
||||
str += network->pathName(crpr_clk_pin);
|
||||
result += " crpr_pin ";
|
||||
result += network->pathName(crpr_clk_pin);
|
||||
}
|
||||
|
||||
if (is_gen_clk_src_path_)
|
||||
str += " genclk";
|
||||
result += " genclk";
|
||||
|
||||
char *result = makeTmpString(str.size() + 1);
|
||||
strcpy(result, str.c_str());
|
||||
return result;
|
||||
char *tmp = makeTmpString(result.size() + 1);
|
||||
strcpy(tmp, result.c_str());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const Clock *
|
||||
|
|
|
|||
|
|
@ -1028,7 +1028,9 @@ getProperty(Edge *edge,
|
|||
auto graph = sta->graph();
|
||||
const char *from = edge->from(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"))
|
||||
return edgeDelayProperty(edge, RiseFall::fall(), MinMax::min(), sta);
|
||||
|
|
|
|||
|
|
@ -94,83 +94,84 @@ Tag::asString(bool report_index,
|
|||
{
|
||||
const Network *network = sta->network();
|
||||
const Corners *corners = sta->corners();
|
||||
string str;
|
||||
string result;
|
||||
|
||||
if (report_index)
|
||||
str += stringPrintTmp("%4d ", index_);
|
||||
result += std::to_string(index_);
|
||||
|
||||
if (report_rf_min_max) {
|
||||
const RiseFall *rf = transition();
|
||||
PathAnalysisPt *path_ap = corners->findPathAnalysisPt(path_ap_index_);
|
||||
str += stringPrintTmp("%s %s/%d ",
|
||||
rf->asString(),
|
||||
path_ap->pathMinMax()->asString(),
|
||||
path_ap_index_);
|
||||
result += rf->asString();
|
||||
result += " ";
|
||||
result += path_ap->pathMinMax()->asString();
|
||||
result += "/";
|
||||
result += std::to_string(path_ap_index_);
|
||||
}
|
||||
|
||||
const ClockEdge *clk_edge = clkEdge();
|
||||
if (clk_edge)
|
||||
str += clk_edge->name();
|
||||
result += clk_edge->name();
|
||||
else
|
||||
str += "unclocked";
|
||||
result += "unclocked";
|
||||
|
||||
bool is_genclk_src = clk_info_->isGenClkSrcPath();
|
||||
if (is_clk_ || is_genclk_src) {
|
||||
str += " (";
|
||||
result += " (";
|
||||
if (is_clk_) {
|
||||
str += "clock";
|
||||
result += "clock";
|
||||
if (clk_info_->isPropagated())
|
||||
str += " prop";
|
||||
result += " prop";
|
||||
else
|
||||
str += " ideal";
|
||||
result += " ideal";
|
||||
if (is_genclk_src)
|
||||
str += " ";
|
||||
result += " ";
|
||||
}
|
||||
if (clk_info_->isGenClkSrcPath())
|
||||
str += "genclk";
|
||||
str += ")";
|
||||
result += "genclk";
|
||||
result += ")";
|
||||
}
|
||||
|
||||
const Pin *clk_src = clkSrc();
|
||||
if (clk_src) {
|
||||
str += " clk_src ";
|
||||
str += network->pathName(clk_src);
|
||||
result += " clk_src ";
|
||||
result += network->pathName(clk_src);
|
||||
}
|
||||
|
||||
const PathVertex crpr_clk_path(clk_info_->crprClkPath(), sta);
|
||||
if (!crpr_clk_path.isNull()) {
|
||||
str += " crpr_pin ";
|
||||
str += network->pathName(crpr_clk_path.pin(sta));
|
||||
result += " crpr_pin ";
|
||||
result += network->pathName(crpr_clk_path.pin(sta));
|
||||
}
|
||||
|
||||
if (input_delay_) {
|
||||
str += " input ";
|
||||
str += network->pathName(input_delay_->pin());
|
||||
result += " input ";
|
||||
result += network->pathName(input_delay_->pin());
|
||||
}
|
||||
|
||||
if (is_segment_start_)
|
||||
str += " segment_start";
|
||||
result += " segment_start";
|
||||
|
||||
if (states_) {
|
||||
for (ExceptionState *state : *states_) {
|
||||
ExceptionPath *exception = state->exception();
|
||||
str += " ";
|
||||
str += exception->asString(network);
|
||||
result += " ";
|
||||
result += exception->asString(network);
|
||||
if (state->nextThru()) {
|
||||
str += " (next thru ";
|
||||
str += state->nextThru()->asString(network);
|
||||
str += ")";
|
||||
result += " (next thru ";
|
||||
result += state->nextThru()->asString(network);
|
||||
result += ")";
|
||||
}
|
||||
else {
|
||||
if (exception->thrus() != nullptr)
|
||||
str += " (thrus complete)";
|
||||
result += " (thrus complete)";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *result = makeTmpString(str.size() + 1);
|
||||
strcpy(result, str.c_str());
|
||||
return result;
|
||||
char *tmp = makeTmpString(result.size() + 1);
|
||||
strcpy(tmp, result.c_str());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const RiseFall *
|
||||
|
|
|
|||
|
|
@ -57,6 +57,18 @@ PatternMatch::PatternMatch(const char *pattern,
|
|||
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
|
||||
PatternMatch::compileRegexp()
|
||||
{
|
||||
|
|
@ -89,6 +101,12 @@ PatternMatch::hasWildcards() const
|
|||
return patternWildcards(pattern_);
|
||||
}
|
||||
|
||||
bool
|
||||
PatternMatch::match(const string &str) const
|
||||
{
|
||||
return match(str.c_str());
|
||||
}
|
||||
|
||||
bool
|
||||
PatternMatch::match(const char *str) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ inst_named_pins:
|
|||
inst_named_pin:
|
||||
// Scalar port.
|
||||
'.' ID '(' ')'
|
||||
{ $$ = sta::verilog_reader->makeNetNamedPortRefScalarNet($2, NULL); }
|
||||
{ $$ = sta::verilog_reader->makeNetNamedPortRefScalarNet($2); }
|
||||
| '.' ID '(' ID ')'
|
||||
{ $$ = sta::verilog_reader->makeNetNamedPortRefScalarNet($2, $4); }
|
||||
| '.' ID '(' ID '[' INT ']' ')'
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ namespace sta {
|
|||
VerilogReader *verilog_reader;
|
||||
static const char *unconnected_net_name = reinterpret_cast<const char*>(1);
|
||||
|
||||
static const char *
|
||||
verilogBusBitNameTmp(const char *bus_name,
|
||||
static string
|
||||
verilogBusBitName(const char *bus_name,
|
||||
int index);
|
||||
static int
|
||||
hierarchyLevel(Net *net,
|
||||
|
|
@ -255,17 +255,18 @@ VerilogReader::makeModule(const char *module_vname,
|
|||
VerilogStmtSeq *stmts,
|
||||
int line)
|
||||
{
|
||||
const char *module_name = moduleVerilogToSta(module_vname);
|
||||
Cell *cell = network_->findCell(library_, module_name);
|
||||
string module_name = moduleVerilogToSta(module_vname);
|
||||
Cell *cell = network_->findCell(library_, module_name.c_str());
|
||||
if (cell) {
|
||||
VerilogModule *module = module_map_[cell];
|
||||
delete module;
|
||||
module_map_.erase(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);
|
||||
cell = network_->makeCell(library_, module_name, false, filename_);
|
||||
cell = network_->makeCell(library_, module_name.c_str(), false, filename_);
|
||||
module_map_[cell] = module;
|
||||
makeCellPorts(cell, module, ports);
|
||||
module_count_++;
|
||||
|
|
@ -300,26 +301,25 @@ VerilogReader::makeCellPorts(Cell *cell,
|
|||
VerilogModule *module,
|
||||
VerilogNetSeq *ports)
|
||||
{
|
||||
StringSet port_names;
|
||||
set<string> port_names;
|
||||
for (VerilogNet *mod_port : *ports) {
|
||||
const char *port_name = mod_port->name();
|
||||
if (port_names.findKey(port_name) == nullptr) {
|
||||
port_names.insert(stringCopy(port_name));
|
||||
const string &port_name = mod_port->name();
|
||||
if (port_names.find(port_name) == port_names.end()) {
|
||||
port_names.insert(port_name);
|
||||
if (mod_port->isNamed()) {
|
||||
if (mod_port->isNamedPortRef())
|
||||
makeNamedPortRefCellPorts(cell, module, mod_port, port_names);
|
||||
else
|
||||
makeCellPort(cell, module, mod_port->name());
|
||||
makeCellPort(cell, module, mod_port->name().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
warn(165, module->filename(), module->line(),
|
||||
"module %s repeated port name %s.",
|
||||
module->name(),
|
||||
port_name);
|
||||
port_name.c_str());
|
||||
}
|
||||
checkModuleDcls(module, port_names);
|
||||
deleteContents(&port_names);
|
||||
}
|
||||
|
||||
Port *
|
||||
|
|
@ -351,25 +351,25 @@ void
|
|||
VerilogReader::makeNamedPortRefCellPorts(Cell *cell,
|
||||
VerilogModule *module,
|
||||
VerilogNet *mod_port,
|
||||
StringSet &port_names)
|
||||
set<string> &port_names)
|
||||
{
|
||||
PortSeq *member_ports = new PortSeq;
|
||||
VerilogNetNameIterator *net_name_iter = mod_port->nameIterator(module,this);
|
||||
while (net_name_iter->hasNext()) {
|
||||
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);
|
||||
member_ports->push_back(port);
|
||||
}
|
||||
delete net_name_iter;
|
||||
// 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.
|
||||
void
|
||||
VerilogReader::checkModuleDcls(VerilogModule *module,
|
||||
StringSet &port_names)
|
||||
set<string> &port_names)
|
||||
{
|
||||
VerilogDclMap::ConstIterator dcl_iter(module->declarationMap());
|
||||
while (dcl_iter.hasNext()) {
|
||||
|
|
@ -380,7 +380,7 @@ VerilogReader::checkModuleDcls(VerilogModule *module,
|
|||
if (dir->isInput()
|
||||
|| dir->isOutput()
|
||||
|| dir->isBidirect()) {
|
||||
if (port_names.findKey(port_name) == nullptr)
|
||||
if (port_names.find(port_name) == port_names.end())
|
||||
linkWarn(197, module->filename(), module->line(),
|
||||
"module %s declared signal %s is not in the port list.",
|
||||
module->name(),
|
||||
|
|
@ -457,8 +457,8 @@ VerilogDclArg *
|
|||
VerilogReader::makeDclArg(const char *net_vname)
|
||||
{
|
||||
dcl_arg_count_++;
|
||||
const char *net_name = netVerilogToSta(net_vname);
|
||||
VerilogDclArg *dcl =new VerilogDclArg(net_name);
|
||||
string net_name = netVerilogToSta(net_vname);
|
||||
VerilogDclArg *dcl =new VerilogDclArg(net_name.c_str());
|
||||
stringDelete(net_vname);
|
||||
return dcl;
|
||||
}
|
||||
|
|
@ -478,8 +478,9 @@ VerilogReader::makeNetPartSelect(const char *net_vname,
|
|||
net_part_select_count_++;
|
||||
if (report_stmt_stats_)
|
||||
net_bus_names_ += strlen(net_vname) + 1;
|
||||
const char *net_name = netVerilogToSta(net_vname);
|
||||
VerilogNetPartSelect *select = new VerilogNetPartSelect(net_name, from_index,
|
||||
string net_name = netVerilogToSta(net_vname);
|
||||
VerilogNetPartSelect *select = new VerilogNetPartSelect(net_name.c_str(),
|
||||
from_index,
|
||||
to_index);
|
||||
stringDelete(net_vname);
|
||||
return select;
|
||||
|
|
@ -498,8 +499,8 @@ VerilogReader::makeNetScalar(const char *net_vname)
|
|||
net_scalar_count_++;
|
||||
if (report_stmt_stats_)
|
||||
net_scalar_names_ += strlen(net_vname) + 1;
|
||||
const char *net_name = netVerilogToSta(net_vname);
|
||||
VerilogNetScalar *scalar = new VerilogNetScalar(net_name);
|
||||
string net_name = netVerilogToSta(net_vname);
|
||||
VerilogNetScalar *scalar = new VerilogNetScalar(net_name.c_str());
|
||||
stringDelete(net_vname);
|
||||
return scalar;
|
||||
}
|
||||
|
|
@ -511,8 +512,8 @@ VerilogReader::makeNetBitSelect(const char *net_vname,
|
|||
net_bit_select_count_++;
|
||||
if (report_stmt_stats_)
|
||||
net_bus_names_ += strlen(net_vname) + 1;
|
||||
const char *net_name = netVerilogToSta(net_vname);
|
||||
VerilogNetBitSelect *select = new VerilogNetBitSelect(net_name, index);
|
||||
string net_name = netVerilogToSta(net_vname);
|
||||
VerilogNetBitSelect *select = new VerilogNetBitSelect(net_name.c_str(), index);
|
||||
stringDelete(net_vname);
|
||||
return select;
|
||||
}
|
||||
|
|
@ -532,9 +533,9 @@ VerilogReader::makeModuleInst(const char *module_vname,
|
|||
VerilogNetSeq *pins,
|
||||
const int line)
|
||||
{
|
||||
const char *module_name = moduleVerilogToSta(module_vname);
|
||||
const char *inst_name = instanceVerilogToSta(inst_vname);
|
||||
Cell *cell = network_->findAnyCell(module_name);
|
||||
string module_name = moduleVerilogToSta(module_vname);
|
||||
string inst_name = instanceVerilogToSta(inst_vname);
|
||||
Cell *cell = network_->findAnyCell(module_name.c_str());
|
||||
LibertyCell *liberty_cell = nullptr;
|
||||
if (cell)
|
||||
liberty_cell = network_->libertyCell(cell);
|
||||
|
|
@ -549,7 +550,7 @@ VerilogReader::makeModuleInst(const char *module_vname,
|
|||
for (VerilogNet *vnet : *pins) {
|
||||
VerilogNetPortRefScalarNet *vpin =
|
||||
dynamic_cast<VerilogNetPortRefScalarNet*>(vnet);
|
||||
const char *port_name = vpin->name();
|
||||
const char *port_name = vpin->name().c_str();
|
||||
const char *net_name = vpin->netName();
|
||||
// Steal the net name string.
|
||||
vpin->setNetName(nullptr);
|
||||
|
|
@ -569,11 +570,11 @@ VerilogReader::makeModuleInst(const char *module_vname,
|
|||
delete vpin;
|
||||
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);
|
||||
delete pins;
|
||||
if (report_stmt_stats_) {
|
||||
inst_names_ += strlen(inst_name) + 1;
|
||||
inst_names_ += inst_name.size() + 1;
|
||||
inst_lib_count_++;
|
||||
inst_lib_net_arrays_ += port_count;
|
||||
}
|
||||
|
|
@ -582,10 +583,12 @@ VerilogReader::makeModuleInst(const char *module_vname,
|
|||
return inst;
|
||||
}
|
||||
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_) {
|
||||
inst_module_names_ += strlen(module_name) + 1;
|
||||
inst_names_ += strlen(inst_name) + 1;
|
||||
inst_module_names_ += module_name.size() + 1;
|
||||
inst_names_ += inst_name.size() + 1;
|
||||
inst_mod_count_++;
|
||||
}
|
||||
stringDelete(module_vname);
|
||||
|
|
@ -602,7 +605,7 @@ VerilogReader::hasScalarNamedPortRefs(LibertyCell *liberty_cell,
|
|||
&& pins->size() > 0
|
||||
&& (*pins)[0]->isNamedPortRef()) {
|
||||
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);
|
||||
if (port) {
|
||||
if (!(port->size() == 1
|
||||
|
|
@ -618,6 +621,18 @@ VerilogReader::hasScalarNamedPortRefs(LibertyCell *liberty_cell,
|
|||
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 *
|
||||
VerilogReader::makeNetNamedPortRefScalarNet(const char *port_vname,
|
||||
const char *net_vname)
|
||||
|
|
@ -628,9 +643,10 @@ VerilogReader::makeNetNamedPortRefScalarNet(const char *port_vname,
|
|||
net_scalar_names_ += strlen(net_vname) + 1;
|
||||
port_names_ += strlen(port_vname) + 1;
|
||||
}
|
||||
const char *port_name = portVerilogToSta(port_vname);
|
||||
const char *net_name = netVerilogToSta(net_vname);
|
||||
VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name, net_name);
|
||||
string port_name = portVerilogToSta(port_vname);
|
||||
string net_name = netVerilogToSta(net_vname);
|
||||
VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name.c_str(),
|
||||
net_name.c_str());
|
||||
stringDelete(port_vname);
|
||||
stringDelete(net_vname);
|
||||
return ref;
|
||||
|
|
@ -642,14 +658,15 @@ VerilogReader::makeNetNamedPortRefBitSelect(const char *port_vname,
|
|||
int index)
|
||||
{
|
||||
net_port_ref_scalar_net_count_++;
|
||||
const char *bus_name = portVerilogToSta(bus_vname);
|
||||
const char *net_name = verilogBusBitNameTmp(bus_name, index);
|
||||
string bus_name = portVerilogToSta(bus_vname);
|
||||
string net_name = verilogBusBitName(bus_name.c_str(), index);
|
||||
if (report_stmt_stats_) {
|
||||
net_scalar_names_ += strlen(net_name) + 1;
|
||||
net_scalar_names_ += net_name.length() + 1;
|
||||
port_names_ += strlen(port_vname) + 1;
|
||||
}
|
||||
const char *port_name = portVerilogToSta(port_vname);
|
||||
VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name, net_name);
|
||||
string port_name = portVerilogToSta(port_vname);
|
||||
VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name.c_str(),
|
||||
net_name.c_str());
|
||||
stringDelete(port_vname);
|
||||
stringDelete(bus_vname);
|
||||
return ref;
|
||||
|
|
@ -662,8 +679,8 @@ VerilogReader::makeNetNamedPortRefScalar(const char *port_vname,
|
|||
net_port_ref_scalar_count_++;
|
||||
if (report_stmt_stats_)
|
||||
port_names_ += strlen(port_vname) + 1;
|
||||
const char *port_name = portVerilogToSta(port_vname);
|
||||
VerilogNetPortRef *ref = new VerilogNetPortRefScalar(port_name, net);
|
||||
string port_name = portVerilogToSta(port_vname);
|
||||
VerilogNetPortRef *ref = new VerilogNetPortRefScalar(port_name.c_str(), net);
|
||||
stringDelete(port_vname);
|
||||
return ref;
|
||||
}
|
||||
|
|
@ -674,8 +691,9 @@ VerilogReader::makeNetNamedPortRefBit(const char *port_vname,
|
|||
VerilogNet *net)
|
||||
{
|
||||
net_port_ref_bit_count_++;
|
||||
const char *port_name = portVerilogToSta(port_vname);
|
||||
VerilogNetPortRef *ref = new VerilogNetPortRefBit(port_name, index, net);
|
||||
string port_name = portVerilogToSta(port_vname);
|
||||
VerilogNetPortRef *ref = new VerilogNetPortRefBit(port_name.c_str(),
|
||||
index, net);
|
||||
stringDelete(port_vname);
|
||||
return ref;
|
||||
}
|
||||
|
|
@ -687,8 +705,9 @@ VerilogReader::makeNetNamedPortRefPart(const char *port_vname,
|
|||
VerilogNet *net)
|
||||
{
|
||||
net_port_ref_part_count_++;
|
||||
const char *port_name = portVerilogToSta(port_vname);
|
||||
VerilogNetPortRef *ref = new VerilogNetPortRefPart(port_name, from_index,
|
||||
string port_name = portVerilogToSta(port_vname);
|
||||
VerilogNetPortRef *ref = new VerilogNetPortRefPart(port_name.c_str(),
|
||||
from_index,
|
||||
to_index, net);
|
||||
stringDelete(port_vname);
|
||||
return ref;
|
||||
|
|
@ -776,20 +795,20 @@ VerilogReader::warn(int id,
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
const char *
|
||||
string
|
||||
VerilogReader::verilogName(VerilogModuleInst *mod_inst)
|
||||
{
|
||||
return sta::instanceVerilogName(mod_inst->instanceName(),
|
||||
network_->pathEscape());
|
||||
}
|
||||
|
||||
const char *
|
||||
string
|
||||
VerilogReader::instanceVerilogName(const char *inst_name)
|
||||
{
|
||||
return sta::netVerilogName(inst_name, network_->pathEscape());
|
||||
}
|
||||
|
||||
const char *
|
||||
string
|
||||
VerilogReader::netVerilogName(const char *net_name)
|
||||
{
|
||||
return sta::netVerilogName(net_name, network_->pathEscape());
|
||||
|
|
@ -862,12 +881,14 @@ VerilogModule::parseDcl(VerilogDcl *dcl,
|
|||
// supply0/supply1 dcl can be used as modifier for
|
||||
// input/output/inout dcls.
|
||||
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(),
|
||||
"signal %s previously declared on line %d.",
|
||||
reader->netVerilogName(net_name),
|
||||
net_vname.c_str(),
|
||||
existing_dcl->line());
|
||||
}
|
||||
}
|
||||
else
|
||||
dcl_map_[net_name] = dcl;
|
||||
}
|
||||
|
|
@ -890,9 +911,10 @@ VerilogModule::checkInstanceName(VerilogInst *inst,
|
|||
stringDelete(replacement_name);
|
||||
replacement_name = stringPrint("%s_%d", inst_name, i);
|
||||
} while (inst_names.findKey(replacement_name));
|
||||
string inst_vname = reader->instanceVerilogName(inst_name);
|
||||
reader->warn(19, filename_, inst->line(),
|
||||
"instance name %s duplicated - renamed to %s.",
|
||||
reader->instanceVerilogName(inst_name),
|
||||
inst_vname.c_str(),
|
||||
replacement_name);
|
||||
inst_name = replacement_name;
|
||||
inst->setInstanceName(inst_name);
|
||||
|
|
@ -1078,7 +1100,7 @@ VerilogDclArg::netName()
|
|||
if (net_name_)
|
||||
return net_name_;
|
||||
else if (assign_)
|
||||
return assign_->lhs()->name();
|
||||
return assign_->lhs()->name().c_str();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -1112,6 +1134,7 @@ class VerilogOneNetNameIterator : public VerilogNetNameIterator
|
|||
{
|
||||
public:
|
||||
explicit VerilogOneNetNameIterator(const char *name);
|
||||
explicit VerilogOneNetNameIterator(string name);
|
||||
virtual bool hasNext();
|
||||
virtual const char *next();
|
||||
|
||||
|
|
@ -1152,6 +1175,7 @@ protected:
|
|||
int from_index_;
|
||||
int to_index_;
|
||||
int index_;
|
||||
string bit_name_;
|
||||
};
|
||||
|
||||
VerilogBusNetNameIterator::VerilogBusNetNameIterator(const char *bus_name,
|
||||
|
|
@ -1176,19 +1200,21 @@ VerilogBusNetNameIterator::hasNext()
|
|||
const char *
|
||||
VerilogBusNetNameIterator::next()
|
||||
{
|
||||
const char *bit_name = verilogBusBitNameTmp(bus_name_, index_);
|
||||
bit_name_ = verilogBusBitName(bus_name_, index_);
|
||||
if (to_index_ > from_index_)
|
||||
index_++;
|
||||
else
|
||||
index_--;
|
||||
return bit_name;
|
||||
return bit_name_.c_str();
|
||||
}
|
||||
|
||||
static const char *
|
||||
verilogBusBitNameTmp(const char *bus_name,
|
||||
static string
|
||||
verilogBusBitName(const char *bus_name,
|
||||
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
|
||||
|
|
@ -1291,21 +1317,27 @@ VerilogNetConcatNameIterator::next()
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
const string VerilogNetUnnamed::null_;
|
||||
|
||||
VerilogNetNamed::VerilogNetNamed(const char *name) :
|
||||
VerilogNet(),
|
||||
name_(stringCopy(name))
|
||||
name_(name)
|
||||
{
|
||||
}
|
||||
|
||||
VerilogNetNamed::VerilogNetNamed(const string &name) :
|
||||
VerilogNet(),
|
||||
name_(name)
|
||||
{
|
||||
}
|
||||
|
||||
VerilogNetNamed::~VerilogNetNamed()
|
||||
{
|
||||
stringDelete(name_);
|
||||
}
|
||||
|
||||
void
|
||||
VerilogNetNamed::setName(const char *name)
|
||||
{
|
||||
stringDelete(name_);
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
|
|
@ -1329,7 +1361,7 @@ verilogNetScalarSize(const char *name,
|
|||
int
|
||||
VerilogNetScalar::size(VerilogModule *module)
|
||||
{
|
||||
return verilogNetScalarSize(name_, module);
|
||||
return verilogNetScalarSize(name_.c_str(), module);
|
||||
}
|
||||
|
||||
static VerilogNetNameIterator *
|
||||
|
|
@ -1354,22 +1386,16 @@ VerilogNetNameIterator *
|
|||
VerilogNetScalar::nameIterator(VerilogModule *module,
|
||||
VerilogReader *)
|
||||
{
|
||||
return verilogNetScalarNameIterator(name_, module);
|
||||
return verilogNetScalarNameIterator(name_.c_str(), module);
|
||||
}
|
||||
|
||||
VerilogNetBitSelect::VerilogNetBitSelect(const char *name,
|
||||
int index) :
|
||||
VerilogNetNamed(name),
|
||||
VerilogNetNamed(verilogBusBitName(name, index)),
|
||||
index_(index)
|
||||
{
|
||||
}
|
||||
|
||||
const char *
|
||||
VerilogNetBitSelect::name()
|
||||
{
|
||||
return verilogBusBitNameTmp(name_, index_);
|
||||
}
|
||||
|
||||
int
|
||||
VerilogNetBitSelect::size(VerilogModule *)
|
||||
{
|
||||
|
|
@ -1380,7 +1406,7 @@ VerilogNetNameIterator *
|
|||
VerilogNetBitSelect::nameIterator(VerilogModule *,
|
||||
VerilogReader *)
|
||||
{
|
||||
return new VerilogOneNetNameIterator(verilogBusBitNameTmp(name_, index_));
|
||||
return new VerilogOneNetNameIterator(name_.c_str());
|
||||
}
|
||||
|
||||
VerilogNetPartSelect::VerilogNetPartSelect(const char *name,
|
||||
|
|
@ -1405,7 +1431,7 @@ VerilogNetNameIterator *
|
|||
VerilogNetPartSelect::nameIterator(VerilogModule *,
|
||||
VerilogReader *)
|
||||
{
|
||||
return new VerilogBusNetNameIterator(name_, from_index_, to_index_);
|
||||
return new VerilogBusNetNameIterator(name_.c_str(), from_index_, to_index_);
|
||||
}
|
||||
|
||||
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,
|
||||
const char *net_name) :
|
||||
VerilogNetPortRef(name),
|
||||
|
|
@ -1651,16 +1683,10 @@ VerilogNetPortRefBit::VerilogNetPortRefBit(const char *name,
|
|||
int index,
|
||||
VerilogNet *net) :
|
||||
VerilogNetPortRefScalar(name, net),
|
||||
index_(index)
|
||||
bit_name_(verilogBusBitName(name, index))
|
||||
{
|
||||
}
|
||||
|
||||
const char *
|
||||
VerilogNetPortRefBit::name()
|
||||
{
|
||||
return verilogBusBitNameTmp(name_, index_);
|
||||
}
|
||||
|
||||
VerilogNetPortRefPart::VerilogNetPortRefPart(const char *name,
|
||||
int from_index,
|
||||
int to_index,
|
||||
|
|
@ -1670,8 +1696,8 @@ VerilogNetPortRefPart::VerilogNetPortRefPart(const char *name,
|
|||
{
|
||||
}
|
||||
|
||||
const char *
|
||||
VerilogNetPortRefPart::name()
|
||||
const string &
|
||||
VerilogNetPortRefPart::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
|
@ -1813,18 +1839,19 @@ VerilogReader::makeModuleInstNetwork(VerilogModuleInst *mod_inst,
|
|||
const char *module_name = mod_inst->moduleName();
|
||||
Cell *cell = network_->findAnyCell(module_name);
|
||||
if (cell == nullptr) {
|
||||
string inst_vname = verilogName(mod_inst);
|
||||
if (make_black_boxes) {
|
||||
cell = makeBlackBox(mod_inst, parent_module);
|
||||
linkWarn(198, parent_module->filename(), mod_inst->line(),
|
||||
"module %s not found. Creating black box for %s.",
|
||||
mod_inst->moduleName(),
|
||||
verilogName(mod_inst));
|
||||
inst_vname.c_str());
|
||||
}
|
||||
else
|
||||
linkError(199, parent_module->filename(), mod_inst->line(),
|
||||
"module %s not found for instance %s.",
|
||||
mod_inst->moduleName(),
|
||||
verilogName(mod_inst));
|
||||
inst_vname.c_str());
|
||||
}
|
||||
if (cell) {
|
||||
LibertyCell *lib_cell = network_->libertyCell(cell);
|
||||
|
|
@ -1868,20 +1895,22 @@ VerilogReader::makeNamedInstPins(Cell *cell,
|
|||
VerilogBindingTbl *parent_bindings,
|
||||
bool is_leaf)
|
||||
{
|
||||
string inst_vname = verilogName(mod_inst);
|
||||
VerilogNetSeq::Iterator pin_iter(mod_inst->pins());
|
||||
while (pin_iter.hasNext()) {
|
||||
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);
|
||||
if (port) {
|
||||
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(),
|
||||
"instance %s port %s size %d does not match net size %d.",
|
||||
verilogName(mod_inst),
|
||||
inst_vname.c_str(),
|
||||
network_->name(port),
|
||||
network_->size(port),
|
||||
vpin->size(parent_module));
|
||||
}
|
||||
else {
|
||||
VerilogNetNameIterator *net_name_iter =
|
||||
vpin->nameIterator(parent_module, this);
|
||||
|
|
@ -1907,14 +1936,15 @@ VerilogReader::makeNamedInstPins(Cell *cell,
|
|||
if (lib_cell)
|
||||
pg_port = lib_cell->findPgPort(port_name);
|
||||
// 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(),
|
||||
"instance %s port %s not found.",
|
||||
verilogName(mod_inst),
|
||||
inst_vname.c_str(),
|
||||
port_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VerilogReader::makeOrderedInstPins(Cell *cell,
|
||||
|
|
@ -1931,13 +1961,15 @@ VerilogReader::makeOrderedInstPins(Cell *cell,
|
|||
while (pin_iter.hasNext() && port_iter->hasNext()) {
|
||||
VerilogNet *net = pin_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(),
|
||||
"instance %s port %s size %d does not match net size %d.",
|
||||
verilogName(mod_inst),
|
||||
inst_vname.c_str(),
|
||||
network_->name(port),
|
||||
network_->size(port),
|
||||
net->size(parent_module));
|
||||
}
|
||||
else {
|
||||
VerilogNetNameIterator *net_name_iter=net->nameIterator(parent_module,
|
||||
this);
|
||||
|
|
@ -2027,9 +2059,8 @@ VerilogReader::makeLibertyInst(VerilogLibertyInst *lib_inst,
|
|||
if (dcl && dcl->isBus()) {
|
||||
VerilogDclBus *dcl_bus = dynamic_cast<VerilogDclBus *>(dcl);
|
||||
// Bus is only 1 bit wide.
|
||||
const char *bus_name = verilogBusBitNameTmp(net_name,
|
||||
dcl_bus->fromIndex());
|
||||
net = parent_bindings->ensureNetBinding(bus_name, parent, network_);
|
||||
string bus_name = verilogBusBitName(net_name, dcl_bus->fromIndex());
|
||||
net = parent_bindings->ensureNetBinding(bus_name.c_str(), parent, network_);
|
||||
}
|
||||
else
|
||||
net = parent_bindings->ensureNetBinding(net_name, parent, network_);
|
||||
|
|
@ -2066,7 +2097,7 @@ VerilogReader::makeBlackBoxNamedPorts(Cell *cell,
|
|||
VerilogNetSeq::Iterator pin_iter(mod_inst->pins());
|
||||
while (pin_iter.hasNext()) {
|
||||
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);
|
||||
Port *port = (size == 1)
|
||||
? network_->makePort(cell, port_name)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ VerilogParse_error(const char *msg);
|
|||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::set;
|
||||
|
||||
class Debug;
|
||||
class Report;
|
||||
class VerilogReader;
|
||||
|
|
@ -117,6 +120,7 @@ public:
|
|||
VerilogNet *rhs,
|
||||
int line);
|
||||
VerilogNetScalar *makeNetScalar(const char *name);
|
||||
VerilogNetPortRef *makeNetNamedPortRefScalarNet(const char *port_vname);
|
||||
VerilogNetPortRef *makeNetNamedPortRefScalarNet(const char *port_name,
|
||||
const char *net_name);
|
||||
VerilogNetPortRef *makeNetNamedPortRefBitSelect(const char *port_name,
|
||||
|
|
@ -160,11 +164,11 @@ public:
|
|||
void reportStmtCounts();
|
||||
const char *constant10Max() const { return constant10_max_; }
|
||||
size_t constant10MaxLength() const { return constant10_max_length_; }
|
||||
const char *
|
||||
string
|
||||
verilogName(VerilogModuleInst *inst);
|
||||
const char *
|
||||
string
|
||||
instanceVerilogName(const char *inst_name);
|
||||
const char *
|
||||
string
|
||||
netVerilogName(const char *net_name);
|
||||
|
||||
protected:
|
||||
|
|
@ -178,9 +182,9 @@ protected:
|
|||
void makeNamedPortRefCellPorts(Cell *cell,
|
||||
VerilogModule *module,
|
||||
VerilogNet *mod_port,
|
||||
StringSet &port_names);
|
||||
set<string> &port_names);
|
||||
void checkModuleDcls(VerilogModule *module,
|
||||
StringSet &port_names);
|
||||
set<string> &port_names);
|
||||
void makeModuleInstBody(VerilogModule *module,
|
||||
Instance *inst,
|
||||
VerilogBindingTbl *bindings,
|
||||
|
|
@ -488,8 +492,8 @@ class VerilogNet
|
|||
public:
|
||||
VerilogNet() {}
|
||||
virtual ~VerilogNet() {}
|
||||
virtual bool isNamed() = 0;
|
||||
virtual const char *name() = 0;
|
||||
virtual bool isNamed() const = 0;
|
||||
virtual const string &name() const = 0;
|
||||
virtual bool isNamedPortRef() { return false; }
|
||||
virtual bool isNamedPortRefScalarNet() const { return false; }
|
||||
virtual int size(VerilogModule *module) = 0;
|
||||
|
|
@ -503,23 +507,27 @@ class VerilogNetUnnamed : public VerilogNet
|
|||
{
|
||||
public:
|
||||
VerilogNetUnnamed() {}
|
||||
virtual bool isNamed() { return false; }
|
||||
virtual const char *name() { return nullptr; }
|
||||
bool isNamed() const override { return false; }
|
||||
const string &name() const override { return null_; }
|
||||
|
||||
private:
|
||||
static const string null_;
|
||||
};
|
||||
|
||||
class VerilogNetNamed : public VerilogNet
|
||||
{
|
||||
public:
|
||||
explicit VerilogNetNamed(const char *name);
|
||||
explicit VerilogNetNamed(const string &name);
|
||||
virtual ~VerilogNetNamed();
|
||||
virtual bool isNamed() { return true; }
|
||||
bool isNamed() const override { return true; }
|
||||
virtual bool isScalar() const = 0;
|
||||
virtual const char *name() { return name_; }
|
||||
const char *baseName() { return name_; }
|
||||
const string &name() const override { return name_; }
|
||||
const string baseName() const { return name_; }
|
||||
void setName(const char *name);
|
||||
|
||||
protected:
|
||||
const char *name_;
|
||||
string name_;
|
||||
};
|
||||
|
||||
// Named net reference, which could be the name of a scalar or bus signal.
|
||||
|
|
@ -538,7 +546,6 @@ class VerilogNetBitSelect : public VerilogNetNamed
|
|||
public:
|
||||
VerilogNetBitSelect(const char *name,
|
||||
int index);
|
||||
virtual const char *name();
|
||||
int index() { return index_; }
|
||||
virtual bool isScalar() const { return false; }
|
||||
virtual int size(VerilogModule *module);
|
||||
|
|
@ -620,6 +627,7 @@ public:
|
|||
class VerilogNetPortRefScalarNet : public VerilogNetPortRef
|
||||
{
|
||||
public:
|
||||
VerilogNetPortRefScalarNet(const char *name);
|
||||
VerilogNetPortRefScalarNet(const char *name,
|
||||
const char *net_name);
|
||||
virtual ~VerilogNetPortRefScalarNet();
|
||||
|
|
@ -658,10 +666,10 @@ public:
|
|||
VerilogNetPortRefBit(const char *name,
|
||||
int index,
|
||||
VerilogNet *net);
|
||||
virtual const char *name();
|
||||
const string &name() const override { return bit_name_; }
|
||||
|
||||
private:
|
||||
int index_;
|
||||
string bit_name_;
|
||||
};
|
||||
|
||||
class VerilogNetPortRefPart : public VerilogNetPortRefBit
|
||||
|
|
@ -671,7 +679,7 @@ public:
|
|||
int from_index,
|
||||
int to_index,
|
||||
VerilogNet *net);
|
||||
virtual const char *name();
|
||||
const string &name() const override;
|
||||
int toIndex() const { return to_index_; }
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -159,8 +159,9 @@ VerilogWriter::writePorts(Cell *cell)
|
|||
|| !network_->direction(port)->isPowerGround()) {
|
||||
if (!first)
|
||||
fprintf(stream_, ",\n ");
|
||||
fprintf(stream_, "%s", portVerilogName(network_->name(port),
|
||||
network_->pathEscape()));
|
||||
string verillg_name = portVerilogName(network_->name(port),
|
||||
network_->pathEscape());
|
||||
fprintf(stream_, "%s", verillg_name.c_str());
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -177,7 +178,7 @@ VerilogWriter::writePortDcls(Cell *cell)
|
|||
PortDirection *dir = network_->direction(port);
|
||||
if (include_pwr_gnd_
|
||||
|| !network_->direction(port)->isPowerGround()) {
|
||||
const char *port_name = portVerilogName(network_->name(port),
|
||||
string port_vname = portVerilogName(network_->name(port),
|
||||
network_->pathEscape());
|
||||
const char *vtype = verilogPortDir(dir);
|
||||
if (vtype) {
|
||||
|
|
@ -186,14 +187,14 @@ VerilogWriter::writePortDcls(Cell *cell)
|
|||
fprintf(stream_, " [%d:%d]",
|
||||
network_->fromIndex(port),
|
||||
network_->toIndex(port));
|
||||
fprintf(stream_, " %s;\n", port_name);
|
||||
fprintf(stream_, " %s;\n", port_vname.c_str());
|
||||
if (dir->isTristate()) {
|
||||
fprintf(stream_, " tri");
|
||||
if (network_->isBus(port))
|
||||
fprintf(stream_, " [%d:%d]",
|
||||
network_->fromIndex(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);
|
||||
if (network_->findPort(cell, net_name) == nullptr) {
|
||||
if (isBusName(net_name, '[', ']', escape)) {
|
||||
char *bus_name;
|
||||
bool is_bus;
|
||||
string bus_name;
|
||||
int index;
|
||||
parseBusName(net_name, '[', ']', escape, bus_name, index);
|
||||
BusIndexRange &range = bus_ranges[bus_name];
|
||||
parseBusName(net_name, '[', ']', escape, is_bus, bus_name, index);
|
||||
BusIndexRange &range = bus_ranges[bus_name.c_str()];
|
||||
range.first = max(range.first, index);
|
||||
range.second = min(range.second, index);
|
||||
}
|
||||
else
|
||||
fprintf(stream_, " wire %s;\n",
|
||||
netVerilogName(net_name, network_->pathEscape()));;
|
||||
else {
|
||||
string net_vname = netVerilogName(net_name, network_->pathEscape());
|
||||
fprintf(stream_, " wire %s;\n", net_vname.c_str());;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete net_iter;
|
||||
|
|
@ -255,10 +258,11 @@ VerilogWriter::writeWireDcls(Instance *inst)
|
|||
for (auto name_range : bus_ranges) {
|
||||
const char *bus_name = name_range.first;
|
||||
const BusIndexRange &range = name_range.second;
|
||||
string net_vname = netVerilogName(bus_name, network_->pathEscape());
|
||||
fprintf(stream_, " wire [%d:%d] %s;\n",
|
||||
range.first,
|
||||
range.second,
|
||||
netVerilogName(bus_name, network_->pathEscape()));;
|
||||
net_vname.c_str());;
|
||||
}
|
||||
|
||||
// Wire net dcls for writeInstBusPinBit.
|
||||
|
|
@ -297,11 +301,10 @@ VerilogWriter::writeChild(Instance *child)
|
|||
Cell *child_cell = network_->cell(child);
|
||||
if (!remove_cells_.hasKey(child_cell)) {
|
||||
const char *child_name = network_->name(child);
|
||||
const char *child_vname = instanceVerilogName(child_name,
|
||||
network_->pathEscape());
|
||||
string child_vname = instanceVerilogName(child_name, network_->pathEscape());
|
||||
fprintf(stream_, " %s %s (",
|
||||
network_->name(child_cell),
|
||||
child_vname);
|
||||
child_vname.c_str());
|
||||
bool first_port = true;
|
||||
CellPortIterator *port_iter = network_->portIterator(child_cell);
|
||||
while (port_iter->hasNext()) {
|
||||
|
|
@ -329,14 +332,14 @@ VerilogWriter::writeInstPin(Instance *inst,
|
|||
Net *net = network_->net(pin);
|
||||
if (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)
|
||||
fprintf(stream_, ",\n ");
|
||||
const char *port_name = portVerilogName(network_->name(port),
|
||||
string port_vname = portVerilogName(network_->name(port),
|
||||
network_->pathEscape());
|
||||
fprintf(stream_, ".%s(%s)",
|
||||
port_name,
|
||||
net_vname);
|
||||
port_vname.c_str(),
|
||||
net_vname.c_str());
|
||||
first_port = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -382,19 +385,17 @@ VerilogWriter::writeInstBusPinBit(Instance *inst,
|
|||
bool &first_member)
|
||||
{
|
||||
Pin *pin = network_->findPin(inst, port);
|
||||
const char *net_name = nullptr;
|
||||
if (pin) {
|
||||
Net *net = network_->net(pin);
|
||||
Net *net = pin ? network_->net(pin) : nullptr;
|
||||
string net_name;
|
||||
if (net)
|
||||
net_name = network_->name(net);
|
||||
}
|
||||
if (net_name == nullptr)
|
||||
else
|
||||
// There is no verilog syntax to "skip" a bit in the concatentation.
|
||||
net_name = stringPrintTmp("_NC%d", unconnected_net_index_++);
|
||||
const char *net_vname = netVerilogName(net_name, network_->pathEscape());
|
||||
stringPrint(net_name, "_NC%d", unconnected_net_index_++);
|
||||
string net_vname = netVerilogName(net_name.c_str(), network_->pathEscape());
|
||||
if (!first_member)
|
||||
fprintf(stream_, ",\n ");
|
||||
fprintf(stream_, "%s", net_vname);
|
||||
fprintf(stream_, "%s", net_vname.c_str());
|
||||
first_member = false;
|
||||
}
|
||||
|
||||
|
|
@ -414,11 +415,13 @@ VerilogWriter::writeAssigns(Instance *inst)
|
|||
&& network_->direction(port)->isAnyOutput()
|
||||
&& !stringEqual(network_->name(port), network_->name(net))) {
|
||||
// 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",
|
||||
netVerilogName(network_->name(port),
|
||||
network_->pathEscape()),
|
||||
netVerilogName(network_->name(net),
|
||||
network_->pathEscape()));
|
||||
port_vname.c_str(),
|
||||
net_vname.c_str());
|
||||
}
|
||||
}
|
||||
delete pin_iter;
|
||||
|
|
|
|||
Loading…
Reference in New Issue