Beispiel #1
0
 def __radd__(self, other):
     from spira.yevon.gdsii.elem_list import ElementList
     if isinstance(other, list):
         l = ElementList(other)
         l.append(self)
         return l
     elif isinstance(other, __Element__):
         return ElementList([other, self])
     else:
         raise TypeError(
             "Wrong type of argument for addition in __Element__: " +
             str(type(other)))
Beispiel #2
0
    def __and__(self, other):
        el = ElementList()
        for e1 in self.elements:
            for e2 in other.elements:
                # e1 = deepcopy(e1)
                # e2 = deepcopy(e2)
                # shape1 = e1.shape.transform_copy(e1.transformation)
                # shape2 = e2.shape.transform_copy(e2.transformation)
                shape1 = deepcopy(e1.shape).transform(e1.transformation)
                shape2 = deepcopy(e2.shape).transform(e2.transformation)
                # if shape1 != shape2:
                # if e1.shape != e2.shape:
                # if (e1.shape != e2.shape) and (e1.layer == e2.layer):
                # if (e1.shape != e2.shape) and (e1.layer.process == e2.layer.process):
                if (shape1 != shape2) and (e1.layer.process
                                           == e2.layer.process):
                    shapes = shape1 & shape2
                    # print(shape1.points)
                    # print(shape2.points)
                    # print(shapes)
                    # print('')
                    for shape in shapes:
                        el += Polygon(shape=shape, layer=e1.layer)

                    # polygons = e1.intersection(e2)
                    # for p in polygons:
                    #     p.layer.purpose = RDD.PURPOSE.INTERSECTED
                    # for p in polygons:
                    #     el += p
        self.elements = el
        return self
Beispiel #3
0
    def __filter___Cell____(self, item):
        from spira.yevon.utils import clipping
        from spira.yevon.gdsii.cell import Cell

        ports = PortList()
        elems = ElementList()

        for e in item.elements.polygons:
            e.shape = clipping.simplify_points(e.points)
            elems += e

            # points = clipping.simplify_points(e.points)
            # elems += e.copy(shape=points)

            # p = e.__class__(shape=points, layer=e.layer, transformation=e.transformation)
            # elems += e.__class__(shape=points, layer=e.layer, transformation=e.transformation)

        for e in item.elements.sref:
            elems += e
        for e in item.elements.labels:
            elems += e
        for p in item.ports:
            ports += p

        cell = Cell(elements=elems, ports=ports)
        # cell = item.__class__(elements=elems, ports=ports)
        return cell
Beispiel #4
0
 def write_gdsii_mask(self, **kwargs):
     elems = ElementList()
     for pg in self.process_elements:
         for e in pg.elements:
             elems += e
     D = Cell(name=self.name + '_VMODEL', elements=elems)
     D.gdsii_output()
Beispiel #5
0
    def filter_Cell(self, item):
        from copy import deepcopy
        from spira.yevon.gdsii.cell import Cell

        elems = ElementList()
        if self.width is None:
            for p1 in deepcopy(item.elements.polygons):
                if p1.layer.purpose in self.purposes:
                    for edge in p1.edges:
                        shape = ShapeEdge(original_shape=edge.line_shape,
                                          edge_width=edge.width,
                                          edge_type=self.edge_type)
                        elems += edge.copy(shape=shape)
                    elems += p1
        else:
            for p1 in deepcopy(item.elements.polygons):
                if p1.layer.purpose in self.purposes:
                    for edge in p1.edges:
                        shape = ShapeEdge(original_shape=edge.line_shape,
                                          edge_width=self.width,
                                          edge_type=self.edge_type)
                        elems += edge.copy(shape=shape)
                    elems += p1

        cell = Cell(elements=elems)
        return cell
Beispiel #6
0
 def view_derived_overlap_elements(self, **kwargs):
     elems = ElementList()
     for pg in self.derived_overlap_elements:
         for e in pg.elements:
             elems += e
     name = '{}_{}'.format(self.name, 'DERIVED_OVERLAP_ELEMENTS')
     D = Cell(name=name, elements=elems)
     D.gdsii_view()
Beispiel #7
0
 def __or__(self, other):
     if self.layer == other.layer:
         s1 = self.shape.transform_copy(self.transformation)
         s2 = other.shape.transform_copy(other.transformation)
         shapes = s1.__or__(s2)
         elems = [Polygon(shape=s, layer=self.layer) for s in shapes]
         return elems
     return ElementList([self, other])
 def filter_Port(self, item):
     elems = ElementList()
     elems += self._create_label(item)
     if item.purpose.symbol == 'C':
         elems += self._contact_template(item)
     else:
         elems += self._edge_template(item)
         elems += self._create_arrow(item)
     cell = Cell(elements=elems)
     return cell
 def filter_Polygon(self, item):
     elems = ElementList()
     for p in item.ports:
         el = self.filter_Port(p).elements
         # FIXME: We have to use this for PCells.
         elems += el.transform(item.transformation)
         # FIXME: Have to use this for GDS files.
         # elems += el
     cell = Cell(elements=elems)
     return cell
Beispiel #10
0
def reference_metal_blocks(S):
    from copy import deepcopy
    elems = ElementList()
    for layer in RDD.get_physical_layers_by_purpose(purposes=['METAL', 'GND']):
        layer = deepcopy(layer)
        if S.reference.is_layer_in_cell(layer):
            bbox_shape = S.bbox_info.bounding_box()
            layer.purpose = RDD.PURPOSE.BOUNDARY_BOX
            elems += Polygon(shape=bbox_shape, layer=layer)
    return elems
Beispiel #11
0
def get_process_polygons(elements, operation='or'):
    elems = ElementList()
    for process in RDD.VMODEL.PROCESS_FLOW.active_processes:
        for layer in RDD.get_physical_layers_by_process(processes=process):
            LF = LayerFilterAllow(layers=[layer])
            el = LF(elements.polygons)
            if operation == 'or':
                pg = PolygonGroup(elements=el, layer=layer).merge
            elif operation == 'and':
                pg = PolygonGroup(elements=el, layer=layer).intersect
            elems += pg
    return elems
Beispiel #12
0
    def __init__(self,
                 name=None,
                 elements=None,
                 ports=None,
                 library=None,
                 **kwargs):
        super().__init__(**kwargs)

        if name is not None:
            s = '{}_{}'.format(name, Cell._next_uid)
            self.__dict__['__name__'] = s
            Cell.name.__set__(self, s)

        self.uid = Cell._next_uid
        Cell._next_uid += 1

        if library is not None:
            self.library = library
        if elements is not None:
            self.elements = ElementList(elements)
        if ports is not None:
            self.ports = PortList(ports)
Beispiel #13
0
    def gdsii_output_electrical_connection(self):

        elems = ElementList()
        overlap_elems, edges = self.edges
        for e in overlap_elems:
            elems += e
        for edge in edges:
            elems += edge.outside
        for e in self.cell.elements:
            elems += e

        D = Cell(name='_ELECTRICAL_CONNECT', elements=elems)
        D.gdsii_output()
Beispiel #14
0
 def intersect(self):
     elems = ElementList()
     el1 = deepcopy(self.elements)
     el2 = deepcopy(self.elements)
     for i, e1 in enumerate(el1):
         for j, e2 in enumerate(el2):
             if e1.shape != e2.shape:
                 polygons = e1 & e2
                 for p in polygons:
                     p.layer.purpose = RDD.PURPOSE.INTERSECTED
                 for p in polygons:
                     elems += p
     self.elements = elems
     return self
Beispiel #15
0
 def union(self):
     elems = ElementList()
     if len(self.elements) > 1:
         points = []
         for e in self.elements:
             shape = e.shape.transform(e.transformation).snap_to_grid()
             points.append(shape.points)
         merged_points = clipping.boolean(subj=points, clip_type='or')
         for uid, pts in enumerate(merged_points):
             elems += Polygon(shape=pts, layer=self.layer)
     else:
         elems = self.elements
     self.elements = elems
     return self
Beispiel #16
0
def get_derived_elements(elements, mapping, store_as_edge=False):
    """ Given a list of elements and a list of tuples (DerivedLayer, PPLayer),
    create new elements according to the boolean operations of the DerivedLayer
    and place these elements on the specified PPLayer. """

    derived_layers = mapping.keys()
    export_layers = mapping.values()
    elems = ElementList()
    for derived_layer, export_layer in zip(derived_layers, export_layers):
        pg = _derived_elements(elems=elements, derived_layer=derived_layer)
        for p in pg.elements:
            if store_as_edge is True:
                elems += Edge(shape=p.shape, layer=deepcopy(export_layer))
            else:
                elems += Polygon(shape=p.shape, layer=deepcopy(export_layer))
    return elems
Beispiel #17
0
        def wrap_references(cell, c2dmap, devices):
            for e in cell.elements.sref:
                if isinstance(e.reference, Device):
                    D = deepcopy(e.reference)
                    D.elements.transform(e.transformation)
                    D.ports.transform(e.transformation)
                    devices[D] = D.elements

                    D.elements = ElementList()
                    S = deepcopy(e)
                    S.reference = D
                    c2dmap[cell] += S
                else:
                    S = deepcopy(e)
                    S.reference = c2dmap[e.reference]
                    c2dmap[cell] += S
Beispiel #18
0
    def __filter___Cell____(self, item):
        from copy import deepcopy
        from spira.yevon.gdsii.cell import Cell

        elems = ElementList()
        for p1 in deepcopy(item.elements):
            if p1.layer.purpose == RDD.PURPOSE.METAL:
                for edge in p1.edges:
                    e = EdgeAdapter(original_edge=edge,
                                    edge_type=self.edge_type)
                    # print(e)
                    elems += e
                    # elems += edge.outside.transform(edge.transformation)
                elems += p1

        cell = Cell(elements=elems)
        return cell
Beispiel #19
0
def get_process_polygons(elements, operation='or'):
    from spira.yevon.gdsii.polygon_group import PolygonGroup
    from spira.yevon.filters.layer_filter import LayerFilterAllow

    elems = ElementList()
    for process in RDD.VMODEL.PROCESS_FLOW.active_processes:
        for layer in RDD.get_physical_layers_by_process(processes=process):
            LF = LayerFilterAllow(layers=[layer])
            el = LF(elements.polygons)
            if operation == 'or':
                pg = PolygonGroup(elements=el, layer=layer).union
            elif operation == 'and':
                pg = PolygonGroup(elements=el, layer=layer).intersect
            elif operation == 'not':
                pg = PolygonGroup(elements=el, layer=layer).difference
            elems += pg
    return elems
Beispiel #20
0
    def wrap_references(self, cell, c2dmap, devices):
        from spira.yevon.gdsii.pcell import Device
        for e in cell.elements.sref:
            if isinstance(e.reference, Device):
                D = deepcopy(e.reference)
                D.elements.transform(e.transformation)
                D.ports.transform(e.transformation)
                devices[D] = D.elements

                D.elements = ElementList()
                S = deepcopy(e)
                S.reference = D
                c2dmap[cell] += S
            else:
                S = deepcopy(e)
                S.reference = c2dmap[e.reference]
                c2dmap[cell] += S
Beispiel #21
0
def RouteManhattan(ports, layer, width=None, corners='miter', bend_radius=1):
    """  """

    elems = ElementList()

    if isinstance(ports, list):
        list1 = [p for p in ports if (p.alias[0] == 'D')]
    else:
        list1 = ports.get_ports_by_type('D')
    list2 = [p.flip() for p in list1]

    n = 2
    iter1 = iter(list1)
    pl = []
    for x in list2:
        pl.extend([next(iter1) for _ in range(n - 1)])
        pl.append(x)
    pl.extend(iter1)

    pl.insert(0, ports[0])
    pl.append(ports[-1])

    for x in range(len(pl) - 1):
        p1, p2 = pl[x], pl[x + 1]
        angle = ug.angle_diff(p2.orientation, p1.orientation)

        if angle not in [90, 180, 270]:
            raise ValueError('Angle must be in 90 degree angles.')

        if (angle == 180) and (p1.midpoint != p2.midpoint):
            elems += Route180(port1=p1,
                              port2=p2,
                              width=width,
                              layer=layer,
                              corners=corners,
                              bend_radius=bend_radius)
        elif (angle == 90) or (angle == 270):
            elems += Route90(port1=p1,
                             port2=p2,
                             width=width,
                             layer=layer,
                             corners=corners,
                             bend_radius=bend_radius)
    return elems
Beispiel #22
0
    def __xor__(self, other):
        pts1, pts2 = [], []

        for e in self.elements:
            s1 = e.shape.transform_copy(e.transformation)
            pts1.append(s1.points)
        for e in other.elements:
            s1 = e.shape.transform_copy(e.transformation)
            pts2.append(s1.points)

        self.elements = ElementList()
        if (len(pts1) > 0) and (len(pts2) > 0):
            p1 = gdspy.PolygonSet(polygons=pts1)
            p2 = gdspy.PolygonSet(polygons=pts2)
            ply = gdspy.boolean(p1, p2, operation='not')
            for points in ply.polygons:
                self.elements += Polygon(shape=points, layer=self.layer)

        return self
Beispiel #23
0
def generate_edges(shape, layer):
    """ Generates edge objects for each shape segment. """

    xpts = list(shape.x_coords)
    ypts = list(shape.y_coords)

    n = len(xpts)
    xpts.append(xpts[0])
    ypts.append(ypts[0])

    clockwise = 0
    for i in range(0, n):
        clockwise += ((xpts[i + 1] - xpts[i]) * (ypts[i + 1] + ypts[i]))

    if layer.name == 'BBOX': bbox = True
    else: bbox = False

    edges = ElementList()
    for i in range(0, n):

        name = '{}_e{}'.format(layer.name, i)
        x = np.sign(clockwise) * (xpts[i + 1] - xpts[i])
        y = np.sign(clockwise) * (ypts[i] - ypts[i + 1])
        orientation = (np.arctan2(x, y) * constants.RAD2DEG)
        midpoint = [(xpts[i + 1] + xpts[i]) / 2, (ypts[i + 1] + ypts[i]) / 2]
        width = np.abs(
            np.sqrt((xpts[i + 1] - xpts[i])**2 + (ypts[i + 1] - ypts[i])**2))

        layer = RDD.GDSII.IMPORT_LAYER_MAP[layer]
        inward_extend = RDD[layer.process.symbol].MIN_SIZE / 2
        outward_extend = RDD[layer.process.symbol].MIN_SIZE / 2

        edge = Edge(width=width,
                    inward_extend=inward_extend,
                    outward_extend=outward_extend,
                    process=layer.process)

        T = Rotation(orientation + 90) + Translation(midpoint)
        edge.transform(T)
        edges += edge

    return edges
Beispiel #24
0
    def filter_Cell(self, item):
        from spira.yevon.gdsii.cell import Cell

        ports = PortList()
        elems = ElementList()

        for e in item.derived_merged_elements:
            elems += e
        for e in item.elements.sref:
            elems += e
        for e in item.elements.labels:
            elems += e
        for p in item.ports:
            if p.purpose.symbol == 'P':
                ports += p
            if p.purpose.symbol == 'T':
                ports += p

        cell = Cell(elements=elems, ports=ports)
        return cell
Beispiel #25
0
    def filter_Cell(self, item):
        from spira.yevon.utils import clipping
        from spira.yevon.gdsii.cell import Cell

        ports = PortList()
        elems = ElementList()

        for e in item.elements.polygons:
            e.shape = clipping.simplify_points(e.points)
            elems += e

        for e in item.elements.sref:
            elems += e
        for e in item.elements.labels:
            elems += e
        for p in item.ports:
            ports += p

        cell = Cell(elements=elems, ports=ports)
        return cell
Beispiel #26
0
    def __filter___Cell____(self, item):
        from spira.yevon.gdsii.cell import Cell

        ports = PortList()
        elems = ElementList()

        # for pg in item.process_elements:
        # for e in pg.elements:
        # elems += e

        for e in item.process_elements:
            elems += e
        for e in item.elements.sref:
            elems += e
        for e in item.elements.labels:
            elems += e
        for p in item.ports:
            ports += p

        cell = Cell(elements=elems, ports=ports)
        return cell
Beispiel #27
0
    def __filter___Cell____(self, item):
        from spira.yevon.gdsii.cell import Cell
        from spira.yevon.utils import clipping
        from spira.yevon.vmodel.virtual import virtual_connect
        from shapely.geometry import Polygon as ShapelyPolygon

        ports = PortList()
        elems = ElementList()

        v_model = virtual_connect(device=item)
        for e in v_model.connected_elements:
            elems += e

        for e in item.elements.sref:
            elems += e
        for e in item.elements.labels:
            elems += e
        for p in item.ports:
            ports += p

        cell = Cell(elements=elems, ports=ports)
        return cell
Beispiel #28
0
    def filter_Cell(self, item):
        from spira.yevon.utils import clipping
        from spira.yevon.gdsii.cell import Cell
        from spira.yevon.geometry.ports import Port
        from spira.yevon.vmodel.virtual import virtual_connect
        from shapely.geometry import Polygon as ShapelyPolygon

        # ports = PortList()
        elems = ElementList()

        v_model = virtual_connect(device=item)

        for e1 in v_model.derived_contacts:
            ps = e1.layer.process.symbol
            for e2 in item.elements:
                for m in ['BOT_LAYER', 'TOP_LAYER']:
                    if ps in RDD.VIAS.keys:
                        if e2.layer == RDD.VIAS[ps].LAYER_STACK[m]:
                            if e2.encloses(e1.center):
                                port = Port(
                                    name='{}:Cv'.format(ps),
                                    midpoint=e1.center,
                                    process=e1.layer.process)
                                e2.ports += port
        elems += item.elements

        for e in item.elements.sref:
            elems += e
        for e in item.elements.labels:
            elems += e
        # for p in item.ports:
        #     ports += p

        # cell = Cell(elements=elems, ports=ports)
        cell = Cell(elements=elems)
        return cell
Beispiel #29
0
    def filter_Cell(self, item):
        from spira.yevon.gdsii.cell import Cell

        ports = PortList()
        elems = ElementList()

        c2dmap, devices = {}, {}

        for cell in item.dependencies():
            # FIXME: Why can I not use Cell?
            # ERC Port doesn't connect.
            D = item.__class__(name=cell.name,
                               elements=deepcopy(cell.elements.polygons),
                               ports=deepcopy(cell.ports))
            c2dmap.update({cell: D})

        for cell in item.dependencies():
            self.wrap_references(cell, c2dmap, devices)

        D = c2dmap[item]

        for e in D.elements.polygons:
            if e.layer.purpose.symbol == 'METAL':
                e.layer.purpose = RDD.PURPOSE.CIRCUIT_METAL
                # e.layer.purpose = RDD.PURPOSE.METAL

        for d in D.dependencies():
            if d in devices.keys():
                d.elements = devices[d]

                for e in d.elements.polygons:
                    if e.layer.purpose.symbol == 'METAL':
                        e.layer.purpose = RDD.PURPOSE.DEVICE_METAL
                        # e.layer.purpose = RDD.PURPOSE.METAL

        return D
Beispiel #30
0
    def __and__(self, other):
        el = ElementList()
        for e1 in self.elements:
            for e2 in other.elements:
                shape1 = e1.shape.transform_copy(e1.transformation)
                shape2 = e2.shape.transform_copy(e2.transformation)

                # if (shape1 != shape2) and (e1.layer.process == e2.layer.process):
                #     shapes = shape1 & shape2
                #     for shape in shapes:
                #         el += Polygon(shape=shape, layer=e1.layer)
                
                # # FIXME: We need this for virtual contact connections.
                # if shape1 != shape2:
                #     shapes = shape1 & shape2
                #     for shape in shapes:
                #         el += Polygon(shape=shape, layer=e1.layer)

                shapes = shape1 & shape2
                for shape in shapes:
                    el += Polygon(shape=shape, layer=e1.layer)

        self.elements = el
        return self