Browse Source

generate proper simprims in bench parser

devel
Stefan Holst 2 days ago
parent
commit
df8a58f57b
  1. 36
      src/kyupy/bench.py
  2. 5
      src/kyupy/sim.py

36
src/kyupy/bench.py

@ -10,7 +10,11 @@ Besides loading these benchmarks, this module is also useful for easily construc
from lark import Lark, Transformer from lark import Lark, Transformer
from .circuit import Circuit, Node, Line from .circuit import Circuit, Node, Line
from . import readtext from . import readtext, batchrange
def treeify(l, max_degree=4):
if len(l) <= max_degree: return l
return treeify([l[bo:bo+bs] for bo, bs in batchrange(len(l), max_degree)])
class BenchTransformer(Transformer): class BenchTransformer(Transformer):
@ -25,9 +29,35 @@ class BenchTransformer(Transformer):
def interface(self, args): self.c.io_nodes.extend(args[0]) def interface(self, args): self.c.io_nodes.extend(args[0])
def _cell_tree_inner(self, name, kind, inner_kind, drivers):
cell = Node(self.c, name, f'{kind}{len(drivers)}')
fork = self.c.get_or_add_fork(name)
Line(self.c, cell, fork)
for i, d in enumerate(drivers):
while isinstance(d, list) and len(d) == 1: d = d[0]
if isinstance(d, list):
d = self._cell_tree_inner(f'{name}~{i}', inner_kind, inner_kind, d)
Line(self.c, d, cell)
return fork
def cell_tree(self, name, kind, drivers):
root_kind = kind.upper()
inner_kind = root_kind
if root_kind == 'NAND': inner_kind = 'AND'
if root_kind == 'NOR': inner_kind = 'OR'
if root_kind == 'XNOR': inner_kind = 'XOR'
return self._cell_tree_inner(name, root_kind, inner_kind, treeify(drivers))
def assignment(self, args): def assignment(self, args):
name, cell_type, drivers = args name, kind, drivers = args
cell = Node(self.c, str(name), str(cell_type)) if kind.upper() in ('AND', 'NAND', 'OR', 'NOR', 'XOR', 'XNOR'):
self.cell_tree(name, kind, drivers)
return
if kind.upper().startswith('BUF'):
kind = 'BUF1'
elif kind.upper().startswith('INV') or kind.upper().startswith('NOT'):
kind = 'INV1'
cell = Node(self.c, str(name), str(kind))
Line(self.c, cell, self.c.get_or_add_fork(str(name))) Line(self.c, cell, self.c.get_or_add_fork(str(name)))
for d in drivers: Line(self.c, d, cell) for d in drivers: Line(self.c, d, cell)

5
src/kyupy/sim.py

@ -4,6 +4,7 @@ from bisect import bisect, insort_left
import numpy as np import numpy as np
from . import log
from .circuit import Circuit from .circuit import Circuit
BUF1 = np.uint16(0b1010_1010_1010_1010) BUF1 = np.uint16(0b1010_1010_1010_1010)
@ -199,6 +200,8 @@ class SimOps:
for l in level_lines: for l in level_lines:
n = l.driver n = l.driver
if len(n.ins) > 4:
log.warn(f'too many input pins: {n}')
in_idxs = [n.ins[x].index if len(n.ins) > x and n.ins[x] is not None else self.zero_idx for x in [0,1,2,3]] in_idxs = [n.ins[x].index if len(n.ins) > x and n.ins[x] is not None else self.zero_idx for x in [0,1,2,3]]
if n in ppio2idx: if n in ppio2idx:
in_idxs[0] = self.ppi_offset + ppio2idx[n] in_idxs[0] = self.ppi_offset + ppio2idx[n]
@ -223,7 +226,7 @@ class SimOps:
sp = prims[2] sp = prims[2]
break break
if sp is None: if sp is None:
print('unknown cell type', kind) log.warn(f'ignored cell of unknown type: {n}')
else: else:
level_ops.append((sp, l.index, *in_idxs, *a_ctrl[l])) level_ops.append((sp, l.index, *in_idxs, *a_ctrl[l]))

Loading…
Cancel
Save