diff --git a/minitests/clb_ram64x1d/.gitignore b/minitests/clb_ram64x1d/.gitignore new file mode 100644 index 00000000..e969ce50 --- /dev/null +++ b/minitests/clb_ram64x1d/.gitignore @@ -0,0 +1,10 @@ +/.Xil +/design/ +/design.bit +/design.bits +/design.dcp +/usage_statistics_webtalk.* +/vivado* +/design.txt +/top.v +/params.csv diff --git a/minitests/clb_ram64x1d/Makefile b/minitests/clb_ram64x1d/Makefile new file mode 100644 index 00000000..fb7d393d --- /dev/null +++ b/minitests/clb_ram64x1d/Makefile @@ -0,0 +1,30 @@ +N := 3 +SPECIMENS := $(addprefix specimen_,$(shell seq -f '%03.0f' $(N))) +SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS)) + +all: top.v + bash runme.sh + test -z $(fgrep CRITICAL vivado.log) + ${XRAY_SEGPRINT} -z -D design.bits >design.txt + +top.v: top.py + python top.py >top.v + +database: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} -o seg_clblx.segbits $(addsuffix /segdata_clbl[lm]_[lr].txt,$(SPECIMENS)) + +pushdb: + ${XRAY_MERGEDDB} clbll_l seg_clblx.segbits + ${XRAY_MERGEDDB} clbll_r seg_clblx.segbits + ${XRAY_MERGEDDB} clblm_l seg_clblx.segbits + ${XRAY_MERGEDDB} 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 design.txt .Xil + +.PHONY: database pushdb clean + diff --git a/minitests/clb_ram64x1d/README.txt b/minitests/clb_ram64x1d/README.txt new file mode 100644 index 00000000..ec055893 --- /dev/null +++ b/minitests/clb_ram64x1d/README.txt @@ -0,0 +1,51 @@ +X10, X11 is generating bits +others are not + +Ex: +seg SEG_CLBLM_L_X10Y149 +seg SEG_CLBLM_R_X11Y100 + + + +N=1 + +seg SEG_CLBLM_L_X10Y149 +bit 01_23 +bit 31_46 +bit 31_47 + +seg SEG_CLBLM_L_X10Y148 +bit 01_23 +bit 31_46 +bit 31_47 + +seg SEG_CLBLM_L_X10Y147 +bit 01_23 +bit 31_46 +bit 31_47 + + + +N = 2 + +seg SEG_CLBLM_L_X10Y149 +bit 01_23 +bit 31_16 +bit 31_17 +bit 31_46 +bit 31_47 + +seg SEG_CLBLM_L_X10Y148 +bit 01_23 +bit 31_16 +bit 31_17 +bit 31_46 +bit 31_47 + +seg SEG_CLBLM_L_X10Y147 +bit 01_23 +bit 31_16 +bit 31_17 +bit 31_46 +bit 31_47 + diff --git a/minitests/clb_ram64x1d/runme.sh b/minitests/clb_ram64x1d/runme.sh new file mode 100755 index 00000000..7810c911 --- /dev/null +++ b/minitests/clb_ram64x1d/runme.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -ex +# rm -f vivado*.log vivado*.jou +vivado -mode batch -source runme.tcl +${XRAY_BITREAD} -F $XRAY_ROI_FRAMES -o design.bits -z -y design.bit +#${XRAY_SEGPRINT} design.bits SLICE_X16Y100 SLICE_X16Y101 SLICE_X16Y102 SLICE_X16Y103 +test -z $(fgrep CRITICAL vivado.log) + diff --git a/minitests/clb_ram64x1d/runme.tcl b/minitests/clb_ram64x1d/runme.tcl new file mode 100644 index 00000000..3a61d1fa --- /dev/null +++ b/minitests/clb_ram64x1d/runme.tcl @@ -0,0 +1,29 @@ +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] +# Need to go outside +# SLICE_X12Y100:SLICE_X27Y149 +# resize_pblock [get_pblocks roi] -add "$::env(XRAY_ROI)" +resize_pblock [get_pblocks roi] -add "SLICE_X6Y100:SLICE_X27Y149" + +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 + diff --git a/minitests/clb_ram64x1d/top.py b/minitests/clb_ram64x1d/top.py new file mode 100644 index 00000000..57f098fb --- /dev/null +++ b/minitests/clb_ram64x1d/top.py @@ -0,0 +1,155 @@ +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 = 400 +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 (6, 8, 10, 12, 14): + for slicey in range(*SLICEY): + # caller may reject position if needs more room + yield ("SLICE_X%dY%d" % (slicex, slicey), (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\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): + module = 'my_RAM64X1D_N' + try: + loc, loc_pos = next(slices) + except StopIteration: + break + n = 2 + + print(' %s' % module) + print(' #(.LOC("%s"), .N(%d))' % (loc, n)) + 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, n)) +f.close() +print('''endmodule + +// --------------------------------------------------------------------- + +''') + +print(''' +module my_RAM64X1D_N (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter N = 1; + + generate + if (N >= 2) begin + (* LOC=LOC *) + RAM64X1D #( + .INIT(64'h0), + .IS_WCLK_INVERTED(1'b0) + ) ramb ( + .DPO(dout[1]), + .D(din[0]), + .WCLK(clk), + .WE(din[2]), + .A0(din[3]), + .A1(din[4]), + .A2(din[5]), + .A3(din[6]), + .A4(din[7]), + .A5(din[0]), + .DPRA0(din[1]), + .DPRA1(din[2]), + .DPRA2(din[3]), + .DPRA3(din[4]), + .DPRA4(din[5]), + .DPRA5(din[6])); + end + + if (N >= 1) begin + (* LOC=LOC *) + RAM64X1D #( + .INIT(64'h0), + .IS_WCLK_INVERTED(1'b0) + ) rama ( + .DPO(dout[0]), + .D(din[0]), + .WCLK(clk), + .WE(din[2]), + .A0(din[3]), + .A1(din[4]), + .A2(din[5]), + .A3(din[6]), + .A4(din[7]), + .A5(din[0]), + .DPRA0(din[1]), + .DPRA1(din[2]), + .DPRA2(din[3]), + .DPRA3(din[4]), + .DPRA4(din[5]), + .DPRA5(din[6])); + end + endgenerate +endmodule +''') +