mirror of https://github.com/openXC7/prjxray.git
Merge pull request #1592 from antmicro/fix-iob-lvds-tmds
030-iob: improve rdb processing for LVDS and TMDS
This commit is contained in:
commit
6867429cc3
|
|
@ -64,33 +64,35 @@ def filter_bits(site, bits):
|
||||||
return frozenset(inner())
|
return frozenset(inner())
|
||||||
|
|
||||||
|
|
||||||
def process_features_sets(iostandard_lines, only_diff=False):
|
def process_features_sets(iostandard_lines):
|
||||||
sites = {}
|
sites = {}
|
||||||
|
|
||||||
for l in iostandard_lines:
|
for iostd_type, iostd_list in iostandard_lines.items():
|
||||||
feature = get_name(l)
|
for iostd_line in iostd_list:
|
||||||
feature_parts = feature.split('.')
|
feature = get_name(iostd_line)
|
||||||
site = get_site(l)
|
feature_parts = feature.split('.')
|
||||||
iostandard = feature_parts[2]
|
site = get_site(iostd_line)
|
||||||
|
iostandard = feature_parts[2]
|
||||||
|
|
||||||
bits = parse_bits(l)
|
bits = parse_bits(iostd_line)
|
||||||
bits = filter_bits(site, bits)
|
bits = filter_bits(site, bits)
|
||||||
|
|
||||||
if site not in sites:
|
key = (site, iostd_type)
|
||||||
sites[site] = {}
|
if key not in sites:
|
||||||
|
sites[key] = {}
|
||||||
|
|
||||||
group = feature_parts[3]
|
group = feature_parts[3]
|
||||||
if group not in sites[site]:
|
if group not in sites[key]:
|
||||||
sites[site][group] = {}
|
sites[key][group] = {}
|
||||||
|
|
||||||
if group in ['DRIVE', 'SLEW']:
|
if group in ['DRIVE', 'SLEW']:
|
||||||
enum = feature_parts[4]
|
enum = feature_parts[4]
|
||||||
sites[site][group][(iostandard, enum)] = bits
|
sites[key][group][(iostandard, enum)] = bits
|
||||||
elif group in ['IN', 'IN_DIFF', 'IN_ONLY', 'IN_USE', 'OUT', 'STEPDOWN',
|
elif group in ['IN', 'IN_DIFF', 'IN_ONLY', 'IN_USE', 'OUT',
|
||||||
'ZIBUF_LOW_PWR']:
|
'STEPDOWN', 'ZIBUF_LOW_PWR']:
|
||||||
sites[site][group][(iostandard, None)] = bits
|
sites[key][group][(iostandard, None)] = bits
|
||||||
else:
|
else:
|
||||||
assert False, group
|
assert False, group
|
||||||
|
|
||||||
for site in sites:
|
for site in sites:
|
||||||
for iostandard, enum in sites[site]['DRIVE']:
|
for iostandard, enum in sites[site]['DRIVE']:
|
||||||
|
|
@ -102,40 +104,41 @@ def process_features_sets(iostandard_lines, only_diff=False):
|
||||||
iostandard, enum)]
|
iostandard, enum)]
|
||||||
|
|
||||||
common_bits = {}
|
common_bits = {}
|
||||||
for site in sites:
|
for site, iostd_type in sites:
|
||||||
for group in sites[site]:
|
for group in sites[(site, iostd_type)]:
|
||||||
if (site, group) not in common_bits:
|
if (site, group) not in common_bits:
|
||||||
common_bits[(site, group)] = set()
|
common_bits[(site, group)] = set()
|
||||||
|
|
||||||
for bits in sites[site][group].values():
|
for bits in sites[(site, iostd_type)][group].values():
|
||||||
common_bits[(site, group)] |= bits
|
common_bits[(site, group)] |= bits
|
||||||
|
|
||||||
slew_in_drives = {}
|
slew_in_drives = {}
|
||||||
|
|
||||||
for site in sites:
|
for site, iostd_type in sites:
|
||||||
common_bits[(site, 'IN')] |= common_bits[(site, 'IN_DIFF')]
|
common_bits[(site, 'IN')] |= common_bits[(site, 'IN_DIFF')]
|
||||||
common_bits[(site, 'IN_DIFF')] |= common_bits[(site, 'IN')]
|
common_bits[(site, 'IN_DIFF')] |= common_bits[(site, 'IN')]
|
||||||
|
|
||||||
# Only DIFF IOSTANDARDS such as LVDS or TMDS do not have DRIVE,
|
# Only DIFF IOSTANDARDS such as LVDS or TMDS do not have DRIVE,
|
||||||
# STEPDOWN or SLEW features
|
# STEPDOWN or SLEW features
|
||||||
if not only_diff:
|
if iostd_type == "NORMAL":
|
||||||
|
key = (site, iostd_type)
|
||||||
common_bits[(site, 'DRIVE')] -= common_bits[(site, 'SLEW')]
|
common_bits[(site, 'DRIVE')] -= common_bits[(site, 'SLEW')]
|
||||||
common_bits[(site, 'DRIVE')] -= common_bits[(site, 'STEPDOWN')]
|
common_bits[(site, 'DRIVE')] -= common_bits[(site, 'STEPDOWN')]
|
||||||
common_bits[(site, 'IN_ONLY')] |= common_bits[(site, 'DRIVE')]
|
common_bits[(site, 'IN_ONLY')] |= common_bits[(site, 'DRIVE')]
|
||||||
common_bits[(site, 'IN_ONLY')] -= common_bits[(site, 'STEPDOWN')]
|
common_bits[(site, 'IN_ONLY')] -= common_bits[(site, 'STEPDOWN')]
|
||||||
|
|
||||||
for iostandard, enum in sites[site]['DRIVE']:
|
for iostandard, enum in sites[key]['DRIVE']:
|
||||||
slew_in_drive = common_bits[
|
slew_in_drive = common_bits[
|
||||||
(site, 'SLEW')] & sites[site]['DRIVE'][(iostandard, enum)]
|
(site, 'SLEW')] & sites[key]['DRIVE'][(iostandard, enum)]
|
||||||
if slew_in_drive:
|
if slew_in_drive:
|
||||||
if (site, iostandard) not in slew_in_drives:
|
if (key, iostandard) not in slew_in_drives:
|
||||||
slew_in_drives[(site, iostandard)] = set()
|
slew_in_drives[(key, iostandard)] = set()
|
||||||
|
|
||||||
slew_in_drives[(site, iostandard)] |= slew_in_drive
|
slew_in_drives[(key, iostandard)] |= slew_in_drive
|
||||||
sites[site]['DRIVE'][(iostandard, enum)] -= slew_in_drive
|
sites[key]['DRIVE'][(iostandard, enum)] -= slew_in_drive
|
||||||
|
|
||||||
sites[site]['DRIVE'][(iostandard,
|
sites[key]['DRIVE'][(iostandard,
|
||||||
enum)] -= common_bits[(site, 'STEPDOWN')]
|
enum)] -= common_bits[(site, 'STEPDOWN')]
|
||||||
|
|
||||||
for site, iostandard in slew_in_drives:
|
for site, iostandard in slew_in_drives:
|
||||||
for _, enum in sites[site]['SLEW']:
|
for _, enum in sites[site]['SLEW']:
|
||||||
|
|
@ -148,20 +151,30 @@ def process_features_sets(iostandard_lines, only_diff=False):
|
||||||
iostandard, None)]
|
iostandard, None)]
|
||||||
|
|
||||||
for iostandard, enum in sites[site]['IN']:
|
for iostandard, enum in sites[site]['IN']:
|
||||||
if sites[site]['IN_DIFF'][(iostandard, enum)]:
|
_, iostd_type = site
|
||||||
|
if iostd_type == "ONLY_DIFF":
|
||||||
|
sites[site]['IN_DIFF'][(iostandard, enum)] = \
|
||||||
|
sites[site]['IN'][(iostandard, enum)]
|
||||||
|
elif sites[site]['IN_DIFF'][(iostandard, enum)]:
|
||||||
sites[site]['IN_DIFF'][(iostandard, enum)] |= \
|
sites[site]['IN_DIFF'][(iostandard, enum)] |= \
|
||||||
sites[site]['IN'][(iostandard, enum)]
|
sites[site]['IN'][(iostandard, enum)]
|
||||||
|
|
||||||
if not only_diff:
|
for site, iostd_type in sites:
|
||||||
for site in sites:
|
del sites[(site, iostd_type)]['IN_USE']
|
||||||
del sites[site]['OUT']
|
if iostd_type == "NORMAL":
|
||||||
del sites[site]['IN_USE']
|
del sites[(site, iostd_type)]['OUT']
|
||||||
|
|
||||||
allow_zero = ['SLEW']
|
allow_zero = ['SLEW']
|
||||||
|
|
||||||
for site in sites:
|
common_groups = dict()
|
||||||
for group in sites[site]:
|
for site, iostd_type in sites:
|
||||||
common_groups = {}
|
if site not in common_groups:
|
||||||
|
common_groups[site] = dict()
|
||||||
|
|
||||||
|
key = (site, iostd_type)
|
||||||
|
for group in sites[key]:
|
||||||
|
if iostd_type == "ONLY_DIFF" and group == "IN":
|
||||||
|
continue
|
||||||
|
|
||||||
# Merge features that are identical.
|
# Merge features that are identical.
|
||||||
#
|
#
|
||||||
|
|
@ -171,40 +184,40 @@ def process_features_sets(iostandard_lines, only_diff=False):
|
||||||
# IOB33.IOB_Y1.LVCMOS18.IN 38_42 39_41
|
# IOB33.IOB_Y1.LVCMOS18.IN 38_42 39_41
|
||||||
#
|
#
|
||||||
# Must be grouped.
|
# Must be grouped.
|
||||||
for (iostandard, enum), bits in sites[site][group].items():
|
for (iostandard, enum), bits in sites[key][group].items():
|
||||||
if bits not in common_groups:
|
if (bits, group) not in common_groups[site]:
|
||||||
common_groups[bits] = {
|
common_groups[site][(bits, group)] = {
|
||||||
'IOSTANDARDS': set(),
|
'IOSTANDARDS': set(),
|
||||||
'enums': set(),
|
'enums': set(),
|
||||||
}
|
}
|
||||||
|
|
||||||
common_groups[bits]['IOSTANDARDS'].add(iostandard)
|
common_groups[site][(bits,
|
||||||
|
group)]['IOSTANDARDS'].add(iostandard)
|
||||||
if enum is not None:
|
if enum is not None:
|
||||||
common_groups[bits]['enums'].add(enum)
|
common_groups[site][(bits, group)]['enums'].add(enum)
|
||||||
|
|
||||||
for bits, v in common_groups.items():
|
for site, groups in common_groups.items():
|
||||||
if v['enums']:
|
for (bits, group), v in groups.items():
|
||||||
feature = 'IOB33.{site}.{iostandards}.{group}.{enums}'.format(
|
if v['enums']:
|
||||||
site=site,
|
feature = 'IOB33.{site}.{iostandards}.{group}.{enums}'.format(
|
||||||
iostandards='_'.join(sorted(v['IOSTANDARDS'])),
|
site=site,
|
||||||
group=group,
|
iostandards='_'.join(sorted(v['IOSTANDARDS'])),
|
||||||
enums='_'.join(sorted(v['enums'])),
|
group=group,
|
||||||
)
|
enums='_'.join(sorted(v['enums'])),
|
||||||
else:
|
)
|
||||||
feature = 'IOB33.{site}.{iostandards}.{group}'.format(
|
else:
|
||||||
site=site,
|
feature = 'IOB33.{site}.{iostandards}.{group}'.format(
|
||||||
iostandards='_'.join(sorted(v['IOSTANDARDS'])),
|
site=site,
|
||||||
group=group,
|
iostandards='_'.join(sorted(v['IOSTANDARDS'])),
|
||||||
)
|
group=group,
|
||||||
|
)
|
||||||
|
|
||||||
if not bits and group not in allow_zero:
|
if not bits and group not in allow_zero:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
neg_bits = frozenset(
|
neg_bits = frozenset(
|
||||||
'!{}'.format(b)
|
'!{}'.format(b) for b in (common_bits[(site, group)] - bits))
|
||||||
for b in (common_bits[(site, group)] - bits))
|
print('{} {}'.format(feature, ' '.join(sorted(bits | neg_bits))))
|
||||||
print(
|
|
||||||
'{} {}'.format(feature, ' '.join(sorted(bits | neg_bits))))
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
@ -215,20 +228,22 @@ def main():
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
iostandard_lines = []
|
iostandard_lines = {
|
||||||
iostandard_lines_only_diff = []
|
"NORMAL": list(),
|
||||||
|
"ONLY_DIFF": list(),
|
||||||
|
}
|
||||||
|
|
||||||
with open(args.input_rdb) as f:
|
with open(args.input_rdb) as f:
|
||||||
for l in f:
|
for l in f:
|
||||||
if ('.SSTL' in l or '.LVCMOS' in l
|
if ('.SSTL' in l or '.LVCMOS' in l
|
||||||
or '.LVTTL' in l) and 'IOB_' in l:
|
or '.LVTTL' in l) and 'IOB_' in l:
|
||||||
iostandard_lines.append(l)
|
iostandard_lines["NORMAL"].append(l)
|
||||||
elif ('.TMDS' in l or 'LVDS' in l):
|
elif ('.TMDS' in l or 'LVDS' in l):
|
||||||
iostandard_lines_only_diff.append(l)
|
iostandard_lines["ONLY_DIFF"].append(l)
|
||||||
else:
|
else:
|
||||||
print(l.strip())
|
print(l.strip())
|
||||||
|
|
||||||
process_features_sets(iostandard_lines)
|
process_features_sets(iostandard_lines)
|
||||||
process_features_sets(iostandard_lines_only_diff, True)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue