luceda ipkiss教程 71:统计线路中器件的个数

**案例分享:**统计线路中某一器件的个数
如,统计SplitterTree中mmi的个数:
在这里插入图片描述
在这里插入图片描述
所有代码如下:

# Copyright (C) 2020 Luceda Photonics

from si_fab import all as pdk
from ipkiss3 import all as i3


class GeneralizedSplitterTree(i3.Circuit):
    splitter = i3.ChildCellProperty(doc="Splitter used.")
    n_levels = i3.PositiveIntProperty(default=3, doc="Number of tree levels.")
    spacing_x = i3.PositiveNumberProperty(default=100.0, doc="Horizontal spacing between the splitter levels.")
    spacing_y = i3.PositiveNumberProperty(default=50.0, doc="Vertical spacing between the splitters in the last level.")

    def _default_splitter(self):
        return pdk.MMI1x2Optimized1550()  # try changing this to the y-junction in the si_fab PDK

    def _default_insts(self):
        insts = {}

        # 1.  Using nested for loops we can add all the splitters we need for the circuit, as well as name them
        # according to their position (level) in the circuit. Also note that the splitter is a parameter, so we could
        # easily replace all the MMIs with different MMIs or a y-splitter with just one change to the code.

        for level in range(self.n_levels):
            for splitter_no in range(2 ** level):
                insts[f"sp_{level}_{splitter_no}"] = self.splitter
        return insts

    def _default_specs(self):
        specs = []

        # 2. Placing the MMIs is fairly straight forward, using local variables of x and y coordinates to help improve
        # the readability of the code. The "y-coord" in particular is not obvious, however the coordinate is derived
        # from the level and number in each level due to the relationship between each MMI. Again we use nested for
        # loops to achieve this.

        for level in range(self.n_levels):
            for splitter in range(2 ** level):
                x_coord = level * self.spacing_x
                y_coord = self.spacing_y * (
                        -0.5 * 2 ** (self.n_levels - 1) + ((splitter + 0.5) * 2 ** (self.n_levels - level - 1))
                )
                specs.append(i3.Place(f"sp_{level}_{splitter}", (x_coord, y_coord)))

        # 3. For each MMI there are two output ports that need connecting. We decide how best to do this, using
        # "splitter % 2" which returns the remainder from dividing by 2. This will be 0 for even numbers and non-zero
        # for odd numbers. In this way we can separate the two outputs correctly.
        # In the level loop we start at 1, but then subtract 1 during the naming as the final level will not have any
        # connections.

        for level in range(1, self.n_levels):
            for splitter in range(2 ** level):
                if splitter % 2 == 0:
                    in_port = f"sp_{level - 1}_{int(splitter / 2)}:out1"
                else:
                    in_port = f"sp_{level - 1}_{int(splitter / 2)}:out2"
                out_port = f"sp_{level}_{splitter}:in1"
                specs.append(i3.ConnectBend(in_port, out_port))
        return specs

    def _default_exposed_ports(self):
        # 4. In the same way we can expose the ports in the circuit. By default, all unconnected ports would be exposed,
        # but we want to rename them for simplicity.

        exposed_ports = {"sp_0_0:in1": "in"}  # adding the input port
        cnt = 1  # we use a local variable to keep track of how many output we have labeled
        level = self.n_levels - 1
        n_splitters = 2 ** level
        for splitter in range(n_splitters):  # looping over the output ports
            exposed_ports[f"sp_{level}_{splitter}:out1"] = f"out{cnt}"
            cnt += 1
            exposed_ports[f"sp_{level}_{splitter}:out2"] = f"out{cnt}"
            cnt += 1
        return exposed_ports


if __name__ == "__main__":
    splitter_tree1 = GeneralizedSplitterTree(n_levels=5, splitter=pdk.MMI1x2Optimized1550())
    splitter_tree1_layout = splitter_tree1.Layout()
    splitter_tree1_layout.visualize()

    component_counted = pdk.MMI1x2Optimized1550()
    num_mmi = sum(1 for elems in splitter_tree1.Layout().layout if component_counted.name in elems.reference.name)
    print(num_mmi)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值