RSZ: Resizer::findMaxWireLength1 is unnecessarily / unreasonably pessimistic
Describe the bug
In Resizer::findMaxWireLength1, it loops through each corner then each buffer to find the smallest among the max wire length in all {corner, buffer} pair.
This is basically saying that for the resulting max_wire_length, any buffer at any corner will be able do drive it, which is unnecessarily pessimistic. If BufferA can drive 100um at CornerA and 200um at CornerB, BufferB can drive 50um at CornerA and 150um at CornerB. Based on the description of max_wire_length_, it seems that in such a case, max_wire_length_ should be equal to 100um instead of 50um because it is unnecessary to break the long wire every 50um if we know there exists a buffer that allows us to break it every 100um.
Expected Behavior
Loop through all buffer cell. For each buffer cell, find the minimal max wire length across all corners. Return the value based on the best buffer cell. See example code below.
double Resizer::findMaxWireLength1() {
double result = 0.0;
std::unordered_map<const Corner*, double> corner_to_wire_signal_resistance;
for (const Corner* corner : *sta_->corners()) {
if (wireSignalResistance(corner) <= 0.0) {
logger_->warn(RSZ,
88,
"Corner: {} has no wire signal resistance value.",
corner->name());
continue;
}
corner_to_wire_signal_resistance[corner] = wireSignalResistance(corner);
}
if (corner_to_wire_signal_resistance.empty()) {
logger_->error(RSZ,
89,
"Could not find a resistance value for any corner. Cannot "
"evaluate max wire length for buffer. Check over your "
"`set_wire_rc` configuration");
return result;
}
for (LibertyCell* buffer_cell : buffer_cells_) {
// Find the max wire length for the buffer across all corners.
double max_buffer_length_all_corners = INF;
for (const Corner* corner : *sta_->corners()) {
if (auto it = corner_to_wire_signal_resistance.find(corner);
it == corner_to_wire_signal_resistance.end()) {
continue;
}
double corner_buffer_length = findMaxWireLength(buffer_cell, corner);
max_buffer_length_all_corners =
min(max_buffer_length_all_corners, corner_buffer_length);
}
// Update the all-corner best wire length.
result = max(result, max_buffer_length_all_corners);
}
return result;
}
Environment
N/A
To Reproduce
N/A
Relevant log output
Screenshots
No response
Additional Context
No response
cc @QuantamHD and @mikesinouye for visibility
Hi @povik , have you gotten a chance to visit this issue yet? Any thoughts on this observation?
Hi @mikesinouye, sorry for the delayed response. I agree the min over all buffer sizes is too conservative. We are in the process of revisiting buffering more generally which should improve over the conservative behavior.