diff --git a/fuzzers/005-tilegrid/add_tdb.py b/fuzzers/005-tilegrid/add_tdb.py index 793b2a3f..3dc7eae3 100644 --- a/fuzzers/005-tilegrid/add_tdb.py +++ b/fuzzers/005-tilegrid/add_tdb.py @@ -84,7 +84,7 @@ def run(fn_in, fn_out, verbose=False): ("bram_block/build/segbits_tilegrid.tdb", 128, 10), ("clb/build/segbits_tilegrid.tdb", 36, 2), ("dsp/build/segbits_tilegrid.tdb", 28, 10), - ("clk_hrow/build/segbits_tilegrid.tdb", 30, 7), + ("clk_hrow/build/segbits_tilegrid.tdb", 30, 18), ("clk_bufg/build/segbits_tilegrid.tdb", 30, 8), ("clb_int/build/segbits_tilegrid.tdb", int_frames, int_words), ("iob_int/build/segbits_tilegrid.tdb", int_frames, int_words), diff --git a/fuzzers/005-tilegrid/clk_hrow/Makefile b/fuzzers/005-tilegrid/clk_hrow/Makefile index 17297e84..1934a3f7 100644 --- a/fuzzers/005-tilegrid/clk_hrow/Makefile +++ b/fuzzers/005-tilegrid/clk_hrow/Makefile @@ -1,4 +1,4 @@ N ?= 5 -GENERATE_ARGS?="--oneval 1 --design params.csv --dword 1 --dframe 1A" +GENERATE_ARGS?="--oneval 1 --design params.csv --dword 6 --dframe 1A" include ../fuzzaddr/common.mk diff --git a/fuzzers/005-tilegrid/generate_full.py b/fuzzers/005-tilegrid/generate_full.py index 476c9221..11aabfa6 100644 --- a/fuzzers/005-tilegrid/generate_full.py +++ b/fuzzers/005-tilegrid/generate_full.py @@ -233,7 +233,7 @@ def propagate_rebuf(database, tiles_by_grid): rebuf_below]['type'] assert database[tile_name]['bits']['CLB_IO_CLK'][ - 'offset'] == 47, database[tile_name]['bits']['CLB_IO_CLK'] + 'offset'] == 42, database[tile_name]['bits']['CLB_IO_CLK'] database[rebuf_below]['bits'] = copy.deepcopy( database[tile_name]['bits']) database[rebuf_below]['bits']['CLB_IO_CLK']['offset'] = 73 diff --git a/fuzzers/041-clk-hrow-pips/Makefile b/fuzzers/041-clk-hrow-pips/Makefile index 98c03ac9..df0a7b87 100644 --- a/fuzzers/041-clk-hrow-pips/Makefile +++ b/fuzzers/041-clk-hrow-pips/Makefile @@ -5,12 +5,15 @@ PIPLIST_TCL=$(FUZDIR)/clk_hrow_pip_list.tcl ifeq (${XRAY_PART}, xc7z010clg400-1) # xc7z010clg400-1 is missing some side clock connections, so these bits cannot # be documented. +# FIXME: Use EXCLUDE_RE rather than complicated include RE. TODO_RE="[^\.]+\.CLK_HROW_CK_MUX_OUT_[LR][0-9]+\.CLK_HROW_.*[KR_][0-9]+" +TODO_EXCLUDE_RE="^CLK_HROW_BOT_R.*CASCIN[0-9]+$$" else TODO_RE=".*" +TODO_EXCLUDE_RE="^CLK_HROW_BOT_R.*CASCIN[0-9]+$$" endif -MAKETODO_FLAGS=--sides "bot_r,top_r" --pip-type ${PIP_TYPE} --seg-type clk_hrow --re $(TODO_RE) +MAKETODO_FLAGS=--sides "bot_r,top_r" --pip-type ${PIP_TYPE} --seg-type clk_hrow --re $(TODO_RE) --exclude-re $(TODO_EXCLUDE_RE) N = 50 # These PIPs all appear to be either a 2 bit solutions. @@ -20,39 +23,49 @@ A_PIPLIST=clk_hrow_bot_r.txt include ../pip_loop.mk -database: build/segbits_clk_hrow.db - -build/cmt_regions.csv: output_cmt.tcl - mkdir -p build - cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_cmt.tcl - -build/segbits_clk_hrow.rdb: $(SPECIMENS_OK) - ${XRAY_SEGMATCH} ${SEGMATCH_FLAGS} -o build/segbits_clk_hrow.rdb \ - $(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 +database: build/segbits_clk_hrow_bot_r.rdb build/segbits_clk_hrow_top_r.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.db + --seg-fn-in build/segbits_clk_hrow_top_r.rdb \ + --seg-fn-out build/segbits_clk_hrow_top_r.db + ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ + --seg-fn-in build/segbits_clk_hrow_bot_r.rdb \ + --seg-fn-out build/segbits_clk_hrow_bot_r.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_top_r.rdb build/$(ITER)/segbits_clk_hrow_top_r.rdb + cp build/segbits_clk_hrow_bot_r.rdb build/$(ITER)/segbits_clk_hrow_bot_r.rdb - ${XRAY_MASKMERGE} build/mask_clk_hrow.db \ - $(shell find build -name segdata_clk_hrow_top_r.txt) \ + ${XRAY_MASKMERGE} build/mask_clk_hrow_top_r.db \ + $(shell find build -name segdata_clk_hrow_top_r.txt) + ${XRAY_MASKMERGE} build/mask_clk_hrow_bot_r.db \ $(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 + XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow_bot_r.db + XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow_top_r.db + +build/cmt_regions.csv: output_cmt.tcl + mkdir -p build + cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_cmt.tcl + +generate: $(SPECIMENS_OK) + +build/segbits_clk_hrow_top_r.rdb: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} ${SEGMATCH_FLAGS} -o build/segbits_clk_hrow_top_r.rdb \ + $(shell find build -name segdata_clk_hrow_top_r.txt) + +build/segbits_clk_hrow_bot_r.rdb: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} ${SEGMATCH_FLAGS} -o build/segbits_clk_hrow_bot_r.rdb \ + $(shell find build -name segdata_clk_hrow_bot_r.txt) + +build/segbits_clk_hrow.db: build/segbits_clk_hrow_top_.rdb pushdb: database - ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow.db - ${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow.db - ${XRAY_MERGEDB} mask_clk_hrow_bot_r build/mask_clk_hrow.db - ${XRAY_MERGEDB} mask_clk_hrow_top_r build/mask_clk_hrow.db + ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow_bot_r.db + ${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow_top_r.db + ${XRAY_MERGEDB} mask_clk_hrow_bot_r build/mask_clk_hrow_bot_r.db + ${XRAY_MERGEDB} mask_clk_hrow_top_r build/mask_clk_hrow_top_r.db -.PHONY: database pushdb +.PHONY: database pushdb generate diff --git a/fuzzers/041-clk-hrow-pips/generate.py b/fuzzers/041-clk-hrow-pips/generate.py index de28cde3..98be0a87 100644 --- a/fuzzers/041-clk-hrow-pips/generate.py +++ b/fuzzers/041-clk-hrow-pips/generate.py @@ -3,7 +3,6 @@ import os import os.path from prjxray.segmaker import Segmaker -import pprint def main(): @@ -12,6 +11,7 @@ def main(): tiledata = {} pipdata = {} clk_list = {} + casco_list = {} ignpip = set() with open(os.path.join(os.getenv('FUZDIR'), '..', 'piplist', 'build', @@ -21,9 +21,13 @@ def main(): if tile_type not in pipdata: pipdata[tile_type] = [] clk_list[tile_type] = set() + casco_list[tile_type] = set() pipdata[tile_type].append((src, dst)) + if 'CASCO' in dst: + casco_list[tile_type].add(dst) + if dst.startswith('CLK_HROW_CK_MUX_OUT_'): clk_list[tile_type].add(src) @@ -34,9 +38,13 @@ def main(): if tile_type not in pipdata: pipdata[tile_type] = [] clk_list[tile_type] = set() + casco_list[tile_type] = set() pipdata[tile_type].append((src, dst)) + if 'CASCO' in dst: + casco_list[tile_type].add(dst) + if dst.startswith('CLK_HROW_CK_MUX_OUT_'): clk_list[tile_type].add(src) @@ -78,7 +86,6 @@ def main(): active_gclks = {} active_clks = {} - for tile, pips_srcs_dsts in tiledata.items(): tile_type = pips_srcs_dsts["type"] pips = pips_srcs_dsts["pips"] @@ -87,15 +94,13 @@ def main(): 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) - active_clks[tile].add(src) + if 'GCLK' in src: + if src not in active_gclks: + active_gclks[src] = set() - if 'GCLK' in src: - if src not in active_gclks: - active_gclks[src] = set() - - active_gclks[src].add(tile) + active_gclks[src].add(tile) for src, dst in pipdata[tile_type]: if (src, dst) in ignpip: diff --git a/fuzzers/041-clk-hrow-pips/generate.tcl b/fuzzers/041-clk-hrow-pips/generate.tcl index e9f672b4..09bcabd9 100644 --- a/fuzzers/041-clk-hrow-pips/generate.tcl +++ b/fuzzers/041-clk-hrow-pips/generate.tcl @@ -121,7 +121,7 @@ proc route_todo {} { } set origin_node [get_nodes -of_objects [get_site_pins -filter {DIRECTION == OUT} -of_objects $net]] - set destination_nodes [get_nodes -of_objects [get_site_pins -filter {DIRECTION == IN} -of_objects $net]] + set destination_nodes [filter [get_nodes -of_objects [get_site_pins -filter {DIRECTION == IN} -of_objects $net]] {NAME =~ *CLK_HROW*}] route_design -unroute -nets $net set new_route [find_routing_path -to $target_node -from $origin_node] puts "Origin node: $origin_node" @@ -151,6 +151,7 @@ proc run {} { set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] set_property IS_ENABLED 0 [get_drc_checks {REQP-161}] set_property IS_ENABLED 0 [get_drc_checks {REQP-123}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-13}] set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets] diff --git a/fuzzers/041-clk-hrow-pips/output_cmt.tcl b/fuzzers/041-clk-hrow-pips/output_cmt.tcl index d1af528c..06aba163 100644 --- a/fuzzers/041-clk-hrow-pips/output_cmt.tcl +++ b/fuzzers/041-clk-hrow-pips/output_cmt.tcl @@ -3,7 +3,7 @@ set_property design_mode PinPlanning [current_fileset] open_io_design -name io_1 set fp [open "cmt_regions.csv" "w"] -foreach site_type {MMCME2_ADV PLLE2_ADV BUFHCE} { +foreach site_type {MMCME2_ADV PLLE2_ADV BUFHCE BUFR} { foreach site [get_sites -filter "SITE_TYPE == $site_type"] { puts $fp "$site,[get_property CLOCK_REGION $site]" } diff --git a/fuzzers/041-clk-hrow-pips/top.py b/fuzzers/041-clk-hrow-pips/top.py index 819f3a61..8712ee68 100644 --- a/fuzzers/041-clk-hrow-pips/top.py +++ b/fuzzers/041-clk-hrow-pips/top.py @@ -1,11 +1,17 @@ """ Emits top.v's for various BUFHCE routing inputs. """ import os import random +import re random.seed(int(os.getenv("SEED"), 16)) from prjxray import util +from prjxray import verilog from prjxray.db import Database +from prjxray.lut_maker import LutMaker +from io import StringIO CMT_XY_FUN = util.create_xy_fun(prefix='') +BUFGCTRL_XY_FUN = util.create_xy_fun('BUFGCTRL_') +BUFHCE_XY_FUN = util.create_xy_fun('BUFHCE_') def gen_sites(desired_site_type): @@ -17,7 +23,7 @@ def gen_sites(desired_site_type): gridinfo = grid.gridinfo_at_loc(loc) for site, site_type in gridinfo.sites.items(): if site_type == desired_site_type: - yield site + yield loc, gridinfo.tile_type, site def gen_bufhce_sites(): @@ -59,8 +65,10 @@ class ClockSources(object): self.merged_sources = {} self.source_to_cmt = {} self.used_sources_from_cmt = {} + self.sources_by_loc = {} + self.active_cmt_ports = {} - def add_clock_source(self, source, cmt): + def add_clock_source(self, source, cmt, loc=None): """ Adds a source from a specific CMT. cmt='ANY' indicates that this source can be routed to any CMT. @@ -73,6 +81,14 @@ class ClockSources(object): source] == cmt, source self.source_to_cmt[source] = cmt + self.add_bufg_clock_source(source, cmt, loc) + + def add_bufg_clock_source(self, source, cmt, loc): + if loc not in self.sources_by_loc: + self.sources_by_loc[loc] = [] + + self.sources_by_loc[loc].append((cmt, source)) + def get_random_source(self, cmt): """ Get a random source that is routable to the specific CMT. @@ -113,12 +129,91 @@ class ClockSources(object): if source_cmt != 'ANY' and len( self.used_sources_from_cmt[source_cmt]) > 14: - print('//', self.used_sources_from_cmt) self.used_sources_from_cmt[source_cmt].remove(source) return None else: return source + def get_bufg_source(self, loc, tile_type, site, todos, i_wire, used_only): + bufg_sources = [] + + top = '_TOP_' in tile_type + bottom = '_BOT_' in tile_type + + assert top ^ bottom, tile_type + + if top: + for src_loc, cmt_sources in self.sources_by_loc.items(): + if src_loc is None: + continue + if src_loc.grid_y <= loc.grid_y: + bufg_sources.extend(cmt_sources) + elif bottom: + for src_loc, cmt_sources in self.sources_by_loc.items(): + if src_loc is None: + continue + if src_loc.grid_y > loc.grid_y: + bufg_sources.extend(cmt_sources) + + # CLK_HROW_TOP_R_CK_BUFG_CASCO0 -> CLK_BUFG_BUFGCTRL0_I0 + # CLK_HROW_TOP_R_CK_BUFG_CASCO22 -> CLK_BUFG_BUFGCTRL11_I0 + # CLK_HROW_TOP_R_CK_BUFG_CASCO23 -> CLK_BUFG_BUFGCTRL11_I1 + # CLK_HROW_BOT_R_CK_BUFG_CASCO27 -> CLK_BUFG_BUFGCTRL13_I1 + + x, y = BUFGCTRL_XY_FUN(site) + assert x == 0 + y = y % 16 + + + assert i_wire in [0, 1], i_wire + + casco_wire = '{tile_type}_CK_BUFG_CASCO{casco_idx}'.format( + tile_type=tile_type.replace('BUFG', 'HROW'), + casco_idx=(y*2+i_wire)) + + if casco_wire not in todos: + return None + + target_wires = [] + + need_bufr = False + for src_wire in todos[casco_wire]: + if 'BUFRCLK' in src_wire: + need_bufr = True + break + + for cmt, wire in bufg_sources: + if 'BUFR' in wire: + if need_bufr: + target_wires.append((cmt, wire)) + else: + target_wires.append((cmt, wire)) + + random.shuffle(target_wires) + for cmt, source in target_wires: + if cmt == 'ANY': + return source + else: + # Make sure to not try to import move than 14 sources from + # the CMT, there is limited routing. + if cmt not in self.used_sources_from_cmt: + self.used_sources_from_cmt[cmt] = set() + + if source in self.used_sources_from_cmt[cmt]: + return source + elif used_only: + continue + + if len(self.used_sources_from_cmt[cmt]) < 14: + self.used_sources_from_cmt[cmt].add(source) + return source + else: + continue + + return None + + + def check_allowed(mmcm_pll_dir, cmt): """ Check whether the CMT specified is in the allowed direction. @@ -140,6 +235,45 @@ def check_allowed(mmcm_pll_dir, cmt): else: assert False, mmcm_pll_dir +def read_todo(): + dsts = {} + + with open(os.path.join('..', 'todo_all.txt')) as f: + for l in f: + tile_type, dst, src = l.strip().split('.') + + if dst not in dsts: + dsts[dst] = set() + + dsts[dst].add(src) + + return dsts + +def need_int_connections(todos): + for srcs in todos.values(): + for src in srcs: + if re.search('INT_._.', src): + return True + + return False + +def bufhce_in_todo(todos, site): + if 'BUFHCE' in site: + # CLK_HROW_CK_MUX_OUT_R9 -> X1Y9 + # CLK_HROW_CK_MUX_OUT_L11 -> X0Y35 + x, y = BUFHCE_XY_FUN(site) + y = y % 12 + + if x == 0: + lr = 'L' + elif x == 1: + lr = 'R' + else: + assert False, x + + return 'CLK_HROW_CK_MUX_OUT_{lr}{y}'.format(lr=lr, y=y) in todos + else: + return True def main(): """ @@ -166,26 +300,27 @@ module top(); mmcm_pll_only = random.randint(0, 1) mmcm_pll_dir = random.choice(('ODD', 'EVEN', 'BOTH', 'NONE')) + todos = read_todo() + if not mmcm_pll_only: - for _ in range(2): - clock_sources.add_clock_source('one', 'ANY') - clock_sources.add_clock_source('zero', 'ANY') + if need_int_connections(todos): + for _ in range(10): + clock_sources.add_clock_source('one', 'ANY') + clock_sources.add_clock_source('zero', 'ANY') print(""" wire zero = 0; wire one = 1;""") - for site in gen_sites('MMCME2_ADV'): + for loc, _, site in gen_sites('MMCME2_ADV'): mmcm_clocks = [ 'mmcm_clock_{site}_{idx}'.format(site=site, idx=idx) for idx in range(13) ] - if not check_allowed(mmcm_pll_dir, site_to_cmt[site]): - continue - - for clk in mmcm_clocks: - clock_sources.add_clock_source(clk, site_to_cmt[site]) + if check_allowed(mmcm_pll_dir, site_to_cmt[site]): + for clk in mmcm_clocks: + clock_sources.add_clock_source(clk, site_to_cmt[site], loc) print( """ @@ -223,17 +358,15 @@ module top(); c12=mmcm_clocks[12], )) - for site in gen_sites('PLLE2_ADV'): + for loc, _, site in gen_sites('PLLE2_ADV'): pll_clocks = [ 'pll_clock_{site}_{idx}'.format(site=site, idx=idx) for idx in range(6) ] - if not check_allowed(mmcm_pll_dir, site_to_cmt[site]): - continue - - for clk in pll_clocks: - clock_sources.add_clock_source(clk, site_to_cmt[site]) + if check_allowed(mmcm_pll_dir, site_to_cmt[site]): + for clk in pll_clocks: + clock_sources.add_clock_source(clk, site_to_cmt[site], loc) print( """ @@ -257,30 +390,65 @@ module top(); c5=pll_clocks[5], )) + for loc, _, site in gen_sites('BUFR'): + clock_sources.add_bufg_clock_source('O_{site}'.format(site=site), site_to_cmt[site], loc) + print(""" + wire O_{site}; + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFR bufr_{site} ( + .O(O_{site}) + );""".format(site=site)) + + luts = LutMaker() + bufhs = StringIO() + bufgs = StringIO() + gclks = [] - for site in sorted(gen_sites("BUFGCTRL"), - key=util.create_xy_fun('BUFGCTRL_')): - wire_name = 'clk_{}'.format(site) + for _, _, site in sorted(gen_sites("BUFGCTRL"), + key=lambda x: BUFGCTRL_XY_FUN(x[2])): + wire_name = 'gclk_{}'.format(site) gclks.append(wire_name) if not mmcm_pll_only: clock_sources.add_clock_source(wire_name, 'ANY') + print(""" + wire {wire_name}; + """.format(wire_name=wire_name)) print( """ - wire {wire_name}; + wire I1_{site}; + wire I0_{site}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) - BUFG bufg_{site} ( - .O({wire_name}) + BUFGCTRL bufg_{site} ( + .O({wire_name}), + .S1({s1net}), + .S0({s0net}), + .IGNORE1({ignore1net}), + .IGNORE0({ignore0net}), + .I1(I1_{site}), + .I0(I0_{site}), + .CE1({ce1net}), + .CE0({ce0net}) ); """.format( site=site, wire_name=wire_name, - )) + s1net=luts.get_next_output_net(), + s0net=luts.get_next_output_net(), + ignore1net=luts.get_next_output_net(), + ignore0net=luts.get_next_output_net(), + ce1net=luts.get_next_output_net(), + ce0net=luts.get_next_output_net(), + ), file=bufgs) + any_bufhce = False for tile_name, sites in gen_bufhce_sites(): for site in sites: + if not bufhce_in_todo(todos, site): + continue + any_bufhce = True print( """ @@ -291,10 +459,11 @@ module top(); ); """.format( site=site, - )) + ), file=bufhs) if random.random() > .05: wire_name = clock_sources.get_random_source(site_to_cmt[site]) + if wire_name is None: continue @@ -302,7 +471,7 @@ module top(); assign I_{site} = {wire_name};""".format( site=site, wire_name=wire_name, - )) + ), file=bufhs) if not any_bufhce: @@ -311,16 +480,52 @@ module top(); print( """ (* KEEP, DONT_TOUCH, LOC = "{site}" *) - BUFHCE buf_{site} ( + BUFHCE #( + .INIT_OUT({INIT_OUT}), + .CE_TYPE({CE_TYPE}), + .IS_CE_INVERTED({IS_CE_INVERTED}) + ) buf_{site} ( .I({wire_name}) ); """.format( + INIT_OUT=random.randint(0, 1), + CE_TYPE=verilog.quote( + random.choice(('SYNC', 'ASYNC'))), + IS_CE_INVERTED = random.randint(0, 1), site=site, wire_name=gclks[0], )) break break + for l in luts.create_wires_and_luts(): + print(l) + + print(bufhs.getvalue()) + print(bufgs.getvalue()) + + used_only = random.random() < .25 + + for loc, tile_type, site in sorted(gen_sites("BUFGCTRL"), + key=lambda x: BUFGCTRL_XY_FUN(x[2])): + if random.randint(0, 1): + wire_name = clock_sources.get_bufg_source(loc, tile_type, site, todos, 1, used_only) + if wire_name is not None: + print(""" + assign I1_{site} = {wire_name};""".format( + site=site, + wire_name=wire_name, + )) + + if random.randint(0, 1): + wire_name = clock_sources.get_bufg_source(loc, tile_type, site, todos, 0, used_only) + if wire_name is not None: + print(""" + assign I0_{site} = {wire_name};""".format( + site=site, + wire_name=wire_name, + )) + print("endmodule") diff --git a/fuzzers/int_maketodo.py b/fuzzers/int_maketodo.py index a1729a10..970d8d07 100644 --- a/fuzzers/int_maketodo.py +++ b/fuzzers/int_maketodo.py @@ -33,7 +33,7 @@ def load_pipfile(pipfile, verbose=False): return todos, tile_type -def maketodo(pipfile, dbfile, intre, not_endswith=None, verbose=False): +def maketodo(pipfile, dbfile, intre, exclude_re=None, not_endswith=None, verbose=False): ''' db files start with INT., but pipfile lines start with INT_L Normalize by removing before the first dot @@ -75,8 +75,15 @@ def maketodo(pipfile, dbfile, intre, not_endswith=None, verbose=False): drops = 0 lines = 0 for line in todos: - if re.match(intre, line) and (not_endswith is None - or not line.endswith(not_endswith)): + include = re.match(intre, line) is not None + + if include and not_endswith is not None: + include = not line.endswith(not_endswith) + + if include and exclude_re is not None: + include = re.match(exclude_re, line) is None + + if include: print(line) else: drops += 1 @@ -94,6 +101,7 @@ def run( r, pip_type, seg_type, + exclude_re=None, not_endswith=None, verbose=False): if db_dir is None: @@ -117,7 +125,8 @@ def run( "%s/%s_%s.txt" % (pip_dir, pip_type, side), "%s/segbits_%s_%s.db" % (db_dir, seg_type, side), intre, - not_endswith, + exclude_re=exclude_re, + not_endswith=not_endswith, verbose=verbose) @@ -132,6 +141,7 @@ def main(): parser.add_argument('--db-dir', default=None, help='') parser.add_argument('--pip-dir', default=None, help='') parser.add_argument('--re', required=True, help='') + parser.add_argument('--exclude-re', required=False, default=None, help='') parser.add_argument('--pip-type', default="pips_int", help='') parser.add_argument('--seg-type', default="int", help='') parser.add_argument('--sides', default="l,r", help='') @@ -146,6 +156,7 @@ def main(): db_dir=args.db_dir, pip_dir=args.pip_dir, intre=args.re, + exclude_re=args.exclude_re, sides=args.sides.split(','), l=args.l, r=args.r,