diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index 22b38aa2..38859dfc 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -1093,4 +1093,7 @@ private: LibertyCell *cell_; }; +const char * +portLibertyToSta(const char *port_name); + } // namespace diff --git a/include/sta/StringUtil.hh b/include/sta/StringUtil.hh index 94553966..ddaf1dae 100644 --- a/include/sta/StringUtil.hh +++ b/include/sta/StringUtil.hh @@ -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); //////////////////////////////////////////////////////////////// diff --git a/include/sta/VerilogNamespace.hh b/include/sta/VerilogNamespace.hh index d0524391..3e379ba3 100644 --- a/include/sta/VerilogNamespace.hh +++ b/include/sta/VerilogNamespace.hh @@ -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 diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index b3683b64..9846765c 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -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 diff --git a/liberty/LibertyBuilder.cc b/liberty/LibertyBuilder.cc index 50835c8b..8374f2c7 100644 --- a/liberty/LibertyBuilder.cc +++ b/liberty/LibertyBuilder.cc @@ -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); } } diff --git a/liberty/LibertyBuilder.hh b/liberty/LibertyBuilder.hh index b07fe061..2086dae3 100644 --- a/liberty/LibertyBuilder.hh +++ b/liberty/LibertyBuilder.hh @@ -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, diff --git a/liberty/LibertyExpr.cc b/liberty/LibertyExpr.cc index 27f55601..5e5d3e40 100644 --- a/liberty/LibertyExpr.cc +++ b/liberty/LibertyExpr.cc @@ -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; } diff --git a/liberty/LibertyExprLex.ll b/liberty/LibertyExprLex.ll index d756cf6e..15a7e2a2 100644 --- a/liberty/LibertyExprLex.ll +++ b/liberty/LibertyExprLex.ll @@ -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] diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 980c511d..8e703b22 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -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_--; diff --git a/network/SdcNetwork.cc b/network/SdcNetwork.cc index 99a4ee70..7d1f8383 100644 --- a/network/SdcNetwork.cc +++ b/network/SdcNetwork.cc @@ -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), diff --git a/network/VerilogNamespace.cc b/network/VerilogNamespace.cc index e806e4c5..8252b5da 100644 --- a/network/VerilogNamespace.cc +++ b/network/VerilogNamespace.cc @@ -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 diff --git a/parasitics/SpefNamespace.cc b/parasitics/SpefNamespace.cc index 5f977004..f1537b86 100644 --- a/parasitics/SpefNamespace.cc +++ b/parasitics/SpefNamespace.cc @@ -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]; diff --git a/power/ReadVcdActivities.cc b/power/ReadVcdActivities.cc index dfc2c13d..329cd1c6 100644 --- a/power/ReadVcdActivities.cc +++ b/power/ReadVcdActivities.cc @@ -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 { diff --git a/sdf/SdfLex.ll b/sdf/SdfLex.ll index 02b0f59f..e333ca43 100644 --- a/sdf/SdfLex.ll +++ b/sdf/SdfLex.ll @@ -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(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 { . { 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. */ } diff --git a/sdf/SdfParse.yy b/sdf/SdfParse.yy index 9367b45a..eea4e83b 100644 --- a/sdf/SdfParse.yy +++ b/sdf/SdfParse.yy @@ -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 +%type FNUMBER NUMBER +%type DNUMBER %type number_opt %type value triple %type delval_list -%type QSTRING ID PATH path port_instance +%type QSTRING ID path port port_instance %type EXPR_OPEN_IOPATH EXPR_OPEN EXPR_ID_CLOSE %type port_spec port_tchk %type 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($1); } +| '-' DNUMBER + { $$ = static_cast(-$2); } +; + %% diff --git a/sdf/SdfReader.cc b/sdf/SdfReader.cc index 1ad8598f..ae51eeed 100644 --- a/sdf/SdfReader.cc +++ b/sdf/SdfReader.cc @@ -20,6 +20,7 @@ #include #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) diff --git a/sdf/SdfReaderPvt.hh b/sdf/SdfReaderPvt.hh index 466a4d39..105bd4cd 100644 --- a/sdf/SdfReaderPvt.hh +++ b/sdf/SdfReaderPvt.hh @@ -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_; diff --git a/sdf/SdfWriter.cc b/sdf/SdfWriter.cc index 39c0ba7a..8283368e 100644 --- a/sdf/SdfWriter.cc +++ b/sdf/SdfWriter.cc @@ -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; diff --git a/util/StringUtil.cc b/util/StringUtil.cc index 7ac2c01c..2add4630 100644 --- a/util/StringUtil.cc +++ b/util/StringUtil.cc @@ -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 diff --git a/verilog/VerilogLex.ll b/verilog/VerilogLex.ll index 0e2fc9fc..8fa39eb4 100644 --- a/verilog/VerilogLex.ll +++ b/verilog/VerilogLex.ll @@ -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; } diff --git a/verilog/VerilogReader.cc b/verilog/VerilogReader.cc index c77efff4..3bb312c5 100644 --- a/verilog/VerilogReader.cc +++ b/verilog/VerilogReader.cc @@ -36,9 +36,6 @@ namespace sta { VerilogReader *verilog_reader; static const char *unconnected_net_name = reinterpret_cast(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(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)) { }