Skip to content

Implementation of Netlist extraction

lukasc-ubc edited this page Apr 30, 2020 · 2 revisions

This page describes how netlist extraction is implemented in KLayout, within SiEPIC-Tools.

The objective of netlist extraction

The objective is to generate a netlist file (Spice format) for circuit simulations and for verifying the circuit functionality. Each component is represented as follows:

<component>_<index> Net1 Net2 ... <component_model_name> param1=value1 param2=value2 ...

where parameters for devices include:

  • library="Design kits/ebeam": this is the compact model library in Lumerical INTERCONNECT

  • lay_x=133.392E-6 lay_y=-105.0E-9: location of the component in the layout, in meters; used for layout-aware Monte Carlo simulations

  • sch_x=3.579420791E0 sch_y=-2.817554E-3: location of the component, scaled, to be used for placing the component symbols in the schematic

Netlist examples:

ebeam_gc_te1550_6 ebeam_gc_te1550_detector1 N ebeam_gc_te1550 library="Design kits/ebeam" lay_x=133.392E-6 lay_y=-105.0E-9 sch_x=3.579420791E0 sch_y=-2.817554E-3

ebeam_wg_integral_1550_11 N0 N ebeam_wg_integral_1550 library="Design kits/ebeam" wg_length=227.275u wg_width=0.500u points="[[165.351,-46.482],[165.351,-63.333],[112.558,-63.333],[112.558,19.81],[162.384,19.81],[162.384,-0.105],[149.892,-0.105]]" radius=5.0 lay_x=138.954E-6 lay_y=-21.762E-6 sch_x=3.72867066E0 sch_y=-583.958223E-3

where "points" is used for the layout-aware Monte Carlo simulations

KLayout implementation

Classes

The following are defined in SiEPIC.core:

  • Net: connectivity between pins. Used for netlist generation and verification; data generated by class extensions cell.identify_nets()

  • Component: contains information about a layout component (cell with pins); data generated by class extensions cell.find_components() and will contain pin objects

  • Pin: pin details (direction); data generated by class extensions cell.find_pins()

The data structure is based on using pointers to cross-reference the database, e.g., Component -> Pin -> Net. Specifically, a component has pins; pins can be connected to other pins and are assigned to nets.

Net:

  • describes a connection between pins
    • optical nets can only have two pins
    • electrical nets can have multiple pins
  • the pin array points to Pins

Pin:

This is a class that describes pins on components (including waveguides). A pin consists of:

  • a Pin recognition geometry, on the PinRec layer; different geometry types are used to differentiate optical and electrical pins:
    • optical pin: a Path with 2 points, with its vector giving the direction of how to leave the component (pointing out of the component)
    • electrical pin: a Box
    • optical IO: a polygon, but on layer "FbrTgt"
  • a Text label giving its name; the label should be exactly at the midpoint of the optical pin path, or anywhere in the electrical pin box.
  • a type: OPTICAL, OPTICALIO, ELECTRICAL; this is an enum, one of PIN_TYPES, defined in SiEPIC._globals.PINTYPES

A pin can be associated with / point to:

  • a component
  • a net

Uses:

  • Waveguide snapping to nearest pin (in SiEPIC.scripts.path_to_waveguide, and SiEPIC.extend: path.snap)
    • does not need info about the component, net; only use nearest pins
  • Component snapping to nearest pin (in SiEPIC.scripts.snap_component)
    • does not need info about the component, net; only use nearest pins
  • Netlist extraction
    • needs connectivity: which component and net the pin belongs to

Component:

This is a class that describes components (PCells and fixed). A component consists of:

  • a layout representation
  • additional information from parameters

Uses:

  • Netlist extraction
    • needs connectivity: components and how they are connected (net)

Important component defs:

  • find_pins: find the pins belonging to this component

Functions

SiEPIC.extend: cell.find_pins()

This function finds the pins within a cell. It can be a cell containing many components, or the cell for a single component. Steps include:

  • create an empty dataset, pins, of class Pin
  • iterate through all the PinRec shapes in the cell
  • check the shape type,
    • if path, and if containing a pin name, then add to the pins dataset. Include the pin path (location, direction), pin type (OPTICAL), and the pin name.
    • if box, and if containing a pin name, then add to the pins dataset. Include the pin box (location), pin type (ELECTRICAL), and the pin name.
  • iterate through all the FbrTgt shapes in the cell, then add to the pins dataset. Include the pin polygon (location), pin type (OPTICALIO), and the pin name.

SiEPIC.extend: cell.find_components()

This function traverses the cell's hierarchy and finds all the components; returns a list of components (class Component). It uses the DevRec layer shapes to identify the component. The assumption is that there is only DevRec shape per component.

The steps include:

  • find all the DevRec shapes; DevRec must be either a Box or a Polygon
  • identify the component it belongs to; record the info as a Component. For each component instance,
    • find all Text shapes on the DevRec layer; these are used to pass parameters from the layout to the simulation:

      • Lumerical_INTERCONNECT_library=xxx: the name of the compact model library is xxx
      • Lumerical_INTERCONNECT_component=xxx or Component=xxx: the name of the component's compact model is xxx
      • Component_ID=xxx: [optional] a unique value used to differentiate several same components in a layout so they can be found / cross-referenced in the schematic. For example, in a layout with multiple ring resonators, each ring can have a unique number, which will be the same on both layout and schematic.
      • Spice_param:xxx: parameters that are passed to the circuit simulator, e.g., Spice_param:wg_length=227.275u wg_width=0.500u points="[[165.351,-46.482],[165.351,-63.333],[112.558,-63.333]]" radius=5.0
    • Find all the pins for the component, save in each component

      • sort them alphabetically by their pin name
      • record both their relative position within the component, as well as the absolute position on the layout

SiEPIC.extend: cell.identify_nets()

This function is used to identify all the nets in the cell layout. Note: Presently only optical netlist functionality is implemented.

The steps are:

  • create an empty dataset, nets, of class Net
  • find the components, using SiEPIC.extend: cell.find_components()
  • find the pins, using SiEPIC.extend: cell.find_pins(). Downselect to only the OPTICAL pin types.
  • Loop through all pairs components (c1, c2), by doing a nested for loop
    • only look at touching components (to speed it up)
    • Loop through all the pins (p1) in c1, and compare to all the other pins of the touching component (c2); find overlapping pins (p2) in c2
      • check that pins are facing each other, 180 degree
      • check that the pin centres are perfectly overlapping (to avoid slight disconnections and to correctly account for the phase of waveguides and components for simulations)
      • for matching pins, save the information in:
        • Net class, nets: the two pins
        • in each Pin, record the Net
  • the function returns the nets and components datasets

SiEPIC.extend: get_LumericalINTERCONNECT_analyzers_from_opt_in()

Automated testing of silicon photonic chips is performed using automated probe stations (e.g., www.mapleleafphotonics.com). Design for Test (DFT) rules are used to both verify that the circuit is testable with the probe station, as well as to perform simulations similar to how experiments are performed. An example DFT file is included in the EBeam PDK, as DFT.xml

We use "opt_in" text labels on the layout to indicate where the laser input should be applied. The opt_in labels are unique to each circuit, include experimental parameters (polarization, wavelength), and optionally circuit parameters. These are found using the SiEPIC.scripts.user_select_opt_in() function, which returns one opt_in label for one simulation.

For simulations, we need to identify the laser input into the circuit, and the outputs which are connected to detectors. Lumerical INTERCONNECT has an instrument, Optical Vector Network Analyzer (ONA), which includes both.

The most important input to this function is the list of components.

This function does the following:

  • using the DFT rules, checks that there is a grating coupler close enough to the opt_in label; find the closest one; this will be used to connect to the laser.
  • using the DFT rules for the fibre array, find all the other grating couplers that are under the array, which will be connected to the detectors; make sure the grating couplers are exactly placed as per the DFT rules. Sort the detectors in order from top to bottom along the grating coupler array.
  • configure the laser wavelength span and resolution based on the DFT experimental specifications.
  • determine which polarization is used (TE or TM), from the opt_in label
  • return the Nets which are to be connected to the laser and the detectors, and simulation parameters

SiEPIC.scripts.user_select_opt_in()

This function is to select one (or more) opt_in label(s) from the layout, via one of:

  • GUI with drop-down menu from all labels in the layout, to select one label,
  • User selection of a Text object in the layout before calling the function, or
  • an argument to the function, opt_in_selection_text, array of opt_in labels (strings)

It uses SiEPIC.utils.find_automated_measurement_labels() to find all the labels in the layout

SiEPIC.utils.find_automated_measurement_labels()

This function searches the layout for all text labels containing the string "opt_in". It then parses the strings to extract the (x,y) location, and all label parameters. It returns a dictionary containing the entire 'opt_in' string, x and y coordinates, 'pol' for the polarization (TE or TM), 'wavelength' for the centre wavelength (e.g., 1550), a 'type' used to categorize the devices during automated measurements (e.g., alignment, device), a 'deviceID' and 'params' to uniquely describe the circuit under test.

SiEPIC.extend: cell.spice_netlist_export()

This function generates a spice netlist file, using the netlist extraction and using the design for test opt_in label.

example output: ebeam_gc_te1550_6 ebeam_gc_te1550_detector1 N ebeam_gc_te1550 library="Design kits/ebeam" lay_x=133.392E-6 lay_y=-105.0E-9 sch_x=3.579420791E0 sch_y=-2.817554E-3

The steps are:

  • identify the nets, components and pins, using SiEPIC.extend: cell.identify_nets()
  • identify to which nets the laser and detectors should be connected, based on the selected opt_in label, using SiEPIC.extend: cell.get_LumericalINTERCONNECT_analyzers_from_opt_in()
  • trim the netlist, based on where the laser is connected; remove all components that are not part of the circuit attached to the grating coupler connected to the laser; using SiEPIC.scripts.trim_netlist()
  • determine a schematic scaling based on the layout (x,y) coordinates and the extent of the layout
  • write a Spice netlist file, as follows:
    • find all the electrical pins, and create a DC source for each pin.
    • find all the optical IO
    • create a top subckt, which will be the "chip", including
      • the subckt has a definition of .subckt chip_name electrical_IO_pins ... optical_IO_pins ...
      • variables required for Monte Carlo (define variables even when not using MC simulations)
      • make a list of all components, including their nets, library, and parameters; include location, flip, mirror and rotation
        • When netlisting each component, check pin names to see if they are explicitly ordered numerically (requires every pin name to start with a digit [i.e. 00, 01, .. NN]). If they are not ordered, then default ordering is used: electrical, optical IO, then optical
    • add an Optical Network Analyzer to the main spice file, including the parameters found from the opt_in label and DFT rules; connect it to the subckt.
  • return the two spice files (main and subckt)