SYMBOL_TYPE_GATE = 1
SYMBOL_TYPE_XOR = 2
SYMBOL_TYPE_TG_LATCH = 3
-N_SYMBOL_TYPES = 4
+SYMBOL_TYPE_SB_NOT = 4
+SYMBOL_TYPE_SB_AND_OR = 5
+N_SYMBOL_TYPES = 5
dump_nets = False
if len(sys.argv) >= 2 and sys.argv[1] == '--dump_nets':
(d_net, le_net, len_net, q_net, qn_net)
)
)
+ elif symbol_type == SYMBOL_TYPE_SB_NOT:
+ assert len(fields) == 5
+ a_net, oen_net, y_net = fields[2:]
+
+ for net in [a_net, oen_net, y_net]:
+ if net not in nets:
+ nets[net] = set() # blocks (of symbols) that the net visits
+ nets[net].add(block)
+
+ symbols.append(
+ (
+ symbol_type,
+ block,
+ (a_net, oen_net, y_net)
+ )
+ )
+ elif symbol_type == SYMBOL_TYPE_SB_AND_OR:
+ assert len(fields) == 8
+ a0_net, a1_net, b0_net, b1_net, oen_net, y_net = fields[2:]
+
+ for net in [a0_net, a1_net, b0_net, b1_net, oen_net, y_net]:
+ if net not in nets:
+ nets[net] = set() # blocks (of symbols) that the net visits
+ nets[net].add(block)
+
+ symbols.append(
+ (
+ symbol_type,
+ block,
+ (a0_net, a1_net, b0_net, b1_net, oen_net, y_net)
+ )
+ )
else:
assert False
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')
+ elif symbol_type == SYMBOL_TYPE_SB_NOT:
+ _, _, (a_net, oen_net, y_net) = symbols[i]
+
+ node = f'sb_not:{q_net:s}'
+ fout.write(f' "{node:s}" [shape="invhouse", label="SB_NOT"]\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')
+ elif symbol_type == SYMBOL_TYPE_SB_AND_OR:
+ _, _, (a0_net, a1_net, b0_net, b1_net, oen_net, y_net) = symbols[i]
+
+ node = f'sb_and_or:{q_net:s}'
+ fout.write(f' "{node:s}" [shape="invhouse", label="SB_AND_OR"]\n')
+
+ net_node = make_net_node(a0_net)
+ fout.write(f' "{net_node:s}" -> "{node:s}" [label="A0"]\n')
+ net_node = make_net_node(a1_net)
+ fout.write(f' "{net_node:s}" -> "{node:s}" [label="A1"]\n')
+ net_node = make_net_node(b0_net)
+ fout.write(f' "{net_node:s}" -> "{node:s}" [label="B0"]\n')
+ net_node = make_net_node(b1_net)
+ fout.write(f' "{net_node:s}" -> "{node:s}" [label="B1"]\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')
else:
assert False
fout.write('}\n')
SYMBOL_TYPE_GATE = 1
SYMBOL_TYPE_XOR = 2
SYMBOL_TYPE_TG_LATCH = 3
-N_SYMBOL_TYPES = 4
+SYMBOL_TYPE_SB_NOT = 4
+SYMBOL_TYPE_SB_AND_OR = 5
+N_SYMBOL_TYPES = 6
CIRCUITS = [
# XOR gate as follows:
- # int = a NOR b
- # q = (a AND b) NOR int
- # virtual nets are 0 = a, 1 = b, 2 = int, 3 = out
+ # int = a NOR b
+ # q = (a AND b) NOR int
+ # virtual nets are:
+ # 0 = a
+ # 1 = b
+ # 2 = int
+ # 3 = out
(
[
(SYMBOL_TYPE_GATE, (3, [[0, 1], [2]])),
[False, False, True, False],
),
# transmission-gate latch with d, le, /le, q, /q as follows:
- # fb = le ? d : q, /q = NOT fb, q = NOT /q
- # virtual nets are 0 = d, 1 = le, 2 = /le, 3 = fb, 4 = /q, 5 = q
+ # fb = le ? d : /le ? q : Z
+ # /q = NOT fb
+ # q = NOT /q
+ # virtual nets are:
+ # 0 = d
+ # 1 = le
+ # 2 = /le
+ # 3 = fb
+ # 4 = /q
+ # 5 = q
(
[
(SYMBOL_TYPE_FET, (1, [0, 3])),
],
[False, False, False, True, False, False]
),
+ # inverting superbuffer with a, /oe, y as follows:
+ # h = /oe NOR a
+ # l = /oe NOR h
+ # y = h ? VCC : l ? GND : Z
+ # virtual nets are:
+ # -2 = VCC
+ # -1 = GND
+ # 0 = a
+ # 1 = /oe
+ # 2 = h
+ # 3 = l
+ # 4 = y
+ (
+ [
+ (SYMBOL_TYPE_GATE, (2, [[1], [0]])),
+ (SYMBOL_TYPE_GATE, (3, [[1], [2]])),
+ (SYMBOL_TYPE_FET, (2, [-2, 4])),
+ (SYMBOL_TYPE_FET, (3, [-1, 4])),
+ ],
+ [
+ (SYMBOL_TYPE_SB_NOT, (0, 1, 4)),
+ ],
+ [False, False, True, True, False],
+ ),
+ # non-inverting superbuffer with a0, a1, b0, b1, /oe, y as follows:
+ # l = /oe NOR (a0 AND a1) NOR (b0 AND b1)
+ # h = /oe NOR l
+ # y = l ? GND : h ? VCC : Z
+ # virtual nets are:
+ # -4 = VCC
+ # -1 = GND
+ # 0 = a0
+ # 1 = a1
+ # 2 = b0
+ # 3 = b1
+ # 4 = /oe
+ # 5 = l
+ # 6 = h
+ # 7 = y
+ (
+ [
+ (SYMBOL_TYPE_GATE, (5, [[4], [0, 1], [2, 3]])),
+ (SYMBOL_TYPE_GATE, (6, [[4], [5]])),
+ (SYMBOL_TYPE_FET, (5, [-1, 7])),
+ (SYMBOL_TYPE_FET, (6, [-2, 7])),
+ ],
+ [
+ (SYMBOL_TYPE_SB_AND_OR, (0, 1, 2, 3, 4, 7)),
+ ],
+ [False, False, False, False, False, True, True, False],
+ ),
]
if len(sys.argv) < 3:
print(f'usage: {sys.argv[0]:s} symbols.txt net_gnd,net_vcc')
sys.exit(1)
symbols_txt = sys.argv[1]
-[net_gnd, net_vcc] = sys.argv[2].split(',')
+global_nets = sys.argv[2].split(',')
nets = {}
symbols = []
for circuit_find, circuit_replace, circuit_internal in CIRCUITS:
assert len(circuit_find)
circuit_symbols = [-1] * len(circuit_find)
- circuit_nets = [None] * len(circuit_internal)
+ circuit_nets = global_nets[::-1] + [None] * len(circuit_internal)
# recurse into symbol template looking for nets that already know (as we
# have unified against them already) and use them to narrow candidate set
if isinstance(t, tuple) or isinstance(t, list):
candidates1 = candidate_symbols(t)
else: # FIX THIS
- #print('circuit_nets[t]', circuit_nets[t])
- if circuit_nets[t] is not None:
- candidates1 = nets[circuit_nets[t]]
+ gt = len(global_nets) + t
+ if circuit_nets[gt] is not None:
+ candidates1 = nets[circuit_nets[gt]]
else:
continue
#print('candidates1', candidates1)
# all nets flagged as internal are not connected to another symbol
symbols_internal = set(circuit_symbols)
for j in range(len(circuit_internal)):
+ gj = len(global_nets) + j
if (
circuit_internal[j] and
- len(nets[circuit_nets[j]] - symbols_internal)
+ len(nets[circuit_nets[gj]] - symbols_internal)
):
- #print('rejecting net', circuit_net[j])
+ #print('rejecting net', circuit_nets[gj])
return
#print('match')
raise Match()
return
elif isinstance(t, int):
assert isinstance(a, str)
- if circuit_nets[t] != a:
- if circuit_nets[t] is None:
+ gt = len(global_nets) + t
+ if circuit_nets[gt] != a:
+ if circuit_nets[gt] is None:
#print('trying net', t, a)
stack = (i, template, actual, stack)
- circuit_nets[t] = a
+ circuit_nets[gt] = a
match(level, stack)
#print('failed net', t, a)
- circuit_nets[t] = None
+ circuit_nets[gt] = None
#else:
- # print('rejecting circuit_nets[t]', circuit_nets[t])
+ # print('rejecting circuit_nets[gt]', circuit_nets[gt])
return
#else:
- # print('matched circuit_nets[t]', circuit_nets[t])
+ # print('matched circuit_nets[gt]', circuit_nets[gt])
else:
assert False
level -= 1
if isinstance(template, list):
return [substitute(t) for t in template]
if isinstance(template, int):
- return circuit_nets[template]
+ return circuit_nets[len(global_nets) + template]
assert False
# outer search is special, as it keeps track of symbol we are up to,
# continue search
circuit_symbols = [-1] * len(circuit_find)
- circuit_nets = [None] * len(circuit_internal)
+ circuit_nets = global_nets[::-1] + [None] * len(circuit_internal)
for i in range(len(symbols)):
symbol_type = symbols[i][0]
elif symbol_type == SYMBOL_TYPE_TG_LATCH:
[_, block, (d_net, le_net, len_net, q_net, qn_net)] = symbols[i]
print(symbol_type, block, d_net, le_net, len_net, q_net, qn_net)
+ elif symbol_type == SYMBOL_TYPE_SB_NOT:
+ [_, block, (a_net, oen_net, y_net)] = symbols[i]
+ print(symbol_type, block, a_net, oen_net, y_net)
+ elif symbol_type == SYMBOL_TYPE_SB_AND_OR:
+ [_, block, (a0_net, a1_net, b0_net, b1_net, oen_net, y_net)] = symbols[i]
+ print(symbol_type, block, a0_net, a1_net, b0_net, b1_net, oen_net, y_net)