From 73b3342adbede0a1607c237a1a255ae7bc5db115 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 26 Jul 2019 13:48:43 -0700 Subject: [PATCH 1/2] Add initial DIFF_ support to IOB fuzzer. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/030-iob/check_results.py | 37 ++++- fuzzers/030-iob/generate.py | 44 +++++- fuzzers/030-iob/process_rdb.py | 23 ++- fuzzers/030-iob/top.py | 253 +++++++++++++++++++++++-------- 4 files changed, 285 insertions(+), 72 deletions(-) diff --git a/fuzzers/030-iob/check_results.py b/fuzzers/030-iob/check_results.py index 12cd6fc6..0a60c68f 100644 --- a/fuzzers/030-iob/check_results.py +++ b/fuzzers/030-iob/check_results.py @@ -22,8 +22,11 @@ import generate def process_parts(parts): + if len(parts) == 0: + return + if parts[-1] == 'IN_ONLY': - yield 'type', ['IBUF'] + yield 'type', ['IBUF', 'IBUFDS'] if len(parts) > 2 and parts[-2] == 'SLEW': yield 'SLEW', verilog.quote(parts[-1]) @@ -35,6 +38,10 @@ def process_parts(parts): yield 'IOSTANDARDS', parts[0].split('_') yield 'IN', True + if len(parts) > 1 and parts[1] == 'IN_DIFF': + yield 'IOSTANDARDS', parts[0].split('_') + yield 'IN_DIFF', True + if len(parts) > 1 and parts[1] == 'DRIVE': yield 'IOSTANDARDS', parts[0].split('_') @@ -47,6 +54,8 @@ def process_parts(parts): def create_sites_from_fasm(fasm_file): sites = {} + diff_tiles = set() + with open(fasm_file) as f: for l in f: if 'IOB33' not in l: @@ -55,19 +64,27 @@ def create_sites_from_fasm(fasm_file): parts = l.strip().split('.') tile = parts[0] site = parts[1] + + if 'OUT_DIFF' == site: + diff_tiles.add(tile) + continue + if (tile, site) not in sites: sites[(tile, site)] = { 'tile': tile, 'site_key': site, } + if len(parts) > 3 and 'IN_DIFF' == parts[3]: + diff_tiles.add(tile) + for key, value in process_parts(parts[2:]): sites[(tile, site)][key] = value for key in sites: if 'type' not in sites[key]: if 'IOSTANDARDS' not in sites[key]: - sites[key]['type'] = None + sites[key]['type'] = [None] else: assert 'IOSTANDARDS' in sites[key], sites[key] assert 'DRIVES' in sites[key], sites[key] @@ -77,15 +94,17 @@ def create_sites_from_fasm(fasm_file): else: sites[key]['type'] = [ "OBUF", + "OBUFDS", + "OBUFTDS", "OBUFDS_DUAL_BUF", "OBUFTDS_DUAL_BUF", ] - return sites + return sites, diff_tiles def process_specimen(fasm_file, params_json): - sites = create_sites_from_fasm(fasm_file) + sites, diff_tiles = create_sites_from_fasm(fasm_file) with open(params_json) as f: params = json.load(f) @@ -107,8 +126,12 @@ def process_specimen(fasm_file, params_json): site_from_fasm = sites[(tile, site_key)] - assert p['type'] in site_from_fasm['type'], ( - tile, site_key, p['type'], site_from_fasm['type']) + if site_y == 0 or tile not in diff_tiles: + assert p['type'] in site_from_fasm['type'], ( + tile, site_key, p['type'], site_from_fasm['type']) + else: + # Y1 on DIFF tiles is always none. + assert p['type'] is None, p if p['type'] is None: continue @@ -136,7 +159,7 @@ def process_specimen(fasm_file, params_json): site_from_fasm['IOSTANDARDS'], ) - if p['type'] != 'IBUF': + if p['type'] not in ['IBUF', 'IBUFDS']: if verilog.unquote(p['SLEW']) == '': # Default is None. slew = verilog.quote('SLOW') diff --git a/fuzzers/030-iob/generate.py b/fuzzers/030-iob/generate.py index 3989b4ee..19c8576f 100644 --- a/fuzzers/030-iob/generate.py +++ b/fuzzers/030-iob/generate.py @@ -48,6 +48,7 @@ def drives_for_iostandard(iostandard): STEPDOWN_IOSTANDARDS = ['LVCMOS12', 'LVCMOS15', 'LVCMOS18', 'SSTL135'] +IBUF_LOW_PWR_SUPPORTED = ['SSTL135'] def main(): @@ -61,13 +62,24 @@ def main(): with open('params.json', 'r') as f: design = json.load(f) + diff_pairs = set() + for d in design['tiles']: + iostandard = verilog.unquote(d['IOSTANDARD']) + if iostandard.startswith('DIFF_'): + diff_pairs.add(d['pair_site']) + for d in design['tiles']: site = d['site'] if skip_broken_tiles(d): continue + if site in diff_pairs: + continue + iostandard = verilog.unquote(d['IOSTANDARD']) + if iostandard.startswith('DIFF_'): + iostandard = iostandard[5:] segmk.add_site_tag( site, '_'.join(STEPDOWN_IOSTANDARDS) + '.STEPDOWN', @@ -83,13 +95,43 @@ def main(): 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), 1) + segmk.add_site_tag(site, '{}.IN_DIFF'.format(iostandard), 0) 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', 0) + + if iostandard in IBUF_LOW_PWR_SUPPORTED: + segmk.add_site_tag(site, 'IBUF_LOW_PWR', d['IBUF_LOW_PWR']) + segmk.add_site_tag( + site, 'ZIBUF_LOW_PWR', 1 ^ d['IBUF_LOW_PWR']) + elif d['type'] == 'IBUFDS': + 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), 1) + segmk.add_site_tag(site, '{}.IN_DIFF'.format(iostandard), 1) + 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) elif d['type'] == 'OBUF': 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', 0) + elif d['type'] == 'OBUFDS': + 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', 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) elif d['type'] == 'IOBUF_INTERMDISABLE': segmk.add_site_tag(site, 'INOUT', 1) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) @@ -102,7 +144,7 @@ def main(): ("NONE", "KEEPER", "PULLDOWN", "PULLUP"), "PULLDOWN", verilog.unquote(d['PULLTYPE'])) - if d['type'] == 'IBUF' or d['type'] is None: + if d['type'] in [None, 'IBUF', 'IBUFDS']: continue drive_opts = set() diff --git a/fuzzers/030-iob/process_rdb.py b/fuzzers/030-iob/process_rdb.py index 004683f8..e3385d1f 100644 --- a/fuzzers/030-iob/process_rdb.py +++ b/fuzzers/030-iob/process_rdb.py @@ -21,7 +21,7 @@ def get_site(l): def parse_bits(l): parts = l.strip().split(' ') - if parts[1] == '<0': + if parts[1] in ['<0', '']: return frozenset() else: return frozenset(parts[1:]) @@ -93,7 +93,8 @@ def main(): if group in ['DRIVE', 'SLEW']: enum = feature_parts[4] sites[site][group][(iostandard, enum)] = bits - elif group in ['IN', 'IN_ONLY', 'IN_USE', 'OUT', 'STEPDOWN']: + elif group in ['IN', 'IN_DIFF', 'IN_ONLY', 'IN_USE', 'OUT', + 'STEPDOWN']: sites[site][group][(iostandard, None)] = bits else: assert False, group @@ -124,6 +125,9 @@ def main(): 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)] @@ -142,10 +146,22 @@ def main(): sites[site]['SLEW'][(iostandard, enum)] |= slew_in_drives[(site, iostandard)] + for site in sites: + for iostandard, enum in sites[site]['DRIVE']: + sites[site]['DRIVE'][(iostandard, enum)] |= sites[site]['IN_USE'][( + iostandard, None)] + + for iostandard, enum in sites[site]['IN']: + if sites[site]['IN_DIFF'][(iostandard, enum)]: + sites[site]['IN_DIFF'][(iostandard, enum)] |= \ + sites[site]['IN'][(iostandard, enum)] + for site in sites: del sites[site]['OUT'] del sites[site]['IN_USE'] + allow_zero = ['SLEW'] + for site in sites: for group in sites[site]: common_groups = {} @@ -184,6 +200,9 @@ def main(): group=group, ) + if not bits and group not in allow_zero: + continue + neg_bits = frozenset( '!{}'.format(b) for b in (common_bits[(site, group)] - bits)) diff --git a/fuzzers/030-iob/top.py b/fuzzers/030-iob/top.py index 35b2222d..b622fc78 100644 --- a/fuzzers/030-iob/top.py +++ b/fuzzers/030-iob/top.py @@ -22,9 +22,13 @@ def gen_sites(): loc = grid.loc_of_tilename(tile_name) gridinfo = grid.gridinfo_at_loc(loc) + sites = {} for site_name, site_type in gridinfo.sites.items(): if site_type in ['IOB33S', 'IOB33M']: - yield tile_name, site_name + sites[site_type] = site_name + + if sites: + yield tile_name, sites def write_params(params): @@ -53,6 +57,11 @@ def run(): 'LVTTL', 'SSTL135', ] + + diff_map = { + "SSTL135": ["DIFF_SSTL135"], + } + iostandard = random.choice(iostandards) if iostandard in ['LVTTL', 'LVCMOS18']: @@ -93,70 +102,136 @@ def run(): )) any_idelay = False - for tile, site in gen_sites(): - p = {} - p['tile'] = tile - p['site'] = site - p['type'] = random.choice(tile_types) - p['IOSTANDARD'] = verilog.quote(iostandard) - p['PULLTYPE'] = verilog.quote(random.choice(pulls)) + for tile, sites in gen_sites(): + site_bels = {} + for site_type in sites: + if site_type.endswith('M'): + if iostandard in diff_map: + site_bels[site_type] = random.choice( + tile_types + ['IBUFDS', 'OBUFDS', 'OBUFTDS']) + else: + site_bels[site_type] = random.choice(tile_types) + is_m_diff = site_bels[site_type] is not None and site_bels[ + site_type].endswith('DS') + else: + site_bels[site_type] = random.choice(tile_types) - if p['type'] is None: - p['pad_wire'] = None - elif p['type'] == 'IBUF': - p['pad_wire'] = 'di[{}]'.format(i_idx) - p['IDELAY_ONLY'] = random.randint(0, 1) - if not p['IDELAY_ONLY']: + if is_m_diff: + site_bels['IOB33S'] = None + + for site_type, site in sites.items(): + p = {} + p['tile'] = tile + p['site'] = site + p['type'] = site_bels[site_type] + + if p['type'] is not None and p['type'].endswith('DS'): + iostandard_site = random.choice(diff_map[iostandard]) + p['pair_site'] = sites['IOB33S'] + else: + iostandard_site = iostandard + + p['IOSTANDARD'] = verilog.quote(iostandard_site) + p['PULLTYPE'] = verilog.quote(random.choice(pulls)) + + if p['type'] is None: + p['pad_wire'] = None + elif p['type'] == 'IBUF': + p['pad_wire'] = 'di[{}]'.format(i_idx) + p['IDELAY_ONLY'] = random.randint(0, 1) + if not p['IDELAY_ONLY']: + p['owire'] = luts.get_next_input_net() + else: + any_idelay = True + p['owire'] = 'idelay_{site}'.format(**p) + + p['DRIVE'] = None + p['SLEW'] = None + p['IBUF_LOW_PWR'] = random.randint(0, 1) + + i_idx += 1 + elif p['type'] == 'IBUFDS': + p['pad_wire'] = 'di[{}]'.format(i_idx) + i_idx += 1 + p['bpad_wire'] = 'di[{}]'.format(i_idx) + i_idx += 1 + + p['IDELAY_ONLY'] = random.randint(0, 1) + p['DIFF_TERM'] = random.randint(0, 1) + if not p['IDELAY_ONLY']: + p['owire'] = luts.get_next_input_net() + else: + any_idelay = True + p['owire'] = 'idelay_{site}'.format(**p) + + p['DRIVE'] = None + p['SLEW'] = None + p['IBUF_LOW_PWR'] = random.randint(0, 1) + + elif p['type'] == 'OBUF': + p['pad_wire'] = 'do[{}]'.format(o_idx) + p['iwire'] = luts.get_next_output_net() + if drives is not None: + p['DRIVE'] = random.choice(drives) + else: + p['DRIVE'] = None + p['SLEW'] = verilog.quote(random.choice(slews)) + + o_idx += 1 + elif p['type'] == 'OBUFDS': + p['pad_wire'] = 'do[{}]'.format(o_idx) + o_idx += 1 + p['bpad_wire'] = 'do[{}]'.format(o_idx) + o_idx += 1 + p['iwire'] = luts.get_next_output_net() + if drives is not None: + p['DRIVE'] = random.choice(drives) + else: + p['DRIVE'] = None + p['SLEW'] = verilog.quote(random.choice(slews)) + elif p['type'] == 'OBUFTDS': + p['pad_wire'] = 'do[{}]'.format(o_idx) + o_idx += 1 + p['bpad_wire'] = 'do[{}]'.format(o_idx) + o_idx += 1 + p['tristate_wire'] = random.choice( + ('0', luts.get_next_output_net())) + p['iwire'] = luts.get_next_output_net() + if drives is not None: + p['DRIVE'] = random.choice(drives) + else: + p['DRIVE'] = None + p['SLEW'] = verilog.quote(random.choice(slews)) + elif p['type'] == 'IOBUF_INTERMDISABLE': + p['pad_wire'] = 'dio[{}]'.format(io_idx) + p['iwire'] = luts.get_next_output_net() p['owire'] = luts.get_next_input_net() - else: - any_idelay = True - p['owire'] = 'idelay_{site}'.format(**p) + if drives is not None: + p['DRIVE'] = random.choice(drives) + else: + p['DRIVE'] = None + p['SLEW'] = verilog.quote(random.choice(slews)) + p['tristate_wire'] = random.choice( + ('0', luts.get_next_output_net())) + p['ibufdisable_wire'] = random.choice( + ('0', luts.get_next_output_net())) + p['intermdisable_wire'] = random.choice( + ('0', luts.get_next_output_net())) + io_idx += 1 - p['DRIVE'] = None - p['SLEW'] = None - p['IBUF_LOW_PWR'] = random.randint(0, 1) + if 'DRIVE' in p: + if p['DRIVE'] is not None: + p['DRIVE_STR'] = '.DRIVE({}),'.format(p['DRIVE']) + else: + p['DRIVE_STR'] = '' - i_idx += 1 - elif p['type'] == 'OBUF': - p['pad_wire'] = 'do[{}]'.format(o_idx) - p['iwire'] = luts.get_next_output_net() - if drives is not None: - p['DRIVE'] = random.choice(drives) - else: - p['DRIVE'] = None - p['SLEW'] = verilog.quote(random.choice(slews)) - - o_idx += 1 - elif p['type'] == 'IOBUF_INTERMDISABLE': - p['pad_wire'] = 'dio[{}]'.format(io_idx) - p['iwire'] = luts.get_next_output_net() - p['owire'] = luts.get_next_input_net() - if drives is not None: - p['DRIVE'] = random.choice(drives) - else: - p['DRIVE'] = None - p['SLEW'] = verilog.quote(random.choice(slews)) - p['tristate_wire'] = random.choice( - ('0', luts.get_next_output_net())) - p['ibufdisable_wire'] = random.choice( - ('0', luts.get_next_output_net())) - p['intermdisable_wire'] = random.choice( - ('0', luts.get_next_output_net())) - io_idx += 1 - - if 'DRIVE' in p: - if p['DRIVE'] is not None: - p['DRIVE_STR'] = '.DRIVE({}),'.format(p['DRIVE']) - else: - p['DRIVE_STR'] = '' - - if p['type'] is not None: - tile_params.append( - ( - tile, site, p['pad_wire'], iostandard, p['DRIVE'], - verilog.unquote(p['SLEW']) if p['SLEW'] else None, - verilog.unquote(p['PULLTYPE']))) - params['tiles'].append(p) + if p['type'] is not None: + tile_params.append( + ( + tile, site, p['pad_wire'], iostandard_site, p['DRIVE'], + verilog.unquote(p['SLEW']) if p['SLEW'] else None, + verilog.unquote(p['PULLTYPE']))) + params['tiles'].append(p) write_params(tile_params) @@ -209,6 +284,31 @@ module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do, inout wire [`N );""".format(**p), file=connects) + elif p['type'] == 'IBUFDS': + print( + ''' + wire idelay_{site}; + + (* KEEP, DONT_TOUCH *) + IBUFDS #( + .IBUF_LOW_PWR({IBUF_LOW_PWR}), + .DIFF_TERM({DIFF_TERM}), + .IOSTANDARD({IOSTANDARD}) + ) ibuf_{site} ( + .I({pad_wire}), + .IB({bpad_wire}), + .O({owire}) + );'''.format(**p), + file=connects) + if p['IDELAY_ONLY']: + print( + """ + (* KEEP, DONT_TOUCH *) + IDELAYE2 idelay_site_{site} ( + .IDATAIN(idelay_{site}) + );""".format(**p), + file=connects) + elif p['type'] == 'OBUF': print( ''' @@ -217,11 +317,40 @@ module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do, inout wire [`N .IOSTANDARD({IOSTANDARD}), {DRIVE_STR} .SLEW({SLEW}) - ) ibuf_{site} ( + ) obuf_{site} ( .O({pad_wire}), .I({iwire}) );'''.format(**p), file=connects) + elif p['type'] == 'OBUFDS': + print( + ''' + (* KEEP, DONT_TOUCH *) + OBUFDS #( + .IOSTANDARD({IOSTANDARD}), + {DRIVE_STR} + .SLEW({SLEW}) + ) obufds_{site} ( + .O({pad_wire}), + .OB({bpad_wire}), + .I({iwire}) + );'''.format(**p), + file=connects) + elif p['type'] == 'OBUFTDS': + print( + ''' + (* KEEP, DONT_TOUCH *) + OBUFTDS #( + .IOSTANDARD({IOSTANDARD}), + {DRIVE_STR} + .SLEW({SLEW}) + ) obufds_{site} ( + .O({pad_wire}), + .OB({bpad_wire}), + .T({tristate_wire}), + .I({iwire}) + );'''.format(**p), + file=connects) elif p['type'] == 'IOBUF_INTERMDISABLE': print( ''' From f723091e50b9a24e03c550644b40cd0a6b0671ed Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 26 Jul 2019 14:21:40 -0700 Subject: [PATCH 2/2] Add IN_TERM fuzzing. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/030-iob/generate.py | 7 +++++++ fuzzers/030-iob/generate.tcl | 5 +++++ fuzzers/030-iob/top.py | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/fuzzers/030-iob/generate.py b/fuzzers/030-iob/generate.py index 19c8576f..82ecd66b 100644 --- a/fuzzers/030-iob/generate.py +++ b/fuzzers/030-iob/generate.py @@ -85,6 +85,13 @@ def main(): site, '_'.join(STEPDOWN_IOSTANDARDS) + '.STEPDOWN', iostandard in STEPDOWN_IOSTANDARDS) + if 'IN_TERM' in d: + segmaker.add_site_group_zero( + segmk, site, 'IN_TERM.', [ + 'NONE', 'UNTUNED_SPLIT_40', 'UNTUNED_SPLIT_50', + 'UNTUNED_SPLIT_60' + ], 'NONE', d['IN_TERM']) + if d['type'] is None: segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 0) diff --git a/fuzzers/030-iob/generate.tcl b/fuzzers/030-iob/generate.tcl index f0776206..7d1c18d5 100644 --- a/fuzzers/030-iob/generate.tcl +++ b/fuzzers/030-iob/generate.tcl @@ -44,6 +44,7 @@ proc loc_pins {} { set drive [lindex $line 4] set slew [lindex $line 5] set pulltype [lindex $line 6] + set in_term [lindex $line 7] # Have: site # Want: pin for site @@ -69,6 +70,10 @@ proc loc_pins {} { lappend props SLEW $slew } + if {$in_term != "None"} { + lappend props IN_TERM $in_term + } + puts $props set_property -dict "$props" $port diff --git a/fuzzers/030-iob/top.py b/fuzzers/030-iob/top.py index b622fc78..e7c59238 100644 --- a/fuzzers/030-iob/top.py +++ b/fuzzers/030-iob/top.py @@ -62,6 +62,19 @@ def run(): "SSTL135": ["DIFF_SSTL135"], } + IN_TERM_ALLOWED = [ + 'SSTL15', + 'SSTL15_R', + 'SSTL18', + 'SSTL18_R', + 'SSTL135', + 'SSTL135_R', + 'HSTL_I' + 'HSTL_I_18' + 'HSTL_II', + 'HSTL_II_18', + ] + iostandard = random.choice(iostandards) if iostandard in ['LVTTL', 'LVCMOS18']: @@ -149,6 +162,15 @@ def run(): p['SLEW'] = None p['IBUF_LOW_PWR'] = random.randint(0, 1) + if iostandard in IN_TERM_ALLOWED: + p['IN_TERM'] = random.choice( + ( + 'NONE', + 'UNTUNED_SPLIT_40', + 'UNTUNED_SPLIT_50', + 'UNTUNED_SPLIT_60', + )) + i_idx += 1 elif p['type'] == 'IBUFDS': p['pad_wire'] = 'di[{}]'.format(i_idx) @@ -228,9 +250,15 @@ def run(): if p['type'] is not None: tile_params.append( ( - tile, site, p['pad_wire'], iostandard_site, p['DRIVE'], + tile, + site, + p['pad_wire'], + iostandard_site, + p['DRIVE'], verilog.unquote(p['SLEW']) if p['SLEW'] else None, - verilog.unquote(p['PULLTYPE']))) + verilog.unquote(p['PULLTYPE']), + p['IN_TERM'] if 'IN_TERM' in p else None, + )) params['tiles'].append(p) write_params(tile_params)