From 1352b36ccd8f42fccb3a21355b68f80a82da54d1 Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Mon, 21 Jul 2025 00:50:45 +1000 Subject: [PATCH] Add latch subcircuit (transmission gate latch found in e.g. 8085 block_alu22) --- scripts/blocks.py | 35 ++++++++++++++++++++++++++++++++++- scripts/circuits.py | 26 ++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/scripts/blocks.py b/scripts/blocks.py index 5fd139e..15aab6c 100755 --- a/scripts/blocks.py +++ b/scripts/blocks.py @@ -6,7 +6,8 @@ import sys SYMBOL_TYPE_FET = 0 SYMBOL_TYPE_GATE = 1 SYMBOL_TYPE_XOR = 2 -N_SYMBOL_TYPES = 3 +SYMBOL_TYPE_LATCH = 3 +N_SYMBOL_TYPES = 4 if len(sys.argv) < 3: print(f'usage: {sys.argv[0]:s} symbols.txt dot_dir') @@ -96,6 +97,22 @@ with open(symbols_txt) as fin: nets[net].add(block) symbols.append((symbol_type, block, (output_net, input_nets))) + elif symbol_type == SYMBOL_TYPE_LATCH: + assert len(fields) == 7 + d_net, le_net, len_net, q_net, qn_net = fields[2:] + + for net in [d_net, le_net, len_net, q_net, qn_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, + (d_net, le_net, len_net, q_net, qn_net) + ) + ) else: assert False @@ -206,6 +223,22 @@ for block, block_symbols in sorted(blocks.items()): fout.write(f' "{net_node:s}" -> "{node:s}"\n') net_node = make_net_node(output_net) fout.write(f' "{node:s}" -> "{net_node:s}"\n') + elif symbol_type == SYMBOL_TYPE_LATCH: + _, _, (d_net, le_net, len_net, q_net, qn_net) = symbols[i] + + node = f'latch:{q_net:s}' + fout.write(f' "{node:s}" [shape="invhouse", label="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') else: assert False fout.write('}\n') diff --git a/scripts/circuits.py b/scripts/circuits.py index 63008f0..1ce083f 100755 --- a/scripts/circuits.py +++ b/scripts/circuits.py @@ -7,10 +7,14 @@ import sys SYMBOL_TYPE_FET = 0 SYMBOL_TYPE_GATE = 1 SYMBOL_TYPE_XOR = 2 -N_SYMBOL_TYPES = 3 +SYMBOL_TYPE_LATCH = 3 +N_SYMBOL_TYPES = 4 CIRCUITS = [ - # (a AND b) NOR (a NOR b) => a XOR b + # 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 ( [ (SYMBOL_TYPE_GATE, (3, [[0, 1], [2]])), @@ -21,6 +25,21 @@ CIRCUITS = [ ], [False, False, True, False], ), + # 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 + ( + [ + (SYMBOL_TYPE_FET, (1, [0, 3])), + (SYMBOL_TYPE_FET, (2, [3, 5])), + (SYMBOL_TYPE_GATE, (4, [[3]])), + (SYMBOL_TYPE_GATE, (5, [[4]])), + ], + [ + (SYMBOL_TYPE_LATCH, (0, 1, 2, 5, 4)), + ], + [False, False, False, True, False, False] + ), ] if len(sys.argv) < 3: @@ -293,3 +312,6 @@ for i in range(len(symbols)): elif symbol_type == SYMBOL_TYPE_XOR: [_, block, (output_net, input_nets)] = symbols[i] print(symbol_type, block, output_net, ' '.join(input_nets)) + elif symbol_type == SYMBOL_TYPE_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) -- 2.34.1