| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -54,26 +54,26 @@ class StilFile: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    launch = dict((k, v.replace('\n', '')) for k, v in call.parameters.items()) | 
					 | 
					 | 
					 | 
					                    launch = dict((k, v.replace('\n', '')) for k, v in call.parameters.items()) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                else: | 
					 | 
					 | 
					 | 
					                else: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    capture = dict((k, v.replace('\n', '')) for k, v in call.parameters.items()) | 
					 | 
					 | 
					 | 
					                    capture = dict((k, v.replace('\n', '')) for k, v in call.parameters.items()) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					     | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def _maps(self, c): | 
					 | 
					 | 
					 | 
					    def _maps(self, c): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        interface = list(c.interface) + [n for n in c.nodes if 'DFF' in n.kind] | 
					 | 
					 | 
					 | 
					        interface = list(c.interface) + [n for n in c.nodes if 'DFF' in n.kind] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        intf_pos = dict([(n.name, i) for i, n in enumerate(interface)]) | 
					 | 
					 | 
					 | 
					        intf_pos = dict((n.name, i) for i, n in enumerate(interface)) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        pi_map = [intf_pos[n] for n in self.signal_groups['_pi']] | 
					 | 
					 | 
					 | 
					        pi_map = [intf_pos[n] for n in self.signal_groups['_pi']] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        po_map = [intf_pos[n] for n in self.signal_groups['_po']] | 
					 | 
					 | 
					 | 
					        po_map = [intf_pos[n] for n in self.signal_groups['_po']] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        scan_maps = {} | 
					 | 
					 | 
					 | 
					        scan_maps = {} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        scan_inversions = {} | 
					 | 
					 | 
					 | 
					        scan_inversions = {} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for chain_name, chain in self.scan_chains.items(): | 
					 | 
					 | 
					 | 
					        for chain in self.scan_chains.values(): | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            scan_map = [] | 
					 | 
					 | 
					 | 
					            scan_map = [] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            scan_in_inversion = [] | 
					 | 
					 | 
					 | 
					            scan_in_inversion = [] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            scan_out_inversion = [] | 
					 | 
					 | 
					 | 
					            scan_out_inversion = [] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            inversion = False | 
					 | 
					 | 
					 | 
					            inversion = False | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            for n in chain[1:-1]: | 
					 | 
					 | 
					 | 
					            for n in chain[1:-1]: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if n == '!':  | 
					 | 
					 | 
					 | 
					                if n == '!': | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    inversion = not inversion | 
					 | 
					 | 
					 | 
					                    inversion = not inversion | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                else: | 
					 | 
					 | 
					 | 
					                else: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    scan_in_inversion.append(inversion) | 
					 | 
					 | 
					 | 
					                    scan_in_inversion.append(inversion) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            scan_in_inversion = list(reversed(scan_in_inversion)) | 
					 | 
					 | 
					 | 
					            scan_in_inversion = list(reversed(scan_in_inversion)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            inversion = False              | 
					 | 
					 | 
					 | 
					            inversion = False | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            for n in reversed(chain[1:-1]): | 
					 | 
					 | 
					 | 
					            for n in reversed(chain[1:-1]): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if n == '!': | 
					 | 
					 | 
					 | 
					                if n == '!': | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    inversion = not inversion | 
					 | 
					 | 
					 | 
					                    inversion = not inversion | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -85,13 +85,13 @@ class StilFile: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            scan_inversions[chain[0]] = scan_in_inversion | 
					 | 
					 | 
					 | 
					            scan_inversions[chain[0]] = scan_in_inversion | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            scan_inversions[chain[-1]] = scan_out_inversion | 
					 | 
					 | 
					 | 
					            scan_inversions[chain[-1]] = scan_out_inversion | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return interface, pi_map, po_map, scan_maps, scan_inversions | 
					 | 
					 | 
					 | 
					        return interface, pi_map, po_map, scan_maps, scan_inversions | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def tests(self, circuit): | 
					 | 
					 | 
					 | 
					    def tests(self, circuit): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        """Assembles and returns a scan test pattern set for given circuit. | 
					 | 
					 | 
					 | 
					        """Assembles and returns a scan test pattern set for given circuit. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        This function assumes a static (stuck-at fault) test. | 
					 | 
					 | 
					 | 
					        This function assumes a static (stuck-at fault) test. | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        """ | 
					 | 
					 | 
					 | 
					        """ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        interface, pi_map, po_map, scan_maps, scan_inversions = self._maps(circuit) | 
					 | 
					 | 
					 | 
					        interface, pi_map, _, scan_maps, scan_inversions = self._maps(circuit) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        tests = logic.MVArray((len(interface), len(self.patterns))) | 
					 | 
					 | 
					 | 
					        tests = logic.MVArray((len(interface), len(self.patterns))) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for i, p in enumerate(self.patterns): | 
					 | 
					 | 
					 | 
					        for i, p in enumerate(self.patterns): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            for si_port in self.si_ports.keys(): | 
					 | 
					 | 
					 | 
					            for si_port in self.si_ports.keys(): | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -133,10 +133,10 @@ class StilFile: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            launch.data[po_map, i] = logic.UNASSIGNED | 
					 | 
					 | 
					 | 
					            launch.data[po_map, i] = logic.UNASSIGNED | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return logic.mv_transition(init, launch) | 
					 | 
					 | 
					 | 
					        return logic.mv_transition(init, launch) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def responses(self, circuit): | 
					 | 
					 | 
					 | 
					    def responses(self, circuit): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        """Assembles and returns a scan test response pattern set for given circuit.""" | 
					 | 
					 | 
					 | 
					        """Assembles and returns a scan test response pattern set for given circuit.""" | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        interface, pi_map, po_map, scan_maps, scan_inversions = self._maps(circuit) | 
					 | 
					 | 
					 | 
					        interface, _, po_map, scan_maps, scan_inversions = self._maps(circuit) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        resp = logic.MVArray((len(interface), len(self.patterns))) | 
					 | 
					 | 
					 | 
					        resp = logic.MVArray((len(interface), len(self.patterns))) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        # resp = PackedVectors(len(self.patterns), len(interface), 2) | 
					 | 
					 | 
					 | 
					        # resp = PackedVectors(len(self.patterns), len(interface), 2) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for i, p in enumerate(self.patterns): | 
					 | 
					 | 
					 | 
					        for i, p in enumerate(self.patterns): | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -150,27 +150,27 @@ class StilFile: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                resp.data[scan_maps[so_port], i] = pattern.data[:, 0] | 
					 | 
					 | 
					 | 
					                resp.data[scan_maps[so_port], i] = pattern.data[:, 0] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                # resp.set_values(i, p.unload[so_port], scan_maps[so_port], scan_inversions[so_port]) | 
					 | 
					 | 
					 | 
					                # resp.set_values(i, p.unload[so_port], scan_maps[so_port], scan_inversions[so_port]) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return resp | 
					 | 
					 | 
					 | 
					        return resp | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class StilTransformer(Transformer): | 
					 | 
					 | 
					 | 
					class StilTransformer(Transformer): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def __init__(self): | 
					 | 
					 | 
					 | 
					    def __init__(self): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        super().__init__() | 
					 | 
					 | 
					 | 
					        super().__init__() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self._signal_groups = None | 
					 | 
					 | 
					 | 
					        self._signal_groups = None | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self._calls = None | 
					 | 
					 | 
					 | 
					        self._calls = None | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self._scan_chains = None | 
					 | 
					 | 
					 | 
					        self._scan_chains = None | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    @staticmethod | 
					 | 
					 | 
					 | 
					    @staticmethod | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def quoted(args): return args[0][1:-1] | 
					 | 
					 | 
					 | 
					    def quoted(args): return args[0][1:-1] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    @staticmethod | 
					 | 
					 | 
					 | 
					    @staticmethod | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def call(args): return Call(args[0], dict(args[1:])) | 
					 | 
					 | 
					 | 
					    def call(args): return Call(args[0], dict(args[1:])) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					         | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    @staticmethod | 
					 | 
					 | 
					 | 
					    @staticmethod | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def call_parameter(args): return args[0], args[1].value | 
					 | 
					 | 
					 | 
					    def call_parameter(args): return args[0], args[1].value | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    @staticmethod | 
					 | 
					 | 
					 | 
					    @staticmethod | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def signal_group(args): return args[0], args[1:] | 
					 | 
					 | 
					 | 
					    def signal_group(args): return args[0], args[1:] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					     | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    @staticmethod | 
					 | 
					 | 
					 | 
					    @staticmethod | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def scan_chain(args): | 
					 | 
					 | 
					 | 
					    def scan_chain(args): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        scan_in = None | 
					 | 
					 | 
					 | 
					        scan_in = None | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -187,7 +187,7 @@ class StilTransformer(Transformer): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return args[0], ([scan_in] + scan_cells + [scan_out]) | 
					 | 
					 | 
					 | 
					        return args[0], ([scan_in] + scan_cells + [scan_out]) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def signal_groups(self, args): self._signal_groups = dict(args) | 
					 | 
					 | 
					 | 
					    def signal_groups(self, args): self._signal_groups = dict(args) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					     | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def pattern(self, args): self._calls = [c for c in args if isinstance(c, Call)] | 
					 | 
					 | 
					 | 
					    def pattern(self, args): self._calls = [c for c in args if isinstance(c, Call)] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def scan_structures(self, args): self._scan_chains = dict(args) | 
					 | 
					 | 
					 | 
					    def scan_structures(self, args): self._scan_chains = dict(args) | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -196,7 +196,7 @@ class StilTransformer(Transformer): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return StilFile(float(args[0]), self._signal_groups, self._scan_chains, self._calls) | 
					 | 
					 | 
					 | 
					        return StilFile(float(args[0]), self._signal_groups, self._scan_chains, self._calls) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					grammar = r""" | 
					 | 
					 | 
					 | 
					GRAMMAR = r""" | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    start: "STIL" FLOAT _ignore _block* | 
					 | 
					 | 
					 | 
					    start: "STIL" FLOAT _ignore _block* | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    _block: signal_groups | scan_structures | pattern | 
					 | 
					 | 
					 | 
					    _block: signal_groups | scan_structures | pattern | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        | "Header" _ignore | 
					 | 
					 | 
					 | 
					        | "Header" _ignore | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -240,7 +240,7 @@ grammar = r""" | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					def parse(text): | 
					 | 
					 | 
					 | 
					def parse(text): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    """Parses the given ``text`` and returns a :class:`StilFile` object.""" | 
					 | 
					 | 
					 | 
					    """Parses the given ``text`` and returns a :class:`StilFile` object.""" | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return Lark(grammar, parser="lalr", transformer=StilTransformer()).parse(text) | 
					 | 
					 | 
					 | 
					    return Lark(GRAMMAR, parser="lalr", transformer=StilTransformer()).parse(text) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					def load(file): | 
					 | 
					 | 
					 | 
					def load(file): | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |