A pure-Python parser for Standard Delay Format (SDF) files used in EDA timing flows
Project description
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.
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, andRECREM - 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
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file eda_sdf_parser-0.1.2.tar.gz.
File metadata
- Download URL: eda_sdf_parser-0.1.2.tar.gz
- Upload date:
- Size: 10.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
684f73de1333ab09ce908d0848b63407b3aebf568e87b31cbce4b649ea05bd24
|
|
| MD5 |
9171a71f1062e19a5b7d0356a9b98dbf
|
|
| BLAKE2b-256 |
d669162801bf144d39c4f201b2449261c359200b6ab667e9c36022d9041de142
|
File details
Details for the file eda_sdf_parser-0.1.2-py3-none-any.whl.
File metadata
- Download URL: eda_sdf_parser-0.1.2-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4db310b0aa6f919731962978735f857f54e9206fc8f6d9241b9612f0f955c318
|
|
| MD5 |
9d2c703d2804c17921b77b65dc2a48da
|
|
| BLAKE2b-256 |
73aebc053de2e9379f52f8fd309e6678f95ecbe94febb2f81e6fd4e623cf54ff
|