在ipkiss中,通常以i3.Circuit来设计线路(见教程2),以i3.Pcell的框架也可以来设计线路:
以SplitterTree为例:
线路仿真结果:
所有代码如下:
from si_fab import all as pdk
import ipkiss3.all as i3class SplitterTree(i3.PCell):class Layout(i3.LayoutView):def _generate_instances(self, insts):insts += i3.place_and_route(insts={"splitter1": pdk.MMI1x2Optimized1550(),"splitter2": pdk.MMI1x2Optimized1550(),"splitter3": pdk.MMI1x2Optimized1550(),},specs=[i3.Place('splitter1', (0, 0)),i3.Place('splitter2', (100, -30)),i3.Place('splitter3', (100, 30)),])insts = i3.place_and_route(insts=insts,specs=[i3.ConnectBend("splitter1:out1", "splitter2:in1", bend_radius=10),i3.ConnectBend("splitter1:out2", "splitter3:in1", bend_radius=10),])return instsdef _generate_ports(self, ports):ports += i3.expose_ports(instances=self.instances,port_name_map={"splitter1:in1": "in1","splitter2:out1": "out1","splitter2:out2": "out2","splitter3:out1": "out3","splitter3:out2": "out4",})return portsclass Netlist(i3.NetlistFromLayout):passclass CircuitModel(i3.CircuitModelView):def _generate_model(self):return i3.HierarchicalModel.from_netlistview(self.netlist_view)if __name__ == '__main__':SplitterTree().Layout().visualize(annotate=True)import numpy as npfrom matplotlib import pyplot as pltwavelengths = np.linspace(1.5, 1.6, 2001)cm = SplitterTree().CircuitModel()S = cm.get_smatrix(wavelengths=wavelengths)plt.plot(wavelengths, i3.signal_power_dB(S["out1", "in1"]), label="in1 -> out1")plt.plot(wavelengths, i3.signal_power_dB(S["out2", "in1"]), label="in1 -> out2")plt.plot(wavelengths, i3.signal_power_dB(S["out3", "in1"]), label="in1 -> out3")plt.plot(wavelengths, i3.signal_power_dB(S["out4", "in1"]), label="in1 -> out4")plt.plot(wavelengths, i3.signal_power_dB(S["in1", "in1"]), label="in1 -> in1")plt.legend()plt.xlabel("Wavelengths [um]")plt.ylabel("Transmission")plt.show()
以pcell的方式定义线路需要分别定义:Layout、Netlist 以及CircuitModel
Layout给出线路的版图:
class Layout(i3.LayoutView):def _generate_instances(self, insts):insts += i3.place_and_route(insts={"splitter1": pdk.MMI1x2Optimized1550(),"splitter2": pdk.MMI1x2Optimized1550(),"splitter3": pdk.MMI1x2Optimized1550(),},specs=[i3.Place('splitter1', (0, 0)),i3.Place('splitter2', (100, -30)),i3.Place('splitter3', (100, 30)),])insts = i3.place_and_route(insts=insts,specs=[i3.ConnectBend("splitter1:out1", "splitter2:in1", bend_radius=10),i3.ConnectBend("splitter1:out2", "splitter3:in1", bend_radius=10),])return instsdef _generate_ports(self, ports):ports += i3.expose_ports(instances=self.instances,port_name_map={"splitter1:in1": "in1","splitter2:out1": "out1","splitter2:out2": "out2","splitter3:out1": "out3","splitter3:out2": "out4",})return ports
Netlist 给出线路中的逻辑连接关系:
layout中定义了ports,Netlist可以直接从Layout继承
class Netlist(i3.NetlistFromLayout):pass
CircuitModel 给出线路中的逻辑连接关系:
线路中的每个器件都有了CircuitModel,所有整个线路的CircuitModel可以通过HierarchicalModel来定义
class CircuitModel(i3.CircuitModelView):def _generate_model(self):return i3.HierarchicalModel.from_netlistview(self.netlist_view)
线路仿真:
import numpy as npfrom matplotlib import pyplot as pltwavelengths = np.linspace(1.5, 1.6, 2001)cm = SplitterTree().CircuitModel()S = cm.get_smatrix(wavelengths=wavelengths)plt.plot(wavelengths, i3.signal_power_dB(S["out1", "in1"]), label="in1 -> out1")plt.plot(wavelengths, i3.signal_power_dB(S["out2", "in1"]), label="in1 -> out2")plt.plot(wavelengths, i3.signal_power_dB(S["out3", "in1"]), label="in1 -> out3")plt.plot(wavelengths, i3.signal_power_dB(S["out4", "in1"]), label="in1 -> out4")plt.plot(wavelengths, i3.signal_power_dB(S["in1", "in1"]), label="in1 -> in1")plt.legend()plt.xlabel("Wavelengths [um]")plt.ylabel("Transmission")plt.show()
线路仿真结果: