diff --git a/base/anneal.c b/base/anneal.c index b2ef531..c24136f 100644 --- a/base/anneal.c +++ b/base/anneal.c @@ -20,7 +20,6 @@ int MaxCPUTime = 100; /* max number of seconds to burn */ #define MAX_CHANGES_PER_ITER 2 #if 0 -/* INLINE */ float RandomUniform(void) { /* DANGER! DANGER! Non-portable code below!! */ diff --git a/base/bottomup.c b/base/bottomup.c index 8eba883..0dd24e3 100644 --- a/base/bottomup.c +++ b/base/bottomup.c @@ -36,7 +36,6 @@ int CountFanoutOK; int CountSwallowedElements; -INLINE int Independent(int E1, int E2) /* return 1 if E1 and E2 share no leaves in common */ { @@ -47,7 +46,6 @@ int Independent(int E1, int E2) return(1); } -INLINE int FanoutOK(int E1, int E2) { int approxfanout; @@ -67,7 +65,6 @@ int FanoutOK(int E1, int E2) } -INLINE int Swallowed(int Parent, int Child) /* returns 1 if Child's fanout is contained in Parent's */ { @@ -107,7 +104,6 @@ int SmallEnough(int E1, int E2) } #endif -INLINE int SuccessfulEmbedding(int E) /* returns 1 if element E is a successful embedding */ { diff --git a/base/config.h b/base/config.h index dd58aa2..3cef240 100644 --- a/base/config.h +++ b/base/config.h @@ -117,15 +117,6 @@ #define memzero(ptr, len) memset(ptr, 0, len) #endif - -#ifndef INLINE -#ifdef __GNUC__ -#define INLINE inline -#else -#define INLINE -#endif /* __GNUC__ */ -#endif - #ifdef HAVE_SYSV_STRING #undef NEED_STRING #endif diff --git a/base/embed.c b/base/embed.c index d2d8bb2..95c6204 100644 --- a/base/embed.c +++ b/base/embed.c @@ -348,7 +348,6 @@ void PRINTPACKED(unsigned long *mstar) #ifdef IBMPC static unsigned int lochash(unsigned long *mstar) #else -INLINE static unsigned long lochash(unsigned long *mstar) #endif { @@ -432,7 +431,6 @@ static struct ex_entry *hashinstall(unsigned long *mstar) return(ex_tab[hashval] = np); } -/* INLINE */ int Exists(int E1, int E2) { int i; @@ -470,7 +468,6 @@ int InitializeExistTest(void) return(1); } -/* INLINE */ void AddToExistSet(int E1, int E2) { int i; diff --git a/base/netcmp.c b/base/netcmp.c index 35c0bf9..6d364cc 100644 --- a/base/netcmp.c +++ b/base/netcmp.c @@ -1411,7 +1411,6 @@ int ElementListAllocated; int NodeListAllocated; #endif -INLINE struct Element *GetElement(void) { struct Element *new_element; @@ -1429,14 +1428,12 @@ struct Element *GetElement(void) return(new_element); } -INLINE void FreeElement(struct Element *old) { old->next = ElementFreeList; ElementFreeList = old; } -INLINE struct Node *GetNode(void) { struct Node *new_node; @@ -1454,14 +1451,12 @@ struct Node *GetNode(void) return(new_node); } -INLINE void FreeNode(struct Node *old) { old->next = NodeFreeList; NodeFreeList = old; } -INLINE struct ElementClass *GetElementClass(void) { struct ElementClass *new_elementclass; @@ -1481,14 +1476,12 @@ struct ElementClass *GetElementClass(void) return(new_elementclass); } -INLINE void FreeElementClass(struct ElementClass *old) { old->next = ElementClassFreeList; ElementClassFreeList = old; } -INLINE struct NodeClass *GetNodeClass(void) { struct NodeClass *new_nodeclass; @@ -1508,14 +1501,12 @@ struct NodeClass *GetNodeClass(void) return(new_nodeclass); } -INLINE void FreeNodeClass(struct NodeClass *old) { old->next = NodeClassFreeList; NodeClassFreeList = old; } -INLINE struct ElementList *GetElementList(void) { struct ElementList *new_elementlist; @@ -1534,14 +1525,12 @@ struct ElementList *GetElementList(void) return(new_elementlist); } -INLINE void FreeElementList(struct ElementList *old) { old->next = ElementListFreeList; ElementListFreeList = old; } -INLINE struct NodeList *GetNodeList(void) { struct NodeList *new_nodelist; @@ -1559,7 +1548,6 @@ struct NodeList *GetNodeList(void) return(new_nodelist); } -INLINE void FreeNodeList(struct NodeList *old) { old->next = NodeListFreeList; @@ -1834,6 +1822,7 @@ void CreateLists(char *name, short graph) } CombineParallel(name, graph); + CombineSerial(name, graph); Elements = CreateElementList(name, graph); Nodes = CreateNodeList(name, graph); @@ -1962,6 +1951,7 @@ void CreateLists(char *name, short graph) ConnectAllNodes(name, graph); CombineParallel(name, graph); + CombineSerial(name, graph); E = CreateElementList(name, graph); N = CreateNodeList(name, graph); diff --git a/base/netfile.c b/base/netfile.c index b276a15..10695f1 100644 --- a/base/netfile.c +++ b/base/netfile.c @@ -730,7 +730,6 @@ char *readbuf; int bytes_in_buffer; char *bufptr; -INLINE int READ(void *buf, int bytes) { if (bytes_in_buffer >= bytes) { diff --git a/base/netgen.c b/base/netgen.c index aee2446..e439a10 100644 --- a/base/netgen.c +++ b/base/netgen.c @@ -3033,6 +3033,199 @@ void CombineParallel(char *model, int file) } } +/*----------------------------------------------------------------------*/ +/* Find all nodes that are connected to exactly two devices of the same */ +/* class. Where found, if the device is allowed to combine serially */ +/* (check properties), then remove the node and merge the devices into */ +/* one. */ +/* */ +/* This routine depends on CombineParallel() being run first so that no */ +/* parallel devices are reported as serial. */ +/*----------------------------------------------------------------------*/ + +void CombineSerial(char *model, int file) +{ + struct nlist *tp, *tp2; + struct objlist ***instlist; + struct objlist *ob, *ob2, *obs, *obp, *obn; + int i, j; + struct valuelist *kv; + + if ((tp = LookupCellFile(model, file)) == NULL) { + Printf("Cell: %s does not exist.\n", model); + return; + } + instlist = (struct objlist ***)CALLOC((tp->nodename_cache_maxnodenum + 1), + sizeof(struct objlist **)); + + for (ob = tp->cell; ob; ob = ob->next) { + if ((ob->type >= FIRSTPIN) && (ob->node >= 0)) { + if (ob->type == FIRSTPIN) + obp = ob; // Save pointer to first pin of device + if (instlist[ob->node] == NULL) { + /* Node has not been seen before, so add it to list */ + instlist[ob->node] = (struct objlist **)CALLOC(2, + sizeof(struct objlist *)); + + /* For now, simple rule: Device must be a resistor */ + tp2 = LookupCellFile(ob->model.class, file); + if (tp2->class != CLASS_RES) + /* invalidate node */ + instlist[ob->node][0] = NULL; + else + instlist[ob->node][0] = obp; + } + else if (instlist[ob->node][0] == NULL) { + /* Node is not valid for serial connection */ + } + else if (instlist[ob->node][1] == NULL) { + /* Check if first instance is the same type */ + if ((*matchfunc)(instlist[ob->node][0]->model.class, ob->model.class)) + instlist[ob->node][1] = obp; + else + /* invalidate node */ + instlist[ob->node][0] = NULL; + } + } + } + for (i = 0; i <= tp->nodename_cache_maxnodenum; i++) { + if (instlist[i] != NULL) { + if ((instlist[i][0] != NULL) && (instlist[i][1] != NULL)) { + Fprintf(stdout, "Found serial instances %s and %s\n", + instlist[i][0]->instance.name, + instlist[i][1]->instance.name); + + /* To maintain knowledge of the topology, each device gets */ + /* a parameter 'S', string value set to "/". */ + + for (j = 0; j <= 1; j++) { + for (obp = instlist[i][j]; ; obp = obp->next) { + int found = FALSE; + int k, l; + char *nodename1, *nodename2; + struct valuelist *kv2; + + nodename1 = tp->nodename_cache[instlist[i][j]->node]->name; + nodename2 = tp->nodename_cache[instlist[i][j]->next->node]->name; + if (obp->type == PROPERTY) { + /* Add to properties */ + k = 0; + for (k = 0; ; k++) { + kv = &(obp->instance.props[k]); + if (kv->type == PROP_ENDLIST) + break; + } + kv2 = (struct valuelist *)MALLOC((k + 2) * + sizeof(struct valuelist)); + kv2->key = strsave("S"); + kv2->type = PROP_STRING; + /* Value is set to "/" */ + kv2->value.string = (char *)MALLOC(strlen(nodename1) + + strlen(nodename2) + 2); + sprintf(kv2->value.string, "%s/%s", nodename1, nodename2); + + for (l = 0; l <= k; l++) + kv2[l + 1] = obp->instance.props[l]; + FREE(obp->instance.props); + obp->instance.props = kv2; + found = TRUE; + } + if (obp->next == NULL || obp->next->type == FIRSTPIN) { + struct objlist *nob; + /* No property record, so insert one */ + if (found == FALSE) { + nob = GetObject(); + nob->type = PROPERTY; + nob->name = strsave("properties"); + nob->node = -2; /* Don't report as disconnected node */ + nob->model.class = strsave(obp->model.class); + nob->instance.props = NewPropValue(2); + + /* Create property record for property "S" */ + kv = &(nob->instance.props[0]); + kv->key = strsave("S"); + kv->type = PROP_STRING; + /* Value is set to "/" */ + kv->value.string = (char *)MALLOC(strlen(nodename1) + + strlen(nodename2) + 2); + sprintf(kv->value.string, "%s/%s", nodename1, nodename2); + + /* End of property list */ + kv = &(nob->instance.props[1]); + kv->key = NULL; + kv->type = PROP_ENDLIST; + kv->value.ival = 0; + + nob->next = obp->next; + obp->next = nob; + } + break; + } + } + } + + /* Combine these two instances and remove node i */ + for (ob2 = instlist[i][0]; ob2; ob2 = ob2->next) { + if (ob2->node == i) + break; + } + for (obs = instlist[i][1]; obs; obs = obs->next) { + if (obs->node != i) { + ob2->node = obs->node; + break; + } + } + + /* Excise the 2nd instance. instlist[i][1] remains as the */ + /* only pointer to it. */ + for (obp = instlist[i][0]; obp->next->type != FIRSTPIN; obp = obp->next); + for (ob2 = obp; ob2->next != instlist[i][1]; ob2 = ob2->next); + for (obs = ob2->next; obs->next && obs->next->type != FIRSTPIN; + obs = obs->next); + ob2->next = obs->next; + if (obs->next) obs->next = NULL; // Terminate 2nd instance record + + /* Move property record(s) of the 2nd device to the first */ + for (obs = instlist[i][1]; obs && obs->type != PROPERTY; obs = obs->next); + while (obs && (obs->type == PROPERTY)) { + obn = obs->next; + obs->next = obp->next; + obp->next = obs; + obs = obn; + } + + /* If 2nd device appears anywhere else in the serial device */ + /* list, replace it with the 1st device. */ + for (j = i + 1; j <= tp->nodename_cache_maxnodenum; j++) { + if (instlist[j][0] == instlist[i][1]) + instlist[j][0] = instlist[i][0]; + if (instlist[j][1] == instlist[i][1]) + instlist[j][1] = instlist[i][0]; + } + + /* Free 2nd device's object */ + for (obs = instlist[i][1]; obs && obs->type != PROPERTY; ) { + obn = obs->next; + FreeObjectAndHash(obs, tp); + obs = obn; + } + + /* Free node i and remove from object hash */ + for (obp = tp->cell; obp->next; obp = obp->next) { + if ((obp->next->type == NODE) && (obp->next->node == i)) { + obn = obp->next; + obp->next = obp->next->next; + FreeObjectAndHash(obn, tp); + break; + } + } + } + FREE(instlist[i]); + } + } + FREE(instlist); +} + /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ diff --git a/base/netgen.h b/base/netgen.h index 7f3fe14..0fb20aa 100644 --- a/base/netgen.h +++ b/base/netgen.h @@ -117,6 +117,7 @@ extern void ConvertGlobals(char *name, int fnum); extern int CleanupPins(char *name, int fnum); extern void ConnectAllNodes(char *model, int fnum); extern void CombineParallel(char *model, int fnum); +extern void CombineSerial(char *model, int fnum); extern int NoDisconnectedNodes; extern int PropertyKeyMatch(char *, char *); extern int PropertyValueMatch(char *, char *); diff --git a/base/place.c b/base/place.c index 2488546..b2f860f 100644 --- a/base/place.c +++ b/base/place.c @@ -315,7 +315,6 @@ void PrintE(FILE *outfile, int E) #if 0 -INLINE int UsedLeaves(int E1, int E2) /* returns the number of leaves in E1 + E2, which are assumed independent */ { @@ -327,7 +326,6 @@ int UsedLeaves(int E1, int E2) #endif -INLINE int CommonNodes(int E1, int E2, int IncludeGlobals) /* returns the number of nodes that E1 and E2 share */ /* if IncludeGlobals == 0, do not count large connectivity nodes */ @@ -350,7 +348,6 @@ int CommonNodes(int E1, int E2, int IncludeGlobals) return(result); } -INLINE int GlobalNodes(int E) /* return the number of global nodes that E contacts */ /* for now, global nodes are just cell ports */