mirror of https://github.com/openXC7/prjxray.git
Initial cascade pip fuzzer.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
a8299c84a3
commit
741715851a
|
|
@ -0,0 +1,38 @@
|
|||
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
|
||||
N = 50
|
||||
SEGMATCH_FLAGS=-m 20 -M 45
|
||||
include ../pip_loop.mk
|
||||
#
|
||||
# Specimens from current run must complete, but previous iterations may exist
|
||||
database: $(SPECIMENS_OK)
|
||||
${XRAY_SEGMATCH} $(SEGMATCH_FLAGS) -o build/segbits_bram_l.rdb $(shell find build -name segdata_bram_l.txt)
|
||||
${XRAY_SEGMATCH} $(SEGMATCH_FLAGS) -o build/segbits_bram_r.rdb $(shell find build -name segdata_bram_r.txt)
|
||||
|
||||
# Keep a copy to track iter progress
|
||||
# Also is pre-fixup, which drops and converts
|
||||
cp build/segbits_bram_l.rdb build/$(ITER)/segbits_bram_l.rdb
|
||||
cp build/segbits_bram_r.rdb build/$(ITER)/segbits_bram_r.rdb
|
||||
${XRAY_DBFIXUP} --db-root build \
|
||||
--verbose \
|
||||
--zero-db bits.dbf \
|
||||
--seg-fn-in build/segbits_bram_l.rdb \
|
||||
--seg-fn-out build/segbits_bram_l.db
|
||||
${XRAY_DBFIXUP} --db-root build \
|
||||
--verbose \
|
||||
--zero-db bits.dbf \
|
||||
--seg-fn-in build/segbits_bram_r.rdb \
|
||||
--seg-fn-out build/segbits_bram_r.db
|
||||
|
||||
# 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} bram_l build/segbits_bram_l.db
|
||||
XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} bram_r build/segbits_bram_r.db
|
||||
|
||||
# Final pushdb to real repo
|
||||
pushdb: database
|
||||
${XRAY_MERGEDB} bram_l build/segbits_bram_l.db
|
||||
${XRAY_MERGEDB} bram_r build/segbits_bram_r.db
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
26_184 26_185 26_187,BRAM.BRAM_ADDRBWRADDRL7.BRAM_IMUX_ADDRBWRADDRL7
|
||||
26_88 26_89 26_91 ,BRAM.BRAM_ADDRBWRADDRL8.BRAM_IMUX_ADDRBWRADDRL8
|
||||
|
||||
26_197 26_198 26_199,BRAM.BRAM_ADDRARDADDRU3.BRAM_IMUX_ADDRARDADDRU3
|
||||
26_101 26_102 26_103,BRAM.BRAM_ADDRARDADDRU4.BRAM_IMUX_ADDRARDADDRU4
|
||||
26_229 26_230 26_231,BRAM.BRAM_ADDRARDADDRU5.BRAM_IMUX_ADDRARDADDRU5
|
||||
26_165 26_166 26_167,BRAM.BRAM_ADDRARDADDRU6.BRAM_IMUX_ADDRARDADDRU6
|
||||
26_181 26_182 26_183,BRAM.BRAM_ADDRARDADDRU7.BRAM_IMUX_ADDRARDADDRU7
|
||||
26_85 26_86 26_87 ,BRAM.BRAM_ADDRARDADDRU8.BRAM_IMUX_ADDRARDADDRU8
|
||||
26_213 26_214 26_215,BRAM.BRAM_ADDRARDADDRU9.BRAM_IMUX_ADDRARDADDRU9
|
||||
|
||||
26_77 26_78 26_79 ,BRAM.BRAM_ADDRBWRADDRU2.BRAM_IMUX_ADDRBWRADDRU2
|
||||
26_205 26_206 26_207,BRAM.BRAM_ADDRBWRADDRU3.BRAM_IMUX_ADDRBWRADDRU3
|
||||
26_237 26_238 26_239,BRAM.BRAM_ADDRBWRADDRU5.BRAM_IMUX_ADDRBWRADDRU5
|
||||
26_173 26_174 26_175,BRAM.BRAM_ADDRBWRADDRU6.BRAM_IMUX_ADDRBWRADDRU6
|
||||
26_189 26_190 26_191,BRAM.BRAM_ADDRBWRADDRU7.BRAM_IMUX_ADDRBWRADDRU7
|
||||
26_93 26_94 26_95 ,BRAM.BRAM_ADDRBWRADDRU8.BRAM_IMUX_ADDRBWRADDRU8
|
||||
26_221 26_222 26_223,BRAM.BRAM_ADDRBWRADDRU9.BRAM_IMUX_ADDRBWRADDRU9
|
||||
|
||||
26_176 26_177 26_179,BRAM.BRAM_ADDRARDADDRL7.BRAM_R_IMUX_ADDRARDADDRL7
|
||||
26_80 26_81 26_83 ,BRAM.BRAM_ADDRARDADDRL8.BRAM_R_IMUX_ADDRARDADDRL8
|
||||
|
||||
26_165 26_166 26_167,BRAM.BRAM_ADDRARDADDRU6.BRAM_R_IMUX_ADDRARDADDRU6
|
||||
26_181 26_182 26_183,BRAM.BRAM_ADDRARDADDRU7.BRAM_R_IMUX_ADDRARDADDRU7
|
||||
26_85 26_86 26_87 ,BRAM.BRAM_ADDRARDADDRU8.BRAM_R_IMUX_ADDRARDADDRU8
|
||||
|
||||
26_88 26_89 26_91 ,BRAM.BRAM_ADDRBWRADDRL8.BRAM_R_IMUX_ADDRBWRADDRL8
|
||||
|
||||
26_189 26_190 26_191,BRAM.BRAM_ADDRBWRADDRU7.BRAM_R_IMUX_ADDRBWRADDRU7
|
||||
26_93 26_94 26_95 ,BRAM.BRAM_ADDRBWRADDRU8.BRAM_R_IMUX_ADDRBWRADDRU8
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
create_project -force -part $::env(XRAY_PART) design design
|
||||
set_property design_mode PinPlanning [current_fileset]
|
||||
open_io_design -name io_1
|
||||
|
||||
proc print_tile_pips {tile_type filename} {
|
||||
set tile [lindex [get_tiles -filter "TYPE == $tile_type"] 0]
|
||||
puts "Dumping BRAM PIPs for tile $tile ($tile_type) to $filename."
|
||||
set fp [open $filename w]
|
||||
foreach pip [lsort [get_pips -filter {IS_DIRECTIONAL} -of_objects [get_tiles $tile]]] {
|
||||
set src [get_wires -uphill -of_objects $pip]
|
||||
set dst [get_wires -downhill -of_objects $pip]
|
||||
if {[llength [get_nodes -uphill -of_objects [get_nodes -of_objects $dst]]] != 1} {
|
||||
puts $fp "$tile_type.[regsub {.*/} $dst ""].[regsub {.*/} $src ""]"
|
||||
}
|
||||
}
|
||||
close $fp
|
||||
}
|
||||
|
||||
print_tile_pips BRAM_L bram_pips_int_l.txt
|
||||
print_tile_pips BRAM_R bram_pips_int_r.txt
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from prjxray.segmaker import Segmaker
|
||||
|
||||
segmk = Segmaker("design.bits")
|
||||
|
||||
tiledata = {}
|
||||
pipdata = {}
|
||||
ignpip = set()
|
||||
|
||||
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('BRAM_'):
|
||||
continue
|
||||
|
||||
# BRAM_R_X37Y0/BRAM_R.BRAM_IMUX35_1->BRAM_R_IMUX_ADDRBWRADDRL2
|
||||
pip_prefix, pip = pip.split(".")
|
||||
tile_from_pip, tile_type = pip_prefix.split('/')
|
||||
assert tile == tile_from_pip
|
||||
_, src = src.split("/")
|
||||
_, dst = dst.split("/")
|
||||
pnum = int(pnum)
|
||||
pdir = int(pdir)
|
||||
|
||||
if tile not in tiledata:
|
||||
tiledata[tile] = {"type": tile_type, "pips": set(), "srcs": set(), "dsts": set()}
|
||||
|
||||
if tile_type not in pipdata:
|
||||
pipdata[tile_type] = {}
|
||||
|
||||
if pip in pipdata[tile_type]:
|
||||
assert pipdata[tile_type][pip] == (src, dst)
|
||||
else:
|
||||
pipdata[tile_type][pip] = (src, dst)
|
||||
|
||||
tiledata[tile]["pips"].add(pip)
|
||||
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:
|
||||
ignpip.add(pip)
|
||||
|
||||
for tile, pips_srcs_dsts in tiledata.items():
|
||||
tile_type = pips_srcs_dsts["type"]
|
||||
pips = pips_srcs_dsts["pips"]
|
||||
srcs = pips_srcs_dsts["srcs"]
|
||||
dsts = pips_srcs_dsts["dsts"]
|
||||
|
||||
for pip, src_dst in pipdata[tile_type].items():
|
||||
src, dst = src_dst
|
||||
if pip in ignpip:
|
||||
pass
|
||||
|
||||
elif pip in pips:
|
||||
segmk.add_tile_tag(tile, "%s.%s" % (dst, src), 1)
|
||||
elif src_dst[1] not in dsts:
|
||||
segmk.add_tile_tag(tile, "%s.%s" % (dst, src), 0)
|
||||
|
||||
segmk.compile()
|
||||
segmk.write()
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -ex
|
||||
|
||||
FUZDIR=$PWD
|
||||
source ${XRAY_GENHEADER}
|
||||
|
||||
echo '`define SEED 32'"'h$(echo $1 | md5sum | cut -c1-8)" > setseed.vh
|
||||
|
||||
${XRAY_VIVADO} -mode batch -source $FUZDIR/generate.tcl | tee vivado_stdout.log | grep "FUZ[^:]\+:"
|
||||
|
||||
${XRAY_BITREAD} -F $XRAY_ROI_FRAMES -o design.bits -z -y design.bit
|
||||
python3 $FUZDIR/generate.py
|
||||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
puts "FUZ([pwd]): Creating project"
|
||||
create_project -force -part $::env(XRAY_PART) design design
|
||||
|
||||
puts "FUZ([pwd]): Reading verilog"
|
||||
read_verilog top.v
|
||||
|
||||
puts "FUZ([pwd]): Synth design"
|
||||
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_param tcl.collectionResultDisplayLimit 0
|
||||
|
||||
source "$::env(XRAY_DIR)/utils/utils.tcl"
|
||||
|
||||
puts "FUZ([pwd]): Placing design"
|
||||
place_design
|
||||
puts "FUZ([pwd]): Routing design"
|
||||
route_design
|
||||
|
||||
write_checkpoint -force design.dcp
|
||||
|
||||
proc write_txtdata {filename} {
|
||||
puts "FUZ([pwd]): Writing $filename."
|
||||
set fp [open $filename w]
|
||||
foreach net [get_nets -hierarchical] {
|
||||
if [string match "*addr*" $net] {
|
||||
puts "Tick $net."
|
||||
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
|
||||
}
|
||||
|
||||
write_bitstream -force design.bit
|
||||
write_txtdata design.txt
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
import os
|
||||
import sys
|
||||
import random
|
||||
import math
|
||||
from prjxray import util
|
||||
from prjxray.db import Database
|
||||
random.seed(int(os.getenv("SEED"), 16))
|
||||
|
||||
def bram_count():
|
||||
db = Database(util.get_db_root())
|
||||
grid = db.grid()
|
||||
|
||||
count = 0
|
||||
for tile_name in grid.tiles():
|
||||
loc = grid.loc_of_tilename(tile_name)
|
||||
gridinfo = grid.gridinfo_at_loc(loc)
|
||||
|
||||
for site_name, site_type in gridinfo.sites.items():
|
||||
if site_type in ['RAMBFIFO36E1']:
|
||||
count += 1
|
||||
|
||||
return count
|
||||
|
||||
class LutMaker(object):
|
||||
def __init__(self):
|
||||
self.input_lut_idx = 0
|
||||
self.output_lut_idx = 0
|
||||
self.lut_input_idx = 0
|
||||
|
||||
def get_next_input_net(self):
|
||||
net = 'lut_{}_i[{}]'.format(self.input_lut_idx, self.lut_input_idx)
|
||||
|
||||
self.lut_input_idx += 1
|
||||
if self.lut_input_idx > 5:
|
||||
self.lut_input_idx = 0
|
||||
self.input_lut_idx += 1
|
||||
|
||||
return net
|
||||
|
||||
def get_next_output_net(self):
|
||||
net = 'lut_{}_o'.format(self.output_lut_idx)
|
||||
self.output_lut_idx += 1
|
||||
return net
|
||||
|
||||
def create_wires_and_luts(self):
|
||||
if self.output_lut_idx > self.input_lut_idx:
|
||||
nluts = self.output_lut_idx
|
||||
else:
|
||||
nluts = self.input_lut_idx
|
||||
if self.lut_input_idx > 0:
|
||||
nluts += 1
|
||||
|
||||
for lut in range(nluts):
|
||||
yield """
|
||||
wire [5:0] lut_{lut}_i;
|
||||
wire lut_{lut}_o;
|
||||
|
||||
(* KEEP, DONT_TOUCH *)
|
||||
LUT6 lut_{lut} (
|
||||
.I0(lut_{lut}_i[0]),
|
||||
.I1(lut_{lut}_i[1]),
|
||||
.I2(lut_{lut}_i[2]),
|
||||
.I3(lut_{lut}_i[3]),
|
||||
.I4(lut_{lut}_i[4]),
|
||||
.I5(lut_{lut}_i[5]),
|
||||
.O(lut_{lut}_o)
|
||||
);
|
||||
""".format(lut=lut)
|
||||
|
||||
def sdp_bram(name, width, address_bits):
|
||||
depth = 2**address_bits
|
||||
|
||||
return '''
|
||||
module {name}(
|
||||
// Write port
|
||||
input wrclk,
|
||||
input [{width}-1:0] di,
|
||||
input wren,
|
||||
input [{address_bits}-1:0] wraddr,
|
||||
// Read port
|
||||
input rdclk,
|
||||
input rden,
|
||||
input [{address_bits}-1:0] rdaddr,
|
||||
output reg [{width}-1:0] do);
|
||||
|
||||
(* ram_style = "block" *) reg [{width}-1:0] ram[0:{depth}];
|
||||
|
||||
always @ (posedge wrclk) begin
|
||||
if(wren == 1) begin
|
||||
ram[wraddr] <= di;
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge rdclk) begin
|
||||
if(rden == 1) begin
|
||||
do <= ram[rdaddr];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
'''.format(
|
||||
name=name,
|
||||
width=width,
|
||||
address_bits=address_bits,
|
||||
depth=depth,
|
||||
)
|
||||
|
||||
MAX_BRAM = 8
|
||||
|
||||
def emit_sdp_bram(luts, name, modules, lines, width, address_bits):
|
||||
modules.append(sdp_bram(name=name, width=width, address_bits=address_bits))
|
||||
|
||||
lines.append('''
|
||||
wire [9:0] {name}_wraddr;
|
||||
wire [9:0] {name}_rdaddr;
|
||||
'''.format(name=name))
|
||||
|
||||
for bit in range(10):
|
||||
lines.append("""
|
||||
assign {name}_wraddr[{bit}] = {net};""".format(
|
||||
name=name,
|
||||
bit=bit,
|
||||
net=luts.get_next_output_net()))
|
||||
|
||||
for bit in range(10):
|
||||
lines.append("""
|
||||
assign {name}_rdaddr[{bit}] = {net};""".format(
|
||||
name=name,
|
||||
bit=bit,
|
||||
net=luts.get_next_output_net()))
|
||||
|
||||
lines.append('''
|
||||
(* KEEP, DONT_TOUCH *)
|
||||
{name} {name}_inst(
|
||||
.wraddr({name}_wraddr),
|
||||
.rdaddr({name}_rdaddr)
|
||||
);
|
||||
'''.format(name=name))
|
||||
|
||||
return width, address_bits, math.ceil(float(width)/72)*72*(2**address_bits)
|
||||
|
||||
def max_address_bits(width):
|
||||
return math.floor(math.log(float(MAX_BRAM*36*1024)/width, 2))
|
||||
|
||||
def random_sdp_bram(luts, name, modules, lines):
|
||||
sdp_choices = set()
|
||||
|
||||
for width in (1, 18, 36):
|
||||
sdp_choices.add((width, (1, max_address_bits(width))))
|
||||
|
||||
for nbram in range(2, MAX_BRAM+1):
|
||||
#sdp_choices.add((nbram*32, (1, max_address_bits(nbram*32))))
|
||||
#sdp_choices.add((nbram*36, (1, max_address_bits(nbram*36))))
|
||||
#sdp_choices.add((nbram*16, (1, max_address_bits(nbram*16))))
|
||||
#sdp_choices.add((nbram*32, (1, max_address_bits(nbram*32))))
|
||||
|
||||
# Bias some wide but shallow BRAMs to toggle the lower address bits
|
||||
# more.
|
||||
for address_bits in range(1, 4):
|
||||
sdp_choices.add((nbram*32, (address_bits, address_bits)))
|
||||
|
||||
sdp_choices = sorted(sdp_choices)
|
||||
|
||||
width, address_bits_range = random.choice(sdp_choices)
|
||||
address_bits = random.randint(*address_bits_range)
|
||||
return emit_sdp_bram(luts, name, modules, lines, width, address_bits)
|
||||
|
||||
|
||||
def run():
|
||||
luts = LutMaker()
|
||||
count = bram_count()
|
||||
|
||||
max_bram_count = random.randint(1, 200)
|
||||
|
||||
modules = []
|
||||
lines = []
|
||||
|
||||
idx = 0
|
||||
while count > MAX_BRAM:
|
||||
width, address_bits, bits = random_sdp_bram(luts, "ram{}".format(idx), modules, lines)
|
||||
|
||||
brams = math.ceil(bits/float(36*1024))
|
||||
|
||||
count -= brams
|
||||
|
||||
print(width, address_bits, bits, brams, count, file=sys.stderr)
|
||||
idx += 1
|
||||
|
||||
if idx >= max_bram_count:
|
||||
break
|
||||
|
||||
for module in modules:
|
||||
print(module)
|
||||
|
||||
print(
|
||||
'''
|
||||
module top();
|
||||
''')
|
||||
|
||||
for lut in luts.create_wires_and_luts():
|
||||
print(lut)
|
||||
|
||||
for l in lines:
|
||||
print(l)
|
||||
|
||||
print("endmodule")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
|
|
@ -60,6 +60,29 @@ proc write_int_ppips_db {filename tile} {
|
|||
close $fp
|
||||
}
|
||||
|
||||
proc write_bram_ppips_db {filename tile} {
|
||||
set fp [open $filename "w"]
|
||||
set tile [get_tiles $tile]
|
||||
set tile_type [get_property TILE_TYPE $tile]
|
||||
|
||||
foreach pip [get_pips -of_objects $tile] {
|
||||
set dst_wire [get_wires -downhill -of_objects $pip]
|
||||
if {[get_pips -uphill -of_objects [get_nodes -of_objects $dst_wire]] == $pip} {
|
||||
set src_wire [get_wires -uphill -of_objects $pip]
|
||||
puts $fp "${tile_type}.[regsub {.*/} $dst_wire ""].[regsub {.*/} $src_wire ""] always"
|
||||
}
|
||||
|
||||
# LOGIC_OUTS pips appear to be always, even thought multiple inputs to
|
||||
# the pip junction. Best guess is that the underlying hardware is
|
||||
# actually just one wire, and there is no actually junction.
|
||||
if [string match "*LOGIC_OUTS*" dst_wire] {
|
||||
puts $fp "${tile_type}.[regsub {.*/} $dst_wire ""].[regsub {.*/} $src_wire ""] always"
|
||||
}
|
||||
}
|
||||
|
||||
close $fp
|
||||
}
|
||||
|
||||
foreach tile_type {CLBLM_L CLBLM_R CLBLL_L CLBLL_R} {
|
||||
set tiles [get_tiles -filter "TILE_TYPE == $tile_type"]
|
||||
if {[llength $tiles] != 0} {
|
||||
|
|
@ -68,10 +91,17 @@ foreach tile_type {CLBLM_L CLBLM_R CLBLL_L CLBLL_R} {
|
|||
}
|
||||
}
|
||||
|
||||
foreach tile_type {INT_L INT_R BRAM_L BRAM_R BRAM_INT_INTERFACE_L BRAM_INT_INTERFACE_R} {
|
||||
foreach tile_type {INT_L INT_R BRAM_INT_INTERFACE_L BRAM_INT_INTERFACE_R} {
|
||||
set tiles [get_tiles -filter "TILE_TYPE == $tile_type"]
|
||||
if {[llength $tiles] != 0} {
|
||||
set tile [lindex $tiles 0]
|
||||
write_int_ppips_db "ppips_[string tolower $tile_type].db" $tile
|
||||
}
|
||||
}
|
||||
foreach tile_type {BRAM_L BRAM_R} {
|
||||
set tiles [get_tiles -filter "TILE_TYPE == $tile_type"]
|
||||
if {[llength $tiles] != 0} {
|
||||
set tile [lindex $tiles 0]
|
||||
write_bram_ppips_db "ppips_[string tolower $tile_type].db" $tile
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,4 @@
|
|||
TODO_N ?= 50
|
||||
# Number of spcimens
|
||||
ifeq ($(QUICK),Y)
|
||||
N = 1
|
||||
TODO_N = 3
|
||||
SEGMATCH_FLAGS=
|
||||
else
|
||||
# Should be at least the -m value
|
||||
N ?= 20
|
||||
SEGMATCH_FLAGS=-m 15 -M 45
|
||||
endif
|
||||
# Iteration number (each containing N specimens)
|
||||
# Driven by int_loop.sh
|
||||
ITER ?= 1
|
||||
MAKETODO_FLAGS ?=
|
||||
PIP_TYPE?=pips_int
|
||||
PIPLIST_TCL?=$(XRAY_FUZZERS_DIR)/piplist/piplist.tcl
|
||||
|
||||
# See int_loop_check.py
|
||||
# rempips took 35 iters once, so set 50 as a good start point
|
||||
CHECK_ARGS := --zero-entries --timeout-iters 50
|
||||
SPECIMENS := $(addprefix build/$(ITER)/specimen_,$(shell seq -f '%03.0f' $(N)))
|
||||
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
|
||||
# Individual fuzzer directory, such as ~/prjxray/fuzzers/010-lutinit
|
||||
export FUZDIR=$(shell pwd)
|
||||
include pip_loop.mk
|
||||
|
||||
# Specimens from current run must complete, but previous iterations may exist
|
||||
database: $(SPECIMENS_OK)
|
||||
|
|
@ -55,50 +31,3 @@ pushdb:
|
|||
${XRAY_MERGEDB} mask_clbll_r build/mask_clbll_r.db
|
||||
${XRAY_MERGEDB} mask_clblm_l build/mask_clblm_l.db
|
||||
${XRAY_MERGEDB} mask_clblm_r build/mask_clblm_r.db
|
||||
|
||||
$(SPECIMENS_OK): build/todo.txt
|
||||
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)
|
||||
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) $(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
|
||||
mkdir -p build/$(ITER)
|
||||
cp build/todo_all.txt build/todo.txt build/$(ITER)/
|
||||
# All in one dir for easier trending
|
||||
mkdir -p build/todo
|
||||
cp build/todo_all.txt build/todo/$(ITER)_all.txt
|
||||
|
||||
# Initial copy for first todo.txt
|
||||
# Subsequent are based on updated db
|
||||
build/database/seeded:
|
||||
mkdir -p build/database/${XRAY_DATABASE}
|
||||
cp ${XRAY_DATABASE_DIR}/${XRAY_DATABASE}/segbits*.db build/database/${XRAY_DATABASE}
|
||||
touch build/database/seeded
|
||||
|
||||
# XXX: conider moving to script
|
||||
run:
|
||||
$(MAKE) clean
|
||||
XRAY_DIR=${XRAY_DIR} MAKE="$(MAKE)" QUICK=$(QUICK) $(XRAY_DIR)/fuzzers/int_loop.sh --check-args "$(CHECK_ARGS)"
|
||||
touch run.ok
|
||||
|
||||
clean:
|
||||
rm -rf build run.ok todo
|
||||
|
||||
# Remove iteration specific files, but keep piplist.tcl output
|
||||
cleaniter:
|
||||
rm -rf build/$(ITER) build/todo.txt
|
||||
|
||||
cleanpiplist:
|
||||
rm -rf $(XRAY_FUZZERS_DIR)/piplist/build
|
||||
|
||||
.PHONY: database pushdb run clean cleaniter cleanpiplist
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ def run(
|
|||
pip_dir,
|
||||
intre,
|
||||
pip_type,
|
||||
seg_type,
|
||||
not_endswith=None,
|
||||
verbose=False):
|
||||
if db_dir is None:
|
||||
|
|
@ -103,13 +104,13 @@ def run(
|
|||
assert intre, "RE is required"
|
||||
maketodo(
|
||||
"%s/%s_l.txt" % (pip_dir, pip_type),
|
||||
"%s/segbits_int_l.db" % db_dir,
|
||||
"%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_int_r.db" % db_dir,
|
||||
"%s/segbits_%s_r.db" % (db_dir, seg_type),
|
||||
intre,
|
||||
not_endswith,
|
||||
verbose=verbose)
|
||||
|
|
@ -127,6 +128,7 @@ def main():
|
|||
parser.add_argument('--pip-dir', default=None, help='')
|
||||
parser.add_argument('--re', required=True, help='')
|
||||
parser.add_argument('--pip-type', default="pips_int", help='')
|
||||
parser.add_argument('--seg-type', default="int", help='')
|
||||
parser.add_argument(
|
||||
'--not-endswith', help='Drop lines if they end with this')
|
||||
args = parser.parse_args()
|
||||
|
|
@ -137,6 +139,7 @@ def main():
|
|||
pip_dir=args.pip_dir,
|
||||
intre=args.re,
|
||||
pip_type=args.pip_type,
|
||||
seg_type=args.seg_type,
|
||||
not_endswith=args.not_endswith,
|
||||
verbose=args.verbose)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
TODO_N ?= 50
|
||||
# Number of spcimens
|
||||
ifeq ($(QUICK),Y)
|
||||
N = 1
|
||||
TODO_N = 3
|
||||
SEGMATCH_FLAGS=
|
||||
else
|
||||
# Should be at least the -m value
|
||||
N ?= 20
|
||||
SEGMATCH_FLAGS=-m 15 -M 45
|
||||
endif
|
||||
# Iteration number (each containing N specimens)
|
||||
# Driven by int_loop.sh
|
||||
ITER ?= 1
|
||||
MAKETODO_FLAGS ?=
|
||||
PIP_TYPE?=pips_int
|
||||
SEG_TYPE?=int
|
||||
PIPLIST_TCL?=$(XRAY_FUZZERS_DIR)/piplist/piplist.tcl
|
||||
|
||||
# See int_loop_check.py
|
||||
# rempips took 35 iters once, so set 50 as a good start point
|
||||
CHECK_ARGS := --zero-entries --timeout-iters 50
|
||||
SPECIMENS := $(addprefix build/$(ITER)/specimen_,$(shell seq -f '%03.0f' $(N)))
|
||||
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
|
||||
# Individual fuzzer directory, such as ~/prjxray/fuzzers/010-lutinit
|
||||
export FUZDIR=$(shell pwd)
|
||||
|
||||
all: database
|
||||
|
||||
$(SPECIMENS_OK): build/todo.txt
|
||||
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)
|
||||
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
|
||||
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
|
||||
mkdir -p build/$(ITER)
|
||||
cp build/todo_all.txt build/todo.txt build/$(ITER)/
|
||||
# All in one dir for easier trending
|
||||
mkdir -p build/todo
|
||||
cp build/todo_all.txt build/todo/$(ITER)_all.txt
|
||||
|
||||
# Initial copy for first todo.txt
|
||||
# Subsequent are based on updated db
|
||||
build/database/seeded:
|
||||
mkdir -p build/database/${XRAY_DATABASE}
|
||||
cp ${XRAY_DATABASE_DIR}/${XRAY_DATABASE}/segbits*.db build/database/${XRAY_DATABASE}
|
||||
touch build/database/seeded
|
||||
|
||||
# XXX: conider moving to script
|
||||
run:
|
||||
$(MAKE) clean
|
||||
XRAY_DIR=${XRAY_DIR} MAKE="$(MAKE)" QUICK=$(QUICK) $(XRAY_DIR)/fuzzers/int_loop.sh --check-args "$(CHECK_ARGS)"
|
||||
touch run.ok
|
||||
|
||||
clean:
|
||||
rm -rf build run.ok todo
|
||||
|
||||
# Remove iteration specific files, but keep piplist.tcl output
|
||||
cleaniter:
|
||||
rm -rf build/$(ITER) build/todo.txt
|
||||
|
||||
cleanpiplist:
|
||||
rm -rf $(XRAY_FUZZERS_DIR)/piplist/build
|
||||
|
||||
.PHONY: all database pushdb run clean cleaniter cleanpiplist
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ clb_int_zero_db = [
|
|||
def zero_range(tag, bits, wordmin, wordmax):
|
||||
"""
|
||||
If any bits occur wordmin <= word <= wordmax,
|
||||
default bits in wordmin <= word <= wordmax to 0
|
||||
default bits in wordmin <= word <= wordmax to 0
|
||||
"""
|
||||
|
||||
# The bit index, if any, that needs to be one hotted
|
||||
|
|
@ -105,7 +105,7 @@ def zero_groups(tag, bits, zero_db, strict=True, verbose=False):
|
|||
|
||||
|
||||
def add_zero_bits(
|
||||
fn_in, fn_out, zero_db, clb_int=False, strict=True, verbose=False):
|
||||
fn_in, zero_db, clb_int=False, strict=True, verbose=False):
|
||||
'''
|
||||
Add multibit entries
|
||||
This requires adding some zero bits (ex: !31_09)
|
||||
|
|
@ -154,6 +154,13 @@ def add_zero_bits(
|
|||
zero_range(tag, bits, 22, 25)
|
||||
zero_groups(tag, bits, zero_db, strict=strict, verbose=verbose)
|
||||
|
||||
if len(bits) == 0:
|
||||
verbose and print(
|
||||
"WARNING: dropping unresolved line: %s" % line)
|
||||
drops += 1
|
||||
continue
|
||||
|
||||
|
||||
new_line = " ".join([tag] + sorted(bits))
|
||||
|
||||
if re.match(r'.*<.*>.*', new_line):
|
||||
|
|
@ -168,11 +175,7 @@ def add_zero_bits(
|
|||
if drops:
|
||||
print("WARNING: %s dropped %s unresolved lines" % (fn_in, drops))
|
||||
|
||||
with open(fn_out, "w") as f:
|
||||
for line in sorted(new_lines):
|
||||
print(line, file=f)
|
||||
|
||||
return changes
|
||||
return changes, new_lines
|
||||
|
||||
|
||||
def update_mask(db_root, mask_db, src_dbs, offset=0):
|
||||
|
|
@ -224,6 +227,57 @@ def load_zero_db(fn):
|
|||
ret.append(l)
|
||||
return ret
|
||||
|
||||
def remove_ambiguous_solutions(fn_in, db_lines, strict=True, verbose=True):
|
||||
""" Removes features with identical solutions.
|
||||
|
||||
During solving, some tags may be tightly coupled and solve to the same
|
||||
solution. In these cases, those solutions must be dropped until
|
||||
disambiguating information can be found.
|
||||
"""
|
||||
solutions = {}
|
||||
dropped_solutions = set()
|
||||
|
||||
for l in db_lines:
|
||||
parts = l.split()
|
||||
feature = parts[0]
|
||||
bits = frozenset(parts[1:])
|
||||
|
||||
if bits in solutions:
|
||||
if strict:
|
||||
assert False, "Found solution {} at least twice, in {} and {}".format(
|
||||
bits, feature, solutions[bits])
|
||||
else:
|
||||
dropped_solutions.add(bits)
|
||||
else:
|
||||
solutions[bits] = feature
|
||||
|
||||
|
||||
if strict:
|
||||
return 0, db_lines
|
||||
|
||||
drops = 0
|
||||
output_lines = []
|
||||
|
||||
for l in db_lines:
|
||||
parts = l.split()
|
||||
feature = parts[0]
|
||||
bits = frozenset(parts[1:])
|
||||
|
||||
if bits not in dropped_solutions:
|
||||
output_lines.append(l)
|
||||
drops += 1
|
||||
else:
|
||||
if verbose:
|
||||
print(
|
||||
"WARNING: dropping line due to duplicate solution: %s" % l)
|
||||
|
||||
if drops > 0:
|
||||
print("WARNING: %s dropped %s duplicate solutions" % (fn_in, drops))
|
||||
|
||||
return drops, output_lines
|
||||
|
||||
|
||||
|
||||
|
||||
def update_seg_fns(
|
||||
fn_inouts, zero_db, clb_int, lazy=False, strict=True, verbose=False):
|
||||
|
|
@ -234,13 +288,27 @@ def update_seg_fns(
|
|||
if lazy and not os.path.exists(fn_in):
|
||||
continue
|
||||
|
||||
changes = add_zero_bits(
|
||||
changes, new_lines = add_zero_bits(
|
||||
fn_in,
|
||||
fn_out,
|
||||
zero_db,
|
||||
clb_int=clb_int,
|
||||
strict=strict,
|
||||
verbose=verbose)
|
||||
|
||||
new_changes, final_lines = remove_ambiguous_solutions(
|
||||
fn_in,
|
||||
new_lines,
|
||||
strict=strict,
|
||||
verbose=verbose,
|
||||
)
|
||||
|
||||
changes += new_changes
|
||||
|
||||
|
||||
with open(fn_out, "w") as f:
|
||||
for line in sorted(final_lines):
|
||||
print(line, file=f)
|
||||
|
||||
if changes is not None:
|
||||
seg_files += 1
|
||||
seg_lines += changes
|
||||
|
|
@ -249,6 +317,7 @@ def update_seg_fns(
|
|||
(seg_files, seg_lines))
|
||||
|
||||
|
||||
|
||||
def update_masks(db_root):
|
||||
for mask_db, src_dbs in [
|
||||
("clbll_l", ("clbll_l", "int_l")),
|
||||
|
|
@ -348,7 +417,7 @@ def main():
|
|||
parser.add_argument('--zero-db', help='Apply custom patches')
|
||||
parser.add_argument('--seg-fn-in', help='')
|
||||
parser.add_argument('--seg-fn-out', help='')
|
||||
util.add_bool_arg(parser, "--strict", default=None)
|
||||
util.add_bool_arg(parser, "--strict", default=False)
|
||||
args = parser.parse_args()
|
||||
|
||||
run(
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export XRAY_DBFIXUP="python3 ${XRAY_UTILS_DIR}/dbfixup.py"
|
|||
export XRAY_MASKMERGE="bash ${XRAY_UTILS_DIR}/maskmerge.sh"
|
||||
export XRAY_SEGMATCH="${XRAY_TOOLS_DIR}/segmatch"
|
||||
export XRAY_SEGPRINT="python3 ${XRAY_UTILS_DIR}/segprint.py"
|
||||
export XRAY_BITS2FASM="python3 ${XRAY_UTILS_DIR}/bits2fasm.py"
|
||||
export XRAY_BIT2FASM="python3 ${XRAY_UTILS_DIR}/bit2fasm.py"
|
||||
export XRAY_FASM2FRAMES="python3 ${XRAY_UTILS_DIR}/fasm2frames.py"
|
||||
export XRAY_BITTOOL="${XRAY_TOOLS_DIR}/bittool"
|
||||
export XRAY_BLOCKWIDTH="python3 ${XRAY_UTILS_DIR}/blockwidth.py"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ design_bits.ok: vivado.ok
|
|||
\
|
||||
for x in design*.bit; do \
|
||||
${XRAY_BITREAD} -F ${XRAY_ROI_FRAMES} -o $${x}s -z -y $$x ; \
|
||||
${XRAY_BIT2FASM} --verbose $$x > $${x%.*}.fasm; \
|
||||
done
|
||||
touch design_bits.ok
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue