tap: error on invalid endcap_master type - #11268
Conversation
Signed-off-by: Peter Gadfort <gadfort@zeroasic.com>
There was a problem hiding this comment.
Code Review
This pull request prevents rows from being incorrectly cut away on short cores by ensuring sentinel obstruction bands are not paired with each other in cutRows, and by rejecting block masters (macros) in checkPlaceable. A new test case cut_rows_short_core has been added to verify these changes. The feedback suggests a performance optimization in src/odb/src/db/util.cpp to reserve capacity for the bands vector to avoid reallocation overhead.
| vector<Rect> bands = effective_blockages; | ||
| const size_t blockage_count = bands.size(); | ||
| bands.emplace_back(core.xMin(), core.yMax(), core.xMax(), core.yMax() + 1); | ||
| bands.emplace_back(core.xMin(), core.yMin() - 1, core.xMax(), core.yMin()); |
There was a problem hiding this comment.
When copying effective_blockages to bands, the vector is initialized with the exact size of effective_blockages. Calling emplace_back immediately after will trigger a reallocation and copy of all elements because the vector's capacity is fully utilized. To avoid this unnecessary reallocation and copy overhead, we can reserve the required capacity (effective_blockages.size() + 2) beforehand.
vector<Rect> bands;
bands.reserve(effective_blockages.size() + 2);
bands.assign(effective_blockages.begin(), effective_blockages.end());
const size_t blockage_count = bands.size();
bands.emplace_back(core.xMin(), core.yMax(), core.xMax(), core.yMax() + 1);
bands.emplace_back(core.xMin(), core.yMin() - 1, core.xMax(), core.yMin());
Summary
odb::cutRowscould mark the whole core as a narrow region.To find gaps too narrow to hold endcaps, cutRows scans every pair of blockages and flags the vertical space between them when it is shorter than
min_row_height + site_height - 1. The core's top and bottom edges are appended to that list as zero-thickness sentinel bands so that slivers between a macro and the core boundary are caught by the same scan.The scan paired every band with every other one — including the two sentinels with each other. That pair does not measure a gap between obstructions; it measures the core height itself. So whenever the core was shorter than min_region_height, the scan produced a single "narrow region" spanning the entire core, and every row was cut away.
A sentinel is now only ever paired with a real blockage.
This is not specific to a bad
-endcap_master.min_row_heightis2 * endcap_height + max_core_cell_height(or an explicit-row_min_height), so a legitimate endcap master plus a tall multi-height cell in the library is enough to exceed a small core's height and silently delete every row.-endcap_master.isCoreAutoPlaceable()returns true for BLOCK, socheckPlaceablelet macros through. Besides being unplaceable in a row, an endcap master's dimensions set the minimum row width and height used to cut rows — the issue's test case passes the macro's own 419x484um master, which alone guarantees over-cutting. Block masters are now rejected with TAP-0036. The message dropped its "would be ignored by detailed placement" tail, which is not accurate for a macro; the golden was updated.Type of Change
Impact
Should only impact users with incorrect input to the function
Verification
./etc/Build.sh).Related Issues
Closes #11223