blifparser


Nameblifparser JSON
Version 2.0.0 PyPI version JSON
download
home_pagehttps://github.com/mario33881/blifparser
SummaryA simple BLIF parser
upload_time2022-12-12 14:04:33
maintainer
docs_urlNone
authorZenaro Stefano (mario33881)
requires_python>=3.7
licenseMIT
keywords sis blif parser development
VCS
bugtrack_url
requirements networkx
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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](https://en.wikipedia.org/wiki/Parsing_expression_grammar) 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](#requirements)
* [Installation](#installation)
* [Usage](#usage)
* [Description](#description)
* [Changelog](#changelog)
* [Author](#author)

## 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](#as-a-validator-tool)" section

* if you want to use this library inside your software, check the "[As a library](#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:
```py
# 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:

```py
# 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:
```python
# 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:
```py
# 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, a ```keywords.generic.Model()``` object
    > gets created and set in the ```keywords.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](#as-a-library)" section for more details

## Changelog

**2022-12-12 2.0.0**:

* Added ```get_graph()``` method to the ```BlifParser``` 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
[Zenaro Stefano (mario33881)](https://github.com/mario33881)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/mario33881/blifparser",
    "name": "blifparser",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "SIS,BLIF,parser,development",
    "author": "Zenaro Stefano (mario33881)",
    "author_email": "mariortgasd@hotmail.com",
    "download_url": "https://files.pythonhosted.org/packages/06/5a/160a94a2c37112326f3ec632c6800deb6ddcca35b231ea7711ccbe253fc3/blifparser-2.0.0.tar.gz",
    "platform": null,
    "description": "# BLIFPARSER\r\n\r\nThis is a simple Python library that parses BLIF (Berkeley Logic Interchange Format) files (used by SIS, Sequential Interactive Synthesis).\r\n> And also evalutes if some keyword's parameters have syntactically correct values.\r\n\r\nOnly the basic keywords are parsed (```.model```, ```.inputs```, ```.outputs```, ```.names```, all the FSM keywords, ```.latch```, ```.exdc```, ```.end```).\r\n> More complex BLIF files with ```.clock```, ```.gate```, ```.mlatch```, ```.clock_event``` and delay constraits are only partially parsed.\r\n>\r\n> This is because the workflow I am supporting does not use these keywords\r\n\r\nCurrently only one ```.model``` keyword per file is supported.\r\n> You can see this as a \"feature\" because it forces the use of a good practise: use many files, one per each component.\r\n\r\nYou can also use this library as a basic BLIF validator.\r\n> Complex checks such as cross file definition checks and input-output names check are NOT implemented\r\n> because the primary intent of this library is to parse BLIF files.\r\n\r\nA more full/complex validator is in the works (and it will use this parser).\r\n\r\n---\r\n---\r\n\r\nWARNING\r\n\r\nThis parser DOES NOT use grammar files NOR [PEG](https://en.wikipedia.org/wiki/Parsing_expression_grammar) for parsing blif files:\r\n\r\nthis means that the parsing could be \"not perfect\".\r\n> If someone wants to contribute and change this feel free to make pull requests!\r\n>\r\n> If this library inspires you to write a better parser from scratch, please let me know by making a GH issue\r\n\r\nThis means that the library works because:\r\n* the BLIF (format) is simple: most of the time parameters are on the same line of the keywords\r\n* (some) unit and end to end tests were written\r\n\r\n---\r\n---\r\n\r\n## Index\r\n\r\n* [Requirements](#requirements)\r\n* [Installation](#installation)\r\n* [Usage](#usage)\r\n* [Description](#description)\r\n* [Changelog](#changelog)\r\n* [Author](#author)\r\n\r\n## Requirements\r\n* python 3 (>= 3.7)\r\n\r\n## Installation\r\n\r\nFirst, install the library using PIP:\r\n\r\n    pip install blifparser\r\n\r\nThen:\r\n* if you want to use this library as a validation tool, check the \"[As a validator tool](#as-a-validator-tool)\" section\r\n\r\n* if you want to use this library inside your software, check the \"[As a library](#as-a-library)\" section\r\n    > 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\r\n\r\n## Usage\r\n\r\n## As a validator tool\r\n\r\nExecute the script using this command:\r\n\r\n    blifparser <input_path>\r\n\r\nYou can also execute it this way:\r\n\r\n    python -m blifparser <input_path>\r\n\r\n> Replace ```<input_path>``` with the path to the BLIF file to validate\r\n\r\nWhen you have fixed the errors, execute the script until\r\nyou have fixed all the errors.\r\n> Not all errors appear after the first script execution.\r\n\r\n### As a library\r\n\r\nBasic/common usage:\r\n```py\r\n# import the os library: useful to get the absolute path to the input file\r\nimport os\r\n# import this library\r\nimport blifparser.blifparser as blifparser\r\n\r\n# get the file path and pass it to the parser\r\nfilepath = os.path.abspath(\"example.blif\")\r\nparser = blifparser.BlifParser(filepath)\r\n\r\n# get the object that contains the parsed data\r\n# from the parser\r\nblif = parser.blif\r\n```\r\n\r\nNow you can:\r\n\r\n```py\r\n# get the name of the model\r\nprint(blif.model.name)\r\n\r\n# get the list of the inputs\r\nprint(blif.inputs.inputs)\r\n\r\n# get the list of the outputs\r\nprint(blif.outputs.outputs)\r\n\r\n# get the list of .search keyword\r\nprint(blif.imports)\r\n\r\n# get the imported file name/path of the first .search keyword\r\nfirst_import = blif.imports[0]\r\nprint(first_import.filepath)\r\n\r\n# get the list of subcircuits (.subckt)\r\nprint(blif.subcircuits)\r\n\r\n# get data from the first subcircuit definition\r\nfirst_subcircuit = blif.subcircuits[0]\r\nprint(first_subcircuit.modelname)  # name of the model\r\nprint(first_subcircuit.params)     # subcircuit's parameters\r\n\r\n# get the list of boolean functions (.names)\r\nprint(blif.booleanfunctions)\r\n\r\n# get data from the first boolean function definition\r\nfirst_boolfunc = blif.booleanfunctions[0]\r\nprint(first_boolfunc.inputs)      # list with the names of the inputs\r\nprint(first_boolfunc.output)      # string with the name of the output\r\nprint(first_boolfunc.truthtable)  # list of lists (each row is a truth table row)\r\n\r\n# get the dictionary with the number of occurrencies of each keyword\r\nprint(blif.nkeywords)\r\n\r\n# get the list of problems/issues\r\nprint(blif.problems)\r\n\r\n# get the list of the latches\r\nprint(blif.latches)\r\n\r\n# get the data of the first latch\r\nfirst_latch = blif.latches[0]\r\nprint(first_latch.input)    # name of the input\r\nprint(first_latch.output)   # name of the output\r\nprint(first_latch.type)     # type of latch (like \"re\", ...)\r\nprint(first_latch.control)  # clock name\r\nprint(first_latch.initval)  # initial value\r\n\r\n# get the data of the FSM (Finite State Machine)\r\nprint(blif.fsm.i.num)       # number of inputs\r\nprint(blif.fsm.o.num)       # number of outputs\r\nprint(blif.fsm.s.num)       # number of states\r\nprint(blif.fsm.p.num)       # number of state transitions\r\nprint(blif.fsm.r.name)      # name of the reset state\r\nprint(blif.fsm.transtable)  # list of lists (contains the transition table)\r\n```\r\n\r\nYou can also obtain a networkx graph using the ```get_graph()``` method:\r\n```python\r\n# import the os library: useful to get the absolute path to the input file\r\nimport os\r\n# import this library\r\nimport blifparser.blifparser as blifparser\r\n\r\n# get the file path and pass it to the parser\r\nfilepath = os.path.abspath(\"example.blif\")\r\nparser = blifparser.BlifParser(filepath)\r\n\r\n# generate the graph and memorize some statistics\r\ngraph_data = parser.get_graph()\r\n\r\n# retrive networkx graph: can be used to export it as an image or customize it\r\nnx_graph = graph_data.nx_graph\r\n\r\n# extract nodes from the graph: each node has inputs, outputs, a type and the color that can be used to fill the node\r\n# > by default .model inputs are red, .model outputs are blue, everything else is black\r\next_nodes = [n for n in nx_graph.nodes]\r\n\r\n# retrive the length of the longest label: can be used to determine the height of the graph exported onto an image\r\nlongest_label = nx_graph.longest_label\r\n\r\n# 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\r\n# > where \"item\" is .inputs/.outputs/.names/.subckt/.latch\r\nmax_inputs = nx_graph.max_inputs\r\n```\r\n\r\n## Description\r\n\r\nThese are the first steps to use this library:\r\n```py\r\n# import the os library: useful to get the absolute path to the input file\r\nimport os\r\n# import this library\r\nimport blifparser.blifparser as blifparser\r\n\r\n# get the file path and pass it to the parser\r\nfilepath = os.path.abspath(\"example.blif\")\r\nparser = blifparser.BlifParser(filepath)\r\n\r\n# get the object that contains the parsed data\r\n# from the parser\r\nblif = parser.blif\r\n\r\n# get an object that contains a networkx graph of the blif file and memorize some statistics\r\ngraph_data = parser.get_graph()\r\n```\r\n\r\nThe ```blifparser.BlifParser()``` object is the parser:\r\nit prepares the file for parsing using the ```prepare_file()``` method\r\nand then creates a ```keywords.generic.Blif()``` object that will contain\r\nall the information parsed from the file.\r\n> The ```prepare_file()``` method copies the file and \r\n> then removes (on the copy): \r\n> * the newlines made with the backslash \"```\\```\"\r\n> * the comments made with \"```#```\".\r\n\r\nThen each line is read and parsed:\r\n* if the line contains a keyword, a \"keyword\" object is created and then\r\n  \"linked\" to the ```keywords.generic.Blif()``` object (its parameters get parsed with the keyword)\r\n\r\n    > For example: if a ```.model``` keyword is found, a ```keywords.generic.Model()``` object\r\n    > gets created and set in the ```keywords.generic.Blif()``` object. (```keywords.generic.Blif().model```)\r\n\r\n* if the line contains text and the line comes after the ```.names``` keyword\r\n  it is interpreted as the truth table of the latest boolean function (defined by ```.names```)\r\n    \r\n    > This behavior stops when the next keyword is found\r\n\r\n* if the line contains text and the line comes after the ```.start_kiss``` keyword\r\n  it is interpreted as the transition table of the Finite State Machine.\r\n\r\n    > This behavior stops when the next keyword is found\r\n\r\n* If an unexpected text/keyword is found a \"problem\" or issue is collected inside the ```keywords.generic.Blif().problems``` list.\r\n\r\nAt the end of the parsing:\r\n* if an FSM was found, a validation step checks if it is syntactically correct\r\n* if some boolean functions were found, a validation step checks if they are syntactically correct\r\n> The other validation steps are executed during object definition\r\n\r\nNow you can use the ```blif``` object to get the parsed data\r\n> Check the \"Usage > [As a library](#as-a-library)\" section for more details\r\n\r\n## Changelog\r\n\r\n**2022-12-12 2.0.0**:\r\n\r\n* Added ```get_graph()``` method to the ```BlifParser``` class: generates and returns an object containing a networkx graph with inputs, outputs, latches, subckts and boolean functions connected together.\r\n  > 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.\r\n\r\n* Dropped python < 3.7 support.\r\n\r\n**2021-04-23 1.0.0**:\r\n\r\nFirst commit\r\n\r\n## Author\r\n[Zenaro Stefano (mario33881)](https://github.com/mario33881)\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A simple BLIF parser",
    "version": "2.0.0",
    "split_keywords": [
        "sis",
        "blif",
        "parser",
        "development"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "ae6f8c3015b39e9e7c94d68b14c61715",
                "sha256": "9ac51a4d0536ad39f766db6619b80627d71cdbbe4c8a270d62c69f025a005d53"
            },
            "downloads": -1,
            "filename": "blifparser-2.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "ae6f8c3015b39e9e7c94d68b14c61715",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 17368,
            "upload_time": "2022-12-12T14:04:31",
            "upload_time_iso_8601": "2022-12-12T14:04:31.163426Z",
            "url": "https://files.pythonhosted.org/packages/ac/2a/3291f0b3bfd38df5bb91abb9a381e5eb625a476172430d2f2db12bd1f874/blifparser-2.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "9025d8bdf2c7b2d86f163f7feac0a726",
                "sha256": "3e1345a1f04f3b23b66ec1c1121f2728b001c089cde16c45a2b3a2aeaa488c84"
            },
            "downloads": -1,
            "filename": "blifparser-2.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "9025d8bdf2c7b2d86f163f7feac0a726",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 17609,
            "upload_time": "2022-12-12T14:04:33",
            "upload_time_iso_8601": "2022-12-12T14:04:33.188069Z",
            "url": "https://files.pythonhosted.org/packages/06/5a/160a94a2c37112326f3ec632c6800deb6ddcca35b231ea7711ccbe253fc3/blifparser-2.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-12-12 14:04:33",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "mario33881",
    "github_project": "blifparser",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "networkx",
            "specs": [
                [
                    "==",
                    "2.6.3"
                ]
            ]
        }
    ],
    "lcname": "blifparser"
}
        
Elapsed time: 0.01822s