wire_load fanout_length values in quotes ucsd20190808

This commit is contained in:
James Cherry 2019-08-08 14:12:07 -07:00
parent 73fef1117e
commit e16696c347
3 changed files with 81 additions and 87 deletions

View File

@ -1700,30 +1700,13 @@ void
LibertyReader::visitFanoutLength(LibertyAttr *attr) LibertyReader::visitFanoutLength(LibertyAttr *attr)
{ {
if (wireload_) { if (wireload_) {
if (attr->isComplex()) { float fanout, length;
LibertyAttrValueIterator value_iter(attr->values()); bool exists;
if (value_iter.hasNext()) { getAttrFloat2(attr, fanout, length, exists);
LibertyAttrValue *value = value_iter.next(); if (exists)
if (value->isFloat()) { wireload_->addFanoutLength(fanout, length);
float fanout = value->floatValue();
if (value_iter.hasNext()) {
value = value_iter.next();
if (value->isFloat())
wireload_->addFanoutLength(fanout, value->floatValue());
else
libWarn(attr, "fanout_length fanout not a float.\n");
}
else
libWarn(attr, "fanout_length is missing length.\n");
}
else
libWarn(attr, "fanout_length fanout not an integer.\n");
}
else
libWarn(attr, "fanout_length is missing fanout and length.\n");
}
else else
libWarn(attr, "fanout_length is missing fanout and length.\n"); libWarn(attr, "fanout_length is missing length and fanout.\n");
} }
} }
@ -4155,33 +4138,41 @@ LibertyReader::getAttrFloat(LibertyAttr *attr,
bool &valid) bool &valid)
{ {
valid = false; valid = false;
if (attr->isSimple()) { if (attr->isSimple())
LibertyAttrValue *first = attr->firstValue(); getAttrFloat(attr, attr->firstValue(), value, valid);
if (first->isFloat()) {
valid = true;
value = first->floatValue();
}
else if (first->isString()) {
const char *string = first->stringValue();
// See if attribute string is a variable.
variableValue(string, value, valid);
if (!valid) {
// For some reason area attributes for pads are quoted floats.
// Check that the string is a valid double.
char *end;
value = strtof(string, &end);
if (*end && !isspace(*end))
libWarn(attr, "%s value %s is not a float.\n",
attr->name(),
string);
valid = true;
}
}
}
else else
libWarn(attr, "%s is not a simple attribute.\n", attr->name()); libWarn(attr, "%s is not a simple attribute.\n", attr->name());
} }
void
LibertyReader::getAttrFloat(LibertyAttr *attr,
LibertyAttrValue *attr_value,
// Return values.
float &value,
bool &valid)
{
if (attr_value->isFloat()) {
valid = true;
value = attr_value->floatValue();
}
else if (attr_value->isString()) {
const char *string = attr_value->stringValue();
// See if attribute string is a variable.
variableValue(string, value, valid);
if (!valid) {
// For some reason area attributes for pads are quoted floats.
// Check that the string is a valid double.
char *end;
value = strtof(string, &end);
if (*end && !isspace(*end))
libWarn(attr, "%s value %s is not a float.\n",
attr->name(),
string);
valid = true;
}
}
}
// Get two floats in a complex attribute. // Get two floats in a complex attribute.
// attr(float1, float2); // attr(float1, float2);
void void
@ -4196,25 +4187,18 @@ LibertyReader::getAttrFloat2(LibertyAttr *attr,
LibertyAttrValueIterator value_iter(attr->values()); LibertyAttrValueIterator value_iter(attr->values());
if (value_iter.hasNext()) { if (value_iter.hasNext()) {
LibertyAttrValue *value = value_iter.next(); LibertyAttrValue *value = value_iter.next();
if (value->isFloat()) { getAttrFloat(attr, value, value1, exists);
value1 = value->floatValue(); if (exists) {
if (value_iter.hasNext()) { if (value_iter.hasNext()) {
value = value_iter.next(); value = value_iter.next();
if (value->isFloat()) { getAttrFloat(attr, value, value2, exists);
value2 = value->floatValue();
exists = true;
}
else
libWarn(attr, "%s value is not a float.\n", attr->name());
} }
else else
libWarn(attr, "%s range missing second value.\n", attr->name()); libWarn(attr, "%s missing values.\n", attr->name());
} }
else
libWarn(attr, "%s value is not a float.\n", attr->name());
} }
else else
libWarn(attr, "%s range missing values.\n", attr->name()); libWarn(attr, "%s missing values.\n", attr->name());
} }
else else
libWarn(attr, "%s is not a complex attribute.\n", attr->name()); libWarn(attr, "%s is not a complex attribute.\n", attr->name());

View File

@ -454,6 +454,11 @@ protected:
// Return values. // Return values.
float &value, float &value,
bool &valid); bool &valid);
void getAttrFloat(LibertyAttr *attr,
LibertyAttrValue *attr_value,
// Return values.
float &value,
bool &valid);
void getAttrFloat2(LibertyAttr *attr, void getAttrFloat2(LibertyAttr *attr,
// Return values. // Return values.
float &value1, float &value1,

View File

@ -106,38 +106,43 @@ Wireload::findWireload(float fanout,
float &cap, float &cap,
float &res) const float &res) const
{ {
int max = static_cast<int>(fanout_lengths_.size()) - 1; size_t size = fanout_lengths_.size();
float fanout0 = fanout_lengths_[0]->first;
float fanout_max = fanout_lengths_[max]->first;
float length; float length;
if (fanout == fanout0) if (size == 0)
length = fanout_lengths_[0]->second; length = 0;
else if (fanout <= fanout0) {
// Extrapolate from lowest fanout entry.
length = fanout_lengths_[0]->second - (fanout0 - fanout) * slope_;
if (length < 0)
length = 0;
}
else if (fanout >= fanout_max)
// Extrapolate from max fanout entry.
length = fanout_lengths_[max]->second + (fanout - fanout_max) * slope_;
else { else {
// Bisection search. size_t max = size - 1;
int lower = -1; float fanout0 = fanout_lengths_[0]->first;
int upper = max + 1; float fanout_max = fanout_lengths_[max]->first;
while (upper - lower > 1) { if (fanout < fanout0) {
int mid = (upper + lower) >> 1; // Extrapolate from lowest fanout entry.
if (fanout >= fanout_lengths_[mid]->first) length = fanout_lengths_[0]->second - (fanout0 - fanout) * slope_;
lower = mid; if (length < 0)
else length = 0;
upper = mid; }
else if (fanout == fanout0)
length = fanout_lengths_[0]->second;
else if (fanout >= fanout_max)
// Extrapolate from max fanout entry.
length = fanout_lengths_[max]->second + (fanout - fanout_max) * slope_;
else {
// Bisection search.
int lower = -1;
int upper = size;
while (upper - lower > 1) {
int mid = (upper + lower) >> 1;
if (fanout >= fanout_lengths_[mid]->first)
lower = mid;
else
upper = mid;
}
// Interpolate between lower and lower+1 entries.
float fanout1 = fanout_lengths_[lower]->first;
float fanout2 = fanout_lengths_[lower+1]->first;
float l1 = fanout_lengths_[lower]->second;
float l2 = fanout_lengths_[lower+1]->second;
length = l1 + (l2 - l1) * (fanout - fanout1) / (fanout2 - fanout1);
} }
// Interpolate between lower and lower+1 entries.
float fanout1 = fanout_lengths_[lower]->first;
float fanout2 = fanout_lengths_[lower+1]->first;
float l1 = fanout_lengths_[lower]->second;
float l2 = fanout_lengths_[lower+1]->second;
length = l1 + (l2 - l1) * (fanout - fanout1) / (fanout2 - fanout1);
} }
// Scale resistance and capacitance. // Scale resistance and capacitance.
cap = length * capacitance_ cap = length * capacitance_