Glyph

GDSII File Format Reference

GDSII (also written GDS2 or GDS) is a binary stream format for hierarchical integrated-circuit and photomask layout. A file is a linear sequence of length-prefixed records that describe a library of cells, each holding polygons, paths, text, and references to other cells, with all coordinates stored as integers in database units.

What is GDSII?

GDSII Stream Format was created by Calma Company for its GDS II layout systems in the late 1970s and became the de facto interchange format for mask and IC layout. It stores a hierarchical drawing: a library contains named structures (cells), and a cell can place a copy of another cell, so a memory array or a repeated device is described once and instanced many times.

Despite newer formats, GDSII remains the dominant handoff format between design tools and mask shops decades later — foundries, EDA tools, and viewers all read and write it. Glyph parses and writes it directly in your browser; your files never leave your machine. For background, see the Calma GDS II Stream Format Manual and the Wikipedia GDSII article listed under further reading.

File anatomy: HEADER … ENDLIB

A GDSII file is not a tree on disk — it is a flat stream of records read start to finish. Structure comes from begin/end record pairs that nest by convention. Every record is:

[ length : 2 bytes ][ record-type : 1 byte ][ data-type : 1 byte ][ data : length − 4 bytes ]
Byte layout of one GDSII record One GDSII record — a length-prefixed byte strip length 2 bytes rec-type 1 byte data-type 1 byte data length − 4 bytes byte 0 byte 2 byte 3 byte 4

All multi-byte integers are big-endian, and every record length is even (a null pad byte is appended when the payload is odd). The top-level nesting looks like this:

HEADER                     stream version
BGNLIB                     begin library  (timestamps)
  LIBNAME                  library name
  UNITS                    user unit + database unit (two REAL8s)
  BGNSTR                   begin structure / cell (timestamps)
    STRNAME               cell name
    BOUNDARY              a filled polygon
      LAYER / DATATYPE
      XY                  coordinate list
    ENDEL
    SREF                  a placed instance of another cell
      SNAME / XY
    ENDEL
  ENDSTR                   end of cell
  BGNSTR … ENDSTR          (more cells)
ENDLIB                     end of library — last record in the file
GDSII record-stream nesting, HEADER to ENDLIB HEADER stream version BGNLIB begin library LIBNAME library name UNITS user + database unit BGNSTR begin structure (cell) STRNAME cell name BOUNDARY filled polygon LAYER / DATATYPE XY coordinate list ENDEL close element ENDSTR end structure ENDLIB end of library — last record

A reader keeps a small state machine: BOUNDARY/PATH/SREF/AREF/TEXT open an element, the following records fill in its attributes, and ENDEL closes it. Glyph's parser is exactly this loop over the record catalogue below.

Units and the database unit

GDSII stores every coordinate as a signed integer in database units, never as a floating-point length. The single UNITS record carries two 8-byte reals that tell a reader what those integers mean:

  1. User units per database unit — the size of one database unit expressed in user units (e.g. 0.001, meaning 1000 database units per user unit).
  2. Database unit in metres — the physical size of one database unit (e.g. 1e-9, i.e. one nanometre).

With that common pair, an integer coordinate of 1500 is 1500 nm = 1.5 µm. Storing coordinates as integers avoids floating-point drift: a vertex that should sit exactly on a 5 nm grid stays exact through every read/write. Glyph works internally in world nanometres and, by default, writes 0.001 and 1e-9 so one database unit equals one nanometre — see Open & save GDS files.

The record catalogue

The 29 record types below are the ones Glyph reads and/or writes. The record number is the record-type byte (the third byte of the header, shown in decimal and hex); the data type is the fourth byte and fixes how the payload is decoded. Meanings are written from Glyph's own parser and writer.

Record Number (dec / hex) Data type Meaning
HEADER 0 / 0x00 INT2 Stream format version number.
BGNLIB 1 / 0x01 INT2 Begin library; last-modified and last-access timestamps.
LIBNAME 2 / 0x02 ASCII Library name.
UNITS 3 / 0x03 REAL8 Two reals: user units per database unit, and database unit in metres.
ENDLIB 4 / 0x04 (none) End of library — the final record in the file.
BGNSTR 5 / 0x05 INT2 Begin structure (cell); creation and modification timestamps.
STRNAME 6 / 0x06 ASCII Structure (cell) name.
ENDSTR 7 / 0x07 (none) End of the current structure.
BOUNDARY 8 / 0x08 (none) Begin a filled polygon element.
PATH 9 / 0x09 (none) Begin a path (wire) element.
SREF 10 / 0x0A (none) Begin a structure reference — one placed instance of another cell.
AREF 11 / 0x0B (none) Begin an array reference — a regular grid of instances.
TEXT 12 / 0x0C (none) Begin a text (label) element.
LAYER 13 / 0x0D INT2 Layer number of the current element.
DATATYPE 14 / 0x0E INT2 Datatype number of a boundary or path.
WIDTH 15 / 0x0F INT4 Path width in database units (negative means an absolute width).
XY 16 / 0x10 INT4 Coordinate list, as pairs of database-unit integers.
ENDEL 17 / 0x11 (none) End of the current element.
SNAME 18 / 0x12 ASCII Name of the referenced structure, for an SREF or AREF.
COLROW 19 / 0x13 INT2 Column and row counts for an AREF.
TEXTTYPE 22 / 0x16 INT2 Texttype number of a text element.
PRESENTATION 23 / 0x17 bit array Text font slot and horizontal/vertical justification.
STRING 25 / 0x19 ASCII The label text of a text element.
STRANS 26 / 0x1A bit array Reflection and absolute-magnification/angle flags for a reference or text.
MAG 27 / 0x1B REAL8 Magnification of a reference or text.
ANGLE 28 / 0x1C REAL8 Rotation angle in degrees, counter-clockwise.
PATHTYPE 33 / 0x21 INT2 Path end-cap style: 0 flush, 1 round, 2 half-square.
PROPATTR 43 / 0x2B INT2 Property attribute index for per-element key/value metadata.
PROPVALUE 44 / 0x2C ASCII Property value string paired with the preceding PROPATTR.

Data types map as follows: 0x00 no data, 0x01 bit array, 0x02 two-byte signed integer (INT2), 0x03 four-byte signed integer (INT4), 0x05 eight-byte real (REAL8), 0x06 ASCII string.

The 8-byte excess-64 REAL, with a worked example

GDSII does not use IEEE 754. Its 8-byte real is a historical IBM/VAX-style excess-64 format, and in a stream file it appears only in UNITS, MAG, and ANGLE. The layout, big-endian, is:

byte 0 : [ sign : 1 bit ][ exponent : 7 bits ]     exponent is biased by +64, base 16
bytes 1–7 : 56-bit mantissa
value = (−1)^sign × (mantissa / 2^56) × 16^(exponent − 64)

The sign bit set means negative. The exponent is a power of sixteen, not two, and is stored with a bias of 64 (so a stored 65 means an actual exponent of +1). The mantissa is a 56-bit fraction, normalised so its leading hex digit is non-zero — equivalently, the fraction sits in the range [1/16, 1).

Worked example: encoding 1.0.

  1. Sign is positive, so the sign bit is 0.
  2. Normalise 1.0 into [1/16, 1): divide by 16 once to get 0.0625, so the actual exponent is +1.
  3. Bias the exponent: 1 + 64 = 65 = 0x41. With the clear sign bit, byte 0 is 0x41.
  4. The mantissa is 0.0625 × 2^56 = 2^52 = 0x10000000000000. Written across the seven mantissa bytes that is 10 00 00 00 00 00 00.

So 1.0 encodes to the eight bytes 41 10 00 00 00 00 00 00. Decoding reverses it: 0x41 & 0x7F = 65, minus the 64 bias gives exponent 1; the mantissa 2^52 divided by 2^56 is 0.0625; and 0.0625 × 16^1 = 1.0. Glyph's readGdsFloat/writeGdsFloat implement exactly this round-trip, which is why a file re-saved by Glyph keeps its UNITS bytes identical to the original.

Excess-64 REAL worked example: 1.0 = 41 10 00 00 00 00 00 00 byte 0 byte 1 byte 2 byte 3 byte 4 byte 5 byte 6 byte 7 41 10 00 00 00 00 00 00 56-bit mantissa = 0x10000000000000 = 2⁵² byte 0 = 0x41 = binary 0 1 0 0 0 0 0 1 sign 7-bit exponent sign = 0 (positive) · exponent = 1000001₂ = 65 − 64 bias = +1 mantissa ÷ 2⁵⁶ = 2⁵² ÷ 2⁵⁶ = 0.0625 value = (−1)⁰ × 0.0625 × 16¹ = 1.0

Limits and quirks our parser handles

Real files lean on several edge cases; Glyph's parser and writer treat them as follows.

Further reading and provenance

Primary and historical sources — cited for reference; none of their text or tables is reproduced here:

Glyph is not affiliated with, endorsed by, or sponsored by Cadence or the former Calma Company; "GDSII" is used here descriptively. This reference is maintained by the authors of Glyph's from-scratch GDSII parser and writer.

Frequently asked questions

Is GDSII still used?

Yes. Even though newer formats exist, GDSII remains the standard interchange format between IC/photomask design tools and mask shops. Foundries, EDA tools, and viewers continue to read and write it, which is why a from-scratch parser and writer is still worth maintaining.

What is the difference between GDSII and a .gds file?

None in practice — "GDSII" (or GDS2) names the stream format, and .gds (sometimes .gds2 or .gdsii) is the usual filename extension for a file in that format. Opening a .gds file means parsing the GDSII record stream described above.

Can I open a GDSII file in a browser?

Yes. Glyph parses GDSII entirely client-side, so you can open the editor and load a .gds file with nothing to install and no upload — your files never leave your browser. For how GDSII compares to the newer OASIS format, see GDS vs OASIS.

Updated 2026-07-12

Open Glyph — free, no install Your files never leave your browser.
Open Glyph →