/* sf.c -- Flatten hierarchical LOGSPC (version 1.0) output. Written by Harold Levy (har@caltech.edu) Version Date Description ^^^^^^^ ^^^^ ^^^^^^^^^^^ 0.1 beta 11/06/93 First version handles MOSFET's only. 0.2 beta 02/22/94 Fixed internal-node prefixes and added version-number print-out. */ #define VERSION "0.2" #include #include "hash.h" #include "spice.h" void Flatten (); void ShowInstance (); main (argc, argv) int argc; char *argv[]; { FILE *inputfile; char STR1[256], STR2[256], STR3[256], STR4[256], STR5[256]; char *line, *word, *label; struct Bucket *CellTable[HASH_TABLE_SIZE]; struct Bucket *NodeTable[HASH_TABLE_SIZE]; struct Bucket *RemainderTable[HASH_TABLE_SIZE]; struct Bucket *CounterTable[HASH_TABLE_SIZE]; struct Symbol *cell, *node, *instance, *remainder, *port, *subordinate; struct Symbol *counter; int i, nPorts; /* initialize hash tables for cells & nodes */ InitHashTable (CellTable); InitHashTable (NodeTable); InitHashTable (RemainderTable); InitHashTable (CounterTable); cell = GetSymbol (CellTable, "M"); /* MOSFET */ cell->namePtr = &cell->name; cell->label = NULL; cell->ports = NULL; cell->remainder = NULL; cell->instances = NULL; for (i = 1; i <= 4; i ++) AddBucket (&cell->ports); /* open input file */ if (argc == 2) { strcpy (STR1, argv[1]); inputfile = fopen (STR1, "r"); if (!inputfile) { fprintf (stderr, "Cannot find \"%s\"\n", STR1); exit (2); } } else { fprintf (stderr, "usage (v%s): sf \n", VERSION); exit (1); } /* read subcircuits */ while (fgets (STR1, 256, inputfile)) { strcpy (STR2, STR1); line = STR1; word = STR2; GetSpiceWord (line, word, inputfile); if (strcmp (word, ".SUBCKT")) continue; GetSpiceWord (line, word, inputfile); /* subckt name */ strcpy (STR3, "_"); strcat (STR3, word); cell = GetSymbol (CellTable, STR3); cell->namePtr = &cell->name; cell->label = NULL; cell->ports = NULL; cell->instances = NULL; do { GetSpiceWord (line, word, inputfile); /* subckt ports */ if (*word) { node = GetSymbol (NodeTable, word); AddBucket (&cell->ports); cell->ports->symbol->name = node->name; cell->ports->symbol->namePtr = &cell->ports->symbol->name; } } while (*word); while (strncmp (fgets (STR1, 256, inputfile), ".ENDS", 5)) { strcpy (STR2, STR1); line = STR1; word = STR2; GetSpiceWord (line, word, inputfile); /* device name */ if (word[1]) label = &word[1]; else label = NULL; counter = GetSymbol (CounterTable, label); switch (*word) { case 'M': instance = GetSymbol (CellTable, "M"); AddBucket (&cell->instances); cell->instances->symbol->name = instance->name; cell->instances->symbol->namePtr = &cell->instances->symbol->name; cell->instances->symbol->label = counter->name; for (i = 1; i <= 4; i ++) { GetSpiceWord (line, word, inputfile); /* MOSFET pins */ if (*word) { AddBucket (&cell->instances->symbol->ports); if (port = InBucket (&cell->ports, word)) cell->instances->symbol->ports->symbol->namePtr = &port->name; else { node = GetSymbol (NodeTable, word); cell->instances->symbol->ports->symbol->name = node->name; cell->instances->symbol->ports->symbol->namePtr = &cell->instances->symbol->ports->symbol->name; } } } if (*line) { remainder = GetSymbol (RemainderTable, line); cell->instances->symbol->remainder = remainder->name; } break; case 'X': nPorts = GetLastSpiceWord (line, STR3, inputfile) - 1; strcpy (STR4, "_"); strcat (STR4, STR3); instance = GetSymbol (CellTable, STR4); AddBucket (&cell->instances); cell->instances->symbol->name = instance->name; cell->instances->symbol->namePtr = &cell->instances->symbol->name; cell->instances->symbol->label = counter->name; for (i = 1; i <= nPorts; i ++) { GetSpiceWord (line, word, inputfile); /* SUBCKT pins */ if (*word) { AddBucket (&cell->instances->symbol->ports); if (port = InBucket (&cell->ports, word)) cell->instances->symbol->ports->symbol->namePtr = &port->name; else { node = GetSymbol (NodeTable, word); cell->instances->symbol->ports->symbol->name = node->name; cell->instances->symbol->ports->symbol->namePtr = &cell->instances->symbol->ports->symbol->name; } } } break; } } } /* read root cell */ rewind (inputfile); while (fgets (STR1, 256, inputfile)) { strcpy (STR2, STR1); line = STR1; word = STR2; GetSpiceWord (line, word, inputfile); if (*word == '*') continue; /* comment */ if (*word == 0) continue; /* blank line */ if (!strncmp (word, ".SUBCKT", 7)) /* skip subcircuit definitions now */ { while (strncmp (fgets (STR1, 256, inputfile), ".ENDS", 5)) ; continue; } if (word[1]) label = &word[1]; else label = NULL; counter = GetSymbol (CounterTable, label); switch (*word) { case 'M': instance = GetSymbol (CellTable, "M"); FirstBucket (&instance->ports); for (i = 1; i <= 4; i ++) { GetSpiceWord (line, word, inputfile); if (*word) { node = GetSymbol (NodeTable, word); instance->ports->symbol->name = node->name; if (instance->ports->next) instance->ports = instance->ports->next; } } remainder = GetSymbol (RemainderTable, line); instance->remainder = remainder->name; Flatten (CellTable, instance, counter->name); break; case 'X': nPorts = GetLastSpiceWord (line, STR3, inputfile) - 1; strcpy (STR4, "_"); strcat (STR4, STR3); instance = GetSymbol (CellTable, STR4); FirstBucket (&instance->ports); for (i = 1; i <= nPorts; i ++) { GetSpiceWord (line, word, inputfile); if (*word) { node = GetSymbol (NodeTable, word); instance->ports->symbol->name = node->name; if (instance->ports->next) instance->ports = instance->ports->next; } } FirstBucket (&instance->instances); sprintf (STR5, "%s#%s", STR4, counter->name); Flatten (CellTable, NodeTable, instance->instances->symbol, STR5); while (instance->instances->next) { instance->instances = instance->instances->next; sprintf (STR5, "%s#%s", STR4, counter->name); Flatten (CellTable, NodeTable, instance->instances->symbol, STR5); } break; } } /* close input file */ fclose (inputfile); } void Flatten (celltable, nodetable, instance, prefix) struct Bucket *celltable[HASH_TABLE_SIZE]; struct Bucket *nodetable[HASH_TABLE_SIZE]; struct Symbol *instance; char *prefix; { static int m_counter = 0; int i; struct Symbol *subordinate, *node; struct Bucket *ipBP, *spBP; char STR1[256], STR2[256]; switch (*(instance->name)) { case 'M': m_counter ++; printf ("M%s/%s", prefix, instance->label); FirstBucket (&instance->ports); for (i = 1; i <= 4; i ++) { if (*instance->ports->symbol->namePtr == instance->ports->symbol->name) printf (" %s/%s", prefix, *instance->ports->symbol->namePtr); else printf (" %s", *instance->ports->symbol->namePtr); if (instance->ports->next) instance->ports = instance->ports->next; } printf (" %s", instance->remainder); break; case '_': subordinate = GetSymbol (celltable, instance->name); sprintf (STR1, "%s/%s#%s", prefix, subordinate->name, instance->label); FirstBucket (&instance->ports); ipBP = instance->ports; FirstBucket (&subordinate->ports); spBP = subordinate->ports; if (*ipBP->symbol->namePtr == ipBP->symbol->name) { sprintf (STR2, "%s/%s", prefix, *ipBP->symbol->namePtr); node = GetSymbol (nodetable, STR2); spBP->symbol->name = node->name; } else spBP->symbol->name = *ipBP->symbol->namePtr; while (ipBP->next) { ipBP = ipBP->next; spBP = spBP->next; if (*ipBP->symbol->namePtr == ipBP->symbol->name) { sprintf (STR2, "%s/%s", prefix, *ipBP->symbol->namePtr); node = GetSymbol (nodetable, STR2); spBP->symbol->name = node->name; } else spBP->symbol->name = *ipBP->symbol->namePtr; } FirstBucket (&subordinate->instances); Flatten (celltable, nodetable, subordinate->instances->symbol, STR1); while (subordinate->instances->next) { subordinate->instances = subordinate->instances->next; Flatten (celltable, nodetable, subordinate->instances->symbol, STR1); } break; } } void ShowInstance (instance) struct Symbol *instance; { printf ("name = %s:\n\n", instance->name); FirstBucket (&instance->instances); printf ("%s\n", instance->instances->symbol->name); FirstBucket (&instance->instances->symbol->ports); printf ("%s\n", *instance->instances->symbol->ports->symbol->namePtr); while (instance->instances->symbol->ports->next) { instance->instances->symbol->ports = instance->instances->symbol->ports->next; printf ("%s\n", *instance->instances->symbol->ports->symbol->namePtr); } printf ("%s\n", instance->instances->symbol->remainder); while (instance->instances->next) { instance->instances = instance->instances->next; printf ("%s\n", instance->instances->symbol->name); FirstBucket (&instance->instances->symbol->ports); printf ("%s\n", *instance->instances->symbol->ports->symbol->namePtr); while (instance->instances->symbol->ports->next) { instance->instances->symbol->ports = instance->instances->symbol->ports->next; printf ("%s\n", *instance->instances->symbol->ports->symbol->namePtr); } printf ("%s\n", instance->instances->symbol->remainder); } }