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:
Tim Edwards 2016-10-18 14:17:57 -04:00
parent bb07a84ae1
commit 9148edde69
7 changed files with 145 additions and 16 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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. */

View File

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

View File

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