interface -> io_nodes, io_loc fix
This commit is contained in:
1 parent
b2953aef25
commit
f0dac36ac7
11 files changed
+52
-34
No files matched your search
+11
-5
@@ -115,6 +115,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
@@ -125,7 +126,7 @@
|
||||
"\n",
|
||||
"A line in the circuit has a unique ID, a driver node and a receiver node. The connections in the dump show the direction (\">\" for output, \"<\" for input) and the line-ID. For example in `mycircuit`: Node-0 has one output connected to Line-1, and this Line-1 is connected to the input of Node-5.\n",
|
||||
"\n",
|
||||
"The `interface` is the list of nodes forming the ports (inputs and outputs):"
|
||||
"The `io_nodes` is the list of nodes forming the ports (inputs and outputs):"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -149,7 +150,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"mycircuit.interface"
|
||||
"mycircuit.io_nodes"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1326,9 +1327,9 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "worker",
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "worker"
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
@@ -1340,7 +1341,12 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.13"
|
||||
"version": "3.6.8"
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ class BenchTransformer(Transformer):
|
||||
|
||||
def parameters(self, args): return [self.c.get_or_add_fork(name) for name in args]
|
||||
|
||||
def interface(self, args): self.c.interface.extend(args[0])
|
||||
def interface(self, args): self.c.io_nodes.extend(args[0])
|
||||
|
||||
def assignment(self, args):
|
||||
name, cell_type, drivers = args
|
||||
|
||||
+25
-18
@@ -5,7 +5,7 @@ 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, defaultdict
|
||||
import re
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ class Circuit:
|
||||
to enforce consecutiveness.
|
||||
|
||||
A subset of nodes can be designated as primary input- or output-ports of the circuit.
|
||||
This is done by adding them to the :py:attr:`interface` list.
|
||||
This is done by adding them to the :py:attr:`io_nodes` list.
|
||||
"""
|
||||
def __init__(self, name=None):
|
||||
self.name = name
|
||||
@@ -219,13 +219,13 @@ class Circuit:
|
||||
|
||||
The position of a line in this list equals its index :code:`self.lines[42].index == 42`.
|
||||
"""
|
||||
self.interface = GrowingList()
|
||||
self.io_nodes = GrowingList()
|
||||
"""A list of nodes that are designated as primary input- or output-ports.
|
||||
|
||||
Port-nodes are contained in :py:attr:`nodes` as well as :py:attr:`interface`.
|
||||
The position of a node in the interface list corresponds to positions of logic values in test vectors.
|
||||
Port-nodes are contained in :py:attr:`nodes` as well as :py:attr:`io_nodes`.
|
||||
The position of a node in the io_nodes list corresponds to positions of logic values in test vectors.
|
||||
The port direction is not stored explicitly.
|
||||
Usually, nodes in the interface list without any lines in their :py:attr:`Node.ins` list are primary inputs,
|
||||
Usually, nodes in the io_nodes list without any lines in their :py:attr:`Node.ins` list are primary inputs,
|
||||
and nodes without any lines in their :py:attr:`Node.outs` list are regarded as primary outputs.
|
||||
"""
|
||||
self.cells = {}
|
||||
@@ -248,50 +248,57 @@ class Circuit:
|
||||
d = c.forks[line.driver.name] if line.driver.kind == '__fork__' else c.cells[line.driver.name]
|
||||
r = c.forks[line.reader.name] if line.reader.kind == '__fork__' else c.cells[line.reader.name]
|
||||
Line(c, (d, line.driver_pin), (r, line.reader_pin))
|
||||
for node in self.interface:
|
||||
for node in self.io_nodes:
|
||||
if node.kind == '__fork__':
|
||||
n = c.forks[node.name]
|
||||
else:
|
||||
n = c.cells[node.name]
|
||||
c.interface.append(n)
|
||||
c.io_nodes.append(n)
|
||||
return c
|
||||
|
||||
def __getstate__(self):
|
||||
nodes = [(node.name, node.kind) for node in self.nodes]
|
||||
lines = [(line.driver.index, line.driver_pin, line.reader.index, line.reader_pin) for line in self.lines]
|
||||
interface = [n.index for n in self.interface]
|
||||
io_nodes = [n.index for n in self.io_nodes]
|
||||
return {'name': self.name,
|
||||
'nodes': nodes,
|
||||
'lines': lines,
|
||||
'interface': interface }
|
||||
'io_nodes': io_nodes }
|
||||
|
||||
def __setstate__(self, state):
|
||||
self.name = state['name']
|
||||
self.nodes = IndexList()
|
||||
self.lines = IndexList()
|
||||
self.interface = GrowingList()
|
||||
self.io_nodes = GrowingList()
|
||||
self.cells = {}
|
||||
self.forks = {}
|
||||
for s in state['nodes']:
|
||||
Node(self, *s)
|
||||
for driver, driver_pin, reader, reader_pin in state['lines']:
|
||||
Line(self, (self.nodes[driver], driver_pin), (self.nodes[reader], reader_pin))
|
||||
for n in state['interface']:
|
||||
self.interface.append(self.nodes[n])
|
||||
for n in state['io_nodes']:
|
||||
self.io_nodes.append(self.nodes[n])
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.nodes == other.nodes and self.lines == other.lines and self.interface == other.interface
|
||||
return self.nodes == other.nodes and self.lines == other.lines and self.io_nodes == other.io_nodes
|
||||
|
||||
def dump(self):
|
||||
"""Returns a string representation of the circuit and all its nodes.
|
||||
"""
|
||||
header = f'{self.name}({",".join([str(n.index) for n in self.interface])})\n'
|
||||
header = f'{self.name}({",".join([str(n.index) for n in self.io_nodes])})\n'
|
||||
return header + '\n'.join([str(n) for n in self.nodes])
|
||||
|
||||
def __repr__(self):
|
||||
name = f' {self.name}' if self.name else ''
|
||||
return f'<Circuit{name} cells={len(self.cells)} forks={len(self.forks)} ' + \
|
||||
f'lines={len(self.lines)} ports={len(self.interface)}>'
|
||||
f'lines={len(self.lines)} ports={len(self.io_nodes)}>'
|
||||
|
||||
@property
|
||||
def cell_counts(self):
|
||||
counts = defaultdict(int)
|
||||
for n in self.cells.values():
|
||||
counts[n.kind] += 1
|
||||
return counts
|
||||
|
||||
def topological_order(self):
|
||||
"""Generator function to iterate over all nodes in topological order.
|
||||
@@ -375,8 +382,8 @@ class Circuit:
|
||||
|
||||
def io_loc(self, prefix):
|
||||
d_top = dict()
|
||||
for i, n in enumerate(list(self.interface) + [n for n in self.nodes if 'dff' in n.kind.lower()]):
|
||||
if m := re.match(fr'({prefix}.*?)((?:[_\[\]]\d+)*[_\[\]]*$)', n.name):
|
||||
for i, n in enumerate(list(self.io_nodes) + [n for n in self.nodes if 'dff' in n.kind.lower()]):
|
||||
if m := re.match(fr'({prefix}.*?)((?:\d+[_\[\]])*$)', n.name):
|
||||
path = [m[1]] + [int(v) for v in re.split(r'[_\[\]]+', m[2]) if len(v) > 0]
|
||||
d = d_top
|
||||
for j in path[:-1]:
|
||||
|
||||
@@ -32,7 +32,7 @@ class LogicSim:
|
||||
nbytes = (sims - 1) // 8 + 1
|
||||
dffs = [n for n in circuit.nodes if 'dff' in n.kind.lower()]
|
||||
latches = [n for n in circuit.nodes if 'latch' in n.kind.lower()]
|
||||
self.interface = list(circuit.interface) + dffs + latches
|
||||
self.interface = list(circuit.io_nodes) + dffs + latches
|
||||
|
||||
self.width = len(self.interface)
|
||||
"""The number of bits in the circuit state (number of ports + number of state-elements)."""
|
||||
|
||||
@@ -157,7 +157,7 @@ class Schedule:
|
||||
"""
|
||||
def __init__(self, circuit, strip_forks=False, keep_signals=True, signal_caps=1):
|
||||
self.circuit = circuit
|
||||
self.interface = list(circuit.interface) + [n for n in circuit.nodes if 'dff' in n.kind.lower()]
|
||||
self.interface = list(circuit.io_nodes) + [n for n in circuit.nodes if 'dff' in n.kind.lower()]
|
||||
|
||||
if isinstance(signal_caps, int):
|
||||
signal_caps = [signal_caps] * len(circuit.lines)
|
||||
@@ -303,3 +303,8 @@ class Schedule:
|
||||
self.vat[self.ppo_offset + i] = self.vat[n.ins[0]]
|
||||
|
||||
self.state_length = h.max_size
|
||||
|
||||
from collections import defaultdict
|
||||
self.prim_counts = defaultdict(int)
|
||||
names_dict = SimPrim.names()
|
||||
for op, _, _, _, _, _ in self.ops: self.prim_counts[names_dict[op]] += 1
|
||||
+1
-1
@@ -55,7 +55,7 @@ class StilFile:
|
||||
capture = dict((k, v.replace('\n', '').replace('N', '-')) for k, v in call.parameters.items())
|
||||
|
||||
def _maps(self, c):
|
||||
interface = list(c.interface) + [n for n in c.nodes if 'DFF' in n.kind]
|
||||
interface = list(c.io_nodes) + [n for n in c.nodes if 'DFF' in n.kind]
|
||||
intf_pos = dict((n.name, i) for i, n in enumerate(interface))
|
||||
pi_map = [intf_pos[n] for n in self.signal_groups['_pi']]
|
||||
po_map = [intf_pos[n] for n in self.signal_groups['_po']]
|
||||
|
||||
@@ -96,7 +96,7 @@ class VerilogTransformer(Transformer):
|
||||
for name in sd.names:
|
||||
n = Node(c, name, kind=sd.kind)
|
||||
if name in positions:
|
||||
c.interface[positions[name]] = n
|
||||
c.io_nodes[positions[name]] = n
|
||||
if sd.kind == 'input':
|
||||
Line(c, n, Node(c, name))
|
||||
for s1, s2 in assignments: # pass 1.5: process signal assignments
|
||||
|
||||
@@ -117,7 +117,7 @@ class WaveSim:
|
||||
self.circuit = circuit
|
||||
self.sims = sims
|
||||
self.overflows = 0
|
||||
self.interface = list(circuit.interface) + [n for n in circuit.nodes if 'dff' in n.kind.lower()]
|
||||
self.interface = list(circuit.io_nodes) + [n for n in circuit.nodes if 'dff' in n.kind.lower()]
|
||||
|
||||
self.lst_eat_valid = False
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ class WaveSim:
|
||||
self.circuit = circuit
|
||||
self.sims = sims
|
||||
self.overflows = 0
|
||||
self.interface = list(circuit.interface) + [n for n in circuit.nodes if 'dff' in n.kind.lower()]
|
||||
self.interface = list(circuit.io_nodes) + [n for n in circuit.nodes if 'dff' in n.kind.lower()]
|
||||
|
||||
self.lst_eat_valid = False
|
||||
|
||||
|
||||
+1
-1
@@ -12,4 +12,4 @@ def test_b01(mydir):
|
||||
def test_simple():
|
||||
c = bench.parse('input(a, b) output(z) z=and(a,b)')
|
||||
assert len(c.nodes) == 4
|
||||
assert len(c.interface) == 3
|
||||
assert len(c.io_nodes) == 3
|
||||
@@ -57,9 +57,9 @@ def test_circuit():
|
||||
assert 'in1' in c.cells
|
||||
assert 'and1' not in c.cells
|
||||
|
||||
c.interface[0] = in1
|
||||
c.interface[1] = in2
|
||||
c.interface[2] = out1
|
||||
c.io_nodes[0] = in1
|
||||
c.io_nodes[1] = in2
|
||||
c.io_nodes[2] = out1
|
||||
|
||||
and1 = Node(c, 'and1', kind='and')
|
||||
Line(c, in1, and1)
|
||||
|
||||
Reference in new issue
Block a user