Modified the LEF read routine so that it determines the LEF-to-
magic conversion for making magic contact types from contact cuts from the CIF/GDS input rules rather than the output rules. This generally makes more sense, plus avoids conflicts where the output rules may be set for CIF-DRC checks and may not be appropriate for LEF input without changing the style.
This commit is contained in:
parent
3b99464080
commit
4ae868802d
|
|
@ -1070,6 +1070,65 @@ CIFReadLoadStyle(stylename)
|
||||||
CIFTechInputScale(DBLambda[0], DBLambda[1], TRUE);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
||||||
#include "textio/textio.h"
|
#include "textio/textio.h"
|
||||||
#include "cif/cif.h"
|
#include "cif/cif.h"
|
||||||
#include "cif/CIFint.h" /* Access to CIFCurStyle. . . */
|
#include "cif/CIFint.h" /* Access to CIFCurStyle. . . */
|
||||||
|
#include "cif/CIFread.h" /* Access to cifCurReadStyle. . . */
|
||||||
#include "lef/lefInt.h"
|
#include "lef/lefInt.h"
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------*/
|
/* ---------------------------------------------------------------------*/
|
||||||
|
|
@ -1618,12 +1619,43 @@ LefAddViaGeometry(f, lefl, curlayer, oscale)
|
||||||
/* For LEF contact types matching magic contact types, */
|
/* For LEF contact types matching magic contact types, */
|
||||||
/* size the LEF contact cut to cover the minimum */
|
/* size the LEF contact cut to cover the minimum */
|
||||||
/* rectangle in the other layers that satisfies the */
|
/* 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;
|
int edgeSize = 0, contSize, halfSize;
|
||||||
float fcontSize;
|
|
||||||
|
|
||||||
/* Get the minimum size of a contact (cut + borders) from cifoutput */
|
/* Get the minimum size of a contact (cut + borders) from cifoutput */
|
||||||
contSize = CIFGetContactSize(curlayer, &edgeSize, NULL, NULL);
|
contSize = CIFGetContactSize(curlayer, &edgeSize, NULL, NULL);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue