@ -291,6 +291,15 @@ class Circuit:
				@@ -291,6 +291,15 @@ class Circuit:
					 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    @property  
			
		
	
		
			
				
					    def  stats ( self ) :  
			
		
	
		
			
				
					        """ Generates a dictionary with the number of all different elements in the circuit.  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        The  dictionary  contains  the  number  of  all  different  kinds  of  nodes ,  the  number  
			
		
	
		
			
				
					        of  lines ,  as  well  various  sums  like  number  of  combinational  gates ,  number  of  
			
		
	
		
			
				
					        primary  I / Os ,  number  of  sequential  elements ,  and  so  on .  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        The  count  of  regular  cells  use  their  ` Node . kind `  as  key ,  other  statistics  use  
			
		
	
		
			
				
					        dunder - keys  like :  ` __comb__ ` ,  ` __io__ ` ,  ` __seq__ ` ,  and  so  on .  
			
		
	
		
			
				
					        """  
			
		
	
		
			
				
					        stats  =  defaultdict ( int )  
			
		
	
		
			
				
					        stats [ ' __node__ ' ]  =  len ( self . nodes )  
			
		
	
		
			
				
					        stats [ ' __cell__ ' ]  =  len ( self . cells )  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -386,15 +395,31 @@ class Circuit:
				@@ -386,15 +395,31 @@ class Circuit:
					 
			
		
	
		
			
				
					            yield  stem ,  region  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    def  io_locs ( self ,  prefix ) :  
			
		
	
		
			
				
					        """ Returns the indices of primary I/Os that start with given name prefix.  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        The  returned  values  are  used  to  index  into  the  : py : attr : ` io_nodes `  array .  
			
		
	
		
			
				
					        If  only  one  I / O  cell  matches  the  given  prefix ,  a  single  integer  is  returned .  
			
		
	
		
			
				
					        If  a  bus  matches  the  given  prefix ,  a  sorted  list  of  indices  is  returned .  
			
		
	
		
			
				
					        Busses  are  identified  by  integers  in  the  cell  names  following  the  given  prefix .  
			
		
	
		
			
				
					        Lists  for  bus  indices  are  sorted  from  LSB  ( e . g .  ` data [ 0 ] ` )  to  MSB  ( e . g .  ` data [ 31 ] ` ) .  
			
		
	
		
			
				
					        If  a  prefix  matches  multiple  different  signals  or  busses ,  alphanumerically  sorted  
			
		
	
		
			
				
					        lists  of  lists  are  returned .  Therefore ,  higher - dimensional  busses  
			
		
	
		
			
				
					        ( e . g .  ` data0 [ 0 ] ,  data0 [ 1 ] ,  . . . ` ,  ` data1 [ 0 ] ,  data1 [ 1 ] ,  . . . ` )  are  supported  as  well .  
			
		
	
		
			
				
					        """  
			
		
	
		
			
				
					        return  self . _locs ( prefix ,  list ( self . io_nodes ) )  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    def  s_locs ( self ,  prefix ) :  
			
		
	
		
			
				
					        """ Returns the indices of I/Os and sequential elements that start with given name prefix.  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        The  returned  values  are  used  to  index  into  the  : py : attr : ` s_nodes `  array .  
			
		
	
		
			
				
					        It  works  the  same  as  : py : attr : ` io_locs ` .  See  there  for  more  details .  
			
		
	
		
			
				
					        """  
			
		
	
		
			
				
					        return  self . _locs ( prefix ,  self . s_nodes )  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    def  _locs ( self ,  prefix ,  nodes ) :  
			
		
	
		
			
				
					        d_top  =  dict ( )  
			
		
	
		
			
				
					        for  i ,  n  in  enumerate ( nodes ) :  
			
		
	
		
			
				
					            if  m  :=  re . match ( fr ' ( { prefix } .*?)((?: \ d+[_ \ [ \ ]])*$) ' ,  n . name ) :  
			
		
	
		
			
				
					            if  m  :=  re . match ( fr ' ( { prefix } .*?)((?:[  \ d_ \ [ \ ]])*$) ' ,  n . name ) :  
			
		
	
		
			
				
					                path  =  [ m [ 1 ] ]  +  [ int ( v )  for  v  in  re . split ( r ' [_ \ [ \ ]]+ ' ,  m [ 2 ] )  if  len ( v )  >  0 ]  
			
		
	
		
			
				
					                d  =  d_top  
			
		
	
		
			
				
					                for  j  in  path [ : - 1 ] :  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -402,6 +427,7 @@ class Circuit:
				@@ -402,6 +427,7 @@ class Circuit:
					 
			
		
	
		
			
				
					                    d  =  d [ j ]  
			
		
	
		
			
				
					                d [ path [ - 1 ] ]  =  i  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					        # sort recursively for multi-dimensional lists.  
			
		
	
		
			
				
					        def  sorted_values ( d ) :  return  [ sorted_values ( v )  for  k ,  v  in  sorted ( d . items ( ) ) ]  if  isinstance ( d ,  dict )  else  d  
			
		
	
		
			
				
					        l  =  sorted_values ( d_top )  
			
		
	
		
			
				
					        while  isinstance ( l ,  list )  and  len ( l )  ==  1 :  l  =  l [ 0 ]