# Step 2: Building circuits¶

Result

We assemble a circuit using existing components, visualize the layout and perform a circuit simulation of the entire circuit.

Circuit of a ring resonator coupled to a grating coupler.

Illustrates

1. how to build a circuit using place and auto-route.
2. how to perform a circuit simulation of a circuit.

How to run this example

To run the example, run execute_02_circuit.py.

## Making the building blocks¶

The first step is to instantiate the building blocks we will use. As shown in step-1 of this tutorial we instantiate a ring drop filter and a grating coupler.

# 1.  Importing the technology file.
from technologies import silicon_photonics
from ipkiss3 import all as i3

# 2. Import other python libraries.
import numpy as np
import pylab as plt

# 3. Creating the ring resonator
from picazzo3.filters.ring import RingRect180DropFilter
my_ring = RingRect180DropFilter()

cp = dict(cross_coupling1=1j*0.3**0.5,
straight_coupling1=0.7**0.5) #The coupling from bus to ring and back

my_ring_cm = my_ring.CircuitModel(ring_length=2 * np.pi * my_ring_layout.bend_radius, # we can manually specify the ring length, or take it from the layout
coupler_parameters=[cp, cp]) # 2 couplers

# 4. Creating the grating coupler.
from picazzo3.fibcoup.curved import FiberCouplerCurvedGrating
my_grating = FiberCouplerCurvedGrating()
my_grating_layout = my_grating.Layout(n_o_lines=24, period_x=0.65, box_width=15.5)
my_grating_cm = my_grating.CircuitModel(center_wavelength=1.55,
bandwidth_3dB=0.06,
peak_transmission=0.60**0.5,
reflection=0.05**0.5)



## Layout¶

The simplest way of building circuits in IPKISS is to use PlaceAndAutoRoute. PlaceAndAutoRoute is a generic PICAZZO component that allows you to easily define connectivity between a number of child cells. When placing these child cells, PlaceAndAutoRoute will then generate all the waveguides (as separate PCells) needed to connect the child cells together.

In order to create a PlaceAndAutoRoute cell we have to create a dictionary of:

• child_cells : a dictionary with the names of the child cell instances as keys. You can have multiple instances of each child cell.
• links : a list of tuples with the end terms of each link. We identify the terms through the name of the instance and the name of the term, like inst:term. The terms of the PICAZZO ring resonators are named in1, in2, out1, out2. The terms of the grating couplers are called out and vertical_in.

In the Layout of the PlaceAndAutoRoute you can provide:

• child_transformations : a Python dict containing all the transformations that apply to each component. Those transformations usually include translations and rotations
from picazzo3.routing.place_route import PlaceAndAutoRoute
my_circuit = PlaceAndAutoRoute(child_cells={"in_grating": my_grating,
"pass_grating": my_grating,
"drop_grating" : my_grating,
"ring" : my_ring},

("pass_grating:out", "ring:out1"),
("drop_grating:out", "ring:out2")]
)

distance_x = 100.0
distance_y = 30.0
my_circuit_layout = my_circuit.Layout(child_transformations={"ring": (0, 0),
"in_grating": i3.Rotation(rotation=0) + i3.Translation((-distance_x, -distance_y)),
"pass_grating": i3.Rotation(rotation=180) + i3.Translation((distance_x, -distance_y)),
"drop_grating": i3.Rotation(rotation=0) + i3.Translation((-distance_x, distance_y)),
})
my_circuit_layout.visualize()



Layout of a ring resonator connected to grating couplers.

## CircuitModel¶

The circuit model of a circuit is automatically composed from the circuit models of all of its subcomponents. The default simulation model of the waveguide extracts its length from the layout. This is a very powerful technique in IPKISS; this means you can run post-layout simulations to get an accurate representation of the circuit behavior, taking into account layout-dependent properties of the system.

my_circuit_cm = my_circuit.CircuitModel()
wavelengths = np.linspace(1.50, 1.6, 2001)
S = my_circuit_cm.get_smatrix(wavelengths=wavelengths)

# 7. Plot
plt.plot(wavelengths, np.abs(S['in_grating_vertical_in', 'pass_grating_vertical_in'])**2, 'b', label="pass")
plt.plot(wavelengths, np.abs(S['in_grating_vertical_in', 'drop_grating_vertical_in'])**2, 'r', label="drop")
plt.plot(wavelengths, np.abs(S['in_grating_vertical_in', 'in_grating_vertical_in'])**2, 'k', label="reflection")
plt.legend()
plt.show()


In the simulation, you clearly see the interference fringes that are obtained due to the reflections in grating couplers. The period of those fringes is based on the distance between the grating couplers and that information is obtained form the LayoutView. If you modify your layout - the simulations will follow accordingly.

Note

The name of the terms of the place and route component (these are all the terms that are not connected by links) is obtained by composition of the name of the child with the name of the term of the child.

Transmission and reflection spectra of a ring resonator connected to grating couplers, obtained by circuit simulation.

You have just finished your first tutorial!

### Recap¶

In this tutorial you learned how to assemble a circuit of existing Picazzo components. You can also learn how to write your own (hierarchical) components from scratch. This is the subject of the next tutorials.

Take me back to the overview!