本篇教程将会展示:
将一个光栅耦合器输出为 GDSⅡ 版图
1. 导入所需的 PDK 库以及 IPKISS 函数库等。此示例中,使用的是 Luceda academy 自带的示例 PDK:
si_fab
。from si_fab import all as pdk
from ipkiss3 import all as i3
import numpy as np
import pylab as plt
注意
2. 调用已有器件库中的器件并输出为 GDSⅡ 文件
(1) 从 Picazzo 通用器件库中调用一个光纤光栅耦合器:
FiberCouplerCurvedGrating
。from picazzo3.fibcoup.curved.cell import FiberCouplerCurvedGrating
【在 Luceda IPKISS 中有三种器件设计的方式】
- 从不同流片厂的 pdk 中调用已有器件,具体可查看相应的
文件all.py
- 从 IPKISS 内置的通用器件库
中调用现有器件(本案例所采用的方式)Picazzo
- 通过参数化单元
自定义器件(包括器件属性+布局视图+网表视图+行为模型视图)i3.PCell
(2) 创建并输出 GDSⅡ 文件
给调用的器件定义唯一名称
unique_grating_name_used_in_GDSII
,并对其实例化
,通过write_gdsii
函数将实例化的光纤光栅耦合器输出为 GDSⅡ 文件,文件名为my_grating.gds
。my_grating = FiberCouplerCurvedGrating(
name = "unique_grating_name_used_in_GDSⅡ"
)
my_grating_layout = my_grating.Layout()
my_grating_layout_ports = my_grating_layout.ports
my_grating_layout.visualize()
my_grating_layout.write_gdsii("my_grating.gds")
(3) 定义光栅耦合器的仿真模型
用
i3.CompactModel
生成光栅耦合器的紧凑型模型,需要定义以下属性及方法:- 定义该紧凑型模型所需要的所有参数
(包括:用来计算散射矩阵或频率响应、时间响应等参数),还可以提供参数的默认值。在光栅耦合器中需要定义 3dB 带宽、传输谱峰值、中心波长、反射率。parameters
- 定义期间的端口
(注意区别于布局视图terms
下需要构建器件交互端口时所用到的i3.Layoutview
)。在光栅耦合器中包含两个端口,一个是与光纤垂直耦合的端口i3.OpticalPort
,一个是与波导连接的输入端口vertical_in
。in
- 定义计算散射矩阵的方法:
。由于光栅耦合器是一个具有固定反射参数的简单高斯模型,因此有以下关系:calculate_smatrix
class GratingModel(i3.CompactModel):
parameters = [
"bandwidth_3dB",
"peak_transmission",
"center_wavelength",
"reflection",
]
terms = [
i3.OpticalTerm(name="in"),
i3.OpticalTerm(name="vertical_in"),
]
def calculate_smatrix(parameters, env, S):
sigma = parameters.bandwidth_3dB / 2.35482
power_S = parameters.peak_transmission * np.exp(
-((env.wavelength - parameters.center_wavelength) ** 2.0 / (2.0 * sigma ** 2.0))
)
S["vertical_in","in"] = S["in","vertical_in"] = np.sqrt(power_S)
S["in","in"] = parameters.reflection
导入 GDSⅡ 版图
1.
使用
i3.GDSCell
导入 GDSⅡ 文件 定义一个继承自
i3.GDSCell
的类ImportedGrating
,其作用类似于用i3.PCell
来定义器件。class ImportedGrating(i3.GDSCell):
def _default_filename(self):
return "my_grating.gds" # gdsii 文件的路径,该文件包含要导入的单元
def _default_cell_name(self):
return "unique_grating_name_used_in_GDSII" # 要导入 gdsii 文件中的单元名称
2. 构建布局视图
由于导入的
GDSCell
还没有端口信息,所以我们需要先在class ImportedGrating
下构建布局视图,给器件添加端口。 class Layout(i3.GDSCell.Layout):
# 导入的GDS已经包含视图属性及器件基本形状,因此省去了定义property及_generate_elements的步骤
def _generate_ports(self, ports):
ports += i3.OpticalPort(
name = "in",
position = (20.0, 0.0),
angle = 0.0,
) # 需要手动设置端口,因为gdsii文件中还没有此信息
ports += i3.VerticalOpticalPort(
name = "vertical_in",
position = (0.0, 0.0),
inclination = 90.0, # 轨道倾角,垂直耦合
angle = 0.0,
)
return ports
3. 构建行为模型视图
为了对导入的
GDSCell
进行器件/线路仿真 ,我们还需要在class ImportedGrating
下构建行为模型视图,这里使用_generate_model
方法调用前面定义的紧凑型模型来生成CircuitModel
class CircuitModel(i3.CircuitModelView):
center_wavelength = i3.PositiveNumberProperty(default=1.55, doc = "center wavelength[um]")
bandwidth_3dB = i3.PositiveNumberProperty(default=0.060, doc = "3dB bamdwidth[um]")
peak_transmission = i3.NonNegativeNumberProperty(default=1.0, doc = "peak transmission (0 to 1)")
reflection = i3.ComplexFractionProperty(default=0.0, doc = "Complex reflection back into the waveguide")
def _generate_model(self):
return GratingModel(
center_wavelength = self.center_wavelength,
bandwidth_3dB = self.bandwidth_3dB,
peak_transmission = self.peak_transmission,
reflection = self.reflection,
)
实例化导入的 GDSCell
定义后的 GDSCell 和 PCell 一样,可以被调用、实例化,用于绘制更复杂的线路版图,还可以进行线路仿真。
1. 实例化、可视化版图
# 实例化导入的光栅耦合器的布局视图
grating_cell = ImportedGrating()
grating_lv = grating_cell.Layout()
grating_lv.visualize(annotate = True)
2. 线路仿真
# 实例化导入的光栅耦合器的线路模型视图并进行线路仿真
grating_cm = grating_cell.CircuitModel(bandwidth_3dB=0.1, peak_transmission=0.6)
wavelengths = np.linspace(1.5, 1.6, 51)
S = grating_cm.get_smatrix(wavelengths=wavelengths)
plt.plot(wavelengths, np.abs(S["vertical_in","in"]) ** 2, '-', linewidth=2.2)
plt.xlabel('Wavelength [um]', fontsize=16)
plt.ylabel('Transmission [dB]', fontsize=16)
plt.show()
完整代码
from si_fab import all as pdk
from ipkiss3 import all as i3
import numpy as np
import pylab as plt
# 1.将已有的设计导出为GDSⅡ格式文件
from picazzo3.fibcoup.curved.cell import FiberCouplerCurvedGrating
my_grating = FiberCouplerCurvedGrating(
name = "unique_grating_name_used_in_GDSII"
)
my_grating_layout = my_grating.Layout()
my_grating_layout_ports = my_grating_layout.ports
my_grating_layout.visualize()
my_grating_layout.write_gdsii("my_grating.gds")
class GratingModel(i3.CompactModel):
parameters = [
"bandwidth_3dB",
"peak_transmission",
"center_wavelength",
"reflection",
]
terms = [
i3.OpticalTerm(name="in"),
i3.OpticalTerm(name="vertical_in"),
]
def calculate_smatrix(parameters, env, S):
sigma = parameters.bandwidth_3dB / 2.35482
power_S = parameters.peak_transmission * np.exp(
-((env.wavelength - parameters.center_wavelength) ** 2.0 / (2.0 * sigma ** 2.0))
)
S["vertical_in","in"] = S["in","vertical_in"] = np.sqrt(power_S)
S["in","in"] = parameters.reflection
# 2.将生成的GDSⅡ文件导入IPKISS中
class ImportedGrating(i3.GDSCell):
def _default_filename(self):
return "my_grating.gds"
def _default_cell_name(self):
return "unique_grating_name_used_in_GDSII"
class Layout(i3.GDSCell.Layout):
def _generate_ports(self, ports):
ports += i3.OpticalPort(
name = "in",
position = (20.0, 0.0),
angle = 0.0,
)
ports += i3.VerticalOpticalPort(
name = "vertical_in",
position = (0.0, 0.0),
inclination = 90.0,
angle = 0.0,
)
return ports
class CircuitModel(i3.CircuitModelView):
center_wavelength = i3.PositiveNumberProperty(default=1.55, doc = "center wavelength[um]")
bandwidth_3dB = i3.PositiveNumberProperty(default=0.060, doc = "3dB bamdwidth[um]")
peak_transmission = i3.NonNegativeNumberProperty(default=1.0, doc = "peak transmission (0 to 1)")
reflection = i3.ComplexFractionProperty(default=0.0, doc = "Complex reflection back into the waveguide")
def _generate_model(self):
return GratingModel(
center_wavelength = self.center_wavelength,
bandwidth_3dB = self.bandwidth_3dB,
peak_transmission = self.peak_transmission,
reflection = self.reflection,
)
# 3. 使用“布局视图”、“行为模型视图”实例化导入的GDS Cell
grating_cell = ImportedGrating()
grating_lv = grating_cell.Layout()
grating_lv.visualize(annotate = True)
grating_cm = grating_cell.CircuitModel(bandwidth_3dB=0.1, peak_transmission=0.6)
wavelengths = np.linspace(1.5, 1.6, 51)
S = grating_cm.get_smatrix(wavelengths=wavelengths)
plt.plot(wavelengths, np.abs(S["vertical_in","in"]) ** 2, '-', linewidth=2.2)
plt.xlabel('Wavelength [um]', fontsize=16)
plt.ylabel('Transmission [dB]', fontsize=16)
plt.show()
参考文档:Luceda 官方技术文档:Creating a Cell from an Existing GDSII