Compare commits

..
82 Commits
Author SHA1 Message Date
Tim Edwards 763117aabe Merge branch 'master' into work 2018-01-29 13:26:41 -05:00
Tim Edwards 96a95d337f Update at Mon Jan 29 13:26:39 EST 2018 by tim 2018-01-29 13:26:39 -05:00
Tim Edwards 393788a039 Changed behavior of the "lvs" script so that the setup file can
be specified as "nosetup" if the "lvs" command is being called
interactively from a terminal or as part of a larger script where
setup commands have been issued prior to running the "lvs" script.
Similarly, the log file can be specified as "nolog" to prevent any
log file from being generated.
2018-01-29 13:24:54 -05:00
Tim Edwards c630c2e397 Merge branch 'master' into work 2018-01-26 11:58:07 -05:00
Tim Edwards 1e8685128c Update at Fri Jan 26 11:58:05 EST 2018 by tim 2018-01-26 11:58:05 -05:00
Tim Edwards 440f61d540 Corrected a number of function returns, mainly to avoid compile-
time warnings and errors.  Removed the "-lazy" option from the
Tcl load command, which is not needed when the stubs libraries
are compiled in correctly, and which causes issues on some
systems (e.g., Mac OS).  Thanks to Matt Guthaus for the patch.
2018-01-26 11:56:41 -05:00
Tim Edwards cc532b2cb7 Merge branch 'master' into work 2017-12-14 21:50:33 -05:00
Tim Edwards 2a4c7b3cde Update at Thu Dec 14 21:50:32 EST 2017 by tim 2017-12-14 21:50:32 -05:00
Tim Edwards 87e44b0d8c Corrected an issue in which netgen would attempt to find a file
from a ".include" line by trying alternate extensions.  This
should be discouraged, as it happened that a file included
"name.defparams", a file that didn't exist, and instead of calling
out the missing file, it recast it to "name.spice" and caused it
to drop into an infinite loop.  Oops.
2017-12-14 21:48:01 -05:00
Tim Edwards e1322dbaf6 Merge branch 'master' into work 2017-12-07 08:46:43 -05:00
Tim Edwards 661157e041 Update at Thu Dec 7 08:46:40 EST 2017 by tim 2017-12-07 08:46:40 -05:00
Tim Edwards 77e5d70626 Corrected Tcl list output (and, by consequence, the JSON file
output) to include pin information (missing "-list" argument to
the "equate pins" command).
2017-12-07 08:45:37 -05:00
Tim Edwards 4098b7d5fd Completed an unimplemented method that sets missing properties to
the default before comparing instances against each other for
serial/parallel combination.  In particular, this avoids a
failure to serially combine a device with M = 1 vs. a device with
no M declared.
2017-10-12 15:26:29 -04:00
Tim Edwards f860244700 Provide additional output for mismatched serial/parallel networks.
Netgen was incorrectly treating mismatched networks as a missing
set of parameters on whichever device had more property records,
resulting in misleading output.
2017-10-12 14:17:24 -04:00
Tim Edwards 66015511cb Corrected mismatch count, which was prematurely declaring a
mismatch on "M=" even though some conditions pass.
2017-10-12 12:30:33 -04:00
Tim Edwards b3277ca53e Modified reading of SPICE files so that parameters in quotes get
treated monolithically instead of being broken up into separate
tokens according to space characters, which screws up the parameter
parsing.
2017-10-12 12:11:30 -04:00
Tim Edwards 00c2e74524 Merge branch 'master' into work 2017-10-12 10:52:58 -04:00
Tim Edwards bdb8917327 Update at Thu Oct 12 10:52:56 EDT 2017 by tim 2017-10-12 10:52:56 -04:00
Tim Edwards 95bce5dbd6 Corrected another error in the serial combination in which the
attempt to resolve values by combining over serial chains was
attempting to access a property "S" in the component's master
record, which generally won't exist unless it has been explicitly
set in the netlist (which is unlikely since "S" is not a standard
SPICE/CDL parameter like "M").
2017-10-12 10:51:13 -04:00
Tim Edwards e15620257c Merge branch 'master' into work 2017-10-10 22:25:50 -04:00
Tim Edwards 7a947ee9be Update at Tue Oct 10 22:25:49 EDT 2017 by tim 2017-10-10 22:25:49 -04:00
Tim Edwards b5f188de42 Corrected two errors in the serial combine function, one which
misses a device if it has been already moved due to earlier
merging in the serial combine routine, and runs off the end of
the list;  the other if the pin check routine falls on the last
device in the list, leading to an incorrect check for a record
where there is only a NULL.
2017-10-10 22:24:09 -04:00
Tim Edwards ccbb286cf3 Merge branch 'master' into work 2017-08-24 09:51:46 -04:00
Tim Edwards 4809c02f79 Update at Thu Aug 24 09:51:44 EDT 2017 by tim 2017-08-24 09:51:44 -04:00
Tim Edwards af3982766e Prevented a crash condition in the error case in which ports are
unordered at the time of reaching reorderpins().  Pins will be
ordered arbitrarily (in the order of appearance in the linked
list), but netgen will not crash.
2017-08-24 09:50:40 -04:00
Tim Edwards 25c1f13e16 Update at Thu Aug 10 22:41:12 EDT 2017 by tim 2017-08-10 22:41:12 -04:00
Tim Edwards f0eec657a3 Update at Wed Aug 9 09:04:43 EDT 2017 by tim 2017-08-09 09:04:43 -04:00
Tim Edwards 9d476bc25a Merge branch 'master' into work 2017-06-22 08:13:02 -04:00
Tim Edwards 5ed3fcb3f1 Update at Thu Jun 22 08:12:59 EDT 2017 by tim 2017-06-22 08:13:00 -04:00
Tim Edwards ab9659af17 Corrected coding error in tilde expansion of .include filenames. 2017-06-22 08:12:41 -04:00
Tim Edwards 41939adb84 Merge branch 'master' into work 2017-06-20 22:55:26 -04:00
Tim Edwards 39573981be Update at Tue Jun 20 22:55:24 EDT 2017 by tim 2017-06-20 22:55:24 -04:00
Tim Edwards b9e26f6fce Implemented better black-box handling. Netlist with "stub" entries
for subcircuits (.subckt ... .ends pair with cellname and pin names
and pin order, but no contents) are automatically treated as black-
box circuits if found and if the "-blackbox" option is passed to the
"lvs" (scripted) command.  The "equate pins" command can be used
outside of a comparison to force two circuits (black-box or
otherwise) to be matched by pin name (if not a black-box circuit,
then this is a provisional name match, as a circuit comparison will
order based on connectivity first, not pin names).  So two sets of
black-box circuit libraries can be used as long as their pin names
match.  One hack added to ignore the "!" at the end of global names
when comparing pin names for matching.  Otherwise, pin names must
compare by case-insensitive string match.
2017-06-20 22:50:31 -04:00
Tim Edwards 78779ce2e9 Corrected the "property parallel none" command option so that it
gets applied properly to all existing cells (as well as all
future cells, but normally the former is applicable in a setup
file for LVS).
2017-06-19 22:22:08 -04:00
Tim Edwards 70bb33cc62 Finally reworked "cells" command behavior into something
consistent.
2017-06-19 21:04:33 -04:00
Tim Edwards fdf2f32654 Fixed the "cells -all" command so that it now matches the
documentation, and behaves as intended, which is that "-all" is
not a standalone option but is itself an optional qualifier to
the "cells <valid_cellname>" command.  So the options are
"cells <valid_cellname>" and "cells -all <valid_cellname>".
2017-06-19 20:22:59 -04:00
Tim Edwards 05d4225e97 New command option "model blackbox on|off" makes "readnet spice"
treat empty subcircuits as blackbox cells automatically without
requiring specific callse to "model <cell> blackbox" for each.
Enabled in LVS script by giving option "-blackbox" at the end
of the LVS command.
2017-06-19 17:41:31 -04:00
Tim Edwards b6218699a9 Merge branch 'master' into work 2017-06-19 12:39:02 -04:00
Tim Edwards d7927ef547 Update at Mon Jun 19 12:39:00 EDT 2017 by tim 2017-06-19 12:39:00 -04:00
Tim Edwards af7bc39bbf Added tilde expansion handling for .INCLUDE statements to the
SPICE netlist read routine.
2017-06-19 12:38:27 -04:00
Tim Edwards 5cd68b9ef1 Merge branch 'master' into work 2017-06-18 22:48:13 -04:00
Tim Edwards 07788e7501 Update at Sun Jun 18 22:48:11 EDT 2017 by tim 2017-06-18 22:48:11 -04:00
Tim Edwards 24cc7d0c94 Update to add "property parallel none" command option. 2017-06-18 22:47:51 -04:00
Tim Edwards dbcd36d3ec Merge branch 'master' into work 2017-05-15 16:31:03 -04:00
Tim Edwards 25c17abb70 Update at Mon May 15 16:31:00 EDT 2017 by tim 2017-05-15 16:31:00 -04:00
Tim Edwards fd019b4afd Corrected the same error as a few commits back that causes a message
about property errors to show up, not due to property errors, but
due to proxy pins being inserted in the middle of a device record.
However, the first one was fixed for the case of proxy pins being
added to circuit 1, but the same fix was not made for the opposite
case of proxy pins being added to circuit 2.  This commit corrects
that omission.
2017-05-15 16:29:12 -04:00
Tim Edwards cdfd74bac4 Removed old comment from code referring to the development state. 2017-05-08 21:00:43 -04:00
Tim Edwards dd9e02c5f3 Merge branch 'master' into work 2017-05-08 20:57:01 -04:00
Tim Edwards 26cd16f3ff Update at Mon May 8 20:56:58 EDT 2017 by tim 2017-05-08 20:56:58 -04:00
Tim Edwards ccdd47bc0b Corrected rare case where a cell that is flattened is the first
instance in a cell, and is empty, and causes the cell contents
to be nulled out.
2017-05-08 20:55:58 -04:00
Tim Edwards ace1c28507 Corrected an error placing proxy pins after the first pin of the
first object if the (presumably top-level) cell has no pins
(top-level cells not in a subcircuit definition satisfy this
condition).
2017-05-05 21:08:09 -04:00
Tim Edwards 5e9635e05f Merge branch 'master' into work 2017-05-05 17:36:32 -04:00
Tim Edwards 5c168946e3 Update at Fri May 5 17:36:29 EDT 2017 by tim 2017-05-05 17:36:29 -04:00
Tim Edwards 1471f0c09f Corrected error in combining property records of serial devices. 2017-05-05 17:35:57 -04:00
Tim Edwards 73b81fcfe3 Merge branch 'master' into work 2017-04-25 08:47:58 -04:00
Tim Edwards b083a6df7c Update at Tue Apr 25 08:47:57 EDT 2017 by tim 2017-04-25 08:47:57 -04:00
Tim Edwards 2b5a96500c Corrected the .gitignore file, which was apparently missed when
version 1.5 was first created in git.
2017-04-25 08:47:33 -04:00
Tim Edwards 66f94b47e6 Merge branch 'master' into work 2017-03-06 14:01:26 -05:00
Tim Edwards 09532ee628 Update at Mon Mar 6 14:01:25 EST 2017 by tim 2017-03-06 14:01:25 -05:00
Tim Edwards 2b7d416a41 A few corrections to the JSON format output. 2017-03-06 14:01:14 -05:00
Tim Edwards 090e9e122a Merge branch 'master' into work 2017-03-03 09:11:54 -05:00
Tim Edwards 67f1c1a2e9 Update at Fri Mar 3 09:11:52 EST 2017 by tim 2017-03-03 09:11:52 -05:00
Tim Edwards a7dcb4ef45 Corrected new JSON file output format from netgen. 2017-03-03 09:11:30 -05:00
Tim Edwards a0f1b4cc92 Merge branch 'master' into work 2017-02-27 09:36:54 -05:00
Tim Edwards b5d5496e40 Update at Mon Feb 27 09:36:52 EST 2017 by tim 2017-02-27 09:36:52 -05:00
Tim Edwards 7cac67c81b Corrected an error in the property match subroutine that was failing
to stop at the end of an instance record without properties, leading
to strange errors where netgen declares "There were property errors"
but does not print any errors (because there aren't any).
2017-02-27 09:35:18 -05:00
Tim Edwards ede7406b08 Merge branch 'master' into work 2017-02-08 15:17:01 -05:00
Tim Edwards 516d1c33fb Update at Wed Feb 8 15:16:59 EST 2017 by tim 2017-02-08 15:16:59 -05:00
Tim Edwards 0ad5730701 Corrected an error where snprintf() was not used when printing
formatted side-by-side output, causing a crash for names that
exceed the 40-column limit.
2017-02-08 15:16:24 -05:00
Tim Edwards 24d98ff0d3 Removed backup file for netgen.tcl.in, and made corrections for
the output JSON format, which was incorrect when some entries
were empty.
2017-01-09 17:06:23 -05:00
Tim Edwards 092c99dc1b Merge branch 'master' into work 2017-01-09 12:53:00 -05:00
Tim Edwards 4659b0795d Update at Mon Jan 9 12:52:59 EST 2017 by tim 2017-01-09 12:52:59 -05:00
Tim Edwards b1924bff65 Finished implementing the Tcl list output format, and added a
routine to convert the list output format to a JSON output file,
for easy readback, parsing, and display using python.
2017-01-09 12:51:31 -05:00
Tim Edwards bd356553fd Merge branch 'master' into work 2017-01-07 06:57:27 -05:00
Tim Edwards 46458f2836 Update at Sat Jan 7 06:57:25 EST 2017 by tim 2017-01-07 06:57:25 -05:00
Tim Edwards 8deccaad9c Fixed a bug in the combine routine that causes a segfault; added
preliminary support for a Tcl list output format.
2017-01-07 06:56:51 -05:00
Tim Edwards 4f24915661 Correction to device property matching code to fix a problem that
caused LVS(A, B) to give different results for property errors
than LVS(B, A).
2016-12-12 13:31:56 -05:00
Tim Edwards fdab366627 Corrected typo with == vs. = 2016-12-12 11:51:24 -05:00
Tim Edwards 310d7512a0 Removed backup file. 2016-12-12 11:32:52 -05:00
Tim Edwards 86f52b164a Merge branch 'master' into work 2016-12-12 11:32:44 -05:00
Tim Edwards 4a47c3076d Update at Mon Dec 12 11:32:42 EST 2016 by tim 2016-12-12 11:32:42 -05:00
Tim Edwards 777498b30e Completed the implementation of serial/parallel device network
matching.
2016-12-12 11:32:07 -05:00
29 changed files with 9461 additions and 674 deletions
+11 -10
View File
@@ -1,12 +1,13 @@
*.*%
*.cdslck
.inca.db.*
inca.*.pak
*.swp
*.log
netgen
netgenexec
defs.mak
Depend
config.cache
config.log
config.status
*.o
*.so
*~
*/av_extracted*/
.nfs*
*.cd-
*/mommdl/
*.log
UPDATE_ME
VERSION
+6 -5
View File
@@ -1,15 +1,14 @@
TO_DO list for version 1.5
------------------------------
1) Parallel (transistors and capacitors) and serial (resistors)
device merging, plus methods for describing how any device
class may be merged.
As of version 1.5.70, the major to-do item list is complete.
Possible useful additions (not critical)
----------------------
1) Add new output style allowing netlists to be described by Tcl scripts
(similar to the C-Code format, but does not require compiling).
(similar to the C-Code format, but does not require compiling) (this
was done in 1.5.72, but now needs some scripts to make use of it.)
2) Add automatic file format guessing from file extension for "write" command
3) Add Tk GUI to match (and improve upon!) the original X11 GUI.
4) Incorporate into Tcl-based xcircuit
@@ -33,5 +32,7 @@ Possible useful additions (not critical)
ntk and ext formats, SPICE format writing, and sim format reading).
11) Add a "property" command to add/remove properties to check, and change
the slop values (done).
12) Add a "subcircuit" command to mimic a SPICE ".SUBCKT ... .ENDS" card.
12) Add a "subcircuit" command to mimic a SPICE ".SUBCKT ... .ENDS" card
(i.e., the ability to add subcircuit "stub" definitions from the
command line or from a setup file).
+1 -1
View File
@@ -1 +1 @@
1.5.68
1.5.92
+2 -2
View File
@@ -170,7 +170,7 @@ char *ReadExt(char *fname, int doflat, int *fnum)
SetExtension(name, fname, EXT_EXTENSION);
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
Printf("No file: %s\n",name);
Printf("Error in ext file read: No file %s\n",name);
*fnum = filenum;
return NULL;
}
@@ -643,7 +643,7 @@ char *ReadSim(char *fname, int *fnum)
SetExtension(name, fname, SIM_EXTENSION);
if (OpenParseFile(name, *fnum) < 0) {
Printf("No file: %s\n",name);
Printf("Error in ext file read: No file %s\n",name);
*fnum = filenum;
return NULL;
}
+26 -16
View File
@@ -486,24 +486,30 @@ int flattenInstancesOf(char *name, int fnum, char *instance)
}
/* splice instance out of parent */
if (ParentParams == ThisCell->cell) {
/* ParentParams are the very first thing in the list */
ThisCell->cell = ChildObjList;
for (ob2 = ChildObjList; ob2 && ob2->next != NULL; ob2 = ob2->next) ;
if ((ParentParams == ThisCell->cell) && (ChildObjList == NULL)) {
ThisCell->cell = ob2; /* Child cell was empty */
tmp = ob2;
}
else {
/* find ParentParams in ThisCell list */
for (ob2 = ThisCell->cell; ob2 && ob2->next != ParentParams; ob2=ob2->next);
if (ob2)
for (ob2->next = ChildObjList; ob2->next != NULL; ob2 = ob2->next) ;
}
/* now, ob2 is last element in child list, so skip and reclaim parent */
if (ParentParams == ThisCell->cell) {
/* ParentParams are the very first thing in the list */
ThisCell->cell = ChildObjList;
for (ob2 = ChildObjList; ob2 && ob2->next != NULL; ob2 = ob2->next) ;
}
else {
/* find ParentParams in ThisCell list */
for (ob2 = ThisCell->cell; ob2 && ob2->next != ParentParams; ob2=ob2->next);
if (ob2)
for (ob2->next = ChildObjList; ob2->next != NULL; ob2 = ob2->next) ;
}
/* now, ob2 is last element in child list, so skip and reclaim parent */
tmp = ParentParams;
do {
tmp = tmp->next;
} while ((tmp != NULL) && ((tmp->type > FIRSTPIN) || (tmp->type == PROPERTY)));
if (ob2) ob2->next = tmp;
tmp = ParentParams;
do {
tmp = tmp->next;
} while ((tmp != NULL) && ((tmp->type > FIRSTPIN) || (tmp->type == PROPERTY)));
if (ob2) ob2->next = tmp;
}
while (ParentParams != tmp) {
ob2 = ParentParams->next;
FreeObjectAndHash(ParentParams, ThisCell);
@@ -1224,6 +1230,10 @@ int CleanupPins(char *name, int filenum)
return 0;
}
// If cell is type MODULE, this is a black-box circuit and
// pins are expected to be disconnected (so don't remove them).
if (ThisCell->class == CLASS_MODULE) return 0;
// Avoid a loop through all cells unless we have to do it.
for (ob = ThisCell->cell; ob != NULL; ob = ob->next) {
@@ -1407,7 +1417,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
else
tc2 = LookupCellFile(name2, file2);
if (tc1 == NULL || tc2 == NULL) return;
if (tc1 == NULL || tc2 == NULL) return 0;
InitializeHashTable(&compdict, OBJHASHSIZE);
+1 -1
View File
@@ -309,7 +309,7 @@ struct hashlist *HashInt2PtrInstall(char *name, int c, void *ptr,
/* destroy a hash table, freeing associated memory */
/*----------------------------------------------------------------------*/
void *HashKill(struct hashdict *dict)
void HashKill(struct hashdict *dict)
{
struct hashlist *np, *p;
int i;
+1
View File
@@ -25,6 +25,7 @@ extern struct nlist *RecurseHashTablePointer(struct hashdict *dict,
void *pointer);
extern void HashDelete(char *name, struct hashdict *dict);
extern void HashIntDelete(char *name, int value, struct hashdict *dict);
extern void HashKill(struct hashdict *dict);
extern int CountHashTableEntries(struct hashlist *p);
+1917 -362
View File
File diff suppressed because it is too large Load Diff
+6423
View File
File diff suppressed because it is too large Load Diff
+9 -3
View File
@@ -9,6 +9,7 @@ extern struct nlist *Circuit2;
extern int ExhaustiveSubdivision;
#ifdef TCL_NETGEN
#include <tcl.h>
extern int InterruptPending;
#endif
@@ -17,10 +18,11 @@ extern int InterruptPending;
extern void PrintElementClasses(struct ElementClass *EC, int type, int dolist);
extern void PrintNodeClasses(struct NodeClass *NC, int type, int dolist);
extern void SummarizeNodeClasses(struct NodeClass *NC);
extern void PrintPropertyResults(void);
extern void PrintPropertyResults(int do_list);
extern void PrintCoreStats(void);
extern void ResetState(void);
extern void CreateTwoLists(char *name1, int file1, char *name2, int file2);
extern void CreateTwoLists(char *name1, int file1, char *name2, int file2,
int dolist);
extern int Iterate(void);
extern int VerifyMatching(void);
extern void PrintAutomorphisms(void);
@@ -33,7 +35,8 @@ extern int EquivalenceElements(char *name1, int file1, char *name2, int file2);
extern int EquivalenceNodes(char *name1, int file1, char *name2, int file2);
extern int EquivalenceClasses(char *name1, int file1, char *name2, int file2);
extern int IgnoreClass(char *name, int file, unsigned char type);
extern int MatchPins(struct nlist *tp1, struct nlist *tp2);
extern int MatchPins(struct nlist *tp1, struct nlist *tp2, int dolist);
extern int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int serial);
extern int CreateCompareQueue(char *, int, char *, int);
extern int GetCompareQueueTop(char **, int *, char **, int *);
@@ -50,5 +53,8 @@ extern int EquivalentElement();
extern void enable_interrupt();
extern void disable_interrupt();
extern Tcl_Obj *ListNodeClasses(int legal);
extern Tcl_Obj *ListElementClasses(int legal);
#endif
+67 -4
View File
@@ -77,8 +77,9 @@ extern char *SetExtension(char *buffer, char *path, char *extension)
strcat(tmpbuf, extension);
/* step 4: lower-case the entire name */
for (pt = tmpbuf; *pt != '\0'; pt++)
if (isupper(*pt)) *pt = tolower(*pt);
/* (Commented out because this is really stupid.) */
// for (pt = tmpbuf; *pt != '\0'; pt++)
// if (isupper(*pt)) *pt = tolower(*pt);
if (buffer != NULL) {
strcpy(buffer, tmpbuf);
@@ -192,6 +193,67 @@ static struct filestack *OpenFiles = NULL;
#define TOKEN_DELIMITER " \t\n\r"
/*----------------------------------------------------------------------*/
/* TrimQuoted() --- */
/* Remove spaces from inside single- or double-quoted strings. */
/*----------------------------------------------------------------------*/
void TrimQuoted(char *line)
{
char *qstart, *qend, *lptr;
int slen;
int changed;
/* Single-quoted entries */
changed = TRUE;
lptr = line;
while (changed)
{
changed = FALSE;
qstart = strchr(lptr, '\'');
if (qstart)
{
qend = strchr(qstart + 1, '\'');
if (qend && (qend > qstart)) {
slen = strlen(lptr);
for (lptr = qstart + 1; lptr < qend; lptr++) {
if (*lptr == ' ') {
memmove(lptr, lptr + 1, slen);
qend--;
changed = TRUE;
}
}
lptr++;
}
}
}
/* Double-quoted entries */
changed = TRUE;
lptr = line;
while (changed)
{
changed = FALSE;
qstart = strchr(lptr, '\"');
if (qstart)
{
qend = strchr(qstart + 1, '\"');
if (qend && (qend > qstart)) {
slen = strlen(lptr);
for (lptr = qstart + 1; lptr < qend; lptr++) {
if (*lptr == ' ') {
memmove(lptr, lptr + 1, slen);
qend--;
changed = TRUE;
}
}
lptr++;
}
}
}
}
/*----------------------------------------------------------------------*/
/* GetNextLineNoNewline() */
/* */
@@ -232,6 +294,7 @@ int GetNextLineNoNewline()
}
linenum++;
strcpy(linetok, line);
TrimQuoted(linetok);
nexttok = strtok(linetok, TOKEN_DELIMITER);
return 0;
@@ -567,7 +630,7 @@ char *ReadNetgenFile (char *fname, int *fnum)
if ((filenum = OpenParseFile(fname, *fnum)) < 0) {
SetExtension(name, fname, NETGEN_EXTENSION);
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
Printf("No file: %s\n",name);
Printf("Error in netgen read: No file %s\n",name);
*fnum = -1;
return NULL;
}
@@ -803,7 +866,7 @@ char *ReadNetgenFile (char *fname, int *fnum)
if ((File = open(fname, O_RDONLY, FILE_ACCESS_BITS)) == -1) {
SetExtension(name, fname, NETGEN_EXTENSION);
if ((File = open(name, O_RDONLY, FILE_ACCESS_BITS)) == -1) {
Printf("No file: %s\n",name);
Printf("Error in netgen read: No file %s\n",name);
return NULL;
}
}
+220 -146
View File
@@ -49,6 +49,7 @@ int NextNode;
int Composition = NONE;
int QuickSearch = 0;
int GlobalParallelNone = FALSE;
int AddToExistingDefinition = 0; /* default: overwrite cell when reopened */
@@ -870,6 +871,32 @@ int ReduceExpressions(struct objlist *instprop, struct objlist *parprops,
return 0;
}
/*----------------------------------------------------------------------*/
/* Set/clear the flag bit COMB_NO_PARALLEL on all cells. Note that the */
/* function is called with value for enabling combine parallel, so */
/* value TRUE means clear bit, value FALSE means set bit. */
/*----------------------------------------------------------------------*/
struct nlist *SetParallelCombineFlag(struct hashlist *p, void *clientdata)
{
struct nlist *ptr;
int *value = (int *)clientdata;
ptr = (struct nlist *)(p->ptr);
if (*value == TRUE)
ptr->flags &= (~COMB_NO_PARALLEL);
else
ptr->flags |= COMB_NO_PARALLEL;
return NULL; /* NULL keeps search alive */
}
void SetParallelCombine(int value)
{
ClearDumpedList();
RecurseCellHashTable2(SetParallelCombineFlag, (void *)(&value));
}
/*----------------------------------------------------------------------*/
/* Delete a property from the master cell record. */
/*----------------------------------------------------------------------*/
@@ -948,10 +975,10 @@ PropertyTolerance(char *name, int fnum, char *key, int ival, double dval)
switch (kl->type) {
case PROP_DOUBLE:
case PROP_VALUE:
case PROP_STRING:
kl->slop.dval = dval;
break;
case PROP_INTEGER:
case PROP_STRING:
case PROP_EXPRESSION:
kl->slop.ival = ival;
break;
@@ -1011,7 +1038,7 @@ struct property *PropertyValue(char *name, int fnum, char *key,
if ((fnum == -1) && (Circuit1 != NULL) && (Circuit2 != NULL)) {
PropertyValue(name, Circuit1->file, key, slop, pdefault);
PropertyValue(name, Circuit2->file, key, slop, pdefault);
return;
return NULL;
}
tc = LookupCellFile(name, fnum);
@@ -1046,7 +1073,7 @@ struct property *PropertyDouble(char *name, int fnum, char *key,
if ((fnum == -1) && (Circuit1 != NULL) && (Circuit2 != NULL)) {
PropertyDouble(name, Circuit1->file, key, slop, pdefault);
PropertyDouble(name, Circuit2->file, key, slop, pdefault);
return;
return NULL;
}
tc = LookupCellFile(name, fnum);
@@ -1079,7 +1106,7 @@ struct property *PropertyInteger(char *name, int fnum, char *key,
if ((fnum == -1) && (Circuit1 != NULL) && (Circuit2 != NULL)) {
PropertyInteger(name, Circuit1->file, key, slop, pdefault);
PropertyInteger(name, Circuit2->file, key, slop, pdefault);
return;
return NULL;
}
tc = LookupCellFile(name, fnum);
@@ -1103,16 +1130,16 @@ struct property *PropertyInteger(char *name, int fnum, char *key,
/*----------------------------------------------------------------------*/
struct property *PropertyString(char *name, int fnum, char *key, int range,
struct property *PropertyString(char *name, int fnum, char *key, double dval,
char *pdefault)
{
struct property *kl = NULL;
struct nlist *tc;
if ((fnum == -1) && (Circuit1 != NULL) && (Circuit2 != NULL)) {
PropertyString(name, Circuit1->file, key, range, pdefault);
PropertyString(name, Circuit2->file, key, range, pdefault);
return;
PropertyString(name, Circuit1->file, key, dval, pdefault);
PropertyString(name, Circuit2->file, key, dval, pdefault);
return NULL;
}
tc = LookupCellFile(name, fnum);
@@ -1127,7 +1154,7 @@ struct property *PropertyString(char *name, int fnum, char *key, int range,
kl->idx = 0;
kl->merge = MERGE_NONE;
kl->type = PROP_STRING;
kl->slop.ival = (range >= 0) ? range : 0;
kl->slop.dval = dval;
if (pdefault != NULL)
kl->pdefault.string = strsave(pdefault);
else
@@ -1192,7 +1219,7 @@ void CellDef(char *name, int fnum)
np = InstallInCellHashTable(name, fnum);
CurrentCell = LookupCellFile(name, fnum);
CurrentCell->class = CLASS_SUBCKT; /* default */
CurrentCell->flags = 0;
CurrentCell->flags = (GlobalParallelNone) ? COMB_NO_PARALLEL : 0;
LastPlaced = NULL;
CurrentTail = NULL;
@@ -2054,7 +2081,7 @@ struct objlist *LinkProperties(char *model, struct keyvalue *topptr)
kl->idx = 0;
kl->merge = MERGE_NONE;
kl->type = PROP_STRING;
kl->slop.ival = 0;
kl->slop.dval = 0.0;
kl->pdefault.string = NULL;
HashPtrInstall(kl->key, kl, &(cell->propdict));
}
@@ -2318,7 +2345,7 @@ void ResolveProperties(char *name1, int file1, char *name2, int file2)
switch (kl1->type) {
case PROP_STRING:
kl2 = PropertyString(tp2->name, tp2->file, kl1->key,
kl1->slop.ival, kl1->pdefault.string);
kl1->slop.dval, kl1->pdefault.string);
break;
case PROP_INTEGER:
kl2 = PropertyInteger(tp2->name, tp2->file, kl1->key,
@@ -2350,7 +2377,7 @@ void ResolveProperties(char *name1, int file1, char *name2, int file2)
switch (kl2->type) {
case PROP_STRING:
kl1 = PropertyString(tp1->name, tp1->file, kl2->key,
kl2->slop.ival, kl2->pdefault.string);
kl2->slop.dval, kl2->pdefault.string);
break;
case PROP_INTEGER:
kl1 = PropertyInteger(tp1->name, tp1->file, kl2->key,
@@ -2884,10 +2911,10 @@ void ConnectAllNodes(char *model, int file)
/* 2) Always tag B with "serial". */
/* */
/* Tags are indicated by a property named "_tag" which has a string */
/* value of ordered characters, "S" for serial, "O" for open, and "C" */
/* value of ordered characters, "+" for serial, "(" for open, and ")" */
/* for close. A device with only one property record has no "_tag" */
/* record. A device which is in parallel with the device(s) in front */
/* of it is implicitly parallel by not having an "S" tag, and may not */
/* of it is implicitly parallel by not having an "+" tag, and may not */
/* have a tag at all. */
/* */
/* The property check routine is responsible for comparing device */
@@ -2979,9 +3006,9 @@ void add_balancing_close(struct objlist *ob1, struct objlist *ob2)
if (kv->type == PROP_ENDLIST) break;
if (kv->type == PROP_STRING) {
if (!strcmp(kv->key, "_tag")) {
for (tag == kv->value.string; *tag != '\0'; tag++) {
if (*tag == 'O') opentags++;
else if (*tag == 'C') opentags--;
for (tag = kv->value.string; *tag != '\0'; tag++) {
if (*tag == '(') opentags++;
else if (*tag == ')') opentags--;
}
break;
}
@@ -2997,7 +3024,7 @@ void add_balancing_close(struct objlist *ob1, struct objlist *ob2)
if (nob->type != PROPERTY) return; // shouldn't happen
// This is slow but it's the easiest way to do it
while (opentags-- > 0) add_prop_tag(nob, 'C');
while (opentags-- > 0) add_prop_tag(nob, ')');
}
/*----------------------------------------------------------------------*/
@@ -3024,7 +3051,8 @@ int CombineParallel(char *model, int file)
{
struct nlist *tp, *tsub;
struct objlist *ob, *ob2, *nextob;
struct objlist *sob, *lob, *tlob, *nob, *pob, *obr;
struct objlist *sob, *lob, *nob, *pob, *obr;
struct objlist *propfirst, *proplast, *spropfirst, *sproplast;
struct hashdict devdict;
struct Permutation *perm;
size_t pcnt;
@@ -3048,6 +3076,7 @@ int CombineParallel(char *model, int file)
tsub = LookupCellFile(ob->model.class, file);
if ((tsub != NULL) && (tsub->flags & COMB_NO_PARALLEL)) {
lob = ob;
ob = ob->next;
continue;
}
@@ -3064,14 +3093,17 @@ int CombineParallel(char *model, int file)
pcnt = strlen(ob->model.class) + 2;
pptr = (char *)pcnt;
propfirst = proplast = NULL;
for (ob2 = ob; ob2 && (ob2->type > FIRSTPIN || ob2 == ob); ob2 = ob2->next) {
tlob = ob2;
pob = ob2;
pcnt += 10;
}
if (ob2 && (ob2->type == PROPERTY)) propfirst = ob2;
/* Find last record in device and first record in next object */
while (ob2 && ob2->type == PROPERTY) {
tlob = ob2;
proplast = ob2;
ob2 = ob2->next;
}
nextob = ob2;
@@ -3128,73 +3160,117 @@ int CombineParallel(char *model, int file)
FREE((char *)p2str);
}
/* Set last object ptr to end of this record */
lob = tlob;
/* Move last object marker to end of sob record */
if (proplast != NULL)
lob = proplast;
else
lob = pob;
}
else {
/* Find parallel device "ob" and append properties of */
/* "sob" to it. If "ob" does not have properties, then */
/* create a property record and set property "M" to 2. */
for (obr = ob; obr != ob2 ; ) {
/* Find last non-property record of sob ( = pob) */
/* Find first property record of sob ( = spropfirst) */
/* Find last property record of sob ( = sproplast) */
spropfirst = sproplast = NULL;
for (ob2 = sob; ob2->type > FIRSTPIN || ob2 == sob; ob2 = ob2->next)
pob = ob2;
if (ob2->type == PROPERTY) spropfirst = ob2;
for (; ob2->type == PROPERTY; ob2 = ob2->next)
sproplast = ob2;
if (spropfirst == NULL) {
/* Create new property instance record if one doesn't exist */
nob = GetObject();
nob->type = PROPERTY;
nob->name = strsave("properties");
nob->node = -2; /* Don't report as disconnected node */
nob->model.class = strsave(sob->model.class);
nob->instance.props = NewPropValue(2);
/* Create property record for property "M" and set to 1 */
kv = &(nob->instance.props[0]);
kv->key = strsave("M");
kv->type = PROP_INTEGER;
kv->value.ival = 1;
/* End of property list */
kv = &(nob->instance.props[1]);
kv->key = NULL;
kv->type = PROP_ENDLIST;
kv->value.ival = 0;
nob->next = pob->next;
pob->next = nob;
if (lob == pob) lob = nob;
spropfirst = sproplast = nob;
}
if (propfirst == NULL) {
/* Create new property instance record if one doesn't exist */
nob = GetObject();
nob->type = PROPERTY;
nob->name = strsave("properties");
nob->node = -2; /* Don't report as disconnected node */
nob->model.class = strsave(ob->model.class);
nob->instance.props = NewPropValue(2);
/* Create property record for property "M" and set to 1 */
kv = &(nob->instance.props[0]);
kv->key = strsave("M");
kv->type = PROP_INTEGER;
kv->value.ival = 1;
/* End of property list */
kv = &(nob->instance.props[1]);
kv->key = NULL;
kv->type = PROP_ENDLIST;
kv->value.ival = 0;
/* Append to sob's property list */
nob->next = sproplast->next;
sproplast->next = nob;
if (lob == sproplast) lob = nob;
}
if (propfirst != NULL) {
// Serial/Parallel logic:
// If propfirst has _tag in properties,
// then add an "open" tag at propfirst
add_prop_tag(propfirst, '(');
// if spropfirst has _tag in properties then add an "open" tag
// to spropfirst and a "close" tag to propfirst
if (add_prop_tag(spropfirst, '(')) add_prop_tag(propfirst, ')');
/* Append ob's property list to sob */
proplast->next = sproplast->next;
sproplast->next = propfirst;
if (lob == sproplast) lob = proplast;
}
/* Link up around object to be removed */
lob->next = nextob;
/* Remove the object */
for (obr = ob; obr != propfirst && obr != nextob; ) {
nob = obr->next;
FreeObjectAndHash(obr, tp);
obr = nob;
}
dcnt++;
/* Find (first) property record of sob */
for (pob = sob->next; pob->type > FIRSTPIN; pob = pob->next) {
if (pob->next->type == PROPERTY)
break;
else if (pob->next->type == FIRSTPIN) {
/* Create new property instance record if one doesn't exist */
nob = GetObject();
nob->type = PROPERTY;
nob->name = strsave("properties");
nob->node = -2; /* Don't report as disconnected node */
nob->model.class = strsave(sob->model.class);
nob->instance.props = NewPropValue(2);
/* Create property record for property "M" and set to 1 */
kv = &(nob->instance.props[0]);
kv->key = strsave("M");
kv->type = PROP_INTEGER;
kv->value.ival = (obr->type != PROPERTY) ? 2 : 1;
/* End of property list */
kv = &(nob->instance.props[1]);
kv->key = NULL;
kv->type = PROP_ENDLIST;
kv->value.ival = 0;
nob->next = pob->next;
pob->next = nob;
break;
}
}
if (lob == pob) lob = tlob;
if (obr->type == PROPERTY) {
/* Pull out property records and append to sob's */
/* property list */
tlob->next = pob->next;
pob->next = obr;
}
lob->next = nextob;
// Serial/Parallel logic:
// If obr has _tag in properties, then add an "open" tag at obr
add_prop_tag(obr, 'O');
// if ob2 has _tag in properties then add an "open" tag to ob2
// and a "close" tag to obr
if (add_prop_tag(ob2, 'O')) add_prop_tag(obr, 'C');
}
FREE((char *)pstr);
}
else
else {
lob = ob;
nextob = ob->next;
}
ob = nextob;
}
HashKill(&devdict);
@@ -3233,7 +3309,9 @@ int check_pin_nodes(struct objlist *ob1, struct objlist *ob2)
pob = pob->next;
}
if (nob->type > FIRSTPIN || pob->type > FIRSTPIN) return FALSE;
if (nob && pob && (nob->type > FIRSTPIN || pob->type > FIRSTPIN))
return FALSE;
return TRUE;
}
@@ -3257,11 +3335,6 @@ int CombineSerial(char *model, int file)
int i, j, scnt = 0;
struct valuelist *kv;
// To avoid posting a non-working version, serial combination is
// disabled here until code is finished to compare the serial/parallel
// property networks.
return 0;
if ((tp = LookupCellFile(model, file)) == NULL) {
Printf("Cell: %s does not exist.\n", model);
return -1;
@@ -3325,83 +3398,77 @@ int CombineSerial(char *model, int file)
for (i = 0; i <= tp->nodename_cache_maxnodenum; i++) {
if (instlist[i] != NULL) {
if ((instlist[i][0] != NULL) && (instlist[i][1] != NULL)) {
Fprintf(stdout, "Found serial instances %s and %s\n",
int k, l;
struct valuelist *kv2;
/* Diagnostic */
/* Fprintf(stdout, "Found serial instances %s and %s\n",
instlist[i][0]->instance.name,
instlist[i][1]->instance.name);
instlist[i][1]->instance.name); */
scnt++;
/* Diagnostic */
/* Printf("CombineSerial: Merging serial instances %s (0x%x) and %s (0x%x)"
", remove node %s (%d)\n",
instlist[i][0]->instance.name,
instlist[i][0],
instlist[i][1]->instance.name,
instlist[i][1],
tp->nodename_cache[i]->name, i); */
/* To maintain knowledge of the topology, each device gets */
/* a parameter '_tag', string value set to "S". */
/* To maintain knowledge of the topology, 2nd device gets */
/* a parameter '_tag', string value set to "+". */
for (j = 0; j <= 1; j++) {
for (obp = instlist[i][j]; ; obp = obp->next) {
int found = FALSE;
int k, l;
char *nodename1, *nodename2;
struct valuelist *kv2;
for (obn = instlist[i][1]; obn->next &&
obn->next->type > FIRSTPIN; obn = obn->next);
obp = obn->next;
nodename1 = tp->nodename_cache[instlist[i][j]->node]->name;
nodename2 = tp->nodename_cache[instlist[i][j]->next->node]->name;
if (obp->type == PROPERTY) {
/* Add to properties */
k = 0;
for (k = 0; ; k++) {
kv = &(obp->instance.props[k]);
if (kv->type == PROP_ENDLIST)
break;
}
if (obp == NULL || obp->type != PROPERTY) {
struct objlist *nob;
/* No property record, so insert one */
nob = GetObject();
nob->type = PROPERTY;
nob->name = strsave("properties");
nob->node = -2; /* Don't report as disconnected node */
nob->model.class = (obp->model.class == NULL) ? NULL :
strsave(obp->model.class);
nob->instance.props = NewPropValue(2);
/* Create property record for property "_tag" */
kv = &(nob->instance.props[0]);
kv->key = strsave("_tag");
kv->type = PROP_STRING;
/* Value is set to "+" */
kv->value.string = (char *)MALLOC(2);
sprintf(kv->value.string, "+");
/* End of property list */
kv = &(nob->instance.props[1]);
kv->key = NULL;
kv->type = PROP_ENDLIST;
kv->value.ival = 0;
nob->next = obp;
obn->next = nob;
}
else if (obp->type == PROPERTY) {
/* Add to properties */
k = 0;
for (k = 0; ; k++) {
kv = &(obp->instance.props[k]);
if (kv->type == PROP_ENDLIST) {
kv2 = (struct valuelist *)MALLOC((k + 2) *
sizeof(struct valuelist));
kv2->key = strsave("_tag");
kv2->type = PROP_STRING;
/* Value is set to "S" */
/* Value is set to "+" */
kv2->value.string = (char *)MALLOC(2);
sprintf(kv2->value.string, "S");
sprintf(kv2->value.string, "+");
for (l = 0; l <= k; l++)
kv2[l + 1] = obp->instance.props[l];
kv2[l + 1] = obp->instance.props[l];
FREE(obp->instance.props);
obp->instance.props = kv2;
found = TRUE;
}
if (obp->next == NULL || obp->next->type == FIRSTPIN) {
struct objlist *nob;
/* No property record, so insert one */
if (found == FALSE) {
nob = GetObject();
nob->type = PROPERTY;
nob->name = strsave("properties");
nob->node = -2; /* Don't report as disconnected node */
nob->model.class = (obp->model.class == NULL) ? NULL :
strsave(obp->model.class);
nob->instance.props = NewPropValue(2);
/* Create property record for property "_tag" */
kv = &(nob->instance.props[0]);
kv->key = strsave("_tag");
kv->type = PROP_STRING;
/* Value is set to "S" */
kv->value.string = (char *)MALLOC(2);
sprintf(kv->value.string, "S");
/* End of property list */
kv = &(nob->instance.props[1]);
kv->key = NULL;
kv->type = PROP_ENDLIST;
kv->value.ival = 0;
nob->next = obp->next;
obp->next = nob;
}
break;
}
}
else if (!strcmp(kv->key, "_tag")) {
int l = strlen(kv->value.string);
char *newstr = (char *)MALLOC(l + 2);
sprintf(newstr, "S%s", kv->value.string);
FREE(kv->value.string);
kv->value.string = newstr;
break;
}
}
}
@@ -3419,10 +3486,17 @@ int CombineSerial(char *model, int file)
/* Excise the 2nd instance. instlist[i][1] remains as the */
/* only pointer to it. */
for (obp = instlist[i][0]; obp->next->type != FIRSTPIN; obp = obp->next);
for (ob2 = obp; ob2->next != instlist[i][1]; ob2 = ob2->next);
for (obs = ob2->next; obs->next && obs->next->type != FIRSTPIN;
obs = obs->next);
for (obp = instlist[i][0]; obp->next->type > FIRSTPIN ||
obp->next->type == PROPERTY; obp = obp->next);
for (ob2 = obp; ob2 && ob2->next != instlist[i][1]; ob2 = ob2->next);
/* Device may have been moved by the above code. If so, look for */
/* it from the beginning of the list. */
if (ob2 == NULL)
for (ob2 = tp->cell; ob2->next != instlist[i][1]; ob2 = ob2->next);
for (obs = ob2->next; obs->next && (obs->next->type > FIRSTPIN
|| obs->next->type == PROPERTY); obs = obs->next);
ob2->next = obs->next;
if (obs->next) obs->next = NULL; // Terminate 2nd instance record
+5 -1
View File
@@ -33,8 +33,9 @@ extern struct property *PropertyDouble(char *name, int fnum, char *key,
extern struct property *PropertyInteger(char *name, int fnum, char *key,
int slop, int pdefault);
extern struct property *PropertyString(char *name, int fnum, char *key,
int range, char *pdefault);
double slop, char *pdefault);
extern int PropertyDelete(char *name, int fnum, char *key);
extern void SetParallelCombine(int value);
extern int PropertyTolerance(char *name, int fnum, char *key, int ival,
double dval);
extern int PropertyMerge(char *name, int fnum, char *key, int merge_type);
@@ -53,6 +54,8 @@ extern void PortList(char *prefix, char *list_template);
extern char *Cell(char *inststr, char *model, ...);
extern int IsIgnored(char *, int);
extern int auto_blackbox; /* For handling empty subcircuits */
/* netcmp.c */
extern struct nlist *LookupClassEquivalent(char *model, int file1, int file2);
extern void AssignCircuits(char *name1, int file1, char *name2, int file2);
@@ -132,6 +135,7 @@ extern int IgnoreRC; /* set this to 1 to ignore capacitance and resistance */
extern int NoOutput; /* set this to 1 to disable stdout output */
extern int Composition; /* direction of composition */
extern int UnixWildcards; /* TRUE if *,?,{},[] only; false if full REGEXP */
extern int GlobalParallelNone; /* If TRUE, don't parallel combine any cells */
/* magic internal flag to restrict searches to recently placed cells */
extern int QuickSearch;
/* does re"CellDef"ing a cell add to it or overwrite it??? */
+1 -1
View File
@@ -186,7 +186,7 @@ char *ReadNtk (char *fname, int *fnum)
if ((filenum = OpenParseFile(fname, *fnum)) < 0) {
SetExtension(name, fname, NTK_EXTENSION);
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
Printf("No file: %s\n",name);
Printf("Error in ntk file read: No file %s\n",name);
*fnum = filenum;
return NULL;
}
+9 -6
View File
@@ -348,7 +348,7 @@ int removeshorted(struct hashlist *p, int file)
ptr = (struct nlist *)(p->ptr);
if ((file != -1) && (ptr->file != file)) return;
if ((file != -1) && (ptr->file != file)) return 0;
lob = NULL;
for (ob = ptr->cell; ob != NULL;) {
@@ -412,7 +412,7 @@ int deleteclass(struct hashlist *p, int file)
ptr = (struct nlist *)(p->ptr);
if ((file != -1) && (ptr->file != file)) return;
if ((file != -1) && (ptr->file != file)) return 0;
lob = NULL;
for (ob = ptr->cell; ob != NULL;) {
@@ -469,7 +469,7 @@ int renameinstances(struct hashlist *p, int file)
ptr = (struct nlist *)(p->ptr);
if ((file != -1) && (ptr->file != file)) return;
if ((file != -1) && (ptr->file != file)) return 0;
for (ob = ptr->cell; ob != NULL; ob = ob->next) {
if ((ob->type >= FIRSTPIN) && (ob->model.class != NULL)) {
@@ -563,8 +563,11 @@ static int PrintCellHashTableElement(struct hashlist *p)
/* only print primitive cells if Debug is enabled */
if (Debug == 1) Printf("Cell: %s (instanced %d times); Primitive\n",
ptr->name, ptr->number);
else if (Debug == 3) { /* list */
Tcl_AppendElement(netgeninterp, ptr->name);
}
}
else if (Debug == 2) { /* list only */
else if ((Debug == 2) || (Debug == 3)) { /* list only */
#ifdef TCL_NETGEN
Tcl_AppendElement(netgeninterp, ptr->name);
#else
@@ -595,7 +598,7 @@ void PrintCellHashTable(int full, int filenum)
bins = RecurseHashTable(&cell_dict, CountHashTableBinsUsed);
total = RecurseHashTable(&cell_dict, CountHashTableEntries);
if (full != 2)
if (full < 2)
Printf("Hash table: %d of %d bins used; %d cells total (%.2f per bin)\n",
bins, CELLHASHSIZE, total, (bins == 0) ? 0 :
(float)((float)total / (float)bins));
@@ -605,7 +608,7 @@ void PrintCellHashTable(int full, int filenum)
RecurseHashTable(&cell_dict, PrintCellHashTableElement);
Debug = OldDebug;
#ifndef TCL_NETGEN
if (full == 2) Printf("\n");
if (full >= 2) Printf("\n");
#endif
}
+4 -2
View File
@@ -104,10 +104,12 @@ struct valuelist {
/* Part 3: Keys & Defaults (kept in the cell record as a hash table) */
#define MERGE_NONE 0 /* Property does not change when devices merge */
#define MERGE_ADD 1 /* Properties sum with device merge */
#define MERGE_ADD_CRIT 2 /* Properties sum with device merge */
#define MERGE_ADD 1 /* Properties sum with device parallel merge */
#define MERGE_ADD_CRIT 2 /* Properties sum with device parallel merge */
#define MERGE_PAR 3 /* Properties add in parallel with device merge */
#define MERGE_PAR_CRIT 4 /* Properties add in parallel with device merge */
#define MERGE_SER 5 /* Properties sum with device parallel merge */
#define MERGE_SER_CRIT 6 /* Properties sum with device parallel merge */
/* Note: A "critical" merge means that the property causes the number of */
/* devices to change. e.g., transistor width is critical; transistor drain */
+58 -12
View File
@@ -25,8 +25,10 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdarg.h> /* what about varargs, like in pdutils.c ??? */
#endif
#ifdef IBMPC
#include <stdlib.h> /* for calloc(), free() */
#include <stdlib.h> /* for calloc(), free(), getenv() */
#ifndef IBMPC
#include <sys/types.h> /* for getpwnam() tilde expansion */
#include <pwd.h>
#endif
#ifdef TCL_NETGEN
@@ -42,6 +44,10 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
// Global storage for parameters from .PARAM
struct hashdict spiceparams;
// Global setting for auto-detect of empty subcircuits as
// black-box subcells.
int auto_blackbox = FALSE;
// Check if a token represents a numerical value (with
// units) or an expression. This is basically a hack
// to see if it either passes StringIsValue() or is
@@ -398,6 +404,7 @@ int renamepins(struct hashlist *p, int file)
void CleanupSubcell() {
int maxnode = 0;
int has_devices = FALSE;
struct objlist *sobj, *nobj, *lobj, *pobj;
if (CurrentCell == NULL) return;
@@ -409,6 +416,8 @@ void CleanupSubcell() {
lobj = NULL;
for (sobj = CurrentCell->cell; sobj != NULL;) {
nobj = sobj->next;
if (sobj->type == FIRSTPIN)
has_devices = TRUE;
if (sobj->node < 0) {
if (IsGlobal(sobj)) {
if (lobj != NULL)
@@ -437,6 +446,8 @@ void CleanupSubcell() {
lobj = sobj;
sobj = nobj;
}
if ((has_devices == FALSE) && (auto_blackbox == TRUE))
SetClass(CLASS_MODULE);
}
/*------------------------------------------------------*/
@@ -615,7 +626,7 @@ void ReadSpiceFile(char *fname, int filenum, struct cellstack **CellStackPtr,
}
SpiceTokNoNewline();
}
SetClass((blackbox) ? CLASS_MODULE : CLASS_SUBCKT);
SetClass((blackbox) ? CLASS_MODULE : CLASS_SUBCKT);
if (hasports == 0) {
// If the cell defines no ports, then create a proxy
@@ -743,7 +754,7 @@ skip_ends:
SpiceSkipNewLine();
}
else if (matchnocase(nexttok, ".INCLUDE")) {
char *iname, *iptr, *quotptr, *pathend;
char *iname, *iptr, *quotptr, *pathend, *userpath = NULL;
SpiceTokNoNewline();
if (nexttok == NULL) continue; /* Ignore if no filename */
@@ -755,12 +766,44 @@ skip_ends:
pathend = strrchr(fname, '/');
iptr = nexttok;
while (*iptr == '\'' || *iptr == '\"' || *iptr == '`') iptr++;
if ((pathend != NULL) && (*iptr != '/')) {
if ((pathend != NULL) && (*iptr != '/') && (*iptr != '~')) {
*pathend = '\0';
iname = (char *)MALLOC(strlen(fname) + strlen(iptr) + 2);
sprintf(iname, "%s/%s", fname, iptr);
*pathend = '/';
}
#ifndef IBMPC
else if ((*iptr == '~') && (*(iptr + 1) == '/')) {
/* For ~/<path>, substitute tilde from $HOME */
userpath = getenv("HOME");
iname = (char *)MALLOC(strlen(userpath) + strlen(iptr));
sprintf(iname, "%s%s", userpath, iptr + 1);
}
else if (*iptr == '~') {
/* For ~<user>/<path>, substitute tilde from getpwnam() */
struct passwd *passwd;
char *pathstart;
pathstart = strchr(iptr, '/');
if (pathstart) *pathstart = '\0';
passwd = getpwnam(iptr + 1);
if (passwd != NULL) {
userpath = passwd->pw_dir;
if (pathstart) {
*pathstart = '/';
iname = (char *)MALLOC(strlen(userpath) + strlen(pathstart) + 1);
sprintf(iname, "%s%s", userpath, pathstart);
}
else {
/* Almost certainly an error, but make the substitution anyway */
iname = STRDUP(userpath);
}
}
else {
/* Probably an error, but copy the filename verbatim */
iname = STRDUP(iptr);
}
}
#endif
else
iname = STRDUP(iptr);
@@ -795,7 +838,7 @@ skip_ends:
kl->key = strsave(nexttok);
kl->idx = 0;
kl->type = PROP_STRING;
kl->slop.ival = 0;
kl->slop.dval = 0.0;
kl->pdefault.string = strsave(eqptr + 1);
HashPtrInstall(nexttok, kl, &spiceparams);
}
@@ -1808,7 +1851,7 @@ char *ReadSpiceTop(char *fname, int *fnum, int blackbox)
SetExtension(name, fname, SPICE_EXTENSION);
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
Fprintf(stderr,"No file: %s\n",name);
Fprintf(stderr,"Error in SPICE file read: No file %s\n",name);
*fnum = filenum;
return NULL;
}
@@ -1898,12 +1941,15 @@ void IncludeSpice(char *fname, int parent, struct cellstack **CellStackPtr,
if ((filenum = OpenParseFile(fname, parent)) < 0) {
/* If that fails, see if a standard SPICE extension */
/* helps. But really, we're getting desperate at this */
/* point. */
/* helps, if the file didn't have an extension. But */
/* really, we're getting desperate at this point. */
SetExtension(name, fname, SPICE_EXTENSION);
if ((filenum = OpenParseFile(name, parent)) < 0) {
Fprintf(stderr,"No file: %s\n",name);
if (strchr(fname, '.') == NULL) {
SetExtension(name, fname, SPICE_EXTENSION);
filenum = OpenParseFile(name, parent);
}
if (filenum < 0) {
Fprintf(stderr,"Error in SPICE file include: No file %s\n",name);
return;
}
}
+1
View File
@@ -132,6 +132,7 @@ char *xilinx_class(model)
}
return(model);
}
void
Xilinx(cellname, filename)
char *cellname;
char *filename;
+1 -1
View File
@@ -271,7 +271,7 @@ void initialize_netcmp_datastructures(Widget w, Widget textwidget,
{
X_START();
Printf("Comparing cells '%s' and '%s'\n", get_cell(), get_other());
CreateTwoLists(get_cell(), get_other());
CreateTwoLists(get_cell(), get_other(), 0);
Permute();
#ifdef DEBUG_ALLOC
PrintCoreStats();
+2 -2
View File
@@ -66,8 +66,8 @@ CPP = gcc -E -x c
CXX = @CXX@
CPPFLAGS = -I. -I${NETGENDIR}
DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DUSE_TCL_STUBS -DUSE_TK_STUBS -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"60\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
DFLAGS_NOSTUB = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"60\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DUSE_TCL_STUBS -DUSE_TK_STUBS -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"90\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
DFLAGS_NOSTUB = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"90\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
CFLAGS = -g -m64 -fPIC -fPIC
DEPEND_FILE = Depend
+2 -2
View File
@@ -22,8 +22,8 @@ tclnetgen${SHDLIB_EXT}: ${EXTRA_LIBS}
@echo --- making netgen Tcl library \(tclnetgen${SHDLIB_EXT}\)
${RM} tclnetgen${SHDLIB_EXT}
${CC} ${CFLAGS} ${CPPFLAGS} -o $@ ${LDDL_FLAGS} \
${LD_RUN_PATH} ${EXTRA_LIBS} ${LD_EXTRA_LIBS} -lc ${LIBS} \
${LIB_SPECS} ${LDFLAGS}
${LD_RUN_PATH} ${EXTRA_LIBS} ${LD_EXTRA_LIBS} \
-lc ${LIBS} ${LIB_SPECS} ${LDFLAGS}
$(DESTDIR)${BINDIR}/netgen:
${RM} $@
+14 -14
View File
@@ -12,9 +12,9 @@ generated by GNU Autoconf 2.69. Invocation command line was
hostname = stravinsky
uname -m = x86_64
uname -r = 3.18.3-201.fc21.x86_64
uname -r = 4.1.13-100.fc21.x86_64
uname -s = Linux
uname -v = #1 SMP Mon Jan 19 15:59:31 UTC 2015
uname -v = #1 SMP Tue Nov 10 13:13:20 UTC 2015
/usr/bin/uname -p = x86_64
/bin/uname -X = unknown
@@ -50,7 +50,7 @@ configure:2584: found /bin/gcc
configure:2595: result: gcc
configure:2824: checking for C compiler version
configure:2833: gcc --version >&5
gcc (GCC) 4.9.2 20141101 (Red Hat 4.9.2-1)
gcc (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -61,9 +61,9 @@ Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.9.2/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.9.2-20141101/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.9.2-20141101/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.9.2-20150212/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.9.2-20150212/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.9.2 20141101 (Red Hat 4.9.2-1) (GCC)
gcc version 4.9.2 20150212 (Red Hat 4.9.2-6) (GCC)
configure:2844: $? = 0
configure:2833: gcc -V >&5
gcc: error: unrecognized command line option '-V'
@@ -125,7 +125,7 @@ configure: failed program was:
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define NETGEN_VERSION "1.5"
| #define NETGEN_REVISION "60"
| #define NETGEN_REVISION "90"
| /* end confdefs.h. */
| #include <ac_nonexistent.h>
configure:3384: result: gcc -E
@@ -146,7 +146,7 @@ configure: failed program was:
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define NETGEN_VERSION "1.5"
| #define NETGEN_REVISION "60"
| #define NETGEN_REVISION "90"
| /* end confdefs.h. */
| #include <ac_nonexistent.h>
configure:3447: checking for library containing strerror
@@ -261,7 +261,7 @@ configure: failed program was:
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define NETGEN_VERSION "1.5"
| #define NETGEN_REVISION "60"
| #define NETGEN_REVISION "90"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
@@ -302,7 +302,7 @@ configure: failed program was:
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define NETGEN_VERSION "1.5"
| #define NETGEN_REVISION "60"
| #define NETGEN_REVISION "90"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
@@ -382,7 +382,7 @@ configure: failed program was:
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define NETGEN_VERSION "1.5"
| #define NETGEN_REVISION "60"
| #define NETGEN_REVISION "90"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
@@ -454,7 +454,7 @@ configure: failed program was:
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define NETGEN_VERSION "1.5"
| #define NETGEN_REVISION "60"
| #define NETGEN_REVISION "90"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
@@ -521,7 +521,7 @@ configure:5949: checking for IceConnectionNumber in -lICE
configure:5974: gcc -o conftest -g conftest.c -lICE >&5
configure:5974: $? = 0
configure:5983: result: yes
configure:6705: creating ./config.status
configure:6704: creating ./config.status
## ---------------------- ##
## Running config.status. ##
@@ -621,7 +621,7 @@ CC='gcc'
CFLAGS='-g -m64 -fPIC'
CPP='gcc -E -x c'
CPPFLAGS=''
DEFS='-DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"60\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1'
DEFS='-DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"90\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1'
DEPEND_FLAG='-MM'
ECHO_C=''
ECHO_N='printf'
@@ -736,7 +736,7 @@ unused=''
#define PACKAGE_BUGREPORT "[email protected]"
#define PACKAGE_URL ""
#define NETGEN_VERSION "1.5"
#define NETGEN_REVISION "60"
#define NETGEN_REVISION "90"
#define STDC_HEADERS 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_STAT_H 1
+1 -1
View File
@@ -659,7 +659,7 @@ S["ECHO_T"]=""
S["ECHO_N"]="-n"
S["ECHO_C"]=""
S["DEFS"]="-DPACKAGE_NAME=\\\"netgen\\\" -DPACKAGE_TARNAME=\\\"netgen\\\" -DPACKAGE_VERSION=\\\"1.3\\\" -DPACKAGE_STRING=\\\"netgen\\ 1.3\\\" -DPACKAGE_BUGREPORT=\\\"eda-dev@open"\
"circuitdesign.com\\\" -DPACKAGE_URL=\\\"\\\" -DNETGEN_VERSION=\\\"1.5\\\" -DNETGEN_REVISION=\\\"60\\\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -"\
"circuitdesign.com\\\" -DPACKAGE_URL=\\\"\\\" -DNETGEN_VERSION=\\\"1.5\\\" -DNETGEN_REVISION=\\\"90\\\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -"\
"DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -D"\
"SIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHA"\
"VE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1"
+1 -2
View File
@@ -6081,8 +6081,7 @@ case $target in
;;
*darwin*)
$as_echo "#define macosx 1" >>confdefs.h
$as_echo "#define macosx macos" >> confdefs.h
if test "$CPP" = "cc -E" ; then
CPPFLAGS="$CPPFLAGS -no-cpp-precomp"
fi
+1 -1
View File
@@ -868,7 +868,7 @@ case $target in
AC_DEFINE(i386)
;;
*darwin*)
AC_DEFINE(macosx)
$as_echo "#define macosx macos" >> confdefs.h
if test "$CPP" = "cc -E" ; then
CPPFLAGS="$CPPFLAGS -no-cpp-precomp"
fi
+2 -2
View File
@@ -66,8 +66,8 @@ CPP = gcc -E -x c
CXX = @CXX@
CPPFLAGS = -I. -I${NETGENDIR}
DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DUSE_TCL_STUBS -DUSE_TK_STUBS -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"60\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
DFLAGS_NOSTUB = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"60\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DUSE_TCL_STUBS -DUSE_TK_STUBS -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"90\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
DFLAGS_NOSTUB = -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"netgen\" -DPACKAGE_TARNAME=\"netgen\" -DPACKAGE_VERSION=\"1.3\" -DPACKAGE_STRING=\"netgen\ 1.3\" -DPACKAGE_BUGREPORT=\"[email protected]\" -DPACKAGE_URL=\"\" -DNETGEN_VERSION=\"1.5\" -DNETGEN_REVISION=\"90\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DDBUG_OFF=1 -DTCL_NETGEN=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DSHDLIB_EXT=\".so\" -DNDEBUG
CFLAGS = -g -m64 -fPIC -fPIC
DEPEND_FILE = Depend
+5 -5
View File
@@ -28,14 +28,14 @@ netgenexec${EXEEXT}: netgenexec.c
${LDFLAGS} ${LIBS} ${LIB_SPECS_NOSTUB}
netgen.tcl: netgen.tcl.in
sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g \
-e /SHDLIB_EXT/s%SHDLIB_EXT%${SHDLIB_EXT}%g \
sed -e 's%TCL_DIR%${TCLDIR}%g' \
-e 's%SHDLIB_EXT%${SHDLIB_EXT}%g' \
netgen.tcl.in > netgen.tcl
netgen.sh: netgen.sh.in
sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g \
-e /TCLLIB_DIR/s%TCLLIB_DIR%${TCL_LIB_DIR}%g \
-e /WISH_EXE/s%WISH_EXE%${WISH_EXE}%g \
sed -e 's%TCL_DIR%${TCLDIR}%g' \
-e 's%TCLLIB_DIR%${TCL_LIB_DIR}%g' \
-e 's%WISH_EXE%${WISH_EXE}%g' \
netgen.sh.in > netgen.sh
$(DESTDIR)${TCLDIR}/%: %
+407 -19
View File
@@ -20,10 +20,336 @@ foreach i $nlist {
}
}
if {${tcl_version} >= 8.6} {
load -lazy TCL_DIR/tclnetgenSHDLIB_EXT
} else {
load TCL_DIR/tclnetgenSHDLIB_EXT
# -lazy option not needed if stubs libraries are handled correctly
# load -lazy TCL_DIR/tclnetgenSHDLIB_EXT
load TCL_DIR/tclnetgenSHDLIB_EXT
#----------------------------------------------------------------
# Convert LVS list result into a JSON file
#----------------------------------------------------------------
proc netgen::convert_to_json {filename lvs_final} {
set pidx [string last . $filename]
set jsonname [string replace $filename $pidx end ".json"]
if {![catch {open $jsonname w} fjson]} {
puts $fjson "\["
# Outer list is of each cell compared
set clen [llength $lvs_final]
set cidx 0
foreach circuit $lvs_final {
incr cidx
puts $fjson " \{"
set nkeys [llength $circuit]
set kidx 0
foreach {key value} $circuit {
incr kidx 2
switch $key {
name {
puts $fjson " \"${key}\": \["
set cktval [lindex $value 0]
puts $fjson " \"${cktval}\","
set cktval [lindex $value 1]
puts $fjson " \"${cktval}\""
if {$kidx == $nkeys} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
pins {
puts $fjson " \"${key}\": \["
puts $fjson " \["
set cktval [lindex $value 0]
foreach pin [lrange $cktval 0 end-1] {
puts $fjson " \"$pin\","
}
set pin [lindex $cktval end]
puts $fjson " \"$pin\""
puts $fjson " \], \["
set cktval [lindex $value 1]
foreach pin [lrange $cktval 0 end-1] {
puts $fjson " \"$pin\","
}
set pin [lindex $cktval end]
puts $fjson " \"$pin\""
puts $fjson " \]"
if {$kidx == $nkeys} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
nets {
puts $fjson " \"${key}\": \["
set cktval [lindex $value 0]
puts $fjson " $cktval,"
set cktval [lindex $value 1]
puts $fjson " $cktval"
if {$kidx == $nkeys} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
devices {
puts $fjson " \"${key}\": \["
puts $fjson " \["
set cktval [lindex $value 0]
foreach dev [lrange $cktval 0 end-1] {
set devname [lindex $dev 0]
set devnum [lindex $dev 1]
puts $fjson " \[\"${devname}\", ${devnum}\],"
}
set dev [lindex $cktval end]
set devname [lindex $dev 0]
set devnum [lindex $dev 1]
puts $fjson " \[\"${devname}\", ${devnum} \]"
puts $fjson " \], \["
set cktval [lindex $value 1]
foreach dev [lrange $cktval 0 end-1] {
set devname [lindex $dev 0]
set devnum [lindex $dev 1]
puts $fjson " \[\"${devname}\", ${devnum} \],"
}
set dev [lindex $cktval end]
set devname [lindex $dev 0]
set devnum [lindex $dev 1]
puts $fjson " \[\"${devname}\", ${devnum} \]"
puts $fjson " \]"
if {$kidx == $nkeys} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
goodnets -
badnets {
puts $fjson " \"${key}\": \["
set glen [llength $value]
set gidx 0
foreach group $value {
incr gidx
puts $fjson " \["
puts $fjson " \["
set cktval [lindex $group 0]
set nlen [llength $cktval]
set nidx 0
foreach net $cktval {
incr nidx
puts $fjson " \["
set netname [lindex $net 0]
puts $fjson " \"$netname\","
puts $fjson " \["
set netconn [lindex $net 1]
foreach fanout [lrange $netconn 0 end-1] {
set devname [lindex $fanout 0]
set pinname [lindex $fanout 1]
set count [lindex $fanout 2]
if {$count == {}} {set count 0}
puts $fjson " \[ \"$devname\", \"$pinname\", $count \],"
}
set fanout [lindex $netconn end]
set devname [lindex $fanout 0]
set pinname [lindex $fanout 1]
set count [lindex $fanout 2]
if {$count == {}} {set count 0}
puts $fjson " \[ \"$devname\", \"$pinname\", $count \]"
puts $fjson " \]"
if {$nidx == $nlen} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
puts $fjson " \], \["
set cktval [lindex $group 1]
set nlen [llength $cktval]
set nidx 0
foreach net $cktval {
incr nidx
puts $fjson " \["
set netname [lindex $net 0]
puts $fjson " \"$netname\","
puts $fjson " \["
set netconn [lindex $net 1]
foreach fanout [lrange $netconn 0 end-1] {
set devname [lindex $fanout 0]
set pinname [lindex $fanout 1]
set count [lindex $fanout 2]
if {$count == {}} {set count 0}
puts $fjson " \[ \"$devname\", \"$pinname\", $count \],"
}
set fanout [lindex $netconn end]
set devname [lindex $fanout 0]
set pinname [lindex $fanout 1]
set count [lindex $fanout 2]
if {$count == {}} {set count 0}
puts $fjson " \[ \"$devname\", \"$pinname\", $count \]"
puts $fjson " \]"
if {$nidx == $nlen} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
puts $fjson " \]"
if {$gidx == $glen} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
if {$kidx == $nkeys} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
goodelements -
badelements {
puts $fjson " \"${key}\": \["
set glen [llength $value]
set gidx 0
foreach group $value {
incr gidx
puts $fjson " \["
puts $fjson " \["
set cktval [lindex $group 0]
set ilen [llength $cktval]
set iidx 0
foreach inst $cktval {
incr iidx
puts $fjson " \["
set instname [lindex $inst 0]
puts $fjson " \"$instname\","
puts $fjson " \["
set instpins [lindex $inst 1]
foreach fanout [lrange $instpins 0 end-1] {
set pinname [lindex $fanout 0]
set count [lindex $fanout 1]
if {$count == {}} {set count 0}
puts $fjson " \[ \"$pinname\", $count \],"
}
set fanout [lindex $instpins end]
set pinname [lindex $fanout 0]
set count [lindex $fanout 1]
if {$count == {}} {set count 0}
puts $fjson " \[ \"$pinname\", $count \]"
puts $fjson " \]"
if {$iidx == $ilen} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
puts $fjson " \], \["
set cktval [lindex $group 1]
set ilen [llength $cktval]
set iidx 0
foreach inst $cktval {
incr iidx
puts $fjson " \["
set instname [lindex $inst 0]
puts $fjson " \"$instname\","
puts $fjson " \["
set instpins [lindex $inst 1]
foreach fanout [lrange $instpins 0 end-1] {
set pinname [lindex $fanout 0]
set count [lindex $fanout 1]
if {$count == {}} {set count 0}
puts $fjson " \[ \"$pinname\", $count \],"
}
set fanout [lindex $instpins end]
set pinname [lindex $fanout 0]
set count [lindex $fanout 1]
if {$count == {}} {set count 0}
puts $fjson " \[ \"$pinname\", $count \]"
puts $fjson " \]"
if {$iidx == $ilen} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
puts $fjson " \]"
if {$gidx == $glen} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
if {$kidx == $nkeys} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
properties {
puts $fjson " \"${key}\": \["
set plen [llength $value]
set pidx 0
foreach instance $value {
incr pidx
puts $fjson " \["
set instnames [lindex $instance 0]
set instname0 [lindex $instnames 0]
puts $fjson " \["
puts $fjson " \"${instname0}\","
puts $fjson " \["
foreach property [lrange $instance 1 end-1] {
set prop0 [lindex $property 0]
set propname [lindex $prop0 0]
set propval [lindex $prop0 1]
puts $fjson " \[\"${propname}\", \"${propval}\"\],"
}
set property [lindex $instance end]
set prop0 [lindex $property 0]
set propname [lindex $prop0 0]
set propval [lindex $prop0 1]
puts $fjson " \[\"${propname}\", \"${propval}\"\]"
puts $fjson " \]"
puts $fjson " \],"
set instname1 [lindex $instnames 1]
puts $fjson " \["
puts $fjson " \"${instname1}\","
puts $fjson " \["
foreach property [lrange $instance 1 end-1] {
set prop1 [lindex $property 1]
set propname [lindex $prop1 0]
set propval [lindex $prop1 1]
puts $fjson " \[\"${propname}\", \"${propval}\"\],"
}
set property [lindex $instance end]
set prop1 [lindex $property 1]
set propname [lindex $prop1 0]
set propval [lindex $prop1 1]
puts $fjson " \[\"${propname}\", \"${propval}\"\]"
puts $fjson " \]"
puts $fjson " \]"
if {$pidx == $plen} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
if {$kidx == $nkeys} {
puts $fjson " \]"
} else {
puts $fjson " \],"
}
}
}
}
if {$cidx == $clen} {
puts $fjson " \}"
} else {
puts $fjson " \},"
}
}
puts $fjson "\]"
}
close $fjson
}
#----------------------------------------------------------------
@@ -34,9 +360,30 @@ if {${tcl_version} >= 8.6} {
# Use the "canonical" command to parse the file and cell names,
# although if the cells have not been read in yet, then the
# original syntax of filename or {filename cellname} is required.
#
# "args" is passed to verify and may therefore contain only the
# value "-list" or nothing. If "-list", then output is returned
# as a nested list.
#----------------------------------------------------------------
proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out}} {
proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
set dolist 0
set dojson 0
foreach arg $args {
if {$arg == "-list"} {
puts stdout "Generating list result"
set dolist 1
set lvs_final {}
} elseif {$arg == "-json"} {
puts stdout "Generating JSON file result"
set dolist 1
set dojson 1
set lvs_final {}
} elseif {$arg == "-blackbox"} {
puts stdout "Treating empty subcircuits as black-box cells"
netgen::model blackbox on
}
}
# Allow name1 or name2 to be a list of {filename cellname},
# A single <filename>, or any valid_cellname form if the
@@ -128,33 +475,56 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out}} {
if {$perrors > 0} {
puts stdout "Warning: There were errors reading the setup file"
}
} else {
} elseif {[string first nosetup $setupfile] < 0} {
netgen::permute default ;# transistors and resistors
netgen::property default
}
puts stdout "Comparison output logged to file $logfile"
netgen::log file $logfile
netgen::log start
netgen::log echo off
set endval [netgen::compare hierarchical "$fnum1 $cell1" "$fnum2 $cell2"]
if {[string first nolog $logfile] < 0} {
puts stdout "Comparison output logged to file $logfile"
netgen::log file $logfile
netgen::log start
netgen::log echo off
set dolog true
} else {
set dolog false
}
if {$dolist == 1} {
set endval [netgen::compare -list hierarchical "$fnum1 $cell1" "$fnum2 $cell2"]
} else {
set endval [netgen::compare hierarchical "$fnum1 $cell1" "$fnum2 $cell2"]
}
if {$endval == {}} {
netgen::log put "No cells in queue!\n"
return
}
set properr {}
while {$endval != {}} {
netgen::run converge
if {$dolist == 1} {
netgen::run -list converge
} else {
netgen::run converge
}
netgen::log echo on
if {[verify equivalent]} {
# Resolve automorphisms by pin and property
netgen::run resolve
if {$dolist == 1} {
netgen::run -list resolve
} else {
netgen::run resolve
}
set uresult [verify unique]
if {$uresult == 0} {
netgen::log put " Networks match locally but not globally.\n"
netgen::log put " Probably connections are swapped.\n"
netgen::log put " Check the end of logfile ${logfile} for implicated nodes.\n"
netgen::verify nodes
if {$dolist == 1} {
verify -list nodes
} else {
verify nodes
}
# Flatten the non-matching subcircuit (but not the top-level cells)
if {[netgen::print queue] != {}} {
@@ -165,8 +535,13 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out}} {
} else {
# Match pins
netgen::log echo off
set result [equate pins "$fnum1 [lindex $endval 0]" \
"$fnum2 [lindex $endval 1]"]
if {$dolist == 1} {
set result [equate pins "$fnum1 [lindex $endval 0]" \
"$fnum2 [lindex $endval 1]"]
} else {
set result [equate -list pins "$fnum1 [lindex $endval 0]" \
"$fnum2 [lindex $endval 1]"]
}
if {$result != 0} {
equate classes "$fnum1 [lindex $endval 0]" \
"$fnum2 [lindex $endval 1]"
@@ -183,17 +558,30 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out}} {
}
}
netgen::log echo off
set endval [netgen::compare hierarchical]
if {$dolist == 1} {
catch {lappend lvs_final $lvs_out}
set lvs_out {}
set endval [netgen::compare -list hierarchical]
} else {
set endval [netgen::compare hierarchical]
}
}
netgen::log echo off
puts stdout "Result: " nonewline
netgen::log echo on
netgen::verify only
verify only
if {$properr != {}} {
netgen::log put "The following cells had property errors: $properr\n"
}
netgen::log end
if {$dolog} {
netgen::log end
}
puts stdout "LVS Done."
if {$dojson == 1} {
netgen::convert_to_json $logfile $lvs_final
} elseif {$dolist == 1} {
return $lvs_final
}
}
# It is important to make sure no netgen commands overlap with Tcl built-in
+263 -53
View File
@@ -1437,9 +1437,9 @@ _netgen_cells(ClientData clientData,
char *optstart;
int filenum = -1;
struct nlist *np = NULL;
int result, dolist = 0;
int result, printopt, dolist = 0, doall = 0, dotop = 0;
if (objc > 1) {
while (objc > 1) {
optstart = Tcl_GetString(objv[1]);
if (*optstart == '-') optstart++;
if (!strcmp(optstart, "list")) {
@@ -1447,27 +1447,41 @@ _netgen_cells(ClientData clientData,
objv++;
objc--;
}
else if (!strcmp(optstart, "all")) {
doall = 1;
objv++;
objc--;
}
else if (!strcmp(optstart, "top")) {
dotop = 1;
objv++;
objc--;
}
else {
result = CommonParseCell(interp, objv[1], &np, &filenum);
if (result != TCL_OK) return result;
objv++;
objc--;
}
}
if (objc == 1) {
PrintCellHashTable((dolist) ? 2 : 0, -1);
}
else if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "[list] [-all|-top|valid_filename]");
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "[list] [-top] [-all] [valid_filename]");
return TCL_ERROR;
}
else {
Tcl_Obj *lobj;
repstr = Tcl_GetString(objv[1]);
if (!strncmp(repstr, "-top", 4)) {
if (dotop) {
if (dolist)
lobj = Tcl_NewListObj(0, NULL);
else
Fprintf(stdout, "Top level cells: ");
np = FirstCell();
while (np != NULL) {
if (np->flags & CELL_TOP) {
if ((np->flags & CELL_TOP) && ((filenum == -1) ||
(np->file == filenum))) {
if (dolist)
Tcl_ListObjAppendElement(interp, lobj,
Tcl_NewStringObj(np->name, -1));
@@ -1483,11 +1497,13 @@ _netgen_cells(ClientData clientData,
return TCL_OK;
}
else if (strncmp(repstr, "-all", 4)) {
result = CommonParseCell(interp, objv[1], &np, &filenum);
if (result != TCL_OK) return result;
else {
if (dolist)
printopt = (doall) ? 3 : 2;
else
printopt = (doall) ? 1 : 0;
PrintCellHashTable(printopt, filenum);
}
PrintCellHashTable((dolist) ? 2 : 1, filenum);
}
return TCL_OK;
}
@@ -1528,8 +1544,27 @@ _netgen_model(ClientData clientData,
return TCL_ERROR;
}
/* Check for "model blackbox on|off" */
/* Behavior is to treat empty subcircuits as blackbox cells */
if ((objc > 1) && !strcmp(Tcl_GetString(objv[1]), "blackbox")) {
if ((objc > 2) && !strcmp(Tcl_GetString(objv[2]), "on")) {
auto_blackbox = TRUE;
return TCL_OK;
}
else if ((objc > 2) && !strcmp(Tcl_GetString(objv[2]), "off")) {
auto_blackbox = FALSE;
return TCL_OK;
}
else if (objc == 2) {
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(auto_blackbox));
return TCL_OK;
}
}
result = CommonParseCell(interp, objv[1], &tp, &fnum);
if (result != TCL_OK) return result;
if (result != TCL_OK)
return result;
if (objc == 3) {
model = Tcl_GetString(objv[2]);
@@ -1641,6 +1676,13 @@ _netgen_model(ClientData clientData,
retclass = modelclasses[SUBCKT_IDX];
break;
case CLASS_MODULE:
if (auto_blackbox)
retclass = modelclasses[BLACKBOX_IDX];
else
retclass = modelclasses[MODULE_IDX];
break;
default: /* (includes case CLASS_UNDEF) */
retclass = modelclasses[UNDEF_IDX];
break;
@@ -1939,13 +1981,24 @@ int
_netcmp_compare(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *name1, *name2, *file1, *file2;
int fnum1, fnum2;
char *name1, *name2, *file1, *file2, *optstart;
int fnum1, fnum2, dolist = 0;
int dohierarchy = FALSE;
int assignonly = FALSE;
int argstart = 1, qresult, llen, result;
struct Correspond *nextcomp;
struct nlist *tp;
Tcl_Obj *flist = NULL;
if (objc > 1) {
optstart = Tcl_GetString(objv[1]);
if (*optstart == '-') optstart++;
if (!strcmp(optstart, "list")) {
dolist = 1;
objv++;
objc--;
}
}
if (objc > 1) {
if (!strncmp(Tcl_GetString(objv[argstart]), "assign", 6)) {
@@ -2033,18 +2086,15 @@ _netcmp_compare(ClientData clientData,
ConvertGlobals(name2, fnum2);
}
// Run cleanup a 2nd time; this corrects for cells that have no ports
// but define global nodes that are brought out as ports by
// ConvertGlobals().
CreateTwoLists(name1, fnum1, 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);
CreateTwoLists(name1, fnum1, name2, fnum2, dolist);
}
// Return the names of the two cells being compared, if doing "compare
// hierarchical"
// hierarchical". If "-list" was specified, then append the output
// to the end of the list.
if (dohierarchy) {
Tcl_Obj *lobj;
@@ -2242,6 +2292,19 @@ _netcmp_run(ClientData clientData,
};
int result, index;
int automorphisms;
char *optstart;
int dolist;
dolist = 0;
if (objc > 1) {
optstart = Tcl_GetString(objv[1]);
if (*optstart == '-') optstart++;
if (!strcmp(optstart, "list")) {
dolist = 1;
objv++;
objc--;
}
}
if (objc == 1)
index = RESOLVE_IDX;
@@ -2260,8 +2323,13 @@ _netcmp_run(ClientData clientData,
else {
enable_interrupt();
while (!Iterate() && !InterruptPending);
_netcmp_verify(clientData, interp, 1, NULL);
if (dolist) {
result = _netcmp_verify(clientData, interp, 2, objv - 1);
}
else
result = _netcmp_verify(clientData, interp, 1, NULL);
disable_interrupt();
if (result != TCL_OK) return result;
}
break;
case RESOLVE_IDX:
@@ -2304,7 +2372,7 @@ _netcmp_run(ClientData clientData,
}
if (PropertyErrorDetected) {
Fprintf(stdout, "There were property errors.\n");
PrintPropertyResults();
PrintPropertyResults(dolist);
}
disable_interrupt();
}
@@ -2318,9 +2386,17 @@ _netcmp_run(ClientData clientData,
/* Syntax: netgen::verify [option] */
/* options: nodes, elements, only, all, */
/* equivalent, or unique. */
/* option "-list" may be used with nodes, elements */
/* all, or no option. */
/* Formerly: v */
/* Results: */
/* For only, equivalent, unique: Return 1 if */
/* verified, zero if not. */
/* Side Effects: */
/* For options elements, nodes, and all without */
/* option -list: Write output to log file. */
/* For -list options, append list to global */
/* variable "lvs_out", if it exists. */
/*------------------------------------------------------*/
int
@@ -2333,8 +2409,23 @@ _netcmp_verify(ClientData clientData,
enum OptionIdx {
NODE_IDX, ELEM_IDX, PROP_IDX, ONLY_IDX, ALL_IDX, EQUIV_IDX, UNIQUE_IDX
};
char *optstart;
int result, index = -1;
int automorphisms;
int dolist = 0;
Tcl_Obj *egood, *ebad, *ngood, *nbad;
if (objc > 1) {
optstart = Tcl_GetString(objv[1]);
if (*optstart == '-') optstart++;
if (!strcmp(optstart, "list")) {
dolist = 1;
egood = ngood = NULL;
ebad = nbad = NULL;
objv++;
objc--;
}
}
if (objc != 1 && objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv,
@@ -2365,14 +2456,28 @@ _netcmp_verify(ClientData clientData,
if (objc == 1 || index == NODE_IDX || index == ALL_IDX) {
if (Debug == TRUE)
PrintIllegalNodeClasses(); // Old style
else
FormatIllegalNodeClasses(); // Side-by-side
else {
FormatIllegalNodeClasses(); // Side-by-side, to log file
if (dolist) {
nbad = ListNodeClasses(FALSE); // As Tcl nested list
#if 0
ngood = ListNodeClasses(TRUE); // As Tcl nested list
#endif
}
}
}
if (objc == 1 || index == ELEM_IDX || index == ALL_IDX) {
if (Debug == TRUE)
PrintIllegalElementClasses(); // Old style
else
FormatIllegalElementClasses(); // Side-by-side
else {
FormatIllegalElementClasses(); // Side-by-side, to log file
if (dolist) {
ebad = ListElementClasses(FALSE); // As Tcl nested list
#if 0
egood = ListElementClasses(TRUE); // As Tcl nested list
#endif
}
}
}
disable_interrupt();
if (index == EQUIV_IDX || index == UNIQUE_IDX)
@@ -2403,9 +2508,57 @@ _netcmp_verify(ClientData clientData,
Fprintf(stdout, "Property errors were found.\n");
}
}
if ((index == PROP_IDX) && (PropertyErrorDetected != 0)) {
PrintPropertyResults();
#if 0
if (dolist) {
ngood = ListNodeClasses(TRUE); // As Tcl nested list
egood = ListElementClasses(TRUE); // As Tcl nested list
}
#endif
if ((index == PROP_IDX) && (PropertyErrorDetected != 0)) {
PrintPropertyResults(dolist);
}
}
}
/* If "dolist" has been specified, then return the */
/* list-formatted output. For "verify nodes" or */
/* "verify elements", return the associated list. */
/* For "verify" or "verify all", return a nested */
/* list of {node list, element list}. */
if (dolist)
{
if (objc == 1 || index == NODE_IDX || index == ALL_IDX) {
if (nbad == NULL) nbad = Tcl_NewListObj(0, NULL);
Tcl_SetVar2Ex(interp, "lvs_out", NULL,
Tcl_NewStringObj("badnets", -1),
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
Tcl_SetVar2Ex(interp, "lvs_out", NULL, nbad,
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
#if 0
if (ngood == NULL) ngood = Tcl_NewListObj(0, NULL);
Tcl_SetVar2Ex(interp, "lvs_out", NULL,
Tcl_NewStringObj("goodnets", -1),
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
Tcl_SetVar2Ex(interp, "lvs_out", NULL, ngood,
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
#endif
}
if (objc == 1 || index == ELEM_IDX || index == ALL_IDX) {
if (ebad == NULL) ebad = Tcl_NewListObj(0, NULL);
Tcl_SetVar2Ex(interp, "lvs_out", NULL,
Tcl_NewStringObj("badelements", -1),
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
Tcl_SetVar2Ex(interp, "lvs_out", NULL, ebad,
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
#if 0
if (egood == NULL) egood = Tcl_NewListObj(0, NULL);
Tcl_SetVar2Ex(interp, "lvs_out", NULL,
Tcl_NewStringObj("goodelements", -1),
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
Tcl_SetVar2Ex(interp, "lvs_out", NULL, egood,
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
#endif
}
}
return TCL_OK;
@@ -2566,13 +2719,23 @@ _netcmp_equate(ClientData clientData,
NODE_IDX, ELEM_IDX, CLASS_IDX, PINS_IDX
};
int result, index;
char *name1 = NULL, *name2 = NULL;
struct nlist *tp1, *tp2;
char *name1 = NULL, *name2 = NULL, *optstart;
struct nlist *tp1, *tp2, *SaveC1, *SaveC2;
struct objlist *ob1, *ob2;
int file1, file2;
int i, l1, l2, ltest, lent;
int i, l1, l2, ltest, lent, dolist = 0;
Tcl_Obj *tobj1, *tobj2, *tobj3;
if (objc > 1) {
optstart = Tcl_GetString(objv[1]);
if (*optstart == '-') optstart++;
if (!strcmp(optstart, "list")) {
dolist = 1;
objv++;
objc--;
}
}
if ((objc != 2) && (objc != 4) && (objc != 6)) {
Tcl_WrongNumArgs(interp, 1, objv, "?nodes|elements|classes|pins? name1 name2");
return TCL_ERROR;
@@ -2728,7 +2891,7 @@ _netcmp_equate(ClientData clientData,
break;
case PINS_IDX:
if (ElementClasses == NULL) {
if ((ElementClasses == NULL) && (auto_blackbox == FALSE)) {
if (CurrentCell == NULL)
Fprintf(stderr, "Equate elements: no current cell.\n");
Fprintf(stderr, "Equate pins: cell %s and/or %s has no elements.\n",
@@ -2736,19 +2899,30 @@ _netcmp_equate(ClientData clientData,
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
return TCL_OK;
}
if (tp1 == Circuit1 && tp2 == Circuit2) {
if (MatchPins(tp1, tp2)) {
Fprintf(stdout, "Cell pin lists are equivalent.\n");
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
}
else {
Fprintf(stdout, "Cell pin lists for %s and %s altered to match.\n",
name1, name2);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
}
else if (ElementClasses == NULL) {
/* This has been called outside of a netlist compare, */
/* probably to force name matching of pins on black-box */
/* devices. But MatchPins only works if tp1 == Circuit1 */
/* and tp2 == Circuit2, so preserve these values and */
/* recover afterward (what a hack). */
SaveC1 = Circuit1;
SaveC2 = Circuit2;
Circuit1 = tp1;
Circuit2 = tp2;
}
if (MatchPins(tp1, tp2, dolist)) {
Fprintf(stdout, "Cell pin lists are equivalent.\n");
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
}
else {
Fprintf(stderr, "Function not yet defined outside of LVS scope.\n");
Fprintf(stdout, "Cell pin lists for %s and %s altered to match.\n",
name1, name2);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
}
if (ElementClasses == NULL) {
/* Recover temporarily set global variables (see above) */
Circuit1 = SaveC1;
Circuit2 = SaveC2;
}
break;
@@ -2971,8 +3145,12 @@ _netcmp_equate(ClientData clientData,
/* netgen::property <device>|<model> <option> */
/* yes|no */
/* Where <option> is one of: */
/* serial --- allow/prohibit serial combination */
/* serial --- allow/prohibit serial combination */
/* parallel --- allow/prohibit parallel combination */
/* or */
/* netgen::property parallel none */
/* --- prohibit parallel combinations by */
/* default. */
/* */
/* Formerly: (none) */
/* Results: */
@@ -3008,13 +3186,18 @@ _netcmp_property(ClientData clientData,
};
char *mergeoptions[] = {
"none", "add", "add_critical", "par", "par_critical", NULL
"none", "add", "add_critical", "par", "par_critical",
"parallel", "parallel_critical", "ser_critical", "ser",
"serial_critical", "serial", NULL
};
enum MergeOptionIdx {
NONE_IDX, ADD_ONLY_IDX, ADD_CRIT_IDX, PAR_ONLY_IDX, PAR_CRIT_IDX
NONE_IDX, ADD_ONLY_IDX, ADD_CRIT_IDX,
PAR_ONLY_IDX, PAR_CRIT_IDX, PAR2_ONLY_IDX, PAR2_CRIT_IDX,
SER_CRIT_IDX, SER_IDX, SER2_CRIT_IDX, SER2_IDX
};
char *yesno[] = {
"on", "yes", "true", "enable", "allow", "off", "no", "false", "disable", "prohibit", NULL
"on", "yes", "true", "enable", "allow",
"off", "no", "false", "disable", "prohibit", NULL
};
if (objc < 2) {
@@ -3043,7 +3226,8 @@ _netcmp_property(ClientData clientData,
PropertyDelete(tp->name, tp->file, "pd");
break;
case CLASS_RES: case CLASS_RES3:
PropertyMerge(tp->name, tp->file, "l", MERGE_PAR_CRIT);
PropertyMerge(tp->name, tp->file, "w", MERGE_ADD_CRIT);
PropertyMerge(tp->name, tp->file, "l", MERGE_SER_CRIT);
tp->flags |= COMB_SERIAL;
break;
case CLASS_CAP: case CLASS_ECAP: case CLASS_CAP3:
@@ -3060,6 +3244,22 @@ _netcmp_property(ClientData clientData,
}
return TCL_OK;
}
else if ((objc == 3) && (!strcmp(Tcl_GetString(objv[1]), "parallel"))) {
if (!strcmp(Tcl_GetString(objv[2]), "none")) {
GlobalParallelNone = TRUE;
SetParallelCombine(FALSE);
}
else if (!strcmp(Tcl_GetString(objv[2]), "all")) {
GlobalParallelNone = FALSE;
SetParallelCombine(TRUE);
}
else {
Tcl_SetResult(interp, "Bad option, should be property parallel none|all",
NONE);
return TCL_ERROR;
}
return TCL_OK;
}
result = CommonParseCell(interp, objv[1], &tp, &fnum);
if (result != TCL_OK) return result;
@@ -3351,11 +3551,21 @@ _netcmp_property(ClientData clientData,
mergeval = MERGE_ADD_CRIT;
break;
case PAR_ONLY_IDX:
case PAR2_ONLY_IDX:
mergeval = MERGE_PAR;
break;
case PAR_CRIT_IDX:
case PAR2_CRIT_IDX:
mergeval = MERGE_PAR_CRIT;
break;
case SER_CRIT_IDX:
case SER2_CRIT_IDX:
mergeval = MERGE_SER_CRIT;
break;
case SER_IDX:
case SER2_IDX:
mergeval = MERGE_SER;
break;
}
PropertyMerge(tp->name, fnum, Tcl_GetString(tobj1), mergeval);
}
@@ -3861,7 +4071,7 @@ int Tclnetgen_Init(Tcl_Interp *interp)
if (cadroot == NULL) cadroot = CAD_DIR;
Tcl_SetVar(interp, "CAD_ROOT", cadroot, TCL_GLOBAL_ONLY);
Tcl_PkgProvide(interp, "Tclnetgen", "1.1");
Tcl_PkgProvide(interp, "Tclnetgen", NETGEN_VERSION);
if ((consoleinterp = Tcl_GetMaster(interp)) == NULL)
consoleinterp = interp;