Magic Mailing List |
|
From: Andrew Lines (lines AT avlsi DOT com) Date: Sat May 20 2000 - 13:28:36 EDT
I fixed a subtle bug in the cifSquareFunc (which generates the cut pattern for magic contacts). The code assumes that the magic contact, cut size, and cut spacing are all even centimicrons. Unfortunately for lambda = 0.09um, this doesn't always hold. The routine can't center the cut pattern exactly in the magic contact. Therfore, overlapping contacts between different subcells may generate inconsistent cuts. This is impossible to completely avoid with an odd lamba (except by adding a highly inconvenient no_overlap design rule for contacts!) However, the problem can be mostly solved by changing cifSquareFunc to find the center of the square by trunctating toward negative infinity, instead of toward zero. At least this lets you overlap contacts between cells which haven't been flipped upsidedown or sideways with respect to each other. This works great for arrays elements which share contacts (which is the most common place you would do that). We run our layout through Mentor Graphic's Calibre program before submitting it, so is acceptable for us to catch uncommon errors that slip past Magic. If you want to solely use Magic for DRC checking, you'd better avoid odd lambdas or overlapping contacts! Here is the new code in cif/CIFgen.c. (Rajit, could you explain how to work your Magic cvs repository?) By the way, I did NOT fix cifSquareGridFunc because I don't use that, but perhaps somebody should to keep it consistent. int cifSquareFunc(tile, op) Tile *tile; /* Tile to be diced up. */ CIFOp *op; /* Describes how to generate squares. */ { Rect area, square; int i, nAcross, j, nUp, left, xcenter, ycenter; TiToRect(tile, &area); /* Compute the real border to leave around the sides. If only * one square will fit in a particular direction, center it * regardless of the requested border size. If more than one * square will fit, then fit it in extras only if at least the * requested border size can be left. Also center things in the * rectangle, so that the box's exact size doesn't matter. This * trickiness is done so that (a) coincident contacts from overlapping * cells always have their squares line up, regardless of the * orientation of the cells, and (b) we can generate contact vias * for non-square contact areas, for example poly-metal contacts * in the MOSIS CMOS process. */ /* AML: round center of area toward -infinity to be consistent for odd centerings */ xcenter = area.r_xbot + (area.r_xtop - area.r_xbot)/2; ycenter = area.r_ybot + (area.r_ytop - area.r_ybot)/2; nAcross = (area.r_xtop - area.r_xbot + op->co_bloats[2] - (2*op->co_bloats[0])) / (op->co_bloats[1] + op->co_bloats[2]); if (nAcross == 0) { left = xcenter - op->co_bloats[1]/2; if (left >= area.r_xbot) nAcross = 1; } else { left = xcenter + (op->co_bloats[2] - (nAcross * (op->co_bloats[1] + op->co_bloats[2])))/2; } nUp= (area.r_ytop - area.r_ybot + op->co_bloats[2] - (2*op->co_bloats[0])) / (op->co_bloats[1] + op->co_bloats[2]); if (nUp == 0) { square.r_ybot = ycenter - op->co_bloats[1]/2; if (square.r_ybot >= area.r_ybot) nUp = 1; } else { square.r_ybot = ycenter + (op->co_bloats[2] - (nUp * (op->co_bloats[1] + op->co_bloats[2])))/2; } for (i = 0; i < nUp; i += 1) { square.r_ytop = square.r_ybot + op->co_bloats[1]; square.r_xbot = left; for (j = 0; j < nAcross; j += 1) { square.r_xtop = square.r_xbot + op->co_bloats[1]; DBPaintPlane(cifPlane, &square, CIFPaintTable, (PaintUndoInfo *) NULL); CIFTileOps += 1; square.r_xbot += op->co_bloats[2] + op->co_bloats[1]; } square.r_ybot += op->co_bloats[2] + op->co_bloats[1]; } return 0; }
|
|