Skip to main content

sdf-parser

A pure-Python parser for Standard Delay Format (SDF) files — the industry-standard format used by EDA tools to back-annotate timing delays and constraints onto digital designs.

CI Python License: MIT

Building a Python SDF Parser for EDA Flow Automation — Closing a tooling gap that every EDA engineer eventually runs into.

Features

  • Parses IOPATH, COND, CONDELSE, WIDTH, SETUPHOLD, and RECREM
  • Single file or directory of SDF files (with cross-file consistency checks)
  • Single-cell extraction mode — stops early once the target cell is found
  • Zero required dependencies — only the Python standard library
  • Optional colored warnings via termcolor
  • CLI included: sdf-parser timing.sdf --cell INV_X1

Installation

pip install eda-sdf-parser                  # no extra dependencies
pip install "eda-sdf-parser[color]"         # adds termcolor for colored warnings

PyPI Python

Or for development:

git clone https://github.com/rohaansch/sdf-parser
cd sdf-parser
pip install -e ".[dev]"

Quick start

from sdf_parser import SDFParser

parser = SDFParser()
sdf = parser.read("timing.sdf")

print(repr(sdf))
# SDF(cells=142, files=1, header=['SDFVERSION', 'DESIGN', 'TIMESCALE'])

for entry in sdf.cells["INV_X1"]:
    print(entry)
# ['IOPATH', 'A', 'ZN', 2]
# ['COND', "A==1'b0", 'A', 'ZN', 1]
# ['WIDTH', None, 'posedge', 'A', 1]

Parsed entry format

Each entry in sdf.cells["CELLNAME"] is a list whose first element is the construct keyword:

Construct Entry format
IOPATH [IOPATH, pin_1, pin_2, n]
COND [COND, condition, pin_1, pin_2, n]
CONDELSE [CONDELSE, pin_1, pin_2, n]
WIDTH [WIDTH, condition, edge, port, n]
SETUPHOLD [SETUPHOLD, cond_1, edge_1, port_1, cond_2, edge_2, port_2, n]
RECREM [RECREM, cond_1, edge_1, port_1, cond_2, edge_2, port_2, n]

condition is None when no COND qualifier is present. n is the number of delay value tuples (e.g. 3 for min/typ/max).

Full example

SDF input:

(CELL
  (CELLTYPE "DFFS_X2")
  (INSTANCE FF1)
  (TIMINGCHECK
    (SETUPHOLD (posedge D) (posedge CK) (0.1:0.1:0.1) (0.05:0.05:0.05))
    (RECREM   (negedge SN) (posedge CK) (0.2:0.2:0.2) (0.1:0.1:0.1))
    (WIDTH    (posedge CK) (0.3:0.3:0.3))
  )
)

Python output:

sdf.cells["DFFS_X2"]
# [
#   ['SETUPHOLD', None, 'posedge', 'D', None, 'posedge', 'CK', 2],
#   ['RECREM',    None, 'negedge', 'SN', None, 'posedge', 'CK', 2],
#   ['WIDTH',     None, 'posedge', 'CK', 1],
# ]

API reference

SDFParser(path=None)

Create a parser. path sets the default file/directory used by read().

SDFParser.read(path=None, given_cell=None) → SDF

Argument Type Description
path str .sdf file or directory. Falls back to the constructor path.
given_cell str Extract only this cell (case-insensitive).

Raises ValueError / FileNotFoundError / IOError on bad input.

SDFParser.reset()

Clear internal state to reuse the parser for a different file:

sdf_fast = parser.read("fast.sdf")
parser.reset()
sdf_slow = parser.read("slow.sdf")

SDF object

Attribute Type Description
header_data dict Header fields (SDFVERSION, DESIGN, TIMESCALE, …)
cells dict[str, list] Cell name → list of parsed entries
files list[str] All files that contributed to this object

format_entries(cell) → str

Format a cell's entries as a human-readable multi-line string:

from sdf_parser import format_entries
print(format_entries(sdf.cells["INV_X1"]))

Parsing a directory

When path is a directory every .sdf file inside it is parsed and merged. Cells found in multiple files are compared; mismatches produce a warning:

sdf = SDFParser().read("sdf_corners/")
print(repr(sdf))
# SDF(cells=142, files=3, header=['SDFVERSION', 'DESIGN', 'TIMESCALE'])

Command-line usage

sdf-parser timing.sdf
sdf-parser timing.sdf --cell INV_X1
sdf-parser timing.sdf --cell INV_X1 --header
sdf-parser sdf_corners/ --header
sdf-parser --version

Or without installing:

python -m sdf_parser timing.sdf --cell INV_X1

Limitations

  • Delay values are not parsed — only the count of value tuples is stored.
  • Only the constructs listed above are extracted; other SDF keywords are skipped.
  • OASIS and binary SDF formats are not supported.

Running the tests

pip install -e ".[dev]"
pytest -v

License

MIT

Metadata

Release files for eda-sdf-parser 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for eda-sdf-parser 0.1.2
File Size Uploaded Provenance
eda_sdf_parser-0.1.2.tar.gz 10.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for eda-sdf-parser 0.1.2
File Interpreter ABI Platform
eda_sdf_parser-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 21.2 kB

Release files / eda_sdf_parser-0.1.2.tar.gz

Download URL eda_sdf_parser-0.1.2.tar.gz
Size 10.5 kB
Tags Source
SHA-256 checksum
How to use checksums
684f73de1333ab09ce908d0848b63407b3aebf568e87b31cbce4b649ea05bd24
BLAKE2b-256 checksum
How to use checksums
d669162801bf144d39c4f201b2449261c359200b6ab667e9c36022d9041de142
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / eda_sdf_parser-0.1.2-py3-none-any.whl

Download URL eda_sdf_parser-0.1.2-py3-none-any.whl
Size 10.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4db310b0aa6f919731962978735f857f54e9206fc8f6d9241b9612f0f955c318
BLAKE2b-256 checksum
How to use checksums
73aebc053de2e9379f52f8fd309e6678f95ecbe94febb2f81e6fd4e623cf54ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Security for eda-sdf-parser 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page