Files
tt-support-tools/reports.py
T
matt venn d61bcbd17a Update reports.py
switch to HD cells, closes issue #10
2023-05-02 12:38:59 +02:00

116 lines
4.2 KiB
Python
Executable File

import os
import csv
import json
import re
import glob
# can't find a google version
CELL_URL = 'https://antmicro-skywater-pdk-docs.readthedocs.io/en/test-submodules-in-rtd/contents/libraries/sky130_fd_sc_hd/cells/'
def print_warnings(args):
warnings = []
with open(os.path.join(args.run_dir, 'logs/synthesis/1-synthesis.log')) as f:
for line in f.readlines():
if line.startswith('Warning:'):
# bogus warning https://github.com/YosysHQ/yosys/commit/bfacaddca8a2e113e4bc3d6177612ccdba1555c8
if 'WIDTHLABEL' not in line:
warnings.append(line.strip())
if len(warnings):
print('# Synthesis warnings')
print()
for warning in warnings:
print(f'* {warning}')
def print_stats(args):
with open(os.path.join(args.run_dir, 'reports/metrics.csv')) as f:
report = list(csv.DictReader(f))[0]
print('# Routing stats')
print()
print('| Utilisation (%) | Wire length (um) |')
print('|-------------|------------------|')
print('| {} | {} |'.format(report['OpenDP_Util'], report['wire_length']))
# Print the summaries
def summarize(args):
cell_count = get_cell_count_from_gl(args)
script_dir = os.path.dirname(os.path.realpath(__file__))
with open(os.path.join(script_dir, 'categories.json')) as fh:
categories = json.load(fh)
with open(os.path.join(script_dir, 'defs.json')) as fh:
defs = json.load(fh)
# print all used cells, sorted by frequency
total = 0
if args.print_cell_summary:
print('# Cell usage')
print()
print('| Cell Name | Description | Count |')
print('|-----------|-------------|-------|')
for name, count in sorted(cell_count.items(), key=lambda item: item[1], reverse=True):
if count > 0:
total += count
cell_link = f'{CELL_URL}{name}'
print(f'| [{name}]({cell_link}) | {defs[name]["description"]} |{count} |')
print(f'| | Total | {total} |')
if args.print_cell_category:
by_category = {}
for cell_name in cell_count:
cat_index = categories['map'][cell_name]
cat_name = categories['categories'][cat_index]
if cat_name in by_category:
by_category[cat_name]['count'] += cell_count[cell_name]
by_category[cat_name]['examples'].append(cell_name)
else:
by_category[cat_name] = {'count' : cell_count[cell_name], 'examples' : [cell_name]}
print('# Cell usage by Category')
print()
print('| Category | Cells | Count |')
print('|---------------|----------|-------|')
for cat_name, cat_dict in sorted(by_category.items(), key=lambda x: x[1]['count'], reverse=True):
cell_links = [f'[{name}]({CELL_URL}{name})' for name in cat_dict['examples']]
print(f'|{cat_name} | {" ".join(cell_links)} | {cat_dict["count"]}|')
# Parse the lib, cell and drive strength an OpenLane gate-level Verilog file
def get_cell_count_from_gl(args):
cell_count = {}
total = 0
gl_files = glob.glob(os.path.join(args.run_dir, 'results/final/verilog/gl/*.nl.v'))
with open(gl_files[0]) as fh:
for line in fh.readlines():
m = re.search(r'sky130_(\S+)__(\S+)_(\d+)', line)
if m is not None:
total += 1
cell_lib = m.group(1)
cell_name = m.group(2)
cell_drive = m.group(3)
assert cell_lib in ['fd_sc_hd', 'ef_sc_hd']
try:
cell_count[cell_name] += 1
except KeyError:
cell_count[cell_name] = 1
return (cell_count)
# Load all the json defs and combine into one big dict, keyed by cellname
# Needs access to the PDK
def create_defs(args):
# replace this with a find
json_files = glob.glob('sky130_fd_sc_hd/latest/cells/*/definition.json')
definitions = {}
for json_file in json_files:
with open(json_file) as fh:
definition = json.load(fh)
definitions[definition['name']] = definition
with open('defs.json', 'w') as fh:
json.dump(definitions, fh)