A simple BLIF parser
Project description
BLIFPARSER
This is a simple Python library that parses BLIF (Berkeley Logic Interchange Format) files (used by SIS, Sequential Interactive Synthesis).
And also evalutes if some keyword's parameters have syntactically correct values.
Only the basic keywords are parsed (.model
, .inputs
, .outputs
, .names
, all the FSM keywords, .latch
, .exdc
, .end
).
More complex BLIF files with
.clock
,.gate
,.mlatch
,.clock_event
and delay constraits are only partially parsed.This is because the workflow I am supporting does not use these keywords
Currently only one .model
keyword per file is supported.
You can see this as a "feature" because it forces the use of a good practise: use many files, one per each component.
You can also use this library as a basic BLIF validator.
Complex checks such as cross file definition checks and input-output names check are NOT implemented because the primary intent of this library is to parse BLIF files.
A more full/complex validator is in the works (and it will use this parser).
WARNING
This parser DOES NOT use grammar files NOR PEG for parsing blif files:
this means that the parsing could be "not perfect".
If someone wants to contribute and change this feel free to make pull requests!
If this library inspires you to write a better parser from scratch, please let me know by making a GH issue
This means that the library works because:
- the BLIF (format) is simple: most of the time parameters are on the same line of the keywords
- (some) unit and end to end tests were written
Index
Requirements
- python 3 (>= 3.7)
Installation
First, install the library using PIP:
pip install blifparser
Then:
-
if you want to use this library as a validation tool, check the "As a validator tool" section
-
if you want to use this library inside your software, check the "As a library" section
If this is the only way you want to use this software, you can also install it using the installer on the Github Release page
Usage
As a validator tool
Execute the script using this command:
blifparser <input_path>
You can also execute it this way:
python -m blifparser <input_path>
Replace
<input_path>
with the path to the BLIF file to validate
When you have fixed the errors, execute the script until you have fixed all the errors.
Not all errors appear after the first script execution.
As a library
Basic/common usage:
# import the os library: useful to get the absolute path to the input file
import os
# import this library
import blifparser.blifparser as blifparser
# get the file path and pass it to the parser
filepath = os.path.abspath("example.blif")
parser = blifparser.BlifParser(filepath)
# get the object that contains the parsed data
# from the parser
blif = parser.blif
Now you can:
# get the name of the model
print(blif.model.name)
# get the list of the inputs
print(blif.inputs.inputs)
# get the list of the outputs
print(blif.outputs.outputs)
# get the list of .search keyword
print(blif.imports)
# get the imported file name/path of the first .search keyword
first_import = blif.imports[0]
print(first_import.filepath)
# get the list of subcircuits (.subckt)
print(blif.subcircuits)
# get data from the first subcircuit definition
first_subcircuit = blif.subcircuits[0]
print(first_subcircuit.modelname) # name of the model
print(first_subcircuit.params) # subcircuit's parameters
# get the list of boolean functions (.names)
print(blif.booleanfunctions)
# get data from the first boolean function definition
first_boolfunc = blif.booleanfunctions[0]
print(first_boolfunc.inputs) # list with the names of the inputs
print(first_boolfunc.output) # string with the name of the output
print(first_boolfunc.truthtable) # list of lists (each row is a truth table row)
# get the dictionary with the number of occurrencies of each keyword
print(blif.nkeywords)
# get the list of problems/issues
print(blif.problems)
# get the list of the latches
print(blif.latches)
# get the data of the first latch
first_latch = blif.latches[0]
print(first_latch.input) # name of the input
print(first_latch.output) # name of the output
print(first_latch.type) # type of latch (like "re", ...)
print(first_latch.control) # clock name
print(first_latch.initval) # initial value
# get the data of the FSM (Finite State Machine)
print(blif.fsm.i.num) # number of inputs
print(blif.fsm.o.num) # number of outputs
print(blif.fsm.s.num) # number of states
print(blif.fsm.p.num) # number of state transitions
print(blif.fsm.r.name) # name of the reset state
print(blif.fsm.transtable) # list of lists (contains the transition table)
You can also obtain a networkx graph using the get_graph()
method:
# import the os library: useful to get the absolute path to the input file
import os
# import this library
import blifparser.blifparser as blifparser
# get the file path and pass it to the parser
filepath = os.path.abspath("example.blif")
parser = blifparser.BlifParser(filepath)
# generate the graph and memorize some statistics
graph_data = parser.get_graph()
# retrive networkx graph: can be used to export it as an image or customize it
nx_graph = graph_data.nx_graph
# extract nodes from the graph: each node has inputs, outputs, a type and the color that can be used to fill the node
# > by default .model inputs are red, .model outputs are blue, everything else is black
ext_nodes = [n for n in nx_graph.nodes]
# retrive the length of the longest label: can be used to determine the height of the graph exported onto an image
longest_label = nx_graph.longest_label
# retrive the size of the "item" node that has the most number of inputs: can be used to determine the width of the graph exported onto an image
# > where "item" is .inputs/.outputs/.names/.subckt/.latch
max_inputs = nx_graph.max_inputs
Description
These are the first steps to use this library:
# import the os library: useful to get the absolute path to the input file
import os
# import this library
import blifparser.blifparser as blifparser
# get the file path and pass it to the parser
filepath = os.path.abspath("example.blif")
parser = blifparser.BlifParser(filepath)
# get the object that contains the parsed data
# from the parser
blif = parser.blif
# get an object that contains a networkx graph of the blif file and memorize some statistics
graph_data = parser.get_graph()
The blifparser.BlifParser()
object is the parser:
it prepares the file for parsing using the prepare_file()
method
and then creates a keywords.generic.Blif()
object that will contain
all the information parsed from the file.
The
prepare_file()
method copies the file and then removes (on the copy):
- the newlines made with the backslash "
\
"- the comments made with "
#
".
Then each line is read and parsed:
-
if the line contains a keyword, a "keyword" object is created and then "linked" to the
keywords.generic.Blif()
object (its parameters get parsed with the keyword)For example: if a
.model
keyword is found, akeywords.generic.Model()
object gets created and set in thekeywords.generic.Blif()
object. (keywords.generic.Blif().model
) -
if the line contains text and the line comes after the
.names
keyword it is interpreted as the truth table of the latest boolean function (defined by.names
)This behavior stops when the next keyword is found
-
if the line contains text and the line comes after the
.start_kiss
keyword it is interpreted as the transition table of the Finite State Machine.This behavior stops when the next keyword is found
-
If an unexpected text/keyword is found a "problem" or issue is collected inside the
keywords.generic.Blif().problems
list.
At the end of the parsing:
- if an FSM was found, a validation step checks if it is syntactically correct
- if some boolean functions were found, a validation step checks if they are syntactically correct
The other validation steps are executed during object definition
Now you can use the blif
object to get the parsed data
Check the "Usage > As a library" section for more details
Changelog
2022-12-12 2.0.0:
-
Added
get_graph()
method to theBlifParser
class: generates and returns an object containing a networkx graph with inputs, outputs, latches, subckts and boolean functions connected together.This object also contains statistics which can be used when exporting the graph to an image file to roughly determine the dimensions of the image.
-
Dropped python < 3.7 support.
2021-04-23 1.0.0:
First commit
Author
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
File details
Details for the file blifparser-2.0.0.tar.gz
.
File metadata
- Download URL: blifparser-2.0.0.tar.gz
- Upload date:
- Size: 17.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3e1345a1f04f3b23b66ec1c1121f2728b001c089cde16c45a2b3a2aeaa488c84 |
|
MD5 | 9025d8bdf2c7b2d86f163f7feac0a726 |
|
BLAKE2b-256 | 065a160a94a2c37112326f3ec632c6800deb6ddcca35b231ea7711ccbe253fc3 |
File details
Details for the file blifparser-2.0.0-py3-none-any.whl
.
File metadata
- Download URL: blifparser-2.0.0-py3-none-any.whl
- Upload date:
- Size: 17.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9ac51a4d0536ad39f766db6619b80627d71cdbbe4c8a270d62c69f025a005d53 |
|
MD5 | ae6f8c3015b39e9e7c94d68b14c61715 |
|
BLAKE2b-256 | ac2a3291f0b3bfd38df5bb91abb9a381e5eb625a476172430d2f2db12bd1f874 |