Implemented command option 'ignore shorted', same syntax as
'ignore class', but removes instances of the specified class whose pins are shorted together. Currently requires that all pins must be shorted together.
This commit is contained in:
parent
bb07a84ae1
commit
9148edde69
|
|
@ -4551,13 +4551,13 @@ int EquivalenceNodes(char *name1, int file1, char *name2, int file2)
|
|||
/* database. */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
int IgnoreClass(char *name, int file)
|
||||
int IgnoreClass(char *name, int file, unsigned char type)
|
||||
{
|
||||
struct IgnoreList *newIgnore;
|
||||
|
||||
if ((file == -1) && (Circuit1 != NULL) && (Circuit2 != NULL)) {
|
||||
IgnoreClass(name, Circuit1->file);
|
||||
IgnoreClass(name, Circuit2->file);
|
||||
IgnoreClass(name, Circuit1->file, type);
|
||||
IgnoreClass(name, Circuit2->file, type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4567,9 +4567,13 @@ int IgnoreClass(char *name, int file)
|
|||
newIgnore->class = (char *)MALLOC(1 + strlen(name));
|
||||
strcpy(newIgnore->class, name);
|
||||
newIgnore->file = file;
|
||||
newIgnore->type = type;
|
||||
|
||||
/* Remove existing classes from database */
|
||||
ClassDelete(name, file);
|
||||
if (type == IGNORE_CLASS)
|
||||
ClassDelete(name, file);
|
||||
else
|
||||
RemoveShorted(name, file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ extern int PermuteForget(char *model, int filenum, char *pin1, char *pin2);
|
|||
extern int EquivalenceElements(char *name1, int file1, char *name2, int file2);
|
||||
extern int EquivalenceNodes(char *name1, int file1, char *name2, int file2);
|
||||
extern int EquivalenceClasses(char *name1, int file1, char *name2, int file2);
|
||||
extern int IgnoreClass(char *name, int file);
|
||||
extern int IgnoreClass(char *name, int file, unsigned char type);
|
||||
extern int MatchPins(struct nlist *tp1, struct nlist *tp2);
|
||||
|
||||
extern int CreateCompareQueue(char *, int, char *, int);
|
||||
|
|
|
|||
|
|
@ -1212,6 +1212,10 @@ void CellDefNoCase(char *name, int file)
|
|||
CurrentCell->flags |= CELL_NOCASE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Return 0 if class 'name' is not being ignored (per the 'ignore' */
|
||||
/* command); 1 if it is ignored, and 2 if shorted instances should be */
|
||||
/* ignored. */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
int IsIgnored(char *name, int file)
|
||||
|
|
@ -1223,7 +1227,7 @@ int IsIgnored(char *name, int file)
|
|||
{
|
||||
if ((file == -1) || (ilist->file == -1) || (file == ilist->file))
|
||||
if ((*matchfunc)(ilist->class, nptr))
|
||||
return 1;
|
||||
return ilist->type; /* IGNORE_CLASS or IGNORE_SHORTED */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1361,10 +1365,6 @@ void Instance(char *model, char *instancename)
|
|||
return;
|
||||
}
|
||||
fnum = CurrentCell->file;
|
||||
if (IsIgnored(model, fnum)) {
|
||||
Printf("Class '%s' instanced in input but is being ignored.\n", model);
|
||||
return;
|
||||
}
|
||||
instanced_cell = LookupCellFile(model, fnum);
|
||||
if (instanced_cell == NULL) {
|
||||
Printf("Attempt to instance undefined model '%s'\n", model);
|
||||
|
|
@ -1504,7 +1504,7 @@ char *Cell(char *inststr, char *model, ...)
|
|||
struct objlist *namedporthead, *namedportp, *namedlisthead, *namedlistp;
|
||||
int portnum, portlist, done;
|
||||
char namedport[512]; /* tmp buffers */
|
||||
int filenum;
|
||||
int filenum, itype, samenode;
|
||||
|
||||
static char *instancename = NULL;
|
||||
char *instnameptr;
|
||||
|
|
@ -1517,7 +1517,7 @@ char *Cell(char *inststr, char *model, ...)
|
|||
filenum = CurrentCell->file;
|
||||
|
||||
if (Debug) Printf(" calling cell: %s\n",model);
|
||||
if (IsIgnored(model, filenum)) {
|
||||
if ((itype = IsIgnored(model, filenum)) == IGNORE_CLASS) {
|
||||
Printf("Class '%s' instanced in input but is being ignored.\n", model);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1600,6 +1600,21 @@ char *Cell(char *inststr, char *model, ...)
|
|||
}
|
||||
va_end(ap);
|
||||
|
||||
/* Check for shorted pins */
|
||||
if ((itype == IGNORE_SHORTED) && (head != NULL)) {
|
||||
unsigned char shorted = (unsigned char)1;
|
||||
for (tp = head->next; tp; tp = tp->next) {
|
||||
if (strcasecmp(head->name, tp->name))
|
||||
shorted = (unsigned char)0;
|
||||
break;
|
||||
}
|
||||
if (shorted == (unsigned char)1) {
|
||||
Printf("Instance of '%s' is shorted, ignoring.\n", model);
|
||||
FreeObject(head);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (inststr == NULL) {
|
||||
if (instancename != NULL)
|
||||
FreeString(instancename);
|
||||
|
|
@ -1992,7 +2007,7 @@ struct objlist *LinkProperties(char *model, struct keyvalue *topptr)
|
|||
else
|
||||
filenum = CurrentCell->file;
|
||||
|
||||
if (IsIgnored(model, filenum)) {
|
||||
if (IsIgnored(model, filenum) == IGNORE_CLASS) {
|
||||
Printf("Class '%s' instanced in input but is being ignored.\n", model);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -340,6 +340,71 @@ void CellRehash(char *name, char *newname, int file)
|
|||
|
||||
struct nlist *OldCell;
|
||||
|
||||
int removeshorted(struct hashlist *p, int file)
|
||||
{
|
||||
struct nlist *ptr;
|
||||
struct objlist *ob, *lob, *nob, *tob;
|
||||
unsigned char shorted;
|
||||
|
||||
ptr = (struct nlist *)(p->ptr);
|
||||
|
||||
if ((file != -1) && (ptr->file != file)) return;
|
||||
|
||||
lob = NULL;
|
||||
for (ob = ptr->cell; ob != NULL;) {
|
||||
nob = ob->next;
|
||||
if ((ob->type == FIRSTPIN) && (ob->model.class != NULL)) {
|
||||
if ((*matchfunc)(ob->model.class, OldCell->name)) {
|
||||
shorted = (unsigned char)1;
|
||||
for (tob = nob; tob->type > FIRSTPIN; tob = tob->next) {
|
||||
if (tob->node != ob->node) {
|
||||
shorted = (unsigned char)0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (shorted == (unsigned char)0) {
|
||||
lob = ob;
|
||||
ob = nob;
|
||||
continue;
|
||||
}
|
||||
HashDelete(ob->instance.name, &(ptr->instdict));
|
||||
while (1) {
|
||||
FreeObjectAndHash(ob, ptr);
|
||||
ob = nob;
|
||||
if (ob == NULL) break;
|
||||
nob = ob->next;
|
||||
if (ob->type != PROPERTY && ob->type <= FIRSTPIN) break;
|
||||
}
|
||||
if (lob == NULL)
|
||||
ptr->cell = ob;
|
||||
else
|
||||
lob->next = ob;
|
||||
}
|
||||
else {
|
||||
lob = ob;
|
||||
ob = nob;
|
||||
}
|
||||
}
|
||||
else {
|
||||
lob = ob;
|
||||
ob = nob;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove shorted instances of class "class" from the database */
|
||||
|
||||
void RemoveShorted(char *class, int file)
|
||||
{
|
||||
if (file == -1)
|
||||
OldCell = LookupCell(class);
|
||||
else
|
||||
OldCell = LookupCellFile(class, file);
|
||||
|
||||
if (OldCell == NULL) return;
|
||||
RecurseCellFileHashTable(removeshorted, file);
|
||||
}
|
||||
|
||||
int deleteclass(struct hashlist *p, int file)
|
||||
{
|
||||
struct nlist *ptr;
|
||||
|
|
|
|||
|
|
@ -159,9 +159,16 @@ extern struct objlist *LastPlaced;
|
|||
struct IgnoreList {
|
||||
char *class;
|
||||
int file;
|
||||
unsigned char type;
|
||||
struct IgnoreList *next;
|
||||
};
|
||||
|
||||
/* Types used by IgnoreList above */
|
||||
|
||||
#define IGNORE_NONE (unsigned char)0
|
||||
#define IGNORE_CLASS (unsigned char)1
|
||||
#define IGNORE_SHORTED (unsigned char)2
|
||||
|
||||
/* Record structure for handling pin permutations in a cell */
|
||||
/* Linked list structure allows multiple permutations per cell. */
|
||||
|
||||
|
|
|
|||
31
base/spice.c
31
base/spice.c
|
|
@ -1530,6 +1530,8 @@ skip_ends:
|
|||
|
||||
else if (toupper(nexttok[0]) == 'X') { /* subcircuit instances */
|
||||
char instancename[100], subcktname[100];
|
||||
int itype;
|
||||
|
||||
instancename[99] = '\0';
|
||||
subcktname[99] = '\0';
|
||||
|
||||
|
|
@ -1602,6 +1604,34 @@ skip_ends:
|
|||
if (scan->next != NULL) scan = scan->next;
|
||||
tail->next = NULL;
|
||||
|
||||
/* Check for ignored class */
|
||||
|
||||
if ((itype = IsIgnored(subcktname, filenum)) == IGNORE_CLASS) {
|
||||
Printf("Class '%s' instanced in input but is being ignored.\n", model);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for shorted pins */
|
||||
|
||||
if ((itype == IGNORE_SHORTED) && (head != NULL)) {
|
||||
unsigned char shorted = (unsigned char)1;
|
||||
struct portelement *p;
|
||||
for (p = head->next; p; p = p->next) {
|
||||
if (strcasecmp(head->name, p->name))
|
||||
shorted = (unsigned char)0;
|
||||
break;
|
||||
}
|
||||
if (shorted == (unsigned char)1) {
|
||||
Printf("Instance of '%s' is shorted, ignoring.\n", subcktname);
|
||||
while (head) {
|
||||
p = head->next;
|
||||
FREE(head);
|
||||
head = p;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create cell name and revise instance name based on the cell name */
|
||||
/* For clarity, if "instancename" does not contain the cellname, */
|
||||
/* then prepend the cellname to the instance name. HOWEVER, if any */
|
||||
|
|
@ -1658,6 +1688,7 @@ skip_ends:
|
|||
}
|
||||
|
||||
/* nexttok is now NULL, scan->name points to class */
|
||||
|
||||
Instance(subcktname, instancename);
|
||||
pobj = LinkProperties(subcktname, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
|
|
|
|||
|
|
@ -2518,10 +2518,10 @@ _netcmp_ignore(ClientData clientData,
|
|||
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
||||
{
|
||||
char *options[] = {
|
||||
"class", NULL
|
||||
"class", "shorted", NULL
|
||||
};
|
||||
enum OptionIdx {
|
||||
CLASS_IDX
|
||||
CLASS_IDX, SHORTED_IDX
|
||||
};
|
||||
int result, index;
|
||||
int file = -1;
|
||||
|
|
@ -2542,7 +2542,14 @@ _netcmp_ignore(ClientData clientData,
|
|||
Tcl_WrongNumArgs(interp, 1, objv, "[class] valid_cellname");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
IgnoreClass(name, file);
|
||||
switch (index) {
|
||||
case CLASS_IDX:
|
||||
IgnoreClass(name, file, IGNORE_CLASS);
|
||||
break;
|
||||
case SHORTED_IDX:
|
||||
IgnoreClass(name, file, IGNORE_SHORTED);
|
||||
break;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue