# Phase shifters¶

SiFab contains electro-optic components that modulate the phase of the light when a voltage difference is applied.

## PhaseShifterWaveguide¶

This PCell is an electro-optical waveguide with adjustable length. The p-n junction is centered in the middle of the optical waveguide and can be offset by tuning the property junction_offset. Many other properties can be controlled and are listed below.

• The width and offset of the doped regions:

• p_width
• pplus_offset
• pplus_extension
• n_width
• nplus_offset
• nplus_extension
• The offset of the contacts and vias:

• nr_contact_rows_p
• nr_contact_rows_n
• contact_offset_p
• contact_offset_n
• contact_pitch
• m1_width
• m1_offset
• m2_width
• m2_offset
• nr_via_rows
• via_pitch
• via_offset
from si_fab import all as pdk
from ipkiss3 import all as i3

# Phase Shifter
ps = pdk.PhaseShifterWaveguide(length=20.0,
trace_template=pdk.RWG450(),
junction_offset=-0.1,
p_width=4.0,
pplus_offset=1.5,
pplus_extension=0.25,
n_width=4.0,
nplus_offset=1.5,
nplus_extension=0.25,
nr_contact_rows_p=3,
nr_contact_rows_n=3,
contact_offset_p=2.025,
contact_offset_n=2.025,
contact_pitch=0.6,
m1_width=3.6,
m1_offset=2.0,
m2_width=2.8,
m2_offset=3.2,
nr_via_rows=4,
via_pitch=0.6,
via_offset=3.8)

ps_lv = ps.Layout()
ps_lv.visualize(annotate=True)
xs = ps_lv.cross_section(cross_section_path=i3.Shape([(1.0, -8.0), (1.0, 8.0)]))
xs.visualize()
ps_lv.write_gdsii("ps.gds")


### Model and simulation recipes¶

The phase of the waveguide is calculated using the effective index ($$n_{eff}$$) of the trace template (trace_template) used to draw the waveguide. The model of the heater adds a phase modulation to the phase of the waveguide that is calculated as follows:

$\Delta \Phi = \frac{\pi L V_d}{ V_{\pi} L_{\pi}}$

where

• $$L$$ is the length of the phase shifter;
• $$V_d$$ is the voltage drop over the phase shifter junction;
• $$V_{\pi} L_{\pi}$$ is the efficiency of the phase shifter.

The voltage $$V_d$$ is associated with a delay $$\tau$$ that is, in first approximation, equal to $$RC$$. The resistance $$R$$ equals the output impedance of the driving electronics. The capacitance $$C$$ equals the total electrical capacitance over the junction, which is usually dominated by the junction capacitance. This model does not account for the voltage dependence of $$V_{\pi} L_{\pi}$$ and $$\tau$$. In addition, their values are not linked to the layout and need to be calculated or measured independently.

Using the simulation recipe simulate_phaseshifter, one can easily check the phase shift achieved by a specified voltage, as well as the speed to achieve this response. Here we apply a voltage of $$V_{\pi} L_{\pi}$$ V on a modulator that has length of 1 cm, which gives a phase shift of $$\pi$$.

from si_fab import all as pdk
from si_fab.components.phase_shifter.simulate.simulate import simulate_phaseshifter
import pylab as plt
import numpy as np
import os

# Phase Shifter
name = "simple_step"
results_array = []
length = 1e4
ps = pdk.PhaseShifterWaveguide(length=length,
trace_template=pdk.RWG450(),
junction_offset=-0.1)
vpi_lpi = 1.2
Cl = 1.1e-15  # F/um
R = 50
tau = ps.length * Cl * R
ps.CircuitModel(vpi_lpi=vpi_lpi)

results = simulate_phaseshifter(cell=ps,
nsteps=1000,
dt=5e-12,
step_amplitude=vpi_lpi,
center_wavelength=1.5,
simulate_sources=True,
simulate_circuit=True,
debug=False)
times = results["timesteps"]
results_array.append(results)

def phase_unwrap_normalize(results):
unwrapped = np.unwrap(np.angle(results))
return (unwrapped-unwrapped[1] * np.ones(unwrapped.shape))/np.pi

outputs = ["in", "elec1", "elec2", "out"]
process = [np.real, np.real, np.real, phase_unwrap_normalize]
ylabels = ["V/m", "V", "V", "rad"]
fig, axs = plt.subplots(nrows=len(outputs), ncols=1, figsize=(6, 8))

for cnt, (f, pn, ylabel) in enumerate(zip(process, outputs, ylabels)):
axs[cnt].set_title(pn)
axs[cnt].plot(times, f(results[pn]), label="length: {}".format(length))
axs[cnt].set_ylabel(ylabel)

plt.tight_layout()
fig.savefig(os.path.join("{}.png".format(name)), bbox_inches='tight')