diff --git a/fuzzers/041-clk-hrow-pips/Makefile b/fuzzers/041-clk-hrow-pips/Makefile index 400f43c9..1bb8bc01 100644 --- a/fuzzers/041-clk-hrow-pips/Makefile +++ b/fuzzers/041-clk-hrow-pips/Makefile @@ -1,15 +1,19 @@ -N ?= 150 +export FUZDIR=$(shell pwd) +PIP_TYPE?=clk_hrow +PIPLIST_TCL=$(FUZDIR)/clk_hrow_pip_list.tcl +MAKETODO_FLAGS=--no-l --pip-type clk_hrow_bot --seg-type clk_hrow_bot --re "[^\.]+\.CLK_HROW_CK_MUX_OUT_" +N = 50 +# These PIPs all appear to be either a 0 or 2 bit solution. +SEGMATCH_FLAGS=-m 20 -M 45 -c 2 SPECIMENS_DEPS=build/cmt_regions.csv -include ../fuzzer.mk +A_PIPLIST=clk_hrow_bot_r.txt + +include ../pip_loop.mk database: build/segbits_clk_hrow.db -build/clk_hrow_bot_r.txt: clk_hrow_pip_list.tcl - mkdir -p build - cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/clk_hrow_pip_list.tcl - -build/cmt_regions.csv: output_cmt.tcl build/clk_hrow_bot_r.txt +build/cmt_regions.csv: output_cmt.tcl mkdir -p build cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_cmt.tcl @@ -18,19 +22,31 @@ build/segbits_clk_hrow.rdb: $(SPECIMENS_OK) $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) \ $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) -build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb build/clk_hrow_bot_r.txt +build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb $(XRAY_FUZZERS_DIR)/piplist/build/clk_hrow_bot_r.txt ${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 \ - build/clk_hrow_bot_r.txt \ + $(XRAY_FUZZERS_DIR)/piplist/build/clk_hrow_bot_r.txt \ 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 \ $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) \ $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) + # Clobber existing .db to eliminate potential conflicts + 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 + pushdb: database ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow.db ${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow.db diff --git a/fuzzers/041-clk-hrow-pips/clk_hrow_pip_list.tcl b/fuzzers/041-clk-hrow-pips/clk_hrow_pip_list.tcl index b21bec3a..83872c61 100644 --- a/fuzzers/041-clk-hrow-pips/clk_hrow_pip_list.tcl +++ b/fuzzers/041-clk-hrow-pips/clk_hrow_pip_list.tcl @@ -18,4 +18,3 @@ open_io_design -name io_1 print_tile_pips CLK_HROW_TOP_R clk_hrow_top_r.txt print_tile_pips CLK_HROW_BOT_R clk_hrow_bot_r.txt -print_tile_pips CLK_BUFG_REBUF clk_bufg_rebuf.txt diff --git a/fuzzers/041-clk-hrow-pips/clk_table.py b/fuzzers/041-clk-hrow-pips/clk_table.py index 0b46564b..a6721dc3 100644 --- a/fuzzers/041-clk-hrow-pips/clk_table.py +++ b/fuzzers/041-clk-hrow-pips/clk_table.py @@ -8,14 +8,10 @@ CLK_TABLE_NUM_COLS = 8 for gclk in range(GCLKS): gclk_name = 'CLK_HROW_R_CK_GCLK{}'.format(gclk) - row = gclk % 8 - column = int(gclk / 8) + row = gclk % CLK_TABLE_NUM_ROWS + column = int(gclk / CLK_TABLE_NUM_ROWS) CLK_TABLE[gclk_name] = (row, column) -for lr in ['L', 'R']: - for side_inputs in range(SIDE_CLK_INPUTS): - side_clk_name = 'CLK_HROW_CK_IN_{}{}'.format(lr, side_inputs) - for row in range(8): CLK_TABLE['CLK_HROW_CK_IN_L{}'.format(row)] = (row, 4) for row in range(6): diff --git a/fuzzers/041-clk-hrow-pips/generate.tcl b/fuzzers/041-clk-hrow-pips/generate.tcl index 05210e30..e9f672b4 100644 --- a/fuzzers/041-clk-hrow-pips/generate.tcl +++ b/fuzzers/041-clk-hrow-pips/generate.tcl @@ -1,3 +1,5 @@ +source "$::env(XRAY_DIR)/utils/utils.tcl" + proc write_pip_txtdata {filename} { puts "FUZ([pwd]): Writing $filename." set fp [open $filename w] @@ -21,6 +23,124 @@ proc write_pip_txtdata {filename} { close $fp } +proc load_todo {} { + set fp [open "../../todo.txt" r] + set todo_lines {} + for {gets $fp line} {$line != ""} {gets $fp line} { + lappend todo_lines [split $line .] + } + close $fp + return $todo_lines +} + +proc route_todo {} { + puts "Checking TODO's" + set todo_lines [load_todo] + set srcs {} + foreach todo $todo_lines { + set src [lindex $todo 2] + + if [string match "*CLK_HROW_CK_IN_*" $src] { + lappend srcs $src + } + } + + set srcs [lsort -unique $srcs] + + set nets [get_nets -hierarchical "*clock*"] + set found_wires {} + set remaining_nets {} + foreach net $nets { + set wires [get_wires -of_objects $net] + + foreach wire $wires { + if [regexp "CLK_HROW_CK_IN_\[LR\]\[0-9\]+" $wire] { + # Route already going where we want it, continue + puts "Checking wire $wire." + set wire [lindex [split $wire "/"] 1] + if {[lsearch -regexp $srcs "$wire$"] != -1} { + puts "Found in TODO list, removing from list." + lappend found_wires $wire + # Fix route that is using target net. + set_property is_route_fixed 1 $net + } else { + puts "Wire not in TODO list, adding to reroute list." + lappend remaining_nets $net + } + break + } + } + } + + set found_wires [lsort -unique $found_wires] + foreach wire $found_wires { + puts "Removing $wire" + set srcs [lsearch -regexp -all -inline -not $srcs "$wire$"] + } + + puts "Remaining TODOs:" + foreach src $srcs { + puts $src + } + + set remaining_nets [lsort -unique $remaining_nets] + set completed_todos {} + + foreach net $remaining_nets { + set wires [get_wires -of_objects $net] + + set clk_in_wire "" + foreach wire $wires { + if [regexp "CLK_HROW_CK_IN_(\[LR\])\[0-9\]+" $wire match lr] { + set clk_in_wire $wire + break + } + } + + if {$clk_in_wire == ""} { + error "$net does not appear to be correct net for rerouting?" + } + + puts "" + puts "Rerouting net $net at $clk_in_wire ($lr)" + + # Find an input in the todo list that this can can drive. + foreach src $srcs { + if {[lsearch -exact $completed_todos $src] != -1} { + continue + } + + if [regexp "CLK_HROW_CK_IN_$lr\[0-9\]+" $src] { + puts "Found target pip $src for net $net." + set tile [get_tiles -of_objects $clk_in_wire] + + set target_wire [get_wires "$tile/$src"] + set target_node [get_nodes -of_objects $target_wire] + if {[llength $target_node] == 0} { + error "Failed to find node for $tile/$src." + } + + 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]] + route_design -unroute -nets $net + set new_route [find_routing_path -to $target_node -from $origin_node] + puts "Origin node: $origin_node" + puts "Target wire: $target_wire" + puts "Target node: $target_node" + puts "Destination nodes: $destination_nodes" + + # Only need to set route to one of the destinations. + # Router will handle the rest. + set_property FIXED_ROUTE [concat $new_route [lindex $destination_nodes 0]] $net + + # Remove wire, as we've found a clock to set + lappend completed_todos $src + break + } + } + } +} + proc run {} { create_project -force -part $::env(XRAY_PART) design design read_verilog top.v @@ -36,6 +156,8 @@ proc run {} { place_design route_design + route_todo + route_design write_checkpoint -force design.dcp write_bitstream -force design.bit diff --git a/fuzzers/060-bram-cascades/Makefile b/fuzzers/060-bram-cascades/Makefile index 2b8d61bc..bf8f531b 100644 --- a/fuzzers/060-bram-cascades/Makefile +++ b/fuzzers/060-bram-cascades/Makefile @@ -1,11 +1,12 @@ -MAKETODO_FLAGS=--re "BRAM_.\.BRAM_(?!LOGIC_OUTS).*" export FUZDIR=$(shell pwd) -PIPLIST_TCL=$(FUZDIR)/bram_pip_list.tcl PIP_TYPE?=bram_pips_int -SEG_TYPE?=bram +PIPLIST_TCL=$(FUZDIR)/bram_pip_list.tcl +MAKETODO_FLAGS=--pip-type ${PIP_TYPE} --seg-type bram --re "BRAM_.\.BRAM_(?!LOGIC_OUTS).*" N = 50 + # These PIPs all appear to be either a 0 or 2 bit solution. SEGMATCH_FLAGS=-m 20 -M 45 -c 2 + include ../pip_loop.mk # # Specimens from current run must complete, but previous iterations may exist diff --git a/fuzzers/int_maketodo.py b/fuzzers/int_maketodo.py index 69b1d9e3..f022202d 100644 --- a/fuzzers/int_maketodo.py +++ b/fuzzers/int_maketodo.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 import os, re -import sys from prjxray import util @@ -90,6 +89,7 @@ def run( db_dir, pip_dir, intre, + l, r, pip_type, seg_type, not_endswith=None, @@ -102,18 +102,22 @@ def run( pip_dir = "%s/piplist/build" % (os.getenv("XRAY_FUZZERS_DIR")) assert intre, "RE is required" - maketodo( - "%s/%s_l.txt" % (pip_dir, pip_type), - "%s/segbits_%s_l.db" % (db_dir, seg_type), - intre, - not_endswith, - verbose=verbose) - maketodo( - "%s/%s_r.txt" % (pip_dir, pip_type), - "%s/segbits_%s_r.db" % (db_dir, seg_type), - intre, - not_endswith, - verbose=verbose) + + if l: + maketodo( + "%s/%s_l.txt" % (pip_dir, pip_type), + "%s/segbits_%s_l.db" % (db_dir, seg_type), + intre, + not_endswith, + verbose=verbose) + + if r: + maketodo( + "%s/%s_r.txt" % (pip_dir, pip_type), + "%s/segbits_%s_r.db" % (db_dir, seg_type), + intre, + not_endswith, + verbose=verbose) def main(): @@ -129,6 +133,8 @@ def main(): parser.add_argument('--re', required=True, help='') parser.add_argument('--pip-type', default="pips_int", help='') parser.add_argument('--seg-type', default="int", help='') + util.add_bool_arg(parser, '--l', default=True, help='') + util.add_bool_arg(parser, '--r', default=True, help='') parser.add_argument( '--not-endswith', help='Drop lines if they end with this') args = parser.parse_args() @@ -138,6 +144,8 @@ def main(): db_dir=args.db_dir, pip_dir=args.pip_dir, intre=args.re, + l=args.l, + r=args.r, pip_type=args.pip_type, seg_type=args.seg_type, not_endswith=args.not_endswith, diff --git a/fuzzers/pip_loop.mk b/fuzzers/pip_loop.mk index 1c1497b9..6fad6d66 100644 --- a/fuzzers/pip_loop.mk +++ b/fuzzers/pip_loop.mk @@ -12,10 +12,11 @@ endif # Iteration number (each containing N specimens) # Driven by int_loop.sh ITER ?= 1 -MAKETODO_FLAGS ?= PIP_TYPE?=pips_int -SEG_TYPE?=int +MAKETODO_FLAGS ?=--pip-type pips_int --seg-type int +A_PIPLIST?=$(PIP_TYPE)_l.txt PIPLIST_TCL?=$(XRAY_FUZZERS_DIR)/piplist/piplist.tcl +SPECIMENS_DEPS ?= # See int_loop_check.py # rempips took 35 iters once, so set 50 as a good start point @@ -27,18 +28,20 @@ export FUZDIR=$(shell pwd) all: database -$(SPECIMENS_OK): build/todo.txt +$(SPECIMENS_OK): build/todo.txt $(SPECIMENS_DEPS) mkdir -p build/$(ITER) bash ${XRAY_DIR}/utils/top_generate.sh $(subst /OK,,$@) touch $@ -$(XRAY_FUZZERS_DIR)/piplist/build/$(PIP_TYPE)_l.txt: $(PIPLIST_TCL) +$(XRAY_FUZZERS_DIR)/piplist/build/$(A_PIPLIST): $(PIPLIST_TCL) mkdir -p $(XRAY_FUZZERS_DIR)/piplist/build cd $(XRAY_FUZZERS_DIR)/piplist/build && ${XRAY_VIVADO} -mode batch -source $(PIPLIST_TCL) # Used 1) to see if we are done 2) pips to try in generate.tcl -build/todo.txt: $(XRAY_FUZZERS_DIR)/piplist/build/$(PIP_TYPE)_l.txt $(XRAY_DIR)/fuzzers/int_maketodo.py build/database/seeded - XRAY_DATABASE_DIR=${FUZDIR}/build/database python3 $(XRAY_DIR)/fuzzers/int_maketodo.py --pip-type $(PIP_TYPE) --seg-type $(SEG_TYPE) $(MAKETODO_FLAGS) |sort >build/todo_all.txt +build/todo.txt: $(XRAY_FUZZERS_DIR)/piplist/build/$(A_PIPLIST) $(XRAY_DIR)/fuzzers/int_maketodo.py build/database/seeded + XRAY_DATABASE_DIR=${FUZDIR}/build/database \ + python3 $(XRAY_DIR)/fuzzers/int_maketodo.py \ + $(MAKETODO_FLAGS) |sort >build/todo_all.txt cat build/todo_all.txt | sort -R | head -n$(TODO_N) > build/todo.txt.tmp mv build/todo.txt.tmp build/todo.txt # Per iter files