|
|
|
@ -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) |
|
|
|
|
|
|
|
|
|
|
|
|