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