Modified "def write" to prevent out-of-bounds array access when
writing vias. However, the underlying problem, which is that stacked vias are not decomposed into their constituent parts, has not been addressed. A "-units" option was added to the "def write" command to force the units of the output file to be different than the default of 1000 (nanometers). No checks are made for whether values can be accurately represented at the specified scale.
This commit is contained in:
parent
770a6f4a17
commit
f7d57c913c
|
|
@ -84,10 +84,11 @@ char *defGetType(); /* Forward declaration */
|
|||
*/
|
||||
|
||||
void
|
||||
defWriteHeader(def, f, oscale)
|
||||
defWriteHeader(def, f, oscale, units)
|
||||
CellDef *def; /* Def for which to generate DEF output */
|
||||
FILE *f; /* Output to this file */
|
||||
float oscale;
|
||||
int units; /* Units for UNITS; could be derived from oscale */
|
||||
{
|
||||
TileType type;
|
||||
|
||||
|
|
@ -113,10 +114,10 @@ defWriteHeader(def, f, oscale)
|
|||
/* technology). */
|
||||
fprintf(f, " TECHNOLOGY %s ;\n", DBTechName);
|
||||
|
||||
/* As I understand it, this refers to the scalefactor of the GDS */
|
||||
/* file output. Magic does all GDS in nanometers, so the LEF */
|
||||
/* scalefactor (conversion to microns) is always 1000. */
|
||||
fprintf(f, " UNITS DISTANCE MICRONS 1000 ;\n");
|
||||
/* The DEF scalefactor (conversion to microns) is always 1000 */
|
||||
/* (nanometers) unless overridden on the command line. */
|
||||
|
||||
fprintf(f, " UNITS DISTANCE MICRONS %d ;\n", units);
|
||||
|
||||
/* Die area, taken from the cell def bounding box. */
|
||||
fprintf(f, " DIEAREA ( %.10g %.10g ) ( %.10g %.10g ) ;\n",
|
||||
|
|
@ -1864,10 +1865,10 @@ defMakeInverseLayerMap()
|
|||
TileType i;
|
||||
char *lefname;
|
||||
|
||||
lefMagicToLefLayer = (LefMapping *)mallocMagic(DBNumUserLayers
|
||||
lefMagicToLefLayer = (LefMapping *)mallocMagic(DBNumTypes
|
||||
* sizeof(LefMapping));
|
||||
memset(lefMagicToLefLayer, 0, sizeof(LefMapping) * TT_TECHDEPBASE);
|
||||
for (i = TT_TECHDEPBASE; i < DBNumUserLayers; i++)
|
||||
for (i = TT_TECHDEPBASE; i < DBNumTypes; i++)
|
||||
{
|
||||
lefname = defGetType(i, &lefl);
|
||||
lefMagicToLefLayer[i].lefName = lefname;
|
||||
|
|
@ -1916,23 +1917,28 @@ defMakeInverseLayerMap()
|
|||
*/
|
||||
|
||||
void
|
||||
DefWriteCell(def, outName, allSpecial)
|
||||
DefWriteCell(def, outName, allSpecial, units)
|
||||
CellDef *def; /* Cell being written */
|
||||
char *outName; /* Name of output file, or NULL. */
|
||||
bool allSpecial; /* Treat all nets as SPECIALNETS? */
|
||||
int units; /* Force units to this value (default 1000) */
|
||||
{
|
||||
char *filename;
|
||||
FILE *f;
|
||||
NetCount nets;
|
||||
int total;
|
||||
float scale = CIFGetOutputScale(1); /* Note that "1" here corresponds
|
||||
* to "1000" in the header UNITS line
|
||||
*/
|
||||
float scale;
|
||||
|
||||
LefMapping *lefMagicToLefLayer;
|
||||
int i;
|
||||
lefLayer *lefl;
|
||||
HashEntry *he;
|
||||
|
||||
/* Note that "1" corresponds to "1000" in the header UNITS line, */
|
||||
/* or units of nanometers. 10 = centimicrons, 1000 = microns. */
|
||||
|
||||
scale = CIFGetOutputScale(1000 / units);
|
||||
|
||||
f = lefFileOpen(def, outName, ".def", "w", &filename);
|
||||
|
||||
TxPrintf("Generating DEF output %s for cell %s:\n", filename, def->cd_name);
|
||||
|
|
@ -1949,7 +1955,7 @@ DefWriteCell(def, outName, allSpecial)
|
|||
return;
|
||||
}
|
||||
|
||||
defWriteHeader(def, f, scale);
|
||||
defWriteHeader(def, f, scale, units);
|
||||
|
||||
lefMagicToLefLayer = defMakeInverseLayerMap();
|
||||
|
||||
|
|
|
|||
23
lef/lefCmd.c
23
lef/lefCmd.c
|
|
@ -61,7 +61,7 @@ CmdLef(w, cmd)
|
|||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
{
|
||||
int option, i, cargs;
|
||||
int option, i, cargs, units = 1000; /* Default nanometers */
|
||||
char **msg, *namep;
|
||||
CellUse *selectedUse;
|
||||
CellDef *selectedDef;
|
||||
|
|
@ -219,6 +219,25 @@ CmdLef(w, cmd)
|
|||
else
|
||||
TxPrintf("The \"-hide\" option is only for lef write\n");
|
||||
}
|
||||
else if (!strncmp(cmd->tx_argv[i], "-units", 5))
|
||||
{
|
||||
if (is_lef)
|
||||
TxPrintf("The \"-units\" option is only for def write\n");
|
||||
else
|
||||
{
|
||||
i++;
|
||||
cargs--;
|
||||
if ((cmd->tx_argc < i) || (!StrIsInt(cmd->tx_argv[i])))
|
||||
{
|
||||
TxPrintf("The \"-units\" option requires an argument.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
units = atoi(cmd->tx_argv[i]);
|
||||
// To do: Check range of units
|
||||
}
|
||||
}
|
||||
}
|
||||
else goto wrongNumArgs;
|
||||
cargs--;
|
||||
}
|
||||
|
|
@ -236,7 +255,7 @@ CmdLef(w, cmd)
|
|||
else
|
||||
namep = cmd->tx_argv[2];
|
||||
if (!is_lef)
|
||||
DefWriteCell(selectedUse->cu_def, namep, allSpecial);
|
||||
DefWriteCell(selectedUse->cu_def, namep, allSpecial, units);
|
||||
else
|
||||
LefWriteCell(selectedUse->cu_def, namep, selectedUse->cu_def
|
||||
== EditRootDef, lefTech, lefHide);
|
||||
|
|
|
|||
Loading…
Reference in New Issue