Merge branch 'master' into magic-8.2

This commit is contained in:
Tim Edwards 2019-10-17 03:00:07 -04:00
commit 42031c45ff
10 changed files with 365 additions and 23 deletions

View File

@ -945,7 +945,7 @@ cifBloatAllFunc(tile, bls)
t = tile;
type = TiGetType(tile);
pNum = DBPlane(type);
pmask = CoincidentPlanes(&connect, pNum);
pmask = CoincidentPlanes(&connect, PlaneNumToMaskBit(pNum));
if (pmask == 0)
{
TiToRect(tile, &area);

View File

@ -38,7 +38,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
* Standard DBWind command set
*/
extern void CmdAddPath(), CmdArray();
extern void CmdAddPath(), CmdAntennaCheck(), CmdArray();
extern void CmdBox(), CmdCellname(), CmdClockwise();
extern void CmdContact(), CmdCopy(), CmdCorner();
extern void CmdCrash(), CmdCrosshair();
@ -222,6 +222,9 @@ DBWInitCommands()
WindAddCommand(DBWclientID,
"addpath [path] append to current search path",
CmdAddPath, FALSE);
WindAddCommand(DBWclientID,
"antennacheck [path] check for antenna violations",
CmdAntennaCheck, FALSE);
WindAddCommand(DBWclientID,
"array xsize ysize OR\n"
"array xlo xhi ylo yhi\n"

View File

@ -504,10 +504,7 @@ drcCifCheck(arg)
if (CIFCurStyle != drcCifStyle)
{
if (drcNeedStyle == NULL) {
TxError("Error: No DRC CIF style declared!\n");
return;
}
if (drcNeedStyle == NULL) return;
CIFSaveStyle = CIFCurStyle;

View File

@ -1147,6 +1147,17 @@ spcmainArgs(pargc, pargv)
char **argv = *pargv, *cp;
int argc = *pargc;
char usage_text[] = "Usage: ext2spice "
"[-B] [-o spicefile] [-M|-m] [-y cap_digits] "
"[-J flat|hier]\n"
"[-f spice2|spice3|hspice|ngspice] [-M] [-m] "
#ifdef MAGIC_WRAPPER
"[file]\n";
#else
"[-j device:sdRclass[/subRclass]/defaultSubstrate]\n"
"file\n\n or else see options to extcheck(1)\n";
#endif
switch (argv[0][1])
{
case 'd':
@ -1243,6 +1254,9 @@ spcmainArgs(pargc, pargv)
break;
}
#endif /* MAGIC_WRAPPER */
case 'h': /* -h or -help, as suggested by "ext2spice help" */
TxPrintf(usage_text);
break;
default:
TxError("Unrecognized flag: %s\n", argv[0]);
goto usage;
@ -1253,16 +1267,7 @@ spcmainArgs(pargc, pargv)
return 0;
usage:
TxError("Usage: ext2spice [-B] [-o spicefile] [-M|-m] [-y cap_digits] "
"[-J flat|hier]\n"
"[-f spice2|spice3|hspice|ngspice] [-M] [-m] "
#ifdef MAGIC_WRAPPER
"[file]\n"
#else
"[-j device:sdRclass[/subRclass]/defaultSubstrate]\n"
"file\n\n or else see options to extcheck(1)\n"
#endif
);
TxError(usage_text);
#ifdef MAGIC_WRAPPER
return 1;

View File

@ -28,3 +28,8 @@ EFsym.o: EFsym.c ../utils/magic.h ../utils/geometry.h ../utils/geofast.h \
EFvisit.o: EFvisit.c ../utils/magic.h ../utils/geometry.h \
../utils/geofast.h ../utils/hash.h ../utils/malloc.h ../utils/utils.h \
../extflat/extflat.h ../extflat/EFint.h ../extract/extract.h
EFantenna.o: EFantenna.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/geometry.h ../utils/hash.h ../utils/utils.h ../tiles/tile.h \
../database/database.h ../windows/windows.h ../textio/textio.h \
../dbwind/dbwind.h ../textio/txcommands.h ../extflat/extflat.h \
../extract/extract.h ../utils/malloc.h

297
extflat/EFantenna.c Normal file
View File

@ -0,0 +1,297 @@
/*
* EFantenna.c --
*
* Program to flatten hierarchical .ext files and then execute an
* antenna violation check for every MOSFET device in the flattened
* design.
*
* Flattens the tree rooted at file.ext, reading in additional .ext
* files as specified by "use" lines in file.ext.
*
*/
#include <stdio.h>
#include <stdlib.h> /* for atof() */
#include <string.h>
#include <ctype.h>
#include "tcltk/tclmagic.h"
#include "utils/magic.h"
#include "utils/geometry.h"
#include "utils/hash.h"
#include "utils/utils.h"
#include "tiles/tile.h"
#ifdef MAGIC_WRAPPER
#include "database/database.h"
#include "windows/windows.h"
#include "textio/textio.h"
#include "dbwind/dbwind.h" /* for DBWclientID */
#include "textio/txcommands.h"
#endif
#include "extflat/extflat.h"
#include "extract/extract.h" /* for extDevTable */
#include "utils/malloc.h"
/* Forward declarations */
int antennacheckArgs();
int antennacheckVisit();
typedef struct {
long visitMask:MAXDEVTYPES;
} nodeClient;
typedef struct {
HierName *lastPrefix;
long visitMask:MAXDEVTYPES;
} nodeClientHier;
#define NO_RESCLASS -1
#define markVisited(client, rclass) \
{ (client)->visitMask |= (1<<rclass); }
#define clearVisited(client) \
{ (client)->visitMask = (long)0; }
#define beenVisited(client, rclass) \
( (client)->visitMask & (1<<rclass))
#define initNodeClient(node) \
{ \
(node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \
(( nodeClient *)(node)->efnode_client)->visitMask = (long) 0; \
}
#define initNodeClientHier(node) \
{ \
(node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClientHier))); \
((nodeClientHier *) (node)->efnode_client)->visitMask = (long) 0; \
}
/*
* ----------------------------------------------------------------------------
*
* Main Tcl callback for command "magic::antennacheck"
*
* ----------------------------------------------------------------------------
*/
#define ANTENNACHECK_RUN 0
#define ANTENNACHECK_HELP 1
void
CmdAntennaCheck(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
int i,flatFlags;
char *inName;
FILE *f;
int option = ANTENNACHECK_RUN;
int value;
int argc = cmd->tx_argc;
char **argv = cmd->tx_argv;
char **msg;
bool err_result;
short sd_rclass;
short sub_rclass;
char *devname;
char *subname;
int idx;
static char *cmdAntennaCheckOption[] = {
"[run] [options] run antennacheck on current cell\n"
" use \"run -help\" to get standard options",
"help print help information",
NULL
};
if (cmd->tx_argc > 1)
{
option = Lookup(cmd->tx_argv[1], cmdAntennaCheckOption);
if (option < 0) option = ANTENNACHECK_RUN;
else argv++;
}
switch (option)
{
case ANTENNACHECK_RUN:
goto runantennacheck;
break;
case ANTENNACHECK_HELP:
usage:
for (msg = &(cmdAntennaCheckOption[0]); *msg != NULL; msg++)
{
TxPrintf(" %s\n", *msg);
}
break;
}
return;
runantennacheck:
EFInit();
EFCapThreshold = INFINITY;
EFResistThreshold = INFINITY;
/* Process command line arguments */
inName = EFArgs(argc, argv, &err_result, antennacheckArgs, (ClientData) NULL);
if (err_result == TRUE)
{
EFDone();
return /* TCL_ERROR */;
}
if (inName == NULL)
{
/* Assume that we want to do exttospice on the currently loaded cell */
if (w == (MagWindow *) NULL)
windCheckOnlyWindow(&w, DBWclientID);
if (w == (MagWindow *) NULL)
{
TxError("Point to a window or specify a cell name.\n");
EFDone();
return /* TCL_ERROR */;
}
inName = ((CellUse *) w->w_surfaceID)->cu_def->cd_name;
}
/*
* Initializations specific to this program.
*/
/* Read the hierarchical description of the input circuit */
if (EFReadFile(inName, FALSE, FALSE, FALSE) == FALSE)
{
EFDone();
return /* TCL_ERROR */;
}
/* Convert the hierarchical description to a flat one */
flatFlags = EF_FLATNODES;
EFFlatBuild(inName, flatFlags);
EFVisitDevs(antennacheckVisit, (ClientData)NULL);
EFFlatDone();
EFDone();
TxPrintf("antennacheck finished.\n");
}
/*
* ----------------------------------------------------------------------------
*
* antennacheckArgs --
*
* Process those arguments that are specific to antennacheck.
* Assumes that *pargv[0][0] is '-', indicating a flag
* argument.
*
* Results:
* None. TCL version returns False if an error is encountered
* while parsing arguments, True otherwise.
*
* Side effects:
* After processing an argument, updates *pargc and *pargv
* to point to after the argument.
*
* May initialize various global variables based on the
* arguments given to us.
*
* Exits in the event of an improper argument.
*
* ----------------------------------------------------------------------------
*/
int
antennacheckArgs(pargc, pargv)
int *pargc;
char ***pargv;
{
char **argv = *pargv, *cp;
int argc = *pargc;
switch (argv[0][1])
{
default:
TxError("Unrecognized flag: %s\n", argv[0]);
goto usage;
}
*pargv = argv;
*pargc = argc;
return 0;
usage:
TxError("Usage: antennacheck\n");
return 1;
}
/*
* ----------------------------------------------------------------------------
*
* antennacheckVisit --
*
* Procedure to check for antenna violations from a single device.
* Called by EFVisitDevs().
*
* Results:
* Returns 0 always.
*
* Side effects:
* May tag other device records to avoid double-counting devices.
* Generates feedback entries if an antenna violation is found.
*
* ----------------------------------------------------------------------------
*/
int
antennacheckVisit(dev, hierName, scale, trans)
Dev *dev; /* Device being output */
HierName *hierName; /* Hierarchical path down to this device */
float scale; /* Scale transform for output */
Transform *trans; /* Coordinate transform */
{
DevTerm *gate, *source, *drain;
int l, w;
Rect r;
switch(dev->dev_class)
{
case DEV_FET:
case DEV_MOSFET:
GeoTransRect(trans, &dev->dev_rect, &r);
/* Procedure:
*
* 1. If device is marked visited, return.
* 2. Mark device visited
* 3. Mark all connected devices visited
* 4. For each plane from metal1 up (determined by planeorder):
* a. Run SimTreeCopyConnect()
* b. Accumulate gate area of connected devices
* c. Accumulate metal area of connected devices
* d. Check against antenna ratio
* e. Generate feedback if in violation of antenna rule
*
* NOTE: SimTreeCopyConnect() is used cumulatively, so that
* additional searching only needs to be done for the additional
* layer being searched. This is the reason for using
* SimTreeCopyConnect() instead of DBTreeCopyConnect().
*/
/* To be completed */
}
return 0;
}

View File

@ -160,6 +160,15 @@ EFArgs(argc, argv, err_result, argsProc, cdata)
HierName *hierName;
FILE *f;
char usage_text[] =
"Standard arguments: [-R] [-C] [-r rthresh] [-c cthresh] [-v]\n"
"[-p searchpath] [-s sym=value] [-S symfile] [-t trimchars]\n"
#ifdef MAGIC_WRAPPER
"[rootfile]\n";
#else
"[-T techname] rootfile\n";
#endif
if (err_result != NULL) *err_result = FALSE;
/* Hash table of nodes we're going to watch if -N given */
@ -270,6 +279,11 @@ EFArgs(argc, argv, err_result, argsProc, cdata)
case 'z':
efHNStats = TRUE;
break;
case 'h':
if (argsProc != NULL) (*argsProc)(&argc, &argv, cdata);
TxPrintf(usage_text);
if (err_result != NULL) *err_result = TRUE;
return NULL;
/*** Try a caller-supplied argument processing function ***/
default:
@ -312,19 +326,15 @@ EFArgs(argc, argv, err_result, argsProc, cdata)
realIn[cp - inname] = '\0';
inname = realIn;
}
return inname;
usage:
TxError("Standard arguments: [-R] [-C] [-r rthresh] [-c cthresh] [-v]\n"
"[-p searchpath] [-s sym=value] [-S symfile] [-t trimchars]\n"
TxError(usage_text);
#ifdef MAGIC_WRAPPER
"[rootfile]\n");
if (err_result != NULL) *err_result = TRUE;
return NULL;
#else
"[-T techname] rootfile\n");
exit (1);
/*NOTREACHED*/
#endif

View File

@ -5,7 +5,7 @@
MODULE = extflat
MAGICDIR = ..
SRCS = EFargs.c EFbuild.c EFdef.c EFerr.c EFflat.c EFhier.c EFname.c \
EFread.c EFsym.c EFvisit.c
EFread.c EFsym.c EFvisit.c EFantenna.c
include ${MAGICDIR}/defs.mak
include ${MAGICDIR}/rules.mak

View File

@ -71,7 +71,7 @@ typedef enum
AREAC, CONTACT, CSCALE,
DEFAULTAREACAP, DEFAULTOVERLAP, DEFAULTPERIMETER, DEFAULTSIDEOVERLAP,
DEFAULTSIDEWALL,
DEVICE, FET, FETRESIST, HEIGHT, LAMBDA, OVERC,
DEVICE, FET, FETRESIST, HEIGHT, ANTENNA, LAMBDA, OVERC,
PERIMC, PLANEORDER, NOPLANEORDER, RESIST, RSCALE, SIDEHALO, SIDEOVERLAP,
SIDEWALL, STEP, STYLE, SUBSTRATE, UNITS, VARIANT
} Key;
@ -122,6 +122,9 @@ static keydesc keyTable[] = {
"height", HEIGHT, 4, 4,
"type height-above-subtrate thickness",
"antenna", ANTENNA, 3, 3,
"type antenna-ratio",
"lambda", LAMBDA, 2, 2,
"units-per-lambda",
@ -1785,6 +1788,7 @@ ExtTechLine(sectionName, argc, argv)
case FET:
case FETRESIST:
case HEIGHT:
case ANTENNA:
case OVERC:
case PERIMC:
case RESIST:
@ -2226,6 +2230,8 @@ ExtTechLine(sectionName, argc, argv)
if (subsName != NULL)
devptr->exts_deviceSubstrateName =
StrDup((char **) NULL, subsName);
else
devptr->exts_deviceSubstrateName = (char *)NULL;
devptr->exts_deviceSubstrateTypes = subsTypes;
devptr->exts_deviceIdentifierTypes = idTypes;
devptr->exts_deviceParams = (ParamList *) NULL;
@ -2303,6 +2309,22 @@ ExtTechLine(sectionName, argc, argv)
}
}
break;
case ANTENNA: {
float antennaratio;
if (!StrIsNumeric(argv[2]))
{
TechError("Layer antenna ratio %s must be numeric\n", argv[2]);
break;
}
antennaratio = (float)strtod(argv[2], NULL);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
if (TTMaskHasType(&types1, t))
{
ExtCurStyle->exts_antennaRatio[t] = antennaratio;
}
}
break;
case UNITS:
if (!strcmp(argv[1], "microns"))
doConvert = TRUE;

View File

@ -656,6 +656,9 @@ typedef struct extstyle
float exts_height[NT];
float exts_thick[NT];
/* Antenna area ratio for each layer */
float exts_antennaRatio[NT];
/*
* Capacitance to substrate for each tile type, in units of
* attofarads per square lambda.