generate proper simprims in bench parser
This commit is contained in:
1 parent
3dfd0cb60d
commit
df8a58f57b
2 files changed
+37
-4
No files matched your search
+33
-3
@@ -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)
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -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]))
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user