start documentation
This commit is contained in:
1 parent
a77ac4a397
commit
cff18e0915
11 files changed
+230
-78
No files matched your search
@@ -3,3 +3,8 @@
|
|||||||
**/.pytest_cache
|
**/.pytest_cache
|
||||||
**/.DS_Store
|
**/.DS_Store
|
||||||
**/*.pyc
|
**/*.pyc
|
||||||
|
docs/_build
|
||||||
|
build
|
||||||
|
dist
|
||||||
|
.idea
|
||||||
|
src/kyupy.egg-info
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
KyuPy - Processing VLSI Circuits With Ease
|
|
||||||
==========================================
|
|
||||||
|
|
||||||
KyuPy is a python package for high-performance processing and analysis of
|
|
||||||
non-hierarchical VLSI designs. Its purpose is to provide a rapid prototyping
|
|
||||||
platform to aid and accelerate research in the fields of VLSI test, diagnosis
|
|
||||||
and reliability. KyuPy is freely available under the MIT license.
|
|
||||||
|
|
||||||
|
|
||||||
Main Features
|
|
||||||
-------------
|
|
||||||
|
|
||||||
* Partial [lark](https://github.com/lark-parser/lark) parsers for common files used with synthesized designs:
|
|
||||||
bench, gate-level verilog, standard delay format (SDF), standard test interface language (STIL)
|
|
||||||
* Bit-parallel gate-level 2-, 4-, and 8-valued logic simulation
|
|
||||||
* GPU-accelerated high-throughput gate-level timing simulation
|
|
||||||
* High-performance through the use of [numpy](https://numpy.org) and [numba](https://numba.pydata.org)
|
|
||||||
|
|
||||||
|
|
||||||
Getting Started
|
|
||||||
---------------
|
|
||||||
|
|
||||||
KyuPy requires Python 3.6 or newer.
|
|
||||||
Install the latest release by running:
|
|
||||||
```commandline
|
|
||||||
pip3 install --user kyupy
|
|
||||||
```
|
|
||||||
For best performance, ensure you have [numba](https://pypi.org/project/numba) installed:
|
|
||||||
```commandline
|
|
||||||
pip3 install --user numba
|
|
||||||
```
|
|
||||||
GPU/CUDA support may [require some additional setup](https://numba.pydata.org/numba-doc/latest/cuda/index.html).
|
|
||||||
If CUDA or numba is not available, KyuPy will automatically fall back to slow, pure python execution.
|
|
||||||
|
|
||||||
The Jupyter Notebook [UsageExamples.ipynb](https://github.com/s-holst/kyupy/blob/main/UsageExamples.ipynb) on GitHub
|
|
||||||
contains some useful examples to get familiar with the API.
|
|
||||||
|
|
||||||
|
|
||||||
Development
|
|
||||||
-----------
|
|
||||||
|
|
||||||
To contribute to KyuPy or simply explore the source code, clone the KyuPy [repository](https://github.com/s-holst/kyupy) on GitHub.
|
|
||||||
Within your local checkout, run:
|
|
||||||
```commandline
|
|
||||||
pip3 install --user -e .
|
|
||||||
```
|
|
||||||
to make the kyupy package available in your python environment.
|
|
||||||
The source code comes with tests that can be run with:
|
|
||||||
```
|
|
||||||
pytest
|
|
||||||
```
|
|
||||||
|
|
||||||
KyuPy depends on the following packages:
|
|
||||||
* [lark-parser](https://pypi.org/project/lark-parser)
|
|
||||||
* [numpy](https://pypi.org/project/numpy)
|
|
||||||
* [numba](https://pypi.org/project/numba) (optional, required only for GPU/CUDA support)
|
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
KyuPy - Pythonic Processing of VLSI Circuits
|
||||||
|
============================================
|
||||||
|
|
||||||
|
KyuPy is a Python package for processing and analysis of non-hierarchical gate-level VLSI designs.
|
||||||
|
It contains fundamental building blocks for research software in the fields of VLSI test, diagnosis and reliability:
|
||||||
|
|
||||||
|
* Efficient data structures for gate-level circuits and related design data.
|
||||||
|
* Partial `lark <https://github.com/lark-parser/lark>`_ parsers for common design files like
|
||||||
|
bench, gate-level verilog, standard delay format (SDF), standard test interface language (STIL).
|
||||||
|
* Bit-parallel gate-level 2-, 4-, and 8-valued logic simulation.
|
||||||
|
* GPU-accelerated high-throughput gate-level timing simulation.
|
||||||
|
* High-performance through the use of `numpy <https://numpy.org>`_ and `numba <https://numba.pydata.org>`_.
|
||||||
|
|
||||||
|
|
||||||
|
Getting Started
|
||||||
|
---------------
|
||||||
|
|
||||||
|
KyuPy is available in `PyPI <https://pypi.org/project/kyupy>`_.
|
||||||
|
It requires Python 3.6 or newer, `lark-parser <https://pypi.org/project/lark-parser>`_, and `numpy <https://pypi.org/project/numpy>`_.
|
||||||
|
Although optional, `numba <https://pypi.org/project/numba>`_ should be installed for best performance.
|
||||||
|
GPU/CUDA support in numba may `require some additional setup <https://numba.pydata.org/numba-doc/latest/cuda/index.html>`_.
|
||||||
|
If numba is not available, KyuPy will automatically fall back to slow, pure Python execution.
|
||||||
|
|
||||||
|
The Jupyter Notebook `UsageExamples.ipynb <https://github.com/s-holst/kyupy/blob/main/UsageExamples.ipynb>`_ contains some useful examples to get familiar with the API.
|
||||||
|
|
||||||
|
To work with the latest pre-release source code, clone the `KyuPy GitHub repository <https://github.com/s-holst/kyupy>`_.
|
||||||
|
Run ``pip3 install --user -e .`` within your local checkout to make the package available in your Python environment.
|
||||||
|
The source code comes with tests that can be run with ``pytest``.
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# Minimal makefile for Sphinx documentation
|
||||||
|
#
|
||||||
|
|
||||||
|
# You can set these variables from the command line, and also
|
||||||
|
# from the environment for the first two.
|
||||||
|
SPHINXOPTS ?=
|
||||||
|
SPHINXBUILD ?= sphinx-build
|
||||||
|
SOURCEDIR = .
|
||||||
|
BUILDDIR = _build
|
||||||
|
|
||||||
|
# Put it first so that "make" without argument is like "make help".
|
||||||
|
help:
|
||||||
|
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||||
|
|
||||||
|
.PHONY: help Makefile
|
||||||
|
|
||||||
|
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||||
|
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||||
|
%: Makefile
|
||||||
|
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
# Configuration file for the Sphinx documentation builder.
|
||||||
|
#
|
||||||
|
# This file only contains a selection of the most common options. For a full
|
||||||
|
# list see the documentation:
|
||||||
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||||
|
|
||||||
|
# -- Path setup --------------------------------------------------------------
|
||||||
|
|
||||||
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
|
#
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import sphinx_rtd_theme
|
||||||
|
sys.path.insert(0, os.path.abspath('../src'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
|
project = 'KyuPy'
|
||||||
|
copyright = '2020, Stefan Holst'
|
||||||
|
author = 'Stefan Holst'
|
||||||
|
|
||||||
|
# The full version, including alpha/beta/rc tags
|
||||||
|
release = '0.0.2'
|
||||||
|
|
||||||
|
|
||||||
|
# -- General configuration ---------------------------------------------------
|
||||||
|
|
||||||
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
|
# ones.
|
||||||
|
extensions = [
|
||||||
|
'sphinx.ext.autodoc',
|
||||||
|
'sphinx_rtd_theme',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
|
templates_path = ['_templates']
|
||||||
|
|
||||||
|
# List of patterns, relative to source directory, that match files and
|
||||||
|
# directories to ignore when looking for source files.
|
||||||
|
# This pattern also affects html_static_path and html_extra_path.
|
||||||
|
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for HTML output -------------------------------------------------
|
||||||
|
|
||||||
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
|
# a list of builtin themes.
|
||||||
|
#
|
||||||
|
# html_theme = 'alabaster'
|
||||||
|
html_theme = 'sphinx_rtd_theme'
|
||||||
|
|
||||||
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
|
html_static_path = ['_static']
|
||||||
|
|
||||||
|
autodoc_default_options = {
|
||||||
|
'member-order': 'bysource',
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
Core Data Structures
|
||||||
|
====================
|
||||||
|
|
||||||
|
KyuPy provides two types of core data structures, one for gate-level circuits, and a few others for representing and storing logic data and signal values.
|
||||||
|
The data structures are designed to work together nicely with numpy arrays.
|
||||||
|
For example, all the nodes and connections in the circuit graph have numerical indices that can be used to access ndarrays with associated data.
|
||||||
|
Circuit graphs also define an ordering of inputs, outputs and other nodes to easily process test vector data and alike.
|
||||||
|
|
||||||
|
Module :mod:`kyupy.circuit`
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
.. automodule:: kyupy.circuit
|
||||||
|
|
||||||
|
.. autoclass:: kyupy.circuit.Node
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: kyupy.circuit.Circuit
|
||||||
|
:members:
|
||||||
|
|
||||||
|
Logic Values and Arrays
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
.. automodule:: kyupy.logic
|
||||||
|
|
||||||
|
.. autoclass:: kyupy.logic.MVArray
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: kyupy.logic.BPArray
|
||||||
|
:members:
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
.. include:: ../README.rst
|
||||||
|
|
||||||
|
API Reference
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
datastructures
|
||||||
|
parsers
|
||||||
|
simulators
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
Parsers
|
||||||
|
=======
|
||||||
|
|
||||||
|
bench
|
||||||
|
|
||||||
|
verilog
|
||||||
|
|
||||||
|
SDF
|
||||||
|
|
||||||
|
STIL
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Simulators
|
||||||
|
==========
|
||||||
|
|
||||||
|
Logic Sim
|
||||||
|
|
||||||
|
Wave Sim
|
||||||
|
|
||||||
|
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
from setuptools import setup, find_packages
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
with open('README.md', 'r') as f:
|
with open('README.rst', 'r') as f:
|
||||||
long_description = f.read()
|
long_description = f.read()
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='kyupy',
|
name='kyupy',
|
||||||
version='0.0.1',
|
version='0.0.2',
|
||||||
description='High-performance processing and analysis of non-hierarchical VLSI designs',
|
description='High-performance processing and analysis of non-hierarchical VLSI designs',
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
long_description_content_type='text/markdown',
|
|
||||||
packages=find_packages(where='src'),
|
packages=find_packages(where='src'),
|
||||||
package_dir={'': 'src'},
|
package_dir={'': 'src'},
|
||||||
url='https://github.com/s-holst/kyupy',
|
url='https://github.com/s-holst/kyupy',
|
||||||
|
|||||||
+49
-19
@@ -1,3 +1,10 @@
|
|||||||
|
"""Data structures for representing non-hierarchical gate-level circuits.
|
||||||
|
|
||||||
|
The class :class:`Circuit` is a container of nodes connected by lines.
|
||||||
|
A node is an instance of class :class:`Node`,
|
||||||
|
and a line is an instance of class :class:`Line`.
|
||||||
|
"""
|
||||||
|
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
|
||||||
|
|
||||||
@@ -19,36 +26,51 @@ class IndexList(list):
|
|||||||
|
|
||||||
|
|
||||||
class Node:
|
class Node:
|
||||||
"""A Node is a named entity in a circuit (e.g. a gate, a standard cell,
|
"""A named entity in a circuit (e.g. a gate, a standard cell,
|
||||||
a named signal, or a fan-out point) that has connections to other nodes.
|
a named signal, or a fan-out point) that is connected to other nodes via lines.
|
||||||
Each node contains:
|
|
||||||
|
|
||||||
* `self.index`: a circuit-unique integer index.
|
The constructor automatically adds the new node to the given circuit.
|
||||||
* `self.kind`: a type describing its function (e.g. 'AND', 'NOR').
|
|
||||||
The type '__fork__' is special. It signifies a named signal
|
|
||||||
or a fan-out in the circuit. Any other type is considered a physical cell.
|
|
||||||
* `self.name`: a name. Names must be unique among all forks and all cells
|
|
||||||
in the circuit. However, a fork (`self.kind=='__fork__'`) and a cell with
|
|
||||||
the same name may coexist.
|
|
||||||
* `self.ins`: a list of input connections (objects of class `Line`)
|
|
||||||
* `self.outs`: a list of output connections (objects of class `Line`).
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, circuit, name, kind='__fork__'):
|
def __init__(self, circuit, name, kind='__fork__'):
|
||||||
if kind == '__fork__':
|
if kind == '__fork__':
|
||||||
if name in circuit.forks:
|
assert name not in circuit.forks, f'fork of name {name} already in circuit.'
|
||||||
raise ValueError(f'fork of name {name} already exists.')
|
|
||||||
circuit.forks[name] = self
|
circuit.forks[name] = self
|
||||||
else:
|
else:
|
||||||
if name in circuit.cells:
|
assert name not in circuit.cells, f'cell of name {name} already in circuit.'
|
||||||
raise ValueError(f'cell of name {name} already exists.')
|
|
||||||
circuit.cells[name] = self
|
circuit.cells[name] = self
|
||||||
self.index = len(circuit.nodes)
|
|
||||||
circuit.nodes.append(self)
|
circuit.nodes.append(self)
|
||||||
self.circuit = circuit
|
self.circuit = circuit
|
||||||
|
"""The :class:`Circuit` object the node is part of.
|
||||||
|
"""
|
||||||
self.name = name
|
self.name = name
|
||||||
|
"""The name of the node.
|
||||||
|
|
||||||
|
Names must be unique among all forks and all cells in the circuit.
|
||||||
|
However, a fork (:code:`kind=='__fork__'`) and a cell with the same name may coexist.
|
||||||
|
"""
|
||||||
self.kind = kind
|
self.kind = kind
|
||||||
|
"""A string describing the type of the node.
|
||||||
|
|
||||||
|
Common types are the names from a standard cell library or general gate names like 'AND' or 'NOR'.
|
||||||
|
If :code:`kind` is set to '__fork__', it receives special treatment.
|
||||||
|
A `fork` describes a named signal or a fan-out point in the circuit and not a physical `cell` like a gate.
|
||||||
|
In the circuit, the namespaces of forks and cells are kept separate.
|
||||||
|
While :code:`name` must be unique among all forks and all cells, a fork can have the same name as a cell.
|
||||||
|
The :code:`index`, however, is unique among all nodes; a fork cannot have the same index as a cell.
|
||||||
|
"""
|
||||||
|
self.index = len(circuit.nodes) - 1
|
||||||
|
"""A unique and consecutive integer index of the node within the circuit.
|
||||||
|
|
||||||
|
It can be used to store additional data about the node :code:`n`
|
||||||
|
by allocating an array or list :code:`my_data` of length :code:`len(n.circuit.nodes)` and
|
||||||
|
accessing it by :code:`my_data[n.index]`.
|
||||||
|
"""
|
||||||
self.ins = GrowingList()
|
self.ins = GrowingList()
|
||||||
|
"""A list of input connections (:class:`Line` objects).
|
||||||
|
"""
|
||||||
self.outs = GrowingList()
|
self.outs = GrowingList()
|
||||||
|
"""A list of output connections (:class:`Line` objects).
|
||||||
|
"""
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
ins = ' '.join([f'<{line.index}' if line is not None else '<None' for line in self.ins])
|
ins = ' '.join([f'<{line.index}' if line is not None else '<None' for line in self.ins])
|
||||||
@@ -56,6 +78,13 @@ class Node:
|
|||||||
return f'{self.index}:{self.kind}"{self.name}" {ins} {outs}'
|
return f'{self.index}:{self.kind}"{self.name}" {ins} {outs}'
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
|
"""Removes the node from its circuit.
|
||||||
|
|
||||||
|
Lines may still reference the removed node.
|
||||||
|
The user must connect such lines to other nodes or remove the lines from the circuit.
|
||||||
|
To keep the indices consecutive, the node with the highest index within the circuit
|
||||||
|
will be assigned the index of the removed node.
|
||||||
|
"""
|
||||||
if self.circuit is not None:
|
if self.circuit is not None:
|
||||||
del self.circuit.nodes[self.index]
|
del self.circuit.nodes[self.index]
|
||||||
if self.kind == '__fork__':
|
if self.kind == '__fork__':
|
||||||
@@ -66,8 +95,9 @@ class Node:
|
|||||||
|
|
||||||
|
|
||||||
class Line:
|
class Line:
|
||||||
"""A Line is a directional 1:1 connection between two Nodes. It always
|
"""A directional 1:1 connection between two nodes.
|
||||||
connects an output of a node (called `driver`) to an input of a node
|
|
||||||
|
It always connects an output of a node (called `driver`) to an input of a node
|
||||||
(called `reader`) and has a circuit-unique index (`self.index`).
|
(called `reader`) and has a circuit-unique index (`self.index`).
|
||||||
|
|
||||||
Furthermore, `self.driver_pin` and `self.reader_pin` are the
|
Furthermore, `self.driver_pin` and `self.reader_pin` are the
|
||||||
|
|||||||
Reference in new issue
Block a user