From e26a6432a4b98707e0d5aa64b9af2529b0b50379 Mon Sep 17 00:00:00 2001 From: Alessandro Comodi Date: Mon, 8 Jul 2019 17:37:00 +0200 Subject: [PATCH 1/5] iob-pips: initial attempt to document ioi pips Signed-off-by: Alessandro Comodi --- fuzzers/037-iob-pips/Makefile | 48 ++++ fuzzers/037-iob-pips/bits.dbf | 0 fuzzers/037-iob-pips/generate.py | 104 ++++++++ fuzzers/037-iob-pips/generate.tcl | 250 ++++++++++++++++++ fuzzers/037-iob-pips/ioi3_pip_list.tcl | 43 ++++ fuzzers/037-iob-pips/output_cmt.tcl | 11 + fuzzers/037-iob-pips/top.py | 336 +++++++++++++++++++++++++ fuzzers/Makefile | 1 + utils/mergedb.sh | 6 + 9 files changed, 799 insertions(+) create mode 100644 fuzzers/037-iob-pips/Makefile create mode 100644 fuzzers/037-iob-pips/bits.dbf create mode 100644 fuzzers/037-iob-pips/generate.py create mode 100644 fuzzers/037-iob-pips/generate.tcl create mode 100644 fuzzers/037-iob-pips/ioi3_pip_list.tcl create mode 100644 fuzzers/037-iob-pips/output_cmt.tcl create mode 100644 fuzzers/037-iob-pips/top.py diff --git a/fuzzers/037-iob-pips/Makefile b/fuzzers/037-iob-pips/Makefile new file mode 100644 index 00000000..f31f236a --- /dev/null +++ b/fuzzers/037-iob-pips/Makefile @@ -0,0 +1,48 @@ +export FUZDIR=$(shell pwd) +PIP_TYPE?=ioi3 +PIPLIST_TCL=$(FUZDIR)/ioi3_pip_list.tcl + +TODO_RE="[LR]IOI3\.(IOI_([IO]LOGIC[01]_CLK(DIV|B)?)|(IOI_OCLK_[01]))\.IOI_LEAF_GCLK[0-9]" + +MAKETODO_FLAGS=--pip-type ${PIP_TYPE} --seg-type $(PIP_TYPE) --re $(TODO_RE) +N = 40 + +SEGMATCH_FLAGS=-c 2 -m 15 -M 30 +SPECIMENS_DEPS=build/cmt_regions.csv + +include ../pip_loop.mk + +build/segbits_ioi3_x.rdb: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} ${SEGMATCH_FLAGS} -o build/segbits_ioi3_x.rdb \ + $(shell find build -name segdata_lioi3*.txt) $(shell find build -name segdata_rioi3*.txt) + +RDBS = build/segbits_ioi3_x.rdb + +database: ${RDBS} + ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ + --seg-fn-in build/segbits_ioi3_x.rdb \ + --seg-fn-out build/segbits_ioi3_x.db + + # Keep a copy to track iter progress + cp build/segbits_ioi3_x.rdb build/$(ITER)/segbits_ioi3_x.rdb + cp build/segbits_ioi3_x.db build/$(ITER)/segbits_ioi3_x.db + + + ${XRAY_MASKMERGE} build/mask_xioi3.db \ + $(shell find build -name segdata_ioi3_l.txt) \ + $(shell find build -name segdata_ioi3_r.txt) + + # 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} ioi3_l build/segbits_ioi3_x.db + XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} ioi3_r build/segbits_ioi3_x.db + +build/cmt_regions.csv: output_cmt.tcl + mkdir -p build + cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_cmt.tcl + +pushdb: + ${XRAY_MERGEDB} lioi3 build/segbits_ioi3_x.db + ${XRAY_MERGEDB} rioi3 build/segbits_ioi3_x.db + +.PHONY: database pushdb diff --git a/fuzzers/037-iob-pips/bits.dbf b/fuzzers/037-iob-pips/bits.dbf new file mode 100644 index 00000000..e69de29b diff --git a/fuzzers/037-iob-pips/generate.py b/fuzzers/037-iob-pips/generate.py new file mode 100644 index 00000000..5ea9eb91 --- /dev/null +++ b/fuzzers/037-iob-pips/generate.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 + +from prjxray.segmaker import Segmaker +import os, re +import os.path + + +def bitfilter(frame, word): + if frame < 26: + return False + return True + + +def main(): + segmk = Segmaker("design.bits") + + tiledata = {} + pipdata = {} + ignpip = set() + + with open(os.path.join(os.getenv('FUZDIR'), '..', 'piplist', 'build', + 'ioi3', 'ioi3_l.txt')) as f: + for l in f: + tile_type, dst, src = l.strip().split('.') + if tile_type not in pipdata: + pipdata[tile_type] = [] + + pipdata[tile_type].append((src, dst)) + + with open(os.path.join(os.getenv('FUZDIR'), '..', 'piplist', 'build', + 'ioi3', 'ioi3_r.txt')) as f: + for l in f: + tile_type, dst, src = l.strip().split('.') + if tile_type not in pipdata: + pipdata[tile_type] = [] + + pipdata[tile_type].append((src, dst)) + + print("Loading tags from design.txt.") + with open("design.txt", "r") as f: + for line in f: + tile, pip, src, dst, pnum, pdir = line.split() + if not tile.startswith('LIOI3') and not tile.startswith('RIOI3'): + continue + + log = open("log.txt", "a") + print(line, file=log) + pip_prefix, _ = pip.split(".") + tile_from_pip, tile_type = pip_prefix.split('/') + + _, src = src.split("/") + _, dst = dst.split("/") + pnum = int(pnum) + pdir = int(pdir) + + if tile not in tiledata: + tiledata[tile] = { + "type": tile_type, + "pips": set(), + "srcs": set(), + "dsts": set(), + } + + tiledata[tile]["pips"].add((src, dst)) + tiledata[tile]["srcs"].add(src) + tiledata[tile]["dsts"].add(dst) + + if pdir == 0: + tiledata[tile]["srcs"].add(dst) + tiledata[tile]["dsts"].add(src) + + if pnum == 1 or pdir == 0: + print("Ignoring pip: {}".format(pip), file=log) + ignpip.add((src, dst)) + + for tile, pips_srcs_dsts in tiledata.items(): + tile_type = pips_srcs_dsts["type"] + + if tile_type.startswith('LIOI3'): + tile_type = 'LIOI3' + elif tile_type.startswith('RIOI3'): + tile_type = 'RIOI3' + + pips = pips_srcs_dsts["pips"] + + for src, dst in pipdata[tile_type]: + if (src, dst) in ignpip: + pass + if re.match(r'.*PHASER.*', src) or re.match(r'.*CLKDIV[PFB].*', + dst): + pass + elif (src, dst) in tiledata[tile]["pips"]: + segmk.add_tile_tag(tile, "%s.%s" % (dst, src), 1) + elif (src, dst) not in tiledata[tile]["pips"]: + segmk.add_tile_tag(tile, "%s.%s" % (dst, src), 0) + + internal_feedback = False + + segmk.compile(bitfilter=bitfilter) + segmk.write() + + +if __name__ == "__main__": + main() diff --git a/fuzzers/037-iob-pips/generate.tcl b/fuzzers/037-iob-pips/generate.tcl new file mode 100644 index 00000000..8b81bcbe --- /dev/null +++ b/fuzzers/037-iob-pips/generate.tcl @@ -0,0 +1,250 @@ +source "$::env(XRAY_DIR)/utils/utils.tcl" + +proc write_pip_txtdata {filename} { + puts "FUZ([pwd]): Writing $filename." + set fp [open $filename w] + set nets [get_nets -hierarchical] + set nnets [llength $nets] + set neti 0 + foreach net $nets { + incr neti + if {($neti % 100) == 0 } { + puts "FUZ([pwd]): Dumping pips from net $net ($neti / $nnets)" + } + foreach pip [get_pips -of_objects $net] { + set tile [get_tiles -of_objects $pip] + set src_wire [get_wires -uphill -of_objects $pip] + set dst_wire [get_wires -downhill -of_objects $pip] + set num_pips [llength [get_nodes -uphill -of_objects [get_nodes -of_objects $dst_wire]]] + set dir_prop [get_property IS_DIRECTIONAL $pip] + puts $fp "$tile $pip $src_wire $dst_wire $num_pips $dir_prop" + } + } + close $fp +} + +proc load_todo {} { + set fp [open "../todo.txt" r] + + # Create map of pip source to remaining destinations for that pip + set todo_map [dict create] + for {gets $fp line} {$line != ""} {gets $fp line} { + set parts [split $line .] + dict lappend todo_map [lindex $parts 1] [list [lindex $parts 0] [lindex $parts 2]] + } + close $fp + return $todo_map +} + +proc route_todo {} { + puts "Checking TODO's" + set todo_map [load_todo] + + puts $todo_map + + set nets [get_nets] + + set todo_nets [dict create] + set used_sources [dict create] + + foreach net $nets { + # Check to see if this net is one we are interested in + set wires [get_wires -of_objects $net -filter {TILE_NAME =~ *IOI3*}] + set is_gclk_net 0 + foreach wire $wires { + if [regexp "IOI_\[IO\]LOGIC\[01\]_CLKB?" $wire] { + set is_gclk_net 1 + break + } + if [regexp "IOI_OCLK_\[01\]" $wire] { + set is_gclk_net 1 + break + } + if [regexp "IOI_\[IO\]LOGIC\[01\]_CLKDIV" $wire] { + set is_gclk_net 1 + break + } + } + + if {$is_gclk_net == 0} { + puts "$net not going to a IOI3 port, skipping." + continue + } + + foreach wire $wires { + set tile [lindex [split $wire /] 0] + set wire [lindex [split $wire /] 1] + set tile_type [get_property TILE_TYPE [get_tiles $tile]] + + if { ![dict exists $todo_map $wire] } { + continue + } + + set srcs [dict get $todo_map $wire] + + # This net is interesting, see if it is already going somewhere we + # want. + set found_target 0 + foreach other_wire $wires { + if { $found_target == 1 } { + break + } + + set other_wire [lindex [split $other_wire /] 1] + + if { $wire == $other_wire } { + continue + } + + foreach src $srcs { + set src_tile_type [lindex $src 0] + + if {$src_tile_type != $tile_type} { + continue + } + + set src_wire [lindex $src 1] + + if { $other_wire == $src } { + set found_target 1 + puts "Interesting net $net already going from $wire to $other_wire." + break + } + } + } + + if { $found_target == 1 } { + # Net has an interesting + continue + } + + dict set todo_nets $net [list $tile $wire] + puts "Interesting net $net (including $wire) is being rerouted." + } + } + + dict for {net tile_wire} $todo_nets { + set tile [lindex $tile_wire 0] + set wire [lindex $tile_wire 1] + set srcs [dict get $todo_map $wire] + set site [lindex [get_sites -of_objects [get_tiles $tile]] 0] + set region [get_clock_regions -of_objects [get_sites $site]] + + puts "Rerouting net $net at $tile / $wire (type $tile_type)" + + set tile_type [get_property TILE_TYPE [get_tiles $tile]] + + set todos {} + foreach src $srcs { + set src_tile_type [lindex $src 0] + if {$src_tile_type != $tile_type} { + continue + } + + set src_wire [lindex $src 1] + + set is_gclk_net 0 + if [regexp "IOI_LEAF_GCLK\[0-9\]+" $src_wire] { + set is_gclk_net 1 + } + + if {$is_gclk_net == 0} { + continue + } + + lappend todos $src_wire + } + + puts "All todos for $tile_type / $wire" + foreach src_wire $todos { + puts " - $src_wire" + } + + route_design -unroute -nets $net + + # Find an input in the todo list that this can can drive. + foreach src_wire $todos { + puts "Attempting to route to $src_wire for net $net." + set target_wire [get_wires "$tile/$src_wire"] + set target_node [get_nodes -of_objects $target_wire] + + if {[llength $target_node] == 0} { + error "Failed to find node for $tile/$src_wire." + } + + if { [regexp ".*TOP.*" $target_node match group] } { + set loc TOP + } elseif { [regexp ".*BOT.*" $target_node match group] } { + set loc BOT + } + + if { [dict exists $used_sources "$region/$loc/$src_wire"] } { + puts "Not routing to $tile / $src_wire, in use." + continue + } + + + set old_nets [get_nets -of_objects $target_node] + + if { $old_nets != {} } { + set old_nets_property [get_property IS_ROUTE_FIXED [get_nets -of_objects $target_node]] + if { $old_nets_property == 0 } { + route_design -unroute -nets $old_nets + } + } + + set origin_node [get_nodes -of_objects [get_site_pins -filter {DIRECTION == OUT} -of_objects $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" + + # Only need to set route to one of the destinations. + # Router will handle the rest. + set_property FIXED_ROUTE $new_route $net + + dict set used_sources "$region/$loc/$src_wire" 1 + break + } + } +} + +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] + set_property IS_ENABLED 0 [get_drc_checks {PDRC-25}] + set_property IS_ENABLED 0 [get_drc_checks {PDRC-39}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-4}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-5}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-98}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-99}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-123}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-144}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-1576}] + set_property IS_ENABLED 0 [get_drc_checks {AVAL-74}] + set_property IS_ENABLED 0 [get_drc_checks {AVAL-81}] + set_property IS_ENABLED 0 [get_drc_checks {DRC INBB-1}] + + set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets] + + place_design + route_design + write_checkpoint -force design_before.dcp + + route_todo + route_design + write_checkpoint -force design_after.dcp + + set_property SEVERITY {Warning} [get_drc_checks UCIO-1] + set_property SEVERITY {Warning} [get_drc_checks NSTD-1] + + write_bitstream -force design.bit + write_pip_txtdata design.txt +} + +run diff --git a/fuzzers/037-iob-pips/ioi3_pip_list.tcl b/fuzzers/037-iob-pips/ioi3_pip_list.tcl new file mode 100644 index 00000000..6eb726ca --- /dev/null +++ b/fuzzers/037-iob-pips/ioi3_pip_list.tcl @@ -0,0 +1,43 @@ +proc print_tile_pips {tile_type filename} { + set fp [open $filename w] + set pips [dict create] + foreach tile [get_tiles -filter "TYPE == $tile_type"] { + puts "Dumping PIPs for tile $tile ($tile_type) to $filename." + foreach pip [lsort [get_pips -of_objects $tile]] { + set src [get_wires -uphill -of_objects $pip] + set dst [get_wires -downhill -of_objects $pip] + + # Skip pips with disconnected nodes + set src_node [get_nodes -of_objects $src] + + if { $src_node == {} } { + continue + } + + set dst_node [get_nodes -of_objects $src] + if { $dst_node == {} } { + continue + } + + if {[llength [get_nodes -uphill -of_objects [get_nodes -of_objects $dst]]] != 1} { + set pip_string "$tile_type.[regsub {.*/} $dst ""].[regsub {.*/} $src ""]" + if ![dict exists $pips $pip_string] { + puts $fp $pip_string + dict set pips $pip_string 1 + } + } + } + } + close $fp +} + +create_project -force -part $::env(XRAY_PART) design design +set_property design_mode PinPlanning [current_fileset] +open_io_design -name io_1 + +# Cleaning ioi3.txt pip file +set fp [open ioi3.txt w] +close $fp + +print_tile_pips LIOI3 ioi3_l.txt +print_tile_pips RIOI3 ioi3_r.txt diff --git a/fuzzers/037-iob-pips/output_cmt.tcl b/fuzzers/037-iob-pips/output_cmt.tcl new file mode 100644 index 00000000..663789a5 --- /dev/null +++ b/fuzzers/037-iob-pips/output_cmt.tcl @@ -0,0 +1,11 @@ +create_project -force -part $::env(XRAY_PART) design design +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 BUFHCE BUFR BUFMRCE BUFIO ILOGICE3 OLOGICE3 IDELAYE2 IDELAYCTRL PLLE2_ADV} { + foreach site [get_sites -filter "SITE_TYPE == $site_type"] { + puts $fp "$site,[get_property CLOCK_REGION $site]" + } +} +close $fp diff --git a/fuzzers/037-iob-pips/top.py b/fuzzers/037-iob-pips/top.py new file mode 100644 index 00000000..e5fc72ef --- /dev/null +++ b/fuzzers/037-iob-pips/top.py @@ -0,0 +1,336 @@ +import json +import io +import os +import random +import math +random.seed(int(os.getenv("SEED"), 16)) +from prjxray import util +from prjxray import lut_maker +from prjxray import verilog +from prjxray.db import Database + +NOT_INCLUDED_TILES = ['LIOI3_SING', 'RIOI3_SING'] + +SITE_TYPES = ['OLOGICE3', 'ILOGICE3'] + +REGIONAL_CLOCK_BUFFERS = ['BUFHCE', 'BUFIO'] +GLOBAL_CLOCK_BUFFERS = ['BUFGCTRL'] +CLOCK_BUFFERS = REGIONAL_CLOCK_BUFFERS + GLOBAL_CLOCK_BUFFERS + +MAX_REG_CLK_BUF = 2 +MAX_GLB_CLK_BUF = 24 +CUR_CLK = 0 +MAX_ATTEMPTS = 50 + + +def get_location(tile_name, divisor): + y_location = int(tile_name.split("Y")[-1]) + + if math.floor(y_location / divisor) % 2 == 0: + # Location is on the bottom of the row/tile + return "BOT" + else: + return "TOP" + + +def read_site_to_cmt(): + """ Yields clock sources and which CMT they route within. """ + with open(os.path.join(os.getenv('FUZDIR'), 'build', + 'cmt_regions.csv')) as f: + for l in f: + site, cmt = l.strip().split(',') + yield (site, cmt) + + +def gen_sites(site_types): + ''' + Generates all sites belonging to `site_types` of + a desired `tile` + ''' + db = Database(util.get_db_root()) + grid = db.grid() + + tiles = grid.tiles() + + #Randomize tiles + tiles_list = list(tiles) + random.shuffle(tiles_list) + + for tile_name in tiles: + loc = grid.loc_of_tilename(tile_name) + gridinfo = grid.gridinfo_at_loc(loc) + tile_type = gridinfo.tile_type + + for site_name, site_type in gridinfo.sites.items(): + if site_type in site_types: + yield tile_type, tile_name, site_type, site_name + + +def generate_mmcm(site_to_cmt, clock_region): + mmcm_clocks = None + + for _, _, _, site in gen_sites('MMCME2_ADV'): + mmcm_region = site_to_cmt[site] + + if mmcm_region == clock_region: + mmcm_clocks = [ + 'mmcm_clock_{site}_{idx}'.format(site=site, idx=idx) + for idx in range(3) + ] + + print( + """ + wire {c0}, {c1}, {c2}; + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + MMCME2_ADV mmcm_{site} ( + .CLKOUT0({c0}), + .CLKOUT1({c1}), + .CLKOUT2({c2}) + );""".format( + site=site, + c0=mmcm_clocks[0], + c1=mmcm_clocks[1], + c2=mmcm_clocks[2])) + + if not mmcm_clocks: + return None + + return mmcm_clocks + + +def generate_glb_clk_buf(clock_regions, mmcm_clocks_dict): + clk_buf_count = 0 + + clock_signals = [] + + for tile_type, _, site_type, site_name in gen_sites(GLOBAL_CLOCK_BUFFERS): + + if clk_buf_count >= MAX_GLB_CLK_BUF: + break + + clock_signal = "buf_clk_{site}".format(site=site_name) + + if site_type == 'BUFGCTRL': + mmcm_clocks = [] + + for clock_region in clock_regions: + # BUFGCTRL must have the clock coming from the same fabric row + if ('Y0' in clock_region and tile_type == 'CLK_BUFG_BOT_R' + ) or ('Y0' not in clock_region + and tile_type == 'CLK_BUFG_TOP_R'): + mmcm_clocks = mmcm_clocks_dict[clock_region] + break + + assert mmcm_clocks, "No clock can be produced. Buffer not instantiated" + + print( + ''' + wire {clk_out}; + + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFG buf_{site} (.I({clk_in}), .O({clk_out}));'''.format( + clk_in=random.choice(mmcm_clocks), + clk_out=clock_signal, + site=site_name)) + + else: + assert False, "The site is somehow corrupted" + + clk_buf_count += 1 + + clock_signals.append(clock_signal) + + return clock_signals + + +def generate_reg_clk_buf(site_to_cmt, clock_region, mmcm_clocks, buf_type): + clk_buf_count = 0 + clock_signals = [] + + for tile_type, _, site_type, site_name in gen_sites( + REGIONAL_CLOCK_BUFFERS): + buf_region = site_to_cmt[site_name] + + if clk_buf_count >= MAX_REG_CLK_BUF: + break + + if buf_type != site_type: + continue + + if buf_region != clock_region: + continue + + clock_signal = "buf_clk_{site}".format(site=site_name) + + if site_type == 'BUFR': + print( + ''' + wire {clk_out}; + + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFR buf_{site} (.I({clk_in}), .O({clk_out}));'''.format( + clk_in=random.choice(mmcm_clocks), + clk_out=clock_signal, + site=site_name)) + + elif site_type == 'BUFIO': + print( + ''' + wire {clk_out}; + + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFIO buf_{site} (.I({clk_in}), .O({clk_out}));'''.format( + clk_in=random.choice(mmcm_clocks), + clk_out=clock_signal, + site=site_name)) + + elif site_type == 'BUFHCE': + print( + ''' + wire {clk_out}; + + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFH buf_{site} (.I({clk_in}), .O({clk_out}));'''.format( + clk_in=random.choice(mmcm_clocks), + clk_out=clock_signal, + site=site_name)) + + else: + assert False, "The site is somehow corrupted" + + clk_buf_count += 1 + + clock_signals.append(clock_signal) + + return clock_signals + + +def get_clock_signal(clock_signals, clock_types): + ''' + Get a unique clock signals for a specific tile. + ''' + global CUR_CLK + + clock_signal_string = '' + is_first_clock = True + + for clock_type in clock_types: + if random.choice([True, True, False]): + continue + + clock_signal = clock_signals[CUR_CLK] + if is_first_clock: + clock_signal_string += ''' + .{}({})'''.format(clock_type, clock_signal) + else: + clock_signal_string += ''', + .{}({})'''.format(clock_type, clock_signal) + + is_first_clock = False + + CUR_CLK = (CUR_CLK + 1) % MAX_GLB_CLK_BUF + + return clock_signal_string + + +def run(): + + global CUR_CLK + # One buffer type for each specimen + buf_type = random.choice(GLOBAL_CLOCK_BUFFERS) + + site_location = random.choice(['TOP', 'BOT']) + + site_to_cmt = dict(read_site_to_cmt()) + clock_regions = list(dict.fromkeys(site_to_cmt.values())) + + print("module top();") + + clock_mmcm_dict = {} + clock_signals_dict = {} + site_types_dict = {} + + # Generate MMCM Clock generator + for clock_region in clock_regions: + mmcm_clocks = generate_mmcm(site_to_cmt, clock_region) + + if mmcm_clocks: + clock_mmcm_dict[clock_region] = mmcm_clocks + clock_signals_dict[clock_region] = [] + + if buf_type in REGIONAL_CLOCK_BUFFERS: + clock_signals_dict[clock_region] = generate_reg_clk_buf( + site_to_cmt, clock_region, mmcm_clocks, buf_type) + else: + clock_regions.remove(clock_region) + + if buf_type in GLOBAL_CLOCK_BUFFERS: + clock_signals = generate_glb_clk_buf(clock_regions, clock_mmcm_dict) + + for clock_region in clock_regions: + clock_signals_dict[clock_region] = clock_signals + site_types_dict[clock_region] = random.choice(SITE_TYPES) + + half_column_used_clocks = {} + + for tile_type, tile_name, site_type, site_name in gen_sites(SITE_TYPES): + if tile_type in NOT_INCLUDED_TILES: + continue + + if random.choice([True, True, False]): + continue + + site_region = site_to_cmt[site_name] + + if site_type != site_types_dict[site_region]: + continue + + clock_signals = clock_signals_dict[site_region] + + bot_or_top = get_location(site_name, 1) + + half_column = '{}_{}'.format(site_region, get_location(tile_name, 25)) + + if half_column not in half_column_used_clocks: + half_column_used_clocks[half_column] = { + 'TOP': { + 'ILOGIC': + get_clock_signal(clock_signals, ['CLK', 'CLKB', 'CLKDIV']), + 'OLOGIC': + get_clock_signal(clock_signals, ['CLK', 'CLKDIV']) + }, + 'BOT': { + 'ILOGIC': + get_clock_signal(clock_signals, ['CLK', 'CLKB', 'CLKDIV']), + 'OLOGIC': + get_clock_signal(clock_signals, ['CLK', 'CLKDIV']) + } + } + + if site_type == 'ILOGICE3': + print( + ''' + (* KEEP, DONT_TOUCH, LOC = "{site_name}" *) + ISERDESE2 #( + .DATA_RATE("SDR") + ) iserdes_{site_name} ({clk});'''.format( + site_name=site_name, + clk=half_column_used_clocks[half_column][bot_or_top] + ['ILOGIC'])) + elif site_type == 'OLOGICE3': + print( + ''' + (* KEEP, DONT_TOUCH, LOC = "{site_name}" *) + OSERDESE2 #( + .DATA_RATE_OQ("SDR"), + .DATA_RATE_TQ("SDR") + ) oserdes_{site_name} ({clk});'''.format( + site_name=site_name, + clk=half_column_used_clocks[half_column][bot_or_top] + ['OLOGIC'])) + + print("endmodule") + + +if __name__ == '__main__': + run() diff --git a/fuzzers/Makefile b/fuzzers/Makefile index c515cde3..532fa5d1 100644 --- a/fuzzers/Makefile +++ b/fuzzers/Makefile @@ -88,6 +88,7 @@ $(eval $(call fuzzer,034-cmt-pll-pips,005-tilegrid)) $(eval $(call fuzzer,035-iob-ilogic,005-tilegrid)) $(eval $(call fuzzer,035a-iob-idelay,005-tilegrid)) $(eval $(call fuzzer,036-iob-ologic,005-tilegrid)) +$(eval $(call fuzzer,037-iob-pips,005-tilegrid)) $(eval $(call fuzzer,038-cfg,005-tilegrid)) $(eval $(call fuzzer,040-clk-hrow-config,005-tilegrid)) $(eval $(call fuzzer,041-clk-hrow-pips,005-tilegrid)) diff --git a/utils/mergedb.sh b/utils/mergedb.sh index 6e85a2c3..d39cd95b 100755 --- a/utils/mergedb.sh +++ b/utils/mergedb.sh @@ -144,6 +144,12 @@ case "$1" in hclk_ioi3) cp "$2" "$tmp1" ;; + ioi3_l) + sed < "$2" > "$tmp1" -e 's/^IOI3\./LIOI3./' ;; + + ioi3_r) + sed < "$2" > "$tmp1" -e 's/^IOI3\./RIOI3./' ;; + mask_*) db=$XRAY_DATABASE_DIR/$XRAY_DATABASE/$1.db ismask=true From b1780e76a07c4f4847e522e7b354b12e5ea2ce8b Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 19 Jul 2019 16:53:12 -0700 Subject: [PATCH 2/5] Refactor 037 to capture non-inverted pips. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/000-init-db/Makefile | 2 + fuzzers/037-iob-pips/Makefile | 2 +- fuzzers/037-iob-pips/generate.py | 4 +- fuzzers/037-iob-pips/generate.tcl | 17 +- fuzzers/037-iob-pips/top.py | 461 ++++++++++++++---------------- 5 files changed, 226 insertions(+), 260 deletions(-) diff --git a/fuzzers/000-init-db/Makefile b/fuzzers/000-init-db/Makefile index ebef99a1..f2c368d5 100644 --- a/fuzzers/000-init-db/Makefile +++ b/fuzzers/000-init-db/Makefile @@ -22,6 +22,8 @@ SEGBITS=\ dsp \ hclk \ int \ + ioi \ + ioi3 \ SEGBITS_R=\ clk_bufg_top \ diff --git a/fuzzers/037-iob-pips/Makefile b/fuzzers/037-iob-pips/Makefile index f31f236a..e77c23b4 100644 --- a/fuzzers/037-iob-pips/Makefile +++ b/fuzzers/037-iob-pips/Makefile @@ -7,7 +7,7 @@ TODO_RE="[LR]IOI3\.(IOI_([IO]LOGIC[01]_CLK(DIV|B)?)|(IOI_OCLK_[01]))\.IOI_LEAF_G MAKETODO_FLAGS=--pip-type ${PIP_TYPE} --seg-type $(PIP_TYPE) --re $(TODO_RE) N = 40 -SEGMATCH_FLAGS=-c 2 -m 15 -M 30 +SEGMATCH_FLAGS=-c -1 -m 15 -M 30 SPECIMENS_DEPS=build/cmt_regions.csv include ../pip_loop.mk diff --git a/fuzzers/037-iob-pips/generate.py b/fuzzers/037-iob-pips/generate.py index 5ea9eb91..bfc426ac 100644 --- a/fuzzers/037-iob-pips/generate.py +++ b/fuzzers/037-iob-pips/generate.py @@ -6,7 +6,7 @@ import os.path def bitfilter(frame, word): - if frame < 26: + if frame < 28: return False return True @@ -91,7 +91,7 @@ def main(): pass elif (src, dst) in tiledata[tile]["pips"]: segmk.add_tile_tag(tile, "%s.%s" % (dst, src), 1) - elif (src, dst) not in tiledata[tile]["pips"]: + elif dst not in tiledata[tile]["dsts"]: segmk.add_tile_tag(tile, "%s.%s" % (dst, src), 0) internal_feedback = False diff --git a/fuzzers/037-iob-pips/generate.tcl b/fuzzers/037-iob-pips/generate.tcl index 8b81bcbe..a2d15ddf 100644 --- a/fuzzers/037-iob-pips/generate.tcl +++ b/fuzzers/037-iob-pips/generate.tcl @@ -217,32 +217,27 @@ proc run {} { set_property CFGBVS VCCO [current_design] set_property CONFIG_VOLTAGE 3.3 [current_design] set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] - set_property IS_ENABLED 0 [get_drc_checks {PDRC-25}] - set_property IS_ENABLED 0 [get_drc_checks {PDRC-39}] + set_property IS_ENABLED 0 [get_drc_checks {AVAL-74}] + set_property IS_ENABLED 0 [get_drc_checks {PDRC-26}] set_property IS_ENABLED 0 [get_drc_checks {REQP-4}] set_property IS_ENABLED 0 [get_drc_checks {REQP-5}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-13}] set_property IS_ENABLED 0 [get_drc_checks {REQP-98}] set_property IS_ENABLED 0 [get_drc_checks {REQP-99}] - set_property IS_ENABLED 0 [get_drc_checks {REQP-123}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-115}] set_property IS_ENABLED 0 [get_drc_checks {REQP-144}] - set_property IS_ENABLED 0 [get_drc_checks {REQP-1576}] - set_property IS_ENABLED 0 [get_drc_checks {AVAL-74}] - set_property IS_ENABLED 0 [get_drc_checks {AVAL-81}] - set_property IS_ENABLED 0 [get_drc_checks {DRC INBB-1}] set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets] place_design + write_checkpoint -force design_before_route.dcp route_design write_checkpoint -force design_before.dcp - route_todo + #route_todo route_design write_checkpoint -force design_after.dcp - set_property SEVERITY {Warning} [get_drc_checks UCIO-1] - set_property SEVERITY {Warning} [get_drc_checks NSTD-1] - write_bitstream -force design.bit write_pip_txtdata design.txt } diff --git a/fuzzers/037-iob-pips/top.py b/fuzzers/037-iob-pips/top.py index e5fc72ef..e240db93 100644 --- a/fuzzers/037-iob-pips/top.py +++ b/fuzzers/037-iob-pips/top.py @@ -1,22 +1,16 @@ -import json -import io import os import random import math random.seed(int(os.getenv("SEED"), 16)) from prjxray import util -from prjxray import lut_maker from prjxray import verilog +from prjxray import lut_maker from prjxray.db import Database NOT_INCLUDED_TILES = ['LIOI3_SING', 'RIOI3_SING'] SITE_TYPES = ['OLOGICE3', 'ILOGICE3'] -REGIONAL_CLOCK_BUFFERS = ['BUFHCE', 'BUFIO'] -GLOBAL_CLOCK_BUFFERS = ['BUFGCTRL'] -CLOCK_BUFFERS = REGIONAL_CLOCK_BUFFERS + GLOBAL_CLOCK_BUFFERS - MAX_REG_CLK_BUF = 2 MAX_GLB_CLK_BUF = 24 CUR_CLK = 0 @@ -42,292 +36,267 @@ def read_site_to_cmt(): yield (site, cmt) -def gen_sites(site_types): - ''' - Generates all sites belonging to `site_types` of - a desired `tile` - ''' +def gen_sites(): + ''' Return dict of ISERDES/OSERDES locations. ''' db = Database(util.get_db_root()) grid = db.grid() + xy_fun = util.create_xy_fun('\S+') + tiles = grid.tiles() - #Randomize tiles - tiles_list = list(tiles) - random.shuffle(tiles_list) - - for tile_name in tiles: + for tile_name in sorted(tiles): loc = grid.loc_of_tilename(tile_name) gridinfo = grid.gridinfo_at_loc(loc) tile_type = gridinfo.tile_type + tile = { + 'tile': tile_name, + 'tile_type': tile_type, + 'ioi_sites': {} + } + for site_name, site_type in gridinfo.sites.items(): - if site_type in site_types: - yield tile_type, tile_name, site_type, site_name + if site_type in SITE_TYPES: + xy = xy_fun(site_name) + if xy not in tile['ioi_sites']: + tile['ioi_sites'][xy] = {} + + tile['ioi_sites'][xy][site_type] = site_name + + yield tile -def generate_mmcm(site_to_cmt, clock_region): - mmcm_clocks = None +class ClockSources(object): + def __init__(self): + self.site_to_cmt = dict(read_site_to_cmt()) - for _, _, _, site in gen_sites('MMCME2_ADV'): - mmcm_region = site_to_cmt[site] + self.leaf_gclks = {} + self.ioclks = {} + self.rclks = {} + self.selected_leaf_gclks = {} + self.lut_maker = lut_maker.LutMaker() - if mmcm_region == clock_region: - mmcm_clocks = [ - 'mmcm_clock_{site}_{idx}'.format(site=site, idx=idx) - for idx in range(3) - ] + for cmt in set(self.site_to_cmt.values()): + self.leaf_gclks[cmt] = [] + self.ioclks[cmt] = [] + self.rclks[cmt] = [] - print( - """ - wire {c0}, {c1}, {c2}; - (* KEEP, DONT_TOUCH, LOC = "{site}" *) - MMCME2_ADV mmcm_{site} ( - .CLKOUT0({c0}), - .CLKOUT1({c1}), - .CLKOUT2({c2}) - );""".format( + def init_clocks(self): + """ Initialize all IOI clock sources. """ + for site, cmt in self.site_to_cmt.items(): + clk = 'clk_' + site + if 'BUFHCE' in site: + print(""" + wire {clk}; + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFH bufh_{site}( + .O({clk}) + ); + """.format( + clk=clk, site=site, - c0=mmcm_clocks[0], - c1=mmcm_clocks[1], - c2=mmcm_clocks[2])) + )) - if not mmcm_clocks: - return None + self.leaf_gclks[cmt].append(clk) - return mmcm_clocks + if 'BUFIO' in site: + print(""" + wire {clk}; + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFIO bufio_{site}( + .O({clk}) + ); + """.format( + clk=clk, + site=site, + )) + + self.ioclks[cmt].append(clk) + + if 'BUFR' in site: + print(""" + wire {clk}; + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFR bufr_{site}( + .O({clk}) + ); + """.format( + clk=clk, + site=site, + )) + + self.rclks[cmt].append(clk) -def generate_glb_clk_buf(clock_regions, mmcm_clocks_dict): - clk_buf_count = 0 + # Choose 6 leaf_gclks to be used in each CMT. + for cmt in self.leaf_gclks: + self.selected_leaf_gclks[cmt] = random.choices(self.leaf_gclks[cmt], k=6) - clock_signals = [] + def get_clock(self, site, allow_ioclks, allow_rclks, allow_fabric=True, allow_empty=True): + cmt = self.site_to_cmt[site] + choices = [] + if allow_fabric: + choices.append('lut') - for tile_type, _, site_type, site_name in gen_sites(GLOBAL_CLOCK_BUFFERS): + if allow_empty: + choices.append('') - if clk_buf_count >= MAX_GLB_CLK_BUF: - break + choices.extend(self.selected_leaf_gclks[cmt]) + if allow_ioclks: + choices.extend(self.ioclks[cmt]) - clock_signal = "buf_clk_{site}".format(site=site_name) + if allow_rclks: + choices.extend(self.rclks[cmt]) - if site_type == 'BUFGCTRL': - mmcm_clocks = [] - - for clock_region in clock_regions: - # BUFGCTRL must have the clock coming from the same fabric row - if ('Y0' in clock_region and tile_type == 'CLK_BUFG_BOT_R' - ) or ('Y0' not in clock_region - and tile_type == 'CLK_BUFG_TOP_R'): - mmcm_clocks = mmcm_clocks_dict[clock_region] - break - - assert mmcm_clocks, "No clock can be produced. Buffer not instantiated" - - print( - ''' - wire {clk_out}; - - (* KEEP, DONT_TOUCH, LOC = "{site}" *) - BUFG buf_{site} (.I({clk_in}), .O({clk_out}));'''.format( - clk_in=random.choice(mmcm_clocks), - clk_out=clock_signal, - site=site_name)) - - else: - assert False, "The site is somehow corrupted" - - clk_buf_count += 1 - - clock_signals.append(clock_signal) - - return clock_signals + clock = random.choice(choices) + is_lut = False + if clock == "lut": + clock = self.lut_maker.get_next_output_net() + is_lut = True + return clock, is_lut -def generate_reg_clk_buf(site_to_cmt, clock_region, mmcm_clocks, buf_type): - clk_buf_count = 0 - clock_signals = [] - - for tile_type, _, site_type, site_name in gen_sites( - REGIONAL_CLOCK_BUFFERS): - buf_region = site_to_cmt[site_name] - - if clk_buf_count >= MAX_REG_CLK_BUF: - break - - if buf_type != site_type: - continue - - if buf_region != clock_region: - continue - - clock_signal = "buf_clk_{site}".format(site=site_name) - - if site_type == 'BUFR': - print( - ''' - wire {clk_out}; - - (* KEEP, DONT_TOUCH, LOC = "{site}" *) - BUFR buf_{site} (.I({clk_in}), .O({clk_out}));'''.format( - clk_in=random.choice(mmcm_clocks), - clk_out=clock_signal, - site=site_name)) - - elif site_type == 'BUFIO': - print( - ''' - wire {clk_out}; - - (* KEEP, DONT_TOUCH, LOC = "{site}" *) - BUFIO buf_{site} (.I({clk_in}), .O({clk_out}));'''.format( - clk_in=random.choice(mmcm_clocks), - clk_out=clock_signal, - site=site_name)) - - elif site_type == 'BUFHCE': - print( - ''' - wire {clk_out}; - - (* KEEP, DONT_TOUCH, LOC = "{site}" *) - BUFH buf_{site} (.I({clk_in}), .O({clk_out}));'''.format( - clk_in=random.choice(mmcm_clocks), - clk_out=clock_signal, - site=site_name)) - - else: - assert False, "The site is somehow corrupted" - - clk_buf_count += 1 - - clock_signals.append(clock_signal) - - return clock_signals - - -def get_clock_signal(clock_signals, clock_types): - ''' - Get a unique clock signals for a specific tile. - ''' - global CUR_CLK - - clock_signal_string = '' - is_first_clock = True - - for clock_type in clock_types: - if random.choice([True, True, False]): - continue - - clock_signal = clock_signals[CUR_CLK] - if is_first_clock: - clock_signal_string += ''' - .{}({})'''.format(clock_type, clock_signal) - else: - clock_signal_string += ''', - .{}({})'''.format(clock_type, clock_signal) - - is_first_clock = False - - CUR_CLK = (CUR_CLK + 1) % MAX_GLB_CLK_BUF - - return clock_signal_string - +def add_port(ports, port, signal): + ports.append('.{}({})'.format(port, signal)) def run(): - - global CUR_CLK - # One buffer type for each specimen - buf_type = random.choice(GLOBAL_CLOCK_BUFFERS) - - site_location = random.choice(['TOP', 'BOT']) - - site_to_cmt = dict(read_site_to_cmt()) - clock_regions = list(dict.fromkeys(site_to_cmt.values())) - print("module top();") - clock_mmcm_dict = {} - clock_signals_dict = {} - site_types_dict = {} + clocks = ClockSources() + clocks.init_clocks() - # Generate MMCM Clock generator - for clock_region in clock_regions: - mmcm_clocks = generate_mmcm(site_to_cmt, clock_region) + """ - if mmcm_clocks: - clock_mmcm_dict[clock_region] = mmcm_clocks - clock_signals_dict[clock_region] = [] + ISERDESE2 clock sources: - if buf_type in REGIONAL_CLOCK_BUFFERS: - clock_signals_dict[clock_region] = generate_reg_clk_buf( - site_to_cmt, clock_region, mmcm_clocks, buf_type) - else: - clock_regions.remove(clock_region) + CLK/CLKB: + - Allows LEAF_GCLK, IOCLKS, RCLKS and fabric + - Dedicated pips - if buf_type in GLOBAL_CLOCK_BUFFERS: - clock_signals = generate_glb_clk_buf(clock_regions, clock_mmcm_dict) + CLKDIV: + - No dedicated pips, uses fabric clock in. - for clock_region in clock_regions: - clock_signals_dict[clock_region] = clock_signals - site_types_dict[clock_region] = random.choice(SITE_TYPES) + CLKDIVP: + - Has pips, MIG only, PHASER or fabric. - half_column_used_clocks = {} + OCLK/OCLKB: + - Allows LEAF_GCLK, IOCLKS, RCLKS and fabric + - Must match OSERDESE2:CLK/CLKB - for tile_type, tile_name, site_type, site_name in gen_sites(SITE_TYPES): - if tile_type in NOT_INCLUDED_TILES: + OSERDESE2 clock sources: + + CLKDIV/CLKDIVB: + - Allows LEAF_GCLK and RCLKS and fabric + - Dedicated pips + + CLKDIVF/CLKDIVFB: + - Allows LEAF_GCLK and RCLKS and fabric + - No explicit port, follows CLKDIV/CLKDIVB? + """ + + output = [] + + for tile in gen_sites(): + if tile['tile_type'] in NOT_INCLUDED_TILES: continue - if random.choice([True, True, False]): - continue - site_region = site_to_cmt[site_name] + for xy in tile['ioi_sites']: + use_iserdes = random.randint(0, 1) + use_oserdes = random.randint(0, 1) - if site_type != site_types_dict[site_region]: - continue + ilogic_site = tile['ioi_sites'][xy]['ILOGICE3'] + ologic_site = tile['ioi_sites'][xy]['OLOGICE3'] - clock_signals = clock_signals_dict[site_region] + if use_oserdes: + oclk, _ = clocks.get_clock( + ologic_site, + allow_ioclks=True, + allow_rclks=True) - bot_or_top = get_location(site_name, 1) + oclkb = oclk + else: + oclk, is_lut = clocks.get_clock( + ilogic_site, + allow_ioclks=True, + allow_rclks=True) - half_column = '{}_{}'.format(site_region, get_location(tile_name, 25)) + if random.randint(0, 1): + oclkb = oclk + else: + oclkb, _ = clocks.get_clock( + ilogic_site, + allow_ioclks=True, + allow_rclks=True, + allow_fabric=not is_lut) - if half_column not in half_column_used_clocks: - half_column_used_clocks[half_column] = { - 'TOP': { - 'ILOGIC': - get_clock_signal(clock_signals, ['CLK', 'CLKB', 'CLKDIV']), - 'OLOGIC': - get_clock_signal(clock_signals, ['CLK', 'CLKDIV']) - }, - 'BOT': { - 'ILOGIC': - get_clock_signal(clock_signals, ['CLK', 'CLKB', 'CLKDIV']), - 'OLOGIC': - get_clock_signal(clock_signals, ['CLK', 'CLKDIV']) - } - } + if use_iserdes: + DATA_RATE = random.choice(['DDR', 'SDR']) + ports = [] - if site_type == 'ILOGICE3': - print( - ''' - (* KEEP, DONT_TOUCH, LOC = "{site_name}" *) - ISERDESE2 #( - .DATA_RATE("SDR") - ) iserdes_{site_name} ({clk});'''.format( - site_name=site_name, - clk=half_column_used_clocks[half_column][bot_or_top] - ['ILOGIC'])) - elif site_type == 'OLOGICE3': - print( - ''' - (* KEEP, DONT_TOUCH, LOC = "{site_name}" *) - OSERDESE2 #( - .DATA_RATE_OQ("SDR"), - .DATA_RATE_TQ("SDR") - ) oserdes_{site_name} ({clk});'''.format( - site_name=site_name, - clk=half_column_used_clocks[half_column][bot_or_top] - ['OLOGIC'])) + clk, is_lut = clocks.get_clock( + ilogic_site, + allow_ioclks=True, + allow_rclks=True, + allow_empty=DATA_RATE=='SDR') + if random.randint(0, 1): + clkb = clk + else: + clkb, _ = clocks.get_clock( + ilogic_site, + allow_ioclks=True, + allow_rclks=True, + allow_empty=DATA_RATE=='SDR') + + add_port(ports, 'CLK', clk) + add_port(ports, 'CLKB', clkb) + add_port(ports, 'OCLK', oclk) + add_port(ports, 'OCLKB', oclkb) + + output.append(""" + (* KEEP, DONT_TOUCH, LOC="{site}" *) + ISERDESE2 #( + .DATA_RATE({DATA_RATE}), + .INTERFACE_TYPE("MEMORY_QDR"), + .IS_CLK_INVERTED({IS_CLK_INVERTED}), + .IS_CLKB_INVERTED({IS_CLKB_INVERTED}) + ) iserdes_{site}( + {ports});""".format( + site=ilogic_site, + ports=',\n'.join(ports), + DATA_RATE=verilog.quote(DATA_RATE), + IS_CLK_INVERTED=random.randint(0, 1), + IS_CLKB_INVERTED=random.randint(0, 1), + )) + + if use_oserdes: + ports = [] + + add_port(ports, 'CLKDIV', clocks.get_clock( + ologic_site, + allow_ioclks=False, + allow_rclks=True, + )[0]) + + add_port(ports, 'CLK', oclk) + + output.append(""" + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + OSERDESE2 #( + .DATA_RATE_OQ("SDR"), + .DATA_RATE_TQ("SDR") + ) oserdes_{site} ( + {ports});""".format( + site=ologic_site, + ports=',\n'.join(ports), + )) + + for s in clocks.lut_maker.create_wires_and_luts(): + print(s) + + for s in output: + print(s) print("endmodule") From e3b5fe97f41c00ac29e8a1552a1568e67ec2cce3 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 19 Jul 2019 17:41:11 -0700 Subject: [PATCH 3/5] Make CLKB for ISERDES work correctly. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/037-iob-pips/top.py | 82 +++++++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 16 deletions(-) diff --git a/fuzzers/037-iob-pips/top.py b/fuzzers/037-iob-pips/top.py index e240db93..d6b5185d 100644 --- a/fuzzers/037-iob-pips/top.py +++ b/fuzzers/037-iob-pips/top.py @@ -203,7 +203,7 @@ def run(): for xy in tile['ioi_sites']: - use_iserdes = random.randint(0, 1) + ilogic_site_type = random.choice([None, 'ISERDESE2', 'IDDR']) use_oserdes = random.randint(0, 1) ilogic_site = tile['ioi_sites'][xy]['ILOGICE3'] @@ -231,23 +231,35 @@ def run(): allow_rclks=True, allow_fabric=not is_lut) - if use_iserdes: - DATA_RATE = random.choice(['DDR', 'SDR']) - ports = [] - - clk, is_lut = clocks.get_clock( - ilogic_site, - allow_ioclks=True, - allow_rclks=True, - allow_empty=DATA_RATE=='SDR') - if random.randint(0, 1): - clkb = clk - else: + DATA_RATE = random.choice(['DDR', 'SDR']) + clk, is_lut = clocks.get_clock( + ilogic_site, + allow_ioclks=True, + allow_rclks=True, + allow_empty=DATA_RATE=='SDR') + if False: + clkb = clk + else: + clkb = clk + while clkb == clk: clkb, _ = clocks.get_clock( ilogic_site, allow_ioclks=True, allow_rclks=True, - allow_empty=DATA_RATE=='SDR') + allow_empty=False) + + if ilogic_site_type is None: + pass + elif ilogic_site_type == 'ISERDESE2': + INTERFACE_TYPE = random.choice([ + 'MEMORY', + 'MEMORY_DDR3', + 'MEMORY_QDR', + 'NETWORKING', + 'OVERSAMPLE', + ]) + ports = [] + add_port(ports, 'CLK', clk) add_port(ports, 'CLKB', clkb) @@ -258,17 +270,55 @@ def run(): (* KEEP, DONT_TOUCH, LOC="{site}" *) ISERDESE2 #( .DATA_RATE({DATA_RATE}), - .INTERFACE_TYPE("MEMORY_QDR"), + .INTERFACE_TYPE({INTERFACE_TYPE}), .IS_CLK_INVERTED({IS_CLK_INVERTED}), - .IS_CLKB_INVERTED({IS_CLKB_INVERTED}) + .IS_CLKB_INVERTED({IS_CLKB_INVERTED}), + .INIT_Q1({INIT_Q1}), + .INIT_Q2({INIT_Q2}), + .INIT_Q3({INIT_Q3}), + .INIT_Q4({INIT_Q4}), + .SRVAL_Q1({SRVAL_Q1}), + .SRVAL_Q2({SRVAL_Q2}), + .SRVAL_Q3({SRVAL_Q3}), + .SRVAL_Q4({SRVAL_Q4}) ) iserdes_{site}( {ports});""".format( site=ilogic_site, ports=',\n'.join(ports), DATA_RATE=verilog.quote(DATA_RATE), + INTERFACE_TYPE=verilog.quote(INTERFACE_TYPE), IS_CLK_INVERTED=random.randint(0, 1), IS_CLKB_INVERTED=random.randint(0, 1), + INIT_Q1=random.randint(0, 1), + INIT_Q2=random.randint(0, 1), + INIT_Q3=random.randint(0, 1), + INIT_Q4=random.randint(0, 1), + SRVAL_Q1=random.randint(0, 1), + SRVAL_Q2=random.randint(0, 1), + SRVAL_Q3=random.randint(0, 1), + SRVAL_Q4=random.randint(0, 1), )) + elif ilogic_site_type == 'IDDR': + ports = [] + add_port(ports, 'C', clk) + add_port(ports, 'CB', clkb) + + output.append(""" + (* KEEP, DONT_TOUCH, LOC="{site}" *) + IDDR_2CLK #( + .INIT_Q1({INIT_Q1}), + .INIT_Q2({INIT_Q2}), + .SRTYPE({SRTYPE}) + ) iserdes_{site}( + {ports});""".format( + site=ilogic_site, + ports=',\n'.join(ports), + INIT_Q1=random.randint(0, 1), + INIT_Q2=random.randint(0, 1), + SRTYPE=verilog.quote(random.choice(['ASYNC','SYNC'])), + )) + else: + assert False, ilogic_site_type if use_oserdes: ports = [] From 089b2c447e9abbba774cefa9c9302debf1cdb15a Mon Sep 17 00:00:00 2001 From: Alessandro Comodi Date: Sun, 21 Jul 2019 01:58:06 +0200 Subject: [PATCH 4/5] 037-ioi-pips: fixed and cleaned fuzzer Signed-off-by: Alessandro Comodi --- fuzzers/000-init-db/Makefile | 6 +- fuzzers/037-iob-pips/Makefile | 24 ++-- fuzzers/037-iob-pips/generate.py | 4 +- fuzzers/037-iob-pips/generate.tcl | 192 +------------------------ fuzzers/037-iob-pips/ioi3_pip_list.tcl | 8 +- fuzzers/037-iob-pips/top.py | 154 ++++++++++---------- fuzzers/int_maketodo.py | 14 +- utils/mergedb.sh | 6 - 8 files changed, 104 insertions(+), 304 deletions(-) diff --git a/fuzzers/000-init-db/Makefile b/fuzzers/000-init-db/Makefile index f2c368d5..ee42445a 100644 --- a/fuzzers/000-init-db/Makefile +++ b/fuzzers/000-init-db/Makefile @@ -22,8 +22,6 @@ SEGBITS=\ dsp \ hclk \ int \ - ioi \ - ioi3 \ SEGBITS_R=\ clk_bufg_top \ @@ -41,6 +39,10 @@ DB_SIMPLE=\ $(addsuffix _r, $(DB_SIMPLE_LR) $(DB_SIMPLE_R)) \ segbits_cmt_top_l_upper_t \ segbits_cmt_top_r_upper_t \ + segbits_lioi3 \ + segbits_rioi3 \ + segbits_liob33 \ + segbits_riob33 BLOCK_RAM_EXTRA_FOR=\ mask_bram \ diff --git a/fuzzers/037-iob-pips/Makefile b/fuzzers/037-iob-pips/Makefile index e77c23b4..57f3d46b 100644 --- a/fuzzers/037-iob-pips/Makefile +++ b/fuzzers/037-iob-pips/Makefile @@ -2,12 +2,15 @@ export FUZDIR=$(shell pwd) PIP_TYPE?=ioi3 PIPLIST_TCL=$(FUZDIR)/ioi3_pip_list.tcl -TODO_RE="[LR]IOI3\.(IOI_([IO]LOGIC[01]_CLK(DIV|B)?)|(IOI_OCLK_[01]))\.IOI_LEAF_GCLK[0-9]" +TODO_RE="[LR]IOI3\.(IOI_([IO]LOGIC[01]_CLK(DIV|B)?)|(IOI_OCLK_[01]))\..*" +EXCLUDE_RE=".*\..*\.(?=IOI_((PHASER)|(OCLK)|(IMUX22_1))).*" -MAKETODO_FLAGS=--pip-type ${PIP_TYPE} --seg-type $(PIP_TYPE) --re $(TODO_RE) +MAKETODO_FLAGS=--pip-type ${PIP_TYPE} --seg-type $(PIP_TYPE) --re $(TODO_RE) --sides "xr,xl" --exclude-re $(EXCLUDE_RE) N = 40 -SEGMATCH_FLAGS=-c -1 -m 15 -M 30 +A_PIPLIST=lioi3.txt + +SEGMATCH_FLAGS=-c -1 -m 20 -M 50 SPECIMENS_DEPS=build/cmt_regions.csv include ../pip_loop.mk @@ -27,22 +30,21 @@ database: ${RDBS} cp build/segbits_ioi3_x.rdb build/$(ITER)/segbits_ioi3_x.rdb cp build/segbits_ioi3_x.db build/$(ITER)/segbits_ioi3_x.db - - ${XRAY_MASKMERGE} build/mask_xioi3.db \ - $(shell find build -name segdata_ioi3_l.txt) \ - $(shell find build -name segdata_ioi3_r.txt) - # 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} ioi3_l build/segbits_ioi3_x.db - XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} ioi3_r build/segbits_ioi3_x.db + XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} lioi3 build/segbits_ioi3_x.db + XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} rioi3 build/segbits_ioi3_x.db build/cmt_regions.csv: output_cmt.tcl mkdir -p build cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_cmt.tcl -pushdb: +pushdb: database ${XRAY_MERGEDB} lioi3 build/segbits_ioi3_x.db ${XRAY_MERGEDB} rioi3 build/segbits_ioi3_x.db + ${XRAY_MERGEDB} lioi3_tbytesrc build/segbits_ioi3_x.db + ${XRAY_MERGEDB} rioi3_tbytesrc build/segbits_ioi3_x.db + ${XRAY_MERGEDB} lioi3_tbyteterm build/segbits_ioi3_x.db + ${XRAY_MERGEDB} rioi3_tbyteterm build/segbits_ioi3_x.db .PHONY: database pushdb diff --git a/fuzzers/037-iob-pips/generate.py b/fuzzers/037-iob-pips/generate.py index bfc426ac..4ee3c186 100644 --- a/fuzzers/037-iob-pips/generate.py +++ b/fuzzers/037-iob-pips/generate.py @@ -19,7 +19,7 @@ def main(): ignpip = set() with open(os.path.join(os.getenv('FUZDIR'), '..', 'piplist', 'build', - 'ioi3', 'ioi3_l.txt')) as f: + 'ioi3', 'lioi3.txt')) as f: for l in f: tile_type, dst, src = l.strip().split('.') if tile_type not in pipdata: @@ -28,7 +28,7 @@ def main(): pipdata[tile_type].append((src, dst)) with open(os.path.join(os.getenv('FUZDIR'), '..', 'piplist', 'build', - 'ioi3', 'ioi3_r.txt')) as f: + 'ioi3', 'rioi3.txt')) as f: for l in f: tile_type, dst, src = l.strip().split('.') if tile_type not in pipdata: diff --git a/fuzzers/037-iob-pips/generate.tcl b/fuzzers/037-iob-pips/generate.tcl index a2d15ddf..39cdcf39 100644 --- a/fuzzers/037-iob-pips/generate.tcl +++ b/fuzzers/037-iob-pips/generate.tcl @@ -23,192 +23,6 @@ proc write_pip_txtdata {filename} { close $fp } -proc load_todo {} { - set fp [open "../todo.txt" r] - - # Create map of pip source to remaining destinations for that pip - set todo_map [dict create] - for {gets $fp line} {$line != ""} {gets $fp line} { - set parts [split $line .] - dict lappend todo_map [lindex $parts 1] [list [lindex $parts 0] [lindex $parts 2]] - } - close $fp - return $todo_map -} - -proc route_todo {} { - puts "Checking TODO's" - set todo_map [load_todo] - - puts $todo_map - - set nets [get_nets] - - set todo_nets [dict create] - set used_sources [dict create] - - foreach net $nets { - # Check to see if this net is one we are interested in - set wires [get_wires -of_objects $net -filter {TILE_NAME =~ *IOI3*}] - set is_gclk_net 0 - foreach wire $wires { - if [regexp "IOI_\[IO\]LOGIC\[01\]_CLKB?" $wire] { - set is_gclk_net 1 - break - } - if [regexp "IOI_OCLK_\[01\]" $wire] { - set is_gclk_net 1 - break - } - if [regexp "IOI_\[IO\]LOGIC\[01\]_CLKDIV" $wire] { - set is_gclk_net 1 - break - } - } - - if {$is_gclk_net == 0} { - puts "$net not going to a IOI3 port, skipping." - continue - } - - foreach wire $wires { - set tile [lindex [split $wire /] 0] - set wire [lindex [split $wire /] 1] - set tile_type [get_property TILE_TYPE [get_tiles $tile]] - - if { ![dict exists $todo_map $wire] } { - continue - } - - set srcs [dict get $todo_map $wire] - - # This net is interesting, see if it is already going somewhere we - # want. - set found_target 0 - foreach other_wire $wires { - if { $found_target == 1 } { - break - } - - set other_wire [lindex [split $other_wire /] 1] - - if { $wire == $other_wire } { - continue - } - - foreach src $srcs { - set src_tile_type [lindex $src 0] - - if {$src_tile_type != $tile_type} { - continue - } - - set src_wire [lindex $src 1] - - if { $other_wire == $src } { - set found_target 1 - puts "Interesting net $net already going from $wire to $other_wire." - break - } - } - } - - if { $found_target == 1 } { - # Net has an interesting - continue - } - - dict set todo_nets $net [list $tile $wire] - puts "Interesting net $net (including $wire) is being rerouted." - } - } - - dict for {net tile_wire} $todo_nets { - set tile [lindex $tile_wire 0] - set wire [lindex $tile_wire 1] - set srcs [dict get $todo_map $wire] - set site [lindex [get_sites -of_objects [get_tiles $tile]] 0] - set region [get_clock_regions -of_objects [get_sites $site]] - - puts "Rerouting net $net at $tile / $wire (type $tile_type)" - - set tile_type [get_property TILE_TYPE [get_tiles $tile]] - - set todos {} - foreach src $srcs { - set src_tile_type [lindex $src 0] - if {$src_tile_type != $tile_type} { - continue - } - - set src_wire [lindex $src 1] - - set is_gclk_net 0 - if [regexp "IOI_LEAF_GCLK\[0-9\]+" $src_wire] { - set is_gclk_net 1 - } - - if {$is_gclk_net == 0} { - continue - } - - lappend todos $src_wire - } - - puts "All todos for $tile_type / $wire" - foreach src_wire $todos { - puts " - $src_wire" - } - - route_design -unroute -nets $net - - # Find an input in the todo list that this can can drive. - foreach src_wire $todos { - puts "Attempting to route to $src_wire for net $net." - set target_wire [get_wires "$tile/$src_wire"] - set target_node [get_nodes -of_objects $target_wire] - - if {[llength $target_node] == 0} { - error "Failed to find node for $tile/$src_wire." - } - - if { [regexp ".*TOP.*" $target_node match group] } { - set loc TOP - } elseif { [regexp ".*BOT.*" $target_node match group] } { - set loc BOT - } - - if { [dict exists $used_sources "$region/$loc/$src_wire"] } { - puts "Not routing to $tile / $src_wire, in use." - continue - } - - - set old_nets [get_nets -of_objects $target_node] - - if { $old_nets != {} } { - set old_nets_property [get_property IS_ROUTE_FIXED [get_nets -of_objects $target_node]] - if { $old_nets_property == 0 } { - route_design -unroute -nets $old_nets - } - } - - set origin_node [get_nodes -of_objects [get_site_pins -filter {DIRECTION == OUT} -of_objects $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" - - # Only need to set route to one of the destinations. - # Router will handle the rest. - set_property FIXED_ROUTE $new_route $net - - dict set used_sources "$region/$loc/$src_wire" 1 - break - } - } -} - proc run {} { create_project -force -part $::env(XRAY_PART) design design read_verilog top.v @@ -232,11 +46,7 @@ proc run {} { place_design write_checkpoint -force design_before_route.dcp route_design - write_checkpoint -force design_before.dcp - - #route_todo - route_design - write_checkpoint -force design_after.dcp + write_checkpoint -force design.dcp write_bitstream -force design.bit write_pip_txtdata design.txt diff --git a/fuzzers/037-iob-pips/ioi3_pip_list.tcl b/fuzzers/037-iob-pips/ioi3_pip_list.tcl index 6eb726ca..d7c940af 100644 --- a/fuzzers/037-iob-pips/ioi3_pip_list.tcl +++ b/fuzzers/037-iob-pips/ioi3_pip_list.tcl @@ -35,9 +35,5 @@ create_project -force -part $::env(XRAY_PART) design design set_property design_mode PinPlanning [current_fileset] open_io_design -name io_1 -# Cleaning ioi3.txt pip file -set fp [open ioi3.txt w] -close $fp - -print_tile_pips LIOI3 ioi3_l.txt -print_tile_pips RIOI3 ioi3_r.txt +print_tile_pips LIOI3 lioi3.txt +print_tile_pips RIOI3 rioi3.txt diff --git a/fuzzers/037-iob-pips/top.py b/fuzzers/037-iob-pips/top.py index d6b5185d..e6e4e3f0 100644 --- a/fuzzers/037-iob-pips/top.py +++ b/fuzzers/037-iob-pips/top.py @@ -11,21 +11,6 @@ NOT_INCLUDED_TILES = ['LIOI3_SING', 'RIOI3_SING'] SITE_TYPES = ['OLOGICE3', 'ILOGICE3'] -MAX_REG_CLK_BUF = 2 -MAX_GLB_CLK_BUF = 24 -CUR_CLK = 0 -MAX_ATTEMPTS = 50 - - -def get_location(tile_name, divisor): - y_location = int(tile_name.split("Y")[-1]) - - if math.floor(y_location / divisor) % 2 == 0: - # Location is on the bottom of the row/tile - return "BOT" - else: - return "TOP" - def read_site_to_cmt(): """ Yields clock sources and which CMT they route within. """ @@ -50,11 +35,7 @@ def gen_sites(): gridinfo = grid.gridinfo_at_loc(loc) tile_type = gridinfo.tile_type - tile = { - 'tile': tile_name, - 'tile_type': tile_type, - 'ioi_sites': {} - } + tile = {'tile': tile_name, 'tile_type': tile_type, 'ioi_sites': {}} for site_name, site_type in gridinfo.sites.items(): if site_type in SITE_TYPES: @@ -87,53 +68,62 @@ class ClockSources(object): for site, cmt in self.site_to_cmt.items(): clk = 'clk_' + site if 'BUFHCE' in site: - print(""" + print( + """ wire {clk}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFH bufh_{site}( .O({clk}) ); """.format( - clk=clk, - site=site, + clk=clk, + site=site, )) self.leaf_gclks[cmt].append(clk) if 'BUFIO' in site: - print(""" + print( + """ wire {clk}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFIO bufio_{site}( .O({clk}) ); """.format( - clk=clk, - site=site, + clk=clk, + site=site, )) self.ioclks[cmt].append(clk) if 'BUFR' in site: - print(""" + print( + """ wire {clk}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFR bufr_{site}( .O({clk}) ); """.format( - clk=clk, - site=site, + clk=clk, + site=site, )) self.rclks[cmt].append(clk) - # Choose 6 leaf_gclks to be used in each CMT. for cmt in self.leaf_gclks: - self.selected_leaf_gclks[cmt] = random.choices(self.leaf_gclks[cmt], k=6) + self.selected_leaf_gclks[cmt] = random.sample( + self.leaf_gclks[cmt], 6) - def get_clock(self, site, allow_ioclks, allow_rclks, allow_fabric=True, allow_empty=True): + def get_clock( + self, + site, + allow_ioclks, + allow_rclks, + allow_fabric=True, + allow_empty=True): cmt = self.site_to_cmt[site] choices = [] if allow_fabric: @@ -160,12 +150,12 @@ class ClockSources(object): def add_port(ports, port, signal): ports.append('.{}({})'.format(port, signal)) + def run(): print("module top();") clocks = ClockSources() clocks.init_clocks() - """ ISERDESE2 clock sources: @@ -201,7 +191,6 @@ def run(): if tile['tile_type'] in NOT_INCLUDED_TILES: continue - for xy in tile['ioi_sites']: ilogic_site_type = random.choice([None, 'ISERDESE2', 'IDDR']) use_oserdes = random.randint(0, 1) @@ -211,62 +200,59 @@ def run(): if use_oserdes: oclk, _ = clocks.get_clock( - ologic_site, - allow_ioclks=True, - allow_rclks=True) + ologic_site, allow_ioclks=True, allow_rclks=True) oclkb = oclk else: oclk, is_lut = clocks.get_clock( - ilogic_site, - allow_ioclks=True, - allow_rclks=True) + ilogic_site, allow_ioclks=True, allow_rclks=True) if random.randint(0, 1): oclkb = oclk else: oclkb, _ = clocks.get_clock( - ilogic_site, - allow_ioclks=True, - allow_rclks=True, - allow_fabric=not is_lut) + ilogic_site, + allow_ioclks=True, + allow_rclks=True, + allow_fabric=not is_lut) DATA_RATE = random.choice(['DDR', 'SDR']) clk, is_lut = clocks.get_clock( ilogic_site, allow_ioclks=True, allow_rclks=True, - allow_empty=DATA_RATE=='SDR') + allow_empty=DATA_RATE == 'SDR') if False: clkb = clk else: clkb = clk while clkb == clk: clkb, _ = clocks.get_clock( - ilogic_site, - allow_ioclks=True, - allow_rclks=True, - allow_empty=False) + ilogic_site, + allow_ioclks=True, + allow_rclks=True, + allow_empty=False) if ilogic_site_type is None: pass elif ilogic_site_type == 'ISERDESE2': - INTERFACE_TYPE = random.choice([ - 'MEMORY', - 'MEMORY_DDR3', - 'MEMORY_QDR', - 'NETWORKING', - 'OVERSAMPLE', + INTERFACE_TYPE = random.choice( + [ + 'MEMORY', + 'MEMORY_DDR3', + 'MEMORY_QDR', + 'NETWORKING', + 'OVERSAMPLE', ]) ports = [] - add_port(ports, 'CLK', clk) add_port(ports, 'CLKB', clkb) add_port(ports, 'OCLK', oclk) add_port(ports, 'OCLKB', oclkb) - output.append(""" + output.append( + """ (* KEEP, DONT_TOUCH, LOC="{site}" *) ISERDESE2 #( .DATA_RATE({DATA_RATE}), @@ -283,27 +269,28 @@ def run(): .SRVAL_Q4({SRVAL_Q4}) ) iserdes_{site}( {ports});""".format( - site=ilogic_site, - ports=',\n'.join(ports), - DATA_RATE=verilog.quote(DATA_RATE), - INTERFACE_TYPE=verilog.quote(INTERFACE_TYPE), - IS_CLK_INVERTED=random.randint(0, 1), - IS_CLKB_INVERTED=random.randint(0, 1), - INIT_Q1=random.randint(0, 1), - INIT_Q2=random.randint(0, 1), - INIT_Q3=random.randint(0, 1), - INIT_Q4=random.randint(0, 1), - SRVAL_Q1=random.randint(0, 1), - SRVAL_Q2=random.randint(0, 1), - SRVAL_Q3=random.randint(0, 1), - SRVAL_Q4=random.randint(0, 1), + site=ilogic_site, + ports=',\n'.join(ports), + DATA_RATE=verilog.quote(DATA_RATE), + INTERFACE_TYPE=verilog.quote(INTERFACE_TYPE), + IS_CLK_INVERTED=random.randint(0, 1), + IS_CLKB_INVERTED=random.randint(0, 1), + INIT_Q1=random.randint(0, 1), + INIT_Q2=random.randint(0, 1), + INIT_Q3=random.randint(0, 1), + INIT_Q4=random.randint(0, 1), + SRVAL_Q1=random.randint(0, 1), + SRVAL_Q2=random.randint(0, 1), + SRVAL_Q3=random.randint(0, 1), + SRVAL_Q4=random.randint(0, 1), )) elif ilogic_site_type == 'IDDR': ports = [] add_port(ports, 'C', clk) add_port(ports, 'CB', clkb) - output.append(""" + output.append( + """ (* KEEP, DONT_TOUCH, LOC="{site}" *) IDDR_2CLK #( .INIT_Q1({INIT_Q1}), @@ -311,11 +298,11 @@ def run(): .SRTYPE({SRTYPE}) ) iserdes_{site}( {ports});""".format( - site=ilogic_site, - ports=',\n'.join(ports), - INIT_Q1=random.randint(0, 1), - INIT_Q2=random.randint(0, 1), - SRTYPE=verilog.quote(random.choice(['ASYNC','SYNC'])), + site=ilogic_site, + ports=',\n'.join(ports), + INIT_Q1=random.randint(0, 1), + INIT_Q2=random.randint(0, 1), + SRTYPE=verilog.quote(random.choice(['ASYNC', 'SYNC'])), )) else: assert False, ilogic_site_type @@ -323,23 +310,26 @@ def run(): if use_oserdes: ports = [] - add_port(ports, 'CLKDIV', clocks.get_clock( + add_port( + ports, 'CLKDIV', + clocks.get_clock( ologic_site, allow_ioclks=False, allow_rclks=True, - )[0]) + )[0]) add_port(ports, 'CLK', oclk) - output.append(""" + output.append( + """ (* KEEP, DONT_TOUCH, LOC = "{site}" *) OSERDESE2 #( .DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR") ) oserdes_{site} ( {ports});""".format( - site=ologic_site, - ports=',\n'.join(ports), + site=ologic_site, + ports=',\n'.join(ports), )) for s in clocks.lut_maker.create_wires_and_luts(): diff --git a/fuzzers/int_maketodo.py b/fuzzers/int_maketodo.py index 4bef0ec9..c6444f3c 100644 --- a/fuzzers/int_maketodo.py +++ b/fuzzers/int_maketodo.py @@ -209,12 +209,18 @@ def run( if side == "r" and not r: continue - if side != "": - side = "_" + side + if side == "xl": + filename = "l{}".format(pip_type) + elif side == "xr": + filename = "r{}".format(pip_type) + elif side == "l" or side == "r": + filename = "{}_{}".format(pip_type, side) + else: + filename = "{}".format(pip_type) maketodo( - "%s/%s%s.txt" % (pip_dir, pip_type, side), - "%s/segbits_%s%s.db" % (db_dir, seg_type, side), + "%s/%s.txt" % (pip_dir, filename), + "%s/segbits_%s.db" % (db_dir, filename), intre, exclude_re=exclude_re, balance_wire_re=balance_wire_re, diff --git a/utils/mergedb.sh b/utils/mergedb.sh index d39cd95b..6e85a2c3 100755 --- a/utils/mergedb.sh +++ b/utils/mergedb.sh @@ -144,12 +144,6 @@ case "$1" in hclk_ioi3) cp "$2" "$tmp1" ;; - ioi3_l) - sed < "$2" > "$tmp1" -e 's/^IOI3\./LIOI3./' ;; - - ioi3_r) - sed < "$2" > "$tmp1" -e 's/^IOI3\./RIOI3./' ;; - mask_*) db=$XRAY_DATABASE_DIR/$XRAY_DATABASE/$1.db ismask=true From 702ae02655b7a9fdf7a4abf72f497967701e7b4f Mon Sep 17 00:00:00 2001 From: Alessandro Comodi Date: Thu, 25 Jul 2019 15:06:12 +0200 Subject: [PATCH 5/5] pips: fix maketodo Signed-off-by: Alessandro Comodi --- fuzzers/int_maketodo.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/fuzzers/int_maketodo.py b/fuzzers/int_maketodo.py index c6444f3c..df800e33 100644 --- a/fuzzers/int_maketodo.py +++ b/fuzzers/int_maketodo.py @@ -210,17 +210,21 @@ def run( continue if side == "xl": - filename = "l{}".format(pip_type) + segfile = "l{}".format(seg_type) + pipfile = "l{}".format(pip_type) elif side == "xr": - filename = "r{}".format(pip_type) + segfile = "r{}".format(seg_type) + pipfile = "r{}".format(pip_type) elif side == "l" or side == "r": - filename = "{}_{}".format(pip_type, side) + segfile = "{}_{}".format(seg_type, side) + pipfile = "{}_{}".format(pip_type, side) else: - filename = "{}".format(pip_type) + segfile = "{}".format(seg_type) + pipfile = "{}".format(pip_type) maketodo( - "%s/%s.txt" % (pip_dir, filename), - "%s/segbits_%s.db" % (db_dir, filename), + "%s/%s.txt" % (pip_dir, pipfile), + "%s/segbits_%s.db" % (db_dir, segfile), intre, exclude_re=exclude_re, balance_wire_re=balance_wire_re,