예제 #1
0
  def test_1_Trans(self):

    a = pya.Trans()
    b = pya.Trans( pya.Trans.M135, pya.Point( 17, 5 ))
    c = pya.Trans( 3, True, pya.Point( 17, 5 ))
    d = pya.Trans( pya.Point( 17, 5 ))
    e = pya.Trans( pya.Trans.M135 )
    e2 = pya.Trans.from_dtrans( pya.DTrans.M135 )
    f = pya.Trans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 )) )

    self.assertEqual( str(a), "r0 0,0" )
    self.assertEqual( str(pya.Trans.from_s(str(a))), str(a) )
    self.assertEqual( str(b), "m135 17,5" )
    self.assertEqual( str(c), "m135 17,5" )
    self.assertEqual( str(d), "r0 17,5" )
    self.assertEqual( str(e), "m135 0,0" )
    self.assertEqual( str(e2), "m135 0,0" )
    self.assertEqual( str(f), "m135 17,5" )
    self.assertEqual( str(pya.Trans.from_s(str(f))), str(f) )

    self.assertEqual( str(b.trans( pya.Point( 1, 0 ))), "17,4" )

    self.assertEqual( a == b, False )
    self.assertEqual( a == a, True )
    self.assertEqual( a != b, True )
    self.assertEqual( a != a, False )
    self.assertEqual( (d * e) == b, True )
    self.assertEqual( (e * d) == b, False )

    i = c.inverted()

    self.assertEqual( str(i), "m135 5,17" )
    self.assertEqual( (i * b) == a, True )
    self.assertEqual( (b * i) == a, True )

    c = pya.Trans( 3, True, pya.Point( 17, 5 ))
    self.assertEqual( str(c), "m135 17,5" )
    c.disp = pya.Point(1, 7)
    self.assertEqual( str(c), "m135 1,7" )
    c.angle = 1
    self.assertEqual( str(c), "m45 1,7" )
    c.rot = 3
    self.assertEqual( str(c), "r270 1,7" )
    c.mirror = True
    self.assertEqual( str(c), "m135 1,7" )

    self.assertEqual( str(e.trans( pya.Edge(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
    self.assertEqual( str(( e * pya.Edge(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
    self.assertEqual( str(e.trans( pya.Box(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
    self.assertEqual( str(( e * pya.Box(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
    self.assertEqual( str(e.trans( pya.Text("text", pya.Vector(0, 1)) )), "('text',m135 -1,0)" )
    self.assertEqual( str(( e * pya.Text("text", pya.Vector(0, 1)) )), "('text',m135 -1,0)" )
    self.assertEqual( str(e.trans( pya.Polygon( [ pya.Point(0, 1), pya.Point(2, -3), pya.Point(4, 5) ] ) )), "(-5,-4;-1,0;3,-2)" )
    self.assertEqual( str(( e * pya.Polygon( [ pya.Point(0, 1), pya.Point(2, -3), pya.Point(4, 5) ] ) )), "(-5,-4;-1,0;3,-2)" )
    self.assertEqual( str(e.trans( pya.Path( [ pya.Point(0, 1), pya.Point(2, 3) ], 10 ) )), "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false" )
    self.assertEqual( str(( e * pya.Path( [ pya.Point(0, 1), pya.Point(2, 3) ], 10 ) )), "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false" )
예제 #2
0
    def test_4_Trans(self):

        a = pya.Trans()
        m = pya.CplxTrans(a, 1.1)
        da = pya.DTrans()
        dm = pya.DCplxTrans(da, 1.1)

        self.assertEqual(str(m), "r0 *1.1 0,0")
        self.assertEqual(str(pya.DCplxTrans.from_s(str(m))), str(m))
        self.assertEqual(str(m.trans(pya.Point(5, -7))), "5.5,-7.7")

        im = pya.ICplxTrans(a, 0.5)
        im_old = im.dup()

        self.assertEqual(str(im), "r0 *0.5 0,0")
        self.assertEqual(str(pya.ICplxTrans.from_s(str(im))), str(im))
        self.assertEqual(str(im.trans(pya.Point(5, -7))), "3,-4")

        im = pya.ICplxTrans(m)
        self.assertEqual(str(im), "r0 *1.1 0,0")
        self.assertEqual(str(im.trans(pya.Point(5, -7))), "6,-8")

        im = pya.ICplxTrans(dm)
        self.assertEqual(str(im), "r0 *1.1 0,0")
        self.assertEqual(str(im.trans(pya.Point(5, -7))), "6,-8")

        im.assign(im_old)
        self.assertEqual(str(im), "r0 *0.5 0,0")
        self.assertEqual(str(im.trans(pya.Point(5, -7))), "3,-4")

        self.assertEqual(str(pya.ICplxTrans(5, -7)), "r0 *1 5,-7")

        self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, 5, -7)),
                         "r180 *1.5 5,-7")
        self.assertEqual(
            str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, pya.Point(5, -7))),
            "r180 *1.5 5,-7")
        self.assertEqual(
            str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, pya.Vector(5, -7))),
            "r180 *1.5 5,-7")
        self.assertEqual(
            str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, pya.DVector(5, -7))),
            "r180 *1.5 5,-7")
        self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5)),
                         "r180 *1.5 0,0")

        c = pya.ICplxTrans.from_dtrans(pya.DCplxTrans.M135)
        self.assertEqual(str(c), "m135 *1 0,0")
        c = pya.ICplxTrans.from_trans(pya.CplxTrans.M135)
        self.assertEqual(str(c), "m135 *1 0,0")
예제 #3
0
def main():
    # [1] Create TOP layout (LAYOUT_TOP, where layouts A,B,... would be merged)
    import pya
    LAYOUT_TOP = pya.Layout()
    CELL_TOP = LAYOUT_TOP.create_cell("CELL_TOP")
    # Create layer #'s
    import layer_numbers as lm
    l_TP_outline = LAYOUT_TOP.layer(lm.layer_num_TP_outline,
                                    0)  # One touch pixel Outline
    # Insert box outline for unit touch pixel dimensions
    CELL_TOP.shapes(l_TP_outline).insert(pya.Box(0, 0, p * 14, p * 14))

    for ind, (k, v) in enumerate(gds_files_d.items()):
        print("\nProcessing ... : ", ind, k, v)  # 0 | 2_unit_1_7.gds | [1, 7]
        # [2] Loop over each GDS, create separate layouts (LAYOUT_A, LAYOUT_B, ...), and read each GDS files
        LAYOUT_A = pya.Layout()
        LAYOUT_A.read(k)

        # From GDS name, get # of repeats in x-y dir
        [nx, ny] = get_nx_ny(k)
        #[nx, ny] = [1, 1]

        # [3] In TOP layout, create (empty) target cells (ta, tb, ...)
        CELL_TA = LAYOUT_TOP.create_cell("CELL_" + str(v[0]) + "_" +
                                         str(v[1]))  # CELL_2_7, CELL_14_5, ...
        CELL_TOP.insert(
            pya.CellInstArray(
                CELL_TA.cell_index(),
                pya.Trans(pya.Point(p * (v[1] - 1), p * (v[0] - 1))),
                pya.Vector(p, 0), pya.Vector(0, p), nx, ny))
        # v : value (e.g. [1, 7]) --> x = v[1], y = v[0]

        # [4] From [3], copy over the layouts from A to TA, using ta.move_tree(layout_A.top_cell() )
        CELL_TA.move_tree(LAYOUT_A.top_cell())

    # Export GDS
    LAYOUT_TOP.write("3_PANEL_wip.gds")
예제 #4
0
    def test_3_DTrans(self):

        c = pya.DCplxTrans(5.0, -7.0)
        self.assertEqual(str(c), "r0 *1 5,-7")

        c = pya.DCplxTrans(pya.DCplxTrans.M135)
        self.assertEqual(str(c), "m135 *1 0,0")
        self.assertEqual(c.is_unity(), False)
        self.assertEqual(c.is_ortho(), True)
        self.assertEqual(c.is_mag(), False)
        self.assertEqual(c.is_mirror(), True)
        self.assertEqual(c.rot(), pya.DCplxTrans.M135.rot())
        self.assertEqual(str(c.s_trans()), "m135 0,0")
        self.assertAlmostEqual(c.angle, 270)

        self.assertEqual(str(c.trans(pya.DEdge(0, 1, 2, 3))), "(-3,-2;-1,0)")
        self.assertEqual(str((c * pya.DEdge(0, 1, 2, 3))), "(-3,-2;-1,0)")
        self.assertEqual(str(c.trans(pya.DBox(0, 1, 2, 3))), "(-3,-2;-1,0)")
        self.assertEqual(str((c * pya.DBox(0, 1, 2, 3))), "(-3,-2;-1,0)")
        self.assertEqual(str(c.trans(pya.DText("text", pya.DVector(0, 1)))),
                         "('text',m135 -1,0)")
        self.assertEqual(str((c * pya.DText("text", pya.DVector(0, 1)))),
                         "('text',m135 -1,0)")
        self.assertEqual(
            str(
                c.trans(
                    pya.DPolygon([
                        pya.DPoint(0, 1),
                        pya.DPoint(2, -3),
                        pya.DPoint(4, 5)
                    ]))), "(-5,-4;-1,0;3,-2)")
        self.assertEqual(
            str((c * pya.DPolygon(
                [pya.DPoint(0, 1),
                 pya.DPoint(2, -3),
                 pya.DPoint(4, 5)]))), "(-5,-4;-1,0;3,-2)")
        self.assertEqual(
            str(c.trans(pya.DPath(
                [pya.DPoint(0, 1), pya.DPoint(2, 3)], 10))),
            "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false")
        self.assertEqual(
            str((c * pya.DPath(
                [pya.DPoint(0, 1), pya.DPoint(2, 3)], 10))),
            "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false")

        c = pya.DCplxTrans.from_itrans(pya.CplxTrans.M135)
        self.assertEqual(str(c), "m135 *1 0,0")

        c = pya.DCplxTrans(1.5)
        self.assertEqual(str(c), "r0 *1.5 0,0")
        self.assertEqual(c.is_unity(), False)
        self.assertEqual(c.is_ortho(), True)
        self.assertEqual(c.is_mag(), True)
        self.assertEqual(c.is_mirror(), False)
        self.assertEqual(c.rot(), pya.DCplxTrans.R0.rot())
        self.assertEqual(str(c.s_trans()), "r0 0,0")
        self.assertAlmostEqual(c.angle, 0)

        c = pya.DCplxTrans(0.75, 45, True, 2.5, -12.5)
        self.assertEqual(str(c), "m22.5 *0.75 2.5,-12.5")
        c = pya.DCplxTrans(0.75, 45, True, pya.DPoint(2.5, -12.5))
        self.assertEqual(str(c), "m22.5 *0.75 2.5,-12.5")
        self.assertEqual(c.is_unity(), False)
        self.assertEqual(c.is_ortho(), False)
        self.assertEqual(c.is_mag(), True)
        self.assertEqual(c.rot(), pya.DCplxTrans.M0.rot())
        self.assertEqual(str(c.s_trans()), "m0 2.5,-12.5")
        self.assertAlmostEqual(c.angle, 45)

        self.assertEqual(str(c.ctrans(5)), "3.75")
        self.assertEqual(str(c.trans(pya.DPoint(12, 16))),
                         "17.3492424049,-14.6213203436")

        self.assertEqual(str(pya.DCplxTrans()), "r0 *1 0,0")
        self.assertEqual(pya.DCplxTrans().is_unity(), True)
        self.assertEqual((c * c.inverted()).is_unity(), True)

        c.mirror = False
        self.assertEqual(str(c), "r45 *0.75 2.5,-12.5")
        c.mag = 1.5
        self.assertEqual(str(c), "r45 *1.5 2.5,-12.5")
        c.disp = pya.DPoint(-1.0, 5.5)
        self.assertEqual(str(c), "r45 *1.5 -1,5.5")
        self.assertEqual(c.mag, 1.5)
        c.angle = 60
        self.assertEqual(str(c), "r60 *1.5 -1,5.5")
        self.assertEqual(("%g" % c.angle), "60")

        # Constructor variations
        self.assertEqual(str(pya.ICplxTrans()), "r0 *1 0,0")
        self.assertEqual(str(pya.ICplxTrans(1.5)), "r0 *1.5 0,0")
        self.assertEqual(str(pya.ICplxTrans(pya.Trans(1, False, 10, 20), 1.5)),
                         "r90 *1.5 10,20")
        self.assertEqual(str(pya.ICplxTrans(pya.Trans(1, False, 10, 20))),
                         "r90 *1 10,20")
        self.assertEqual(
            str(pya.ICplxTrans(1.5, 80, True, pya.Vector(100, 200))),
            "m40 *1.5 100,200")
        self.assertEqual(str(pya.ICplxTrans(1.5, 80, True, 100, 200)),
                         "m40 *1.5 100,200")
        self.assertEqual(str(pya.ICplxTrans(pya.Vector(100, 200))),
                         "r0 *1 100,200")
        self.assertEqual(str(pya.ICplxTrans(100, 200)), "r0 *1 100,200")
        self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans(100, 200))),
                         "r0 *1 100,200")
        self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5)),
                         "r0 *1.5 150,300")
        self.assertEqual(
            str(
                pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5,
                               pya.Vector(10, 20))), "r0 *1.5 160,320")
        self.assertEqual(
            str(pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5, 10, 20)),
            "r0 *1.5 160,320")

        self.assertEqual(str(pya.DCplxTrans()), "r0 *1 0,0")
        self.assertEqual(str(pya.DCplxTrans(1.5)), "r0 *1.5 0,0")
        self.assertEqual(
            str(pya.DCplxTrans(pya.DTrans(1, False, 0.01, 0.02), 1.5)),
            "r90 *1.5 0.01,0.02")
        self.assertEqual(str(pya.DCplxTrans(pya.DTrans(1, False, 0.01, 0.02))),
                         "r90 *1 0.01,0.02")
        self.assertEqual(
            str(pya.DCplxTrans(1.5, 80, True, pya.DVector(0.1, 0.2))),
            "m40 *1.5 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(1.5, 80, True, 0.1, 0.2)),
                         "m40 *1.5 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(pya.DVector(0.1, 0.2))),
                         "r0 *1 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(0.1, 0.2)), "r0 *1 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2))),
                         "r0 *1 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5)),
                         "r0 *1.5 0.15,0.3")
        self.assertEqual(
            str(
                pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5,
                               pya.DVector(0.01, 0.02))), "r0 *1.5 0.16,0.32")
        self.assertEqual(
            str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5, 0.01, 0.02)),
            "r0 *1.5 0.16,0.32")
예제 #5
0
            current = via_iter.shape().bbox()
            v_x = (current.left - init_loc[0]) // m1_track_pitch
            v_y = (current.bottom - init_loc[1] - m1_enc) // m2_track_pitch
            if not check_via_pitch_pass(v_x,
                                        v_y,
                                        via_mtx,
                                        m1_track_pitch,
                                        m2_track_pitch,
                                        min_via_pitch_y=min_via1_pitch_y):
                via_iter.shape().delete()
                via_mtx[v_y, v_x] = 0
            via_iter.next()
        '''draw sraf forbidden and access region / store via/contact coordinates'''
        l_forbidden = layout.layer(210, 0)
        l_access = layout.layer(230, 0)
        offset_forbidden = pya.Vector(100, 100)
        offset_access = pya.Vector(500, 500)
        via_iter = layout.begin_shapes(cell, l_via1)
        tmp_iter = 0
        while not via_iter.at_end():
            current = via_iter.shape().bbox()
            llp = current.p1
            urp = current.p2
            llp_forbidden = llp - offset_forbidden
            urp_forbidden = urp + offset_forbidden
            cell.shapes(l_forbidden).insert(
                pya.Box(llp_forbidden, urp_forbidden))

            llp_access = llp - offset_access
            urp_access = urp + offset_access
            cell.shapes(l_access).insert(pya.Box(llp_access, urp_access))
예제 #6
0
# Define array of GDS files to read
gds_files = ["0_unit_1x1.gds"]

# Read each GDS files
for each_gds in gds_files:
    KLAYOUT.read(each_gds)

    # Read Top Cell for each GDS file
    for top_cell_read in KLAYOUT.top_cells():
        if (top_cell_read.name !=
                "1_UNIT"):  # Don't insert TOP_CELL("1_UNIT") on itself
            # print ( "Adding " + top_cell_read.name )
            cell_index = top_cell_read.cell_index()
            new_instance = pya.CellInstArray(cell_index,
                                             pya.Trans(pya.Point(0, 0)),
                                             pya.Vector(pitch, 0),
                                             pya.Vector(0, pitch), 3, 3)
            # pya.Trans(pya.Point(0,0)) --> defines the LOCATION at which instance should be placed
            # pya.Vector(pitch, 0) --> defines the PITCH at which instance should repeat
            # 3, 3 --> defines number of repeats
            TOP_CELL.insert(new_instance)

# Create layer #'s
l_3x3_outline = KLAYOUT.layer(3, 0)  # 3x3 Outline

# Draw outline (of 3x3)
TOP_CELL.shapes(l_3x3_outline).insert(pya.Box(0, 0, 3 * pitch, 3 * pitch))

# Export GDS
KLAYOUT.write("1_unit_3x3.gds")
예제 #7
0
    def coerce_parameters_impl(self):
        """Method called by Klayout to update a PCell. For photonic PCells the ports are updated/calculated in the
        parameter of the PCell. And desired movement transformations are performed.

        Because the calculated ports of our own PCell are used by parent cells and are needed before
        `~produce_impl`, we must calculate them twice. First to calculate where our own ports are and then again to
        instantiate the child cells. This is unfortunate but not a big problem, since dataprep and DR-cleaning take
        the majority of computation time.

        :return:
        """
        self.clear_ports()
        instances_and_ports = self.create_param_inst()
        if not instances_and_ports:
            return
        if isnamedtupleinstance(instances_and_ports) or isinstance(
                instances_and_ports, InstanceHolder):
            instances_and_ports = [instances_and_ports]
        id = 0
        insts = []
        for inst_port in instances_and_ports:
            # For each object test if it is a list of InstanceHolders/Port or plain objects and then separate them accordingly
            if isinstance(inst_port, InstanceHolder):
                inst_port.id = id
                id += 1
                insts.append(inst_port)
            elif isnamedtupleinstance(inst_port):
                self.create_port(inst_port.x, inst_port.y, inst_port.rot,
                                 inst_port.length)
            elif type(inst_port) is list:
                for iinst_port in inst_port:
                    if isinstance(iinst_port, InstanceHolder):
                        iinst_port.id = id
                        id += 1
                        insts.append(iinst_port)
                    elif isnamedtupleinstance(iinst_port):
                        self.create_port(iinst_port.x, iinst_port.y,
                                         iinst_port.rot, iinst_port.length)
            else:
                raise ValueError(
                    "Expected type instances (InstanceHolder), ports (PortCreation) or a list of instances,ports. Instead got {}"
                    .format(str(type(inst_port))))
        self.transformations = ''
        # If child instances have requested movements in their InstanceHolder move them now
        for i, inst in enumerate(insts):
            if self.transformations:
                self.transformations += ';'
            if inst.movement:
                # Adjust movement for database
                inst.movement.disp = pya.Vector(
                    inst.movement.disp.x / self.layout.dbu,
                    inst.movement.disp.y / self.layout.dbu)
                self.transformations += inst.movement.to_s()
                inst.placed = True
            elif inst.connection:
                self.transformations += pya.ICplxTrans.R0.to_s()
            else:
                self.transformations += pya.ICplxTrans.R0.to_s()
                inst.placed = True
        # If the InstanceHolder object has a Port to connect to, calculate the transformation
        all_placed = False
        count = 0
        while (not all_placed) and count < 50:
            all_placed = True
            count += 1
            for i, inst in enumerate(insts):
                if inst.connection:
                    if not inst.connection.placed:
                        all_placed = False
                        continue
                    retcode = self.connect_port(inst.connection.id,
                                                inst.connection.params_mod[0],
                                                inst.connection_port, inst.id,
                                                inst.params_mod[0],
                                                inst.port_to_connect)
                    if retcode < 0:
                        msg = pya.QMessageBox(
                            pya.Application.instance().main_window())
                        msg.text = 'Port {} of {} cannot be connected to Port {} of {}'.format(
                            inst.port_to_connect,
                            inst.connection.params['cellname'],
                            inst.port_to_connect, inst.params['cellname'])
                        msg.windowTitle = 'ImportError'
                        msg.exec_()
                        return False
                    inst.placed = True
        # Update the transformations and self.portlist with the calculated transformations of the children
        self.calculate_ports(insts)
예제 #8
0
        xpos = xpos + 4 * Xcell_size
        t = pya.Trans(xpos, ypos)
    n += 1

#-----------------------------DECODERS--------------------------

if (n_decoders and decoders25):
    decoder_cell = layout.create_cell("decoder_cell")
    xpos1 = pmos_placement_width * 4
    ypos1 = 0
    xpos2 = -nmos_placement_width * 4
    ypos2 = 0
    num_addr_bus = find_pwr2(num_words, 0)

    for i in range(0, num_addr_bus):
        t1 = pya.Trans(1, False, pya.Vector(xpos1, ypos1))
        t2 = pya.Trans(1, False, pya.Vector(xpos2, ypos2))
        pmos.place(decoder_cell, t1)
        nmos.place(decoder_cell, t2)
        xpos1 = xpos1 + pmos_placement_width * 4
        xpos2 = xpos2 - nmos_placement_width * 4
    # GND Via

    # Vdd Via #MANUAL PLACEMENT!
    xpos1 = pmos_placement_width * 4 + 250
    xpos2 = -nmos_placement_width * 4 + 250
    ypos1 = -nmos_width * 2 - 60
    ypos2 = -nmos_width * 2 - 60

    for i in range(0, num_addr_bus):
        t1 = pya.Trans(1, False, pya.Vector(xpos1, ypos1))