mirror of
https://github.com/RTimothyEdwards/netgen.git
synced 2026-08-23 14:37:42 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e1d506697 | ||
|
|
013fff9f37 | ||
|
|
4edaf0813d | ||
|
|
2292ab813b | ||
|
|
a4ae5ed989 | ||
|
|
7e8508db53 | ||
|
|
c9f7b24e0f | ||
|
|
d850586a14 | ||
|
|
95605ebbd4 | ||
|
|
4b5b117100 | ||
|
|
98e6a4bd8f | ||
|
|
c73d9ec4ff | ||
|
|
a5375177c5 | ||
|
|
935e54abe6 | ||
|
|
27b095754e | ||
|
|
49ccf1949a | ||
|
|
db457c562b | ||
|
|
9b84776374 | ||
|
|
06386bee1b | ||
|
|
2af3f2a3f7 | ||
|
|
7cd8d82964 | ||
|
|
738abbdad9 | ||
|
|
3aeea9d164 | ||
|
|
12e1ff295f | ||
|
|
8d7569e9a3 | ||
|
|
2f9e898ec6 | ||
|
|
9663579dd0 |
+1
-1
@@ -131,7 +131,7 @@ if format = 1, use the actel .pin file format
|
||||
struct nlist *tp;
|
||||
struct objlist *ob, *ob2;
|
||||
char *ptr;
|
||||
char physicalpin[200];
|
||||
char physicalpin[MAX_STR_LEN];
|
||||
|
||||
tp = LookupCell(name);
|
||||
if (tp == NULL) return;
|
||||
|
||||
@@ -176,4 +176,6 @@ extern int open(char *path, int oflag, ...); /* HPUX has it in <sys/fcntl.h> */
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define MAX_STR_LEN 256
|
||||
|
||||
#endif /* _CONFIG_H */
|
||||
|
||||
+3
-3
@@ -629,7 +629,7 @@ struct embed *FlattenEmbeddingTree(struct embed *E)
|
||||
int LenEmbed(char *prefix, struct nlist *np, struct embed *E, int flatten)
|
||||
/* return the number of characters required to print element E */
|
||||
{
|
||||
char longstr[200];
|
||||
char longstr[MAX_STR_LEN];
|
||||
|
||||
if (E == NULL) return(0);
|
||||
if (E->left == NULL && E->right == NULL) {
|
||||
@@ -668,7 +668,7 @@ void PrintEmb(FILE *outfile, char *prefix, struct nlist *np,
|
||||
struct objlist *ob;
|
||||
char *instancename;
|
||||
struct nlist *np2;
|
||||
char name[200];
|
||||
char name[MAX_STR_LEN];
|
||||
|
||||
ob = InstanceNumber(np,E->instancenumber);
|
||||
instancename = ob->instance.name;
|
||||
@@ -706,7 +706,7 @@ void PrintEmbed(FILE *outfile, char *prefix, struct nlist *np,
|
||||
struct objlist *ob;
|
||||
char *instancename;
|
||||
struct nlist *np2;
|
||||
char name[200];
|
||||
char name[MAX_STR_LEN];
|
||||
|
||||
ob = InstanceNumber(np,E->instancenumber);
|
||||
instancename = ob->instance.name;
|
||||
|
||||
+23
-23
@@ -167,7 +167,7 @@ char *ReadExt(char *fname, int doflat, int *fnum)
|
||||
int filenum;
|
||||
|
||||
if ((filenum = OpenParseFile(fname, *fnum)) < 0) {
|
||||
char name[100];
|
||||
char name[MAX_STR_LEN];
|
||||
|
||||
SetExtension(name, fname, EXT_EXTENSION);
|
||||
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
|
||||
@@ -208,7 +208,7 @@ char *ReadExt(char *fname, int doflat, int *fnum)
|
||||
else if (match(nexttok, "style")) SkipNewLine(NULL);
|
||||
else if (match(nexttok, "resistclasses")) SkipNewLine(NULL);
|
||||
else if (match(nexttok, "node")) {
|
||||
char name[200];
|
||||
char name[MAX_STR_LEN];
|
||||
|
||||
/* No cell is generated until at least one valid "node" or "use" */
|
||||
/* has been read in the file. */
|
||||
@@ -223,8 +223,8 @@ char *ReadExt(char *fname, int doflat, int *fnum)
|
||||
SkipNewLine(NULL);
|
||||
}
|
||||
else if (match(nexttok, "equiv")) {
|
||||
char name[200];
|
||||
char name2[200];
|
||||
char name[MAX_STR_LEN];
|
||||
char name2[MAX_STR_LEN];
|
||||
SkipTok(NULL);
|
||||
GetExtName(name, nexttok);
|
||||
if (LookupObject(name,CurrentCell) == NULL) Node(name);
|
||||
@@ -235,8 +235,8 @@ char *ReadExt(char *fname, int doflat, int *fnum)
|
||||
SkipNewLine(NULL);
|
||||
}
|
||||
else if (match(nexttok, "device")) {
|
||||
char dev_name[100], dev_class[100];
|
||||
char gate[200], drain[200], source[200], subs[200];
|
||||
char dev_name[MAX_STR_LEN], dev_class[MAX_STR_LEN];
|
||||
char gate[MAX_STR_LEN], drain[MAX_STR_LEN], source[MAX_STR_LEN], subs[MAX_STR_LEN];
|
||||
char inststr[64];
|
||||
SkipTok(NULL);
|
||||
strcpy(dev_class, nexttok);
|
||||
@@ -306,8 +306,8 @@ char *ReadExt(char *fname, int doflat, int *fnum)
|
||||
SkipNewLine(NULL);
|
||||
}
|
||||
else if (match(nexttok, "fet")) { /* old-style FET record */
|
||||
char fet_class[100];
|
||||
char gate[200], drain[200], source[200], subs[200];
|
||||
char fet_class[MAX_STR_LEN];
|
||||
char gate[MAX_STR_LEN], drain[MAX_STR_LEN], source[MAX_STR_LEN], subs[MAX_STR_LEN];
|
||||
char inststr[64];
|
||||
SkipTok(NULL);
|
||||
strcpy(fet_class, nexttok);
|
||||
@@ -365,7 +365,7 @@ char *ReadExt(char *fname, int doflat, int *fnum)
|
||||
SkipNewLine(NULL);
|
||||
}
|
||||
else {
|
||||
char ctop[200], cbot[200], cdummy[200];
|
||||
char ctop[MAX_STR_LEN], cbot[MAX_STR_LEN], cdummy[MAX_STR_LEN];
|
||||
SkipTok(NULL);
|
||||
GetExtName(ctop, nexttok);
|
||||
SkipTok(NULL);
|
||||
@@ -375,8 +375,8 @@ char *ReadExt(char *fname, int doflat, int *fnum)
|
||||
}
|
||||
}
|
||||
else if (match(nexttok, "use")) {
|
||||
char name[200];
|
||||
char instancename[200];
|
||||
char name[MAX_STR_LEN];
|
||||
char instancename[MAX_STR_LEN];
|
||||
char *basename;
|
||||
|
||||
/* No cell is generated until at least one valid "node" or "use" */
|
||||
@@ -390,7 +390,7 @@ char *ReadExt(char *fname, int doflat, int *fnum)
|
||||
SkipTok(NULL);
|
||||
GetExtName(name, nexttok);
|
||||
if ((basename = strrchr(name,'/')) != NULL) {
|
||||
char tmp[200];
|
||||
char tmp[MAX_STR_LEN];
|
||||
strcpy(tmp, basename+1);
|
||||
strcpy(name, tmp);
|
||||
}
|
||||
@@ -405,8 +405,8 @@ char *ReadExt(char *fname, int doflat, int *fnum)
|
||||
SkipNewLine(NULL);
|
||||
}
|
||||
else if (match(nexttok, "merge")) {
|
||||
char name[200];
|
||||
char name2[200];
|
||||
char name[MAX_STR_LEN];
|
||||
char name2[MAX_STR_LEN];
|
||||
SkipTok(NULL);
|
||||
GetExtName(name, nexttok);
|
||||
SkipTok(NULL);
|
||||
@@ -640,7 +640,7 @@ char *ReadSim(char *fname, int *fnum)
|
||||
double simscale = 1.0;
|
||||
|
||||
if ((filenum = OpenParseFile(fname, *fnum)) < 0) {
|
||||
char name[100];
|
||||
char name[MAX_STR_LEN];
|
||||
|
||||
SetExtension(name, fname, SIM_EXTENSION);
|
||||
if (OpenParseFile(name, *fnum) < 0) {
|
||||
@@ -670,7 +670,7 @@ char *ReadSim(char *fname, int *fnum)
|
||||
SkipNewLine(NULL);
|
||||
}
|
||||
else if (match(nexttok, "n")) {
|
||||
char gate[200], drain[200], source[200];
|
||||
char gate[MAX_STR_LEN], drain[MAX_STR_LEN], source[MAX_STR_LEN];
|
||||
char inststr[25], *instptr = NULL;
|
||||
|
||||
SkipTok(NULL);
|
||||
@@ -714,7 +714,7 @@ char *ReadSim(char *fname, int *fnum)
|
||||
LinkProperties("n", kvlist);
|
||||
}
|
||||
else if (match(nexttok, "p")) {
|
||||
char gate[200], drain[200], source[200];
|
||||
char gate[MAX_STR_LEN], drain[MAX_STR_LEN], source[MAX_STR_LEN];
|
||||
char inststr[25], *instptr = NULL;
|
||||
SkipTok(NULL);
|
||||
GetExtName(gate, nexttok);
|
||||
@@ -754,7 +754,7 @@ char *ReadSim(char *fname, int *fnum)
|
||||
LinkProperties("p", kvlist);
|
||||
}
|
||||
else if (match(nexttok, "e")) { /* 3-port capacitors (poly/poly2) */
|
||||
char gate[200], drain[200], source[200];
|
||||
char gate[MAX_STR_LEN], drain[MAX_STR_LEN], source[MAX_STR_LEN];
|
||||
char inststr[25], *instptr = NULL;
|
||||
SkipTok(NULL);
|
||||
GetExtName(gate, nexttok);
|
||||
@@ -788,7 +788,7 @@ char *ReadSim(char *fname, int *fnum)
|
||||
E(fname, instptr, gate, drain, source);
|
||||
}
|
||||
else if (match(nexttok, "b")) { /* bipolars added by Tim 7/16/96 */
|
||||
char base[200], emitter[200], collector[200];
|
||||
char base[MAX_STR_LEN], emitter[MAX_STR_LEN], collector[MAX_STR_LEN];
|
||||
char inststr[25], *instptr = NULL;
|
||||
SkipTok(NULL);
|
||||
GetExtName(base, nexttok);
|
||||
@@ -826,7 +826,7 @@ char *ReadSim(char *fname, int *fnum)
|
||||
SkipNewLine(NULL);
|
||||
}
|
||||
else {
|
||||
char ctop[200], cbot[200], cdummy[200];
|
||||
char ctop[MAX_STR_LEN], cbot[MAX_STR_LEN], cdummy[MAX_STR_LEN];
|
||||
SkipTok(NULL);
|
||||
GetExtName(ctop, nexttok);
|
||||
if (LookupObject(ctop, CurrentCell) == NULL)
|
||||
@@ -851,7 +851,7 @@ char *ReadSim(char *fname, int *fnum)
|
||||
SkipNewLine(NULL);
|
||||
}
|
||||
else {
|
||||
char rtop[200], rbot[200];
|
||||
char rtop[MAX_STR_LEN], rbot[MAX_STR_LEN];
|
||||
SkipTok(NULL);
|
||||
GetExtName(rtop, nexttok);
|
||||
if (LookupObject(rtop, CurrentCell) == NULL)
|
||||
@@ -875,7 +875,7 @@ char *ReadSim(char *fname, int *fnum)
|
||||
SkipNewLine(NULL);
|
||||
}
|
||||
else {
|
||||
char rtop[200], rbot[200], rdummy[200];
|
||||
char rtop[MAX_STR_LEN], rbot[MAX_STR_LEN], rdummy[MAX_STR_LEN];
|
||||
char inststr[25], *instptr = NULL;
|
||||
SkipTok(NULL);
|
||||
GetExtName(rdummy, nexttok);
|
||||
@@ -917,7 +917,7 @@ char *ReadSim(char *fname, int *fnum)
|
||||
SkipNewLine(NULL);
|
||||
}
|
||||
else if (match(nexttok, "=")) {
|
||||
char node1[200], node2[200];
|
||||
char node1[MAX_STR_LEN], node2[MAX_STR_LEN];
|
||||
SkipTok(NULL);
|
||||
GetExtName(node1, nexttok);
|
||||
SkipTok(NULL);
|
||||
|
||||
+42
-1
@@ -53,7 +53,7 @@ void flattenCell(char *name, int file)
|
||||
struct nlist *ChildCell;
|
||||
struct objlist *tmp, *ob2, *ob3;
|
||||
int notdone, rnodenum;
|
||||
char tmpstr[200];
|
||||
char tmpstr[MAX_STR_LEN];
|
||||
int nextnode, oldmax;
|
||||
#if !OLDPREFIX
|
||||
int prefixlength;
|
||||
@@ -243,6 +243,13 @@ void flattenCell(char *name, int file)
|
||||
ThisCell->dumped = 1; /* indicate cell has been flattened */
|
||||
}
|
||||
|
||||
/* Structure used to keep track of nodes needing checking */
|
||||
|
||||
struct linkednode {
|
||||
int node;
|
||||
struct linkednode *next;
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* flattenInstancesOf -- */
|
||||
/* */
|
||||
@@ -265,6 +272,7 @@ int flattenInstancesOf(char *name, int fnum, char *instance)
|
||||
struct nlist *ThisCell;
|
||||
struct nlist *ChildCell;
|
||||
struct objlist *tmp, *ob2, *ob3;
|
||||
struct linkednode *checknodes = NULL, *newlnode, *chknode;
|
||||
int notdone, rnodenum;
|
||||
char tmpstr[1024];
|
||||
int nextnode, oldmax, numflat = 0;
|
||||
@@ -416,6 +424,16 @@ int flattenInstancesOf(char *name, int fnum, char *instance)
|
||||
}
|
||||
UpdateNodeNumbers(ChildStart, tmp->node, ob2->node);
|
||||
}
|
||||
else if (tmp->node == -1) {
|
||||
/* Opposite case: If child port is an unconnected node, then */
|
||||
/* removing the instance may make the parent node become */
|
||||
/* unconnected. For now, just record the node number. At the */
|
||||
/* end we'll check if these nodes are actually disconnected. */
|
||||
newlnode = (struct linkednode *)MALLOC(sizeof(struct linkednode));
|
||||
newlnode->node = ob2->node;
|
||||
newlnode->next = checknodes;
|
||||
checknodes = newlnode;
|
||||
}
|
||||
|
||||
/* in pathological cases, the lengths of the port lists may
|
||||
* change. This is an error, but that is no reason to allow
|
||||
@@ -598,6 +616,29 @@ int flattenInstancesOf(char *name, int fnum, char *instance)
|
||||
NextObj = ParentParams;
|
||||
} /* repeat until no more instances found */
|
||||
}
|
||||
|
||||
/* Check nodes that may have become disconnected after child flattening */
|
||||
while (checknodes != NULL) {
|
||||
struct objlist *portnode = NULL;
|
||||
|
||||
chknode = checknodes;
|
||||
checknodes = checknodes->next;
|
||||
|
||||
for (ob3 = ThisCell->cell; ob3; ob3 = ob3->next) {
|
||||
if ((ob3->type != PORT) && (portnode == NULL))
|
||||
break;
|
||||
else if ((ob3->type == PORT) && (ob3->node == chknode->node))
|
||||
portnode = ob3;
|
||||
else if ((ob3->type >= FIRSTPIN) && (ob3->node == chknode->node))
|
||||
break;
|
||||
}
|
||||
if ((ob3 == NULL) && (portnode != NULL)) {
|
||||
/* Port became disconnected when child was flattened */
|
||||
portnode->node = -1;
|
||||
}
|
||||
FREE(chknode);
|
||||
}
|
||||
|
||||
CacheNodeNames(ThisCell);
|
||||
ThisCell->dumped = 1; /* indicate cell has been flattened */
|
||||
return numflat;
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ void STRCPY(char *dest, char *source)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char cell1[200], cell2[200];
|
||||
char cell1[MAX_STR_LEN], cell2[MAX_STR_LEN];
|
||||
|
||||
Debug = 0;
|
||||
if (argc != 1) {
|
||||
|
||||
+562
-284
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -914,7 +914,7 @@ char *ReadNetlist(char *fname, int *fnum)
|
||||
}
|
||||
/* try appending extensions in sequence, and testing for file existance */
|
||||
for (index = 0; formats[index].extension != NULL; index++) {
|
||||
char testname[200];
|
||||
char testname[MAX_STR_LEN];
|
||||
strcpy(testname, fname);
|
||||
strcat(testname, formats[index].extension);
|
||||
if (OpenParseFile(testname, *fnum) >= 0) {
|
||||
@@ -1019,7 +1019,7 @@ void WriteNetgenFile(char *name, char *filename)
|
||||
|
||||
char *ReadNetgenFile (char *fname, int *fnum)
|
||||
{
|
||||
char name[100];
|
||||
char name[MAX_STR_LEN];
|
||||
char *LastCellRead = NULL;
|
||||
int filenum;
|
||||
|
||||
@@ -1255,7 +1255,7 @@ int READ(void *buf, int bytes)
|
||||
|
||||
char *ReadNetgenFile (char *fname, int *fnum)
|
||||
{
|
||||
char name[100];
|
||||
char name[MAX_STR_LEN];
|
||||
int len, chars;
|
||||
char *LastCellRead = NULL;
|
||||
|
||||
|
||||
+46
-1
@@ -57,7 +57,7 @@ int AddToExistingDefinition = 0; /* default: overwrite cell when reopened */
|
||||
extern int errno; /* Defined in stdlib.h */
|
||||
|
||||
#define MAX_STATIC_STRINGS 5
|
||||
static char staticstrings[MAX_STATIC_STRINGS][200];
|
||||
static char staticstrings[MAX_STATIC_STRINGS][MAX_STR_LEN];
|
||||
static int laststring;
|
||||
|
||||
extern struct hashdict spiceparams; /* From spice.c */
|
||||
@@ -984,6 +984,51 @@ PropertyDelete(char *name, int fnum, char *key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Associate a property with a specific pin */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
int
|
||||
PropertyAssociatePin(char *name, int fnum, char *key, char *pin)
|
||||
{
|
||||
struct property *kl = NULL;
|
||||
struct nlist *tc;
|
||||
struct objlist *ob;
|
||||
int result;
|
||||
|
||||
if ((fnum == -1) && (Circuit1 != NULL) && (Circuit2 != NULL)) {
|
||||
result = PropertyAssociatePin(name, Circuit1->file, key, pin);
|
||||
result = PropertyAssociatePin(name, Circuit2->file, key, pin);
|
||||
return result;
|
||||
}
|
||||
|
||||
tc = LookupCellFile(name, fnum);
|
||||
if (tc == NULL) {
|
||||
Printf("No device %s found for PropertyAssociatePin()\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
kl = (struct property *)HashLookup(key, &(tc->propdict));
|
||||
if (kl == NULL) {
|
||||
Printf("No property %s found for device %s\n", key, name);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
for (ob = tc->cell; ob != NULL; ob = ob->next) {
|
||||
if (ob->type != PORT) break;
|
||||
else if ((*matchfunc)(ob->name, pin)) {
|
||||
kl->pin = ob->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ob == NULL) {
|
||||
Printf("No pin %s found for device %s\n", pin, name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Set the tolerance of a property in the master cell record. */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
@@ -39,6 +39,7 @@ extern void SetParallelCombine(int value);
|
||||
extern void SetSeriesCombine(int value);
|
||||
extern int PropertyTolerance(char *name, int fnum, char *key, int ival,
|
||||
double dval);
|
||||
extern int PropertyAssociatePin(char *name, int fnum, char *key, char *pin);
|
||||
extern int PropertyMerge(char *name, int fnum, char *key, int merge_type,
|
||||
int merge_mask);
|
||||
extern void ResolveProperties(char *name1, int file1, char *name2, int file2);
|
||||
|
||||
+2
-2
@@ -181,7 +181,7 @@ void Ntk(char *name, char *filename)
|
||||
|
||||
char *ReadNtk (char *fname, int *fnum)
|
||||
{
|
||||
char model[100], instancename[100], name[100];
|
||||
char model[MAX_STR_LEN], instancename[MAX_STR_LEN], name[MAX_STR_LEN];
|
||||
struct objlist *ob;
|
||||
int CellDefInProgress = 0;
|
||||
int filenum;
|
||||
@@ -218,7 +218,7 @@ char *ReadNtk (char *fname, int *fnum)
|
||||
}
|
||||
}
|
||||
else if (match(nexttok, "s")) {
|
||||
char last[100];
|
||||
char last[MAX_STR_LEN];
|
||||
*last = '\0';
|
||||
if (!CellDefInProgress) {
|
||||
/* fake cell declaration for top-level call */
|
||||
|
||||
+42
-3
@@ -130,6 +130,7 @@ struct property *NewProperty(void)
|
||||
|
||||
kl = (struct property *)CALLOC(1,sizeof(struct property));
|
||||
if (kl == NULL) Fprintf(stderr,"NewProperty: Core allocation error\n");
|
||||
kl->pin = (char *)NULL;
|
||||
return (kl);
|
||||
}
|
||||
|
||||
@@ -440,15 +441,32 @@ void RemoveShorted(char *class, int file)
|
||||
RecurseCellFileHashTable(removeshorted, file);
|
||||
}
|
||||
|
||||
/* Remove instances of a deleted class from the database. */
|
||||
/* NOTE: This treats deleted classes as not existing, so it */
|
||||
/* needs to take care of disconnected ports in the same manner */
|
||||
/* as flattenInstancesOf() in disconnecting the port of a */
|
||||
/* parent cell if it connected to nothing other than the */
|
||||
/* deleted instance. */
|
||||
|
||||
int deleteclass(struct hashlist *p, int file)
|
||||
{
|
||||
struct nlist *ptr;
|
||||
struct objlist *ob, *lob, *nob;
|
||||
struct objlist *ob, *lob, *nob, *portnode;
|
||||
unsigned char *checknodes;
|
||||
int i;
|
||||
|
||||
ptr = (struct nlist *)(p->ptr);
|
||||
|
||||
if ((file != -1) && (ptr->file != file)) return 0;
|
||||
|
||||
/* Note: This could be made faster by enumerating all times each
|
||||
* node is used during the full pass, then subtracting each time
|
||||
* the node is deleted in a child, then disconnecting all nodes
|
||||
* that ended up with a zero count.
|
||||
*/
|
||||
checknodes = (unsigned char *)CALLOC(ptr->nodename_cache_maxnodenum + 1,
|
||||
sizeof(unsigned char));
|
||||
|
||||
lob = NULL;
|
||||
for (ob = ptr->cell; ob != NULL;) {
|
||||
nob = ob->next;
|
||||
@@ -456,6 +474,8 @@ int deleteclass(struct hashlist *p, int file)
|
||||
if ((*matchfunc)(ob->model.class, OldCell->name)) {
|
||||
HashDelete(ob->instance.name, &(ptr->instdict));
|
||||
while (1) {
|
||||
if (ob->type >= FIRSTPIN)
|
||||
checknodes[ob->node] = (unsigned char)1;
|
||||
FreeObjectAndHash(ob, ptr);
|
||||
ob = nob;
|
||||
if (ob == NULL) break;
|
||||
@@ -477,6 +497,25 @@ int deleteclass(struct hashlist *p, int file)
|
||||
ob = nob;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= ptr->nodename_cache_maxnodenum; i++) {
|
||||
if (checknodes[i] != 0) {
|
||||
portnode = NULL;
|
||||
for (ob = ptr->cell; ob != NULL; ob = ob->next) {
|
||||
if ((ob->type != PORT) && (portnode == NULL))
|
||||
break;
|
||||
else if ((ob->type == PORT) && (ob->node == i))
|
||||
portnode = ob;
|
||||
else if ((ob->type >= FIRSTPIN) && (ob->node == i))
|
||||
break;
|
||||
}
|
||||
if ((ob == NULL) && (portnode != NULL)) {
|
||||
/* Port became disconnected when child was deleted */
|
||||
portnode->node = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
FREE(checknodes);
|
||||
}
|
||||
|
||||
/* Remove all instances of class "class" from the database */
|
||||
@@ -697,7 +736,7 @@ struct nlist *RecurseCellHashTable2(struct nlist *(*foo)(struct hashlist *,
|
||||
|
||||
char *FixTemplate(char *t)
|
||||
{
|
||||
char buffer[200];
|
||||
char buffer[MAX_STR_LEN];
|
||||
char *rstr;
|
||||
int i,j;
|
||||
int InsideBrace;
|
||||
@@ -1208,7 +1247,7 @@ static char *OldNodeName(struct nlist *tp, int node)
|
||||
struct objlist *firstuniqueglobal;
|
||||
struct objlist *firstglobal;
|
||||
struct objlist *firstpin;
|
||||
static char StrBuffer[100];
|
||||
static char StrBuffer[MAX_STR_LEN];
|
||||
|
||||
#if 0
|
||||
/* make second pass, looking for ports */
|
||||
|
||||
+11
-9
@@ -135,6 +135,7 @@ struct property {
|
||||
unsigned char idx; /* index into valuelist */
|
||||
unsigned char type; /* string, integer, double, value, expression */
|
||||
unsigned char merge; /* how property changes when devices are merged */
|
||||
char *pin; /* associated pin (or NULL if not associated) */
|
||||
union {
|
||||
char *string;
|
||||
double dval;
|
||||
@@ -206,7 +207,7 @@ struct nlist {
|
||||
char *name;
|
||||
int number; /* number of instances defined */
|
||||
int dumped; /* instance count, and general-purpose marker */
|
||||
unsigned char flags;
|
||||
unsigned short flags;
|
||||
unsigned char class;
|
||||
unsigned long classhash; /* randomized hash value for cell class */
|
||||
struct Permutation *permutes; /* list of permuting pins */
|
||||
@@ -222,17 +223,18 @@ struct nlist {
|
||||
|
||||
/* Defined nlist structure flags */
|
||||
|
||||
#define CELL_MATCHED 0x01 /* cell matched to another */
|
||||
#define CELL_NOCASE 0x02 /* cell is case-insensitive (e.g., SPICE) */
|
||||
#define CELL_TOP 0x04 /* cell is a top-level cell */
|
||||
#define CELL_PLACEHOLDER 0x08 /* cell is a placeholder cell */
|
||||
#define CELL_PROPSMATCHED 0x10 /* properties matched to matching cell */
|
||||
#define CELL_DUPLICATE 0x20 /* cell has a duplicate */
|
||||
#define CELL_MATCHED 0x001 /* cell matched to another */
|
||||
#define CELL_NOCASE 0x002 /* cell is case-insensitive (e.g., SPICE) */
|
||||
#define CELL_TOP 0x004 /* cell is a top-level cell */
|
||||
#define CELL_PLACEHOLDER 0x008 /* cell is a placeholder cell */
|
||||
#define CELL_PROPSMATCHED 0x010 /* properties matched to matching cell */
|
||||
#define CELL_DUPLICATE 0x020 /* cell has a duplicate */
|
||||
#define CELL_VERILOG 0x040 /* cell is verilog module */
|
||||
|
||||
/* Flags for combination allowances and prohibitions */
|
||||
|
||||
#define COMB_SERIES 0x40
|
||||
#define COMB_NO_PARALLEL 0x80
|
||||
#define COMB_SERIES 0x100
|
||||
#define COMB_NO_PARALLEL 0x200
|
||||
|
||||
extern struct nlist *CurrentCell;
|
||||
extern struct objlist *CurrentTail;
|
||||
|
||||
+9
-9
@@ -511,8 +511,8 @@ int OpenEmbeddingFile(char *cellname, char *filename)
|
||||
/* returns 1 if OK */
|
||||
{
|
||||
struct nlist *tp;
|
||||
char outfilename[200];
|
||||
char logfilename[200];
|
||||
char outfilename[MAX_STR_LEN];
|
||||
char logfilename[MAX_STR_LEN];
|
||||
|
||||
tp = LookupCell(cellname);
|
||||
if (tp == NULL) {
|
||||
@@ -783,7 +783,7 @@ void SetupArray(char *prompt1, char *prompt2, char *prompt3, int *data,
|
||||
void (*proc)(void))
|
||||
{
|
||||
int i, oldfanout;
|
||||
char name[100];
|
||||
char name[MAX_STR_LEN];
|
||||
|
||||
Printf(prompt1);
|
||||
for (i = 1; i <= MAX_TREE_DEPTH; i++)
|
||||
@@ -792,7 +792,7 @@ void SetupArray(char *prompt1, char *prompt2, char *prompt3, int *data,
|
||||
|
||||
oldfanout = 1;
|
||||
for (i = 1; i <= MAX_TREE_DEPTH; i++) {
|
||||
char prompt[100];
|
||||
char prompt[MAX_STR_LEN];
|
||||
int newfanout;
|
||||
sprintf(prompt, prompt2, i);
|
||||
promptstring(prompt, name);
|
||||
@@ -822,7 +822,7 @@ void SetupArrayFromString(char *prompt1, char *prompt3, int *data,
|
||||
void (*proc)(void), char *text)
|
||||
{
|
||||
int i, oldfanout, newfanout;
|
||||
char string[100];
|
||||
char string[MAX_STR_LEN];
|
||||
char *ch;
|
||||
char *endch;
|
||||
|
||||
@@ -962,7 +962,7 @@ void ProtoPrintParameters(void)
|
||||
void PROTOCHIP(void)
|
||||
/* a simple command interpreter to manage embedding/routing */
|
||||
{
|
||||
char name[100];
|
||||
char name[MAX_STR_LEN];
|
||||
char ch;
|
||||
|
||||
InitializeFanout();
|
||||
@@ -1136,7 +1136,7 @@ void PROTOCHIP(void)
|
||||
|
||||
oldfanout = 1;
|
||||
for (i = 1; i <= MAX_TREE_DEPTH; i++) {
|
||||
char prompt[100];
|
||||
char prompt[MAX_STR_LEN];
|
||||
int newfanout;
|
||||
sprintf(prompt,"Fanout for level %d (0 to quit): ",i);
|
||||
promptstring(prompt, name);
|
||||
@@ -1168,7 +1168,7 @@ void PROTOCHIP(void)
|
||||
|
||||
oldfanout = 1;
|
||||
for (i = 1; i <= MAX_TREE_DEPTH; i++) {
|
||||
char prompt[100];
|
||||
char prompt[MAX_STR_LEN];
|
||||
int newfanout;
|
||||
sprintf(prompt,"Common nodes for level %d (0 to quit): ",i);
|
||||
promptstring(prompt, name);
|
||||
@@ -1200,7 +1200,7 @@ void PROTOCHIP(void)
|
||||
|
||||
oldfanout = 1;
|
||||
for (i = 1; i <= MAX_TREE_DEPTH; i++) {
|
||||
char prompt[100];
|
||||
char prompt[MAX_STR_LEN];
|
||||
int newfanout;
|
||||
sprintf(prompt,"Used leaves for level %d (0 to quit): ",i);
|
||||
promptstring(prompt, name);
|
||||
|
||||
+3
-3
@@ -37,7 +37,7 @@ extern int ColumnBase;
|
||||
|
||||
struct filestr {
|
||||
FILE *f;
|
||||
char buffer[200];
|
||||
char buffer[MAX_STR_LEN];
|
||||
int wrap; /* column to wrap around in, or 0 if no wrap */
|
||||
} file_buffers[MAXFILES];
|
||||
|
||||
@@ -107,7 +107,7 @@ void Fprintf(FILE *f, char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int FileIndex;
|
||||
char tmpstr[200];
|
||||
char tmpstr[MAX_STR_LEN];
|
||||
int bufferlongenough;
|
||||
int linewrapexceeded;
|
||||
|
||||
@@ -203,7 +203,7 @@ void Printf(char *format, ...)
|
||||
void Printf(char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char tmpstr[200];
|
||||
char tmpstr[MAX_STR_LEN];
|
||||
|
||||
va_start(ap, format);
|
||||
vsprintf(tmpstr, format, ap);
|
||||
|
||||
+4
-4
@@ -52,7 +52,7 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
/*************************************************************************/
|
||||
|
||||
static int SuppressPrompts = 0;
|
||||
static char InputLine[200];
|
||||
static char InputLine[MAX_STR_LEN];
|
||||
|
||||
void typeahead(char *str)
|
||||
{
|
||||
@@ -73,7 +73,7 @@ but reads from 'promptstring_infile' if nec. */
|
||||
/* If interactive, puts out 'prompt' */
|
||||
{
|
||||
char *nexttok;
|
||||
char tmpstr[200];
|
||||
char tmpstr[MAX_STR_LEN];
|
||||
int echo;
|
||||
|
||||
if (promptstring_infile == NULL)
|
||||
@@ -959,8 +959,8 @@ void Query(void)
|
||||
{
|
||||
/* little interactive debugger */
|
||||
char reply;
|
||||
char repstr[100];
|
||||
char repstr2[100];
|
||||
char repstr[MAX_STR_LEN];
|
||||
char repstr2[MAX_STR_LEN];
|
||||
float StartTime; /* for elapsed CPU times */
|
||||
int Timing; /* if true, print times of each command */
|
||||
int filenum = -1;
|
||||
|
||||
+117
-105
@@ -518,13 +518,13 @@ void ReadSpiceFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
int warnings = 0, update = 0, hasports = 0;
|
||||
char *eqptr, devtype, in_subckt;
|
||||
struct keyvalue *kvlist = NULL;
|
||||
char inst[256], model[256], instname[256];
|
||||
char inst[MAX_STR_LEN], model[MAX_STR_LEN], instname[MAX_STR_LEN];
|
||||
struct nlist *tp;
|
||||
struct objlist *parent, *sobj, *nobj, *lobj, *pobj;
|
||||
|
||||
inst[255] = '\0';
|
||||
model[255] = '\0';
|
||||
instname[255] = '\0';
|
||||
inst[MAX_STR_LEN-1] = '\0';
|
||||
model[MAX_STR_LEN-1] = '\0';
|
||||
instname[MAX_STR_LEN-1] = '\0';
|
||||
in_subckt = (char)0;
|
||||
|
||||
while (!EndParseFile()) {
|
||||
@@ -555,7 +555,7 @@ void ReadSpiceFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
|
||||
/* Check for existence of the cell. We may need to rename it. */
|
||||
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
snprintf(model, MAX_STR_LEN-1, "%s", nexttok);
|
||||
tp = LookupCellFile(nexttok, filenum);
|
||||
|
||||
/* Check for name conflict with duplicate cell names */
|
||||
@@ -703,7 +703,7 @@ skip_ends:
|
||||
|
||||
SpiceTokNoNewline();
|
||||
if (nexttok == NULL) continue; /* Ignore if no model name */
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
snprintf(model, MAX_STR_LEN-1, "%s", nexttok);
|
||||
SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
|
||||
@@ -887,29 +887,29 @@ skip_ends:
|
||||
}
|
||||
|
||||
else if (toupper(nexttok[0]) == 'Q') {
|
||||
char emitter[100], base[100], collector[100];
|
||||
emitter[99] = '\0';
|
||||
base[99] = '\0';
|
||||
collector[99] = '\0';
|
||||
char emitter[MAX_STR_LEN], base[MAX_STR_LEN], collector[MAX_STR_LEN];
|
||||
emitter[MAX_STR_LEN-1] = '\0';
|
||||
base[MAX_STR_LEN-1] = '\0';
|
||||
collector[MAX_STR_LEN-1] = '\0';
|
||||
|
||||
if (!(*CellStackPtr)) {
|
||||
CellDef(fname, filenum);
|
||||
PushStack(fname, CellStackPtr);
|
||||
}
|
||||
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
|
||||
strncpy(inst, nexttok + 1, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(collector, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(collector, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(base, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(base, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(emitter, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(emitter, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
/* make sure all the nodes exist */
|
||||
if (LookupObject(collector, CurrentCell) == NULL) Node(collector);
|
||||
if (LookupObject(base, CurrentCell) == NULL) Node(base);
|
||||
if (LookupObject(emitter, CurrentCell) == NULL) Node(emitter);
|
||||
|
||||
/* Read the device model */
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
snprintf(model, MAX_STR_LEN-1, "%s", nexttok);
|
||||
|
||||
while (nexttok != NULL)
|
||||
{
|
||||
@@ -940,30 +940,30 @@ skip_ends:
|
||||
goto baddevice;
|
||||
}
|
||||
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
snprintf(instname, MAX_STR_LEN-1, "%s:%s", model, inst);
|
||||
Cell(instname, model, collector, base, emitter);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
DeleteProperties(&kvlist);
|
||||
}
|
||||
else if (toupper(nexttok[0]) == 'M') {
|
||||
char drain[100], gate[100], source[100], bulk[100];
|
||||
drain[99] = '\0';
|
||||
gate[99] = '\0';
|
||||
source[99] = '\0';
|
||||
bulk[99] = '\0';
|
||||
char drain[MAX_STR_LEN], gate[MAX_STR_LEN], source[MAX_STR_LEN], bulk[MAX_STR_LEN];
|
||||
drain[MAX_STR_LEN-1] = '\0';
|
||||
gate[MAX_STR_LEN-1] = '\0';
|
||||
source[MAX_STR_LEN-1] = '\0';
|
||||
bulk[MAX_STR_LEN-1] = '\0';
|
||||
|
||||
if (!(*CellStackPtr)) {
|
||||
CellDef(fname, filenum);
|
||||
PushStack(fname, CellStackPtr);
|
||||
}
|
||||
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
|
||||
strncpy(inst, nexttok + 1, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(drain, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(drain, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(gate, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(gate, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(source, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(source, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
/* make sure all the nodes exist */
|
||||
if (LookupObject(drain, CurrentCell) == NULL) Node(drain);
|
||||
@@ -971,11 +971,11 @@ skip_ends:
|
||||
if (LookupObject(source, CurrentCell) == NULL) Node(source);
|
||||
|
||||
/* handle the substrate node */
|
||||
strncpy(bulk, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(bulk, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (LookupObject(bulk, CurrentCell) == NULL) Node(bulk);
|
||||
|
||||
/* Read the device model */
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
snprintf(model, MAX_STR_LEN-1, "%s", nexttok);
|
||||
|
||||
while (nexttok != NULL)
|
||||
{
|
||||
@@ -1013,7 +1013,7 @@ skip_ends:
|
||||
goto baddevice;
|
||||
}
|
||||
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
snprintf(instname, MAX_STR_LEN-1, "%s:%s", model, inst);
|
||||
Cell(instname, model, drain, gate, source, bulk);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
@@ -1027,19 +1027,19 @@ skip_ends:
|
||||
SpiceSkipNewLine();
|
||||
}
|
||||
else {
|
||||
char ctop[100], cbot[100];
|
||||
ctop[99] = '\0';
|
||||
cbot[99] = '\0';
|
||||
char ctop[MAX_STR_LEN], cbot[MAX_STR_LEN];
|
||||
ctop[MAX_STR_LEN-1] = '\0';
|
||||
cbot[MAX_STR_LEN-1] = '\0';
|
||||
|
||||
if (!(*CellStackPtr)) {
|
||||
CellDef(fname, filenum);
|
||||
PushStack(fname, CellStackPtr);
|
||||
}
|
||||
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
|
||||
strncpy(inst, nexttok + 1, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(ctop, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(ctop, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(cbot, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(cbot, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
|
||||
/* make sure all the nodes exist */
|
||||
if (LookupObject(ctop, CurrentCell) == NULL) Node(ctop);
|
||||
@@ -1058,7 +1058,7 @@ skip_ends:
|
||||
|
||||
model[0] = '\0';
|
||||
if ((nexttok != NULL) && ((eqptr = strchr(nexttok, '=')) == NULL))
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
snprintf(model, MAX_STR_LEN-1, "%s", nexttok);
|
||||
|
||||
/* Any other device properties? */
|
||||
while (nexttok != NULL)
|
||||
@@ -1071,7 +1071,7 @@ skip_ends:
|
||||
}
|
||||
else if (!strncmp(nexttok, "$[", 2)) {
|
||||
// Support for CDL modeled capacitor format
|
||||
snprintf(model, 99, "%s", nexttok + 2);
|
||||
snprintf(model, MAX_STR_LEN-1, "%s", nexttok + 2);
|
||||
if ((eqptr = strchr(model, ']')) != NULL)
|
||||
*eqptr = '\0';
|
||||
}
|
||||
@@ -1104,7 +1104,7 @@ skip_ends:
|
||||
usemodel = 1;
|
||||
}
|
||||
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
snprintf(instname, MAX_STR_LEN-1, "%s:%s", model, inst);
|
||||
if (usemodel)
|
||||
Cell(instname, model, ctop, cbot);
|
||||
else
|
||||
@@ -1121,19 +1121,19 @@ skip_ends:
|
||||
SpiceSkipNewLine();
|
||||
}
|
||||
else {
|
||||
char rtop[100], rbot[100];
|
||||
rtop[99] = '\0';
|
||||
rbot[99] = '\0';
|
||||
char rtop[MAX_STR_LEN], rbot[MAX_STR_LEN];
|
||||
rtop[MAX_STR_LEN-1] = '\0';
|
||||
rbot[MAX_STR_LEN-1] = '\0';
|
||||
|
||||
if (!(*CellStackPtr)) {
|
||||
CellDef(fname, filenum);
|
||||
PushStack(fname, CellStackPtr);
|
||||
}
|
||||
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
|
||||
strncpy(inst, nexttok + 1, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(rtop, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(rtop, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(rbot, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(rbot, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
/* make sure all the nodes exist */
|
||||
if (LookupObject(rtop, CurrentCell) == NULL) Node(rtop);
|
||||
if (LookupObject(rbot, CurrentCell) == NULL) Node(rbot);
|
||||
@@ -1152,7 +1152,7 @@ skip_ends:
|
||||
|
||||
model[0] = '\0';
|
||||
if ((nexttok != NULL) && ((eqptr = strchr(nexttok, '=')) == NULL))
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
snprintf(model, MAX_STR_LEN-1, "%s", nexttok);
|
||||
|
||||
/* Any other device properties? */
|
||||
while (nexttok != NULL) {
|
||||
@@ -1164,7 +1164,7 @@ skip_ends:
|
||||
}
|
||||
else if (!strncmp(nexttok, "$[", 2)) {
|
||||
// Support for CDL modeled resistor format
|
||||
snprintf(model, 99, "%s", nexttok + 2);
|
||||
snprintf(model, MAX_STR_LEN-1, "%s", nexttok + 2);
|
||||
if ((eqptr = strchr(model, ']')) != NULL)
|
||||
*eqptr = '\0';
|
||||
}
|
||||
@@ -1197,7 +1197,7 @@ skip_ends:
|
||||
else
|
||||
strcpy(model, "r"); /* Use default resistor model */
|
||||
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
snprintf(instname, MAX_STR_LEN-1, "%s:%s", model, inst);
|
||||
if (usemodel)
|
||||
Cell(instname, model, rtop, rbot);
|
||||
else
|
||||
@@ -1208,25 +1208,25 @@ skip_ends:
|
||||
}
|
||||
}
|
||||
else if (toupper(nexttok[0]) == 'D') { /* diode */
|
||||
char cathode[100], anode[100];
|
||||
cathode[99] = '\0';
|
||||
anode[99] = '\0';
|
||||
char cathode[MAX_STR_LEN], anode[MAX_STR_LEN];
|
||||
cathode[MAX_STR_LEN-1] = '\0';
|
||||
anode[MAX_STR_LEN-1] = '\0';
|
||||
|
||||
if (!(*CellStackPtr)) {
|
||||
CellDef(fname, filenum);
|
||||
PushStack(fname, CellStackPtr);
|
||||
}
|
||||
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
|
||||
strncpy(inst, nexttok + 1, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(anode, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(anode, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(cathode, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(cathode, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
/* make sure all the nodes exist */
|
||||
if (LookupObject(anode, CurrentCell) == NULL) Node(anode);
|
||||
if (LookupObject(cathode, CurrentCell) == NULL) Node(cathode);
|
||||
|
||||
/* Read the device model */
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
snprintf(model, MAX_STR_LEN-1, "%s", nexttok);
|
||||
|
||||
while (nexttok != NULL)
|
||||
{
|
||||
@@ -1255,7 +1255,7 @@ skip_ends:
|
||||
Fprintf(stderr, "Device \"%s\" has wrong number of ports for a diode.\n");
|
||||
goto baddevice;
|
||||
}
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
snprintf(instname, MAX_STR_LEN-1, "%s:%s", model, inst);
|
||||
Cell(instname, model, anode, cathode);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
@@ -1268,25 +1268,25 @@ skip_ends:
|
||||
SpiceSkipNewLine();
|
||||
}
|
||||
else {
|
||||
char node1[100], node2[100], node3[100], node4[100];
|
||||
node1[99] = '\0';
|
||||
node2[99] = '\0';
|
||||
node3[99] = '\0';
|
||||
node4[99] = '\0';
|
||||
char node1[MAX_STR_LEN], node2[MAX_STR_LEN], node3[MAX_STR_LEN], node4[MAX_STR_LEN];
|
||||
node1[MAX_STR_LEN-1] = '\0';
|
||||
node2[MAX_STR_LEN-1] = '\0';
|
||||
node3[MAX_STR_LEN-1] = '\0';
|
||||
node4[MAX_STR_LEN-1] = '\0';
|
||||
|
||||
if (!(*CellStackPtr)) {
|
||||
CellDef(fname, filenum);
|
||||
PushStack(fname, CellStackPtr);
|
||||
}
|
||||
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
|
||||
strncpy(inst, nexttok + 1, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(node1, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(node1, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(node2, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(node2, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(node3, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(node3, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(node4, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(node4, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
/* make sure all the nodes exist */
|
||||
if (LookupObject(node1, CurrentCell) == NULL) Node(node1);
|
||||
if (LookupObject(node2, CurrentCell) == NULL) Node(node2);
|
||||
@@ -1298,7 +1298,7 @@ skip_ends:
|
||||
|
||||
model[0] = '\0';
|
||||
if ((nexttok != NULL) && ((eqptr = strchr(nexttok, '=')) == NULL))
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
snprintf(model, MAX_STR_LEN-1, "%s", nexttok);
|
||||
|
||||
/* Any other device properties? */
|
||||
while (nexttok != NULL) {
|
||||
@@ -1334,7 +1334,7 @@ skip_ends:
|
||||
else
|
||||
strcpy(model, "t"); /* Use default xline model */
|
||||
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
snprintf(instname, MAX_STR_LEN-1, "%s:%s", model, inst);
|
||||
|
||||
if (usemodel)
|
||||
Cell(instname, model, node1, node2, node3, node4);
|
||||
@@ -1347,20 +1347,20 @@ skip_ends:
|
||||
}
|
||||
}
|
||||
else if (toupper(nexttok[0]) == 'L') { /* inductor */
|
||||
char end_a[100], end_b[100];
|
||||
char end_a[MAX_STR_LEN], end_b[MAX_STR_LEN];
|
||||
int usemodel = 0;
|
||||
end_a[99] = '\0';
|
||||
end_b[99] = '\0';
|
||||
end_a[MAX_STR_LEN-1] = '\0';
|
||||
end_b[MAX_STR_LEN-1] = '\0';
|
||||
|
||||
if (!(*CellStackPtr)) {
|
||||
CellDef(fname, filenum);
|
||||
PushStack(fname, CellStackPtr);
|
||||
}
|
||||
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
|
||||
strncpy(inst, nexttok + 1, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(end_a, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(end_a, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(end_b, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(end_b, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
/* make sure all the nodes exist */
|
||||
if (LookupObject(end_a, CurrentCell) == NULL) Node(end_a);
|
||||
if (LookupObject(end_b, CurrentCell) == NULL) Node(end_b);
|
||||
@@ -1379,7 +1379,7 @@ skip_ends:
|
||||
|
||||
model[0] = '\0';
|
||||
if ((nexttok != NULL) && ((eqptr = strchr(nexttok, '=')) == NULL))
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
snprintf(model, MAX_STR_LEN-1, "%s", nexttok);
|
||||
|
||||
/* Any other device properties? */
|
||||
while (nexttok != NULL)
|
||||
@@ -1417,7 +1417,7 @@ skip_ends:
|
||||
else
|
||||
strcpy(model, "l"); /* Use default inductor model */
|
||||
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
snprintf(instname, MAX_STR_LEN-1, "%s:%s", model, inst);
|
||||
if (usemodel)
|
||||
Cell(instname, model, end_a, end_b);
|
||||
else
|
||||
@@ -1431,19 +1431,19 @@ skip_ends:
|
||||
/* black-box subcircuits (class MODULE): V, I, E */
|
||||
|
||||
else if (toupper(nexttok[0]) == 'V') { /* voltage source */
|
||||
char pos[100], neg[100];
|
||||
pos[99] = '\0';
|
||||
neg[99] = '\0';
|
||||
char pos[MAX_STR_LEN], neg[MAX_STR_LEN];
|
||||
pos[MAX_STR_LEN-1] = '\0';
|
||||
neg[MAX_STR_LEN-1] = '\0';
|
||||
|
||||
if (!(*CellStackPtr)) {
|
||||
CellDef(fname, filenum);
|
||||
PushStack(fname, CellStackPtr);
|
||||
}
|
||||
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
|
||||
strncpy(inst, nexttok + 1, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(pos, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(pos, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(neg, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(neg, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
/* make sure all the nodes exist */
|
||||
if (LookupObject(pos, CurrentCell) == NULL) Node(pos);
|
||||
@@ -1499,19 +1499,19 @@ skip_ends:
|
||||
DeleteProperties(&kvlist);
|
||||
}
|
||||
else if (toupper(nexttok[0]) == 'I') { /* current source */
|
||||
char pos[100], neg[100];
|
||||
pos[99] = '\0';
|
||||
neg[99] = '\0';
|
||||
char pos[MAX_STR_LEN], neg[MAX_STR_LEN];
|
||||
pos[MAX_STR_LEN-1] = '\0';
|
||||
neg[MAX_STR_LEN-1] = '\0';
|
||||
|
||||
if (!(*CellStackPtr)) {
|
||||
CellDef(fname, filenum);
|
||||
PushStack(fname, CellStackPtr);
|
||||
}
|
||||
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
|
||||
strncpy(inst, nexttok + 1, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(pos, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(pos, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(neg, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(neg, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
/* make sure all the nodes exist */
|
||||
if (LookupObject(pos, CurrentCell) == NULL) Node(pos);
|
||||
if (LookupObject(neg, CurrentCell) == NULL) Node(neg);
|
||||
@@ -1553,25 +1553,25 @@ skip_ends:
|
||||
DeleteProperties(&kvlist);
|
||||
}
|
||||
else if (toupper(nexttok[0]) == 'E') { /* controlled voltage source */
|
||||
char pos[100], neg[100], ctrlp[100], ctrln[100];
|
||||
pos[99] = '\0';
|
||||
neg[99] = '\0';
|
||||
ctrlp[99] = '\0';
|
||||
ctrln[99] = '\0';
|
||||
char pos[MAX_STR_LEN], neg[MAX_STR_LEN], ctrlp[MAX_STR_LEN], ctrln[MAX_STR_LEN];
|
||||
pos[MAX_STR_LEN-1] = '\0';
|
||||
neg[MAX_STR_LEN-1] = '\0';
|
||||
ctrlp[MAX_STR_LEN-1] = '\0';
|
||||
ctrln[MAX_STR_LEN-1] = '\0';
|
||||
|
||||
if (!(*CellStackPtr)) {
|
||||
CellDef(fname, filenum);
|
||||
PushStack(fname, CellStackPtr);
|
||||
}
|
||||
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
|
||||
strncpy(inst, nexttok + 1, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(pos, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(pos, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(neg, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(neg, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(ctrlp, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(ctrlp, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
if (nexttok == NULL) goto baddevice;
|
||||
strncpy(ctrln, nexttok, 99); SpiceTokNoNewline();
|
||||
strncpy(ctrln, nexttok, MAX_STR_LEN-1); SpiceTokNoNewline();
|
||||
|
||||
/* make sure all the nodes exist */
|
||||
if (LookupObject(pos, CurrentCell) == NULL) Node(pos);
|
||||
@@ -1619,11 +1619,11 @@ skip_ends:
|
||||
}
|
||||
|
||||
else if (toupper(nexttok[0]) == 'X') { /* subcircuit instances */
|
||||
char instancename[100], subcktname[100];
|
||||
char instancename[MAX_STR_LEN], subcktname[MAX_STR_LEN];
|
||||
int itype, in_props;
|
||||
|
||||
instancename[99] = '\0';
|
||||
subcktname[99] = '\0';
|
||||
instancename[MAX_STR_LEN-1] = '\0';
|
||||
subcktname[MAX_STR_LEN-1] = '\0';
|
||||
|
||||
struct portelement {
|
||||
char *name;
|
||||
@@ -1633,8 +1633,8 @@ skip_ends:
|
||||
struct portelement *head, *tail, *scan, *scannext;
|
||||
struct objlist *obptr;
|
||||
|
||||
snprintf(instancename, 99, "%s", nexttok + 1);
|
||||
strncpy(instancename, nexttok + 1, 99);
|
||||
snprintf(instancename, MAX_STR_LEN-1, "%s", nexttok + 1);
|
||||
strncpy(instancename, nexttok + 1, MAX_STR_LEN-1);
|
||||
if (!(*CellStackPtr)) {
|
||||
CellDef(fname, filenum);
|
||||
PushStack(fname, CellStackPtr);
|
||||
@@ -1742,14 +1742,14 @@ skip_ends:
|
||||
/* names. */
|
||||
|
||||
if (strncmp(instancename, scan->name, strlen(scan->name))) {
|
||||
snprintf(subcktname, 99, "%s:%s", scan->name, instancename);
|
||||
snprintf(subcktname, MAX_STR_LEN-1, "%s:%s", scan->name, instancename);
|
||||
strcpy(instancename, subcktname);
|
||||
}
|
||||
else {
|
||||
snprintf(subcktname, 99, "/%s", instancename);
|
||||
snprintf(subcktname, MAX_STR_LEN-1, "/%s", instancename);
|
||||
strcpy(instancename, subcktname);
|
||||
}
|
||||
snprintf(subcktname, 99, "%s", scan->name);
|
||||
snprintf(subcktname, MAX_STR_LEN-1, "%s", scan->name);
|
||||
|
||||
if (scan == head) {
|
||||
head = NULL;
|
||||
@@ -1783,6 +1783,18 @@ skip_ends:
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
update = 1;
|
||||
}
|
||||
else if (tp->flags & CELL_VERILOG) {
|
||||
if (tp->flags & CELL_PLACEHOLDER) {
|
||||
/* Flag this as an error. To do: Rearrange the verilog instance pins to */
|
||||
/* match the SPICE subcircuit pin order. */
|
||||
Fprintf(stderr, "Error: SPICE subcircuit %s should be read before verilog "
|
||||
"module using it, or pins may not match!\n", subcktname);
|
||||
}
|
||||
else {
|
||||
Fprintf(stderr, "Error: SPICE subcircuit %s redefines a verilog module!\n",
|
||||
subcktname);
|
||||
}
|
||||
}
|
||||
|
||||
/* nexttok is now NULL, scan->name points to class */
|
||||
|
||||
@@ -1985,7 +1997,7 @@ void IncludeSpice(char *fname, int parent, struct cellstack **CellStackPtr,
|
||||
int blackbox)
|
||||
{
|
||||
int filenum = -1;
|
||||
char name[256];
|
||||
char name[MAX_STR_LEN];
|
||||
|
||||
/* If fname does not begin with "/", then assume that it is */
|
||||
/* in the same relative path as its parent. */
|
||||
|
||||
+116
-38
@@ -803,6 +803,56 @@ extern void IncludeVerilog(char *, int, struct cellstack **, int);
|
||||
extern void PushStack(char *cellname, struct cellstack **top);
|
||||
extern void PopStack(struct cellstack **top);
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* Callback routine for FindInstanceOf() */
|
||||
/* NOTE: This casts a (struct objlist) pointer to a */
|
||||
/* (struct nlist) pointer for the purpose of using */
|
||||
/* RecurseCellHashTable2(). FindInstanceOf() casts it */
|
||||
/* back into a (struct objlist) pointer. */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
struct nlist *findInstance(struct hashlist *p, void *clientdata)
|
||||
{
|
||||
struct nlist *ptr;
|
||||
struct objlist *ob;
|
||||
struct nlist *tref = (struct nlist *)clientdata;
|
||||
|
||||
ptr = (struct nlist *)(p->ptr);
|
||||
if (ptr->file != tref->file) return NULL;
|
||||
|
||||
ob = LookupInstance(tref->name, ptr);
|
||||
return (struct nlist *)ob;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* Routine to find the first instance of a cell */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
struct objlist *FindInstanceOf(struct nlist *tc)
|
||||
{
|
||||
return (struct objlist *)RecurseCellHashTable2(findInstance, (void *)tc);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* Given a reference cell pointer tref and a port name */
|
||||
/* portname, check if portname is a port of tref. If */
|
||||
/* not, then call Port() to add one. If tref is NULL, */
|
||||
/* then always add the port. */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
void CheckPort(struct objlist *tref, char *portname)
|
||||
{
|
||||
struct objlist *ob;
|
||||
|
||||
if (tref != NULL) {
|
||||
for (ob = CurrentCell->cell; ob && (ob->type == PORT); ob = ob->next) {
|
||||
if ((*matchfunc)(ob->name, portname))
|
||||
return;
|
||||
}
|
||||
}
|
||||
Port(portname);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* Read a verilog structural netlist */
|
||||
/*------------------------------------------------------*/
|
||||
@@ -816,13 +866,13 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
char devtype, in_module, in_param;
|
||||
char *eqptr, *matchptr;
|
||||
struct keyvalue *kvlist = NULL;
|
||||
char inst[256], model[256], instname[256], portname[256], pkey[256];
|
||||
char inst[MAX_STR_LEN], model[MAX_STR_LEN], instname[MAX_STR_LEN], portname[MAX_STR_LEN], pkey[MAX_STR_LEN];
|
||||
struct nlist *tp;
|
||||
struct objlist *parent, *sobj, *nobj, *lobj, *pobj;
|
||||
struct objlist *parent, *sobj, *nobj, *lobj, *pobj, *cref;
|
||||
|
||||
inst[255] = '\0';
|
||||
model[255] = '\0';
|
||||
instname[255] = '\0';
|
||||
inst[MAX_STR_LEN-1] = '\0';
|
||||
model[MAX_STR_LEN-1] = '\0';
|
||||
instname[MAX_STR_LEN-1] = '\0';
|
||||
in_module = (char)0;
|
||||
in_param = (char)0;
|
||||
|
||||
@@ -938,6 +988,7 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
InputParseError(stderr);
|
||||
}
|
||||
in_module = (char)1;
|
||||
cref = NULL;
|
||||
|
||||
/* Save pointer to current cell */
|
||||
if (CurrentCell != NULL)
|
||||
@@ -947,8 +998,9 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
|
||||
/* Check for existence of the cell. We may need to rename it. */
|
||||
|
||||
snprintf(model, 99, "%s", nexttok);
|
||||
snprintf(model, MAX_STR_LEN-1, "%s", nexttok);
|
||||
tp = LookupCellFile(nexttok, filenum);
|
||||
hasports = (char)0;
|
||||
|
||||
/* Check for name conflict with duplicate cell names */
|
||||
/* This may mean that the cell was used before it was */
|
||||
@@ -986,23 +1038,48 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
CellDef(nexttok, filenum);
|
||||
tp = LookupCellFile(nexttok, filenum);
|
||||
}
|
||||
else if (tp != NULL) { /* Make a new definition for an empty cell */
|
||||
FreePorts(nexttok);
|
||||
CellDelete(nexttok, filenum); /* This removes any PLACEHOLDER flag */
|
||||
else if (tp != NULL) { /* Cell exists, but as a placeholder */
|
||||
struct nlist *tptmp = NULL;
|
||||
char ctemp[8];
|
||||
int n = 0;
|
||||
|
||||
/* This redefines a placeholder module to an unused temporary cell name */
|
||||
while (1) {
|
||||
sprintf(ctemp, "%d", n);
|
||||
tptmp = LookupCellFile(ctemp, filenum);
|
||||
if (tptmp == NULL) break;
|
||||
n++;
|
||||
}
|
||||
CellRehash(nexttok, ctemp, filenum);
|
||||
tptmp = LookupCellFile(ctemp, filenum);
|
||||
|
||||
/* Create a new module definition */
|
||||
CellDef(model, filenum);
|
||||
tp = LookupCellFile(model, filenum);
|
||||
|
||||
/* Find an instance of this module in the netlist */
|
||||
cref = FindInstanceOf(tp);
|
||||
if ((cref != NULL) && (cref->name != NULL)) {
|
||||
hasports = (char)1;
|
||||
/* Copy ports from the original parent cell to the new parent cell */
|
||||
for (pobj = tptmp->cell; pobj && (pobj->type == PORT); pobj = pobj->next)
|
||||
Port(pobj->name);
|
||||
}
|
||||
/* Remove the original cell definition */
|
||||
FreePorts(ctemp);
|
||||
CellDelete(ctemp, filenum); /* This removes any PLACEHOLDER flag */
|
||||
}
|
||||
else if (tp == NULL) { /* Completely new cell, no name conflict */
|
||||
CellDef(model, filenum);
|
||||
tp = LookupCellFile(model, filenum);
|
||||
}
|
||||
|
||||
hasports = (char)0;
|
||||
inlined_decls = (char)0;
|
||||
|
||||
if (tp != NULL) {
|
||||
struct bus wb, *nb;
|
||||
|
||||
tp->flags |= CELL_VERILOG;
|
||||
PushStack(tp->name, CellStackPtr);
|
||||
|
||||
/* Need to support both types of I/O lists: Those */
|
||||
@@ -1071,7 +1148,7 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
if (GetBusTok(&wb) != 0) {
|
||||
// Didn't parse as a bus, so wing it
|
||||
wb.start = wb.end = -1;
|
||||
Port(nexttok);
|
||||
CheckPort(cref, nexttok);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1079,13 +1156,13 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
if (wb.start > wb.end) {
|
||||
for (i = wb.start; i >= wb.end; i--) {
|
||||
sprintf(portname, "%s[%d]", nexttok, i);
|
||||
Port(portname);
|
||||
CheckPort(cref, portname);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = wb.start; i <= wb.end; i++) {
|
||||
sprintf(portname, "%s[%d]", nexttok, i);
|
||||
Port(portname);
|
||||
CheckPort(cref, portname);
|
||||
}
|
||||
}
|
||||
/* Also register this port as a bus */
|
||||
@@ -1097,7 +1174,7 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
wb.start = wb.end = -1;
|
||||
}
|
||||
else {
|
||||
Port(nexttok);
|
||||
CheckPort(cref, nexttok);
|
||||
}
|
||||
}
|
||||
hasports = 1;
|
||||
@@ -1153,7 +1230,7 @@ skip_endmodule:
|
||||
if (GetBusTok(&wb) != 0) {
|
||||
// Didn't parse as a bus, so wing it
|
||||
wb.start = wb.end = -1;
|
||||
Port(nexttok);
|
||||
CheckPort(cref, nexttok);
|
||||
}
|
||||
}
|
||||
else if (!match(nexttok, ",")) {
|
||||
@@ -1161,13 +1238,13 @@ skip_endmodule:
|
||||
if (wb.start > wb.end) {
|
||||
for (i = wb.start; i >= wb.end; i--) {
|
||||
sprintf(portname, "%s[%d]", nexttok, i);
|
||||
Port(portname);
|
||||
CheckPort(cref, portname);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = wb.start; i <= wb.end; i++) {
|
||||
sprintf(portname, "%s[%d]", nexttok, i);
|
||||
Port(portname);
|
||||
CheckPort(cref, portname);
|
||||
}
|
||||
}
|
||||
/* Also register this port as a bus */
|
||||
@@ -1178,7 +1255,7 @@ skip_endmodule:
|
||||
wb.start = wb.end = -1;
|
||||
}
|
||||
else {
|
||||
Port(nexttok);
|
||||
CheckPort(cref, nexttok);
|
||||
}
|
||||
}
|
||||
hasports = 1;
|
||||
@@ -1194,6 +1271,7 @@ skip_endmodule:
|
||||
InputParseError(stderr);
|
||||
}
|
||||
in_module = (char)0;
|
||||
cref = NULL;
|
||||
|
||||
if (*CellStackPtr) PopStack(CellStackPtr);
|
||||
if (*CellStackPtr) ReopenCellDef((*CellStackPtr)->cellname, filenum);
|
||||
@@ -1340,7 +1418,7 @@ skip_endmodule:
|
||||
}
|
||||
else if (match(nexttok, "wire") || match(nexttok, "assign")) { /* wire = node */
|
||||
struct bus wb, wb2, *nb;
|
||||
char nodename[128], noderoot[100];
|
||||
char nodename[MAX_STR_LEN], noderoot[MAX_STR_LEN];
|
||||
int is_wire = match(nexttok, "wire");
|
||||
int j;
|
||||
struct objlist *lhs, *rhs;
|
||||
@@ -1438,7 +1516,7 @@ skip_endmodule:
|
||||
// "assign" using any boolean arithmetic is not structural verilog.
|
||||
|
||||
if (nexttok && match(nexttok, "=")) {
|
||||
char assignname[128], assignroot[100];
|
||||
char assignname[MAX_STR_LEN], assignroot[MAX_STR_LEN];
|
||||
|
||||
i = wb.start;
|
||||
while (1) {
|
||||
@@ -1552,12 +1630,12 @@ skip_endmodule:
|
||||
goto skip_endmodule;
|
||||
}
|
||||
else { /* module instances */
|
||||
char instancename[100], modulename[100];
|
||||
char instancename[MAX_STR_LEN], modulename[MAX_STR_LEN];
|
||||
int itype, arraystart, arrayend, arraymax, arraymin;
|
||||
char ignore;
|
||||
|
||||
instancename[99] = '\0';
|
||||
modulename[99] = '\0';
|
||||
instancename[MAX_STR_LEN-1] = '\0';
|
||||
modulename[MAX_STR_LEN-1] = '\0';
|
||||
|
||||
struct portelement {
|
||||
char *name; // Name of port in subcell
|
||||
@@ -1570,7 +1648,7 @@ skip_endmodule:
|
||||
struct portelement *head, *tail, *scan, *last, *scannext;
|
||||
struct objlist *obptr;
|
||||
|
||||
strncpy(modulename, nexttok, 99);
|
||||
strncpy(modulename, nexttok, MAX_STR_LEN-1);
|
||||
|
||||
/* If module name is a verilog primitive, then treat the module as a */
|
||||
/* black box (this is not a complete list. Preferable to use hash */
|
||||
@@ -1648,7 +1726,7 @@ nextinst:
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(instancename, nexttok, 99);
|
||||
strncpy(instancename, nexttok, MAX_STR_LEN-1);
|
||||
/* Printf("Diagnostic: new instance is %s\n", instancename); */
|
||||
SkipTokComments(VLOG_DELIMITERS);
|
||||
|
||||
@@ -1698,7 +1776,7 @@ nextinst:
|
||||
}
|
||||
SkipTokComments(VLOG_PIN_CHECK_DELIMITERS);
|
||||
if (match(nexttok, ")")) {
|
||||
char localnet[100];
|
||||
char localnet[MAX_STR_LEN];
|
||||
// Empty parens, so create a new local node
|
||||
savetok = (char)1;
|
||||
if (arraystart != -1) {
|
||||
@@ -1830,7 +1908,7 @@ nextinst:
|
||||
tp = LookupCellFile(modulename, filenum);
|
||||
if (tp == NULL) {
|
||||
struct bus wb, pb;
|
||||
char defport[128];
|
||||
char defport[MAX_STR_LEN];
|
||||
|
||||
Fprintf(stdout, "Creating placeholder cell definition for "
|
||||
"module %s.\n", modulename);
|
||||
@@ -1921,7 +1999,7 @@ nextinst:
|
||||
if (portstart != -1) {
|
||||
struct bus wb;
|
||||
struct portelement *new_port;
|
||||
char vname[256];
|
||||
char vname[MAX_STR_LEN];
|
||||
int j, result;
|
||||
struct objlist *bobj;
|
||||
char *bptr;
|
||||
@@ -2074,7 +2152,7 @@ nextinst:
|
||||
for (i = arraymin; i <= arraymax; i++) {
|
||||
char *brackptr;
|
||||
int j;
|
||||
char locinst[128];
|
||||
char locinst[MAX_STR_LEN];
|
||||
|
||||
if (i != -1)
|
||||
sprintf(locinst, "%s[%d]", instancename, i);
|
||||
@@ -2109,13 +2187,13 @@ nextinst:
|
||||
scan = scan->next;
|
||||
}
|
||||
if (scan == NULL) {
|
||||
char localnet[100];
|
||||
char localnet[MAX_STR_LEN];
|
||||
|
||||
/* Assume an implicit unconnected pin */
|
||||
sprintf(localnet, "_noconnect_%d_", localcount++);
|
||||
Node(localnet);
|
||||
join(localnet, obptr->name);
|
||||
Fprintf(stderr,
|
||||
Fprintf(stdout,
|
||||
"Note: Implicit pin %s in instance %s of %s in cell %s\n",
|
||||
obpinname, locinst, modulename, CurrentCell->name);
|
||||
}
|
||||
@@ -2129,7 +2207,7 @@ nextinst:
|
||||
if (arraystart == -1) {
|
||||
// Port may be an array
|
||||
int range;
|
||||
char pinname[128];
|
||||
char pinname[MAX_STR_LEN];
|
||||
|
||||
// Check if port is an array
|
||||
if (obpinidx == -1) {
|
||||
@@ -2154,7 +2232,7 @@ nextinst:
|
||||
}
|
||||
else {
|
||||
// Instance must be an array
|
||||
char netname[128];
|
||||
char netname[MAX_STR_LEN];
|
||||
int slice, portlen, siglen;
|
||||
|
||||
/* Get the array size of the port for bit slicing */
|
||||
@@ -2204,11 +2282,11 @@ nextinst:
|
||||
for (scan = head; scan; scan = scan->next) {
|
||||
if (!(scan->flags & PORT_FOUND)) {
|
||||
if (tp->flags & CELL_PLACEHOLDER) {
|
||||
char tempname[128];
|
||||
char tempname[MAX_STR_LEN];
|
||||
int maxnode;
|
||||
|
||||
/* This pin was probably implicit in the first call */
|
||||
/* and so it needs to be added to the definition. */
|
||||
/* This pin was probably implicit in the first call */
|
||||
/* and so it needs to be added to the definition. */
|
||||
|
||||
ReopenCellDef(modulename, filenum);
|
||||
Port(scan->name);
|
||||
@@ -2265,7 +2343,7 @@ nextinst:
|
||||
sprintf(tempname, "_noconnect_%d_", localcount++);
|
||||
Node(tempname);
|
||||
join(tempname, nobj->name);
|
||||
Fprintf(stderr, "Note: Implicit pin %s in instance "
|
||||
Fprintf(stdout, "Note: Implicit pin %s in instance "
|
||||
"%s of %s in cell %s\n",
|
||||
scan->name, sobj->instance.name,
|
||||
modulename, CurrentCell->name);
|
||||
@@ -2432,7 +2510,7 @@ void IncludeVerilog(char *fname, int parent, struct cellstack **CellStackPtr,
|
||||
int blackbox)
|
||||
{
|
||||
int filenum = -1;
|
||||
char name[256];
|
||||
char name[MAX_STR_LEN];
|
||||
|
||||
/* If fname does not begin with "/", then assume that it is */
|
||||
/* in the same relative path as its parent. */
|
||||
|
||||
+5
-5
@@ -65,10 +65,10 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
Widget toplevel = NULL;
|
||||
|
||||
char GlobalFileName[100],
|
||||
GlobalCellName[100],
|
||||
GlobalOtherName[100],
|
||||
GlobalDataName[100];
|
||||
char GlobalFileName[MAX_STR_LEN],
|
||||
GlobalCellName[MAX_STR_LEN],
|
||||
GlobalOtherName[MAX_STR_LEN],
|
||||
GlobalDataName[MAX_STR_LEN];
|
||||
|
||||
/*********************************************************
|
||||
* Menu structure: attaches label string to a function,
|
||||
@@ -1708,7 +1708,7 @@ void X_main_loop(int argc, char *argv[])
|
||||
|
||||
XmStringCharSet cs = "ISOLatin1";
|
||||
|
||||
static char prompt_response[100];
|
||||
static char prompt_response[MAX_STR_LEN];
|
||||
int prompt_done;
|
||||
int calling_editor; /* which string are we trying to get ? */
|
||||
#define FILE_NAME 1
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ void STRCPY(char *dest, char *source)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char cell1[200], cell2[200];
|
||||
char cell1[MAX_STR_LEN], cell2[MAX_STR_LEN];
|
||||
|
||||
Debug = 0;
|
||||
if (argc != 1) {
|
||||
|
||||
+2
-2
@@ -51,7 +51,7 @@ void STRCPY(char *dest, char *source)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifndef HAVE_GETOPT
|
||||
char cell1[200], cell2[200];
|
||||
char cell1[MAX_STR_LEN], cell2[MAX_STR_LEN];
|
||||
int filenum = -1;
|
||||
|
||||
Debug = 0;
|
||||
@@ -67,7 +67,7 @@ int main(int argc, char *argv[])
|
||||
STRCPY(cell2, ReadNetlist(argv[2], &filenum));
|
||||
if (argc == 5) STRCPY(cell2, argv[4]); /* if explicit cell name specified */
|
||||
#else
|
||||
char cell1[200], cell2[200];
|
||||
char cell1[MAX_STR_LEN], cell2[MAX_STR_LEN];
|
||||
int usage = 0;
|
||||
int args;
|
||||
int c;
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ void STRCPY(char *dest, char *source)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char cellname[200];
|
||||
char cellname[MAX_STR_LEN];
|
||||
int filenum = -1;
|
||||
|
||||
Debug = 0;
|
||||
|
||||
+2
-2
@@ -62,7 +62,7 @@ proc netgen::convert_to_json {filename lvs_final} {
|
||||
puts $fjson " \["
|
||||
set cktval [lindex $value 0]
|
||||
foreach pin [lrange $cktval 0 end-1] {
|
||||
set pinstr [string map {"\\" "\\\\"} $pin]
|
||||
set pinstr [string map {"\\" "\\\\"} $pin]
|
||||
puts $fjson " \"$pinstr\","
|
||||
}
|
||||
set pin [string map {"\\" "\\\\"} [lindex $cktval end]]
|
||||
@@ -70,7 +70,7 @@ proc netgen::convert_to_json {filename lvs_final} {
|
||||
puts $fjson " \], \["
|
||||
set cktval [lindex $value 1]
|
||||
foreach pin [lrange $cktval 0 end-1] {
|
||||
set pinstr [string map {"\\" "\\\\"} $pin]
|
||||
set pinstr [string map {"\\" "\\\\"} $pin]
|
||||
puts $fjson " \"$pinstr\","
|
||||
}
|
||||
set pin [string map {"\\" "\\\\"} [lindex $cktval end]]
|
||||
|
||||
+33
-7
@@ -2228,7 +2228,13 @@ _netcmp_compare(ClientData clientData,
|
||||
Fprintf(stdout, "\nCircuit 1 cell %s is a black box; will not flatten "
|
||||
"Circuit 2\n", name1);
|
||||
}
|
||||
else if (hascontents1 || hascontents2) {
|
||||
else if (!hascontents1 && !hascontents2 && (tp1->flags & CELL_PLACEHOLDER)
|
||||
&& (tp2->flags & CELL_PLACEHOLDER)) {
|
||||
/* Two empty subcircuits, don't flatten anything */
|
||||
Fprintf(stdout, "\nCircuit 1 cell %s and Circuit 2 cell %s are black"
|
||||
" boxes.\n", name1, name2);
|
||||
}
|
||||
else {
|
||||
FlattenUnmatched(tp1, name1, 1, 0);
|
||||
FlattenUnmatched(tp2, name2, 1, 0);
|
||||
DescribeContents(name1, fnum1, name2, fnum2);
|
||||
@@ -2241,10 +2247,6 @@ _netcmp_compare(ClientData clientData,
|
||||
DescribeContents(name1, fnum1, name2, fnum2);
|
||||
}
|
||||
}
|
||||
else { /* Two empty subcircuits */
|
||||
Fprintf(stdout, "\nCircuit 1 cell %s and Circuit 2 cell %s are black"
|
||||
" boxes.\n", name1, name2);
|
||||
}
|
||||
CreateTwoLists(name1, fnum1, name2, fnum2, dolist);
|
||||
|
||||
// Return the names of the two cells being compared, if doing "compare
|
||||
@@ -3375,6 +3377,7 @@ _netcmp_equate(ClientData clientData,
|
||||
/* add --- add new property */
|
||||
/* remove --- delete existing property */
|
||||
/* tolerance --- set property tolerance */
|
||||
/* associate --- associate property with a pin */
|
||||
/* merge --- (deprecated) */
|
||||
/* or */
|
||||
/* netgen::property default */
|
||||
@@ -3413,11 +3416,11 @@ _netcmp_property(ClientData clientData,
|
||||
|
||||
char *options[] = {
|
||||
"add", "create", "remove", "delete", "tolerance", "merge", "serial",
|
||||
"series", "parallel", NULL
|
||||
"series", "parallel", "associate", NULL
|
||||
};
|
||||
enum OptionIdx {
|
||||
ADD_IDX, CREATE_IDX, REMOVE_IDX, DELETE_IDX, TOLERANCE_IDX, MERGE_IDX,
|
||||
SERIAL_IDX, SERIES_IDX, PARALLEL_IDX
|
||||
SERIAL_IDX, SERIES_IDX, PARALLEL_IDX, ASSOCIATE_IDX
|
||||
};
|
||||
int result, index, idx2;
|
||||
|
||||
@@ -3840,6 +3843,29 @@ _netcmp_property(ClientData clientData,
|
||||
}
|
||||
break;
|
||||
|
||||
case ASSOCIATE_IDX:
|
||||
if (objc == 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "{property_key pin_name} ...");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for (i = 3; i < objc; i++) {
|
||||
// Each value must be a duplet
|
||||
result = Tcl_ListObjLength(interp, objv[i], &llen);
|
||||
if ((result != TCL_OK) || (llen != 2)) {
|
||||
Tcl_SetResult(interp, "Not a {key pin} pair list.",
|
||||
NULL);
|
||||
}
|
||||
else {
|
||||
result = Tcl_ListObjIndex(interp, objv[i], 0, &tobj1);
|
||||
if (result != TCL_OK) return result;
|
||||
result = Tcl_ListObjIndex(interp, objv[i], 1, &tobj2);
|
||||
if (result != TCL_OK) return result;
|
||||
PropertyAssociatePin(tp->name, fnum, Tcl_GetString(tobj1),
|
||||
Tcl_GetString(tobj2));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TOLERANCE_IDX:
|
||||
if (objc == 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "{property_key tolerance} ...");
|
||||
|
||||
Reference in New Issue
Block a user