|
|
|
@ -134,10 +134,10 @@ class Node: |
|
|
|
|
|
|
|
|
|
|
|
This is ok, because (name, kind) is unique within a circuit. |
|
|
|
This is ok, because (name, kind) is unique within a circuit. |
|
|
|
""" |
|
|
|
""" |
|
|
|
return self.name == other.name and self.kind == other.kind |
|
|
|
return self.name == other.name and self.kind == other.kind and self.circuit == other.circuit |
|
|
|
|
|
|
|
|
|
|
|
def __hash__(self): |
|
|
|
def __hash__(self): |
|
|
|
return hash((self.name, self.kind)) |
|
|
|
return hash((self.name, self.kind, id(self.circuit))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Line: |
|
|
|
class Line: |
|
|
|
@ -539,9 +539,6 @@ class Circuit: |
|
|
|
for n in state['io_nodes']: |
|
|
|
for n in state['io_nodes']: |
|
|
|
self.io_nodes.append(self.nodes[n]) |
|
|
|
self.io_nodes.append(self.nodes[n]) |
|
|
|
|
|
|
|
|
|
|
|
def __eq__(self, other): |
|
|
|
|
|
|
|
return self.nodes == other.nodes and self.lines == other.lines and self.io_nodes == other.io_nodes |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __repr__(self): |
|
|
|
def __repr__(self): |
|
|
|
return f'{{name: "{self.name}", cells: {len(self.cells)}, forks: {len(self.forks)}, lines: {len(self.lines)}, io_nodes: {len(self.io_nodes)}}}' |
|
|
|
return f'{{name: "{self.name}", cells: {len(self.cells)}, forks: {len(self.forks)}, lines: {len(self.lines)}, io_nodes: {len(self.io_nodes)}}}' |
|
|
|
|
|
|
|
|
|
|
|
@ -651,9 +648,9 @@ class Circuit: |
|
|
|
region.append(n) |
|
|
|
region.append(n) |
|
|
|
yield stem, region |
|
|
|
yield stem, region |
|
|
|
|
|
|
|
|
|
|
|
def dot(self, format='svg'): |
|
|
|
def dot(self, format='svg', graph_attr={}, line_labels={}): |
|
|
|
from graphviz import Digraph |
|
|
|
from graphviz import Digraph |
|
|
|
dot = Digraph(format=format, graph_attr={'rankdir': 'LR', 'splines': 'true'}) |
|
|
|
dot = Digraph(format=format, graph_attr={'rankdir': 'LR', 'splines': 'true', 'size': '10', 'ranksep': '0.1'} | graph_attr) |
|
|
|
|
|
|
|
|
|
|
|
s_dict = dict((n, i) for i, n in enumerate(self.s_nodes)) |
|
|
|
s_dict = dict((n, i) for i, n in enumerate(self.s_nodes)) |
|
|
|
node_level = np.zeros(len(self.nodes), dtype=np.uint32) |
|
|
|
node_level = np.zeros(len(self.nodes), dtype=np.uint32) |
|
|
|
@ -666,20 +663,24 @@ class Circuit: |
|
|
|
with dot.subgraph() as s: |
|
|
|
with dot.subgraph() as s: |
|
|
|
s.attr(rank='same') |
|
|
|
s.attr(rank='same') |
|
|
|
for n in level_nodes[lv]: |
|
|
|
for n in level_nodes[lv]: |
|
|
|
ins = '|'.join([f'<i{i}>{i}' for i in range(len(n.ins))]) |
|
|
|
ins = '{' + '|'.join([f'<i{i}>{i}' for i in range(len(n.ins))]) + '}|' if len(n.ins) > 1 else '' |
|
|
|
outs = '|'.join([f'<o{i}>{i}' for i in range(len(n.outs))]) |
|
|
|
outs = '|{' + '|'.join([f'<o{i}>{i}' for i in range(len(n.outs))]) + '}' if len(n.outs) > 1 else '' |
|
|
|
io = f' [{s_dict[n]}]' if n in s_dict else '' |
|
|
|
io = f' [{s_dict[n]}]' if n in s_dict else '' |
|
|
|
s.node(name=str(n.index), label = fr'{{{{{ins}}}|{n.index}{io}\n{n.kind}\n{n.name}|{{{outs}}}}}', shape='record') |
|
|
|
color = '#f5f5f5' if n.kind == '__fork__' else '#cccccc' |
|
|
|
|
|
|
|
kind = '' if n.kind == '__fork__' else fr'\n{n.kind}' |
|
|
|
|
|
|
|
s.node(name=str(n.index), label = fr'{{{ins}{n.index}{io}{kind}\n{n.name}{outs}}}', shape='record', style='filled', fillcolor=color) |
|
|
|
|
|
|
|
|
|
|
|
for l in self.lines: |
|
|
|
for l in self.lines: |
|
|
|
driver, reader = f'{l.driver.index}:o{l.driver_pin}', f'{l.reader.index}:i{l.reader_pin}' |
|
|
|
driver = f'{l.driver.index}:o{l.driver_pin}' if len(l.driver.outs)>1 else f'{l.driver.index}' |
|
|
|
|
|
|
|
reader = f'{l.reader.index}:i{l.reader_pin}' if len(l.reader.ins)>1 else f'{l.reader.index}' |
|
|
|
|
|
|
|
label = str(line_labels.get(l, l.index)) |
|
|
|
if node_level[l.driver] == node_level[l.reader]: |
|
|
|
if node_level[l.driver] == node_level[l.reader]: |
|
|
|
s.node(f'_{l.index}_') |
|
|
|
s.node(f'_{l.index}_') |
|
|
|
dot.edge(driver, f'_{l.index}_', style='dotted', label=str(l.index)) |
|
|
|
dot.edge(driver, f'_{l.index}_', style='dotted', label=label) |
|
|
|
dot.edge(f'_{l.index}_', reader, style='dotted', label=str(l.index)) |
|
|
|
dot.edge(f'_{l.index}_', reader, style='dotted', label=label) |
|
|
|
elif node_level[l.driver] > node_level[l.reader]: |
|
|
|
elif node_level[l.driver] > node_level[l.reader]: |
|
|
|
dot.edge(driver, reader, style='dotted', label=str(l.index)) |
|
|
|
dot.edge(driver, reader, style='dotted', label=label) |
|
|
|
else: |
|
|
|
else: |
|
|
|
dot.edge(driver, reader, label=str(l.index)) |
|
|
|
dot.edge(driver, reader, label=label) |
|
|
|
|
|
|
|
|
|
|
|
return dot |
|
|
|
return dot |
|
|
|
|