mirror of
https://github.com/The-OpenROAD-Project/OpenSTA.git
synced 2026-09-01 10:27:10 +02:00
Merge remote-tracking branch 'upstream/master' into sta_latest_merge_strings
This commit is contained in:
@@ -406,14 +406,14 @@ ConcreteParasiticNode::incrCapacitance(float cap)
|
||||
cap_ += cap;
|
||||
}
|
||||
|
||||
const char *
|
||||
std::string
|
||||
ConcreteParasiticNode::name(const Network *network) const
|
||||
{
|
||||
if (is_net_) {
|
||||
std::string name = std::string(network->pathName(net_pin_.net_))
|
||||
+ ':'
|
||||
+ std::to_string(id_);
|
||||
return makeTmpString(name);
|
||||
return name;
|
||||
}
|
||||
else
|
||||
return network->pathName(net_pin_.pin_);
|
||||
@@ -1312,7 +1312,7 @@ ConcreteParasitics::capacitors(const Parasitic *parasitic) const
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
std::string
|
||||
ConcreteParasitics::name(const ParasiticNode *node) const
|
||||
{
|
||||
const ConcreteParasiticNode *cnode =
|
||||
|
||||
@@ -24,9 +24,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "MinMax.hh"
|
||||
#include "Parasitics.hh"
|
||||
@@ -143,7 +144,7 @@ public:
|
||||
ParasiticNodeSeq nodes(const Parasitic *parasitic) const override;
|
||||
void incrCap(ParasiticNode *node,
|
||||
float cap) override;
|
||||
const char *name(const ParasiticNode *node) const override;
|
||||
std::string name(const ParasiticNode *node) const override;
|
||||
const Pin *pin(const ParasiticNode *node) const override;
|
||||
const Net *net(const ParasiticNode *node,
|
||||
const Network *network) const override;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "Parasitics.hh"
|
||||
|
||||
@@ -272,7 +273,7 @@ public:
|
||||
ConcreteParasiticNode(const Pin *pin,
|
||||
bool is_external);
|
||||
float capacitance() const { return cap_; }
|
||||
const char *name(const Network *network) const;
|
||||
std::string name(const Network *network) const;
|
||||
const Net *net(const Network *network) const;
|
||||
unsigned id() const { return id_; }
|
||||
bool isExternal() const { return is_external_; }
|
||||
|
||||
@@ -163,7 +163,7 @@ INDEX "*"{POS_INTEGER}
|
||||
|
||||
"\"" {
|
||||
BEGIN INITIAL;
|
||||
yylval->string = sta::stringCopy(token_.c_str());
|
||||
yylval->emplace<std::string>(std::move(token_));
|
||||
return token::QSTRING;
|
||||
}
|
||||
|
||||
@@ -179,27 +179,27 @@ INDEX "*"{POS_INTEGER}
|
||||
{BLANK}*\n { loc->lines(); loc->step(); }
|
||||
|
||||
{INTEGER} {
|
||||
yylval->integer = atoi(yytext);
|
||||
yylval->emplace<int>(atoi(yytext));
|
||||
return token::INTEGER;
|
||||
}
|
||||
|
||||
{FLOAT} {
|
||||
yylval->number = static_cast<float>(atof(yytext));
|
||||
yylval->emplace<float>(static_cast<float>(atof(yytext)));
|
||||
return token::FLOAT;
|
||||
}
|
||||
|
||||
{IDENT} {
|
||||
yylval->string = reader_->translated(yytext);
|
||||
yylval->emplace<std::string>(reader_->translated(yytext));
|
||||
return token::IDENT;
|
||||
}
|
||||
|
||||
{PATH}|{NAME_PAIR} {
|
||||
yylval->string = reader_->translated(yytext);
|
||||
yylval->emplace<std::string>(reader_->translated(yytext));
|
||||
return token::NAME;
|
||||
}
|
||||
|
||||
{INDEX} {
|
||||
yylval->string = sta::stringCopy(yytext);
|
||||
yylval->emplace<std::string>(yytext);
|
||||
return token::INDEX;
|
||||
}
|
||||
|
||||
|
||||
+33
-38
@@ -26,97 +26,92 @@
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace sta {
|
||||
|
||||
char *
|
||||
spefToSta(const char *token,
|
||||
std::string
|
||||
spefToSta(std::string_view spef_name,
|
||||
char spef_divider,
|
||||
char path_divider,
|
||||
char path_escape)
|
||||
{
|
||||
const char spef_escape = '\\';
|
||||
char *trans_token = new char[strlen(token) + 1];
|
||||
char *t = trans_token;
|
||||
|
||||
for (const char *s = token; *s ; s++) {
|
||||
char ch = *s;
|
||||
std::string sta_name;
|
||||
for (size_t i = 0; i < spef_name.size(); i++) {
|
||||
char ch = spef_name[i];
|
||||
if (ch == spef_escape) {
|
||||
char next_ch = s[1];
|
||||
char next_ch = spef_name[i + 1];
|
||||
if (next_ch == spef_divider) {
|
||||
// Translate spef escape to network escape.
|
||||
*t++ = path_escape;
|
||||
sta_name += path_escape;
|
||||
// Translate spef divider to network divider.
|
||||
*t++ = path_divider;
|
||||
sta_name += path_divider;
|
||||
}
|
||||
else if (next_ch == '['
|
||||
|| next_ch == ']'
|
||||
|| next_ch == spef_escape) {
|
||||
// Translate spef escape to network escape.
|
||||
*t++ = path_escape;
|
||||
*t++ = next_ch;
|
||||
sta_name += path_escape;
|
||||
sta_name += next_ch;
|
||||
}
|
||||
else
|
||||
// No need to escape other characters.
|
||||
*t++ = next_ch;
|
||||
s++;
|
||||
sta_name += next_ch;
|
||||
i++;
|
||||
}
|
||||
else if (ch == spef_divider)
|
||||
// Translate spef divider to network divider.
|
||||
*t++ = path_divider;
|
||||
sta_name += path_divider;
|
||||
else
|
||||
// Just the normal noises.
|
||||
*t++ = ch;
|
||||
sta_name += ch;
|
||||
}
|
||||
*t++ = '\0';
|
||||
return trans_token;
|
||||
return sta_name;
|
||||
}
|
||||
|
||||
char *
|
||||
staToSpef(const char *token,
|
||||
std::string
|
||||
staToSpef(std::string_view sta_name,
|
||||
char spef_divider,
|
||||
char path_divider,
|
||||
char path_escape)
|
||||
{
|
||||
const char spef_escape = '\\';
|
||||
char *trans_token = new char[strlen(token) + 1];
|
||||
char *t = trans_token;
|
||||
|
||||
for (const char *s = token; *s ; s++) {
|
||||
char ch = *s;
|
||||
std::string spef_name;
|
||||
for (size_t i = 0; i < sta_name.size(); i++) {
|
||||
char ch = sta_name[i];
|
||||
if (ch == path_escape) {
|
||||
char next_ch = s[1];
|
||||
char next_ch = sta_name[i + 1];
|
||||
if (next_ch == path_divider) {
|
||||
// Translate network escape to spef escape.
|
||||
*t++ = spef_escape;
|
||||
spef_name += spef_escape;
|
||||
// Translate network divider to spef divider.
|
||||
*t++ = spef_divider;
|
||||
spef_name += spef_divider;
|
||||
}
|
||||
else if (next_ch == '['
|
||||
|| next_ch == ']') {
|
||||
// Translate network escape to spef escape.
|
||||
*t++ = spef_escape;
|
||||
*t++ = next_ch;
|
||||
spef_name += spef_escape;
|
||||
spef_name += next_ch;
|
||||
}
|
||||
else
|
||||
// No need to escape other characters.
|
||||
*t++ = next_ch;
|
||||
s++;
|
||||
spef_name += next_ch;
|
||||
i++;
|
||||
}
|
||||
else if (ch == path_divider)
|
||||
// Translate network divider to spef divider.
|
||||
*t++ = spef_divider;
|
||||
spef_name += spef_divider;
|
||||
else if (!(isdigit(ch) || isalpha(ch) || ch == '_')) {
|
||||
// Escape non-alphanum characters.
|
||||
*t++ = spef_escape;
|
||||
*t++ = ch;
|
||||
spef_name += spef_escape;
|
||||
spef_name += ch;
|
||||
}
|
||||
else
|
||||
// Just the normal noises.
|
||||
*t++ = ch;
|
||||
spef_name += ch;
|
||||
}
|
||||
*t++ = '\0';
|
||||
return trans_token;
|
||||
return spef_name;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -24,18 +24,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace sta {
|
||||
|
||||
// Translate from spf/spef namespace to sta namespace.
|
||||
// Caller owns the result string.
|
||||
char *
|
||||
spefToSta(const char *token, char spef_divider,
|
||||
char path_escape, char path_divider);
|
||||
// Translate from sta namespace to spf/spef namespace.
|
||||
// Caller owns the result string.
|
||||
char *
|
||||
staToSpef(const char *token, char spef_divider,
|
||||
char path_divider, char path_escape);
|
||||
std::string
|
||||
spefToSta(std::string_view spef_name,
|
||||
char spef_divider,
|
||||
char path_divider,
|
||||
char path_escape);
|
||||
|
||||
// Translate from sta namespace to spf/spef namespace.
|
||||
std::string
|
||||
staToSpef(std::string_view sta_name,
|
||||
char spef_divider,
|
||||
char path_divider,
|
||||
char path_escape);
|
||||
|
||||
} // namespace
|
||||
|
||||
+61
-96
@@ -23,11 +23,11 @@
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%{
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "Report.hh"
|
||||
#include "StringUtil.hh"
|
||||
#include "StringUtil.hh"
|
||||
#include "parasitics/SpefReaderPvt.hh"
|
||||
#include "parasitics/SpefScanner.hh"
|
||||
|
||||
@@ -41,10 +41,19 @@ void
|
||||
sta::SpefParse::error(const location_type &loc,
|
||||
const std::string &msg)
|
||||
{
|
||||
reader->report()->fileError(1670,reader->filename(), loc.begin. line, "{}", msg);
|
||||
reader->report()->fileError(1670, reader->filename(), loc.begin.line, "{}", msg);
|
||||
}
|
||||
%}
|
||||
|
||||
%code requires {
|
||||
#include <string>
|
||||
|
||||
namespace sta {
|
||||
// Bison's C++ variant skeleton cannot use void as a semantic type.
|
||||
struct SpefParseVoid {};
|
||||
}
|
||||
}
|
||||
|
||||
%require "3.2"
|
||||
%skeleton "lalr1.cc"
|
||||
%debug
|
||||
@@ -55,19 +64,11 @@ sta::SpefParse::error(const location_type &loc,
|
||||
%parse-param { SpefScanner *scanner }
|
||||
%parse-param { SpefReader *reader }
|
||||
%define api.parser.class {SpefParse}
|
||||
%define api.value.type variant
|
||||
|
||||
%union {
|
||||
char ch;
|
||||
char *string;
|
||||
int integer;
|
||||
float number;
|
||||
sta::StringSeq *std_string_seq;
|
||||
sta::PortDirection *port_dir;
|
||||
sta::SpefRspfPi *pi;
|
||||
sta::SpefTriple *triple;
|
||||
sta::Pin *pin;
|
||||
sta::Net *net;
|
||||
}
|
||||
%token <int> INTEGER
|
||||
%token <float> FLOAT
|
||||
%token <std::string> QSTRING INDEX IDENT NAME
|
||||
|
||||
%token SPEF DESIGN DATE VENDOR PROGRAM DESIGN_FLOW
|
||||
%token PVERSION DIVIDER DELIMITER
|
||||
@@ -78,48 +79,42 @@ sta::SpefParse::error(const location_type &loc,
|
||||
%token CONN CAP RES INDUC KW_P KW_I KW_N DRIVER CELL C2_R1_C1 LOADS
|
||||
%token RC KW_Q KW_K
|
||||
|
||||
%token INTEGER FLOAT QSTRING INDEX IDENT NAME
|
||||
%type <int> conf cap_id res_id induc_id cap_elem cap_elems
|
||||
%type <int> res_elem res_elems induc_elem induc_elems
|
||||
%type <int> pos_integer
|
||||
|
||||
%type <integer> INTEGER
|
||||
%type <number> FLOAT
|
||||
%type <string> QSTRING INDEX IDENT NAME
|
||||
%type <float> number pos_number threshold
|
||||
%type <float> real_component imaginary_component pole poles
|
||||
%type <float> residue residues complex_par_value cnumber
|
||||
|
||||
%type <integer> conf cap_id res_id induc_id cap_elem cap_elems
|
||||
%type <integer> res_elem res_elems induc_elem induc_elems
|
||||
%type <integer> pos_integer
|
||||
%nterm <sta::SpefParseVoid> name_map_entries name_map_entry net_names
|
||||
%nterm <sta::SpefParseVoid> net_name port_entries port_entry pport_entries pport_entry
|
||||
%nterm <sta::SpefParseVoid> pport_name pexternal_connection
|
||||
|
||||
%type <number> number pos_number threshold
|
||||
%type <number> real_component imaginary_component pole poles
|
||||
%type <number> residue residues complex_par_value cnumber
|
||||
%type <std::string> name_or_index inst_name
|
||||
%type <std::string> mapped_item
|
||||
%type <std::string> physical_inst port_name pport
|
||||
%type <std::string> entity external_connection
|
||||
%type <std::string> cell_type
|
||||
%type <std::string> driver_cell pnet_ref
|
||||
%type <std::string> internal_pdspf_node
|
||||
%type <std::string> parasitic_node internal_parasitic_node
|
||||
|
||||
%type <string> name_or_index net_name net_names inst_name
|
||||
%type <string> name_map_entries name_map_entry mapped_item
|
||||
%type <string> physical_inst port_name pport_name port_entry pport_entry
|
||||
%type <string> port_entries pport_entries pport
|
||||
%type <string> entity external_connection
|
||||
%type <string> cell_type
|
||||
%type <string> driver_cell pnet_ref
|
||||
%type <string> pexternal_connection internal_pdspf_node
|
||||
%type <string> parasitic_node internal_parasitic_node
|
||||
%type <char> hchar suffix_bus_delim prefix_bus_delim
|
||||
|
||||
%type <ch> hchar suffix_bus_delim prefix_bus_delim
|
||||
%type <sta::StringSeq *> qstrings
|
||||
%type <sta::PortDirection *> direction
|
||||
|
||||
%type <std_string_seq> qstrings
|
||||
%type<port_dir> direction
|
||||
%type <sta::SpefTriple *> par_value total_cap
|
||||
|
||||
%type<triple> par_value total_cap
|
||||
%type <sta::SpefRspfPi *> pi_model
|
||||
|
||||
%type<pi> pi_model
|
||||
%type <sta::Pin *> pin_name driver_pair internal_connection
|
||||
|
||||
%type<pin> pin_name driver_pair internal_connection
|
||||
|
||||
%type<net> net
|
||||
%type <sta::Net *> net
|
||||
|
||||
%start file
|
||||
|
||||
%{
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
file:
|
||||
@@ -184,32 +179,26 @@ header_def:
|
||||
|
||||
spef_version:
|
||||
SPEF QSTRING
|
||||
{ sta::stringDelete($2); }
|
||||
;
|
||||
|
||||
design_name:
|
||||
DESIGN QSTRING
|
||||
{ sta::stringDelete($2); }
|
||||
;
|
||||
|
||||
date:
|
||||
DATE QSTRING
|
||||
{ sta::stringDelete($2); }
|
||||
;
|
||||
|
||||
program_name:
|
||||
PROGRAM QSTRING
|
||||
{ sta::stringDelete($2); }
|
||||
;
|
||||
|
||||
program_version:
|
||||
PVERSION QSTRING
|
||||
{ sta::stringDelete($2); }
|
||||
;
|
||||
|
||||
vendor:
|
||||
VENDOR QSTRING
|
||||
{ sta::stringDelete($2); }
|
||||
;
|
||||
|
||||
design_flow:
|
||||
@@ -220,12 +209,11 @@ design_flow:
|
||||
qstrings:
|
||||
QSTRING
|
||||
{ $$ = new sta::StringSeq;
|
||||
$$->push_back($1);
|
||||
sta::stringDelete($1);
|
||||
$$->push_back(std::move($1));
|
||||
}
|
||||
| qstrings QSTRING
|
||||
{ $$->push_back($2);
|
||||
sta::stringDelete($2);
|
||||
{ $$ = $1;
|
||||
$$->push_back(std::move($2));
|
||||
}
|
||||
;
|
||||
|
||||
@@ -322,7 +310,7 @@ net_names:
|
||||
|
||||
net_name:
|
||||
name_or_index
|
||||
{ sta::stringDelete($1); }
|
||||
{ $$ = sta::SpefParseVoid{}; }
|
||||
;
|
||||
|
||||
/****************************************************************/
|
||||
@@ -345,14 +333,12 @@ port_entries:
|
||||
|
||||
port_entry:
|
||||
port_name direction conn_attrs
|
||||
{ sta::stringDelete($1); }
|
||||
{ $$ = sta::SpefParseVoid{}; }
|
||||
;
|
||||
|
||||
direction:
|
||||
IDENT
|
||||
{ $$ = reader->portDirection($1);
|
||||
sta::stringDelete($1);
|
||||
}
|
||||
{ $$ = reader->portDirection($1); }
|
||||
;
|
||||
|
||||
port_name:
|
||||
@@ -374,15 +360,14 @@ pport_entries:
|
||||
|
||||
pport_entry:
|
||||
pport_name IDENT conn_attrs
|
||||
{ $$ = sta::SpefParseVoid{}; }
|
||||
;
|
||||
|
||||
pport_name:
|
||||
name_or_index
|
||||
{ sta::stringDelete($1); }
|
||||
{ $$ = sta::SpefParseVoid{}; }
|
||||
| physical_inst ':' pport
|
||||
{ sta::stringDelete($1);
|
||||
sta::stringDelete($3);
|
||||
}
|
||||
{ $$ = sta::SpefParseVoid{}; }
|
||||
;
|
||||
|
||||
pport:
|
||||
@@ -441,7 +426,6 @@ threshold:
|
||||
|
||||
driving_cell:
|
||||
KW_D cell_type
|
||||
{ sta::stringDelete($2); }
|
||||
;
|
||||
|
||||
cell_type:
|
||||
@@ -458,18 +442,8 @@ define_def:
|
||||
|
||||
define_entry:
|
||||
DEFINE inst_name entity
|
||||
{ sta::stringDelete($2);
|
||||
sta::stringDelete($3);
|
||||
}
|
||||
| DEFINE inst_name inst_name entity
|
||||
{ sta::stringDelete($2);
|
||||
sta::stringDelete($3);
|
||||
sta::stringDelete($4);
|
||||
}
|
||||
| PDEFINE physical_inst entity
|
||||
{ sta::stringDelete($2);
|
||||
sta::stringDelete($3);
|
||||
}
|
||||
;
|
||||
|
||||
entity:
|
||||
@@ -501,9 +475,7 @@ d_net:
|
||||
|
||||
net:
|
||||
name_or_index
|
||||
{ $$ = reader->findNet($1);
|
||||
sta::stringDelete($1);
|
||||
}
|
||||
{ $$ = reader->findNet($1); }
|
||||
;
|
||||
|
||||
total_cap:
|
||||
@@ -538,11 +510,9 @@ conn_def:
|
||||
|
||||
external_connection:
|
||||
name_or_index
|
||||
{ sta::stringDelete($1); }
|
||||
{ $$ = std::string(); }
|
||||
| physical_inst ':' pport
|
||||
{ sta::stringDelete($1);
|
||||
sta::stringDelete($3);
|
||||
}
|
||||
{ $$ = std::string(); }
|
||||
;
|
||||
|
||||
internal_connection:
|
||||
@@ -551,9 +521,7 @@ internal_connection:
|
||||
|
||||
pin_name:
|
||||
name_or_index
|
||||
{ $$ = reader->findPin($1);
|
||||
sta::stringDelete($1);
|
||||
}
|
||||
{ $$ = reader->findPin($1); }
|
||||
;
|
||||
|
||||
internal_node_coords:
|
||||
@@ -567,7 +535,7 @@ internal_node_coord:
|
||||
|
||||
internal_parasitic_node:
|
||||
name_or_index
|
||||
{ sta::stringDelete($1); }
|
||||
{ $$ = std::string(); }
|
||||
;
|
||||
|
||||
/****************************************************************/
|
||||
@@ -581,6 +549,7 @@ cap_elems:
|
||||
/* empty */
|
||||
{ $$ = 0; }
|
||||
| cap_elems cap_elem
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
cap_elem:
|
||||
@@ -609,6 +578,7 @@ res_elems:
|
||||
/* empty */
|
||||
{ $$ = 0; }
|
||||
| res_elems res_elem
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
res_elem:
|
||||
@@ -631,6 +601,7 @@ induc_elems:
|
||||
/* empty */
|
||||
{ $$ = 0; }
|
||||
| induc_elems induc_elem
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
induc_elem:
|
||||
@@ -658,9 +629,7 @@ driver_reducs:
|
||||
|
||||
driver_reduc:
|
||||
driver_pair driver_cell pi_model
|
||||
{ reader->rspfDrvrBegin($1, $3);
|
||||
sta::stringDelete($2);
|
||||
}
|
||||
{ reader->rspfDrvrBegin($1, $3); }
|
||||
load_desc
|
||||
{ reader->rspfDrvrFinish(); }
|
||||
;
|
||||
@@ -709,6 +678,7 @@ pole_desc:
|
||||
poles:
|
||||
pole
|
||||
| poles pole
|
||||
{ $$ = $2; }
|
||||
;
|
||||
|
||||
pole:
|
||||
@@ -753,7 +723,6 @@ residue:
|
||||
d_pnet:
|
||||
D_PNET pnet_ref total_cap routing_conf pconn_sec cap_sec res_sec
|
||||
induc_sec END
|
||||
{ sta::stringDelete($2); }
|
||||
;
|
||||
|
||||
pnet_ref:
|
||||
@@ -789,10 +758,7 @@ internal_pnode_coord:
|
||||
|
||||
internal_pdspf_node:
|
||||
name_or_index
|
||||
{
|
||||
sta::stringDelete($1);
|
||||
$$ = 0;
|
||||
}
|
||||
{ $$ = std::string(); }
|
||||
;
|
||||
|
||||
name_or_index:
|
||||
@@ -805,9 +771,7 @@ name_or_index:
|
||||
|
||||
r_pnet:
|
||||
R_PNET pnet_ref total_cap routing_conf END
|
||||
{ sta::stringDelete($2); }
|
||||
| R_PNET pnet_ref total_cap routing_conf pdriver_reduc END
|
||||
{ sta::stringDelete($2); }
|
||||
;
|
||||
|
||||
pdriver_reduc:
|
||||
@@ -824,6 +788,7 @@ number:
|
||||
INTEGER
|
||||
{ $$ = static_cast<float>($1); }
|
||||
| FLOAT
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
pos_integer:
|
||||
|
||||
+86
-95
@@ -24,6 +24,10 @@
|
||||
|
||||
#include "SpefReader.hh"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include "Zlib.hh"
|
||||
#include "Stats.hh"
|
||||
#include "Report.hh"
|
||||
@@ -44,7 +48,7 @@
|
||||
namespace sta {
|
||||
|
||||
bool
|
||||
readSpefFile(const std::string &filename,
|
||||
readSpefFile(std::string_view filename,
|
||||
Instance *instance,
|
||||
bool pin_cap_included,
|
||||
bool keep_coupling_caps,
|
||||
@@ -61,7 +65,7 @@ readSpefFile(const std::string &filename,
|
||||
return success;
|
||||
}
|
||||
|
||||
SpefReader::SpefReader(const std::string &filename,
|
||||
SpefReader::SpefReader(std::string_view filename,
|
||||
Instance *instance,
|
||||
bool pin_cap_included,
|
||||
bool keep_coupling_caps,
|
||||
@@ -103,7 +107,7 @@ bool
|
||||
SpefReader::read()
|
||||
{
|
||||
bool success;
|
||||
gzstream::igzstream stream(filename_.c_str());
|
||||
gzstream::igzstream stream(std::string(filename_).c_str());
|
||||
if (stream.is_open()) {
|
||||
Stats stats(debug_, report_);
|
||||
SpefScanner scanner(&stream, filename_, this, report_);
|
||||
@@ -144,13 +148,13 @@ SpefReader::setBusBrackets(char left,
|
||||
}
|
||||
|
||||
Instance *
|
||||
SpefReader::findInstanceRelative(const char *name)
|
||||
SpefReader::findInstanceRelative(std::string_view name)
|
||||
{
|
||||
return sdc_network_->findInstanceRelative(instance_, name);
|
||||
}
|
||||
|
||||
Net *
|
||||
SpefReader::findNetRelative(const char *name)
|
||||
SpefReader::findNetRelative(std::string_view name)
|
||||
{
|
||||
Net *net = network_->findNetRelative(instance_, name);
|
||||
// Relax spef escaping requirement because some commercial tools
|
||||
@@ -161,21 +165,22 @@ SpefReader::findNetRelative(const char *name)
|
||||
}
|
||||
|
||||
Pin *
|
||||
SpefReader::findPinRelative(const char *name)
|
||||
SpefReader::findPinRelative(std::string_view name)
|
||||
{
|
||||
return network_->findPinRelative(instance_, name);
|
||||
}
|
||||
|
||||
Pin *
|
||||
SpefReader::findPortPinRelative(const char *name)
|
||||
SpefReader::findPortPinRelative(std::string_view name)
|
||||
{
|
||||
return network_->findPin(instance_, name);
|
||||
}
|
||||
|
||||
char *
|
||||
SpefReader::translated(const char *token)
|
||||
std::string
|
||||
SpefReader::translated(std::string_view spef_name)
|
||||
{
|
||||
return spefToSta(token, divider_, network_->pathDivider(), network_->pathEscape());
|
||||
return spefToSta(spef_name, divider_, network_->pathDivider(),
|
||||
network_->pathEscape());
|
||||
}
|
||||
|
||||
int
|
||||
@@ -187,79 +192,74 @@ SpefReader::warnLine() const
|
||||
|
||||
void
|
||||
SpefReader::setTimeScale(float scale,
|
||||
const char *units)
|
||||
std::string_view units)
|
||||
{
|
||||
if (stringEq(units, "NS"))
|
||||
if (stringEqual(units, "NS"))
|
||||
time_scale_ = scale * 1E-9F;
|
||||
else if (stringEq(units, "PS"))
|
||||
else if (stringEqual(units, "PS"))
|
||||
time_scale_ = scale * 1E-12F;
|
||||
else
|
||||
warn(1641, "unknown units {}.", units);
|
||||
stringDelete(units);
|
||||
}
|
||||
|
||||
void
|
||||
SpefReader::setCapScale(float scale,
|
||||
const char *units)
|
||||
std::string_view units)
|
||||
{
|
||||
if (stringEq(units, "PF"))
|
||||
if (stringEqual(units, "PF"))
|
||||
cap_scale_ = scale * 1E-12F;
|
||||
else if (stringEq(units, "FF"))
|
||||
else if (stringEqual(units, "FF"))
|
||||
cap_scale_ = scale * 1E-15F;
|
||||
else
|
||||
warn(1642, "unknown units {}.", units);
|
||||
stringDelete(units);
|
||||
}
|
||||
|
||||
void
|
||||
SpefReader::setResScale(float scale,
|
||||
const char *units)
|
||||
std::string_view units)
|
||||
{
|
||||
if (stringEq(units, "OHM"))
|
||||
if (stringEqual(units, "OHM"))
|
||||
res_scale_ = scale;
|
||||
else if (stringEq(units, "KOHM"))
|
||||
else if (stringEqual(units, "KOHM"))
|
||||
res_scale_ = scale * 1E+3F;
|
||||
else
|
||||
warn(1643, "unknown units {}.", units);
|
||||
stringDelete(units);
|
||||
}
|
||||
|
||||
void
|
||||
SpefReader::setInductScale(float scale,
|
||||
const char *units)
|
||||
std::string_view units)
|
||||
{
|
||||
if (stringEq(units, "HENRY"))
|
||||
if (stringEqual(units, "HENRY"))
|
||||
induct_scale_ = scale;
|
||||
else if (stringEq(units, "MH"))
|
||||
else if (stringEqual(units, "MH"))
|
||||
induct_scale_ = scale * 1E-3F;
|
||||
else if (stringEq(units, "UH"))
|
||||
else if (stringEqual(units, "UH"))
|
||||
induct_scale_ = scale * 1E-6F;
|
||||
else
|
||||
warn(1644, "unknown units {}.", units);
|
||||
stringDelete(units);
|
||||
}
|
||||
|
||||
void
|
||||
SpefReader::makeNameMapEntry(const char *index,
|
||||
const char *name)
|
||||
SpefReader::makeNameMapEntry(std::string_view index,
|
||||
std::string_view name)
|
||||
{
|
||||
int i = atoi(index + 1);
|
||||
int i = std::stoi(std::string(index.substr(1)));
|
||||
name_map_[i] = name;
|
||||
stringDelete(index);
|
||||
stringDelete(name);
|
||||
}
|
||||
|
||||
const char *
|
||||
SpefReader::nameMapLookup(const char *name)
|
||||
std::string_view
|
||||
SpefReader::nameMapLookup(std::string_view name)
|
||||
{
|
||||
if (name && name[0] == '*') {
|
||||
int index = atoi(name + 1);
|
||||
if (!name.empty() && name[0] == '*') {
|
||||
std::string index_str(name.substr(1));
|
||||
int index = std::stoi(index_str);
|
||||
const auto &itr = name_map_.find(index);
|
||||
if (itr != name_map_.end())
|
||||
return itr->second.c_str();
|
||||
return itr->second;
|
||||
else {
|
||||
warn(1645, "no name map entry for {}.", index);
|
||||
return nullptr;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -267,14 +267,14 @@ SpefReader::nameMapLookup(const char *name)
|
||||
}
|
||||
|
||||
PortDirection *
|
||||
SpefReader::portDirection(char *spef_dir)
|
||||
SpefReader::portDirection(std::string_view spef_dir)
|
||||
{
|
||||
PortDirection *direction = PortDirection::unknown();
|
||||
if (stringEq(spef_dir, "I"))
|
||||
if (spef_dir == "I")
|
||||
direction = PortDirection::input();
|
||||
else if (stringEq(spef_dir, "O"))
|
||||
else if (spef_dir == "O")
|
||||
direction = PortDirection::output();
|
||||
else if (stringEq(spef_dir, "B"))
|
||||
else if (spef_dir == "B")
|
||||
direction = PortDirection::bidirect();
|
||||
else
|
||||
warn(1646, "unknown port direction {}.", spef_dir);
|
||||
@@ -284,31 +284,31 @@ SpefReader::portDirection(char *spef_dir)
|
||||
void
|
||||
SpefReader::setDesignFlow(StringSeq *flow)
|
||||
{
|
||||
design_flow_ = std::move(*flow);
|
||||
design_flow_ = *flow;
|
||||
delete flow;
|
||||
}
|
||||
|
||||
Pin *
|
||||
SpefReader::findPin(char *name)
|
||||
SpefReader::findPin(std::string_view name)
|
||||
{
|
||||
Pin *pin = nullptr;
|
||||
if (name) {
|
||||
char *delim = strrchr(name, delimiter_);
|
||||
if (delim) {
|
||||
*delim = '\0';
|
||||
const char *name1 = nameMapLookup(name);
|
||||
if (name1) {
|
||||
Instance *inst = findInstanceRelative(name1);
|
||||
// Replace delimiter for error messages.
|
||||
*delim = delimiter_;
|
||||
const char *port_name = delim + 1;
|
||||
if (!name.empty()) {
|
||||
size_t delim = name.rfind(delimiter_);
|
||||
if (delim != std::string::npos) {
|
||||
std::string inst_name_mapped(name.substr(0, delim));
|
||||
std::string_view inst_name = nameMapLookup(inst_name_mapped);
|
||||
if (!inst_name.empty()) {
|
||||
Instance *inst = findInstanceRelative(inst_name);
|
||||
std::string port_name(name.substr(delim + 1, std::string::npos));
|
||||
if (inst) {
|
||||
pin = network_->findPin(inst, port_name);
|
||||
if (pin == nullptr)
|
||||
warn(1647, "pin {} not found.", name1);
|
||||
warn(1647, "pin {}{}{} not found.",
|
||||
inst_name, delimiter_, port_name);
|
||||
}
|
||||
else
|
||||
warn(1648, "instance {} not found.", name1);
|
||||
warn(1648, "instance {}{}{} not found.",
|
||||
inst_name, delimiter_, port_name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -321,11 +321,11 @@ SpefReader::findPin(char *name)
|
||||
}
|
||||
|
||||
Net *
|
||||
SpefReader::findNet(const char *name)
|
||||
SpefReader::findNet(std::string_view name)
|
||||
{
|
||||
Net *net = nullptr;
|
||||
const char *name1 = nameMapLookup(name);
|
||||
if (name1) {
|
||||
std::string_view name1 = nameMapLookup(name);
|
||||
if (!name1.empty()) {
|
||||
net = findNetRelative(name1);
|
||||
if (net == nullptr)
|
||||
warn(1650, "net {} not found.", name1);
|
||||
@@ -425,16 +425,16 @@ SpefReader::dspfFinish()
|
||||
}
|
||||
|
||||
ParasiticNode *
|
||||
SpefReader::findParasiticNode(char *name,
|
||||
SpefReader::findParasiticNode(std::string_view name,
|
||||
bool local_only)
|
||||
{
|
||||
if (name && parasitic_) {
|
||||
char *delim = strrchr(name, delimiter_);
|
||||
if (delim) {
|
||||
*delim = '\0';
|
||||
char *name2 = delim + 1;
|
||||
const char *name1 = nameMapLookup(name);
|
||||
if (name1) {
|
||||
if (!name.empty() && parasitic_) {
|
||||
size_t delim = name.rfind(delimiter_);
|
||||
if (delim != std::string::npos) {
|
||||
std::string name1_mapped(name.substr(0, delim));
|
||||
std::string name2(name.substr(delim + 1, std::string::npos));
|
||||
std::string_view name1 = nameMapLookup(name1_mapped);
|
||||
if (!name1.empty()) {
|
||||
Instance *inst = findInstanceRelative(name1);
|
||||
if (inst) {
|
||||
// <instance>:<port>
|
||||
@@ -445,36 +445,32 @@ SpefReader::findParasiticNode(char *name,
|
||||
sdc_network_->pathName(net_));
|
||||
return parasitics_->ensureParasiticNode(parasitic_, pin, network_);
|
||||
}
|
||||
else {
|
||||
// Replace delimiter for error message.
|
||||
*delim = delimiter_;
|
||||
warn(1652, "pin {} not found.", name1);
|
||||
}
|
||||
else
|
||||
warn(1652, "pin {}{}{} not found.",
|
||||
name1, delimiter_, name2);
|
||||
}
|
||||
else {
|
||||
Net *net = findNet(name1);
|
||||
// Replace delimiter for error messages.
|
||||
*delim = delimiter_;
|
||||
if (net) {
|
||||
// <net>:<subnode_id>
|
||||
const char *id_str = delim + 1;
|
||||
if (isDigits(id_str)) {
|
||||
int id = atoi(id_str);
|
||||
if (isDigits(name2)) {
|
||||
int id = std::stoi(name2);
|
||||
if (local_only && !network_->isConnected(net, net_))
|
||||
warn(1653, "{} not connected to net {}.", name1,
|
||||
network_->pathName(net_));
|
||||
warn(1653, "{}{}{} not connected to net {}.",
|
||||
name1, delimiter_, name2, network_->pathName(net_));
|
||||
return parasitics_->ensureParasiticNode(parasitic_, net, id, network_);
|
||||
}
|
||||
else
|
||||
warn(1654, "node {} not a pin or net:number", name1);
|
||||
warn(1654, "node {}{}{} not a pin or net:number",
|
||||
name1, delimiter_, name2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// <top_level_port>
|
||||
const char *name1 = nameMapLookup(name);
|
||||
if (name1) {
|
||||
std::string_view name1 = nameMapLookup(name);
|
||||
if (!name1.empty()) {
|
||||
Pin *pin = findPortPinRelative(name1);
|
||||
if (pin) {
|
||||
if (local_only && !network_->isConnected(net_, pin))
|
||||
@@ -494,7 +490,7 @@ SpefReader::findParasiticNode(char *name,
|
||||
|
||||
void
|
||||
SpefReader::makeCapacitor(int,
|
||||
char *node_name,
|
||||
std::string_view node_name,
|
||||
SpefTriple *cap)
|
||||
{
|
||||
ParasiticNode *node = findParasiticNode(node_name, true);
|
||||
@@ -503,13 +499,12 @@ SpefReader::makeCapacitor(int,
|
||||
parasitics_->incrCap(node, cap1);
|
||||
}
|
||||
delete cap;
|
||||
stringDelete(node_name);
|
||||
}
|
||||
|
||||
void
|
||||
SpefReader::makeCapacitor(int id,
|
||||
char *node_name1,
|
||||
char *node_name2,
|
||||
std::string_view node_name1,
|
||||
std::string_view node_name2,
|
||||
SpefTriple *cap)
|
||||
{
|
||||
ParasiticNode *node1 = findParasiticNode(node_name1, false);
|
||||
@@ -527,14 +522,12 @@ SpefReader::makeCapacitor(int id,
|
||||
}
|
||||
}
|
||||
delete cap;
|
||||
stringDelete(node_name1);
|
||||
stringDelete(node_name2);
|
||||
}
|
||||
|
||||
void
|
||||
SpefReader::makeResistor(int id,
|
||||
char *node_name1,
|
||||
char *node_name2,
|
||||
std::string_view node_name1,
|
||||
std::string_view node_name2,
|
||||
SpefTriple *res)
|
||||
{
|
||||
ParasiticNode *node1 = findParasiticNode(node_name1, true);
|
||||
@@ -544,8 +537,6 @@ SpefReader::makeResistor(int id,
|
||||
parasitics_->makeResistor(parasitic_, id, res1, node1, node2);
|
||||
}
|
||||
delete res;
|
||||
stringDelete(node_name1);
|
||||
stringDelete(node_name2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
@@ -596,7 +587,7 @@ SpefTriple::value(int index) const
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
SpefScanner::SpefScanner(std::istream *stream,
|
||||
const std::string &filename,
|
||||
std::string_view filename,
|
||||
SpefReader *reader,
|
||||
Report *report) :
|
||||
yyFlexLexer(stream),
|
||||
@@ -607,9 +598,9 @@ SpefScanner::SpefScanner(std::istream *stream,
|
||||
}
|
||||
|
||||
void
|
||||
SpefScanner::error(const char *msg)
|
||||
SpefScanner::error(std::string_view msg)
|
||||
{
|
||||
report_->fileError(1658, filename_.c_str(), lineno(), "{}", msg);
|
||||
report_->fileError(1658, filename_, lineno(), "{}", msg);
|
||||
}
|
||||
|
||||
} // namespace sta
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "Zlib.hh"
|
||||
#include "MinMax.hh"
|
||||
@@ -43,7 +44,7 @@ class StaState;
|
||||
// Min/max and operating condition op_cond are used for parasitic network reduction.
|
||||
// Return true if successful.
|
||||
bool
|
||||
readSpefFile(const std::string &filename,
|
||||
readSpefFile(std::string_view filename,
|
||||
Instance *instance,
|
||||
bool pin_cap_included,
|
||||
bool keep_coupling_caps,
|
||||
|
||||
+25
-26
@@ -25,6 +25,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "Zlib.hh"
|
||||
@@ -47,7 +48,7 @@ using SpefNameMap = std::map<int, std::string>;
|
||||
class SpefReader : public StaState
|
||||
{
|
||||
public:
|
||||
SpefReader(const std::string &filename,
|
||||
SpefReader(std::string_view filename,
|
||||
Instance *instance,
|
||||
bool pin_cap_included,
|
||||
bool keep_coupling_caps,
|
||||
@@ -63,25 +64,25 @@ public:
|
||||
void setDivider(char divider);
|
||||
char delimiter() const { return delimiter_; }
|
||||
void setDelimiter(char delimiter);
|
||||
const std::string &filename() const { return filename_; }
|
||||
std::string_view filename() const { return filename_; }
|
||||
// Translate from spf/spef namespace to sta namespace.
|
||||
char *translated(const char *token);
|
||||
std::string translated(std::string_view spef_name);
|
||||
void setBusBrackets(char left,
|
||||
char right);
|
||||
void setTimeScale(float scale,
|
||||
const char *units);
|
||||
std::string_view units);
|
||||
void setCapScale(float scale,
|
||||
const char *units);
|
||||
std::string_view units);
|
||||
void setResScale(float scale,
|
||||
const char *units);
|
||||
std::string_view units);
|
||||
void setInductScale(float scale,
|
||||
const char *units);
|
||||
void makeNameMapEntry(const char *index,
|
||||
const char *name);
|
||||
const char *nameMapLookup(const char *index);
|
||||
std::string_view units);
|
||||
void makeNameMapEntry(std::string_view index,
|
||||
std::string_view name);
|
||||
std::string_view nameMapLookup(std::string_view name);
|
||||
void setDesignFlow(StringSeq *flow_keys);
|
||||
Pin *findPin(char *name);
|
||||
Net *findNet(const char *name);
|
||||
Pin *findPin(std::string_view name);
|
||||
Net *findNet(std::string_view name);
|
||||
void rspfBegin(Net *net,
|
||||
SpefTriple *total_cap);
|
||||
void rspfFinish();
|
||||
@@ -94,17 +95,17 @@ public:
|
||||
SpefTriple *total_cap);
|
||||
void dspfFinish();
|
||||
void makeCapacitor(int id,
|
||||
char *node_name,
|
||||
std::string_view node_name,
|
||||
SpefTriple *cap);
|
||||
void makeCapacitor(int id,
|
||||
char *node_name1,
|
||||
char *node_name2,
|
||||
std::string_view node_name1,
|
||||
std::string_view node_name2,
|
||||
SpefTriple *cap);
|
||||
void makeResistor(int id,
|
||||
char *node_name1,
|
||||
char *node_name2,
|
||||
std::string_view node_name1,
|
||||
std::string_view node_name2,
|
||||
SpefTriple *res);
|
||||
PortDirection *portDirection(char *spef_dir);
|
||||
PortDirection *portDirection(std::string_view spef_dir);
|
||||
int warnLine() const;
|
||||
template <typename... Args>
|
||||
void warn(int id,
|
||||
@@ -116,14 +117,14 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Pin *findPinRelative(const char *name);
|
||||
Pin *findPortPinRelative(const char *name);
|
||||
Net *findNetRelative(const char *name);
|
||||
Instance *findInstanceRelative(const char *name);
|
||||
ParasiticNode *findParasiticNode(char *name,
|
||||
Pin *findPinRelative(std::string_view name);
|
||||
Pin *findPortPinRelative(std::string_view name);
|
||||
Net *findNetRelative(std::string_view name);
|
||||
Instance *findInstanceRelative(std::string_view name);
|
||||
ParasiticNode *findParasiticNode(std::string_view name,
|
||||
bool local_only);
|
||||
|
||||
const std::string filename_;
|
||||
std::string_view filename_;
|
||||
SpefScanner *scanner_;
|
||||
Instance *instance_;
|
||||
bool pin_cap_included_;
|
||||
@@ -180,6 +181,4 @@ private:
|
||||
SpefTriple *c1_;
|
||||
};
|
||||
|
||||
extern SpefReader *spef_reader;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include "SpefLocation.hh"
|
||||
#include "SpefParse.hh"
|
||||
|
||||
@@ -41,7 +43,7 @@ class SpefScanner : public SpefFlexLexer
|
||||
{
|
||||
public:
|
||||
SpefScanner(std::istream *stream,
|
||||
const std::string &filename,
|
||||
std::string_view filename,
|
||||
SpefReader *reader,
|
||||
Report *report);
|
||||
virtual ~SpefScanner() {}
|
||||
@@ -51,14 +53,14 @@ public:
|
||||
// YY_DECL defined in SpefLex.ll
|
||||
// Method body created by flex in SpefLex.cc
|
||||
|
||||
void error(const char *msg);
|
||||
void error(std::string_view msg);
|
||||
int line() const { return yylineno; }
|
||||
|
||||
// Get rid of override virtual function warning.
|
||||
using FlexLexer::yylex;
|
||||
|
||||
private:
|
||||
std::string filename_;
|
||||
std::string_view filename_;
|
||||
SpefReader *reader_;
|
||||
Report *report_;
|
||||
std::string token_;
|
||||
|
||||
Reference in New Issue
Block a user