Skip to content

Commit 71f4dd2

Browse files
Discovered that the non-Euclidean distance checks had not been
completely implemented for the "cifwidth" and "cifspacing" rules, resulting in those rules being Manhattan distance checks. Finished the implementation (duplicating code from DRCbasic.c, with appropriate scaling to CIF coordinates).
1 parent 8b35245 commit 71f4dd2

File tree

3 files changed

+102
-18
lines changed

3 files changed

+102
-18
lines changed

drc/DRCbasic.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ extern MaxRectsData *drcCanonicalMaxwidth();
6161
/*
6262
*-----------------------------------------------------------------------
6363
*
64-
* point_to_segment
64+
* drcCifPointToSegment
6565
*
6666
* Euclidean-distance point-to-segment distance (squared)
6767
* calculation (borrowed from XCircuit)
@@ -77,7 +77,7 @@ extern MaxRectsData *drcCanonicalMaxwidth();
7777
*/
7878

7979
long
80-
point_to_segment(px, py, s1x, s1y, s2x, s2y)
80+
drcCifPointToSegment(px, py, s1x, s1y, s2x, s2y)
8181
int px, py; /* The position of the point */
8282
int s1x, s1y; /* One endpoint of the line segment */
8383
int s2x, s2y; /* The other endpoint of the line segment */
@@ -187,7 +187,7 @@ areaCheck(tile, arg)
187187
return 0;
188188
else if (IsSplit(tile) && !SplitDirection(tile) && !SplitSide(tile))
189189
{
190-
sstest = point_to_segment(arg->dCD_constraint->r_xbot + sdist,
190+
sstest = drcCifPointToSegment(arg->dCD_constraint->r_xbot + sdist,
191191
arg->dCD_constraint->r_ytop - sdist,
192192
LEFT(tile), BOTTOM(tile), RIGHT(tile), TOP(tile));
193193
if (sstest > ssdist) return 0;
@@ -202,7 +202,7 @@ areaCheck(tile, arg)
202202
return 0;
203203
else if (IsSplit(tile) && SplitDirection(tile) && SplitSide(tile))
204204
{
205-
sstest = point_to_segment(arg->dCD_constraint->r_xtop - sdist,
205+
sstest = drcCifPointToSegment(arg->dCD_constraint->r_xtop - sdist,
206206
arg->dCD_constraint->r_ytop - sdist,
207207
LEFT(tile), TOP(tile), RIGHT(tile), BOTTOM(tile));
208208
if (sstest > ssdist) return 0;
@@ -218,7 +218,7 @@ areaCheck(tile, arg)
218218
return 0;
219219
else if (IsSplit(tile) && SplitDirection(tile) && !SplitSide(tile))
220220
{
221-
sstest = point_to_segment(arg->dCD_constraint->r_xbot + sdist,
221+
sstest = drcCifPointToSegment(arg->dCD_constraint->r_xbot + sdist,
222222
arg->dCD_constraint->r_ybot + sdist,
223223
LEFT(tile), TOP(tile), RIGHT(tile), BOTTOM(tile));
224224
if (sstest > ssdist) return 0;
@@ -234,7 +234,7 @@ areaCheck(tile, arg)
234234
return 0;
235235
else if (IsSplit(tile) && !SplitDirection(tile) && SplitSide(tile))
236236
{
237-
sstest = point_to_segment(arg->dCD_constraint->r_xtop - sdist,
237+
sstest = drcCifPointToSegment(arg->dCD_constraint->r_xtop - sdist,
238238
arg->dCD_constraint->r_ybot + sdist,
239239
LEFT(tile), BOTTOM(tile), RIGHT(tile), TOP(tile));
240240
if (sstest > ssdist) return 0;

drc/DRCcif.c

+95-12
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ char *drcNeedStyle = NULL;
7777
#define DRC_CIF_SPACE 0
7878
#define DRC_CIF_SOLID 1
7979

80+
/* Define Euclidean distance checks */
81+
82+
#define RADIAL_NW 0x1000
83+
#define RADIAL_NE 0x8000
84+
#define RADIAL_SW 0x2000
85+
#define RADIAL_SE 0x4000
86+
8087
/*
8188
* ----------------------------------------------------------------------------
8289
*
@@ -715,7 +722,7 @@ drcCifTile (tile, arg)
715722
{
716723
errRect.r_ybot -= cptr->drcc_cdist;
717724
if (DRCEuclidean)
718-
arg->dCD_radial |= 0x1000;
725+
arg->dCD_radial |= RADIAL_SW;
719726
}
720727

721728
if (cptr->drcc_flags & DRC_BOTHCORNERS)
@@ -731,7 +738,7 @@ drcCifTile (tile, arg)
731738
{
732739
errRect.r_ytop += cptr->drcc_cdist;
733740
if (DRCEuclidean)
734-
arg->dCD_radial |= 0x2000;
741+
arg->dCD_radial |= RADIAL_NW;
735742
}
736743
}
737744

@@ -761,7 +768,7 @@ drcCifTile (tile, arg)
761768
{
762769
errRect.r_ytop += cptr->drcc_cdist;
763770
if (DRCEuclidean)
764-
arg->dCD_radial |= 0x8000;
771+
arg->dCD_radial |= RADIAL_NE;
765772
}
766773

767774
if (cptr->drcc_flags & DRC_BOTHCORNERS)
@@ -777,7 +784,7 @@ drcCifTile (tile, arg)
777784
{
778785
errRect.r_ybot -= cptr->drcc_cdist;
779786
if (DRCEuclidean)
780-
arg->dCD_radial |= 0x4000;
787+
arg->dCD_radial |= RADIAL_SE;
781788
}
782789
}
783790

@@ -797,7 +804,7 @@ drcCifTile (tile, arg)
797804
}
798805
if (arg->dCD_radial)
799806
{
800-
arg->dCD_radial &= 0xf0000;
807+
arg->dCD_radial &= 0xf000;
801808
arg->dCD_radial |= (0xfff & cptr->drcc_cdist);
802809
}
803810

@@ -902,7 +909,7 @@ drcCifTile (tile, arg)
902909
{
903910
errRect.r_xtop += cptr->drcc_cdist;
904911
if (DRCEuclidean)
905-
arg->dCD_radial |= 0x4000;
912+
arg->dCD_radial |= RADIAL_SE;
906913
}
907914

908915
if (cptr->drcc_flags & DRC_BOTHCORNERS)
@@ -917,7 +924,7 @@ drcCifTile (tile, arg)
917924
{
918925
errRect.r_xbot -= cptr->drcc_cdist;
919926
if (DRCEuclidean)
920-
arg->dCD_radial |= 0x1000;
927+
arg->dCD_radial |= RADIAL_SW;
921928
}
922929
}
923930

@@ -949,7 +956,7 @@ drcCifTile (tile, arg)
949956
{
950957
errRect.r_xbot -= cptr->drcc_cdist;
951958
if (DRCEuclidean)
952-
arg->dCD_radial |= 0x2000;
959+
arg->dCD_radial |= RADIAL_NW;
953960
}
954961

955962
if (cptr->drcc_flags & DRC_BOTHCORNERS)
@@ -964,7 +971,7 @@ drcCifTile (tile, arg)
964971
{
965972
errRect.r_xtop += cptr->drcc_cdist;
966973
if (DRCEuclidean)
967-
arg->dCD_radial |= 0x8000;
974+
arg->dCD_radial |= RADIAL_NE;
968975
}
969976
}
970977

@@ -1029,6 +1036,7 @@ areaCifCheck(tile, arg)
10291036
struct drcClientData *arg;
10301037
{
10311038
Rect rect; /* Area where error is to be recorded. */
1039+
Rect cifrect; /* rect, in CIF coordinates */
10321040
int scale = drcCifStyle->cs_scaleFactor;
10331041

10341042
/* If the tile has a legal type, then return. */
@@ -1039,10 +1047,11 @@ areaCifCheck(tile, arg)
10391047
* the clip area for errors.
10401048
*/
10411049

1042-
TiToRect(tile, &rect);
1043-
GeoClip(&rect, arg->dCD_constraint);
1044-
if ((rect.r_xbot >= rect.r_xtop) || (rect.r_ybot >= rect.r_ytop))
1050+
TiToRect(tile, &cifrect);
1051+
GeoClip(&cifrect, arg->dCD_constraint);
1052+
if ((cifrect.r_xbot >= cifrect.r_xtop) || (cifrect.r_ybot >= cifrect.r_ytop))
10451053
return 0;
1054+
rect = cifrect;
10461055
rect.r_xbot /= scale;
10471056
rect.r_xtop /= scale;
10481057
if (rect.r_xbot == rect.r_xtop)
@@ -1059,6 +1068,80 @@ areaCifCheck(tile, arg)
10591068
if ((rect.r_xbot >= rect.r_xtop) || (rect.r_ybot >= rect.r_ytop))
10601069
return 0;
10611070

1071+
/*
1072+
* Euclidean distance checks
1073+
*/
1074+
if (arg->dCD_radial != 0)
1075+
{
1076+
unsigned int i;
1077+
int sqx, sqy;
1078+
int sdist = arg->dCD_radial & 0xfff;
1079+
long sstest, ssdist = sdist * sdist;
1080+
1081+
if ((arg->dCD_radial & RADIAL_NW) != 0)
1082+
{
1083+
if (((sqx = arg->dCD_constraint->r_xbot + sdist
1084+
- cifrect.r_xtop) >= 0) && ((sqy = cifrect.r_ybot
1085+
- arg->dCD_constraint->r_ytop + sdist) >= 0)
1086+
&& ((sqx * sqx + sqy * sqy) >= ssdist))
1087+
return 0;
1088+
else if (IsSplit(tile) && !SplitDirection(tile) && !SplitSide(tile))
1089+
{
1090+
sstest = drcCifPointToSegment(arg->dCD_constraint->r_xbot + sdist,
1091+
arg->dCD_constraint->r_ytop - sdist,
1092+
LEFT(tile), BOTTOM(tile), RIGHT(tile), TOP(tile));
1093+
if (sstest > ssdist) return 0;
1094+
}
1095+
}
1096+
if ((arg->dCD_radial & RADIAL_NE) != 0)
1097+
{
1098+
if (((sqx = cifrect.r_xbot - arg->dCD_constraint->r_xtop
1099+
+ sdist) >= 0) && ((sqy = cifrect.r_ybot
1100+
- arg->dCD_constraint->r_ytop + sdist) >= 0)
1101+
&& ((sqx * sqx + sqy * sqy) >= ssdist))
1102+
return 0;
1103+
else if (IsSplit(tile) && SplitDirection(tile) && SplitSide(tile))
1104+
{
1105+
sstest = drcCifPointToSegment(arg->dCD_constraint->r_xtop - sdist,
1106+
arg->dCD_constraint->r_ytop - sdist,
1107+
LEFT(tile), TOP(tile), RIGHT(tile), BOTTOM(tile));
1108+
if (sstest > ssdist) return 0;
1109+
}
1110+
}
1111+
if ((arg->dCD_radial & RADIAL_SW) != 0)
1112+
{
1113+
if (((sqx = arg->dCD_constraint->r_xbot + sdist
1114+
- cifrect.r_xtop) >= 0) &&
1115+
((sqy = arg->dCD_constraint->r_ybot
1116+
+ sdist - cifrect.r_ytop) >= 0)
1117+
&& ((sqx * sqx + sqy * sqy) >= ssdist))
1118+
return 0;
1119+
else if (IsSplit(tile) && SplitDirection(tile) && !SplitSide(tile))
1120+
{
1121+
sstest = drcCifPointToSegment(arg->dCD_constraint->r_xbot + sdist,
1122+
arg->dCD_constraint->r_ybot + sdist,
1123+
LEFT(tile), TOP(tile), RIGHT(tile), BOTTOM(tile));
1124+
if (sstest > ssdist) return 0;
1125+
}
1126+
}
1127+
if ((arg->dCD_radial & RADIAL_SE) != 0)
1128+
{
1129+
if (((sqx = cifrect.r_xbot - arg->dCD_constraint->r_xtop
1130+
+ sdist) >= 0) &&
1131+
((sqy = arg->dCD_constraint->r_ybot
1132+
+ sdist - cifrect.r_ytop) >= 0)
1133+
&& ((sqx * sqx + sqy * sqy) >= ssdist))
1134+
return 0;
1135+
else if (IsSplit(tile) && !SplitDirection(tile) && SplitSide(tile))
1136+
{
1137+
sstest = drcCifPointToSegment(arg->dCD_constraint->r_xtop - sdist,
1138+
arg->dCD_constraint->r_ybot + sdist,
1139+
LEFT(tile), BOTTOM(tile), RIGHT(tile), TOP(tile));
1140+
if (sstest > ssdist) return 0;
1141+
}
1142+
}
1143+
}
1144+
10621145
(*(arg->dCD_function)) (arg->dCD_celldef, &rect,
10631146
arg->dCD_cptr, arg->dCD_clientData);
10641147
(*(arg->dCD_errors))++;

drc/drc.h

+1
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ extern void drcCheckRectSize();
309309
extern void drcCheckOffGrid();
310310
extern int LowestMaskBit();
311311
extern void drcCifScale();
312+
extern long drcCifPointToSegment();
312313

313314
/* The following macro can be used by the outside world to see if
314315
* the background checker needs to be called.

0 commit comments

Comments
 (0)