OpenROAD icon indicating copy to clipboard operation
OpenROAD copied to clipboard

RSZ: Resizer::findMaxWireLength1 is unnecessarily / unreasonably pessimistic

Open bangqixu opened this issue 9 months ago • 3 comments

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

bangqixu avatar Apr 25 '25 07:04 bangqixu

cc @QuantamHD and @mikesinouye for visibility

bangqixu avatar Apr 25 '25 07:04 bangqixu

Hi @povik , have you gotten a chance to visit this issue yet? Any thoughts on this observation?

mikesinouye avatar May 06 '25 23:05 mikesinouye

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.

povik avatar May 19 '25 14:05 povik