mirror of https://github.com/openXC7/prjxray.git
Add 010-lutinit fuzzer, Improve segmatch
Signed-off-by: Clifford Wolf <clifford@clifford.at> Signed-off-by: Tim 'mithro' Ansell <mithro@mithis.com>
This commit is contained in:
parent
c5eaa5af77
commit
715b261c3e
|
|
@ -0,0 +1,2 @@
|
|||
/specimen_[0-9][0-9][0-9]/
|
||||
/database.txt
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
N := 1
|
||||
SPECIMENS := $(addprefix specimen_,$(shell seq -f '%03.0f' $(N)))
|
||||
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
|
||||
|
||||
database.txt: $(SPECIMENS_OK)
|
||||
../../tools/segmatch -o database.txt \
|
||||
$(addsuffix /segdata_0.txt,$(SPECIMENS)) \
|
||||
$(addsuffix /segdata_1.txt,$(SPECIMENS)) \
|
||||
$(addsuffix /segdata_2.txt,$(SPECIMENS))
|
||||
|
||||
$(SPECIMENS_OK):
|
||||
bash generate.sh $(subst /OK,,$@)
|
||||
touch $@
|
||||
|
||||
clean:
|
||||
rm -rf $(SPECIMENS)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, sys, json, re
|
||||
|
||||
|
||||
#################################################
|
||||
# Loading Raw Source Data
|
||||
|
||||
grid = None
|
||||
bits = dict()
|
||||
luts = dict()
|
||||
|
||||
print("Loading grid.")
|
||||
with open("../../../gridinfo/grid-%s-db.json" % os.getenv("XRAY_PART"), "r") as f:
|
||||
grid = json.load(f)
|
||||
|
||||
print("Loading bits.")
|
||||
with open("design_%s.bits" % sys.argv[1], "r") as f:
|
||||
for line in f:
|
||||
line = line.split("_")
|
||||
bit_frame = int(line[1], 16)
|
||||
bit_wordidx = int(line[2], 16)
|
||||
bit_bitidx = int(line[3], 16)
|
||||
base_frame = bit_frame & ~0x7f
|
||||
|
||||
if base_frame not in bits:
|
||||
bits[base_frame] = dict()
|
||||
|
||||
if bit_wordidx not in bits[base_frame]:
|
||||
bits[base_frame][bit_wordidx] = set()
|
||||
|
||||
bits[base_frame][bit_wordidx].add((bit_frame, bit_wordidx, bit_bitidx))
|
||||
|
||||
print("Loading lut data.")
|
||||
with open("lutdata_%s.txt" % sys.argv[1], "r") as f:
|
||||
for line in f:
|
||||
line = line.split()
|
||||
site = line[0]
|
||||
bel = line[1]
|
||||
init = int(line[2][4:], 16)
|
||||
|
||||
if site not in luts:
|
||||
luts[site] = dict()
|
||||
|
||||
for i in range(64):
|
||||
bitname = "%s.INIT[%02d]" % (bel, i)
|
||||
luts[site][bitname] = ((init >> i) & 1) != 0
|
||||
|
||||
|
||||
#################################################
|
||||
# Group per Segment
|
||||
|
||||
print("Compile segment data.")
|
||||
|
||||
segments = dict()
|
||||
|
||||
for tilename, tiledata in grid["tiles"].items():
|
||||
found_data = False
|
||||
for site in tiledata["sites"]:
|
||||
if site in luts:
|
||||
found_data = True
|
||||
|
||||
if not found_data:
|
||||
continue
|
||||
|
||||
tile_type = tiledata["props"]["TYPE"]
|
||||
segname = "%s_%02x" % (tiledata["cfgcol"]["BASE_FRAMEID"][2:], min(tiledata["cfgcol"]["WORDS"]))
|
||||
|
||||
if not segname in segments:
|
||||
segments[segname] = { "bits": list(), "tags": dict() }
|
||||
|
||||
for site in tiledata["sites"]:
|
||||
if site not in luts:
|
||||
continue
|
||||
|
||||
if re.match(r"SLICE_X[0-9]*[02468]Y", site):
|
||||
sitekey = "SLICE_X0"
|
||||
elif re.match(r"SLICE_X[0-9]*[13579]Y", site):
|
||||
sitekey = "SLICE_X1"
|
||||
else:
|
||||
assert 0
|
||||
|
||||
for name, value in luts[site].items():
|
||||
segments[segname]["tags"]["%s.%s.%s" % (tile_type, sitekey, name)] = value
|
||||
|
||||
base_frame = int(tiledata["cfgcol"]["BASE_FRAMEID"][2:], 16)
|
||||
for wordidx in tiledata["cfgcol"]["WORDS"]:
|
||||
if base_frame not in bits:
|
||||
continue
|
||||
if wordidx not in bits[base_frame]:
|
||||
continue
|
||||
for bit_frame, bit_wordidx, bit_bitidx in bits[base_frame][wordidx]:
|
||||
segments[segname]["bits"].append("%02x_%02x_%02x" % (bit_frame - base_frame, bit_wordidx - min(tiledata["cfgcol"]["WORDS"]), bit_bitidx))
|
||||
|
||||
segments[segname]["bits"].sort()
|
||||
|
||||
|
||||
#################################################
|
||||
# Print
|
||||
|
||||
print("Write segment data.")
|
||||
|
||||
with open("segdata_%s.txt" % sys.argv[1], "w") as f:
|
||||
for segname, segdata in sorted(segments.items()):
|
||||
print("seg %s" % segname, file=f)
|
||||
for bitname in sorted(segdata["bits"]):
|
||||
print("bit %s" % bitname, file=f)
|
||||
for tagname, tagval in sorted(segdata["tags"].items()):
|
||||
print("tag %s %d" % (tagname, tagval), file=f)
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -ex
|
||||
source ../../settings.sh
|
||||
|
||||
test $# = 1
|
||||
test ! -e $1
|
||||
mkdir $1
|
||||
cd $1
|
||||
|
||||
echo '`define SEED 32'"'h$(echo $1 | md5sum | cut -c1-8)" > setseed.vh
|
||||
|
||||
vivado -mode batch -source ../generate.tcl
|
||||
|
||||
for i in 0 1 2; do
|
||||
../../../tools/bitread -F $XRAY_ROI_FRAMES -o design_$i.bits -zy < design_$i.bit
|
||||
python3 ../generate.py $i
|
||||
done
|
||||
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
create_project -force -part $::env(XRAY_PART) design design
|
||||
|
||||
read_verilog ../top.v
|
||||
synth_design -top top
|
||||
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_00) IOSTANDARD LVCMOS33" [get_ports clk]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_01) IOSTANDARD LVCMOS33" [get_ports di]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_02) IOSTANDARD LVCMOS33" [get_ports do]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_03) IOSTANDARD LVCMOS33" [get_ports stb]
|
||||
|
||||
set_property LOCK_PINS {I0:A1 I1:A2 I2:A3 I3:A4 I4:A5 I5:A6} \
|
||||
[get_cells -quiet -filter {REF_NAME == LUT6} -hierarchical]
|
||||
|
||||
create_pblock roi
|
||||
add_cells_to_pblock [get_pblocks roi] [get_cells roi]
|
||||
resize_pblock [get_pblocks roi] -add "$::env(XRAY_ROI)"
|
||||
|
||||
set_property CFGBVS VCCO [current_design]
|
||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
|
||||
|
||||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF]
|
||||
|
||||
place_design
|
||||
route_design
|
||||
|
||||
write_checkpoint -force design.dcp
|
||||
|
||||
|
||||
########################################
|
||||
# Unmodified design with random LUTs
|
||||
|
||||
proc write_lutdata {filename} {
|
||||
puts "Writing $filename."
|
||||
set fp [open $filename w]
|
||||
foreach cell [get_cells -hierarchical -filter {REF_NAME == LUT6}] {
|
||||
set bel [get_property BEL $cell]
|
||||
set loc [get_property LOC $cell]
|
||||
set init [get_property INIT $cell]
|
||||
puts $fp "$loc $bel $init"
|
||||
}
|
||||
close $fp
|
||||
}
|
||||
|
||||
write_bitstream -force design_0.bit
|
||||
write_lutdata lutdata_0.txt
|
||||
|
||||
|
||||
########################################
|
||||
# XOR LUT INITs
|
||||
|
||||
set pattern_list {
|
||||
0x1234567812345678
|
||||
0xFFFFFFFF00000000
|
||||
0xFFFF0000FFFF0000
|
||||
0xFF00FF00FF00FF00
|
||||
0xF0F0F0F0F0F0F0F0
|
||||
0xCCCCCCCCCCCCCCCC
|
||||
0xAAAAAAAAAAAAAAAA
|
||||
}
|
||||
|
||||
set pattern_index 0
|
||||
|
||||
foreach cell [get_cells -hierarchical -filter {REF_NAME == LUT6}] {
|
||||
set v [get_property init $cell]
|
||||
set v [scan [string range $v 4 100] %x]
|
||||
set v [expr $v ^ [lindex $pattern_list $pattern_index]]
|
||||
set v [format %x $v]
|
||||
set_property init 64'h$v $cell
|
||||
set pattern_index [expr ($pattern_index + 1) % 7]
|
||||
}
|
||||
|
||||
write_bitstream -force design_1.bit
|
||||
write_lutdata lutdata_1.txt
|
||||
|
||||
|
||||
########################################
|
||||
# Set LUT INITs
|
||||
|
||||
set pattern_index 1
|
||||
|
||||
foreach cell [get_cells -hierarchical -filter {REF_NAME == LUT6}] {
|
||||
set_property init 64'h[lindex $pattern_list $pattern_index] $cell
|
||||
set pattern_index [expr ($pattern_index + 1) % 7]
|
||||
}
|
||||
|
||||
write_bitstream -force design_2.bit
|
||||
write_lutdata lutdata_2.txt
|
||||
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
`include "setseed.vh"
|
||||
|
||||
module top(input clk, stb, di, output do);
|
||||
localparam integer DIN_N = 10;
|
||||
localparam integer DOUT_N = 10;
|
||||
|
||||
reg [DIN_N-1:0] din;
|
||||
wire [DOUT_N-1:0] dout;
|
||||
|
||||
reg [DIN_N-1:0] din_shr;
|
||||
reg [DOUT_N-1:0] dout_shr;
|
||||
|
||||
always @(posedge clk) begin
|
||||
din_shr <= {din_shr, di};
|
||||
dout_shr <= {dout_shr, din_shr[DIN_N-1]};
|
||||
if (stb) begin
|
||||
din <= din_shr;
|
||||
dout_shr <= dout;
|
||||
end
|
||||
end
|
||||
|
||||
assign do = dout_shr[DOUT_N-1];
|
||||
|
||||
roi roi (
|
||||
.clk(clk),
|
||||
.din(din),
|
||||
.dout(dout)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module roi(input clk, input [9:0] din, output [9:0] dout);
|
||||
localparam integer N = 200;
|
||||
|
||||
function [31:0] xorshift32(input [31:0] v);
|
||||
begin
|
||||
xorshift32 = v;
|
||||
xorshift32 = xorshift32 ^ (xorshift32 << 13);
|
||||
xorshift32 = xorshift32 ^ (xorshift32 >> 17);
|
||||
xorshift32 = xorshift32 ^ (xorshift32 << 5);
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [31:0] hash32(input [31:0] v);
|
||||
begin
|
||||
hash32 = v ^ `SEED;
|
||||
hash32 = xorshift32(hash32);
|
||||
hash32 = xorshift32(hash32);
|
||||
hash32 = xorshift32(hash32);
|
||||
hash32 = xorshift32(hash32);
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [63:0] hash64(input [31:0] v);
|
||||
begin
|
||||
hash64[63:32] = hash32(v);
|
||||
hash64[31: 0] = hash32(~v);
|
||||
end
|
||||
endfunction
|
||||
|
||||
wire [N*10+9:0] nets;
|
||||
|
||||
assign nets[9:0] = din;
|
||||
assign dout = nets[N*10+9:N*10];
|
||||
|
||||
genvar i, j;
|
||||
generate
|
||||
for (i = 0; i < N; i = i+1) begin:is
|
||||
for (j = 0; j < 10; j = j+1) begin:js
|
||||
localparam integer k = i*10 + j + 10;
|
||||
wire lut_out;
|
||||
|
||||
LUT6 #(
|
||||
.INIT(hash64({i, j, 8'hff}))
|
||||
) lut (
|
||||
.I0(nets[hash32({i, j, 8'h00}) % k]),
|
||||
.I1(nets[hash32({i, j, 8'h01}) % k]),
|
||||
.I2(nets[k-10]),
|
||||
.I3(nets[k-9]),
|
||||
.I4(nets[k-8]),
|
||||
.I5(nets[k-7]),
|
||||
.O(lut_out)
|
||||
);
|
||||
|
||||
reg lut_out_reg;
|
||||
always @(posedge clk)
|
||||
lut_out_reg <= lut_out;
|
||||
|
||||
assign nets[k] = ((i+j) % 17) < 10 ? lut_out_reg : lut_out;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <numeric>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
|
@ -26,18 +27,18 @@ static inline vector<bool> &segdata_bits(segdata_t &sd) { return std::get<0>(sd)
|
|||
static inline vector<bool> &segdata_tags1(segdata_t &sd) { return std::get<1>(sd); }
|
||||
static inline vector<bool> &segdata_tags0(segdata_t &sd) { return std::get<2>(sd); }
|
||||
|
||||
void read_input()
|
||||
void read_input(std::istream &f, std::string filename)
|
||||
{
|
||||
string token;
|
||||
segdata_t *segptr = nullptr;
|
||||
|
||||
while (std::cin >> token)
|
||||
while (f >> token)
|
||||
{
|
||||
if (token == "seg")
|
||||
{
|
||||
std::cin >> token;
|
||||
while (segdata.count(token))
|
||||
token += "_";
|
||||
f >> token;
|
||||
token = filename + ":" + token;
|
||||
assert(segdata.count(token) == 0);
|
||||
segptr = &segdata[token];
|
||||
continue;
|
||||
}
|
||||
|
|
@ -46,7 +47,7 @@ void read_input()
|
|||
{
|
||||
assert(segptr != nullptr);
|
||||
|
||||
std::cin >> token;
|
||||
f >> token;
|
||||
if (bit_ids.count(token) == 0) {
|
||||
bit_ids[token] = num_bits++;
|
||||
bit_ids_r.push_back(token);
|
||||
|
|
@ -66,7 +67,7 @@ void read_input()
|
|||
{
|
||||
assert(segptr != nullptr);
|
||||
|
||||
std::cin >> token;
|
||||
f >> token;
|
||||
if (tag_ids.count(token) == 0) {
|
||||
tag_ids[token] = num_tags++;
|
||||
tag_ids_r.push_back(token);
|
||||
|
|
@ -74,7 +75,7 @@ void read_input()
|
|||
|
||||
int tag_idx = tag_ids.at(token);
|
||||
|
||||
std::cin >> token;
|
||||
f >> token;
|
||||
assert(token == "0" || token == "1");
|
||||
|
||||
auto &tags = token == "1" ? segdata_tags1(*segptr) : segdata_tags0(*segptr);
|
||||
|
|
@ -116,53 +117,57 @@ void andc_masks(vector<bool> &dst_mask, const vector<bool> &src_mask)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *outfile = nullptr;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "")) != -1)
|
||||
while ((opt = getopt(argc, argv, "o:")) != -1)
|
||||
switch (opt)
|
||||
{
|
||||
// case 'c':
|
||||
// mode_c = true;
|
||||
// break;
|
||||
// case 'r':
|
||||
// mode_r = true;
|
||||
// break;
|
||||
// case 'm':
|
||||
// mode_m = true;
|
||||
// break;
|
||||
// case 'x':
|
||||
// mode_x = true;
|
||||
// break;
|
||||
// case 'y':
|
||||
// mode_y = true;
|
||||
// break;
|
||||
// case 'z':
|
||||
// mode_z = true;
|
||||
// break;
|
||||
// case 'C':
|
||||
// chksum = true;
|
||||
// break;
|
||||
// case 'f':
|
||||
// frames.insert(strtol(optarg, nullptr, 0));
|
||||
// break;
|
||||
// case 'o':
|
||||
// outfile = optarg;
|
||||
// break;
|
||||
case 'o':
|
||||
outfile = optarg;
|
||||
break;
|
||||
default:
|
||||
goto help;
|
||||
}
|
||||
|
||||
if (optind != argc) {
|
||||
if (0) {
|
||||
help:
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Usage: %s [options] < segdata.txt\n", argv[0]);
|
||||
fprintf(stderr, "Usage: %s [options] file..\n", argv[0]);
|
||||
fprintf(stderr, "\n");
|
||||
// fprintf(stderr, " -c\n");
|
||||
// fprintf(stderr, " continuation mode. output '*' for repeating patterns\n");
|
||||
fprintf(stderr, " -o <filename>\n");
|
||||
fprintf(stderr, " set output file\n");
|
||||
fprintf(stderr, "\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
read_input();
|
||||
if (optind != argc) {
|
||||
while (optind != argc) {
|
||||
printf("Reading %s.\n", argv[optind]);
|
||||
std::ifstream f;
|
||||
f.open(argv[optind]);
|
||||
assert(!f.fail());
|
||||
read_input(f, argv[optind++]);
|
||||
}
|
||||
} else {
|
||||
printf("Reading from stding.\n");
|
||||
read_input(std::cin, "stdin");
|
||||
}
|
||||
|
||||
printf("#of segments: %d\n", int(segdata.size()));
|
||||
printf("#of bits: %d\n", num_bits);
|
||||
printf("#of tags: %d\n", num_tags);
|
||||
|
||||
FILE *f = stdout;
|
||||
|
||||
if (outfile) {
|
||||
f = fopen(outfile, "w");
|
||||
assert(f != nullptr);
|
||||
}
|
||||
|
||||
int min_candidates = num_bits;
|
||||
int max_candidates = 0;
|
||||
float avg_candidates = 0;
|
||||
|
||||
for (int tag_idx = 0; tag_idx < num_tags; tag_idx++)
|
||||
{
|
||||
|
|
@ -184,19 +189,26 @@ help:
|
|||
}
|
||||
|
||||
int num_candidates = std::accumulate(mask.begin(), mask.end(), 0);
|
||||
min_candidates = std::min(min_candidates, num_candidates);
|
||||
max_candidates = std::max(max_candidates, num_candidates);
|
||||
avg_candidates += float(num_candidates) / num_tags;
|
||||
|
||||
printf("%s", tag_ids_r.at(tag_idx).c_str());
|
||||
fprintf(f, "%s", tag_ids_r.at(tag_idx).c_str());
|
||||
|
||||
if (0 < num_candidates && num_candidates <= 4) {
|
||||
for (int bit_idx = 0; bit_idx < num_bits; bit_idx++)
|
||||
if (mask.at(bit_idx))
|
||||
printf(" %s", bit_ids_r.at(bit_idx).c_str());
|
||||
printf("\n");
|
||||
fprintf(f, " %s", bit_ids_r.at(bit_idx).c_str());
|
||||
fprintf(f, "\n");
|
||||
} else {
|
||||
printf(" <%d candidates>\n", num_candidates);
|
||||
fprintf(f, " <%d candidates>\n", num_candidates);
|
||||
}
|
||||
}
|
||||
|
||||
printf("min #of candidates: %d\n", min_candidates);
|
||||
printf("max #of candidates: %d\n", max_candidates);
|
||||
printf("avg #of candidates: %f\n", avg_candidates);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue