This repository provides a Python interface to parse LEF (Library Exchange Format) and DEF (Design Exchange Format) files.
Make sure you have installed lib bison and zlib
apt-get update
apt-get install -y bison zlib1g-devAlso cmake
apt-get install -y cmakeYou can install library using pip
pip install lefdefFirst create a build folder then cmake all the files
cd /lefdef-python
mkdir build
cd build
cmake ..
makeAfter generating the .so file, you should copy the .so file under build folder to lefdef/lib. It should be liblefdef.so
Then
python test.pyThe script uses the example LEF and DEF files provided in the test directory:
NanGate_15nm_UTDA.tech.lef and simple.def.
To use the LEF reader, you can follow the example provided in the test.py file:
from lefdef import C_LefReader
from lefdef import C_DefReader
lef_reader = C_LefReader()
_lef = lef_reader.read("/path/to/lef/file.lef")
_lef.print()
def_reader = C_DefReader()
_def = def_reader.read("/path/to/def/file.def")
_def.print()It will read and print all information that have been read.
-
LEF/DEF Reader: A Python classes
C_LefReaderandC_DefReaderthat allows reading LEF/DEF files and extracting the design data. -
LEF Data Structures:
-
c_macros- a list of all macros in lef filec_num_macros- the number of macros in lef (use this to iterate overc_macros)
-
c_name- the name of macroc_class- the value ofCLASSstatementc_source- the value ofSOURCEstatementc_site_name- the value ofSITEstatemenc_origin_x- the postion of macro by x axisc_origin_y-the postion of macro by y axisc_size_x-the width of macroc_size_y- the height of macroc_foreign_name- the name of foreignc_foreign_x- the foreing's position by x axisc_foreign_y- the foreing's position by y axisc_pins- a list of macro's pinsc_num_pins- the number of pins (use this to iterate overc_pins)
-
c_rects- the obstruction's geometryc_num_rects- the number of rectangles in obstruction (use this to iterate overc_rects)
-
c_name- the pin's namec_direction- the value ofDIRECTIONstatementc_use- the value ofUSEstatementc_shape- the value ofSHAPEstatementc_ports- a list pf pin's portsc_num_ports- the number of porst in pin (use this to iterate overc_ports)
-
c_rects- the port's geometryc_num_rects- the number of rectangles in port (use this to iterate overc_rects)
-
c_layer- the layer namec_xl- the x value of lef top cornerc_yl- the y value of lef top cornerc_xh- the x value of right bottom cornerc_yh- the y value of right bottom corner
-
LEF Example
from lefdef import C_LefReader
lef_reader = C_LefReader()
lef = lef_reader.read("/path/to/lef/file.lef")
for i in range(lef.c_num_macros):
class_ = lef.c_macros[i].c_class
source = lef.c_macros[i].c_source
site_name = lef.c_macros[i].c_site_name
origin_x = lef.c_macros[i].c_origin_x
origin_y = lef.c_macros[i].c_origin_y
foreign_name = lef.c_macros[i].c_foreign_name
foreign_x = lef.c_macros[i].c_foreign_x
foreign_y = lef.c_macros[i].c_foreign_y
foreign_orient = lef.c_macros[i].c_foreign_orient
pins = lef.c_macros[i].c_pins
obs = lef.c_macros[i].c_obs
# Access pins
for j in range(lef.c_macros[i].c_num_pins):
name = pins[j].c_name
direction = pins[j].c_direction
use = pins[j].c_use
shape = pins[j].c_shape
ports = pins[j].c_ports
# Access pins's ports
for k in range(pins[j].c_num_ports):
rects = ports[k].c_rects
# Access ports's rectangles
for l in range(ports[k].c_num_rects):
layer = rects[l].c_layer
xl = rects[l].c_xl
yl = rects[l].c_yl
xh = rects[l].c_xh
yh = rects[l].c_yh
# Access obs's rectangles
for j in range(obs.c_num_rects):
layer = obs.rects[j].c_layer
xl = obs.rects[j].c_xl
yl = obs.rects[j].c_yl
xh = obs.rects[j].c_xh
yh = obs.rects[j].c_yh- DEF Data Structures:
-
c_die_area_width- a list of x points of die areac_die_area_height- a list of y points of die araec_num_points- the number of points of die arae (use this to iterate overc_die_area_widthandc_die_area_height)c_g_cell_grid_x- a list of gCellGrid by x axisc_num_g_cell_grid_x- the number of gCellGrid by x axis (use this to iterate overc_num_g_cell_grid_x)c_g_cell_grid_y- a list of gCellGrid by y axisc_num_g_cell_grid_y- the number of gCellGrid by y axis (use this to iterate overc_num_g_cell_grid_x)c_pins- a list of def's pinsc_num_pins- the number of pins (use this to iterate overc_pins)c_nets- a list of def's netsc_num_nets- the number of nets (use this to iterate overc_nets)c_rows- a list of def's rowsc_num_rows- the number of rows (use this to iterate overc_rows)c_tracks_x- a list of def's tracks by x axisc_num_tracks_x- the number of tracks by x axis (use this to iterate overc_tracks_x)c_tracks_y- a list of def's tracks by y axisc_num_tracks_y- the number of tracks by y axis (use this to iterate overc_tracks_y)
-
c_name- the net's namec_instances- a list of names of components in this netc_pins- a list of names of pins in this net, list length is equal toc_instances's lengthc_num_pins- the number of pins in this net
-
c_name- the pin namec_net- the pin's net namec_use- the value ofUSEstatementc_status- the value ofSTATUSstatementc_direction- the value ofDIRECTOINstatementc_orient- the pin's orientationc_rects- the pin's geometryc_num_rects- a number of rectangles (use this to iterate overc_rects)c_ports- a list of pin's portsc_num_ports- a number of ports (use this to iterate overc_ports)
-
c_id- the component name in the designc_name- the name of a model defined in the libraryc_status- the value ofSTATUSstatementc_source- the value ofSOURCEstatementc_oirent- the component's orientationc_x- the location by x axisc_y- the location by y axis
-
c_offest- the location of the first row/columnc_num- the number of rows/columnsc_step- the spacing between rows/columns
-
c_layer- the routing layer used for the tracksc_offest- location of the first track (column/row)c_num- the number of tracks to create for the grid by x or y axisc_step- he spacing between the tracks (column/row)
-
c_name- the row's namec_macro- the value ofSITEstatementc_x- the location of the first site in the row by x axsisc_y- the location of the first site in the row by y axsisc_num_x- a repeating set of sites that create the row by x axsisc_num_y- a repeating set of sites that create the row by y axsisc_step_x- the spacing between sites in vertical rowsc_step_y- the spacing between sites in horizontal rows
-
c_rects- the port's geometryc_num_rects- the number of rectangles in port (use this to iterate overc_rects)
-
c_layer- the layer namec_xl- the x value of lef top cornerc_yl- the y value of lef top cornerc_xh- the x value of right bottom cornerc_yh- the y value of right bottom corner
-
DEF Example
from lefdef import C_DefReader
def_reader = C_DefReader()
_def = def_reader.read("/path/to/def/file.def")
die_area_width = _def.c_die_area_width
die_area_height = _def.c_die_area_height
g_cell_grid_x = _def.c_g_cell_grid_x
num_g_cell_grid_x = _def.c_num_g_cell_grid_x
g_cell_grid_y = _def.c_g_cell_grid_y
components = _def.c_components
pins = _def.c_pins
nets = _def.c_nets
rows = _def.c_rows
tracks_x = _def.c_tracks_x
tracks_y = _def.c_tracks_y
# Access gCellGrid by x axis
for i in range(_def.c_num_g_cell_grid_x):
offset_x = g_cell_grid_x[i].c_offset
num_x = g_cell_grid_x[i].c_num
step_y = g_cell_grid_x[i].c_step
# Access gCellGrid by y axis
for i in range(_def.c_num_g_cell_grid_y):
offset_y = g_cell_grid_y[i].c_offset
num_y = g_cell_grid_y[i].c_num
step_y = g_cell_grid_y[i].c_step
# Access components
for i in range(_def.c_num_components):
id = components[i].c_id
name = components[i].c_name
status = components[i].c_status
source = components[i].c_source
orient = components[i].c_orient
x = components[i].c_x
y = components[i].c_y
# Access pins
for i in range(_def.c_num_pins):
name = pins[i].c_name
net = pins[i].c_net
use = pins[i].c_use
status = pins[i].c_status
direction = pins[i].c_direction
orient = pins[i].c_orient
x = pins[i].c_x
y = pins[i].c_y
rects = pins[i].c_rects
ports = pins[i].c_ports
# Access pin's rectangles
for j in range(pins[i].c_num_rects):
layer = rects[j].c_layer
xl = rects[j].c_xl
yl = rects[j].c_yl
xh = rects[j].c_xh
yh = rects[j].c_yh
# Access pin's ports
for j in range(pins[i].c_num_ports):
rects = ports[j].c_rects
# Access ports's rectangles
for k in range(ports[j].c_num_rects):
layer = rects[k].c_layer
xl = rects[k].c_xl
yl = rects[k].c_yl
xh = rects[k].c_xh
yh = rects[k].c_yh
# Access nets
for i in range(_def.c_num_nets):
name = nets[i].c_name
for j in range(nets[i].c_num_pins):
instance = nets[i].c_instances[j]
pins = nets[i].c_pins[j]
# Access rows
for i in range(_def.c_num_rows):
name = rows[i].c_name
macro = rows[i].c_macro
x = rows[i].c_x
y = rows[i].c_y
num_x = rows[i].c_num_x
num_y = rows[i].c_num_y
step_x = rows[i].c_step_x
step_y = rows[i].c_step_y
# Access tracks by x axis
for i in range(_def.c_num_tracks_x):
layer = tracks_x[i].c_layer
offset = tracks_x[i].c_offset
num = tracks_x[i].c_num
step = tracks_x[i].c_step
# Access tracks by y axis
for i in range(_def.c_num_tracks_y):
layer = tracks_y[i].c_layer
offset = tracks_y[i].c_offset
num = tracks_y[i].c_num
step = tracks_y[i].c_stepWe welcome contributions from the community! Whether it's a bug report, new feature, or a correction, your help is greatly appreciated. Here's how you can contribute:
-
Fork the Repository: Start by forking the lefdef-python repository.
-
Clone Your Fork:
git clone https://github.com/YOUR_USERNAME/lefdef-python.git cd lefdef-python -
Create a New Branch:
git checkout -b feature/your-feature-name
-
Make Your Changes: Implement your changes, enhancements, or bug fixes.
-
Commit and Push:
git add . git commit -m "Your detailed commit message" git push origin feature/your-feature-name
-
Open a Pull Request: Go to the lefdef-python repository on GitHub and click on the "New Pull Request" button. Select your fork and the branch you created to submit a pull request.
-
Wait for Review: Once your pull request is submitted, maintainers will review your changes. Address any feedback to get your changes merged.
If you find a bug or an issue, please create a new issue in the issue tracker describing the problem and providing steps to reproduce it.