Source code for reasitic.resistance.dc

"""DC resistance per polygon / shape.

Per-segment formula:

.. math::

    R = \\rho_\\text{sh} \\cdot \\frac{L}{W}

where ``ρ_sh`` is the metal layer's sheet resistance (Ω/sq), ``L`` is
the segment length and ``W`` its width. The total DC resistance of
a shape is the sum over its segments. Vias contribute the
per-via-cell resistance from the tech file.

This mirrors the simplest path through ``compute_dc_resistance_per_polygon``
(``asitic_kernel.c:267``) — that decompiled function additionally
splits the sum into "primary" / "secondary" buckets at a tap point and
computes microstrip capacitances; the bare resistance summation is
all we need for the standard ``Res`` REPL command.
"""

from __future__ import annotations

from reasitic.geometry import Segment, Shape
from reasitic.tech import Tech


[docs] def segment_dc_resistance(segment: Segment, tech: Tech) -> float: """Return the DC resistance of one segment in Ω. Resolves the metal layer from ``tech`` to read its sheet resistance. Zero-length or zero-width segments contribute 0. """ if segment.length <= 0 or segment.width <= 0: return 0.0 if segment.metal < 0 or segment.metal >= len(tech.metals): # Out-of-range metal index: treat as zero contribution rather # than silently using rsh from a wrong layer. return 0.0 rsh = tech.metals[segment.metal].rsh return rsh * segment.length / segment.width
[docs] def compute_dc_resistance(shape: Shape, tech: Tech) -> float: """Return the total DC resistance of ``shape`` in Ω. Sums :func:`segment_dc_resistance` over every segment, treating the spiral as a single series chain (which is correct for the standard one-port self-resistance reported by ASITIC's ``Res`` command). """ return sum(segment_dc_resistance(s, tech) for s in shape.segments())