Refactor remaining function in tim2json.py

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
Keith Rothman 2020-02-11 20:28:52 -08:00
parent e17f9e8140
commit 564863ccad
1 changed files with 241 additions and 248 deletions

View File

@ -125,7 +125,7 @@ def instance_in_model(instance, model):
return instance in model return instance in model
def create_pin_in_model(pin_aliases, model): def create_pin_in_model(pin_aliases):
""" """
Checks if a given pin belongs to the model. Checks if a given pin belongs to the model.
@ -169,11 +169,11 @@ def create_pin_in_model(pin_aliases, model):
(True, 'o') (True, 'o')
""" """
@functools.lru_cache(maxsize=10000)
def pin_in_model(pin, model, direction=None):
# strip site location # strip site location
model = model.split(':')[0] model = model.split(':')[0]
@functools.lru_cache(maxsize=10000)
def pin_in_model(pin, direction=None):
extended_pin_name = pin extended_pin_name = pin
aliased_pin, aliased_pin_name = find_aliased_pin( aliased_pin, aliased_pin_name = find_aliased_pin(
pin.upper(), model, pin_aliases) pin.upper(), model, pin_aliases)
@ -301,39 +301,54 @@ def extract_properties(tile, site, bel, properties, model):
return model_properties return model_properties
def read_raw_timings(fin, properties, pins, site_pins, pin_alias_map): def parse_raw_timing(fin):
timings = dict()
with open(fin, "r") as f: with open(fin, "r") as f:
for line in f: for line in f:
raw_data = line.split() raw_data = line.split()
slice = raw_data[0] slice = raw_data[0]
#XXX: debug
if slice.startswith('DSP'):
continue
sites_count = int(raw_data[1]) sites_count = int(raw_data[1])
loc = 2 loc = 2
for site in range(0, sites_count): for site in range(0, sites_count):
site_name = raw_data[loc] site_name = raw_data[loc]
bels_count = int(raw_data[loc + 1]) bels_count = int(raw_data[loc + 1])
print(slice, site_name)
# read all BELs data within # read all BELs data within
loc += 2 loc += 2
for bel in range(0, bels_count): for bel in range(0, bels_count):
btype = (raw_data[loc]).lower() bel = raw_data[loc]
delay_count = int(raw_data[loc + 1]) delay_count = int(raw_data[loc + 1])
# get all the delays # get all the delays
loc += 2 loc += 2
for delay in range(0, delay_count): for delay in range(0, delay_count):
speed_model = raw_data[loc] speed_model = raw_data[loc]
# each timing entry reports 5 delays
timing = [
raw_data[d + 1 + loc].split(':')
for d in range(0, 5)
]
yield slice, site_name, bel, speed_model, timing
# 5 delay values + name
loc += 6
def read_raw_timings(fin, properties, pins, site_pins, pin_alias_map):
def inner():
raw = list(parse_raw_timing(fin))
pin_in_models = {}
for slice, site_name, bel, speed_model, timing in progressbar.progressbar(
raw):
btype = bel.lower()
delay_btype = clean_bname(btype) delay_btype = clean_bname(btype)
delay_btype_orig = delay_btype delay_btype_orig = delay_btype
# all the bel names seem to start with "bel_d_" # all the bel names seem to start with "bel_d_"
# let's get rid of it # let's get rid of it
if speed_model.startswith('bel_d_'): if speed_model.startswith('bel_d_'):
@ -381,25 +396,28 @@ def read_raw_timings(fin, properties, pins, site_pins, pin_alias_map):
prop_string.lower(), speed_model_clean) prop_string.lower(), speed_model_clean)
# Get pin alias map # Get pin alias map
if delay_btype not in pin_in_models:
pin_aliases = pin_alias_map.get(delay_btype, None) pin_aliases = pin_alias_map.get(delay_btype, None)
pin_in_models[delay_btype] = create_pin_in_model(
pin_aliases)
pin_in_model = pin_in_models[delay_btype]
# locate pins # locate pins
for pin in pins[slice][site_name][delay_btype_orig]: for pin in pins[slice][site_name][delay_btype_orig]:
orig_pin = pin orig_pin = pin
pim, pin = pin_in_model( pim, pin = pin_in_model(pin.lower(), speed_model_clean, 'in')
pin.lower(), pin_aliases, speed_model_clean,
'in')
if pim: if pim:
if pins[slice][site_name][delay_btype_orig][ if pins[slice][site_name][delay_btype_orig][orig_pin][
orig_pin]['is_clock']: 'is_clock']:
bel_clock = pin bel_clock = pin
bel_clock_orig_pin = orig_pin bel_clock_orig_pin = orig_pin
elif pins[slice][site_name][delay_btype_orig][ elif pins[slice][site_name][delay_btype_orig][orig_pin][
orig_pin]['direction'] == 'IN': 'direction'] == 'IN':
bel_input = pin bel_input = pin
elif pins[slice][site_name][delay_btype_orig][ elif pins[slice][site_name][delay_btype_orig][orig_pin][
orig_pin]['direction'] == 'OUT': 'direction'] == 'OUT':
bel_output = pin bel_output = pin
speed_model_clean = remove_pin_from_model( speed_model_clean = remove_pin_from_model(
pin.lower(), speed_model_clean) pin.lower(), speed_model_clean)
@ -408,12 +426,10 @@ def read_raw_timings(fin, properties, pins, site_pins, pin_alias_map):
if bel_clock is None: if bel_clock is None:
for pin in site_pins[slice][site_name.lower()]: for pin in site_pins[slice][site_name.lower()]:
orig_pin = pin orig_pin = pin
pim, pin = pin_in_model( pim, pin = pin_in_model(pin.lower(), speed_model_clean)
pin.lower(), pin_aliases,
speed_model_clean)
if pim: if pim:
if site_pins[slice][site_name.lower( if site_pins[slice][site_name.
)][orig_pin]['is_clock']: lower()][orig_pin]['is_clock']:
bel_clock = pin bel_clock = pin
bel_clock_orig_pin = orig_pin bel_clock_orig_pin = orig_pin
speed_model_clean = remove_pin_from_model( speed_model_clean = remove_pin_from_model(
@ -423,9 +439,7 @@ def read_raw_timings(fin, properties, pins, site_pins, pin_alias_map):
# search site inputs # search site inputs
for pin in site_pins[slice][site_name.lower()]: for pin in site_pins[slice][site_name.lower()]:
orig_pin = pin orig_pin = pin
pim, pin = pin_in_model( pim, pin = pin_in_model(pin.lower(), speed_model_clean, 'in')
pin.lower(), pin_aliases,
speed_model_clean, 'in')
if pim: if pim:
if site_pins[slice][site_name.lower( if site_pins[slice][site_name.lower(
)][orig_pin]['direction'] == 'IN': )][orig_pin]['direction'] == 'IN':
@ -436,9 +450,7 @@ def read_raw_timings(fin, properties, pins, site_pins, pin_alias_map):
if bel_output is None: if bel_output is None:
for pin in site_pins[slice][site_name.lower()]: for pin in site_pins[slice][site_name.lower()]:
orig_pin = pin orig_pin = pin
pim, pin = pin_in_model( pim, pin = pin_in_model(pin.lower(), speed_model_clean)
pin.lower(), pin_aliases,
speed_model_clean)
if pim: if pim:
if site_pins[slice][site_name.lower( if site_pins[slice][site_name.lower(
)][orig_pin]['direction'] == 'OUT': )][orig_pin]['direction'] == 'OUT':
@ -448,8 +460,8 @@ def read_raw_timings(fin, properties, pins, site_pins, pin_alias_map):
# if we couldn't find input, check if the clock is the # if we couldn't find input, check if the clock is the
# only input. This applies only to combinational paths # only input. This applies only to combinational paths
if (sequential is None) and (bel_input is None) and ( if (sequential is None) and (bel_input is None) and (bel_clock is
bel_clock is not None): not None):
if bel_clock_orig_pin in site_pins[slice][site_name.lower()] and \ if bel_clock_orig_pin in site_pins[slice][site_name.lower()] and \
site_pins[slice][site_name.lower( site_pins[slice][site_name.lower(
)][bel_clock_orig_pin]['direction'] == 'IN': )][bel_clock_orig_pin]['direction'] == 'IN':
@ -458,26 +470,18 @@ def read_raw_timings(fin, properties, pins, site_pins, pin_alias_map):
# if we still don't have the input check if the input # if we still don't have the input check if the input
# is wider than 1 bit and timing defined for the whole # is wider than 1 bit and timing defined for the whole
# port # port
import re
if (bel_input is None) or (bel_output is None): if (bel_input is None) or (bel_output is None):
for pin in pins[slice][site_name][ for pin in pins[slice][site_name][delay_btype_orig]:
delay_btype_orig]: number = NUMBER_RE.search(pin)
number = re.search(r'\d+$', pin)
if number is not None: if number is not None:
orig_pin = pin[:-( orig_pin = pin[:-(len(str(number.group())))]
len(str(number.group())))]
orig_pin_full = pin orig_pin_full = pin
pim, pin = pin_in_model( pim, pin = pin_in_model(orig_pin.lower(), speed_model_clean)
orig_pin.lower(), pin_aliases,
speed_model_clean)
if not pim: if not pim:
# some inputs pins are named with unsignificant zeros # some inputs pins are named with unsignificant zeros
# remove ti and try again # remove ti and try again
orig_pin = orig_pin + str( orig_pin = orig_pin + str(int(number.group()))
int(number.group())) pim, pin = pin_in_model(orig_pin.lower(), speed_model_clean)
pim, pin = pin_in_model(
orig_pin.lower(), pin_aliases,
speed_model_clean)
if pim: if pim:
if pins[slice][site_name][delay_btype_orig][orig_pin_full]['direction'] == 'IN' \ if pins[slice][site_name][delay_btype_orig][orig_pin_full]['direction'] == 'IN' \
@ -487,89 +491,78 @@ def read_raw_timings(fin, properties, pins, site_pins, pin_alias_map):
and bel_output is None: and bel_output is None:
bel_output = pin bel_output = pin
speed_model_clean = remove_pin_from_model( speed_model_clean = remove_pin_from_model(
orig_pin.lower(), orig_pin.lower(), speed_model_clean)
speed_model_clean)
# check if the input is not a BEL property # check if the input is not a BEL property
if bel_input is None: if bel_input is None:
# if there is anything not yet decoded # if there is anything not yet decoded
if len(speed_model_clean.split("_")) > 1: if len(speed_model_clean.split("_")) > 1:
if len(speed_model_properties.keys()) == 1: if len(speed_model_properties.keys()) == 1:
bel_input = list( bel_input = list(speed_model_properties.keys())[0]
speed_model_properties.keys())[0]
# if we still don't have input, give up # if we still don't have input, give up
if bel_input is None: if bel_input is None:
loc += 6
continue continue
# restore speed model name # restore speed model name
speed_model = delay_btype + speed_model_clean speed_model = delay_btype + speed_model_clean
if sequential is not None: if sequential is not None:
if bel_clock is None:
continue
if bel_output is None and bel_clock is None or \ if bel_output is None and bel_clock is None or \
bel_output is None and bel_clock == bel_input: bel_output is None and bel_clock == bel_input:
loc += 6
continue continue
else: else:
if bel_input is None or bel_output is None: if bel_input is None or bel_output is None:
loc += 6
continue continue
delay_btype = speed_model delay_btype = speed_model
# add properties to the delay_btype # add properties to the delay_btype
if speed_model_properties is not None:
for prop in sorted(speed_model_properties): for prop in sorted(speed_model_properties):
prop_string = "_".join( prop_string = "_".join(
[prop, speed_model_properties[prop]]) [prop, speed_model_properties[prop]])
delay_btype += "_" + prop_string delay_btype += "_" + prop_string
extra_ports = None
if slice not in timings: yield (slice, bel_location, delay_btype, speed_model_orig,
timings[slice] = dict() 'type'), btype.upper()
yield (
if bel_location not in timings[slice]: slice, bel_location, delay_btype, speed_model_orig,
timings[slice][bel_location] = dict() 'input'), bel_input.upper()
if delay_btype not in timings[slice][bel_location]:
timings[slice][bel_location][delay_btype] = dict()
timings[slice][bel_location][delay_btype][
speed_model_orig] = dict()
timings[slice][bel_location][delay_btype][
speed_model_orig]['type'] = btype.upper()
timings[slice][bel_location][delay_btype][
speed_model_orig]['input'] = bel_input.upper()
if bel_output is not None: if bel_output is not None:
timings[slice][bel_location][delay_btype][ yield (
speed_model_orig]['output'] = bel_output.upper( slice, bel_location, delay_btype, speed_model_orig,
) 'output'), bel_output.upper()
if bel_clock is not None: if bel_clock is not None:
timings[slice][bel_location][delay_btype][ yield (
speed_model_orig]['clock'] = bel_clock.upper() slice, bel_location, delay_btype, speed_model_orig,
timings[slice][bel_location][delay_btype][ 'clock'), bel_clock.upper()
speed_model_orig]['location'] = bel_location.upper(
) yield (
slice, bel_location, delay_btype, speed_model_orig,
'location'), bel_location.upper()
#XXX: debug #XXX: debug
timings[slice][bel_location][delay_btype][ yield (
speed_model_orig]['model'] = speed_model_orig slice, bel_location, delay_btype, speed_model_orig,
'model'), speed_model_orig
if sequential is not None: if sequential is not None:
timings[slice][bel_location][delay_btype][ assert bel_clock is not None, (
speed_model_orig]['sequential'] = sequential[1] slice, bel_location, delay_btype, speed_model_orig)
if extra_ports is not None: yield (
timings[slice][bel_location][delay_btype][ slice, bel_location, delay_btype, speed_model_orig,
speed_model_orig]['extra_ports'] = extra_ports 'sequential'), sequential[1]
# each timing entry reports 5 delays for t, v in timing:
for d in range(0, 5): yield (
(t, v) = raw_data[d + 1 + loc].split(':') slice, bel_location, delay_btype, speed_model_orig, t), v
timings[slice][bel_location][delay_btype][
speed_model_orig][t] = v
# 5 delay values + name return merged_dict(inner())
loc += 6
return timings
def read_bel_properties(properties_file, properties_map): def read_bel_properties(properties_file, properties_map):