start documentation
This commit is contained in:
1 parent
a77ac4a397
commit
cff18e0915
11 files changed
+230
-78
No files matched your search
+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
|
||||
|
||||
|
||||
@@ -19,36 +26,51 @@ class IndexList(list):
|
||||
|
||||
|
||||
class Node:
|
||||
"""A Node is 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.
|
||||
Each node contains:
|
||||
"""A named entity in a circuit (e.g. a gate, a standard cell,
|
||||
a named signal, or a fan-out point) that is connected to other nodes via lines.
|
||||
|
||||
* `self.index`: a circuit-unique integer index.
|
||||
* `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`).
|
||||
The constructor automatically adds the new node to the given circuit.
|
||||
"""
|
||||
def __init__(self, circuit, name, kind='__fork__'):
|
||||
if kind == '__fork__':
|
||||
if name in circuit.forks:
|
||||
raise ValueError(f'fork of name {name} already exists.')
|
||||
assert name not in circuit.forks, f'fork of name {name} already in circuit.'
|
||||
circuit.forks[name] = self
|
||||
else:
|
||||
if name in circuit.cells:
|
||||
raise ValueError(f'cell of name {name} already exists.')
|
||||
assert name not in circuit.cells, f'cell of name {name} already in circuit.'
|
||||
circuit.cells[name] = self
|
||||
self.index = len(circuit.nodes)
|
||||
circuit.nodes.append(self)
|
||||
self.circuit = circuit
|
||||
"""The :class:`Circuit` object the node is part of.
|
||||
"""
|
||||
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
|
||||
"""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()
|
||||
"""A list of input connections (:class:`Line` objects).
|
||||
"""
|
||||
self.outs = GrowingList()
|
||||
"""A list of output connections (:class:`Line` objects).
|
||||
"""
|
||||
|
||||
def __repr__(self):
|
||||
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}'
|
||||
|
||||
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:
|
||||
del self.circuit.nodes[self.index]
|
||||
if self.kind == '__fork__':
|
||||
@@ -66,8 +95,9 @@ class Node:
|
||||
|
||||
|
||||
class Line:
|
||||
"""A Line is a directional 1:1 connection between two Nodes. It always
|
||||
connects an output of a node (called `driver`) to an input of a node
|
||||
"""A directional 1:1 connection between two nodes.
|
||||
|
||||
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`).
|
||||
|
||||
Furthermore, `self.driver_pin` and `self.reader_pin` are the
|
||||
|
||||
Reference in new issue
Block a user