030-iob: add LVDS_25 and TMDS_33

Signed-off-by: Alessandro Comodi <acomodi@antmicro.com>
This commit is contained in:
Alessandro Comodi 2021-02-12 15:40:49 +01:00
parent 953f8745ba
commit abac14b5a0
4 changed files with 117 additions and 70 deletions

View File

@ -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 $@

View File

@ -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:

View File

@ -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()

View File

@ -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}),