diff --git a/minitests/clb_ram/Makefile b/minitests/clb_ram/Makefile new file mode 100644 index 00000000..7e47a0e0 --- /dev/null +++ b/minitests/clb_ram/Makefile @@ -0,0 +1,27 @@ +N := 3 +SPECIMENS := $(addprefix specimen_,$(shell seq -f '%03.0f' $(N))) +SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS)) + +all: + bash runme.sh + test -z $(fgrep CRITICAL vivado.log) + ${XRAY_SEGPRINT} -z -D design.bits >design.txt + +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_ram/README.txt b/minitests/clb_ram/README.txt new file mode 100644 index 00000000..c2305e7e --- /dev/null +++ b/minitests/clb_ram/README.txt @@ -0,0 +1,22 @@ +SLICEM RAM test +LUT6 => 64 bits +Focus on 64 bit +32 probably uses same O5/O6 stuff +128 probably uses same MUX stuff +Why isn't there a 256? + +RAM128X1D 128-Deep by 1-Wide Dual Port Random Access Memory (Select RAM) +RAM128X1S 128-Deep by 1-Wide Random Access Memory (Select RAM) +RAM256X1S 256-Deep by 1-Wide Random Access Memory (Select RAM) +RAM32M 32-Deep by 8-bit Wide Multi Port Random Access Memory (Select RAM) +RAM32X1D 32-Deep by 1-Wide Static Dual Port Synchronous RAM +RAM32X1S 32-Deep by 1-Wide Static Synchronous RAM +RAM32X1S_1 32-Deep by 1-Wide Static Synchronous RAM with Negative-Edge Clock +RAM32X2S 32-Deep by 2-Wide Static Synchronous RAM + +RAM64M 64-Deep by 4-bit Wide Multi Port Random Access Memory (Select RAM) +RAM64X1D 64-Deep by 1-Wide Dual Port Static Synchronous RAM +RAM64X1S 64-Deep by 1-Wide Static Synchronous RAM +RAM64X1S_1 64-Deep by 1-Wide Static Synchronous RAM with Negative-Edge Clock + + diff --git a/minitests/clb_ram/runme.sh b/minitests/clb_ram/runme.sh new file mode 100755 index 00000000..536f2346 --- /dev/null +++ b/minitests/clb_ram/runme.sh @@ -0,0 +1,7 @@ +#!/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 diff --git a/minitests/clb_ram/runme.tcl b/minitests/clb_ram/runme.tcl new file mode 100644 index 00000000..3a61d1fa --- /dev/null +++ b/minitests/clb_ram/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_ram/top.v b/minitests/clb_ram/top.v new file mode 100644 index 00000000..7ef5f1d9 --- /dev/null +++ b/minitests/clb_ram/top.v @@ -0,0 +1,385 @@ +/* +RAM64M 64-Deep by 4-bit Wide Multi Port Random Access Memory (Select RAM) +RAM64X1D 64-Deep by 1-Wide Dual Port Static Synchronous RAM +RAM64X1S 64-Deep by 1-Wide Static Synchronous RAM +RAM64X1S_1 64-Deep by 1-Wide Static Synchronous RAM with Negative-Edge Clock +*/ + +module top(input clk, stb, di, output do); + localparam integer DIN_N = 256; + localparam integer DOUT_N = 256; + + 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 [255:0] din, output [255:0] dout); + /* + my_RAM64M #(.LOC("SLICE_X6Y100")) + my_RAM64M(.clk(clk), .din(din[ 0 +: 8]), .dout(dout[ 0 +: 8])); + my_RAM64X1S #(.LOC("SLICE_X6Y101")) + my_RAM64X1S(.clk(clk), .din(din[ 8 +: 8]), .dout(dout[ 8 +: 8])); + my_RAM64X1S_1 #(.LOC("SLICE_X6Y102")) + my_RAM64X1S_1(.clk(clk), .din(din[ 16 +: 8]), .dout(dout[ 16 +: 8])); + my_RAM64X2S #(.LOC("SLICE_X6Y103")) + my_RAM64X2S(.clk(clk), .din(din[ 24 +: 8]), .dout(dout[ 24 +: 8])); + my_RAM64X1D #(.LOC("SLICE_X6Y104")) + my_RAM64X1D(.clk(clk), .din(din[ 32 +: 8]), .dout(dout[ 32 +: 8])); + my_RAM128X1D #(.LOC("SLICE_X6Y105")) + my_RAM128X1D(.clk(clk), .din(din[ 40 +: 8]), .dout(dout[ 40 +: 8])); + */ + + /* + my_BDI1MUX_AI #(.LOC("SLICE_X6Y100"), .BEL("A6LUT")) + my_BDI1MUX_AI(.clk(clk), .din(din[ 0 +: 8]), .dout(dout[ 0 +: 8])); + my_BDI1MUX_BDI1 #(.LOC("SLICE_X6Y101"), .BELO("B6LUT"), .BELI("A6LUT")) + my_BDI1MUX_BDI1(.clk(clk), .din(din[ 8 +: 8]), .dout(dout[ 8 +: 8])); + my_BDI1MUX_BMC31 #(.LOC("SLICE_X6Y102"), .BELO("B6LUT"), .BELI("A6LUT")) + my_BDI1MUX_BMC31(.clk(clk), .din(din[ 16 +: 8]), .dout(dout[ 16 +: 8])); + */ + + /* + //BEL isn't taking effect + my_BDI1MUX_AI #(.LOC("SLICE_X6Y100"), .BEL("A6LUT")) + c0(.clk(clk), .din(din[ 0 +: 8]), .dout(dout[ 0 +: 8])); + my_BDI1MUX_AI #(.LOC("SLICE_X6Y101"), .BEL("B6LUT")) + c1(.clk(clk), .din(din[ 8 +: 8]), .dout(dout[ 8 +: 8])); + my_BDI1MUX_AI #(.LOC("SLICE_X6Y102"), .BEL("C6LUT")) + c2(.clk(clk), .din(din[ 16 +: 8]), .dout(dout[ 16 +: 8])); + my_BDI1MUX_AI #(.LOC("SLICE_X6Y103"), .BEL("D6LUT")) + c3(.clk(clk), .din(din[ 24 +: 8]), .dout(dout[ 24 +: 8])); + */ + + + + /* + //BEL works + //No unknown bits + my_SRL16E #(.LOC("SLICE_X6Y100"), .BEL("A6LUT")) + c0(.clk(clk), .din(din[ 0 +: 8]), .dout(dout[ 0 +: 8])); + my_SRL16E #(.LOC("SLICE_X6Y101"), .BEL("B6LUT")) + c1(.clk(clk), .din(din[ 8 +: 8]), .dout(dout[ 8 +: 8])); + my_SRL16E #(.LOC("SLICE_X6Y102"), .BEL("C6LUT")) + c2(.clk(clk), .din(din[ 16 +: 8]), .dout(dout[ 16 +: 8])); + my_SRL16E #(.LOC("SLICE_X6Y103"), .BEL("D6LUT")) + c3(.clk(clk), .din(din[ 24 +: 8]), .dout(dout[ 24 +: 8])); + */ + + //BEL works + my_SRLC32E #(.LOC("SLICE_X6Y100"), .BEL("A6LUT")) + c0(.clk(clk), .din(din[ 0 +: 8]), .dout(dout[ 0 +: 8])); + my_SRLC32E #(.LOC("SLICE_X6Y101"), .BEL("B6LUT")) + c1(.clk(clk), .din(din[ 8 +: 8]), .dout(dout[ 8 +: 8])); + my_SRLC32E #(.LOC("SLICE_X6Y102"), .BEL("C6LUT")) + c2(.clk(clk), .din(din[ 16 +: 8]), .dout(dout[ 16 +: 8])); + my_SRLC32E #(.LOC("SLICE_X6Y103"), .BEL("D6LUT")) + c3(.clk(clk), .din(din[ 24 +: 8]), .dout(dout[ 24 +: 8])); +endmodule + +module my_SRLC32E (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter BEL="A6LUT"; + + wire mc31c; + + (* LOC=LOC, BEL=BEL *) + 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 + +module my_SRL16E (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter BEL="A6LUT"; + + (* LOC=LOC, BEL=BEL *) + 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 + + + +module my_BDI1MUX_AI (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter BEL="A6LUT"; + + (* LOC=LOC, BEL=BEL *) + 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 + +//bad +//Ended in D6LUT and A6LUT +/* +module my_BDI1MUX_BDI1 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter BELO="B6LUT"; + parameter BELI="A6LUT"; + + wire da = din[6]; + + (* LOC=LOC, BEL=BELO *) + RAM64X1S #( + ) lutb ( + .O(dout[0]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .A4(din[4]), + .A5(din[5]), + .D(da), + .WCLK(clk), + .WE(din[0])); + (* LOC=LOC, BEL=BELI *) + RAM64X1S #( + ) luta ( + .O(dout[1]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .A4(din[4]), + .A5(din[5]), + .D(da), + .WCLK(clk), + .WE(din[0])); +endmodule +*/ +//Lets try CMC31 chaining instead +module my_BDI1MUX_BDI1 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter BELO="C6LUT"; + parameter BELI="A6LUT"; + + wire da = din[6]; + + (* LOC=LOC, BEL=BELO *) + SRLC32E #( + .INIT(32'h00000000), + .IS_CLK_INVERTED(1'b0) + ) lutb ( + .Q(dout[0]), + .Q31(mc31c), + .A(din[4:0]), + .CE(din[5]), + .CLK(din[6]), + .D(din[7])); + (* LOC=LOC, BEL=BELI *) + SRLC32E #( + .INIT(32'h00000000), + .IS_CLK_INVERTED(1'b0) + ) luta ( + .Q(dout[1]), + .Q31(dout[2]), + .A(din[4:0]), + .CE(din[5]), + .CLK(din[6]), + .D(da)); +endmodule + +//ok +module my_BDI1MUX_BMC31 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter BELO="B6LUT"; + parameter BELI="A6LUT"; + + wire mc31b; + + (* LOC=LOC, BEL=BELO *) + SRLC32E #( + .INIT(32'h00000000), + .IS_CLK_INVERTED(1'b0) + ) lutb ( + .Q(dout[0]), + .Q31(mc31b), + .A(din[4:0]), + .CE(din[5]), + .CLK(din[6]), + .D(din[7])); + (* LOC=LOC, BEL=BELI *) + SRLC32E #( + .INIT(32'h00000000), + .IS_CLK_INVERTED(1'b0) + ) luta ( + .Q(dout[1]), + .Q31(dout[2]), + .A(din[4:0]), + .CE(din[5]), + .CLK(din[6]), + .D(mc31b)); + +endmodule + + + +module my_RAM64M (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter BEL="A6LUT"; + + (* LOC=LOC, BEL=BEL *) + RAM64M #( + ) RAM64M ( + .DOA(dout[0]), + .DOB(dout[1]), + .DOC(dout[2]), + .DOD(dout[3]), + .ADDRA(din[0]), + .ADDRB(din[1]), + .ADDRC(din[2]), + .ADDRD(din[3]), + .DIA(din[4]), + .DIB(din[5]), + .DIC(din[6]), + .DID(din[7]), + .WCLK(clk), + .WE(din[1])); +endmodule + + + +module my_RAM64X1S (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter BEL="A6LUT"; + + (* LOC=LOC, BEL=BEL *) + 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 + + + +module my_RAM64X1S_1 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + + (* LOC=LOC *) + RAM64X1S_1 #( + ) RAM64X1S_1 ( + .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 + +module my_RAM64X2S (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + + (* LOC=LOC *) + RAM64X2S #( + ) RAM64X2S ( + .O0(dout[0]), + .O1(dout[1]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .A4(din[4]), + .A5(din[5]), + .D0(din[6]), + .D1(din[7]), + .WCLK(clk), + .WE(din[1])); +endmodule + +module my_RAM64X1D (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + + (* LOC=LOC *) + RAM64X1D #( + .INIT(64'h0), + .IS_WCLK_INVERTED(1'b0) + ) RAM64X1D ( + .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])); +endmodule + +module my_RAM128X1D (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + + (* LOC=LOC *) + 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 +