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