Corrected the equations for fringe shielding, as the equation for
the shielding fraction was inverted---I do not know how the tests could pass that way.
This commit is contained in:
parent
a205a0e941
commit
59b68606e0
|
|
@ -1296,8 +1296,8 @@ extShieldLeft(tpfar, efss)
|
|||
|
||||
if (overlap > 0)
|
||||
{
|
||||
frac = (float)(bp->b_segment.r_ytop - bp->b_segment.r_ybot) /
|
||||
(float)(start - limit);
|
||||
frac = (float)(start - limit) /
|
||||
(float)(bp->b_segment.r_ytop - bp->b_segment.r_ybot);
|
||||
/* Use sin() approximation for shielding effect */
|
||||
fshield = 1.0 - sin(1.571 * fsep / halo);
|
||||
efss->shieldfrac = fshield * frac + efss->shieldfrac * (1.0 - frac);
|
||||
|
|
@ -1349,8 +1349,8 @@ extShieldRight(tpfar, efss)
|
|||
|
||||
if (overlap > 0)
|
||||
{
|
||||
frac = (float)(bp->b_segment.r_ytop - bp->b_segment.r_ybot) /
|
||||
(float)(limit - start);
|
||||
frac = (float)(limit - start) /
|
||||
(float)(bp->b_segment.r_ytop - bp->b_segment.r_ybot);
|
||||
/* Use sin() approximation for shielding effect */
|
||||
fshield = 1.0 - sin(1.571 * fsep / halo);
|
||||
efss->shieldfrac = fshield * frac + efss->shieldfrac * (1.0 - frac);
|
||||
|
|
@ -1402,8 +1402,8 @@ extShieldTop(tpfar, efss)
|
|||
|
||||
if (overlap > 0)
|
||||
{
|
||||
frac = (float)(bp->b_segment.r_xtop - bp->b_segment.r_xbot) /
|
||||
(float)(limit - start);
|
||||
frac = (float)(limit - start) /
|
||||
(float)(bp->b_segment.r_xtop - bp->b_segment.r_xbot);
|
||||
/* Use sin() approximation for shielding effect */
|
||||
fshield = 1.0 - sin(1.571 * fsep / halo);
|
||||
efss->shieldfrac = fshield * frac + efss->shieldfrac * (1.0 - frac);
|
||||
|
|
@ -1455,8 +1455,8 @@ extShieldBottom(tpfar, efss)
|
|||
|
||||
if (overlap > 0)
|
||||
{
|
||||
frac = (float)(bp->b_segment.r_xtop - bp->b_segment.r_xbot) /
|
||||
(float)(start - limit);
|
||||
frac = (float)(start - limit) /
|
||||
(float)(bp->b_segment.r_xtop - bp->b_segment.r_xbot);
|
||||
/* Use sin() approximation for shielding effect */
|
||||
fshield = 1.0 - sin(1.571 * fsep / halo);
|
||||
efss->shieldfrac = fshield * frac + efss->shieldfrac * (1.0 - frac);
|
||||
|
|
|
|||
217
lef/defRead.c
217
lef/defRead.c
|
|
@ -94,9 +94,16 @@ DefAddRoutes(rootDef, f, oscale, special, netname, defLayerMap)
|
|||
int routeWidth, paintWidth, saveWidth;
|
||||
TileType routeLayer, paintLayer;
|
||||
HashEntry *he;
|
||||
lefLayer *lefl;
|
||||
lefLayer *lefl = NULL;
|
||||
lefRule *rule = NULL;
|
||||
int keyword;
|
||||
|
||||
static char *regnet_keys[] = {
|
||||
"STYLE",
|
||||
"TAPER",
|
||||
"TAPERRULE",
|
||||
};
|
||||
|
||||
static char *specnet_keys[] = {
|
||||
"SHAPE",
|
||||
"STYLE",
|
||||
|
|
@ -182,6 +189,8 @@ DefAddRoutes(rootDef, f, oscale, special, netname, defLayerMap)
|
|||
DEFAULT_WIDTH * DBLambda[1] / DBLambda[0];
|
||||
saveWidth = paintWidth;
|
||||
}
|
||||
else if (rule)
|
||||
paintWidth = rule->width;
|
||||
else
|
||||
paintWidth = (lefl) ? lefl->info.route.width :
|
||||
DEFAULT_WIDTH * DBLambda[1] / DBLambda[0];
|
||||
|
|
@ -321,6 +330,25 @@ DefAddRoutes(rootDef, f, oscale, special, netname, defLayerMap)
|
|||
/* Should the whole wire leg be ignored? */
|
||||
continue;
|
||||
}
|
||||
else if (!strcmp(token, "TAPER"))
|
||||
{
|
||||
/* Return to the default width for this layer */
|
||||
paintWidth = (lefl) ? lefl->info.route.width :
|
||||
DEFAULT_WIDTH * DBLambda[1] / DBLambda[0];
|
||||
}
|
||||
else if (!strcmp(token, "TAPERRULE"))
|
||||
{
|
||||
token = LefNextToken(f, TRUE);
|
||||
|
||||
he = HashLookOnly(&LefNonDefaultRules, token);
|
||||
if (he != NULL)
|
||||
{
|
||||
rule = (lefRule *)HashGetValue(he);
|
||||
paintWidth = rule->width;
|
||||
}
|
||||
else
|
||||
LefError(DEF_ERROR, "Unknown nondefault rule \"%s\"\n", token);
|
||||
}
|
||||
else if (*token != '(') /* via name */
|
||||
{
|
||||
/* A '+' or ';' record ends the route */
|
||||
|
|
@ -627,6 +655,183 @@ endCoord:
|
|||
return token; /* Pass back the last token found */
|
||||
}
|
||||
|
||||
/*
|
||||
*------------------------------------------------------------
|
||||
*
|
||||
* DefReadNonDefaultRules --
|
||||
*
|
||||
* Read a NONDEFAULTRULES section from a DEF file.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects:
|
||||
* Adds information into the non-default rules hash table.
|
||||
*
|
||||
*------------------------------------------------------------
|
||||
*/
|
||||
|
||||
enum def_nondef_keys {DEF_NONDEF_START = 0, DEF_NONDEF_END};
|
||||
enum def_nondefprop_keys {
|
||||
DEF_NONDEFPROP_HARDSPACING = 0, DEF_NONDEFPROP_LAYER,
|
||||
DEF_NONDEFPROP_VIA, DEF_NONDEFPROP_VIARULE,
|
||||
DEF_NONDEFPROP_MINCUTS, DEF_NONDEFPROP_PROPERTY,
|
||||
DEF_NONDEFLAYER_WIDTH, DEF_NONDEFLAYER_DIAG,
|
||||
DEF_NONDEFLAYER_SPACE, DEF_NONDEFLAYER_EXT};
|
||||
|
||||
void
|
||||
DefReadNonDefaultRules(f, rootDef, sname, oscale, total)
|
||||
FILE *f;
|
||||
CellDef *rootDef;
|
||||
char *sname;
|
||||
float oscale;
|
||||
int total;
|
||||
{
|
||||
char *token;
|
||||
char *rulename = NULL;
|
||||
int keyword, subkey;
|
||||
int processed = 0;
|
||||
HashEntry *he;
|
||||
lefLayer *lefl;
|
||||
float fvalue;
|
||||
lefRule *rule = NULL;
|
||||
|
||||
static char *nondef_keys[] = {
|
||||
"-",
|
||||
"END",
|
||||
NULL
|
||||
};
|
||||
|
||||
static char *nondef_property_keys[] = {
|
||||
"HARDSPACING",
|
||||
"LAYER",
|
||||
"VIA",
|
||||
"VIARULE",
|
||||
"MINCUTS",
|
||||
"PROPERTY",
|
||||
"WIDTH",
|
||||
"DIAGWIDTH",
|
||||
"SPACING",
|
||||
"WIREEXT",
|
||||
NULL
|
||||
};
|
||||
|
||||
while ((token = LefNextToken(f, TRUE)) != NULL)
|
||||
{
|
||||
keyword = Lookup(token, nondef_keys);
|
||||
if (keyword < 0)
|
||||
{
|
||||
LefError(DEF_INFO, "Unknown keyword \"%s\" in NONDEFAULTRULES "
|
||||
"definition; ignoring.\n", token);
|
||||
LefEndStatement(f);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (keyword)
|
||||
{
|
||||
case DEF_NONDEF_START:
|
||||
|
||||
/* Get non-default rule name */
|
||||
token = LefNextToken(f, TRUE);
|
||||
rulename = StrDup((char **)NULL, token);
|
||||
|
||||
/* Create a hash entry for this nondefault rule */
|
||||
/* NOTE: Needs to handle name collisions. */
|
||||
he = HashFind(&LefNonDefaultRules, rulename);
|
||||
rule = (lefRule *)mallocMagic(sizeof(lefRule));
|
||||
HashSetValue(he, rule);
|
||||
rule->lefInfo = NULL;
|
||||
rule->width = 0;
|
||||
rule->spacing = 0;
|
||||
|
||||
/* Process all properties */
|
||||
while (token && (*token != ';'))
|
||||
{
|
||||
if (*token != '+')
|
||||
{
|
||||
token = LefNextToken(f, TRUE);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
token = LefNextToken(f, TRUE);
|
||||
|
||||
subkey = Lookup(token, nondef_property_keys);
|
||||
if (subkey < 0)
|
||||
{
|
||||
LefError(DEF_INFO, "Unknown non-default rule property \"%s\" "
|
||||
"in NONDEFAULTRULE definition; ignoring.\n", token);
|
||||
continue;
|
||||
}
|
||||
switch (subkey)
|
||||
{
|
||||
case DEF_NONDEFPROP_HARDSPACING:
|
||||
lefl = NULL;
|
||||
/* Ignore this */
|
||||
break;
|
||||
case DEF_NONDEFPROP_VIA:
|
||||
case DEF_NONDEFPROP_VIARULE:
|
||||
lefl = NULL;
|
||||
/* Fall through */
|
||||
case DEF_NONDEFPROP_LAYER:
|
||||
token = LefNextToken(f, TRUE);
|
||||
he = HashFind(&LefInfo, token);
|
||||
lefl = (lefLayer *)HashGetValue(he);
|
||||
if (rule)
|
||||
rule->lefInfo = lefl;
|
||||
else
|
||||
LefError(DEF_INFO, "No non-default rule name for \"%s\" "
|
||||
"in NONDEFAULTRULE definition!.\n", token);
|
||||
break;
|
||||
case DEF_NONDEFPROP_MINCUTS:
|
||||
case DEF_NONDEFPROP_PROPERTY:
|
||||
lefl = NULL;
|
||||
/* Ignore the next two tokens */
|
||||
token = LefNextToken(f, TRUE);
|
||||
token = LefNextToken(f, TRUE);
|
||||
break;
|
||||
case DEF_NONDEFLAYER_WIDTH:
|
||||
token = LefNextToken(f, TRUE);
|
||||
sscanf(token, "%f", &fvalue);
|
||||
if (lefl == NULL)
|
||||
LefError(DEF_INFO, "No layer for non-default width.\n");
|
||||
else if (lefl->lefClass == CLASS_ROUTE)
|
||||
lefl->info.route.width = (int)roundf(fvalue / oscale);
|
||||
break;
|
||||
case DEF_NONDEFLAYER_SPACE:
|
||||
token = LefNextToken(f, TRUE);
|
||||
sscanf(token, "%f", &fvalue);
|
||||
if (lefl == NULL)
|
||||
LefError(DEF_INFO, "No layer for non-default width.\n");
|
||||
else if (lefl->lefClass == CLASS_ROUTE)
|
||||
lefl->info.route.spacing = (int)roundf(fvalue / oscale);
|
||||
break;
|
||||
case DEF_NONDEFLAYER_DIAG:
|
||||
case DEF_NONDEFLAYER_EXT:
|
||||
/* Absorb token and ignore */
|
||||
token = LefNextToken(f, TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DEF_NONDEF_END:
|
||||
if (!LefParseEndStatement(f, sname))
|
||||
{
|
||||
LefError(DEF_ERROR, "Non-default rule END statement missing.\n");
|
||||
keyword = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (keyword == DEF_NONDEF_END) break;
|
||||
}
|
||||
|
||||
if (processed == total)
|
||||
TxPrintf(" Processed %d non-default rules total.\n", processed);
|
||||
else
|
||||
LefError(DEF_WARNING, "Number of non-default rules read (%d) does not match "
|
||||
"the number declared (%d).\n", processed, total);
|
||||
}
|
||||
|
||||
/*
|
||||
*------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -1720,7 +1925,7 @@ enum def_sections {DEF_VERSION = 0, DEF_NAMESCASESENSITIVE,
|
|||
DEF_PINS, DEF_PINPROPERTIES, DEF_SPECIALNETS,
|
||||
DEF_NETS, DEF_IOTIMINGS, DEF_SCANCHAINS,
|
||||
DEF_CONSTRAINTS, DEF_GROUPS, DEF_EXTENSION, DEF_BLOCKAGES,
|
||||
DEF_END};
|
||||
DEF_NONDEFAULTRULES, DEF_END};
|
||||
|
||||
void
|
||||
DefRead(inName, dolabels)
|
||||
|
|
@ -1762,6 +1967,7 @@ DefRead(inName, dolabels)
|
|||
"GROUPS",
|
||||
"BEGINEXT",
|
||||
"BLOCKAGES",
|
||||
"NONDEFAULTRULES",
|
||||
"END",
|
||||
NULL
|
||||
};
|
||||
|
|
@ -1912,6 +2118,13 @@ DefRead(inName, dolabels)
|
|||
DefReadNets(f, rootDef, sections[DEF_NETS], oscale, FALSE,
|
||||
dolabels, total);
|
||||
break;
|
||||
case DEF_NONDEFAULTRULES:
|
||||
token = LefNextToken(f, TRUE);
|
||||
if (sscanf(token, "%d", &total) != 1) total = 0;
|
||||
LefEndStatement(f);
|
||||
DefReadNonDefaultRules(f, rootDef, sections[DEF_NONDEFAULTRULES],
|
||||
oscale, total);
|
||||
break;
|
||||
case DEF_IOTIMINGS:
|
||||
LefSkipSection(f, sections[DEF_IOTIMINGS]);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -207,6 +207,8 @@ defCountNets(rootDef, allSpecial)
|
|||
|
||||
total.regular = (allSpecial) ? -1 : 0;
|
||||
total.special = 0;
|
||||
total.numrules = 0;
|
||||
total.rules = NULL;
|
||||
total.has_nets = TRUE;
|
||||
|
||||
TxPrintf("Diagnostic: Finding all nets in cell %s\n", rootDef->cd_name);
|
||||
|
|
@ -2157,19 +2159,39 @@ DefWriteCell(def, outName, allSpecial, units)
|
|||
/* Count the number of nets and "special" nets */
|
||||
nets = defCountNets(def, allSpecial);
|
||||
|
||||
/* "Special" nets---nets matching $GND, $VDD, or $globals(*) */
|
||||
/* Nondefault rules */
|
||||
#if 0
|
||||
/* Not yet implemented */
|
||||
if (nets.numrules > 0)
|
||||
{
|
||||
NetRule *nrule;
|
||||
fprintf(f, "NONDEFAULTRULES %d ;\n", nets.numrules);
|
||||
for (nrule = nets.rules; nrule; nrule = nrule->next)
|
||||
{
|
||||
fprintf(f, " - %s\n", nrule->name);
|
||||
fprintf(f, " + LAYER %s WIDTH %.10g\n", nrule->rule->name,
|
||||
((float)nrule->rule->info.route.width * scale));
|
||||
}
|
||||
fprintf(f, "END NONDEFAULTRULES\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
fprintf(f, "SPECIALNETS %d ;\n", nets.special);
|
||||
/* "Special" nets---nets matching $GND, $VDD, or $globals(*) */
|
||||
if (nets.special > 0)
|
||||
{
|
||||
fprintf(f, "SPECIALNETS %d ;\n", nets.special);
|
||||
defWriteNets(f, def, scale, lefMagicToLefLayer, (allSpecial) ?
|
||||
ALL_SPECIAL : DO_SPECIAL);
|
||||
fprintf(f, "END SPECIALNETS\n\n");
|
||||
fprintf(f, "END SPECIALNETS\n\n");
|
||||
}
|
||||
|
||||
/* "Regular" nets */
|
||||
fprintf(f, "NETS %d ;\n", nets.regular);
|
||||
if (nets.regular > 0)
|
||||
{
|
||||
fprintf(f, "NETS %d ;\n", nets.regular);
|
||||
defWriteNets(f, def, scale, lefMagicToLefLayer, DO_REGULAR);
|
||||
fprintf(f, "END NETS\n\n");
|
||||
fprintf(f, "END NETS\n\n");
|
||||
}
|
||||
|
||||
if (nets.has_nets) {
|
||||
EFFlatDone(NULL);
|
||||
|
|
|
|||
36
lef/lefInt.h
36
lef/lefInt.h
|
|
@ -21,15 +21,6 @@
|
|||
#define DEFAULT_WIDTH 3 /* Default metal width for routes if undefined */
|
||||
#define DEFAULT_SPACING 4 /* Default spacing between metal if undefined */
|
||||
|
||||
/* Structure holding the counts of regular and special nets */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int regular;
|
||||
int special;
|
||||
bool has_nets;
|
||||
} NetCount;
|
||||
|
||||
/* Various modes for writing nets. */
|
||||
#define DO_REGULAR 0
|
||||
#define DO_SPECIAL 1
|
||||
|
|
@ -110,9 +101,36 @@ typedef struct {
|
|||
lefLayer *lefInfo; /* Pointer to information about the layer */
|
||||
} LefMapping;
|
||||
|
||||
/* Structure used for non-default rules. */
|
||||
|
||||
typedef struct {
|
||||
lefLayer *lefInfo; /* Layer or via referenced by the rule */
|
||||
int width; /* Non-default width value for layer */
|
||||
int spacing; /* Non-default spacing value for layer */
|
||||
} lefRule;
|
||||
|
||||
/* Structure to hold nondefault rules required by nets */
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
lefRule *rule;
|
||||
lefRule *next;
|
||||
} LefRules;
|
||||
|
||||
/* Structure holding the counts of regular and special nets */
|
||||
|
||||
typedef struct {
|
||||
int regular;
|
||||
int special;
|
||||
int numrules;
|
||||
LefRules *rules;
|
||||
bool has_nets;
|
||||
} NetCount;
|
||||
|
||||
/* External declaration of global variables */
|
||||
extern int lefCurrentLine;
|
||||
extern HashTable LefInfo;
|
||||
extern HashTable LefNonDefaultRules;
|
||||
|
||||
/* Forward declarations */
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ static char rcsid[] __attribute__ ((unused)) = "$Header$";
|
|||
|
||||
HashTable LefInfo;
|
||||
|
||||
/* Non-default rule table (currently used only by DEF read/write) */
|
||||
|
||||
HashTable LefNonDefaultRules;
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
* LefInit --
|
||||
|
|
@ -68,6 +72,7 @@ LefInit()
|
|||
/* on it when we to the tech initialization. */
|
||||
|
||||
LefInfo.ht_table = (HashEntry **) NULL;
|
||||
LefNonDefaultRules.ht_table = (HashEntry **) NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -114,8 +119,10 @@ LefTechInit()
|
|||
}
|
||||
}
|
||||
HashKill(&LefInfo);
|
||||
HashKill(&LefNonDefaultRules);
|
||||
}
|
||||
HashInit(&LefInfo, 32, HT_STRINGKEYS);
|
||||
HashInit(&LefNonDefaultRules, 32, HT_STRINGKEYS);
|
||||
lefCurrentLine = -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue