コード例 #1
0
def test_quirky_cases():
    pc = ParamContainer()

    pc.add_param(PCellParameter(name="orange", default=1))

    # Don't try to set any value here
    with pytest.raises(
        TypeError, match="'ParamContainer' object does not support item assignment"
    ):
        pc["orange"] = 2
コード例 #2
0
class DCPad(OrientedCell):
    """A standard DC pad.

    Ports: el0
    """

    params = ParamContainer(pad_width, pad_height, port_width, layer_metal,
                            layer_opening)

    def draw(self, cell):
        layout = cell.layout()

        origin, ex, ey = self.origin_ex_ey()
        cp = self.params

        def make_shape_from_dpolygon(dpoly, resize_dx, dbu, layer):
            dpoly.resize(resize_dx, dbu)
            # if resize_dx > dbu:
            #     dpoly.round_corners(resize_dx, 100)
            insert_shape(cell, layer, dpoly)
            return dpoly

        def make_pad(origin, pad_width, pad_height, ex, ey):
            pad_square = rectangle(origin, pad_width, pad_height, ex, ey)
            make_shape_from_dpolygon(pad_square, 0, layout.dbu, cp.layer_metal)
            make_shape_from_dpolygon(pad_square, -2.5, layout.dbu,
                                     cp.layer_opening)

        make_pad(origin + cp.pad_height * ey / 2, cp.pad_width, cp.pad_height,
                 ex, ey)

        port = Port("el0", origin + cp.port_width * ey / 2, -ey, cp.port_width,
                    "el_dc")

        return cell, {"el0": port}
コード例 #3
0
class PositionMixin(PCell):
    """ handles the angle_ex parameter """

    params = ParamContainer(
        PCellParameter(
            name="angle_ex",
            type=TypeDouble,
            description="Placement Angle (0, 90, ..)",
            default=0,
        ))

    def origin_ex_ey(self, multiple_of_90=False):  # pylint: disable=unused-argument
        EX = kdb.DVector(1, 0)
        cp = self.get_cell_params()
        origin = kdb.DPoint(0, 0)
        # if 'angle_ex' not in cp.__dict__:
        #     cp.angle_ex = 0
        if multiple_of_90:
            if cp.angle_ex % 90 != 0:
                raise RuntimeError("Specify an angle multiple of 90 degrees")

        from math import pi

        ex = rotate(EX, cp.angle_ex * pi / 180)
        ey = rotate90(ex)
        return origin, ex, ey
コード例 #4
0
class OrientedCell(PCell):
    """A standard cell that has the following parameters:
    - origin: Point
    - ex: unit vector of x axis
    - ey: unit vector of y axis
    """

    params = ParamContainer(origin, ex, ey)

    def origin_ex_ey(self):
        origin = DPoint(self.params["origin"])
        ex = DVector(self.params.ex)
        ey = DVector(self.params.ey)
        return origin, ex, ey
コード例 #5
0
class DCPadArray(DCPadArray):
    params = ParamContainer(
        PCellParameter(
            name="layer_metal",
            type=TypeLayer,
            description="Metal Layer",
            default=EBeam.layers["M1"],
        ),
        PCellParameter(
            name="layer_opening",
            type=TypeLayer,
            description="Open Layer",
            default=EBeam.layers["13_MLopen"],
        ),
    )
コード例 #6
0
class DCPadArray(DCPad):
    params = ParamContainer(pad_array_count, pad_array_pitch)

    def draw(self, cell):
        cp = self.params
        origin, ex, _ = self.origin_ex_ey()

        ports = dict()

        for i in range(cp.pad_array_count):
            dcpad = DCPad(name=f"pad_{i}", params=cp)
            dc_ports = dcpad.place_cell(cell, origin + cp.pad_array_pitch * i * ex)
            ports[f"el_{i}"] = dc_ports["el0"].rename(f"el_{i}")
            # self.add_port(dc_ports["el0"].rename(f"el_{i}"))

        return cell, ports
コード例 #7
0
class Waveguide_heater(PDKCell):
    params = ParamContainer(
        define_param("mh_length",
                     TypeInt,
                     "Heated waveguide length",
                     default=100,
                     unit="um"),
        define_param("mh_width",
                     TypeDouble,
                     "Heater width",
                     default=5,
                     unit="um"),
        define_param("w_contacts",
                     TypeDouble,
                     "Contact width",
                     default=10,
                     unit="um"),
    )

    def draw(self, cell):
        layout = cell.layout()

        cp = self.get_cell_params()
        lay = self.get_layers(layout)
        origin, ex, ey = self.origin_ex_ey()

        w_mh = cp.mh_width
        length = cp.mh_length
        w_contacts = cp.w_contacts

        input_port_position = origin - length / 2 * ex
        output_port_postion = origin + length / 2 * ex
        x_off = length / 2 - w_contacts / 2
        y_off = w_mh / 2 + w_contacts / 2

        input_contact_position = origin - x_off * ex + y_off * ey
        output_contact_position = origin + x_off * ex + y_off * ey

        # draw metal heater
        layout_waveguide(cell, lay.M_Heater,
                         [input_port_position, output_port_postion], w_mh)

        # draw metal contacts

        # Left contacts
        contact_points = [
            origin - x_off * ex + (y_off - w_contacts / 2) * ey,
            origin - x_off * ex + (y_off + w_contacts / 2) * ey,
        ]

        layout_waveguide(cell, lay.M_Heater, contact_points, w_contacts)
        layout_waveguide(cell, lay.ML, contact_points, w_contacts)

        # Right contacts
        contact_points = [
            origin + x_off * ex + (y_off - w_contacts / 2) * ey,
            origin + x_off * ex + (y_off + w_contacts / 2) * ey,
        ]
        layout_waveguide(cell, lay.M_Heater, contact_points, w_contacts)
        layout_waveguide(cell, lay.ML, contact_points, w_contacts)

        ports = [
            Port("el_contact_1", input_contact_position, ey, w_contacts),
            Port("el_contact_2", output_contact_position, ey, w_contacts),
        ]

        return cell, {port.name: port for port in ports}
コード例 #8
0
class MZI_Broadband_DC(Broadband_DC_te1550, YBranch_te1550, Waveguide_heater):
    params = ParamContainer(
        define_param("MZI_height",
                     TypeDouble,
                     "interferometer_height of MZI",
                     default=20),
        define_param("waveguide_length_MZI",
                     TypeDouble,
                     "waveguide_length_MZI",
                     default=100),
        define_param("layout_ports", TypeBoolean, "Layout Pins?",
                     default=True),
        define_param("wg_width", TypeInt, "Waveguide width ", default=0.5),
    )

    def draw(self, cell):
        layout = cell.layout()

        cp = self.get_cell_params()
        lay = self.get_layers(layout)
        origin, ex, ey = self.origin_ex_ey()

        YBranch_te1550_Cell_0, YBranch_te1550_Ports_0 = YBranch_te1550(
            "Broadband_DC", params={
                "angle_ex": cp.angle_ex
            }).new_cell(layout)
        YBranch_te1550_Ports_0 = place_cell(cell, YBranch_te1550_Cell_0,
                                            YBranch_te1550_Ports_0, origin)

        Broadband_DC_Cell, Broadband_DC_Ports = Broadband_DC_te1550(
            "Broadband_DC", cp).new_cell(layout)
        Broadband_DC_Ports = place_cell(
            cell,
            Broadband_DC_Cell,
            Broadband_DC_Ports,
            origin + (cp.waveguide_length_MZI + 100) * ex,
        )

        top_arm_left = (YBranch_te1550_Ports_0["opt2"].position + 25 * ex +
                        cp.MZI_height / 2 * ey)
        top_arm_right = top_arm_left + cp.waveguide_length_MZI * ex
        layout_waveguide(cell, lay.Si, [top_arm_left, top_arm_right], 0.5)

        Heater_1_MZI_Cell, Heater_1_MZI_Ports = Waveguide_heater(
            "waveguide heater",
            params={
                "wg_length": cp.waveguide_length_MZI,
                "angle_ex": cp.angle_ex
            },
        ).new_cell(layout)
        Heater_1_MZI_Ports = place_cell(
            cell,
            Heater_1_MZI_Cell,
            Heater_1_MZI_Ports,
            YBranch_te1550_Ports_0["opt2"].position + 25 * ex +
            cp.MZI_height / 2 * ey + cp.waveguide_length_MZI / 2 * ex,
        )

        bottom_arm_left = (YBranch_te1550_Ports_0["opt3"].position + 25 * ex -
                           cp.MZI_height / 2 * ey)
        bottom_arm_right = bottom_arm_left + cp.waveguide_length_MZI * ex
        layout_waveguide(cell, lay.Si, [bottom_arm_left, bottom_arm_right],
                         0.5)

        from zeropdk.layout.geometry import bezier_optimal

        def layout_mzi_curve(P0, P1):
            curve = bezier_optimal(P0, P1, cp.angle_ex, cp.angle_ex)
            return layout_waveguide(cell,
                                    lay.Si,
                                    curve,
                                    cp.wg_width,
                                    smooth=True)

        layout_mzi_curve(YBranch_te1550_Ports_0["opt2"].position, top_arm_left)
        layout_mzi_curve(YBranch_te1550_Ports_0["opt3"].position,
                         bottom_arm_left)

        layout_mzi_curve(top_arm_right, Broadband_DC_Ports["opt1"].position)
        layout_mzi_curve(bottom_arm_right, Broadband_DC_Ports["opt2"].position)

        ports = []

        ports.append(YBranch_te1550_Ports_0["opt1"].rename("opt_in"))
        ports.append(Broadband_DC_Ports["opt3"].rename("opt_out_1"))
        ports.append(Broadband_DC_Ports["opt4"].rename("opt_out_2"))
        ports.extend(Heater_1_MZI_Ports.values())

        if cp.layout_ports:
            for port in ports:
                port.draw(cell, lay.PinRec)
            insert_shape(cell, lay.DevRec, cell.bbox())

        return cell, {port.name: port for port in ports}
コード例 #9
0
ファイル: test_pcell_basic.py プロジェクト: mustafacc/zeropdk
class PadArray(Pad):
    params = ParamContainer(pad_array_count)
コード例 #10
0
ファイル: test_pcell_basic.py プロジェクト: mustafacc/zeropdk
class Pad(PCell):
    params = ParamContainer(pad_size)
コード例 #11
0
class EBeamLayersMixin(PCell):
    """ Abstract class with more concise layer handling

    """

    params = ParamContainer(
        define_param("silayer",
                     TypeLayer,
                     "Si (1/0)",
                     default=TECHLAYERS["Si"],
                     layertype='Si',
                     zmin=0,
                     zmax=0.22),
        define_param("sislab",
                     TypeLayer,
                     "Si slab (2/0)",
                     default=TECHLAYERS["Si slab"],
                     layertype='Si',
                     zmin=0,
                     zmax=0.09),
        define_param(
            "31_Si_p6nm",
            TypeLayer,
            "'31_Si_p6nm' (31/0)",
            default=TECHLAYERS["31_Si_p6nm"],
        ),
        define_param("textl",
                     TypeLayer,
                     "Text (10/0)",
                     default=TECHLAYERS["Text"]),
        define_param("si_n",
                     TypeLayer,
                     "'Si N' (20/0)",
                     default=TECHLAYERS["Si N"],
                     layertype='doping',
                     dopinglevel=-5E17),
        define_param("si_npp",
                     TypeLayer,
                     "'Si N++' (24/0)",
                     default=TECHLAYERS["Si N++"],
                     layertype='doping',
                     dopinglevel=-1E20),
        define_param("si_p",
                     TypeLayer,
                     "'Si P' (22/0)",
                     default=TECHLAYERS["Si P"],
                     layertype='doping',
                     dopinglevel=5E17),
        define_param("si_ppp",
                     TypeLayer,
                     "'Si P++' (26/0)",
                     default=TECHLAYERS["Si P++"],
                     layertype='doping',
                     dopinglevel=1E20),
        define_param("SEM",
                     TypeLayer,
                     "SEM (200/0)",
                     default=TECHLAYERS["SEM"]),
        define_param("M1", TypeLayer, "M1 (41/0)", default=TECHLAYERS["M1"]),
        define_param("ML",
                     TypeLayer,
                     "'12_M2' (12/0)",
                     default=TECHLAYERS["12_M2"]),
        define_param("ML_Open",
                     TypeLayer,
                     "'13_MLopen' (13/0)",
                     default=TECHLAYERS["13_MLopen"]),
        define_param("VC",
                     TypeLayer,
                     "VC (40/0)",
                     default=TECHLAYERS["VC"],
                     layertype='contact'),
        define_param("M_Heater",
                     TypeLayer,
                     "'M Heater' (47/0)",
                     default=TECHLAYERS["M Heater"]),
        define_param("devrec",
                     TypeLayer,
                     "DevRec (68/0)",
                     default=TECHLAYERS["DevRec"]),
        define_param("pinrec",
                     TypeLayer,
                     "PinRec (1/10)",
                     default=TECHLAYERS["PinRec"]),
        define_param("FbrTgt",
                     TypeLayer,
                     "FbrTgt (81/0)",
                     default=TECHLAYERS["FbrTgt"]),
        define_param("Lumerical",
                     TypeLayer,
                     "Lumerical (733/0)",
                     default=TECHLAYERS["Lumerical"]),
        define_param("sim_crossSection",
                     TypeLayer,
                     "Simulation cross section (1000/0)",
                     default=TECHLAYERS["sim_crossSection"],
                     layertype='sim',
                     zmin=-0.75,
                     zmax=1),
    )

    def get_layers(self, layout):
        """ Instantiates layers into layout and returns a convenient objectview.

            Use with `lay = self.get_layers(layout); lay.Si`

        """
        cp = self.get_cell_params()
        # breakpoint()

        lay = objectview({})
        lay.Si = layout.layer(cp.silayer)
        lay.slab = layout.layer(cp.sislab)
        lay.SiN = layout.layer(cp.si_n)
        lay.SiNpp = layout.layer(cp.si_npp)
        lay.SiP = layout.layer(cp.si_p)
        lay.SiPpp = layout.layer(cp.si_ppp)
        lay.M1 = layout.layer(cp.M1)
        lay.ML = layout.layer(cp.ML)
        lay.VC = layout.layer(cp.VC)
        lay.M_Heater = layout.layer(cp.M_Heater)
        lay.PinRec = layout.layer(cp.pinrec)
        lay.DevRec = layout.layer(cp.devrec)
        lay.Text = layout.layer(cp.textl)
        lay.MLOpen = layout.layer(cp.ML_Open)

        return lay
コード例 #12
0
def test_basic_usage():
    pc = ParamContainer()

    pc.add_param(PCellParameter(name="orange", default=1))
    assert pc.orange == 1

    pc.orange = 2
    assert pc.orange == 2
    pc["orange"] == 2  # it is also accessible as a dictionary

    with pytest.raises(TypeError, match="Cannot set 'orange' to 'blah'"):
        pc.orange = "blah"

    with pytest.raises(
        RuntimeError, match="Unkown parameter type, cannot determine from default."
    ):
        pc.add_param(PCellParameter(name="apple"))
    pc.add_param(PCellParameter(name="apple", type=int))

    with pytest.raises(TypeError, match="Cannot set 'apple' to 'one'"):
        pc.apple = "one"

    pc.add_param(PCellParameter(name="strawberry", default=DPoint(0, 0)))
    assert type(pc.strawberry) == DPoint

    with pytest.raises(TypeError, match="Cannot set 'strawberry' to 'test'"):
        pc.strawberry = "test"
コード例 #13
0
class EBeamLayersMixin(PCell):
    """ Abstract class with more concise layer handling

    """

    params = ParamContainer(
        define_param("silayer",
                     TypeLayer,
                     "Si (1/0)",
                     default=TECHLAYERS["Si"]),
        define_param(
            "31_Si_p6nm",
            TypeLayer,
            "'31_Si_p6nm' (31/0)",
            default=TECHLAYERS["31_Si_p6nm"],
        ),
        define_param("textl",
                     TypeLayer,
                     "Text (10/0)",
                     default=TECHLAYERS["Text"]),
        define_param("si_n",
                     TypeLayer,
                     "'Si N' (20/0)",
                     default=TECHLAYERS["Si N"]),
        define_param("si_npp",
                     TypeLayer,
                     "'Si N++' (24/0)",
                     default=TECHLAYERS["Si N++"]),
        define_param("SEM",
                     TypeLayer,
                     "SEM (200/0)",
                     default=TECHLAYERS["SEM"]),
        define_param("M1", TypeLayer, "M1 (41/0)", default=TECHLAYERS["M1"]),
        define_param("ML",
                     TypeLayer,
                     "'12_M2' (12/0)",
                     default=TECHLAYERS["12_M2"]),
        define_param("ML_Open",
                     TypeLayer,
                     "'13_MLopen' (13/0)",
                     default=TECHLAYERS["13_MLopen"]),
        define_param("VC", TypeLayer, "VC (40/0)", default=TECHLAYERS["VC"]),
        define_param("M_Heater",
                     TypeLayer,
                     "'M Heater' (47/0)",
                     default=TECHLAYERS["M Heater"]),
        define_param("devrec",
                     TypeLayer,
                     "DevRec (68/0)",
                     default=TECHLAYERS["DevRec"]),
        define_param("pinrec",
                     TypeLayer,
                     "PinRec (1/10)",
                     default=TECHLAYERS["PinRec"]),
        define_param("FbrTgt",
                     TypeLayer,
                     "FbrTgt (81/0)",
                     default=TECHLAYERS["FbrTgt"]),
        define_param("Lumerical",
                     TypeLayer,
                     "Lumerical (733/0)",
                     default=TECHLAYERS["Lumerical"]),
    )

    def get_layers(self, layout):
        """ Instantiates layers into layout and returns a convenient objectview.

            Use with `lay = self.get_layers(layout); lay.Si`

        """
        cp = self.get_cell_params()
        # breakpoint()

        lay = objectview({})
        lay.Si = layout.layer(cp.silayer)
        lay.SiN = layout.layer(cp.si_n)
        lay.SiNpp = layout.layer(cp.si_npp)
        lay.M1 = layout.layer(cp.M1)
        lay.ML = layout.layer(cp.ML)
        lay.M_Heater = layout.layer(cp.M_Heater)
        lay.PinRec = layout.layer(cp.pinrec)
        lay.DevRec = layout.layer(cp.devrec)
        lay.Text = layout.layer(cp.textl)
        lay.MLOpen = layout.layer(cp.ML_Open)

        return lay