From 023cd55bb1f6909d129265e64e52712208558c8f Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Mar 2019 18:23:47 -0700 Subject: [PATCH] Refactor 041 fuzzer to avoid requiring insight into mux structure. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/041-clk-hrow-pips/Makefile | 23 ++-- fuzzers/041-clk-hrow-pips/clk_table.py | 34 ----- fuzzers/041-clk-hrow-pips/generate.py | 117 ++++++++++++------ .../041-clk-hrow-pips/merge_clk_entries.py | 89 ------------- fuzzers/041-clk-hrow-pips/top.py | 24 ++-- 5 files changed, 107 insertions(+), 180 deletions(-) delete mode 100644 fuzzers/041-clk-hrow-pips/clk_table.py delete mode 100644 fuzzers/041-clk-hrow-pips/merge_clk_entries.py diff --git a/fuzzers/041-clk-hrow-pips/Makefile b/fuzzers/041-clk-hrow-pips/Makefile index f3677cf7..98c03ac9 100644 --- a/fuzzers/041-clk-hrow-pips/Makefile +++ b/fuzzers/041-clk-hrow-pips/Makefile @@ -1,5 +1,5 @@ export FUZDIR=$(shell pwd) -PIP_TYPE?=clk_hrow_bot +PIP_TYPE?=clk_hrow PIPLIST_TCL=$(FUZDIR)/clk_hrow_pip_list.tcl ifeq (${XRAY_PART}, xc7z010clg400-1) @@ -7,14 +7,14 @@ ifeq (${XRAY_PART}, xc7z010clg400-1) # be documented. TODO_RE="[^\.]+\.CLK_HROW_CK_MUX_OUT_[LR][0-9]+\.CLK_HROW_.*[KR_][0-9]+" else -TODO_RE="[^\.]+\.CLK_HROW_CK_MUX_OUT_" +TODO_RE=".*" endif -MAKETODO_FLAGS=--no-l --pip-type ${PIP_TYPE} --seg-type clk_hrow_bot --re $(TODO_RE) +MAKETODO_FLAGS=--sides "bot_r,top_r" --pip-type ${PIP_TYPE} --seg-type clk_hrow --re $(TODO_RE) N = 50 -# These PIPs all appear to be either a 1 bit solutions. -SEGMATCH_FLAGS=-c 1 +# These PIPs all appear to be either a 2 bit solutions. +SEGMATCH_FLAGS=-c 2 SPECIMENS_DEPS=build/cmt_regions.csv A_PIPLIST=clk_hrow_bot_r.txt @@ -31,27 +31,20 @@ build/segbits_clk_hrow.rdb: $(SPECIMENS_OK) $(shell find build -name segdata_clk_hrow_top_r.txt) \ $(shell find build -name segdata_clk_hrow_bot_r.txt) -build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb piplist +build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ --seg-fn-in build/segbits_clk_hrow.rdb \ - --seg-fn-out build/segbits_clk_hrow_rc.db - - # Convert row/column into PIP definition. - python3 merge_clk_entries.py \ - build/segbits_clk_hrow_rc.db \ - $(XRAY_FUZZERS_DIR)/piplist/build/${PIP_TYPE}/clk_hrow_bot_r.txt \ - build/segbits_clk_hrow.db + --seg-fn-out build/segbits_clk_hrow.db # Keep a copy to track iter progress cp build/segbits_clk_hrow.rdb build/$(ITER)/segbits_clk_hrow.rdb - cp build/segbits_clk_hrow_rc.db build/$(ITER)/segbits_clk_hrow_rc.db - ${XRAY_MASKMERGE} build/mask_clk_hrow.db \ $(shell find build -name segdata_clk_hrow_top_r.txt) \ $(shell find build -name segdata_clk_hrow_bot_r.txt) # Clobber existing .db to eliminate potential conflicts + rm -f build/database/${XRAY_DATABASE}/* cp ${XRAY_DATABASE_DIR}/${XRAY_DATABASE}/segbits*.db build/database/${XRAY_DATABASE} XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow.db XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow.db diff --git a/fuzzers/041-clk-hrow-pips/clk_table.py b/fuzzers/041-clk-hrow-pips/clk_table.py deleted file mode 100644 index 9b3ccdfd..00000000 --- a/fuzzers/041-clk-hrow-pips/clk_table.py +++ /dev/null @@ -1,34 +0,0 @@ -HCLKS = 24 -GCLKS = 32 -SIDE_CLK_INPUTS = 14 - -CLK_TABLE_NUM_ROWS = 8 -CLK_TABLE_NUM_COLS = 8 - - -def get_clk_table(): - clk_table = {} - for gclk in range(GCLKS): - gclk_name = 'CLK_HROW_R_CK_GCLK{}'.format(gclk) - row = gclk % CLK_TABLE_NUM_ROWS - column = int(gclk / CLK_TABLE_NUM_ROWS) - clk_table[gclk_name] = (row, column) - - for row in range(8): - clk_table['CLK_HROW_CK_IN_L{}'.format(row)] = (row, 4) - for row in range(6): - clk_table['CLK_HROW_CK_IN_L{}'.format(row + 8)] = (row, 5) - - for row in range(8): - clk_table['CLK_HROW_CK_IN_R{}'.format(row)] = (row, 6) - for row in range(6): - clk_table['CLK_HROW_CK_IN_R{}'.format(row + 8)] = (row, 7) - - # HROW_CK_INT__, Y == Y share the same bits, and only X = 0 or X = 1 - # are present on a particular HROW. - for y in range(2): - for x in range(2): - int_clk_name = 'CLK_HROW_CK_INT_{}_{}'.format(x, y) - clk_table[int_clk_name] = (y + 6, 7) - - return clk_table diff --git a/fuzzers/041-clk-hrow-pips/generate.py b/fuzzers/041-clk-hrow-pips/generate.py index f9b20ba2..de28cde3 100644 --- a/fuzzers/041-clk-hrow-pips/generate.py +++ b/fuzzers/041-clk-hrow-pips/generate.py @@ -1,17 +1,46 @@ #!/usr/bin/env python3 +import os +import os.path from prjxray.segmaker import Segmaker -import clk_table +import pprint def main(): segmk = Segmaker("design.bits") - table = clk_table.get_clk_table() + + tiledata = {} + pipdata = {} + clk_list = {} + ignpip = set() + + with open(os.path.join(os.getenv('FUZDIR'), '..', 'piplist', 'build', + 'clk_hrow', 'clk_hrow_bot_r.txt')) as f: + for l in f: + tile_type, dst, src = l.strip().split('.') + if tile_type not in pipdata: + pipdata[tile_type] = [] + clk_list[tile_type] = set() + + pipdata[tile_type].append((src, dst)) + + if dst.startswith('CLK_HROW_CK_MUX_OUT_'): + 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: + tile_type, dst, src = l.strip().split('.') + if tile_type not in pipdata: + pipdata[tile_type] = [] + clk_list[tile_type] = set() + + pipdata[tile_type].append((src, dst)) + + if dst.startswith('CLK_HROW_CK_MUX_OUT_'): + clk_list[tile_type].add(src) print("Loading tags from design.txt.") - - active_gclks = {} - active_clks = {} with open("design.txt", "r") as f: for line in f: tile, pip, src, dst, pnum, pdir = line.split() @@ -19,36 +48,46 @@ def main(): if not tile.startswith('CLK_HROW'): continue - pip_prefix, pip = pip.split(".") + pip_prefix, _ = pip.split(".") tile_from_pip, tile_type = pip_prefix.split('/') assert tile == tile_from_pip _, src = src.split("/") _, dst = dst.split("/") + pnum = int(pnum) + pdir = int(pdir) - rows = set(range(clk_table.CLK_TABLE_NUM_ROWS)) - columns = set(range(clk_table.CLK_TABLE_NUM_COLS)) + if tile not in tiledata: + tiledata[tile] = { + "type": tile_type, + "pips": set(), + "srcs": set(), + "dsts": set() + } - if src in table: - row, column = table[src] + tiledata[tile]["pips"].add((src, dst)) + tiledata[tile]["srcs"].add(src) + tiledata[tile]["dsts"].add(dst) - segmk.add_tile_tag( - tile, '{}.HCLK_ENABLE_ROW{}'.format(dst, row), 1) - segmk.add_tile_tag( - tile, '{}.HCLK_ENABLE_COLUMN{}'.format(dst, column), 1) + if pdir == 0: + tiledata[tile]["srcs"].add(dst) + tiledata[tile]["dsts"].add(src) - rows.remove(row) - columns.remove(column) + if pnum == 1 or pdir == 0: + ignpip.add((src, dst)) - for row in rows: - segmk.add_tile_tag( - tile, '{}.HCLK_ENABLE_ROW{}'.format(dst, row), 0) + active_gclks = {} + active_clks = {} - for column in columns: - segmk.add_tile_tag( - tile, '{}.HCLK_ENABLE_COLUMN{}'.format(dst, column), 0) - if tile not in active_clks: - active_clks[tile] = set() + for tile, pips_srcs_dsts in tiledata.items(): + tile_type = pips_srcs_dsts["type"] + pips = pips_srcs_dsts["pips"] + + if tile not in active_clks: + active_clks[tile] = set() + + for src, dst in pips_srcs_dsts["pips"]: + if dst.startswith('CLK_HROW_CK_MUX_OUT_'): active_clks[tile].add(src) @@ -58,18 +97,26 @@ def main(): active_gclks[src].add(tile) - tiles = sorted(active_clks.keys()) + for src, dst in pipdata[tile_type]: + if (src, dst) in ignpip: + pass + elif (src, dst) in pips: + segmk.add_tile_tag(tile, "%s.%s" % (dst, src), 1) + elif dst not in tiledata[tile]["dsts"]: + segmk.add_tile_tag(tile, "%s.%s" % (dst, src), 0) + + for tile_type, srcs in clk_list.items(): + for tile, pips_srcs_dsts in tiledata.items(): + for src in srcs: + if 'GCLK' not in src: + active = src in active_clks[tile] + segmk.add_tile_tag(tile, '{}_ACTIVE'.format(src), active) + else: + if src not in active_gclks: + segmk.add_tile_tag(tile, '{}_ACTIVE'.format(src), 0) + elif tile in active_gclks[src]: + segmk.add_tile_tag(tile, '{}_ACTIVE'.format(src), 1) - for tile in active_clks: - for src in table: - if 'GCLK' not in src: - active = src in active_clks[tile] - segmk.add_tile_tag(tile, '{}_ACTIVE'.format(src), active) - else: - if src not in active_gclks: - segmk.add_tile_tag(tile, '{}_ACTIVE'.format(src), 0) - elif tile in active_gclks[src]: - segmk.add_tile_tag(tile, '{}_ACTIVE'.format(src), 1) segmk.compile() segmk.write() diff --git a/fuzzers/041-clk-hrow-pips/merge_clk_entries.py b/fuzzers/041-clk-hrow-pips/merge_clk_entries.py deleted file mode 100644 index 1ddd2ebe..00000000 --- a/fuzzers/041-clk-hrow-pips/merge_clk_entries.py +++ /dev/null @@ -1,89 +0,0 @@ -import argparse -import clk_table - - -def main(): - parser = argparse.ArgumentParser( - description="Convert HCLK ROW/COLUMN definitions into HCLK pips.") - parser.add_argument('in_segbit') - parser.add_argument('piplist') - parser.add_argument('out_segbit') - - args = parser.parse_args() - - output_features = [] - hrow_outs = {} - tile = None - with open(args.in_segbit) as f: - for l in f: - parts = l.strip().split(' ') - feature = parts[0] - bits = ' '.join(parts[1:]) - - # No post-processing on _ACTIVE bits. - if feature.endswith('_ACTIVE'): - output_features.append(l.strip()) - continue - - tile1, dst, src = feature.split('.') - if tile is None: - tile = tile1 - else: - assert tile == tile1 - - n = int(src[-1]) - - if dst not in hrow_outs: - hrow_outs[dst] = { - 'rows': {}, - 'columns': {}, - } - - if src[-4:-1] == 'ROW': - hrow_outs[dst]['rows'][n] = bits - else: - assert src[-7:-1] == 'COLUMN', src - hrow_outs[dst]['columns'][n] = bits - - piplists = {} - with open(args.piplist) as f: - for l in f: - tile, dst, src = l.strip().split('.') - assert tile == 'CLK_HROW_BOT_R', tile - - if dst not in piplists: - piplists[dst] = [] - - piplists[dst].append(src) - - table = clk_table.get_clk_table() - - with open(args.out_segbit, 'w') as f: - for l in output_features: - print(l, file=f) - - for dst in sorted(hrow_outs): - for src in sorted(piplists[dst]): - if src not in table: - continue - - row, column = table[src] - - if row not in hrow_outs[dst]['rows']: - continue - - if column not in hrow_outs[dst]['columns']: - continue - - print( - 'CLK_HROW.{dst}.{inclk} {row_bits} {column_bits}'.format( - dst=dst, - inclk=src, - row_bits=hrow_outs[dst]['rows'][row], - column_bits=hrow_outs[dst]['columns'][column], - ), - file=f) - - -if __name__ == "__main__": - main() diff --git a/fuzzers/041-clk-hrow-pips/top.py b/fuzzers/041-clk-hrow-pips/top.py index 74c8d2de..819f3a61 100644 --- a/fuzzers/041-clk-hrow-pips/top.py +++ b/fuzzers/041-clk-hrow-pips/top.py @@ -135,6 +135,8 @@ def check_allowed(mmcm_pll_dir, cmt): elif mmcm_pll_dir == 'EVEN': x, y = CMT_XY_FUN(cmt) return (x & 1) == 0 + elif mmcm_pll_dir == 'NONE': + return False else: assert False, mmcm_pll_dir @@ -162,7 +164,7 @@ module top(); # sources are allowed. The force of ODD/EVEN/BOTH further biases the # clock sources to the left or right column inputs. mmcm_pll_only = random.randint(0, 1) - mmcm_pll_dir = random.choice(('ODD', 'EVEN', 'BOTH')) + mmcm_pll_dir = random.choice(('ODD', 'EVEN', 'BOTH', 'NONE')) if not mmcm_pll_only: for _ in range(2): @@ -279,22 +281,30 @@ module top(); any_bufhce = False for tile_name, sites in gen_bufhce_sites(): for site in sites: - wire_name = clock_sources.get_random_source(site_to_cmt[site]) - if wire_name is None: - continue - any_bufhce = True print( """ + wire I_{site}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFHCE buf_{site} ( - .I({wire_name}) + .I(I_{site}) ); """.format( site=site, - wire_name=wire_name, )) + if random.random() > .05: + wire_name = clock_sources.get_random_source(site_to_cmt[site]) + if wire_name is None: + continue + + print(""" + assign I_{site} = {wire_name};""".format( + site=site, + wire_name=wire_name, + )) + + if not any_bufhce: for tile_name, sites in gen_bufhce_sites(): for site in sites: