clbn5ffmux fuzzer

Signed-off-by: John McMaster <JohnDMcMaster@gmail.com>
Signed-off-by: Tim 'mithro' Ansell <mithro@mithis.com>
This commit is contained in:
John McMaster 2017-12-01 16:20:13 -08:00 committed by Tim 'mithro' Ansell
parent 8317c00c4e
commit 7c2500eee7
6 changed files with 314 additions and 0 deletions

View File

@ -0,0 +1,22 @@
N := 1
SPECIMENS := $(addprefix specimen_,$(shell seq -f '%03.0f' $(N)))
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
database: $(SPECIMENS_OK)
${XRAY_SEGMATCH} -o seg_clblx.segbits $(addsuffix /segdata_clbl[lm]_[lr].txt,$(SPECIMENS))
pushdb:
${XRAY_MERGEDB} clbll_l seg_clblx.segbits
${XRAY_MERGEDB} clbll_r seg_clblx.segbits
${XRAY_MERGEDB} clblm_l seg_clblx.segbits
${XRAY_MERGEDB} clblm_r seg_clblx.segbits
$(SPECIMENS_OK):
bash generate.sh $(subst /OK,,$@)
touch $@
clean:
rm -rf specimen_[0-9][0-9][0-9]/ seg_clblx.segbits vivado*.log vivado_*.str vivado*.jou design *.bits *.dcp *.bit top.v
.PHONY: database pushdb clean

View File

@ -0,0 +1,16 @@
Purpose:
Document A5FFMUX family of CLB muxes
Algorithm:
*5FFMUX
Inputs can come from either the LUT6_2 NO5 output or the CLB NX input
To perturb the CLB the smallest, want LUT6 always instantiated
However, some routing congestion that would require putting FFs in bypass
(which turns out is actually okay, but didn't realize that at the time)
Decided instead ot instantiate LUT8, but not use the output
Turns out this is okay and won't optimize things away
So then, the 5FF D input is switched between the O5 output and an external CLB input
Outcome:
Bits are one hot encoded per mux position

View File

@ -0,0 +1,33 @@
#!/usr/bin/env python3
import sys, re
sys.path.append("../../../utils/")
from segmaker import segmaker
segmk = segmaker("design.bits")
print("Loading tags")
'''
module,loc,n,def_a
clb_N5FFMUX,SLICE_X12Y100,3,1
clb_N5FFMUX,SLICE_X13Y100,0,1
clb_N5FFMUX,SLICE_X14Y100,3,1
'''
f = open('params.csv', 'r')
f.readline()
for l in f:
module,loc,n,def_a = l.split(',')
def_a = int(def_a)
n = int(n)
#which = chr(ord('A') + n)
for i, which in enumerate('ABCD'):
# Theory: there is one bit for each mux positon
# In each config 3 muxes are in one position, other 3 are in another
inv = int(i == n)
segmk.addtag(loc, "%c5FF.MUX.A" % which, def_a ^ inv)
segmk.addtag(loc, "%c5FF.MUX.B" % which, 1 ^ def_a ^ inv)
segmk.compile()
segmk.write()

View File

@ -0,0 +1,17 @@
#!/bin/bash
set -ex
. ../../utils/genheader.sh
#echo '`define SEED 32'"'h$(echo $1 | md5sum | cut -c1-8)" > setseed.vh
python3 ../top.py >top.v
vivado -mode batch -source ../generate.tcl
for x in design*.bit; do
../../../build/tools/bitread -F $XRAY_ROI_FRAMES -o ${x}s -z -y $x
done
python3 ../generate.py

View File

@ -0,0 +1,26 @@
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 stb]
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_02) IOSTANDARD LVCMOS33" [get_ports di]
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_03) IOSTANDARD LVCMOS33" [get_ports do]
create_pblock roi
set_property EXCLUDE_PLACEMENT 1 [get_pblocks 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
write_bitstream -force design.bit

View File

@ -0,0 +1,200 @@
import random
random.seed(0)
CLBN = 40
# SLICE_X12Y100
# SLICE_X27Y149
SLICEX = (12, 28)
SLICEY = (100, 150)
# 800
SLICEN = (SLICEY[1] - SLICEY[0]) * (SLICEX[1] - SLICEX[0])
print('//SLICEX: %s' % str(SLICEX))
print('//SLICEY: %s' % str(SLICEY))
print('//SLICEN: %s' % str(SLICEN))
print('//Requested CLBs: %s' % str(CLBN))
def gen_slices():
for slicey in range(*SLICEY):
for slicex in range(*SLICEX):
yield "SLICE_X%dY%d" % (slicex, slicey)
DIN_N = CLBN * 8
DOUT_N = CLBN * 8
print('''
module top(input clk, stb, di, output do);
localparam integer DIN_N = %d;
localparam integer DOUT_N = %d;
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
''' % (DIN_N, DOUT_N))
f = open('params.csv', 'w')
f.write('module,loc,n,def_a\n')
slices = gen_slices()
print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1))
for i in range(CLBN):
bel = ''
module = 'clb_N5FFMUX'
n = random.randint(0, 3)
def_a = random.randint(0, 1)
loc = next(slices)
print(' %s' % module)
print(' #(.LOC("%s"), .N(%d), .DEF_A(%d))' % (loc, n, def_a))
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
f.write('%s,%s,%s,%s\n' % (module, loc, n, def_a))
f.close()
print('''endmodule
// ---------------------------------------------------------------------
''')
print('''
module clb_N5FFMUX (input clk, input [7:0] din, output [7:0] dout);
parameter LOC="SLICE_X22Y100";
parameter N=-1;
parameter DEF_A=1;
wire lutdo, lutco, lutbo, lutao;
wire lut7bo, lut7ao;
wire lut8o;
reg [3:0] ffds;
wire lutdo5, lutco5, lutbo5, lutao5;
//wire lutno5 [3:0] = {lutao5, lutbo5, lutco5, lutdo5};
wire lutno5 [3:0] = {lutdo5, lutco5, lutbo5, lutao5};
always @(*) begin
if (DEF_A) begin
//Default poliarty A
ffds[3] = lutdo5;
ffds[2] = lutco5;
ffds[1] = lutbo5;
ffds[0] = lutao5;
ffds[N] = din[6];
end else begin
//Default polarity B
ffds[3] = din[6];
ffds[2] = din[6];
ffds[1] = din[6];
ffds[0] = din[6];
ffds[N] = lutno5[N];
end
end
(* LOC=LOC, BEL="F8MUX", KEEP, DONT_TOUCH *)
MUXF8 mux8 (.O(), .I0(lut7bo), .I1(lut7ao), .S(din[6]));
(* LOC=LOC, BEL="F7BMUX", KEEP, DONT_TOUCH *)
MUXF7 mux7b (.O(lut7bo), .I0(lutdo), .I1(lutco), .S(din[6]));
(* LOC=LOC, BEL="F7AMUX", KEEP, DONT_TOUCH *)
MUXF7 mux7a (.O(lut7ao), .I0(lutbo), .I1(lutao), .S(din[6]));
(* LOC=LOC, BEL="D6LUT", KEEP, DONT_TOUCH *)
LUT6_2 #(
.INIT(64'h8000_DEAD_0000_0001)
) lutd (
.I0(din[0]),
.I1(din[1]),
.I2(din[2]),
.I3(din[3]),
.I4(din[4]),
.I5(din[5]),
.O5(lutdo5),
.O6(lutdo));
(* LOC=LOC, BEL="D5FF" *)
FDPE ffd (
.C(clk),
.Q(dout[1]),
.CE(din[0]),
.PRE(din[1]),
.D(ffds[3]));
(* LOC=LOC, BEL="C6LUT", KEEP, DONT_TOUCH *)
LUT6_2 #(
.INIT(64'h8000_BEEF_0000_0001)
) lutc (
.I0(din[0]),
.I1(din[1]),
.I2(din[2]),
.I3(din[3]),
.I4(din[4]),
.I5(din[5]),
.O5(lutco5),
.O6(lutco));
(* LOC=LOC, BEL="C5FF" *)
FDPE ffc (
.C(clk),
.Q(dout[2]),
.CE(din[0]),
.PRE(din[1]),
.D(ffds[2]));
(* LOC=LOC, BEL="B6LUT", KEEP, DONT_TOUCH *)
LUT6_2 #(
.INIT(64'h8000_CAFE_0000_0001)
) lutb (
.I0(din[0]),
.I1(din[1]),
.I2(din[2]),
.I3(din[3]),
.I4(din[4]),
.I5(din[5]),
.O5(lutbo5),
.O6(lutbo));
(* LOC=LOC, BEL="B5FF" *)
FDPE ffb (
.C(clk),
.Q(dout[3]),
.CE(din[0]),
.PRE(din[1]),
.D(ffds[1]));
(* LOC=LOC, BEL="A6LUT", KEEP, DONT_TOUCH *)
LUT6_2 #(
.INIT(64'h8000_1CE0_0000_0001)
) luta (
.I0(din[0]),
.I1(din[1]),
.I2(din[2]),
.I3(din[3]),
.I4(din[4]),
.I5(din[5]),
.O5(lutao5),
.O6(lutao));
(* LOC=LOC, BEL="A5FF" *)
FDPE ffa (
.C(clk),
.Q(dout[4]),
.CE(din[0]),
.PRE(din[1]),
//D can only come from O5 or AX
//AX is used by MUXF7:S
.D(ffds[0]));
endmodule
''')