From 52cc0b0b7914c9692077202ce9e57b3d5d528e4c Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Mon, 21 Jul 2025 16:21:57 +1000 Subject: [PATCH] In /scripts/circuits.py and /scripts/blocks.py rename SB_* to *_SUPER, add the TG_LATCH_FB, NOR_SUPER, NOR_SUPER_HD circuits which are used in special cases --- scripts/blocks.py | 125 ++++++++++++++++++++++++++++++++++----- scripts/circuits.py | 141 ++++++++++++++++++++++++++++++++------------ 2 files changed, 212 insertions(+), 54 deletions(-) diff --git a/scripts/blocks.py b/scripts/blocks.py index db6c48f..85c1066 100755 --- a/scripts/blocks.py +++ b/scripts/blocks.py @@ -8,11 +8,14 @@ SYMBOL_TYPE_FET = 0 SYMBOL_TYPE_GATE = 1 SYMBOL_TYPE_XOR = 2 SYMBOL_TYPE_TG_LATCH = 3 -SYMBOL_TYPE_SB = 4 -SYMBOL_TYPE_SB_NOT = 5 -SYMBOL_TYPE_SB_OE = 6 -SYMBOL_TYPE_SB_NOT_OE = 7 -N_SYMBOL_TYPES = 8 +SYMBOL_TYPE_TG_LATCH_FB = 4 +SYMBOL_TYPE_SUPER = 5 +SYMBOL_TYPE_NOT_SUPER = 6 +SYMBOL_TYPE_SUPER_OE = 7 +SYMBOL_TYPE_NOT_SUPER_OE = 8 +SYMBOL_TYPE_NOR_SUPER = 9 +SYMBOL_TYPE_NOR_SUPER_HD = 10 +N_SYMBOL_TYPES = 11 dump_nets = False if len(sys.argv) >= 2 and sys.argv[1] == '--dump_nets': @@ -122,9 +125,25 @@ with open(symbols_txt) as fin: (d_net, le_net, len_net, q_net, qn_net) ) ) + elif symbol_type == SYMBOL_TYPE_TG_LATCH_FB: + assert len(fields) == 8 + d_net, le_net, len_net, q_net, qn_net, fb_net = fields[2:] + + for net in [d_net, le_net, len_net, q_net, qn_net, fb_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, fb_net) + ) + ) elif ( - symbol_type == SYMBOL_TYPE_SB or - symbol_type == SYMBOL_TYPE_SB_NOT + symbol_type == SYMBOL_TYPE_SUPER or + symbol_type == SYMBOL_TYPE_NOT_SUPER ): assert len(fields) == 4 a_net, y_net = fields[2:] @@ -142,8 +161,8 @@ with open(symbols_txt) as fin: ) ) elif ( - symbol_type == SYMBOL_TYPE_SB_OE or - symbol_type == SYMBOL_TYPE_SB_NOT_OE + symbol_type == SYMBOL_TYPE_SUPER_OE or + symbol_type == SYMBOL_TYPE_NOT_SUPER_OE ): assert len(fields) == 5 a_net, oen_net, y_net = fields[2:] @@ -160,6 +179,38 @@ with open(symbols_txt) as fin: (a_net, oen_net, y_net) ) ) + elif symbol_type == SYMBOL_TYPE_NOR_SUPER: + assert len(fields) == 5 + a_net, b_net, y_net = fields[2:] + + for net in [a_net, b_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, b_net, y_net) + ) + ) + elif symbol_type == SYMBOL_TYPE_NOR_SUPER_HD: + assert len(fields) == 6 + a_net, b_net, y_net, hd_net = fields[2:] + + for net in [a_net, b_net, y_net, hd_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, b_net, y_net, hd_net) + ) + ) else: assert False @@ -295,14 +346,32 @@ 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_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') elif ( - symbol_type == SYMBOL_TYPE_SB or - symbol_type == SYMBOL_TYPE_SB_NOT + 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 = 'SB' if symbol_type == SYMBOL_TYPE_SB else 'SB_NOT' + label = 'SUPER' if symbol_type == SYMBOL_TYPE_SUPER else 'NOT_SUPER' fout.write(f' "{node:s}" [shape="invhouse", label="{label:s}"]\n') net_node = make_net_node(a_net) @@ -310,14 +379,14 @@ for block, block_symbols in sorted(blocks.items()): net_node = make_net_node(y_net) fout.write(f' "{node:s}" -> "{net_node:s}" [label="Y"]\n') elif ( - symbol_type == SYMBOL_TYPE_SB_OE or - symbol_type == SYMBOL_TYPE_SB_NOT_OE + 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 = 'SB_OE' if symbol_type == SYMBOL_TYPE_SB else 'SB_NOT_OE' + 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) @@ -326,6 +395,32 @@ for block, block_symbols in sorted(blocks.items()): 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_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') + + 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') + 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') else: assert False fout.write('}\n') diff --git a/scripts/circuits.py b/scripts/circuits.py index 535db3f..1141632 100755 --- a/scripts/circuits.py +++ b/scripts/circuits.py @@ -8,11 +8,14 @@ SYMBOL_TYPE_FET = 0 SYMBOL_TYPE_GATE = 1 SYMBOL_TYPE_XOR = 2 SYMBOL_TYPE_TG_LATCH = 3 -SYMBOL_TYPE_SB = 4 -SYMBOL_TYPE_SB_NOT = 5 -SYMBOL_TYPE_SB_OE = 6 -SYMBOL_TYPE_SB_NOT_OE = 7 -N_SYMBOL_TYPES = 8 +SYMBOL_TYPE_TG_LATCH_FB = 4 +SYMBOL_TYPE_SUPER = 5 +SYMBOL_TYPE_NOT_SUPER = 6 +SYMBOL_TYPE_SUPER_OE = 7 +SYMBOL_TYPE_NOT_SUPER_OE = 8 +SYMBOL_TYPE_NOR_SUPER = 9 +SYMBOL_TYPE_NOR_SUPER_HD = 10 +N_SYMBOL_TYPES = 11 CIRCUITS = [ # XOR gate as follows: @@ -56,14 +59,27 @@ CIRCUITS = [ ], [False, False, False, True, False, False] ), + # special case of SYMBOL_TYPE_TG_LATCH where fb signal is external + ( + [ + (SYMBOL_TYPE_FET, (1, [0, 3])), + (SYMBOL_TYPE_FET, (2, [3, 5])), + (SYMBOL_TYPE_GATE, (4, [[3]])), + (SYMBOL_TYPE_GATE, (5, [[4]])), + ], + [ + (SYMBOL_TYPE_TG_LATCH_FB, (0, 1, 2, 5, 4, 3)), + ], + [False, False, False, False, False, False] + ), # non-inverting superbuffer with a, y as follows: - # l = NOT a - # y = a ? VCC : l ? GND : Z + # ld = NOT a + # y = a ? VCC : ld ? GND : Z # virtual nets are: # -0 = VCC # -1 = GND # 0 = a - # 1 = l + # 1 = ld # 2 = y ( [ @@ -72,18 +88,18 @@ CIRCUITS = [ (SYMBOL_TYPE_FET, (1, [-1, 2])), ], [ - (SYMBOL_TYPE_SB, (0, 2)), + (SYMBOL_TYPE_SUPER, (0, 2)), ], [False, True, False], ), # inverting superbuffer with a, y as follows: - # h = NOT a - # y = h ? VCC : a ? GND : Z + # hd = NOT a + # y = hd ? VCC : a ? GND : Z # virtual nets are: # -0 = VCC # -1 = GND # 0 = a - # 1 = h + # 1 = hd # 2 = y ( [ @@ -92,21 +108,21 @@ CIRCUITS = [ (SYMBOL_TYPE_FET, (1, [-2, 2])), ], [ - (SYMBOL_TYPE_SB_NOT, (0, 2)), + (SYMBOL_TYPE_NOT_SUPER, (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 + # ld = /oe NOR a + # hd = /oe NOR hd + # y = hd ? VCC : ld ? GND : Z # virtual nets are: # -2 = VCC # -1 = GND # 0 = a # 1 = /oe - # 2 = l - # 3 = h + # 2 = ld + # 3 = hd # 4 = y ( [ @@ -116,21 +132,21 @@ CIRCUITS = [ (SYMBOL_TYPE_FET, (3, [-2, 4])), ], [ - (SYMBOL_TYPE_SB_OE, (0, 1, 4)), + (SYMBOL_TYPE_SUPER_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 - # y = h ? VCC : l ? GND : Z + # hd = /oe NOR a + # ld = /oe NOR hd + # y = hd ? VCC : ld ? GND : Z # virtual nets are: # -2 = VCC # -1 = GND # 0 = a # 1 = /oe - # 2 = h - # 3 = l + # 2 = hd + # 3 = ld # 4 = y ( [ @@ -140,24 +156,25 @@ CIRCUITS = [ (SYMBOL_TYPE_FET, (3, [-1, 4])), ], [ - (SYMBOL_TYPE_SB_NOT_OE, (0, 1, 4)), + (SYMBOL_TYPE_NOT_SUPER_OE, (0, 1, 4)), ], [False, False, True, True, False], ), - # 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) + # special case of SYMBOL_TYPE_SUPER_OE preceded by a MUX, unmerge them -- + # the unmerged MUX will be inverting, so we use SYMBOL_TYPE_NOT_SUPER_OE, + # probably it was this way originally and then merged for layout reasons + # ld = /oe NOR (a AND b) NOR (c AND d) # ... # virtual nets are: # -4 = VCC # -1 = GND - # 0 = a0 - # 1 = a1 - # 2 = b0 - # 3 = b1 + # 0 = a + # 1 = b + # 2 = c + # 3 = d # 4 = /oe - # 5 = l - # 6 = h + # 5 = ld + # 6 = hd # 7 = y ( [ @@ -169,10 +186,47 @@ CIRCUITS = [ [ # 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)), + (SYMBOL_TYPE_NOT_SUPER_OE, (5, 4, 7)), ], [False, False, False, False, False, True, True, False], ), + # low-current inverting superbuffer with a, b, y as follows: + # hd = a NOR b + # y = hd ? VCC : a ? GND : b ? GND : Z + # note: as it is low current, the low driver is simply duplicated, + # making it unnecessary to synthesize a combined low-drive signal + # virtual nets are: + # -0 = VCC + # -1 = GND + # 0 = a + # 1 = b + # 2 = hd + # 3 = y + ( + [ + (SYMBOL_TYPE_GATE, (2, [[0], [1]])), + (SYMBOL_TYPE_FET, (0, [-1, 3])), + (SYMBOL_TYPE_FET, (1, [-1, 3])), + (SYMBOL_TYPE_FET, (2, [-2, 3])), + ], + [ + (SYMBOL_TYPE_NOR_SUPER, (0, 1, 3)), + ], + [False, False, True, False], + ), + # special case of SYMBOL_TYPE_NOR_SUPER where hd signal is external + ( + [ + (SYMBOL_TYPE_GATE, (2, [[0], [1]])), + (SYMBOL_TYPE_FET, (0, [-1, 3])), + (SYMBOL_TYPE_FET, (1, [-1, 3])), + (SYMBOL_TYPE_FET, (2, [-2, 3])), + ], + [ + (SYMBOL_TYPE_NOR_SUPER_HD, (0, 1, 3, 2)), + ], + [False, False, False, False], + ), ] if len(sys.argv) < 3: @@ -450,15 +504,24 @@ 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_TG_LATCH_FB: + [_, block, (d_net, le_net, len_net, q_net, qn_net, fb_net)] = symbols[i] + print(symbol_type, block, d_net, le_net, len_net, q_net, qn_net, fb_net) elif ( - symbol_type == SYMBOL_TYPE_SB or - symbol_type == SYMBOL_TYPE_SB_NOT + symbol_type == SYMBOL_TYPE_SUPER or + symbol_type == SYMBOL_TYPE_NOT_SUPER ): [_, 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 + symbol_type == SYMBOL_TYPE_SUPER_OE or + symbol_type == SYMBOL_TYPE_NOT_SUPER_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_NOR_SUPER: + [_, block, (a_net, b_net, y_net)] = symbols[i] + print(symbol_type, block, a_net, b_net, y_net) + elif symbol_type == SYMBOL_TYPE_NOR_SUPER_HD: + [_, block, (a_net, b_net, y_net, hd_net)] = symbols[i] + print(symbol_type, block, a_net, b_net, y_net, hd_net) -- 2.34.1