def apply(self, elems): pos_elems = spira.ElementList() neg_elems = spira.ElementList() for C in elems.dependencies(): if C.layer.number == self.layer1.number: pos_elems = C.elements elif C.layer.number == self.layer2.number: neg_elems = C.elements fails = False Ap = self.get_layer_area(pos_elems) An = self.get_layer_area(neg_elems) if (Ap > 0) and (An > 0): presentage = 100 - (An / Ap) * 100 if presentage < self.minimum: fails = True print('\n ------ Design Rules ------') print(self.layer1) message = '[DRC: Density ({})]: (layer1 {}, layer2 {}, extracted_value {}%, rule_value {}%)'.format( 'fail', self.layer1.number, self.layer2.number, int(round(presentage)), self.min) raise ValueError(message) else: fails = False print('\n ------ Design Rules ------') print(self.layer1) print('Density ({}): {}%'.format('pass', int(round(presentage)))) return fails
def view_virtual_connect(self, show_layers=False, write=False, **kwargs): """ View that contains all derived connections (attached contacts, derived edges). """ elems = spira.ElementList() if show_layers is True: el = self.derived_contacts F = filters.PurposeFilterAllow(purposes=['JJ', 'VIA']) elems += F(el) elems += self.device.elements else: elems += self.derived_contacts for ply_overlap, edges in self.derived_edges.items(): if ply_overlap.is_empty() is False: for e in edges: EF = filters.EdgeToPolygonFilter() elems += EF(e) if not isinstance(ply_overlap, spira.Edge): elems += ply_overlap name = self.device.name + '_VConnect' D = spira.Cell(name=name, elements=elems, ports=self.device.ports, transformation=self.device.transformation) D.gdsii_view() if write is True: D.gdsii_output(file_name=name)
def cut(ply, position, axis): import spira.all as spira plys = spira.ElementList() gp = ply.commit_to_gdspy() pl = gdspy.slice(objects=[gp], position=position, axis=axis) for p in pl: if len(p.polygons) > 0: plys += spira.Polygon(shape=p.polygons[0]) return plys
def view_derived_edges(self, show_layers=False, **kwargs): elems = spira.ElementList() if show_layers is True: elems += self.device.elements for ply_overlap, edges in self.derived_edges.items(): if ply_overlap.is_empty() is False: for e in edges: EF = filters.EdgeToPolygonFilter() elems += EF(e) D = spira.Cell(name='_DERIVED_EDGES', elements=elems) D.gdsii_view()
def gdsii_output_virtual_connect(self, **kwargs): elems = spira.ElementList() # for e in self.__make_polygons__(): # elems += e for ply_overlap, edges in self.connected_edges.items(): if len(ply_overlap.points) > 0: elems += ply_overlap elems += edges for e in self.device.elements: elems += e D = spira.Cell(name='_VIRTUAL_CONNECT', elements=elems) D.gdsii_output()
def view_derived_contacts(self, show_layers=False, **kwargs): elems = spira.ElementList() # if show_layers is True: # elems += self.device.elements # el = self.derived_contacts # F = filters.PurposeFilterAllow(purposes=['JJ', 'VIA']) # elems += F(el) el = self.derived_contacts elems += el D = spira.Cell(name='_DERIVED_CONTACTS', elements=elems) D.gdsii_view()
def __make_polygons__(self): elems = spira.ElementList() if self.connect_type == 'contact_layer': mapping = {} for k in RDD.VIAS.keys: mapping[RDD.PLAYER[k]. CLAYER_CONTACT] = RDD.VIAS[k].LAYER_STACK['VIA_LAYER'] mapping[RDD.PLAYER[k]. CLAYER_M1] = RDD.VIAS[k].LAYER_STACK['BOT_LAYER'] mapping[RDD.PLAYER[k]. CLAYER_M2] = RDD.VIAS[k].LAYER_STACK['TOP_LAYER'] # print('\nMapping:') # for k, v in mapping.items(): # print(k, v) # print('') # print(self.device.elements) el = get_derived_elements(elements=self.device.elements, mapping=mapping) for e in el: if e.purpose == 'METAL': pass else: elems += e else: pass # # D = self.device.expand_flat_copy() # D = self.device.expand_flat_no_jjcopy() # elems = spira.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(D.elements.polygons) # elems += spira.PolygonGroup(elements=el, layer=layer).intersect return elems
import numpy as np import spira.all as spira from spira.yevon.vmodel.virtual import virtual_connect from spira.yevon.filters.boolean_filter import MetalConnectFilter from spira.technologies.mit.process import RDD el = spira.ElementList() p1 = spira.Rectangle(p1=(0, 0), p2=(4, 10), layer=RDD.PLAYER.M5.METAL) p2 = spira.Rectangle(p1=(0, 0), p2=(4, 12), layer=RDD.PLAYER.M5.METAL) # FIXME: Throught a weird polygon error. # p2 = spira.Rectangle(p1=(0, 0), p2=(4, 10), layer=RDD.PLAYER.M5.METAL) p2.shape.move(pos=(7, 0)) el += [p1, p2] el += spira.Rectangle(p1=(3, 4), p2=(8, 6), layer=RDD.PLAYER.M5.METAL) # el += spira.Rectangle(p1=(8, 4), p2=(-4, 6), layer=RDD.PLAYER.M5.METAL) # el += spira.Rectangle(p1=(-4, 4), p2=(1, 6), layer=RDD.PLAYER.M5.METAL) # el += spira.Rectangle(p1=(3, 4), p2=(8, 6), layer=RDD.PLAYER.M5.METAL) # el += spira.Rectangle(p1=(-4, 8), p2=(8, 12), layer=RDD.PLAYER.M5.METAL) # el += spira.Rectangle(p1=(1, 9), p2=(3, 14), layer=RDD.PLAYER.M5.METAL) # el += spira.Rectangle(p1=(-1, 9), p2=(5, 14), layer=RDD.PLAYER.M5.METAL) # NOTE: Edge cases. # el += spira.Rectangle(p1=(0, 10), p2=(4, 14), layer=RDD.PLAYER.M5.METAL)
def flat_copy(self, level=-1): if not level == 0: return self.elements.flat_copy(level).transform( self.transformation) else: return spira.ElementList(self.elements)
def edge_to_minimum_width(self, e1): ports = spira.ElementList() for p in e1.edge_ports: p.length = 2 * self.minimum ports += p return ports