VIA

class ipkiss3.all.VIA

Place a via and change trace template at a certain point along the route.

Parameters:
xy: Sequence, Symbol

XY-coordinate through which the route should go.

direction_in: DIRECTION

Direction from which the route comes into the control point (i3.NORTH, i3.EAST, i3.SOUTH, i3.WEST). If not specified, the routing algorithms will use heuristics to provide a guess.

direction_out: DIRECTION

Direction at which the route goes out of the control point (i3.NORTH, i3.EAST, i3.SOUTH, i3.WEST). If not specified, the routing algorithms will use heuristics to provide a guess.

trace_template: TraceTemplate, None

New trace template to use, starting from the current control point.

layout: PCell, LayoutView, _Element, Sequence[_Element], None

Via (reference) elements or PCell to insert at the control point’s location.

relative_to: str, Sequence, None

Reference to an instance, port, or a coordinate, relative to which this control point is defined. This cannot be combined with a symbolic xy. See Symbols for more information.

Examples

First to define VIA_M1_M2_ARRAY which is used for layout property of i3.VIA

import si_fab.all as pdk
import ipkiss3.all as i3

class VIA_M1_M2_ARRAY(i3.PCell):
    box_size = i3.Size2Property(default=(10, 10))
    via_pitch = i3.Size2Property(
        default=i3.TECH.BONDPAD.VIA_PITCH, doc="2D pitch (center-to-center) of the vias"
    )
    via = i3.ChildCellProperty(doc="Via used")

    def _default_via(self):
        return pdk.VIA_M1_M2()

    class Layout(i3.LayoutView):
        def _generate_elements(self, elems):
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.M1, box_size=self.box_size)
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.M2, box_size=self.box_size)
            return elems

        def _generate_instances(self, insts):
            periods_x = int(self.box_size[0] / self.via_pitch[0]) - 1
            periods_y = int(self.box_size[1] / self.via_pitch[1]) - 1

            insts += i3.ARef(
                reference=self.via,
                origin=(
                    -(periods_x - 1) * self.via_pitch[0] / 2.0,
                    -(periods_y - 1) * self.via_pitch[1] / 2.0,
                ),
                period=self.via_pitch,
                n_o_periods=(periods_x, periods_y),
            )
            return insts

VIA_M1_M2_ARRAY().Layout().visualize()
../../../../_images/ipkiss3-all-VIA-1.png
# define direction_in and direction_out of VIA
bp = pdk.BondPad()
via_array = VIA_M1_M2_ARRAY()
tt_m2 = pdk.M2WireTemplate()

circuit = i3.Circuit(
    insts={"pad1": bp, "pad2": bp},
    specs=[
        i3.Place("pad1", (0, 0)),
        i3.Place("pad2", (200, 200)),
        i3.ConnectElectrical(
            "pad1:m1",
            "pad2:m2",
            start_angle=45,
            start_straight=50,
            end_angle=180,
            control_points=[
                i3.VIA(
                    (100, 100),
                    direction_in=i3.SOUTH,
                    direction_out=i3.NORTH,
                    trace_template=tt_m2,
                    layout=via_array,
                ),
            ],
        ),
    ],
)
circuit.get_default_view(i3.LayoutView).visualize()
../../../../_images/ipkiss3-all-VIA-2.png
bp = pdk.BondPad()
via_array = VIA_M1_M2_ARRAY()
M1_wire_tpl = pdk.M1WireTemplate().Layout(width=10)
M2_wire_tpl = pdk.M2WireTemplate().Layout(width=10)

circuit = i3.Circuit(
    insts={"pad1": bp, "pad2": bp},
    specs=[
        i3.Place("pad1", (0, 0)),
        i3.Place("pad2", (200, 200)),
        i3.ConnectElectrical(
            "pad1:m1",
            "pad2:m2",
            start_angle=45,
            start_straight=50,
            end_angle=180,
            trace_template=M1_wire_tpl,  # Override start trace template
            control_points=[
                i3.VIA(
                    (100, 100),
                    direction_in=i3.SOUTH,
                    direction_out=i3.NORTH,
                    trace_template=M2_wire_tpl,  # Set end trace template
                    layout=via_array,
                ),
            ],
        ),
    ],
)
circuit.get_default_view(i3.LayoutView).visualize()
../../../../_images/ipkiss3-all-VIA-3.png
# Use multiple vias in Electrical route
bp = pdk.BondPad()
via_array = VIA_M1_M2_ARRAY()
M1_wire_tpl = pdk.M1WireTemplate().Layout(width=10)
M2_wire_tpl = pdk.M2WireTemplate().Layout(width=10)

circuit = i3.Circuit(
    insts={"pad1": bp, "pad2": bp},
    specs=[
        i3.Place("pad1", (0, 0)),
        i3.Place("pad2", (200, 200)),
        i3.ConnectElectrical(
            "pad1:m1",
            "pad2:m2",
            start_angle=90,
            end_angle=180,
            trace_template=M1_wire_tpl,
            control_points=[
                i3.VIA(
                    (50, 70),
                    direction_in=i3.WEST,
                    direction_out=i3.EAST,
                    trace_template=M2_wire_tpl,
                    layout=via_array,
                ),
                i3.VIA(
                    (100, 70),
                    direction_in=i3.WEST,
                    direction_out=i3.NORTH,
                    trace_template=M1_wire_tpl,
                    layout=via_array,
                ),
                i3.VIA(
                    (100, 120),
                    direction_in=i3.SOUTH,
                    direction_out=i3.NORTH,
                    trace_template=M2_wire_tpl,
                    layout=via_array,
                ),

            ],
        ),
    ],
)
circuit.get_default_view(i3.LayoutView).visualize()
../../../../_images/ipkiss3-all-VIA-4.png