clbram fuzzer WIP

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-13 16:42:49 -08:00 committed by Tim 'mithro' Ansell
parent d0458bca71
commit ffd77f321d
6 changed files with 539 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

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,18 @@
#!/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
test -z "$(fgrep CRITICAL vivado.log)"
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

440
fuzzers/018-clbram/top.py Normal file
View File

@ -0,0 +1,440 @@
import random
random.seed(0)
import os
import re
def slice_xy():
'''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)'''
# SLICE_X12Y100:SLICE_X27Y149
# Note XRAY_ROI_GRID_* is something else
m = re.match(r'SLICE_X(.*)Y(.*):SLICE_X(.*)Y(.*)', os.getenv('XRAY_ROI'))
ms = [int(m.group(i + 1)) for i in range(4)]
return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
CLBN = 4
SLICEX, SLICEY = slice_xy()
# 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))
# Rearranged to sweep Y so that carry logic is easy to allocate
# XXX: careful...if odd number of Y in ROI will break carry
def gen_slicems():
'''
SLICEM at the following:
SLICE_XxY*
Where Y any value
x
Always even (ie 100, 102, 104, etc)
In our ROI
x = 6, 8, 10, 12, 14
'''
# TODO: generate this from DB
assert((12, 28) == SLICEX)
for slicex in (12, 14):
for slicey in range(*SLICEY):
# caller may reject position if needs more room
#yield ("SLICE_X%dY%d" % (slicex, slicey), (slicex, slicey))
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_slicems()
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 = ''
# Can fit 4 per CLB
# BELable
multi_bels_by = [
'SRL16E',
'SRLC32E',
]
# Not BELable
multi_bels_bn = [
'RAM32X1S',
'RAM64X1S',
]
# Those requiring special resources
# Just make one per module
greedy_modules = [
'my_RAM128X1D',
'my_RAM128X1S',
'my_RAM256X1S',
]
loc = next(slices)
cparams = ''
# Multi module
if random.randint(0, 3) > 0:
params = ''
module = 'my_ram_N'
# Pick one un-LOCable and then fill in with LOCable
unbel_beli = random.randint(0, 3)
bels = []
for beli in range(4):
belc = chr(ord('A') + beli)
if beli == unbel_beli:
# Chose a BEL instance that will get implicitly placed
bel = random.choice(multi_bels_bn)
params += ', .N_%s(1)' % bel
else:
bel = random.choice(multi_bels_by)
params += ', .%c_%s(1)' % (belc, bel)
bels.append(bel)
# Record the BELs we chose in the module (A, B, C, D)
cparams = ',' + (', '.join(bels))
# Greedy module
# Don't place anything else in it
# For solving muxes vs previous results
else:
module = random.choice(greedy_modules)
params = ''
print(' %s' % module)
print(' #(.LOC("%s")%s)' % (loc, params))
print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i))
f.write('%s,%s%s\n' % (module, loc, cparams))
f.close()
print('''endmodule
// ---------------------------------------------------------------------
''')
print('''
//***************************************************************
//Supermodule
//BEL: yes
module my_ram_N (input clk, input [7:0] din, output [7:0] dout);
parameter LOC = "";
parameter D_SRL16E=0;
parameter D_SRLC32E=0;
parameter C_SRL16E=0;
parameter C_SRLC32E=0;
parameter B_SRL16E=0;
parameter B_SRLC32E=0;
parameter A_SRL16E=0;
parameter A_SRLC32E=0;
parameter N_RAM32X1S=0;
parameter N_RAM64X1S=0;
generate
if (D_SRL16E) begin
(* LOC=LOC, BEL="D6LUT", KEEP, DONT_TOUCH *)
SRL16E #(
) lutd (
.Q(dout[3]),
.A0(din[0]),
.A1(din[1]),
.A2(din[2]),
.A3(din[3]),
.CE(din[4]),
.CLK(din[5]),
.D(din[6]));
end
if (D_SRLC32E) begin
(* LOC=LOC, BEL="D6LUT", KEEP, DONT_TOUCH *)
SRLC32E #(
.INIT(32'h00000000),
.IS_CLK_INVERTED(1'b0)
) lutd (
.Q(dout[3]),
.Q31(),
.A(din[4:0]),
.CE(din[5]),
.CLK(din[6]),
.D(din[7]));
end
if (C_SRL16E) begin
(* LOC=LOC, BEL="C6LUT", KEEP, DONT_TOUCH *)
SRL16E #(
) lutc (
.Q(dout[2]),
.A0(din[0]),
.A1(din[1]),
.A2(din[2]),
.A3(din[3]),
.CE(din[4]),
.CLK(din[5]),
.D(din[6]));
end
if (C_SRLC32E) begin
(* LOC=LOC, BEL="C6LUT", KEEP, DONT_TOUCH *)
SRLC32E #(
.INIT(32'h00000000),
.IS_CLK_INVERTED(1'b0)
) lutc (
.Q(dout[2]),
.Q31(),
.A(din[4:0]),
.CE(din[5]),
.CLK(din[6]),
.D(din[7]));
end
if (B_SRL16E) begin
(* LOC=LOC, BEL="B6LUT", KEEP, DONT_TOUCH *)
SRL16E #(
) lutb (
.Q(dout[1]),
.A0(din[0]),
.A1(din[1]),
.A2(din[2]),
.A3(din[3]),
.CE(din[4]),
.CLK(din[5]),
.D(din[6]));
end
if (B_SRLC32E) begin
(* LOC=LOC, BEL="B6LUT", KEEP, DONT_TOUCH *)
SRLC32E #(
.INIT(32'h00000000),
.IS_CLK_INVERTED(1'b0)
) lutb (
.Q(dout[1]),
.Q31(),
.A(din[4:0]),
.CE(din[5]),
.CLK(din[6]),
.D(din[7]));
end
if (A_SRL16E) begin
(* LOC=LOC, BEL="A6LUT", KEEP, DONT_TOUCH *)
SRL16E #(
) luta (
.Q(dout[0]),
.A0(din[0]),
.A1(din[1]),
.A2(din[2]),
.A3(din[3]),
.CE(din[4]),
.CLK(din[5]),
.D(din[6]));
end
if (A_SRLC32E) begin
(* LOC=LOC, BEL="A6LUT", KEEP, DONT_TOUCH *)
SRLC32E #(
.INIT(32'h00000000),
.IS_CLK_INVERTED(1'b0)
) luta (
.Q(dout[0]),
.Q31(),
.A(din[4:0]),
.CE(din[5]),
.CLK(din[6]),
.D(din[7]));
end
if (N_RAM32X1S) begin
(* LOC=LOC, KEEP, DONT_TOUCH *)
RAM32X1S #(
) RAM32X1S (
.O(dout[4]),
.A0(din[0]),
.A1(din[1]),
.A2(din[2]),
.A3(din[3]),
.A4(din[4]),
.D(din[5]),
.WCLK(din[6]),
.WE(din[7]));
end
if (N_RAM64X1S) begin
(* LOC=LOC, KEEP, DONT_TOUCH *)
RAM64X1S #(
) RAM64X1S (
.O(dout[4]),
.A0(din[0]),
.A1(din[1]),
.A2(din[2]),
.A3(din[3]),
.A4(din[4]),
.A5(din[5]),
.D(din[6]),
.WCLK(clk),
.WE(din[0]));
end
endgenerate
endmodule
//***************************************************************
//Basic
//BEL: yes
module my_SRL16E (input clk, input [7:0] din, output [7:0] dout);
parameter LOC = "";
parameter BEL="A6LUT";
(* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *)
SRL16E #(
) SRL16E (
.Q(dout[0]),
.A0(din[0]),
.A1(din[1]),
.A2(din[2]),
.A3(din[3]),
.CE(din[4]),
.CLK(din[5]),
.D(din[6]));
endmodule
//BEL: yes
module my_SRLC32E (input clk, input [7:0] din, output [7:0] dout);
parameter LOC = "";
parameter BEL="A6LUT";
wire mc31c;
(* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *)
SRLC32E #(
.INIT(32'h00000000),
.IS_CLK_INVERTED(1'b0)
) lut (
.Q(dout[0]),
.Q31(mc31c),
.A(din[4:0]),
.CE(din[5]),
.CLK(din[6]),
.D(din[7]));
endmodule
//BEL: can't
module my_RAM32X1S (input clk, input [7:0] din, output [7:0] dout);
parameter LOC = "";
(* LOC=LOC, KEEP, DONT_TOUCH *)
RAM32X1S #(
) RAM32X1S (
.O(dout[0]),
.A0(din[0]),
.A1(din[1]),
.A2(din[2]),
.A3(din[3]),
.A4(din[4]),
.D(din[5]),
.WCLK(din[6]),
.WE(din[7]));
endmodule
//BEL: can't
module my_RAM64X1S (input clk, input [7:0] din, output [7:0] dout);
parameter LOC = "";
(* LOC=LOC, KEEP, DONT_TOUCH *)
RAM64X1S #(
) RAM64X1S (
.O(dout[0]),
.A0(din[0]),
.A1(din[1]),
.A2(din[2]),
.A3(din[3]),
.A4(din[4]),
.A5(din[5]),
.D(din[6]),
.WCLK(clk),
.WE(din[0]));
endmodule
//***************************************************************
//WA*USED
//Dedicated LOC
module my_RAM128X1D (input clk, input [7:0] din, output [7:0] dout);
parameter LOC = "";
(* LOC=LOC, KEEP, DONT_TOUCH *)
RAM128X1D #(
.INIT(128'h0),
.IS_WCLK_INVERTED(1'b0)
) RAM128X1D (
.DPO(dout[0]),
.SPO(dout[1]),
.D(din[0]),
.WCLK(clk),
.WE(din[2]));
endmodule
//Dedicated LOC
module my_RAM128X1S (input clk, input [7:0] din, output [7:0] dout);
parameter LOC = "";
(* LOC=LOC, KEEP, DONT_TOUCH *)
RAM128X1S #(
) RAM128X1S (
.O(dout[0]),
.A0(din[0]),
.A1(din[1]),
.A2(din[2]),
.A3(din[3]),
.A4(din[4]),
.A5(din[5]),
.A6(din[6]),
.D(din[7]),
.WCLK(din[0]),
.WE(din[1]));
endmodule
//Dedicated LOC
module my_RAM256X1S (input clk, input [7:0] din, output [7:0] dout);
parameter LOC = "";
(* LOC=LOC, KEEP, DONT_TOUCH *)
RAM256X1S #(
) RAM256X1S (
.O(dout[0]),
.A({din[0], din[7:0]}),
.D(din[0]),
.WCLK(din[1]),
.WE(din[2]));
endmodule
''')