Compare commits

...
103 Commits
Author SHA1 Message Date
Tim Edwards afe0e9f758 Merge branch 'master' into netgen-1.5 2022-01-01 03:00:43 -05:00
Tim Edwards 68ec2b2a7c Modified two print statements to change "%s(%d)" to "%s (%d)" as
is my typographic preference.
2021-12-31 13:30:13 -05:00
Tim Edwards ca49a90ed6 Merged changes from github issue #45 from Mitch Bailey. These changes
speed up the time needed to flatten an instance, and add clarity to the
output by specifying the file number for each cell name being modified
during the pre-match stage.
2021-12-31 12:13:11 -05:00
Tim Edwards e487890641 Merge branch 'master' into netgen-1.5 2021-12-31 03:00:42 -05:00
Tim Edwards e07a5b416a Removed lvs_manager.py, which is a derived file and should not have
ended up in the repository, as pointed out by Mitch Bailey in github
issue #44.  Added lvs_manager.py to .gitignore to prevent that from
happening again in the future.
2021-12-30 09:19:44 -05:00
Tim Edwards bb44d3f827 Merge branch 'master' into netgen-1.5 2021-12-30 03:00:43 -05:00
Tim Edwards 8094740048 Corrected a problem that stems from code that was deprecated and
marked as unneeded, so I simply removed the code rather than
debug the issue, which was that buses got the delimeters erased
for checking but never put back again.  Also:  Modified the verilog
reading code so that if an empty set "()" is given for a pin, then
the initial proxy, which is a single net with the name prefix
"_noconnect_", can be promoted to a bus if further processing
reveals it to be a bus and not a single-bit signal.
2021-12-29 14:31:38 -05:00
Tim Edwards c25c4e1160 Merge branch 'master' into netgen-1.5 2021-12-27 03:00:18 -05:00
Tim Edwards a026d37f11 Corrected a place in the verilog read routine where ob->next is
used when ob may be NULL.  Added a check in front for ob == NULL.
Also:  Changed the disconnected node alert so that it does not
mention nodes marked "port_mismatch_error".  These are disconnected
by definition, will show up in the pin list, and printing them as
"disconnected pins" is just confusing to the end user.
2021-12-26 10:31:48 -05:00
Tim Edwards 8ed4e3cf38 Merge branch 'master' into netgen-1.5 2021-12-20 03:00:02 -05:00
Tim Edwards ab614b63f7 Corrected the last commit (again) because FlattenUnmatched()
should not be called after CreateTwoLists().  CreateTwoLists()
was being called in one case only to print the contents of the
cells, so that part was pulled out into a separate routine.
2021-12-19 16:25:32 -05:00
Tim Edwards 83dce151d8 Made a correction to the last commit. The "FlattenUnmatched()"
routine does not have an exact equivalent in PrematchLists() and
needs to be run beforehand.  This fix keeps FlattenUnmatched()
from being run on all cells at the beginning and restricts it
to being run on the contents of individual cells during matching,
after checking if either of the cells is a black-box.  Avoiding
flattening contents of one side when the other is a black-box
(or simply doesn't contain any subcircuits or devices) prevents
unnecessary flattening of cells that will never get compared.
2021-12-17 20:31:41 -05:00
Tim Edwards 69838d79e4 Merge branch 'master' into netgen-1.5 2021-12-16 03:00:06 -05:00
Tim Edwards de18ae85a4 Removed the call to FlattenUnmatched() in CreateCompareQueue().
The FlattenUnmatched() is inefficient compared to just letting
the PrematchLists() routine handle flattening of unmatched
instances.
2021-12-15 11:05:00 -05:00
Tim Edwards fc7c9371e8 Merge branch 'master' into netgen-1.5 2021-12-08 03:00:14 -05:00
Tim Edwards 9908349fdd Modified the output of "debug on" mode to print the instance name
for each connection in the dump of incorrect nets.  This is
definitely critical to finding local swapping errors, and needs
to be incorporated into the non-debug mode, preferably as part of
the JSON file dump.  But that's for later.
2021-12-07 16:33:43 -05:00
Tim Edwards 964bb0e91a Added sorting of the output lines for items which match both name and
contents (previously wasn't done), and also added sorting for items with
non-matching names which have only one item in the group for each circuit
(so they must be matching in some sense).  This makes the output a bit
more readable without re-enabling the compute-intensive sorting method
for non-matching entries.
2021-12-07 15:34:45 -05:00
Tim Edwards 0d19868145 Merge branch 'master' into netgen-1.5 2021-11-18 03:00:10 -05:00
Tim Edwards cfdc60104b Updated version to go along with the merge of pull request #39
from Kamyar Mohajerani, with a few minor edits such as renaming
my_hash to hashcase, as a better counterpoint to "hashnocase".
2021-11-17 12:05:01 -05:00
Kamyar Mohajerani 879711def3 revert removal of superfluous 'extern'
.. for functions based on review comments
2021-11-17 11:53:04 -05:00
Kamyar Mohajerani 5def9e0ffc remove <xlocale.h> 2021-11-16 22:18:59 -05:00
Kamyar Mohajerani b5c70decbd fix wrong 'hash' being linked in + C99 compat
This fixes crash on macos due to wrong hash() being linked in.
It also makes sure that proper function defs are declared and available
(as required by C99) to make compile possible in newer compilers (e.g.
Apple clang) and to some extend prevent similar linkage issues happening
again.
2021-11-16 20:06:15 -05:00
Tim Edwards 6b4eb01ee8 Merge branch 'master' into netgen-1.5 2021-11-12 03:00:29 -05:00
Tim Edwards 20f6d76926 Corrected the "format" command, which failed to return TCL_OK
after executing the command with non-zero options.
2021-11-11 08:42:46 -05:00
Tim Edwards 737b2a73bf Merge branch 'master' into netgen-1.5 2021-10-30 03:00:02 -04:00
Tim Edwards e4a15f12fb Updated version to go along with the merge of pull request #37
from Mitch Bailey.
2021-10-29 18:11:03 -04:00
D. Mitch Bailey c6fb204f0c Cosmetic report changes.
Changed line breaks in log and stdout to better differentiate subcircuits.
Added merged series device counts and differentiated from parallel merged device counts.
Added file number to disconnected net, merged count messages.
Changed black box errors to show file numbers instead of hard coded values.
Final error cell list changed from all on one line to one per line.
Removed redundant display in black box warning.
2021-10-29 18:10:30 -04:00
Tim Edwards 6b8c6d1718 Merge branch 'master' into netgen-1.5 2021-10-29 03:00:32 -04:00
Tim Edwards c7dfff4bb9 Updated version to go along with the merge of pull request #36 from
Mitch Bailey.
2021-10-28 14:24:47 -04:00
D. Mitch Bailey 12fa080212 When comparing instance counts to determine is flattening makes a better match,
flatten cells that have no instances in common.
Display a screen message to indicate a re-compare afterr flattening.
2021-10-28 01:29:32 -07:00
Tim Edwards 610eebb758 Merge branch 'master' into netgen-1.5 2021-10-24 03:00:12 -04:00
Tim Edwards 4c4bad08f2 After reverting back to before pull request #33, updated the
version and re-applied the fixes from issue #34.
2021-10-23 14:47:30 -04:00
Tim Edwards 23ff2f00a3 Revert "Remove disconnected ports after flattening."
This reverts commit 6d6da9cf5c.

Reverting back to before pull request #33.
2021-10-23 14:42:37 -04:00
Tim Edwards d09f0dd53b Revert "Flatten unmatched cells that don't contain instances from the other file."
This reverts commit 42b1acc564.

Reverting back to before pull request #33.
2021-10-23 14:42:32 -04:00
Tim Edwards 56d4d581e7 Revert "Minor syntactical editing of pull request #33, and updated version"
This reverts commit 6ceeddf096.

Reverting back to before pull request #33.
2021-10-23 14:42:28 -04:00
Tim Edwards 1bb4866226 Revert "Made a correction to the flattening code, removed a duplicate"
This reverts commit 625e043eff.

Reverting back to before pull request #33.
2021-10-23 14:41:58 -04:00
Tim Edwards 97058c5017 Merge branch 'master' into netgen-1.5 2021-10-16 03:00:13 -04:00
Tim Edwards 625e043eff Made a correction to the flattening code, removed a duplicate
print statement, and clarified the messages about non-matching
circuits at the end, all of them suggestions made by Mitch
Bailey (see issue #34 on github).
2021-10-15 09:13:02 -04:00
Tim Edwards aa120460d0 Merge branch 'master' into netgen-1.5 2021-10-15 03:00:03 -04:00
Tim Edwards 6ceeddf096 Minor syntactical editing of pull request #33, and updated version
to go along with the merge of the pull request (from Mitch Bailey).
2021-10-14 11:22:20 -04:00
D. Mitch Bailey 42b1acc564 Flatten unmatched cells that don't contain instances from the other file. 2021-10-13 21:00:49 -07:00
D. Mitch Bailey 6d6da9cf5c Remove disconnected ports after flattening. 2021-10-13 01:15:15 -07:00
Tim Edwards ea5cbacf1c Merge branch 'master' into netgen-1.5 2021-10-06 03:00:12 -04:00
Tim Edwards bbcc79fc72 Updated version to go along with merge of pull request #32 from
Harald Pretl.
2021-10-05 09:41:24 -04:00
Harald Pretl 6d5946eaf2 Added MacOS (Big Sur) installation instructions. 2021-10-03 13:58:34 +02:00
Tim Edwards cdd768addc Merge branch 'master' into netgen-1.5 2021-09-08 03:00:04 -04:00
Tim Edwards 18dcac73bc Updated version to go along with the merge of pull request #31
from Mitch Bailey.
2021-09-07 22:27:31 -04:00
D. Mitch Bailey 1338e3beb5 Removed debugging statement. 2021-09-07 19:16:33 -07:00
D. Mitch Bailey df1c4c5153 Changed debug print increment from 100 -> 10000. 2021-09-07 10:19:27 -07:00
D. Mitch Bailey a05ede99db Added missing newlines
Print debug message every 100 lines
2021-09-06 18:31:38 -07:00
D. Mitch Bailey 2d6f1f71b5 Reduce and clarify debugging message.
Add missing new line to "Flattening non-matched subcircuits.
2021-09-02 22:29:17 -07:00
Tim Edwards 66cf2b82d9 Merge branch 'master' into netgen-1.5 2021-08-30 03:00:02 -04:00
Tim Edwards d7355cea95 Updated the vezzal docker image version for CI. 2021-08-29 19:41:14 -04:00
Tim Edwards bc4192496b Merge branch 'master' into netgen-1.5 2021-08-28 13:15:58 -04:00
Tim Edwards 32585a572c Corrected the badge link at the top of README.md to point to my
own repository instead of a fork.
2021-08-28 13:14:11 -04:00
Tim Edwards 168e5502a1 Merge branch 'master' into netgen-1.5 2021-08-06 11:38:38 -04:00
Tim Edwards e773739e7d Updated VERSION as a forced change to check continuous integration
on github.
2021-08-06 11:37:29 -04:00
Tim Edwards 8d4b621b7d Merge branch 'master' into netgen-1.5 2021-08-06 11:25:01 -04:00
Tim Edwards 583cc3a151 Updated VERSION to go along with the merge of pull request #27 from
Sai Charan.  Subsequent mirror pushes to github should trigger the
continuous integration.
2021-08-06 11:18:56 -04:00
Sai Charan Lanka bdd7d25943 Update main.yml 2021-08-06 11:18:32 -04:00
Sai Charan Lanka 903b813821 Update README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka 1f9d4317e3 Update main.yml 2021-08-06 11:18:32 -04:00
Sai Charan Lanka 7b8086fc3a Update main.yml 2021-08-06 11:18:32 -04:00
Sai Charan Lanka e80f70e67b Update main.yml 2021-08-06 11:18:32 -04:00
Sai Charan Lanka 6cc898b34b Update README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka 30bbc28c17 Update README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka 5ec0db678a Update README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka e643563d4e Update README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka 67f2801aa1 Update README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka f76f2e002a Update README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka 9ec613b0cb Update README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka 9128eeda60 Update README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka aeedf5fae9 Update README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka f50dfd9261 Update README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka 409ce224ad Update README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka f50093e6c6 Rename README to README.md 2021-08-06 11:18:32 -04:00
Sai Charan Lanka a27ac8c679 Update README 2021-08-06 11:18:32 -04:00
Sai Charan Lanka 883755eed3 Update main.yml 2021-08-06 11:18:31 -04:00
Sai Charan Lanka 484cb26eee Update main.yml 2021-08-06 11:18:31 -04:00
Sai Charan Lanka 7cc6996017 Update main.yml 2021-08-06 11:18:31 -04:00
Sai Charan Lanka 7f9acf6a1a Update main.yml 2021-08-06 11:18:31 -04:00
Sai Charan Lanka e1a3ae5619 Update main.yml 2021-08-06 11:18:31 -04:00
Sai Charan Lanka 4e75889605 Update main.yml 2021-08-06 11:18:31 -04:00
Sai Charan Lanka e017811239 Update main.yml 2021-08-06 11:18:31 -04:00
Sai Charan Lanka 4468d36462 Update main.yml 2021-08-06 11:18:31 -04:00
Sai Charan Lanka b99fb96259 Update main.yml 2021-08-06 11:18:31 -04:00
Sai Charan Lanka ec8299ea14 Update main.yml 2021-08-06 11:18:31 -04:00
Sai Charan Lanka 376296eda5 Update main.yml 2021-08-06 11:18:31 -04:00
Sai Charan Lanka 30acb8be63 Update main.yml 2021-08-06 11:18:31 -04:00
Sai Charan Lanka 7e15a26417 Create main.yml 2021-08-06 11:18:31 -04:00
Tim Edwards ba3e862552 Merge branch 'master' into netgen-1.5 2021-07-30 03:00:29 -04:00
Tim Edwards 21750da6c4 Corrected the Makefile in the python directory to set the
lvs_manager.py script to be executable, or else "netgen -gui" will
not work.
2021-07-29 10:45:44 -04:00
Tim Edwards cf6dd2a638 Merge branch 'master' into netgen-1.5 2021-07-16 03:00:11 -04:00
Tim Edwards a332c23524 Corrected an error in "series_sort" that will overwrite memory
randomly if combining series devices that do not have an "S"
property (which is the typical case).  This will normally result in
a crash.
2021-07-15 16:03:43 -04:00
Tim Edwards b6d896e73f Merge branch 'master' into netgen-1.5 2021-07-12 03:00:10 -04:00
Tim Edwards 064195ecc9 Reinstated some code that had been commented out that prints pin
information for a non-matching pin in circuit1 and generates a
proxy pin in circuit2---there is some case where this is redundant,
I think, but I need to find the example.
2021-07-11 17:04:50 -04:00
Tim Edwards 88d53fab15 Correction to the verilog parser to recognize modifiers such as
"~", "!", or "-" in front of variable names in a pin list that would
render the module behavioral verilog.
2021-07-11 12:06:16 -04:00
Tim Edwards c287b6cd28 A previous attempt (in revision 193) to make the "lvs" script stop
saying that pins were mismatched when pin matching was never run
accidentally resulted in pin matching not being applied to black-box
entries.  This has been corrected.
2021-07-11 10:58:30 -04:00
Tim Edwards 9251ce2a48 Merge branch 'master' into netgen-1.5 2021-07-11 03:00:33 -04:00
Tim Edwards 0a0a6bcf63 Modified the handling of missing pins (again) such that netgen
continues to allow missing pins to match unconnected pins, but
*only* on subcircuits below the top level.  This essentially forces
layouts to separate merged pins with metal resistors, although
there should be an option in magic's ext2spice routine that allows
"equiv" statements, when declaring equivalence of two ports, to be
replaced by a zero volt source or zero ohm ideal resistor.
2021-07-10 13:54:14 -04:00
Tim Edwards 72ef2f2637 Corrected the pin matching so that it runs the same loop on unmatched
pins on non-black-boxed circuits as it does not black-boxed circuits,
but specifically looking for pins that are disconnected on both sides,
since those do not appear in the node list and are not otherwise
handled.  Otherwise, disconnected pins will appear to have disappeared
from the first netlist.
2021-07-10 11:25:07 -04:00
Tim Edwards aa82164c08 Merge branch 'master' into netgen-1.5 2021-07-09 03:00:34 -04:00
Tim Edwards 287f5963d1 Corrected an error that crept into the netgen.tcl script that causes
the "failed pin matching" error message to appear for cells mismatching
topology (in which case pin matching is never done).
2021-07-08 08:56:52 -04:00
23 changed files with 443 additions and 214 deletions
+40
View File
@@ -0,0 +1,40 @@
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
pull_request:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Runs a set of commands using the runners shell
#- name: Logging into Dockerhub
# run: docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Pulling the docker image
run: docker pull vezzal/vezzal:v1
- name: Start the container with the docker image
run: docker run -id --name test_netgen vezzal/vezzal:v1 bash | exit
- name: Run the testing on the container and send the mail
run: docker exec test_netgen /vezzal/test_netgen.sh "[email protected],[email protected]" ${{ secrets.MAILING_KEY }}
+1
View File
@@ -7,6 +7,7 @@ config.log
scripts/config.log
config.status
scripts/config.status
python/lvs_manager.py
*.o
*.so
*~
+48 -1
View File
@@ -1,4 +1,8 @@
NETGEN: VERSION 1.5
![Continuous Integration](https://github.com/RTimothyEdwards/netgen/actions/workflows/main.yml/badge.svg)
# NETGEN
### VERSION 1.5
NETGEN is a general-purpose netlist management system. It can read
and write several netlist formats, including NTK (Caltech, CMU),
@@ -87,6 +91,49 @@ and IRSIM version 9.7:
Note: For FreeBSD, use 'gmake' instead.
Note: On MacOS (Big Sur) follow the following procedure. If you have installed `xschem` and `magic` already on MacOS then steps (1) and (2) can likely be skipped.
**1) Build Tcl for X11**
We are following the instructions from `xschem` (https://github.com/StefanSchippers/xschem/blob/master/README_MacOS.md).
* Download `Tcl` from https://prdownloads.sourceforge.net/tcl/tcl8.6.10-src.tar.gz
We are using not `opt` but `opt2` so that this `Tcl` does not interfere with `tcl-tk` from HomeBrew.
```
./configure --prefix=/usr/local/opt2/tcl-tk
make
make install
```
**2) Build Tk for X11**
* Download `Tk` from https://prdownloads.sourceforge.net/tcl/tk8.6.10-src.tar.gz
```
./configure --prefix=/usr/local/opt2/tcl-tk \
--with-tcl=/usr/local/opt2/tcl-tk/lib --with-x \
--x-includes=/opt/X11/include --x-libraries=/opt/X11/lib
make
make install
```
**3) Build netgen**
We need to provide this custom-built `tcl-tk` and suppress compilation errors.
```
./configure --with-tcl=/usr/local/opt2/tcl-tk/lib \
--with-tk=/usr/local/opt2/tcl-tk/lib \
--x-includes=/opt/X11/include \
--x-libraries=/opt/X11/lib \
CFLAGS=-Wno-error=implicit-function-declaration
make
make install
```
IN CASE OF FAILURE
-------------------
Please contact me (tim@opencircuitdesign.com) to report compile-time and
+1 -1
View File
@@ -1 +1 @@
1.5.192
1.5.217
+4 -3
View File
@@ -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
View File
@@ -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);
+8
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+116 -59
View File
@@ -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;
@@ -4121,6 +4164,7 @@ void series_sort(struct objlist *ob1, struct nlist *tp1, int idx1, int run)
sval = 1;
cval = slop = 0.0;
for (i = 0; i < run; i++) {
sl = NULL;
merge_type = MERGE_NONE;
for (p = 0;; p++) {
vl = &(obp->instance.props[p]);
@@ -4149,13 +4193,13 @@ void series_sort(struct objlist *ob1, struct nlist *tp1, int idx1, int run)
proplist[i].value = cval * (double)sval;
proplist[i].slop = slop;
proplist[i].avalue = 0;
sl->value.ival = 1;
if (sl) sl->value.ival = 1;
}
else if (merge_type == MERGE_S_PAR) {
proplist[i].value = cval / (double)sval;
proplist[i].slop = slop;
proplist[i].avalue = 0;
sl->value.ival = 1;
if (sl) sl->value.ival = 1;
}
else {
/* Components which declare no series addition method stay unsorted */
@@ -6891,11 +6935,6 @@ int reorderpins(struct hashlist *p, int file)
"Ordering will be arbitrary.\n", tc2->name);
for (ob = ptr->cell; ob != NULL; ) {
/* Catch badness */
if (ob->next && (ob->next->node > 100000)) {
Fprintf(stdout, "Bad.\n");
}
if (ob->type == FIRSTPIN) {
if ((*matchfunc)(ob->model.class, tc2->name)) {
char *sptr = ob->instance.name;
@@ -7343,35 +7382,44 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
/* so apply only to black-box (CELL_PLACEHOLDER) entries. */
/* (Semi-hack: Allow "!" global flag) */
if (((tc1->flags & CELL_PLACEHOLDER) && (tc2->flags & CELL_PLACEHOLDER)) ||
(NodeClasses == NULL)) {
ob1 = tc1->cell;
bangptr1 = strrchr(ob1->name, '!');
if (bangptr1 && (*(bangptr1 + 1) == '\0'))
*bangptr1 = '\0';
else bangptr1 = NULL;
ob1 = tc1->cell;
bangptr1 = strrchr(ob1->name, '!');
if (bangptr1 && (*(bangptr1 + 1) == '\0'))
*bangptr1 = '\0';
else bangptr1 = NULL;
for (i = 0; i < numorig; i++) {
if (*(cover + i) == (char)0) {
j = 0;
for (ob2 = tc2->cell; ob2 != NULL; ob2 = ob2->next) {
char *name1, *name2;
for (i = 0; i < numorig; i++) {
if (*(cover + i) == (char)0) {
j = 0;
for (ob2 = tc2->cell; ob2 != NULL; ob2 = ob2->next) {
char *name1, *name2;
if (!IsPort(ob2)) break;
if (!IsPort(ob2)) break;
bangptr2 = strrchr(ob2->name, '!');
if (bangptr2 && (*(bangptr2 + 1) == '\0'))
*bangptr2 = '\0';
else bangptr2 = NULL;
bangptr2 = strrchr(ob2->name, '!');
if (bangptr2 && (*(bangptr2 + 1) == '\0'))
*bangptr2 = '\0';
else bangptr2 = NULL;
name1 = ob1->name;
name2 = ob2->name;
name1 = ob1->name;
name2 = ob2->name;
/* Recognize proxy pins as matching */
if (!strncmp(name1, "proxy", 5)) name1 +=5;
if (!strncmp(name2, "proxy", 5)) name2 +=5;
/* Recognize proxy pins as matching unconnected pins */
if (!strncmp(name1, "proxy", 5) && (ob2->node == -1)) name1 +=5;
if (!strncmp(name2, "proxy", 5) && (ob1->node == -1)) name2 +=5;
if ((*matchfunc)(name1, name2)) {
/* If both sides have unconnected nodes, then pins with */
/* matching names are an automatic match. Otherwise, if */
/* matching black-box entries, then pins are always */
/* matched by name. */
if (((ob1->node == -1) && (ob2->node == -1)) ||
(((tc1->flags & CELL_PLACEHOLDER) &&
(tc2->flags & CELL_PLACEHOLDER)) ||
(NodeClasses == NULL))) {
if ((*matchfunc)(name1, name2)) {
ob2->model.port = i; /* save order */
*(cover + i) = (char)1;
@@ -7398,13 +7446,15 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
Tcl_NewStringObj(ob2->name, -1));
}
#endif
if (bangptr2) *bangptr2 = '!';
break;
}
if (bangptr2) *bangptr2 = '!';
j++;
}
if (bangptr2) *bangptr2 = '!';
j++;
}
ob1 = ob1->next;
}
ob1 = ob1->next;
if (bangptr1) *bangptr1 = '!';
}
@@ -7456,6 +7506,12 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
if ((obt == NULL) && (notempty == 1)) {
ob2->node = -2; // Will run this through cleanuppins
needclean2 = 1;
/* On the top level, missing pins are an error, even if */
/* they appear to match unconnected pins on the other side. */
if (CompareQueue == NULL)
result = 0;
#ifdef TCL_NETGEN
if (dolist) {
Tcl_ListObjAppendElement(netgeninterp, plist1,
@@ -7543,7 +7599,8 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
}
if (ob1 == NULL || ob1->type != PORT || ob1->node >= 0
|| (ob1->node < 0 && tc1->class == CLASS_MODULE)) {
|| (ob1->node < 0 && tc1->class == CLASS_MODULE)
|| (ob1->node < 0 && ob1->model.port == -1)) {
/* Add a proxy pin to tc2 */
obn = (struct objlist *)CALLOC(1, sizeof(struct objlist));
@@ -7560,8 +7617,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
obn->instance.name = NULL;
obn->node = -1;
#if 0
/* Note: This pin has already been accounted for */
/* Note: Has this pin already been accounted for? */
if (Debug == 0) {
if (strcmp(ob1->name, "(no pins)")) {
for (m = 0; m < left_col_end; m++) *(ostr + m) = ' ';
@@ -7577,7 +7633,6 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
Fprintf(stderr, "No netlist match for cell %s pin %s\n",
tc1->name, ob1->name);
}
#endif
if (ob2 == tc2->cell) {
obn->next = ob2;
@@ -7890,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());
@@ -7950,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();
+11
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+13
View File
@@ -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
View File
@@ -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
View File
@@ -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 {
+8
View File
@@ -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 */
+30 -52
View File
@@ -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.
@@ -1577,6 +1577,14 @@ nextinst:
}
new_port->net = wire_bundle;
}
else if (nexttok[0] == '~' || nexttok[0] == '!' || nexttok[0] == '-') {
/* All of these imply that the signal is logically manipulated */
/* in turn implying behavioral code. */
Printf("Module '%s' is not structural verilog, "
"making black-box.\n", model);
SetClass(CLASS_MODULE);
goto skip_endmodule;
}
else
new_port->net = strsave(nexttok);
@@ -1770,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;
@@ -1927,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);
}
}
@@ -2109,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;
@@ -2231,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
View File
@@ -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();
+10
View File
@@ -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 */
+1
View File
@@ -29,6 +29,7 @@ lvs_manager.py: lvs_manager.py.in
$(DESTDIR)${INSTALL_PYDIR}/lvs_manager.py: lvs_manager.py
${RM} $@
${CP} lvs_manager.py $@
chmod a+x $@
$(DESTDIR)${INSTALL_PYDIR}/treeviewsplit.py: treeviewsplit.py
${RM} $@
+19 -15
View File
@@ -532,7 +532,7 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
}
set properr {}
set matcherr {}
set pinsgood 0
set pinsgood -1
while {$endval != {}} {
if {$dolist == 1} {
netgen::run -list converge
@@ -562,12 +562,13 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
if {[netgen::print queue] != {}} {
if {([lsearch $noflat [lindex $endval 0]] == -1) &&
([lsearch $noflat [lindex $endval 1]] == -1)} {
netgen::log put " Flattening non-matched subcircuits $endval"
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"
lappend matcherr [lindex $endval 0]
netgen::log put " Continuing with black-boxed subcircuits $endval\n"
lappend matcherr [lindex $endval 0]"($fnum1)"
lappend matcherr [lindex $endval 1]"($fnum2)"
# Match pins
netgen::log echo off
if {$dolist == 1} {
@@ -586,7 +587,6 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
}
}
} else {
# Match pins
netgen::log echo off
if {$dolist == 1} {
set result [equate -list pins "$fnum1 [lindex $endval 0]" \
@@ -599,23 +599,26 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
equate classes "$fnum1 [lindex $endval 0]" \
"$fnum2 [lindex $endval 1]"
}
set pinsgood $result
# If $uresult == -1 then these are black-box entries and
# $pinsgood should not be set to the resulting value.
if {$uresult > 0} {
set pinsgood $result
}
netgen::log echo on
}
if {$uresult == 2} {lappend properr [lindex $endval 0]}
} 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"
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"
lappend matcherr [lindex $endval 0]
netgen::log put " Continuing with black-boxed subcircuits $endval"
lappend matcherr [lindex $endval 0]
netgen::log put " Continuing with black-boxed subcircuits $endval\n"
lappend matcherr [lindex $endval 0]"($fnum1)"
lappend matcherr [lindex $endval 0]"($fnum2)"
# Match pins
netgen::log echo off
if {$dolist == 1} {
@@ -647,15 +650,16 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
puts stdout "Result: " nonewline
netgen::log echo on
if {$pinsgood == 0} {
netgen::log put "The top level cell failed pin matching.\n"
# NOTE: Need to disambiguate these two cases. . .
netgen::log put "Cells failed matching, or top level cell failed pin matching.\n"
} else {
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
View File
@@ -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.