can provide a delta offset such as "l+0.06", indicating that
the extraction model has a length larger than the drawn device.
Previously the value was assumed to be in microns but did not
scale between the .ext file and the SPICE netlist. Corrected
so that it scales like the other parameter values, being
converted to internal units and tracking the internal grid
scale.
"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.
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.
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.
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.
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.
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.
from ext2spice due to "equiv" statements in the .ext file. The
algorithm was not properly keeping the port as the preferred
name of the node, resulting in the non-preferred name being
used instead of the port name in the output. This would happen
only if there was a label on a net that had a different name than
the port name. The error became much more prevalent after changing
the extract behavior to make "extract do aliases" default. Also
fixed a somewhat related minor error in which magic would print an
error message about ports being shorted together on the same kind
of net where both a port and a (different) label were attached to
the net. Since the non-port label is not a preferred name, then
there should be no warning message. The warning is only intended
for cases where two (or more) ports are truly shorted together.
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.
"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).
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.
partitioning of unshielded areas reaching outward from any given
edge, caused by using a boundary value in the 2nd recursion call
that had been modified for the 1st recursion call and so was no
longer valid.
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).
computing the amount of fringe shielding was wrong. This fixes
one of my example cases, but not the other one, so I still need to
pin down a condition that can result in negative capacitance.
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.
(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).
222 from Sean Cross. Corrected a few places where the blanket
conversion "Region"->"ExtRegion" picked up some comment lines
that were unrelated to the structure name.
the "connected other node to. . ." message when terminals of a
device are shorted. A long enough node name, especially one
created by concatenating hierarchy when flattening a cell, can
easily overrun the short 256-byte string buffer. Fixed by
changing strcat() to strncat().
natural sort instead of ASCII-based sorting, so that ports that
are numbered arrays will be indexed properly by count. Also:
Modified the "extresist" handling of substrate to draw the default
substrate type over the entire cell area (less areas of nwell or
other conflicting type). This allows extresist to extract the
entire substrate as a resistive network. The result is ugly and
may warrant some aggressive network simplification, but it should
at least be realistic.
that allocates and deallocates a single layer mask used by the
tech reader. Decided to work around the issue just by allocating
it only once and not releasing it---it's just a few bytes.
tech file "extract" section to work correctly when the offset is
negative. Generally, a negative offset is nonphysical and is just
curve-fitting round-off error, but the existing code was failing
to divide out the factor of 1000 that had been multiplied through
when reading the tech file, resulting in a very wrong offset.
isolate the terminal areas of a device (e.g., source and drain)
and calculate their area and perimeter individually for the
device (in addition to the traditional method of calculating
area and perimeter of each resistance class for the entire node).
Also: Reworked the SPICE syntax output to generate SI values
in the range 1-1000 with the appropriate suffix (e.g., "20u")
instead of defaulting to "u" for lengths and "p" for areas.
This prevents it from producing weird units like "150000u" when
a process definition already includes a scalefactor.
Reworked the "extresist" code to use the device terminal area
and perimeter. This fixes an error in which "extresist" would
lose these values and "ext2spice" with option "extresist on"
would generate a new netlist output with zero terminal areas
and perimeters.
This is diagnostic only and does not change the read-in
behavior.
(2) ext2spice: Corrected an error that had been introduced
into version 8.3.171 that accidentally marks all devices
as visited which causes all source/drain areas and
perimeters to be output as zero.
(3) extract: Sweeping changes to handling of fringe
capacitance. Removed the (recently added) "fringeshieldhalo"
parameter from the tech file. Reworked the fringe
capacitance models based on results from the "capiche"
project (github/RTimothyEdwards/capiche). Fringe shielding
is now done by clipping fringe at the boundary of a
shielding shape, rather than trying to calculate the
amount of shielding (as the "capiche" project proved this
to be equivalent). Values for partial fringing are modeled
by atan(x), which like the sidewall (1/x) curve, extends to
infinity and values are limited by the halo but do not
otherwise depend on the halo. Because of this, the halo can
be made variable and controlled by the user for deciding on
the tradeoff between accuracy and run time. A new command
option "extract halo" was added to allow this control over
the halo distance.
commit to prevent port labels from being copied up from the
flattened cell into the parent, and prefixing the instance
name to text in the instance top level so that there will be
no port or label collisions in the parent cell after flattening
the child cell in place. Also: Changed "extract dolabelcheck"
to be the default setting.
parameters l1 and l2. Provides a way to pass the source or drain
length as a parameter for, for example, an extended FET drain
implemented as a resistor abutting the FET gate. Could potentially
be used as a way to determine source/drain area and perimeter
without resorting to measurements of a shared node.
use of a resistor type as a FET extended drain, allowing the
FET drain node to short across to the other side of the resistor
so that the resistor is absorbed into the FET device. Used with
the GF180MCU process to describe the salicide-block ESD FET types.
library has been read in with the "gds readonly true" option set
because the cell contains information on where in the GDS the
cell is located, but the cell is empty because it was flattened
into the magic view and all of its contents were erased. This can
cause issues with LVS if magic generates an empty cell into the
netlist and the LVS tool tries to compare the cells by name. Also,
this prevents unnecessary .ext files and unnecessary merges to the
substrate of such cells (since all cells have an implied substrate).
respect to calculations around diode-connected diffusion regions.
The diffusion area calculation needed to be fixed to avoid double-
counting contacts, and the value for the ratioDiffA coefficient
needed to be scaled, since it is multiplied by the diffusion area
and therefore has dimensioned units of (1/area^2) and should be
treated like all other dimensioned units in magic.
attempt is made to write an abstract view to GDS. This behavior can
be overridded with the new command option "gds abstract [enable|disable]".
Also: Corrected extraction to allow split tiles to be set as the
reference tile for a node. Previously this was allowed only if the
tile was the first to be searched, but that can cause different tiles to
be marked as the reference depending on where the search starts,
resulting in different names for the same node in .ext files, which is
bad. Also: Modified the LEF annotation to avoid bad entries in the LEF
that would create layers in the layout where none exist.
This commit makes the code (mostly) C99-compatible, enabling to compile
it without the -Wno-error=implicit-function-declaration flag. This
way, Magic becomes usable on arm64 architectures, specifically on Apple
computers with M1/M2 SoC.
tech files which incorrectly parses the syntax using five
parameters. This syntax variant does not get used often, which
is why the error went undetected for a long time.
run free() on a memory location that was never allocated. This
error has no effect on anything, but correcting it prevents magic
from issuing a mysterious warning.
caused by other code that can move the plane of a device to match
the plane of a port. Solved by retaining the original plane of the
node in the extTransRec structure, and using that to determine the
device plane for purposes of calculating perimeters and not double-
counting contacts.
fringe capacitance halo where the default halo distance was set to
zero instead of one and caused divide-by-zero issues; (2) Found
extraction issues where labels picked up from cells flattened
during GDS reading cause the flattened/emptied cells to show up
in the extraction with extra pins that can mess up LVS. Solved
this by removing labels from flattened/emptied cells.
using the newer methods for nearest-edge searching and fringe area
of effect. Removed a same-net check in a routine that removes
capacitances that are redundant due to hierarchical overlaps; these
redundancies must be checked on shapes within the same net. Corrected
(again) an out-of-clip-bounds check.
reading GDS files, caused by an unneeded change to pass both
the "original" filename and the actual filename when handling
compressed files---The original filename is unneeded.
(2) Implemented several new methods for parasitic extraction. The
first is an option offset value to apply to sidewall calculations.
This handles issues where actual wire separation is different
from drawn wire separation, which can be significant for the
1/d calculation of sidewall coupling. The second method is to
use the recently-added fringe halo to compute the coupling of the
fringe capacitance to nearby wires. Prior to this change, all
fringe capacitance was applied to surfaces directly under a wire
edge as if the fringe capacitance did not extend outward from the
edge. Now the capacitance is properly pro-rated for the position
of any overlapped shape inside the fringing field. Finally, the
third method added is a new search algorithm for finding the
nearest shapes along the length of a boundary. This is used for
sidewall coupling and fringe shielding, where the nearest shape
dominates the coupling, and any shapes behind are shielded and
may (to first order) be ignored. Previously, the entire halo
was searched without regard to shapes shielding other shapes
behind, and a recent correction added an ad-hoc search for
blocking shapes that was inefficient and not always correct.
The new method is both efficient and accurate.
to the fringe shielding calculations, which uses very similar code and
suffered the same problem of not being able to recognize when another
shape was between the two edges under consideration. Fixing this
makes the fringe shielding calculations symmetric, as they should be.
computing coupling to shapes that are shielded by other
intervening shapes. This is not a perfect solution but will
properly handle all but a few pathological cases.
which instead of defining a device or subcircuit that exists inside
the cell, instead redefines the cell itself as a device or subcircuit
model that exists in the PDK. This is used where a specific layout
subcell has its own associated device definition in the PDK. Instead
of the "device" property value being the line that gets generated for
a device in the subcells .ext file, the property value should be the
word "primitive" optionally followed by any parameters that need to
be passed to the subcircuit call.
recognized as a valid command when file locking has been disabled as
a compile-time option. The command then generates an error on
"locking enable" but simply ignores the command "locking disable".
substrate shielding types in a subcell inside the interaction area
only. Since the interaction area is clipped by the "cookie cutter"
extraction areas, it could completely miss the shielding. As
revised, any shielding under a subcell will effectively shield the
entire subcell. This could be improved by warning if the subcell
has substrate connections outside of the shield area (as that is
not extractable), but that requires additional processing.
fact that "extract all" does not enumerate cells from bottom up
as I had assumed---The order is roughly bottom-to-top, but cells
re-used in different places in the hierarchy could end up called
before one or more of their own subcells is extracted. Since
this conflicted with the preparation of the substrate in each
extracted subcircuit, I changed the method to enumerate cells so
that it is properly bottom-to-top. Also, methods were added to
"extract" (incremental), "extract cell", and "extract parents"
to ensure that the substrate is prepared on all subcells before
extraction.
extFindNodes() does; consequently, ExtLabelRegions() when called
after ExtFindRegions() may accidentally chain together a substrate
region with whatever was left in this linked list after the
previous call to extFindNodes(), with unpredictable results.
is specified in the extraction section of the techfile, then magic
will compute the effect of a nearby shape partially shielding the
sidewall overlap capacitance, which approaches 100% shielding as
the shapes converge to zero separation. This method prevents
magic from vastly overestimating the fringe capacitance of closely
spaced wires, which was magic's worst problem with parasitic
accuracy. The "fringeshieldhalo" value is the distance at which
the fringe shielding becomes negligible. Typically, it will be
about three times the distance at which half the fringe value is
shielded. It may be necessary at some point to make both the
fringe shielding halo and the sidewall halo values per-type values
(or per-plane, at least). For now, it should suffice to bring
Magic's parasitic extraction back in line with other tools.
not be seen during hierarchical processing, causing the substrate
to get split into several names that may conflict in the netlist.
At issue is the fact that ExtLabelRegions() will not attach a
default substrate label to a default substrate region. This may
need further untangling, as extFindNodes() will set the default
substrate node and is sometimes followed by ExtLabelRegions(),
which will label it. Any place ExtFindRegions() is called, this
could be an issue.
Most of this had to do with the incorrect use of the parent's substrate
name in extHierSubstrate(). After the correction, there still remains
an issue that is caused when a labeled isolated substrate region overlaps
an extraction tile boundary. I believe that this particular error has
existed for some time and is not new, so I am committing these changes.
which had become fouled up due to the changes in the way that the
substrate is defined and handled. Worked through a large torture
test until all types of substrate coupling and overlap shielding
were resolved to be extracted as expected.
a routine that should have been called with a NULL argument, but
instead was called with no argument, making the behavior system-
dependent. Revised the parsing of the "defaultareacap" and
"defaultperimeter" statements in the tech file, such that the short
version of both statements gets automatic handling of the substrate
and isolated substrate areas; this goes back to the recent change
in extraction behavior to redefine the "substrate type" (e.g., pwell)
during extraction as defining isolated substrate areas, and not the
default substrate. The earlier code change dealt with problems
related to extracting nodes and regions, but did not consider how
parasitic capacitance was affected. This commit resolves that issue.
The extSubtree() routine cuts a layout into squares and extracts
each separately, checking for subcell interactions. In each
square it parses all labels looking for unconnected ones. This
section of code not only parses all labels M x N times, but it
then marks interaction areas where there may be none, forcing
additional unnecessary processing. This commit makes the first
quick optimization, which is to change the return value of
DRCFindInteractions() from boolean to integer, allowing it to
return a value indicating that there are no subcells in the
area. This prevents the loop through labels from happening in
cases where there can never be interactions. More to come.
effectively forcing the substrate type (e.g., "pwell") to be defined
as delineating isolated substrate areas only (e.g., pwell in deep nwell
or isosub a.k.a. subcut). It does so by erasing all of the substrate
type out of a cell prior to extraction before redrawing it in the
isolated areas. This avoids issues caused by pwell drawn in separate
unconnected areas of a cell, as these are removed and the area treated
as the default substrate everywhere. Has worked on all layouts tested
so far.
check for abstract views to determine how to handle the substrate
node. Running tests to check if this has any negative impact on
the extraction of abstract views that do not specify substrate
and well types.
traditionally been kept for backwards compatibility. However, the
operation of "ext2spice" and "ext2sim" as separate programs has
become extremely difficult to maintain, and so it has been dropped
in favor of folding both into the program as commands, as was done
a long time ago in the Tcl/Tk version.
the timestamp is updated after reading in CIF or GDS, and managed to
get the timestamp dirty flag to remain clear after reading when
"gds datestamp" is used. This includes a modification of the timestamp
update routine that only updates timestamps on a single file if only a
single file is being written.
file to generate a mask of all the types called out in the section
as being used for parasitic calculations (resistive and capacitive)
and device terminal types. This is supplemented with a list of all
types that are specified in the "connect" and "contact" sections as
connecting to something other than themselves. All remaining types
are considered non-electrical and removed from the list of types
that can be considered electrical nodes. This works a bit better
than the existing method of using "resist <types> None" to specify
non-electrical types, as it is backwardly-compatible to older tech
files. The upshot is that in the worst case, if a type needs to be
extracted as an electrical node but does not satisfy any of the
above criteria, then it should be added to the "resist" list, with
a resistance of 0 if necessary.
time ago by cleaning up excess usage of "equiv" lines in the .ext
file output. The hierarchical extraction code did not distinguish
between node names which were output and those that were not,
requiring a setting "extract do aliases" to force all node aliases
to be output with "equiv" statements. So hierarchical names
might be any alias, whether output or not, and "merge" and "cap"
lines might contain references to nodes that were not output,
causing them to be disconnected nodes. This fix handles the
"extract no aliases" (default) case by flagging node names that
are redundant and not output, and not creating hierarchical names
with them.
node representing the global substrate on cells that are abstract
views. Corrected a typecasting issue in ext2spice.c that throws
a compiler warning. Added another check for a cell being editable
when painting, which is a case that was not covered by the
previous code change to address the same issue.
Print the names of the tile types that are illegally overlapping. This
gives us a better idea of what is wrong, eg:
feedback add "Illegal overlap between obsm2 and m2 (types do not connect)" medium
"defaultareacap" and "defaultperimeter" statements in the technology
file. Now, the parser makes use of the configuration of the
substrate from the "substrate" line to generate a default list of
which types and planes represent the substrate, and which types and
planes represent shielding to the substrate. This solves an issue
with the use of substrate isolation layers (e.g., "isosub" in
sky130A), because its definition and usage created substrate shields
on two planes (well and dwell), while the syntax for "defaultareacap"
and "defaultperimeter" only allow one shielding plane to be defined.
value 1 after finding a substrate connecting type shielded (by deep
nwell, in the example) from the substrate, thus preventing the
search from processing any remaining substrate types. Solved by
changing the return value to zero to keep the search going.
record to the label structure to hold the port number. One major
issue stemming from this was reported in github issue #203 by Anton
Blanchard. This commit fixes that error.
clean up memory after running "ext2spice". There are apparently
still memory leaks somewhere, difficult to diagnose with valgrind,
but this fix removes the most substantial leakage and allows
"ext2spice" to be run continuously, at least for a while.
this limited ports to 16384, which seemed reasonable at the time.
However, the sky130_sram_macro layouts connect power and ground in a
way that when coupled with "extract unique" can generate tens of
thousands of ports and overrun the bit field, showing that automation
can do the unexpected. The solution was to split out the port number
from the label record as its own 32-bit value.
connections through the substrate as the same node, and so will
not force different nodes names on the soft connection to be
unique. This should probably be selectable behavior. However, as
written, the "extract" command will always merge soft connections,
so giving them unique names just causes problems with "extract".
entries for "floating" labels. Otherwise it is possible for the
hierarchical checks to find the label in flattened geometry and
reference it, resulting in merge statements in an .ext file that
reference undeclared nodes, ultimately resulting in extflat
failing to perform the merge, and an incorrect netlist.
to eliminate all redundant names resulting from redundant labels.
Changed the behavior of "goto" so that it will find local names with
slashes, which are the result of using "flatten". A hierarchical
search is done first, as before, but on failure to find a subcell
component, the local cell is searched for the verbatim name.
statements in the .ext file output to those that mark a port as
equivalent to the node name used elsewhere in the file. This
limits unnecessary output of "equiv" statements that can bog down
ext2spice and other commands that use the .ext file contents.
wrong, and it needs revisiting. This is the cause of a number of
negative capacitances appearing in the netlist (even after accounting
for overlap with subcircuits).
(since these are interpreted by IRSIM, the only known program to
parse .sim output)---the "ext2sim alias on" option now just moves
such statements from the ".sim" file to a ".al" file. Corrected the
ResSimMerge() routine to reverse the nodes, so that the devices
belonging to the aliased node are added to the original node, instead
of the other way around. This corrects "missing gate" and "missing SD"
errors that occur due to nodes connected through the substrate.
text formatting. Made one critical correction to ResGetDevice() to
pass the device type; otherwise, devices on different planes (e.g.,
MiM caps) with the same coordinate will always return the device on
the lowest plane, leading to incorrect results and an eventual crash
when the device record is free'd twice.