예제 #1
0
    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)
예제 #2
0
    def test_20_Antenna(self):

        ut_testsrc = os.getenv("TESTSRC")

        # --- simple antenna check

        input = os.path.join(ut_testsrc, "testdata", "algo", "antenna_l1.gds")
        ly = pya.Layout()
        ly.read(input)

        au = os.path.join(ut_testsrc, "testdata", "algo", "antenna_au1.gds")
        ly_au = pya.Layout()
        ly_au.read(au)

        dss = pya.DeepShapeStore()
        self.assertEqual(dss.is_singular(), False)

        rdiode = pya.Region(ly.top_cell().begin_shapes_rec(ly.layer(1, 0)),
                            dss)
        rpoly = pya.Region(ly.top_cell().begin_shapes_rec(ly.layer(6, 0)), dss)
        rcont = pya.Region(ly.top_cell().begin_shapes_rec(ly.layer(8, 0)), dss)
        rmetal1 = pya.Region(ly.top_cell().begin_shapes_rec(ly.layer(9, 0)),
                             dss)
        rvia1 = pya.Region(ly.top_cell().begin_shapes_rec(ly.layer(11, 0)),
                           dss)
        rmetal2 = pya.Region(ly.top_cell().begin_shapes_rec(ly.layer(12, 0)),
                             dss)
        self.assertEqual(dss.is_singular(), True)

        l2n = pya.LayoutToNetlist(dss)

        l2n.register(rdiode, "diode")
        l2n.register(rpoly, "poly")
        l2n.register(rcont, "cont")
        l2n.register(rmetal1, "metal1")
        l2n.register(rvia1, "via1")
        l2n.register(rmetal2, "metal2")

        l2n.connect(rpoly)
        l2n.connect(rcont)
        l2n.connect(rmetal1)
        l2n.connect(rpoly, rcont)
        l2n.connect(rcont, rmetal1)

        l2n.extract_netlist()

        a1_3 = l2n.antenna_check(rpoly, rmetal1, 3)
        a1_10 = l2n.antenna_check(rpoly, rmetal1, 10)
        a1_30 = l2n.antenna_check(rpoly, rmetal1, 30)

        # Note: flatten.merged performs some normalization
        self.assertEqual(
            str(a1_3.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(100, 0)))), "")
        self.assertEqual(
            str(a1_10.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(101, 0)))), "")
        self.assertEqual(
            str(a1_30.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(102, 0)))), "")

        # --- same with flat

        l2n._destroy()

        input = os.path.join(ut_testsrc, "testdata", "algo", "antenna_l1.gds")
        ly = pya.Layout()
        ly.read(input)

        au = os.path.join(ut_testsrc, "testdata", "algo", "antenna_au1.gds")
        ly_au = pya.Layout()
        ly_au.read(au)

        rfdiode = pya.Region(ly.top_cell().begin_shapes_rec(ly.layer(1, 0)))
        rfpoly = pya.Region(ly.top_cell().begin_shapes_rec(ly.layer(6, 0)))
        rfcont = pya.Region(ly.top_cell().begin_shapes_rec(ly.layer(8, 0)))
        rfmetal1 = pya.Region(ly.top_cell().begin_shapes_rec(ly.layer(9, 0)))
        rfvia1 = pya.Region(ly.top_cell().begin_shapes_rec(ly.layer(11, 0)))
        rfmetal2 = pya.Region(ly.top_cell().begin_shapes_rec(ly.layer(12, 0)))
        self.assertEqual(rfdiode.is_deep(), False)
        self.assertEqual(rfpoly.is_deep(), False)
        self.assertEqual(rfmetal1.is_deep(), False)
        self.assertEqual(rfvia1.is_deep(), False)
        self.assertEqual(rfmetal2.is_deep(), False)

        l2n = pya.LayoutToNetlist(ly.top_cell().name, ly.dbu)

        l2n.register(rfdiode, "diode")
        l2n.register(rfpoly, "poly")
        l2n.register(rfcont, "cont")
        l2n.register(rfmetal1, "metal1")
        l2n.register(rfvia1, "via1")
        l2n.register(rfmetal2, "metal2")

        l2n.connect(rfpoly)
        l2n.connect(rfcont)
        l2n.connect(rfmetal1)
        l2n.connect(rfpoly, rfcont)
        l2n.connect(rfcont, rfmetal1)

        l2n.extract_netlist()

        a1_3 = l2n.antenna_check(rfpoly, rfmetal1, 3)
        a1_10 = l2n.antenna_check(rfpoly, rfmetal1, 10)
        a1_30 = l2n.antenna_check(rfpoly, rfmetal1, 30)

        # Note: flatten.merged performs some normalization
        self.assertEqual(
            str(a1_3.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(100, 0)))), "")
        self.assertEqual(
            str(a1_10.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(101, 0)))), "")
        self.assertEqual(
            str(a1_30.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(102, 0)))), "")

        # --- simple antenna check with metal2

        l2n._destroy()
        l2n = pya.LayoutToNetlist(dss)

        l2n.register(rdiode, "diode")
        l2n.register(rpoly, "poly")
        l2n.register(rcont, "cont")
        l2n.register(rmetal1, "metal1")
        l2n.register(rvia1, "via1")
        l2n.register(rmetal2, "metal2")

        l2n.connect(rpoly)
        l2n.connect(rcont)
        l2n.connect(rmetal1)
        l2n.connect(rmetal2)
        l2n.connect(rpoly, rcont)
        l2n.connect(rcont, rmetal1)
        l2n.connect(rmetal1, rvia1)
        l2n.connect(rvia1, rmetal2)

        l2n.extract_netlist()

        a2_5 = l2n.antenna_check(rpoly, rmetal2, 5)
        a2_10 = l2n.antenna_check(rpoly, rmetal2, 10)
        a2_17 = l2n.antenna_check(rpoly, rmetal2, 17)

        # Note: flatten.merged performs some normalization
        self.assertEqual(
            str(a2_5.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(200, 0)))), "")
        self.assertEqual(
            str(a2_10.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(201, 0)))), "")
        self.assertEqual(
            str(a2_17.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(202, 0)))), "")

        # --- antenna check with diodes and antenna effect reduction

        l2n._destroy()
        l2n = pya.LayoutToNetlist(dss)

        l2n.register(rdiode, "diode")
        l2n.register(rpoly, "poly")
        l2n.register(rcont, "cont")
        l2n.register(rmetal1, "metal1")
        l2n.register(rvia1, "via1")
        l2n.register(rmetal2, "metal2")

        l2n.connect(rdiode)
        l2n.connect(rpoly)
        l2n.connect(rcont)
        l2n.connect(rmetal1)
        l2n.connect(rdiode, rcont)
        l2n.connect(rpoly, rcont)
        l2n.connect(rcont, rmetal1)

        l2n.extract_netlist()

        a3_3 = l2n.antenna_check(rpoly, rmetal1, 3, [[rdiode, 8.0]])
        a3_10 = l2n.antenna_check(rpoly, rmetal1, 10, [[rdiode, 8.0]])
        a3_30 = l2n.antenna_check(rpoly, rmetal1, 30, [[rdiode, 8.0]])

        # Note: flatten.merged performs some normalization
        self.assertEqual(
            str(a3_3.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(300, 0)))), "")
        self.assertEqual(
            str(a3_10.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(301, 0)))), "")
        self.assertEqual(
            str(a3_30.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(302, 0)))), "")

        # --- antenna check with diodes

        l2n._destroy()
        l2n = pya.LayoutToNetlist(dss)

        l2n.register(rdiode, "diode")
        l2n.register(rpoly, "poly")
        l2n.register(rcont, "cont")
        l2n.register(rmetal1, "metal1")
        l2n.register(rvia1, "via1")
        l2n.register(rmetal2, "metal2")

        l2n.connect(rdiode)
        l2n.connect(rpoly)
        l2n.connect(rcont)
        l2n.connect(rmetal1)
        l2n.connect(rdiode, rcont)
        l2n.connect(rpoly, rcont)
        l2n.connect(rcont, rmetal1)

        l2n.extract_netlist()

        a4_3 = l2n.antenna_check(rpoly, rmetal1, 3, [rdiode])
        a4_10 = l2n.antenna_check(rpoly, rmetal1, 10, [rdiode])
        a4_30 = l2n.antenna_check(rpoly, rmetal1, 30, [rdiode])

        # Note: flatten.merged performs some normalization
        self.assertEqual(
            str(a4_3.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(400, 0)))), "")
        self.assertEqual(
            str(a4_10.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(401, 0)))), "")
        self.assertEqual(
            str(a4_30.flatten() ^ pya.Region(ly_au.top_cell().begin_shapes_rec(
                ly_au.layer(402, 0)))), "")