def test_9(self): ly = pya.Layout() l1 = ly.insert_layer(pya.LayerInfo(1, 0)) c1 = ly.create_cell("a") self.assertEqual(ly.under_construction(), False) s1 = c1.shapes(l1).insert(pya.Box(0, 500, 1000, 2000)) self.assertEqual(c1.bbox().to_s(), "(0,500;1000,2000)") ly = pya.Layout() ly.start_changes() self.assertEqual(ly.under_construction(), True) ly.start_changes() self.assertEqual(ly.under_construction(), True) l1 = ly.insert_layer(pya.LayerInfo(1, 0)) c1 = ly.create_cell("a") s1 = c1.shapes(l1).insert(pya.Box(0, 500, 1000, 2000)) self.assertEqual(c1.bbox().to_s(), "()") # while under_construction, an explicit update is required to update the cell's bbox ly.update() self.assertEqual(c1.bbox().to_s(), "(0,500;1000,2000)") ly.end_changes() self.assertEqual(ly.under_construction(), True) ly.end_changes() self.assertEqual(ly.under_construction(), False)
def test_2(self): # instantiate and register the library tl = PCellTestLib() ly = pya.Layout(True) ly.dbu = 0.01 ci1 = ly.add_cell("c1") c1 = ly.cell(ci1) lib = pya.Library.library_by_name("PCellTestLib") pcell_decl_id = lib.layout().pcell_id("Box") param = [ pya.LayerInfo(1, 0), 10.0, 2.0 ] pcell_var_id = ly.add_pcell_variant(lib, pcell_decl_id, param) pcell_var = ly.cell(pcell_var_id) pcell_inst = c1.insert(pya.CellInstArray(pcell_var_id, pya.Trans())) li1 = find_layer(ly, "1/0") self.assertEqual(li1 != None, True) self.assertEqual(ly.is_valid_layer(li1), True) self.assertEqual(str(ly.get_info(li1)), "1/0") self.assertEqual(pcell_inst.is_pcell(), True) self.assertEqual(ly.begin_shapes(pcell_inst.cell_index, li1).shape().__str__(), "box (-500,-100;500,100)") pcell_inst.convert_to_static() self.assertEqual(pcell_inst.is_pcell(), False) self.assertEqual(ly.begin_shapes(pcell_inst.cell_index, li1).shape().__str__(), "box (-500,-100;500,100)") pcell_inst.convert_to_static() self.assertEqual(pcell_inst.is_pcell(), False) self.assertEqual(ly.begin_shapes(pcell_inst.cell_index, li1).shape().__str__(), "box (-500,-100;500,100)")
def pcell(self, layout, cell=None, params=None): if cell is None: cell = layout.create_cell(self.name) cp = self.parse_param_args(params) origin, _, _ = CellWithPosition.origin_ex_ey(self, params, multiple_of_90=True) if from_library is not None: # Topcell must be same as filename gdscell = get_lib_cell(layout, cell_name, from_library) else: # BUG loading this file twice segfaults klayout layout2 = pya.Layout() layout2.read(os.path.join(gds_dir, filename)) gdscell2 = layout2.cell(cell_name) gdscell = layout.create_cell(cell_name) gdscell.copy_tree(gdscell2) del gdscell2 del layout2 rot_DTrans = pya.DTrans.R0 angle_multiple_90 = cp.angle_ex // 90 rot_DTrans.rot = (angle_multiple_90) % 4 cell.insert( pya.DCellInstArray(gdscell.cell_index(), pya.DTrans(rot_DTrans, origin))) return cell, {}
def Start(mod="guiopen"): if mod == "gds": IO.layout = pya.Layout() elif mod == "guinew": IO.main_window = pya.Application.instance().main_window() IO.layout = IO.main_window.create_layout(1).layout() IO.layout_view = IO.main_window.current_view() IO.layout_view.rename_cellview("pythonout", 0) elif mod == "guiopen": IO.main_window = pya.Application.instance().main_window() IO.layout_view = IO.main_window.current_view() try: IO.layout = IO.layout_view.cellview( IO.layout_view.active_cellview_index()).layout() except AttributeError as _: return IO.Start("guinew") if len(IO.layout.top_cells()) > 0: IO.top = IO.layout.top_cells()[0] else: IO.top = IO.layout.create_cell("TOP") # IO.auxiliary = IO.layout.create_cell("auxiliary") IO.top.insert(pya.CellInstArray(IO.auxiliary.cell_index(), pya.Trans())) # IO.link = IO.layout.create_cell("link") IO.auxiliary.insert( pya.CellInstArray(IO.link.cell_index(), pya.Trans())) # IO.layer = IO.layout.layer(0, 0) for li1, li2 in [(0, 1), (0, 2)]: IO.layout.layer(li1, li2) return IO.layout, IO.top
def test_13(self): n = 100 w = 10000 ly = pya.Layout() l1 = ly.layer(1, 0) top = ly.create_cell("TOP") ix = 0 while ix < n: sys.stdout.write(str(ix) + "/" + str(n) + "\n") sys.stdout.flush() iy = 0 while iy < n: x = ix * w y = iy * w cell = ly.create_cell("X" + str(ix) + "Y" + str(iy)) cell.shapes(l1).insert(pya.Box(0, 0, w, w)) top.insert( pya.CellInstArray(cell.cell_index(), pya.Trans(pya.Point(ix * w, iy * w)))) iy += 1 ix += 1 ly._destroy()
def test_1_Basic(self): ut_testsrc = os.getenv("TESTSRC") ly = pya.Layout() ly.read( os.path.join(ut_testsrc, "testdata", "algo", "device_extract_l1.gds")) l2n = pya.LayoutToNetlist( pya.RecursiveShapeIterator(ly, ly.top_cell(), [])) l2n.threads = 17 l2n.max_vertex_count = 42 l2n.area_ratio = 7.5 self.assertEqual(l2n.threads, 17) self.assertEqual(l2n.max_vertex_count, 42) self.assertEqual(l2n.area_ratio, 7.5) r = l2n.make_layer(ly.layer(6, 0)) self.assertNotEqual(l2n.internal_layout() is ly, True) self.assertEqual(l2n.internal_layout().top_cell().name, ly.top_cell().name) self.assertEqual(l2n.internal_top_cell().name, ly.top_cell().name) self.assertNotEqual(l2n.layer_of(r), ly.layer(6, 0)) # would be a strange coincidence ... cm = l2n.const_cell_mapping_into(ly, ly.top_cell()) for ci in range(0, l2n.internal_layout().cells()): self.assertEqual(l2n.internal_layout().cell(ci).name, ly.cell(cm.cell_mapping(ci)).name) ly2 = pya.Layout() ly2.create_cell(ly.top_cell().name) cm = l2n.cell_mapping_into(ly2, ly2.top_cell()) self.assertEqual(ly2.cells(), ly.cells()) for ci in range(0, l2n.internal_layout().cells()): self.assertEqual(l2n.internal_layout().cell(ci).name, ly2.cell(cm.cell_mapping(ci)).name) rmetal1 = l2n.make_polygon_layer(ly.layer(6, 0), "metal1") bulk_id = l2n.connect_global(rmetal1, "BULK") self.assertEqual(l2n.global_net_name(bulk_id), "BULK")
def pyaCell_reader(pya_cell, filename, *args, **kwargs): templayout = pya.Layout() templayout.read(filename) tempcell = templayout.top_cell() # Transfer the geometry of the imported cell to the one specified pya_cell.name = tempcell.name pya_cell.copy_tree(tempcell) return pya_cell
def test_1a(self): # instantiate and register the library tl = PCellTestLib2() ly = pya.Layout(True) ly.dbu = 0.01 li1 = find_layer(ly, "1/0") self.assertEqual(li1 == None, True) ci1 = ly.add_cell("c1") c1 = ly.cell(ci1) lib = pya.Library.library_by_name("PCellTestLib2") self.assertEqual(lib != None, True) pcell_decl = lib.layout().pcell_declaration("Box2") param = [ pya.LayerInfo(1, 0) ] # rest is filled with defaults pcell_var_id = ly.add_pcell_variant(lib, pcell_decl.id(), param) pcell_var = ly.cell(pcell_var_id) pcell_inst = c1.insert(pya.CellInstArray(pcell_var_id, pya.Trans())) self.assertEqual(pcell_var.basic_name(), "Box2") self.assertEqual(pcell_var.pcell_parameters().__repr__(), "[<1/0>, 1.0, 1.0]") self.assertEqual(pcell_var.display_title(), "PCellTestLib2.Box2(L=1/0,W=1.000,H=1.000)") self.assertEqual(nh(pcell_var.pcell_parameters_by_name()), "{'height': 1.0, 'layer': <1/0>, 'width': 1.0}") self.assertEqual(pcell_var.pcell_parameter("height").__repr__(), "1.0") self.assertEqual(c1.pcell_parameters(pcell_inst).__repr__(), "[<1/0>, 1.0, 1.0]") self.assertEqual(nh(c1.pcell_parameters_by_name(pcell_inst)), "{'height': 1.0, 'layer': <1/0>, 'width': 1.0}") self.assertEqual(c1.pcell_parameter(pcell_inst, "height").__repr__(), "1.0") self.assertEqual(nh(pcell_inst.pcell_parameters_by_name()), "{'height': 1.0, 'layer': <1/0>, 'width': 1.0}") self.assertEqual(pcell_inst["height"].__repr__(), "1.0") self.assertEqual(pcell_inst.pcell_parameter("height").__repr__(), "1.0") self.assertEqual(pcell_var.pcell_declaration().__repr__(), pcell_decl.__repr__()) self.assertEqual(c1.pcell_declaration(pcell_inst).__repr__(), pcell_decl.__repr__()) self.assertEqual(pcell_inst.pcell_declaration().__repr__(), pcell_decl.__repr__()) li1 = find_layer(ly, "1/0") self.assertEqual(li1 == None, False) pcell_inst.change_pcell_parameter("height", 2.0) self.assertEqual(nh(pcell_inst.pcell_parameters_by_name()), "{'height': 2.0, 'layer': <1/0>, 'width': 1.0}") self.assertEqual(ly.begin_shapes(c1.cell_index(), li1).shape().__str__(), "box (-50,-100;50,100)") param = { "layer": pya.LayerInfo(2, 0), "width": 2, "height": 1 } li2 = ly.layer(2, 0) c1.change_pcell_parameters(pcell_inst, param) self.assertEqual(ly.begin_shapes(c1.cell_index(), li2).shape().__str__(), "box (-100,-50;100,50)") l10 = ly.layer(10, 0) c1.shapes(l10).insert(pya.Box(0, 10, 100, 210)) l11 = ly.layer(11, 0) c1.shapes(l11).insert(pya.Text("hello", pya.Trans())) self.assertEqual(pcell_decl.can_create_from_shape(ly, ly.begin_shapes(c1.cell_index(), l11).shape(), l10), False) self.assertEqual(pcell_decl.can_create_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10), True) self.assertEqual(repr(pcell_decl.parameters_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10)), "[<10/0>, 1.0, 2.0]") self.assertEqual(str(pcell_decl.transformation_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10)), "r0 50,110")
def test_bug109(self): testtmp = os.getenv("TESTTMP_WITH_NAME", os.getenv("TESTTMP", ".")) file_gds = os.path.join(testtmp, "bug109.gds") file_oas = os.path.join(testtmp, "bug109.oas") ly = pya.Layout() top = ly.create_cell("TOP") l1 = ly.layer(1, 0) shape = top.shapes(l1).insert(pya.Box(0, 10, 20, 30)) shape.set_property(2, "hello, world") shape.set_property("42", "the answer") ly.write(file_gds) ly.write(file_oas) ly2 = pya.Layout() ly2.read(file_gds) l2 = ly2.layer(1, 0) shape = None for s in ly2.top_cell().shapes(l2).each(): shape = s self.assertEqual(shape.property(2), "hello, world") self.assertEqual(shape.property("2"), None) self.assertEqual(shape.property(2.0), "hello, world") self.assertEqual(shape.property(22), None) self.assertEqual(shape.property(42), "the answer") self.assertEqual(shape.property("42"), None) self.assertEqual(shape.property(42.0), "the answer") ly2 = pya.Layout() ly2.read(file_oas) l2 = ly2.layer(1, 0) shape = None for s in ly2.top_cell().shapes(l2).each(): shape = s self.assertEqual(shape.property(2), "hello, world") self.assertEqual(shape.property("2"), None) self.assertEqual(shape.property(2.0), "hello, world") self.assertEqual(shape.property(22), None) self.assertEqual(shape.property("42"), "the answer") self.assertEqual(shape.property(42), None) self.assertEqual(shape.property(42.0), None)
def test_deep1(self): ut_testsrc = os.getenv("TESTSRC") # construction/destruction magic ... self.assertEqual(pya.DeepShapeStore.instance_count(), 0) dss = pya.DeepShapeStore() dss._create() self.assertEqual(pya.DeepShapeStore.instance_count(), 1) dss = None self.assertEqual(pya.DeepShapeStore.instance_count(), 0) dss = pya.DeepShapeStore() ly = pya.Layout() ly.read( os.path.join(ut_testsrc, "testdata", "algo", "deep_region_l1.gds")) l1 = ly.layer(1, 0) r = pya.Region(ly.top_cell().begin_shapes_rec(l1), dss) rf = pya.Region(ly.top_cell().begin_shapes_rec(l1)) self.assertEqual(r.area(), 53120000) self.assertEqual(rf.area(), 53120000) ly_new = pya.Layout() tc = ly_new.add_cell("TOP") l1 = ly_new.layer(1, 0) l2 = ly_new.layer(2, 0) ly_new.insert(tc, l1, r) ly_new.insert(tc, l2, rf) s1 = {} s2 = {} for cell in ly_new.each_cell(): s1[cell.name] = cell.shapes(l1).size() s2[cell.name] = cell.shapes(l2).size() self.assertEqual(s1, {"INV2": 1, "TOP": 0, "TRANS": 0}) self.assertEqual(s2, {"INV2": 0, "TOP": 10, "TRANS": 0}) # force destroy, so the unit tests pass on the next iteration dss = None self.assertEqual(pya.DeepShapeStore.instance_count(), 0)
def __init__(self, filename="[insert].gds"): self.outputlist = [] self.filename = filename layout = pya.Layout() layout.read(filename) names = [i.name for i in layout.top_cells()] if (len(names) != 1): raise RuntimeError('insert file must have only one top cell') if (names[0] == 'TOP'): raise RuntimeError("the name of insert file's cell can not be TOP") self.insertcellname = names[0] self.airbridgedistance = 100000
def test_7(self): # instantiate and register the library tl = PCellTestLib() ly = pya.Layout(True) ly.dbu = 0.01 param = { "w": 4.0, "h": 8.0, "l": pya.LayerInfo(4, 0) } cell = ly.create_cell("Box", "PCellTestLib", param) self.assertEqual(ly.begin_shapes(cell, ly.layer(4, 0)).shape().__str__(), "box (-200,-400;200,400)")
def test_writes(): # Test pya writables import pya layout = pya.Layout() any_write(layout, 'tempfile.gds') TOP = layout.create_cell('TOP') any_write(TOP, 'tempfile.gds') # Test phidl writables import phidl box2 = phidl.geometry.rectangle((20, 20)) any_write(box2, 'tempfile.gds') os.remove('tempfile.gds')
def tough_create(): layout = pya.Layout() ipc.trace_pyainsert(layout, debug_file) layout.dbu = 0.001 TOP = layout.create_cell('TOP') l1 = layout.insert_layer(pya.LayerInfo(1, 0)) l2 = layout.insert_layer(pya.LayerInfo(2, 0)) for i in range(51): for j in range(51): box = pya.DBox(0, 0, 10, 10) box.move(15 * i, 15 * j) TOP.shapes(l1).insert(box) TOP.shapes(l2).insert(pya.DBox(0, 0, 1000, 1000))
def test_6_Layout_props2(self): ly = pya.Layout(True) pv = [[17, "a"], ["b", [1, 5, 7]]] pid = ly.properties_id(pv) # does not work? @@@ # pv = { 17: "a", "b": [ 1, 5, 7 ] } # pid2 = ly.properties_id( pv ) # self.assertEqual( pid, pid2 ) ci1 = ly.add_cell("c1") ci2 = ly.add_cell("c2") linfo = pya.LayerInfo() linfo.layer = 16 linfo.datatype = 1 lindex = ly.insert_layer(linfo) c1 = ly.cell(ci1) c2 = ly.cell(ci2) tr = pya.Trans() inst = c2.insert(pya.CellInstArray(c1.cell_index(), tr)) self.assertEqual(inst.parent_cell.name, c2.name) self.assertEqual(inst.cell.name, c1.name) self.assertEqual(repr(inst.layout()), repr(ly)) s1 = c1.shapes(lindex).insert(pya.Box(10, -10, 50, 40), pid) s2 = c1.shapes(lindex).insert(pya.Box(10, -10, 50, 40)) self.assertEqual(repr(s1.property(17)), "\'a\'") s1.set_property(5, 23) s1.delete_property(17) self.assertEqual(repr(s1.property(17)), "None") self.assertEqual(str(s1.property(5)), "23") self.assertEqual(repr(s2.property(17)), "None") self.assertEqual(repr(inst.property("a")), "None") inst.set_property("a", 33) self.assertEqual(str(inst.property("a")), "33") inst.delete_property("a") self.assertEqual(repr(inst.property("a")), "None") # cell properties self.assertEqual(repr(c1.property(17)), "None") c1.prop_id = pid self.assertEqual(c1.prop_id, pid) self.assertEqual(repr(c1.property(17)), "\'a\'") c1.set_property(5, 23) c1.delete_property(17) self.assertEqual(repr(c1.property(17)), "None") self.assertEqual(str(c1.property(5)), "23")
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")
def __init__(self): self.layout = pya.Layout() self.layout.dbu = 0.001 self.top = self.layout.create_cell("TOP") self.layer_index = self.layout.insert_layer(pya.LayerInfo(15,99)) self.lib = pya.Library.library_by_name("Basic") if self.lib == None: raise Exception("Unknown lib 'Basic'") self.pcell_decl = self.lib.layout().pcell_declaration("TEXT"); if self.pcell_decl == None: raise Exception("Unknown PCell 'TEXT'")
def test_lyp_loading(): from lymask.utilities import set_active_technology, reload_lys, lys layout = pya.Layout() layout.read(layout_file) lys.active_layout = layout lymask.set_active_technology('lymask_example_tech') lymask.utilities.reload_lys() assert lys['m5_wiring'] is lys('m5_wiring') is lys.m5_wiring with pytest.raises(KeyError): batch_main(layout_file, ymlspec='bad_masks', technology='lymask_example_tech')
def simple_create(grids=4): t0 = time.time() layout = pya.Layout() ipc.trace_pyainsert(layout, debug_file) layout.dbu = 0.001 TOP = layout.create_cell('TOP') l1 = layout.insert_layer(pya.LayerInfo(1, 0)) for i in range(grids): for j in range(grids): box = pya.DBox(0, 0, 10, 10) box.move(15 * i, 15 * j) TOP.shapes(l1).insert(box) print(time.time() - t0)
def test_8(self): # instantiate and register the library tl = PCellTestLib() lib = pya.Library.library_by_name("PCellTestLib") ly = pya.Layout(True) ly.dbu = 0.01 param = { "w": 2.0, "h": 6.0, "l": pya.LayerInfo(5, 0) } pcell_var = lib.layout().create_cell("Box", param) pcell_var.name = "BOXVAR" cell = ly.create_cell("BOXVAR", "PCellTestLib") self.assertEqual(cell.begin_shapes_rec(ly.layer(5, 0)).shape().__str__(), "box (-100,-300;100,300)")
def main(): layout = pya.Layout() dbu = layout.dbu = 0.001 TOP = layout.create_cell("TOP") origin = pya.DPoint(0, 0) ex = pya.DVector(1, 0) ey = pya.DVector(0, 1) MZI_Broadband_DC("MZI1x2").place_cell(TOP, origin) # from ebeam_pdk import layout_ebeam_waveguide_from_points # points_list = [origin, origin + 20 * ex, origin + 20 * ex + 40 * ey] # layout_ebeam_waveguide_from_points(TOP, points_list) print("Wrote to example_mask.gds") layout.write("example_mask.gds")
def Start(mod="guiopen"): if mod=="gds": IO.layout=pya.Layout() elif mod=="guinew": IO.main_window = pya.Application.instance().main_window() IO.layout = IO.main_window.create_layout(1).layout() IO.layout_view = IO.main_window.current_view() IO.layout_view.rename_cellview("pythonout",0) elif mod=="guiopen": IO.main_window = pya.Application.instance().main_window() IO.layout_view = IO.main_window.current_view() try: IO.layout=IO.layout_view.cellview(IO.layout_view.active_cellview_index()).layout() except AttributeError as e: IO.layout,IO.top=IO.Start("guinew") IO.top=IO.layout.top_cell() if IO.top==None: IO.top = IO.layout.create_cell("TOP") return IO.layout,IO.top
def test_3(self): # instantiate and register the library tl = PCellTestLib() ly = pya.Layout(True) ly.dbu = 0.01 c1 = ly.create_cell("c1") lib = pya.Library.library_by_name("PCellTestLib") pcell_decl_id = lib.layout().pcell_id("Box") param = { "w": 4.0, "h": 8.0, "l": pya.LayerInfo(1, 0) } pcell_var_id = ly.add_pcell_variant(lib, pcell_decl_id, param) pcell_var = ly.cell(pcell_var_id) pcell_inst = c1.insert(pya.CellInstArray(pcell_var_id, pya.Trans())) self.assertEqual(ly.begin_shapes(c1.cell_index(), ly.layer(1, 0)).shape().__str__(), "box (-200,-400;200,400)")
def klayout_init_layout(): # getting main references of the application try: app = pya.Application.instance() except Exception as e: return pya.Layout(), None mw = app.main_window() lv = mw.current_view() cv = None # this insures that lv and cv are valid objects if (lv == None): cv = mw.create_layout(1) lv = mw.current_view() else: cv = lv.active_cellview() # find or create the desired by programmer cell and layer return cv.layout(), lv
def test_11(self): ly = pya.Layout() self.assertEqual(ly.prop_id, 0) ly.prop_id = 1 self.assertEqual(ly.prop_id, 1) ly.prop_id = 0 self.assertEqual(ly.prop_id, 0) ly.set_property("x", 1) self.assertEqual(ly.prop_id, 1) self.assertEqual(ly.property("x"), 1) ly.set_property("x", 17) self.assertEqual(ly.prop_id, 2) self.assertEqual(ly.property("x"), 17) self.assertEqual(ly.property("y"), None) ly.delete_property("x") self.assertEqual(ly.property("x"), None)
def test_8(self): l = pya.Layout() tc = [] for t in l.each_top_cell(): tc.append(l.cell(t).name()) self.assertEqual(",".join(tc), "") self.assertEqual(repr(l.top_cell()), "None") self.assertEqual(len(l.top_cells()), 0) c0 = l.create_cell("c0") self.assertEqual(c0.name, "c0") tc = [] for t in l.each_top_cell(): tc.append(l.cell(t).name) self.assertEqual(",".join(tc), "c0") self.assertEqual(l.top_cell().name, "c0") tc = [] for t in l.top_cells(): tc.append(t.name) self.assertEqual(",".join(tc), "c0") c1 = l.create_cell("c1") self.assertEqual(c1.name, "c1") tc = [] for t in l.each_top_cell(): tc.append(l.cell(t).name) self.assertEqual(",".join(tc), "c0,c1") error = False try: self.assertEqual(l.top_cell.inspect, "never-true") except: error = True self.assertEqual(error, True) tc = [] for t in l.top_cells(): tc.append(t.name) self.assertEqual(",".join(tc), "c0,c1") c2 = l.create_cell("c1") self.assertEqual(c2.name, "c1$1")
def test_5_Layout(self): ly = pya.Layout() ci1 = ly.add_cell("c1") ci2 = ly.add_cell("c2") linfo = pya.LayerInfo() linfo.layer = 16 linfo.datatype = 1 lindex = ly.insert_layer(linfo) linfo = pya.LayerInfo() linfo.layer = 16 linfo.datatype = 2 ldummy = ly.insert_layer(linfo) c1 = ly.cell(ci1) c2 = ly.cell(ci2) c1.shapes(lindex).insert(pya.Box(10, -10, 50, 40)) self.assertEqual(c1.bbox().to_s(), "(10,-10;50,40)") self.assertEqual(c1.bbox_per_layer(lindex).to_s(), "(10,-10;50,40)") self.assertEqual(c1.bbox_per_layer(ldummy).to_s(), "()") c1.swap(lindex, ldummy) self.assertEqual(c1.bbox_per_layer(lindex).to_s(), "()") self.assertEqual(c1.bbox_per_layer(ldummy).to_s(), "(10,-10;50,40)") c1.clear(lindex) c1.clear(ldummy) self.assertEqual(c1.bbox_per_layer(lindex).to_s(), "()") self.assertEqual(c1.bbox_per_layer(ldummy).to_s(), "()") c1.shapes(lindex).insert(pya.Box(10, -10, 50, 40)) self.assertEqual(c1.bbox_per_layer(lindex).to_s(), "(10,-10;50,40)") self.assertEqual(c1.bbox_per_layer(ldummy).to_s(), "()") c1.clear_shapes() self.assertEqual(c1.bbox_per_layer(lindex).to_s(), "()") self.assertEqual(c1.bbox_per_layer(ldummy).to_s(), "()")
def biggest_bounding_box(fname): """Finds the bounding box enclosing all cells in all layers of a layout. This dimension of the whole layout and its data base unit is returned. Args: fname: Layout file name (string) Returns: biggest_bounding_box: Box enclosing the whole layout (pya.Box()) dbu: Data base unit of the layout (double) """ layout = pya.Layout() layout.read(fname) biggest_bounding_box = pya.Box() for top_cell_index in layout.each_top_cell(): top_cell = layout.cell(top_cell_index) # Cell object from index bbox = top_cell.bbox() # Bounding box of pya.Cell object # + operator joins Boxes into Box enclosing both inputs. biggest_bounding_box = biggest_bounding_box + bbox dbu = layout.dbu # Data base unit return (biggest_bounding_box, dbu)
# -*- coding: utf-8 -*- #测试pcell import pya from math import * #.insert(pya.Polygon.from_dpoly(x)) layout = pya.Layout() top = layout.create_cell("TOP") l1 = layout.layer(1, 0) #Basic.CIRCLE DONUT ELLIESP ROUND_POLYGON #Basic.STROKED_BOX STROKED_POLYGON #ARC CIRCLE DONUT ELLIPSE PIE ROUND_PATH #ROUND_POLYGON STROKED_BOX STROKED_POLYGON TEXT #Box box1 = pya.Box(70, 70, 200, 200) top.shapes(l1).insert(box1) #Polygon pts = [ pya.Point(0, 0), pya.Point(50, 0), pya.Point(50, 50), pya.Point(40, 60), pya.Point(0, 50) ] polygon1 = pya.Polygon(pts) top.shapes(l1).insert(polygon1) #DPath dpts = [ pya.DPoint(0.4, 0), pya.DPoint(50, 0),
def test_2_Flow(self): ut_testsrc = os.getenv("TESTSRC") ly = pya.Layout() ly.read(os.path.join(ut_testsrc, "testdata", "algo", "lvs_test_1.gds")) lvs = pya.LayoutVsSchematic(pya.RecursiveShapeIterator(ly, ly.top_cell(), [])) nwell = lvs.make_layer(ly.layer(1, 0), "nwell") active = lvs.make_layer(ly.layer(2, 0), "active") pplus = lvs.make_layer(ly.layer(10, 0), "pplus") nplus = lvs.make_layer(ly.layer(11, 0), "nplus") poly = lvs.make_layer(ly.layer(3, 0), "poly") poly_lbl = lvs.make_text_layer(ly.layer(3, 1), "poly_lbl") diff_cont = lvs.make_layer(ly.layer(4, 0), "diff_cont") poly_cont = lvs.make_layer(ly.layer(5, 0), "poly_cont") metal1 = lvs.make_layer(ly.layer(6, 0), "metal1") metal1_lbl = lvs.make_text_layer(ly.layer(6, 1), "metal1_lbl") via1 = lvs.make_layer(ly.layer(7, 0), "via1") metal2 = lvs.make_layer(ly.layer(8, 0), "metal2") metal2_lbl = lvs.make_text_layer(ly.layer(8, 1), "metal2_lbl") bulk = lvs.make_layer() # compute some layers active_in_nwell = active & nwell pactive = active_in_nwell & pplus ntie = active_in_nwell & nplus pgate = pactive & poly psd = pactive - pgate active_outside_nwell = active - nwell nactive = active_outside_nwell & nplus ptie = active_outside_nwell & pplus ngate = nactive & poly nsd = nactive - ngate # device extraction pmos_ex = pya.DeviceExtractorMOS4Transistor("PMOS") dl = { "SD": psd, "G": pgate, "P": poly, "W": nwell } lvs.extract_devices(pmos_ex, dl) nmos_ex = pya.DeviceExtractorMOS4Transistor("NMOS") dl = { "SD": nsd, "G": ngate, "P": poly, "W": bulk } lvs.extract_devices(nmos_ex, dl) # register derived layers for connectivity lvs.register(psd, "psd") lvs.register(nsd, "nsd") lvs.register(ptie, "ptie") lvs.register(ntie, "ntie") # intra-layer lvs.connect(psd) lvs.connect(nsd) lvs.connect(nwell) lvs.connect(poly) lvs.connect(diff_cont) lvs.connect(poly_cont) lvs.connect(metal1) lvs.connect(via1) lvs.connect(metal2) lvs.connect(ptie) lvs.connect(ntie) # inter-layer lvs.connect(psd, diff_cont) lvs.connect(nsd, diff_cont) lvs.connect(poly, poly_cont) lvs.connect(poly_cont, metal1) lvs.connect(diff_cont, metal1) lvs.connect(diff_cont, ptie) lvs.connect(diff_cont, ntie) lvs.connect(nwell, ntie) lvs.connect(metal1, via1) lvs.connect(via1, metal2) lvs.connect(poly, poly_lbl) # attaches labels lvs.connect(metal1, metal1_lbl) # attaches labels lvs.connect(metal2, metal2_lbl) # attaches labels # global lvs.connect_global(ptie, "BULK") lvs.connect_global(bulk, "BULK") lvs.extract_netlist() lvs.netlist().combine_devices() lvs.netlist().make_top_level_pins() lvs.netlist().purge() # read the reference netlist reader = pya.NetlistSpiceReader() nl = pya.Netlist() nl.read(os.path.join(ut_testsrc, "testdata", "algo", "lvs_test_1.spi"), reader) self.assertEqual(lvs.reference == None, True) lvs.reference = nl self.assertEqual(lvs.reference == nl, True) # do the actual compare comparer = pya.NetlistComparer() res = lvs.compare(comparer) self.assertEqual(res, True) self.assertEqual(lvs.xref != None, True)