From 8434c2baefa1304a962ea17f05f98df001f6235c Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Mon, 21 Jul 2025 15:42:29 +1000 Subject: [PATCH] In /scripts/circuits.py and /scripts/blocks.py rationalize superbuffer circuits --- scripts/blocks.py | 83 +++++++++++++++++++++----------------- scripts/circuits.py | 98 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 132 insertions(+), 49 deletions(-) diff --git a/scripts/blocks.py b/scripts/blocks.py index 6206b39..db6c48f 100755 --- a/scripts/blocks.py +++ b/scripts/blocks.py @@ -8,9 +8,11 @@ SYMBOL_TYPE_FET = 0 SYMBOL_TYPE_GATE = 1 SYMBOL_TYPE_XOR = 2 SYMBOL_TYPE_TG_LATCH = 3 -SYMBOL_TYPE_SB_NOT = 4 -SYMBOL_TYPE_SB_AND_OR = 5 -N_SYMBOL_TYPES = 5 +SYMBOL_TYPE_SB = 4 +SYMBOL_TYPE_SB_NOT = 5 +SYMBOL_TYPE_SB_OE = 6 +SYMBOL_TYPE_SB_NOT_OE = 7 +N_SYMBOL_TYPES = 8 dump_nets = False if len(sys.argv) >= 2 and sys.argv[1] == '--dump_nets': @@ -120,11 +122,14 @@ with open(symbols_txt) as fin: (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:] + elif ( + symbol_type == SYMBOL_TYPE_SB or + symbol_type == SYMBOL_TYPE_SB_NOT + ): + assert len(fields) == 4 + a_net, y_net = fields[2:] - for net in [a_net, oen_net, y_net]: + for net in [a_net, y_net]: if net not in nets: nets[net] = set() # blocks (of symbols) that the net visits nets[net].add(block) @@ -133,14 +138,17 @@ with open(symbols_txt) as fin: ( symbol_type, block, - (a_net, oen_net, y_net) + (a_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:] + elif ( + symbol_type == SYMBOL_TYPE_SB_OE or + symbol_type == SYMBOL_TYPE_SB_NOT_OE + ): + assert len(fields) == 5 + a_net, oen_net, y_net = fields[2:] - for net in [a0_net, a1_net, b0_net, b1_net, oen_net, y_net]: + 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) @@ -149,7 +157,7 @@ with open(symbols_txt) as fin: ( symbol_type, block, - (a0_net, a1_net, b0_net, b1_net, oen_net, y_net) + (a_net, oen_net, y_net) ) ) else: @@ -204,7 +212,7 @@ for block, block_symbols in sorted(blocks.items()): r_matrix ) = symbols[i] - node = f'fet:{channel:s}' + node = f'{symbol_type:d}:{channel:s}' label = channel if len(r_matrix) == 2: label += f'\nR={r_matrix[1][0]:.3f}' @@ -221,7 +229,7 @@ for block, block_symbols in sorted(blocks.items()): elif symbol_type == SYMBOL_TYPE_GATE: _, _, (y_net, expr) = symbols[i] - node = f'gate:{y_net:s}' + node = f'{symbol_type:d}:{y_net:s}' if len(expr) == 1: label = ( 'FALSE' @@ -263,7 +271,7 @@ for block, block_symbols in sorted(blocks.items()): elif symbol_type == SYMBOL_TYPE_XOR: _, _, (y_net, a_nets) = symbols[i] - node = f'xor:{y_net:s}' + node = f'{symbol_type:d}:{y_net:s}' fout.write(f' "{node:s}" [shape="invhouse", label="XOR"]\n') for a_net in a_nets: @@ -274,7 +282,7 @@ for block, block_symbols in sorted(blocks.items()): elif symbol_type == SYMBOL_TYPE_TG_LATCH: _, _, (d_net, le_net, len_net, q_net, qn_net) = symbols[i] - node = f'latch:{q_net:s}' + 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) @@ -287,32 +295,33 @@ for block, block_symbols in sorted(blocks.items()): 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] + elif ( + symbol_type == SYMBOL_TYPE_SB or + symbol_type == SYMBOL_TYPE_SB_NOT + ): + _, _, (a_net, y_net) = symbols[i] - node = f'sb_not:{q_net:s}' - fout.write(f' "{node:s}" [shape="invhouse", label="SB_NOT"]\n') + node = f'{symbol_type:d}:{y_net:s}' + label = 'SB' if symbol_type == SYMBOL_TYPE_SB else 'SB_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(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') + elif ( + symbol_type == SYMBOL_TYPE_SB_OE or + symbol_type == SYMBOL_TYPE_SB_NOT_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 = 'SB_OE' if symbol_type == SYMBOL_TYPE_SB else 'SB_NOT_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) diff --git a/scripts/circuits.py b/scripts/circuits.py index d1cb4ea..535db3f 100755 --- a/scripts/circuits.py +++ b/scripts/circuits.py @@ -8,9 +8,11 @@ SYMBOL_TYPE_FET = 0 SYMBOL_TYPE_GATE = 1 SYMBOL_TYPE_XOR = 2 SYMBOL_TYPE_TG_LATCH = 3 -SYMBOL_TYPE_SB_NOT = 4 -SYMBOL_TYPE_SB_AND_OR = 5 -N_SYMBOL_TYPES = 6 +SYMBOL_TYPE_SB = 4 +SYMBOL_TYPE_SB_NOT = 5 +SYMBOL_TYPE_SB_OE = 6 +SYMBOL_TYPE_SB_NOT_OE = 7 +N_SYMBOL_TYPES = 8 CIRCUITS = [ # XOR gate as follows: @@ -54,6 +56,70 @@ CIRCUITS = [ ], [False, False, False, True, False, False] ), + # non-inverting superbuffer with a, y as follows: + # l = NOT a + # y = a ? VCC : l ? GND : Z + # virtual nets are: + # -0 = VCC + # -1 = GND + # 0 = a + # 1 = l + # 2 = y + ( + [ + (SYMBOL_TYPE_GATE, (1, [[0]])), + (SYMBOL_TYPE_FET, (0, [-2, 2])), + (SYMBOL_TYPE_FET, (1, [-1, 2])), + ], + [ + (SYMBOL_TYPE_SB, (0, 2)), + ], + [False, True, False], + ), + # inverting superbuffer with a, y as follows: + # h = NOT a + # y = h ? VCC : a ? GND : Z + # virtual nets are: + # -0 = VCC + # -1 = GND + # 0 = a + # 1 = h + # 2 = y + ( + [ + (SYMBOL_TYPE_GATE, (1, [[0]])), + (SYMBOL_TYPE_FET, (0, [-1, 2])), + (SYMBOL_TYPE_FET, (1, [-2, 2])), + ], + [ + (SYMBOL_TYPE_SB_NOT, (0, 2)), + ], + [False, True, False], + ), + # non-inverting superbuffer with a, /oe, y as follows: + # l = /oe NOR a + # h = /oe NOR h + # y = h ? VCC : l ? GND : Z + # virtual nets are: + # -2 = VCC + # -1 = GND + # 0 = a + # 1 = /oe + # 2 = l + # 3 = h + # 4 = y + ( + [ + (SYMBOL_TYPE_GATE, (2, [[1], [0]])), + (SYMBOL_TYPE_GATE, (3, [[1], [2]])), + (SYMBOL_TYPE_FET, (2, [-1, 4])), + (SYMBOL_TYPE_FET, (3, [-2, 4])), + ], + [ + (SYMBOL_TYPE_SB_OE, (0, 1, 4)), + ], + [False, False, True, True, False], + ), # inverting superbuffer with a, /oe, y as follows: # h = /oe NOR a # l = /oe NOR h @@ -74,14 +140,14 @@ CIRCUITS = [ (SYMBOL_TYPE_FET, (3, [-1, 4])), ], [ - (SYMBOL_TYPE_SB_NOT, (0, 1, 4)), + (SYMBOL_TYPE_SB_NOT_OE, (0, 1, 4)), ], [False, False, True, True, False], ), - # non-inverting superbuffer with a0, a1, b0, b1, /oe, y as follows: + # special case of SYMBOL_TYPE_SB_OE preceded by a MUX, unmerge them + # (the unmerged MUX will be inverting, so we use SYMBOL_TYPE_SB_NOT_OE) # 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 @@ -101,7 +167,9 @@ CIRCUITS = [ (SYMBOL_TYPE_FET, (6, [-2, 7])), ], [ - (SYMBOL_TYPE_SB_AND_OR, (0, 1, 2, 3, 4, 7)), + # note: internal net l gets repurposed as unmerged input a + (SYMBOL_TYPE_GATE, (5, [[0, 1], [2, 3]])), + (SYMBOL_TYPE_SB_NOT_OE, (5, 4, 7)), ], [False, False, False, False, False, True, True, False], ), @@ -382,9 +450,15 @@ for i in range(len(symbols)): 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: + elif ( + symbol_type == SYMBOL_TYPE_SB or + symbol_type == SYMBOL_TYPE_SB_NOT + ): + [_, block, (a_net, y_net)] = symbols[i] + print(symbol_type, block, a_net, y_net) + elif ( + symbol_type == SYMBOL_TYPE_SB_OE or + symbol_type == SYMBOL_TYPE_SB_NOT_OE + ): [_, 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) -- 2.34.1