From 6f999ed3d1604260fced6420a25cf212daa266e1 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 2 Aug 2019 16:11:24 -0700 Subject: [PATCH] Add HCLK (BUFR) fuzzer and solve additional bits in CLK_HROW. These fuzzer updates are required for use of BUFR for clock dividing. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/039-hclk-config/Makefile | 22 ++++ fuzzers/039-hclk-config/bits.dbf | 4 + fuzzers/039-hclk-config/generate.py | 46 ++++++++ fuzzers/039-hclk-config/generate.tcl | 17 +++ fuzzers/039-hclk-config/top.py | 149 ++++++++++++++++++++++++++ fuzzers/041-clk-hrow-pips/generate.py | 8 ++ 6 files changed, 246 insertions(+) create mode 100644 fuzzers/039-hclk-config/Makefile create mode 100644 fuzzers/039-hclk-config/bits.dbf create mode 100644 fuzzers/039-hclk-config/generate.py create mode 100644 fuzzers/039-hclk-config/generate.tcl create mode 100644 fuzzers/039-hclk-config/top.py diff --git a/fuzzers/039-hclk-config/Makefile b/fuzzers/039-hclk-config/Makefile new file mode 100644 index 00000000..a6eec0e6 --- /dev/null +++ b/fuzzers/039-hclk-config/Makefile @@ -0,0 +1,22 @@ +N ?= 50 + +include ../fuzzer.mk + +database: build/segbits_hclk_ioi3.db + +build/segbits_hclk_ioi3.rdb: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} -c 5 -o build/segbits_hclk_ioi3.rdb \ + $(addsuffix /segdata_hclk_ioi3.txt,$(SPECIMENS)) + +build/segbits_hclk_ioi3.db: build/segbits_hclk_ioi3.rdb + ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ + --seg-fn-in build/segbits_hclk_ioi3.rdb \ + --seg-fn-out build/segbits_hclk_ioi3.db + ${XRAY_MASKMERGE} build/mask_hclk_ioi3.db \ + $(addsuffix /segdata_hclk_ioi3.txt,$(SPECIMENS)) + +pushdb: database + ${XRAY_MERGEDB} hclk_ioi3 build/segbits_hclk_ioi3.db + ${XRAY_MERGEDB} mask_hclk_ioi3 build/mask_hclk_ioi3.db + +.PHONY: database pushdb diff --git a/fuzzers/039-hclk-config/bits.dbf b/fuzzers/039-hclk-config/bits.dbf new file mode 100644 index 00000000..99d83180 --- /dev/null +++ b/fuzzers/039-hclk-config/bits.dbf @@ -0,0 +1,4 @@ +32_22 33_18 33_19 33_20 33_21,HCLK_IOI3.BUFR_Y0.BUFR_DIVIDE.BYPASS +32_17 33_14 33_15 33_16 33_17,HCLK_IOI3.BUFR_Y1.BUFR_DIVIDE.BYPASS +33_27 33_28 33_29 33_30 33_31,HCLK_IOI3.BUFR_Y2.BUFR_DIVIDE.BYPASS +32_28 33_23 33_24 33_25 33_26,HCLK_IOI3.BUFR_Y3.BUFR_DIVIDE.BYPASS diff --git a/fuzzers/039-hclk-config/generate.py b/fuzzers/039-hclk-config/generate.py new file mode 100644 index 00000000..11c8ce02 --- /dev/null +++ b/fuzzers/039-hclk-config/generate.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 + +import json + +from prjxray.segmaker import Segmaker + + +def bitfilter(frame, bit): + return True + + +def main(): + segmk = Segmaker("design.bits") + + print("Loading tags") + with open('params.json') as f: + params = json.load(f) + + for row in params: + base_name = 'BUFR_Y{}'.format(row['y']) + + segmk.add_tile_tag( + row['tile'], '{}.IN_USE'.format(base_name), row['IN_USE']) + + if not row['IN_USE']: + continue + + segmk.add_tile_tag( + row['tile'], '{}.BUFR_DIVIDE.BYPASS'.format(base_name), + '"BYPASS"' == row['BUFR_DIVIDE']) + for opt in range(1, 9): + if row['BUFR_DIVIDE'] == str(opt): + segmk.add_tile_tag( + row['tile'], '{}.BUFR_DIVIDE.D{}'.format(base_name, opt), + 1) + elif '"BYPASS"' == row['BUFR_DIVIDE']: + segmk.add_tile_tag( + row['tile'], '{}.BUFR_DIVIDE.D{}'.format(base_name, opt), + 0) + + segmk.compile(bitfilter=bitfilter) + segmk.write() + + +if __name__ == '__main__': + main() diff --git a/fuzzers/039-hclk-config/generate.tcl b/fuzzers/039-hclk-config/generate.tcl new file mode 100644 index 00000000..3044e100 --- /dev/null +++ b/fuzzers/039-hclk-config/generate.tcl @@ -0,0 +1,17 @@ +proc run {} { + create_project -force -part $::env(XRAY_PART) design design + read_verilog top.v + synth_design -top top + + set_property CFGBVS VCCO [current_design] + set_property CONFIG_VOLTAGE 3.3 [current_design] + set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] + + place_design + route_design + + write_checkpoint -force design.dcp + write_bitstream -force design.bit +} + +run diff --git a/fuzzers/039-hclk-config/top.py b/fuzzers/039-hclk-config/top.py new file mode 100644 index 00000000..05fce4c7 --- /dev/null +++ b/fuzzers/039-hclk-config/top.py @@ -0,0 +1,149 @@ +import json +import os +import random +random.seed(int(os.getenv("SEED"), 16)) +from prjxray.db import Database +from prjxray import util +from prjxray.lut_maker import LutMaker + + +def gen_sites(): + xy_fun = util.create_xy_fun('BUFR_') + db = Database(util.get_db_root()) + grid = db.grid() + for tile_name in sorted(grid.tiles()): + loc = grid.loc_of_tilename(tile_name) + gridinfo = grid.gridinfo_at_loc(loc) + sites = [] + + xs = [] + ys = [] + for site, site_type in gridinfo.sites.items(): + if site_type == 'BUFR': + x, y = xy_fun(site) + xs.append(x) + ys.append(y) + + sites.append((site, x, y)) + + if not sites: + continue + + ioi3 = grid.gridinfo_at_loc((loc.grid_x, loc.grid_y - 1)) + assert 'IOI3' in ioi3.tile_type + + if ioi3.tile_type.startswith('R'): + dx = 1 + else: + assert ioi3.tile_type.startswith('L') + dx = -1 + + iobs = [] + + for dy in (-1, -3, 2, 4): + iob = grid.gridinfo_at_loc((loc.grid_x + dx, loc.grid_y + dy)) + + for site, site_type in iob.sites.items(): + if site_type == 'IOB33M': + iobs.append(site) + + yield tile_name, min(xs), min(ys), sorted(sites), sorted(iobs) + + +def main(): + + params_list = [] + num_clocks = 0 + outputs = [] + luts = LutMaker() + for tile_name, x_min, y_min, sites, iobs in gen_sites(): + ioclks = [] + for iob in iobs: + ioclk = 'clk_{}'.format(iob) + ioclks.append(ioclk) + idx = num_clocks + num_clocks += 1 + outputs.append( + ''' + wire {ioclk}; + + (* KEEP, DONT_TOUCH, LOC="{site}" *) + IBUF #( + .IOSTANDARD("LVCMOS33") + ) ibuf_{site} ( + .I(clks[{idx}]), + .O({ioclk}) + );'''.format( + ioclk=ioclk, + site=iob, + idx=idx, + )) + + for site, x, y in sites: + params = {} + params['tile'] = tile_name + params['site'] = site + params['IN_USE'] = random.randint(0, 1) + params['x'] = x - x_min + params['y'] = y - y_min + + if params['IN_USE']: + params['BUFR_DIVIDE'] = random.choice( + ( + '"BYPASS"', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + )) + params['I'] = random.choice(ioclks) + + if params['BUFR_DIVIDE'] == '"BYPASS"': + params['CE'] = '1' + params['CLR'] = '0' + else: + params['CE'] = luts.get_next_output_net() + params['CLR'] = luts.get_next_output_net() + + outputs.append( + ''' + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFR #( + .BUFR_DIVIDE({BUFR_DIVIDE}) + ) buf_{site} ( + .CE({CE}), + .CLR({CLR}), + .I({I}) + ); + '''.format(**params)) + + params_list.append(params) + + print( + ''' +module top(input [{n1}:0] clks); + '''.format(n1=num_clocks - 1)) + + print(""" + (* KEEP, DONT_TOUCH *) + LUT6 dummy ( + );""") + + for l in luts.create_wires_and_luts(): + print(l) + + for l in outputs: + print(l) + + print("endmodule") + + with open('params.json', 'w') as f: + json.dump(params_list, f, indent=2) + + +if __name__ == '__main__': + main() diff --git a/fuzzers/041-clk-hrow-pips/generate.py b/fuzzers/041-clk-hrow-pips/generate.py index 5f1f9b61..e6ccc430 100644 --- a/fuzzers/041-clk-hrow-pips/generate.py +++ b/fuzzers/041-clk-hrow-pips/generate.py @@ -38,6 +38,10 @@ def main(): if dst.startswith('CLK_HROW_CK_MUX_OUT_'): clk_list[tile_type].add(src) + if dst.startswith('CLK_HROW_BOT_R_CK_BUFG_'): + if 'CASCIN' not in src: + clk_list[tile_type].add(src) + with open(os.path.join(os.getenv('FUZDIR'), '..', 'piplist', 'build', 'clk_hrow', 'clk_hrow_top_r.txt')) as f: for l in f: @@ -55,6 +59,10 @@ def main(): if dst.startswith('CLK_HROW_CK_MUX_OUT_'): clk_list[tile_type].add(src) + if dst.startswith('CLK_HROW_TOP_R_CK_BUFG_'): + if 'CASCIN' not in src: + clk_list[tile_type].add(src) + print("Loading tags from design.txt.") with open("design.txt", "r") as f: for line in f: