Compare commits

..
277 Commits
Author SHA1 Message Date
Tim Edwards 1428580109 Merge branch 'master' into netgen-1.5 2020-06-17 03:00:38 -04:00
Tim Edwards fb0e1d10b0 Added back a correction that did not get made in this code base
and so didn't make it into the commit.  Handles implicit pins in
verilog.
2020-06-16 17:16:30 -04:00
Tim Edwards 6f81e1d294 Removed a restriction on the "equate pins" command such that pins
are matched on circuits that have no elements.  This condition
does not necessarily indicate an error, and matching pins has no
adverse affect (while refusing to match them certainly can).
2020-06-16 15:56:59 -04:00
Tim Edwards cec6d89474 Corrected an uninitialized variable error in the verilog reading code
that produces a segfault condition.
2020-06-16 12:52:29 -04:00
Tim Edwards 210dfb25c3 Merge branch 'master' into netgen-1.5 2020-06-04 03:00:24 -04:00
Tim Edwards 9bcca3ac21 Corrected the verilog parsing (yet again!) so that it does not
mistakenly flag bus delimiter characters inside backslash-escaped
names when looking for bus delimiters.
2020-06-03 17:00:42 -04:00
Tim Edwards 27f2ab8b3f Merge branch 'master' into netgen-1.5 2020-03-28 03:00:24 -04:00
Tim Edwards 6ae6a246e9 Some additional changes to better identify behavioral verilog
blocks.
2020-03-27 15:09:56 -04:00
Tim Edwards d985ea340e One more bug fix. . . unitialized variable error. 2020-03-27 12:47:24 -04:00
Tim Edwards 5ea7916ff1 Final (I hope) correction to netgen for handling signal wraparound
for buses applied to instance arrayes.
2020-03-27 12:15:57 -04:00
Tim Edwards cf9dedb2f7 Additional corrections; needed to maintain port width in the
scan structure because it is used in two different places and
would have to run a cost-prohibitive search of the cell's
object list.  Also, was missing recording a bus input/output
signal from an "input" or "output" statement (as opposed to
in-line signals in the I/O list).
2020-03-27 11:31:21 -04:00
Tim Edwards da667c3b17 Corrected handling of wire bundles in the verilog parser. 2020-03-27 08:48:48 -04:00
Tim Edwards 1be00bbd99 Merge branch 'master' into netgen-1.5 2020-03-27 03:00:21 -04:00
Tim Edwards 36aa373fb2 Corrected an error in the verilog read to correctly assign signals
to bus pins over an array of instances.  Takes care of the three
situations where the length of the signal bus equals the number of
instances;  where the length of the signal bus is a multiple of
the number of instances;  and where the number of instances is a
multiple of the length of the signal bus.
2020-03-26 11:53:52 -04:00
Tim Edwards 18f230fc46 Changed the default string size for tmpstr in flattenInstancesOf
from 200 to 1024.  Probably this should be dynamically allocated
and expanded as needed, as it is holding names that are of
increasing length as a hierarchy is descended and the instance
prefixes appended to the name.
2020-03-26 09:04:52 -04:00
Tim Edwards 03b241a5d4 Merge branch 'master' into netgen-1.5 2020-03-11 03:00:17 -04:00
Tim Edwards 0f5a618353 Corrected some problems with property matching in netcmp.c.
However, I have identified an issue that has not yet been resolved,
which is that there can be automorphisms that are potentially
broken by property matching.  Currently, the automorphisms are
arbitrarily resolved, then properties are matched---and may fail
accordingly.
2020-03-10 21:39:41 -04:00
Tim Edwards 43cebd1ef9 Merge branch 'master' into netgen-1.5 2020-03-06 03:00:39 -05:00
Tim Edwards 983c654086 Corrected error in property matching that can cause a segfault. 2020-03-05 15:20:46 -05:00
Tim Edwards 515fccc633 Corrected error in printing the name of a file when it is not found
in an "include" statement in either SPICE or verilog.  Modified pin
matching behavior to force cells in both netlists to be marked as
black-box entries if either one is marked as a black-box entry (this
may not be needed, but shouldn't do any harm, either).
2020-03-05 09:41:22 -05:00
Tim Edwards 0490959b07 Merge branch 'master' into netgen-1.5 2020-03-05 03:00:09 -05:00
Tim Edwards 7d94a7d5f6 Updated VERSION for new tarball. 2020-03-04 21:06:21 -05:00
Tim Edwards 39b3bb4d96 Changed behavior of MatchPins so that disconnected pins that are to
be removed because they do not match pins on the other cell being
compared, are marked with a different number (-2) than the usual
(-1).  CleanupPins then only removes those pins that are marked,
rather than all disconnected pins.
2020-03-04 21:01:43 -05:00
Tim Edwards 44673a04b6 Corrected the verilog parser to handle backslash-escape notation
in instance names, and to ignore bus delimiters inside backslash-
escaped names when determining if a net is a bus or not.
2020-03-04 16:55:53 -05:00
Tim Edwards a34f08b20a Corrected problem in flattening code that would attempt to flatten
a cell that mismatched by having zero instances.  Which fails and
repeats indefinitely.
2020-03-04 15:17:42 -05:00
Tim Edwards 240a276431 Changed behavior of "equate pins" to detect placeholder cells as
a different way of treating "black box" cells.  Even when the
"-blackbox" option is specified, any cell that has no definition
will be treated as a black box.  This allows comparison of a
black-box netlist against a non-black-box netlist, such as a
verilog netlist vs. a SPICE netlist, without forcing the black-box
attribute on the SPICE netlist.  Then, if the SPICE netlist
contains cells without elements such as fill/decap/tap cells,
they can be flattened and removed instead of forcing an error or
requiring the use of "ignore".
2020-03-03 10:50:45 -05:00
Tim Edwards dc841f3293 Merge branch 'master' into netgen-1.5 2020-02-24 17:35:04 -05:00
Tim Edwards f7037fc9e6 Updated VERSION manually; checking regeneration of tarball. 2020-02-24 17:34:38 -05:00
Tim Edwards 23fb9356f4 Corrected Makefile to use -include instead of include on defs.mak
so that "make distclean" works.
2020-02-24 17:31:06 -05:00
Tim Edwards 05bcfede69 Merge branch 'master' into netgen-1.5 2020-02-24 16:39:19 -05:00
Tim Edwards 027b4ae468 Test update of VERSION. 2020-02-24 16:38:56 -05:00
Tim Edwards 72ed78e55a Update for change in ocd git script 2020-02-24 15:04:59 -05:00
Tim Edwards 59bb8a89c0 "ocd_git_pure automatic update to repo" 2020-02-24 15:04:27 -05:00
Tim Edwards 08a442fda2 Removed VERSION from .gitignore, and updated VERSION. 2020-02-24 11:50:38 -05:00
Tim Edwards 9bdaee652e "ocd_git_pure automatic update to repo" 2020-02-18 03:00:14 -05:00
Tim Edwards 9879b58f83 Merge branch 'master' into netgen-1.5 2020-02-18 03:00:13 -05:00
Tim Edwards cc0cc512c0 Modified the Makefile per the patch from Charlene at OpenBSD to
add GR_LIBS to the list of options to CC, as this apparently
prevents problems with older binutils, and should not affect
builds otherwise.
2020-02-17 14:04:40 -05:00
Tim Edwards 9e3b705fcc "ocd_git_pure automatic update to repo" 2020-02-11 03:00:09 -05:00
Tim Edwards d2c9129242 Merge branch 'master' into netgen-1.5 2020-02-11 03:00:09 -05:00
Tim Edwards e9c0596dfe One additional change to allow a single value to the "format" command
to apply to both column widths.
2020-02-10 09:17:45 -05:00
Tim Edwards 9a1e295367 Based on code from John Wood, added command "netgen::format <col1_width>
<col2_width>" to set the output format width, to avoid the fixed column
widths of 41 characters which can truncate long strings in the output
such as deep cell hierarchies.  This command can be placed in the setup
script to widen the output columns to accomodate the result (to-do:
provide an "auto" mode to automatically determine the best width).
2020-02-10 09:11:34 -05:00
Tim Edwards 942f421fa3 "ocd_git_pure automatic update to repo" 2020-01-30 03:01:39 -05:00
Tim Edwards 6bc948d8ba Merge branch 'master' into netgen-1.5 2020-01-30 03:01:38 -05:00
Tim Edwards d7272e4ea1 One correction to a variable not pointing to the correct distributed
install location for --with-distdir.
2020-01-28 13:51:23 -05:00
Tim Edwards 7f4b5817e2 Corrected configure.in to correctly use withval for setting the
with-distdir option.
2020-01-28 13:48:24 -05:00
Tim Edwards b5ab38d5d7 Added a distributed install option "--with-distdir=" which replaces
"prefix" with the specified path during install, so that netgen can
be installed in a separate location to be migrated to the final
install location, without appending the entire install path to
DESTDIR.
2020-01-28 10:49:42 -05:00
Tim Edwards c1ad37f05a "ocd_git_pure automatic update to repo" 2020-01-14 03:00:47 -05:00
Tim Edwards 9edefe7d59 Merge branch 'master' into netgen-1.5 2020-01-14 03:00:47 -05:00
Tim Edwards bf671937b9 Changed the behavior with respect to backslashes in the JSON so that
they are converted to the double-backslash escape that is the proper
JSON syntax for backslashes, instead of being removed, which changes
the name and can be confusing.
2020-01-13 09:03:36 -05:00
Tim Edwards a16086d2e9 Added handling of backslash characters in instance names in the
JSON output.  Previously, only net names were checked for
backslash characters.
2020-01-13 09:00:48 -05:00
Tim Edwards f6b9629521 "ocd_git_pure automatic update to repo" 2019-11-20 03:00:33 -05:00
Tim Edwards 7b2e01f2af Merge branch 'master' into netgen-1.5 2019-11-20 03:00:33 -05:00
Tim Edwards 0e03f0bf97 Corrected an error that allows a variable to be used uninitialized
in parallel_sort, resulting in a (potentially intermittant)
segfault condition.
2019-11-19 11:45:49 -05:00
Tim Edwards 224050f153 "ocd_git_pure automatic update to repo" 2019-10-09 03:00:08 -04:00
Tim Edwards 74e8c3e168 Merge branch 'master' into netgen-1.5 2019-10-09 03:00:08 -04:00
Tim Edwards f12d03fcff Corrected the verilog parser for handling parameters and parameters
with increment/decrement syntax at the end.  Also the parser now
handles additional keywords associated with behavioral verilog
(initial, specify) and flags modules with them as black-box entries.
2019-10-08 12:18:13 -04:00
Tim Edwards 95a29fcd8c "ocd_git_pure automatic update to repo" 2019-09-11 03:00:07 -04:00
Tim Edwards 723a950fd3 Merge branch 'master' into netgen-1.5 2019-09-11 03:00:07 -04:00
Tim Edwards f04c72b984 Corrected missing case (greater-than or equal instead of greater than)
that affects vectors sliced across instance arrays.  Can cause vector
numbers to be out-of-bounds if an instance is arrayed but each
instance is listed separately.
2019-09-10 10:52:15 -04:00
Tim Edwards e3368cb22a "ocd_git_pure automatic update to repo" 2019-09-10 03:00:08 -04:00
Tim Edwards f06e6548bb Merge branch 'master' into netgen-1.5 2019-09-10 03:00:08 -04:00
Tim Edwards d38bd77825 Additional fixes to the verilog parser, including handling the
inline-I/O syntax with "wire" (e.g., "input wire [3:0] test")
and addressed the failure to add buses declared in inline I/O
to the list of known buses.
2019-09-09 13:42:21 -04:00
Tim Edwards ea4083893c A fairly large refactoring of the conditional handling code in the
verilog parser.  The parser should now be able to handle any
conditionals anywhere in the verilog code.  Also a bug was found
in the code that handles "a = b" assignments, and corrected.
2019-09-09 11:26:31 -04:00
Tim Edwards 72ed19ff36 "ocd_git_pure automatic update to repo" 2019-09-09 03:00:10 -04:00
Tim Edwards 39b8e3d14a Merge branch 'master' into netgen-1.5 2019-09-09 03:00:10 -04:00
Tim Edwards 3dc70148d1 Added support in the verilog parser for definitions anywhere in the
code using the backtick expression.  Also expanded the parsing of
"ifdef", "ifndef", and "endif" to include "elsif" and "else".  All
forms of "if" statements should now be handled, since verilog does
not define boolean expressions in ifdef operators like most languages
do.
2019-09-08 19:59:27 -04:00
Tim Edwards b63dfa8638 "ocd_git_pure automatic update to repo" 2019-08-20 03:00:20 -04:00
Tim Edwards f918f33c51 Merge branch 'master' into netgen-1.5 2019-08-20 03:00:20 -04:00
Tim Edwards a8576d26a9 Modified the netgen token parser, which (unwisely) is used both for
SPICE and verilog, in spite of the syntactical differences, to
account for the trick that qflow uses to replace the trailing space
in a verilog backslash-escaped name with a second backslash to get
a SPICE-compatible name that can be easily converted back to its
original verilog name without loss of information.  What this means
is that verilog can read SPICE files containing verilog names (which
is illegal SPICE) and verilog files containing hacked-backslash
names (which is illegal verilog).  This should be mostly harmless
although the wisdom of it is surely questionable.
2019-08-19 17:06:05 -04:00
Tim Edwards 63b2e48ea1 "ocd_git_pure automatic update to repo" 2019-08-13 03:00:08 -04:00
Tim Edwards 6e63f49d53 Merge branch 'master' into netgen-1.5 2019-08-13 03:00:07 -04:00
Tim Edwards a31390f152 Some corrections and updates to the commit of a few days ago to
handle wire bundles in wire assignments and pin connections.
Also corrected an error in which a comment after a wire statement
causes parsing issues.
2019-08-12 13:58:19 -04:00
Tim Edwards 419b6de29a "ocd_git_pure automatic update to repo" 2019-08-11 03:00:07 -04:00
Tim Edwards 205cf2aa58 Merge branch 'master' into netgen-1.5 2019-08-11 03:00:07 -04:00
Tim Edwards 44ec952872 Expanded the verilog parser to handle most forms of allowable wire and
assignment statements in verilog netlists, including assignment of
signal bundles.  Also corrected handling of signal bundles in pin
connections, which had been corrected in qflow's verilog parser but
not copied back to netgen.  Note that the syntax for signals multiplied
N times is still not handled.
2019-08-10 22:30:57 -04:00
Tim Edwards 52b6766fc8 "ocd_git_pure automatic update to repo" 2019-08-04 03:00:20 -04:00
Tim Edwards 7b0bdd29e8 Merge branch 'master' into netgen-1.5 2019-08-04 03:00:20 -04:00
Roman-Parise 3892529873 Removed generated files and edited .gitignore 2019-08-03 16:27:13 -04:00
Roman-Parise e3b51c6004 Fixed configure scripts for FreeBSD builds 2019-08-03 16:24:24 -04:00
Roman-Parise 3200b1bf95 Added FreeBSD installation comment to README. 2019-08-03 16:24:24 -04:00
Tim Edwards 814652e552 Updated tkcon.tcl, which was not corrected for a minor problem that
affects use with Tcl/Tk 8.6 (text option "-under" not recognized;
must be "-underline").
2019-08-03 16:22:26 -04:00
Tim Edwards 433cbd090a "ocd_git_pure automatic update to repo" 2019-07-25 03:00:16 -04:00
Tim Edwards 3087bd3337 Merge branch 'master' into netgen-1.5 2019-07-25 03:00:16 -04:00
Tim Edwards 4d138b64ca Corrected a missing "#ifdef TCL_NETGEN" around a Tcl subroutine
call, in objlist.c.
2019-07-24 11:13:25 -04:00
Tim Edwards b79a29d662 "ocd_git_pure automatic update to repo" 2019-07-15 03:00:27 -04:00
Tim Edwards bf9c61e412 Merge branch 'master' into netgen-1.5 2019-07-15 03:00:27 -04:00
Tim Edwards 9a2902abbb Removed "makedbh", which was copied from Magic (a long, long time
ago) when building out the netgen Makefile, and never removed.  The
script is very specific to Magic.
2019-07-14 09:39:39 -04:00
Tim Edwards 8d34bd372d "ocd_git_pure automatic update to repo" 2019-07-03 03:00:22 -04:00
Tim Edwards 229c2931a8 Merge branch 'master' into netgen-1.5 2019-07-03 03:00:22 -04:00
Tim Edwards 840f997133 Corrected a typo that somehow crept into the verilog delimiter set,
replacing the semicolon with a colon, which basically hoses the
verilog parser.
2019-07-02 10:45:10 -04:00
Tim Edwards b8da97deb1 "ocd_git_pure automatic update to repo" 2019-06-16 03:00:15 -04:00
Tim Edwards b7187d5899 Merge branch 'master' into netgen-1.5 2019-06-16 03:00:15 -04:00
Tim Edwards cb3cf592e8 Corrected the arguments to the configure script from the top-level
wrapper.
2019-06-15 12:43:13 -04:00
Tim Edwards b1d40e6d12 Corrected an error in the "permute forget" Tcl command option that
would attempt to access uninitialized variables, possibly causing
a crash.
2019-06-15 12:29:08 -04:00
Tim Edwards edbefbd1c4 Corrected an error in handling partial buses connected to a
full-bus pin in a module instance.
2019-06-15 03:05:50 -04:00
Tim Edwards d27d441c58 "ocd_git_pure automatic update to repo" 2019-06-13 03:00:05 -04:00
Tim Edwards 48c9e6b292 Merge branch 'master' into netgen-1.5 2019-06-13 03:00:05 -04:00
Tim Edwards 527cdb3dab Corrected error in detecting S and M. 2019-06-12 11:11:28 -04:00
Tim Edwards ced5846da3 "ocd_git_pure automatic update to repo" 2019-05-18 03:00:05 -04:00
Tim Edwards b99d33064f Merge branch 'master' into netgen-1.5 2019-05-18 03:00:04 -04:00
Tim Edwards ee66c00121 Further refined the last commit based on the change in definition of
a "critical property".  This lets a device define multiple critical
properties, all of which must match before additive properties can
be combined in the same device.
2019-05-17 14:33:26 -04:00
Tim Edwards f40a50d3b8 Corrected property value merging (again). By the rules of the
re-worked property command, "critical" properties must match
across devices so that all other properties can be combined as
specified (addition, parallel combination, or none).  The code was
still based on the older notion of the "critical" property being
the one to add (and thus preventing multiple properties from being
added in different ways).  This has now been fixed.
2019-05-17 11:25:34 -04:00
Tim Edwards 399472e940 "ocd_git_pure automatic update to repo" 2019-05-07 09:13:00 -04:00
Tim Edwards 8e0371e09b Corrected handling of verilog backslash-escaped names in the
verilog netlist parser.
2019-05-05 10:52:07 -04:00
Tim Edwards 395f857a82 Merge branch 'master' into work 2019-01-21 20:30:42 -05:00
Tim Edwards 9e59048731 Update at Mon Jan 21 20:30:40 EST 2019 by tim 2019-01-21 20:30:40 -05:00
Tim Edwards 7889e2ae73 Small typo, large effect; wrong reference to ob1 (instead of ob2) in
flatten.c can cause a segfault when analyzing whether flattening
cells generates a better circuit match.
2019-01-21 20:29:42 -05:00
Tim Edwards 8c7d2ae239 Merge branch 'master' into work 2019-01-09 20:31:57 -05:00
Tim Edwards e361640947 Update at Wed Jan 9 20:31:54 EST 2019 by tim 2019-01-09 20:31:54 -05:00
Tim Edwards 56b4174646 Fairly substantial overhaul of the tokenizing routine to better
handle verilog syntax.  Also:  Added SPICE voltage and current
sources as separate classes (as opposed to being converted to
subcircuits, which was how they were previously handled).  That
allowed voltage sources to be checked for zero value and removed
by shorting the ends together, as was being done for zero value
resistors (note that like zero-value resistors, removal is only
done if removing the component makes a better match than leaving
it in).  In particular, yosys has SPICE netlist output that
converts equality assignments ("assign a = b") into zero-value
voltage sources, so these components need to be treated as
non-physical elements.
2019-01-09 20:26:38 -05:00
Tim Edwards ccf2dc23c9 Merge branch 'master' into work 2018-11-19 08:12:59 -05:00
Tim Edwards f8ea27d8e8 Update at Mon Nov 19 08:12:57 EST 2018 by tim 2018-11-19 08:12:57 -05:00
Tim Edwards ef914e8d46 Corrected two instances of missing values on return from a function. 2018-11-19 08:12:12 -05:00
Tim Edwards f9cc4d3db6 Merge branch 'master' into work 2018-11-18 13:09:58 -05:00
Tim Edwards d8eefdad9a Update at Sun Nov 18 13:09:56 EST 2018 by tim 2018-11-18 13:09:56 -05:00
Tim Edwards 2cdf3c450f Extended the series/parallel merging setup commands to include
the possibility that a device (e.g., resistor or capacitor) may
not be a semiconductor device (in other words, a parasitic or
ideal device), and therefore uses "value" but not width and
length, and therefore "value" is a critical property to merge
both in series and parallel.  Corrected the series/parallel
network optimization to prevent it from setting both M and S
records > 1 on the same device (which is ambiguous).  To try
to get number of devices to match, where there are both series
and parallel devices, they will be merged across the critical
property early (before property matching).
2018-11-18 13:04:57 -05:00
Tim Edwards 079e0ab5d3 Corrected an error in the handling of node names in verilog that was
accidentally erasing array delimiters from node names, a move that
surprisingly has no effect at all on LVS until the cell containing
the truncated nodes is flattened, at which point it causes odd and
confusing behavior that seems to have nothing to do with node names
at all.
2018-11-14 19:53:19 -05:00
Tim Edwards f0cf6b52d3 Merge branch 'master' into work 2018-11-14 13:46:14 -05:00
Tim Edwards 9432bfc182 Update at Wed Nov 14 13:46:12 EST 2018 by tim 2018-11-14 13:46:12 -05:00
Tim Edwards 4fb892a64f Fixed configure script error that reports python3 as being
configured even when it is not found on the system.  This was only
a reporting error, and had no other repercussions.
2018-11-14 13:45:02 -05:00
Tim Edwards faadb78870 Merge branch 'master' into work 2018-11-12 16:33:17 -05:00
Tim Edwards 7fc668c2d4 Update at Mon Nov 12 16:33:14 EST 2018 by tim 2018-11-12 16:33:14 -05:00
Tim Edwards 13c45c6d0c Encountered a problem with parsing non-inlined ports of a module and
tracked it down to a "to be completed" comment in the source code.
So it is now completed.
2018-11-12 16:32:33 -05:00
Tim Edwards 5efe2151ed Merge branch 'master' into work 2018-10-31 14:05:11 -04:00
Tim Edwards 642de57418 Update at Wed Oct 31 14:05:09 EDT 2018 by tim 2018-10-31 14:05:09 -04:00
Tim Edwards 397444acd3 Modified the JSON generation script to backslash-escape backslashes
in verilog net names, which are apparently legal in verilog but not
in python strings (if not escaped).  This is somewhat critical for
running the LVS GUI as yosys can generate backslashes in generated
net names in the synthesized netlist.
2018-10-31 14:03:15 -04:00
Tim Edwards 5e5720e7be Merge branch 'master' into work 2018-10-29 15:19:57 -04:00
Tim Edwards 65c0f6b840 Update at Mon Oct 29 15:19:54 EDT 2018 by tim 2018-10-29 15:19:54 -04:00
Tim Edwards 09b2bb3316 Extended the verilog parser to account for the fact that there can
be whitespace between a wire/register name and its array delimiter.
2018-10-29 15:19:13 -04:00
Tim Edwards 41665036e9 Merge branch 'master' into work 2018-10-02 14:41:40 -04:00
Tim Edwards b4c189a114 Update at Tue Oct 2 14:41:38 EDT 2018 by tim 2018-10-02 14:41:38 -04:00
Tim Edwards 85af816ab8 Removed references to /usr/local/man/man1 and netgen.1, as the netgen.1
man page does not exist.  Running mkdirs on the empty directory causes
problems with "git rm".
2018-10-02 14:40:17 -04:00
Tim Edwards 4ba5425b6a Merge branch 'master' into work 2018-09-26 10:49:06 -04:00
Tim Edwards 83b2084a10 Update at Wed Sep 26 10:49:04 EDT 2018 by tim 2018-09-26 10:49:04 -04:00
Tim Edwards 0de1c232e4 Corrected property matching so that properties are promoted to
type double before sorting (previously, property promotion was
being done after parallel sorting).  Also, modified the verilog
file reading so that parameters and definitions that are numeric
are stored as numeric (not string) properties.
2018-09-26 10:46:55 -04:00
Tim Edwards b8e6f6c030 Merge branch 'master' into work 2018-09-24 15:13:32 -04:00
Tim Edwards a6742bca2e Update at Mon Sep 24 15:13:30 EDT 2018 by tim 2018-09-24 15:13:30 -04:00
Tim Edwards 3a03e769af Substantially improved verilog parsing (although almost certainly not
perfect).  Given the complexities of the verilog language, the simple
strtok() tokenizer used by the SPICE parser is not sufficient.  Wrote
a better tokenizer that can distinguish between whitespace and
functional tokens like parentheses, semicolons, etc., which are tokens
themselves but also token separators.
2018-09-24 15:09:29 -04:00
Tim Edwards 445f732f8b Merge branch 'master' into work 2018-08-08 11:28:45 -04:00
Tim Edwards b911aa7b2e Update at Wed Aug 8 11:28:43 EDT 2018 by tim 2018-08-08 11:28:43 -04:00
Tim Edwards b979d0ad97 Changed the netgen shell script from "sh" to "bash" due to the
presence of one or more bash-isms in the code.  Thanks to Sean
Cross for the patch.
2018-08-08 11:28:04 -04:00
Tim Edwards 86ab771964 Merge branch 'master' into work 2018-08-01 15:44:34 -04:00
Tim Edwards 2d74b3d94b Update at Wed Aug 1 15:44:32 EDT 2018 by tim 2018-08-01 15:44:32 -04:00
Tim Edwards 036e1f0947 Modified the verilog reading code so that it will automatically
determine if a parameter is a floating-point number, integer, or
string, and set the parameter accordingly.  Found an error in the
parameter comparison if the subcircuit definitions don't agree
on the type of parameter. Now all values are promoted to a single
type based on preference order (double, integer, string).  Tested
on a verilog file with a primitive device type defined as a module
with its properties encoded as parameters.  This successfully
matched against the SPICE primitive device.
2018-08-01 15:40:23 -04:00
Tim Edwards 5223011330 Merge branch 'master' into work 2018-06-25 21:26:47 -04:00
Tim Edwards 7bde5125fd Update at Mon Jun 25 21:26:47 EDT 2018 by tim 2018-06-25 21:26:47 -04:00
Tim Edwards dd6145463e Modified the SPICE parser to at least sanely deal with (possibly
CDL syntax) parameters that have values which are multi-word and
space separated (who the hell comes up with these things?).  One
can presumably safely assume that additional pin names are not
intermixed with parameters, so now if a multi-token parameter
value is encountered, the first word is taken as the value and
the remaining words are ignored, generating a warning message.
Since I have no idea what these values are used for, I cannot say
with certainty whether or not this would break LVS, but in the
test case given to me, the parameter had no impact on LVS, but
was apparently an annotation for the layout editor.
2018-06-25 21:21:45 -04:00
Tim Edwards f4ff74783c Merge branch 'master' into work 2018-06-17 15:06:17 -04:00
Tim Edwards f3d850e68e Update at Sun Jun 17 15:06:17 EDT 2018 by tim 2018-06-17 15:06:17 -04:00
Tim Edwards 1c08e5a48d Corrected missing tcl.h includes, which are needed in files that
call FREE(), since the Tcl/Tk version makes that a macro for the
subroutine Tcl_Free().  Thanks to Laurent Charrier for the bug
fix.
2018-06-17 15:05:15 -04:00
Tim Edwards 821145f9c1 Merge branch 'master' into work 2018-06-01 08:47:34 -04:00
Tim Edwards 6eb1efd55a Update at Fri Jun 1 08:47:33 EDT 2018 by tim 2018-06-01 08:47:33 -04:00
Tim Edwards 6d569ca396 Added a missing top-level clean to the Makefile, which is mainly
responsible for removing the log files.  Otherwise the log files
just keep accumulating output forever.
2018-06-01 08:46:52 -04:00
Tim Edwards 7a0bff846f Merge branch 'master' into work 2018-05-28 21:39:13 -04:00
Tim Edwards ced1299351 Update at Mon May 28 21:39:11 EDT 2018 by tim 2018-05-28 21:39:11 -04:00
Tim Edwards f213376bfd Removed "Depend" from the .gitignore file, as compilation depends
on it and fails the first time if it does not exist, requiring
running "make" twice (which is not advertised in the build
instructions).
2018-05-28 21:37:35 -04:00
Tim Edwards 223b197b71 Merge branch 'master' into work 2018-05-23 13:05:17 -04:00
Tim Edwards f0eb14be5e Update at Wed May 23 13:05:15 EDT 2018 by tim 2018-05-23 13:05:15 -04:00
Tim Edwards 534ea839c0 Revised the verilog parser to correctly identify and parse
parameters passed to instances, so that these can match critical
parameters in the SPICE netlist being compared against.
2018-05-23 13:04:31 -04:00
Tim Edwards b721cacb40 Merge branch 'master' into work 2018-05-01 14:08:18 -04:00
Tim Edwards 84f984e7f0 Update at Tue May 1 14:08:16 EDT 2018 by tim 2018-05-01 14:08:16 -04:00
Tim Edwards 25ac57d103 First pass at incorporating the efabless LVS manager GUI into the
netgen distribution.  It sort of works, but not quite there yet.
2018-05-01 14:07:16 -04:00
Tim Edwards 02a77b61f9 Merge branch 'master' into work 2018-04-26 08:01:20 -04:00
Tim Edwards dfd1e59432 Update at Thu Apr 26 08:01:18 EDT 2018 by tim 2018-04-26 08:01:18 -04:00
Tim Edwards f14ebf323f Fixed a script error that caused pins not to be reported in the
Tcl list and JSON formatted outputs.
2018-04-26 08:00:47 -04:00
Tim Edwards 62648c5672 Merge branch 'master' into work 2018-04-25 15:03:18 -04:00
Tim Edwards 7d113beada Update at Wed Apr 25 15:03:16 EDT 2018 by tim 2018-04-25 15:03:16 -04:00
Tim Edwards 1fe341833c Expanded the verilog parsing to include simple handling of ifdef,
ifndef, endif conditional statements.  Pre-define the key "LVS"
for use with netgen.  Also corrected some problems stemming from
the way delimiters are handled and the flexible use of whitespace
in verilog.
2018-04-25 15:00:49 -04:00
Tim Edwards aee4b846e2 Corrected the known issue with pin bus index matching that was in
the last commit and which was expected to be corrected by this
commit.
2018-04-16 17:19:26 -04:00
Tim Edwards 004378be11 Merge branch 'master' into work 2018-04-16 15:43:25 -04:00
Tim Edwards dc42e98ab9 Update at Mon Apr 16 15:43:23 EDT 2018 by tim 2018-04-16 15:43:23 -04:00
Tim Edwards 58d7e17231 Corrected basic problem with verilog instance pins not needing to
be in any specific order since all ports are named.  Also corrected
problem with pin names not using the same string matching function
as used for nets in general (which affects the ability to match
against different bus delimiters).
2018-04-16 15:41:20 -04:00
Tim Edwards de30eeabe8 Merge branch 'master' into work 2018-04-12 17:13:43 -04:00
Tim Edwards feab5023e5 Update at Thu Apr 12 17:13:41 EDT 2018 by tim 2018-04-12 17:13:41 -04:00
Tim Edwards 4d65b0006d Added new handling for verilog structural netlists, and fixed
some problems stemming from comparing a case-sensitive netlist
against a case-insensitive one.  Verilog netlist reading does
not yet have support for macros other than "`include", and it
does not yet have support for bit vectors constructed with
braces ({}).
2018-04-12 17:09:10 -04:00
Tim Edwards eefdb61e14 Merge branch 'master' into work 2018-04-05 10:10:47 -04:00
Tim Edwards 1d1ad3c833 Update at Thu Apr 5 10:10:44 EDT 2018 by tim 2018-04-05 10:10:44 -04:00
Tim Edwards 4166408576 Discovered a subtle error caused by running a setup script that
calls "equate pins".  This could fail because the routine that forces
uniqueness of pins was being called by the "compare" command but
outside of PinMatch.  Fixed by duplicating the call to force uniqueness
of pins inside the "equate" function.  Redundant calls should not
matter as uniqueness is resolved on the first call and subsequent calls
will need no further action.
2018-04-05 10:06:32 -04:00
Tim Edwards 2b15b731bb Merge branch 'master' into work 2018-03-28 12:40:17 -04:00
Tim Edwards 9ad6ad3338 Update at Wed Mar 28 12:40:15 EDT 2018 by tim 2018-03-28 12:40:15 -04:00
Tim Edwards 0fb5efd914 Corrected a crash condition during pin matching if any subcell has
no pins at all.
2018-03-28 12:39:40 -04:00
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
Tim Edwards 8300531858 Fixed an error that prevented 'circuit1' and 'circuit2' from being
used in the general cell name format as advertised (in fact caused
a segfault), without which all setup file have to be very circuit-
specific.
2016-12-07 22:22:57 -05:00
Tim Edwards 80378d8816 Several errors in the serial combination code fixed, and then
the serial combination routine was disabled so as not to post a
non-working version, since the parallel/serial property networks
are not analyzed.  This should be completed soon.
2016-12-07 21:21:15 -05:00
Tim Edwards 80d981a672 Merge branch 'master' into work 2016-12-07 15:01:56 -05:00
Tim Edwards 809a3c16e9 Update at Wed Dec 7 15:01:55 EST 2016 by tim 2016-12-07 15:01:55 -05:00
Tim Edwards 8d976e5686 Added more handling of serial/parallel device networks, including
making any subcircuit serializable by using the new command option
"property (device) serial|parallel enable|disable".  Note that as
of this commit, serial device detection is enabled but serial
networks are not collapsed for matching, which will tend to lead
to property errors in serial devices until this code is added,
which should be in a day or two.
2016-12-07 14:57:43 -05:00
Tim Edwards 577dfb5a28 Merge branch 'master' into work 2016-11-11 09:52:19 -05:00
Tim Edwards 46252ad6b9 Update at Fri Nov 11 09:52:18 EST 2016 by tim 2016-11-11 09:52:18 -05:00
Tim Edwards 564fab9667 Corrected an error in which property types were not promoted if
an instance property did not match the cell property type, as
long as the cell property types of the two compared cells matched.
Along with a recent change that left "M" as a type double during
SPICE netlist read-in, this caused "M" mismatches to be ignored,
because the double value was ignored and the integer value was
always zero.
2016-11-11 09:49:37 -05:00
Tim Edwards 0df4190e19 Merge branch 'master' into work 2016-10-26 21:21:10 -04:00
Tim Edwards 2f661ea256 Update at Wed Oct 26 21:21:09 EDT 2016 by tim 2016-10-26 21:21:10 -04:00
Tim Edwards fca075e1ed Disabled the newest unfinished experimental code, which was not
supposed to have been pushed to git yet.
2016-10-26 21:20:42 -04:00
Tim Edwards cc2a5e0ee6 Merge branch 'master' into work 2016-10-25 11:29:17 -04:00
Tim Edwards b7a8d3cfda Update at Tue Oct 25 11:29:17 EDT 2016 by tim 2016-10-25 11:29:17 -04:00
Tim Edwards 0205902baa Changed behavior of property mismatch reporting. This is to help
avoid the problem where non-critical properties cause devices not
to match, resulting in apparent mismatches of matched devices.
The current behavior now prints a statement about each device.
However, the result is still somewhat ambiguous.
2016-10-25 11:26:45 -04:00
54 changed files with 14563 additions and 4608 deletions
+12 -10
View File
@@ -1,12 +1,14 @@
*.*%
*.cdslck
.inca.db.*
inca.*.pak
*.swp
*.log
netgen
netgenexec
defs.mak
scripts/defs.mak
config.cache
config.log
scripts/config.log
config.status
scripts/config.status
*.o
*.so
*~
*/av_extracted*/
.nfs*
*.cd-
*/mommdl/
*.log
UPDATE_ME
+10 -9
View File
@@ -3,13 +3,13 @@
#
NETGENDIR = .
PROGRAMS = netgen
PROGRAMS = netgen python
MODULES = base
MAKEFLAGS =
INSTALL_CAD_DIRS = lib doc
include defs.mak
-include defs.mak
all: $(ALL_TARGET)
@@ -51,8 +51,8 @@ depend:
install: $(INSTALL_TARGET)
install-netgen:
@echo --- installing executable to $(DESTDIR)${BINDIR}
@echo --- installing run-time files to $(DESTDIR)${LIBDIR}
@echo --- installing executable to $(DESTDIR)${INSTALL_BINDIR}
@echo --- installing run-time files to $(DESTDIR)${INSTALL_LIBDIR}
@${MAKE} install-real >> install.log
install-real: install-dirs
@@ -60,15 +60,15 @@ install-real: install-dirs
(cd $$dir && ${MAKE} install); done
install-tcl-dirs:
${NETGENDIR}/scripts/mkdirs $(DESTDIR)${BINDIR} $(DESTDIR)${MANDIR} \
$(DESTDIR)${TCLDIR}
${NETGENDIR}/scripts/mkdirs $(DESTDIR)${INSTALL_BINDIR} \
$(DESTDIR)${INSTALL_TCLDIR} $(DESTDIR)${INSTALL_PYDIR}
install-dirs:
${NETGENDIR}/scripts/mkdirs $(DESTDIR)${BINDIR} $(DESTDIR)${MANDIR}
${NETGENDIR}/scripts/mkdirs $(DESTDIR)${INSTALL_BINDIR}
install-tcl: install-dirs
@echo --- installing executable to $(DESTDIR)${BINDIR}
@echo --- installing run-time files to $(DESTDIR)${LIBDIR}
@echo --- installing executable to $(DESTDIR)${INSTALL_BINDIR}
@echo --- installing run-time files to $(DESTDIR)${INSTALL_LIBDIR}
@${MAKE} install-tcl-real 2>&1 >> install.log
install-tcl-real: install-tcl-dirs
@@ -78,6 +78,7 @@ install-tcl-real: install-tcl-dirs
clean:
for dir in ${MODULES} ${PROGRAMS} ${UNUSED_MODULES}; do \
(cd $$dir && ${MAKE} clean); done
${RM} *.tmp */*.tmp *.sav */*.sav *.log TAGS tags
distclean:
touch defs.mak
+3 -1
View File
@@ -78,13 +78,15 @@ of CVS check-in notes on http://opencircuitdesign.com/netgen/.
BUILDING NETGEN:
----------------
NETGEN version 1.4 uses the same "make" procedure as Magic version 7.5
NETGEN version 1.5 uses the same "make" procedure as Magic version 8.1
and IRSIM version 9.7:
./configure
make
make install
Note: For FreeBSD, use 'gmake' instead.
IN CASE OF FAILURE
-------------------
Please contact me ([email protected]) to report compile-time and
+11 -19
View File
@@ -1,37 +1,29 @@
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).
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
5) Extend 2-terminal device handling (namely R and C) to more formats
1) Add automatic file format guessing from file extension for "write" command
2) Incorporate into Tcl-based xcircuit
3) Extend 2-terminal device handling (namely R and C) to more formats
(where appropriate).
6) Generate feedback in the form of a .mag file to facilitate interactive
4) Generate feedback in the form of a .mag file to facilitate interactive
netlist comparison in conjunction with magic. This may be an error
file, but it may also make use of magic 7.2's "element" command to
build rat's nests or outline areas of interest or anything else that
might be helpful to interactive comparison.
7) Improve upon the readability of the netlist comparator output.
In particular, pinpoint situations in which an error does not show
up in an obvious way in either the element or node lists.
8) Handle the hierarchy of ".ext" files automatically.
9) Retain position information from ".ext" files for the purpose of writing
5) Handle the hierarchy of ".ext" files automatically.
6) Retain position information from ".ext" files for the purpose of writing
feedback information into magic and for matching devices in the element
list to their counterparts in the original layout [note---done for .sim
format, which contains position information. Usefulness of improving
the .ext parsing is questionable. Ditto for item 8].
10) Expand upon the details of format-to-format translation, (especially
7) Expand upon the details of format-to-format translation, (especially
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.
8) 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.64
1.5.148
+1 -1
View File
@@ -3,7 +3,7 @@ NETGENDIR = ..
SRCS = actel.c ccode.c greedy.c ntk.c print.c actellib.c embed.c \
hash.c netfile.c objlist.c query.c anneal.c ext.c netcmp.c netgen.c \
pdutils.c random.c timing.c bottomup.c flatten.c place.c spice.c \
wombat.c xilinx.c xillib.c
verilog.c wombat.c xilinx.c xillib.c
X11_SRCS = xnetgen.c
include ${NETGENDIR}/defs.mak
+4
View File
@@ -31,6 +31,10 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdlib.h>
#endif
#ifdef TCL_NETGEN
#include <tcl.h>
#endif
#include "netgen.h"
#include "hash.h"
#include "objlist.h"
+136 -136
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;
}
@@ -196,16 +196,16 @@ char *ReadExt(char *fname, int doflat, int *fnum)
}
while (!EndParseFile()) {
SkipTok();
SkipTok(NULL);
if (EndParseFile()) break;
if (nexttok[0] == '#') SkipNewLine();
else if (match(nexttok, "timestamp")) SkipNewLine();
else if (match(nexttok, "version")) SkipNewLine();
else if (match(nexttok, "tech")) SkipNewLine();
else if (match(nexttok, "scale")) SkipNewLine();
else if (match(nexttok, "style")) SkipNewLine();
else if (match(nexttok, "resistclasses")) SkipNewLine();
if (nexttok[0] == '#') SkipNewLine(NULL);
else if (match(nexttok, "timestamp")) SkipNewLine(NULL);
else if (match(nexttok, "version")) SkipNewLine(NULL);
else if (match(nexttok, "tech")) SkipNewLine(NULL);
else if (match(nexttok, "scale")) SkipNewLine(NULL);
else if (match(nexttok, "style")) SkipNewLine(NULL);
else if (match(nexttok, "resistclasses")) SkipNewLine(NULL);
else if (match(nexttok, "node")) {
char name[200];
@@ -216,122 +216,122 @@ char *ReadExt(char *fname, int doflat, int *fnum)
CellDef(fname, filenum);
CellDefInProgress = 1;
}
SkipTok();
SkipTok(NULL);
GetExtName(name, nexttok);
Node(name); /* Ports will be determined by context */
SkipNewLine();
SkipNewLine(NULL);
}
else if (match(nexttok, "equiv")) {
char name[200];
char name2[200];
SkipTok();
SkipTok(NULL);
GetExtName(name, nexttok);
if (LookupObject(name,CurrentCell) == NULL) Node(name);
SkipTok();
SkipTok(NULL);
GetExtName(name2, nexttok);
if (LookupObject(name2,CurrentCell) == NULL) Node(name2);
join(name, name2);
SkipNewLine();
SkipNewLine(NULL);
}
else if (match(nexttok, "device")) {
char dev_name[100], dev_class[100];
char gate[200], drain[200], source[200], subs[200];
char inststr[64];
SkipTok();
SkipTok(NULL);
strcpy(dev_class, nexttok);
SkipTok();
SkipTok(NULL);
strcpy(dev_name, nexttok);
SkipTok(); /* x coord of gate box */
SkipTok(NULL); /* x coord of gate box */
strcpy(inststr, dev_class);
strcat(inststr, "@");
strcat(inststr, nexttok);
SkipTok(); /* y coord of gate box */
SkipTok(NULL); /* y coord of gate box */
strcat(inststr, ",");
strcat(inststr, nexttok);
SkipTok(); /* skip coord of gate box */
SkipTok(); /* skip coord of gate box */
SkipTok(NULL); /* skip coord of gate box */
SkipTok(NULL); /* skip coord of gate box */
/* Device-dependent parameters */
if (match(dev_class, "mosfet")) {
SkipTok(); /* skip device length */
SkipTok(); /* skip device width */
SkipTok();
SkipTok(NULL); /* skip device length */
SkipTok(NULL); /* skip device width */
SkipTok(NULL);
GetExtName(subs, nexttok);
}
else if (match(dev_class, "bjt")) {
SkipTok(); /* skip device length */
SkipTok(); /* skip device width */
SkipTok();
SkipTok(NULL); /* skip device length */
SkipTok(NULL); /* skip device width */
SkipTok(NULL);
GetExtName(subs, nexttok);
}
else if (match(dev_class, "devcap")) {
SkipTok(); /* skip device length */
SkipTok(); /* skip device width */ /* or. . . */
SkipTok(NULL); /* skip device length */
SkipTok(NULL); /* skip device width */ /* or. . . */
}
else if (match(dev_class, "devres")) {
SkipTok(); /* skip device length */
SkipTok(); /* skip device width */ /* or. . . */
SkipTok(NULL); /* skip device length */
SkipTok(NULL); /* skip device width */ /* or. . . */
}
else if (match(dev_class, "diode")) {
SkipTok();
SkipTok(NULL);
GetExtName(gate, nexttok);
SkipTok(); /* skip terminal length */
SkipTok(); /* skip terminal attributes */
SkipTok();
SkipTok(NULL); /* skip terminal length */
SkipTok(NULL); /* skip terminal attributes */
SkipTok(NULL);
GetExtName(drain, nexttok);
SkipTok(); /* skip terminal length */
SkipTok(); /* skip terminal attributes */
SkipTok(NULL); /* skip terminal length */
SkipTok(NULL); /* skip terminal attributes */
}
else if (match(dev_class, "subckt")) {
SkipTok(); /* skip device length */
SkipTok(); /* skip device width */
SkipTok();
SkipTok(NULL); /* skip device length */
SkipTok(NULL); /* skip device width */
SkipTok(NULL);
GetExtName(subs, nexttok);
while (nexttok != NULL) {
SkipTok();
SkipTok(NULL);
GetExtName(gate, nexttok);
SkipTok(); /* skip terminal length */
SkipTok(); /* skip terminal attributes */
SkipTok(NULL); /* skip terminal length */
SkipTok(NULL); /* skip terminal attributes */
}
}
else if (match(dev_class, "rsubckt")) {
SkipTok(); /* skip device length */
SkipTok(); /* skip device width */
SkipTok();
SkipTok(NULL); /* skip device length */
SkipTok(NULL); /* skip device width */
SkipTok(NULL);
GetExtName(subs, nexttok);
}
SkipTokNoNewline();
SkipNewLine();
SkipTokNoNewline(NULL);
SkipNewLine(NULL);
}
else if (match(nexttok, "fet")) { /* old-style FET record */
char fet_class[100];
char gate[200], drain[200], source[200], subs[200];
char inststr[64];
SkipTok();
SkipTok(NULL);
strcpy(fet_class, nexttok);
SkipTok(); /* x coord of gate box */
SkipTok(NULL); /* x coord of gate box */
strcpy(inststr, fet_class);
strcat(inststr, "@");
strcat(inststr, nexttok);
SkipTok(); /* y coord of gate box */
SkipTok(NULL); /* y coord of gate box */
strcat(inststr, ",");
strcat(inststr, nexttok);
SkipTok(); /* skip coord of gate box */
SkipTok(); /* skip coord of gate box */
SkipTok(); /* skip gate area */
SkipTok(); /* skip gate perimeter */
SkipTok();
SkipTok(NULL); /* skip coord of gate box */
SkipTok(NULL); /* skip coord of gate box */
SkipTok(NULL); /* skip gate area */
SkipTok(NULL); /* skip gate perimeter */
SkipTok(NULL);
GetExtName(subs, nexttok);
SkipTok();
SkipTok(NULL);
GetExtName(gate, nexttok);
SkipTok(); /* skip terminal length */
SkipTok(); /* skip terminal attributes */
SkipTok();
SkipTok(NULL); /* skip terminal length */
SkipTok(NULL); /* skip terminal attributes */
SkipTok(NULL);
GetExtName(drain, nexttok);
SkipTok(); /* skip terminal length */
SkipTok(); /* skip terminal attributes */
SkipTokNoNewline();
SkipTok(NULL); /* skip terminal length */
SkipTok(NULL); /* skip terminal attributes */
SkipTokNoNewline(NULL);
if (nexttok == NULL) {
/* This gets around a problem with the magic extractor in which */
/* transistors having shorted source-drain are written into the */
@@ -341,7 +341,7 @@ char *ReadExt(char *fname, int doflat, int *fnum)
}
else
GetExtName(source, nexttok);
SkipNewLine();
SkipNewLine(NULL);
/* remap transistors into things we know about */
if (match(fet_class, "nfet"))
N(fname, inststr, gate, drain, source);
@@ -361,15 +361,15 @@ char *ReadExt(char *fname, int doflat, int *fnum)
else if (match(nexttok, "cap")) {
if (IgnoreRC) {
/* ignore all capacitances */
SkipNewLine();
SkipNewLine(NULL);
}
else {
char ctop[200], cbot[200], cdummy[200];
SkipTok();
SkipTok(NULL);
GetExtName(ctop, nexttok);
SkipTok();
SkipTok(NULL);
GetExtName(cbot, nexttok);
SkipNewLine(); /* Skip over capacitance value */
SkipNewLine(NULL); /* Skip over capacitance value */
Cap(fname, NULL, ctop, cbot);
}
}
@@ -386,14 +386,14 @@ char *ReadExt(char *fname, int doflat, int *fnum)
CellDefInProgress = 1;
}
SkipTok();
SkipTok(NULL);
GetExtName(name, nexttok);
if ((basename = strrchr(name,'/')) != NULL) {
char tmp[200];
strcpy(tmp, basename+1);
strcpy(name, tmp);
}
SkipTok();
SkipTok(NULL);
GetExtName(instancename, nexttok);
Printf("Instancing %s as %s\n", name, instancename);
Instance(name, instancename);
@@ -401,14 +401,14 @@ char *ReadExt(char *fname, int doflat, int *fnum)
Printf("Flattening %s in %s\n", instancename, fname);
flattenInstancesOf(NULL, filenum, name);
}
SkipNewLine();
SkipNewLine(NULL);
}
else if (match(nexttok, "merge")) {
char name[200];
char name2[200];
SkipTok();
SkipTok(NULL);
GetExtName(name, nexttok);
SkipTok();
SkipTok(NULL);
GetExtName(name2, nexttok);
if (doflat)
join(name, name2);
@@ -416,12 +416,12 @@ char *ReadExt(char *fname, int doflat, int *fnum)
join(name, name2);
else {
}
SkipNewLine();
SkipNewLine(NULL);
}
else {
Printf("Strange token in ext: '%s'\n", nexttok);
InputParseError(stderr);
SkipNewLine();
SkipNewLine(NULL);
}
}
CloseParseFile();
@@ -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;
}
@@ -657,189 +657,189 @@ char *ReadSim(char *fname, int *fnum)
CellDef(fname, filenum);
while (!EndParseFile()) {
SkipTok();
SkipTok(NULL);
if (EndParseFile()) break;
if (nexttok[0] == '|') {
SkipTok(); /* "units" */
SkipTok(NULL); /* "units" */
if (!strcmp(nexttok, "units:")) {
SkipTok();
SkipTok(NULL);
simscale = strtod(nexttok, NULL);
}
SkipNewLine();
SkipNewLine(NULL);
}
else if (match(nexttok, "n")) {
char gate[200], drain[200], source[200];
char inststr[25], *instptr = NULL;
SkipTok();
SkipTok(NULL);
GetExtName(gate, nexttok);
if (LookupObject(gate, CurrentCell) == NULL)
Node(gate); /* define the node if it does not already exist */
SkipTok();
SkipTok(NULL);
GetExtName(drain, nexttok);
if (LookupObject(drain, CurrentCell) == NULL)
Node(drain); /* define the node if it does not already exist */
SkipTok();
SkipTok(NULL);
GetExtName(source, nexttok);
if (LookupObject(source, CurrentCell) == NULL)
Node(source); /* define the node if it does not already exist */
SkipTokNoNewline(); /* length */
SkipTokNoNewline(NULL); /* length */
if ((nexttok != NULL) && (nexttok[0] != '\0')) {
vstr = ScaleStringFloatValue(&nexttok[0], simscale * 1e-8);
AddProperty(&kvlist, "length", vstr);
SkipTok(); /* width */
SkipTok(NULL); /* width */
if ((nexttok != NULL) && (nexttok[0] != '\0')) {
vstr = ScaleStringFloatValue(&nexttok[0], simscale * 1e-8);
AddProperty(&kvlist, "width", vstr);
}
SkipTokNoNewline();
SkipTokNoNewline(NULL);
if (nexttok != NULL) {
if (StrIsInt(nexttok)) {
strcpy(inststr, "n@");
strcat(inststr, nexttok);
SkipTok();
SkipTok(NULL);
strcat(inststr, ",");
strcat(inststr, nexttok);
instptr = inststr;
}
}
}
SkipNewLine(); /* skip any attributes */
SkipNewLine(NULL); /* skip any attributes */
N(fname, instptr, gate, drain, source);
LinkProperties("n", kvlist);
}
else if (match(nexttok, "p")) {
char gate[200], drain[200], source[200];
char inststr[25], *instptr = NULL;
SkipTok();
SkipTok(NULL);
GetExtName(gate, nexttok);
if (LookupObject(gate, CurrentCell) == NULL)
Node(gate); /* define the node if it does not already exist */
SkipTok();
SkipTok(NULL);
GetExtName(drain, nexttok);
if (LookupObject(drain, CurrentCell) == NULL)
Node(drain); /* define the node if it does not already exist */
SkipTok();
SkipTok(NULL);
GetExtName(source, nexttok);
if (LookupObject(source, CurrentCell) == NULL)
Node(source); /* define the node if it does not already exist */
SkipTokNoNewline(); /* length */
SkipTokNoNewline(NULL); /* length */
if ((nexttok != NULL) && (nexttok[0] != '\0')) {
vstr = ScaleStringFloatValue(&nexttok[0], simscale * 1e-8);
AddProperty(&kvlist, "length", vstr);
SkipTok(); /* width */
SkipTok(NULL); /* width */
if ((nexttok != NULL) && (nexttok[0] != '\0')) {
vstr = ScaleStringFloatValue(&nexttok[0], simscale * 1e-8);
AddProperty(&kvlist, "width", vstr);
}
SkipTokNoNewline();
SkipTokNoNewline(NULL);
if (nexttok != NULL) {
if (StrIsInt(nexttok)) {
strcpy(inststr, "p@");
strcat(inststr, nexttok);
SkipTok();
SkipTok(NULL);
strcat(inststr, ",");
strcat(inststr, nexttok);
instptr = inststr;
}
}
}
SkipNewLine(); /* skip various attributes */
SkipNewLine(NULL); /* skip various attributes */
P(fname, instptr, gate, drain, source);
LinkProperties("p", kvlist);
}
else if (match(nexttok, "e")) { /* 3-port capacitors (poly/poly2) */
char gate[200], drain[200], source[200];
char inststr[25], *instptr = NULL;
SkipTok();
SkipTok(NULL);
GetExtName(gate, nexttok);
if (LookupObject(gate, CurrentCell) == NULL)
Node(gate); /* define the node if it does not already exist */
SkipTok();
SkipTok(NULL);
GetExtName(drain, nexttok);
if (LookupObject(drain, CurrentCell) == NULL)
Node(drain); /* define the node if it does not already exist */
SkipTok();
SkipTok(NULL);
GetExtName(source, nexttok);
if (LookupObject(source, CurrentCell) == NULL)
Node(source); /* define the node if it does not already exist */
SkipTokNoNewline(); /* skip length */
SkipTokNoNewline(NULL); /* skip length */
if (nexttok != NULL) {
SkipTok(); /* skip width */
SkipTokNoNewline();
SkipTok(NULL); /* skip width */
SkipTokNoNewline(NULL);
inststr[0] = '\0';
if (nexttok != NULL) {
if (StrIsInt(nexttok)) {
strcpy(inststr, "e@");
strcat(inststr, nexttok);
SkipTok();
SkipTok(NULL);
strcat(inststr, ",");
strcat(inststr, nexttok);
instptr = inststr;
}
}
}
SkipNewLine(); /* skip various attributes */
SkipNewLine(NULL); /* skip various attributes */
E(fname, instptr, gate, drain, source);
}
else if (match(nexttok, "b")) { /* bipolars added by Tim 7/16/96 */
char base[200], emitter[200], collector[200];
char inststr[25], *instptr = NULL;
SkipTok();
SkipTok(NULL);
GetExtName(base, nexttok);
if (LookupObject(base, CurrentCell) == NULL)
Node(base); /* define the node if it does not already exist */
SkipTok();
SkipTok(NULL);
GetExtName(emitter, nexttok);
if (LookupObject(emitter, CurrentCell) == NULL)
Node(emitter); /* define the node if it does not already exist */
SkipTok();
SkipTok(NULL);
GetExtName(collector, nexttok);
if (LookupObject(collector, CurrentCell) == NULL)
Node(collector); /* define the node if it does not already exist */
SkipTokNoNewline(); /* skip length */
SkipTokNoNewline(NULL); /* skip length */
if (nexttok != NULL) {
SkipTok(); /* skip width */
SkipTokNoNewline();
SkipTok(NULL); /* skip width */
SkipTokNoNewline(NULL);
if (nexttok != NULL) {
if (StrIsInt(nexttok)) {
strcpy(inststr, "b@");
strcat(inststr, nexttok);
SkipTok();
SkipTok(NULL);
strcat(inststr, ",");
strcat(inststr, nexttok);
instptr = inststr;
}
}
}
SkipNewLine(); /* skip various attributes */
SkipNewLine(NULL); /* skip various attributes */
B(fname, instptr, collector, base, emitter);
}
else if (matchnocase(nexttok, "c")) { /* 2-port capacitors */
if (IgnoreRC) {
/* ignore all capacitances */
SkipNewLine();
SkipNewLine(NULL);
}
else {
char ctop[200], cbot[200], cdummy[200];
SkipTok();
SkipTok(NULL);
GetExtName(ctop, nexttok);
if (LookupObject(ctop, CurrentCell) == NULL)
Node(ctop); /* define the node if it does not already exist */
SkipTok();
SkipTok(NULL);
GetExtName(cbot, nexttok);
if (LookupObject(cbot, CurrentCell) == NULL)
Node(cbot); /* define the node if it does not already exist */
SkipTokNoNewline();
SkipTokNoNewline(NULL);
if (nexttok != NULL) {
vstr = ScaleStringFloatValue(&nexttok[0], 1e-15);
AddProperty(&kvlist, "value", vstr);
}
SkipNewLine();
SkipNewLine(NULL);
Cap(fname, NULL, ctop, cbot);
LinkProperties("c", kvlist);
}
@@ -847,23 +847,23 @@ char *ReadSim(char *fname, int *fnum)
else if (match(nexttok, "r")) { /* 2-port resistors */
if (IgnoreRC) {
/* ignore all capacitances */
SkipNewLine();
SkipNewLine(NULL);
}
else {
char rtop[200], rbot[200];
SkipTok();
SkipTok(NULL);
GetExtName(rtop, nexttok);
if (LookupObject(rtop, CurrentCell) == NULL)
Node(rtop); /* define the node if it does not already exist */
SkipTok();
SkipTok(NULL);
GetExtName(rbot, nexttok);
if (LookupObject(rbot, CurrentCell) == NULL)
Node(rbot); /* define the node if it does not already exist */
SkipTokNoNewline();
SkipTokNoNewline(NULL);
if (nexttok != NULL) {
AddProperty(&kvlist, "value", &nexttok[0]);
}
SkipNewLine(); /* skip various attributes */
SkipNewLine(NULL); /* skip various attributes */
Res(fname, NULL, rtop, rbot);
LinkProperties("r", kvlist);
}
@@ -871,55 +871,55 @@ char *ReadSim(char *fname, int *fnum)
else if (match(nexttok, "z")) { /* 3-port resistors from magic */
if (IgnoreRC) {
/* ignore all capacitances */
SkipNewLine();
SkipNewLine(NULL);
}
else {
char rtop[200], rbot[200], rdummy[200];
char inststr[25], *instptr = NULL;
SkipTok();
SkipTok(NULL);
GetExtName(rdummy, nexttok);
if (LookupObject(rdummy, CurrentCell) == NULL)
Node(rdummy); /* define the node if it does not already exist */
SkipTok();
SkipTok(NULL);
GetExtName(rtop, nexttok);
if (LookupObject(rtop, CurrentCell) == NULL)
Node(rtop); /* define the node if it does not already exist */
SkipTok();
SkipTok(NULL);
GetExtName(rbot, nexttok);
if (LookupObject(rbot, CurrentCell) == NULL)
Node(rbot); /* define the node if it does not already exist */
SkipTokNoNewline(); /* skip length */
SkipTokNoNewline(NULL); /* skip length */
if (nexttok != NULL) {
SkipTok(); /* skip width */
SkipTokNoNewline();
SkipTok(NULL); /* skip width */
SkipTokNoNewline(NULL);
if (nexttok != NULL) {
if (StrIsInt(nexttok)) {
strcpy(inststr, "z@");
strcat(inststr, nexttok);
SkipTok();
SkipTok(NULL);
strcat(inststr, ",");
strcat(inststr, nexttok);
instptr = inststr;
}
}
}
SkipNewLine(); /* skip various attributes */
SkipNewLine(NULL); /* skip various attributes */
Res3(fname, instptr, rdummy, rtop, rbot);
}
}
else if (match(nexttok, "N")) {
/* ignore this keyword */
SkipNewLine();
SkipNewLine(NULL);
}
else if (match(nexttok, "A")) {
/* ignore this keyword */
SkipNewLine();
SkipNewLine(NULL);
}
else if (match(nexttok, "=")) {
char node1[200], node2[200];
SkipTok();
SkipTok(NULL);
GetExtName(node1, nexttok);
SkipTok();
SkipTok(NULL);
GetExtName(node2, nexttok);
join(node1, node2);
}
@@ -928,12 +928,12 @@ char *ReadSim(char *fname, int *fnum)
Printf("Ignoring lumped resistances (\"R\" records) in .sim.\n");
has_lumped = 1; /* Don't print this message more than once */
}
SkipNewLine();
SkipNewLine(NULL);
}
else {
Printf("Strange token in .sim: '%s'\n", nexttok);
InputParseError(stderr);
SkipNewLine();
SkipNewLine(NULL);
}
DeleteProperties(&kvlist);
}
+40 -28
View File
@@ -259,7 +259,7 @@ int flattenInstancesOf(char *name, int fnum, char *instance)
struct nlist *ChildCell;
struct objlist *tmp, *ob2, *ob3;
int notdone, rnodenum;
char tmpstr[200];
char tmpstr[1024];
int nextnode, oldmax, numflat = 0;
#if !OLDPREFIX
int prefixlength;
@@ -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);
@@ -1160,7 +1166,7 @@ struct nlist *cleanuppins(struct hashlist *p, void *clientdata)
while (ob && obt && (ob->type > FIRSTPIN || ob == firstpin) &&
ob->model.class != NULL) {
nob = ob->next;
if ((obt->type == PORT) && (obt->node == -1)) {
if ((obt->type == PORT) && (obt->node == -2)) {
/* Remove this pin */
@@ -1224,11 +1230,15 @@ 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) {
if (ob->type != PORT) break;
if (ob->node == -1) {
if (ob->node == -2) {
needscleanup = 1;
break;
}
@@ -1255,7 +1265,7 @@ int CleanupPins(char *name, int filenum)
}
else if (ob->type != PORT) break;
nob = ob->next;
if (ob->node == -1) {
if (ob->node == -2) {
if (lob == NULL) {
ThisCell->cell = ob->next;
}
@@ -1381,7 +1391,7 @@ SurveyCell(struct nlist *tc, struct hashdict *compdict, int file1, int file2, in
/* */
/* If there is a mismatch between instances of low- */
/* level devices, determine if the mismatches can be */
/* resolved by parallel/serial combining, according to */
/* resolved by parallel/series combining, according to */
/* combination rules. */
/* */
/* Return the number of modifications made. */
@@ -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);
@@ -1529,7 +1539,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
/* (it without regard to cell1) improves the matching. */
else if ((ecomp->num1 != ecomp->num2) && (ecomp->cell2 != NULL) &&
(ecomp->cell2->class == CLASS_SUBCKT)) {
(ecomp->num2 != 0) && (ecomp->cell2->class == CLASS_SUBCKT)) {
ecomp->add2 = -ecomp->num2;
match = 1;
for (ob2 = ecomp->cell2->cell; ob2; ob2 = ob2->next) {
@@ -1587,7 +1597,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
/* (it without regard to cell1) improves the matching. */
else if ((ecomp->num1 != ecomp->num2) && (ecomp->cell1 != NULL) &&
(ecomp->cell1->class == CLASS_SUBCKT)) {
(ecomp->num1 != 0) && (ecomp->cell1->class == CLASS_SUBCKT)) {
ecomp->add1 = -ecomp->num1;
match = 1;
for (ob2 = ecomp->cell1->cell; ob2; ob2 = ob2->next) {
@@ -1649,7 +1659,8 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
ecomp = (ECompare *)HashFirst(&compdict);
while (ecomp != NULL) {
if ((ecomp->num1 != ecomp->num2) && (ecomp->cell1 != NULL) &&
(ecomp->cell1->class == CLASS_RES)) {
((ecomp->cell1->class == CLASS_RES) ||
(ecomp->cell1->class == CLASS_VSOURCE))) {
int node1 = -1, node2 = -1;
lob = NULL;
for (ob1 = tc1->cell; ob1; ) {
@@ -1693,7 +1704,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
if (found) break;
}
if (found) {
Fprintf(stdout, "Removing zero-valued device"
Fprintf(stdout, "Removing zero-valued device "
"%s from cell %s makes a better match\n",
tsub1->name,
tc1->name);
@@ -1753,7 +1764,8 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
// Repeat the last section for the other circuit
if ((ecomp->num1 != ecomp->num2) && (ecomp->cell2 != NULL) &&
(ecomp->cell2->class == CLASS_RES)) {
((ecomp->cell2->class == CLASS_RES) ||
(ecomp->cell2->class == CLASS_VSOURCE))) {
int node1 = -1, node2 = -1;
lob = NULL;
for (ob2 = tc2->cell; ob2; ) {
@@ -1797,7 +1809,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
if (found) break;
}
if (found) {
Fprintf(stdout, "Removing zero-valued device"
Fprintf(stdout, "Removing zero-valued device "
"%s from cell %s makes a better match\n",
tsub2->name,
tc2->name);
@@ -1907,7 +1919,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
char *dstr = NULL;
tc2 = LookupCellFile(ob2->model.class, ecomp0X->cell2->file);
if (tc2->flags & CELL_DUPLICATE) {
dstr = strstr(ob1->model.class, "[[");
dstr = strstr(ob2->model.class, "[[");
if (dstr) *dstr = '\0';
}
ncomp = (ECompare *)HashInt2Lookup(ob2->model.class,
+5 -1
View File
@@ -25,6 +25,10 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <alloc.h>
#endif
#ifdef TCL_NETGEN
#include <tcl.h>
#endif
#include "netgen.h"
#include "hash.h"
#include "objlist.h"
@@ -309,7 +313,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);
+2367 -530
View File
File diff suppressed because it is too large Load Diff
+16 -3
View File
@@ -8,7 +8,11 @@ extern struct nlist *Circuit2;
extern int ExhaustiveSubdivision;
extern int left_col_end;
extern int right_col_end;
#ifdef TCL_NETGEN
#include <tcl.h>
extern int InterruptPending;
#endif
@@ -17,10 +21,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 +38,9 @@ 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 series, int comb);
extern int CreateCompareQueue(char *, int, char *, int);
extern int GetCompareQueueTop(char **, int *, char **, int *);
@@ -44,11 +51,17 @@ extern void PrintIllegalClasses();
extern void PrintIllegalNodeClasses();
extern void PrintIllegalElementClasses();
extern void DumpNetwork(struct objlist *ob, int cidx);
extern void DumpNetworkAll(char *name, int file);
#ifdef TCL_NETGEN
extern int EquivalentNode();
extern int EquivalentElement();
extern void enable_interrupt();
extern void disable_interrupt();
extern Tcl_Obj *ListNodeClasses(int legal);
extern Tcl_Obj *ListElementClasses(int legal);
#endif
+465 -55
View File
@@ -47,6 +47,18 @@ static FILE *outfile;
static int Graph = 0;
int File;
/*------------------------------------------------------*/
/* Structure for stacking nested `if[n]def in verilog */
/*------------------------------------------------------*/
struct ifstack {
int invert;
struct property *kl;
struct ifstack *next;
};
struct ifstack *condstack = NULL;
extern char *SetExtension(char *buffer, char *path, char *extension)
/* add 'extension' to 'path' (overwriting previous extension, if any),
write it into buffer (if buffer is null, malloc a buffer).
@@ -77,8 +89,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);
@@ -174,7 +187,7 @@ void CloseFile(char *filename)
/* STUFF TO READ INPUT FILES */
static char *line = NULL; /* actual line read in */
static char *linetok; /* line copied to this, then munged by strtok */
static char *linetok; /* line copied to this, then munged by strdtok */
static int linesize = 0; /* amount of memory allocated for line */
static int linenum;
char *nexttok;
@@ -190,7 +203,77 @@ struct filestack {
static struct filestack *OpenFiles = NULL;
#define TOKEN_DELIMITER " \t\n\r"
struct hashdict *definitions = (struct hashdict *)NULL;
#define WHITESPACE_DELIMITER " \t\n\r"
/*----------------------------------------------------------------------*/
/* TrimQuoted() --- */
/* Remove spaces from inside single- or double-quoted strings. */
/* Ignore verilog constant bits (e.g., "1'b0") when parsing. */
/*----------------------------------------------------------------------*/
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 && (qstart > lptr)) {
if (isdigit(*(qstart - 1))) {
lptr = qstart + 1;
changed = TRUE;
continue;
}
}
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() */
@@ -201,40 +284,204 @@ static struct filestack *OpenFiles = NULL;
/* */
/*----------------------------------------------------------------------*/
int GetNextLineNoNewline()
int GetNextLineNoNewline(char *delimiter)
{
char *newbuf;
int testc;
char *newbuf;
int testc;
int nested = 0;
if (feof(infile)) return -1;
if (feof(infile)) return -1;
// This is more reliable than feof() ...
testc = getc(infile);
if (testc == -1) return -1;
ungetc(testc, infile);
while (1) { /* May loop indefinitely in an `if[n]def conditional */
if (linesize == 0) {
/* Allocate memory for line */
linesize = 500;
line = (char *)MALLOC(linesize);
linetok = (char *)MALLOC(linesize);
}
fgets(line, linesize, infile);
while (strlen(line) == linesize - 1) {
newbuf = (char *)MALLOC(linesize + 500);
strcpy(newbuf, line);
FREE(line);
line = newbuf;
fgets(line + linesize - 1, 501, infile);
linesize += 500;
FREE(linetok);
linetok = (char *)MALLOC(linesize);
}
linenum++;
strcpy(linetok, line);
// This is more reliable than feof() ...
testc = getc(infile);
if (testc == -1) return -1;
ungetc(testc, infile);
nexttok = strtok(linetok, TOKEN_DELIMITER);
return 0;
if (linesize == 0) {
/* Allocate memory for line */
linesize = 2000;
line = (char *)MALLOC(linesize + 1);
linetok = (char *)MALLOC(linesize + 1);
}
fgets(line, linesize, infile);
while (strlen(line) == linesize - 1) {
newbuf = (char *)MALLOC(linesize + 501);
strcpy(newbuf, line);
FREE(line);
line = newbuf;
fgets(line + linesize - 1, 501, infile);
linesize += 500;
FREE(linetok);
linetok = (char *)MALLOC(linesize + 1);
}
/* Check for substitutions (verilog only). Make sure linetok is */
/* large enough to hold the entire line after substitutions. */
if (definitions != NULL) {
char *s, *w, e;
struct property *kl;
int len, dlen, vlen, addin = 0;
unsigned char found = FALSE;
for (s = line; *s != '\0'; s++) {
if (*s == '`') {
w = s + 1;
while (isalnum(*w)) w++;
e = *w;
*w = '\0';
kl = (struct property *)HashLookup(s + 1, definitions);
if (kl != NULL) {
dlen = strlen(s);
if (kl->type == PROP_STRING) {
vlen = strlen(kl->pdefault.string);
}
else vlen = 12; /* Leave room for numeric conversion */
addin += vlen - dlen + 1;
found = TRUE;
}
*w = e;
}
}
if (found) {
len = strlen(line);
if (len + addin > linesize) {
while (len + addin > linesize) linesize += 500;
FREE(linetok);
linetok = (char *)MALLOC(linesize);
}
}
}
/* Make definition substitutions (verilog only) */
if (definitions != NULL) {
char *s, *t, *w, e;
struct property *kl;
t = linetok;
for (s = line; *s != '\0'; s++) {
if (*s == '`') {
w = s + 1;
while (isalnum(*w)) w++;
e = *w;
*w = '\0';
kl = (struct property *)HashLookup(s + 1, definitions);
if (kl != NULL) {
if (kl->type == PROP_STRING)
strcpy(t, kl->pdefault.string);
else if (kl->type == PROP_INTEGER)
sprintf(t, "%d", kl->pdefault.ival);
else if (kl->type == PROP_DOUBLE)
sprintf(t, "%g", kl->pdefault.dval);
t += strlen(t);
s = w - 1;
}
else *t++ = *s;
*w = e;
}
else *t++ = *s;
}
*t = '\0';
}
else
strcpy(linetok, line);
TrimQuoted(linetok);
linenum++;
nexttok = strdtok(linetok, WHITESPACE_DELIMITER, delimiter);
if (nexttok == NULL) return 0;
/* Handle `ifdef, `ifndef, `elsif, `else, and `endif (verilog */
/* only, where indicated by a non-NULL "definitions") */
if (definitions == NULL) return 0;
/* If currently skipping through a section, handle conditionals differently */
if (condstack) {
if (((condstack->invert == 0) && (condstack->kl == NULL))
|| ((condstack->invert == 1) && (condstack->kl != NULL))) {
if (match(nexttok, "`ifdef") || match(nexttok, "`ifndef")) {
nested++;
continue;
}
else if (nested > 0) {
if (match(nexttok, "`endif")) nested--;
continue;
}
else if (nexttok[0] != '`') continue;
}
}
/* Handle conditionals (that is not being skipped over) */
if (match(nexttok, "`endif")) {
if (condstack == NULL) {
fprintf(stderr, "Error: `endif without corresponding `if[n]def\n");
}
else {
struct ifstack *iftop = condstack;
condstack = condstack->next;
FREE(iftop);
}
}
/* Note that `if[n]def may be nested. */
else if (match(nexttok, "`ifdef") || match(nexttok, "`ifndef") ||
match(nexttok, "`elsif") || match(nexttok, "`else")) {
/* Every `ifdef or `ifndef increases condstack by 1 */
if (nexttok[1] == 'i') {
struct ifstack *newif = (struct ifstack *)MALLOC(sizeof(struct ifstack));
newif->next = condstack;
condstack = newif;
}
if (condstack == NULL) {
fprintf(stderr, "Error: %s without `if[n]def\n", nexttok);
break;
}
else {
if (match(nexttok, "`else")) {
/* Invert the sense of the if[n]def scope */
condstack->invert = (condstack->invert == 1) ? 0 : 1;
}
else if (match(nexttok, "`elsif")) {
nexttok = strdtok(NULL, WHITESPACE_DELIMITER, delimiter);
if (nexttok == NULL) {
fprintf(stderr, "Error: `elsif with no conditional.\n");
return 0;
}
/* Keep the same scope but redefine the parameter */
condstack->invert = 0;
condstack->kl = (struct property *)HashLookup(nexttok, definitions);
}
else {
condstack->invert = (nexttok[3] == 'n') ? 1 : 0;
nexttok = strdtok(NULL, WHITESPACE_DELIMITER, delimiter);
if (nexttok == NULL) {
fprintf(stderr, "Error: %s with no conditional.\n", nexttok);
return 0;
}
condstack->kl = (struct property *)HashLookup(nexttok, definitions);
}
}
}
else if (condstack) {
if (((condstack->invert == 0) && (condstack->kl == NULL))
|| ((condstack->invert == 1) && (condstack->kl != NULL)))
continue;
else
break;
}
else
break;
}
return 0;
}
/*----------------------------------------------------------------------*/
@@ -242,10 +489,10 @@ int GetNextLineNoNewline()
/* valid token. */
/*----------------------------------------------------------------------*/
void GetNextLine()
void GetNextLine(char *delimiter)
{
do {
if (GetNextLineNoNewline() == -1) return;
if (GetNextLineNoNewline(delimiter) == -1) return;
} while (nexttok == NULL);
}
@@ -253,11 +500,12 @@ void GetNextLine()
/* if nexttok is already NULL, force scanner to read new line */
/*----------------------------------------------------------------------*/
void SkipTok(void)
void SkipTok(char *delimiter)
{
if (nexttok != NULL &&
(nexttok = strtok(NULL, TOKEN_DELIMITER)) != NULL) return;
GetNextLine();
if (nexttok != NULL &&
(nexttok = strdtok(NULL, WHITESPACE_DELIMITER, delimiter)))
return;
GetNextLine(delimiter);
}
/*----------------------------------------------------------------------*/
@@ -265,9 +513,9 @@ void SkipTok(void)
/* must be preceeded by at least one call to SkipTok() */
/*----------------------------------------------------------------------*/
void SkipTokNoNewline(void)
void SkipTokNoNewline(char *delimiter)
{
nexttok = strtok(NULL, TOKEN_DELIMITER);
nexttok = strdtok(NULL, WHITESPACE_DELIMITER, delimiter);
}
/*----------------------------------------------------------------------*/
@@ -289,20 +537,41 @@ void SpiceTokNoNewline(void)
{
int contline;
if ((nexttok = strtok(NULL, TOKEN_DELIMITER)) != NULL) return;
if ((nexttok = strdtok(NULL, WHITESPACE_DELIMITER, NULL)) != NULL) return;
while (nexttok == NULL) {
contline = getc(infile);
if (contline == '*') {
GetNextLine();
SkipNewLine();
GetNextLine(WHITESPACE_DELIMITER);
SkipNewLine(NULL);
continue;
}
else if (contline != '+') {
ungetc(contline, infile);
return;
}
if (GetNextLineNoNewline() == -1) break;
if (GetNextLineNoNewline(WHITESPACE_DELIMITER) == -1) break;
}
}
/*----------------------------------------------------------------------*/
/* Skip to the next token, ignoring any C-style comments. */
/*----------------------------------------------------------------------*/
void SkipTokComments(char *delimiter)
{
SkipTok(delimiter);
while (nexttok) {
if (match(nexttok, "//")) {
SkipNewLine(delimiter);
SkipTok(delimiter);
}
else if (match(nexttok, "/*")) {
while (nexttok && !match(nexttok, "*/"))
SkipTok(delimiter);
if (nexttok) SkipTok(delimiter);
}
else break;
}
}
@@ -310,9 +579,10 @@ void SpiceTokNoNewline(void)
/* skip to the end of the current line */
/*----------------------------------------------------------------------*/
void SkipNewLine(void)
void SkipNewLine(char *delimiter)
{
while (nexttok != NULL) nexttok = strtok(NULL, TOKEN_DELIMITER);
while (nexttok != NULL)
nexttok = strdtok(NULL, WHITESPACE_DELIMITER, delimiter);
}
/*----------------------------------------------------------------------*/
@@ -324,18 +594,155 @@ void SpiceSkipNewLine(void)
{
int contline;
SkipNewLine();
SkipNewLine(NULL);
contline = getc(infile);
while (contline == '+') {
ungetc(contline, infile);
GetNextLine();
SkipNewLine();
GetNextLine(WHITESPACE_DELIMITER);
SkipNewLine(NULL);
contline = getc(infile);
}
ungetc(contline, infile);
}
/*----------------------------------------------------------------------*/
/* Function similar to strtok() for token parsing. The difference is */
/* that it takes two sets of delimiters. The first is whitespace */
/* delimiters, which separate tokens. The second is functional */
/* delimiters, which separate tokens and have additional meaning, such */
/* as parentheses, commas, semicolons, etc. The parser needs to know */
/* when such tokens occur in the string, so they are returned as */
/* individual tokens. */
/* */
/* Definition of delim2: String of single delimiter characters. The */
/* special character "X" (which is never a delimiter in practice) is */
/* used to separate single-character delimiters from two-character */
/* delimiters (this presumably could be further extended as needed). */
/* so ",;()" would be a valid delimiter set, but to include C-style */
/* comments and verilog-style parameter lists, one would need */
/* "X/**///#(X,;()". Two-character delimiters should go first so that */
/* they have precedence over one-character delimiters. 'X' should be */
/* the first character of the delimiter string in addition to marking */
/* the boundary between two-character and one-character delimiters. */
/*----------------------------------------------------------------------*/
char *strdtok(char *pstring, char *delim1, char *delim2)
{
static char *stoken = NULL;
static char *sstring = NULL;
char *s, *s2;
char first = FALSE;
int twofer;
if (pstring != NULL) {
/* Allocate enough memory to hold the string; tokens will be put here */
if (sstring != NULL) FREE(sstring);
sstring = (char *)MALLOC(strlen(pstring) + 1);
stoken = pstring;
first = TRUE;
}
/* Skip over "delim1" delimiters at the string beginning */
for (; *stoken; stoken++) {
for (s2 = delim1; *s2; s2++)
if (*stoken == *s2)
break;
if (*s2 == '\0') break;
}
if (*stoken == '\0') return NULL; /* Finished parsing */
/* "stoken" is now set. Now find the end of the current token */
s = stoken;
/* Special verilog rule: If a name begins with '\', then all characters */
/* are a valid part of the name until a space character is reached. The */
/* space character becomes part of the verilog name. The remainder of the */
/* name is parsed according to the rules of "delim2". */
/* Special verilog rule exception: To handle the problems caused by */
/* translating verilog backslash-escaped names into other netlist formats */
/* like SPICE where the convention is strictly prohibited, I have used the */
/* convention in qflow scripts to replace the trailing space with another */
/* backslash, so the name is effectively delimited by a pair of back- */
/* slashes. Therefore check for a space or another backslash, whichever */
/* comes first. That will satisfy both methods. Technically this routine */
/* should know whether it is parsing SPICE or verilog and handle the syntax */
/* accordingly (needs to be done). */
if (*s == '\\') {
s++;
while (*s != '\0') {
if ((*s == ' ') || (*s == '\\')) {
s++;
break;
}
s++;
}
}
/* Check string from position stoken. If a character in "delim2" is found, */
/* save the character in "lastdelim", null the byte at that position, and */
/* return the token. If a character in "delim1" is found, do the same but */
/* continue checking characters as long as there are contiguous "delim1" */
/* characters. If the series ends in a character from "delim2", then treat */
/* as for "delim2" above. If not, then set "lastdelim" to a null byte and */
/* return the token. */
for (; *s; s++) {
twofer = (delim2 && (*delim2 == 'X')) ? TRUE : FALSE;
for (s2 = ((twofer == TRUE) ? delim2 + 1 : delim2); s2 && *s2; s2++) {
if (*s2 == 'X') {
twofer = FALSE;
continue;
}
if (twofer) {
if ((*s == *s2) && (*(s + 1) == *(s2 + 1))) {
if (s == stoken) {
strncpy(sstring, stoken, 2);
*(sstring + 2) = '\0';
stoken = s + 2;
}
else {
strncpy(sstring, stoken, (int)(s - stoken));
*(sstring + (s - stoken)) = '\0';
stoken = s;
}
return sstring;
}
s2++;
if (*s2 == '\0') break;
}
else if (*s == *s2) {
if (s == stoken) {
strncpy(sstring, stoken, 1);
*(sstring + 1) = '\0';
stoken = s + 1;
}
else {
strncpy(sstring, stoken, (int)(s - stoken));
*(sstring + (s - stoken)) = '\0';
stoken = s;
}
return sstring;
}
}
for (s2 = delim1; *s2; s2++) {
if (*s == *s2) {
strncpy(sstring, stoken, (int)(s - stoken));
*(sstring + (s - stoken)) = '\0';
stoken = s;
return sstring;
}
}
}
strcpy(sstring, stoken); /* Just copy to the end */
stoken = s;
return sstring;
}
/*----------------------------------------------------------------------*/
void InputParseError(FILE *f)
@@ -417,7 +824,7 @@ char *ReadNetlist(char *fname, int *fnum)
};
#ifdef mips
struct filetype formats[6];
struct filetype formats[7];
formats[0].extension = NTK_EXTENSION;
formats[0].proc = ReadNtk;
@@ -429,8 +836,10 @@ char *ReadNetlist(char *fname, int *fnum)
formats[3].proc = ReadSpice;
formats[4].extension = NETGEN_EXTENSION;
formats[4].proc = ReadNetgenFile;
formats[5].extension = NULL;
formats[5].proc = NULL;
formats[5].extension = VERILOG_EXTENSION;
formats[5].proc = ReadVerilogFile;
formats[6].extension = NULL;
formats[6].proc = NULL;
#else /* not mips (i.e. compiler with reasonable initializers) */
@@ -442,6 +851,7 @@ char *ReadNetlist(char *fname, int *fnum)
{SPICE_EXTENSION, ReadSpice},
{SPICE_EXT2, ReadSpice},
{SPICE_EXT3, ReadSpice},
{VERILOG_EXTENSION, ReadVerilog},
{NETGEN_EXTENSION, ReadNetgenFile},
{NULL, NULL}
};
@@ -567,7 +977,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 +1213,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;
}
}
+8 -4
View File
@@ -13,6 +13,7 @@
#define NETGEN_EXTENSION ".ntg"
#define CCODE_EXTENSION ".c.code"
#define ESACAP_EXTENSION ".esa"
#define VERILOG_EXTENSION ".v"
#define LINELENGTH 80
@@ -23,15 +24,18 @@ extern void FlushString (char *format, ...);
extern char *SetExtension(char *buffer, char *path, char *extension);
extern int File;
extern struct hashdict *definitions;
/* input routines */
extern char *nexttok;
#define SKIPTO(a) do {SkipTok();} while (!match(nexttok,a))
extern void SkipTok(void);
extern void SkipTokNoNewline(void);
#define SKIPTO(a) do {SkipTok(NULL);} while (!match(nexttok,a))
extern char *strdtok(char *pstring, char *delim1, char *delim2);
extern void SkipTok(char *delimiter);
extern void SkipTokNoNewline(char *delimiter);
extern void SkipTokComments(char *delimiter);
extern void SkipNewLine(char *delimiter);
extern void SpiceTokNoNewline(void); /* handles SPICE "+" continuation line */
extern void SkipNewLine(void);
extern void SpiceSkipNewLine(void); /* handles SPICE "+" continuation line */
extern void InputParseError(FILE *f);
extern int OpenParseFile(char *name, int fnum);
+597 -171
View File
File diff suppressed because it is too large Load Diff
+17 -8
View File
@@ -33,11 +33,14 @@ 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 void SetSeriesCombine(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);
extern int PropertyMerge(char *name, int fnum, char *key, int merge_type,
int merge_mask);
extern void ResolveProperties(char *name1, int file1, char *name2, int file2);
extern void CopyProperties(struct objlist *obj_to, struct objlist *obj_from);
extern int PromoteProperty(struct property *, struct valuelist *);
@@ -53,6 +56,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);
@@ -82,8 +87,10 @@ extern int PrematchLists(char *, int, char *, int);
#define CLASS_DIODE 16 /* standard SPICE diode */
#define CLASS_INDUCTOR 17 /* standard SPICE inductor */
#define CLASS_XLINE 18 /* transmission line model */
#define CLASS_MODULE 19 /* sim "x"; black-box subcircuit */
#define CLASS_UNDEF 20 /* not defined; error */
#define CLASS_VSOURCE 19 /* independent voltage source */
#define CLASS_ISOURCE 20 /* independent current source */
#define CLASS_MODULE 21 /* sim "x"; black-box subcircuit */
#define CLASS_UNDEF 22 /* not defined; error */
extern char *P(char *fname, char *inststr, char *drain, char *gate, char *source);
extern char *P4(char *fname, char *inststr, char *drain, char *gate, char *source,
@@ -100,9 +107,9 @@ extern char *Res(char *fname, char *inststr, char *, char *);
extern char *XLine(char *fname, char *inststr, char *, char *, char *, char *);
extern char *Inductor(char *fname, char *inststr, char *, char *);
extern int StringIsValue(char *);
extern int StringIsValue(char *);
extern char *ConvertParam(char *);
extern int ConvertStringToFloat(char *, double *);
extern int ConvertStringToFloat(char *, double *);
extern char *ScaleStringFloatValue(char *, double);
extern void join(char *node1, char *node2);
extern void Connect(char *tplt1, char *tplt2);
@@ -116,8 +123,8 @@ extern void FlattenCurrent();
extern void ConvertGlobals(char *name, int fnum);
extern int CleanupPins(char *name, int fnum);
extern void ConnectAllNodes(char *model, int fnum);
extern void CombineParallel(char *model, int fnum);
extern void CombineSerial(char *model, int fnum);
extern int CombineParallel(char *model, int fnum);
extern int CombineSeries(char *model, int fnum);
extern int NoDisconnectedNodes;
extern int PropertyKeyMatch(char *, char *);
extern int PropertyValueMatch(char *, char *);
@@ -132,6 +139,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??? */
@@ -174,6 +182,7 @@ extern char *ReadSim(char *fname, int *fnum);
extern char *ReadSpice(char *fname, int *fnum);
extern char *ReadSpiceLib(char *fname, int *fnum);
extern char *ReadNetgenFile (char *fname, int *fnum);
extern char *ReadVerilog(char *fname, int *fnum);
extern char *ReadNetlist(char *fname, int *fnum);
+27 -23
View File
@@ -27,6 +27,10 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <stdarg.h>
#ifdef TCL_NETGEN
#include <tcl.h>
#endif
#include "netgen.h"
#include "hash.h"
#include "objlist.h"
@@ -186,14 +190,14 @@ 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;
}
}
while (!EndParseFile()) {
SkipTok();
SkipTok(NULL);
if (EndParseFile()) break;
if (nexttok[0] == '|') SKIPTO(";");
else if (match(nexttok, "c")) {
@@ -203,14 +207,14 @@ char *ReadNtk (char *fname, int *fnum)
EndCell();
CellDefInProgress = 0;
}
SkipTok();
SkipTok(NULL);
CellDef(nexttok, CurrentCell->file);
LastCellRead = CurrentCell->name;
CellDefInProgress = 1;
SkipTok();
SkipTok(NULL);
while (!match(nexttok, ";")) {
Port(nexttok);
SkipTok();
SkipTok(NULL);
}
}
else if (match(nexttok, "s")) {
@@ -224,8 +228,8 @@ char *ReadNtk (char *fname, int *fnum)
if (LastCellRead == NULL)
LastCellRead = CurrentCell->name;
}
SkipTok();
SkipTok(); /* eat the 'size' of the node */
SkipTok(NULL);
SkipTok(NULL); /* eat the 'size' of the node */
/* after the 'size', all names are synonyms */
while (!match(nexttok, ";")) {
#if 1
@@ -240,7 +244,7 @@ char *ReadNtk (char *fname, int *fnum)
#endif
if (strlen(last)) join(last, nexttok);
strcpy(last, nexttok);
SkipTok();
SkipTok(NULL);
}
}
else if (match(nexttok, "h")) {
@@ -250,11 +254,11 @@ char *ReadNtk (char *fname, int *fnum)
if (LastCellRead == NULL)
LastCellRead = CurrentCell->name;
}
SkipTok();
SkipTok(NULL);
strcpy(model, nexttok);
strcpy(instancename, nexttok);
strcat(instancename, INSTANCE_DELIMITER);
SkipTok();
SkipTok(NULL);
strcat(instancename, nexttok);
if (LookupCell(model) == NULL) {
#ifdef DEFINE_UNDEFINED_CELLS
@@ -264,7 +268,7 @@ char *ReadNtk (char *fname, int *fnum)
previous_cell = CurrentCell->name;
CellDef(model, CurrentCell->file);
SkipTok();
SkipTok(NULL);
args = 0;
while (!match(nexttok, ";")) {
sprintf(name, "pin%d", args+1);
@@ -273,11 +277,11 @@ char *ReadNtk (char *fname, int *fnum)
args++;
/* check for overflow */
if (args == (sizeof(ports) / sizeof(ports[0]))) {
while (!match(nexttok, ";")) SkipTok();
while (!match(nexttok, ";")) SkipTok(NULL);
break; /* out of while loop */
}
/* if no overflow, get the next token */
SkipTok();
SkipTok(NULL);
}
EndCell();
/* now, reopen previous cell, instance the new cell,
@@ -301,7 +305,7 @@ char *ReadNtk (char *fname, int *fnum)
ob = LookupCell(model)->cell;
while ((ob != NULL) && !IsPort(ob))
ob = ob->next;
SkipTok();
SkipTok(NULL);
while (!match(nexttok, ";")) {
strcpy(name, instancename);
strcat(name, SEPARATOR);
@@ -311,7 +315,7 @@ char *ReadNtk (char *fname, int *fnum)
do {
ob = ob->next;
} while ((ob != NULL) && !IsPort(ob)) ;
SkipTok();
SkipTok(NULL);
}
}
}
@@ -322,12 +326,12 @@ char *ReadNtk (char *fname, int *fnum)
if (LastCellRead == NULL)
LastCellRead = CurrentCell->name;
}
SkipTok();
SkipTok(); /* skip the transistor size */
SkipTok(NULL);
SkipTok(NULL); /* skip the transistor size */
strcpy(name, nexttok);
SkipTok();
SkipTok(NULL);
strcpy(model, nexttok);
SkipTok();
SkipTok(NULL);
strcpy(instancename, nexttok);
N(fname, NULL, name, model, instancename);
SKIPTO(";");
@@ -339,12 +343,12 @@ char *ReadNtk (char *fname, int *fnum)
if (LastCellRead == NULL)
LastCellRead = CurrentCell->name;
}
SkipTok();
SkipTok(); /* skip the transistor size */
SkipTok(NULL);
SkipTok(NULL); /* skip the transistor size */
strcpy(name, nexttok);
SkipTok();
SkipTok(NULL);
strcpy(model, nexttok);
SkipTok();
SkipTok(NULL);
strcpy(instancename, nexttok);
P(fname, NULL, name, model, instancename);
SKIPTO(";");
+49 -8
View File
@@ -184,13 +184,46 @@ int match(char *st1, char *st2)
/* Case-insensitive matching */
/* For case-insensitivity, the alphabet is lower-cased, but */
/* also all common vector delimiters are cast to the same */
/* character so that different vector notations will match. */
static char to_lower[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
':', ';', '<', '=', '>', '?', '@',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'<', '\\', '>', '^', '_', '`',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'<', '|', '>', '~', 127,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
':', ';', '<', '=', '>', '?', '@',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'<', '\\', '>', '^', '_', '`',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'<', '|', '>', '~', 127
};
int matchnocase(char *st1, char *st2)
{
char *sp1 = st1;
char *sp2 = st2;
while (*sp1 != '\0' && *sp2 != '\0') {
if (tolower(*sp1) != tolower(*sp2)) break;
if (to_lower[*sp1] != to_lower[*sp2]) break;
sp1++;
sp2++;
}
@@ -216,7 +249,7 @@ int matchfilenocase(char *st1, char *st2, int f1, int f2)
if (f1 != f2) return 0;
while (*sp1 != '\0' && *sp2 != '\0') {
if (tolower(*sp1) != tolower(*sp2)) break;
if (to_lower[*sp1] != to_lower[*sp2]) break;
sp1++;
sp2++;
}
@@ -257,6 +290,7 @@ void InitCellHashTable(void)
{
hashfunc = hash;
matchfunc = match;
matchintfunc = matchfile;
InitializeHashTable(&cell_dict, CELLHASHSIZE);
}
@@ -348,7 +382,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 +446,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 +503,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 +597,15 @@ 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 */
#ifdef TCL_NETGEN
Tcl_AppendElement(netgeninterp, ptr->name);
#else
Printf("%s ", ptr->name);
#endif
}
}
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 +636,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 +646,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
}
+22 -8
View File
@@ -103,16 +103,30 @@ 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_PAR 3 /* Properties add in parallel with device merge */
#define MERGE_PAR_CRIT 4 /* Properties add in parallel with device merge */
#define MERGE_NONE 0x00 /* Property does not change when devices merge */
#define MERGE_P_ADD 0x01 /* Properties sum with device parallel merge */
#define MERGE_P_PAR 0x02 /* Properties add in parallel with parallel merge */
#define MERGE_P_CRIT 0x04 /* This property enables parallel merging */
#define MERGE_P_XCRIT 0x08 /* Old "critical" behavior (deprecated) */
#define MERGE_S_ADD 0x10 /* Properties sum with device series merge */
#define MERGE_S_PAR 0x20 /* Properties add in parallel with series merge */
#define MERGE_S_CRIT 0x40 /* This property enables series merging */
#define MERGE_S_XCRIT 0x80 /* Old "critical" behavior (deprecated) */
#define MERGE_P_MASK (MERGE_P_ADD | MERGE_P_PAR | MERGE_P_CRIT | MERGE_P_XCRIT)
#define MERGE_S_MASK (MERGE_S_ADD | MERGE_S_PAR | MERGE_S_CRIT | MERGE_S_XCRIT)
#define MERGE_ALL_MASK (MERGE_P_MASK | MERGE_S_MASK)
/* Although the above are flags, "ADD" and "PAR" are mutually exclusive. */
/* Note: A "critical" merge means that the property causes the number of */
/* devices to change. e.g., transistor width is critical; transistor drain */
/* area sums when devices are merged, but does not change the number of devices.*/
/* More than one property can be critical. e.g., width and number of fingers. */
/* Also it is possible for a property (e.g., "value") to be critical for both */
/* series and parallel merging. */
struct property {
char *key; /* name of the property */
@@ -213,10 +227,10 @@ struct nlist {
#define CELL_PROPSMATCHED 0x10 /* properties matched to matching cell */
#define CELL_DUPLICATE 0x20 /* cell has a duplicate */
/* Flags for combination allowances */
/* Flags for combination allowances and prohibitions */
#define COMB_SERIAL 0x20
#define COMB_PARALLEL 0x40
#define COMB_SERIES 0x40
#define COMB_NO_PARALLEL 0x80
extern struct nlist *CurrentCell;
extern struct objlist *CurrentTail;
+14 -3
View File
@@ -801,9 +801,12 @@ void DescribeInstance(char *name, int file)
{
if (ob->node > nodemax) nodemax = ob->node;
else if ((ob->node == -1) && (ob->model.port != PROXY)) {
if (disconnectednodes == 0) Fprintf(stderr, "\n");
disconnectednodes++;
Fprintf(stderr, "Cell %s disconnected node: %s\n", tp->name, ob->name);
if (!(tp->flags & CELL_PLACEHOLDER))
{
if (disconnectednodes == 0) Fprintf(stderr, "\n");
disconnectednodes++;
Fprintf(stderr, "Cell %s disconnected node: %s\n", tp->name, ob->name);
}
}
}
instlist = (unsigned char *) CALLOC((nodemax + 1), sizeof(unsigned char));
@@ -1024,6 +1027,10 @@ void Query(void)
promptstring("Write SPICE: circuit name: ", repstr);
SpiceCell(repstr, filenum, "");
break;
case 'v':
promptstring("Write Verilog: circuit name: ", repstr);
VerilogModule(repstr, filenum, "");
break;
case 'E':
promptstring("Write ESACAP: circuit name: ", repstr);
EsacapCell(repstr,"");
@@ -1062,6 +1069,10 @@ void Query(void)
promptstring("Read SPICE (.ckt) file? ", repstr);
ReadSpice(repstr, &filenum);
break;
case 'V':
promptstring("Read Verilog (.v) file? ", repstr);
ReadVerilog(repstr, &filenum);
break;
case 'G' :
promptstring("Read NETGEN: file? ", repstr);
ReadNetgenFile(repstr, &filenum);
+135 -49
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
@@ -111,6 +117,12 @@ void SpiceSubCell(struct nlist *tp, int IsSubCell)
case CLASS_NPN: case CLASS_PNP: case CLASS_BJT:
spice_class = 'Q';
break;
case CLASS_VSOURCE:
spice_class = 'V';
break;
case CLASS_ISOURCE:
spice_class = 'I';
break;
case CLASS_RES: case CLASS_RES3:
spice_class = 'R';
break;
@@ -166,7 +178,7 @@ void SpiceSubCell(struct nlist *tp, int IsSubCell)
break;
}
/* caps and resistors, print out device value */
/* caps, resistors, voltage and current sources, print out device value */
/* print out device type (model/subcircuit name) */
@@ -211,6 +223,23 @@ void SpiceSubCell(struct nlist *tp, int IsSubCell)
FlushString(" %s", model); /* semiconductor resistor */
break;
case CLASS_VSOURCE:
case CLASS_ISOURCE:
ob = ob->next;
if (ob->type == PROPERTY) {
struct valuelist *vl;
int i;
for (i == 0;; i++) {
vl = &(ob->instance.props[i]);
if (vl->type == PROP_ENDLIST) break;
else if (vl->type == PROP_VALUE) {
FlushString(" %g", vl->value.dval);
break;
}
}
}
break;
default:
FlushString(" %s", model); /* everything else */
}
@@ -398,6 +427,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 +439,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 +469,8 @@ void CleanupSubcell() {
lobj = sobj;
sobj = nobj;
}
if ((has_devices == FALSE) && (auto_blackbox == TRUE))
SetClass(CLASS_MODULE);
}
/*------------------------------------------------------*/
@@ -501,10 +535,10 @@ void ReadSpiceFile(char *fname, int filenum, struct cellstack **CellStackPtr,
while (!EndParseFile()) {
SkipTok(); /* get the next token */
SkipTok(NULL); /* get the next token */
if ((EndParseFile()) && (nexttok == NULL)) break;
if (nexttok[0] == '*') SkipNewLine();
if (nexttok[0] == '*') SkipNewLine(NULL);
else if (matchnocase(nexttok, ".SUBCKT")) {
SpiceTokNoNewline();
@@ -563,18 +597,18 @@ void ReadSpiceFile(char *fname, int filenum, struct cellstack **CellStackPtr,
Printf("Renaming original cell to %s\n", model);
InstanceRename(nexttok, model, filenum);
CellRehash(nexttok, model, filenum);
CellDefNoCase(nexttok, filenum);
CellDef(nexttok, filenum);
tp = LookupCellFile(nexttok, filenum);
}
else if (tp != NULL) { /* Make a new definition for an empty cell */
FreePorts(nexttok);
CellDelete(nexttok, filenum); /* This removes any PLACEHOLDER flag */
CellDefNoCase(model, filenum);
CellDef(model, filenum);
tp = LookupCellFile(model, filenum);
update = 1; /* Will need to update existing instances */
}
else if (tp == NULL) { /* Completely new cell, no name conflict */
CellDefNoCase(model, filenum);
CellDef(model, filenum);
tp = LookupCellFile(model, filenum);
}
@@ -615,7 +649,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
@@ -640,7 +674,7 @@ skip_ends:
while (1) {
SpiceSkipNewLine();
SkipTok();
SkipTok(NULL);
if (EndParseFile()) break;
if (matchnocase(nexttok, ".ENDS")) {
in_subckt = 0;
@@ -662,7 +696,7 @@ skip_ends:
if (*CellStackPtr) PopStack(CellStackPtr);
if (*CellStackPtr) ReopenCellDef((*CellStackPtr)->cellname, filenum);
SkipNewLine();
SkipNewLine(NULL);
}
else if (matchnocase(nexttok, ".MODEL")) {
unsigned char class = CLASS_SUBCKT;
@@ -700,6 +734,12 @@ skip_ends:
else if (!strcasecmp(nexttok, "R")) {
class = CLASS_RES;
}
else if (!strcasecmp(nexttok, "V")) {
class = CLASS_VSOURCE;
}
else if (!strcasecmp(nexttok, "I")) {
class = CLASS_ISOURCE;
}
else if (!strcasecmp(nexttok, "C")) {
class = CLASS_CAP;
}
@@ -734,7 +774,7 @@ skip_ends:
if (numnodes == 0) {
// If there is no current cell, make one
if (!(*CellStackPtr)) {
CellDefNoCase(fname, filenum);
CellDef(fname, filenum);
PushStack(fname, CellStackPtr);
}
Global(nexttok);
@@ -743,7 +783,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 +795,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 +867,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);
}
@@ -816,7 +888,7 @@ skip_ends:
collector[99] = '\0';
if (!(*CellStackPtr)) {
CellDefNoCase(fname, filenum);
CellDef(fname, filenum);
PushStack(fname, CellStackPtr);
}
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
@@ -848,7 +920,7 @@ skip_ends:
}
if (LookupCellFile(model, filenum) == NULL) {
CellDefNoCase(model, filenum);
CellDef(model, filenum);
Port("collector");
Port("base");
Port("emitter");
@@ -877,7 +949,7 @@ skip_ends:
bulk[99] = '\0';
if (!(*CellStackPtr)) {
CellDefNoCase(fname, filenum);
CellDef(fname, filenum);
PushStack(fname, CellStackPtr);
}
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
@@ -918,7 +990,7 @@ skip_ends:
/* SPICE transistor. */
if (LookupCellFile(model, filenum) == NULL) {
CellDefNoCase(model, filenum);
CellDef(model, filenum);
Port("drain");
Port("gate");
Port("source");
@@ -955,7 +1027,7 @@ skip_ends:
cbot[99] = '\0';
if (!(*CellStackPtr)) {
CellDefNoCase(fname, filenum);
CellDef(fname, filenum);
PushStack(fname, CellStackPtr);
}
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
@@ -1009,7 +1081,7 @@ skip_ends:
else
{
if (LookupCellFile(model, filenum) == NULL) {
CellDefNoCase(model, filenum);
CellDef(model, filenum);
Port("top");
Port("bottom");
PropertyValue(model, filenum, "value", 0.01, 0.0);
@@ -1049,7 +1121,7 @@ skip_ends:
rbot[99] = '\0';
if (!(*CellStackPtr)) {
CellDefNoCase(fname, filenum);
CellDef(fname, filenum);
PushStack(fname, CellStackPtr);
}
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
@@ -1100,7 +1172,7 @@ skip_ends:
if (model[0] != '\0')
{
if (LookupCellFile(model, filenum) == NULL) {
CellDefNoCase(model, filenum);
CellDef(model, filenum);
Port("end_a");
Port("end_b");
PropertyValue(model, filenum, "value", 0.01, 0.0);
@@ -1136,7 +1208,7 @@ skip_ends:
anode[99] = '\0';
if (!(*CellStackPtr)) {
CellDefNoCase(fname, filenum);
CellDef(fname, filenum);
PushStack(fname, CellStackPtr);
}
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
@@ -1165,7 +1237,7 @@ skip_ends:
}
if (LookupCellFile(model, filenum) == NULL) {
CellDefNoCase(model, filenum);
CellDef(model, filenum);
Port("anode");
Port("cathode");
PropertyInteger(model, filenum, "M", 0, 1);
@@ -1198,7 +1270,7 @@ skip_ends:
node4[99] = '\0';
if (!(*CellStackPtr)) {
CellDefNoCase(fname, filenum);
CellDef(fname, filenum);
PushStack(fname, CellStackPtr);
}
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
@@ -1236,7 +1308,7 @@ skip_ends:
if (model[0] != '\0')
{
if (LookupCellFile(model, filenum) == NULL) {
CellDefNoCase(model, filenum);
CellDef(model, filenum);
Port("node1");
Port("node2");
Port("node3");
@@ -1276,7 +1348,7 @@ skip_ends:
end_b[99] = '\0';
if (!(*CellStackPtr)) {
CellDefNoCase(fname, filenum);
CellDef(fname, filenum);
PushStack(fname, CellStackPtr);
}
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
@@ -1321,7 +1393,7 @@ skip_ends:
if (model[0] != '\0')
{
if (LookupCellFile(model, filenum) == NULL) {
CellDefNoCase(model, filenum);
CellDef(model, filenum);
Port("end_a");
Port("end_b");
PropertyInteger(model, filenum, "M", 0, 1);
@@ -1359,7 +1431,7 @@ skip_ends:
neg[99] = '\0';
if (!(*CellStackPtr)) {
CellDefNoCase(fname, filenum);
CellDef(fname, filenum);
PushStack(fname, CellStackPtr);
}
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
@@ -1389,11 +1461,11 @@ skip_ends:
}
strcpy(model, "vsrc"); /* Default voltage source */
if (LookupCellFile(model, filenum) == NULL) {
CellDefNoCase(model, filenum);
CellDef(model, filenum);
Port("pos");
Port("neg");
PropertyInteger(model, filenum, "M", 0, 1);
SetClass(CLASS_MODULE);
SetClass(CLASS_VSOURCE);
EndCell();
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
}
@@ -1414,7 +1486,7 @@ skip_ends:
neg[99] = '\0';
if (!(*CellStackPtr)) {
CellDefNoCase(fname, filenum);
CellDef(fname, filenum);
PushStack(fname, CellStackPtr);
}
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
@@ -1443,11 +1515,11 @@ skip_ends:
}
strcpy(model, "isrc"); /* Default current source */
if (LookupCellFile(model, filenum) == NULL) {
CellDefNoCase(model, filenum);
CellDef(model, filenum);
Port("pos");
Port("neg");
PropertyInteger(model, filenum, "M", 0, 1);
SetClass(CLASS_MODULE);
SetClass(CLASS_ISOURCE);
EndCell();
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
}
@@ -1470,7 +1542,7 @@ skip_ends:
ctrln[99] = '\0';
if (!(*CellStackPtr)) {
CellDefNoCase(fname, filenum);
CellDef(fname, filenum);
PushStack(fname, CellStackPtr);
}
strncpy(inst, nexttok + 1, 99); SpiceTokNoNewline();
@@ -1506,7 +1578,7 @@ skip_ends:
}
strcpy(model, "vcvs"); /* Default controlled voltage source */
if (LookupCellFile(model, filenum) == NULL) {
CellDefNoCase(model, filenum);
CellDef(model, filenum);
Port("pos");
Port("neg");
Port("ctrlp");
@@ -1530,7 +1602,7 @@ skip_ends:
else if (toupper(nexttok[0]) == 'X') { /* subcircuit instances */
char instancename[100], subcktname[100];
int itype;
int itype, in_props;
instancename[99] = '\0';
subcktname[99] = '\0';
@@ -1546,13 +1618,14 @@ skip_ends:
snprintf(instancename, 99, "%s", nexttok + 1);
strncpy(instancename, nexttok + 1, 99);
if (!(*CellStackPtr)) {
CellDefNoCase(fname, filenum);
CellDef(fname, filenum);
PushStack(fname, CellStackPtr);
}
head = NULL;
tail = NULL;
SpiceTokNoNewline();
in_props = FALSE;
while (nexttok != NULL) {
/* must still be a node or a parameter */
struct portelement *new_port;
@@ -1579,10 +1652,11 @@ skip_ends:
if (((eqptr = strchr(nexttok, '=')) != NULL) &&
((tp = LookupCellFile(nexttok, filenum)) == NULL))
{
in_props = TRUE;
*eqptr = '\0';
AddProperty(&kvlist, nexttok, eqptr + 1);
}
else
else if (in_props == FALSE)
{
new_port = (struct portelement *)CALLOC(1, sizeof(struct portelement));
new_port->name = strsave(nexttok);
@@ -1591,6 +1665,11 @@ skip_ends:
new_port->next = NULL;
tail = new_port;
}
else
{
Fprintf(stderr, "Token \"%s\" is not a parameter!\n", nexttok);
InputParseError(stderr);
}
SpiceTokNoNewline();
}
@@ -1671,7 +1750,7 @@ skip_ends:
Fprintf(stdout, "Call to undefined subcircuit %s\n"
"Creating placeholder cell definition.\n", subcktname);
CellDefNoCase(subcktname, filenum);
CellDef(subcktname, filenum);
CurrentCell->flags |= CELL_PLACEHOLDER;
for (scan = head, i = 1; scan != NULL; scan = scan->next, i++) {
sprintf(defport, "%d", i);
@@ -1808,7 +1887,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;
}
@@ -1839,7 +1918,7 @@ char *ReadSpiceTop(char *fname, int *fnum, int blackbox)
// as an empty cell. Otherwise, the filename is lost and cells
// cannot be matched to the file!
if (LookupCellFile(fname, filenum) == NULL) CellDefNoCase(fname, filenum);
if (LookupCellFile(fname, filenum) == NULL) CellDef(fname, filenum);
tp = LookupCellFile(fname, filenum);
if (tp) tp->flags |= CELL_TOP;
@@ -1898,14 +1977,21 @@ 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);
return;
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;
}
}
else {
Fprintf(stderr, "Error in SPICE file include: No file %s\n", fname);
return;
}
}
}
ReadSpiceFile(fname, parent, CellStackPtr, blackbox);
+2182
View File
File diff suppressed because it is too large Load Diff
+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();
Vendored
+1 -1
View File
@@ -4,4 +4,4 @@
# all of its config scripts in a different directory than the configure
# script itself.
( CFLAGS="-g" ; export CFLAGS ; cd scripts ; ./configure $* )
( CFLAGS="-g" ; export CFLAGS ; cd scripts ; ./configure "$@" )
-84
View File
@@ -1,84 +0,0 @@
# defs.mak.in --
# source file for autoconf-generated "defs.mak" for netgen
# defs.mak. Generated from defs.mak.in by configure.
# Feel free to change the values in here to suit your needs.
# Be aware that running scripts/configure again will overwrite
# any changes!
SHELL = /bin/sh
prefix = ${BUILDROOT}/usr/local
exec_prefix = ${prefix}
bindir = ${exec_prefix}/bin
libdir = ${exec_prefix}/lib
mandir = ${prefix}/share/man
VERSION =
SCRIPTS = ${NETGENDIR}/scripts
INSTALL = /bin/install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL}
# Override standard "make" target when compiling under TCL
ALL_TARGET = tcl
INSTALL_TARGET = install-tcl
# Change CADDIR to install in a different place
BINDIR = ${bindir}
MANDIR = ${mandir}
LIBDIR = ${libdir}
DOCDIR = ${libdir}/netgen/doc
TCLDIR = ${libdir}/netgen/tcl
MAIN_EXTRA_LIBS = ${NETGENDIR}/tcltk/libtcltk.o
LD_EXTRA_LIBS =
LD_SHARED =
TOP_EXTRA_LIBS =
SUB_EXTRA_LIBS =
MODULES += tcltk
UNUSED_MODULES +=
PROGRAMS += tcltk
INSTALL_CAD_DIRS += tcltk
RM = rm -f
CP = cp
AR = @AR@
ARFLAGS = crv
LINK = /bin/ld -r
LD = /bin/ld
M4 = /bin/m4
RANLIB = ranlib
SHDLIB_EXT = .so
LDDL_FLAGS = -shared -Wl,-soname,$@ -Wl,--version-script=${NETGENDIR}/netgen/symbol.map
LD_RUN_PATH =
LIB_SPECS = -L/usr/lib64 -ltkstub8.6 -L/usr/lib64 -ltclstub8.6
LIB_SPECS_NOSTUB = -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6
WISH_EXE = /usr/bin/wish
TCL_LIB_DIR = /usr/lib
CC = gcc
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
CFLAGS = -g -m64 -fPIC -fPIC
DEPEND_FILE = Depend
DEPEND_FLAG = -MM
EXEEXT =
GR_CFLAGS =
GR_DFLAGS = -DX11 -DXLIB -DNDEBUG
GR_LIBS = -lX11
GR_SRCS = ${TK_SRCS}
OBJS = ${SRCS:.c=.o}
LIB_OBJS = ${LIB_SRCS:.c=.o}
CLEANS = ${OBJS} ${LIB_OBJS} lib${MODULE}.a lib${MODULE}.o ${MODULE}
+9 -9
View File
@@ -2,15 +2,15 @@ NETGENDIR = ..
include ${NETGENDIR}/defs.mak
MANDIRS = $(DESTDIR)${MANDIR} $(DESTDIR)${MANDIR}/man1
DOCDIRS = $(DESTDIR)${DOCDIR}
MANDIRS = $(DESTDIR)${INSTALL_MANDIR} $(DESTDIR)${INSTALL_MANDIR}/man1
DOCDIRS = $(DESTDIR)${INSTALL_DOCDIR}
MANFILES =
DOCFILES = $(DESTDIR)${DOCDIR}/netgen.doc
DOCFILES = $(DESTDIR)${INSTALL_DOCDIR}/netgen.doc
install-tcl: ${MANDIRS} ${MANFILES} ${DOCDIRS} ${DOCFILES}
install-tcl: ${DOCDIRS} ${DOCFILES}
install: ${MANDIRS} ${MANFILES} ${DOCDIRS} ${DOCFILES}
install: ${DOCDIRS} ${DOCFILES}
${MANDIRS}: make-man-dirs
@@ -23,8 +23,8 @@ make-doc-dirs:
${SCRIPTS}/mkdirs ${DOCDIRS}
# This file does not actually exist. . .
$(DESTDIR)${MANDIR}/man1/netgen.1: netgen.1 ${MANDIRS}
${CP} netgen.1 $(DESTDIR)${MANDIR}/man1/netgen.1
$(DESTDIR)${INSTALL_MANDIR}/man1/netgen.1: netgen.1 ${MANDIRS}
${CP} netgen.1 $(DESTDIR)${INSTALL_MANDIR}/man1/netgen.1
$(DESTDIR)${DOCDIR}/netgen.doc: netgen.doc ${DOCDIRS}
${CP} netgen.doc $(DESTDIR)${DOCDIR}/netgen.doc
$(DESTDIR)${INSTALL_DOCDIR}/netgen.doc: netgen.doc ${DOCDIRS}
${CP} netgen.doc $(DESTDIR)${INSTALL_DOCDIR}/netgen.doc
+6 -6
View File
@@ -4,14 +4,14 @@ include ${NETGENDIR}/defs.mak
LIB_FILES = ntk2adl.sh spice spice.bot spice.top
LIB_INST_FILES= $(LIB_FILES:%=$(DESTDIR)${LIBDIR}/netgen/%)
BIN_INST_FILES= $(BIN_FILES:%=$(DESTDIR)${BINDIR}/%)
LIB_INST_FILES= $(LIB_FILES:%=$(DESTDIR)${INSTALL_LIBDIR}/netgen/%)
BIN_INST_FILES= $(BIN_FILES:%=$(DESTDIR)${INSTALL_BINDIR}/%)
install-tcl: ${LIB_INST_FILES}
install: ${LIB_INST_FILES}
$(DESTDIR)${LIBDIR}/netgen/%: %
../scripts/mkdirs $(DESTDIR)${LIBDIR}/netgen
${RM} $(DESTDIR)${LIBDIR}/netgen/$*
${CP} $* $(DESTDIR)${LIBDIR}/netgen/$*
$(DESTDIR)${INSTALL_LIBDIR}/netgen/%: %
../scripts/mkdirs $(DESTDIR)${INSTALL_LIBDIR}/netgen
${RM} $(DESTDIR)${INSTALL_LIBDIR}/netgen/$*
${CP} $* $(DESTDIR)${INSTALL_LIBDIR}/netgen/$*
+14 -14
View File
@@ -22,26 +22,26 @@ 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:
$(DESTDIR)${INSTALL_BINDIR}/netgen:
${RM} $@
${CP} netgen $@
$(DESTDIR)${BINDIR}/ntk2adl:
$(DESTDIR)${INSTALL_BINDIR}/ntk2adl:
${RM} $@
${CP} ntk2adl $@
$(DESTDIR)${BINDIR}/ntk2xnf:
$(DESTDIR)${INSTALL_BINDIR}/ntk2xnf:
${RM} $@
${CP} ntk2xnf $@
$(DESTDIR)${BINDIR}/netcomp:
$(DESTDIR)${INSTALL_BINDIR}/netcomp:
${RM} $@
${CP} netcomp $@
$(DESTDIR)${BINDIR}/inetcomp:
$(DESTDIR)${INSTALL_BINDIR}/inetcomp:
${RM} $@
${CP} inetcomp $@
@@ -61,14 +61,14 @@ ntk2xnf: ntk2xnf.c
${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} ntk2xnf.c -o $@ ${EXTRA_LIBS} \
${LIBS} ${LDFLAGS}
install: $(DESTDIR)${BINDIR}/netgen $(DESTDIR)${BINDIR}/netcomp \
$(DESTDIR)${BINDIR}/inetcomp $(DESTDIR)${BINDIR}/ntk2adl \
$(DESTDIR)${BINDIR}/ntk2xnf
install: $(DESTDIR)${INSTALL_BINDIR}/netgen $(DESTDIR)${INSTALL_BINDIR}/netcomp \
$(DESTDIR)${INSTALL_BINDIR}/inetcomp $(DESTDIR)${INSTALL_BINDIR}/ntk2adl \
$(DESTDIR)${INSTALL_BINDIR}/ntk2xnf
install-tcl: $(DESTDIR)${TCLDIR} $(DESTDIR)${TCLDIR}/tclnetgen${SHDLIB_EXT}
install-tcl: $(DESTDIR)${INSTALL_TCLDIR} $(DESTDIR)${INSTALL_TCLDIR}/tclnetgen${SHDLIB_EXT}
$(DESTDIR)${TCLDIR}/tclnetgen${SHDLIB_EXT}: tclnetgen${SHDLIB_EXT}
${RM} $(DESTDIR)${TCLDIR}/tclnetgen${SHDLIB_EXT}
${CP} tclnetgen${SHDLIB_EXT} $(DESTDIR)${TCLDIR}/tclnetgen${SHDLIB_EXT}
$(DESTDIR)${INSTALL_TCLDIR}/tclnetgen${SHDLIB_EXT}: tclnetgen${SHDLIB_EXT}
${RM} $(DESTDIR)${INSTALL_TCLDIR}/tclnetgen${SHDLIB_EXT}
${CP} tclnetgen${SHDLIB_EXT} $(DESTDIR)${INSTALL_TCLDIR}/tclnetgen${SHDLIB_EXT}
include ${NETGENDIR}/rules.mak
View File
+54
View File
@@ -0,0 +1,54 @@
MODULE = python
NETGENDIR = ..
SRCS =
SCRIPTS = consoletext.py helpwindow.py lvs_manager.py treeviewsplit.py
SCRIPTS += tksimpledialog.py tooltip.py lvs_help.txt
SCRIPTINSTALL = $(DESTDIR)${INSTALL_PYDIR}
include ${NETGENDIR}/defs.mak
main: lvs_manager.py
tcl-main: lvs_manager.py
$(DESTDIR)${INSTALL_PYDIR}/consoletext.py:
${RM} $@
${CP} consoletext.py $@
$(DESTDIR)${INSTALL_PYDIR}/helpwindow.py:
${RM} $@
${CP} helpwindow.py $@
lvs_manager.py: lvs_manager.py.in
sed -e '/SUBST_SCRIPT_DIR/s#SUBST_SCRIPT_DIR#$(SCRIPTINSTALL)#' \
lvs_manager.py.in > lvs_manager.py
$(DESTDIR)${INSTALL_PYDIR}/lvs_manager.py: lvs_manager.py
${RM} $@
${CP} lvs_manager.py $@
$(DESTDIR)${INSTALL_PYDIR}/treeviewsplit.py: treeviewsplit.py
${RM} $@
${CP} treeviewsplit.py $@
$(DESTDIR)${INSTALL_PYDIR}/tksimpledialog.py: tksimpledialog.py
${RM} $@
${CP} tksimpledialog.py $@
$(DESTDIR)${INSTALL_PYDIR}/tooltip.py: tooltip.py
${RM} $@
${CP} tooltip.py $@
$(DESTDIR)${INSTALL_PYDIR}/lvs_help.txt: lvs_help.txt
${RM} $@
${CP} lvs_help.txt $@
install: install-tcl
install-tcl: $(DESTDIR)${INSTALL_PYDIR} $(DESTDIR)${INSTALL_PYDIR}/consoletext.py \
$(DESTDIR)${INSTALL_PYDIR}/helpwindow.py $(DESTDIR)${INSTALL_PYDIR}/lvs_manager.py \
$(DESTDIR)${INSTALL_PYDIR}/treeviewsplit.py $(DESTDIR)${INSTALL_PYDIR}/tksimpledialog.py \
$(DESTDIR)${INSTALL_PYDIR}/tooltip.py $(DESTDIR)${INSTALL_PYDIR}/lvs_help.txt
include ${NETGENDIR}/rules.mak
+54
View File
@@ -0,0 +1,54 @@
#!/bin/env python3
#
#--------------------------------------------------------
"""
consoletext --- extends tkinter class Text
with stdout and stderr redirection.
"""
#--------------------------------------------------------
# Written by Tim Edwards
# efabless, inc.
# September 11, 2016
# Version 0.1
#--------------------------------------------------------
import sys
import tkinter
class ConsoleText(tkinter.Text):
linelimit = 500
class IORedirector(object):
'''A general class for redirecting I/O to this Text widget.'''
def __init__(self,text_area):
self.text_area = text_area
class StdoutRedirector(IORedirector):
'''A class for redirecting stdout to this Text widget.'''
def write(self,str):
self.text_area.write(str,False)
class StderrRedirector(IORedirector):
'''A class for redirecting stderr to this Text widget.'''
def write(self,str):
self.text_area.write(str,True)
def __init__(self, master=None, cnf={}, **kw):
'''See the __init__ for Tkinter.Text.'''
tkinter.Text.__init__(self, master, cnf, **kw)
self.tag_configure('stdout',background='white',foreground='black')
self.tag_configure('stderr',background='white',foreground='red')
# None of these works! Cannot change selected text background!
self.config(selectbackground='blue', selectforeground='white')
self.tag_configure('sel',background='blue',foreground='white')
def write(self, val, is_stderr=False):
lines = int(self.index('end-1c').split('.')[0])
if lines > self.linelimit:
self.delete('1.0', str(lines - self.linelimit) + '.0')
self.insert('end',val,'stderr' if is_stderr else 'stdout')
self.see('end')
def limit(self, val):
self.linelimit = val
+229
View File
@@ -0,0 +1,229 @@
#!/bin/env python3
#
#--------------------------------------------------------
# Help Window for the Open Galaxy project manager
#
#--------------------------------------------------------
# Written by Tim Edwards
# efabless, inc.
# September 12, 2016
# Version 0.1
#--------------------------------------------------------
import re
import tkinter
from tkinter import ttk
class HelpWindow(tkinter.Toplevel):
"""Open Galaxy help window."""
def __init__(self, parent=None, fontsize = 11, *args, **kwargs):
'''See the __init__ for Tkinter.Toplevel.'''
tkinter.Toplevel.__init__(self, parent, *args, **kwargs)
s = ttk.Style()
s.configure('normal.TButton', font=('Helvetica', fontsize), border = 3, relief = 'raised')
self.withdraw()
self.title('Open Galaxy Help')
self.helptitle = ttk.Label(self, style='title.TLabel', text = '(no text)')
self.helptitle.grid(column = 0, row = 0, sticky = "news")
self.helpbar = ttk.Separator(self, orient='horizontal')
self.helpbar.grid(column = 0, row = 1, sticky = "news")
self.hframe = tkinter.Frame(self)
self.hframe.grid(column = 0, row = 2, sticky = "news")
self.hframe.helpdisplay = ttk.Frame(self.hframe)
self.hframe.helpdisplay.pack(side = 'left', fill = 'both', expand = 'true')
self.hframe.helpdisplay.helptext = tkinter.Text(self.hframe.helpdisplay, wrap='word')
self.hframe.helpdisplay.helptext.pack(side = 'top', fill = 'both', expand = 'true')
# Add scrollbar to help window
self.hframe.scrollbar = ttk.Scrollbar(self.hframe)
self.hframe.scrollbar.pack(side='right', fill='y')
# attach help window to scrollbar
self.hframe.helpdisplay.helptext.config(yscrollcommand = self.hframe.scrollbar.set)
self.hframe.scrollbar.config(command = self.hframe.helpdisplay.helptext.yview)
self.hframe.toc = ttk.Treeview(self.hframe, selectmode='browse')
self.hframe.toc.bind('<<TreeviewSelect>>', self.toc_to_page)
self.hframe.toc.bind('<<TreeviewOpen>>', self.toc_toggle)
self.hframe.toc.bind('<<TreeviewClose>>', self.toc_toggle)
self.hframe.toc.tag_configure('title', font=('Helvetica', fontsize, 'bold italic'),
foreground = 'brown', anchor = 'center')
self.hframe.toc.heading('#0', text = "Table of Contents")
self.bbar = ttk.Frame(self)
self.bbar.grid(column = 0, row = 3, sticky = "news")
self.bbar.close_button = ttk.Button(self.bbar, text='Close',
command=self.close, style = 'normal.TButton')
self.bbar.close_button.grid(column=0, row=0, padx = 5)
self.bbar.prev_button = ttk.Button(self.bbar, text='Prev',
command=self.prevpage, style = 'normal.TButton')
self.bbar.prev_button.grid(column=1, row=0, padx = 5)
self.bbar.next_button = ttk.Button(self.bbar, text='Next',
command=self.nextpage, style = 'normal.TButton')
self.bbar.next_button.grid(column=2, row=0, padx = 5)
self.bbar.contents_button = ttk.Button(self.bbar, text='Table of Contents',
command=self.page_to_toc, style = 'normal.TButton')
self.bbar.contents_button.grid(column=3, row=0, padx = 5)
self.rowconfigure(0, weight=0)
self.rowconfigure(1, weight=0)
self.rowconfigure(2, weight=1)
self.rowconfigure(3, weight=0)
self.columnconfigure(0, weight=1)
# Help pages
self.pages = []
self.pageno = -1 # No page
self.toggle = False
def grid_configure(self, padx, pady):
pass
def redisplay(self):
# remove contents
if self.pageno >= 0 and self.pageno < len(self.pages):
self.hframe.helpdisplay.helptext.delete('1.0', 'end')
self.hframe.helpdisplay.helptext.insert('end', self.pages[self.pageno]['text'])
self.helptitle.configure(text = self.pages[self.pageno]['title'])
def toc_toggle(self, event):
self.toggle = True
def toc_to_page(self, event):
treeview = event.widget
selection = treeview.item(treeview.selection())
# Make sure any open/close callback is handled first!
self.update_idletasks()
if self.toggle:
# Item was opened or closed, so consider this a 'false select' and
# do not go to the page.
self.toggle = False
return
if 'values' in selection:
pagenum = selection['values'][0]
else:
print('Unknown page selected.')
pagenum = 0
# Display a page after displaying the table of contents
self.hframe.toc.pack_forget()
self.hframe.scrollbar.pack_forget()
self.hframe.helpdisplay.pack(side='left', fill='both', expand = 'true')
self.hframe.scrollbar.pack(side='right', fill='y')
self.hframe.scrollbar.config(command = self.hframe.helpdisplay.helptext.yview)
# Enable Prev and Next buttons
self.bbar.prev_button.configure(state='enabled')
self.bbar.next_button.configure(state='enabled')
# Redisplay
self.page(pagenum)
def page_to_toc(self):
# Display the table of contents after displaying a page
self.hframe.scrollbar.pack_forget()
self.hframe.helpdisplay.pack_forget()
self.hframe.toc.pack(side='left', fill='both', expand = 'true')
self.hframe.scrollbar.pack(side='right', fill='y')
self.hframe.scrollbar.config(command = self.hframe.toc.yview)
# Disable Prev and Next buttons
self.bbar.prev_button.configure(state='disabled')
self.bbar.next_button.configure(state='disabled')
# Simple add page with a single block of plain text
def add_page(self, toc_text, text_block):
newdict = {}
newdict['text'] = text_block
newdict['title'] = toc_text
self.pages.append(newdict)
newpageno = len(self.pages)
self.hframe.toc.insert('', 'end', text=str(newpageno) + '. ' + toc_text,
tag='title', value = newpageno - 1)
if self.pageno < 0:
self.pageno = 0 # First page
# Fill the help text from a file. The format of the file is:
# <page_num>
# <title>
# <text>
# '.'
# Text is multi-line and ends when '.' is encountered by itself
def add_pages_from_file(self, filename):
endpagerex = re.compile('^\.$')
newpagerex = re.compile('^[0-9\.]+$')
commentrex = re.compile('^[\-]+$')
hierarchy = ''
print('Loading help text from file ' + filename)
with open(filename, 'r') as f:
toc_text = []
page_text = []
for line in f:
if newpagerex.match(line) or endpagerex.match(line):
if toc_text and page_text:
newdict = {}
self.pages.append(newdict)
newpageno = len(self.pages)
if '.' in hierarchy:
pageinfo = hierarchy.rsplit('.', 1)
if pageinfo[1] == '':
parentid = ''
pageid = pageinfo[0]
else:
parentid = pageinfo[0]
pageid = pageinfo[1]
else:
parentid = ''
pageid = hierarchy
if parentid:
pageid = parentid + '.' + pageid
newdict['text'] = page_text
newdict['title'] = pageid + '. ' + toc_text
self.hframe.toc.insert(parentid, 'end',
text=newdict['title'], tag='title',
value = newpageno - 1, iid = pageid)
if newpagerex.match(line):
hierarchy = line.rstrip()
toc_text = []
elif not toc_text:
toc_text = line.rstrip()
page_text = []
elif not commentrex.match(line):
if not page_text:
page_text = line
else:
page_text += line
def nextpage(self):
# Go to next page
if self.pageno < len(self.pages) - 1:
self.pageno += 1
self.redisplay()
def prevpage(self):
# Go to previous page
if self.pageno > 0:
self.pageno -= 1
self.redisplay()
def page(self, pagenum):
# Go to indicated page
if pagenum >= 0 and pagenum < len(self.pages):
self.pageno = pagenum
self.redisplay()
def close(self):
# pop down help window
self.withdraw()
def open(self):
# pop up help window
self.deiconify()
self.lift()
+5
View File
@@ -0,0 +1,5 @@
1.
Selecting a project
-------
Start by selecting a project. This step is only necessary if the application is started from the command line. If started from the project manager, then it can only be run if a project was selected.
.
+819
View File
@@ -0,0 +1,819 @@
#!/bin/env python3
#
#--------------------------------------------------------
# LVS Manager GUI.
#
# This is a Python tkinter script that handles the
# process of running LVS and interpreting results.
#
#--------------------------------------------------------
# Written by Tim Edwards
# efabless, inc.
# Version 1. November 30, 2016
# Version 2. March 6, 2017. Reads JSON format output
# Version 3. April 25, 2018. Handles layout vs. verilog
#--------------------------------------------------------
import io
import os
import re
import sys
import json
import shutil
import signal
import socket
import select
import datetime
import contextlib
import subprocess
import tkinter
from tkinter import ttk
from tkinter import filedialog
import tksimpledialog
import tooltip
from consoletext import ConsoleText
from helpwindow import HelpWindow
from treeviewsplit import TreeViewSplit
# User preferences file (if it exists)
prefsfile = '~/.profile/prefs.json'
netgen_script_dir = '/usr/local/lib/netgen/python'
#------------------------------------------------------
# Simple dialog for confirming quit
#------------------------------------------------------
class ConfirmDialog(tksimpledialog.Dialog):
def body(self, master, warning, seed):
if warning:
ttk.Label(master, text=warning, wraplength=500).grid(row = 0, columnspan = 2, sticky = 'wns')
return self
def apply(self):
return 'okay'
#------------------------------------------------------
# Main class for this application
#------------------------------------------------------
class LVSManager(ttk.Frame):
"""LVS Manager GUI."""
def __init__(self, parent, *args, **kwargs):
ttk.Frame.__init__(self, parent, *args, **kwargs)
self.root = parent
self.init_gui()
parent.protocol("WM_DELETE_WINDOW", self.on_quit)
def on_quit(self):
"""Exits program."""
if self.msock:
self.msock.close()
quit()
def init_gui(self):
"""Builds GUI."""
global prefsfile
message = []
fontsize = 11
# Read user preferences file, get default font size from it.
prefspath = os.path.expanduser(prefsfile)
if os.path.exists(prefspath):
with open(prefspath, 'r') as f:
self.prefs = json.load(f)
if 'fontsize' in self.prefs:
fontsize = self.prefs['fontsize']
else:
self.prefs = {}
s = ttk.Style()
available_themes = s.theme_names()
s.theme_use(available_themes[0])
s.configure('bg.TFrame', background='gray40')
s.configure('italic.TLabel', font=('Helvetica', fontsize, 'italic'))
s.configure('title.TLabel', font=('Helvetica', fontsize, 'bold italic'),
foreground = 'brown', anchor = 'center')
s.configure('normal.TLabel', font=('Helvetica', fontsize))
s.configure('red.TLabel', font=('Helvetica', fontsize), foreground = 'red')
s.configure('green.TLabel', font=('Helvetica', fontsize), foreground = 'green3')
s.configure('blue.TLabel', font=('Helvetica', fontsize), foreground = 'blue')
s.configure('normal.TButton', font=('Helvetica', fontsize),
border = 3, relief = 'raised')
s.configure('red.TButton', font=('Helvetica', fontsize), foreground = 'red',
border = 3, relief = 'raised')
s.configure('green.TButton', font=('Helvetica', fontsize), foreground = 'green3',
border = 3, relief = 'raised')
s.configure('blue.TButton', font=('Helvetica', fontsize), foreground = 'blue',
border = 3, relief = 'raised')
s.configure('redtitle.TButton', font=('Helvetica', fontsize, 'bold italic'),
foreground = 'red', border = 3, relief = 'raised')
s.configure('bluetitle.TButton', font=('Helvetica', fontsize, 'bold italic'),
foreground = 'blue', border = 3, relief = 'raised')
# These values to be overridden from arguments
self.rootpath = None
self.project = None
self.logfile = None
self.msock = None
self.help = None
# Create the help window
if os.path.exists(netgen_script_dir + '/netgen_help.txt'):
self.help = HelpWindow(self, fontsize = fontsize)
with io.StringIO() as buf, contextlib.redirect_stdout(buf):
self.help.add_pages_from_file('lvs_help.txt')
message = buf.getvalue()
# Set the help display to the first page
self.help.page(0)
# Variables used by option menus and other stuff
self.project = "(no selection)"
self.layout = "(default)"
self.schematic = "(default)"
self.tech = "(none)"
self.lvs_setup = ''
self.lvsdata = {}
# Root window title
self.root.title('LVS Manager')
self.root.option_add('*tearOff', 'FALSE')
self.pack(side = 'top', fill = 'both', expand = 'true')
pane = tkinter.PanedWindow(self, orient = 'vertical', sashrelief='groove', sashwidth=6)
pane.pack(side = 'top', fill = 'both', expand = 'true')
self.toppane = ttk.Frame(pane)
self.botpane = ttk.Frame(pane)
# Get username
if 'username' in self.prefs:
username = self.prefs['username']
else:
username = os.environ['USER']
# Label with the user
self.toppane.title_frame = ttk.Frame(self.toppane)
self.toppane.title_frame.pack(side = 'top', fill = 'x')
self.toppane.title_frame.title = ttk.Label(self.toppane.title_frame, text='User:', style = 'red.TLabel')
self.toppane.title_frame.user = ttk.Label(self.toppane.title_frame, text=username, style = 'blue.TLabel')
self.toppane.title_frame.title.grid(column=0, row=0, ipadx = 5)
self.toppane.title_frame.user.grid(column=1, row=0, ipadx = 5)
self.toppane.title2_frame = ttk.Frame(self.toppane)
self.toppane.title2_frame.pack(side = 'top', fill = 'x')
self.toppane.title2_frame.project_label = ttk.Label(self.toppane.title2_frame, text="Project:",
style = 'title.TLabel')
self.toppane.title2_frame.project_label.grid(column=0, row=0, ipadx = 5)
# New project select button
self.toppane.title2_frame.project_select = ttk.Button(self.toppane.title2_frame,
text=self.project, style='normal.TButton', command=self.choose_project)
self.toppane.title2_frame.project_select.grid(column=1, row=0, ipadx = 5)
tooltip.ToolTip(self.toppane.title2_frame.project_select,
text = "Select new project")
# Show path to project
self.toppane.title2_frame.path_label = ttk.Label(self.toppane.title2_frame, text=self.project,
style = 'normal.TLabel')
self.toppane.title2_frame.path_label.grid(column=2, row=0, ipadx = 5, padx = 10)
# Show top-level layout cellname with select button. Initial cell name is the top-level cell.
self.toppane.title2_frame.tech_label = ttk.Label(self.toppane.title2_frame, text="Technology setup:",
style = 'title.TLabel')
self.toppane.title2_frame.tech_label.grid(column=3, row=0, ipadx = 5)
self.toppane.title2_frame.tech_select = ttk.Button(self.toppane.title2_frame,
text=self.tech, style='normal.TButton', command=self.choose_tech)
self.toppane.title2_frame.tech_select.grid(column=4, row=0, ipadx = 3, padx = 3)
self.toppane.title2_frame.layout_label = ttk.Label(self.toppane.title2_frame, text="Layout:",
style = 'title.TLabel')
self.toppane.title2_frame.layout_label.grid(column=0, row=1, ipadx = 5)
self.toppane.title2_frame.layout_select = ttk.Button(self.toppane.title2_frame,
text=self.layout, style='normal.TButton', command=self.choose_layout)
self.toppane.title2_frame.layout_select.grid(column=1, row=1, ipadx = 3, padx = 3)
# Show top-level schematic cellname with select button. Initial cell name is the top-level cell.
self.toppane.title2_frame.schem_label = ttk.Label(self.toppane.title2_frame, text="Schematic:",
style = 'title.TLabel')
self.toppane.title2_frame.schem_label.grid(column=3, row=1, ipadx = 5)
self.toppane.title2_frame.schem_select = ttk.Button(self.toppane.title2_frame,
text=self.schematic, style='normal.TButton', command=self.choose_netlist)
self.toppane.title2_frame.schem_select.grid(column=4, row=1, ipadx = 3, padx = 3)
tooltip.ToolTip(self.toppane.title2_frame.project_select,
text = "Select new project")
tooltip.ToolTip(self.toppane.title2_frame.layout_select,
text = "Select a layout subcirucit to compare")
tooltip.ToolTip(self.toppane.title2_frame.schem_select,
text = "Select a schematic subcirucit to compare")
#---------------------------------------------
ttk.Separator(self.toppane, orient='horizontal').pack(side = 'top', fill = 'x')
#---------------------------------------------
# Create listbox of Circuit1 vs. Circuit2 results
height = 10
self.toppane.lvsreport = TreeViewSplit(self.toppane, fontsize = fontsize)
self.toppane.lvsreport.populate("Layout:", [], "Schematic:", [],
[["Run", True, self.run_lvs],
# ["Find", True, self.findrecord]
], height = height)
self.toppane.lvsreport.set_title("Line")
self.toppane.lvsreport.pack(side = 'top', fill = 'both', expand = 'true')
tooltip.ToolTip(self.toppane.lvsreport.get_button(0), text="Run LVS")
#---------------------------------------------
# ttk.Separator(self, orient='horizontal').grid(column=0, row=3, sticky='ew')
#---------------------------------------------
# Add a text window below the project name to capture output. Redirect
# print statements to it.
self.botpane.console = ttk.Frame(self.botpane)
self.botpane.console.pack(side = 'top', fill = 'both', expand = 'true')
self.text_box = ConsoleText(self.botpane.console, wrap='word', height = 4)
self.text_box.pack(side='left', fill='both', expand='true')
console_scrollbar = ttk.Scrollbar(self.botpane.console)
console_scrollbar.pack(side='right', fill='y')
# attach console to scrollbar
self.text_box.config(yscrollcommand = console_scrollbar.set)
console_scrollbar.config(command = self.text_box.yview)
# Add button bar at the bottom of the window
self.botpane.bbar = ttk.Frame(self.botpane)
self.botpane.bbar.pack(side = 'top', fill = 'x')
# Define the "quit" button and action
self.botpane.bbar.quit_button = ttk.Button(self.botpane.bbar, text='Quit', command=self.on_quit,
style = 'normal.TButton')
self.botpane.bbar.quit_button.grid(column=0, row=0, padx = 5)
# Define help button
if self.help:
self.botpane.bbar.help_button = ttk.Button(self.botpane.bbar, text='Help',
command=self.help.open, style = 'normal.TButton')
self.botpane.bbar.help_button.grid(column = 2, row = 0, padx = 5)
tooltip.ToolTip(self.botpane.bbar.help_button, text = "Show help window")
# Add the panes once the internal geometry is known.
pane.add(self.toppane)
pane.add(self.botpane)
pane.paneconfig(self.toppane, stretch='first')
# Redirect stdout and stderr to the console as the last thing to do. . .
# Otherwise errors in the GUI get sucked into the void.
self.stdout = sys.stdout
self.stderr = sys.stderr
sys.stdout = ConsoleText.StdoutRedirector(self.text_box)
sys.stderr = ConsoleText.StderrRedirector(self.text_box)
if message:
print(message)
def logprint(self, message, doflush=False):
if self.logfile:
self.logfile.buffer.write(message.encode('utf-8'))
self.logfile.buffer.write('\n'.encode('utf-8'))
if doflush:
self.logfile.flush()
def printout(self, output):
# Generate output
if not output:
return
outlines = output.splitlines()
for line in outlines:
try:
print(line)
except TypeError:
line = line.decode('utf-8')
pritn(line)
def printwarn(self, output):
# Check output for warning or error
if not output:
return 0
warnrex = re.compile('.*warning', re.IGNORECASE)
errrex = re.compile('.*error', re.IGNORECASE)
errors = 0
outlines = output.splitlines()
for line in outlines:
try:
wmatch = warnrex.match(line)
except TypeError:
line = line.decode('utf-8')
wmatch = warnrex.match(line)
ematch = errrex.match(line)
if ematch:
errors += 1
if ematch or wmatch:
print(line)
return errors
def choose_tech(self):
try:
project_path = self.rootpath
initdirname = self.rootpath + '/tech',
except:
print('Must choose a project first.')
return
techname = filedialog.askopenfilename(multiple=False,
initialdir = initdirname,
filetypes = (("Tcl script", "*.tcl"),("All Files","*.*")),
title = "Choose a netgen technology setup script.")
if techname != '':
print("Selected technology setup script " + techname)
techbase = os.path.split(techname)[1]
self.tech = os.path.splitext(techbase)[0]
self.lvs_setup = techname
self.toppane.title2_frame.layout_select.config(text = self.tech)
def choose_layout(self):
try:
project_path = self.rootpath
initdirname = self.rootpath + '/layout',
except:
print('Must choose a project first.')
return
cellname = filedialog.askopenfilename(multiple=False,
initialdir = initdirname,
filetypes = (("Magic layout", "*.mag"),("All Files","*.*")),
title = "Choose a layout cell to compare.")
if cellname != '':
print("Selected compare cell " + cellname)
cellbase = os.path.split(cellname)[1]
self.layout = os.path.splitext(cellbase)[0]
self.toppane.title2_frame.layout_select.config(text = self.layout)
def choose_netlist(self):
try:
project_path = self.rootpath
initdirname = self.rootpath + '/netlist/' + self.project + '.spi'
except:
print('Must choose a project first.')
return
cellname = filedialog.askopenfilename(multiple=False,
initialdir = initdirname,
filetypes = (("Spice netlist", "*.spi"),("Verilog netlist", "*.v")),
title = "Choose a netlist to compare.")
if cellname != '':
print("Selected compare cell " + cellname)
cellbase = os.path.split(cellname)[1]
self.schematic = os.path.splitext(cellbase)[0]
self.toppane.title2_frame.schem_select.config(text = self.schematic)
fileext = os.path.splitext(cellbase)[1]
if fileext == '.v':
self.toppane.title2_frame.schem_label.config(text = 'Verilog netlist:')
elif fileext == '.sp' or fileext == '.spi' or fileext == '.spice' or fileext == '.spc' or fileext == '.ckt':
self.toppane.title2_frame.schem_label.config(text = 'SPICE netlist:')
elif fileext == '.cdl':
self.toppane.title2_frame.schem_label.config(text = 'CDL netlist:')
else:
self.toppane.title2_frame.schem_label.config(text = 'Unknown netlist:')
def choose_project(self):
project = filedialog.askdirectory(initialdir = os.getcwd(),
title = "Find a project.")
if project != '':
print("Selected project " + str(project))
result = self.set_project(project)
def set_project(self, rootpath, project_name=None):
# Check if rootpath is valid. For LVS, there should be subdirectories
# "layout/" and "netlist/" or "verilog/".
haslay = os.path.isdir(rootpath + '/layout')
hasvlog = os.path.isdir(rootpath + '/verilog')
hasnet = os.path.isdir(rootpath + '/netlist')
if not haslay or not (hasvlog or hasnet):
if not haslay:
print("Project path has no layout (/layout) subdirectory.")
if not (hasvlog or hasnet):
print("Project path has no verilog (/verilog), or netlist (/netlist) subdirectory.")
# Continue anyway; assume that netlists will be selected manually
if self.logfile:
self.logfile.close()
self.logfile = None
if not project_name:
project = os.path.split(rootpath)[1]
else:
project = project_name
if self.project != project:
self.rootpath = rootpath
self.project = project
# Clear out old project data
self.toppane.lvsreport.repopulate([], [])
# Close any open logfile.
if self.logfile:
self.logfile.close()
self.logfile = None
# Put new log file called 'lvs.log' in the mag/ subdirectory
self.logfile = open(rootpath + '/layout/lvs.log', 'w')
# Print some initial information to the logfile.
self.logprint('Starting new log file ' + datetime.datetime.now().strftime('%c'),
doflush=True)
# Update project button
self.toppane.title2_frame.project_select.config(text = self.project)
self.toppane.title2_frame.path_label.config(text = self.rootpath)
# Cell name is the same as project name initially
self.layout = self.project
self.schematic = self.project
self.toppane.title2_frame.layout_select.config(text = self.layout)
self.toppane.title2_frame.schem_select.config(text = self.schematic)
# Update schematic button
if os.path.isfile(rootpath + '/verilog/' + self.schematic + '.v'):
self.toppane.title2_frame.schem_label.config(text = 'Verilog netlist:')
else:
self.toppane.title2_frame.schem_label.config(text = 'Schematic netlist:')
# If there is a comparison file that post-dates both netlists, load it.
self.check_lvs()
return True
def check_layout_out_of_date(self, spipath, layoutpath):
# Check if a netlist (spipath) is out-of-date relative to the layouts
# (layoutpath). Need to read the netlist and check all of the subcells.
need_capture = False
if not os.path.isfile(spipath):
return True
if os.path.isfile(layoutpath):
spi_statbuf = os.stat(spipath)
lay_statbuf = os.stat(layoutpath)
if spi_statbuf.st_mtime < lay_statbuf.st_mtime:
# netlist exists but is out-of-date
need_capture = True
else:
# only found that the top-level-layout is older than the
# netlist. Now need to read the netlist, find all subcircuits,
# and check those dates, too.
layoutdir = os.path.split(layoutpath)[0]
subrex = re.compile('^[^\*]*[ \t]*.subckt[ \t]+([^ \t]+).*$', re.IGNORECASE)
with open(spipath, 'r') as ifile:
duttext = ifile.read()
dutlines = duttext.replace('\n+', ' ').splitlines()
for line in dutlines:
lmatch = subrex.match(line)
if lmatch:
subname = lmatch.group(1)
sublayout = layoutdir + '/' + subname + '.mag'
# subcircuits that cannot be found in the current directory are
# assumed to be library components and therefore never out-of-date.
if os.path.exists(sublayout):
sub_statbuf = os.stat(sublayout)
if spi_statbuf.st_mtime < lay_statbuf.st_mtime:
# netlist exists but is out-of-date
need_capture = True
break
return need_capture
def check_schematic_out_of_date(self, spipath, schempath):
# Check if a netlist (spipath) is out-of-date relative to the schematics
# (schempath). Need to read the netlist and check all of the subcells.
need_capture = False
if not os.path.isfile(spipath):
return True
if os.path.isfile(schempath):
spi_statbuf = os.stat(spipath)
sch_statbuf = os.stat(schempath)
if spi_statbuf.st_mtime < sch_statbuf.st_mtime:
# netlist exists but is out-of-date
need_capture = True
else:
# only found that the top-level-schematic is older than the
# netlist. Now need to read the netlist, find all subcircuits,
# and check those dates, too.
schemdir = os.path.split(schempath)[0]
subrex = re.compile('^[^\*]*[ \t]*.subckt[ \t]+([^ \t]+).*$', re.IGNORECASE)
with open(spipath, 'r') as ifile:
duttext = ifile.read()
dutlines = duttext.replace('\n+', ' ').splitlines()
for line in dutlines:
lmatch = subrex.match(line)
if lmatch:
subname = lmatch.group(1)
# NOTE: Electric uses library:cell internally to track libraries,
# and maps the ":" to "__" in the netlist. Not entirely certain that
# the double-underscore uniquely identifies the library:cell. . .
librex = re.compile('(.*)__(.*)', re.IGNORECASE)
lmatch = librex.match(subname)
if lmatch:
elecpath = os.path.split(os.path.split(schempath)[0])[0]
libname = lmatch.group(1)
subschem = elecpath + '/' + libname + '.delib/' + lmatch.group(2) + '.sch'
else:
libname = {}
subschem = schemdir + '/' + subname + '.sch'
# subcircuits that cannot be found in the current directory are
# assumed to be library components and therefore never out-of-date.
if os.path.exists(subschem):
sub_statbuf = os.stat(subschem)
if spi_statbuf.st_mtime < sub_statbuf.st_mtime:
# netlist exists but is out-of-date
need_capture = True
break
# mapping of characters to what's allowed in SPICE makes finding
# the associated schematic file a bit difficult. Requires wild-card
# searching.
elif libname:
restr = lmatch.group(2) + '.sch'
restr = restr.replace('.', '\.')
restr = restr.replace('_', '.')
schrex = re.compile(restr, re.IGNORECASE)
libpath = elecpath + '/' + libname + '.delib'
if os.path.exists(libpath):
liblist = os.listdir(libpath)
for file in liblist:
lmatch = schrex.match(file)
if lmatch:
subschem = libpath + '/' + file
sub_statbuf = os.stat(subschem)
if spi_statbuf.st_mtime < sch_statbuf.st_mtime:
# netlist exists but is out-of-date
need_capture = True
break
return need_capture
def check_lvs(self):
# If both netlists exist, and comp.json is more recent than both, then
# load LVS results from comp.json
project_path = self.rootpath
project_name = self.project
layout_path = project_path + '/layout/' + project_name + '.spc'
net_path = project_path + '/netlist/' + project_name + '.spi'
comp_path = project_path + '/layout/comp.json'
if os.path.exists(layout_path) and os.path.exists(net_path) and os.path.exists(comp_path):
magtime = os.stat(layout_path).st_mtime
schemtime = os.stat(net_path).st_mtime
comptime = os.stat(comp_path).st_mtime
if comptime > magtime and comptime > schemtime:
print("Loading LVS results from file.")
self.generate(comp_path)
def generate_layout_netlist(self, layout_path, layout_src, project_path):
# Does layout netlist exist and is it current?
if self.check_layout_out_of_date(layout_path, layout_src):
print('Generating layout netlist.')
self.update_idletasks()
mproc = subprocess.Popen(['magic', '-dnull', '-noconsole',
self.layout], stdin = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = subprocess.PIPE, cwd = project_path + '/layout',
universal_newlines = True)
mproc.stdin.write("select top cell\n")
mproc.stdin.write("expand\n")
mproc.stdin.write("extract all\n")
mproc.stdin.write("ext2spice hierarchy on\n")
mproc.stdin.write("ext2spice format ngspice\n")
mproc.stdin.write("ext2spice scale off\n")
mproc.stdin.write("ext2spice renumber off\n")
mproc.stdin.write("ext2spice subcircuit top auto\n")
mproc.stdin.write("ext2spice cthresh infinite\n")
mproc.stdin.write("ext2spice rthresh infinite\n")
mproc.stdin.write("ext2spice blackbox on\n")
mproc.stdin.write("ext2spice -o " + self.layout + ".spi\n")
mproc.stdin.write("quit -noprompt\n")
magicout = mproc.communicate()[0]
self.printwarn(magicout)
if mproc.returncode != 0:
print('Failure to generate new layout netlist.')
return False
# Move .spi netlist to project_dir/netlist/lvs/
shutil.move(project_path + '/layout/' + self.layout + '.spi', layout_path)
# Remove extraction files
for file in os.listdir(project_path + '/layout'):
if os.path.splitext(file)[1] == '.ext':
os.remove(project_path + '/layout/' + file)
else:
print('Layout netlist is up-to-date, not regenerating.')
return True
def run_lvs(self, value):
# "value" is ignored (?)
# Check if netlists exist and are current; otherwise create them.
# Then run LVS.
project_path = self.rootpath
project_name = self.project
comp_path = project_path + '/layout/comp.json'
has_vlog = False
vlog_path = project_path + '/verilog/' + project_name + '.v'
layout_path = project_path + '/netlist/lvs/' + self.layout + '.spi'
net_path = project_path + '/netlist/schem/' + self.schematic + '.spi'
layout_src = project_path + '/layout/' + self.layout + '.mag'
# Does the setup file exist (this is optional)?
if self.lvs_setup != '' and not os.path.isfile('setup.tcl'):
print('No technology setup file selected.')
# Does schematic netlist exist?
if not os.path.isfile(vlog_path) and not os.path.isfile(net_path):
print('Error: No schematic netlist or verilog netlist.')
return
# Does LVS netlist subdirectory exist?
if not os.path.exists(project_path + '/netlist/lvs'):
os.makedirs(project_path + '/netlist/lvs')
# Does layout netlist exist and is it current?
if not self.generate_layout_netlist(layout_path, layout_src, project_path):
return False
# Final check
if not os.path.isfile(layout_path):
print('Error: No netlist generated from magic.')
return
else:
# Read in netlist and convert commas from [X,Y] arrays to vertical bars
# as something that can be converted back as necessary. ngspice treats
# commas as special characters for some reason.
with open(layout_path) as ifile:
spitext = ifile.read()
# spilines = spitext.replace(',', '|')
# with open(layout_path, 'w') as ofile:
# ofile.write(spilines)
# Check the netlist to see if the cell to match is a subcircuit. If
# not, then assume it is the top level.
is_subckt = False
subrex = re.compile('^[^\*]*[ \t]*.subckt[ \t]+([^ \t]+).*$', re.IGNORECASE)
dutlines = spitext.replace('\n+', ' ').splitlines()
for line in dutlines:
lmatch = subrex.match(line)
if lmatch:
subname = lmatch.group(1)
if subname == self.layout:
is_subckt = True
break
if is_subckt:
layout_arg = layout_path + ' ' + self.layout
layout_text = '"' + layout_arg + '"'
else:
layout_arg = layout_path
layout_text = layout_arg
if has_vlog:
schem_arg = vlog_path + ' ' + self.schematic
else:
schem_arg = net_path + ' ' + self.schematic
schem_text = '"' + schem_arg + '"'
# Remove any previous comparison output file
comp_out_path = os.path.splitext(comp_path)[0] + '.out'
if os.path.exists(comp_out_path):
os.remove(comp_out_path)
# Run netgen as subprocess
print('Running: netgen -batch lvs ' + layout_text +
' ' + schem_text + ' ' + self.lvs_setup + ' ' + comp_out_path +
' -json -blackbox')
# Note: Because arguments to subprocess are list items, the {filename cell}
# pair does *not* have to be quoted or braced. Doing so causes a parse
# error.
self.lvsproc = subprocess.Popen(['netgen', '-batch', 'lvs',
layout_arg, schem_arg,
self.lvs_setup, comp_out_path, '-json', '-blackbox'],
cwd=project_path + '/layout',
stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0)
# This is largely unnecessary as netgen usually runs to completion very quickly.
self.watchclock(comp_path)
def watchclock(self, filename):
if self.lvsproc == None:
return
lvs_status = self.lvsproc.poll()
sresult = select.select([self.lvsproc.stdout, self.lvsproc.stderr], [], [], 0)[0]
if self.lvsproc.stdout in sresult:
outstring = self.lvsproc.stdout.readline().decode().strip()
self.logprint(outstring, doflush=True)
print(outstring)
elif self.lvsproc.stderr in sresult:
errstring = self.lvsproc.stderr.readline().decode().strip()
self.logprint(errstring, doflush = True)
print(errstring, file=sys.stderr)
if lvs_status != None:
print("netgen LVS exited with status " + str(lvs_status))
self.lvsproc = None
if lvs_status != 0:
print('Errors encountered in LVS.')
self.logprint('Errors in LVS, lvs status = ' + str(lvs_status), doflush=True)
# Done; now read comp.json and fill the treeview listbox.
self.generate(filename)
else:
self.after(500, lambda: self.watchclock(filename))
# Generate display from "comp.out" file (json file now preferred)
def generate_orig(self, lvspath):
lefttext = []
righttext = []
print("Reading LVS output file " + lvspath)
if os.path.exists(lvspath):
with open(lvspath, 'r') as ifile:
lvslines = ifile.read().splitlines()
for line in lvslines:
if '|' in line:
# parts = line.split('|')
# lefttext.append(parts[0])
# righttext.append(parts[1])
lefttext.append(line[0:42].strip())
righttext.append(line[44:].strip())
else:
lefttext.append(line)
righttext.append('')
# Populate treeview with text
self.toppane.lvsreport.repopulate(lefttext, righttext)
else:
print("Error: No output file generated from LVS.")
# Generate output from LVS report JSON file comp.json
def generate(self, lvspath):
lefttext = []
righttext = []
print("Reading LVS output file " + lvspath)
if os.path.exists(lvspath):
with open(lvspath, 'r') as ifile:
self.lvsdata = json.load(ifile)
# Populate treeview with text
self.toppane.lvsreport.json_repopulate(self.lvsdata)
else:
print("Error: No output file generated from LVS.")
def findrecord(self, value):
print("Unimplemented function")
def findrecord_test(self, value):
# Check if socket is defined; if not, attempt to open one
if not self.msock:
try:
self.msock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except:
print("No response from layout tool.")
if self.msock:
self.msock.connect(("0.0.0.0", 12946))
self.msock.setblocking(False)
if self.msock:
# Pull name of net or device from 'value'
# This is a test:
self.msock.sendall(b'box 0 0 100 100\r\n')
if __name__ == '__main__':
options = []
arguments = []
for item in sys.argv[1:]:
if item.find('-', 0) == 0:
options.append(item)
else:
arguments.append(item)
root = tkinter.Tk()
app = LVSManager(root)
if arguments:
if len(arguments) >= 2:
app.set_project(arguments[0], project_name=arguments[1])
else:
app.set_project(arguments[0])
root.mainloop()
+819
View File
@@ -0,0 +1,819 @@
#!/bin/env python3
#
#--------------------------------------------------------
# LVS Manager GUI.
#
# This is a Python tkinter script that handles the
# process of running LVS and interpreting results.
#
#--------------------------------------------------------
# Written by Tim Edwards
# efabless, inc.
# Version 1. November 30, 2016
# Version 2. March 6, 2017. Reads JSON format output
# Version 3. April 25, 2018. Handles layout vs. verilog
#--------------------------------------------------------
import io
import os
import re
import sys
import json
import shutil
import signal
import socket
import select
import datetime
import contextlib
import subprocess
import tkinter
from tkinter import ttk
from tkinter import filedialog
import tksimpledialog
import tooltip
from consoletext import ConsoleText
from helpwindow import HelpWindow
from treeviewsplit import TreeViewSplit
# User preferences file (if it exists)
prefsfile = '~/.profile/prefs.json'
netgen_script_dir = 'SUBST_SCRIPT_DIR'
#------------------------------------------------------
# Simple dialog for confirming quit
#------------------------------------------------------
class ConfirmDialog(tksimpledialog.Dialog):
def body(self, master, warning, seed):
if warning:
ttk.Label(master, text=warning, wraplength=500).grid(row = 0, columnspan = 2, sticky = 'wns')
return self
def apply(self):
return 'okay'
#------------------------------------------------------
# Main class for this application
#------------------------------------------------------
class LVSManager(ttk.Frame):
"""LVS Manager GUI."""
def __init__(self, parent, *args, **kwargs):
ttk.Frame.__init__(self, parent, *args, **kwargs)
self.root = parent
self.init_gui()
parent.protocol("WM_DELETE_WINDOW", self.on_quit)
def on_quit(self):
"""Exits program."""
if self.msock:
self.msock.close()
quit()
def init_gui(self):
"""Builds GUI."""
global prefsfile
message = []
fontsize = 11
# Read user preferences file, get default font size from it.
prefspath = os.path.expanduser(prefsfile)
if os.path.exists(prefspath):
with open(prefspath, 'r') as f:
self.prefs = json.load(f)
if 'fontsize' in self.prefs:
fontsize = self.prefs['fontsize']
else:
self.prefs = {}
s = ttk.Style()
available_themes = s.theme_names()
s.theme_use(available_themes[0])
s.configure('bg.TFrame', background='gray40')
s.configure('italic.TLabel', font=('Helvetica', fontsize, 'italic'))
s.configure('title.TLabel', font=('Helvetica', fontsize, 'bold italic'),
foreground = 'brown', anchor = 'center')
s.configure('normal.TLabel', font=('Helvetica', fontsize))
s.configure('red.TLabel', font=('Helvetica', fontsize), foreground = 'red')
s.configure('green.TLabel', font=('Helvetica', fontsize), foreground = 'green3')
s.configure('blue.TLabel', font=('Helvetica', fontsize), foreground = 'blue')
s.configure('normal.TButton', font=('Helvetica', fontsize),
border = 3, relief = 'raised')
s.configure('red.TButton', font=('Helvetica', fontsize), foreground = 'red',
border = 3, relief = 'raised')
s.configure('green.TButton', font=('Helvetica', fontsize), foreground = 'green3',
border = 3, relief = 'raised')
s.configure('blue.TButton', font=('Helvetica', fontsize), foreground = 'blue',
border = 3, relief = 'raised')
s.configure('redtitle.TButton', font=('Helvetica', fontsize, 'bold italic'),
foreground = 'red', border = 3, relief = 'raised')
s.configure('bluetitle.TButton', font=('Helvetica', fontsize, 'bold italic'),
foreground = 'blue', border = 3, relief = 'raised')
# These values to be overridden from arguments
self.rootpath = None
self.project = None
self.logfile = None
self.msock = None
self.help = None
# Create the help window
if os.path.exists(netgen_script_dir + '/netgen_help.txt'):
self.help = HelpWindow(self, fontsize = fontsize)
with io.StringIO() as buf, contextlib.redirect_stdout(buf):
self.help.add_pages_from_file('lvs_help.txt')
message = buf.getvalue()
# Set the help display to the first page
self.help.page(0)
# Variables used by option menus and other stuff
self.project = "(no selection)"
self.layout = "(default)"
self.schematic = "(default)"
self.tech = "(none)"
self.lvs_setup = ''
self.lvsdata = {}
# Root window title
self.root.title('LVS Manager')
self.root.option_add('*tearOff', 'FALSE')
self.pack(side = 'top', fill = 'both', expand = 'true')
pane = tkinter.PanedWindow(self, orient = 'vertical', sashrelief='groove', sashwidth=6)
pane.pack(side = 'top', fill = 'both', expand = 'true')
self.toppane = ttk.Frame(pane)
self.botpane = ttk.Frame(pane)
# Get username
if 'username' in self.prefs:
username = self.prefs['username']
else:
username = os.environ['USER']
# Label with the user
self.toppane.title_frame = ttk.Frame(self.toppane)
self.toppane.title_frame.pack(side = 'top', fill = 'x')
self.toppane.title_frame.title = ttk.Label(self.toppane.title_frame, text='User:', style = 'red.TLabel')
self.toppane.title_frame.user = ttk.Label(self.toppane.title_frame, text=username, style = 'blue.TLabel')
self.toppane.title_frame.title.grid(column=0, row=0, ipadx = 5)
self.toppane.title_frame.user.grid(column=1, row=0, ipadx = 5)
self.toppane.title2_frame = ttk.Frame(self.toppane)
self.toppane.title2_frame.pack(side = 'top', fill = 'x')
self.toppane.title2_frame.project_label = ttk.Label(self.toppane.title2_frame, text="Project:",
style = 'title.TLabel')
self.toppane.title2_frame.project_label.grid(column=0, row=0, ipadx = 5)
# New project select button
self.toppane.title2_frame.project_select = ttk.Button(self.toppane.title2_frame,
text=self.project, style='normal.TButton', command=self.choose_project)
self.toppane.title2_frame.project_select.grid(column=1, row=0, ipadx = 5)
tooltip.ToolTip(self.toppane.title2_frame.project_select,
text = "Select new project")
# Show path to project
self.toppane.title2_frame.path_label = ttk.Label(self.toppane.title2_frame, text=self.project,
style = 'normal.TLabel')
self.toppane.title2_frame.path_label.grid(column=2, row=0, ipadx = 5, padx = 10)
# Show top-level layout cellname with select button. Initial cell name is the top-level cell.
self.toppane.title2_frame.tech_label = ttk.Label(self.toppane.title2_frame, text="Technology setup:",
style = 'title.TLabel')
self.toppane.title2_frame.tech_label.grid(column=3, row=0, ipadx = 5)
self.toppane.title2_frame.tech_select = ttk.Button(self.toppane.title2_frame,
text=self.tech, style='normal.TButton', command=self.choose_tech)
self.toppane.title2_frame.tech_select.grid(column=4, row=0, ipadx = 3, padx = 3)
self.toppane.title2_frame.layout_label = ttk.Label(self.toppane.title2_frame, text="Layout:",
style = 'title.TLabel')
self.toppane.title2_frame.layout_label.grid(column=0, row=1, ipadx = 5)
self.toppane.title2_frame.layout_select = ttk.Button(self.toppane.title2_frame,
text=self.layout, style='normal.TButton', command=self.choose_layout)
self.toppane.title2_frame.layout_select.grid(column=1, row=1, ipadx = 3, padx = 3)
# Show top-level schematic cellname with select button. Initial cell name is the top-level cell.
self.toppane.title2_frame.schem_label = ttk.Label(self.toppane.title2_frame, text="Schematic:",
style = 'title.TLabel')
self.toppane.title2_frame.schem_label.grid(column=3, row=1, ipadx = 5)
self.toppane.title2_frame.schem_select = ttk.Button(self.toppane.title2_frame,
text=self.schematic, style='normal.TButton', command=self.choose_netlist)
self.toppane.title2_frame.schem_select.grid(column=4, row=1, ipadx = 3, padx = 3)
tooltip.ToolTip(self.toppane.title2_frame.project_select,
text = "Select new project")
tooltip.ToolTip(self.toppane.title2_frame.layout_select,
text = "Select a layout subcirucit to compare")
tooltip.ToolTip(self.toppane.title2_frame.schem_select,
text = "Select a schematic subcirucit to compare")
#---------------------------------------------
ttk.Separator(self.toppane, orient='horizontal').pack(side = 'top', fill = 'x')
#---------------------------------------------
# Create listbox of Circuit1 vs. Circuit2 results
height = 10
self.toppane.lvsreport = TreeViewSplit(self.toppane, fontsize = fontsize)
self.toppane.lvsreport.populate("Layout:", [], "Schematic:", [],
[["Run", True, self.run_lvs],
# ["Find", True, self.findrecord]
], height = height)
self.toppane.lvsreport.set_title("Line")
self.toppane.lvsreport.pack(side = 'top', fill = 'both', expand = 'true')
tooltip.ToolTip(self.toppane.lvsreport.get_button(0), text="Run LVS")
#---------------------------------------------
# ttk.Separator(self, orient='horizontal').grid(column=0, row=3, sticky='ew')
#---------------------------------------------
# Add a text window below the project name to capture output. Redirect
# print statements to it.
self.botpane.console = ttk.Frame(self.botpane)
self.botpane.console.pack(side = 'top', fill = 'both', expand = 'true')
self.text_box = ConsoleText(self.botpane.console, wrap='word', height = 4)
self.text_box.pack(side='left', fill='both', expand='true')
console_scrollbar = ttk.Scrollbar(self.botpane.console)
console_scrollbar.pack(side='right', fill='y')
# attach console to scrollbar
self.text_box.config(yscrollcommand = console_scrollbar.set)
console_scrollbar.config(command = self.text_box.yview)
# Add button bar at the bottom of the window
self.botpane.bbar = ttk.Frame(self.botpane)
self.botpane.bbar.pack(side = 'top', fill = 'x')
# Define the "quit" button and action
self.botpane.bbar.quit_button = ttk.Button(self.botpane.bbar, text='Quit', command=self.on_quit,
style = 'normal.TButton')
self.botpane.bbar.quit_button.grid(column=0, row=0, padx = 5)
# Define help button
if self.help:
self.botpane.bbar.help_button = ttk.Button(self.botpane.bbar, text='Help',
command=self.help.open, style = 'normal.TButton')
self.botpane.bbar.help_button.grid(column = 2, row = 0, padx = 5)
tooltip.ToolTip(self.botpane.bbar.help_button, text = "Show help window")
# Add the panes once the internal geometry is known.
pane.add(self.toppane)
pane.add(self.botpane)
pane.paneconfig(self.toppane, stretch='first')
# Redirect stdout and stderr to the console as the last thing to do. . .
# Otherwise errors in the GUI get sucked into the void.
self.stdout = sys.stdout
self.stderr = sys.stderr
sys.stdout = ConsoleText.StdoutRedirector(self.text_box)
sys.stderr = ConsoleText.StderrRedirector(self.text_box)
if message:
print(message)
def logprint(self, message, doflush=False):
if self.logfile:
self.logfile.buffer.write(message.encode('utf-8'))
self.logfile.buffer.write('\n'.encode('utf-8'))
if doflush:
self.logfile.flush()
def printout(self, output):
# Generate output
if not output:
return
outlines = output.splitlines()
for line in outlines:
try:
print(line)
except TypeError:
line = line.decode('utf-8')
pritn(line)
def printwarn(self, output):
# Check output for warning or error
if not output:
return 0
warnrex = re.compile('.*warning', re.IGNORECASE)
errrex = re.compile('.*error', re.IGNORECASE)
errors = 0
outlines = output.splitlines()
for line in outlines:
try:
wmatch = warnrex.match(line)
except TypeError:
line = line.decode('utf-8')
wmatch = warnrex.match(line)
ematch = errrex.match(line)
if ematch:
errors += 1
if ematch or wmatch:
print(line)
return errors
def choose_tech(self):
try:
project_path = self.rootpath
initdirname = self.rootpath + '/tech',
except:
print('Must choose a project first.')
return
techname = filedialog.askopenfilename(multiple=False,
initialdir = initdirname,
filetypes = (("Tcl script", "*.tcl"),("All Files","*.*")),
title = "Choose a netgen technology setup script.")
if techname != '':
print("Selected technology setup script " + techname)
techbase = os.path.split(techname)[1]
self.tech = os.path.splitext(techbase)[0]
self.lvs_setup = techname
self.toppane.title2_frame.layout_select.config(text = self.tech)
def choose_layout(self):
try:
project_path = self.rootpath
initdirname = self.rootpath + '/layout',
except:
print('Must choose a project first.')
return
cellname = filedialog.askopenfilename(multiple=False,
initialdir = initdirname,
filetypes = (("Magic layout", "*.mag"),("All Files","*.*")),
title = "Choose a layout cell to compare.")
if cellname != '':
print("Selected compare cell " + cellname)
cellbase = os.path.split(cellname)[1]
self.layout = os.path.splitext(cellbase)[0]
self.toppane.title2_frame.layout_select.config(text = self.layout)
def choose_netlist(self):
try:
project_path = self.rootpath
initdirname = self.rootpath + '/netlist/' + self.project + '.spi'
except:
print('Must choose a project first.')
return
cellname = filedialog.askopenfilename(multiple=False,
initialdir = initdirname,
filetypes = (("Spice netlist", "*.spi"),("Verilog netlist", "*.v")),
title = "Choose a netlist to compare.")
if cellname != '':
print("Selected compare cell " + cellname)
cellbase = os.path.split(cellname)[1]
self.schematic = os.path.splitext(cellbase)[0]
self.toppane.title2_frame.schem_select.config(text = self.schematic)
fileext = os.path.splitext(cellbase)[1]
if fileext == '.v':
self.toppane.title2_frame.schem_label.config(text = 'Verilog netlist:')
elif fileext == '.sp' or fileext == '.spi' or fileext == '.spice' or fileext == '.spc' or fileext == '.ckt':
self.toppane.title2_frame.schem_label.config(text = 'SPICE netlist:')
elif fileext == '.cdl':
self.toppane.title2_frame.schem_label.config(text = 'CDL netlist:')
else:
self.toppane.title2_frame.schem_label.config(text = 'Unknown netlist:')
def choose_project(self):
project = filedialog.askdirectory(initialdir = os.getcwd(),
title = "Find a project.")
if project != '':
print("Selected project " + str(project))
result = self.set_project(project)
def set_project(self, rootpath, project_name=None):
# Check if rootpath is valid. For LVS, there should be subdirectories
# "layout/" and "netlist/" or "verilog/".
haslay = os.path.isdir(rootpath + '/layout')
hasvlog = os.path.isdir(rootpath + '/verilog')
hasnet = os.path.isdir(rootpath + '/netlist')
if not haslay or not (hasvlog or hasnet):
if not haslay:
print("Project path has no layout (/layout) subdirectory.")
if not (hasvlog or hasnet):
print("Project path has no verilog (/verilog), or netlist (/netlist) subdirectory.")
# Continue anyway; assume that netlists will be selected manually
if self.logfile:
self.logfile.close()
self.logfile = None
if not project_name:
project = os.path.split(rootpath)[1]
else:
project = project_name
if self.project != project:
self.rootpath = rootpath
self.project = project
# Clear out old project data
self.toppane.lvsreport.repopulate([], [])
# Close any open logfile.
if self.logfile:
self.logfile.close()
self.logfile = None
# Put new log file called 'lvs.log' in the mag/ subdirectory
self.logfile = open(rootpath + '/layout/lvs.log', 'w')
# Print some initial information to the logfile.
self.logprint('Starting new log file ' + datetime.datetime.now().strftime('%c'),
doflush=True)
# Update project button
self.toppane.title2_frame.project_select.config(text = self.project)
self.toppane.title2_frame.path_label.config(text = self.rootpath)
# Cell name is the same as project name initially
self.layout = self.project
self.schematic = self.project
self.toppane.title2_frame.layout_select.config(text = self.layout)
self.toppane.title2_frame.schem_select.config(text = self.schematic)
# Update schematic button
if os.path.isfile(rootpath + '/verilog/' + self.schematic + '.v'):
self.toppane.title2_frame.schem_label.config(text = 'Verilog netlist:')
else:
self.toppane.title2_frame.schem_label.config(text = 'Schematic netlist:')
# If there is a comparison file that post-dates both netlists, load it.
self.check_lvs()
return True
def check_layout_out_of_date(self, spipath, layoutpath):
# Check if a netlist (spipath) is out-of-date relative to the layouts
# (layoutpath). Need to read the netlist and check all of the subcells.
need_capture = False
if not os.path.isfile(spipath):
return True
if os.path.isfile(layoutpath):
spi_statbuf = os.stat(spipath)
lay_statbuf = os.stat(layoutpath)
if spi_statbuf.st_mtime < lay_statbuf.st_mtime:
# netlist exists but is out-of-date
need_capture = True
else:
# only found that the top-level-layout is older than the
# netlist. Now need to read the netlist, find all subcircuits,
# and check those dates, too.
layoutdir = os.path.split(layoutpath)[0]
subrex = re.compile('^[^\*]*[ \t]*.subckt[ \t]+([^ \t]+).*$', re.IGNORECASE)
with open(spipath, 'r') as ifile:
duttext = ifile.read()
dutlines = duttext.replace('\n+', ' ').splitlines()
for line in dutlines:
lmatch = subrex.match(line)
if lmatch:
subname = lmatch.group(1)
sublayout = layoutdir + '/' + subname + '.mag'
# subcircuits that cannot be found in the current directory are
# assumed to be library components and therefore never out-of-date.
if os.path.exists(sublayout):
sub_statbuf = os.stat(sublayout)
if spi_statbuf.st_mtime < lay_statbuf.st_mtime:
# netlist exists but is out-of-date
need_capture = True
break
return need_capture
def check_schematic_out_of_date(self, spipath, schempath):
# Check if a netlist (spipath) is out-of-date relative to the schematics
# (schempath). Need to read the netlist and check all of the subcells.
need_capture = False
if not os.path.isfile(spipath):
return True
if os.path.isfile(schempath):
spi_statbuf = os.stat(spipath)
sch_statbuf = os.stat(schempath)
if spi_statbuf.st_mtime < sch_statbuf.st_mtime:
# netlist exists but is out-of-date
need_capture = True
else:
# only found that the top-level-schematic is older than the
# netlist. Now need to read the netlist, find all subcircuits,
# and check those dates, too.
schemdir = os.path.split(schempath)[0]
subrex = re.compile('^[^\*]*[ \t]*.subckt[ \t]+([^ \t]+).*$', re.IGNORECASE)
with open(spipath, 'r') as ifile:
duttext = ifile.read()
dutlines = duttext.replace('\n+', ' ').splitlines()
for line in dutlines:
lmatch = subrex.match(line)
if lmatch:
subname = lmatch.group(1)
# NOTE: Electric uses library:cell internally to track libraries,
# and maps the ":" to "__" in the netlist. Not entirely certain that
# the double-underscore uniquely identifies the library:cell. . .
librex = re.compile('(.*)__(.*)', re.IGNORECASE)
lmatch = librex.match(subname)
if lmatch:
elecpath = os.path.split(os.path.split(schempath)[0])[0]
libname = lmatch.group(1)
subschem = elecpath + '/' + libname + '.delib/' + lmatch.group(2) + '.sch'
else:
libname = {}
subschem = schemdir + '/' + subname + '.sch'
# subcircuits that cannot be found in the current directory are
# assumed to be library components and therefore never out-of-date.
if os.path.exists(subschem):
sub_statbuf = os.stat(subschem)
if spi_statbuf.st_mtime < sub_statbuf.st_mtime:
# netlist exists but is out-of-date
need_capture = True
break
# mapping of characters to what's allowed in SPICE makes finding
# the associated schematic file a bit difficult. Requires wild-card
# searching.
elif libname:
restr = lmatch.group(2) + '.sch'
restr = restr.replace('.', '\.')
restr = restr.replace('_', '.')
schrex = re.compile(restr, re.IGNORECASE)
libpath = elecpath + '/' + libname + '.delib'
if os.path.exists(libpath):
liblist = os.listdir(libpath)
for file in liblist:
lmatch = schrex.match(file)
if lmatch:
subschem = libpath + '/' + file
sub_statbuf = os.stat(subschem)
if spi_statbuf.st_mtime < sch_statbuf.st_mtime:
# netlist exists but is out-of-date
need_capture = True
break
return need_capture
def check_lvs(self):
# If both netlists exist, and comp.json is more recent than both, then
# load LVS results from comp.json
project_path = self.rootpath
project_name = self.project
layout_path = project_path + '/layout/' + project_name + '.spc'
net_path = project_path + '/netlist/' + project_name + '.spi'
comp_path = project_path + '/layout/comp.json'
if os.path.exists(layout_path) and os.path.exists(net_path) and os.path.exists(comp_path):
magtime = os.stat(layout_path).st_mtime
schemtime = os.stat(net_path).st_mtime
comptime = os.stat(comp_path).st_mtime
if comptime > magtime and comptime > schemtime:
print("Loading LVS results from file.")
self.generate(comp_path)
def generate_layout_netlist(self, layout_path, layout_src, project_path):
# Does layout netlist exist and is it current?
if self.check_layout_out_of_date(layout_path, layout_src):
print('Generating layout netlist.')
self.update_idletasks()
mproc = subprocess.Popen(['magic', '-dnull', '-noconsole',
self.layout], stdin = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = subprocess.PIPE, cwd = project_path + '/layout',
universal_newlines = True)
mproc.stdin.write("select top cell\n")
mproc.stdin.write("expand\n")
mproc.stdin.write("extract all\n")
mproc.stdin.write("ext2spice hierarchy on\n")
mproc.stdin.write("ext2spice format ngspice\n")
mproc.stdin.write("ext2spice scale off\n")
mproc.stdin.write("ext2spice renumber off\n")
mproc.stdin.write("ext2spice subcircuit top auto\n")
mproc.stdin.write("ext2spice cthresh infinite\n")
mproc.stdin.write("ext2spice rthresh infinite\n")
mproc.stdin.write("ext2spice blackbox on\n")
mproc.stdin.write("ext2spice -o " + self.layout + ".spi\n")
mproc.stdin.write("quit -noprompt\n")
magicout = mproc.communicate()[0]
self.printwarn(magicout)
if mproc.returncode != 0:
print('Failure to generate new layout netlist.')
return False
# Move .spi netlist to project_dir/netlist/lvs/
shutil.move(project_path + '/layout/' + self.layout + '.spi', layout_path)
# Remove extraction files
for file in os.listdir(project_path + '/layout'):
if os.path.splitext(file)[1] == '.ext':
os.remove(project_path + '/layout/' + file)
else:
print('Layout netlist is up-to-date, not regenerating.')
return True
def run_lvs(self, value):
# "value" is ignored (?)
# Check if netlists exist and are current; otherwise create them.
# Then run LVS.
project_path = self.rootpath
project_name = self.project
comp_path = project_path + '/layout/comp.json'
has_vlog = False
vlog_path = project_path + '/verilog/' + project_name + '.v'
layout_path = project_path + '/netlist/lvs/' + self.layout + '.spi'
net_path = project_path + '/netlist/schem/' + self.schematic + '.spi'
layout_src = project_path + '/layout/' + self.layout + '.mag'
# Does the setup file exist (this is optional)?
if self.lvs_setup != '' and not os.path.isfile('setup.tcl'):
print('No technology setup file selected.')
# Does schematic netlist exist?
if not os.path.isfile(vlog_path) and not os.path.isfile(net_path):
print('Error: No schematic netlist or verilog netlist.')
return
# Does LVS netlist subdirectory exist?
if not os.path.exists(project_path + '/netlist/lvs'):
os.makedirs(project_path + '/netlist/lvs')
# Does layout netlist exist and is it current?
if not self.generate_layout_netlist(layout_path, layout_src, project_path):
return False
# Final check
if not os.path.isfile(layout_path):
print('Error: No netlist generated from magic.')
return
else:
# Read in netlist and convert commas from [X,Y] arrays to vertical bars
# as something that can be converted back as necessary. ngspice treats
# commas as special characters for some reason.
with open(layout_path) as ifile:
spitext = ifile.read()
# spilines = spitext.replace(',', '|')
# with open(layout_path, 'w') as ofile:
# ofile.write(spilines)
# Check the netlist to see if the cell to match is a subcircuit. If
# not, then assume it is the top level.
is_subckt = False
subrex = re.compile('^[^\*]*[ \t]*.subckt[ \t]+([^ \t]+).*$', re.IGNORECASE)
dutlines = spitext.replace('\n+', ' ').splitlines()
for line in dutlines:
lmatch = subrex.match(line)
if lmatch:
subname = lmatch.group(1)
if subname == self.layout:
is_subckt = True
break
if is_subckt:
layout_arg = layout_path + ' ' + self.layout
layout_text = '"' + layout_arg + '"'
else:
layout_arg = layout_path
layout_text = layout_arg
if has_vlog:
schem_arg = vlog_path + ' ' + self.schematic
else:
schem_arg = net_path + ' ' + self.schematic
schem_text = '"' + schem_arg + '"'
# Remove any previous comparison output file
comp_out_path = os.path.splitext(comp_path)[0] + '.out'
if os.path.exists(comp_out_path):
os.remove(comp_out_path)
# Run netgen as subprocess
print('Running: netgen -batch lvs ' + layout_text +
' ' + schem_text + ' ' + self.lvs_setup + ' ' + comp_out_path +
' -json -blackbox')
# Note: Because arguments to subprocess are list items, the {filename cell}
# pair does *not* have to be quoted or braced. Doing so causes a parse
# error.
self.lvsproc = subprocess.Popen(['netgen', '-batch', 'lvs',
layout_arg, schem_arg,
self.lvs_setup, comp_out_path, '-json', '-blackbox'],
cwd=project_path + '/layout',
stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0)
# This is largely unnecessary as netgen usually runs to completion very quickly.
self.watchclock(comp_path)
def watchclock(self, filename):
if self.lvsproc == None:
return
lvs_status = self.lvsproc.poll()
sresult = select.select([self.lvsproc.stdout, self.lvsproc.stderr], [], [], 0)[0]
if self.lvsproc.stdout in sresult:
outstring = self.lvsproc.stdout.readline().decode().strip()
self.logprint(outstring, doflush=True)
print(outstring)
elif self.lvsproc.stderr in sresult:
errstring = self.lvsproc.stderr.readline().decode().strip()
self.logprint(errstring, doflush = True)
print(errstring, file=sys.stderr)
if lvs_status != None:
print("netgen LVS exited with status " + str(lvs_status))
self.lvsproc = None
if lvs_status != 0:
print('Errors encountered in LVS.')
self.logprint('Errors in LVS, lvs status = ' + str(lvs_status), doflush=True)
# Done; now read comp.json and fill the treeview listbox.
self.generate(filename)
else:
self.after(500, lambda: self.watchclock(filename))
# Generate display from "comp.out" file (json file now preferred)
def generate_orig(self, lvspath):
lefttext = []
righttext = []
print("Reading LVS output file " + lvspath)
if os.path.exists(lvspath):
with open(lvspath, 'r') as ifile:
lvslines = ifile.read().splitlines()
for line in lvslines:
if '|' in line:
# parts = line.split('|')
# lefttext.append(parts[0])
# righttext.append(parts[1])
lefttext.append(line[0:42].strip())
righttext.append(line[44:].strip())
else:
lefttext.append(line)
righttext.append('')
# Populate treeview with text
self.toppane.lvsreport.repopulate(lefttext, righttext)
else:
print("Error: No output file generated from LVS.")
# Generate output from LVS report JSON file comp.json
def generate(self, lvspath):
lefttext = []
righttext = []
print("Reading LVS output file " + lvspath)
if os.path.exists(lvspath):
with open(lvspath, 'r') as ifile:
self.lvsdata = json.load(ifile)
# Populate treeview with text
self.toppane.lvsreport.json_repopulate(self.lvsdata)
else:
print("Error: No output file generated from LVS.")
def findrecord(self, value):
print("Unimplemented function")
def findrecord_test(self, value):
# Check if socket is defined; if not, attempt to open one
if not self.msock:
try:
self.msock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except:
print("No response from layout tool.")
if self.msock:
self.msock.connect(("0.0.0.0", 12946))
self.msock.setblocking(False)
if self.msock:
# Pull name of net or device from 'value'
# This is a test:
self.msock.sendall(b'box 0 0 100 100\r\n')
if __name__ == '__main__':
options = []
arguments = []
for item in sys.argv[1:]:
if item.find('-', 0) == 0:
options.append(item)
else:
arguments.append(item)
root = tkinter.Tk()
app = LVSManager(root)
if arguments:
if len(arguments) >= 2:
app.set_project(arguments[0], project_name=arguments[1])
else:
app.set_project(arguments[0])
root.mainloop()
+86
View File
@@ -0,0 +1,86 @@
#!/bin/env python3
#
# Dialog class for tkinter
import os
import tkinter
from tkinter import ttk
class Dialog(tkinter.Toplevel):
def __init__(self, parent, message = None, title = None, seed = None, border = 'blue', **kwargs):
tkinter.Toplevel.__init__(self, parent)
self.transient(parent)
if title:
self.title(title)
self.configure(background=border, padx=2, pady=2)
self.obox = ttk.Frame(self)
self.obox.pack(side = 'left', fill = 'both', expand = 'true')
self.parent = parent
self.result = None
body = ttk.Frame(self.obox)
self.initial_focus = self.body(body, message, seed, **kwargs)
body.pack(padx = 5, pady = 5)
self.buttonbox()
self.grab_set()
if not self.initial_focus:
self.initial_focus = self
self.protocol("WM_DELETE_WINDOW", self.cancel)
self.geometry("+%d+%d" % (parent.winfo_rootx() + 50,
parent.winfo_rooty() + 50))
self.initial_focus.focus_set()
self.wait_window(self)
# Construction hooks
def body(self, master, **kwargs):
# Create dialog body. Return widget that should have
# initial focus. This method should be overridden
pass
def buttonbox(self):
# Add standard button box. Override if you don't want the
# standard buttons
box = ttk.Frame(self.obox)
self.okb = ttk.Button(box, text="OK", width=10, command=self.ok, default='active')
self.okb.pack(side='left', padx=5, pady=5)
w = ttk.Button(box, text="Cancel", width=10, command=self.cancel)
w.pack(side='left', padx=5, pady=5)
self.bind("<Return>", self.ok)
self.bind("<Escape>", self.cancel)
box.pack(fill='x', expand='true')
# Standard button semantics
def ok(self, event=None):
if not self.validate():
self.initial_focus.focus_set() # put focus back
return
self.withdraw()
self.update_idletasks()
self.result = self.apply()
self.cancel()
def cancel(self, event=None):
# Put focus back to the parent window
self.parent.focus_set()
self.destroy()
def validate(self):
return 1 # Override this
def apply(self):
return None # Override this
+158
View File
@@ -0,0 +1,158 @@
#!/bin/env python3
'''Michael Lange <klappnase (at) freakmail (dot) de>
The ToolTip class provides a flexible tooltip widget for tkinter; it is based on IDLE's ToolTip
module which unfortunately seems to be broken (at least the version I saw).
INITIALIZATION OPTIONS:
anchor : where the text should be positioned inside the widget, must be on of "n", "s", "e", "w", "nw" and so on;
default is "center"
bd : borderwidth of the widget; default is 1 (NOTE: don't use "borderwidth" here)
bg : background color to use for the widget; default is "lightyellow" (NOTE: don't use "background")
delay : time in ms that it takes for the widget to appear on the screen when the mouse pointer has
entered the parent widget; default is 1500
fg : foreground (i.e. text) color to use; default is "black" (NOTE: don't use "foreground")
follow_mouse : if set to 1 the tooltip will follow the mouse pointer instead of being displayed
outside of the parent widget; this may be useful if you want to use tooltips for
large widgets like listboxes or canvases; default is 0
font : font to use for the widget; default is system specific
justify : how multiple lines of text will be aligned, must be "left", "right" or "center"; default is "left"
padx : extra space added to the left and right within the widget; default is 4
pady : extra space above and below the text; default is 2
relief : one of "flat", "ridge", "groove", "raised", "sunken" or "solid"; default is "solid"
state : must be "normal" or "disabled"; if set to "disabled" the tooltip will not appear; default is "normal"
text : the text that is displayed inside the widget
textvariable : if set to an instance of tkinter.StringVar() the variable's value will be used as text for the widget
width : width of the widget; the default is 0, which means that "wraplength" will be used to limit the widgets width
wraplength : limits the number of characters in each line; default is 150
WIDGET METHODS:
configure(**opts) : change one or more of the widget's options as described above; the changes will take effect the
next time the tooltip shows up; NOTE: follow_mouse cannot be changed after widget initialization
Other widget methods that might be useful if you want to subclass ToolTip:
enter() : callback when the mouse pointer enters the parent widget
leave() : called when the mouse pointer leaves the parent widget
motion() : is called when the mouse pointer moves inside the parent widget if follow_mouse is set to 1 and the
tooltip has shown up to continually update the coordinates of the tooltip window
coords() : calculates the screen coordinates of the tooltip window
create_contents() : creates the contents of the tooltip window (by default a tkinter.Label)
'''
# Ideas gleaned from PySol
import tkinter
class ToolTip:
def __init__(self, master, text='Your text here', delay=1500, **opts):
self.master = master
self._opts = {'anchor':'center', 'bd':1, 'bg':'lightyellow', 'delay':delay, 'fg':'black',\
'follow_mouse':0, 'font':None, 'justify':'left', 'padx':4, 'pady':2,\
'relief':'solid', 'state':'normal', 'text':text, 'textvariable':None,\
'width':0, 'wraplength':150}
self.configure(**opts)
self._tipwindow = None
self._id = None
self._id1 = self.master.bind("<Enter>", self.enter, '+')
self._id2 = self.master.bind("<Leave>", self.leave, '+')
self._id3 = self.master.bind("<ButtonPress>", self.leave, '+')
self._follow_mouse = 0
if self._opts['follow_mouse']:
self._id4 = self.master.bind("<Motion>", self.motion, '+')
self._follow_mouse = 1
def configure(self, **opts):
for key in opts:
if key in self._opts:
self._opts[key] = opts[key]
else:
KeyError = 'KeyError: Unknown option: "%s"' %key
raise KeyError
##----these methods handle the callbacks on "<Enter>", "<Leave>" and "<Motion>"---------------##
##----events on the parent widget; override them if you want to change the widget's behavior--##
def enter(self, event=None):
self._schedule()
def leave(self, event=None):
self._unschedule()
self._hide()
def motion(self, event=None):
if self._tipwindow and self._follow_mouse:
x, y = self.coords()
self._tipwindow.wm_geometry("+%d+%d" % (x, y))
##------the methods that do the work:---------------------------------------------------------##
def _schedule(self):
self._unschedule()
if self._opts['state'] == 'disabled':
return
self._id = self.master.after(self._opts['delay'], self._show)
def _unschedule(self):
id = self._id
self._id = None
if id:
self.master.after_cancel(id)
def _show(self):
if self._opts['state'] == 'disabled':
self._unschedule()
return
if not self._tipwindow:
self._tipwindow = tw = tkinter.Toplevel(self.master)
# hide the window until we know the geometry
tw.withdraw()
tw.wm_overrideredirect(1)
if tw.tk.call("tk", "windowingsystem") == 'aqua':
tw.tk.call("::tk::unsupported::MacWindowStyle", "style", tw._w, "help", "none")
self.create_contents()
tw.update_idletasks()
x, y = self.coords()
tw.wm_geometry("+%d+%d" % (x, y))
tw.deiconify()
tw.lift()
def _hide(self):
tw = self._tipwindow
self._tipwindow = None
if tw:
tw.destroy()
##----these methods might be overridden in derived classes:----------------------------------##
def coords(self):
# The tip window must be completely outside the master widget;
# otherwise when the mouse enters the tip window we get
# a leave event and it disappears, and then we get an enter
# event and it reappears, and so on forever :-(
# or we take care that the mouse pointer is always outside the tipwindow :-)
tw = self._tipwindow
twx, twy = tw.winfo_reqwidth(), tw.winfo_reqheight()
w, h = tw.winfo_screenwidth(), tw.winfo_screenheight()
# calculate the y coordinate:
if self._follow_mouse:
y = tw.winfo_pointery() + 20
# make sure the tipwindow is never outside the screen:
if y + twy > h:
y = y - twy - 30
else:
y = self.master.winfo_rooty() + self.master.winfo_height() + 3
if y + twy > h:
y = self.master.winfo_rooty() - twy - 3
# we can use the same x coord in both cases:
x = tw.winfo_pointerx() - twx / 2
if x < 0:
x = 0
elif x + twx > w:
x = w - twx
return x, y
def create_contents(self):
opts = self._opts.copy()
for opt in ('delay', 'follow_mouse', 'state'):
del opts[opt]
label = tkinter.Label(self._tipwindow, **opts)
label.pack()
+653
View File
@@ -0,0 +1,653 @@
#!/bin/env python3
#
# Simple ttk treeview with split view, scrollbar, and
# row of callback buttons
import os
import re
import itertools
import tkinter
from tkinter import ttk
#------------------------------------------------------
# Tree view used as a multi-column list box
#------------------------------------------------------
class TreeViewSplit(ttk.Frame):
def __init__(self, parent, fontsize=11, *args, **kwargs):
ttk.Frame.__init__(self, parent, *args, **kwargs)
s = ttk.Style()
s.configure('normal.TLabel', font=('Helvetica', fontsize))
s.configure('title.TLabel', font=('Helvetica', fontsize, 'bold'))
s.configure('normal.TButton', font=('Helvetica', fontsize),
border = 3, relief = 'raised')
s.configure('Treeview.Heading', font=('Helvetica', fontsize, 'bold'))
s.configure('Treeview.Column', font=('Helvetica', fontsize))
self.fontsize = fontsize
# Last item is a list of 2-item lists, each containing the name of a button
# to place along the button bar at the bottom, and a callback function to
# run when the button is pressed.
def populate(self, title1="", item1list=[], title2="", item2list=[], buttons=[], height=10):
self.item1list = item1list[:]
self.item2list = item2list[:]
columns = [0, 1]
treeFrame = ttk.Frame(self)
treeFrame.pack(side='top', padx=5, pady=5, fill='both', expand='true')
scrollBar = ttk.Scrollbar(treeFrame)
scrollBar.pack(side='right', fill='y')
self.treeView = ttk.Treeview(treeFrame, selectmode='browse', columns=columns, height=height)
self.treeView.pack(side='left', fill='both', expand='true')
scrollBar.config(command=self.treeView.yview)
self.treeView.config(yscrollcommand=scrollBar.set)
self.treeView.column('#0', width=120, stretch='false')
self.treeView.heading(0, text=title1, anchor='w')
self.treeView.heading(1, text=title2, anchor='w')
buttonFrame = ttk.Frame(self)
buttonFrame.pack(side='bottom', fill='x')
self.treeView.tag_configure('select',background='darkslategray',foreground='white')
# Test type tags
self.treeView.tag_configure('error', font=('Helvetica', self.fontsize - 1), foreground = 'red')
self.treeView.tag_configure('clean', font=('Helvetica', self.fontsize - 1), foreground = 'green3')
self.treeView.tag_configure('normal', font=('Helvetica', self.fontsize - 1), foreground = 'black')
self.treeView.tag_configure('prep', font=('Helvetica', self.fontsize, 'bold italic'),
foreground = 'black', anchor = 'center')
self.treeView.tag_configure('header1', font=('Helvetica', self.fontsize, 'bold italic'),
foreground = 'brown', anchor = 'center')
self.treeView.tag_configure('header2', font=('Helvetica', self.fontsize - 1, 'bold'),
foreground = 'blue', anchor = 'center')
self.treeView.tag_configure('header3', font=('Helvetica', self.fontsize - 1, 'italic'),
foreground = 'green4', anchor = 'center')
self.treeView.tag_configure('header4', font=('Helvetica', self.fontsize - 1),
foreground = 'purple', anchor = 'center')
self.func_buttons = []
for button in buttons:
func = button[2]
# Each func_buttons entry is a list of two items; first is the
# button widget, and the second is a boolean that is True if the
# button is to be present always, False if the button is only
# present when there are entries in the itemlists.
self.func_buttons.append([ttk.Button(buttonFrame, text=button[0],
style = 'normal.TButton',
command = lambda func=func: self.func_callback(func)),
button[1]])
self.selectcallback = None
self.lastselected = None
self.lasttag = None
self.repopulate(item1list, item2list)
def get_button(self, index):
if index >= 0 and index < len(self.func_buttons):
return self.func_buttons[index][0]
else:
return None
def set_title(self, title):
self.treeView.heading('#0', text=title, anchor='w')
def repopulate(self, item1list=[], item2list=[]):
# Remove all children of treeview
self.treeView.delete(*self.treeView.get_children())
self.item1list = item1list[:]
self.item2list = item2list[:]
lines = max(len(self.item1list), len(self.item2list))
# Parse the information coming from comp.out. This is preferably
# handled from inside netgen, but that requires development in netgen.
# Note: A top-level group is denoted by an empty string.
nested = ['']
if lines > 0:
# print("Create item ID 0 parent = ''")
self.treeView.insert(nested[-1], 'end', text='-', iid='0',
value=['Initialize', 'Initialize'], tags=['prep'])
nested.append('0')
tagstyle = 'header1'
emptyrec = re.compile('^[\t ]*$')
subrex = re.compile('Subcircuit summary')
cktrex = re.compile('Circuit[\t ]+[12]:[\t ]+([^ \t]+)')
netrex = re.compile('NET mismatches')
devrex = re.compile('DEVICE mismatches')
seprex = re.compile('-----')
sumrex = re.compile('Netlists ')
matchrex = re.compile('.*\*\*Mismatch\*\*')
incircuit = False
watchgroup = False
groupnum = 0
for item1, item2, index in zip(self.item1list, self.item2list, range(lines)):
cname1 = 'Layout' # Placeholder
cname2 = 'Schematic' # Placeholder
# Remove blank lines from the display
lmatch = emptyrec.match(item1)
if lmatch:
lmatch = emptyrec.match(item2)
if lmatch:
continue
index = str(index + 1)
# Parse text to determine how to structure and display it.
tagstyle = 'normal'
nextnest = None
lmatch = subrex.match(item1)
if lmatch:
nested = [''] # pop back to topmost level
nextnest = index
tagstyle = 'header1'
incircuit = False
watchgroup = False
groupnum = 0
item1 = 'Layout compare'
item2 = 'Schematic compare'
else:
lmatch = cktrex.match(item1)
if lmatch and not incircuit:
# Pick up circuit names and replace them in the title, then use them
# for all following titles.
cname1 = lmatch.group(1)
lmatch = cktrex.match(item2)
cname2 = lmatch.group(1)
print("Circuit names " + cname1 + " " + cname2)
# Rewrite title
cktitem = self.treeView.item(nested[-1], values=[cname1 + ' compare',
cname2 + ' compare'])
nextnest = index
tagstyle = 'header2'
incircuit = True
item1 = cname1 + ' Summary'
item2 = cname2 + ' Summary'
elif lmatch:
continue
else:
lmatch = netrex.match(item1)
if lmatch:
if watchgroup:
nested = nested[0:-1]
nested = nested[0:-1]
nextnest = index
tagstyle = 'header2'
groupnum = 1
watchgroup = True
item1 = cname1 + ' Net mismatches'
item2 = cname2 + ' Net mismatches'
else:
lmatch = devrex.match(item1)
if lmatch:
if watchgroup:
nested = nested[0:-1]
nested = nested[0:-1]
nextnest = index
tagstyle = 'header2'
groupnum = 1
watchgroup = True
item1 = cname1 + ' Device mismatches'
item2 = cname2 + ' Device mismatches'
else:
lmatch = seprex.match(item1)
if lmatch:
if watchgroup:
tagstyle = 'header3'
item1 = 'Group ' + str(groupnum)
item2 = 'Group ' + str(groupnum)
if groupnum > 1:
nested = nested[0:-1]
groupnum += 1
nextnest = index
watchgroup = False
else:
if groupnum > 0:
watchgroup = True
continue
else:
lmatch = sumrex.match(item1)
if lmatch:
if watchgroup:
nested = nested[0:-1]
nested = nested[0:-1]
watchgroup = False
tagstyle = 'header2'
groupnum = 0
lmatch1 = matchrex.match(item1)
lmatch2 = matchrex.match(item2)
if lmatch1 or lmatch2:
tagstyle='error'
# print("Create item ID " + str(index) + " parent = " + str(nested[-1]))
self.treeView.insert(nested[-1], 'end', text=index, iid=index, value=[item1, item2],
tags=[tagstyle])
if nextnest:
nested.append(nextnest)
for button in self.func_buttons:
button[0].pack_forget()
if lines == 0:
self.treeView.insert('', 'end', text='-', value=['(no items)', '(no items)'])
for button in self.func_buttons:
if button[1]:
button[0].pack(side='left', padx = 5)
else:
for button in self.func_buttons:
button[0].pack(side='left', padx = 5)
# Special routine to pull in the JSON file data produced by netgen-1.5.72
def json_repopulate(self, lvsdata):
# Remove all children of treeview
self.treeView.delete(*self.treeView.get_children())
# Parse the information coming from comp.out. This is preferably
# handled from inside netgen, but that requires development in netgen.
# Note: A top-level group is denoted by an empty string.
index = 0
errtotal = {}
errtotal['net'] = 0
errtotal['netmatch'] = 0
errtotal['device'] = 0
errtotal['devmatch'] = 0
errtotal['property'] = 0
errtotal['pin'] = 0
ncells = len(lvsdata)
for c in range(0, ncells):
cellrec = lvsdata[c]
if c == ncells - 1:
topcell = True
else:
topcell = False
errcell = {}
errcell['net'] = 0
errcell['netmatch'] = 0
errcell['device'] = 0
errcell['devmatch'] = 0
errcell['property'] = 0
errcell['pin'] = 0;
cname1 = 'Layout'
cname2 = 'Schematic'
# cellrec is a dictionary. Parse the cell summary, then failing nets,
# devices, and properties, and finally pins.
if 'name' in cellrec:
names = cellrec['name']
cname1 = names[0]
cname2 = names[1]
else:
# This is an error but don't halt the program because of it.
cname1 = '(unknown layout)'
cname2 = '(unknown schematic)'
item1 = cname1
item2 = cname2
tagstyle = 'header1'
index += 1
nest0 = index
self.treeView.insert('', 'end', text=index, iid=index, value=[item1, item2],
tags=[tagstyle])
if 'devices' in cellrec or 'nets' in cellrec:
item1 = cname1 + " Summary"
item2 = cname2 + " Summary"
tagstyle = 'header2'
index += 1
nest1 = index
self.treeView.insert(nest0, 'end', text=index, iid=index, value=[item1, item2],
tags=[tagstyle])
if 'devices' in cellrec:
item1 = cname1 + " Devices"
item2 = cname2 + " Devices"
tagstyle = 'header3'
index += 1
nest2 = index
self.treeView.insert(nest1, 'end', text=index, iid=index, value=[item1, item2],
tags=[tagstyle])
devices = cellrec['devices']
devlist = [val for pair in zip(devices[0], devices[1]) for val in pair]
devpair = list(devlist[p:p + 2] for p in range(0, len(devlist), 2))
for dev in devpair:
c1dev = dev[0]
c2dev = dev[1]
item1 = c1dev[0] + "(" + str(c1dev[1]) + ")"
item2 = c2dev[0] + "(" + str(c2dev[1]) + ")"
diffdevs = abs(c1dev[1] - c2dev[1])
if diffdevs == 0:
tagstyle = 'normal'
else:
tagstyle = 'error'
errcell['device'] += diffdevs
if topcell:
errtotal['device'] += diffdevs
index += 1
nest2 = index
self.treeView.insert(nest1, 'end', text=index, iid=index,
value=[item1, item2], tags=[tagstyle])
if 'nets' in cellrec:
item1 = cname1 + " Nets"
item2 = cname2 + " Nets"
tagstyle = 'header3'
index += 1
nest2 = index
self.treeView.insert(nest1, 'end', text=index, iid=index, value=[item1, item2],
tags=[tagstyle])
nets = cellrec['nets']
item1 = nets[0]
item2 = nets[1]
diffnets = abs(nets[0] - nets[1])
if diffnets == 0:
tagstyle = 'normal'
else:
tagstyle = 'error'
errcell['net'] = diffnets
if topcell:
errtotal['net'] += diffnets
index += 1
nest2 = index
self.treeView.insert(nest1, 'end', text=index, iid=index,
value=[item1, item2], tags=[tagstyle])
if 'badnets' in cellrec:
badnets = cellrec['badnets']
if len(badnets) > 0:
item1 = cname1 + " Net Mismatches"
item2 = cname2 + " Net Mismatches"
tagstyle = 'header2'
index += 1
nest1 = index
self.treeView.insert(nest0, 'end', text=index, iid=index,
value=[item1, item2], tags=[tagstyle])
groupnum = 0
for group in badnets:
groupc1 = group[0]
groupc2 = group[1]
nnets = len(groupc1)
groupnum += 1
tagstyle = 'header3'
index += 1
nest2 = index
item1 = "Group " + str(groupnum) + ' (' + str(nnets) + ' nets)'
self.treeView.insert(nest1, 'end', text=index, iid=index,
value=[item1, item1], tags=[tagstyle])
tagstyle = 'error'
errcell['netmatch'] += nnets
if topcell:
errtotal['netmatch'] += nnets
for netnum in range(0, nnets):
if netnum > 0:
item1 = ""
index += 1
nest3 = index
self.treeView.insert(nest2, 'end', text=index, iid=index,
value=[item1, item1], tags=[tagstyle])
net1 = groupc1[netnum]
net2 = groupc2[netnum]
tagstyle = 'header4'
item1 = net1[0]
item2 = net2[0]
index += 1
nest3 = index
self.treeView.insert(nest2, 'end', text=index, iid=index,
value=[item1, item2], tags=[tagstyle])
# Pad shorter device list to the length of the longer one
netdevs = list(itertools.zip_longest(net1[1], net2[1]))
for devpair in netdevs:
devc1 = devpair[0]
devc2 = devpair[1]
tagstyle = 'normal'
if devc1 and devc1[0] != "":
item1 = devc1[0] + '/' + devc1[1] + ' = ' + str(devc1[2])
else:
item1 = ""
if devc2 and devc2[0] != "":
item2 = devc2[0] + '/' + devc2[1] + ' = ' + str(devc2[2])
else:
item2 = ""
index += 1
nest3 = index
self.treeView.insert(nest2, 'end', text=index, iid=index,
value=[item1, item2], tags=[tagstyle])
if 'badelements' in cellrec:
badelements = cellrec['badelements']
if len(badelements) > 0:
item1 = cname1 + " Device Mismatches"
item2 = cname2 + " Device Mismatches"
tagstyle = 'header2'
index += 1
nest1 = index
self.treeView.insert(nest0, 'end', text=index, iid=index,
value=[item1, item2], tags=[tagstyle])
groupnum = 0
for group in badelements:
groupc1 = group[0]
groupc2 = group[1]
ndevs = len(groupc1)
groupnum += 1
tagstyle = 'header3'
index += 1
nest2 = index
item1 = "Group " + str(groupnum) + ' (' + str(ndevs) + ' devices)'
self.treeView.insert(nest1, 'end', text=index, iid=index,
value=[item1, item1], tags=[tagstyle])
tagstyle = 'error'
errcell['devmatch'] += ndevs
if topcell:
errtotal['devmatch'] += ndevs
for elemnum in range(0, ndevs):
if elemnum > 0:
item1 = ""
index += 1
nest3 = index
self.treeView.insert(nest2, 'end', text=index, iid=index,
value=[item1, item1], tags=[tagstyle])
elem1 = groupc1[elemnum]
elem2 = groupc2[elemnum]
tagstyle = 'header4'
item1 = elem1[0]
item2 = elem2[0]
index += 1
nest3 = index
self.treeView.insert(nest2, 'end', text=index, iid=index,
value=[item1, item2], tags=[tagstyle])
# Pad shorter pin list to the length of the longer one
elempins = list(itertools.zip_longest(elem1[1], elem2[1]))
for pinpair in elempins:
pinc1 = pinpair[0]
pinc2 = pinpair[1]
tagstyle = 'normal'
if pinc1 and pinc1[0] != "":
item1 = pinc1[0] + ' = ' + str(pinc1[1])
else:
item1 = ""
if pinc2 and pinc2[0] != "":
item2 = pinc2[0] + ' = ' + str(pinc2[1])
else:
item2 = ""
index += 1
nest3 = index
self.treeView.insert(nest2, 'end', text=index, iid=index,
value=[item1, item2], tags=[tagstyle])
if 'properties' in cellrec:
properties = cellrec['properties']
numproperr = len(properties)
if numproperr > 0:
item1 = cname1 + " Properties"
item2 = cname2 + " Properties"
tagstyle = 'header2'
index += 1
nest1 = index
self.treeView.insert(nest0, 'end', text=index, iid=index, value=[item1, item2],
tags=[tagstyle])
errcell['property'] = numproperr
errtotal['property'] += numproperr
for prop in properties:
if prop != properties[0]:
item1 = ""
index += 1
nest2 = index
self.treeView.insert(nest1, 'end', text=index, iid=index,
value=[item1, item1], tags=[tagstyle])
propc1 = prop[0]
propc2 = prop[1]
tagstyle = 'header3'
item1 = propc1[0]
item2 = propc2[0]
index += 1
nest2 = index
self.treeView.insert(nest1, 'end', text=index, iid=index,
value=[item1, item2], tags=[tagstyle])
# Pad shorter property list to the length of the longer one
elemprops = list(itertools.zip_longest(propc1[1], propc2[1]))
for proppair in elemprops:
perrc1 = proppair[0]
perrc2 = proppair[1]
tagstyle = 'normal'
if perrc1 and perrc1[0] != "":
item1 = perrc1[0] + ' = ' + str(perrc1[1])
else:
item1 = ""
if perrc2 and perrc2[0] != "":
item2 = perrc2[0] + ' = ' + str(perrc2[1])
else:
item2 = ""
index += 1
nest2 = index
self.treeView.insert(nest1, 'end', text=index, iid=index,
value=[item1, item2], tags=[tagstyle])
if 'pins' in cellrec:
item1 = cname1 + " Pins"
item2 = cname2 + " Pins"
tagstyle = 'header2'
index += 1
nest1 = index
self.treeView.insert(nest0, 'end', text=index, iid=index, value=[item1, item2],
tags=[tagstyle])
pins = cellrec['pins']
pinlist = [val for pair in zip(pins[0], pins[1]) for val in pair]
pinpair = list(pinlist[p:p + 2] for p in range(0, len(pinlist), 2))
for pin in pinpair:
item1 = pin[0]
item2 = pin[1]
if item1.lower() == item2.lower():
tagstyle = 'header4'
else:
tagstyle = 'error'
errcell['pin'] += 1
if topcell:
errtotal['pin'] += 1
index += 1
nest2 = index
self.treeView.insert(nest1, 'end', text=index, iid=index,
value=[item1, item2], tags=[tagstyle])
allcellerror = errcell['net'] + errcell['device'] + errcell['property'] + errcell['pin'] + errcell['netmatch'] + errcell['devmatch']
if allcellerror > 0:
item1 = 'Errors: Net = ' + str(errcell['net']) + ', Device = ' + str(errcell['device']) + ', Property = ' + str(errcell['property']) + ', Pin = ' + str(errcell['pin']) + ', Net match = ' + str(errcell['netmatch']) + ', Device match = ' + str(errcell['devmatch'])
tagstyle = 'error'
else:
item1 = 'LVS Clean'
tagstyle = 'clean'
item2 = ""
index += 1
nest0 = index
self.treeView.insert('', 'end', text=index, iid=index, value=[item1, item2],
tags=[tagstyle])
item1 = "Final LVS result:"
item2 = ""
tagstyle = 'header1'
index += 1
nest0 = index
self.treeView.insert('', 'end', text=index, iid=index, value=[item1, item2],
tags=[tagstyle])
allerror = errtotal['net'] + errtotal['device'] + errtotal['property'] + errtotal['pin'] + errtotal['netmatch'] + errtotal['devmatch']
if allerror > 0:
item1 = 'Errors: Net = ' + str(errtotal['net']) + ', Device = ' + str(errtotal['device']) + ', Property = ' + str(errtotal['property']) + ', Pin = ' + str(errtotal['pin']) + ', Net match = ' + str(errtotal['netmatch']) + ', Device match = ' + str(errtotal['devmatch'])
tagstyle = 'error'
else:
item1 = 'LVS Clean'
tagstyle = 'clean'
item2 = ""
index += 1
nest0 = index
self.treeView.insert('', 'end', text=index, iid=index, value=[item1, item2],
tags=[tagstyle])
for button in self.func_buttons:
button[0].pack_forget()
if index == 0:
self.treeView.insert('', 'end', text='-', value=['(no items)', '(no items)'])
for button in self.func_buttons:
if button[1]:
button[0].pack(side='left', padx = 5)
else:
for button in self.func_buttons:
button[0].pack(side='left', padx = 5)
# Return values from the treeview
def getlist(self):
return self.treeView.get_children()
def func_callback(self, callback, event=None):
callback(self.treeView.item(self.treeView.selection()))
def bindselect(self, callback):
self.selectcallback = callback
def setselect(self, value):
self.treeView.selection_set(value)
def selected(self):
value = self.treeView.item(self.treeView.selection())
if value['values']:
return value
else:
return None
-767
View File
@@ -1,767 +0,0 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by netgen configure 1.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ ./configure
## --------- ##
## Platform. ##
## --------- ##
hostname = stravinsky
uname -m = x86_64
uname -r = 3.18.3-201.fc21.x86_64
uname -s = Linux
uname -v = #1 SMP Mon Jan 19 15:59:31 UTC 2015
/usr/bin/uname -p = x86_64
/bin/uname -X = unknown
/bin/arch = x86_64
/usr/bin/arch -k = unknown
/usr/convex/getsysinfo = unknown
/usr/bin/hostinfo = unknown
/bin/machine = unknown
/usr/bin/oslevel = unknown
/bin/universe = unknown
PATH: .
PATH: /bin
PATH: /sbin
PATH: /usr/bin
PATH: /usr/sbin
PATH: /usr/local/bin
## ----------- ##
## Core tests. ##
## ----------- ##
configure:2397: checking build system type
configure:2411: result: x86_64-unknown-linux-gnu
configure:2431: checking host system type
configure:2444: result: x86_64-unknown-linux-gnu
configure:2464: checking target system type
configure:2477: result: x86_64-unknown-linux-gnu
configure:2568: checking for gcc
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)
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.
configure:2844: $? = 0
configure:2833: gcc -v >&5
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
Thread model: posix
gcc version 4.9.2 20141101 (Red Hat 4.9.2-1) (GCC)
configure:2844: $? = 0
configure:2833: gcc -V >&5
gcc: error: unrecognized command line option '-V'
gcc: fatal error: no input files
compilation terminated.
configure:2844: $? = 4
configure:2833: gcc -qversion >&5
gcc: error: unrecognized command line option '-qversion'
gcc: fatal error: no input files
compilation terminated.
configure:2844: $? = 4
configure:2864: checking whether the C compiler works
configure:2886: gcc -g conftest.c >&5
configure:2890: $? = 0
configure:2938: result: yes
configure:2941: checking for C compiler default output file name
configure:2943: result: a.out
configure:2949: checking for suffix of executables
configure:2956: gcc -o conftest -g conftest.c >&5
configure:2960: $? = 0
configure:2982: result:
configure:3004: checking whether we are cross compiling
configure:3012: gcc -o conftest -g conftest.c >&5
configure:3016: $? = 0
configure:3023: ./conftest
configure:3027: $? = 0
configure:3042: result: no
configure:3047: checking for suffix of object files
configure:3069: gcc -c -g conftest.c >&5
configure:3073: $? = 0
configure:3094: result: o
configure:3098: checking whether we are using the GNU C compiler
configure:3117: gcc -c -g conftest.c >&5
configure:3117: $? = 0
configure:3126: result: yes
configure:3135: checking whether gcc accepts -g
configure:3155: gcc -c -g conftest.c >&5
configure:3155: $? = 0
configure:3196: result: yes
configure:3213: checking for gcc option to accept ISO C89
configure:3276: gcc -c -g conftest.c >&5
configure:3276: $? = 0
configure:3289: result: none needed
configure:3314: checking how to run the C preprocessor
configure:3345: gcc -E conftest.c
configure:3345: $? = 0
configure:3359: gcc -E conftest.c
conftest.c:11:28: fatal error: ac_nonexistent.h: No such file or directory
#include <ac_nonexistent.h>
^
compilation terminated.
configure:3359: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "netgen"
| #define PACKAGE_TARNAME "netgen"
| #define PACKAGE_VERSION "1.3"
| #define PACKAGE_STRING "netgen 1.3"
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define NETGEN_VERSION "1.5"
| #define NETGEN_REVISION "60"
| /* end confdefs.h. */
| #include <ac_nonexistent.h>
configure:3384: result: gcc -E
configure:3404: gcc -E conftest.c
configure:3404: $? = 0
configure:3418: gcc -E conftest.c
conftest.c:11:28: fatal error: ac_nonexistent.h: No such file or directory
#include <ac_nonexistent.h>
^
compilation terminated.
configure:3418: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "netgen"
| #define PACKAGE_TARNAME "netgen"
| #define PACKAGE_VERSION "1.3"
| #define PACKAGE_STRING "netgen 1.3"
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define NETGEN_VERSION "1.5"
| #define NETGEN_REVISION "60"
| /* end confdefs.h. */
| #include <ac_nonexistent.h>
configure:3447: checking for library containing strerror
configure:3478: gcc -o conftest -g conftest.c >&5
configure:3478: $? = 0
configure:3495: result: none required
configure:3517: checking for a BSD-compatible install
configure:3585: result: /bin/install -c
configure:3639: checking for ranlib
configure:3655: found /bin/ranlib
configure:3666: result: ranlib
configure:3693: checking for gm4
configure:3726: result: no
configure:3693: checking for gnum4
configure:3726: result: no
configure:3693: checking for m4
configure:3711: found /bin/m4
configure:3723: result: /bin/m4
configure:3764: checking for ld used by GCC
configure:3827: result: /bin/ld
configure:3834: checking if the linker (/bin/ld) is GNU ld
GNU ld version 2.24
configure:3846: result: yes
configure:3853: checking for grep that handles long lines and -e
configure:3911: result: /bin/grep
configure:3916: checking for egrep
configure:3978: result: /bin/grep -E
configure:3983: checking for ANSI C header files
configure:4003: gcc -c -g conftest.c >&5
configure:4003: $? = 0
configure:4076: gcc -o conftest -g conftest.c >&5
configure:4076: $? = 0
configure:4076: ./conftest
configure:4076: $? = 0
configure:4087: result: yes
configure:4100: checking for sys/types.h
configure:4100: gcc -c -g conftest.c >&5
configure:4100: $? = 0
configure:4100: result: yes
configure:4100: checking for sys/stat.h
configure:4100: gcc -c -g conftest.c >&5
configure:4100: $? = 0
configure:4100: result: yes
configure:4100: checking for stdlib.h
configure:4100: gcc -c -g conftest.c >&5
configure:4100: $? = 0
configure:4100: result: yes
configure:4100: checking for string.h
configure:4100: gcc -c -g conftest.c >&5
configure:4100: $? = 0
configure:4100: result: yes
configure:4100: checking for memory.h
configure:4100: gcc -c -g conftest.c >&5
configure:4100: $? = 0
configure:4100: result: yes
configure:4100: checking for strings.h
configure:4100: gcc -c -g conftest.c >&5
configure:4100: $? = 0
configure:4100: result: yes
configure:4100: checking for inttypes.h
configure:4100: gcc -c -g conftest.c >&5
configure:4100: $? = 0
configure:4100: result: yes
configure:4100: checking for stdint.h
configure:4100: gcc -c -g conftest.c >&5
configure:4100: $? = 0
configure:4100: result: yes
configure:4100: checking for unistd.h
configure:4100: gcc -c -g conftest.c >&5
configure:4100: $? = 0
configure:4100: result: yes
configure:4116: checking size of void *
configure:4121: gcc -o conftest -g conftest.c >&5
configure:4121: $? = 0
configure:4121: ./conftest
configure:4121: $? = 0
configure:4135: result: 8
configure:4149: checking size of unsigned int
configure:4154: gcc -o conftest -g conftest.c >&5
configure:4154: $? = 0
configure:4154: ./conftest
configure:4154: $? = 0
configure:4168: result: 4
configure:4182: checking size of unsigned long
configure:4187: gcc -o conftest -g conftest.c >&5
configure:4187: $? = 0
configure:4187: ./conftest
configure:4187: $? = 0
configure:4201: result: 8
configure:4215: checking size of unsigned long long
configure:4220: gcc -o conftest -g conftest.c >&5
configure:4220: $? = 0
configure:4220: ./conftest
configure:4220: $? = 0
configure:4234: result: 8
configure:4245: checking whether byte ordering is bigendian
configure:4260: gcc -c -g conftest.c >&5
conftest.c:26:9: error: unknown type name 'not'
not a universal capable compiler
^
conftest.c:26:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'universal'
not a universal capable compiler
^
conftest.c:26:15: error: unknown type name 'universal'
configure:4260: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "netgen"
| #define PACKAGE_TARNAME "netgen"
| #define PACKAGE_VERSION "1.3"
| #define PACKAGE_STRING "netgen 1.3"
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define NETGEN_VERSION "1.5"
| #define NETGEN_REVISION "60"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_MEMORY_H 1
| #define HAVE_STRINGS_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_UNISTD_H 1
| #define SIZEOF_VOID_P 8
| #define SIZEOF_UNSIGNED_INT 4
| #define SIZEOF_UNSIGNED_LONG 8
| #define SIZEOF_UNSIGNED_LONG_LONG 8
| /* end confdefs.h. */
| #ifndef __APPLE_CC__
| not a universal capable compiler
| #endif
| typedef int dummy;
|
configure:4305: gcc -c -g conftest.c >&5
configure:4305: $? = 0
configure:4323: gcc -c -g conftest.c >&5
conftest.c: In function 'main':
conftest.c:32:4: error: unknown type name 'not'
not big endian
^
conftest.c:32:12: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'endian'
not big endian
^
configure:4323: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "netgen"
| #define PACKAGE_TARNAME "netgen"
| #define PACKAGE_VERSION "1.3"
| #define PACKAGE_STRING "netgen 1.3"
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define NETGEN_VERSION "1.5"
| #define NETGEN_REVISION "60"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_MEMORY_H 1
| #define HAVE_STRINGS_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_UNISTD_H 1
| #define SIZEOF_VOID_P 8
| #define SIZEOF_UNSIGNED_INT 4
| #define SIZEOF_UNSIGNED_LONG 8
| #define SIZEOF_UNSIGNED_LONG_LONG 8
| /* end confdefs.h. */
| #include <sys/types.h>
| #include <sys/param.h>
|
| int
| main ()
| {
| #if BYTE_ORDER != BIG_ENDIAN
| not big endian
| #endif
|
| ;
| return 0;
| }
configure:4451: result: no
configure:4470: checking for ANSI C header files
configure:4574: result: yes
configure:4586: checking for setenv
configure:4586: gcc -o conftest -g conftest.c >&5
configure:4586: $? = 0
configure:4586: result: yes
configure:4586: checking for putenv
configure:4586: gcc -o conftest -g conftest.c >&5
configure:4586: $? = 0
configure:4586: result: yes
configure:4596: checking for vfork
configure:4596: gcc -o conftest -g conftest.c >&5
configure:4596: $? = 0
configure:4596: result: yes
configure:4604: checking dirent.h usability
configure:4604: gcc -c -g conftest.c >&5
configure:4604: $? = 0
configure:4604: result: yes
configure:4604: checking dirent.h presence
configure:4604: gcc -E -x c conftest.c
configure:4604: $? = 0
configure:4604: result: yes
configure:4604: checking for dirent.h
configure:4604: result: yes
configure:4617: checking limits.h usability
configure:4617: gcc -c -g conftest.c >&5
configure:4617: $? = 0
configure:4617: result: yes
configure:4617: checking limits.h presence
configure:4617: gcc -E -x c conftest.c
configure:4617: $? = 0
configure:4617: result: yes
configure:4617: checking for limits.h
configure:4617: result: yes
configure:4630: checking param.h usability
configure:4630: gcc -c -g conftest.c >&5
conftest.c:63:19: fatal error: param.h: No such file or directory
#include <param.h>
^
compilation terminated.
configure:4630: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "netgen"
| #define PACKAGE_TARNAME "netgen"
| #define PACKAGE_VERSION "1.3"
| #define PACKAGE_STRING "netgen 1.3"
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define NETGEN_VERSION "1.5"
| #define NETGEN_REVISION "60"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_MEMORY_H 1
| #define HAVE_STRINGS_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_UNISTD_H 1
| #define SIZEOF_VOID_P 8
| #define SIZEOF_UNSIGNED_INT 4
| #define SIZEOF_UNSIGNED_LONG 8
| #define SIZEOF_UNSIGNED_LONG_LONG 8
| #define STDC_HEADERS 1
| #define HAVE_SETENV 1
| #define HAVE_PUTENV 1
| #define HAVE_DIRENT_H 1
| #define HAVE_LIMITS_H 1
| /* end confdefs.h. */
| #include <stdio.h>
| #ifdef HAVE_SYS_TYPES_H
| # include <sys/types.h>
| #endif
| #ifdef HAVE_SYS_STAT_H
| # include <sys/stat.h>
| #endif
| #ifdef STDC_HEADERS
| # include <stdlib.h>
| # include <stddef.h>
| #else
| # ifdef HAVE_STDLIB_H
| # include <stdlib.h>
| # endif
| #endif
| #ifdef HAVE_STRING_H
| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H
| # include <memory.h>
| # endif
| # include <string.h>
| #endif
| #ifdef HAVE_STRINGS_H
| # include <strings.h>
| #endif
| #ifdef HAVE_INTTYPES_H
| # include <inttypes.h>
| #endif
| #ifdef HAVE_STDINT_H
| # include <stdint.h>
| #endif
| #ifdef HAVE_UNISTD_H
| # include <unistd.h>
| #endif
| #include <param.h>
configure:4630: result: no
configure:4630: checking param.h presence
configure:4630: gcc -E -x c conftest.c
conftest.c:30:19: fatal error: param.h: No such file or directory
#include <param.h>
^
compilation terminated.
configure:4630: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "netgen"
| #define PACKAGE_TARNAME "netgen"
| #define PACKAGE_VERSION "1.3"
| #define PACKAGE_STRING "netgen 1.3"
| #define PACKAGE_BUGREPORT "[email protected]"
| #define PACKAGE_URL ""
| #define NETGEN_VERSION "1.5"
| #define NETGEN_REVISION "60"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_MEMORY_H 1
| #define HAVE_STRINGS_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_UNISTD_H 1
| #define SIZEOF_VOID_P 8
| #define SIZEOF_UNSIGNED_INT 4
| #define SIZEOF_UNSIGNED_LONG 8
| #define SIZEOF_UNSIGNED_LONG_LONG 8
| #define STDC_HEADERS 1
| #define HAVE_SETENV 1
| #define HAVE_PUTENV 1
| #define HAVE_DIRENT_H 1
| #define HAVE_LIMITS_H 1
| /* end confdefs.h. */
| #include <param.h>
configure:4630: result: no
configure:4630: checking for param.h
configure:4630: result: no
configure:4641: checking for va_copy
configure:4659: gcc -o conftest -g conftest.c >&5
configure:4659: $? = 0
configure:4668: result: yes
configure:4676: checking for __va_copy
configure:4694: gcc -o conftest -g conftest.c >&5
configure:4694: $? = 0
configure:4703: result: yes
configure:4834: checking for tclConfig.sh
configure:4906: result: /usr/lib64/tclConfig.sh
configure:4922: checking for tkConfig.sh
configure:4995: result: /usr/lib64/tkConfig.sh
configure:5128: checking for wish executable
configure:5155: result: /usr/bin/wish
configure:5161: checking for tclsh executable
configure:5187: result: /usr/bin/tclsh
configure:5310: checking for X
configure:5449: gcc -o conftest -g conftest.c -lX11 >&5
configure:5449: $? = 0
configure:5499: result: libraries , headers
configure:5598: gcc -o conftest -g conftest.c -lX11 >&5
configure:5598: $? = 0
configure:5696: checking for gethostbyname
configure:5696: gcc -o conftest -g conftest.c >&5
configure:5696: $? = 0
configure:5696: result: yes
configure:5793: checking for connect
configure:5793: gcc -o conftest -g conftest.c >&5
configure:5793: $? = 0
configure:5793: result: yes
configure:5842: checking for remove
configure:5842: gcc -o conftest -g conftest.c >&5
configure:5842: $? = 0
configure:5842: result: yes
configure:5891: checking for shmat
configure:5891: gcc -o conftest -g conftest.c >&5
configure:5891: $? = 0
configure:5891: result: yes
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
## ---------------------- ##
## Running config.status. ##
## ---------------------- ##
This file was extended by netgen config.status 1.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES =
CONFIG_HEADERS =
CONFIG_LINKS =
CONFIG_COMMANDS =
$ ./config.status
on stravinsky
config.status:783: creating defs.mak
config.status:886: WARNING: 'defs.mak.in' seems to ignore the --datarootdir setting
## ---------------- ##
## Cache variables. ##
## ---------------- ##
ac_cv_build=x86_64-unknown-linux-gnu
ac_cv_c___va_copy=yes
ac_cv_c_bigendian=no
ac_cv_c_compiler_gnu=yes
ac_cv_c_va_copy=yes
ac_cv_env_CC_set=
ac_cv_env_CC_value=
ac_cv_env_CFLAGS_set=set
ac_cv_env_CFLAGS_value=-g
ac_cv_env_CPPFLAGS_set=
ac_cv_env_CPPFLAGS_value=
ac_cv_env_CPP_set=
ac_cv_env_CPP_value=
ac_cv_env_LDFLAGS_set=
ac_cv_env_LDFLAGS_value=
ac_cv_env_LIBS_set=
ac_cv_env_LIBS_value=
ac_cv_env_XMKMF_set=
ac_cv_env_XMKMF_value=
ac_cv_env_build_alias_set=
ac_cv_env_build_alias_value=
ac_cv_env_host_alias_set=
ac_cv_env_host_alias_value=
ac_cv_env_target_alias_set=
ac_cv_env_target_alias_value=
ac_cv_func_connect=yes
ac_cv_func_gethostbyname=yes
ac_cv_func_putenv=yes
ac_cv_func_remove=yes
ac_cv_func_setenv=yes
ac_cv_func_shmat=yes
ac_cv_func_vfork=yes
ac_cv_have_x='have_x=yes ac_x_includes='\'''\'' ac_x_libraries='\'''\'''
ac_cv_header_dirent_h=yes
ac_cv_header_inttypes_h=yes
ac_cv_header_limits_h=yes
ac_cv_header_memory_h=yes
ac_cv_header_param_h=no
ac_cv_header_stdc=yes
ac_cv_header_stdint_h=yes
ac_cv_header_stdlib_h=yes
ac_cv_header_string_h=yes
ac_cv_header_strings_h=yes
ac_cv_header_sys_stat_h=yes
ac_cv_header_sys_types_h=yes
ac_cv_header_unistd_h=yes
ac_cv_host=x86_64-unknown-linux-gnu
ac_cv_lib_ICE_IceConnectionNumber=yes
ac_cv_objext=o
ac_cv_path_EGREP='/bin/grep -E'
ac_cv_path_GREP=/bin/grep
ac_cv_path_LD=/bin/ld
ac_cv_path_M4=/bin/m4
ac_cv_path_install='/bin/install -c'
ac_cv_prog_CPP='gcc -E'
ac_cv_prog_ac_ct_CC=gcc
ac_cv_prog_ac_ct_RANLIB=ranlib
ac_cv_prog_cc_c89=
ac_cv_prog_cc_g=yes
ac_cv_prog_gnu_ld=yes
ac_cv_search_strerror='none required'
ac_cv_sizeof_unsigned_int=4
ac_cv_sizeof_unsigned_long=8
ac_cv_sizeof_unsigned_long_long=8
ac_cv_sizeof_void_p=8
ac_cv_target=x86_64-unknown-linux-gnu
## ----------------- ##
## Output variables. ##
## ----------------- ##
ALL_TARGET='tcl'
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'
DEPEND_FLAG='-MM'
ECHO_C=''
ECHO_N='printf'
ECHO_T=''
EGREP='/bin/grep -E'
EXEEXT=''
EXTRA_LIB_SPECS='-ldl'
GREP='/bin/grep'
INC_SPECS=''
INSTALL_DATA='${INSTALL} -m 644'
INSTALL_PROGRAM='${INSTALL}'
INSTALL_SCRIPT='${INSTALL}'
INSTALL_TARGET='install-tcl'
LD='/bin/ld'
LDDL_FLAGS=' -shared -Wl,-soname,$@ -Wl,--version-script=${NETGENDIR}/netgen/symbol.map'
LDFLAGS=''
LD_RUN_PATH=''
LIBOBJS=''
LIBS=''
LIB_SPECS=' -L/usr/lib64 -ltkstub8.6 -L/usr/lib64 -ltclstub8.6'
LIB_SPECS_NOSTUB=' -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6'
LTLIBOBJS=''
M4='/bin/m4'
OBJEXT='o'
PACKAGE='netgen'
PACKAGE_BUGREPORT='[email protected]'
PACKAGE_NAME='netgen'
PACKAGE_STRING='netgen 1.3'
PACKAGE_TARNAME='netgen'
PACKAGE_URL=''
PACKAGE_VERSION='1.3'
PATH_SEPARATOR=':'
RANLIB='ranlib'
SCRIPTS=''
SHDLIB_EXT='.so'
SHELL='/bin/sh'
SHLIB_CFLAGS='-fPIC'
SHLIB_LD=''
SHLIB_LIB_SPECS=''
TCLSH_EXE='/usr/bin/tclsh'
TCL_LIB_DIR='/usr/lib'
VERSION=''
WISH_EXE='/usr/bin/wish'
XMKMF=''
X_CFLAGS=''
X_EXTRA_LIBS=''
X_LIBS=''
X_PRE_LIBS=' -lSM -lICE'
ac_ct_CC='gcc'
bindir='${exec_prefix}/bin'
build='x86_64-unknown-linux-gnu'
build_alias=''
build_cpu='x86_64'
build_os='linux-gnu'
build_vendor='unknown'
cadinstall=' tcltk'
datadir='${datarootdir}'
datarootdir='${prefix}/share'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
dvidir='${docdir}'
exec_prefix='${prefix}'
extra_defs=' -DCAD_DIR=\"${LIBDIR}\" -DTCL_DIR=\"${TCLDIR}\"'
extra_libs=' ${NETGENDIR}/tcltk/libtcltk.o'
gr_cflags=''
gr_dflags=' -DX11 -DXLIB'
gr_libs=' -lX11'
gr_srcs=' ${TK_SRCS}'
host='x86_64-unknown-linux-gnu'
host_alias=''
host_cpu='x86_64'
host_os='linux-gnu'
host_vendor='unknown'
htmldir='${docdir}'
includedir='${prefix}/include'
infodir='${datarootdir}/info'
ld_extra_libs=''
ld_extra_objs=''
libdir='${exec_prefix}/lib'
libexecdir='${exec_prefix}/libexec'
localedir='${datarootdir}/locale'
localstatedir='${prefix}/var'
mandir='${datarootdir}/man'
modules=' tcltk'
oldincludedir='/usr/include'
pdfdir='${docdir}'
prefix='/usr/local'
program_transform_name='s,x,x,'
programs=' tcltk'
psdir='${docdir}'
sbindir='${exec_prefix}/sbin'
sharedstatedir='${prefix}/com'
stub_defs=' -DUSE_TCL_STUBS -DUSE_TK_STUBS'
sub_extra_libs=''
sysconfdir='${prefix}/etc'
target='x86_64-unknown-linux-gnu'
target_alias=''
target_cpu='x86_64'
target_os='linux-gnu'
target_vendor='unknown'
top_extra_libs=''
unused=''
## ----------- ##
## confdefs.h. ##
## ----------- ##
/* confdefs.h */
#define PACKAGE_NAME "netgen"
#define PACKAGE_TARNAME "netgen"
#define PACKAGE_VERSION "1.3"
#define PACKAGE_STRING "netgen 1.3"
#define PACKAGE_BUGREPORT "[email protected]"
#define PACKAGE_URL ""
#define NETGEN_VERSION "1.5"
#define NETGEN_REVISION "60"
#define STDC_HEADERS 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STRINGS_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_UNISTD_H 1
#define SIZEOF_VOID_P 8
#define SIZEOF_UNSIGNED_INT 4
#define SIZEOF_UNSIGNED_LONG 8
#define SIZEOF_UNSIGNED_LONG_LONG 8
#define STDC_HEADERS 1
#define HAVE_SETENV 1
#define HAVE_PUTENV 1
#define HAVE_DIRENT_H 1
#define HAVE_LIMITS_H 1
#define HAVE_VA_COPY 1
#define HAVE___VA_COPY 1
#define DBUG_OFF 1
#define TCL_NETGEN 1
#define linux 1
#define SYSV 1
#define ISC 1
configure: exit 0
-940
View File
@@ -1,940 +0,0 @@
#! /bin/sh
# Generated by configure.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.
debug=false
ac_cs_recheck=false
ac_cs_silent=false
SHELL=${CONFIG_SHELL-/bin/sh}
export SHELL
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##
# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
NULLCMD=:
# Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
else
case `(set -o) 2>/dev/null` in #(
*posix*) :
set -o posix ;; #(
*) :
;;
esac
fi
as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
&& (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
as_echo='print -r --'
as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
as_echo='printf %s\n'
as_echo_n='printf %s'
else
if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
as_echo_n='/usr/ucb/echo -n'
else
as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
as_echo_n_body='eval
arg=$1;
case $arg in #(
*"$as_nl"*)
expr "X$arg" : "X\\(.*\\)$as_nl";
arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
esac;
expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
'
export as_echo_n_body
as_echo_n='sh -c $as_echo_n_body as_echo'
fi
export as_echo_body
as_echo='sh -c $as_echo_body as_echo'
fi
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
PATH_SEPARATOR=:
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
(PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
PATH_SEPARATOR=';'
}
fi
# IFS
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" "" $as_nl"
# Find who we are. Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done
IFS=$as_save_IFS
;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
$as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
exit 1
fi
# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there. '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
&& ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '
# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
as_status=$1; test $as_status -eq 0 && as_status=1
if test "$4"; then
as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
$as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
$as_echo "$as_me: error: $2" >&2
as_fn_exit $as_status
} # as_fn_error
# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
return $1
} # as_fn_set_status
# as_fn_exit STATUS
# -----------------
# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
as_fn_exit ()
{
set +e
as_fn_set_status $1
exit $1
} # as_fn_exit
# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
{ eval $1=; unset $1;}
}
as_unset=as_fn_unset
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
eval 'as_fn_append ()
{
eval $1+=\$2
}'
else
as_fn_append ()
{
eval $1=\$$1\$2
}
fi # as_fn_append
# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
eval 'as_fn_arith ()
{
as_val=$(( $* ))
}'
else
as_fn_arith ()
{
as_val=`expr "$@" || test $? -eq 1`
}
fi # as_fn_arith
if expr a : '\(a\)' >/dev/null 2>&1 &&
test "X`expr 00001 : '.*\(...\)'`" = X001; then
as_expr=expr
else
as_expr=false
fi
if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
as_dirname=dirname
else
as_dirname=false
fi
as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
sed '/^.*\/\([^/][^/]*\)\/*$/{
s//\1/
q
}
/^X\/\(\/\/\)$/{
s//\1/
q
}
/^X\/\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
case `echo 'xy\c'` in
*c*) ECHO_T=' ';; # ECHO_T is single tab character.
xy) ECHO_C='\c';;
*) echo `echo ksh88 bug on AIX 6.1` > /dev/null
ECHO_T=' ';;
esac;;
*)
ECHO_N='-n';;
esac
rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
rm -f conf$$.dir/conf$$.file
else
rm -f conf$$.dir
mkdir conf$$.dir 2>/dev/null
fi
if (echo >conf$$.file) 2>/dev/null; then
if ln -s conf$$.file conf$$ 2>/dev/null; then
as_ln_s='ln -s'
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
# In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -pR'
fi
else
as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
# as_fn_mkdir_p
# -------------
# Create "$as_dir" as a directory, including parents if necessary.
as_fn_mkdir_p ()
{
case $as_dir in #(
-*) as_dir=./$as_dir;;
esac
test -d "$as_dir" || eval $as_mkdir_p || {
as_dirs=
while :; do
case $as_dir in #(
*\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
*) as_qdir=$as_dir;;
esac
as_dirs="'$as_qdir' $as_dirs"
as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
} || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
} # as_fn_mkdir_p
if mkdir -p . 2>/dev/null; then
as_mkdir_p='mkdir -p "$as_dir"'
else
test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
# as_fn_executable_p FILE
# -----------------------
# Test if FILE is an executable regular file.
as_fn_executable_p ()
{
test -f "$1" && test -x "$1"
} # as_fn_executable_p
as_test_x='test -x'
as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
exec 6>&1
## ----------------------------------- ##
## Main body of $CONFIG_STATUS script. ##
## ----------------------------------- ##
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by netgen $as_me 1.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
CONFIG_LINKS = $CONFIG_LINKS
CONFIG_COMMANDS = $CONFIG_COMMANDS
$ $0 $@
on `(hostname || uname -n) 2>/dev/null | sed 1q`
"
# Files that config.status was made for.
config_files=" defs.mak"
ac_cs_usage="\
\`$as_me' instantiates files and other configuration actions
from templates according to the current configuration. Unless the files
and actions are specified as TAGs, all are instantiated by default.
Usage: $0 [OPTION]... [TAG]...
-h, --help print this help, then exit
-V, --version print version number and configuration settings, then exit
--config print configuration, then exit
-q, --quiet, --silent
do not print progress messages
-d, --debug don't remove temporary files
--recheck update $as_me by reconfiguring in the same conditions
--file=FILE[:TEMPLATE]
instantiate the configuration file FILE
Configuration files:
$config_files
Report bugs to <[email protected]>."
ac_cs_config="'CFLAGS=-g'"
ac_cs_version="\
netgen config.status 1.3
configured by ./configure, generated by GNU Autoconf 2.69,
with options \"$ac_cs_config\"
Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
ac_pwd='/home/tim/gitsrc/netgen-1.5/scripts'
srcdir='..'
INSTALL='/bin/install -c'
test -n "$AWK" || AWK=awk
# The default lists apply if the user does not specify any file.
ac_need_defaults=:
while test $# != 0
do
case $1 in
--*=?*)
ac_option=`expr "X$1" : 'X\([^=]*\)='`
ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
ac_shift=:
;;
--*=)
ac_option=`expr "X$1" : 'X\([^=]*\)='`
ac_optarg=
ac_shift=:
;;
*)
ac_option=$1
ac_optarg=$2
ac_shift=shift
;;
esac
case $ac_option in
# Handling of the options.
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
ac_cs_recheck=: ;;
--version | --versio | --versi | --vers | --ver | --ve | --v | -V )
$as_echo "$ac_cs_version"; exit ;;
--config | --confi | --conf | --con | --co | --c )
$as_echo "$ac_cs_config"; exit ;;
--debug | --debu | --deb | --de | --d | -d )
debug=: ;;
--file | --fil | --fi | --f )
$ac_shift
case $ac_optarg in
*\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
'') as_fn_error $? "missing file argument" ;;
esac
as_fn_append CONFIG_FILES " '$ac_optarg'"
ac_need_defaults=false;;
--he | --h | --help | --hel | -h )
$as_echo "$ac_cs_usage"; exit ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil | --si | --s)
ac_cs_silent=: ;;
# This is an error.
-*) as_fn_error $? "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;
*) as_fn_append ac_config_targets " $1"
ac_need_defaults=false ;;
esac
shift
done
ac_configure_extra_args=
if $ac_cs_silent; then
exec 6>/dev/null
ac_configure_extra_args="$ac_configure_extra_args --silent"
fi
if $ac_cs_recheck; then
set X /bin/sh './configure' 'CFLAGS=-g' $ac_configure_extra_args --no-create --no-recursion
shift
$as_echo "running CONFIG_SHELL=/bin/sh $*" >&6
CONFIG_SHELL='/bin/sh'
export CONFIG_SHELL
exec "$@"
fi
exec 5>>config.log
{
echo
sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
$as_echo "$ac_log"
} >&5
# Handling of arguments.
for ac_config_target in $ac_config_targets
do
case $ac_config_target in
"defs.mak") CONFIG_FILES="$CONFIG_FILES defs.mak" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
done
# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used. Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
fi
# Have a temporary directory for convenience. Make it in the build tree
# simply because there is no reason against having it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Hook for its removal unless debugging.
# Note that there is a small window in which the directory will not be cleaned:
# after its creation but before its name has been assigned to `$tmp'.
$debug ||
{
tmp= ac_tmp=
trap 'exit_status=$?
: "${ac_tmp:=$tmp}"
{ test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0
trap 'as_fn_exit 1' 1 2 13 15
}
# Create a (secure) tmp directory for tmp files.
{
tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
test -d "$tmp"
} ||
{
tmp=./conf$$-$RANDOM
(umask 077 && mkdir "$tmp")
} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
ac_tmp=$tmp
# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
# This happens for instance with `./config.status config.h'.
if test -n "$CONFIG_FILES"; then
ac_cr=`echo X | tr X '\015'`
# On cygwin, bash can eat \r inside `` if the user requested igncr.
# But we know of no other shell where ac_cr would be empty at this
# point, so we can use a bashism as a fallback.
if test "x$ac_cr" = x; then
eval ac_cr=\$\'\\r\'
fi
ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
ac_cs_awk_cr='\\r'
else
ac_cs_awk_cr=$ac_cr
fi
echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
cat >>"$ac_tmp/subs1.awk" <<\_ACAWK &&
S["LTLIBOBJS"]=""
S["LIBOBJS"]=""
S["INSTALL_TARGET"]="install-tcl"
S["ALL_TARGET"]="tcl"
S["LD_RUN_PATH"]=""
S["SHLIB_CFLAGS"]="-fPIC"
S["DEPEND_FLAG"]="-MM"
S["gr_srcs"]=" ${TK_SRCS}"
S["gr_libs"]=" -lX11"
S["gr_dflags"]=" -DX11 -DXLIB"
S["gr_cflags"]=""
S["cadinstall"]=" tcltk"
S["programs"]=" tcltk"
S["unused"]=""
S["modules"]=" tcltk"
S["sub_extra_libs"]=""
S["top_extra_libs"]=""
S["ld_extra_objs"]=""
S["ld_extra_libs"]=""
S["stub_defs"]=" -DUSE_TCL_STUBS -DUSE_TK_STUBS"
S["extra_defs"]=" -DCAD_DIR=\\\"${LIBDIR}\\\" -DTCL_DIR=\\\"${TCLDIR}\\\""
S["extra_libs"]=" ${NETGENDIR}/tcltk/libtcltk.o"
S["SCRIPTS"]=""
S["PACKAGE"]="netgen"
S["VERSION"]=""
S["TCL_LIB_DIR"]="/usr/lib"
S["TCLSH_EXE"]="/usr/bin/tclsh"
S["WISH_EXE"]="/usr/bin/wish"
S["LIB_SPECS_NOSTUB"]=" -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6"
S["LIB_SPECS"]=" -L/usr/lib64 -ltkstub8.6 -L/usr/lib64 -ltclstub8.6"
S["INC_SPECS"]=""
S["EXTRA_LIB_SPECS"]="-ldl"
S["SHLIB_LIB_SPECS"]=""
S["LDDL_FLAGS"]=" -shared -Wl,-soname,$@ -Wl,--version-script=${NETGENDIR}/netgen/symbol.map"
S["LD"]="/bin/ld"
S["SHLIB_LD"]=""
S["SHDLIB_EXT"]=".so"
S["X_EXTRA_LIBS"]=""
S["X_LIBS"]=""
S["X_PRE_LIBS"]=" -lSM -lICE"
S["X_CFLAGS"]=""
S["XMKMF"]=""
S["EGREP"]="/bin/grep -E"
S["GREP"]="/bin/grep"
S["M4"]="/bin/m4"
S["RANLIB"]="ranlib"
S["INSTALL_DATA"]="${INSTALL} -m 644"
S["INSTALL_SCRIPT"]="${INSTALL}"
S["INSTALL_PROGRAM"]="${INSTALL}"
S["CPP"]="gcc -E -x c"
S["OBJEXT"]="o"
S["EXEEXT"]=""
S["ac_ct_CC"]="gcc"
S["CPPFLAGS"]=""
S["LDFLAGS"]=""
S["CFLAGS"]="-g -m64 -fPIC"
S["CC"]="gcc"
S["target_os"]="linux-gnu"
S["target_vendor"]="unknown"
S["target_cpu"]="x86_64"
S["target"]="x86_64-unknown-linux-gnu"
S["host_os"]="linux-gnu"
S["host_vendor"]="unknown"
S["host_cpu"]="x86_64"
S["host"]="x86_64-unknown-linux-gnu"
S["build_os"]="linux-gnu"
S["build_vendor"]="unknown"
S["build_cpu"]="x86_64"
S["build"]="x86_64-unknown-linux-gnu"
S["target_alias"]=""
S["host_alias"]=""
S["build_alias"]=""
S["LIBS"]=""
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 -"\
"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"
S["mandir"]="${datarootdir}/man"
S["localedir"]="${datarootdir}/locale"
S["libdir"]="${exec_prefix}/lib"
S["psdir"]="${docdir}"
S["pdfdir"]="${docdir}"
S["dvidir"]="${docdir}"
S["htmldir"]="${docdir}"
S["infodir"]="${datarootdir}/info"
S["docdir"]="${datarootdir}/doc/${PACKAGE_TARNAME}"
S["oldincludedir"]="/usr/include"
S["includedir"]="${prefix}/include"
S["localstatedir"]="${prefix}/var"
S["sharedstatedir"]="${prefix}/com"
S["sysconfdir"]="${prefix}/etc"
S["datadir"]="${datarootdir}"
S["datarootdir"]="${prefix}/share"
S["libexecdir"]="${exec_prefix}/libexec"
S["sbindir"]="${exec_prefix}/sbin"
S["bindir"]="${exec_prefix}/bin"
S["program_transform_name"]="s,x,x,"
S["prefix"]="/usr/local"
S["exec_prefix"]="${prefix}"
S["PACKAGE_URL"]=""
S["PACKAGE_BUGREPORT"]="[email protected]"
S["PACKAGE_STRING"]="netgen 1.3"
S["PACKAGE_VERSION"]="1.3"
S["PACKAGE_TARNAME"]="netgen"
S["PACKAGE_NAME"]="netgen"
S["PATH_SEPARATOR"]=":"
S["SHELL"]="/bin/sh"
_ACAWK
cat >>"$ac_tmp/subs1.awk" <<_ACAWK &&
for (key in S) S_is_set[key] = 1
FS = ""
}
{
line = $ 0
nfields = split(line, field, "@")
substed = 0
len = length(field[1])
for (i = 2; i < nfields; i++) {
key = field[i]
keylen = length(key)
if (S_is_set[key]) {
value = S[key]
line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
len += length(value) + length(field[++i])
substed = 1
} else
len += 1 + keylen
}
print line
}
_ACAWK
if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
else
cat
fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
|| as_fn_error $? "could not setup config files machinery" "$LINENO" 5
fi # test -n "$CONFIG_FILES"
eval set X " :F $CONFIG_FILES "
shift
for ac_tag
do
case $ac_tag in
:[FHLC]) ac_mode=$ac_tag; continue;;
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
:L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
ac_save_IFS=$IFS
IFS=:
set x $ac_tag
IFS=$ac_save_IFS
shift
ac_file=$1
shift
case $ac_mode in
:L) ac_source=$1;;
:[FH])
ac_file_inputs=
for ac_f
do
case $ac_f in
-) ac_f="$ac_tmp/stdin";;
*) # Look for the file first in the build tree, then in the source tree
# (if the path is not absolute). The absolute path cannot be DOS-style,
# because $ac_f cannot contain `:'.
test -f "$ac_f" ||
case $ac_f in
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
esac
case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
done
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
configure_input='Generated from '`
$as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
`' by configure.'
if test x"$ac_file" != x-; then
configure_input="$ac_file. $configure_input"
{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
$as_echo "$as_me: creating $ac_file" >&6;}
fi
# Neutralize special characters interpreted by sed in replacement strings.
case $configure_input in #(
*\&* | *\|* | *\\* )
ac_sed_conf_input=`$as_echo "$configure_input" |
sed 's/[\\\\&|]/\\\\&/g'`;; #(
*) ac_sed_conf_input=$configure_input;;
esac
case $ac_tag in
*:-:* | *:-) cat >"$ac_tmp/stdin" \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
ac_dir=`$as_dirname -- "$ac_file" ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
as_dir="$ac_dir"; as_fn_mkdir_p
ac_builddir=.
case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
# A ".." for each directory in $ac_dir_suffix.
ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
case $ac_top_builddir_sub in
"") ac_top_builddir_sub=. ac_top_build_prefix= ;;
*) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
# for backward compatibility:
ac_top_builddir=$ac_top_build_prefix
case $srcdir in
.) # We are building in place.
ac_srcdir=.
ac_top_srcdir=$ac_top_builddir_sub
ac_abs_top_srcdir=$ac_pwd ;;
[\\/]* | ?:[\\/]* ) # Absolute name.
ac_srcdir=$srcdir$ac_dir_suffix;
ac_top_srcdir=$srcdir
ac_abs_top_srcdir=$srcdir ;;
*) # Relative name.
ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_build_prefix$srcdir
ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
case $ac_mode in
:F)
#
# CONFIG_FILE
#
case $INSTALL in
[\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
*) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
esac
# If the template does not know about datarootdir, expand it.
# FIXME: This hack should be removed a few years after 2.60.
ac_datarootdir_hack=; ac_datarootdir_seen=
ac_sed_dataroot='
/datarootdir/ {
p
q
}
/@datadir@/p
/@docdir@/p
/@infodir@/p
/@localedir@/p
/@mandir@/p'
case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
*datarootdir*) ac_datarootdir_seen=yes;;
*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
ac_datarootdir_hack='
s&@datadir@&${datarootdir}&g
s&@docdir@&${datarootdir}/doc/${PACKAGE_TARNAME}&g
s&@infodir@&${datarootdir}/info&g
s&@localedir@&${datarootdir}/locale&g
s&@mandir@&${datarootdir}/man&g
s&\${datarootdir}&${prefix}/share&g' ;;
esac
ac_sed_extra="
:t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
s|@configure_input@|$ac_sed_conf_input|;t t
s&@top_builddir@&$ac_top_builddir_sub&;t t
s&@top_build_prefix@&$ac_top_build_prefix&;t t
s&@srcdir@&$ac_srcdir&;t t
s&@abs_srcdir@&$ac_abs_srcdir&;t t
s&@top_srcdir@&$ac_top_srcdir&;t t
s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
s&@builddir@&$ac_builddir&;t t
s&@abs_builddir@&$ac_abs_builddir&;t t
s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
s&@INSTALL@&$ac_INSTALL&;t t
$ac_datarootdir_hack
"
eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
>$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
{ ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
{ ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
"$ac_tmp/out"`; test -z "$ac_out"; } &&
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined" >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined" >&2;}
rm -f "$ac_tmp/stdin"
case $ac_file in
-) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
*) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
esac \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
;;
esac
done # for ac_tag
as_fn_exit 0
+79 -3
View File
@@ -633,6 +633,7 @@ gr_srcs
gr_libs
gr_dflags
gr_cflags
DIST_DIR
cadinstall
programs
unused
@@ -664,6 +665,7 @@ X_LIBS
X_PRE_LIBS
X_CFLAGS
XMKMF
HAVE_PYTHON3
EGREP
GREP
M4
@@ -733,6 +735,7 @@ ac_subst_files=''
ac_user_opts='
enable_option_checking
with_gnu_ld
with_distdir
with_interpreter
with_tcl
with_tk
@@ -1371,6 +1374,7 @@ Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
--with-distdir=DIR install into location DIR for distribution
--with-interpreter=arg enable interpreter
--with-tcl=DIR Find tclConfig.sh in DIR
--with-tk=DIR Find tkConfig.sh in DIR
@@ -4638,6 +4642,45 @@ fi
done
# Extract the first word of "python3", so it can be a program name with args.
set dummy python3; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_HAVE_PYTHON3+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$HAVE_PYTHON3"; then
ac_cv_prog_HAVE_PYTHON3="$HAVE_PYTHON3" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_HAVE_PYTHON3="yes"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
test -z "$ac_cv_prog_HAVE_PYTHON3" && ac_cv_prog_HAVE_PYTHON3="no"
fi
fi
HAVE_PYTHON3=$ac_cv_prog_HAVE_PYTHON3
if test -n "$HAVE_PYTHON3"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_PYTHON3" >&5
$as_echo "$HAVE_PYTHON3" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for va_copy" >&5
$as_echo_n "checking for va_copy... " >&6; }
if ${ac_cv_c_va_copy+:} false; then :
@@ -4758,6 +4801,24 @@ usingTcl=1
usingX11=
# For distributed installs, where the run-time files are installed in a
# place that is a temporary staging area, like DESTDIR, but unlike DESTDIR,
# the prefix is replaced by the destination directory, rather than appended
# to it.
DIST_DIR="\${exec_prefix}"
# Check whether --with-distdir was given.
if test "${with_distdir+set}" = set; then :
withval=$with_distdir;
if test "$withval" = "no" -o "$withval" = "NO" ; then
DIST_DIR="\${exec_prefix}"
else
DIST_DIR=${withval}
fi
fi
# Check whether --with-interpreter was given.
if test "${with_interpreter+set}" = set; then :
@@ -6081,8 +6142,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
@@ -6374,7 +6434,7 @@ fi
# Not available on all versions: check for include file.
SHLIB_CFLAGS="-fpic"
LDDL_FLAGS="-shared ${LIB_SPECS}"
CFLAGS="${CFLAGS} -l/usr/X11R6/include"
CFLAGS="${CFLAGS} -L/usr/X11R6/include"
;;
*-netbsd*|*-openbsd*)
@@ -6546,6 +6606,8 @@ fi
@@ -7738,6 +7800,20 @@ else
echo
fi
${ECHO_N} "Python3: "
if test "${HAVE_PYTHON3}" == "yes"; then
echo "yes"
else
echo "no"
echo
echo " Without Python3, you cannot run the GUI interface to netgen."
echo " This is purely optional, as it contains no features not"
echo " available in the command-line (Tcl/Tk) version. If you want"
echo " python3 support, make sure that you have installed python3"
echo " on your system."
echo
fi
echo "-----------------------------------------------------------"
echo
+35 -2
View File
@@ -163,6 +163,9 @@ AC_CHECK_HEADERS(limits.h)
dnl Check for <param.h>
AC_CHECK_HEADERS(param.h)
dnl Check for Python3
AC_CHECK_PROG(HAVE_PYTHON3, python3, yes, no)
dnl Check for va_copy
AC_CACHE_CHECK([for va_copy], ac_cv_c_va_copy,
AC_TRY_LINK(
@@ -246,6 +249,20 @@ usingX11=
dnl Compile-time options below. . .
# For distributed installs, where the run-time files are installed in a
# place that is a temporary staging area, like DESTDIR, but unlike DESTDIR,
# the prefix is replaced by the destination directory, rather than appended
# to it.
DIST_DIR="\${exec_prefix}"
AC_ARG_WITH(distdir,
[ --with-distdir=DIR install into location DIR for distribution], [
if test "$withval" = "no" -o "$withval" = "NO" ; then
DIST_DIR="\${exec_prefix}"
else
DIST_DIR=${withval}
fi
], )
AC_ARG_WITH(interpreter,
[ --with-interpreter=[arg] enable interpreter], [
if test "$withval" = "no" -o "$withval" = "NO"; then
@@ -868,7 +885,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
@@ -1117,7 +1134,7 @@ if test $usingTcl ; then
# Not available on all versions: check for include file.
SHLIB_CFLAGS="-fpic"
LDDL_FLAGS="-shared ${LIB_SPECS}"
CFLAGS="${CFLAGS} -l/usr/X11R6/include"
CFLAGS="${CFLAGS} -L/usr/X11R6/include"
;;
*-netbsd*|*-openbsd*)
@@ -1269,11 +1286,13 @@ AC_SUBST(modules)
AC_SUBST(unused)
AC_SUBST(programs)
AC_SUBST(cadinstall)
AC_SUBST(DIST_DIR)
AC_SUBST(gr_cflags)
AC_SUBST(gr_dflags)
AC_SUBST(gr_libs)
AC_SUBST(gr_srcs)
AC_SUBST(HAVE_PYTHON3)
AC_SUBST(X_LIBS)
AC_SUBST(X_CFLAGS)
@@ -1314,6 +1333,20 @@ else
echo
fi
${ECHO_N} "Python3: "
if test "${HAVE_PYTHON3}" == "yes"; then
echo "yes"
else
echo "no"
echo
echo " Without Python3, you cannot run the GUI interface to netgen."
echo " This is purely optional, as it contains no features not"
echo " available in the command-line (Tcl/Tk) version. If you want"
echo " python3 support, make sure that you have installed python3"
echo " on your system."
echo
fi
echo "-----------------------------------------------------------"
echo
File diff suppressed because it is too large Load Diff
-84
View File
@@ -1,84 +0,0 @@
# defs.mak.in --
# source file for autoconf-generated "defs.mak" for netgen
# defs.mak. Generated from defs.mak.in by configure.
# Feel free to change the values in here to suit your needs.
# Be aware that running scripts/configure again will overwrite
# any changes!
SHELL = /bin/sh
prefix = ${BUILDROOT}/usr/local
exec_prefix = ${prefix}
bindir = ${exec_prefix}/bin
libdir = ${exec_prefix}/lib
mandir = ${prefix}/share/man
VERSION =
SCRIPTS = ${NETGENDIR}/scripts
INSTALL = /bin/install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL}
# Override standard "make" target when compiling under TCL
ALL_TARGET = tcl
INSTALL_TARGET = install-tcl
# Change CADDIR to install in a different place
BINDIR = ${bindir}
MANDIR = ${mandir}
LIBDIR = ${libdir}
DOCDIR = ${libdir}/netgen/doc
TCLDIR = ${libdir}/netgen/tcl
MAIN_EXTRA_LIBS = ${NETGENDIR}/tcltk/libtcltk.o
LD_EXTRA_LIBS =
LD_SHARED =
TOP_EXTRA_LIBS =
SUB_EXTRA_LIBS =
MODULES += tcltk
UNUSED_MODULES +=
PROGRAMS += tcltk
INSTALL_CAD_DIRS += tcltk
RM = rm -f
CP = cp
AR = @AR@
ARFLAGS = crv
LINK = /bin/ld -r
LD = /bin/ld
M4 = /bin/m4
RANLIB = ranlib
SHDLIB_EXT = .so
LDDL_FLAGS = -shared -Wl,-soname,$@ -Wl,--version-script=${NETGENDIR}/netgen/symbol.map
LD_RUN_PATH =
LIB_SPECS = -L/usr/lib64 -ltkstub8.6 -L/usr/lib64 -ltclstub8.6
LIB_SPECS_NOSTUB = -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6
WISH_EXE = /usr/bin/wish
TCL_LIB_DIR = /usr/lib
CC = gcc
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
CFLAGS = -g -m64 -fPIC -fPIC
DEPEND_FILE = Depend
DEPEND_FLAG = -MM
EXEEXT =
GR_CFLAGS =
GR_DFLAGS = -DX11 -DXLIB -DNDEBUG
GR_LIBS = -lX11
GR_SRCS = ${TK_SRCS}
OBJS = ${SRCS:.c=.o}
LIB_OBJS = ${LIB_SRCS:.c=.o}
CLEANS = ${OBJS} ${LIB_OBJS} lib${MODULE}.a lib${MODULE}.o ${MODULE}
+8
View File
@@ -33,6 +33,14 @@ MANDIR = ${mandir}
LIBDIR = ${libdir}
DOCDIR = ${libdir}/netgen/doc
TCLDIR = ${libdir}/netgen/tcl
PYDIR = ${libdir}/netgen/python
INSTALL_BINDIR = @DIST_DIR@/bin
INSTALL_MANDIR = @DIST_DIR@/share/man
INSTALL_LIBDIR = @DIST_DIR@/lib
INSTALL_DOCDIR = ${INSTALL_LIBDIR}/netgen/doc
INSTALL_TCLDIR = ${INSTALL_LIBDIR}/netgen/tcl
INSTALL_PYDIR = ${INSTALL_LIBDIR}/netgen/python
MAIN_EXTRA_LIBS = @extra_libs@
LD_EXTRA_LIBS = @ld_extra_libs@
-187
View File
@@ -1,187 +0,0 @@
#!/bin/csh -f
#
# makes the "database.h" (1st argument, $1) file from "database.h.in"
# (2nd argument, $2), setting various mask operation definitions
# according to the number of words implied by the value of TT_MAXTYPES
# The following mess grabs the value of TT_MAXTYPES from database.h.in
#
set maxtypes=`sed -n -e '/^#define[[:space:]]*TT_MAXTYPES/s/#define[[:space:]]*TT_MAXTYPES[[:space:]]*//p' < $1 | sed -e 's/\/\*[[:print:]]*\*\/[[:space:]]*//g' `
#
# Alternative method works with outdated versions of sed/ed.
#
if ($maxtypes == "") then
set maxtypes=`sed -n -e '/^#define[ ]*TT_MAXTYPES/s/#define[ ]*TT_MAXTYPES[ ]*//p' < $1 | sed -e 's/\/\*.*\*\/[ ]*//g' `
endif
#
# If we can't generate database.h correctly, nothing is going to compile.
#
if ($maxtypes == "") then
echo "Bad sed script in scripts/makedbh: Cannot generate database/database.h!"
exit
endif
# Find derived values from bits per word
# Note that bits-per-word should be determined from the compiler, but
# 32 bits per word has always been hardwired into magic.
#
set bpw = 32
# @ wordmask=$bpw - 1
# set wordshift=`echo "c=l($bpw); d=l(2); scale=0; c/d" | bc -l`
# @ maskwords=$maxtypes + $bpw - 1
# @ maskwords/=$bpw
@ maskwords=$maxtypes + $bpw - 1
@ maskwords/=$bpw
# Generate the main part of the database.h file from database.h.in
cat $1 > $2
# Generate a list of integers from 0 to the value of "maskwords" - 1
set count=""
@ maskwords--
while (${maskwords} >= 0)
set count=`echo ${count} ${maskwords}`
@ maskwords--
end
# Definitions
echo "#define TTMaskZero(m) ( \" >> $2
foreach i (${count})
echo -n " (m)->tt_words[$i] = 0" >> $2
if ($i == 0) then
echo ")" >> $2
echo "" >> $2
else
echo ", \" >> $2
endif
end
echo "#define TTMaskIsZero(m) ( \" >> $2
foreach i (${count})
echo -n " (m)->tt_words[$i] == 0" >> $2
if ($i == 0) then
echo ")" >> $2
echo "" >> $2
else
echo " && \" >> $2
endif
end
echo "#define TTMaskEqual(m, n) ( \" >> $2
foreach i (${count})
echo -n " (m)->tt_words[$i] == (n)->tt_words[$i]" >> $2
if ($i == 0) then
echo ")" >> $2
echo "" >> $2
else
echo " && \" >> $2
endif
end
echo "#define TTMaskIntersect(m, n) ( \" >> $2
foreach i (${count})
echo -n " ((m)->tt_words[$i] & (n)->tt_words[$i])" >> $2
if ($i == 0) then
echo ")" >> $2
echo "" >> $2
else
echo " || \" >> $2
endif
end
echo "#define TTMaskCom(m) ( \" >> $2
foreach i (${count})
echo -n " ((m)->tt_words[$i] = ~(m)->tt_words[$i])" >> $2
if ($i == 0) then
echo ")" >> $2
echo "" >> $2
else
echo ", \" >> $2
endif
end
echo "#define TTMaskCom2(m, n) ( \" >> $2
foreach i (${count})
echo -n " ((m)->tt_words[$i] = ~(n)->tt_words[$i])" >> $2
if ($i == 0) then
echo ")" >> $2
echo "" >> $2
else
echo ", \" >> $2
endif
end
echo "#define TTMaskSetMask(m, n) ( \" >> $2
foreach i (${count})
echo -n " ((m)->tt_words[$i] |= (n)->tt_words[$i])" >> $2
if ($i == 0) then
echo ")" >> $2
echo "" >> $2
else
echo ", \" >> $2
endif
end
echo "#define TTMaskSetMask3(m, n, o) ( \" >> $2
foreach i (${count})
echo -n " ((m)->tt_words[$i] |= (n)->tt_words[$i] | (o)->tt_words[$i])" \
>> $2
if ($i == 0) then
echo ")" >> $2
echo "" >> $2
else
echo ", \" >> $2
endif
end
echo "#define TTMaskAndMask(m, n) ( \" >> $2
foreach i (${count})
echo -n " ((m)->tt_words[$i] &= (n)->tt_words[$i])" >> $2
if ($i == 0) then
echo ")" >> $2
echo "" >> $2
else
echo ", \" >> $2
endif
end
echo "#define TTMaskAndMask3(m, n, o) ( \" >> $2
foreach i (${count})
echo -n " ((m)->tt_words[$i] = (n)->tt_words[$i] & (o)->tt_words[$i])" \
>> $2
if ($i == 0) then
echo ")" >> $2
echo "" >> $2
else
echo ", \" >> $2
endif
end
echo "#define TTMaskClearMask(m, n) ( \" >> $2
foreach i (${count})
echo -n " ((m)->tt_words[$i] &= ~(n)->tt_words[$i])" >> $2
if ($i == 0) then
echo ")" >> $2
echo "" >> $2
else
echo ", \" >> $2
endif
end
echo "#define TTMaskClearMask3(m, n, o) ( \" >> $2
foreach i (${count})
echo -n " ((m)->tt_words[$i] = (n)->tt_words[$i] & ~(o)->tt_words[$i])" \
>> $2
if ($i == 0) then
echo ")" >> $2
else
echo ", \" >> $2
endif
end
echo "" >> $2
echo "#endif /* _DATABASE_H */" >> $2
+20 -19
View File
@@ -12,39 +12,40 @@ CLEANS += netgen.sh netgen.tcl netgenexec${EXEEXT}
CFLAGS += -I${NETGENDIR}/base
TCL_FILES = \
$(DESTDIR)${TCLDIR}/tkcon.tcl \
$(DESTDIR)${TCLDIR}/console.tcl \
$(DESTDIR)${TCLDIR}/netgen.tcl
$(DESTDIR)${INSTALL_TCLDIR}/tkcon.tcl \
$(DESTDIR)${INSTALL_TCLDIR}/console.tcl \
$(DESTDIR)${INSTALL_TCLDIR}/netgen.tcl
tcl-main: netgenexec${EXEEXT} netgen.tcl netgen.sh
install-tcl: netgenexec${EXEEXT} $(DESTDIR)${BINDIR}/netgen.sh ${TCL_FILES}
${RM} $(DESTDIR)${TCLDIR}/netgenexec${EXEEXT}
${CP} netgenexec${EXEEXT} $(DESTDIR)${TCLDIR}/netgenexec${EXEEXT}
install-tcl: netgenexec${EXEEXT} $(DESTDIR)${INSTALL_BINDIR}/netgen.sh ${TCL_FILES}
${RM} $(DESTDIR)${INSTALL_TCLDIR}/netgenexec${EXEEXT}
${CP} netgenexec${EXEEXT} $(DESTDIR)${INSTALL_TCLDIR}/netgenexec${EXEEXT}
netgenexec${EXEEXT}: netgenexec.c
${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS_NOSTUB} netgenexec.c \
-o netgenexec${EXEEXT} \
${LDFLAGS} ${LIBS} ${LIB_SPECS_NOSTUB}
${LIB_SPECS_NOSTUB} ${LDFLAGS} ${LIBS} ${GR_LIBS}
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%PY_DIR%${PYDIR}%g' \
-e 's%TCLLIB_DIR%${TCL_LIB_DIR}%g' \
-e 's%WISH_EXE%${WISH_EXE}%g' \
netgen.sh.in > netgen.sh
$(DESTDIR)${TCLDIR}/%: %
${RM} $(DESTDIR)${TCLDIR}/$*
${CP} $* $(DESTDIR)${TCLDIR}/$*
$(DESTDIR)${INSTALL_TCLDIR}/%: %
${RM} $(DESTDIR)${INSTALL_TCLDIR}/$*
${CP} $* $(DESTDIR)${INSTALL_TCLDIR}/$*
$(DESTDIR)${BINDIR}/netgen.sh: netgen.sh
${RM} $(DESTDIR)${BINDIR}/netgen.sh $(DESTDIR)${BINDIR}/netgen
${CP} netgen.sh $(DESTDIR)${BINDIR}/netgen
(cd $(DESTDIR)${BINDIR}; chmod 0755 netgen)
$(DESTDIR)${INSTALL_BINDIR}/netgen.sh: netgen.sh
${RM} $(DESTDIR)${INSTALL_BINDIR}/netgen.sh $(DESTDIR)${INSTALL_BINDIR}/netgen
${CP} netgen.sh $(DESTDIR)${INSTALL_BINDIR}/netgen
(cd $(DESTDIR)${INSTALL_BINDIR}; chmod 0755 netgen)
include ${NETGENDIR}/rules.mak
+8 -2
View File
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
# For installation, put this file (netgen.sh) in a standard executable path.
# Put startup script "netgen.tcl" and shared library "tclnetgen.so"
@@ -14,6 +14,7 @@
TKCON=true
BATCH=
GUI=
NETGEN_WISH=WISH_EXE
export NETGEN_WISH
@@ -29,6 +30,7 @@ for i in "$@" ; do
case $i in
-noc*) TKCON=;;
-bat*) BATCH=true; TKCON=;;
-gui) GUI=true; TKCON=;;
*) arglist="$arglist${arglist:+ }\"${i//\"/\\\"}\"";;
esac
done
@@ -40,7 +42,10 @@ if [ $TKCON ]; then
-slave "package require Tk; set argc $#; set argv [list $arglist]; \
source TCL_DIR/netgen.tcl"
else
# Run the Python LVS manager GUI
elif [ $GUI ]; then
exec PY_DIR/lvs_manager.py $@
#
# Run the stand-in for wish (netgenexec), which acts exactly like "wish"
@@ -49,6 +54,7 @@ else
# capable of sourcing the startup script.
#
else
exec TCL_DIR/netgenexec -- "$@"
fi
+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 [string map {"\\" "\\\\"} [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 [string map {"\\" "\\\\"} [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 [string map {"\\" "\\\\"} [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 [string map {"\\" "\\\\"} [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 [string map {"\\" "\\\\"} [lindex $instance 0]]
set instname0 [string map {"\\" "\\\\"} [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 [string map {"\\" "\\\\"} [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 -list pins "$fnum1 [lindex $endval 0]" \
"$fnum2 [lindex $endval 1]"]
} else {
set result [equate 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
+559 -85
View File
@@ -85,6 +85,7 @@ int _netcmp_compare(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_iterate(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_summary(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_print(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_format(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_run(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_verify(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_automorphs(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
@@ -199,6 +200,9 @@ Command netcmp_cmds[] = {
{"print", _netcmp_print,
"\n "
"print netcomp internal data structure"},
{"format", _netcmp_format,
"<col1_width> <col2_width>\n "
"set width of formatted output"},
{"run", _netcmp_run,
"[converge|resolve]\n "
"converge: run netcomp to completion (convergence)\n "
@@ -497,7 +501,9 @@ CommonParseCell(Tcl_Interp *interp, Tcl_Obj *objv,
fnum = -1;
}
else
filename = Tcl_GetString(fobj);
/* Both file numbers have been provided, so a */
/* filename is not required. */
filename = NULL;
}
else {
filename = NULL;
@@ -696,11 +702,11 @@ _netgen_readnet(ClientData clientData,
{
char *formats[] = {
"automatic", "ext", "extflat", "sim", "ntk", "spice",
"netgen", "actel", "xilinx", NULL
"verilog", "netgen", "actel", "xilinx", NULL
};
enum FormatIdx {
AUTO_IDX, EXT_IDX, EXTFLAT_IDX, SIM_IDX, NTK_IDX,
SPICE_IDX, NETGEN_IDX, ACTEL_IDX, XILINX_IDX
SPICE_IDX, VERILOG_IDX, NETGEN_IDX, ACTEL_IDX, XILINX_IDX
};
struct nlist *tc;
int result, index, filenum = -1;
@@ -769,7 +775,7 @@ _netgen_readnet(ClientData clientData,
if (retstr) savstr = STRDUP(retstr);
// Check if the file is already loaded
// Check if the file is already loaded.
tc = LookupCell(savstr);
if (tc != NULL) {
@@ -801,6 +807,9 @@ _netgen_readnet(ClientData clientData,
case SPICE_IDX:
retstr = ReadSpice(savstr, &filenum);
break;
case VERILOG_IDX:
retstr = ReadVerilog(savstr, &filenum);
break;
case NETGEN_IDX:
retstr = ReadNetgenFile(savstr, &filenum);
break;
@@ -916,11 +925,13 @@ _netgen_writenet(ClientData clientData,
{
char *formats[] = {
"ext", "sim", "ntk", "actel",
"spice", "wombat", "esacap", "netgen", "ccode", "xilinx", NULL
"spice", "verilog", "wombat", "esacap", "netgen",
"ccode", "xilinx", NULL
};
enum FormatIdx {
EXT_IDX, SIM_IDX, NTK_IDX, ACTEL_IDX,
SPICE_IDX, WOMBAT_IDX, ESACAP_IDX, NETGEN_IDX, CCODE_IDX, XILINX_IDX
SPICE_IDX, VERILOG_IDX, WOMBAT_IDX, ESACAP_IDX, NETGEN_IDX,
CCODE_IDX, XILINX_IDX
};
int result, index, filenum;
char *repstr;
@@ -961,6 +972,9 @@ _netgen_writenet(ClientData clientData,
case SPICE_IDX:
SpiceCell(repstr, filenum, "");
break;
case VERILOG_IDX:
VerilogModule(repstr, filenum, "");
break;
case WOMBAT_IDX:
Wombat(repstr,NULL);
break;
@@ -1435,9 +1449,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")) {
@@ -1445,27 +1459,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));
@@ -1481,11 +1509,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;
}
@@ -1526,8 +1556,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]);
@@ -1639,6 +1688,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;
@@ -1919,6 +1975,61 @@ _netgen_printmem(ClientData clientData,
}
#endif
/*------------------------------------------------------*/
/* Function name: _netcmp_format */
/* Syntax: */
/* netgen::format [col1_width [col2_width]] */
/* Formerly: (none) */
/* Results: */
/* Side Effects: */
/*------------------------------------------------------*/
int
_netcmp_format(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
int col1_width = 41, col2_width = 41;
if (objc > 1) {
if (Tcl_GetIntFromObj(interp, objv[1], &col1_width) != TCL_OK)
return TCL_ERROR;
if (objc > 2) {
if (Tcl_GetIntFromObj(interp, objv[2], &col2_width) != TCL_OK)
return TCL_ERROR;
} else {
/* If only one argument is given, then apply it to both columns */
col2_width = col1_width;
}
if (col1_width <= 0 || col2_width <= 0) {
Tcl_SetResult(interp, "Column width cannot be zero or less\n", NULL);
}
// Default values for left and right columns are 43 and 87
left_col_end = col1_width + 2;
right_col_end = left_col_end + col2_width + 3;
}
else if (objc == 1) {
Tcl_Obj *lobj, *tobj;
col1_width = left_col_end - 2;
col2_width = right_col_end - col1_width - 5;
lobj = Tcl_NewListObj(0, NULL);
tobj = Tcl_NewIntObj(col1_width);
Tcl_ListObjAppendElement(interp, lobj, Tcl_NewIntObj(col1_width));
Tcl_ListObjAppendElement(interp, lobj, Tcl_NewIntObj(col2_width));
Tcl_SetObjResult(interp, lobj);
return TCL_OK;
}
else {
Tcl_WrongNumArgs(interp, 1, objv, "[col1_width [col2_width]]");
return TCL_ERROR;
}
}
/*------------------------------------------------------*/
/* The following code breaks up the NETCOMP() command */
/* from netcmp.c into individual functions w/arguments */
@@ -1937,13 +2048,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)) {
@@ -2022,10 +2144,6 @@ _netcmp_compare(ClientData clientData,
return TCL_ERROR;
}
// WIP!
// CleanupPins(name1, fnum1); // Remove unconnected pins
// CleanupPins(name2, fnum2); // Remove unconnected pins
UniquePins(name1, fnum1); // Check for and remove duplicate pins
UniquePins(name2, fnum2); // Check for and remove duplicate pins
@@ -2035,22 +2153,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().
// WIP!
// CleanupPins(name1, fnum1);
// CleanupPins(name2, fnum2);
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;
@@ -2248,6 +2359,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;
@@ -2266,8 +2390,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:
@@ -2310,7 +2439,7 @@ _netcmp_run(ClientData clientData,
}
if (PropertyErrorDetected) {
Fprintf(stdout, "There were property errors.\n");
PrintPropertyResults();
PrintPropertyResults(dolist);
}
disable_interrupt();
}
@@ -2324,9 +2453,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
@@ -2339,8 +2476,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,
@@ -2371,14 +2523,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)
@@ -2409,9 +2575,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;
@@ -2572,13 +2786,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;
@@ -2734,27 +2958,68 @@ _netcmp_equate(ClientData clientData,
break;
case PINS_IDX:
if (ElementClasses == NULL) {
if (CurrentCell == 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",
name1, name2);
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));
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
return TCL_OK;
}
else if ((tp1->flags & CELL_PLACEHOLDER) ||
(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);
}
if (tp2->flags & CELL_PLACEHOLDER) {
Fprintf(stdout, "Warning: Equate pins: cell %s "
"has no definition, 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.
tp1->flags |= CELL_PLACEHOLDER;
tp2->flags |= CELL_PLACEHOLDER;
}
else {
Fprintf(stdout, "Cell pin lists for %s and %s altered to match.\n",
name1, name2);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
Fprintf(stdout, "Equate pins: cell %s and/or %s "
"has no elements.\n", name1, name2);
/* This is not necessarily an error, so go ahead and match pins. */
}
}
if (ElementClasses == NULL) {
/* This may have 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;
}
// Check for and remove duplicate pins. Normally this is called
// from "compare", but since "equate pins" may be called outside
// of and before "compare", pin uniqueness needs to be ensured.
UniquePins(tp1->name, tp1->file);
UniquePins(tp2->name, tp2->file);
result = MatchPins(tp1, tp2, dolist);
if (result == 2) {
Fprintf(stdout, "Cells have no pins; pin matching not needed.\n");
}
else if (result > 0) {
Fprintf(stdout, "Cell pin lists are equivalent.\n");
}
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_NewIntObj(result));
if (ElementClasses == NULL) {
/* Recover temporarily set global variables (see above) */
Circuit1 = SaveC1;
Circuit2 = SaveC2;
}
break;
@@ -2970,9 +3235,26 @@ _netcmp_equate(ClientData clientData,
/* add --- add new property */
/* remove --- delete existing property */
/* tolerance --- set property tolerance */
/* merge --- set property merge behavior */
/* merge --- (deprecated) */
/* or */
/* netgen::property default */
/* or */
/* netgen::property <device>|<model> <option> */
/* yes|no */
/* Where <option> is one of: */
/* series --- allow/prohibit series combination */
/* parallel --- allow/prohibit parallel combination */
/* or */
/* netgen::property parallel none */
/* --- prohibit parallel combinations by */
/* default (for all devices). */
/* */
/* series|parallel options are: */
/* enable|disable|none|{<key> <combine_option>} */
/* */
/* combine options are: */
/* par|add|par_critical|add_critical */
/* */
/* Formerly: (none) */
/* Results: */
/* Side Effects: */
@@ -2990,10 +3272,12 @@ _netcmp_property(ClientData clientData,
int ival, argstart;
char *options[] = {
"add", "create", "remove", "delete", "tolerance", "merge", NULL
"add", "create", "remove", "delete", "tolerance", "merge", "serial",
"series", "parallel", NULL
};
enum OptionIdx {
ADD_IDX, CREATE_IDX, REMOVE_IDX, DELETE_IDX, TOLERANCE_IDX, MERGE_IDX
ADD_IDX, CREATE_IDX, REMOVE_IDX, DELETE_IDX, TOLERANCE_IDX, MERGE_IDX,
SERIAL_IDX, SERIES_IDX, PARALLEL_IDX
};
int result, index, idx2;
@@ -3004,11 +3288,33 @@ _netcmp_property(ClientData clientData,
INTEGER_IDX, DOUBLE_IDX, VALUE_IDX, STRING_IDX
};
/* Note: "merge" has been deprecated, but kept for backwards compatibility. */
/* It has been replaced by "combineoptions" below, used with "series" and */
/* "parallel". */
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", "series_critical", "serial", "series", 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, SER3_CRIT_IDX, SER2_IDX, SER3_IDX
};
char *combineoptions[] = {
"none", "par", "add", "critical", NULL
};
enum CombineOptionIdx {
COMB_NONE_IDX, COMB_PAR_IDX, COMB_ADD_IDX, COMB_CRITICAL_IDX
};
char *yesno[] = {
"on", "yes", "true", "enable", "allow",
"off", "no", "false", "disable", "prohibit", NULL
};
if (objc < 2) {
@@ -3025,33 +3331,76 @@ _netcmp_property(ClientData clientData,
/* compare source/drain area and perimeter. */
tp = FirstCell();
while (tp != NULL) {
switch (tp->class) {
while (tp != NULL) {
switch (tp->class) {
case CLASS_NMOS: case CLASS_PMOS: case CLASS_FET3:
case CLASS_NMOS4: case CLASS_PMOS4: case CLASS_FET4:
case CLASS_FET:
PropertyMerge(tp->name, tp->file, "w", MERGE_ADD_CRIT);
PropertyMerge(tp->name, tp->file, "w", MERGE_P_ADD | MERGE_P_CRIT,
MERGE_ALL_MASK);
PropertyDelete(tp->name, tp->file, "as");
PropertyDelete(tp->name, tp->file, "ad");
PropertyDelete(tp->name, tp->file, "ps");
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_P_PAR | MERGE_S_CRIT, MERGE_ALL_MASK);
PropertyMerge(tp->name, tp->file, "l",
MERGE_S_ADD | MERGE_P_CRIT, MERGE_ALL_MASK);
PropertyMerge(tp->name, tp->file, "value",
MERGE_S_ADD | MERGE_P_PAR, MERGE_ALL_MASK);
tp->flags |= COMB_SERIES;
break;
case CLASS_CAP: case CLASS_ECAP: case CLASS_CAP3:
// NOTE: No attempt to combine area, width, or length;
// only value.
PropertyMerge(tp->name, tp->file, "value", MERGE_ADD_CRIT);
/* NOTE: No attempt to modify perimeter, length, or width */
PropertyMerge(tp->name, tp->file, "area",
MERGE_P_ADD | MERGE_S_PAR, MERGE_ALL_MASK);
PropertyMerge(tp->name, tp->file, "value",
MERGE_P_ADD | MERGE_S_PAR, MERGE_ALL_MASK);
tp->flags |= COMB_SERIES;
break;
case CLASS_INDUCTOR:
PropertyMerge(tp->name, tp->file, "value", MERGE_PAR_CRIT);
PropertyMerge(tp->name, tp->file, "value",
MERGE_S_ADD | MERGE_P_PAR, MERGE_ALL_MASK);
tp->flags |= COMB_SERIES;
break;
}
tp = NextCell();
}
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",
NULL);
return TCL_ERROR;
}
return TCL_OK;
}
else if ((objc == 3) && ((!strcmp(Tcl_GetString(objv[1]), "series")) ||
(!strcmp(Tcl_GetString(objv[1]), "serial")))) {
if (!strcmp(Tcl_GetString(objv[2]), "none")) {
SetSeriesCombine(FALSE);
}
else if (!strcmp(Tcl_GetString(objv[2]), "all")) {
SetSeriesCombine(TRUE);
}
else {
Tcl_SetResult(interp, "Bad option, should be property series none|all",
NULL);
return TCL_ERROR;
}
return TCL_OK;
}
result = CommonParseCell(interp, objv[1], &tp, &fnum);
if (result != TCL_OK) return result;
@@ -3101,6 +3450,113 @@ _netcmp_property(ClientData clientData,
argstart = 3;
switch (index) {
case SERIAL_IDX:
case SERIES_IDX:
case PARALLEL_IDX:
if (objc == 3) {
if (index == SERIAL_IDX || index == SERIES_IDX) {
tobj1 = Tcl_NewBooleanObj((tp->flags & COMB_SERIES) ? 1 : 0);
Tcl_SetObjResult(interp, tobj1);
return TCL_OK;
}
else {
tobj1 = Tcl_NewBooleanObj((tp->flags & COMB_NO_PARALLEL) ? 0 : 1);
Tcl_SetObjResult(interp, tobj1);
return TCL_OK;
}
}
else if (objc < 4) {
Tcl_WrongNumArgs(interp, 2, objv, "series|parallel enable|disable");
return TCL_ERROR;
}
for (i = 3; i < objc; i++) {
// Each value must be a list of two, or a yes/no answer.
if (Tcl_GetIndexFromObj(interp, objv[i],
(CONST84 char **)yesno,
"combine", 0, &idx2) == TCL_OK) {
if (idx2 <= 4) { /* true, enable, etc. */
if (index == SERIAL_IDX || index == SERIES_IDX)
tp->flags |= COMB_SERIES;
else
tp->flags &= ~COMB_NO_PARALLEL;
}
else { /* false, disable, etc. */
if (index == SERIAL_IDX || index == SERIES_IDX)
tp->flags &= ~COMB_SERIES;
else
tp->flags |= COMB_NO_PARALLEL;
}
continue;
}
result = Tcl_ListObjLength(interp, objv[i], &llen);
if ((result != TCL_OK) || (llen != 2)) {
Tcl_SetResult(interp, "Not a {key merge_type} pair list.",
NULL);
}
else {
int mergeval = MERGE_NONE;
int mergemask = MERGE_NONE;
result = Tcl_ListObjIndex(interp, objv[i], 0, &tobj1);
if (result != TCL_OK) return result;
result = Tcl_ListObjIndex(interp, objv[i], 1, &tobj2);
if (result != TCL_OK) return result;
result = Tcl_GetIndexFromObj(interp, tobj2,
(CONST84 char **)combineoptions,
"combine_type", 0, &idx2);
if (result != TCL_OK) return result;
if (index == SERIAL_IDX || index == SERIES_IDX) {
mergemask = MERGE_S_MASK;
switch (idx2) {
case COMB_NONE_IDX:
mergeval &= ~(MERGE_S_MASK);
tp->flags &= ~COMB_SERIES;
break;
case COMB_PAR_IDX:
mergeval = MERGE_S_PAR;
tp->flags |= COMB_SERIES;
break;
case COMB_ADD_IDX:
mergeval |= MERGE_S_ADD;
tp->flags |= COMB_SERIES;
break;
case COMB_CRITICAL_IDX:
mergeval |= MERGE_S_CRIT;
tp->flags |= COMB_SERIES;
break;
}
}
else { /* index == PARALLEL_IDX */
mergemask = MERGE_P_MASK;
switch (idx2) {
case COMB_NONE_IDX:
mergeval &= ~(MERGE_P_MASK);
tp->flags |= COMB_NO_PARALLEL;
break;
case COMB_PAR_IDX:
mergeval |= MERGE_P_PAR;
tp->flags &= ~COMB_NO_PARALLEL;
break;
case COMB_ADD_IDX:
mergeval |= MERGE_P_ADD;
tp->flags &= ~COMB_NO_PARALLEL;
break;
case COMB_CRITICAL_IDX:
mergeval |= MERGE_P_CRIT;
tp->flags &= ~COMB_NO_PARALLEL;
break;
}
}
PropertyMerge(tp->name, fnum, Tcl_GetString(tobj1), mergeval,
mergemask);
}
}
break;
case ADD_IDX:
case CREATE_IDX:
@@ -3269,6 +3725,11 @@ _netcmp_property(ClientData clientData,
break;
case MERGE_IDX:
// NOTE: This command option is deprecated, kept for backwards
// compatibility, with updated flag values. This command format
// is unable to specify a property as being a critical property
// for merging both in series and in parallel.
if (objc == 3) {
Tcl_WrongNumArgs(interp, 1, objv, "{property_key merge_type} ...");
return TCL_ERROR;
@@ -3298,19 +3759,32 @@ _netcmp_property(ClientData clientData,
mergeval = MERGE_NONE;
break;
case ADD_ONLY_IDX:
mergeval = MERGE_ADD;
mergeval = MERGE_P_ADD;
break;
case ADD_CRIT_IDX:
mergeval = MERGE_ADD_CRIT;
mergeval = MERGE_P_ADD | MERGE_P_XCRIT;
break;
case PAR_ONLY_IDX:
mergeval = MERGE_PAR;
case PAR2_ONLY_IDX:
mergeval = MERGE_P_PAR;
break;
case PAR_CRIT_IDX:
mergeval = MERGE_PAR_CRIT;
case PAR2_CRIT_IDX:
mergeval = MERGE_P_PAR | MERGE_P_XCRIT;
break;
case SER_CRIT_IDX:
case SER2_CRIT_IDX:
case SER3_CRIT_IDX:
mergeval = MERGE_S_ADD | MERGE_S_XCRIT;
break;
case SER_IDX:
case SER2_IDX:
case SER3_IDX:
mergeval = MERGE_S_ADD;
break;
}
PropertyMerge(tp->name, fnum, Tcl_GetString(tobj1), mergeval);
PropertyMerge(tp->name, fnum, Tcl_GetString(tobj1), mergeval,
MERGE_ALL_MASK);
}
}
break;
@@ -3415,8 +3889,8 @@ _netcmp_permute(ClientData clientData,
if (PermuteForget(tp->name, fnum, NULL, NULL))
Fprintf(stdout, "No permutations on circuit %s\n", tp->name);
else
Fprintf(stderr, "Unable to reset model %s pin permutation %s, %s.\n",
tp->name, pin1, pin2);
Fprintf(stderr, "Unable to reset model %s pin permutations.\n",
tp->name);
}
return TCL_OK;
}
@@ -3814,7 +4288,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;
+10 -10
View File
@@ -741,9 +741,9 @@ proc ::tkcon::EvalCmd {w cmd} {
set tag [UniqueTag $w]
$w insert output $res [list stderr $tag] \n stderr
$w tag bind $tag <Enter> \
[list $w tag configure $tag -under 1]
[list $w tag configure $tag -underline 1]
$w tag bind $tag <Leave> \
[list $w tag configure $tag -under 0]
[list $w tag configure $tag -underline 0]
$w tag bind $tag <ButtonRelease-1> \
"if {!\[info exists tkPriv(mouseMoved)\] || !\$tkPriv(mouseMoved)} \
{[list edit -attach [Attach] -type error -- $PRIV(errorInfo)]}"
@@ -2472,8 +2472,8 @@ proc ::tkcon::ErrorHighlight w {
set tag [UniqueTag $w]
$w tag add $tag $start+${c0}c $start+1c+${c1}c
$w tag configure $tag -foreground $COLOR(stdout)
$w tag bind $tag <Enter> [list $w tag configure $tag -under 1]
$w tag bind $tag <Leave> [list $w tag configure $tag -under 0]
$w tag bind $tag <Enter> [list $w tag configure $tag -underline 1]
$w tag bind $tag <Leave> [list $w tag configure $tag -underline 0]
$w tag bind $tag <ButtonRelease-1> "if {!\$tkPriv(mouseMoved)} \
{[list edit -attach $app -type proc -find $what -- $cmd]}"
}
@@ -2501,8 +2501,8 @@ proc ::tkcon::ErrorHighlight w {
set tag [UniqueTag $w]
$w tag add $tag $ix+1c $start
$w tag configure $tag -foreground $COLOR(proc)
$w tag bind $tag <Enter> [list $w tag configure $tag -under 1]
$w tag bind $tag <Leave> [list $w tag configure $tag -under 0]
$w tag bind $tag <Enter> [list $w tag configure $tag -underline 1]
$w tag bind $tag <Leave> [list $w tag configure $tag -underline 0]
$w tag bind $tag <ButtonRelease-1> "if {!\$tkPriv(mouseMoved)} \
{[list edit -attach $app -type proc -- $cmd]}"
}
@@ -2954,14 +2954,14 @@ proc edit {args} {
##
set text $w.text
set m [menu [::tkcon::MenuButton $menu Edit edit]]
$m add command -label "Cut" -under 2 \
$m add command -label "Cut" -underline 2 \
-command [list tk_textCut $text]
$m add command -label "Copy" -under 0 \
$m add command -label "Copy" -underline 0 \
-command [list tk_textCopy $text]
$m add command -label "Paste" -under 0 \
$m add command -label "Paste" -underline 0 \
-command [list tk_textPaste $text]
$m add separator
$m add command -label "Find" -under 0 \
$m add command -label "Find" -underline 0 \
-command [list ::tkcon::FindBox $text]
## Send To Menu
+4405
View File
File diff suppressed because it is too large Load Diff