Skip to content

rohaansch/liberty-parser

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

liberty-parser

A pure-Python parser for Liberty (.lib) cell-library files — the industry-standard format used by EDA tools to describe the timing, power, and interface of standard cells.

CI Python License: MIT

Features

  • Full Liberty grammar — comments, simple attributes, complex attributes, and arbitrarily deep group blocks
  • Round-trip writewrite_liberty() reconstructs the file with the exact original whitespace and formatting
  • In-place editingset_val(), set_vals(), set_LU_matrix(), add_simple(), add_complex(), add_block(), remove_block(), merge_blocks()
  • Hierarchical navigationnavigate() with exact-match or {RE}regex filters, navigate_to_base() to walk up the tree
  • Convenience helpersget_cell_list(), get_pin_list(), map_LU_indexes()
  • Parse from string — no file required; pass a Liberty text block directly
  • Zero required dependencies — only the Python standard library
  • Optional colored output via termcolor
  • CLI included: liberty-parser cells.lib --cell INV_X1 --pins

Installation

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

PyPI Python

Or for development:

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

Quick start

from liberty_parser import LP

lib = LP("cells.lib")

print(lib.get_cell_list())
# ['INV_X1', 'AND2_X1', 'DFFS_X2']

print(lib.get_pin_list(cell="INV_X1"))
# ['A', 'ZN']

# Read a library attribute
time_unit = lib.navigate_single('library', 'time_unit').get_val()
print(time_unit)
# 1ns

Navigation

navigate() accepts a chain of filter strings, one per hierarchy level:

# All cells in the library
cells = lib.navigate('library', 'cell')

# Specific cell by name
inv = lib.navigate_single('library', 'cell:INV_X1')

# Pin direction of a specific pin
direction = lib.navigate_single('library', 'cell:INV_X1', 'pin:ZN', 'direction')
print(direction.get_val())
# output

# Regex filter — find all *_template blocks
for tmpl in lib.navigate('library', '{RE}_template$'):
    print(tmpl.get_val())

navigate_single() returns the first match (or None). navigate_singles() is the fastest variant — stops at the first match at every level.

In-place editing

All edits modify the in-memory dict and are written back with write_liberty():

# Change a simple attribute value
lib.navigate_single('library', 'time_unit').set_val('2ns')

# Or use the two-argument shorthand (nav_to, new_value)
lib.navigate_single('library').set_val('voltage_unit', '1.8V')

# Edit a lookup-table 2-D matrix
cell_rise = lib.navigate_single(
    'library', 'cell:INV_X1', 'pin:ZN', 'timing', 'cell_rise'
)
matrix = cell_rise.get_LU_matrix()
matrix[0][0] = '0.15'
cell_rise.set_LU_matrix(matrix)

# Write back to disk
lib.write_liberty("cells_modified.lib")

Structural edits

library = lib.navigate_single('library')

# Add a new simple attribute
library.add_simple('nom_voltage', '1.8')

# Add a new complex attribute
library.add_complex('operating_conditions', 'typical')

# Remove a cell
cell = lib.navigate_single('library', 'cell:INV_X1')
cell.remove_block()

# Merge another Liberty block into an existing one
lib.navigate_single('library').merge_blocks('extra_cells.lib')

Parsing from a string

No file needed — pass Liberty text directly:

snippet = 'library (mini) { voltage_unit : "1V"; nom_voltage : 1.8; }'
mini = LP(snippet)
print(mini.navigate_single('library', 'nom_voltage').get_val())
# 1.8

Element type predicates

from liberty_parser import is_comment, is_simple_attribute, is_complex_attribute, is_block

for element in lib.navigate('library'):
    if is_block(element):
        print(f"Block: {element.get_val()}")
    elif is_simple_attribute(element):
        print(f"Attr:  {element.get_val()}")

API reference

LP(arg=None)

Argument Behavior
None Create empty LP object
filepath (.lib file) Parse the file
text (Liberty string) Parse the string as a Liberty block
dict Wrap an existing internal dict
LP Share the internal dict of another LP object

Navigation

Method Description
navigate(*filters) Return all matching LP objects
navigate_single(*filters) Return first match at last filter
navigate_singles(*filters) Return first match at every filter (fastest)
navigate_to_base() Walk up to the file root

Getters

Method Description
get_val(nav_to=None) Return value or name string
get_vals(nav_to=None) Return comma-separated value as a list
get_LU_matrix(nav_to=None) Return LU table as a 2-D list
get_type() Return the element type string
get_cell_list() Return all cell names
get_pin_list(cell=None) Return pin names for one or all cells
map_LU_indexes() Return transition/load index map

Setters

Method Description
set_val(nav_or_val, val=None) Set a simple or complex attribute value
set_vals(nav_or_vals, vals=None) Replace comma-separated value list
set_LU_matrix(nav_or_matrix, matrix=None) Replace LU table 2-D matrix

Structural edits

Method Description
add_simple(name, value, insert_ndx=0) Insert a simple attribute
add_complex(type, name, insert_ndx=0) Insert a complex attribute
add_block(lp_block, insert_ndx=0) Insert an LP element
add_blocks(input, insert_ndx=0) Parse and insert multiple elements
remove_block(ndx=None) Remove element at index, or remove self
move_block(from_index, to_index) Reorder elements
merge_blocks(blocks_input) Deep merge another Liberty block

Write & debug

Method Description
write_liberty(out_path) Write parsed dict back to a .lib file
print(indent=0) Pretty-print the internal dict

Command-line usage

liberty-parser cells.lib
liberty-parser cells.lib --cells
liberty-parser cells.lib --cell INV_X1
liberty-parser cells.lib --cell INV_X1 --pins
liberty-parser cells.lib --attr voltage_unit
liberty-parser --version

Or without installing:

python -m liberty_parser cells.lib --cell INV_X1 --pins

Running the tests

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

Companion projects

License

MIT

About

A pure-Python parser for Liberty (.lib) files — extracts cell timing, power, and pin data from standard-cell and pad libraries for EDA automation workflows.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages