From 8d647287e2268f0fa8d98cb217af91768bb10735 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 14 May 2021 18:02:34 -0400 Subject: [PATCH 1/3] Implemented a basic DRC check on non-Manhattan edges. Previously checks on non-Manhattan tiles were made only on the straight edges; this was sufficient for most checks. However, it can miss the case of facing non-Manhattan edges. This check does not do triggered rules because there is no non-Manhattan maxwidth algorithm implemented, and because the triggering clipping area is a triangle and needs an extension to support it. --- VERSION | 2 +- database/DBcellcopy.c | 1 + drc/DRCbasic.c | 171 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 152 insertions(+), 22 deletions(-) diff --git a/VERSION b/VERSION index 7d3253ea..8b702771 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.163 +8.3.164 diff --git a/database/DBcellcopy.c b/database/DBcellcopy.c index cda6e83d..4b6793d7 100644 --- a/database/DBcellcopy.c +++ b/database/DBcellcopy.c @@ -688,6 +688,7 @@ DBCellCopyPaint(scx, mask, xMask, targetUse) arg.caa_mask = mask; arg.caa_targetUse = targetUse; + arg.caa_func = NULL; GeoTransRect(&scx->scx_trans, &scx->scx_area, &arg.caa_rect); /* Build dummy TreeContext */ diff --git a/drc/DRCbasic.c b/drc/DRCbasic.c index de60f127..9b29ed9e 100644 --- a/drc/DRCbasic.c +++ b/drc/DRCbasic.c @@ -26,6 +26,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include #include #include // for memcpy() +#include // for sqrt() for diagonal check #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" @@ -268,6 +269,47 @@ areaCheck(tile, arg) return 0; } +/* + * ---------------------------------------------------------------------------- + * + * areaNMCheck --- + * + * Check for errors in triangular area of a tile + * + * ---------------------------------------------------------------------------- + */ + +int +areaNMCheck(tile, arg) + Tile *tile; + struct drcClientData *arg; +{ + Rect rect; /* Area where error is to be recorded. */ + + /* Ignore the tile that initiates the check, because the error area */ + /* of a non-Manhattan check may fall inside of it. */ + if (tile == arg->dCD_initial) return 0; + + TiToRect(tile, &rect); + + /* Only consider the portion of the suspicious tile that overlaps + * the clip area for errors, unless this is a trigger rule. + */ + + if (!(arg->dCD_cptr->drcc_flags & DRC_TRIGGER)) + GeoClip(&rect, arg->dCD_clip); + + GeoClip(&rect, arg->dCD_constraint); + if ((rect.r_xbot >= rect.r_xtop) || (rect.r_ybot >= rect.r_ytop)) + return 0; + + (*(arg->dCD_function))(arg->dCD_celldef, &rect, arg->dCD_cptr, + arg->dCD_clientData); + (*(arg->dCD_errors))++; + + return 0; +} + /* * ---------------------------------------------------------------------------- * @@ -412,8 +454,11 @@ drcTile (tile, arg) if (IsSplit(tile)) { + int deltax, deltay; + TileType tt, to; + /* Check rules for DRC_ANGLES rule and process */ - TileType tt = TiGetLeftType(tile); + tt = TiGetLeftType(tile); if (tt != TT_SPACE) { for (cptr = DRCCurStyle->DRCRulesTbl[TT_SPACE][tt]; @@ -436,8 +481,98 @@ drcTile (tile, arg) } } - /* This drc is only for the left edge of the tile */ - if (SplitSide(tile)) goto checkbottom; + /* Full check of edge rules along the diagonal. */ + if (SplitSide(tile)) + { + tt = TiGetRightType(tile); /* inside type */ + to = TiGetLeftType(tile); /* outside type */ + } + else + { + tt = TiGetLeftType(tile); /* inside type */ + to = TiGetRightType(tile); /* outside type */ + } + + for (cptr = DRCCurStyle->DRCRulesTbl[to][tt]; cptr != (DRCCookie *) NULL; + cptr = cptr->drcc_next) + { + int deltax, deltay, w, h; + double r; + TileType dinfo, dsplit; + + /* Work to be done: Handle triggering rules for non-Manhattan */ + /* edges; especially important for the wide-spacing rule. */ + + if (cptr->drcc_flags & DRC_TRIGGER) + { + cptr = cptr->drcc_next; // Skip both triggering and triggered rules + continue; + } + + /* Note: Triggered wide-spacing rule will require handling */ + /* the DRC_MAXWIDTH rule on non-Manhattan edges. */ + + if (cptr->drcc_flags & (DRC_ANGLES | DRC_AREA | DRC_MAXWIDTH + | DRC_RECTSIZE | DRC_OFFGRID)) + continue; + + TiToRect(tile, &errRect); + + /* Find the rule distances according to the scale factor */ + dist = cptr->drcc_dist; + + /* drcc_edgeplane is used to avoid checks on edges */ + /* in more than one plane */ + + if (arg->dCD_plane != cptr->drcc_edgeplane) continue; + + DRCstatRules++; + + DRCstatSlow++; + arg->dCD_cptr = cptr; + arg->dCD_entries = 0; + TTMaskCom2(&tmpMask, &cptr->drcc_mask); + TTMaskClearType(&tmpMask, TT_ERROR_S); + arg->dCD_initial = tile; + + /* Compute position that is the rule distance away from */ + /* the tile's diagonal edge, by Euclidean measure */ + /* (rounded down if fractional). Use the forward */ + /* position, and negate if reversed. */ + + w = RIGHT(tile) - LEFT(tile); + h = TOP(tile) - BOTTOM(tile); + r = 1.0 / (1.0 + ((double)(w * w) / (double)(h * h))); + deltax = (int)((double)cptr->drcc_dist * sqrt(r)); + deltay = (deltax * w) / h; + + if (SplitSide(tile) == 1) deltax = -deltax; + if (SplitDirection(tile) == SplitSide(tile)) deltay = -deltay; + + dinfo = TiGetTypeExact(tile) & (TT_DIAGONAL | TT_DIRECTION | TT_SIDE); + if (!(cptr->drcc_flags & DRC_REVERSE)) + { + /* Forward case is behind the triangle */ + deltax = -deltax; + deltay = -deltay; + /* Split side changes in the reverse case */ + if (SplitSide(tile)) + dinfo &= (~TT_SIDE); + else + dinfo |= TT_SIDE; + } + + /* errRect is the tile area offset by (deltax, deltay) */ + errRect.r_xbot += deltax; + errRect.r_ybot += deltay; + errRect.r_xtop += deltax; + errRect.r_ytop += deltay; + + DBSrPaintNMArea((Tile *) NULL, + arg->dCD_celldef->cd_planes[cptr->drcc_plane], dinfo, + &errRect, &tmpMask, areaNMCheck, (ClientData) arg); + } + DRCstatEdges++; } /* @@ -679,8 +814,8 @@ drcTile (tile, arg) else tpl = tpleft; /* Make sure the edge stops at edgeBot */ - if ((TiGetTopType(tpl) != TiGetBottomType(tpleft)) || - (TiGetTopType(tpr) != TiGetBottomType(tile))) + if ((TiGetRightType(tpl) != TiGetRightType(tpleft)) || + (TiGetLeftType(tpr) != TiGetLeftType(tile))) { if (TTMaskHasType(&cptr->drcc_corner, TiGetTopType(tpr))) { @@ -706,8 +841,8 @@ drcTile (tile, arg) else tpl = tpleft; /* Make sure the edge stops at edgeTop */ - if ((TiGetBottomType(tpl) != TiGetTopType(tpleft)) || - (TiGetBottomType(tpr) != TiGetTopType(tile))) + if ((TiGetRightType(tpl) != TiGetRightType(tpleft)) || + (TiGetLeftType(tpr) != TiGetLeftType(tile))) { if (TTMaskHasType(&cptr->drcc_corner, TiGetBottomType(tpr))) @@ -753,8 +888,8 @@ drcTile (tile, arg) else tpr = tile; /* Make sure the edge stops at edgeTop */ - if ((TiGetBottomType(tpl) != TiGetTopType(tpleft)) || - (TiGetBottomType(tpr) != TiGetTopType(tile))) + if ((TiGetRightType(tpl) != TiGetRightType(tpleft)) || + (TiGetLeftType(tpr) != TiGetLeftType(tile))) { if (TTMaskHasType(&cptr->drcc_corner, TiGetBottomType(tpl))) { @@ -780,8 +915,8 @@ drcTile (tile, arg) else tpr = tile; /* Make sure the edge stops at edgeBot */ - if ((TiGetTopType(tpl) != TiGetBottomType(tpleft)) || - (TiGetTopType(tpr) != TiGetBottomType(tile))) + if ((TiGetRightType(tpl) != TiGetRightType(tpleft)) || + (TiGetLeftType(tpr) != TiGetLeftType(tile))) { if (TTMaskHasType(&cptr->drcc_corner, TiGetTopType(tpl))) { @@ -842,12 +977,6 @@ drcTile (tile, arg) } } - /* This drc is only for the bottom edge of the tile */ - -checkbottom: - if (IsSplit(tile)) - if (SplitSide(tile) == SplitDirection(tile)) return 0; - /* * Check design rules along a horizontal boundary between two tiles. * @@ -1052,7 +1181,7 @@ checkbottom: for (tpx = TR(tile); BOTTOM(tpx) > edgeY; tpx = LB(tpx)); else tpx = tile; - if (TTMaskHasType(&cptr->drcc_corner, TiGetLeftType(tpx))) + if (TTMaskHasType(&cptr->drcc_corner, TiGetBottomType(tpx))) { errRect.r_xtop += cdist; if (DRCEuclidean) @@ -1069,7 +1198,7 @@ checkbottom: if (LEFT(tile) >= errRect.r_xbot) tpx = BL(tile); else tpx = tile; - if (TTMaskHasType(&cptr->drcc_corner, TiGetRightType(tpx))) + if (TTMaskHasType(&cptr->drcc_corner, TiGetBottomType(tpx))) { errRect.r_xbot -= cdist; if (DRCEuclidean) @@ -1106,7 +1235,7 @@ checkbottom: for (tpx = BL(tpbot); TOP(tpx) < edgeY; tpx = RT(tpx)); else tpx = tpbot; - if (TTMaskHasType(&cptr->drcc_corner, TiGetRightType(tpx))) + if (TTMaskHasType(&cptr->drcc_corner, TiGetTopType(tpx))) { errRect.r_xbot -= cdist; if (DRCEuclidean) @@ -1122,7 +1251,7 @@ checkbottom: if (RIGHT(tpbot) <= errRect.r_xtop) tpx = TR(tpbot); else tpx = tpbot; - if (TTMaskHasType(&cptr->drcc_corner, TiGetLeftType(tpx))) + if (TTMaskHasType(&cptr->drcc_corner, TiGetTopType(tpx))) { errRect.r_xtop += cdist; if (DRCEuclidean) From 1c328dfe15752a0f6f5c561984e9583d9a4f9e79 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 17 May 2021 15:18:05 -0400 Subject: [PATCH 2/3] Corrected an error in the "cifspacing" rule check for non-Manhattan geometry (which had gone unnoticed due to the lack of use of "cifspacing" in any rule decks). The rule was not checking for all synthetic edges, because the tile type was expected to match the rule type when the function is called, but with a non-Manhattan tile, that may or may not be true and needs to be checked. --- drc/DRCcif.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drc/DRCcif.c b/drc/DRCcif.c index a06d8d0d..af6264d0 100644 --- a/drc/DRCcif.c +++ b/drc/DRCcif.c @@ -613,6 +613,14 @@ drcCifTile (tile, arg) if (SigInterruptPending) return 1; DRCstatTiles++; + /* For non-Manhattan tiles, if the left side of tile is not the */ + /* type that is declared by the rule, then skip the left-right */ + /* check. */ + + if (IsSplit(tile)) + if (SplitSide(tile)) + goto tbcheck; + /* * Check design rules along a vertical boundary between two tiles. * @@ -801,6 +809,15 @@ drcCifTile (tile, arg) } } +tbcheck: + + /* For non-Manhattan tiles, if the bottom side of tile is not */ + /* the type that is declared by the rule, then skip the top- */ + /* bottom check. */ + + if (IsSplit(tile)) + if (SplitSide(tile) == SplitDirection(tile)) + return 0; /* * Check design rules along a horizontal boundary between two tiles. From ff913ddb23f160464e055c22e6ecd449e4303e74 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 17 May 2021 15:22:27 -0400 Subject: [PATCH 3/3] Updated VERSION. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 8b702771..9273499b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.164 +8.3.165