Importing GDS Cells
Select and place cells from a GDS library, preserve their hierarchy, and supply binary imports to browser tools.
Use import to place an existing GDS cell in a Laylight design. The cell's geometry and child hierarchy are copied into the output when it is used. GDS imports need laylight 0.3.1 or later (see the Changelog).
Import and build a cell
Suppose your project has this structure, and components.gds contains a cell named MMI$1:
project/
chip.lyl
vendor/
components.gdsWrite chip.lyl:
import "vendor/components.gds" cell "MMI$1" as ImportedMMI
cell Chip {
place ImportedMMI.origin at (100um, 50um) as first
place ImportedMMI.origin at (200um, 50um) rotate 90deg as second
}Then check and build it with the command-line tool:
laylight check chip.lyl
laylight build chip.lyl --top Chip -o chip.gdsPaths resolve relative to the file containing the import, including when that file is imported by another source. The GDS cell name is matched exactly. The local alias ImportedMMI lets you refer to a name containing $ without changing the original cell's name in the output.
The repository includes a runnable example using samples/gds/mmi_1x2.gds. From the repository root:
laylight build examples/photonics/gds_import.lyl -o imported.gdsImport forms
| Form | Cells available to the DSL |
|---|---|
import "vendor.gds" | All cells with valid DSL identifier names, including nested cells. Hard keywords are excluded. |
import "vendor.gds" cell "Pad" | The cell named Pad, available as Pad. |
import "vendor.gds" cell "PAD$1" as Pad | The cell named PAD$1, available as Pad. |
Extensions .gds and .gdsii are recognized without regard to case. Selection by cell "..." works for any cell in the file, including a child cell; it does not have to be a GDS top cell. Selection is only supported for GDS imports.
An alias must be a valid DSL identifier. It is required when the original name contains characters such as $, spaces or punctuation, or is a hard keyword such as cell. Imported names share the global namespace with source cells, constants and layers. If names collide, select the cell explicitly and choose another alias.
Repeated imports and multiple aliases for the same cell reuse that cell in the output. Only cells reached from the selected design tops are written, together with their recursive children. If output cell names collide with source cells, identical cells are merged and other imported cells are renamed with suffixes such as $1.
Placement and interface metadata
Imported cells have fixed geometry and take no configurable arguments. Place them by their origin, with ordinary rotation, mirror and offset modifiers, or in loops. ImportedMMI.origin refers to the original GDS cell's origin, rather than its bounding-box center.
When a GDS file was written by Laylight, its marker metadata remains available:
cell Chain {
place ImportedMMI.marker.input[0] at (0, 0) as first
place ImportedMMI.marker.input[0] at first.marker.output[0] as second
}This snippet requires input and output markers in the imported cell. Its stored parameter values and attributes are available as read-only attributes. They do not make the imported cell parametric.
Without Laylight metadata, a GDS cell has an origin but no inferred ports or shape bounding-box anchors. Ordinary text labels are not converted into markers. To add a port interface, wrap it in a source cell and define markers at the coordinates of the actual ports:
cell MMIAdapter {
marker {
input { at (0, 0) }
output { at (50um, 0) }
}
place ImportedMMI.origin at self.origin
}The coordinates above are illustrative; use the port positions and directions of your GDS cell. A placement without an explicit anchor uses the first input marker when one exists, otherwise the origin. Use .origin when you want to position the original GDS coordinate origin regardless of metadata.
Layers, grid and supported elements
Geometry keeps its GDS layer and datatype numbers. Layers are matched to the design by those numbers; missing layers are added. The reserved marker and blackbox layers are matched by name when the design declares them.
Coordinates, path widths, instance translations, array steps and marker positions are converted from the GDS database unit to the design's dbu, which defaults to 1nm, and rounded to the nearest grid point. For example, a coordinate of 1000 in a GDS with a 2nm DBU becomes 2000 on a 1nm design grid, preserving its physical position of 2µm. Physical quantities stored in attributes keep their values. Signed blackboxes require matching DBUs to preserve their signatures.
| GDS content | Import behavior |
|---|---|
| BOUNDARY and BOX | Copied as polygons or boxes. |
| PATH with flush ends | Copied with its width. |
| SREF and AREF | Child hierarchy, translations, rotations, mirrors and regular arrays are retained. |
| Laylight cell and marker metadata | Attributes and marker frames are restored. |
| Ordinary TEXT labels | Omitted with a warning at the import. |
| Magnified or absolute instance transforms | Import error. |
| Extended or round-ended PATH, NODE and other unsupported geometry | Import error. |
The entire GDS file is validated for supported elements, even when one cell is selected. Arbitrary GDS element properties are not converted into DSL attributes.
Browser compiler and editor
Browser tools need binary data supplied by the host application. Pass GDS files as Uint8Array, alongside source strings, to @photonstack/laylight-dsl-web:
import { createCompiler } from "@photonstack/laylight-dsl-web";
const compiler = await createCompiler();
const response = await fetch("/vendor/components.gds");
if (!response.ok) throw new Error(`GDS download failed: ${response.status}`);
const gdsBytes = new Uint8Array(await response.arrayBuffer());
const result = compiler.compile({
"chip.lyl": 'import "vendor/components.gds" cell "MMI$1" as MMI\ncell Chip { place MMI.origin at (0, 0) }',
"vendor/components.gds": gdsBytes,
}, "chip.lyl", ["Chip"]);The browser language client's setFiles() also accepts Uint8Array. For the React editor, provide a separate binaryFiles prop:
<LaylightEditor
files={{ "chip.lyl": chipSource }}
binaryFiles={{ "vendor/components.gds": gdsBytes }}
/>Binary files are available to imports without becoming text tabs. The non-React WorkspaceEditor exposes setBinaryFiles() and getBinaryFiles(); merge its text and binary file maps when compiling. The native CLI and language server read GDS files directly from disk.
The language server completes file paths and original GDS cell names, resolves placed cell references to the import, and allows local aliases to be renamed. Original GDS names and their metadata cannot be renamed through the source editor; introduce an alias instead.