#!/usr/bin/env python3
-import os
import sys
SYMBOL_TYPE_FET = 0
dump_nets = True
del sys.argv[1]
if len(sys.argv) < 3:
- print(f'usage: {sys.argv[0]:s} [--dump_nets] symbols.txt dot_dir')
+ print(f'usage: {sys.argv[0]:s} [--dump_nets] symbols.txt symbols.dot')
sys.exit(1)
symbols_txt = sys.argv[1]
-dot_dir = sys.argv[2]
+symbols_dot = sys.argv[2]
+print('input')
nets = {}
blocks = {}
symbols = []
for block in sorted(net_blocks):
print(net, block)
-try:
- os.mkdir(dot_dir)
-except FileExistsError:
- pass
-for block, block_symbols in sorted(blocks.items()):
- with open(f'{dot_dir:s}/{block:s}.dot', 'w') as fout:
- fout.write(f'digraph "{block:s}" {{\n')
- fout.write(f' title="{block:s}"\n')
-
- net_nodes = set()
- disambiguator = 0
+print('output')
+with open(symbols_dot, 'w') as fout:
+ for block, block_symbols in sorted(blocks.items()):
+ fout.write(
+ f'''digraph "{block:s}" {{
+ title="{block:s}"
+ rankdir=LR
+'''
+ )
+
+ next_node = 0
+ def make_node(label, shape = None):
+ global next_node
+ node = next_node
+ next_node += 1
+ attrs = [f'label="{label:s}"']
+ if shape is not None:
+ attrs.append(f'shape={shape:s}')
+ fout.write(' {0:d} [{1:s}]\n'.format(node, ', '.join(attrs)))
+ return node
+
+ local_nets = {}
def make_net_node(net):
- global disambiguator
-
- if len(nets[net]) > 1:
- # global net, make a new copy each time
- net_node = f'net:{net:s}:{disambiguator:d}'
- disambiguator += 1
- shape = 'box'
- else:
+ if net in local_nets:
+ return local_nets[net]
+ if len(nets[net]) <= 1:
# local net, make a shared copy
- net_node = f'net:{net:s}'
+ local_nets[net] = next_node
shape = 'plaintext'
- if net_node not in net_nodes:
- net_nodes.add(net_node)
- fout.write(f' "{net_node:s}" [shape={shape:s}, label="{net:s}"]\n')
- return net_node
+ else:
+ shape = 'box'
+ return make_node(net, shape)
+
+ def make_edge(node0, node1, label = None, arrowhead = None):
+ attrs = []
+ if label is not None:
+ attrs.append(f'label="{label:s}"')
+ if arrowhead is not None:
+ attrs.append(f'arrowhead={arrowhead:s}')
+ fout.write(
+ ' {0:d} -> {1:d}{2:s}\n'.format(
+ node0,
+ node1,
+ '' if len(attrs) == 0 else ' [{0:s}]'.format(', '.join(attrs))
+ )
+ )
for i in block_symbols:
symbol_type = symbols[i][0]
r_matrix
) = symbols[i]
- node = f'{symbol_type:d}:{channel:s}'
label = channel
if len(r_matrix) == 2:
- label += f'\nR={r_matrix[1][0]:.3f}'
+ label += f'\\nR={r_matrix[1][0]:.3f}'
else:
- label += f'\nC={mass / 2e4:.3f}'
- fout.write(f' "{node:s}" [label="{label:s}"]\n')
-
- net_node = make_net_node(poly_net)
- fout.write(f' "{net_node:s}" -> "{node:s}"\n')
+ label += f'\\nC={mass / 2e4:.3f}'
+ node = make_node(label)
+ make_edge(make_net_node(poly_net), node)
for diff_net in diff_nets:
- net_node = make_net_node(diff_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [arrowhead=none]\n')
+ make_edge(node, make_net_node(diff_net), arrowhead = 'none')
elif symbol_type == SYMBOL_TYPE_GATE:
_, _, (y_net, expr) = symbols[i]
- node = f'{symbol_type:d}:{y_net:s}'
if len(expr) == 1:
label = (
'FALSE'
if len(expr[0]) == 1 else
'NAND'
)
- fout.write(
- f' "{node:s}" [shape="invhouse", label="{label:s}"]\n'
- )
+ node = make_node(label, shape = 'cds')
for a_net in expr[0]:
- net_node = make_net_node(a_net)
- fout.write(f' "{net_node:s}" -> "{node:s}"\n')
+ make_edge(make_net_node(a_net), node)
else:
label = 'TRUE' if len(expr) == 0 else 'NOR'
- fout.write(
- f' "{node:s}" [shape="invhouse", label="{label:s}"]\n'
- )
+ node = make_node(label, shape = 'cds')
for j in range(len(expr)):
- inner_node = f'{node:s}:{j:d}'
if len(expr[j]) == 1:
- net_node = make_net_node(expr[j][0])
- fout.write(f' "{net_node:s}" -> "{node:s}"\n')
+ inner_node = make_net_node(expr[j][0])
else:
label = 'TRUE' if len(expr[j]) == 0 else 'AND'
- fout.write(
- f' "{inner_node:s}" [shape="invhouse", label="{label:s}"]\n'
- )
+ inner_node = make_node(label, shape = 'cds')
for a_net in expr[j]:
- net_node = make_net_node(a_net)
- fout.write(f' "{net_node:s}" -> "{inner_node:s}"\n')
- fout.write(f' "{inner_node:s}" -> "{node:s}"\n')
- net_node = make_net_node(y_net)
- fout.write(f' "{node:s}" -> "{net_node:s}"\n')
+ make_edge(make_net_node(a_net), inner_node)
+ make_edge(inner_node, node)
+ make_edge(node, make_net_node(y_net))
elif symbol_type == SYMBOL_TYPE_XOR:
_, _, (a_net, b_net, y_net) = symbols[i]
- node = f'{symbol_type:d}:{y_net:s}'
- fout.write(f' "{node:s}" [shape="invhouse", label="XOR"]\n')
+ node = make_node('XOR', shape = 'cds')
- net_node = make_net_node(a_net)
- fout.write(f' "{net_node:s}" -> "{node:s}"\n')
- net_node = make_net_node(b_net)
- fout.write(f' "{net_node:s}" -> "{node:s}"\n')
- net_node = make_net_node(y_net)
- fout.write(f' "{node:s}" -> "{net_node:s}"\n')
+ make_edge(make_net_node(a_net), node)
+ make_edge(make_net_node(b_net), node)
+ make_edge(node, make_net_node(y_net))
elif symbol_type == SYMBOL_TYPE_TG_LATCH:
_, _, (d_net, le_net, len_net, q_net, qn_net) = symbols[i]
- node = f'{symbol_type:d}:{q_net:s}'
- fout.write(f' "{node:s}" [shape="invhouse", label="TG_LATCH"]\n')
-
- net_node = make_net_node(d_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="D"]\n')
- net_node = make_net_node(le_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="LE"]\n')
- net_node = make_net_node(len_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="/LE"]\n')
- net_node = make_net_node(q_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="Q"]\n')
- net_node = make_net_node(qn_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="/Q"]\n')
+ node = make_node('TG_LATCH', shape = 'cds')
+
+ make_edge(make_net_node(d_net), node, label = 'D')
+ make_edge(make_net_node(le_net), node, label = 'LE')
+ make_edge(make_net_node(len_net), node, label = '/LE')
+ make_edge(node, make_net_node(q_net), label = 'Q')
+ make_edge(node, make_net_node(qn_net), label = '/Q')
elif symbol_type == SYMBOL_TYPE_TG_LATCH_FB:
_, _, (d_net, le_net, len_net, q_net, qn_net, fb_net) = symbols[i]
- node = f'{symbol_type:d}:{q_net:s}'
- fout.write(f' "{node:s}" [shape="invhouse", label="TG_LATCH_FB"]\n')
-
- net_node = make_net_node(d_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="D"]\n')
- net_node = make_net_node(le_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="LE"]\n')
- net_node = make_net_node(len_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="/LE"]\n')
- net_node = make_net_node(q_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="Q"]\n')
- net_node = make_net_node(qn_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="/Q"]\n')
- net_node = make_net_node(fb_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="FB"]\n')
+ node = make_node('TG_LATCH_FB', shape = 'cds')
+
+ make_edge(make_net_node(d_net), node, label = 'D')
+ make_edge(make_net_node(le_net), node, label = 'LE')
+ make_edge(make_net_node(len_net), node, label = '/LE')
+ make_edge(node, make_net_node(q_net), label = 'Q')
+ make_edge(node, make_net_node(qn_net), label = '/Q')
+ make_edge(node, make_net_node(fb_net), label = 'FB')
elif (
symbol_type == SYMBOL_TYPE_TG_LATCH_CLR or
symbol_type == SYMBOL_TYPE_TG_LATCH_SET
(d_net, le_net, len_net, clr_set_net, q_net, qn_net)
) = symbols[i]
- node = f'{symbol_type:d}:{q_net:s}'
clr_set = (
'CLR'
if symbol_type == SYMBOL_TYPE_TG_LATCH_CLR else
'SET'
)
label = f'TG_LATCH_{clr_set:s}'
- fout.write(
- f' "{node:s}" [shape="invhouse", label="{label:s}"]\n'
- )
-
- net_node = make_net_node(d_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="D"]\n')
- net_node = make_net_node(le_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="LE"]\n')
- net_node = make_net_node(len_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="/LE"]\n')
- net_node = make_net_node(clr_set_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="{clr_set:s}"]\n')
- net_node = make_net_node(q_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="Q"]\n')
- net_node = make_net_node(qn_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="/Q"]\n')
+ node = make_node(label, shape = 'cds')
+
+ make_edge(make_net_node(d_net), node, label = 'D')
+ make_edge(make_net_node(le_net), node, label = 'LE')
+ make_edge(make_net_node(len_net), node, label = '/LE')
+ make_edge(make_net_node(clr_set_net), node, label = clr_set)
+ make_edge(node, make_net_node(q_net), label = 'Q')
+ make_edge(node, make_net_node(qn_net), label = '/Q')
elif (
symbol_type == SYMBOL_TYPE_TG_LATCH_CLR_FB or
symbol_type == SYMBOL_TYPE_TG_LATCH_SET_FB
):
- (
- _,
- _,
- (d_net, le_net, len_net, clr_set_net, q_net, qn_net, fb_net)
- ) = symbols[i]
-
- node = f'{symbol_type:d}:{q_net:s}'
clr_set = (
'CLR'
- if symbol_type == SYMBOL_TYPE_TG_LATCH_CLR_FB else
+ if symbol_type == SYMBOL_TYPE_TG_LATCH_CLR else
'SET'
)
label = f'TG_LATCH_{clr_set:s}_FB'
- fout.write(
- f' "{node:s}" [shape="invhouse", label="{label:s}"]\n'
- )
-
- net_node = make_net_node(d_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="D"]\n')
- net_node = make_net_node(le_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="LE"]\n')
- net_node = make_net_node(len_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="/LE"]\n')
- net_node = make_net_node(clr_set_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="{clr_set:s}"]\n')
- net_node = make_net_node(q_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="Q"]\n')
- net_node = make_net_node(qn_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="/Q"]\n')
- net_node = make_net_node(fb_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="FB"]\n')
+ node = make_node(label, shape = 'cds')
+
+ make_edge(make_net_node(d_net), node, label = 'D')
+ make_edge(make_net_node(le_net), node, label = 'LE')
+ make_edge(make_net_node(len_net), node, label = '/LE')
+ make_edge(make_net_node(clr_set_net), node, label = clr_set)
+ make_edge(node, make_net_node(q_net), label = 'Q')
+ make_edge(node, make_net_node(qn_net), label = '/Q')
+ make_edge(node, make_net_node(fb_net), label = 'FB')
elif (
symbol_type == SYMBOL_TYPE_SUPER or
symbol_type == SYMBOL_TYPE_NOT_SUPER
):
_, _, (a_net, y_net) = symbols[i]
- node = f'{symbol_type:d}:{y_net:s}'
label = 'SUPER' if symbol_type == SYMBOL_TYPE_SUPER else 'NOT_SUPER'
- fout.write(f' "{node:s}" [shape="invhouse", label="{label:s}"]\n')
+ node = make_node(label, shape = 'cds')
- net_node = make_net_node(a_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="A"]\n')
- net_node = make_net_node(y_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="Y"]\n')
+ make_edge(make_net_node(a_net), node)
+ make_edge(node, make_net_node(y_net))
elif (
symbol_type == SYMBOL_TYPE_SUPER_OE or
symbol_type == SYMBOL_TYPE_NOT_SUPER_OE
):
_, _, (a_net, oen_net, y_net) = symbols[i]
- # note: need a better way to disambiguate when y net can be hi-Z
- node = f'{symbol_type:d}:{oen_net:s}:{y_net:s}'
- label = 'SUPER_OE' if symbol_type == SYMBOL_TYPE_SUPER else 'NOT_SUPER_OE'
- fout.write(f' "{node:s}" [shape="invhouse", label="{label:s}"]\n')
-
- net_node = make_net_node(a_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="A"]\n')
- net_node = make_net_node(oen_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="/OE"]\n')
- net_node = make_net_node(y_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="Y"]\n')
+ label = (
+ 'SUPER_OE'
+ if symbol_type == SYMBOL_TYPE_SUPER else
+ 'NOT_SUPER_OE'
+ )
+ node = make_node(label, shape = 'cds')
+
+ make_edge(make_net_node(a_net), node, 'A')
+ make_edge(make_net_node(oen_net), node, '/OE')
+ make_edge(node, make_net_node(y_net), 'Y')
elif symbol_type == SYMBOL_TYPE_NOR_SUPER:
_, _, (a_net, b_net, y_net) = symbols[i]
- node = f'{symbol_type:d}:{y_net:s}'
- fout.write(f' "{node:s}" [shape="invhouse", label="NOR_SUPER"]\n')
+ node = make_node('NOR_SUPER', shape = 'cds')
- net_node = make_net_node(a_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="A"]\n')
- net_node = make_net_node(b_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="B"]\n')
- net_node = make_net_node(y_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="Y"]\n')
+ make_edge(make_net_node(a_net), node, 'A')
+ make_edge(make_net_node(b_net), node, 'B')
+ make_edge(node, make_net_node(y_net), 'Y')
elif symbol_type == SYMBOL_TYPE_NOR_SUPER_HD:
_, _, (a_net, b_net, y_net, hd_net) = symbols[i]
- node = f'{symbol_type:d}:{y_net:s}'
- fout.write(f' "{node:s}" [shape="invhouse", label="NOR_SUPER_HD"]\n')
-
- net_node = make_net_node(a_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="A"]\n')
- net_node = make_net_node(b_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="B"]\n')
- net_node = make_net_node(y_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="Y"]\n')
- net_node = make_net_node(hd_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="HD"]\n')
+ node = make_node('NOR_SUPER_HD', shape = 'cds')
+
+ make_edge(make_net_node(a_net), node, 'A')
+ make_edge(make_net_node(b_net), node, 'B')
+ make_edge(node, make_net_node(y_net), 'Y')
+ make_edge(node, make_net_node(hd_net), 'HD')
elif (
symbol_type == SYMBOL_TYPE_MUX2 or
symbol_type == SYMBOL_TYPE_MUX2_NOT
):
_, _, (a_net, b_net, s_net, y_net) = symbols[i]
- node = f'{symbol_type:d}:{y_net:s}'
label = 'MUX2' if symbol_type == SYMBOL_TYPE_MUX2 else 'MUX2_NOT'
- fout.write(f' "{node:s}" [shape="invhouse", label="{label:s}"]\n')
-
- net_node = make_net_node(a_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="A"]\n')
- net_node = make_net_node(b_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="B"]\n')
- net_node = make_net_node(s_net)
- fout.write(f' "{net_node:s}" -> "{node:s}" [label="S"]\n')
- net_node = make_net_node(y_net)
- fout.write(f' "{node:s}" -> "{net_node:s}" [label="Y"]\n')
+ node = make_node(label, shape = 'cds')
+
+ make_edge(make_net_node(a_net), node, 'A')
+ make_edge(make_net_node(b_net), node, 'B')
+ make_edge(make_net_node(s_net), node, 'S')
+ make_edge(node, make_net_node(y_net), 'Y')
else:
assert False
fout.write('}\n')