Liberty power_down_function parse resolves #428
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
7e68e452d3
commit
8cbd400249
|
|
@ -91,6 +91,9 @@ stringEqual(std::string_view s1,
|
|||
|
||||
std::pair<float, bool>
|
||||
stringFloat(const std::string &str);
|
||||
std::pair<long long, bool>
|
||||
stringLong(const std::string &str,
|
||||
int base = 10);
|
||||
|
||||
bool
|
||||
isDigits(const char *str);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ sta::LibertyParse::error(const location_type &loc,
|
|||
%define api.parser.class {LibertyParse}
|
||||
%define api.value.type variant
|
||||
|
||||
%expect 2
|
||||
%expect 0
|
||||
|
||||
%token <std::string> STRING KEYWORD
|
||||
%token <float> FLOAT
|
||||
|
|
@ -75,8 +75,8 @@ sta::LibertyParse::error(const location_type &loc,
|
|||
%type <void *> statement complex_attr simple_attr variable group file
|
||||
%type <sta::LibertyAttrValueSeq *> attr_values
|
||||
%type <sta::LibertyAttrValue *> attr_value
|
||||
%type <std::string> string expr expr_term expr_term1 volt_expr
|
||||
%type <char> expr_op volt_op
|
||||
%type <std::string> string expr expr_term expr_term1
|
||||
%type <char> expr_op
|
||||
|
||||
%start file
|
||||
|
||||
|
|
@ -157,36 +157,8 @@ string:
|
|||
;
|
||||
|
||||
attr_value:
|
||||
FLOAT
|
||||
{ $$ = reader->makeAttrValueFloat($1); }
|
||||
| expr
|
||||
expr
|
||||
{ $$ = reader->makeAttrValueString(std::move($1)); }
|
||||
| volt_expr
|
||||
{ $$ = reader->makeAttrValueString(std::move($1)); }
|
||||
;
|
||||
|
||||
/* Voltage expressions are ignored. */
|
||||
/* Crafted to avoid conflicts with expr */
|
||||
volt_expr:
|
||||
FLOAT volt_op FLOAT
|
||||
{ $$ = sta::format("{}{}{}", $1, $2, $3); }
|
||||
| string volt_op FLOAT
|
||||
{ $$ = sta::format("{}{}{}", $1, $2, $3); }
|
||||
| FLOAT volt_op string
|
||||
{ $$ = sta::format("{}{}{}", $1, $2, $3); }
|
||||
| volt_expr volt_op FLOAT
|
||||
{ $$ = sta::format("{}{}{}", $1, $2, $3); }
|
||||
;
|
||||
|
||||
volt_op:
|
||||
'+'
|
||||
{ $$ = '+'; }
|
||||
| '-'
|
||||
{ $$ = '-'; }
|
||||
| '*'
|
||||
{ $$ = '*'; }
|
||||
| '/'
|
||||
{ $$ = '/'; }
|
||||
;
|
||||
|
||||
expr:
|
||||
|
|
@ -197,6 +169,8 @@ expr:
|
|||
|
||||
expr_term:
|
||||
string
|
||||
| FLOAT
|
||||
{ $$ = sta::format("{}", $1); }
|
||||
| '0'
|
||||
{ $$ = std::string("0"); }
|
||||
| '1'
|
||||
|
|
@ -224,6 +198,10 @@ expr_op:
|
|||
{ $$ = '&'; }
|
||||
| '^'
|
||||
{ $$ = '^'; }
|
||||
| '-'
|
||||
{ $$ = '-'; }
|
||||
| '/'
|
||||
{ $$ = '/'; }
|
||||
;
|
||||
|
||||
semi_opt:
|
||||
|
|
|
|||
|
|
@ -513,6 +513,13 @@ LibertyGroup::findAttrInt(std::string_view attr_name,
|
|||
exists = exists1;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
const std::string &int_str = attr_value.stringValue();
|
||||
auto [value1, valid1] = stringLong(int_str);
|
||||
value = value1;
|
||||
exists = valid1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
exists = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2344,16 +2344,13 @@ LibertyReader::readReceiverCapacitance(const LibertyGroup *timing_group,
|
|||
std::string cap_group_name1 = sta::format("{}_{}", cap_group_name, rf->to_string());
|
||||
const LibertyGroup *cap_group = timing_group->findSubgroup(cap_group_name1);
|
||||
if (cap_group) {
|
||||
const LibertySimpleAttr *segment_attr = cap_group->findSimpleAttr("segment");
|
||||
if (segment_attr) {
|
||||
// For receiver_capacitance groups with mulitiple segments this
|
||||
// overrides the index passed in beginReceiverCapacitance1Rise/Fall.
|
||||
int segment;
|
||||
bool exists;
|
||||
getAttrInt(segment_attr, segment, exists);
|
||||
if (exists)
|
||||
index = segment;
|
||||
}
|
||||
// For receiver_capacitance groups with mulitiple segments this
|
||||
// overrides the index passed in beginReceiverCapacitance1Rise/Fall.
|
||||
int segment;
|
||||
bool exists;
|
||||
cap_group->findAttrInt("segment", segment, exists);
|
||||
if (exists)
|
||||
index = segment;
|
||||
TableModel *model = readTableModel(cap_group, rf, TableTemplateType::delay,
|
||||
cap_scale_, ScaleFactorType::pin_cap);
|
||||
if (ReceiverModel::checkAxes(model)) {
|
||||
|
|
@ -3224,24 +3221,6 @@ LibertyReader::makeFloatTable(const LibertyComplexAttr *values_attr,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
LibertyReader::getAttrInt(const LibertySimpleAttr *attr,
|
||||
// Return values.
|
||||
int &value,
|
||||
bool &exists)
|
||||
{
|
||||
value = 0;
|
||||
exists = false;
|
||||
const LibertyAttrValue &attr_value = attr->value();
|
||||
if (attr_value.isFloat()) {
|
||||
auto [float_val, valid] = attr_value.floatValue();
|
||||
value = static_cast<int>(float_val);
|
||||
exists = true;
|
||||
}
|
||||
else
|
||||
warn(1268, attr, "{} attribute is not an integer.", attr->name());
|
||||
}
|
||||
|
||||
// Get two floats in a complex attribute.
|
||||
// attr(float1, float2);
|
||||
void
|
||||
|
|
|
|||
|
|
@ -418,10 +418,6 @@ protected:
|
|||
StateInternalValues parseStateInternalValues(StringSeq &states,
|
||||
const LibertySimpleAttr *attr);
|
||||
|
||||
void getAttrInt(const LibertySimpleAttr *attr,
|
||||
// Return values.
|
||||
int &value,
|
||||
bool &exists);
|
||||
void getAttrFloat2(const LibertyComplexAttr *attr,
|
||||
// Return values.
|
||||
float &value1,
|
||||
|
|
|
|||
|
|
@ -78,6 +78,32 @@ stringFloat(const std::string &str)
|
|||
#endif
|
||||
}
|
||||
|
||||
std::pair<long long, bool>
|
||||
stringLong(const std::string &str,
|
||||
int base)
|
||||
{
|
||||
long long value;
|
||||
#if defined(__cpp_lib_to_chars) && __cpp_lib_to_chars >= 201611L
|
||||
auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value, base);
|
||||
|
||||
// Check for success and that we consumed the entire string
|
||||
if (ec == std::errc() && ptr == str.data() + str.size())
|
||||
return {value, true};
|
||||
else
|
||||
return {0LL, false};
|
||||
#else
|
||||
char *ptr;
|
||||
errno = 0;
|
||||
// strtoll handles "long long" specifically
|
||||
value = std::strtoll(str.data(), &ptr, base);
|
||||
|
||||
if (errno == ERANGE || *ptr != '\0' || ptr == str.data())
|
||||
return {0LL, false};
|
||||
else
|
||||
return {value, true};
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
trimRight(std::string &str)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue