# mxPIC Quick-Reference Style Guide Welcome to the collaboration of the repository of **mxPIC** program. This repository is aimed for a self-designed PDK that based on ***nazca***, ***gdstk*** and other libraries for the functional build up of photonic integrated circuits (PIC). This is the fast-track guide to contributing to **mxPIC**. Adherence to these rules is mandatory to pass the automated CI/CD pipeline. ### 0. Installation dependencies - python 3.10.1 - nazca 0.5.13 - gdstk 1.0.0 - numpy 1.22.3 - pandas 1.3.3 - matplotlib 3.4.3 - Cython 3.2.4 - Sphnix 7.4.7 - myst-parser 3.0.1 - sphinx-rtd-theme 3.1.0 ``` pip install sphinx myst-parser sphinx-rtd-theme gdstk==1.0.0 ``` ## 1. File & architecture The repository have an archtecture like this. ``` mxpic_forge/ ├── primitives/ │ ├── edge_couplers/ │ │ └── EC_dual_layer_px3.py │ ├── multimode_interferomters/ │ ├── directional_couplers/ │ ├── grating_couplers/ │ └── microring_modulators/ ├── composite/ │ └── mach_zender_modulators/ ├── electronics/ │ ├── resistors/ │ ├── inductors/ │ ├── vias/ │ └── pads/ ├── others/ ├── structures/ ├── routing/ ├── foundries/ └── docs/ └── source/ └── conf.py ``` ## 2. Annotation & Documentation We strictly use **Type Hints** (PEP 484) and **NumPy-Style Docstrings**. * **Rule:** Every function MUST have its parameter types and return type explicitly declared. * **Rule:** Use `"""` for docstrings, broken into `Parameters` and `Returns` sections. ```diff - class Waveguide(length, width): - """Builds a Mach-Zehnder.""" - pass + class Waveguide(length: float, width: float = 0.5) -> nazca.Cell: + """ + Generates an MZM layout. + + Parameters + ---------- + length : float + Arm length in microns. + width : float, optional + Waveguide width in microns. + + Returns + ------- + list[tuple] + Polygon vertices. + """ + pass ``` --- ## 3. Class mangement of devices The devices are divided into four major types, which is **primitives, composite, electronics, and others**. All photonic and electronic devices are built within the for types. In the definitial of classes, compulsary keys are required, including **name** , **show_pins** , all defaults are None. All classes are cored at the **cell** class of **nazca**, which is generated through an internal method named "generate_gds" ``` python class GratingCoupler(): def __init__(self,name:"str"=None,....,show_pins:bool=None) ... ... self.cell = self.generate_gds() ## the generation of cell def generate_gds(self) -> nazca.Cell: """ Creating the cell of the device """ with nd.Cell(name=self.name,inst) as C: return C ``` --- ## 4. Port information formatting The basic routing algorthium is based the information between nodes, which is the **pin** attribute inside each file. The formatting of **pin** name will be important. **Note**: The pin name should only be related to different functionalities instead of material, layer or shaped. Say, the pin name of a *silicon directional coupler* is the same as a *silicon nitride directional coupler*. |Catagory| Prefix | name | index | expample | device instance |---|---|---|---|---|---| | Optical| opt_ | a | 1~x | opt_a_1 | direction_coupler | Optical (Sinlge IO to waveguide)| opt_ | a_ | 1~x | opt_a_1 |grating_coupler | Electrical| ele_ | a | 1~x | ele_a_1 | heater/resistor | PN diodes| ele_ | cathode/anode | 1~x | ele_anode_1 | modulator/p-i-n waveuigde | Transistors (BJT)| ele_ | base/em/collector | 1~x | ele_colloctor_1 | BJT | Transistors (MOS)| ele_ | gt/su/dr | 1~x | ele_gt1 | MOSFET ## 5. Layer and cross-sections Inside **nazca**, an important feature is the concept of **cross-sections (xs)**. Typically, **xs** is a conbination of different layers which is required by the foundry DRC. Below is a example in Silterra tapeout. ``` python nazca.add_xsection("strip") nazca.add_layer_to_xsection("WG_HM",growx=2,growy=2) nazca.add_layer_to_xsection("WG_STRIP",growx=2,growy=2) ```