diff --git a/fuzzers/030-iob/Makefile b/fuzzers/030-iob/Makefile index 851673b6..a104b366 100644 --- a/fuzzers/030-iob/Makefile +++ b/fuzzers/030-iob/Makefile @@ -24,7 +24,7 @@ build/segbits_xiob33.db: build/segbits_xiob33.rdb process_rdb.py bits.dbf ${XRAY_MASKMERGE} build/mask_xiob33.db $$(find -name segdata_liob33.txt) $$(find -name segdata_riob33.txt) build/segbits_hclk_ioi3.rdb: $(SPECIMENS_OK) - ${XRAY_SEGMATCH} -c 4 -o build/segbits_hclk_ioi3.rdb $$(find -name segdata_hclk_ioi3.txt) + ${XRAY_SEGMATCH} -c 10 -o build/segbits_hclk_ioi3.rdb $$(find -name segdata_hclk_ioi3.txt) build/segbits_hclk_ioi3.db: build/segbits_hclk_ioi3.rdb ${XRAY_DBFIXUP} --db-root build --zero-db hclk_bits.dbf --seg-fn-in build/segbits_hclk_ioi3.rdb --seg-fn-out $@ diff --git a/fuzzers/030-iob/generate.py b/fuzzers/030-iob/generate.py index 230adac7..bc642d66 100644 --- a/fuzzers/030-iob/generate.py +++ b/fuzzers/030-iob/generate.py @@ -46,7 +46,9 @@ def drives_for_iostandard(iostandard): STEPDOWN_IOSTANDARDS = [ 'LVCMOS12', 'LVCMOS15', 'LVCMOS18', 'SSTL135', 'SSTL15' ] -IBUF_LOW_PWR_SUPPORTED = ['SSTL135', 'SSTL15'] +IBUF_LOW_PWR_SUPPORTED = ['SSTL135', 'SSTL15', 'LVDS_25', 'TMDS_33'] + +ONLY_DIFF_IOSTANDARDS = ['LVDS_25', 'TMDS_33'] def main(): @@ -95,8 +97,9 @@ def main(): for d in design['tiles']: site = d['site'] + tile = d['tile'] - if d['tile'] in pudc_tiles: + if tile in pudc_tiles: continue if site in diff_pairs: @@ -119,6 +122,8 @@ def main(): 'UNTUNED_SPLIT_60' ], 'NONE', d['IN_TERM']) + only_diff_io = iostandard in ONLY_DIFF_IOSTANDARDS + if d['type'] is None: segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 0) @@ -148,6 +153,12 @@ def main(): segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 0) segmk.add_site_tag(site, '{}.IN_ONLY'.format(iostandard), 1) segmk.add_tile_tag(d['tile'], 'IN_DIFF', 1) + + if iostandard in IBUF_LOW_PWR_SUPPORTED: + segmk.add_tile_tag( + tile, 'DIFF.IBUF_LOW_PWR', d['IBUF_LOW_PWR']) + segmk.add_tile_tag( + tile, 'DIFF.ZIBUF_LOW_PWR', 1 ^ d['IBUF_LOW_PWR']) elif d['type'] == 'OBUF': segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) @@ -159,15 +170,18 @@ def main(): segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) segmk.add_site_tag(site, '{}.IN'.format(iostandard), 0) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 1) - segmk.add_tile_tag(d['tile'], 'OUT_DIFF', 1) + segmk.add_tile_tag( + d['tile'], 'OUT_DIFF', 1 and not only_diff_io) segmk.add_tile_tag(d['tile'], 'OUT_TDIFF', 0) elif d['type'] == 'OBUFTDS': segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) segmk.add_site_tag(site, '{}.IN'.format(iostandard), 0) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 1) - segmk.add_tile_tag(d['tile'], 'OUT_DIFF', 1) - segmk.add_tile_tag(d['tile'], 'OUT_TDIFF', 1) + segmk.add_tile_tag( + d['tile'], 'OUT_DIFF', 1 and not only_diff_io) + segmk.add_tile_tag( + d['tile'], 'OUT_TDIFF', 1 and not only_diff_io) elif d['type'] == 'IOBUF_INTERMDISABLE': segmk.add_site_tag(site, 'INOUT', 1) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) @@ -197,15 +211,18 @@ def main(): drive_opts.add(mk_drive_opt("SSTL135", None)) drive_opts.add(mk_drive_opt("SSTL15", None)) + drive_opts.add(mk_drive_opt("LVDS_25", None)) + drive_opts.add(mk_drive_opt("TMDS_33", None)) segmaker.add_site_group_zero( segmk, site, '', drive_opts, mk_drive_opt('LVCMOS25', '12'), mk_drive_opt(iostandard, d['DRIVE'])) - for opt in ["SLOW", "FAST"]: - segmk.add_site_tag( - site, iostandard + ".SLEW." + opt, opt == verilog.unquote( - d['SLEW'])) + if d['SLEW']: + for opt in ["SLOW", "FAST"]: + segmk.add_site_tag( + site, iostandard + ".SLEW." + opt, + opt == verilog.unquote(d['SLEW'])) if 'ibufdisable_wire' in d: segmk.add_site_tag( @@ -278,6 +295,15 @@ def main(): segmk.add_tile_tag( hclk_cmt_tile, 'STEPDOWN', iostandard in STEPDOWN_IOSTANDARDS) + for only_diff_io in ONLY_DIFF_IOSTANDARDS: + segmk.add_tile_tag( + hclk_cmt_tile, '{}_IN_USE'.format(only_diff_io), + iostandard == only_diff_io) + + segmk.add_tile_tag( + hclk_cmt_tile, 'ONLY_DIFF_IN_USE', + iostandard in ONLY_DIFF_IOSTANDARDS) + # For IOBANK's with no active VREF, clear all VREF options. for cmt, (_, hclk_cmt_tile) in cmt_to_idelay.items(): if cmt in cmt_vref_active: diff --git a/fuzzers/030-iob/process_rdb.py b/fuzzers/030-iob/process_rdb.py index 37832db1..b1842093 100644 --- a/fuzzers/030-iob/process_rdb.py +++ b/fuzzers/030-iob/process_rdb.py @@ -30,7 +30,7 @@ def get_site(l): def parse_bits(l): parts = l.strip().split(' ') - if parts[1] in ['<0', '']: + if parts[1] in ['<0', '', '']: return frozenset() else: return frozenset(parts[1:]) @@ -64,23 +64,7 @@ def filter_bits(site, bits): return frozenset(inner()) -def main(): - parser = argparse.ArgumentParser( - description="Convert IOB rdb into good rdb." - "") - parser.add_argument('input_rdb') - - args = parser.parse_args() - - iostandard_lines = [] - with open(args.input_rdb) as f: - for l in f: - if ('.SSTL' in l or '.LVCMOS' in l - or '.LVTTL' in l) and 'IOB_' in l: - iostandard_lines.append(l) - else: - print(l.strip()) - +def process_features_sets(iostandard_lines, only_diff=False): sites = {} for l in iostandard_lines: @@ -102,8 +86,8 @@ def main(): if group in ['DRIVE', 'SLEW']: enum = feature_parts[4] sites[site][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', 'STEPDOWN', + 'ZIBUF_LOW_PWR']: sites[site][group][(iostandard, None)] = bits else: assert False, group @@ -129,26 +113,29 @@ def main(): slew_in_drives = {} for site in sites: - common_bits[(site, 'DRIVE')] -= common_bits[(site, 'SLEW')] - 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, 'STEPDOWN')] - common_bits[(site, 'IN')] |= common_bits[(site, 'IN_DIFF')] common_bits[(site, 'IN_DIFF')] |= common_bits[(site, 'IN')] - for iostandard, enum in sites[site]['DRIVE']: - slew_in_drive = common_bits[ - (site, 'SLEW')] & sites[site]['DRIVE'][(iostandard, enum)] - if slew_in_drive: - if (site, iostandard) not in slew_in_drives: - slew_in_drives[(site, iostandard)] = set() + # Only DIFF IOSTANDARDS such as LVDS or TMDS do not have DRIVE, + # STEPDOWN or SLEW features + if not only_diff: + common_bits[(site, 'DRIVE')] -= common_bits[(site, 'SLEW')] + 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, 'STEPDOWN')] - slew_in_drives[(site, iostandard)] |= slew_in_drive - sites[site]['DRIVE'][(iostandard, enum)] -= slew_in_drive + for iostandard, enum in sites[site]['DRIVE']: + slew_in_drive = common_bits[ + (site, 'SLEW')] & sites[site]['DRIVE'][(iostandard, enum)] + if slew_in_drive: + if (site, iostandard) not in slew_in_drives: + slew_in_drives[(site, iostandard)] = set() - sites[site]['DRIVE'][(iostandard, - enum)] -= common_bits[(site, 'STEPDOWN')] + slew_in_drives[(site, iostandard)] |= slew_in_drive + sites[site]['DRIVE'][(iostandard, enum)] -= slew_in_drive + + sites[site]['DRIVE'][(iostandard, + enum)] -= common_bits[(site, 'STEPDOWN')] for site, iostandard in slew_in_drives: for _, enum in sites[site]['SLEW']: @@ -165,9 +152,10 @@ def main(): sites[site]['IN_DIFF'][(iostandard, enum)] |= \ sites[site]['IN'][(iostandard, enum)] - for site in sites: - del sites[site]['OUT'] - del sites[site]['IN_USE'] + if not only_diff: + for site in sites: + del sites[site]['OUT'] + del sites[site]['IN_USE'] allow_zero = ['SLEW'] @@ -219,5 +207,29 @@ def main(): '{} {}'.format(feature, ' '.join(sorted(bits | neg_bits)))) +def main(): + parser = argparse.ArgumentParser( + description="Convert IOB rdb into good rdb." + "") + parser.add_argument('input_rdb') + + args = parser.parse_args() + + iostandard_lines = [] + iostandard_lines_only_diff = [] + with open(args.input_rdb) as f: + for l in f: + if ('.SSTL' in l or '.LVCMOS' in l + or '.LVTTL' in l) and 'IOB_' in l: + iostandard_lines.append(l) + elif ('.TMDS' in l or 'LVDS' in l): + iostandard_lines_only_diff.append(l) + else: + print(l.strip()) + + process_features_sets(iostandard_lines) + process_features_sets(iostandard_lines_only_diff, True) + + if __name__ == "__main__": main() diff --git a/fuzzers/030-iob/top.py b/fuzzers/030-iob/top.py index 5ef2701a..36cb9472 100644 --- a/fuzzers/030-iob/top.py +++ b/fuzzers/030-iob/top.py @@ -65,6 +65,8 @@ def run(): 'LVTTL', 'SSTL135', 'SSTL15', + 'LVDS_25', + 'TMDS_33', ] diff_map = { @@ -72,6 +74,11 @@ def run(): "SSTL15": ["DIFF_SSTL15"], } + only_diff_map = { + "LVDS_25": ["LVDS_25"], + "TMDS_33": ["TMDS_33"], + } + IN_TERM_ALLOWED = [ 'SSTL15', 'SSTL15_R', @@ -85,17 +92,6 @@ def run(): 'HSTL_II_18', ] - iostandard = random.choice(iostandards) - - if iostandard in ['LVTTL', 'LVCMOS18']: - drives = [4, 8, 12, 16, 24] - elif iostandard in ['LVCMOS12']: - drives = [4, 8, 12] - elif iostandard in ['SSTL135', 'SSTL15']: - drives = None - else: - drives = [4, 8, 12, 16] - slews = ['FAST', 'SLOW'] pulls = ["NONE", "KEEPER", "PULLDOWN", "PULLUP"] @@ -151,7 +147,7 @@ def run(): drives = [4, 8, 12, 16, 24] elif iostandard in ['LVCMOS12']: drives = [4, 8, 12] - elif iostandard in ['SSTL135', 'SSTL15', 'LVDS', 'LVDS_25']: + elif iostandard in ['SSTL135', 'SSTL15', 'LVDS_25', 'TMDS_33']: drives = None else: drives = [4, 8, 12, 16] @@ -160,6 +156,9 @@ def run(): if iostandard in diff_map: site_bels[site_type] = random.choice( tile_types + ['IBUFDS', 'OBUFDS', 'OBUFTDS']) + elif iostandard in only_diff_map: + site_bels[site_type] = random.choice( + ['IBUFDS', 'OBUFDS', 'OBUFTDS', None, None]) else: site_bels[site_type] = random.choice(tile_types) is_m_diff = site_bels[site_type] is not None and site_bels[ @@ -167,7 +166,7 @@ def run(): else: site_bels[site_type] = random.choice(tile_types) - if is_m_diff: + if is_m_diff or iostandard in only_diff_map: site_bels['IOB33S'] = None for site_type, site in sites.items(): @@ -177,7 +176,10 @@ def run(): p['type'] = site_bels[site_type] if p['type'] is not None and p['type'].endswith('DS'): - iostandard_site = random.choice(diff_map[iostandard]) + if iostandard in diff_map: + iostandard_site = random.choice(diff_map[iostandard]) + elif iostandard in only_diff_map: + iostandard_site = random.choice(only_diff_map[iostandard]) p['pair_site'] = sites['IOB33S'] else: iostandard_site = iostandard @@ -285,6 +287,13 @@ def run(): else: p['DRIVE_STR'] = '' + if 'SLEW' in p: + p['SLEW_STR'] = '' + if iostandard in only_diff_map: + p['SLEW'] = None + elif p['DRIVE'] is not None: + p['SLEW_STR'] = '.SLEW({}),'.format(p['SLEW']) + if p['type'] is not None: tile_params.append( ( @@ -380,9 +389,9 @@ module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do, inout wire [`N ''' (* KEEP, DONT_TOUCH *) OBUF #( - .IOSTANDARD({IOSTANDARD}), {DRIVE_STR} - .SLEW({SLEW}) + {SLEW_STR} + .IOSTANDARD({IOSTANDARD}) ) obuf_{site} ( .O({pad_wire}), .I({iwire}) @@ -393,9 +402,9 @@ module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do, inout wire [`N ''' (* KEEP, DONT_TOUCH *) OBUFDS #( - .IOSTANDARD({IOSTANDARD}), {DRIVE_STR} - .SLEW({SLEW}) + {SLEW_STR} + .IOSTANDARD({IOSTANDARD}) ) obufds_{site} ( .O({pad_wire}), .OB({bpad_wire}), @@ -407,9 +416,9 @@ module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do, inout wire [`N ''' (* KEEP, DONT_TOUCH *) OBUFTDS #( - .IOSTANDARD({IOSTANDARD}), {DRIVE_STR} - .SLEW({SLEW}) + {SLEW_STR} + .IOSTANDARD({IOSTANDARD}) ) obufds_{site} ( .O({pad_wire}), .OB({bpad_wire}), @@ -422,9 +431,9 @@ module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do, inout wire [`N ''' (* KEEP, DONT_TOUCH *) IOBUF_INTERMDISABLE #( - .IOSTANDARD({IOSTANDARD}), {DRIVE_STR} - .SLEW({SLEW}) + {SLEW_STR} + .IOSTANDARD({IOSTANDARD}) ) ibuf_{site} ( .IO({pad_wire}), .I({iwire}),