From 8b2c33d8dd2170968b9b43ffa1cad169d1881ef3 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 20 Apr 2022 16:16:20 -0400 Subject: [PATCH] Added new tech DRC rule option "angles 45-only", which handles rules such as "No 90 degree bends on transistors". --- drc/DRCbasic.c | 17 ++++--- drc/DRCextend.c | 22 ++++----- drc/DRCprint.c | 6 ++- drc/DRCtech.c | 119 ++++++++++++++++++++++++++++++++++++++++++++---- drc/drc.h | 5 +- 5 files changed, 138 insertions(+), 31 deletions(-) diff --git a/drc/DRCbasic.c b/drc/DRCbasic.c index 4ea07e8b..5b57439a 100644 --- a/drc/DRCbasic.c +++ b/drc/DRCbasic.c @@ -260,7 +260,10 @@ areaCheck(tile, arg) } arg->dCD_rlist[arg->dCD_entries - 1] = rect; } - else + /* "angles 45-only" needs to reject errors that are inside split tiles */ + else if (!IsSplit(tile) || + ((arg->dCD_cptr->drcc_flags & (DRC_ANGLES_45 | DRC_ANGLES_90)) + != DRC_ANGLES_45)) { (*(arg->dCD_function))(arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); @@ -461,13 +464,13 @@ drcTile (tile, arg) int deltax, deltay; TileType tt, to; - /* Check rules for DRC_ANGLES rule and process */ + /* Check rules for DRC_ANGLES_90 rule and process */ tt = TiGetLeftType(tile); if (tt != TT_SPACE) { for (cptr = DRCCurStyle->DRCRulesTbl[TT_SPACE][tt]; cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next) - if (cptr->drcc_flags & DRC_ANGLES) + if (cptr->drcc_flags & DRC_ANGLES_90) { drcCheckAngles(tile, arg, cptr); break; @@ -478,7 +481,7 @@ drcTile (tile, arg) { for (cptr = DRCCurStyle->DRCRulesTbl[TT_SPACE][tt]; cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next) - if (cptr->drcc_flags & DRC_ANGLES) + if (cptr->drcc_flags & DRC_ANGLES_90) { drcCheckAngles(tile, arg, cptr); break; @@ -508,7 +511,7 @@ drcTile (tile, arg) /* 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 + if (cptr->drcc_flags & (DRC_ANGLES_90 | DRC_AREA | DRC_MAXWIDTH | DRC_RECTSIZE | DRC_OFFGRID)) continue; @@ -643,7 +646,7 @@ drcTile (tile, arg) for (cptr = DRCCurStyle->DRCRulesTbl[to][tt]; cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next) { - if (cptr->drcc_flags & DRC_ANGLES) continue; + if (cptr->drcc_flags & DRC_ANGLES_90) continue; /* Find the rule distances according to the scale factor */ dist = cptr->drcc_dist; @@ -1041,7 +1044,7 @@ drcTile (tile, arg) for (cptr = DRCCurStyle->DRCRulesTbl[to][tt]; cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next) { - if (cptr->drcc_flags & DRC_ANGLES) continue; + if (cptr->drcc_flags & DRC_ANGLES_90) continue; /* Find the rule distances according to the scale factor */ dist = cptr->drcc_dist; diff --git a/drc/DRCextend.c b/drc/DRCextend.c index 1a4ad0a1..5d350813 100644 --- a/drc/DRCextend.c +++ b/drc/DRCextend.c @@ -40,6 +40,9 @@ Stack *DRCstack = (Stack *)NULL; * * Side Effects: may cause errors to be painted. * + * NOTES: Tile has been determined to be a split tile before this + * routine is called. + * *------------------------------------------------------------------------- */ @@ -51,21 +54,18 @@ drcCheckAngles(tile, arg, cptr) DRCCookie *cptr; { Rect rect; - int ortho = (cptr->drcc_flags & 0x01); /* 1 = orthogonal, 0 = 45s */ + bool ortho = (cptr->drcc_flags & DRC_ANGLES_45) ? FALSE : TRUE; - if (IsSplit(tile)) + if (ortho || ((RIGHT(tile) - LEFT(tile)) != (TOP(tile) - BOTTOM(tile)))) { - if (ortho || (RIGHT(tile) - LEFT(tile)) != (TOP(tile) - BOTTOM(tile))) + TiToRect(tile, &rect); + GeoClip(&rect, arg->dCD_clip); + if (!GEO_RECTNULL(&rect)) { - TiToRect(tile, &rect); - GeoClip(&rect, arg->dCD_clip); - if (!GEO_RECTNULL(&rect)) - { - arg->dCD_cptr = cptr; - (*(arg->dCD_function)) (arg->dCD_celldef, &rect, + arg->dCD_cptr = cptr; + (*(arg->dCD_function)) (arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); - (*(arg->dCD_errors))++; - } + (*(arg->dCD_errors))++; } } } diff --git a/drc/DRCprint.c b/drc/DRCprint.c index 65b6915f..8b15d133 100644 --- a/drc/DRCprint.c +++ b/drc/DRCprint.c @@ -129,8 +129,10 @@ DRCPrintRulesTable (fp) fprintf(fp," bends"); if (dp->drcc_flags & DRC_RECTSIZE) fprintf(fp," rect-size"); - if (dp->drcc_flags & DRC_ANGLES) - fprintf(fp," angles"); + if (dp->drcc_flags & DRC_ANGLES_45) + fprintf(fp," angles_45"); + if (dp->drcc_flags & DRC_ANGLES_90) + fprintf(fp," angles_90"); fprintf(fp,"\n"); } } diff --git a/drc/DRCtech.c b/drc/DRCtech.c index d2c73f54..2fdb4b08 100644 --- a/drc/DRCtech.c +++ b/drc/DRCtech.c @@ -1667,22 +1667,123 @@ drcAngles(argc, argv) char *argv[]; { char *layers = argv[1]; - int angles = atoi(argv[2]); + char *endptr; + long value; + int angles; int why = drcWhyCreate(argv[3]); TileTypeBitMask set; DRCCookie *dp, *dpnew; int plane; + PlaneMask ptest, pset, pmask; TileType i, j; - DBTechNoisyNameMask(layers, &set); + value = strtol(argv[2], &endptr, 10); - angles /= 45; - angles--; /* angles now 0 for 45s and 1 for 90s */ - - if ((angles != 0) && (angles != 1)) + switch (value) { - TechError("angles must be 45 or 90\n"); - return 0; + case 45: + angles = DRC_ANGLES_45 | DRC_ANGLES_90; + break; + case 90: + angles = DRC_ANGLES_90; + break; + default: + TechError("angles must be 45 or 90\n"); + return 0; + } + + if (endptr != NULL) + if (!strcmp(endptr + 1, "only")) + if (angles & DRC_ANGLES_45) + angles = DRC_ANGLES_45; /* 45 degrees only */ + + ptest = DBTechNoisyNameMask(layers, &set); + + /* The 45 degrees only case is implemented like drcRectOnly, except */ + /* that drcRectOnly checks only for inside corners, while this */ + /* also checks for outside corners. Where inside and outside */ + /* corners have been beveled, the error is discarded while */ + /* processing. */ + + if (angles == DRC_ANGLES_45) + { + TileTypeBitMask set2, setC, setM; + + pmask = CoincidentPlanes(&set, ptest); + + if (pmask == 0) + { + TechError("All types for \"rect_only\" must be on the same plane.\n"); + return 0; + } + + /* set2 is the inverse of set */ + TTMaskCom2(&set2, &set); + + for (i = 0; i < DBNumTypes; i++) + { + for (j = 0; j < DBNumTypes; j++) + { + if (i == j) continue; + + if (pset = (DBTypesOnSamePlane(i, j) & pmask)) + { + /* Inside corners */ + if (TTMaskHasType(&set, i) && TTMaskHasType(&set2, j)) + { + plane = LowestMaskBit(pset); + /* setC = all types in plane */ + TTMaskZero(&setC); + TTMaskSetMask(&setC, &DBPlaneTypes[plane]); + + /* Find bucket preceding the new one we wish to insert */ + dp = drcFindBucket(i, j, 1); + dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); + drcAssign(dpnew, 1, dp->drcc_next, &set2, &setC, why, 1, + angles | DRC_FORWARD | DRC_BOTHCORNERS, + plane, plane); + dp->drcc_next = dpnew; + + /* find bucket preceding new one we wish to insert */ + dp = drcFindBucket(j, i, 1); + dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); + drcAssign(dpnew, 1, dp->drcc_next, &set2, &setC, why, 1, + angles | DRC_REVERSE | DRC_BOTHCORNERS, + plane, plane); + dp->drcc_next = dpnew; + } + + /* Outside corners */ + if (TTMaskHasType(&set2, i) && TTMaskHasType(&set, j)) + { + plane = LowestMaskBit(pset); + /* setC = all types in plane */ + TTMaskZero(&setC); + TTMaskSetMask(&setC, &DBPlaneTypes[plane]); + + /* setM = not(i) */ + TTMaskSetOnlyType(&setM, i); + TTMaskCom(&setM); + + /* Find bucket preceding the new one we wish to insert */ + dp = drcFindBucket(i, j, 1); + dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); + drcAssign(dpnew, 1, dp->drcc_next, &setM, &setC, why, 1, + angles | DRC_FORWARD | DRC_BOTHCORNERS, + plane, plane); + dp->drcc_next = dpnew; + + /* find bucket preceding new one we wish to insert */ + dp = drcFindBucket(j, i, 1); + dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); + drcAssign(dpnew, 1, dp->drcc_next, &setM, &setC, why, 1, + angles | DRC_REVERSE | DRC_BOTHCORNERS, + plane, plane); + dp->drcc_next = dpnew; + } + } + } + } } for (i = 0; i < DBNumTypes; i++) @@ -1699,7 +1800,7 @@ drcAngles(argc, argv) dp = drcFindBucket(TT_SPACE, i, 1); dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, 1, dp->drcc_next, &set, &set, why, - 1, DRC_ANGLES | angles, plane, plane); + 1, angles, plane, plane); dp->drcc_next = dpnew; } } diff --git a/drc/drc.h b/drc/drc.h index 86c65da7..f3e8fe90 100644 --- a/drc/drc.h +++ b/drc/drc.h @@ -75,9 +75,10 @@ typedef struct drccookie #define DRC_MAXWIDTH 0x080 #define DRC_MAXWIDTH_BOTH 0x100 #define DRC_RECTSIZE 0x200 -#define DRC_ANGLES 0x400 +#define DRC_ANGLES_45 0x400 +#define DRC_ANGLES_90 0x800 #define DRC_NONSTANDARD (DRC_AREA|DRC_MAXWIDTH|DRC_RECTSIZE\ - |DRC_ANGLES|DRC_OFFGRID) + |DRC_ANGLES_90|DRC_OFFGRID) /* More flags for indicating what the rule type represents */ #define DRC_CIFRULE 0x400