在用i3.circuit设计线路时,往往需要给暴露的端口命名,通过:
def _default_exposed_ports(self):
可以自由选择暴露的端口,并进行命名,这样命名对于画版图是没问题的,但是如果需要对设计的线路进行仿真,那么就需要对所有的端口进行命名。而有时对不需要仿真的端口进行命名又过于麻烦,此时就可以通过i3.expose_ports来选择暴露的端口,并进行命名,而没有命名的端口会自动生成端口名称,这样即简化了命名,又可以进行线路仿真。
具体可以参考下面的例子:
from si_fab import all as pdk
from ipkiss3 import all as i3
class routed_dc(i3.Circuit):
_name_prefix = "routed_dc"
dc = i3.ChildCellProperty(doc="Directional coupler in circuit")
def _default_dc(self):
return pdk.SiDirectionalCouplerSPower(power_fraction=0.5, target_wavelength=1.55)
def _default_insts(self):
insts = { "dc": self.dc,}
return insts
def _default_specs(self):
ports = self.dc.get_default_view(i3.LayoutView).ports
dy = 15
x1 = ports["out2"].x
y1 = ports["out2"].y
x2 = ports["out1"].x
y2 = ports["out1"].y
opt1 = i3.OpticalPort(position=(x1, y1 + dy), angle=180, trace_template=pdk.SWG450())
opt2 = i3.OpticalPort(position=(x2, y2 - dy), angle=180, trace_template=pdk.SWG450())
specs = [
i3.Place("dc", (0, 0)),
i3.ConnectManhattan(opt2, "dc:in1", bend_radius=5),
i3.ConnectManhattan(opt1, "dc:in2", bend_radius=5),
]
return specs
class Layout(i3.Circuit.Layout):
def _generate_ports(self, ports):
map = {
"dc:out1": "out2",
"dc:out2": "out3",
}
ports = i3.expose_ports(
self.instances,
optical='all',
port_name_map=map,
electrical='all',
)
return ports
if __name__ == '__main__':
r_dc = routed_dc()
my_circuit = r_dc.Layout()
print(r_dc.Netlist())
my_circuit.visualize(annotate=True)
my_circuit.write_gdsii("Rounted_dc.gds")
在代码中,可以自定义需要命名的端口:
map = {
"dc_1:in1": "in1",
"dc_1:in2": "in2",
}
剩下的没有暴露的端口,包括光学端口和电学端口,都可以通过expose_ports自动命名:
ports = i3.expose_ports(
self.instances,
optical='all',
port_name_map=map,
electrical='all',
)
代码最终运行结果如下: