mirror of https://github.com/openXC7/prjxray.git
Merge pull request #1587 from antmicro/add-lvds-tmds-iostandards
030-iob: add LVDS_25 and TMDS_33
This commit is contained in:
commit
2c9571d1a9
|
|
@ -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 $@
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ def get_site(l):
|
|||
|
||||
def parse_bits(l):
|
||||
parts = l.strip().split(' ')
|
||||
if parts[1] in ['<0', '<const0>']:
|
||||
if parts[1] in ['<0', '<const0>', '<const1>']:
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -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}),
|
||||
|
|
|
|||
Loading…
Reference in New Issue