In /scripts/circuits.py and /scripts/blocks.py rename SB_* to *_SUPER, add the TG_LAT...
authorNick Downing <nick@ndcode.org>
Mon, 21 Jul 2025 06:21:57 +0000 (16:21 +1000)
committerNick Downing <nick@ndcode.org>
Mon, 21 Jul 2025 08:48:36 +0000 (18:48 +1000)
scripts/blocks.py
scripts/circuits.py

index db6c48f..85c1066 100755 (executable)
@@ -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')
index 535db3f..1141632 100755 (executable)
@@ -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)