|
|
|
@ -14,7 +14,7 @@ Since simulators only support at most four-input-gates, gates with more than fou |
|
|
|
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, batchrange |
|
|
|
from . import readtext, batchrange, log |
|
|
|
|
|
|
|
|
|
|
|
def treeify(l, max_degree=4): |
|
|
|
def treeify(l, max_degree=4): |
|
|
|
if len(l) <= max_degree: return l |
|
|
|
if len(l) <= max_degree: return l |
|
|
|
@ -26,12 +26,32 @@ class BenchTransformer(Transformer): |
|
|
|
def __init__(self, name): |
|
|
|
def __init__(self, name): |
|
|
|
super().__init__() |
|
|
|
super().__init__() |
|
|
|
self.c = Circuit(name) |
|
|
|
self.c = Circuit(name) |
|
|
|
|
|
|
|
self.inputs = set() |
|
|
|
|
|
|
|
self.outputs = set() |
|
|
|
|
|
|
|
|
|
|
|
def start(self, _): return self.c |
|
|
|
def start(self, _): return self.c |
|
|
|
|
|
|
|
|
|
|
|
def parameters(self, args): return [self.c.get_or_add_fork(str(name)) for name in args if name is not None] |
|
|
|
def parameters(self, args): return [self.c.get_or_add_fork(str(name)) for name in args if name is not None] |
|
|
|
|
|
|
|
|
|
|
|
def interface(self, args): self.c.io_nodes.extend(args[0]) |
|
|
|
def input(self, args): |
|
|
|
|
|
|
|
for input in args[0]: |
|
|
|
|
|
|
|
if input in self.outputs: |
|
|
|
|
|
|
|
new_input = self.c.get_or_add_fork(input.name + '~i') |
|
|
|
|
|
|
|
Line(self.c, new_input, input) |
|
|
|
|
|
|
|
log.warn(f'input-output passthrough, renaming input: {input.name} -> {new_input.name}') |
|
|
|
|
|
|
|
input = new_input |
|
|
|
|
|
|
|
self.inputs.add(input) |
|
|
|
|
|
|
|
self.c.io_nodes.append(input) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def output(self, args): |
|
|
|
|
|
|
|
for output in args[0]: |
|
|
|
|
|
|
|
if output in self.inputs: |
|
|
|
|
|
|
|
new_output = self.c.get_or_add_fork(output.name + '~o') |
|
|
|
|
|
|
|
Line(self.c, output, new_output) |
|
|
|
|
|
|
|
log.warn(f'input-output passthrough, renaming output: {output.name} -> {new_output.name}') |
|
|
|
|
|
|
|
output = new_output |
|
|
|
|
|
|
|
self.outputs.add(output) |
|
|
|
|
|
|
|
self.c.io_nodes.append(output) |
|
|
|
|
|
|
|
|
|
|
|
def _cell_tree_inner(self, name, kind, inner_kind, drivers): |
|
|
|
def _cell_tree_inner(self, name, kind, inner_kind, drivers): |
|
|
|
cell = Node(self.c, name, f'{kind}{len(drivers)}') |
|
|
|
cell = Node(self.c, name, f'{kind}{len(drivers)}') |
|
|
|
@ -69,8 +89,8 @@ class BenchTransformer(Transformer): |
|
|
|
GRAMMAR = r""" |
|
|
|
GRAMMAR = r""" |
|
|
|
start: (statement)* |
|
|
|
start: (statement)* |
|
|
|
statement: input | output | assignment |
|
|
|
statement: input | output | assignment |
|
|
|
input: ("INPUT" | "input") parameters -> interface |
|
|
|
input: ("INPUT" | "input") parameters |
|
|
|
output: ("OUTPUT" | "output") parameters -> interface |
|
|
|
output: ("OUTPUT" | "output") parameters |
|
|
|
assignment: NAME "=" NAME parameters |
|
|
|
assignment: NAME "=" NAME parameters |
|
|
|
parameters: "(" [ NAME ( "," NAME )* ] ")" |
|
|
|
parameters: "(" [ NAME ( "," NAME )* ] ")" |
|
|
|
NAME: /[-_a-z0-9]+/i |
|
|
|
NAME: /[-_a-z0-9]+/i |
|
|
|
|