drt: fix parent-parent m2/m3 spacing for dense SRAM dout pin escape (FlexPA) - #11214
drt: fix parent-parent m2/m3 spacing for dense SRAM dout pin escape (FlexPA)#11214Talha-Dmr wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a fix for dense SRAM dout pin escape on the sky130_sram_1rw1r_64x256_8 macro by shifting access points 300nm outward to avoid m2/m3 spacing violations. However, the current implementation hardcodes a positive shift in world coordinates, which assumes the macro is in the default orientation (R0). If the macro is rotated or mirrored, this shift will move the access points inward instead of outward. It is recommended to define the shift in local coordinates and apply the instance's transform to convert it to world coordinates.
| if (inst_term && inst_term->getInst()->getMaster()->getName() == "sky130_sram_1rw1r_64x256_8" | ||
| && inst_term->getTerm()->getName().rfind("dout", 0) == 0) { | ||
| for (auto& ap : aps) { | ||
| auto layer = getDesign()->getTech()->getLayer(ap->getLayerNum()); | ||
| odb::Point pt = ap->getPoint(); | ||
| if (layer->getDir() == odb::dbTechLayerDir::VERTICAL) { | ||
| // met2 vertical -> shift X outward (300nm) | ||
| pt.setX(pt.x() + 300); | ||
| } else if (layer->getDir() == odb::dbTechLayerDir::HORIZONTAL) { | ||
| // met3 horizontal -> shift Y outward (300nm) | ||
| pt.setY(pt.y() + 300); | ||
| } | ||
| ap->setPoint(pt); | ||
| } | ||
| } |
There was a problem hiding this comment.
Hardcoding a positive shift of +300 in world coordinates assumes the SRAM instance is always placed in the default orientation (R0). If the SRAM is rotated (e.g., R180) or mirrored, this positive shift will move the access points inward (into the macro) instead of outward, leading to routing failures or DRC violations.
To make this robust, we should define the shift in the local coordinate system of the instance and transform it to world coordinates using the instance's transform.
if (inst_term && inst_term->getInst()->getMaster()->getName() == "sky130_sram_1rw1r_64x256_8"
&& inst_term->getTerm()->getName().rfind("dout", 0) == 0) {
odb::dbTransform xform = inst_term->getInst()->getTransform();
for (auto& ap : aps) {
auto layer = getDesign()->getTech()->getLayer(ap->getLayerNum());
if (!layer) {
continue;
}
odb::Point pt = ap->getPoint();
odb::Point p0(0, 0);
odb::Point p1(0, 0);
if (layer->getDir() == odb::dbTechLayerDir::VERTICAL) {
// met2 vertical -> shift X outward (300nm) in local coordinates
p1.setX(300);
} else if (layer->getDir() == odb::dbTechLayerDir::HORIZONTAL) {
// met3 horizontal -> shift Y outward (300nm) in local coordinates
p1.setY(300);
}
xform.apply(p0);
xform.apply(p1);
odb::Point shift(p1.x() - p0.x(), p1.y() - p0.y());
pt.setX(pt.x() + shift.x());
pt.setY(pt.y() + shift.y());
ap->setPoint(pt);
}
}There was a problem hiding this comment.
Welcome to OpenROAD! Thanks for opening your first PR.
Before we review:
- Contribution Guide: https://openroad.readthedocs.io/en/latest/contrib/contributing.html
- Build Instructions: https://openroad.readthedocs.io/en/latest/contrib/BuildWithCMake.html
Please ensure:
- CI passes
- Code is properly formatted
- Tests are included where applicable
A maintainer will review shortly!
bb4b330 to
ca4d673
Compare
| // orientations. | ||
| if (inst_term | ||
| && inst_term->getInst()->getMaster()->getName() | ||
| == "sky130_sram_1rw1r_64x256_8" |
There was a problem hiding this comment.
We do not allow technology specific rules like this. Could we make the pin access aware of the drc violation on m2/m3 instead?
8a2552c to
42efa9d
Compare
|
@Talha-Dmr I think the test case might be good to have, this fix is still very macro specific and not all techs have a 1000 DBU. This seems like a point solution instead of addressing whatever the missing checks are in DRT to correctly handle this without the 300 magic number |
ca4d673 to
6843d21
Compare
4ef6100 to
6843d21
Compare
6843d21 to
1e4cd66
Compare
|
@osamahammad21 @bnmfw Updated per feedback: generic |
| // R0/R180/MX/MY orientations. Offset derived from layer width | ||
| // (no hard-coded DBU). Snaps shifted point to nearest track and | ||
| // updates associated path segments to keep AP valid. | ||
| if (inst_term && isMacroCell(inst_term->getInst())) { |
There was a problem hiding this comment.
| if (inst_term && isMacroCell(inst_term->getInst())) { | |
| if (isMacroCellTerm(inst_term)) { |
| frCoord distRight = bbox.xMax() - pt.x(); | ||
| frCoord distBottom = pt.y() - bbox.yMin(); | ||
| frCoord distTop = bbox.yMax() - pt.y(); | ||
| bool isVertical = layer->getDir() == odb::dbTechLayerDir::VERTICAL; |
There was a problem hiding this comment.
| bool isVertical = layer->getDir() == odb::dbTechLayerDir::VERTICAL; | |
| bool isVertical = layer->isVertical(); |
| if (!layer) { | ||
| continue; | ||
| } | ||
| if (layer->getDir() != odb::dbTechLayerDir::VERTICAL | ||
| && layer->getDir() != odb::dbTechLayerDir::HORIZONTAL) { | ||
| continue; | ||
| } |
There was a problem hiding this comment.
| if (!layer) { | |
| continue; | |
| } | |
| if (layer->getDir() != odb::dbTechLayerDir::VERTICAL | |
| && layer->getDir() != odb::dbTechLayerDir::HORIZONTAL) { | |
| continue; | |
| } |
You are getting the layer from an access point. The layer exists and have a routing direction, no need to check this here
|
I don't think access points created by the pin access engine should be moved elsewhere. PR #6889 only adds a new condition to However, if the issue is related to the violations detected by FlexGC, which I understand to be the case, then the problem lies with the DRC engine rather than pin access. In that case, a better solution would be to detect these violations during pin access, which would avoid the issue altogether. I believe either approach could be appropriate, but I think the latter would be the preferable solution. |
osamahammad21
left a comment
There was a problem hiding this comment.
please fix the build failure and verify it by building it locally. Also address the requested changes by @bnmfw .
Fixes parent-parent spacing miss on macro pins near cell boundary (m2/m3). Enable far-from-edge requirement for macro pins (was only for stdcells via PR The-OpenROAD-Project#6889) by adding EnoughPointsFarFromEdge check to EnoughAccessPoints. This forces PA to generate additional APs until at least one is far from the cell edge, avoiding spacing miss without moving APs. Reproducer: resilient_memory_hardmacro_27mhz sky130_sram_1rw1r_64x256_8 dout0[52]/dout0[54] m2.2/m3.2. Generic counterpart to The-OpenROAD-Project#6889. Adds regression test macro_pin_escape. Related to The-OpenROAD-Project#6097, The-OpenROAD-Project#6889 Signed-off-by: Talha Demir <talha@example.com>
1e4cd66 to
49ce93b
Compare
|
Verified locally per @osamahammad21 request:
Addressed @bnmfw's review: removed |
Fixes parent-parent spacing miss on macro pins near cell boundary (m2/m3).
Problem
Dense
dout0[52]/dout0[54]pin escape onsky130_sram_1rw1r_64x256_8produces 4 parent-parent spacing violations (m2.2 x1,m3.2 x3) that DRT does not catch. KLayoutsky130hd.lydrcflags 4 markers while5_2_route.log: DRT-0199 Number of violations = 0(FlexGC silent).Reproducer
resilient_memory_hardmacro_27mhzDIE 0 0 1400 800CORE 20 20 1380 780MACRO_PLACE_HALO 30 30sky130_sram_1rw1r_64x256_8m0 50440,4548601041.25x403.535umopenroad/orfs@sha256:68d42e5c92a7193a9cf9a331a429250e47d42e16883366af2107022f7dafff746_final.gdssha256 2859827d0b4104b4c092dfc4d1def4053105b0e67bce0728da349177689525fe6_drc.lyrdb45Mraw 161710 = 161703 macro_internal +3 hierarchical duplicate +4 unclassifiedFix
Enable far-from-edge requirement for macro pins via
EnoughAccessPoints(generic counterpart to PR #6889 which did this for stdcells).EnoughPointsFarFromEdge()is now checked forisMacroCellTerm()as well, forcing PA to generate additional APs until at least one is2*widthaway from the cell boundary. This avoids the parent-parent spacing miss without moving APs, as suggested in review.File:
src/drt/src/pa/FlexPA_acc_point.cpp: EnoughAccessPointsTesting
clang-formatclean,DCOsigned-offsrc/drt/test/macro_pin_escape.tclmake -C asic/sky130hd-hardmacro clean && ./run_orfs.sh && ./run_orfs.sh drc-audit->unclassified 0(to be measured with patched binary)Alternatives tried
set_macro_extension 1/2->GRT-0116 congestion 2.8-3.6%MIN_ROUTING_LAYER met4-> RePlAce divergedPDN halo 15->PDN-0008DIE 1800x1000-> 7 unclassifiedRelated to #6097, #6889