blob: d8c72515fb4fff0185e25d85828c12f172f8cc48 [file] [log] [blame] [edit]
#!/usr/bin/env python3
"""
Gather data from given lib file. This data is then used to populate JSON file
that has delay numbers for some parameters related to F2A and A2F pins.
"""
import argparse
from collections import defaultdict
# =============================================================================
def main():
"""
Gather lib information from the given library file
"""
parser = argparse.ArgumentParser(
description='Gather lib information from the given library file.'
)
parser.add_argument(
"--lib",
"-l",
"-L",
type=str,
required=True,
help='Specify input lib file'
)
args = parser.parse_args()
lib_fp = open(args.lib, newline='')
for line in lib_fp:
if line.find("bus ( gfpga_pad_IO_A2F") != -1:
a2f_process_lib_data(lib_fp)
elif line.find("bus ( gfpga_pad_IO_F2A") != -1:
f2a_process_lib_data(lib_fp)
# =============================================================================
def f2a_process_lib_data(lib_fp):
"""
Process F2A pin lib_data
"""
f2a_data_max = defaultdict(set)
f2a_data_min = defaultdict(set)
max_transition = set()
capacitance = set()
for f2a_line in lib_fp:
pin_pos = f2a_line.find("pin(\"")
if pin_pos != -1:
for pin_line in lib_fp:
if pin_line.find("rising_edge") != -1:
f2a_data_max, f2a_data_min = f2a_timing_type(
lib_fp, pin_line, "rising_edge", f2a_data_max,
f2a_data_min
)
elif pin_line.find("max_transition") != -1:
val_list = pin_line.split(' : ')
max_transition.add(
float(val_list[1].split(' ;')[0].strip())
)
elif pin_line.find("capacitance") != -1:
val_list = pin_line.split(' : ')
capacitance.add(float(val_list[1].split(' ;')[0].strip()))
elif pin_line.find("end of bus") != -1:
break
print(
'F2A {} least_val: {}, highest_val: {}'.format(
"max_transition", next(iter(sorted(max_transition))),
sorted(max_transition).pop()
)
)
print(
'F2A {} least_val: {}, highest_val: {}'.format(
"capacitance", next(iter(sorted(capacitance))),
sorted(capacitance).pop()
)
)
print(
'F2A {} least_val: {}, highest_val: {}'.format(
"rising_edge_cell_rise_val",
next(iter(sorted(f2a_data_min['rising_edge_cell_rise']))),
sorted(f2a_data_max['rising_edge_cell_rise']).pop()
)
)
print(
'F2A {} least_val: {}, highest_val: {}'.format(
"rising_edge_cell_fall_val",
next(iter(sorted(f2a_data_min['rising_edge_cell_fall']))),
sorted(f2a_data_max['rising_edge_cell_fall']).pop()
)
)
print(
'F2A {} least_val: {}, highest_val: {}'.format(
"rising_edge_rise_tran_val",
next(iter(sorted(f2a_data_min['rising_edge_rise_tran']))),
sorted(f2a_data_max['rising_edge_rise_tran']).pop()
)
)
print(
'F2A {} least_val: {}, highest_val: {}'.format(
"rising_edge_fall_tran_val",
next(iter(sorted(f2a_data_min['rising_edge_fall_tran']))),
sorted(f2a_data_max['rising_edge_fall_tran']).pop()
)
)
break
# =============================================================================
def a2f_process_lib_data(lib_fp):
"""
Process A2F pin lib_data
"""
a2f_data_max = defaultdict(set)
a2f_data_min = defaultdict(set)
max_transition = set()
capacitance = set()
for a2f_line in lib_fp:
pin_pos = a2f_line.find("pin(\"")
if pin_pos != -1:
for pin_line in lib_fp:
if pin_line.find("setup_rising") != -1:
a2f_data_max, a2f_data_min = a2f_timing_type(
lib_fp, pin_line, "setup_rising", a2f_data_max,
a2f_data_min
)
elif pin_line.find("hold_rising") != -1:
a2f_data_max, a2f_data_min = a2f_timing_type(
lib_fp, pin_line, "hold_rising", a2f_data_max,
a2f_data_min
)
elif pin_line.find("max_transition") != -1:
val_list = pin_line.split(' : ')
max_transition.add(
float(val_list[1].split(' ;')[0].strip())
)
elif pin_line.find("capacitance") != -1:
val_list = pin_line.split(' : ')
capacitance.add(float(val_list[1].split(' ;')[0].strip()))
elif pin_line.find("end of bus gfpga_pad_IO_A2F") != -1:
break
print(
'A2F {} least_val: {}, highest_val: {}'.format(
"max_transition", next(iter(sorted(max_transition))),
sorted(max_transition).pop()
)
)
print(
'A2F {} least_val: {}, highest_val: {}'.format(
"capacitance", next(iter(sorted(capacitance))),
sorted(capacitance).pop()
)
)
print(
'A2F {} least_val: {}, highest_val: {}'.format(
"setup_rising_rise_constraint_val",
next(
iter(
sorted(
a2f_data_min['setup_rising_rise_constraint']
)
)
),
sorted(a2f_data_max['setup_rising_rise_constraint']).pop()
)
)
print(
'A2F {} least_val: {}, highest_val: {}'.format(
"setup_rising_fall_constraint_val",
next(
iter(
sorted(
a2f_data_min['setup_rising_fall_constraint']
)
)
),
sorted(a2f_data_max['setup_rising_fall_constraint']).pop()
)
)
print(
'A2F {} least_val: {}, highest_val: {}'.format(
"hold_rising_rise_constraint_val",
next(
iter(
sorted(
a2f_data_min['hold_rising_rise_constraint']
)
)
),
sorted(a2f_data_max['hold_rising_rise_constraint']).pop()
)
)
print(
'A2F {} least_val: {}, highest_val: {}'.format(
"hold_rising_fall_constraint_val",
next(
iter(
sorted(
a2f_data_min['hold_rising_fall_constraint']
)
)
),
sorted(a2f_data_max['hold_rising_fall_constraint']).pop()
)
)
break
# =============================================================================
def a2f_timing_type(lib_fp, pin_line, type_str, a2f_data_max, a2f_data_min):
"""
Collect A2F pin data
"""
type_pos = pin_line.find(type_str)
if type_pos != -1:
for type_line in lib_fp:
rise_pos = type_line.find("rise_constraint")
if rise_pos != -1:
for constraint_line in lib_fp:
if constraint_line.find("}") != -1:
break
if constraint_line.find('values') != -1:
val_set = set()
val_set = populate_set(constraint_line, val_set)
for val_line in lib_fp:
if val_line.find(");") != -1:
val_set = populate_set(val_line, val_set)
break
val_set = populate_set(val_line, val_set)
if type_str == "setup_rising":
a2f_data_max['setup_rising_rise_constraint'].add(
sorted(val_set).pop()
)
a2f_data_min['setup_rising_rise_constraint'].add(
next(iter(sorted(val_set)))
)
else:
a2f_data_max['hold_rising_rise_constraint'].add(
sorted(val_set).pop()
)
a2f_data_min['hold_rising_rise_constraint'].add(
next(iter(sorted(val_set)))
)
break
break
for type_line in lib_fp:
fall_pos = type_line.find("fall_constraint")
if fall_pos != -1:
for constraint_line in lib_fp:
if constraint_line.find("}") != -1:
break
if constraint_line.find('values') != -1:
val_set = set()
val_set = populate_set(constraint_line, val_set)
for val_line in lib_fp:
if val_line.find(");") != -1:
val_set = populate_set(val_line, val_set)
break
val_set = populate_set(val_line, val_set)
if type_str == "setup_rising":
a2f_data_max['setup_rising_fall_constraint'].add(
sorted(val_set).pop()
)
a2f_data_min['setup_rising_fall_constraint'].add(
next(iter(sorted(val_set)))
)
else:
a2f_data_max['hold_rising_fall_constraint'].add(
sorted(val_set).pop()
)
a2f_data_min['hold_rising_fall_constraint'].add(
next(iter(sorted(val_set)))
)
break
break
return a2f_data_max, a2f_data_min
# =============================================================================
def f2a_timing_type(lib_fp, pin_line, type_str, f2a_data_max, f2a_data_min):
"""
Collect F2A pin data
"""
type_pos = pin_line.find(type_str)
if type_pos != -1:
for type_line in lib_fp:
rise_pos = type_line.find("cell_rise")
if rise_pos != -1:
for constraint_line in lib_fp:
if constraint_line.find("}") != -1:
break
if constraint_line.find('values') != -1:
val_set = set()
val_set = populate_set(constraint_line, val_set)
for val_line in lib_fp:
if val_line.find(");") != -1:
val_set = populate_set(val_line, val_set)
break
val_set = populate_set(val_line, val_set)
f2a_data_max['rising_edge_cell_rise'].add(
sorted(val_set).pop()
)
f2a_data_min['rising_edge_cell_rise'].add(
next(iter(sorted(val_set)))
)
break
break
for type_line in lib_fp:
fall_pos = type_line.find("rise_transition")
if fall_pos != -1:
for constraint_line in lib_fp:
if constraint_line.find("}") != -1:
break
if constraint_line.find('values') != -1:
val_set = set()
val_set = populate_set(constraint_line, val_set)
for val_line in lib_fp:
if val_line.find(");") != -1:
val_set = populate_set(val_line, val_set)
break
val_set = populate_set(val_line, val_set)
f2a_data_max['rising_edge_rise_tran'].add(
sorted(val_set).pop()
)
f2a_data_min['rising_edge_rise_tran'].add(
next(iter(sorted(val_set)))
)
break
break
for type_line in lib_fp:
fall_pos = type_line.find("cell_fall")
if fall_pos != -1:
for constraint_line in lib_fp:
if constraint_line.find("}") != -1:
break
if constraint_line.find('values') != -1:
val_set = set()
val_set = populate_set(constraint_line, val_set)
for val_line in lib_fp:
if val_line.find(");") != -1:
val_set = populate_set(val_line, val_set)
break
val_set = populate_set(val_line, val_set)
f2a_data_max['rising_edge_cell_fall'].add(
sorted(val_set).pop()
)
f2a_data_min['rising_edge_cell_fall'].add(
next(iter(sorted(val_set)))
)
break
break
for type_line in lib_fp:
fall_pos = type_line.find("fall_transition")
if fall_pos != -1:
for constraint_line in lib_fp:
if constraint_line.find("}") != -1:
break
if constraint_line.find('values') != -1:
val_set = set()
val_set = populate_set(constraint_line, val_set)
for val_line in lib_fp:
if val_line.find(");") != -1:
val_set = populate_set(val_line, val_set)
break
val_set = populate_set(val_line, val_set)
f2a_data_max['rising_edge_fall_tran'].add(
sorted(val_set).pop()
)
f2a_data_min['rising_edge_fall_tran'].add(
next(iter(sorted(val_set)))
)
break
break
return f2a_data_max, f2a_data_min
# =============================================================================
def populate_set(line, val_set):
"""
Collects values and put it in a set
"""
pos = line.find("\"")
pos1 = line.rfind("\"")
sub = line[pos + 1:pos1]
val_list = sub.split(',')
for val in val_list:
val_set.add(float(val.strip()))
return val_set
# =============================================================================
if __name__ == '__main__':
main()