liberty pin names with brackets and .'s

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2023-02-18 17:20:40 -07:00
parent 84271b26da
commit 5d45a07e34
21 changed files with 570 additions and 325 deletions

View File

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

View File

@ -140,10 +140,14 @@ stringAppend(char *&str1,
str1 += strlen(str2);
}
void
stringDeleteCheck(const char *str);
// Delete for strings allocated with new char[].
inline void
stringDelete(const char *str)
{
stringDeleteCheck(str);
delete [] str;
}
@ -177,6 +181,8 @@ void
initTmpStrings();
void
deleteTmpStrings();
bool
isTmpString(const char *str);
////////////////////////////////////////////////////////////////

View File

@ -18,11 +18,6 @@
namespace sta {
const char *
staToVerilog(const char *sta_name,
const char escape);
const char *
verilogToSta(const char *verilog_name);
const char *
instanceVerilogName(const char *sta_name,
const char escape);
@ -33,4 +28,13 @@ const char *
portVerilogName(const char *sta_name,
const char escape);
const char *
moduleVerilogToSta(const char *sta_name);
const char *
instanceVerilogToSta(const char *sta_name);
const char *
netVerilogToSta(const char *sta_name);
const char *
portVerilogToSta(const char *sta_name);
} // namespace

View File

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

View File

@ -39,25 +39,28 @@ LibertyBuilder::makeCell(LibertyLibrary *library,
LibertyPort *
LibertyBuilder::makePort(LibertyCell *cell,
const char *name)
const char *port_name)
{
LibertyPort *port = new LibertyPort(cell, name, false, nullptr, -1, -1, false, nullptr);
const char *sta_name = portLibertyToSta(port_name);
LibertyPort *port = new LibertyPort(cell, sta_name, false, nullptr,
-1, -1, false, nullptr);
cell->addPort(port);
return port;
}
LibertyPort *
LibertyBuilder::makeBusPort(LibertyCell *cell,
const char *name,
const char *bus_name,
int from_index,
int to_index,
BusDcl *bus_dcl)
{
LibertyPort *port = new LibertyPort(cell, name, true, bus_dcl,
string sta_name = portLibertyToSta(bus_name);
LibertyPort *port = new LibertyPort(cell, sta_name.c_str(), true, bus_dcl,
from_index, to_index,
false, new ConcretePortSeq);
cell->addPort(port);
makeBusPortBits(cell->library(), cell, port, name, from_index, to_index);
makeBusPortBits(cell->library(), cell, port, sta_name.c_str(), from_index, to_index);
return port;
}
@ -65,17 +68,17 @@ void
LibertyBuilder::makeBusPortBits(ConcreteLibrary *library,
LibertyCell *cell,
ConcretePort *bus_port,
const char *name,
const char *bus_name,
int from_index,
int to_index)
{
if (from_index < to_index) {
for (int index = from_index; index <= to_index; index++)
makeBusPortBit(library, cell, bus_port, name, index);
makeBusPortBit(library, cell, bus_port, bus_name, index);
}
else {
for (int index = from_index; index >= to_index; index--)
makeBusPortBit(library, cell, bus_port, name, index);
makeBusPortBit(library, cell, bus_port, bus_name, index);
}
}

View File

@ -38,7 +38,7 @@ public:
virtual LibertyPort *makePort(LibertyCell *cell,
const char *name);
virtual LibertyPort *makeBusPort(LibertyCell *cell,
const char *name,
const char *bus_name,
int from_index,
int to_index,
BusDcl *bus_dcl);
@ -83,7 +83,7 @@ protected:
void makeBusPortBits(ConcreteLibrary *library,
LibertyCell *cell,
ConcretePort *bus_port,
const char *name,
const char *bus_name,
int from_index,
int to_index);
// Bus port bit (internal to makeBusPortBits).
@ -93,7 +93,7 @@ protected:
void makeBusPortBit(ConcreteLibrary *library,
LibertyCell *cell,
ConcretePort *bus_port,
const char *name,
const char *bus_name,
int index);
virtual TimingArcSet *makeTimingArcSet(LibertyCell *cell,
LibertyPort *from,

View File

@ -67,16 +67,20 @@ LibExprParser::~LibExprParser()
stringDelete(token_);
}
LibertyPort *
libertyReaderFindPort(LibertyCell *cell,
const char *port_name);
FuncExpr *
LibExprParser::makeFuncExprPort(const char *port_name)
{
LibertyPort *port = cell_->findLibertyPort(port_name);
FuncExpr *expr = nullptr;
LibertyPort *port = libertyReaderFindPort(cell_, port_name);
if (port)
expr = FuncExpr::makePort(port);
else
report_->error(7, "%s references unknown port %s.",
error_msg_, port_name);
report_->warn(7, "%s references unknown port %s.",
error_msg_, port_name);
stringDelete(port_name);
return expr;
}

View File

@ -49,7 +49,7 @@ libertyExprFlushBuffer()
%x ESCAPED_STRING
PORT [A-Za-z_]([A-Za-z0-9_\[\]])*
PORT [A-Za-z_]([A-Za-z0-9_\.\[\]])*
OP "'"|"!"|"^"|"*"|"&"|"+"|"|"|1|0
PAREN "("|")"
BLANK [ \t\r]

View File

@ -2852,9 +2852,9 @@ LibertyReader::beginPin(LibertyGroup *group)
while (param_iter.hasNext()) {
LibertyAttrValue *param = param_iter.next();
if (param->isString()) {
const char *name = param->stringValue();
debugPrint(debug_, "liberty", 1, " port %s", name);
PortNameBitIterator port_iter(cell_, name, this, group->line());
const char *port_name = param->stringValue();
debugPrint(debug_, "liberty", 1, " port %s", port_name);
PortNameBitIterator port_iter(cell_, port_name, this, group->line());
while (port_iter.hasNext()) {
LibertyPort *port = port_iter.next();
ports_->push_back(port);
@ -2885,8 +2885,6 @@ LibertyReader::beginPin(LibertyGroup *group)
}
else {
ports_ = new LibertyPortSeq;
char brkt_left = library_->busBrktLeft();
char brkt_right = library_->busBrktRight();
// Multiple port names can share group def.
LibertyAttrValueIterator param_iter(group->params());
while (param_iter.hasNext()) {
@ -2894,10 +2892,6 @@ LibertyReader::beginPin(LibertyGroup *group)
if (param->isString()) {
const char *name = param->stringValue();
debugPrint(debug_, "liberty", 1, " port %s", name);
if (isBusName(name, brkt_left, brkt_right, escape_))
// Pins not inside a bus group with bus names are not really
// busses, so escape the brackets.
name = escapeChars(name, brkt_left, brkt_right, escape_);
LibertyPort *port = builder_->makePort(cell_, name);
ports_->push_back(port);
}
@ -3101,21 +3095,29 @@ LibertyReader::findPort(const char *port_name)
return findPort(cell_, port_name);
}
// Also used by LibExprParser::makeFuncExprPort.
LibertyPort *
libertyReaderFindPort(LibertyCell *cell,
const char *port_name)
{
LibertyPort *port = cell->findLibertyPort(port_name);
if (port == nullptr) {
const LibertyLibrary *library = cell->libertyLibrary();
char brkt_left = library->busBrktLeft();
char brkt_right = library->busBrktRight();
const char escape = '\\';
// Pins at top level with bus names have escaped brackets.
port_name = escapeChars(port_name, brkt_left, brkt_right, escape);
port = cell->findLibertyPort(port_name);
}
return port;
}
LibertyPort *
LibertyReader::findPort(LibertyCell *cell,
const char *port_name)
{
LibertyPort *port = cell->findLibertyPort(port_name);
if (port == nullptr) {
char brkt_left = library_->busBrktLeft();
char brkt_right = library_->busBrktRight();
if (isBusName(port_name, brkt_left, brkt_right, escape_)) {
// Pins at top level with bus names have escaped brackets.
port_name = escapeChars(port_name, brkt_left, brkt_right, escape_);
port = cell->findLibertyPort(port_name);
}
}
return port;
return libertyReaderFindPort(cell, port_name);
}
void
@ -3795,7 +3797,10 @@ LibertyReader::endTiming(LibertyGroup *group)
model->setScaleFactorType(type);
}
}
if (timing_->relatedPortNames() == nullptr)
TimingType timing_type = timing_->attrs()->timingType();
if (timing_->relatedPortNames() == nullptr
&& !(timing_type == TimingType::min_clock_tree_path
|| timing_type == TimingType::max_clock_tree_path))
libWarn(170, group, "timing group missing related_pin/related_bus_pin.");
}
timing_ = nullptr;
@ -5548,7 +5553,7 @@ PortNameBitIterator::PortNameBitIterator(LibertyCell *cell,
void
PortNameBitIterator::init(const char *port_name)
{
LibertyPort *port = visitor_->findPort(cell_, port_name);
LibertyPort *port = visitor_->findPort(port_name);
if (port) {
if (port->isBus())
bit_iterator_ = new LibertyPortMemberIterator(port);
@ -5564,7 +5569,7 @@ PortNameBitIterator::init(const char *port_name)
parseBusRange(port_name, library->busBrktLeft(), library->busBrktRight(),
'\\', bus_name, from, to);
if (bus_name) {
port = visitor_->findPort(cell_, port_name);
port = visitor_->findPort(port_name);
if (port) {
if (port->isBus()) {
if (port->busIndexInRange(from)
@ -5656,7 +5661,7 @@ PortNameBitIterator::findRangeBusNameNext()
library->busBrktLeft(),
range_bit_,
library->busBrktRight());
range_name_next_ = visitor_->findPort(cell_, bus_bit_name);
range_name_next_ = visitor_->findPort(bus_bit_name);
if (range_name_next_) {
if (range_from_ > range_to_)
range_bit_--;

View File

@ -1118,7 +1118,7 @@ SdcNetwork::visitMatches(const Instance *parent,
*p = '\0';
PatternMatch matcher(inst_path, pattern);
InstanceSeq matches;
findChildrenMatching(parent, &matcher, matches);
network_->findChildrenMatching(parent, &matcher, matches);
if (has_brkts && matches.empty()) {
// Look for matches after escaping brackets.
const PatternMatch escaped_brkts(escapeBrackets(inst_path, this),

View File

@ -23,6 +23,20 @@
namespace sta {
static const char *
staToVerilog(const char *sta_name,
const char escape);
static const char *
staToVerilog2(const char *sta_name,
const char escape);
static const char *
verilogToSta(const char *verilog_name);
static inline void
vstringAppend(char *&str,
char *&str_end,
char *&insert,
char ch);
const char *
instanceVerilogName(const char *sta_name,
const char escape)
@ -45,41 +59,64 @@ netVerilogName(const char *sta_name,
return vname;
}
else
return staToVerilog(sta_name, escape);
return staToVerilog2(sta_name, escape);
}
const char *
portVerilogName(const char *sta_name,
const char escape)
{
return staToVerilog(sta_name, escape);
return staToVerilog2(sta_name, escape);
}
// 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;
}
const char *
static const char *
staToVerilog(const char *sta_name,
const char escape)
{
const char bus_brkt_left = '[';
const char bus_brkt_right = ']';
// Leave room for leading escape and trailing space if the name
// needs to be escaped.
size_t verilog_name_length = strlen(sta_name) + 3;
char *verilog_name = makeTmpString(verilog_name_length);
char *verilog_name_end = &verilog_name[verilog_name_length];
char *v = verilog_name;
// Assume the name has to be escaped and start copying while scanning.
bool escaped = false;
*v++ = '\\';
for (const char *s = sta_name; *s ; s++) {
char ch = s[0];
if (ch == escape) {
char next_ch = s[1];
if (next_ch == escape) {
vstringAppend(verilog_name, verilog_name_end, v, ch);
vstringAppend(verilog_name, verilog_name_end, v, next_ch);
s++;
}
else
// Skip escape.
escaped = true;
}
else {
if ((!(isalnum(ch) || ch == '_')))
escaped = true;
vstringAppend(verilog_name, verilog_name_end, v, ch);
}
}
if (escaped) {
// Add a terminating space.
vstringAppend(verilog_name, verilog_name_end, v, ' ');
vstringAppend(verilog_name, verilog_name_end, v, '\0');
return verilog_name;
}
else
return sta_name;
}
static const char *
staToVerilog2(const char *sta_name,
const char escape)
{
constexpr char bus_brkt_left = '[';
constexpr char bus_brkt_right = ']';
// Leave room for leading escape and trailing space if the name
// needs to be escaped.
size_t verilog_name_length = strlen(sta_name) + 3;
@ -120,30 +157,60 @@ staToVerilog(const char *sta_name,
return sta_name;
}
////////////////////////////////////////////////////////////////
const char *
moduleVerilogToSta(const char *module_name)
{
return verilogToSta(module_name);
}
const char *
instanceVerilogToSta(const char *inst_name)
{
return verilogToSta(inst_name);
}
const char *
netVerilogToSta(const char *net_name)
{
return verilogToSta(net_name);
}
const char *
portVerilogToSta(const char *port_name)
{
return verilogToSta(port_name);
}
static const char *
verilogToSta(const char *verilog_name)
{
if (verilog_name[0] == '\\') {
const char divider = '/';
const char escape = '\\';
const char bus_brkt_left = '[';
const char bus_brkt_right = ']';
size_t sta_name_length = strlen(verilog_name) + 1;
if (verilog_name && verilog_name[0] == '\\') {
constexpr char divider = '/';
constexpr char escape = '\\';
constexpr char bus_brkt_left = '[';
constexpr char bus_brkt_right = ']';
// Ignore leading '\'.
verilog_name = &verilog_name[1];
size_t verilog_name_length = strlen(verilog_name);
if (verilog_name[verilog_name_length - 1] == ' ')
verilog_name_length--;
// +1 for \0, +2 for escaping brackets.
size_t sta_name_length = verilog_name_length + 1;
char *sta_name = makeTmpString(sta_name_length);
char *sta_name_end = &sta_name[sta_name_length];
char *s = sta_name;
for (const char *v = &verilog_name[1]; *v ; v++) {
char ch = *v;
if (ch == divider
|| ch == bus_brkt_left
|| ch == bus_brkt_right
|| ch == escape)
// Escape dividers, bus brackets and escapes.
for (size_t i = 0; i < verilog_name_length; i++) {
char ch = verilog_name[i];
if (ch == bus_brkt_left
|| ch == bus_brkt_right
|| ch == divider
|| ch == escape)
// Escape bus brackets, dividers and escapes.
vstringAppend(sta_name, sta_name_end, s, escape);
vstringAppend(sta_name, sta_name_end, s, ch);
// Don't include the last character, which is always a space.
if (v[2] == '\0')
break;
}
vstringAppend(sta_name, sta_name_end, s, '\0');
return sta_name;
@ -152,4 +219,23 @@ verilogToSta(const char *verilog_name)
return verilog_name;
}
// Append ch to str at insert. Resize str if necessary.
static inline void
vstringAppend(char *&str,
char *&str_end,
char *&insert,
char ch)
{
if (insert == str_end) {
size_t length = str_end - str;
size_t length2 = length * 2;
char *new_str = makeTmpString(length2);
strncpy(new_str, str, length);
str = new_str;
str_end = &str[length2];
insert = &str[length];
}
*insert++ = ch;
}
} // namespace

View File

@ -22,8 +22,10 @@
namespace sta {
char *
spefToSta(const char *token, char spef_divider,
char path_divider, char path_escape)
spefToSta(const char *token,
char spef_divider,
char path_divider,
char path_escape)
{
const char spef_escape = '\\';
char *trans_token = new char[strlen(token) + 1];
@ -63,8 +65,10 @@ spefToSta(const char *token, char spef_divider,
}
char *
staToSpef(const char *token, char spef_divider,
char path_divider, char path_escape)
staToSpef(const char *token,
char spef_divider,
char path_divider,
char path_escape)
{
const char spef_escape = '\\';
char *trans_token = new char[strlen(token) + 1];

View File

@ -131,11 +131,7 @@ ReadVcdActivities::setVarActivity(VcdVar *var,
string &var_name,
const VcdValues &var_values)
{
// var names include the leading \ but not the trailing space so add it.
if (var_name[0] == '\\')
var_name += ' ';
const char *sta_name = verilogToSta(var_name.c_str());
const char *sta_name = netVerilogToSta(var_name.c_str());
if (var->width() == 1)
setVarActivity(sta_name, var_values, 0);
else {

View File

@ -85,11 +85,16 @@ EOL \r?\n
"//"[^\n]*{EOL} { sta::sdf_reader->incrLine(); }
("-"|"+")?([0-9]*)("."[0-9]+)?([eE]("-"|"+")?[0-9]+)? {
("-"|"+")?([0-9]*)("."[0-9]+)([eE]("-"|"+")?[0-9]+)? {
SdfParse_lval.number = static_cast<float>(atof(yytext));
return NUMBER;
return FNUMBER;
}
"+"?[0-9]+ {
SdfParse_lval.integer = atoi(yytext);
return DNUMBER;
}
":"|"{"|"}"|"["|"]"|","|"*"|";"|"="|"-"|"+"|"|"|"("|")"|{HCHAR} {
return ((int) yytext[0]);
}
@ -178,15 +183,10 @@ COND {
<COND_EXPR>. { sdf_token += yytext[0]; }
{ID} {
SdfParse_lval.string = sta::stringCopy(sta::sdf_reader->unescaped(yytext));
SdfParse_lval.string = sta::stringCopy(yytext);
return ID;
}
{ID}({HCHAR}{ID})* {
SdfParse_lval.string = sta::stringCopy(sta::sdf_reader->unescaped(yytext));
return PATH;
}
{EOL} { sta::sdf_reader->incrLine(); }
{BLANK} { /* Ignore blanks. */ }

View File

@ -25,6 +25,8 @@ int SdfLex_lex();
// use yacc generated parser errors
#define YYERROR_VERBOSE
#define YYDEBUG 1
%}
// expected shift/reduce conflicts
@ -32,9 +34,10 @@ int SdfLex_lex();
%union {
char character;
char *string;
const char *string;
float number;
float *number_ptr;
int integer;
sta::SdfTriple *triple;
sta::SdfTripleSeq *delval_list;
sta::SdfPortSpec *port_spec;
@ -48,13 +51,14 @@ int SdfLex_lex();
%token IOPATH TIMINGCHECK
%token SETUP HOLD SETUPHOLD RECOVERY REMOVAL RECREM WIDTH PERIOD SKEW NOCHANGE
%token POSEDGE NEGEDGE COND CONDELSE
%token QSTRING ID PATH NUMBER EXPR_OPEN_IOPATH EXPR_OPEN EXPR_ID_CLOSE
%token QSTRING ID FNUMBER DNUMBER EXPR_OPEN_IOPATH EXPR_OPEN EXPR_ID_CLOSE
%type <number> NUMBER
%type <number> FNUMBER NUMBER
%type <integer> DNUMBER
%type <number_ptr> number_opt
%type <triple> value triple
%type <delval_list> delval_list
%type <string> QSTRING ID PATH path port_instance
%type <string> QSTRING ID path port port_instance
%type <string> EXPR_OPEN_IOPATH EXPR_OPEN EXPR_ID_CLOSE
%type <port_spec> port_spec port_tchk
%type <transition> port_transition
@ -159,7 +163,9 @@ del_defs:
path:
ID
| PATH
{ $$ = sta::sdf_reader->unescaped($1); }
| path hchar ID
{ $$ = sta::sdf_reader->makePath($1, sta::sdf_reader->unescaped($3)); }
;
del_def:
@ -218,7 +224,6 @@ tchk_def:
{ sta::sdf_reader->timingCheckSetupHold($4, $5, $6, $7);
sta::sdf_reader->setInTimingCheck(false);
}
//| '(' SETUPHOLD port_spec port_spec value value scond? ccond? ')'
| '(' RECOVERY { sta::sdf_reader->setInTimingCheck(true); }
port_tchk port_tchk value ')'
{ sta::sdf_reader->timingCheck(sta::TimingRole::recovery(),$4,$5,$6);
@ -234,7 +239,6 @@ tchk_def:
{ sta::sdf_reader->timingCheckRecRem($4, $5, $6, $7);
sta::sdf_reader->setInTimingCheck(false);
}
//| '(' RECREM port_spec port_spec value value scond? ccond? ')'
| '(' SKEW { sta::sdf_reader->setInTimingCheck(true); }
port_tchk port_tchk value ')'
// Sdf skew clk/ref are reversed from liberty.
@ -258,15 +262,23 @@ tchk_def:
}
;
port_instance:
port:
ID
| PATH
{ $$ = sta::sdf_reader->unescaped($1); }
| ID '[' DNUMBER ']'
{ $$ = sta::stringPrint("%s[%d]", sta::sdf_reader->unescaped($1), $3); }
;
port_instance:
port
| path hchar port
{ $$ = sta::sdf_reader->makePath($1, $3); }
;
port_spec:
ID
port_instance
{ $$=sta::sdf_reader->makePortSpec(sta::Transition::riseFall(),$1,NULL); }
| '(' port_transition ID ')'
| '(' port_transition port_instance ')'
{ $$ = sta::sdf_reader->makePortSpec($2, $3, NULL); }
;
@ -279,8 +291,8 @@ port_tchk:
port_spec
| '(' COND EXPR_ID_CLOSE
{ $$ = sta::sdf_reader->makeCondPortSpec($3); }
| '(' COND EXPR_OPEN port_transition ID ')' ')'
{ $$ = sta::sdf_reader->makePortSpec($4, $5, $3); }
| '(' COND EXPR_OPEN port_transition port_instance ')' ')'
{ $$ = sta::sdf_reader->makePortSpec($4, $5, $3); sta::stringDelete($3); }
;
value:
@ -313,4 +325,12 @@ triple:
}
;
NUMBER:
FNUMBER
| DNUMBER
{ $$ = static_cast<float>($1); }
| '-' DNUMBER
{ $$ = static_cast<float>(-$2); }
;
%%

View File

@ -20,6 +20,7 @@
#include <ctype.h>
#include "Error.hh"
#include "Debug.hh"
#include "Report.hh"
#include "MinMax.hh"
#include "TimingArc.hh"
@ -33,6 +34,7 @@
extern int
SdfParse_parse();
extern int SdfParse_debug;
namespace sta {
@ -55,13 +57,8 @@ class SdfPortSpec
public:
SdfPortSpec(Transition *tr,
const char *port,
const char *cond = nullptr) :
tr_(tr), port_(port), cond_(cond) {}
~SdfPortSpec()
{
stringDelete(port_);
stringDelete(cond_);
}
const char *cond);
~SdfPortSpec();
const char *port() const { return port_; }
Transition *transition() const { return tr_; }
const char *cond() const { return cond_; }
@ -140,6 +137,7 @@ SdfReader::read()
{
// Use zlib to uncompress gzip'd files automagically.
stream_ = gzopen(filename_, "rb");
//::SdfParse_debug = 1;
if (stream_) {
// yyparse returns 0 on success.
bool success = (::SdfParse_parse() == 0);
@ -212,8 +210,6 @@ SdfReader::interconnect(const char *from_pin_name,
sdfWarn(186, "pin %s not found.", to_pin_name);
}
}
stringDelete(from_pin_name);
stringDelete(to_pin_name);
deleteTripleSeq(triples);
}
@ -238,7 +234,6 @@ SdfReader::port(const char *to_pin_name,
}
}
}
stringDelete(to_pin_name);
deleteTripleSeq(triples);
}
@ -314,7 +309,6 @@ SdfReader::setInstance(const char *instance_name)
cell_name_);
}
}
stringDelete(instance_name);
}
else
instance_ = nullptr;
@ -345,12 +339,8 @@ SdfReader::iopath(SdfPortSpec *from_edge,
if (instance_) {
const char *from_port_name = from_edge->port();
Cell *cell = network_->cell(instance_);
Port *from_port = network_->findPort(cell, from_port_name);
Port *to_port = network_->findPort(cell, to_port_name);
if (from_port == nullptr)
portNotFound(from_port_name);
if (to_port == nullptr)
portNotFound(to_port_name);
Port *from_port = findPort(cell, from_port_name);
Port *to_port = findPort(cell, to_port_name);
if (from_port && to_port) {
Pin *from_pin = network_->findPin(instance_, from_port_name);
Pin *to_pin = network_->findPin(instance_, to_port_name);
@ -410,17 +400,33 @@ SdfReader::iopath(SdfPortSpec *from_edge,
}
}
deletePortSpec(from_edge);
stringDelete(to_port_name);
deleteTripleSeq(triples);
if (cond)
stringDelete(cond);
stringDelete(cond);
}
Port *
SdfReader::findPort(const Cell *cell,
const char *port_name)
{
Port *port = network_->findPort(cell, port_name);
if (port == nullptr)
sdfWarn(194, "instance %s port %s not found.",
network_->pathName(instance_),
port_name);
return port;
}
void
SdfReader::timingCheck(TimingRole *role, SdfPortSpec *data_edge,
SdfPortSpec *clk_edge, SdfTriple *triple)
{
timingCheck1(role, data_edge, clk_edge, triple, true);
const char *data_port_name = data_edge->port();
const char *clk_port_name = clk_edge->port();
Cell *cell = network_->cell(instance_);
Port *data_port = findPort(cell, data_port_name);
Port *clk_port = findPort(cell, clk_port_name);
if (data_port && clk_port)
timingCheck1(role, data_port, data_edge, clk_port, clk_edge, triple);
deletePortSpec(data_edge);
deletePortSpec(clk_edge);
deleteTriple(triple);
@ -428,64 +434,54 @@ SdfReader::timingCheck(TimingRole *role, SdfPortSpec *data_edge,
void
SdfReader::timingCheck1(TimingRole *role,
Port *data_port,
SdfPortSpec *data_edge,
Port *clk_port,
SdfPortSpec *clk_edge,
SdfTriple *triple,
bool warn)
SdfTriple *triple)
{
// Ignore non-incremental annotations in incremental only mode.
if (!(is_incremental_only_ && !in_incremental_)
&& instance_) {
const char *data_port_name = data_edge->port();
const char *clk_port_name = clk_edge->port();
Cell *cell = network_->cell(instance_);
Port *data_port = network_->findPort(cell, data_port_name);
Port *clk_port = network_->findPort(cell, clk_port_name);
if (data_port == nullptr && warn)
portNotFound(data_port_name);
if (clk_port == nullptr && warn)
portNotFound(clk_port_name);
if (data_port && clk_port) {
Pin *data_pin = network_->findPin(instance_, data_port_name);
Pin *clk_pin = network_->findPin(instance_, clk_port_name);
if (data_pin && clk_pin) {
// Hack: always use triple max value for check.
float **values = triple->values();
float *value_min = values[triple_min_index_];
float *value_max = values[triple_max_index_];
if (value_min && value_max) {
switch (analysis_type_) {
case AnalysisType::single:
break;
case AnalysisType::bc_wc:
if (role->genericRole() == TimingRole::setup())
*value_min = *value_max;
else
*value_max = *value_min;
break;
case AnalysisType::ocv:
Pin *data_pin = network_->findPin(instance_, data_port);
Pin *clk_pin = network_->findPin(instance_, clk_port);
if (data_pin && clk_pin) {
// Hack: always use triple max value for check.
float **values = triple->values();
float *value_min = values[triple_min_index_];
float *value_max = values[triple_max_index_];
if (value_min && value_max) {
switch (analysis_type_) {
case AnalysisType::single:
break;
case AnalysisType::bc_wc:
if (role->genericRole() == TimingRole::setup())
*value_min = *value_max;
break;
}
else
*value_max = *value_min;
break;
case AnalysisType::ocv:
*value_min = *value_max;
break;
}
bool matched = annotateCheckEdges(data_pin, data_edge,
clk_pin, clk_edge, role,
triple, false);
// Liberty setup/hold checks on preset/clear pins can be translated
// into recovery/removal checks, so be flexible about matching.
if (!matched)
matched = annotateCheckEdges(data_pin, data_edge,
clk_pin, clk_edge, role,
triple, true);
if (!matched
// Only warn when non-null values are present.
&& triple->hasValue())
sdfWarn(192, "cell %s %s -> %s %s check not found.",
network_->cellName(instance_),
data_port_name,
clk_port_name,
role->asString());
}
bool matched = annotateCheckEdges(data_pin, data_edge,
clk_pin, clk_edge, role,
triple, false);
// Liberty setup/hold checks on preset/clear pins can be translated
// into recovery/removal checks, so be flexible about matching.
if (!matched)
matched = annotateCheckEdges(data_pin, data_edge,
clk_pin, clk_edge, role,
triple, true);
if (!matched
// Only warn when non-null values are present.
&& triple->hasValue())
sdfWarn(192, "cell %s %s -> %s %s check not found.",
network_->cellName(instance_),
network_->name(data_port),
network_->name(clk_port),
role->asString());
}
}
}
@ -545,10 +541,8 @@ SdfReader::timingCheckWidth(SdfPortSpec *edge,
&& instance_) {
const char *port_name = edge->port();
Cell *cell = network_->cell(instance_);
Port *port = network_->findPort(cell, port_name);
if (port == nullptr)
portNotFound(port_name);
else {
Port *port = findPort(cell, port_name);
if (port) {
Pin *pin = network_->findPin(instance_, port_name);
if (pin) {
const RiseFall *rf = edge->transition()->asRiseFall();
@ -574,6 +568,49 @@ SdfReader::timingCheckWidth(SdfPortSpec *edge,
deleteTriple(triple);
}
void
SdfReader::timingCheckSetupHold(SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
SdfTriple *setup_triple,
SdfTriple *hold_triple)
{
timingCheckSetupHold1(data_edge, clk_edge, setup_triple, hold_triple,
TimingRole::setup(), TimingRole::hold());
}
void
SdfReader::timingCheckRecRem(SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
SdfTriple *rec_triple,
SdfTriple *rem_triple)
{
timingCheckSetupHold1(data_edge, clk_edge, rec_triple, rem_triple,
TimingRole::recovery(), TimingRole::removal());
}
void
SdfReader::timingCheckSetupHold1(SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
SdfTriple *setup_triple,
SdfTriple *hold_triple,
TimingRole *setup_role,
TimingRole *hold_role)
{
const char *data_port_name = data_edge->port();
const char *clk_port_name = clk_edge->port();
Cell *cell = network_->cell(instance_);
Port *data_port = findPort(cell, data_port_name);
Port *clk_port = findPort(cell, clk_port_name);
if (data_port && clk_port) {
timingCheck1(setup_role, data_port, data_edge, clk_port, clk_edge, setup_triple);
timingCheck1(hold_role, data_port, data_edge, clk_port, clk_edge, hold_triple);
}
deletePortSpec(data_edge);
deletePortSpec(clk_edge);
deleteTriple(setup_triple);
deleteTriple(hold_triple);
}
void
SdfReader::timingCheckPeriod(SdfPortSpec *edge,
SdfTriple *triple)
@ -583,10 +620,8 @@ SdfReader::timingCheckPeriod(SdfPortSpec *edge,
&& instance_) {
const char *port_name = edge->port();
Cell *cell = network_->cell(instance_);
Port *port = network_->findPort(cell, port_name);
if (port == nullptr)
portNotFound(port_name);
else {
Port *port = findPort(cell, port_name);
if (port) {
// Edge specifier is ignored for period checks.
Pin *pin = network_->findPin(instance_, port_name);
if (pin) {
@ -610,34 +645,6 @@ SdfReader::timingCheckPeriod(SdfPortSpec *edge,
deleteTriple(triple);
}
void
SdfReader::timingCheckSetupHold(SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
SdfTriple *setup_triple,
SdfTriple *hold_triple)
{
timingCheck1(TimingRole::setup(), data_edge, clk_edge, setup_triple, true);
timingCheck1(TimingRole::hold(), data_edge, clk_edge, hold_triple, false);
deletePortSpec(data_edge);
deletePortSpec(clk_edge);
deleteTriple(setup_triple);
deleteTriple(hold_triple);
}
void
SdfReader::timingCheckRecRem(SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
SdfTriple *rec_triple,
SdfTriple *rem_triple)
{
timingCheck1(TimingRole::recovery(), data_edge, clk_edge, rec_triple, true);
timingCheck1(TimingRole::removal(), data_edge, clk_edge, rem_triple, false);
deletePortSpec(data_edge);
deletePortSpec(clk_edge);
deleteTriple(rec_triple);
deleteTriple(rem_triple);
}
void
SdfReader::timingCheckNochange(SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
@ -675,15 +682,12 @@ SdfReader::device(const char *to_port_name,
if (!(is_incremental_only_ && !in_incremental_)
&& instance_) {
Cell *cell = network_->cell(instance_);
Port *to_port = network_->findPort(cell, to_port_name);
if (to_port == nullptr)
portNotFound(to_port_name);
else {
Port *to_port = findPort(cell, to_port_name);
if (to_port) {
Pin *to_pin = network_->findPin(instance_, to_port_name);
setDevicePinDelays(to_pin, triples);
}
}
stringDelete(to_port_name);
deleteTripleSeq(triples);
}
@ -822,7 +826,7 @@ SdfReader::makePortSpec(Transition *tr,
}
SdfPortSpec *
SdfReader::makeCondPortSpec(char *cond_port)
SdfReader::makeCondPortSpec(const char *cond_port)
{
// Search from end to find port name because condition may contain spaces.
string cond_port1(cond_port);
@ -834,12 +838,13 @@ SdfReader::makeCondPortSpec(char *cond_port)
if (cond_end != cond_port1.npos) {
string cond1 = cond_port1.substr(0, cond_end + 1);
SdfPortSpec *port_spec = makePortSpec(Transition::riseFall(),
stringCopy(port1.c_str()),
stringCopy(cond1.c_str()));
port1.c_str(),
cond1.c_str());
stringDelete(cond_port);
return port_spec;
}
}
stringDelete(cond_port);
return nullptr;
}
@ -916,14 +921,14 @@ SdfReader::unescaped(const char *token)
char path_divider = network_->pathDivider();
char *unescaped = makeTmpString(strlen(token) + 1);
char *u = unescaped;
for (const char *s = token; *s ; s++) {
char ch = *s;
size_t token_length = strlen(token);
for (size_t i = 0; i < token_length; i++) {
char ch = token[i];
if (ch == escape_) {
char next_ch = s[1];
char next_ch = token[i + 1];
if (next_ch == divider_) {
// Escaped divider.
// Escaped divider.
// Translate sdf escape to network escape.
*u++ = path_escape;
// Translate sdf divider to network divider.
@ -938,21 +943,32 @@ SdfReader::unescaped(const char *token)
*u++ = next_ch;
}
else
// Escaped non-divider/bracket character.
*u++ = next_ch;
s++;
// Escaped non-divider character.
*u++ = next_ch;
i++;
}
else if (ch == divider_)
// Translate sdf divider to network divider.
*u++ = path_divider;
else
// Just the normal noises.
*u++ = ch;
}
*u = '\0';
debugPrint(debug_, "sdf_name", 1, "token %s -> %s", token, unescaped);
stringDelete(token);
return unescaped;
}
// Translate sdf divider to network divider.
char *
SdfReader::makePath(const char *head,
const char *tail)
{
char *path = stringPrintTmp("%s%c%s",
head,
network_->pathDivider(),
tail);
return path;
}
void
SdfReader::incrLine()
{
@ -989,14 +1005,6 @@ SdfReader::notSupported(const char *feature)
sdfError(193, "%s not supported.", feature);
}
void
SdfReader::portNotFound(const char *port_name)
{
sdfWarn(194, "instance %s port %s not found.",
network_->pathName(instance_),
port_name);
}
void
SdfReader::sdfWarn(int id,
const char *fmt, ...)
@ -1044,6 +1052,23 @@ SdfReader::findInstance(const char *name)
////////////////////////////////////////////////////////////////
SdfPortSpec::SdfPortSpec(Transition *tr,
const char *port,
const char *cond) :
tr_(tr),
port_(stringCopy(port)),
cond_(stringCopy(cond))
{
}
SdfPortSpec::~SdfPortSpec()
{
stringDelete(port_);
stringDelete(cond_);
}
////////////////////////////////////////////////////////////////
SdfTriple::SdfTriple(float *min,
float *typ,
float *max)

View File

@ -108,6 +108,12 @@ public:
SdfPortSpec *clk_edge,
SdfTriple *rec_triple,
SdfTriple *rem_triple);
void timingCheckSetupHold1(SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
SdfTriple *setup_triple,
SdfTriple *hold_triple,
TimingRole *setup_role,
TimingRole *hold_role);
void timingCheckNochange(SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
SdfTriple *before_triple,
@ -129,8 +135,10 @@ public:
SdfPortSpec *makePortSpec(Transition *tr,
const char *port,
const char *cond);
SdfPortSpec *makeCondPortSpec(char *cond_port);
const char *unescaped(const char *s);
SdfPortSpec *makeCondPortSpec(const char *cond_port);
const char *unescaped(const char *token);
char *makePath(const char *head,
const char *tail);
// Parser state used to control lexer for COND handling.
bool inTimingCheck() { return in_timing_check_; }
void setInTimingCheck(bool in);
@ -169,10 +177,11 @@ private:
bool condMatch(const char *sdf_cond,
const char *lib_cond);
void timingCheck1(TimingRole *role,
SdfPortSpec *data_edge,
SdfPortSpec *clk_edge,
SdfTriple *triple,
bool warn);
Port *data_port,
SdfPortSpec *data_edge,
Port *clk_port,
SdfPortSpec *clk_edge,
SdfTriple *triple);
bool annotateCheckEdges(Pin *data_pin,
SdfPortSpec *data_edge,
Pin *clk_pin,
@ -181,7 +190,6 @@ private:
SdfTriple *triple,
bool match_generic);
void deletePortSpec(SdfPortSpec *edge);
void portNotFound(const char *port_name);
Pin *findPin(const char *name);
Instance *findInstance(const char *name);
void setEdgeDelays(Edge *edge,
@ -189,6 +197,8 @@ private:
const char *sdf_cmd);
void setDevicePinDelays(Pin *to_pin,
SdfTripleSeq *triples);
Port *findPort(const Cell *cell,
const char *port_name);
const char *filename_;
const char *path_;

View File

@ -792,23 +792,33 @@ char *
SdfWriter::sdfPortName(const Pin *pin)
{
const char *name = network_->portName(pin);
char *sdf_name = makeTmpString(strlen(name) * 2 + 1);
const char *p = name;
size_t name_length = strlen(name);
char *sdf_name = makeTmpString(name_length * 2 + 1);
char *s = sdf_name;
while (*p) {
char ch = *p;
constexpr char bus_brkt_left = '[';
constexpr char bus_brkt_right = ']';
size_t bus_index = name_length;
if (name_length >= 4
&& name[name_length - 1] == bus_brkt_right) {
const char *left = strrchr(name, bus_brkt_left);
if (left)
bus_index = left - name;
}
for (size_t i = 0; i < name_length; i++) {
char ch = name[i];
if (ch == network_escape_) {
// Copy escape and escaped char.
*s++ = sdf_escape_;
*s++ = *++p;
*s++ = name[++i];
}
else {
if (!(isalnum(ch) || ch == '_' || ch == '[' || ch == ']'))
if (!(isalnum(ch) || ch == '_')
&& !(i >= bus_index && (ch == bus_brkt_right || ch == bus_brkt_left)))
// Insert escape.
*s++ = sdf_escape_;
*s++ = ch;
}
p++;
}
*s = '\0';
return sdf_name;

View File

@ -209,7 +209,7 @@ makeTmpString(size_t length)
size_t tmp_length = tmp_string_lengths_[tmp_string_next_];
if (tmp_length < length) {
// String isn't long enough. Make a new one.
stringDelete(tmp_str);
delete [] tmp_str;
tmp_str = new char[length];
tmp_strings_[tmp_string_next_] = tmp_str;
tmp_string_lengths_[tmp_string_next_] = length;
@ -218,6 +218,27 @@ makeTmpString(size_t length)
return tmp_str;
}
void
stringDeleteCheck(const char *str)
{
if (isTmpString(str)) {
printf("Critical error: stringDelete for tmp string.");
exit(1);
}
}
bool
isTmpString(const char *str)
{
if (tmp_strings_) {
for (int i = 0; i < tmp_string_count_; i++) {
if (str == tmp_strings_[i])
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////
void

View File

@ -138,7 +138,7 @@ wire { return WIRE; }
wor { return WOR; }
{ID_TOKEN}("."{ID_TOKEN})* {
VerilogParse_lval.string = sta::stringCopy(sta::verilogToSta(VerilogLex_text));
VerilogParse_lval.string = sta::stringCopy(VerilogLex_text);
return ID;
}

View File

@ -36,9 +36,6 @@ namespace sta {
VerilogReader *verilog_reader;
static const char *unconnected_net_name = reinterpret_cast<const char*>(1);
static const char *
verilogBusBitName(const char *bus_name,
int index);
static const char *
verilogBusBitNameTmp(const char *bus_name,
int index);
@ -253,28 +250,30 @@ VerilogReader::module(Cell *cell)
}
void
VerilogReader::makeModule(const char *name,
VerilogReader::makeModule(const char *module_vname,
VerilogNetSeq *ports,
VerilogStmtSeq *stmts,
int line)
{
Cell *cell = network_->findCell(library_, name);
const char *module_name = moduleVerilogToSta(module_vname);
Cell *cell = network_->findCell(library_, module_name);
if (cell) {
VerilogModule *module = module_map_[cell];
delete module;
module_map_.erase(cell);
network_->deleteCell(cell);
}
VerilogModule *module = new VerilogModule(name, ports, stmts,
VerilogModule *module = new VerilogModule(module_name, ports, stmts,
filename_, line, this);
cell = network_->makeCell(library_, name, false, filename_);
cell = network_->makeCell(library_, module_name, false, filename_);
module_map_[cell] = module;
makeCellPorts(cell, module, ports);
module_count_++;
stringDelete(module_vname);
}
void
VerilogReader::makeModule(const char *name,
VerilogReader::makeModule(const char *module_name,
VerilogStmtSeq *port_dcls,
VerilogStmtSeq *stmts,
int line)
@ -285,8 +284,7 @@ VerilogReader::makeModule(const char *name,
if (dcl->isDeclaration()) {
VerilogDcl *dcl1 = dynamic_cast<VerilogDcl*>(dcl);
for (VerilogDclArg *arg : *dcl1->args()) {
const char *port_name = stringCopy(arg->netName());
VerilogNetNamed *port = new VerilogNetScalar(port_name);
VerilogNetNamed *port = new VerilogNetScalar(arg->netName());
ports->push_back(port);
}
// Add the port declarations to the statements.
@ -294,7 +292,7 @@ VerilogReader::makeModule(const char *name,
}
}
delete port_dcls;
makeModule(name, ports, stmts, line);
makeModule(module_name, ports, stmts, line);
}
void
@ -456,10 +454,13 @@ VerilogReader::makeDclBus(PortDirection *dir,
}
VerilogDclArg *
VerilogReader::makeDclArg(const char *net_name)
VerilogReader::makeDclArg(const char *net_vname)
{
dcl_arg_count_++;
return new VerilogDclArg(net_name);
const char *net_name = netVerilogToSta(net_vname);
VerilogDclArg *dcl =new VerilogDclArg(net_name);
stringDelete(net_vname);
return dcl;
}
VerilogDclArg *
@ -470,14 +471,18 @@ VerilogReader::makeDclArg(VerilogAssign *assign)
}
VerilogNetPartSelect *
VerilogReader::makeNetPartSelect(const char *name,
VerilogReader::makeNetPartSelect(const char *net_vname,
int from_index,
int to_index)
{
net_part_select_count_++;
if (report_stmt_stats_)
net_bus_names_ += strlen(name) + 1;
return new VerilogNetPartSelect(name, from_index, to_index);
net_bus_names_ += strlen(net_vname) + 1;
const char *net_name = netVerilogToSta(net_vname);
VerilogNetPartSelect *select = new VerilogNetPartSelect(net_name, from_index,
to_index);
stringDelete(net_vname);
return select;
}
VerilogNetConstant *
@ -488,22 +493,28 @@ VerilogReader::makeNetConstant(const char *constant)
}
VerilogNetScalar *
VerilogReader::makeNetScalar(const char *name)
VerilogReader::makeNetScalar(const char *net_vname)
{
net_scalar_count_++;
if (report_stmt_stats_)
net_scalar_names_ += strlen(name) + 1;
return new VerilogNetScalar(name);
net_scalar_names_ += strlen(net_vname) + 1;
const char *net_name = netVerilogToSta(net_vname);
VerilogNetScalar *scalar = new VerilogNetScalar(net_name);
stringDelete(net_vname);
return scalar;
}
VerilogNetBitSelect *
VerilogReader::makeNetBitSelect(const char *name,
VerilogReader::makeNetBitSelect(const char *net_vname,
int index)
{
net_bit_select_count_++;
if (report_stmt_stats_)
net_bus_names_ += strlen(name) + 1;
return new VerilogNetBitSelect(name, index);
net_bus_names_ += strlen(net_vname) + 1;
const char *net_name = netVerilogToSta(net_vname);
VerilogNetBitSelect *select = new VerilogNetBitSelect(net_name, index);
stringDelete(net_vname);
return select;
}
VerilogAssign *
@ -516,11 +527,13 @@ VerilogReader::makeAssign(VerilogNet *lhs,
}
VerilogInst *
VerilogReader::makeModuleInst(const char *module_name,
const char *inst_name,
VerilogReader::makeModuleInst(const char *module_vname,
const char *inst_vname,
VerilogNetSeq *pins,
const int line)
{
const char *module_name = moduleVerilogToSta(module_vname);
const char *inst_name = instanceVerilogToSta(inst_vname);
Cell *cell = network_->findAnyCell(module_name);
LibertyCell *liberty_cell = nullptr;
if (cell)
@ -558,13 +571,14 @@ VerilogReader::makeModuleInst(const char *module_name,
}
VerilogInst *inst = new VerilogLibertyInst(liberty_cell, inst_name,
net_names, line);
stringDelete(module_name);
delete pins;
if (report_stmt_stats_) {
inst_names_ += strlen(inst_name) + 1;
inst_lib_count_++;
inst_lib_net_arrays_ += port_count;
}
stringDelete(module_vname);
stringDelete(inst_vname);
return inst;
}
else {
@ -574,6 +588,8 @@ VerilogReader::makeModuleInst(const char *module_name,
inst_names_ += strlen(inst_name) + 1;
inst_mod_count_++;
}
stringDelete(module_vname);
stringDelete(inst_vname);
return inst;
}
}
@ -603,60 +619,79 @@ VerilogReader::hasScalarNamedPortRefs(LibertyCell *liberty_cell,
}
VerilogNetPortRef *
VerilogReader::makeNetNamedPortRefScalarNet(const char *port_name,
const char *net_name)
VerilogReader::makeNetNamedPortRefScalarNet(const char *port_vname,
const char *net_vname)
{
net_port_ref_scalar_net_count_++;
if (report_stmt_stats_) {
if (net_name)
net_scalar_names_ += strlen(net_name) + 1;
port_names_ += strlen(port_name) + 1;
if (net_vname)
net_scalar_names_ += strlen(net_vname) + 1;
port_names_ += strlen(port_vname) + 1;
}
return new VerilogNetPortRefScalarNet(port_name, net_name);
const char *port_name = portVerilogToSta(port_vname);
const char *net_name = netVerilogToSta(net_vname);
VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name, net_name);
stringDelete(port_vname);
stringDelete(net_vname);
return ref;
}
VerilogNetPortRef *
VerilogReader::makeNetNamedPortRefBitSelect(const char *port_name,
const char *bus_name,
VerilogReader::makeNetNamedPortRefBitSelect(const char *port_vname,
const char *bus_vname,
int index)
{
net_port_ref_scalar_net_count_++;
const char *net_name = verilogBusBitName(bus_name, index);
const char *bus_name = portVerilogToSta(bus_vname);
const char *net_name = verilogBusBitNameTmp(bus_name, index);
if (report_stmt_stats_) {
net_scalar_names_ += strlen(net_name) + 1;
port_names_ += strlen(port_name) + 1;
port_names_ += strlen(port_vname) + 1;
}
stringDelete(bus_name);
return new VerilogNetPortRefScalarNet(port_name, net_name);
const char *port_name = portVerilogToSta(port_vname);
VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name, net_name);
stringDelete(port_vname);
stringDelete(bus_vname);
return ref;
}
VerilogNetPortRef *
VerilogReader::makeNetNamedPortRefScalar(const char *port_name,
VerilogReader::makeNetNamedPortRefScalar(const char *port_vname,
VerilogNet *net)
{
net_port_ref_scalar_count_++;
if (report_stmt_stats_)
port_names_ += strlen(port_name) + 1;
return new VerilogNetPortRefScalar(port_name, net);
port_names_ += strlen(port_vname) + 1;
const char *port_name = portVerilogToSta(port_vname);
VerilogNetPortRef *ref = new VerilogNetPortRefScalar(port_name, net);
stringDelete(port_vname);
return ref;
}
VerilogNetPortRef *
VerilogReader::makeNetNamedPortRefBit(const char *port_name,
VerilogReader::makeNetNamedPortRefBit(const char *port_vname,
int index,
VerilogNet *net)
{
net_port_ref_bit_count_++;
return new VerilogNetPortRefBit(port_name, index, net);
const char *port_name = portVerilogToSta(port_vname);
VerilogNetPortRef *ref = new VerilogNetPortRefBit(port_name, index, net);
stringDelete(port_vname);
return ref;
}
VerilogNetPortRef *
VerilogReader::makeNetNamedPortRefPart(const char *port_name,
VerilogReader::makeNetNamedPortRefPart(const char *port_vname,
int from_index,
int to_index,
VerilogNet *net)
{
net_port_ref_part_count_++;
return new VerilogNetPortRefPart(port_name, from_index, to_index, net);
const char *port_name = portVerilogToSta(port_vname);
VerilogNetPortRef *ref = new VerilogNetPortRefPart(port_name, from_index,
to_index, net);
stringDelete(port_vname);
return ref;
}
VerilogNetConcat *
@ -769,7 +804,7 @@ VerilogModule::VerilogModule(const char *name,
int line,
VerilogReader *reader) :
VerilogStmt(line),
name_(name),
name_(stringCopy(name)),
filename_(filename),
ports_(ports),
stmts_(stmts)
@ -879,9 +914,9 @@ VerilogStmt::VerilogStmt(int line) :
}
VerilogInst::VerilogInst(const char *inst_name,
const int line) :
const int line) :
VerilogStmt(line),
inst_name_(inst_name)
inst_name_(stringCopy(inst_name))
{
}
@ -902,7 +937,7 @@ VerilogModuleInst::VerilogModuleInst(const char *module_name,
VerilogNetSeq *pins,
int line) :
VerilogInst(inst_name, line),
module_name_(module_name),
module_name_(stringCopy(module_name)),
pins_(pins)
{
}
@ -1020,7 +1055,7 @@ VerilogDclBus::size() const
}
VerilogDclArg::VerilogDclArg(const char *net_name) :
net_name_(net_name),
net_name_(stringCopy(net_name)),
assign_(nullptr)
{
}
@ -1156,13 +1191,6 @@ verilogBusBitNameTmp(const char *bus_name,
return stringPrintTmp("%s[%d]", bus_name, index);
}
static const char *
verilogBusBitName(const char *bus_name,
int index)
{
return stringPrint("%s[%d]", bus_name, index);
}
class VerilogConstantNetNameIterator : public VerilogNetNameIterator
{
public:
@ -1265,7 +1293,7 @@ VerilogNetConcatNameIterator::next()
VerilogNetNamed::VerilogNetNamed(const char *name) :
VerilogNet(),
name_(name)
name_(stringCopy(name))
{
}
@ -1277,6 +1305,7 @@ VerilogNetNamed::~VerilogNetNamed()
void
VerilogNetNamed::setName(const char *name)
{
stringDelete(name_);
name_ = name;
}
@ -1554,11 +1583,10 @@ VerilogNetPortRef::VerilogNetPortRef(const char *name) :
{
}
VerilogNetPortRefScalarNet::
VerilogNetPortRefScalarNet(const char *name,
const char *net_name) :
VerilogNetPortRefScalarNet::VerilogNetPortRefScalarNet(const char *name,
const char *net_name) :
VerilogNetPortRef(name),
net_name_(net_name)
net_name_(stringCopy(net_name))
{
}