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