| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -8,7 +8,7 @@ from collections import namedtuple | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from lark import Lark, Transformer | 
					 | 
					 | 
					 | 
					from lark import Lark, Transformer | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from . import readtext | 
					 | 
					 | 
					 | 
					from . import log, readtext | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from .circuit import Circuit, Node, Line | 
					 | 
					 | 
					 | 
					from .circuit import Circuit, Node, Line | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from .techlib import TechLib | 
					 | 
					 | 
					 | 
					from .techlib import TechLib | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -17,27 +17,21 @@ Instantiation = namedtuple('Instantiation', ['type', 'name', 'pins']) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class SignalDeclaration: | 
					 | 
					 | 
					 | 
					class SignalDeclaration: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def __init__(self, kind, tokens): | 
					 | 
					 | 
					 | 
					    def __init__(self, kind, name, rnge=None): | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.left = None | 
					 | 
					 | 
					 | 
					        self.left = None | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.right = None | 
					 | 
					 | 
					 | 
					        self.right = None | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.kind = kind | 
					 | 
					 | 
					 | 
					        self.kind = kind | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if len(tokens.children) == 1: | 
					 | 
					 | 
					 | 
					        self.basename = name | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            self.basename = tokens.children[0] | 
					 | 
					 | 
					 | 
					        self.rnge = rnge | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        else: | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            self.basename = tokens.children[2] | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            self.left = int(tokens.children[0].value) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            self.right = int(tokens.children[1].value) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    @property | 
					 | 
					 | 
					 | 
					    @property | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def names(self): | 
					 | 
					 | 
					 | 
					    def names(self): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if self.left is None: | 
					 | 
					 | 
					 | 
					        if self.rnge is None: | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return [self.basename] | 
					 | 
					 | 
					 | 
					            return [self.basename] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if self.left <= self.right: | 
					 | 
					 | 
					 | 
					        return [f'{self.basename}[{i}]' for i in self.rnge] | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return [f'{self.basename}[{i}]' for i in range(self.left, self.right + 1)] | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return [f'{self.basename}[{i}]' for i in range(self.left, self.right - 1, -1)] | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def __repr__(self): | 
					 | 
					 | 
					 | 
					    def __repr__(self): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return f"{self.kind}:{self.basename}[{self.left}:{self.right}]" | 
					 | 
					 | 
					 | 
					        return f"{self.kind}:{self.basename}[{self.rnge}]" | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class VerilogTransformer(Transformer): | 
					 | 
					 | 
					 | 
					class VerilogTransformer(Transformer): | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -60,23 +54,25 @@ class VerilogTransformer(Transformer): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                             dict((pin.children[0], | 
					 | 
					 | 
					 | 
					                             dict((pin.children[0], | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                             pin.children[1]) for pin in args[2:] if len(pin.children) > 1)) | 
					 | 
					 | 
					 | 
					                             pin.children[1]) for pin in args[2:] if len(pin.children) > 1)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def input(self, args): | 
					 | 
					 | 
					 | 
					    def range(self, args): | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for sd in [SignalDeclaration('input', signal) for signal in args]: | 
					 | 
					 | 
					 | 
					        left = int(args[0].value) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            self._signal_declarations[sd.basename] = sd | 
					 | 
					 | 
					 | 
					        right = int(args[1].value) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					        return range(left, right+1) if left <= right else range(left, right-1, -1) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def inout(self, args): | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for sd in [SignalDeclaration('input', signal) for signal in args]:  # just treat as input | 
					 | 
					 | 
					 | 
					    def declaration(self, kind, args): | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            self._signal_declarations[sd.basename] = sd | 
					 | 
					 | 
					 | 
					        rnge = None | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					        if isinstance(args[0], range): | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def output(self, args): | 
					 | 
					 | 
					 | 
					            rnge = args[0] | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for sd in [SignalDeclaration('output', signal) for signal in args]: | 
					 | 
					 | 
					 | 
					            args = args[1:] | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            self._signal_declarations[sd.basename] = sd | 
					 | 
					 | 
					 | 
					        for sd in [SignalDeclaration(kind, signal, rnge) for signal in args]: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					            if kind != 'wire' or sd.basename not in self._signal_declarations: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def wire(self, args): | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for sd in [SignalDeclaration('wire', signal) for signal in args]: | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            if sd.basename not in self._signal_declarations: | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                self._signal_declarations[sd.basename] = sd | 
					 | 
					 | 
					 | 
					                self._signal_declarations[sd.basename] = sd | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    def input(self, args): self.declaration("input", args) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    def output(self, args): self.declaration("output", args) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    def inout(self, args): self.declaration("input", args)  # just treat as input | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    def wire(self, args): self.declaration("wire", args) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def module(self, args): | 
					 | 
					 | 
					 | 
					    def module(self, args): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        c = Circuit(args[0]) | 
					 | 
					 | 
					 | 
					        c = Circuit(args[0]) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        positions = {} | 
					 | 
					 | 
					 | 
					        positions = {} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -125,6 +121,9 @@ class VerilogTransformer(Transformer): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        const_count += 1 | 
					 | 
					 | 
					 | 
					                        const_count += 1 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        s = cname | 
					 | 
					 | 
					 | 
					                        s = cname | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        Line(c, cnode, Node(c, s)) | 
					 | 
					 | 
					 | 
					                        Line(c, cnode, Node(c, s)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    if s not in c.forks: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        log.warn(f'Signal not driven: {s}') | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        Node(c, s)  # generate fork here | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    fork = c.forks[s] | 
					 | 
					 | 
					 | 
					                    fork = c.forks[s] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    if self.branchforks: | 
					 | 
					 | 
					 | 
					                    if self.branchforks: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        branchfork = Node(c, fork.name + "~" + n.name + "/" + p) | 
					 | 
					 | 
					 | 
					                        branchfork = Node(c, fork.name + "~" + n.name + "/" + p) | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -134,7 +133,10 @@ class VerilogTransformer(Transformer): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for sd in self._signal_declarations.values(): | 
					 | 
					 | 
					 | 
					        for sd in self._signal_declarations.values(): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            if sd.kind == 'output': | 
					 | 
					 | 
					 | 
					            if sd.kind == 'output': | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                for name in sd.names: | 
					 | 
					 | 
					 | 
					                for name in sd.names: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    Line(c, c.forks[name], c.cells[name]) | 
					 | 
					 | 
					 | 
					                    if name not in c.forks: | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        log.warn(f'Output not driven: {name}') | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    else: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        Line(c, c.forks[name], c.cells[name]) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return c | 
					 | 
					 | 
					 | 
					        return c | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    @staticmethod | 
					 | 
					 | 
					 | 
					    @staticmethod | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -144,18 +146,19 @@ class VerilogTransformer(Transformer): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					GRAMMAR = """ | 
					 | 
					 | 
					 | 
					GRAMMAR = """ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    start: (module)* | 
					 | 
					 | 
					 | 
					    start: (module)* | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    module: "module" name parameters ";" (_statement)* "endmodule" | 
					 | 
					 | 
					 | 
					    module: "module" name parameters ";" (_statement)* "endmodule" | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    parameters: "(" [ name ( "," name )* ] ")" | 
					 | 
					 | 
					 | 
					    parameters: "(" [ _namelist ] ")" | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    _statement: input | output | inout | tri | wire | assign | instantiation | 
					 | 
					 | 
					 | 
					    _statement: input | output | inout | tri | wire | assign | instantiation | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    input: "input" signal ( "," signal )* ";" | 
					 | 
					 | 
					 | 
					    input: "input" range? _namelist ";" | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    output: "output" signal ( "," signal )* ";" | 
					 | 
					 | 
					 | 
					    output: "output" range? _namelist ";" | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    inout: "inout" signal ( "," signal )* ";" | 
					 | 
					 | 
					 | 
					    inout: "inout" range? _namelist ";" | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    tri: "tri" name ";" | 
					 | 
					 | 
					 | 
					    tri: "tri" range? _namelist ";" | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    wire: "wire" signal ( "," signal )* ";" | 
					 | 
					 | 
					 | 
					    wire: "wire" range? _namelist ";" | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    assign: "assign" name "=" name ";" | 
					 | 
					 | 
					 | 
					    assign: "assign" name "=" name ";" | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    instantiation: name name "(" [ pin ( "," pin )* ] ")" ";" | 
					 | 
					 | 
					 | 
					    instantiation: name name "(" [ pin ( "," pin )* ] ")" ";" | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    pin: "." name "(" name? ")" | 
					 | 
					 | 
					 | 
					    pin: "." name "(" name? ")" | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    signal: ( name | "[" /[0-9]+/ ":" /[0-9]+/ "]" name ) | 
					 | 
					 | 
					 | 
					    range: "[" /[0-9]+/ ":" /[0-9]+/ "]" | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    _namelist: name ( "," name )* | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    name: ( /[a-z_][a-z0-9_\\[\\]]*/i | /\\\\[^\\t \\r\\n]+[\\t \\r\\n](\\[[0-9]+\\])?/i | /1'b0/i | /1'b1/i ) | 
					 | 
					 | 
					 | 
					    name: ( /[a-z_][a-z0-9_\\[\\]]*/i | /\\\\[^\\t \\r\\n]+[\\t \\r\\n](\\[[0-9]+\\])?/i | /1'b0/i | /1'b1/i ) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    COMMENT: "//" /[^\\n]*/ | 
					 | 
					 | 
					 | 
					    COMMENT: "//" /[^\\n]*/ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    %ignore ( /\\r?\\n/ | COMMENT )+ | 
					 | 
					 | 
					 | 
					    %ignore ( /\\r?\\n/ | COMMENT )+ | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |