Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions liberty/LibertyReader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3317,21 +3317,28 @@ LibertyReader::visitShifts(LibertyAttr *attr)
{
if (generated_clock_) {
if (!attr->isComplex()) {
libError(1234, attr, "'shifts' attribute is not a complex attribute.");
libError(1234, attr, "'shifts' attribute must be a complex attribute.");
}
// Initialize edges sequence
FloatSeq *shifts = new FloatSeq;
LibertyAttrValueIterator value_iter(attr->values());
while (value_iter.hasNext()) {
LibertyAttrValue *value = value_iter.next();
if (!value->isFloat()) {
// Convert string to float if necessary
if (value->isFloat()) {
float float_value = value->floatValue();
shifts->push_back(float_value);
}
else if (value->isString()) {
const char *string_value = value->stringValue();
float float_value = strtof(string_value, nullptr);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strtof with nullptr as the second parameter doesn't validate conversion errors. invalid strings like "abc" will silently convert to 0.0. see line 5282 in this file for proper error handling pattern with char *end

shifts->push_back(float_value);
}
else {
delete shifts;
libError(1234, attr, "shifts attribute must be a float.");
libError(1234, attr, "shifts attribute must be a float or string.");
}
float float_value = value->floatValue();
shifts->push_back(float_value);
}

// Error checking, only size 3 is supported at the moment
if (shifts->size() != 3) {
delete shifts;
Expand All @@ -3350,22 +3357,30 @@ LibertyReader::visitEdges(LibertyAttr *attr)
{
if (generated_clock_) {
if (!attr->isComplex()) {
libError(1234, attr, "'edges' attribute is not a complex attribute.");
libError(1234, attr, "'edges' attribute must be a complex attribute.");
}
// Initialize edges sequence
IntSeq *edges = new IntSeq;
LibertyAttrValueIterator value_iter(attr->values());
while (value_iter.hasNext()) {
LibertyAttrValue *value = value_iter.next();
if (!value->isFloat()) {
// Convert string to float if necessary
if (value->isFloat()) {
float float_value = value->floatValue();
int int_value = static_cast<int>(float_value);
edges->push_back(int_value);
}
else if (value->isString()) {
const char *string_value = value->stringValue();
float float_value = strtof(string_value, nullptr);
int int_value = static_cast<int>(float_value);
edges->push_back(int_value);
}
else {
delete edges;
libError(1234, attr, "edges attribute must be a float.");
libError(1234, attr, "edges attribute must be a float or string.");
}
float float_value = value->floatValue();
int int_value = static_cast<int>(float_value);
edges->push_back(int_value);
}

// Error checking, only size 3 is supported at the moment
if (edges->size() != 3) {
delete edges;
Expand Down
8 changes: 6 additions & 2 deletions test/generated_clock.lib
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,12 @@ library (generated_clock) {
generated_clock (shift) {
clock_pin : CLK_OUT ;
master_pin : CLK_IN;
edges (1, 3, 5);
shifts (0, 0, 0)
edges("1", \
3, \
"5");
shifts(0, \
"0", \
0);
}
timing () {
related_pin : CLK_IN;
Expand Down
2 changes: 1 addition & 1 deletion test/generated_clock.ok
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Warning: generated_clock.lib line 57, shifts are not supported yet, may cause malformed waveforms.
Warning: generated_clock.lib line 59, shifts are not supported yet, may cause malformed waveforms.
Number of clocks: 9
clk period: 10.000000
u_second_hierarchy/clk_gen/CLK_OUT_DIV period: 20.000000
Expand Down