Skip to main content

Layout scripting for photonic and electronic chip design

Project description

Lumicron API

Layout scripting for photonic and electronic chip design.

Define cells, place components, route waveguides, and export to GDS/OASIS — all in Python.

Install

pip install lumicron_api

Requires Python 3.12+.

Quick Start

import lumicron_api.all as lm
import lumicron_api.pdks.elyon_demo.all as pdk

@lm.cell_params
def MZI(arm_length: float = 100, arm_spacing: float = 10):
    c = lm.CELL("MZI")

    # Components
    splitter = pdk.YSplitter(layer=pdk.LAYER.SILC)
    combiner = pdk.YSplitter(layer=pdk.LAYER.SILC)

    # Add and place
    s = c.add(splitter)
    k = c.add(combiner)
    c.Place(s).at((0, 0))
    c.Place(k).using("i1").at((arm_length + 50, 0)).rotate_by(180)

    # Route
    c.Route(s.port["o1"], k.port["o1"], radius=10)
    c.Route(s.port["o2"], k.port["o2"], radius=10)

    return c

mzi = MZI()
mzi.to_layout().to_gds()  # writes mzi.gds (auto-named from cell)

Features

  • Hierarchical Cells — build complex designs from reusable parametric components
  • Fluid Chain-based Syntax - chain verbs and descriptors to your place and route commands using intuitive commands to "speak" your layout into existence. c.Place(mmi).using("in1").relative_to(heater.port["in"]).move_by(dx=-50, dy=-50).rotate_by(90)
  • Intuitive Placement System - anchor-based positioning with directional helpers (.above(), .below(), .right_of(), .left_of()) and .move_by() offset helper
  • Smart Routing — auto-router that automatically selects route style based on port position, overridable by style="manhattan", "sbend", or "direct". Automatically validates bend radius and automatically tapers routes with flexible positional placement
  • Robust routing — routing supported for ports at arbitrary angles. Contains intuitive route management via .go() commands: c.Route(coupler.port["out"], mod_array.port["m0_in"], bend_radius=25).go("N", to=mod_array.S, dy=-100).go("W", to=mod_array.port["m0_in"]). Allows custom bend and taper PCell to be auto-placed into routes
  • Route shaping.jog(direction, by) inserts a U-shaped manhattan detour at the route's bend radius for delay lines, MZI arms, and pad fanout
  • Bend types — circular (default), euler (clothoid), and custom bend PCells with adjustable p parameter
  • Bundle routingc.RouteBundle(ports_a, ports_b, spacing=10) routes multiple port pairs with a single call
  • Layout-aware routingc.Route(a, b, clearance=5) auto-detours routes around placed cell bounding boxes, bend-radius-aware with path simplification
  • Waveguide — standalone path primitive for spirals, delay lines, and tapered structures with custom bend PCell support
  • Arrays — 1D and 2D arrays with per-element rotation
  • Port promotion — access deeply nested ports from any level in the hierarchy
  • Shapes — Rectangle, Circle, Ring, Oval, Arc, Triangle, Parallelogram, Trapezoid
  • PDK support — ships with Elyon Demo PDK (17 layers, 11 components, 3 route profiles)
  • Export — GDSII, OASIS with auto-filename from cell name

Placement

# Absolute
c.Place(shape).at((100, 200))

# Relative
c.Place(pad).right_of(coupler)
c.Place(stalk).below(segment).move_by(dy=5)

# Anchor + rotate
c.Place(splitter).using("i1").at(frame.NW).rotate_by(90)

Routing

# Auto-route with circular bends
c.Route(port_a, port_b, radius=10)

# Euler bends (smooth curvature transition)
c.Route(port_a, port_b, radius=10, bend="euler")
c.Route(port_a, port_b, radius=10, bend="euler", p=0.3)  # adjust euler fraction

# Off-angle ports — auto-detected
c.Route(angled_port_a, angled_port_b, radius=25)

# Force a routing style
c.Route(port_a, port_b, radius=10, style="manhattan")
c.Route(port_a, port_b, radius=10, style="sbend")
c.Route(port_a, port_b, radius=10, style="direct")

# Custom bend PCell (user-defined 90° bend geometry)
c.Route(port_a, port_b, bend=my_euler_bend_cell)

# Manual with GPS-style directions
c.Route(port_a, port_b, radius=15) \
    .go("E", by=50) \
    .go("N", to=port_b, dy=-20)

# Route jog — U-shaped detour for delay lines, MZI arms, pad fanout
c.Route(port_a, port_b, radius=10).jog("S", by=50)

# Positional taper — place taper 50µm from port A
c.Route(port_a, port_b, radius=10).start_taper(length=10, at=50)

# With route profile
c.Route(port_a, port_b, profile=pdk.RPROF.siln_strip)

# Layout-aware routing — detour around placed cells
c.Route(port_a, port_b, radius=10, clearance=5)

# Control distance from port to first/last bend (direct paths)
c.Route(port_a, port_b, radius=10, start_straight=20, end_straight=15)

# Bundle routing — route multiple port pairs at once
c.RouteBundle(
    ports_a=[ref_a.port["o1"], ref_a.port["o2"]],
    ports_b=[ref_b.port["i1"], ref_b.port["i2"]],
    spacing=10, radius=10,
)

Waveguide

# Standalone path from points — auto-generates i1/o1 ports
wg = lm.Waveguide(
    points=[(0, 0), (50, 0), (50, 100), (100, 100)],
    layer=pdk.LAYER.SILC, width=0.5, radius=10,
)

# Tapered waveguide (width interpolates linearly)
wg = lm.Waveguide(
    points=spiral_points,
    layer=pdk.LAYER.SILC, width=0.2, width_end=1.0, radius=10,
)

# Custom bend PCell in waveguide
wg = lm.Waveguide(
    points=[(0, 0), (50, 0), (50, 50)],
    layer=pdk.LAYER.SILC, width=0.5, bend=my_bend_cell,
)

ref = c.add(wg)
c.Route(some_port, ref.port["o1"], radius=10)

Arrays

couplers = lm.ARRAY(coupler, count=8, pitch=(0, 127), rotation=90)
arr = c.add(couplers)
c.Place(arr).at((0, 0))

# Access individual element ports
arr[0].port["o1"]
arr[3].C

Parametric Cells

@lm.cell_params
def Ring(radius: float = 50, width: float = 5):
    c = lm.CELL("Ring")
    c.add(lm.Ring(outer_radius=radius, width=width, layer=pdk.LAYER.SILC))
    return c

Ring()              # cell name: "Ring"
Ring(radius=100)    # cell name: "Ring_radius=100"

Documentation

See docs/user_guide.md for the full API reference.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lumicron_api-0.3.6.tar.gz (116.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lumicron_api-0.3.6-py3-none-any.whl (98.9 kB view details)

Uploaded Python 3

File details

Details for the file lumicron_api-0.3.6.tar.gz.

File metadata

  • Download URL: lumicron_api-0.3.6.tar.gz
  • Upload date:
  • Size: 116.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for lumicron_api-0.3.6.tar.gz
Algorithm Hash digest
SHA256 2cd3cddc66d72c244d4a42f16ef62576a929e19583daf8732f00fe8bb5a3ee2c
MD5 49c3c17977853e6f12aa5200e619cab6
BLAKE2b-256 e46e29318ab45d2a3d0b0d17a08fbd9c16be7ad9b1f724e4bdcef74c58f16d65

See more details on using hashes here.

File details

Details for the file lumicron_api-0.3.6-py3-none-any.whl.

File metadata

  • Download URL: lumicron_api-0.3.6-py3-none-any.whl
  • Upload date:
  • Size: 98.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for lumicron_api-0.3.6-py3-none-any.whl
Algorithm Hash digest
SHA256 a6def67b9c07c9eb75ef301a9acc4b3e652742caf7e9df72d26d178bf15c8649
MD5 1d911f87e66a08b373e728d8842560bd
BLAKE2b-256 7c819d214d6f38a94a8b17d8ef16d412d5e77ff0b9b9dbcc96db719b06af7eed

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page