report it after "Failure to read in entire sub-tree". This will
not report every failing cell (since it quits reading after the
first failure) but will avoid the existing issue of printing
nothing and leaving the user with no feedback as to which cell
was the problem.
non-Manhattan geometry is analyzed for resistance extraction.
This patch merely prevents the crash condition. It does not
solve the root of the problem, which is that split tiles can
belong to two different nets, but the tile can hold extraction
information for at most one of those nets.
reduce the amount of redundant painting done by the connectivity
search algorithm, but which was preventing composed types (such
as FET gates) from getting added to a net if one of the composing
types (such as poly) was drawn over the device in an ancestor
cell. Removing the "if" statement does not appear to have any
significant performance impact, so this change is being adopted.
argument. For interactive magic in the Tcl/Tk wrapper, the
"-nowindow" option was appended to the command line. But for
Tcl scripts on the command line, all arguments following the
script name are considered arguments of the script. So the
"-nowindow" argument has to be inserted at the beginning of
the command line as the first argument after "magic".
previously, MASTERSLICE layers would not be added to obstruction
layers made by "-hide". However, an nwell, for example, that
stuck outside of a prBoundary *would* be recorded, which was
inconsistent. Resolved this by allowing MASTERSLICE layers
in the OBS block, but only for layers that are not a substrate
type. NOTE: It may be better to just insist that a MASTERSLICE
layer define an obstruction type in the "lef" section of the
tech file, and treat it like routing obstructions. Alternatively,
one may question whether special obstruction types are needed at
all, as one could simply define an obstruction as a type without
a port label.
contains brackets which are not indicating a cell array. Also
fixed a related issue with the PDK toolkit code, in which the
gencell routines fail if an instance name contains brackets which
are not indicating a cell array.
present. Note, however, this fix breaks the use of "ext2spice
subcircuit descend off" because subcircuits are always descended
into. It's not clear that "subcircuit descend off" worked at all
before, anyway. That still needs fixing.
non-default rule. The code was first failing to identify the via
cut type from the generated via record, and then it was failing
to return to the non-default rule width after the route exits the
via. Both issues have been fixed. Thanks to Sylvain Munaut for
providing a reproducible test case.
new port labels are created for an existing port, then they must
take the existing port number. The code was previously causing
collisions between port numbers on different pins.
lefLayer's "via" record even when the layer might not be a via,
causing potential issues with uninitialized variables. Not sure
if this is related to the bug that started this investigation,
but it was the only thing that looked relevant.
used in a re-entrant manner. Applied to an existing layout,
it will no longer keep generating new instances and ports over
top existing ones. Could use improvement by attempting to
retain the location of a device when the instance changes
device type (such as when a device parameter was changed in
the netlist). However, the current set of changes should
help, whether the re-entrant use is purposeful or accidental.
fails in the bplane code for subcell binning. It is still not
clear why this example causes a failure when the bplane code
has been working for so long. However, simply checking for the
BT_ARRAY bit at one additional point in the code prevents the
crash condition and appears not to have caused any issue with
the database.
a method that failed to work on devices with complex shapes on the
device recognition layer, such as snake-geometry resistors. (2)
The use of contact type "xpc" in the sky130 tech file as its own
contact residue caused the contact tracing in extresist to fail.
I opted to keep the unorthodox contact description in the tech
file and wrote an extension to a routine in extresist to handle
the case.
from Ryan Schmidt, changing regular expression strings in the python
preprocessor to raw string types so that they don't produce warnings
in python 3.12.
name. The instance search routine was not rejecting internal cells,
and so would choose, e.g., a selection cell and reject it because it
was not the edit cell.
The fractional part of the rule distance (modulus after scaling)
does not fit in the unsigned char variable unless it is first
divided by the scalefactor (also requires multiplying up by the same
amount when scaling the other direction). The truncation of the
unsigned char value was causing the minimum area value to be off by
a small amount, causing false negatives (no DRC violation is shown
when metal area is slightly smaller than the minimum allowed).
that resolves issues of excessive tile fracturing during read-in
of GDS (or CIF) polygons and paths that have non-manhattan geometry.
This was particularly noticeable when reading the GF180MCU corner
I/O cell, which ended up being something close to a worst-case
scenario.
missing from a netlist generated by ext2spice with the "extresist"
option enabled. The first had to do with some parts of nets being
given alias names for a net, and the second was caused during
"extresist" and would also result in error messages about devices
missing terminals.
"gds readonly true" mode and when writing a GDS file in full-dump
mode. Reading or writing a file with an incompatible DBU is now
prohibited. This is not a great solution, as it forces the
original file to be rewritten with a different DBU. Preferably
there should be code to scale the units during a dump, but that
needs to be coded.
correctly handle subcircuits that are used before they are
defined, and will determine whether the imported spice does or
does not contain a top level, and either return to the top level
or any top level cell found in the netlist.
client data value as the exit status value (this was not at
all clear from the documentation and required a bit of
experimentation). The fix allows Tcl scripts to exit magic
with a non-zero status by invoking "exit" in Tcl.
depending on the order of extraction devices. Specifically, the
case of a source-drain tied FET was breaking out of a loop when
it should have been breaking out of a double loop.
cell being generated. This statement does not disambiguate the
case where a cell is being ripped verbatim from GDS instead of
being generated from the magic database. This print statement
has been split into two cases, and where a cell is being ripped
verbatim, the name of the file is indicated. This provides better
information to the user.
no way to implement boolean operators on labels, so any "label"
statement in the section can apply only to one magic layer. This
is regularly violated in most (all?) techfiles (due mainly to lack
of explanation and guidance). The addition of the "no-reconnect-
labels" option for cifinput made it worse, as it can cause a label
to be attached to the wrong layer and be stuck that way. Even
without the option, an attachment to a non-connecting type is a
problem; DIFF cannot simultaneously have a connection to both
ndiff and pdiff, so it will be one or the other, and the one not
connected can easily get labels moved to other nets. To avoid
this: (1) removed the "no-reconnect-labels" option, and (2) made
the automatic label reconnection smarter, as well as splitting it
into two different behaviors based on whether a label is being
created or manipulated from the command line (more or less the
original behavior) vs. being read from GDS or LEF. The new rules
assume that labels attached to a GDS type will all map to the
same plane in magic. To avoid excessive error messages from
existing tech files, a warning is issued only if "labels" changes
the plane of the target layer (a realistic solution rather than
the preferred one). Also: Fixed an error that causes a crash on
the "wizard" command "*watch" if the cell being observed is
read-only (see github issue #271).
"unexpected asymmetric device" is printed prematurely, as it
is inside a loop checking over all device entries compatible
with a device type. Also: Flagged an issue with the "label"
keyword in the "cifinput" section of a tech file. The "label"
keyword cannot be used in conjunction with boolean operators.
It can only connect labels on a specific GDS type to one magic
type. Unfortunately, because this was not flagged before as
an error or warning, the incorrect usage has crept into a lot
of tech files. This uncovers an underlying issue that labels
must be allowed to automatically reconnect types, which is
undermined by the "no-reconnect-labels" cifinput option. That
issue will be addressed in an upcoming commit.
to pick up properties from an existing cell and prints an error
message instead. This will likely cause non-default properties
of an instance to be lost if the SPICE import is used in a
re-entrant manner (not exactly a common use-case).
was made to limit the ExtFindRegions() search to one plane per
contact. Fixed this simply by doubling the resistance per via
so that the final result is correct.
bounds should be called whenever an entry is changed and either
the entry window loses focus or the <Enter> key is pressed.
This had ended up disabled when the scrollbar was added to the
dialog window, causing the window hierarchy to change, which
invalidated the regexp used to identify the entry and checkbox
widgets.
cuts per contact area during parasitic resistance extraction.
Previously, the result was divided by the via pitch twice,
resulting in most contact areas being reported as a single
cut.
in DEF read and write. The NONDEFAULT LAYER WIREEXT was assumed
to refer to the default wire extension at segments, when instead
it refers to the wire extension only at vias. The wire
extension at segments is presumably defined by the nondefault
segment (and wire extension at vias remains unimplemented, which
is probably not a big issue because everyone puts the wire
extensions into the via definitions anyway).
all of its time running area searches on zero-area rectangles,
which was causing simple extractions to run hours. Checking for
a zero area rectangle and conditionally skipping the area search
resulted in a massive speed-up in parasitic extraction.
because commands issued during initialization set the DRC status
in a way that causes DRCContinuous() to return immediately.
Also: Implemented a slightly different method when automatically
finding the tech file from the input .mag file that loads a
technology .magicrc file if one exists. If not, just the .tech
file is loaded. This replaces the method of a previous commit
that loads the technology .tcl script. The .magicrc file will
include the .tcl script but does other things as well.
the time the option was implemented), and also implemented (and
documented!) a similar command option "extract stepsize" for
reporting or changing the extraction step size.
out where to find the technology corresponding to a file given on
the command line: (1) Changed the default search location from
/usr/share/pdk to /usr/local/share/pdk, which is the actual default
for open_pdks (can still be overridden by environment variable
PDK_ROOT). (2) Made the PDK name by itself preferable to the PDK
name plus any extension when searching (e.g., "sky130A" is preferred
over "sky130A_backup"). (3) Check the located directory for any
file <tech_name>.tcl and source it if it exists. (4) Run any tag
callbacks on the "tech load" command, which rebuilds the tool icons.
when a label has no area and magic has to go searching for the
label area. The resulting behavior is better but is not really
a substitute for adding ports on the proper layers in the proper
locations for routing connections.
(fixes some issues around python3 on the Mac, python3 conflicting
with that found by /usr/bin/env, and an issue around "make clean"
attempting to rebuild the Depend files).
engine. Rule checks of triggering rules are not subject to
clipping to the clip area. However, they *must* be clipped to
the (larger) overall DRC check area, because no layout is valid
outside of that area. This clipping was missed, allowing
triggering rules to trigger on areas outside the valid layout,
resulting in mysterious false-positive DRC errors. This has
been fixed.
Lookup() is used for command-line parsing in magic and accepts any
unique string that matches a partial keyword. LEF and DEF do not
allow partial keywords, so only LookupFull() is appropriate to use
for LEF and DEF file parsing. This fixes issue #263 from Christian
Haufe.
command for use with "extract path"; the cellname was being cleared
after generating the filename with the extract path, but was being
used afterward, so it needed to be reverted back to the original
value, not just free'd. Otherwise "extresist" will fail to produce
any results.
".res.ext" file from "extresist" after using "extract do local" (and
probably with "extract path" as well). Fixed this, and also made
sure that "extresist" writes the ".res.ext" file to the same location
as ".ext" always, so that handling is consistent throughout the
full R-C extraction process, across the use of "extract", "ext2sim",
"extresist", and "ext2spice".
front of the list during extraction, except that after copying
they're not. Removed the expectation, although that causes the
entire linked list of labels to be parsed and may cause excessive
run-times in pathological situations. Keep an eye out for
unintended consequences.
to catch cases where a device terminal is connected to the global
substrate node even when the terminal is not specifically a substrate
terminal (e.g., diode cathode or bipolar collector) and mark them with
the "substrate is port" flag.
unrelated nets to be captured in the same selection, due to the
use of the label bounding box instead of the label rectangle.
The bounding box is used for display only and should not be used
for connectivity.
warning messages about ports being electrically connected when
those ports have names that match under rules of case-insensitivity,
and the .ext file is being read for the purpose of generating a
SPICE netlist, which is case-insensitive. Also: Corrected a crash
condition when using "extract path <name>" when directory <name>
does not exist.
become truncated, causing the "About" menu item in the console
to generate an error message. Since the tkcon.tcl used in my
other software packages like IRSIM was correct, I just pulled
the RCS string from there, and it seems to be okay now. This
solves github issue #259.
of command logging, which caused the "select cell <instance>" command
option to become invalid; this command option is used by the
parameterized cell generator and makes it impossible to edit the
parameterized cells.
and would keep files open (even though they were not marked as
locked) and not close them, causing an open file descriptor overflow
when too many files are read for the same design.
meaning of the MAG record in GDS files. Most available GDS
documentation is decidedly vague about what MAG means. Most
layout tools seem to interpret a MAG of 1 as corresponding to a
text height of 1um. However, there are a few tools that
interpret it as 1 centimicron, and there's no reason to assume
that any given interpretation is correct. "gds magscale" allows
the scale to be redefined.
the assumption of case insensitivity (e.g., VSS, Vss, and vss)
are kept separate even when writing SPICE netlists, which are
case insensitive. The code fix both avoids flagging these ports
when running ext2spice, and more importantly, allows the use of
"ext2spice short" without these ports ending up separate in the
output netlist.
to be declared for each device model, so that different models can
be specified for different parameter ranges. For example, this
will simplify the definition of the high-sheet-rho poly resistors
and the bipolar transistors in sky130 by removing the need for ID
marker layers; it also allows the correct device model to be
extracted when reading data from GDS that does not contain the
extra (and not foundry-approved) ID markers.
nets to be avoided for running antenna gate and diffusion area
checks when doing "lef write", which is to check if the pin of
the net is flagged with use "power" or use "ground". This avoids
the need to use the (recently added) "lef nocheck" option (although
that still exists as an additional way to control which nets do and
do not get checked).
been broken ever since moving to the Tcl/Tk wrapped version. Added
some new features that allow background commands from the window
handling (like pointer tracking) to be omitted from the log file
via a suspend/resume function. Added a header file and a few
commands at the top of the log file that align the log file contents
with the screen and box state at the start of logging. This makes
a log file which can be "played back" by sourcing it from the magic
console prompt. Per request from Harald Pretl.
list for output, but that the code in ExtRegion.c does not sort a
region's label list to keep ports at the beginning of the list. So
any net with multiple labels may end up with a non-port label as
the name of the node, which eventually becomes the name of the port.
A quick fix keeps these lists sorted.
"drc printrules". Implemented a new "drc" command option called
"drc ignore", which can be used to suppress reporting of specific
rules, for both "drc why" and "drc find". This can help with
finding an error buried among a large number of other errors.
be output twice for scaled devices (such as diodes in the sky130
process). Above and beyond the typo, though, the implementation
of offsets is not very well thought out and needs to be revised.
For one, the +/- notation can be confused with signs in the
parameter expression; that is also fixed in this commit. But
there is currently no way to express both a scale and an offset
for a device parameter.
'+' and '-' in the same way that '*' is currently used for specifying
a parameter scaling. The combination of a scale and offset for the
same parameter has not (yet) been implemented.
with "extract do local" now being equivalent to "extract path .".
This allows extraction files to be put in a subdirectory and not
clog up the current working directory. Also: Fixed some behavior
around the use of "ext2spice -p <path>" so that it (1) works, and
(2) is compatible with the new "extract path". Since the ext2spice
and ext2sim commands are effectively independent of the primary
extraction, the "-p" option is needed to correspond to the use of
"extract path". Hopefully this is seen as only a minor inconvenience.
to create a list of net names to ignore for antenna gate and
diffusion area checks. This allows the nets not to have to be
selected in their entirity but selected by chunk only. This
reduces the time to write LEF on a large layout back to approximately
what it was before the change to include the hidden area from "-hide"
in the antenna area checks. Plus, it greatly reduces the time to
generate LEF for large layouts when not using the "-hide" option.
perimeter are not initialized, and if a terminal perimeter/area
calculation is missed (which is happening on devices with terminals
in planes other than the plane of the identifying type), then the
perimeter/area of a previously handled device will get output.
(2) Corrected an error with "flatten -inplace" in which the command
fails to deal with instance arrays.
NaN results for devices which are not FETs (specifically, devices
that are declared using "msubckt" but are not FETs, although there
may have been a related issue with non-FET devices not getting the
correct M count), due to the device having zero measured width or
length. NOTE: This may need more investigation. If a subcircuit
device's method of merging cannot be understood, then such devices
should never extract with "merge aggressive", and should always
merge conservatively if and only if all parameters match.
when reading .ext files with "equiv" statements in them. The
generation of "equiv" statements was expanded recently, making it
more likely for this issue to show up. There may be devices in
a file that have a terminal node pointing to the node that gets
removed, and these must be updated to point to the node that
remains after merging. This requires a full loop over all
devices and so could have a potentially large impact; but in
general there are not many equiv statements (implying multiple
different labels attached to the same node) and so it is unlikely
that there would be a noticeable performance hit in practice.
gate and diffusion area on each pin is done before erasing parts
of the cell that are to be hidden by obstruction layers. That
preserves the antenna information even when "-hide" is used. This
corrects the issue raised by Kareem Farid in the github issue
tracker #236.
"space" is considered part of the substrate, then the check for
planes to search should exclude "space" from the type mask
first. Otherwise, all planes get searched, not just the substrate.
Also: The same routine can falsely flag a device terminal as
substrate if a split tile is marked as the device's region. This
was also fixed.
previous behavior that had inadvertently been changed. In recent
versions, "load <absolute_path> -dereference" would incorrectly
apply the dereferencing to <absolute_path> rather than just its
subcells. Cleaned up the code around DBCellRead() in the process,
so everything is more straightforward (although probably more
could be done in that regard).
of the cell. This will greatly help in diagnosing issues when
reading cells from multiple locations including cwd, relative
paths, PDK libraries, and the search path. Also: Reworked
the timestamp update message so that it prints all at once at
the end of processing, not printing output for every cell
processed as it is being processed. That prevents output from
the file read routine from getting interleaved with the
timestamp processing output.
labels that are not connected to their declared layers. It's the
latter type that need additional processing in ExtSubtree.
Limiting this processing significantly cuts down on processing
time when there are many labels in a layout, as happens with the
"def read -labels" command option.
can result in negative resistors due to integer overflow. In all
cases, the target was floating-point and it was only necessary to
recast everything to float first.
causing the SI suffix not to be the expected one. Adjusted the
bounds where each SI suffix is used to keep output in the range of
0.1 to 100, although the boundary is very subjective. Made a
correction to the extresist code to scan through all device records
for a tile type. However, (1) there are cases being missed, and (2)
this should not be necessary since all device types should be able
to be known exactly from the contents of the .sim file. Needs more
work.
window in the toolkit, which was to the "tkwait" command, which
waits for a change in state. What was intended was to wait for
a change in state to visible only; once visible, the "tkwait"
command should not invoked or else the process will block.
to "safer" strncpy() calls to prevent string buffer overflow.
Also: Reimplemented the loop in the GDS write routine that counts
ports and then outputs them in order. It was possible to hang
magic for a long time by giving a port a very, very large index
number. The new implementation uses qsort() to sort the ports
by index, which is obviously much more efficient for the worst
case (and efficient enough for all normal cases).
dereferencing, and making the behavior of "load" on the command
line (i.e., loading a cell from a file) the same as the
behavior of loading a cell as a result of expanding an unloaded
instance. In both cases, if "load -dereference" is used, and
a cell does not exist in any search path but does exist in the
original location, without dereferencing, then the cell will be
loaded from the original location. Also: Corrected an error
that has existed since adding the capability to read compressed
files, which causes magic to crash when attempting to run the
"crash recover" command (because that routine was mixing
compressed and regular file stream calls).
inside a halo area. The previous implementation used a linear
accounting of error to determine the amount of shielding, but
since the shielding is nonlinear, this is a poor approximation
and regularly overestimates the shielding and leads to negative
capacitances. The corrected method makes many more calls to
the atan() function and the performance impact for extraction
will need to be evaluated.
ground node name (which is static) gets put on the node list and
is improperly deallocated. Corrected by simply allocating the
string for the default substrate node instead of using the static
string.
that aren't actually handled by the "lef write" command. The three
mentions are "LEFsource", "LEFuse", and "LEFshape", all of which
refer to names of pin properties, not macro properties. These
mentions were probably left over from early work.
(truly) missing a terminal (such as a MOSCAP made with a gate
extending into but not crossing a diffusion region). Added the
most requested GUI feature, which is a vertical scrollbar on the
parameterized device window (could be improved by maximizing
window height without exceeding display height).