Fixup OSERDES features to handle missing bits.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
Keith Rothman 2020-09-25 14:12:10 -07:00
parent 7692b9bea9
commit 8957367dd4
4 changed files with 96 additions and 27 deletions

View File

@ -11,7 +11,7 @@ include ../fuzzer.mk
database: build/segbits_xioi3.db
build/segbits_xioi3.rdb: $(SPECIMENS_OK)
${XRAY_SEGMATCH} -c 6 -o build/segbits_xioi3.rdb $$(find -name segdata_*)
${XRAY_SEGMATCH} -c 7 -o build/segbits_xioi3.rdb $$(find -name segdata_*)
build/segbits_xioi3.db: build/segbits_xioi3.rdb
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in $^ --seg-fn-out $@

View File

@ -2,5 +2,7 @@
30_35,IOB33.IOB_Y1.ODDR.DDR_CLK_EDGE.OPPOSITE_EDGE
33_91 33_93
32_36 32_34
30_127 31_126 31_124 30_121 31_120 30_123 31_116
31_00 30_01 30_03 31_06 30_07 31_04 30_11
33_61 32_38 32_58 33_57
32_70 32_66 33_89 33_69
30_95 30_99 30_127 31_126 31_124 30_121 31_120 30_123 31_116 31_100
31_00 30_01 30_03 31_06 30_07 31_04 30_11 31_28 31_32 30_29 30_27

View File

@ -30,24 +30,23 @@ def handle_data_width(segmk, d):
site = d['ologic_loc']
for opt in [2, 3, 4, 5, 6, 7, 8]:
segmk.add_site_tag(
site, 'OSERDES.DATA_WIDTH.W{}'.format(opt), d['DATA_WIDTH'] == opt)
data_rate = verilog.unquote(d['DATA_RATE_OQ'])
segmk.add_site_tag(
site, 'OSERDES.DATA_WIDTH.{}.W{}'.format(data_rate, d['DATA_WIDTH']),
1)
if verilog.unquote(d['DATA_RATE_OQ']) == 'DDR':
# DDR + WIDTH 6/8 have some overlapping bits, create a feature.
OVERLAPPING_WIDTHS = [6, 8]
segmk.add_site_tag(
site, 'OSERDES.DATA_WIDTH.DDR.W{}'.format(
'_'.join(map(str, OVERLAPPING_WIDTHS))),
d['DATA_WIDTH'] in OVERLAPPING_WIDTHS)
else:
# SDR + WIDTH 2/4/5/6 have some overlapping bits, create a feature.
OVERLAPPING_WIDTHS = [2, 4, 5, 6]
segmk.add_site_tag(
site, 'OSERDES.DATA_WIDTH.SDR.W{}'.format(
'_'.join(map(str, OVERLAPPING_WIDTHS))),
d['DATA_WIDTH'] in OVERLAPPING_WIDTHS)
def no_oserdes(segmk, site):
for mode in ['SDR', 'DDR']:
if mode == 'SDR':
widths = [2, 3, 4, 5, 6, 7, 8]
else:
assert mode == 'DDR'
widths = [4, 6, 8]
for opt in widths:
segmk.add_site_tag(
site, 'OSERDES.DATA_WIDTH.{}.W{}'.format(mode, opt), 0)
def main():
@ -72,10 +71,16 @@ def main():
site, 'OSERDES.DATA_RATE_OQ.{}'.format(opt),
verilog.unquote(d['DATA_RATE_OQ']) == opt)
data_rate_tq = verilog.unquote(d['DATA_RATE_TQ'])
segmk.add_site_tag(
site, 'OSERDES.DATA_RATE_TQ.{}'.format(data_rate_tq), 1)
for opt in ['BUF', 'SDR', 'DDR']:
segmk.add_site_tag(
site, 'OSERDES.DATA_RATE_TQ.{}'.format(opt),
verilog.unquote(d['DATA_RATE_TQ']) == opt)
opt == data_rate_tq)
segmk.add_site_tag(
site, 'OSERDES.DATA_RATE_TQ.ZBUF', data_rate_tq != 'BUF')
for opt in ['SRVAL_OQ', 'SRVAL_TQ', 'INIT_OQ', 'INIT_TQ']:
segmk.add_site_tag(site, opt, d[opt])
@ -112,12 +117,39 @@ def main():
site, 'OSERDES.SERDES_MODE.{}'.format(opt),
opt == verilog.unquote(d['OSERDES_MODE']))
if 'o_sr_used' in d:
if d['o_sr_used'] in ['S', 'R']:
segmk.add_site_tag(site, 'ODDR.SRUSED', 1)
segmk.add_site_tag(site, 'ODDR.ZSRUSED', 0)
else:
assert d['o_sr_used'] == 'None'
segmk.add_site_tag(site, 'ODDR.SRUSED', 0)
segmk.add_site_tag(site, 'ODDR.ZSRUSED', 1)
if 't_sr_used' in d:
if d['t_sr_used'] in ['S', 'R']:
segmk.add_site_tag(site, 'TDDR.SRUSED', 1)
segmk.add_site_tag(site, 'TDDR.ZSRUSED', 0)
else:
assert d['t_sr_used'] == 'None'
segmk.add_site_tag(site, 'TDDR.SRUSED', 0)
segmk.add_site_tag(site, 'TDDR.ZSRUSED', 1)
if d['oddr_mux_config'] == 'direct':
segmk.add_site_tag(site, 'ODDR_TDDR.IN_USE', 1)
if d['tddr_mux_config'] == 'direct':
segmk.add_site_tag(site, 'ODDR_TDDR.IN_USE', 1)
if d['oddr_mux_config'] == 'direct' and d[
'tddr_mux_config'] == 'direct':
for opt in ['OPPOSITE_EDGE', 'SAME_EDGE']:
segmk.add_site_tag(
site, 'ODDR.DDR_CLK_EDGE.{}'.format(opt),
verilog.unquote(d['ODDR_CLK_EDGE']) == opt)
segmk.add_site_tag(site, 'ZINV_CLK', 1 ^ d['IS_CLK_INVERTED'])
if d['IS_CLK_INVERTED'] == 0:
for opt in ['OPPOSITE_EDGE', 'SAME_EDGE']:
segmk.add_site_tag(
site, 'ODDR.DDR_CLK_EDGE.{}'.format(opt),
verilog.unquote(d['ODDR_CLK_EDGE']) == opt)
segmk.add_site_tag(
site, 'TDDR.DDR_CLK_EDGE.INV',
@ -138,7 +170,9 @@ def main():
verilog.unquote(d['TSRTYPE']) == opt)
if not d['use_oserdese2']:
no_oserdes(segmk, site)
if d['oddr_mux_config'] == 'lut':
segmk.add_site_tag(site, 'ODDR_TDDR.IN_USE', 0)
segmk.add_site_tag(site, 'OMUX.D1', 1)
segmk.add_site_tag(site, 'OQUSED', 1)
elif d['oddr_mux_config'] == 'direct':

View File

@ -210,8 +210,12 @@ def use_direct_and_oddr(p, luts, connects):
p['tddr_mux_config'] = 'none'
# toddr and oddr share the same clk
clknet = luts.get_next_output_net()
p['IS_CLK_INVERTED'] = 0
if random.randint(0, 1):
clknet = luts.get_next_output_net()
p['IS_CLK_INVERTED'] = 0
else:
clknet = 'bufg_o'
p['IS_CLK_INVERTED'] = random.randint(0, 1)
if p['tddr_mux_config'] == 'direct':
p['TINIT'] = random.randint(0, 1)
@ -221,6 +225,17 @@ def use_direct_and_oddr(p, luts, connects):
# Note: it seems that CLK_EDGE setting is ignored for TDDR
p['TDDR_CLK_EDGE'] = verilog.quote(
random.choice(('OPPOSITE_EDGE', 'SAME_EDGE')))
p['t_sr_used'] = random.choice(('None', 'S', 'R'))
if p['t_sr_used'] == 'None':
p['t_srnet'] = ''
elif p['t_sr_used'] == 'S':
p['srnet'] = luts.get_next_output_net()
p['t_srnet'] = '.S({}),\n'.format(p['srnet'])
elif p['t_sr_used'] == 'R':
p['srnet'] = luts.get_next_output_net()
p['t_srnet'] = '.R({}),\n'.format(p['srnet'])
print(
'''
(* KEEP, DONT_TOUCH, LOC = "{ologic_loc}" *)
@ -234,6 +249,7 @@ def use_direct_and_oddr(p, luts, connects):
.D1({d1net}),
.D2({d2net}),
.CE({cenet}),
{t_srnet}
.Q(tddr_d_{site})
);
'''.format(
@ -269,6 +285,18 @@ def use_direct_and_oddr(p, luts, connects):
'SAME_EDGE',
)))
p['o_sr_used'] = random.choice(('None', 'S', 'R'))
if p['o_sr_used'] == 'None':
p['o_srnet'] = ''
elif p['o_sr_used'] == 'S':
if 'srnet' not in p:
p['srnet'] = luts.get_next_output_net()
p['o_srnet'] = '.S({}),\n'.format(p['srnet'])
elif p['o_sr_used'] == 'R':
if 'srnet' not in p:
p['srnet'] = luts.get_next_output_net()
p['o_srnet'] = '.R({}),\n'.format(p['srnet'])
print(
'''
(* KEEP, DONT_TOUCH, LOC = "{ologic_loc}" *)
@ -282,6 +310,7 @@ def use_direct_and_oddr(p, luts, connects):
.D1({d1net}),
.D2({d2net}),
.CE({cenet}),
{o_srnet}
.Q(oddr_d_{site})
);
'''.format(
@ -386,6 +415,10 @@ module top(input clk, output wire [`N_DO-1:0] do, inout wire [`N_DIO-1:0] dio);
'''
(* KEEP, DONT_TOUCH *)
LUT6 dummy_lut();
wire bufg_o;
(* KEEP, DONT_TOUCH *)
BUFG (.O(bufg_o));
''')
for p in params: