037-ioi-pips: fixed and cleaned fuzzer

Signed-off-by: Alessandro Comodi <acomodi@antmicro.com>
This commit is contained in:
Alessandro Comodi 2019-07-21 01:58:06 +02:00
parent e3b5fe97f4
commit 089b2c447e
8 changed files with 104 additions and 304 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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():

View File

@ -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,

View File

@ -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