Merge remote-tracking branch 'opensta/master' into secure-sta-test-by-opus

Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
This commit is contained in:
Jaehyun Kim
2026-03-21 18:54:37 +09:00
176 changed files with 13586 additions and 13837 deletions

View File

@@ -222,12 +222,10 @@ ConcreteCell::makeBusPortBit(ConcretePort *bus_port,
const char *bus_name,
int bit_index)
{
std::string bit_name;
stringPrint(bit_name, "%s%c%d%c",
bus_name,
library_->busBrktLeft(),
bit_index,
library_->busBrktRight());
std::string bit_name = std::string(bus_name)
+ library_->busBrktLeft()
+ std::to_string(bit_index)
+ library_->busBrktRight();
ConcretePort *port = makePort(bit_name.c_str(), bit_index);
bus_port->addPortBit(port);
addPortBit(port);
@@ -465,12 +463,13 @@ ConcretePort::busName() const
{
if (is_bus_) {
ConcreteLibrary *lib = cell_->library();
return stringPrintTmp("%s%c%d:%d%c",
name(),
lib->busBrktLeft(),
from_index_,
to_index_,
lib->busBrktRight());
std::string bus_name = sta::format("{}{}{}:{}{}",
name(),
lib->busBrktLeft(),
from_index_,
to_index_,
lib->busBrktRight());
return makeTmpString(bus_name);
}
else
return name();

View File

@@ -2003,7 +2003,7 @@ ConcreteNetwork::linkNetwork(const char *top_cell_name,
return top_instance_ != nullptr;
}
else {
report->error(1000, "cell type %s can not be linked.", top_cell_name);
report->error(1000, "cell type {} can not be linked.", top_cell_name);
return false;
}
}

View File

@@ -293,15 +293,16 @@ HpinDrvrLoad::~HpinDrvrLoad()
void
HpinDrvrLoad::report(const Network *network)
{
printf("%s -> %s: ",
drvr_ ? network->pathName(drvr_) : "-",
load_ ? network->pathName(load_) : "-");
Report *report = network->report();
std::string line = sta::format("{} -> {}: ",
drvr_ ? network->pathName(drvr_) : "-",
load_ ? network->pathName(load_) : "-");
for (const Pin *pin : *hpins_from_drvr_)
printf("%s ", network->pathName(pin));
printf("* ");
line += sta::format("{} ", network->pathName(pin));
line += "* ";
for (const Pin *pin : *hpins_to_load_)
printf("%s ", network->pathName(pin));
printf("\n");
line += sta::format("{} ", network->pathName(pin));
report->report(line);
}
void

View File

@@ -262,24 +262,15 @@ Network::pathName(const Instance *instance) const
{
InstanceSeq inst_path;
path(instance, inst_path);
size_t name_length = 0;
for (const Instance *inst : inst_path)
name_length += strlen(name(inst)) + 1;
char *path_name = makeTmpString(name_length + 1);
char *path_ptr = path_name;
// Top instance has null string name, so terminate the string here.
*path_name = '\0';
std::string path_name;
while (inst_path.size()) {
const Instance *inst = inst_path.back();
const char *inst_name = name(inst);
strcpy(path_ptr, inst_name);
path_ptr += strlen(inst_name);
path_name += name(inst);
inst_path.pop_back();
if (inst_path.size())
*path_ptr++ = pathDivider();
*path_ptr = '\0';
if (!inst_path.empty())
path_name += pathDivider();
}
return path_name;
return makeTmpString(path_name);
}
bool
@@ -376,18 +367,10 @@ Network::pathName(const Pin *pin) const
{
const Instance *inst = instance(pin);
if (inst && inst != topInstance()) {
const char *inst_name = pathName(inst);
size_t inst_name_length = strlen(inst_name);
const char *port_name = portName(pin);
size_t port_name_length = strlen(port_name);
size_t path_name_length = inst_name_length + port_name_length + 2;
char *path_name = makeTmpString(path_name_length);
char *path_ptr = path_name;
strcpy(path_ptr, inst_name);
path_ptr += inst_name_length;
*path_ptr++ = pathDivider();
strcpy(path_ptr, port_name);
return path_name;
std::string path_name = pathName(inst);
path_name += pathDivider();
path_name += portName(pin);
return makeTmpString(path_name);
}
else
return portName(pin);
@@ -464,18 +447,10 @@ Network::pathName(const Net *net) const
{
const Instance *inst = instance(net);
if (inst && inst != topInstance()) {
const char *inst_name = pathName(inst);
size_t inst_name_length = strlen(inst_name);
const char *net_name = name(net);
size_t net_name_length = strlen(net_name);
size_t path_name_length = inst_name_length + net_name_length + 2;
char *path_name = makeTmpString(path_name_length);
char *path_ptr = path_name;
strcpy(path_ptr, inst_name);
path_ptr += inst_name_length;
*path_ptr++ = pathDivider();
strcpy(path_ptr, net_name);
return path_name;
std::string path_name = pathName(inst);
path_name += pathDivider();
path_name += name(net);
return makeTmpString(path_name);
}
else
return name(net);

View File

@@ -511,7 +511,7 @@ net_pins(Net *net)
return pins;
}
const char *
std::string
pin_location(const Pin *pin)
{
Network *network = Sta::sta()->ensureLinked();
@@ -520,12 +520,12 @@ pin_location(const Pin *pin)
network->location(pin, x, y, exists);
// return x/y as tcl list
if (exists)
return sta::stringPrintTmp("%f %f", x, y);
return sta::format("{} {}", x, y);
else
return "";
}
const char *
std::string
port_location(const Port *port)
{
Network *network = Sta::sta()->ensureLinked();

View File

@@ -24,35 +24,34 @@
#include "ParseBus.hh"
#include <cstring>
#include <cstdlib>
#include <string>
#include <string_view>
#include "StringUtil.hh"
namespace sta {
bool
isBusName(const char *name,
isBusName(std::string_view name,
const char brkt_left,
const char brkt_right,
char escape)
{
size_t len = strlen(name);
size_t len = name.size();
// Shortest bus name is a[0].
if (len >= 4
// Escaped bus brackets are not buses.
&& name[len - 2] != escape
&& name[len - 1] == brkt_right) {
const char *left = strrchr(name, brkt_left);
return left != nullptr;
size_t left = name.rfind(brkt_left);
return left != std::string_view::npos;
}
else
return false;
}
void
parseBusName(const char *name,
parseBusName(std::string_view name,
const char brkt_left,
const char brkt_right,
const char escape,
@@ -61,16 +60,15 @@ parseBusName(const char *name,
std::string &bus_name,
int &index)
{
const char brkts_left[2] = {brkt_left, '\0'};
const char brkts_right[2] = {brkt_right, '\0'};
parseBusName(name, brkts_left, brkts_right, escape,
parseBusName(name, std::string_view(&brkt_left, 1),
std::string_view(&brkt_right, 1), escape,
is_bus, bus_name, index);
}
void
parseBusName(const char *name,
const char *brkts_left,
const char *brkts_right,
parseBusName(std::string_view name,
std::string_view brkts_left,
std::string_view brkts_right,
char escape,
// Return values.
bool &is_bus,
@@ -78,30 +76,28 @@ parseBusName(const char *name,
int &index)
{
is_bus = false;
size_t len = strlen(name);
size_t len = name.size();
// Shortest bus name is a[0].
if (len >= 4
// Escaped bus brackets are not buses.
&& name[len - 2] != escape) {
char last_ch = name[len - 1];
const char *brkt_right_ptr = strchr(brkts_right, last_ch);
if (brkt_right_ptr) {
size_t brkt_index = brkt_right_ptr - brkts_right;
char brkt_left = brkts_left[brkt_index];
const char *left = strrchr(name, brkt_left);
if (left) {
size_t brkt_index = brkts_right.find(last_ch);
if (brkt_index != std::string_view::npos) {
char brkt_left_ch = brkts_left[brkt_index];
size_t left = name.rfind(brkt_left_ch);
if (left != std::string_view::npos) {
is_bus = true;
size_t bus_name_len = left - name;
bus_name.append(name, bus_name_len);
bus_name.append(name.data(), left);
// Simple bus subscript.
index = atoi(left + 1);
index = std::stoi(std::string(name.substr(left + 1)));
}
}
}
}
void
parseBusName(const char *name,
parseBusName(std::string_view name,
const char brkt_left,
const char brkt_right,
char escape,
@@ -113,16 +109,15 @@ parseBusName(const char *name,
int &to,
bool &subscript_wild)
{
const char brkts_left[2] = {brkt_left, '\0'};
const char brkts_right[2] = {brkt_right, '\0'};
parseBusName(name, brkts_left, brkts_right, escape,
parseBusName(name, std::string_view(&brkt_left, 1),
std::string_view(&brkt_right, 1), escape,
is_bus, is_range, bus_name, from, to, subscript_wild);
}
void
parseBusName(const char *name,
const char *brkts_left,
const char *brkts_right,
parseBusName(std::string_view name,
std::string_view brkts_left,
std::string_view brkts_right,
char escape,
// Return values.
bool &is_bus,
@@ -135,36 +130,31 @@ parseBusName(const char *name,
is_bus = false;
is_range = false;
subscript_wild = false;
size_t len = strlen(name);
size_t len = name.size();
// Shortest bus is a[0].
if (len >= 4
// Escaped bus brackets are not buses.
&& name[len - 2] != escape) {
char last_ch = name[len - 1];
const char *brkt_right_ptr = strchr(brkts_right, last_ch);
if (brkt_right_ptr) {
size_t brkt_index = brkt_right_ptr - brkts_right;
char brkt_left = brkts_left[brkt_index];
const char *left = strrchr(name, brkt_left);
if (left) {
size_t brkt_index = brkts_right.find(last_ch);
if (brkt_index != std::string_view::npos) {
char brkt_left_ch = brkts_left[brkt_index];
size_t left = name.rfind(brkt_left_ch);
if (left != std::string_view::npos) {
is_bus = true;
bus_name.append(name.data(), left);
// Check for bus range.
const char range_sep = ':';
const char *range = strchr(name, range_sep);
if (range) {
size_t range = name.find(':', left);
if (range != std::string_view::npos) {
is_range = true;
bus_name.append(name, left - name);
// No need to terminate bus subscript because atoi stops
// scanning at first non-digit character.
from = atoi(left + 1);
to = atoi(range + 1);
from = std::stoi(std::string(name.substr(left + 1)));
to = std::stoi(std::string(name.substr(range + 1)));
}
else {
bus_name.append(name, left - name);
if (left[1] == '*')
if (left + 1 < len && name[left + 1] == '*')
subscript_wild = true;
else
from = to = atoi(left + 1);
from = to = std::stoi(std::string(name.substr(left + 1)));
}
}
}
@@ -172,22 +162,23 @@ parseBusName(const char *name,
}
std::string
escapeChars(const char *token,
escapeChars(std::string_view token,
const char ch1,
const char ch2,
const char escape)
{
std::string escaped;
for (const char *s = token; *s; s++) {
char ch = *s;
escaped.reserve(token.size());
for (size_t i = 0; i < token.size(); i++) {
char ch = token[i];
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') {
if (i + 1 < token.size()) {
escaped += ch;
escaped += next_ch;
s++;
escaped += token[i + 1];
i++;
}
else
escaped += ch;
}
else if (ch == ch1 || ch == ch2) {
escaped += escape;

View File

@@ -640,28 +640,27 @@ SdcNetwork::SdcNetwork(Network *network) :
// Translate sta namespace to sdc namespace.
// Remove all escapes.
const char *
SdcNetwork::staToSdc(const char *sta_name) const
SdcNetwork::staToSdc(std::string_view sta_name) const
{
char escape = pathEscape();
char *sdc_name = makeTmpString(strlen(sta_name) + 1);
char *d = sdc_name;
for (const char *s = sta_name; *s; s++) {
char ch = s[0];
size_t sta_length = sta_name.length();
std::string sdc_name;
for (size_t i = 0; i < sta_length; i++) {
char ch = sta_name[i];
if (ch == escape) {
char next_ch = s[1];
char next_ch = sta_name[i + 1];
// Escaped escape.
if (next_ch == escape) {
*d++ = ch;
*d++ = next_ch;
s++;
sdc_name += ch;
sdc_name += next_ch;
i++;
}
}
else
// Non escape.
*d++ = ch;
sdc_name += ch;
}
*d++ = '\0';
return sdc_name;
return makeTmpString(sdc_name);
}
Port *
@@ -680,11 +679,11 @@ SdcNetwork::findPort(const Cell *cell,
port = network_->findPort(cell, escaped1.c_str());
if (port == nullptr) {
// Try escaping base foo\[0\][1]
std::string escaped2;
std::string escaped_bus_name = escapeBrackets(bus_name.c_str(), this);
stringPrint(escaped2, "%s[%d]",
escaped_bus_name.c_str(),
index);
std::string escaped2 = escaped_bus_name
+ '['
+ std::to_string(index)
+ ']';
port = network_->findPort(cell, escaped2.c_str());
}
}
@@ -966,8 +965,10 @@ SdcNetwork::findPin(const Instance *instance,
if (pin == nullptr) {
// Try escaping base foo\[0\][1]
std::string escaped_bus_name = escapeBrackets(bus_name.c_str(), this);
std::string escaped2;
stringPrint(escaped2, "%s[%d]", escaped_bus_name.c_str(), index);
std::string escaped2 = escaped_bus_name
+ '['
+ std::to_string(index)
+ ']';
pin = network_->findPin(instance, escaped2.c_str());
}
}
@@ -1149,46 +1150,39 @@ SdcNetwork::parsePath(const char *path,
const char *&path_tail) const
{
Instance *parent = topInstance();
std::string inst_path;
// Leave room to escape all the dividers and '\0'.
int inst_path_length = path_length + divider_count + 1;
char *inst_path = new char[inst_path_length];
inst_path.reserve(path_length + divider_count + 1);
inst = nullptr;
path_tail = path;
char *p = inst_path;
for (const char *s = path; *s; s++) {
char ch = *s;
if (ch == escape_) {
// Make sure we don't skip the null if escape is the last char.
if (s[1] != '\0') {
*p++ = ch;
*p++ = s[1];
inst_path += ch;
inst_path += s[1];
s++;
}
}
else if (ch == divider_) {
// Terminate the sub-path up to this divider.
*p = '\0';
Instance *child = findChild(parent, inst_path);
Instance *child = findChild(parent, inst_path.c_str());
if (child) {
// Found an instance for the sub-path up to this divider.
parent = inst = child;
// Reset the instance path.
p = inst_path;
inst_path.clear();
path_tail = s + 1;
}
else {
// No match for sub-path. Escape the divider and keep looking.
*p++ = escape_;
*p++ = divider_;
inst_path += escape_;
inst_path += divider_;
}
}
else
*p++ = ch;
if (p - inst_path + 1 > inst_path_length)
report_->critical(1500, "inst path std::string lenth estimate busted");
inst_path += ch;
}
*p = '\0';
stringDelete(inst_path);
}
// Helper to visit instance path matches.
@@ -1207,11 +1201,9 @@ SdcNetwork::visitMatches(const Instance *parent,
{
int divider_count, path_length;
scanPath(pattern->pattern(), divider_count, path_length);
std::string inst_path;
// Leave room to escape all the dividers and '\0'.
int inst_path_length = path_length + divider_count + 1;
char *inst_path = new char[inst_path_length];
char *p = inst_path;
inst_path.reserve(path_length + divider_count + 1);
bool has_brkts = false;
bool found_match = false;
for (const char *s = pattern->pattern(); *s; s++) {
@@ -1219,20 +1211,18 @@ SdcNetwork::visitMatches(const Instance *parent,
if (ch == escape_) {
// Make sure we don't skip the null if escape is the last char.
if (s[1] != '\0') {
*p++ = ch;
*p++ = s[1];
inst_path += ch;
inst_path += s[1];
s++;
}
}
else if (ch == divider_) {
// Terminate the sub-path up to this divider.
*p = '\0';
PatternMatch matcher(inst_path, pattern);
PatternMatch matcher(inst_path.c_str(), pattern);
InstanceSeq matches;
network_->findChildrenMatching(parent, &matcher, matches);
if (has_brkts && matches.empty()) {
// Look for matches after escaping brackets.
std::string escaped_brkts = escapeBrackets(inst_path, this);
std::string escaped_brkts = escapeBrackets(inst_path.c_str(), this);
const PatternMatch escaped_pattern(escaped_brkts, pattern);
network_->findChildrenMatching(parent, &escaped_pattern, matches);
}
@@ -1245,29 +1235,25 @@ SdcNetwork::visitMatches(const Instance *parent,
found_match |= visitMatches(match, &tail_pattern, visit_tail);
}
// Escape the divider and keep looking.
*p++ = escape_;
*p++ = divider_;
inst_path += escape_;
inst_path += divider_;
}
else {
if (ch == '[' || ch == ']')
has_brkts = true;
*p++ = ch;
inst_path += ch;
}
if (p - inst_path + 1 > inst_path_length)
report_->critical(1501, "inst path std::string lenth estimate exceeded");
}
*p = '\0';
if (!found_match) {
PatternMatch tail_pattern(inst_path, pattern);
PatternMatch tail_pattern(inst_path.c_str(), pattern);
found_match |= visit_tail(parent, &tail_pattern);
if (!found_match && has_brkts) {
// Look for matches after escaping brackets.
std::string escaped_path = escapeBrackets(inst_path, this);
std::string escaped_path = escapeBrackets(inst_path.c_str(), this);
const PatternMatch escaped_tail(escaped_path, pattern);
found_match |= visit_tail(parent, &escaped_tail);
}
}
stringDelete(inst_path);
return found_match;
}

View File

@@ -34,35 +34,34 @@ namespace sta {
constexpr char verilog_escape = '\\';
static std::string
staToVerilog(const char *sta_name);
staToVerilog(std::string sta_name);
static std::string
staToVerilog2(const char *sta_name);
staToVerilog2(std::string sta_name);
static std::string
verilogToSta(const std::string *verilog_name);
verilogToSta(const std::string verilog_name);
std::string
cellVerilogName(const char *sta_name)
cellVerilogName(std::string sta_name)
{
return staToVerilog(sta_name);
}
std::string
instanceVerilogName(const char *sta_name)
instanceVerilogName(std::string sta_name)
{
return staToVerilog(sta_name);
}
std::string
netVerilogName(const char *sta_name)
netVerilogName(std::string sta_name)
{
bool is_bus;
std::string bus_name;
int index;
parseBusName(sta_name, '[', ']', verilog_escape, is_bus, bus_name, index);
parseBusName(sta_name.c_str(), '[', ']', verilog_escape, is_bus, bus_name, index);
if (is_bus) {
std::string bus_vname = staToVerilog(bus_name.c_str());
std::string vname;
stringPrint(vname, "%s[%d]", bus_vname.c_str(), index);
std::string vname = bus_vname + '[' + std::to_string(index) + ']';
return vname;
}
else
@@ -70,27 +69,28 @@ netVerilogName(const char *sta_name)
}
std::string
portVerilogName(const char *sta_name)
portVerilogName(std::string sta_name)
{
return staToVerilog2(sta_name);
}
static std::string
staToVerilog(const char *sta_name)
staToVerilog(std::string sta_name)
{
// Leave room for leading escape and trailing space if the name
// needs to be escaped.
// Assume the name has to be escaped and start copying while scanning.
std::string escaped_name = "\\";
bool escaped = false;
for (const char *s = sta_name; *s ; s++) {
char ch = s[0];
size_t sta_length = sta_name.size();
for (size_t i = 0; i < sta_length; i++) {
char ch = sta_name[i];
if (ch == verilog_escape) {
escaped = true;
char next_ch = s[1];
char next_ch = sta_name[i + 1];
if (next_ch == verilog_escape) {
escaped_name += next_ch;
s++;
i++;
}
}
else {
@@ -105,11 +105,11 @@ staToVerilog(const char *sta_name)
return escaped_name;
}
else
return std::string(sta_name);
return sta_name;
}
static std::string
staToVerilog2(const char *sta_name)
staToVerilog2(std::string sta_name)
{
constexpr char bus_brkt_left = '[';
constexpr char bus_brkt_right = ']';
@@ -118,14 +118,15 @@ staToVerilog2(const char *sta_name)
std::string escaped_name = "\\";
// Assume the name has to be escaped and start copying while scanning.
bool escaped = false;
for (const char *s = sta_name; *s ; s++) {
char ch = s[0];
size_t sta_length = sta_name.size();
for (size_t i = 0; i < sta_length; i++) {
char ch = sta_name[i];
if (ch == verilog_escape) {
escaped = true;
char next_ch = s[1];
char next_ch = sta_name[i + 1];
if (next_ch == verilog_escape) {
escaped_name += next_ch;
s++;
i++;
}
}
else {
@@ -142,50 +143,50 @@ staToVerilog2(const char *sta_name)
return escaped_name;
}
else
return std::string(sta_name);
return sta_name;
}
////////////////////////////////////////////////////////////////
std::string
moduleVerilogToSta(const std::string *module_name)
moduleVerilogToSta(std::string module_name)
{
return verilogToSta(module_name);
}
std::string
instanceVerilogToSta(const std::string *inst_name)
instanceVerilogToSta(std::string inst_name)
{
return verilogToSta(inst_name);
}
std::string
netVerilogToSta(const std::string *net_name)
netVerilogToSta(std::string net_name)
{
return verilogToSta(net_name);
}
std::string
portVerilogToSta(const std::string *port_name)
portVerilogToSta(std::string port_name)
{
return verilogToSta(port_name);
}
static std::string
verilogToSta(const std::string *verilog_name)
verilogToSta(std::string verilog_name)
{
if (verilog_name->front() == '\\') {
if (verilog_name.front() == '\\') {
constexpr char divider = '/';
constexpr char bus_brkt_left = '[';
constexpr char bus_brkt_right = ']';
size_t verilog_name_length = verilog_name->size();
if (isspace(verilog_name->back()))
size_t verilog_name_length = verilog_name.size();
if (isspace(verilog_name.back()))
verilog_name_length--;
std::string sta_name;
// Ignore leading '\'.
for (size_t i = 1; i < verilog_name_length; i++) {
char ch = verilog_name->at(i);
char ch = verilog_name[i];
if (ch == bus_brkt_left
|| ch == bus_brkt_right
|| ch == divider
@@ -197,7 +198,7 @@ verilogToSta(const std::string *verilog_name)
return sta_name;
}
else
return std::string(*verilog_name);
return verilog_name;
}
} // namespace