diff --git a/fuzzers/036-iob-ologic/Makefile b/fuzzers/036-iob-ologic/Makefile index 7bbb000b..23f43f79 100644 --- a/fuzzers/036-iob-ologic/Makefile +++ b/fuzzers/036-iob-ologic/Makefile @@ -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 $@ diff --git a/fuzzers/036-iob-ologic/bits.dbf b/fuzzers/036-iob-ologic/bits.dbf index 27463582..05c818f1 100644 --- a/fuzzers/036-iob-ologic/bits.dbf +++ b/fuzzers/036-iob-ologic/bits.dbf @@ -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 diff --git a/fuzzers/036-iob-ologic/generate.py b/fuzzers/036-iob-ologic/generate.py index e8afdcd2..9e17fc1f 100644 --- a/fuzzers/036-iob-ologic/generate.py +++ b/fuzzers/036-iob-ologic/generate.py @@ -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': diff --git a/fuzzers/036-iob-ologic/top.py b/fuzzers/036-iob-ologic/top.py index 868e15e1..4977a5ef 100644 --- a/fuzzers/036-iob-ologic/top.py +++ b/fuzzers/036-iob-ologic/top.py @@ -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: