diff --git a/experiments/ffprim/Makefile b/experiments/ffprim/Makefile new file mode 100644 index 00000000..9694622c --- /dev/null +++ b/experiments/ffprim/Makefile @@ -0,0 +1,22 @@ +N := 1 +SPECIMENS := $(addprefix specimen_,$(shell seq -f '%03.0f' $(N))) +SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS)) + +database: $(SPECIMENS_OK) + ../../tools/segmatch -o seg_clblx.segbits $(addsuffix /segdata_clbl[lm]_[lr].txt,$(SPECIMENS)) + +pushdb: + bash ../../utils/mergedb.sh clbll_l seg_clblx.segbits + bash ../../utils/mergedb.sh clbll_r seg_clblx.segbits + bash ../../utils/mergedb.sh clblm_l seg_clblx.segbits + bash ../../utils/mergedb.sh 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 + diff --git a/experiments/ffprim/README.txt b/experiments/ffprim/README.txt new file mode 100644 index 00000000..deae162f --- /dev/null +++ b/experiments/ffprim/README.txt @@ -0,0 +1,40 @@ +Clock inversion is per slice (as BEL CLKINV) +Vivado GUI is misleading as it often shows it per FF, which is not actually true + +CLB.SLICE_X0.AFF.FF_INV_CLK 00_51 +CLB.SLICE_X1.AFF.FF_INV_CLK <0 candidates> +Clifford suggests X1 may be in adjacent tile +as he found with X1 INIT values +More research needed + + + + +CLB.SLICE_X0.AFF.FF_INV_CLK 00_51 +CLB.SLICE_X0.FF_FDCE 00_21 00_24 00_25 00_26 00_29 00_35 29_01 29_12 30_01 30_03 +CLB.SLICE_X0.FF_FDPE 00_21 00_24 00_25 00_26 00_29 00_35 29_01 30_01 +CLB.SLICE_X0.FF_FDRE 00_21 00_24 00_25 00_26 00_29 29_01 29_12 30_01 30_03 +CLB.SLICE_X0.FF_FDSE 00_21 00_24 00_25 00_26 00_29 00_35 29_01 30_01 +CLB.SLICE_X0.FF_USED 00_21 00_24 00_25 00_26 00_29 29_01 30_01 +CLB.SLICE_X1.AFF.FF_INV_CLK <0 candidates> +CLB.SLICE_X1.FF_FDCE 00_21 00_24 00_25 00_26 00_29 29_01 30_01 30_04 30_15 +CLB.SLICE_X1.FF_FDPE 00_21 00_24 00_25 00_26 00_29 29_01 30_01 +CLB.SLICE_X1.FF_FDRE 00_21 00_24 00_25 00_26 00_29 00_31 29_01 30_01 30_04 30_15 +CLB.SLICE_X1.FF_FDSE 00_21 00_24 00_25 00_26 00_29 00_31 29_01 30_01 +CLB.SLICE_X1.FF_USED 00_21 00_24 00_25 00_26 00_29 29_01 30_01 + + +Following bits are always present with a FF + 00_21 + 00_24 + 00_25 + 00_26 + 00_29 + 29_01 + 30_01 +Interesting bits are then +CLB.SLICE_X0.FF_FDCE 00_35 29_12 30_03 +CLB.SLICE_X0.FF_FDPE 00_35 +CLB.SLICE_X0.FF_FDSE 00_35 +CLB.SLICE_X0.FF_FDRE 29_12 30_03 + diff --git a/experiments/ffprim/generate.py b/experiments/ffprim/generate.py new file mode 100644 index 00000000..27a6242f --- /dev/null +++ b/experiments/ffprim/generate.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 + +import sys, re + +sys.path.append("../../../utils/") +from segmaker import segmaker + +segmk = segmaker("design.bits") + +ffprims = ( + 'FD', + 'FD_1', + 'FDC', + 'FDC_1', + 'FDCE', + 'FDCE_1', + 'FDE', + 'FDE_1', + 'FDP', + 'FDP_1', + 'FDPE', + 'FDPE_1', + 'FDR', + 'FDR_1', + 'FDRE', + 'FDRE_1', + 'FDS', + 'FDS_1', + 'FDSE', + 'FDSE_1', + ) +ffprims = ( + 'FDRE', + 'FDSE', + 'FDCE', + 'FDPE', + ) + +print("Loading tags from design.txt") +with open("design.txt", "r") as f: + for line in f: + ''' + puts $fp "$type $tile $grid_x $grid_y $ff $bel_type $used $usedstr" + + CLBLM_L CLBLM_L_X10Y137 30 13 SLICE_X13Y137/AFF REG_INIT 1 FDRE + CLBLM_L CLBLM_L_X10Y137 30 13 SLICE_X12Y137/D5FF FF_INIT 0 + ''' + line = line.split() + tile_type = line[0] + tile_name = line[1] + grid_x = line[2] + grid_y = line[3] + # Other code uses BEL name + site_ff_name = line[4] + site, ff_name = site_ff_name.split('/') + ff_type = line[5] + used = int(line[6]) + ref_name = None + cel_name = None + if used: + cel_name = line[7] + ref_name = line[8] + # 1'b1 + # cinv = int(line[9][-1]) + cinv = int(line[9]) + + which = ff_name[0] + # Reduced test for now + if ff_name != 'AFF': + continue + + segmk.addtag(site, "FF_USED", used) + if 1: + # If unused mark all primitives as not present + # Otherwise mark the primitive we are using + for ffprim in ffprims: + if not used: + segmk.addtag(site, "FF_%s" % ffprim, 0) + elif ref_name == ffprim: + segmk.addtag(site, "FF_%s" % ffprim, 1) + + ''' + Experiment diffing against one of the lower bit set candidates + can probably isolate a few bits this way + really though I want to diff against USED but not sure how to do that + + CLB.SLICE_X0.FF_USED <7 candidates> + CLB.SLICE_X0.FF_FDSE <8 candidates> + CLB.SLICE_X0.FF_FDPE <8 candidates> + CLB.SLICE_X0.FF_FDRE <9 candidates> + CLB.SLICE_X0.FF_FDCE <10 candidates> + ''' + if 1: + # If unused mark all primitives as not present + # Otherwise mark the primitive we are using + if used: + base = 'FDSE' + if ref_name == base: + for ffprim in ffprims: + segmk.addtag(site, "FF_DIFF_%s_%s" % (base, fprim, 0) + + + for ffprim in ffprims: + segmk.addtag(site, "FF_%s" % ffprim, 0) + elif + segmk.addtag(site, "FF_%s" % ffprim, 1) + + # Compare '_1' negative edge clock to positive edge + if used: + #inv_clk = ref_name.endswith("_1") + inv_clk = cinv + segmk.addtag(site, "%s.FF_INV_CLK" % ff_name, inv_clk) + +segmk.compile() +segmk.write() + diff --git a/experiments/ffprim/generate.sh b/experiments/ffprim/generate.sh new file mode 100644 index 00000000..9fb78153 --- /dev/null +++ b/experiments/ffprim/generate.sh @@ -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 + ../../../tools/bitread -F $XRAY_ROI_FRAMES -o ${x}s -zy $x +done + +python3 ../generate.py + diff --git a/experiments/ffprim/generate.tcl b/experiments/ffprim/generate.tcl new file mode 100644 index 00000000..50983877 --- /dev/null +++ b/experiments/ffprim/generate.tcl @@ -0,0 +1,58 @@ +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 + + + +# Get all FF's in pblock +set ffs [get_bels -of_objects [get_sites -of_objects [get_pblocks roi]] -filter {TYPE =~ *} */*FF] + +set fp [open "design.txt" w] +# set ff [lindex $ffs 0] +# set ff [get_bels SLICE_X23Y100/AFF] +# proc putl {lst} { foreach line $lst {puts $line} } +foreach ff $ffs { + set tile [get_tile -of_objects $ff] + set grid_x [get_property GRID_POINT_X $tile] + set grid_y [get_property GRID_POINT_Y $tile] + set type [get_property TYPE $tile] + set bel_type [get_property TYPE $ff] + set used [get_property IS_USED $ff] + set usedstr "" + if $used { + set ffc [get_cells -of_objects $ff] + set cell_bel [get_property BEL $ffc] + # ex: FDRE + set ref_name [get_property REF_NAME $ffc] + #set cinv [get_property IS_C_INVERTED $ffc] + + set cpin [get_pins -of_objects $ffc -filter {REF_PIN_NAME == C}] + set cinv [get_property IS_INVERTED $cpin] + set usedstr "$cell_bel $ref_name $cinv" + } + puts $fp "$type $tile $grid_x $grid_y $ff $bel_type $used $usedstr" +} +close $fp + diff --git a/experiments/ffprim/top.py b/experiments/ffprim/top.py new file mode 100644 index 00000000..ad229d0c --- /dev/null +++ b/experiments/ffprim/top.py @@ -0,0 +1,350 @@ +import random + +CLBN = 600 +# 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 * 4 +DOUT_N = CLBN * 1 +clbs = ( + 'FD', + 'FD_1', + 'FDC', + 'FDC_1', + 'FDCE', + 'FDCE_1', + 'FDE', + 'FDE_1', + 'FDP', + 'FDP_1', + 'FDPE', + 'FDPE_1', + 'FDR', + 'FDR_1', + 'FDRE', + 'FDRE_1', + 'FDS', + 'FDS_1', + 'FDSE', + 'FDSE_1', + ) +ff_bels = ( + 'AFF', + 'A5FF', + 'BFF', + 'B5FF', + 'CFF', + 'C5FF', + 'DFF', + 'D5FF', + ) + +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)) + +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): + clb = random.choice(clbs) + # clb_FD clb_FD (.clk(clk), .din(din[ 0 +: 4]), .dout(dout[ 0])); + # clb_FD_1 clb_FD_1 (.clk(clk), .din(din[ 4 +: 4]), .dout(dout[ 1])); + loc = next(slices) + #bel = random.choice(ff_bels) + bel = "AFF" + print(' clb_%s' % clb) + print(' #(.LOC("%s"), .BEL("%s"))' % (loc, bel)) + print(' clb_%d (.clk(clk), .din(din[ %d +: 4]), .dout(dout[ %d]));' % (i, 4 * i, 1 * i)) +print('''endmodule + +// --------------------------------------------------------------------- + +''') + +print(''' +module clb_FD (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y100"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FD ff ( + .C(clk), + .Q(dout), + .D(din[0]) + ); + endmodule + +module clb_FD_1 (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y101"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FD_1 ff ( + .C(clk), + .Q(dout), + .D(din[0]) + ); + endmodule + +module clb_FDC (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y102"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDC ff ( + .C(clk), + .Q(dout), + .CLR(din[0]), + .D(din[1]) + ); + endmodule + +module clb_FDC_1 (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y103"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDC_1 ff ( + .C(clk), + .Q(dout), + .CLR(din[0]), + .D(din[1]) + ); + endmodule + +module clb_FDCE (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y104"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDCE ff ( + .C(clk), + .Q(dout), + .CE(din[0]), + .CLR(din[1]), + .D(din[2]) + ); + endmodule + +module clb_FDCE_1 (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y105"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDCE_1 ff ( + .C(clk), + .Q(dout), + .CE(din[0]), + .CLR(din[1]), + .D(din[2]) + ); + endmodule + +module clb_FDE (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y106"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDE ff ( + .C(clk), + .Q(dout), + .D(din[0]), + .CE(din[1]) + ); + endmodule + +module clb_FDE_1 (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y107"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDE_1 ff ( + .C(clk), + .Q(dout), + .D(din[0]), + .CE(din[1]) + ); + endmodule + +module clb_FDP (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y108"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDP ff ( + .C(clk), + .Q(dout), + .D(din[0]), + .PRE(din[1]) + ); + endmodule + +module clb_FDP_1 (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y109"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDP_1 ff ( + .C(clk), + .Q(dout), + .D(din[0]), + .PRE(din[1]) + ); + endmodule + +module clb_FDPE (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y110"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDPE ff ( + .C(clk), + .Q(dout), + .CE(din[0]), + .PRE(din[1]), + .D(din[2]) + ); + endmodule + +module clb_FDPE_1 (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y111"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDPE_1 ff ( + .C(clk), + .Q(dout), + .CE(din[0]), + .PRE(din[1]), + .D(din[2]) + ); + endmodule + +module clb_FDR (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y112"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDR ff ( + .C(clk), + .Q(dout), + .D(din[0]), + .R(din[1]) + ); + endmodule + +module clb_FDR_1 (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y113"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDR_1 ff ( + .C(clk), + .Q(dout), + .D(din[0]), + .R(din[1]) + ); + endmodule + +module clb_FDRE (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y114"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDRE ff ( + .C(clk), + .Q(dout), + .CE(din[0]), + .R(din[1]), + .D(din[2]) + ); + endmodule + +module clb_FDRE_1 (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y115"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDRE_1 ff ( + .C(clk), + .Q(dout), + .CE(din[0]), + .R(din[1]), + .D(din[2]) + ); + endmodule + +module clb_FDS (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y116"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDS ff ( + .C(clk), + .Q(dout), + .S(din[0]), + .D(din[1]) + ); + endmodule + +module clb_FDS_1 (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y117"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDS_1 ff ( + .C(clk), + .Q(dout), + .S(din[0]), + .D(din[1]) + ); + endmodule + +module clb_FDSE (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y118"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDSE ff ( + .C(clk), + .Q(dout), + .CE(din[0]), + .S(din[1]), + .D(din[2]) + ); + endmodule + +module clb_FDSE_1 (input clk, input [3:0] din, output dout); + parameter LOC="SLICE_X16Y119"; + parameter BEL="AFF"; + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + FDSE_1 ff ( + .C(clk), + .Q(dout), + .CE(din[0]), + .S(din[1]), + .D(din[2]) + ); + endmodule +''') +