start documentation

This commit is contained in:
Stefan Holst committed 2020-12-15 19:20:30 +09:00
1 parent a77ac4a397
commit cff18e0915
11 files changed
+230 -78

No files matched your search

+49 -19
View File
@@ -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