mirror of
https://github.com/RTimothyEdwards/netgen.git
synced 2026-08-23 06:27:07 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afe0e9f758 | ||
|
|
68ec2b2a7c | ||
|
|
ca49a90ed6 | ||
|
|
e487890641 | ||
|
|
e07a5b416a | ||
|
|
bb44d3f827 | ||
|
|
8094740048 | ||
|
|
c25c4e1160 | ||
|
|
a026d37f11 | ||
|
|
8ed4e3cf38 | ||
|
|
ab614b63f7 | ||
|
|
83dce151d8 | ||
|
|
69838d79e4 | ||
|
|
de18ae85a4 | ||
|
|
fc7c9371e8 | ||
|
|
9908349fdd | ||
|
|
964bb0e91a | ||
|
|
0d19868145 | ||
|
|
cfdc60104b | ||
|
|
879711def3 | ||
|
|
5def9e0ffc | ||
|
|
b5c70decbd | ||
|
|
6b4eb01ee8 | ||
|
|
20f6d76926 | ||
|
|
737b2a73bf | ||
|
|
e4a15f12fb | ||
|
|
c6fb204f0c | ||
|
|
6b8c6d1718 | ||
|
|
c7dfff4bb9 | ||
|
|
12fa080212 | ||
|
|
610eebb758 | ||
|
|
4c4bad08f2 | ||
|
|
23ff2f00a3 | ||
|
|
d09f0dd53b | ||
|
|
56d4d581e7 | ||
|
|
1bb4866226 | ||
|
|
97058c5017 | ||
|
|
625e043eff | ||
|
|
aa120460d0 | ||
|
|
6ceeddf096 | ||
|
|
42b1acc564 | ||
|
|
6d6da9cf5c |
@@ -7,6 +7,7 @@ config.log
|
||||
scripts/config.log
|
||||
config.status
|
||||
scripts/config.status
|
||||
python/lvs_manager.py
|
||||
*.o
|
||||
*.so
|
||||
*~
|
||||
|
||||
+4
-3
@@ -23,12 +23,13 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* for strtod() */
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "netgen.h"
|
||||
#include "hash.h"
|
||||
#include "objlist.h"
|
||||
#include "netfile.h"
|
||||
#include "print.h"
|
||||
#include "hash.h"
|
||||
|
||||
void extCell(char *name, int filenum)
|
||||
{
|
||||
@@ -186,7 +187,7 @@ char *ReadExt(char *fname, int doflat, int *fnum)
|
||||
/* Make sure all .ext file reading is case sensitive */
|
||||
matchfunc = match;
|
||||
matchintfunc = matchfile;
|
||||
hashfunc = hash;
|
||||
hashfunc = hashcase;
|
||||
|
||||
if (LookupCellFile(fname, filenum) != NULL) {
|
||||
Printf("Error: Duplicate cell name \"%s\"!\n", fname);
|
||||
@@ -652,7 +653,7 @@ char *ReadSim(char *fname, int *fnum)
|
||||
/* Make sure all .sim file reading is case sensitive */
|
||||
matchfunc = match;
|
||||
matchintfunc = matchfile;
|
||||
hashfunc = hash;
|
||||
hashfunc = hashcase;
|
||||
|
||||
CellDef(fname, filenum);
|
||||
|
||||
|
||||
+55
-43
@@ -372,22 +372,16 @@ int flattenInstancesOf(char *name, int fnum, char *instance)
|
||||
|
||||
/* update node numbers in child to unique numbers */
|
||||
oldmax = 0;
|
||||
for (tmp = ChildStart; tmp != NULL; tmp = tmp->next)
|
||||
for (tmp = ChildStart; tmp != NULL; tmp = tmp->next) {
|
||||
if (tmp->node > oldmax) oldmax = tmp->node;
|
||||
if (nextnode <= oldmax) nextnode = oldmax + 1;
|
||||
|
||||
for (tmp = ChildStart; tmp != NULL; tmp = tmp->next)
|
||||
if (tmp->node <= oldmax && tmp->node > 0) {
|
||||
if (Debug) Printf("Update node %d --> %d\n", tmp->node, nextnode);
|
||||
UpdateNodeNumbers(ChildStart, tmp->node, nextnode);
|
||||
nextnode++;
|
||||
}
|
||||
if (tmp->node > 0) tmp->node += (nextnode - 1);
|
||||
}
|
||||
nextnode += oldmax;
|
||||
|
||||
/* copy nodenumbers of ports from parent */
|
||||
ob2 = ParentParams;
|
||||
for (tmp = ChildStart; tmp != NULL; tmp = tmp->next) {
|
||||
if (IsPort(tmp)) {
|
||||
if (tmp->node > 0) {
|
||||
for (tmp = ChildStart; tmp && IsPort(tmp); tmp = tmp->next) {
|
||||
if (tmp->node > 0) {
|
||||
if (ob2->node == -1) {
|
||||
|
||||
// Before commiting to attaching to a unconnected node, see
|
||||
@@ -413,17 +407,16 @@ int flattenInstancesOf(char *name, int fnum, char *instance)
|
||||
Printf("Update node %d --> %d\n", tmp->node, ob2->node);
|
||||
}
|
||||
UpdateNodeNumbers(ChildStart, tmp->node, ob2->node);
|
||||
}
|
||||
}
|
||||
|
||||
/* in pathological cases, the lengths of the port lists may
|
||||
* change. This is an error, but that is no reason to allow
|
||||
* the code to core dump. We avoid this by placing a
|
||||
* superfluous check on ob2->type
|
||||
*/
|
||||
if (ob2 != NULL) ob2 = ob2->next;
|
||||
/* in pathological cases, the lengths of the port lists may
|
||||
* change. This is an error, but that is no reason to allow
|
||||
* the code to core dump. We avoid this by placing a
|
||||
* superfluous check on ob2->type
|
||||
*/
|
||||
if (ob2 != NULL) ob2 = ob2->next;
|
||||
|
||||
if (ob2 == NULL) break;
|
||||
}
|
||||
if (ob2 == NULL) break;
|
||||
}
|
||||
|
||||
/* Using name == NULL to indicate that a .ext file is being */
|
||||
@@ -1421,6 +1414,22 @@ typedef struct ecomplist {
|
||||
ECompListPtr next;
|
||||
} ECompList;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Determine if a cell contains at least one device or subcircuit */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
int
|
||||
HasContents(struct nlist *tc)
|
||||
{
|
||||
struct objlist *ob;
|
||||
|
||||
for (ob = tc->cell; ob; ob = ob->next)
|
||||
if (ob->type == FIRSTPIN)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* Survey the contents of a cell and sort into a hash */
|
||||
/*------------------------------------------------------*/
|
||||
@@ -1518,6 +1527,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
struct hashdict compdict;
|
||||
ECompare *ecomp, *ncomp;
|
||||
ECompList *list0X, *listX0;
|
||||
int hascontents1, hascontents2;
|
||||
int match, modified = 0;
|
||||
|
||||
if (file1 == -1)
|
||||
@@ -1533,6 +1543,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
if (tc1 == NULL || tc2 == NULL) return 0;
|
||||
|
||||
InitializeHashTable(&compdict, OBJHASHSIZE);
|
||||
listX0 = list0X = NULL;
|
||||
|
||||
// Gather information about instances of cell "name1"
|
||||
SurveyCell(tc1, &compdict, file1, file2, 0);
|
||||
@@ -1545,7 +1556,6 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
// in the hierarchy of each instance contain devices
|
||||
// or subcircuits that have more in the compared circuit.
|
||||
|
||||
listX0 = list0X = NULL;
|
||||
ecomp = (ECompare *)HashFirst(&compdict);
|
||||
while (ecomp != NULL) {
|
||||
|
||||
@@ -1582,22 +1592,23 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
}
|
||||
}
|
||||
else {
|
||||
match = 0;
|
||||
// cell exists in one circuit but not the other, so flatten it.
|
||||
// match = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
if (ecomp->cell1 && (ecomp->num1 > 0)) {
|
||||
Fprintf(stdout, "Flattening instances of %s in cell %s"
|
||||
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)"
|
||||
" makes a better match\n", ecomp->cell1->name,
|
||||
name1);
|
||||
name1, file1);
|
||||
flattenInstancesOf(name1, file1, ecomp->cell1->name);
|
||||
}
|
||||
if (ecomp->cell2 && (ecomp->num2 > 0)) {
|
||||
Fprintf(stdout, "Flattening instances of %s in cell %s"
|
||||
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)"
|
||||
" makes a better match\n", ecomp->cell2->name,
|
||||
name2);
|
||||
name2, file2);
|
||||
flattenInstancesOf(name2, file2, ecomp->cell2->name);
|
||||
}
|
||||
modified++;
|
||||
@@ -1649,7 +1660,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
}
|
||||
|
||||
/* Case 2: Cell2 class is a subcircuit, and flattening */
|
||||
/* (it without regard to cell1) improves the matching. */
|
||||
/* it (without regard to cell1) improves the matching. */
|
||||
|
||||
else if ((ecomp->num1 != ecomp->num2) && (ecomp->cell2 != NULL) &&
|
||||
(ecomp->num2 != 0) && (ecomp->cell2->class == CLASS_SUBCKT)) {
|
||||
@@ -1678,9 +1689,9 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
}
|
||||
if (match) {
|
||||
if (ecomp->cell2) {
|
||||
Fprintf(stdout, "Flattening instances of %s in cell %s"
|
||||
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)"
|
||||
" makes a better match\n", ecomp->cell2->name,
|
||||
name2);
|
||||
name2, file2);
|
||||
flattenInstancesOf(name2, file2, ecomp->cell2->name);
|
||||
}
|
||||
modified++;
|
||||
@@ -1707,7 +1718,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
}
|
||||
|
||||
/* Case 3: Cell1 class is a subcircuit, and flattening */
|
||||
/* (it without regard to cell1) improves the matching. */
|
||||
/* it (without regard to cell1) improves the matching. */
|
||||
|
||||
else if ((ecomp->num1 != ecomp->num2) && (ecomp->cell1 != NULL) &&
|
||||
(ecomp->num1 != 0) && (ecomp->cell1->class == CLASS_SUBCKT)) {
|
||||
@@ -1736,9 +1747,9 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
}
|
||||
if (match) {
|
||||
if (ecomp->cell1) {
|
||||
Fprintf(stdout, "Flattening instances of %s in cell %s"
|
||||
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)"
|
||||
" makes a better match\n", ecomp->cell1->name,
|
||||
name1);
|
||||
name1, file1);
|
||||
flattenInstancesOf(name1, file1, ecomp->cell1->name);
|
||||
}
|
||||
modified++;
|
||||
@@ -1819,9 +1830,9 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
}
|
||||
if (found) {
|
||||
Fprintf(stdout, "Removing zero-valued device "
|
||||
"%s from cell %s makes a better match\n",
|
||||
tsub1->name,
|
||||
tc1->name);
|
||||
"%s from cell %s (%d) makes a better "
|
||||
"match\n",
|
||||
tsub1->name, tc1->name, tc1->file);
|
||||
|
||||
/* A current source is an open, while a */
|
||||
/* resistor or voltage source is a short. */
|
||||
@@ -1930,9 +1941,9 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
}
|
||||
if (found) {
|
||||
Fprintf(stdout, "Removing zero-valued device "
|
||||
"%s from cell %s makes a better match\n",
|
||||
tsub2->name,
|
||||
tc2->name);
|
||||
"%s from cell %s (%d) makes a better "
|
||||
"match\n",
|
||||
tsub2->name, tc2->name, tc2->file);
|
||||
|
||||
/* merge node of endpoints */
|
||||
if (ecomp->cell2->class != CLASS_ISOURCE) {
|
||||
@@ -2023,8 +2034,8 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
if (dstr) *dstr = '[';
|
||||
if ((ncomp == ecomp0X) && (ecomp0X->num2 <= ecompX0->num1)) {
|
||||
Fprintf(stdout, "Flattening instances of %s in cell %s"
|
||||
" makes a better match\n", ecompX0->cell1->name,
|
||||
name1);
|
||||
"(%d) makes a better match\n",
|
||||
ecompX0->cell1->name, name1, file1);
|
||||
flattenInstancesOf(name1, file1, ecompX0->cell1->name);
|
||||
ecompX0->num1 = 0;
|
||||
ecomp0X->num1 += ecompX0->num1;
|
||||
@@ -2049,8 +2060,8 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
if (dstr) *dstr = '[';
|
||||
if ((ncomp == ecompX0) && (ecompX0->num1 <= ecomp0X->num2)) {
|
||||
Fprintf(stdout, "Flattening instances of %s in cell %s"
|
||||
" makes a better match\n", ecomp0X->cell2->name,
|
||||
name2);
|
||||
" (%d) makes a better match\n",
|
||||
ecomp0X->cell2->name, name2, file2);
|
||||
flattenInstancesOf(name2, file2, ecomp0X->cell2->name);
|
||||
ecomp0X->num2 = 0;
|
||||
ecompX0->num2 += ecomp0X->num2;
|
||||
@@ -2064,6 +2075,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
// Free the hash table and its contents.
|
||||
|
||||
ecomp = (ECompare *)HashFirst(&compdict);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef _FLATTEN_H
|
||||
#define _FLATTEN_H
|
||||
|
||||
extern int UniquePins(char *name, int filenum);
|
||||
extern void flattenCell(char *name, int file);
|
||||
extern int HasContents(struct nlist *);
|
||||
|
||||
#endif /* _FLATTEN_H */
|
||||
+2
-2
@@ -30,8 +30,8 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#endif
|
||||
|
||||
#include "netgen.h"
|
||||
#include "hash.h"
|
||||
#include "objlist.h"
|
||||
#include "hash.h"
|
||||
|
||||
unsigned long (*hashfunc)(char *, int) = NULL;
|
||||
int (*matchfunc)(char *, char *) = NULL;
|
||||
@@ -148,7 +148,7 @@ unsigned long hashnocase(char *s, int hashsize)
|
||||
return (hashsize == 0) ? hashval : (hashval % hashsize);
|
||||
}
|
||||
|
||||
unsigned long hash(char *s, int hashsize)
|
||||
unsigned long hashcase(char *s, int hashsize)
|
||||
{
|
||||
unsigned long hashval;
|
||||
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ extern void *HashFirst(struct hashdict *dict);
|
||||
extern void *HashNext(struct hashdict *dict);
|
||||
|
||||
extern unsigned long hashnocase(char *s, int hashsize);
|
||||
extern unsigned long hash(char *s, int hashsize);
|
||||
extern unsigned long hashcase(char *s, int hashsize);
|
||||
|
||||
extern int (*matchfunc)(char *, char *);
|
||||
/* matchintfunc() compares based on the name and the first */
|
||||
|
||||
+67
-22
@@ -21,11 +21,13 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* for rand(), abs(), etc */
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <time.h> /* for time() as a seed for random number generator */
|
||||
#include <limits.h>
|
||||
#include <math.h> /* for fabs() */
|
||||
#include <ctype.h> /* for toupper() */
|
||||
|
||||
#ifdef IBMPC
|
||||
#include <alloc.h>
|
||||
@@ -45,11 +47,13 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "netfile.h"
|
||||
#include "print.h"
|
||||
#include "dbug.h"
|
||||
#include "hash.h"
|
||||
|
||||
#ifdef TCL_NETGEN
|
||||
int InterruptPending = 0;
|
||||
void (*oldinthandler)() = SIG_DFL;
|
||||
extern Tcl_Interp *netgeninterp;
|
||||
extern int check_interrupt();
|
||||
#endif
|
||||
|
||||
/* define the following to debug core allocation */
|
||||
@@ -889,9 +893,8 @@ struct FormattedList *FormatBadNodeFragment(struct Node *N)
|
||||
WITH THE SAME HASH NUMBER, are on this node */
|
||||
for (j = i+1; j < fanout; j++) {
|
||||
if (pins[j] != NULL &&
|
||||
(*matchfunc) (model,
|
||||
pins[j]->subelement->element->object->model.class) &&
|
||||
pins[i]->subelement->pin_magic == pins[j]->subelement->pin_magic) {
|
||||
(*matchfunc)(model, pins[j]->subelement->element->object->model.class) &&
|
||||
pins[i]->subelement->pin_magic == pins[j]->subelement->pin_magic) {
|
||||
count++;
|
||||
nodelist->fanout--;
|
||||
pins[j] = NULL;
|
||||
@@ -971,16 +974,36 @@ void PrintBadNodeFragment(struct Node *N)
|
||||
WITH THE SAME HASH NUMBER, are on this node */
|
||||
for (j = i+1; j < fanout; j++) {
|
||||
if (pins[j] != NULL &&
|
||||
(*matchfunc)(model,
|
||||
pins[j]->subelement->element->object->model.class) &&
|
||||
pins[i]->subelement->pin_magic == pins[j]->subelement->pin_magic) {
|
||||
count++;
|
||||
pins[j] = NULL;
|
||||
}
|
||||
(*matchfunc)(model, pins[j]->subelement->element->object->model.class) &&
|
||||
pins[i]->subelement->pin_magic == pins[j]->subelement->pin_magic) {
|
||||
count++;
|
||||
/* pins[j] = NULL; */ /* Done in diagnostic output, below */
|
||||
}
|
||||
}
|
||||
|
||||
if (i != 0) Fprintf(stdout, ";");
|
||||
if (i != 0) {
|
||||
/* Fprintf(stdout, ";"); */
|
||||
Fprintf(stdout, "\n");
|
||||
Ftab(stdout, 32);
|
||||
}
|
||||
Fprintf(stdout, " %s:%s = %d", model, pinname, count);
|
||||
|
||||
/* Diagnostic */
|
||||
Fprintf(stdout, "\n");
|
||||
Ftab(stdout, 25);
|
||||
Fprintf(stdout, ">>> %s", pins[i]->subelement->element->object->instance);
|
||||
for (j = i+1; j < fanout; j++) {
|
||||
if (pins[j] != NULL &&
|
||||
(*matchfunc)(model, pins[j]->subelement->element->object->model.class) &&
|
||||
pins[i]->subelement->pin_magic == pins[j]->subelement->pin_magic) {
|
||||
/* Diagnostic */
|
||||
Fprintf(stdout, "\n");
|
||||
Ftab(stdout, 25);
|
||||
Fprintf(stdout, ">>> %s", pins[j]->subelement->element->object->instance);
|
||||
pins[j] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pins[i] = NULL; /* not really necessary */
|
||||
}
|
||||
Fprintf(stdout, "\n");
|
||||
@@ -1363,8 +1386,8 @@ void SortUnmatchedLists(nlists1, nlists2, n1max, n2max)
|
||||
nlists2[n1] = temp;
|
||||
HashPtrInstall(nlists2[n1]->name, (void *)((long)n1 + 1), &n2hash);
|
||||
HashPtrInstall(nlists2[n2]->name, (void *)((long)n2 + 1), &n2hash);
|
||||
SortFanoutLists(nlists1[n1], nlists2[n1]);
|
||||
}
|
||||
SortFanoutLists(nlists1[n1], nlists2[n1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1419,8 +1442,13 @@ void SortUnmatchedLists(nlists1, nlists2, n1max, n2max)
|
||||
nlists1[n2] = temp;
|
||||
HashPtrInstall(nlists1[n1]->name, (void *)((long)n1 + 1), &n1hash);
|
||||
HashPtrInstall(nlists1[n2]->name, (void *)((long)n2 + 1), &n1hash);
|
||||
SortFanoutLists(nlists2[n2], nlists1[n2]);
|
||||
}
|
||||
SortFanoutLists(nlists2[n2], nlists1[n2]);
|
||||
}
|
||||
else if ((n1max == 1) && (n2max == 1)) {
|
||||
/* Names didn't match but there's only one entry on each side, */
|
||||
/* so do a sort anyway. */
|
||||
SortFanoutLists(nlists2[n2], nlists1[n2]);
|
||||
}
|
||||
}
|
||||
/* For all nets that didn't match by name, match by content */
|
||||
@@ -3125,7 +3153,7 @@ int FirstElementPass(struct Element *E, int noflat, int dolist)
|
||||
ostr = CALLOC(right_col_end + 2, sizeof(char));
|
||||
|
||||
if (Debug == 0) {
|
||||
Fprintf(stdout, "\nSubcircuit summary:\n");
|
||||
Fprintf(stdout, "Subcircuit summary:\n");
|
||||
*(ostr + left_col_end) = '|';
|
||||
*(ostr + right_col_end) = '\n';
|
||||
*(ostr + right_col_end + 1) = '\0';
|
||||
@@ -3639,12 +3667,19 @@ int CreateCompareQueue(char *name1, int file1, char *name2, int file2)
|
||||
Fprintf(stdout, "Descend level %d circuit 2\n", level);
|
||||
DescendCompareQueue(tc2, tc1, level, 0, 1);
|
||||
|
||||
/* NOTE: Preemptive flattening is inefficient and can cause
|
||||
* unnecessary flattening of cells that will never be compared.
|
||||
* let the prematch stage take care of this.
|
||||
*/
|
||||
/*--------------------------------------
|
||||
if (Debug == TRUE)
|
||||
Fprintf(stdout, "Flatten level %d circuit 1\n", level);
|
||||
FlattenUnmatched(tc1, name1, level, 0);
|
||||
if (Debug == TRUE)
|
||||
Fprintf(stdout, "Flatten level %d circuit 2\n", level);
|
||||
FlattenUnmatched(tc2, name2, level, 0);
|
||||
---------------------------------------*/
|
||||
|
||||
level--;
|
||||
}
|
||||
|
||||
@@ -3723,8 +3758,23 @@ void RemoveCompareQueue()
|
||||
CompareQueue = NULL;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Output a summary of the contents of the two circuits being compared */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
void DescribeContents(char *name1, int file1, char *name2, int file2)
|
||||
{
|
||||
Fprintf(stdout, "\n"); // blank line before new circuit diagnostics in log file
|
||||
/* print preliminary statistics */
|
||||
Printf("\nContents of circuit 1: ");
|
||||
DescribeInstance(name1, file1);
|
||||
Printf("Contents of circuit 2: ");
|
||||
DescribeInstance(name2, file2);
|
||||
Printf("\n");
|
||||
}
|
||||
|
||||
/*----------------------------------*/
|
||||
/* create an initial data structure */
|
||||
/* Create an initial data structure */
|
||||
/*----------------------------------*/
|
||||
|
||||
void CreateTwoLists(char *name1, int file1, char *name2, int file2, int dolist)
|
||||
@@ -3736,13 +3786,6 @@ void CreateTwoLists(char *name1, int file1, char *name2, int file2, int dolist)
|
||||
|
||||
ResetState();
|
||||
|
||||
/* print preliminary statistics */
|
||||
Printf("Contents of circuit 1: ");
|
||||
DescribeInstance(name1, file1);
|
||||
Printf("Contents of circuit 2: ");
|
||||
DescribeInstance(name2, file2);
|
||||
Printf("\n");
|
||||
|
||||
if (file1 == -1)
|
||||
tc1 = LookupCell(name1);
|
||||
else
|
||||
@@ -3756,7 +3799,7 @@ void CreateTwoLists(char *name1, int file1, char *name2, int file2, int dolist)
|
||||
/* determine if matching will be case sensitive or case insensitive */
|
||||
matchfunc = match;
|
||||
matchintfunc = matchfile;
|
||||
hashfunc = hash;
|
||||
hashfunc = hashcase;
|
||||
if (tc1 != NULL && tc2 != NULL) {
|
||||
if ((tc1->flags & CELL_NOCASE) && (tc2->flags & CELL_NOCASE)) {
|
||||
matchfunc = matchnocase;
|
||||
@@ -7902,6 +7945,7 @@ int Compare(char *cell1, char *cell2)
|
||||
{
|
||||
int automorphisms;
|
||||
|
||||
DescribeContents(cell1, -1, cell2, -1);
|
||||
CreateTwoLists(cell1, -1, cell2, -1, 0);
|
||||
Permute();
|
||||
while (!Iterate());
|
||||
@@ -7962,6 +8006,7 @@ void NETCOMP(void)
|
||||
case 'c':
|
||||
promptstring("Enter cell 1: ",name);
|
||||
promptstring("Enter cell 2: ",name2);
|
||||
DescribeContents(name, -1, name2, -1);
|
||||
CreateTwoLists(name, -1, name2, -1, 0);
|
||||
#ifdef DEBUG_ALLOC
|
||||
PrintCoreStats();
|
||||
|
||||
@@ -26,6 +26,7 @@ extern void PrintCoreStats(void);
|
||||
extern void ResetState(void);
|
||||
extern void CreateTwoLists(char *name1, int file1, char *name2, int file2,
|
||||
int dolist);
|
||||
extern void DescribeContents(char *name1, int file1, char *name2, int file2);
|
||||
extern int Iterate(void);
|
||||
extern int VerifyMatching(void);
|
||||
extern void PrintAutomorphisms(void);
|
||||
@@ -46,6 +47,7 @@ extern int CreateCompareQueue(char *, int, char *, int);
|
||||
extern int GetCompareQueueTop(char **, int *, char **, int *);
|
||||
extern int PeekCompareQueueTop(char **, int *, char **, int *);
|
||||
extern void RemoveCompareQueue();
|
||||
extern int FlattenUnmatched(struct nlist *, char *, int, int);
|
||||
|
||||
extern void PrintIllegalClasses();
|
||||
extern void PrintIllegalNodeClasses();
|
||||
@@ -54,6 +56,15 @@ extern void PrintIllegalElementClasses();
|
||||
extern void DumpNetwork(struct objlist *ob, int cidx);
|
||||
extern void DumpNetworkAll(char *name, int file);
|
||||
|
||||
extern void RegroupDataStructures();
|
||||
extern void FormatIllegalElementClasses();
|
||||
extern void FormatIllegalNodeClasses();
|
||||
extern int ResolveAutomorphsByProperty();
|
||||
extern int ResolveAutomorphsByPin();
|
||||
extern void SummarizeElementClasses(struct ElementClass *EC);
|
||||
extern int remove_group_tags(struct objlist *ob);
|
||||
|
||||
|
||||
#ifdef TCL_NETGEN
|
||||
extern int EquivalentNode();
|
||||
extern int EquivalentElement();
|
||||
|
||||
+6
-1
@@ -3441,7 +3441,8 @@ int CombineParallel(char *model, int file)
|
||||
}
|
||||
HashKill(&devdict);
|
||||
if (dcnt > 0) {
|
||||
Fprintf(stdout, "Class %s: Merged %d devices.\n", model, dcnt);
|
||||
Fprintf(stdout, "Class %s (%d): Merged %d parallel devices.\n",
|
||||
model, file, dcnt);
|
||||
}
|
||||
FREE(nodecount);
|
||||
return dcnt;
|
||||
@@ -3738,6 +3739,10 @@ int CombineSeries(char *model, int file)
|
||||
}
|
||||
}
|
||||
FREE(instlist);
|
||||
if (scnt > 0) {
|
||||
Fprintf(stdout, "Class %s (%d): Merged %d series devices.\n",
|
||||
model, file, scnt);
|
||||
}
|
||||
return scnt;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -22,6 +22,7 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#ifdef IBMPC
|
||||
#include <alloc.h>
|
||||
#endif
|
||||
@@ -31,13 +32,13 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#endif
|
||||
|
||||
#include "netgen.h"
|
||||
#include "hash.h"
|
||||
#include "objlist.h"
|
||||
#include "regexp.h"
|
||||
#include "dbug.h"
|
||||
#include "print.h"
|
||||
#include "netfile.h"
|
||||
#include "netcmp.h"
|
||||
#include "hash.h"
|
||||
|
||||
#ifdef TCL_NETGEN
|
||||
extern Tcl_Interp *netgeninterp;
|
||||
@@ -288,7 +289,7 @@ static struct hashdict cell_dict;
|
||||
|
||||
void InitCellHashTable(void)
|
||||
{
|
||||
hashfunc = hash;
|
||||
hashfunc = hashcase;
|
||||
matchfunc = NULL;
|
||||
matchintfunc = matchfile;
|
||||
InitializeHashTable(&cell_dict, CELLHASHSIZE);
|
||||
|
||||
@@ -312,6 +312,19 @@ extern void GarbageCollect(void);
|
||||
extern void InitGarbageCollection(void);
|
||||
extern void AddToGarbageList(struct objlist *head);
|
||||
|
||||
extern void DeleteProperties(struct keyvalue **topptr);
|
||||
extern void AddProperty(struct keyvalue **topptr, char *key, char *value);
|
||||
extern void AddScaledProperty(struct keyvalue **topptr, char *key, char *value, double scale);
|
||||
extern void DeleteProperties(struct keyvalue **topptr);
|
||||
extern struct objlist *LinkProperties(char *model, struct keyvalue *topptr);
|
||||
|
||||
extern void ClassDelete(char *class, int file);
|
||||
extern void RemoveShorted(char *class, int file);
|
||||
extern void CellRehash(char *name, char *newname, int file);
|
||||
|
||||
/* defined in netgen.c */
|
||||
extern int ConvertStringToInteger(char *string, int *ival);
|
||||
|
||||
#ifdef HAVE_MALLINFO
|
||||
void PrintMemoryStats(void);
|
||||
#endif
|
||||
|
||||
+8
-5
@@ -805,11 +805,14 @@ void DescribeInstance(char *name, int file)
|
||||
/* All black-box modules and placeholders by definition have all */
|
||||
/* disconnected pins, so don't report those. */
|
||||
|
||||
if (!(tp->flags & CELL_PLACEHOLDER) && (tp->class != CLASS_MODULE))
|
||||
{
|
||||
if (disconnectednodes == 0) Fprintf(stderr, "\n");
|
||||
if ((!(tp->flags & CELL_PLACEHOLDER)) && (tp->class != CLASS_MODULE)) {
|
||||
// if (disconnectednodes == 0) Fprintf(stderr, "\n");
|
||||
disconnectednodes++;
|
||||
Fprintf(stderr, "Cell %s disconnected node: %s\n", tp->name, ob->name);
|
||||
/* Don't report on ports marked "port_match_error", which is just confusing. */
|
||||
if (strcmp(ob->name, "port_match_error")) {
|
||||
Fprintf(stderr, "Cell %s (%d) disconnected node: %s\n",
|
||||
tp->name, tp->file, ob->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1033,7 +1036,7 @@ void Query(void)
|
||||
break;
|
||||
case 'v':
|
||||
promptstring("Write Verilog: circuit name: ", repstr);
|
||||
VerilogModule(repstr, filenum, "");
|
||||
VerilogTop(repstr, filenum, "");
|
||||
break;
|
||||
case 'E':
|
||||
promptstring("Write ESACAP: circuit name: ", repstr);
|
||||
|
||||
+11
-8
@@ -26,6 +26,7 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> /* for calloc(), free(), getenv() */
|
||||
#include <ctype.h> /* for toupper(), isascii() */
|
||||
#ifndef IBMPC
|
||||
#include <sys/types.h> /* for getpwnam() tilde expansion */
|
||||
#include <pwd.h>
|
||||
@@ -40,6 +41,8 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "objlist.h"
|
||||
#include "netfile.h"
|
||||
#include "print.h"
|
||||
#include "query.h"
|
||||
#include "objlist.h"
|
||||
|
||||
// Global storage for parameters from .PARAM
|
||||
struct hashdict spiceparams;
|
||||
@@ -937,7 +940,7 @@ skip_ends:
|
||||
goto baddevice;
|
||||
}
|
||||
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
Cell(instname, model, collector, base, emitter);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
@@ -1010,7 +1013,7 @@ skip_ends:
|
||||
goto baddevice;
|
||||
}
|
||||
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
Cell(instname, model, drain, gate, source, bulk);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
@@ -1101,7 +1104,7 @@ skip_ends:
|
||||
usemodel = 1;
|
||||
}
|
||||
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
if (usemodel)
|
||||
Cell(instname, model, ctop, cbot);
|
||||
else
|
||||
@@ -1194,7 +1197,7 @@ skip_ends:
|
||||
else
|
||||
strcpy(model, "r"); /* Use default resistor model */
|
||||
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
if (usemodel)
|
||||
Cell(instname, model, rtop, rbot);
|
||||
else
|
||||
@@ -1252,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, 255, "%s:%s", model, inst);
|
||||
Cell(instname, model, anode, cathode);
|
||||
pobj = LinkProperties(model, kvlist);
|
||||
ReduceExpressions(pobj, NULL, CurrentCell, TRUE);
|
||||
@@ -1331,7 +1334,7 @@ skip_ends:
|
||||
else
|
||||
strcpy(model, "t"); /* Use default xline model */
|
||||
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
|
||||
if (usemodel)
|
||||
Cell(instname, model, node1, node2, node3, node4);
|
||||
@@ -1414,7 +1417,7 @@ skip_ends:
|
||||
else
|
||||
strcpy(model, "l"); /* Use default inductor model */
|
||||
|
||||
snprintf(instname, 255, "%s%s", model, inst);
|
||||
snprintf(instname, 255, "%s:%s", model, inst);
|
||||
if (usemodel)
|
||||
Cell(instname, model, end_a, end_b);
|
||||
else
|
||||
@@ -1726,7 +1729,7 @@ skip_ends:
|
||||
/* names. */
|
||||
|
||||
if (strncmp(instancename, scan->name, strlen(scan->name))) {
|
||||
snprintf(subcktname, 99, "%s%s", scan->name, instancename);
|
||||
snprintf(subcktname, 99, "%s:%s", scan->name, instancename);
|
||||
strcpy(instancename, subcktname);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef _TECH_H
|
||||
#define _TECH_H
|
||||
|
||||
extern int ActelLibPresent(void);
|
||||
extern void ActelLib(void);
|
||||
extern void VerilogTop(char *name, int fnum, char *filename);
|
||||
|
||||
#endif /* _TECH_H */
|
||||
+22
-52
@@ -52,10 +52,10 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#endif
|
||||
|
||||
#include "netgen.h"
|
||||
#include "hash.h"
|
||||
#include "objlist.h"
|
||||
#include "netfile.h"
|
||||
#include "print.h"
|
||||
#include "hash.h"
|
||||
|
||||
// See netfile.c for explanation of delimiters. 'X'
|
||||
// separates single-character delimiters from two-character delimiters.
|
||||
@@ -1778,54 +1778,6 @@ nextinst:
|
||||
scan->width = width;
|
||||
|
||||
result = GetBus(scan->net, &wb);
|
||||
if (result == -1) {
|
||||
/* CHECK: THIS CODE SHOULD BE DELETED, IT IS NOT THE ISSUE */
|
||||
/* Not bus notation, but check if signal was defined as a bus */
|
||||
wb.start = wb.end = -1;
|
||||
minnet = maxnet = -1;
|
||||
|
||||
/* Pins should be in index order start->end. Other nodes */
|
||||
/* should be in order start->end by node number. */
|
||||
|
||||
for (bobj = CurrentCell->cell; bobj; bobj = bobj->next) {
|
||||
if (bobj->type == PORT) {
|
||||
if ((bptr = strvchr(bobj->name, '[')) != NULL) {
|
||||
*bptr = '\0';
|
||||
if (!strcmp(bobj->name, scan->net)) {
|
||||
*bptr = '[';
|
||||
if (wb.start == -1)
|
||||
sscanf(bptr + 1, "%d", &wb.start);
|
||||
else
|
||||
sscanf(bptr + 1, "%d", &wb.end);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bobj->type == NODE) {
|
||||
if ((bptr = strvchr(bobj->name, '[')) != NULL) {
|
||||
*bptr = '\0';
|
||||
if (!strcmp(bobj->name, scan->net)) {
|
||||
if (sscanf(bptr + 1, "%d", &testidx) == 1) {
|
||||
if (minnet == -1) {
|
||||
minnet = maxnet = bobj->node;
|
||||
wb.start = wb.end = testidx;
|
||||
}
|
||||
else if (bobj->node < minnet) {
|
||||
minnet = bobj->node;
|
||||
wb.start = testidx;
|
||||
}
|
||||
else if (bobj->node > maxnet) {
|
||||
maxnet = bobj->node;
|
||||
wb.end = testidx;
|
||||
}
|
||||
}
|
||||
}
|
||||
*bptr = '[';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wb.start != -1) result = 0;
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
int match = 0;
|
||||
int wblen, arraylen;
|
||||
@@ -1935,7 +1887,25 @@ nextinst:
|
||||
}
|
||||
}
|
||||
else if (portstart != portend) {
|
||||
Fprintf(stderr, "Error: Single net %s is connected to bus port %s\n",
|
||||
/* If the name starts with "_noconnect_", then it was an
|
||||
* auto-generated name that incorrectly assumed a single-bit
|
||||
* wide signal because it did not have a module prototype.
|
||||
* Rewrite the noconnect name as an array. This just means
|
||||
* that the verilog had an empty list "()" and the initial
|
||||
* assumption was wrong. If not all instances agree on the
|
||||
* size, then this will eventually generate an error.
|
||||
*/
|
||||
if (!strncmp(scan->net, "_noconnect_", 11) &&
|
||||
(strchr(scan->net, '\[') == NULL) && (width > 1)) {
|
||||
char *savenet = scan->net;
|
||||
char *newnet = MALLOC(strlen(scan->net) + 12);
|
||||
sprintf(newnet, "%s[%d:0]", scan->net, scan->width - 1);
|
||||
FREE(savenet);
|
||||
scan->net = newnet;
|
||||
continue; /* Re-process this entry */
|
||||
}
|
||||
else
|
||||
Fprintf(stderr, "Error: Single net %s is connected to bus port %s\n",
|
||||
scan->net, scan->name);
|
||||
}
|
||||
}
|
||||
@@ -2117,7 +2087,7 @@ nextinst:
|
||||
sobj = sobj->next) {
|
||||
if (sobj->type == FIRSTPIN) {
|
||||
if (match(sobj->model.class, obptr->model.class)) {
|
||||
while (sobj->next->type > FIRSTPIN)
|
||||
while (sobj->next && (sobj->next->type > FIRSTPIN))
|
||||
sobj = sobj->next;
|
||||
/* Stop when reaching the current instance */
|
||||
if (sobj->type == obptr->type + 1) break;
|
||||
@@ -2239,7 +2209,7 @@ char *ReadVerilogTop(char *fname, int *fnum, int blackbox)
|
||||
else {
|
||||
matchfunc = match;
|
||||
matchintfunc = matchfile;
|
||||
hashfunc = hash;
|
||||
hashfunc = hashcase;
|
||||
}
|
||||
|
||||
InitializeHashTable(&verilogparams, OBJHASHSIZE);
|
||||
|
||||
+7
-9
@@ -23,6 +23,7 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef IBMPC
|
||||
#include <stdlib.h> /* for strtol on PC */
|
||||
@@ -33,6 +34,8 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "netfile.h"
|
||||
#include "hash.h"
|
||||
#include "print.h"
|
||||
#include "xilinx.h"
|
||||
#include "flatten.h"
|
||||
|
||||
#define XILINXHASHSIZE 99
|
||||
static long xilinxhashbase = 0xA00;
|
||||
@@ -132,10 +135,8 @@ char *xilinx_class(model)
|
||||
}
|
||||
return(model);
|
||||
}
|
||||
void
|
||||
Xilinx(cellname, filename)
|
||||
char *cellname;
|
||||
char *filename;
|
||||
|
||||
void Xilinx(char *cellname, char *filename)
|
||||
{
|
||||
char Path[500];
|
||||
char FileName[500];
|
||||
@@ -163,8 +164,7 @@ Xilinx(cellname, filename)
|
||||
CloseFile(FileName);
|
||||
}
|
||||
|
||||
xilinxCell(cell)
|
||||
char *cell;
|
||||
int xilinxCell(char *cell)
|
||||
{
|
||||
struct nlist *nl;
|
||||
struct objlist *ob;
|
||||
@@ -252,9 +252,7 @@ struct objlist *xilinx_gate(ob,nl)
|
||||
return(nob);
|
||||
}
|
||||
|
||||
xilinx_sym(nl,gob)
|
||||
struct nlist *nl;
|
||||
struct objlist *gob;
|
||||
void xilinx_sym(struct nlist *nl, struct objlist *gob)
|
||||
{
|
||||
struct objlist *ob;
|
||||
char *cp,*rindex();
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef _XILINX_H
|
||||
#define _XILINX_H
|
||||
|
||||
extern void xilinx_sym(struct nlist *nl, struct objlist *gob);
|
||||
extern void Xilinx(char *cellname, char *filename);
|
||||
extern int xilinxCell(char *cell);
|
||||
extern int XilinxLibPresent(void);
|
||||
extern void XilinxLib(void);
|
||||
|
||||
#endif /* _XILINX_H */
|
||||
+7
-7
@@ -567,7 +567,8 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
|
||||
netgen::flatten class "[lindex $endval 1] $fnum2"
|
||||
} else {
|
||||
netgen::log put " Continuing with black-boxed subcircuits $endval\n"
|
||||
lappend matcherr [lindex $endval 0]
|
||||
lappend matcherr [lindex $endval 0]"($fnum1)"
|
||||
lappend matcherr [lindex $endval 1]"($fnum2)"
|
||||
# Match pins
|
||||
netgen::log echo off
|
||||
if {$dolist == 1} {
|
||||
@@ -609,16 +610,15 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
|
||||
} else {
|
||||
# Flatten the non-matching subcircuit (but not the top-level cells)
|
||||
if {[netgen::print queue] != {}} {
|
||||
if {([lsearch $noflat [lindex $endval 1]] == -1) &&
|
||||
if {([lsearch $noflat [lindex $endval 0]] == -1) &&
|
||||
([lsearch $noflat [lindex $endval 1]] == -1)} {
|
||||
netgen::log put " Flattening non-matched subcircuits $endval\n"
|
||||
netgen::flatten class "[lindex $endval 0] $fnum1"
|
||||
netgen::flatten class "[lindex $endval 1] $fnum2"
|
||||
} else {
|
||||
netgen::log put " Continuing with black-boxed subcircuits $endval\n"
|
||||
lappend matcherr [lindex $endval 0]
|
||||
netgen::log put " Continuing with black-boxed subcircuits $endval\n"
|
||||
lappend matcherr [lindex $endval 0]
|
||||
lappend matcherr [lindex $endval 0]"($fnum1)"
|
||||
lappend matcherr [lindex $endval 0]"($fnum2)"
|
||||
# Match pins
|
||||
netgen::log echo off
|
||||
if {$dolist == 1} {
|
||||
@@ -656,10 +656,10 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
|
||||
verify only
|
||||
}
|
||||
if {$properr != {}} {
|
||||
netgen::log put "The following cells had property errors: $properr\n"
|
||||
netgen::log put "The following cells had property errors:\n " [regsub -all { } $properr "\n "] "\n"
|
||||
}
|
||||
if {$matcherr != {}} {
|
||||
netgen::log put "The following subcells failed to match: $matcherr\n"
|
||||
netgen::log put "The following subcells failed to match:\n " [regsub -all { } $matcherr "\n "] "\n"
|
||||
}
|
||||
if {$dolog} {
|
||||
netgen::log end
|
||||
|
||||
+40
-12
@@ -32,6 +32,9 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "print.h"
|
||||
#include "query.h" /* for ElementNodes() */
|
||||
#include "hash.h"
|
||||
#include "xilinx.h"
|
||||
#include "tech.h"
|
||||
#include "flatten.h"
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
@@ -976,7 +979,7 @@ _netgen_writenet(ClientData clientData,
|
||||
SpiceCell(repstr, filenum, "");
|
||||
break;
|
||||
case VERILOG_IDX:
|
||||
VerilogModule(repstr, filenum, "");
|
||||
VerilogTop(repstr, filenum, "");
|
||||
break;
|
||||
case WOMBAT_IDX:
|
||||
Wombat(repstr,NULL);
|
||||
@@ -2066,6 +2069,7 @@ _netcmp_format(ClientData clientData,
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "[col1_width [col2_width]]");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
@@ -2091,8 +2095,9 @@ _netcmp_compare(ClientData clientData,
|
||||
int dohierarchy = FALSE;
|
||||
int assignonly = FALSE;
|
||||
int argstart = 1, qresult, llen, result;
|
||||
int hascontents1, hascontents2;
|
||||
struct Correspond *nextcomp;
|
||||
struct nlist *tp;
|
||||
struct nlist *tp1 = NULL, *tp2 = NULL;
|
||||
Tcl_Obj *flist = NULL;
|
||||
|
||||
if (objc > 1) {
|
||||
@@ -2135,24 +2140,24 @@ _netcmp_compare(ClientData clientData,
|
||||
}
|
||||
else if ((objc - argstart) == 2) {
|
||||
|
||||
result = CommonParseCell(interp, objv[argstart], &tp, &fnum1);
|
||||
result = CommonParseCell(interp, objv[argstart], &tp1, &fnum1);
|
||||
if (result != TCL_OK) return TCL_ERROR;
|
||||
else if (fnum1 == -1) {
|
||||
Tcl_SetResult(interp, "Cannot use wildcard with compare command.\n",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
name1 = tp->name;
|
||||
name1 = tp1->name;
|
||||
argstart++;
|
||||
|
||||
result = CommonParseCell(interp, objv[argstart], &tp, &fnum2);
|
||||
result = CommonParseCell(interp, objv[argstart], &tp2, &fnum2);
|
||||
if (result != TCL_OK) return TCL_ERROR;
|
||||
else if (fnum2 == -1) {
|
||||
Tcl_SetResult(interp, "Cannot use wildcard with compare command.\n",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
name2 = tp->name;
|
||||
name2 = tp2->name;
|
||||
|
||||
if (dohierarchy) {
|
||||
RemoveCompareQueue();
|
||||
@@ -2191,11 +2196,34 @@ _netcmp_compare(ClientData clientData,
|
||||
ConvertGlobals(name2, fnum2);
|
||||
}
|
||||
|
||||
CreateTwoLists(name1, fnum1, name2, fnum2, dolist);
|
||||
while (PrematchLists(name1, fnum1, name2, fnum2) > 0) {
|
||||
Fprintf(stdout, "Making another compare attempt.\n");
|
||||
CreateTwoLists(name1, fnum1, name2, fnum2, dolist);
|
||||
tp1 = LookupCellFile(name1, fnum1);
|
||||
tp2 = LookupCellFile(name2, fnum2);
|
||||
|
||||
hascontents1 = HasContents(tp1);
|
||||
hascontents2 = HasContents(tp2);
|
||||
|
||||
if (hascontents1 && !hascontents2 && (tp2->flags & CELL_PLACEHOLDER)) {
|
||||
Fprintf(stdout, "Circuit 2 cell %s is a black box; will not flatten "
|
||||
"Circuit 1\n", name2);
|
||||
}
|
||||
else if (hascontents2 && !hascontents1 && (tp1->flags & CELL_PLACEHOLDER)) {
|
||||
Fprintf(stdout, "Circuit 1 cell %s is a black box; will not flatten "
|
||||
"Circuit 2\n", name1);
|
||||
}
|
||||
else if (hascontents1 || hascontents2) {
|
||||
FlattenUnmatched(tp1, name1, 1, 0);
|
||||
FlattenUnmatched(tp2, name2, 1, 0);
|
||||
DescribeContents(name1, fnum1, name2, fnum2);
|
||||
|
||||
while (PrematchLists(name1, fnum1, name2, fnum2) > 0) {
|
||||
Fprintf(stdout, "Making another compare attempt.\n");
|
||||
Printf("Flattened mismatched instances and attempting compare again.\n");
|
||||
FlattenUnmatched(tp1, name1, 1, 0);
|
||||
FlattenUnmatched(tp2, name2, 1, 0);
|
||||
DescribeContents(name1, fnum1, name2, fnum2);
|
||||
}
|
||||
}
|
||||
CreateTwoLists(name1, fnum1, name2, fnum2, dolist);
|
||||
|
||||
// Return the names of the two cells being compared, if doing "compare
|
||||
// hierarchical". If "-list" was specified, then append the output
|
||||
@@ -3027,11 +3055,11 @@ _netcmp_equate(ClientData clientData,
|
||||
(tp2->flags & CELL_PLACEHOLDER)) {
|
||||
if (tp1->flags & CELL_PLACEHOLDER) {
|
||||
Fprintf(stdout, "Warning: Equate pins: cell %s "
|
||||
"has no definition, treated as a black box.\n", name1);
|
||||
"is a placeholder, treated as a black box.\n", name1);
|
||||
}
|
||||
if (tp2->flags & CELL_PLACEHOLDER) {
|
||||
Fprintf(stdout, "Warning: Equate pins: cell %s "
|
||||
"has no definition, treated as a black box.\n", name2);
|
||||
"is a placeholder, treated as a black box.\n", name2);
|
||||
}
|
||||
// If a cell in either circuit is marked as a black box, then
|
||||
// the cells in both circuits should be marked as a black box.
|
||||
|
||||
Reference in New Issue
Block a user