44
55
66def find_top_modules (data ):
7- # There can be some cruft in the modules list so that
8- # we have multiple top level candidates.
97 top_module = []
108 instantiations = set (
119 [
@@ -14,7 +12,7 @@ def find_top_modules(data):
1412 for cell in minfo2 ["cells" ].values ()
1513 ]
1614 )
17- for mname , minfo in data ["modules" ].items ():
15+ for mname in data ["modules" ].keys ():
1816 if mname not in instantiations :
1917 top_module .append (mname )
2018 return top_module
@@ -23,16 +21,6 @@ def find_top_modules(data):
2321def find_cells_by_type_in_module (
2422 module_name , data , target_type , current_path , matching_cells
2523):
26- """
27- Searches through hierarchy starting at module_name to find all instances of
28- the given module/type in the hierarchy.
29-
30- Returns list of cell paths, which are constructed as:
31-
32- <top_module_name>.(<child_inst_name>.<child_module_name>+).<memory_inst_name>
33-
34- where the child_inst_name/child_module_name pairs are repeated for each level of the hierarchy.
35- """
3624 for cell_name , cell in data ["modules" ][module_name ]["cells" ].items ():
3725 cell_path = (
3826 f"{ current_path } .{ module_name } .{ cell_name } "
@@ -42,18 +30,15 @@ def find_cells_by_type_in_module(
4230 if cell ["type" ] == target_type :
4331 matching_cells .append (cell_path )
4432 elif cell ["type" ] in data ["modules" ]:
45- # Recursively search within the module
4633 matching_cells .extend (
4734 find_cells_by_type_in_module (
4835 cell ["type" ], data , target_type , cell_path , []
4936 )
5037 )
51-
5238 return matching_cells
5339
5440
5541def find_cells_by_type (top_modules , data , module_name , current_path = "" ):
56- # first find top module, the module without any submodules
5742 names = []
5843 for top_module in top_modules :
5944 names .extend (
@@ -69,13 +54,12 @@ def format_ram_table_from_json(data, max_bits=None):
6954 formatting = "{:>5} | {:>5} | {:>6} | {:<20} | {:<80}\n "
7055 table = formatting .format ("Rows" , "Width" , "Bits" , "Module" , "Instances" )
7156 table += "-" * len (table ) + "\n "
57+
7258 max_ok = True
7359 entries = []
7460
75- # Collect the entries in a list
7661 for module_name , module_info in data ["modules" ].items ():
77- cells = module_info ["cells" ]
78- for cell in cells .values ():
62+ for cell in module_info ["cells" ].values ():
7963 if not cell ["type" ].startswith ("$mem" ):
8064 continue
8165 parameters = cell ["parameters" ]
@@ -84,18 +68,38 @@ def format_ram_table_from_json(data, max_bits=None):
8468 instances = find_cells_by_type (top_modules , data , module_name )
8569 instance_bits = size * width
8670 bits = instance_bits * len (instances )
71+
8772 entries .append ((size , width , bits , module_name , ", " .join (instances )))
73+
8874 if max_bits is not None and instance_bits > max_bits :
8975 max_ok = False
9076
91- # Sort the entries by descending bits
9277 entries .sort (key = lambda x : x [2 ], reverse = True )
9378
94- # Format the sorted entries into the table
9579 for entry in entries :
9680 table += formatting .format (* entry )
9781
98- return table , max_ok
82+ # ---- Summary statistics ----
83+ total_bits = sum (e [2 ] for e in entries )
84+
85+ largest_instance_bits = 0
86+ largest_instance_module = None
87+
88+ for size , width , _ , module , _ in entries :
89+ instance_bits = size * width
90+ if instance_bits > largest_instance_bits :
91+ largest_instance_bits = instance_bits
92+ largest_instance_module = module
93+
94+ summary = {
95+ "memory_count" : len (entries ),
96+ "largest_instance_bits" : largest_instance_bits ,
97+ "largest_instance_module" : largest_instance_module ,
98+ "largest_total_bits" : entries [0 ][2 ] if entries else 0 ,
99+ "total_bits" : total_bits ,
100+ }
101+
102+ return table , max_ok , summary
99103
100104
101105if __name__ == "__main__" :
@@ -119,9 +123,27 @@ def format_ram_table_from_json(data, max_bits=None):
119123 print (" " + "\n " .join (src_files ))
120124
121125 print ("Memories found in the design:" )
122- formatted_table , max_ok = format_ram_table_from_json (json_data , args .max_bits )
126+ formatted_table , max_ok , summary = format_ram_table_from_json (
127+ json_data , args .max_bits
128+ )
129+
123130 print (formatted_table )
124- if not max_ok :
125- sys .exit (
126- f"Error: Synthesized memory size { args .max_bits } exceeds SYNTH_MEMORY_MAX_BITS"
127- )
131+
132+ print ("Summary:" )
133+ print (f"- Total inferred memories: { summary ['memory_count' ]} " )
134+ print (
135+ f"- Largest single memory instance: "
136+ f"{ summary ['largest_instance_bits' ]} bits "
137+ f"(module { summary ['largest_instance_module' ]} )"
138+ )
139+ print (f"- Total inferred memory bits (all instances): { summary ['total_bits' ]} " )
140+
141+ if args .max_bits is not None :
142+ status = "OK" if max_ok else "FAIL"
143+ print (f"- SYNTH_MEMORY_MAX_BITS: { args .max_bits } " )
144+ print (f"- Status: { status } " )
145+
146+ if not max_ok :
147+ sys .exit (
148+ f"Error: Synthesized memory size { args .max_bits } exceeds SYNTH_MEMORY_MAX_BITS"
149+ )
0 commit comments