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:
Tim Edwards 2019-05-11 15:09:01 -04:00
parent 770a6f4a17
commit f7d57c913c
2 changed files with 39 additions and 14 deletions

View File

@ -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();

View File

@ -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);