Corner analysis
Now that we are aware of how the circuit works, let’s analyze its corners. Corners represent the extreme values (e.g., minimum and maximum) that key parameters can take due to process variations. They are commonly defined by two values along with the Nominal: Minimum and Maximum. The nominal value is the parameter’s default, corresponding to the ideal, quasi-perfect conditions we used for the initial simulation. The minimum and maximum corners define the range over which the parameter can deviate from its default value.
For code readability and to work as a team on different aspects of the circuit, the corners are defined in a configuration file (models.yaml) which tells the CA what is modified in the CM and in a mutation file (models.py) which tells the CA how they are modified. These files are in a ca_config folder which our Circuit Analyzer will read from and follow this structure:
ca_config/
├── models.py
└── models.yaml
Building your models.yaml and models.py file
To run a corner analysis, we must first identify the key design parameters we want to vary. Then, we must understand how these parameters relate to the underlying compact model parameters of our circuit’s components.
When referring to parameters, let us start by clarifying that there are two types: (1) fabrication/performance parameters and (2) compact model parameters.
Fabrication or performance parameters corresponding to physical or behavioral variations, such as width or thickness variations, or variations in waveguide losses. Any variation of the user’s choosing can be described.
Compact model parameters are those needed to give to the component’s compact model to be able to calculate the scattering matrix.
The models.yaml file defines the design parameters and their corner values (min, nominal, max). The models.py file then translates these design parameters into the specific compact model parameters. These two files must be consistent, which often requires checking the compact model arguments in the PCell definition.
A very simple option is to use compact model parameters on both files and make a direct correspondence in models.py. The yaml file needs to follow the structure below:
version: 1
libraries:
si_fab: # your library. Can be generic_devices as well or an added component in libraries/pteam_library...
cells:
HeatedWaveguide: # Your chosen component
parameters:
loss:
doc: "loss in dB/m" #parameter description
default: 60
corners: [50, 60, 70]
generate_parameters: "models.heated_waveguide_parameters" # method were parameters are used
In the models.yaml file, we defined the corners for our Beneš switch:
\([0.45, 0.5, 0.65]\) as cross_coupling in the directional coupler.
\([1.1, 1.2, 1.3]\) and \([50, 60, 70]\) as width and loss in the heated waveguide respectively.
With this definition, the models.py will have the methods that take the corners and give them to the parameters of the compact models. We added a small multiplication to the loss parameter to match the units (defined per meter in yaml and per centimeter in CM).
def directional_coupler_parameters(self: library.DirectionalCouplerDC2.CircuitModel, **parameters):
return {
"cross_coupling": np.array([parameters["cross_coupling"]]),
}
def heated_waveguide_parameters(self: pdk.HeatedWaveguide.CircuitModel, **parameters):
return {
"width": parameters["width"],
"loss_db_per_cm": parameters["loss"] * 1e-2,
}
To sum up the process so far:
Select a circuit. Ideally, run a simulation to become familiar with its behavior.
Define, in a yaml file, the parameters you want to vary in the circuit.
Write a models script where you make correspondence between the parameters defined in the yaml file and the compact models’ parameters.
After these 3 steps, we are ready to run corner analysis!
Running CA for Corner Analysis
Once the circuit is selected and the corners are defined, we can start with a basic corner analysis.
We could analyze all corners via ca.corner_analysis_all_combinations, which gives us a lot of information.
However, this can become overwhelming — especially as the number of corners or circuit size increases.
If we have 2 parameters, each with the standard 3 values, we have 9 possibilities.
For 4 parameters - slightly more realistic - it leads to 81 possibilities.
Therefore, we will use ca.corner_analysis which runs for a specific corner selection.
We chose to analyze three specific scenarios: one where all parameters are at their ‘min’ values, one where they are all ‘nominal’, and one where they are all at their ‘max’ values.
This results in 3 distinct simulations:
The minimum corner corresponds to a corner value where all parameters have their minimum value.
The nominal value sets all parameters to their nominal value (which would be the default case).
The maximum corner corresponds to a corner value where all parameters have their maximum value.
ca_config_path = os.path.join(os.path.dirname(__file__), "ca_config")
with ca.setup(ca_config_path):
crns = get_corners(model_4x4)
print(crns) # we can print the corners to verify them
# corners calculation; cycle to select "min", "nominal", "max" to analyze
corner_values = []
for corner in ["min", "nominal", "max"]:
kwargs = {c: corner for c in crns}
smat = ca.corner_analysis(
circuit_model=model_4x4,
wavelengths=wavelengths,
**kwargs,
)
corner_values.append(smat)
ca.visualize_smatrices(
title="Beneš switch min, nominal and max corners 4x4",
smatrices=corner_values,
term_pairs=[("in_4", "out_1"), ("in_4", "out_2"), ("in_4", "out_3"), ("in_4", "out_4")],
smatrix_names=["min", "nominal", "max"],
)
With our S-matrix visualizer, we can easily edit the size of the S-matrix by excluding the ports of no interest (electrical in our case and keeping in_4 only) or select them as term_pairs in code. Changing the Layout theme to “Corner Analysis” once the visualizer opens provides the following visualization. Applying this Plot Theme helps clearly distinguish the results from each individual corner run:
4x4 Beneš switch with selected corner analysis for input 4
In this figure, we used the ‘Plot editor’ in our visualizer to open a small window to manage the S-matrix. There, we controlled the size and entries shown in the S-matrix by toggling them and selected the four entries of interest to us to plot. The entries to be plotted can be specified directly in code, bypassing the need to toggle them in the editor. As expected, if we take corners of “nominal” for all the parameters, it will correspond to the usual simulation as in the first section of this tutorial. Additionally we see the effect of the corners in dashed lines.
From Canvas, we can also open this project and run the CornerAnalysis codelet which runs ca.corner_analysis_all_combinations and we can select which entries to observe.
For completeness, the following figure plots this for input 4 as well:
4x4 Beneš switch all corners analysis for input 4
Note
When running from Canvas, you still need to define models.py separately and you need to provide the path to the model.yaml file to the codelet. Once that is done, you can also modify your corners directly in IPKISS Canvas.
Once the codelet is properly configured with a models.py script, Canvas allows to directly change the corners with adding new parameters, replace values and much more! A window will pop up as in next figure to allow this.
Window on IPKISS Canvas to adjust the corners in CornerAnalysis codelet
In this section, we have taken a significant step beyond nominal simulation by introducing corner analysis.
We have learned how to define process variation corners for our circuit components using models.yaml and models.py, and how to map these variations to the underlying compact models.
By running a corner analysis, we visualized the performance envelope of our 4x4 Beneš switch, observing how the transmission spectrum is affected by best-case and worst-case parameter deviations.
This analysis provides crucial insights into the robustness of our design.
However, it only shows the behavior at the extremes.
To get a more complete statistical picture of how our circuit will perform in a real-world manufacturing environment, the next logical step is to perform a Monte Carlo analysis.
You can find an example of a Monte Carlo analysis on this switch in samples/circuit_analyzer/switch_analysis/example2_monte_carlo.py script.
This will allow us to predict yield and understand the statistical distribution of our circuit’s performance metrics.