Cell

A cell containing geometry and references to other cells.

Cells are the primary container for layout geometry. Each cell has a unique name and holds polygons, paths, text labels, ports, and references to other cells. Use cell.at(x, y) to create positioned instances for ergonomic placement and port queries.

cell = Cell("my_design")
cell.add_polygon(Polygon.rect(Point.origin(), 10, 5), Layer(1, 0))
cell.add_port(Port("in", Point(0, 2.5), Vector2(-1, 0), width=0.5))

# Position and add to a parent cell
top = Cell("top")
top.add_ref(cell.at(100, 50))

Attributes

attributenamestr

Cell name (unique within a design).

attributepath_lengthfloat | None

Path length metadata. Automatically set when a cell is created from a Route via to_cell(). Can also be set manually for component cells.

attributedrc_skipbool

Whether this cell is marked as trusted for DRC. When True, DRC violations attributed entirely to this cell (or to cells in its subtree) are suppressed from the final DrcResult. Inter-cell violations between this cell and an untrusted cell are still reported.

Use this to silence noise from PDK components or vendor IP that you trust:

pd = Cell("PD_A", drc_skip=True)
# ... or set later
pd.drc_skip = True

The skipped-cell counts and number of suppressed violations are surfaced on DrcResult.skipped_cells and DrcResult.suppressed_violations.

Limitations.

  • Density rules are not suppressed. density is a window-level check with no single source cell, so its violations carry no cell-name provenance and always pass through the filter. All other rule types do have provenance and are suppressed when attributed to trusted cells.
  • Placement is also trusted, not just interior. If two trusted cells (or two instances of the same trusted cell) are placed by an untrusted parent in a way that violates a same-layer rule between them, the violation is still suppressed because both endpoint cells are trusted. If you need to catch placement mistakes against trusted blocks, place at least one of the participants in an untrusted cell.
  • Not persisted to GDS. GDS has no standard place to store this flag, so round-tripping a design through write_gds / read_gds clears drc_skip on every cell.

Methods

func__init__(name, *, drc_skip=False) -> None

Create a new empty cell.

paramnamestr

Name of the cell. Must be unique within a design, non-empty, at most 32 characters, and contain only printable ASCII (no spaces or Unicode).

paramdrc_skipbool

If True, mark this cell as trusted for DRC. See the drc_skip attribute above for full semantics.

Returns

None

Geometry

funcadd_polygon(polygon, layer) -> None

Add a polygon to the cell.

parampolygonPolygon

The polygon to add.

paramlayerLayer | int | tuple[int, int]

Target layer. Accepts a Layer object, a single int (datatype defaults to 0), or a (number, datatype) tuple.

Returns

None
funcadd_path(points, width, layer, end_type=None) -> None

Add a path (centerline with width) to the cell.

Paths are an alternative to polygons for representing waveguides and similar structures. They store a centerline and width, which can be more compact than storing the full polygon outline.

Example

cell.add_path(
    [Point(0, 0), Point(100, 0), Point(100, 50)],
    width=0.5,
    layer=1,
    end_type=PathEndType.ROUND
)
parampointslist[Point]

List of Point objects along the path centerline.

paramwidthfloat

Width of the path.

paramlayerLayer | int | tuple[int, int]

Target layer.

paramend_typePathEndType | None
= None

Path end type. Defaults to PathEndType.FLUSH.

Returns

None
funcadd_text(text, position, layer, height=1.0) -> None

Add a text label to the cell.

Text labels are useful for debugging and documentation but are typically not fabricated.

Example

cell.add_text("Input", Point(0, 5), layer=10)
cell.add_text("Big Label", Point(0, 10), layer=10, height=5.0)
paramtextstr

The text string.

parampositionPoint

Position of the text.

paramlayerLayer | int | tuple[int, int]

Target layer.

paramheightfloat
= 1.0

Text height in user units.

Returns

None

Ports

funcadd_port(port) -> None

Add a port to the cell.

paramportPort

The port to add.

Returns

None
funcport(name) -> Port

Get a port by name.

paramnamestr

Name of the port to retrieve.

Returns

Port

The port object.

funcports() -> list[Port]

Get all ports defined on this cell.

Returns

list[Port]

List of all ports.

Counts

funcpolygon_count() -> int

Number of polygons in the cell (not counting child cells).

Returns

int
funcpolygons() -> list[tuple[Polygon, Layer]]

Get all polygons (and their layers) stored directly on this cell.

Does not descend into referenced cells; only returns polygons added via add_polygon. Cell references and paths are excluded.

Returns

list[tuple[Polygon, Layer]]

List of (polygon, layer) tuples, in insertion order.

funcpath_count() -> int

Number of paths in the cell.

Returns

int
functext_count() -> int

Number of text labels in the cell.

Returns

int
funcref_count() -> int

Number of cell references.

Returns

int

Bounding box

funcbbox() -> BBox | None

Calculate the bounding box of the geometry directly in this cell.

Includes polygons and paths. Does not resolve cell references. if this cell contains CellRefs or AREFs, their contribution is ignored. Use Library.cell_bbox(name) for the fully resolved bounding box of a cell inside a library.

Returns None if the cell has no direct geometry.

Returns

BBox | None

Placement

funcat(x, y) -> Instance

Create a positioned instance of this cell.

This is the recommended way to place cells in a design. The returned Instance tracks the cell reference, allowing port queries without redundantly passing the cell.

Example

gc_cell = grating_coupler(layer=layers.silicon.layer)
gc_in = gc_cell.at(0, 0)
gc_out = gc_cell.at(0, 127)

# Get ports directly from instances
port_in = gc_in.port("opt")
port_out = gc_out.port("opt")
paramxfloat

X coordinate.

paramyfloat

Y coordinate.

Returns

Instance

An Instance positioned at (x, y).

funcadd_ref(ref) -> None

Add a cell, cell reference, or instance to this cell.

When adding a Cell or Instance, the child cell is automatically tracked so that write_gds() can collect the full hierarchy without a manual cell list.

Example

top.add_ref(gc_cell.at(0, 0))        # Instance at position
top.add_ref(route.to_cell("wg"))     # Cell at origin
paramrefCell | CellRef | Instance

A Cell (placed at origin), Instance, or CellRef to add.

Returns

None
funcplace_at_port(cell_ref, cell_port, target_port) -> CellRef

Place a cell reference by aligning its port to a target port.

paramcell_refCellRef

The cell reference to place.

paramcell_portPort

Port on the referenced cell to align.

paramtarget_portPort

Target port to align to.

Returns

CellRef

The transformed cell reference.

funcget_child_cells() -> set[Cell]

Get all tracked child cells (for write_gds() auto-collection).

Returns

set[Cell]

Set of child cells that have been added via add_ref().

Metadata

funcadd_bend(radius, x, y, requested_radius=None) -> None

Add a bend info entry to the cell metadata.

This is used by component authors to record bend locations for design checks (run_checks). The bend radius and location are stored so that minimum bend radius violations can be detected.

paramradiusfloat

Effective bend radius in um.

paramxfloat

X coordinate of bend location.

paramyfloat

Y coordinate of bend location.

paramrequested_radiusfloat | None
= None

Original requested radius, if the router auto-reduced it.

Returns

None
attributebendslist[dict]

Bend info entries as list of dicts with keys: radius, x, y, and optionally requested_radius.

funcadd_warning(warning) -> None

Add a warning to the cell metadata.

paramwarningstr

Warning message string.

Returns

None
attributecell_warningslist[str]

Warnings from cell construction (e.g., auto-reduced bend radii).

On this page