2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* lefCmd.c --
|
|
|
|
|
*
|
|
|
|
|
* Commands for the LEF module only.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef lint
|
|
|
|
|
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/lef/lefCmd.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
|
|
|
|
#endif /* not lint */
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
2022-01-22 19:02:47 +01:00
|
|
|
#include <time.h>
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
#include "tcltk/tclmagic.h"
|
|
|
|
|
#include "utils/magic.h"
|
|
|
|
|
#include "utils/geometry.h"
|
|
|
|
|
#include "tiles/tile.h"
|
|
|
|
|
#include "utils/hash.h"
|
|
|
|
|
#include "database/database.h"
|
|
|
|
|
#include "windows/windows.h"
|
|
|
|
|
#include "dbwind/dbwind.h"
|
|
|
|
|
#include "utils/main.h"
|
2020-09-14 21:54:38 +02:00
|
|
|
#include "utils/utils.h"
|
2017-04-25 14:41:48 +02:00
|
|
|
#include "textio/txcommands.h"
|
|
|
|
|
#include "commands/commands.h"
|
|
|
|
|
|
2022-10-10 11:50:15 +02:00
|
|
|
/* C99 compat */
|
|
|
|
|
#include "textio/textio.h"
|
|
|
|
|
#include "cif/cif.h"
|
|
|
|
|
#include "lef/lefInt.h"
|
|
|
|
|
|
2022-01-22 19:30:11 +01:00
|
|
|
int lefDateStamp = -1; /* If not -1, defines the timestamp to use when creating
|
|
|
|
|
* new cell defs from LEF or DEF. Useful when generating
|
|
|
|
|
* libraries to make sure that full and abstract views of
|
|
|
|
|
* the same cell have matching timestamps.
|
|
|
|
|
*/
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* CmdLef --
|
|
|
|
|
*
|
|
|
|
|
* Implement the "lef" and "def" commands: generate LEF-format output
|
|
|
|
|
* for a layout, or read LEF- or DEF-format files.
|
|
|
|
|
*
|
|
|
|
|
* Usage:
|
|
|
|
|
* lef [options]
|
|
|
|
|
* def [options]
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Always return 0.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* Generates LEF-format output on disk somewhere, or reads
|
|
|
|
|
* LEF- or DEF-format files, generating cell definitions and
|
|
|
|
|
* uses in the process.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* These definitions must correspond to the ordering in cmdLefOption[] below */
|
|
|
|
|
|
|
|
|
|
#define LEF_READ 0
|
|
|
|
|
#define LEF_WRITE 1
|
|
|
|
|
#define LEF_WRITEALL 2
|
2022-01-22 19:02:47 +01:00
|
|
|
#define LEF_DATESTAMP 3
|
|
|
|
|
#define LEF_HELP 4
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
CmdLef(w, cmd)
|
|
|
|
|
MagWindow *w;
|
|
|
|
|
TxCommand *cmd;
|
|
|
|
|
{
|
2019-05-11 21:09:01 +02:00
|
|
|
int option, i, cargs, units = 1000; /* Default nanometers */
|
2017-04-25 14:41:48 +02:00
|
|
|
char **msg, *namep;
|
|
|
|
|
CellUse *selectedUse;
|
|
|
|
|
CellDef *selectedDef;
|
|
|
|
|
bool is_lef;
|
|
|
|
|
bool lefImport = FALSE; /* Indicates whether or not we
|
|
|
|
|
* read cells from .mag files
|
|
|
|
|
* when the FOREIGN statement
|
|
|
|
|
* is encountered in a macro.
|
|
|
|
|
*/
|
2020-10-14 23:20:45 +02:00
|
|
|
bool lefAnnotate = FALSE; /* Indicates that no celldefs should be
|
|
|
|
|
* created from any LEF files, which
|
|
|
|
|
* will be used for annotation only.
|
|
|
|
|
*/
|
2017-04-25 14:41:48 +02:00
|
|
|
bool lefTopCell = TRUE; /* Indicates whether or not we
|
|
|
|
|
* write the top-level cell to
|
|
|
|
|
* LEF, or just the subcells.
|
|
|
|
|
*/
|
|
|
|
|
bool allSpecial = FALSE; /* Indicates whether we should
|
|
|
|
|
* treat all geometry as "special"
|
|
|
|
|
* nets in DEF format output.
|
|
|
|
|
*/
|
2017-08-02 04:14:42 +02:00
|
|
|
bool lefTech = FALSE; /* Indicates that technology info
|
|
|
|
|
* will be output along with the
|
|
|
|
|
* lef macro.
|
|
|
|
|
*/
|
2020-09-14 21:54:38 +02:00
|
|
|
int lefHide = -1; /* If >= 0, hide all details of the macro
|
|
|
|
|
* other than pin area surrounding labels,
|
|
|
|
|
* with the indicated setback distance.
|
2018-11-19 21:01:20 +01:00
|
|
|
*/
|
2021-04-20 19:33:25 +02:00
|
|
|
int lefPinOnly = -1; /* If >= 0, make pins only where labels
|
|
|
|
|
* are defined, not the whole net. Values
|
|
|
|
|
* > 0 limit how far pins can extend into
|
|
|
|
|
* the interior of the cell.
|
2021-04-20 16:19:12 +02:00
|
|
|
*/
|
2020-10-06 21:41:35 +02:00
|
|
|
bool lefTopLayer = FALSE; /* If TRUE, only output the topmost
|
2020-07-15 23:29:56 +02:00
|
|
|
* layer used by a pin, and make
|
|
|
|
|
* all layers below it obstructions.
|
|
|
|
|
*/
|
2020-10-06 21:41:35 +02:00
|
|
|
bool lefDoMaster = TRUE; /* If TRUE, output masterslice layers;
|
|
|
|
|
* If FALSE, ignore masterslice layers.
|
|
|
|
|
*/
|
2019-12-19 16:33:22 +01:00
|
|
|
bool recurse = FALSE; /* If TRUE, recurse on all subcells
|
|
|
|
|
* during "writeall". By default,
|
|
|
|
|
* only the immediate children of the
|
|
|
|
|
* top level cell are output.
|
|
|
|
|
*/
|
2020-03-05 20:29:54 +01:00
|
|
|
bool defLabelNets = FALSE; /* If TRUE, attach a label to the
|
|
|
|
|
* center of the first rectangle
|
|
|
|
|
* found on that net.
|
|
|
|
|
*/
|
2022-03-30 19:02:12 +02:00
|
|
|
bool defAnnotate = FALSE; /* Indicates that no geometry should be
|
|
|
|
|
* created from any DEF files, which
|
|
|
|
|
* will be used for label annotation only.
|
|
|
|
|
*/
|
2022-06-24 21:22:53 +02:00
|
|
|
bool defNoBlockage = FALSE; /* Indicates that BLOCKAGE geometry in
|
|
|
|
|
* the DEF file should be ignored; only
|
|
|
|
|
* mask geometry will be generated.
|
|
|
|
|
*/
|
2017-04-25 14:41:48 +02:00
|
|
|
static char *cmdLefOption[] =
|
2020-05-23 23:13:14 +02:00
|
|
|
{
|
2017-04-25 14:41:48 +02:00
|
|
|
"read [filename] read a LEF file filename[.lef]\n"
|
2020-10-17 03:14:10 +02:00
|
|
|
" read [filename] -import read a LEF file; import cells from .mag files\n"
|
2020-12-18 22:38:06 +01:00
|
|
|
" read [filename] -annotate read a LEF file for cell annotation only.",
|
2018-11-19 21:01:20 +01:00
|
|
|
"write [filename] [-tech] write LEF for current cell\n"
|
2020-10-17 03:14:10 +02:00
|
|
|
" write [filename] -hide hide all details other than ports\n"
|
2020-09-14 21:54:38 +02:00
|
|
|
" write [filename] -hide <d> hide details in area set back distance <d>",
|
2017-04-25 14:41:48 +02:00
|
|
|
"writeall write all cells including the top-level cell\n"
|
2019-12-19 16:33:22 +01:00
|
|
|
" writeall -notop write all children of the top-level cell\n"
|
2020-10-17 03:14:10 +02:00
|
|
|
" writeall -all recurse on all subcells of the top-level cell\n"
|
|
|
|
|
" writeall -hide hide all details other than ports\n"
|
2020-09-14 21:54:38 +02:00
|
|
|
" writeall -hide [dist] hide details in area set back distance dist",
|
2022-01-22 19:02:47 +01:00
|
|
|
"datestamp [value] force the timestamp of cells read from LEF",
|
2017-04-25 14:41:48 +02:00
|
|
|
"help print this help information",
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static char *cmdDefOption[] =
|
2020-05-23 23:13:14 +02:00
|
|
|
{
|
2022-03-30 19:02:12 +02:00
|
|
|
"read [filename] read a DEF file filename[.def]\n"
|
|
|
|
|
" read [filename] -labels read a DEF file with net labeling\n"
|
2022-06-24 21:22:53 +02:00
|
|
|
" read [filename] -annotate read a DEF file for net annotation only\n",
|
|
|
|
|
" read [filename] -noblockage read a DEF file (mask layers only).",
|
2022-03-30 19:02:12 +02:00
|
|
|
"write [cell] [-allspecial] write DEF for current or indicated cell",
|
2017-04-25 14:41:48 +02:00
|
|
|
"writeall (use \"flatten -nosubckt\" + \"def"
|
|
|
|
|
" write\" instead)",
|
|
|
|
|
"help print this help information",
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Determine whether this function has been called via the "lef" or
|
|
|
|
|
* the "def" command.
|
|
|
|
|
*/
|
|
|
|
|
is_lef = (cmd->tx_argv[0][0] == 'd') ? FALSE : TRUE;
|
|
|
|
|
|
|
|
|
|
if (cmd->tx_argc < 2)
|
|
|
|
|
option = LEF_HELP;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
option = Lookup(cmd->tx_argv[1], cmdLefOption);
|
|
|
|
|
if (option < 0)
|
|
|
|
|
{
|
|
|
|
|
TxError("\"%s\" isn't a valid %s option.\n", cmd->tx_argv[1],
|
|
|
|
|
cmd->tx_argv[0]);
|
|
|
|
|
option = LEF_HELP;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (option != LEF_HELP)
|
|
|
|
|
{
|
|
|
|
|
selectedUse = CmdGetSelectedCell((Transform *)NULL);
|
|
|
|
|
if (selectedUse == NULL)
|
|
|
|
|
{
|
|
|
|
|
windCheckOnlyWindow(&w, DBWclientID);
|
|
|
|
|
if (w == (MagWindow *) NULL)
|
|
|
|
|
{
|
|
|
|
|
if (ToolGetBox(&selectedDef,NULL) == FALSE)
|
|
|
|
|
{
|
|
|
|
|
TxError("Point to a window first\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
selectedUse = selectedDef->cd_parents;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
selectedUse = (CellUse *)w->w_surfaceID;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (option)
|
|
|
|
|
{
|
|
|
|
|
case LEF_READ:
|
2020-03-05 20:29:54 +01:00
|
|
|
if (cmd->tx_argc > 3)
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
2020-03-05 20:29:54 +01:00
|
|
|
for (i = 3; i < cmd->tx_argc; i++)
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
2020-03-05 20:29:54 +01:00
|
|
|
if (*(cmd->tx_argv[i]) == '-')
|
|
|
|
|
{
|
|
|
|
|
if (!strncmp(cmd->tx_argv[i], "-import", 7))
|
2017-04-25 14:41:48 +02:00
|
|
|
lefImport = TRUE;
|
2020-10-14 23:20:45 +02:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-anno", 5))
|
2022-03-30 19:02:12 +02:00
|
|
|
{
|
|
|
|
|
if (is_lef)
|
|
|
|
|
lefAnnotate = TRUE;
|
|
|
|
|
else
|
|
|
|
|
defAnnotate = TRUE;
|
|
|
|
|
}
|
2020-03-05 20:29:54 +01:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-label", 6))
|
|
|
|
|
{
|
|
|
|
|
if (is_lef)
|
|
|
|
|
TxPrintf("The \"-labels\" option is only for def read\n");
|
|
|
|
|
else
|
|
|
|
|
defLabelNets = TRUE;
|
|
|
|
|
}
|
2022-06-24 21:22:53 +02:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-noblock", 8))
|
|
|
|
|
{
|
|
|
|
|
if (is_lef)
|
|
|
|
|
TxPrintf("The \"-noblockage\" option is only for def read\n");
|
|
|
|
|
else
|
|
|
|
|
defNoBlockage = TRUE;
|
|
|
|
|
}
|
2020-03-05 20:29:54 +01:00
|
|
|
}
|
2017-04-25 14:41:48 +02:00
|
|
|
}
|
|
|
|
|
}
|
2020-03-05 20:29:54 +01:00
|
|
|
else if (cmd->tx_argc < 3)
|
|
|
|
|
goto wrongNumArgs;
|
|
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
namep = cmd->tx_argv[2];
|
|
|
|
|
if (is_lef)
|
2022-01-22 19:02:47 +01:00
|
|
|
LefRead(namep, lefImport, lefAnnotate, lefDateStamp);
|
2017-04-25 14:41:48 +02:00
|
|
|
else
|
2022-06-24 21:22:53 +02:00
|
|
|
DefRead(namep, defLabelNets, defAnnotate, defNoBlockage);
|
2017-04-25 14:41:48 +02:00
|
|
|
break;
|
|
|
|
|
case LEF_WRITEALL:
|
|
|
|
|
if (!is_lef)
|
|
|
|
|
{
|
|
|
|
|
TxError("Sorry, can't write hierarchical DEF at this time.\n");
|
|
|
|
|
TxError("Try \"def write\"\n");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2017-08-02 04:14:42 +02:00
|
|
|
for (i = 2; i < cmd->tx_argc; i++)
|
|
|
|
|
{
|
|
|
|
|
if (*(cmd->tx_argv[i]) == '-')
|
|
|
|
|
{
|
|
|
|
|
if (!strncmp(cmd->tx_argv[i], "-notop", 6))
|
2017-04-25 14:41:48 +02:00
|
|
|
lefTopCell = FALSE;
|
2017-08-02 04:14:42 +02:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-tech", 5))
|
|
|
|
|
lefTech = TRUE;
|
2020-03-05 19:14:47 +01:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-hide", 5))
|
2020-09-14 21:54:38 +02:00
|
|
|
{
|
|
|
|
|
lefHide = 0;
|
|
|
|
|
if ((i < (cmd->tx_argc - 1)) &&
|
|
|
|
|
StrIsNumeric(cmd->tx_argv[i + 1]))
|
|
|
|
|
{
|
|
|
|
|
lefHide = cmdParseCoord(w, cmd->tx_argv[i + 1],
|
|
|
|
|
FALSE, TRUE);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-04-20 16:19:12 +02:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-pinonly", 8))
|
2021-04-20 19:33:25 +02:00
|
|
|
{
|
|
|
|
|
lefPinOnly = 0;
|
|
|
|
|
if ((i < (cmd->tx_argc - 1)) &&
|
|
|
|
|
StrIsNumeric(cmd->tx_argv[i + 1]))
|
|
|
|
|
{
|
|
|
|
|
lefPinOnly = cmdParseCoord(w, cmd->tx_argv[i + 1],
|
|
|
|
|
FALSE, TRUE);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-15 23:29:56 +02:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-toplayer", 9))
|
|
|
|
|
lefTopLayer = TRUE;
|
2020-10-06 21:41:35 +02:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-nomaster", 9))
|
|
|
|
|
lefDoMaster = FALSE;
|
2019-12-19 16:33:22 +01:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-all", 4))
|
|
|
|
|
recurse = TRUE;
|
2017-08-02 04:14:42 +02:00
|
|
|
else goto wrongNumArgs;
|
|
|
|
|
}
|
|
|
|
|
else goto wrongNumArgs;
|
|
|
|
|
}
|
2021-04-20 16:19:12 +02:00
|
|
|
LefWriteAll(selectedUse, lefTopCell, lefTech, lefHide, lefPinOnly,
|
|
|
|
|
lefTopLayer, lefDoMaster, recurse);
|
2017-04-25 14:41:48 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LEF_WRITE:
|
2017-08-02 04:14:42 +02:00
|
|
|
allSpecial = FALSE;
|
2018-11-19 21:01:20 +01:00
|
|
|
cargs = cmd->tx_argc;
|
2017-08-02 04:14:42 +02:00
|
|
|
for (i = 2; i < cmd->tx_argc; i++)
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
2017-08-02 04:14:42 +02:00
|
|
|
if (*(cmd->tx_argv[i]) == '-')
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
2017-08-02 04:14:42 +02:00
|
|
|
if (!strncmp(cmd->tx_argv[i], "-allspec", 8))
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
2017-08-02 04:14:42 +02:00
|
|
|
if (!is_lef)
|
2017-04-25 14:41:48 +02:00
|
|
|
allSpecial = TRUE;
|
2017-08-02 04:14:42 +02:00
|
|
|
else
|
|
|
|
|
TxPrintf("The \"-allspec\" option is only for def write\n");
|
|
|
|
|
}
|
|
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-tech", 5))
|
|
|
|
|
{
|
|
|
|
|
if (is_lef)
|
|
|
|
|
lefTech = TRUE;
|
|
|
|
|
else
|
|
|
|
|
TxPrintf("The \"-tech\" option is only for lef write\n");
|
2017-04-25 14:41:48 +02:00
|
|
|
}
|
2018-11-19 21:01:20 +01:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-hide", 5))
|
|
|
|
|
{
|
|
|
|
|
if (is_lef)
|
2020-09-14 21:54:38 +02:00
|
|
|
{
|
|
|
|
|
lefHide = 0;
|
|
|
|
|
if ((i < (cmd->tx_argc - 1)) &&
|
|
|
|
|
StrIsNumeric(cmd->tx_argv[i + 1]))
|
|
|
|
|
{
|
|
|
|
|
lefHide = cmdParseCoord(w, cmd->tx_argv[i + 1],
|
|
|
|
|
FALSE, TRUE);
|
|
|
|
|
cargs--;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-11-19 21:01:20 +01:00
|
|
|
else
|
2018-11-20 19:04:44 +01:00
|
|
|
TxPrintf("The \"-hide\" option is only for lef write\n");
|
2018-11-19 21:01:20 +01:00
|
|
|
}
|
2021-04-20 16:19:12 +02:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-pinonly", 8))
|
|
|
|
|
{
|
|
|
|
|
if (is_lef)
|
2021-04-20 19:33:25 +02:00
|
|
|
{
|
|
|
|
|
lefPinOnly = 0;
|
|
|
|
|
if ((i < (cmd->tx_argc - 1)) &&
|
|
|
|
|
StrIsNumeric(cmd->tx_argv[i + 1]))
|
|
|
|
|
{
|
|
|
|
|
lefPinOnly = cmdParseCoord(w, cmd->tx_argv[i + 1],
|
|
|
|
|
FALSE, TRUE);
|
|
|
|
|
cargs--;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-04-20 16:19:12 +02:00
|
|
|
else
|
|
|
|
|
TxPrintf("The \"-pinonly\" option is only for lef write\n");
|
|
|
|
|
}
|
2020-07-15 23:29:56 +02:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-toplayer", 9))
|
|
|
|
|
{
|
|
|
|
|
if (is_lef)
|
|
|
|
|
lefTopLayer = TRUE;
|
|
|
|
|
else
|
|
|
|
|
TxPrintf("The \"-toplayer\" option is only for lef write\n");
|
|
|
|
|
}
|
2020-10-06 21:41:35 +02:00
|
|
|
else if (!strncmp(cmd->tx_argv[i], "-nomaster", 9))
|
|
|
|
|
{
|
|
|
|
|
if (is_lef)
|
|
|
|
|
lefDoMaster = FALSE;
|
|
|
|
|
else
|
|
|
|
|
TxPrintf("The \"-nomaster\" option is only for lef write\n");
|
|
|
|
|
}
|
2019-05-11 21:09:01 +02:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-25 14:41:48 +02:00
|
|
|
else goto wrongNumArgs;
|
2018-11-19 21:01:20 +01:00
|
|
|
cargs--;
|
2017-04-25 14:41:48 +02:00
|
|
|
}
|
2017-10-06 04:18:10 +02:00
|
|
|
else if (i != 2) /* Is argument a filename? */
|
|
|
|
|
goto wrongNumArgs;
|
2017-04-25 14:41:48 +02:00
|
|
|
}
|
2018-11-19 21:01:20 +01:00
|
|
|
if (cargs != 2 && cargs != 3) goto wrongNumArgs;
|
2017-04-25 14:41:48 +02:00
|
|
|
if (selectedUse == NULL)
|
|
|
|
|
{
|
|
|
|
|
TxError("No cell selected\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2018-11-19 21:01:20 +01:00
|
|
|
if (cargs == 2)
|
2017-04-25 14:41:48 +02:00
|
|
|
namep = selectedUse->cu_def->cd_name;
|
|
|
|
|
else
|
|
|
|
|
namep = cmd->tx_argv[2];
|
|
|
|
|
if (!is_lef)
|
2019-05-11 21:09:01 +02:00
|
|
|
DefWriteCell(selectedUse->cu_def, namep, allSpecial, units);
|
2017-04-25 14:41:48 +02:00
|
|
|
else
|
|
|
|
|
LefWriteCell(selectedUse->cu_def, namep, selectedUse->cu_def
|
2021-04-20 16:19:12 +02:00
|
|
|
== EditRootDef, lefTech, lefHide, lefPinOnly,
|
|
|
|
|
lefTopLayer, lefDoMaster);
|
2017-04-25 14:41:48 +02:00
|
|
|
break;
|
2022-01-22 19:02:47 +01:00
|
|
|
case LEF_DATESTAMP:
|
|
|
|
|
if (!is_lef)
|
|
|
|
|
{
|
|
|
|
|
TxPrintf("The \"datestamp\" option is only for LEF reads.\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (cmd->tx_argc == 2)
|
|
|
|
|
{
|
|
|
|
|
#ifdef MAGIC_WRAPPER
|
2022-01-22 19:30:11 +01:00
|
|
|
if (lefDateStamp != -1)
|
|
|
|
|
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(lefDateStamp));
|
2022-01-22 19:02:47 +01:00
|
|
|
else
|
|
|
|
|
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj("default", -1));
|
|
|
|
|
#else
|
2022-01-22 19:30:11 +01:00
|
|
|
if (lefDateStamp != -1)
|
2022-01-22 19:02:47 +01:00
|
|
|
TxPrintf("Macros will contain a header creation date "
|
2022-01-22 19:30:11 +01:00
|
|
|
"stamp of %d.\n", lefDateStamp);
|
2022-01-22 19:02:47 +01:00
|
|
|
else
|
|
|
|
|
TxPrintf("Macros will contain a default header creation date "
|
|
|
|
|
"stamp.\n");
|
|
|
|
|
#endif
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else if (cmd->tx_argc != 3)
|
|
|
|
|
goto wrongNumArgs;
|
|
|
|
|
|
|
|
|
|
if (!strcmp(cmd->tx_argv[2], "default"))
|
2022-01-22 19:30:11 +01:00
|
|
|
lefDateStamp = -1;
|
2022-01-22 19:02:47 +01:00
|
|
|
else if (StrIsInt(cmd->tx_argv[2]))
|
2022-01-22 19:30:11 +01:00
|
|
|
lefDateStamp = atoi(cmd->tx_argv[2]);
|
2022-01-22 19:02:47 +01:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TxError("Unrecognizable date stamp \"%s\".\n", cmd->tx_argv[2]);
|
|
|
|
|
goto wrongNumArgs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
2017-04-25 14:41:48 +02:00
|
|
|
case LEF_HELP:
|
|
|
|
|
wrongNumArgs:
|
|
|
|
|
TxPrintf("The \"%s\" options are:\n", cmd->tx_argv[0]);
|
|
|
|
|
msg = (is_lef) ? &(cmdLefOption[0]) : &(cmdDefOption[0]);
|
|
|
|
|
for (; *msg != NULL; msg++)
|
|
|
|
|
{
|
|
|
|
|
TxPrintf(" %s %s\n", cmd->tx_argv[0], *msg);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|