diff --git a/cif/CIFrdtech.c b/cif/CIFrdtech.c index ee638e13..b29509cb 100644 --- a/cif/CIFrdtech.c +++ b/cif/CIFrdtech.c @@ -1070,6 +1070,65 @@ CIFReadLoadStyle(stylename) CIFTechInputScale(DBLambda[0], DBLambda[1], TRUE); } +/* + * ---------------------------------------------------------------------------- + * + * CIFReadGetGrowSize -- + * + * Parse the rules for the given CIF/GDS layer "type" and return the + * amount that it needs to be grown to create the magic contact layer + * type. This assumes that the input manipulations are straightforward. + * It is expected that any "and" or "and-not" operations are to separate + * the via type from other via types, and that the amount to grow is the + * sum of all grow and shrink operations. + * + * Note that the routine works to determine simple grow rules for any + * layer but is specifically designed to determine how to convert cut + * layers from a LEF file into magic contact types. + * + * Results: + * Grow length, in magic units + * + * Side effects: + * None + * + * ---------------------------------------------------------------------------- + */ + +int +CIFReadGetGrowSize(type) + TileType type; +{ + CIFReadStyle *istyle = cifCurReadStyle; + CIFOp *op; + int i, dist = 0; + + if (istyle == NULL) return 0; + + for (i = 0; i < istyle->crs_nLayers; i++) + { + if (istyle->crs_layers[i]->crl_magicType == type) + { + dist = 0; + for (op = istyle->crs_layers[i]->crl_ops; op != NULL; + op = op->co_next) + { + if (op->co_opcode == CIFOP_GROW || + op->co_opcode == CIFOP_GROW_G) + { + dist += op->co_distance; + } + if (op->co_opcode == CIFOP_SHRINK) + { + dist -= op->co_distance; + } + } + if (dist > 0) break; + } + } + return dist; +} + /* * ---------------------------------------------------------------------------- * diff --git a/lef/lefRead.c b/lef/lefRead.c index 31af4640..4906984d 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -40,6 +40,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "textio/textio.h" #include "cif/cif.h" #include "cif/CIFint.h" /* Access to CIFCurStyle. . . */ +#include "cif/CIFread.h" /* Access to cifCurReadStyle. . . */ #include "lef/lefInt.h" /* ---------------------------------------------------------------------*/ @@ -1618,12 +1619,43 @@ LefAddViaGeometry(f, lefl, curlayer, oscale) /* For LEF contact types matching magic contact types, */ /* size the LEF contact cut to cover the minimum */ /* rectangle in the other layers that satisfies the */ - /* CIF/GDS contact generation. */ + /* CIF/GDS contact generation. Use the "cifinput" style */ + /* to determine how much the via layer needs to grow to */ + /* make a contact area. If the "cifinput" style is not */ + /* defined, then determine rules from "cifoutput". */ - if (DBIsContact(curlayer) && CIFCurStyle != NULL) + if (DBIsContact(curlayer) && cifCurReadStyle != NULL) + { + int growSize; + + /* Get the amount (in magic units) that the layer needs to */ + /* expand according to the "cifinput" style rules to convert */ + /* a contact cut to a magic contact layer. */ + + growSize = CIFReadGetGrowSize(curlayer); + + /* All internal LEF via geometry values are doubled */ + growSize <<= 1; + + if (growSize % cifCurReadStyle->crs_scaleFactor == 0) + growSize /= cifCurReadStyle->crs_scaleFactor; + else + growSize = growSize / cifCurReadStyle->crs_scaleFactor + 1; + + if (growSize > 0) + { + /* cifinput styles expect the cut size to be correct, so */ + /* there is no check for correctness of the layer. */ + + currect->r_xbot = currect->r_xbot - growSize; + currect->r_ybot = currect->r_ybot - growSize; + currect->r_xtop = currect->r_xtop + growSize; + currect->r_ytop = currect->r_ytop + growSize; + } + } + else if (DBIsContact(curlayer) && CIFCurStyle != NULL) { int edgeSize = 0, contSize, halfSize; - float fcontSize; /* Get the minimum size of a contact (cut + borders) from cifoutput */ contSize = CIFGetContactSize(curlayer, &edgeSize, NULL, NULL);