diff --git a/minitests/partial_reconfig_flow/Makefile b/minitests/partial_reconfig_flow/Makefile new file mode 100644 index 00000000..6768bd4a --- /dev/null +++ b/minitests/partial_reconfig_flow/Makefile @@ -0,0 +1,83 @@ +# Top-level target for generating a programmable bitstream. Given a .fasm +# file, calling make with the .fasm extension replaced with .hand_crafted.bit +# will generate a bitstream that includes both the harness and the .fasm design +# ready for programming to a board. For example, 'make +# roi_noninv.hand_crafted.bit' will generate a bitstream that includes the +# design from roi_noninv.fasm. +%.hand_crafted.bit: init_sequence.bit %.no_headers.bit final_sequence.bit + cat $^ > $@ + +%.no_headers.bit: %.patched.bit + # WARNING: these values need to be tweaked if anything about the + # Vivado-generated design changes. + xxd -p -s 0x18 $< | xxd -r -p - $@ + +%.patched.bit: %.frm harness_routed.bit + ${XRAY_TOOLS_DIR}/xc7patch \ + --part_file ${XRAY_PART_YAML} \ + --bitstream_file harness_routed.bit \ + --frm_file $< \ + --output_file $@ + +# xc7patch currently only generates the actual frame writes which is +# insufficient to program a device. Grab the initialization and finalization +# sequences from the harness bitstream so they can be tacked on to the +# xc7patch-generated bitstream to create a programmable bitstream. +init_sequence.bit: harness_routed.bit + # WARNING: these values need to be tweaked if anything about the + # Vivado-generated design changes. + xxd -p -l 0x147 $< | xxd -r -p - $@ + +final_sequence.bit: harness_routed.bit + # WARNING: these values need to be tweaked if anything about the + # Vivado-generated design changes. + xxd -p -s 0x216abf $< | \ + tr -d '\n' | \ + sed -e 's/30000001.\{8\}/3000800100000007/g' | \ + fold -w 40 | \ + xxd -r -p - $@ + +# Generate a suitable harness by using Vivado's partial reconfiguration +# feature. roi_inv is used as a sample reconfiguration design as one is +# required to generate a partial reconfiguration design. +harness.dcp: harness.tcl top.v roi_base.v + vivado -mode batch -source harness.tcl + +roi_inv.dcp: roi_inv.tcl roi_inv.v + vivado -mode batch -source roi_inv.tcl + +roi_inv_routed.dcp roi_inv_w_harness_routed.dcp harness_routed.dcp: harness.dcp roi_inv.dcp roi_inv_routed.tcl + vivado -mode batch -source roi_inv_routed.tcl + +# Conversions between various formats. +%.bit: %.dcp write_bitstream.tcl + vivado -mode batch -source write_bitstream.tcl -tclargs $< $@ + +%.bits: %.bit + ${XRAY_BITREAD} -y -o $@ $< + +# Extract only bits that are within the ROI. +%.roi.bits: %.bit + ${XRAY_BITREAD} -F ${XRAY_ROI_FRAMES} -z -y -o $@ $< + +%.segp: %.roi.bits + ${XRAY_SEGPRINT} -zd $< > $@ + +%.fasm: %.segp + ${XRAY_DIR}/tools/segprint2fasm.py $< $@ + +%.frm: %.fasm + ${XRAY_DIR}/tools/fasm2frame.py $< $@ + +%.packets: %.bit + ${XRAY_TOOLS_DIR}/bittool list_config_packets $< > $@ + +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 + rm -rf out_* *~ + rm -rf *.frm *.segp *.packets + rm -rf harness_routed.fasm roi_inv_w_harness_routed.fasm + rm -rf hd_visual + +.PHONY: clean + diff --git a/minitests/partial_reconfig_flow/README.md b/minitests/partial_reconfig_flow/README.md new file mode 100644 index 00000000..8eac3df0 --- /dev/null +++ b/minitests/partial_reconfig_flow/README.md @@ -0,0 +1,53 @@ +# FASM Proof of Concept using Vivado Partial Reconfig flow + +top.v is a top-level design that routes a variety of signal into a black-box +region of interest (ROI). Vivado's Partial Reconfiguration flow (see UG909 +and UG947) is used to implement that design and obtain a bitstream that +configures portions of the chip that are currently undocumented. + +Designs that fit within the ROI are written in FASM and merged with the above +harness into a bitstream with fasm2frame and xc7patch. + +# Usage + +make rules are provided for generating each step of the process so that +intermediate forms can be analyzed. Assuming you have a .fasm file, invoking +the %.hand\_crafted.bit rule will generate a merged bitstream: + +``` +make foo.hand\_crafted.bit # reads foo.fasm +``` + +# Using Vivado to generate .fasm + +Vivado's Partial Reconfiguration flow can be used to synthesize and implement a +design that is then converted to .fasm. The basic process is to write a module +that _exactly_ matches the roi blackbox in the top-level design. Note that +even the name of the module must match exactly. Once you have a design, the +first step is to synthesize the design with -mode out\_of\_context: + +``` +read_verilog .v +synth_design -mode out_of_context -top roi -part $::env(XRAY_PART) +write_checkpoint -force .dcp +``` + +Next, implement that design within the harness. Run 'make harness\_routed.dcp' +if it doesn't already exist. The following TCL will load the fully-routed +harness, load your synthesized design, and generate a bitstream containing +both: +``` +open_checkpoint -force harness_routed.dcp +read_checkpoint -cell .dcp +opt_design +place_design +route_design +write_checkpoint -force _routed.dcp +write_bitstream -force _routed.bit +``` + +'make \_routed.fasm' will run a sequence of tools to extract the bits +that are inside the ROI and convert them to FASM. The resulting .fasm can be +used to generate a marged bitstream using +'make \_routed.hand\_crafted.bit'. The resulting bitstream should be +equivalent to \_routed.bit. diff --git a/minitests/partial_reconfig_flow/defines.v b/minitests/partial_reconfig_flow/defines.v new file mode 100644 index 00000000..1008d558 --- /dev/null +++ b/minitests/partial_reconfig_flow/defines.v @@ -0,0 +1,8 @@ +`ifndef DIN_N +`define DIN_N 8 +`endif + +`ifndef DOUT_N +`define DOUT_N 8 +`endif + diff --git a/minitests/partial_reconfig_flow/harness.tcl b/minitests/partial_reconfig_flow/harness.tcl new file mode 100644 index 00000000..14be2e3c --- /dev/null +++ b/minitests/partial_reconfig_flow/harness.tcl @@ -0,0 +1,5 @@ +read_verilog top.v +read_verilog roi_base.v + +synth_design -top top -part $::env(XRAY_PART) +write_checkpoint -force harness.dcp diff --git a/minitests/partial_reconfig_flow/roi_base.v b/minitests/partial_reconfig_flow/roi_base.v new file mode 100644 index 00000000..ec693408 --- /dev/null +++ b/minitests/partial_reconfig_flow/roi_base.v @@ -0,0 +1,9 @@ +//See README and tcl for more info + +`include "defines.v" + +module roi(input clk, + input [DIN_N-1:0] din, output [DOUT_N-1:0] dout); + parameter DIN_N = `DIN_N; + parameter DOUT_N = `DOUT_N; +endmodule diff --git a/minitests/partial_reconfig_flow/roi_inv.tcl b/minitests/partial_reconfig_flow/roi_inv.tcl new file mode 100644 index 00000000..a963234d --- /dev/null +++ b/minitests/partial_reconfig_flow/roi_inv.tcl @@ -0,0 +1,3 @@ +read_verilog roi_inv.v +synth_design -mode out_of_context -top roi -part $::env(XRAY_PART) +write_checkpoint -force roi_inv.dcp diff --git a/minitests/partial_reconfig_flow/roi_inv.v b/minitests/partial_reconfig_flow/roi_inv.v new file mode 100644 index 00000000..7e575cb5 --- /dev/null +++ b/minitests/partial_reconfig_flow/roi_inv.v @@ -0,0 +1,53 @@ +//Connect the switches to the LEDs, inverting the signal in the ROI +//Assumes # inputs = # outputs + +`include "defines.v" + +module roi(input clk, + input [DIN_N-1:0] din, output [DOUT_N-1:0] dout); + parameter DIN_N = `DIN_N; + parameter DOUT_N = `DOUT_N; + wire [DIN_N-1:0] internal; + + genvar i; + generate + //CLK + (* KEEP, DONT_TOUCH *) + reg clk_reg; + always @(posedge clk) begin + clk_reg <= clk_reg; + end + + //DIN + for (i = 0; i < DIN_N; i = i+1) begin:ins + //Very expensive inverter + (* KEEP, DONT_TOUCH *) + LUT6 #( + .INIT(64'b01) + ) lut ( + .I0(din[i]), + .I1(1'b0), + .I2(1'b0), + .I3(1'b0), + .I4(1'b0), + .I5(1'b0), + .O(internal[i])); + end + + //DOUT + for (i = 0; i < DOUT_N; i = i+1) begin:outs + //Very expensive buffer + (* KEEP, DONT_TOUCH *) + LUT6 #( + .INIT(64'b010) + ) lut ( + .I0(internal[i]), + .I1(1'b0), + .I2(1'b0), + .I3(1'b0), + .I4(1'b0), + .I5(1'b0), + .O(dout[i])); + end + endgenerate +endmodule diff --git a/minitests/partial_reconfig_flow/roi_inv_routed.tcl b/minitests/partial_reconfig_flow/roi_inv_routed.tcl new file mode 100644 index 00000000..0fee8ca2 --- /dev/null +++ b/minitests/partial_reconfig_flow/roi_inv_routed.tcl @@ -0,0 +1,149 @@ +open_checkpoint harness.dcp + +create_pblock 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] + +# Number of package inputs going to ROI +set DIN_N 8 +# Number of ROI outputs going to package +set DOUT_N 8 + +set part $::env(XRAY_PART) +set pincfg $::env(XRAY_PINCFG) + +# Map of top level net names to IOB pin names +array set net2pin [list] + +# Create pin assignments based on what we are targetting +# A50T I/O Bank 16 sequential layout +if {$part eq "xc7a50tfgg484-1"} { + # Partial list, expand as needed + set bank_16 "F21 G22 G21 D21 E21 D22 E22 A21 B21 B22 C22 C20 D20 F20 F19 A19 A18" + set banki 0 + + # CLK + set pin [lindex $bank_16 $banki] + incr banki + set net2pin(clk) $pin + + # DIN + for {set i 0} {$i < $DIN_N} {incr i} { + set pin [lindex $bank_16 $banki] + incr banki + set net2pin(din[$i]) $pin + } + + # DOUT + for {set i 0} {$i < $DOUT_N} {incr i} { + set pin [lindex $bank_16 $banki] + incr banki + set net2pin(dout[$i]) $pin + } +} elseif {$part eq "xc7a35tcsg324-1"} { + # Arty A7 switch, button, and LED + if {$pincfg eq "ARTY-A7-SWBUT"} { + # https://reference.digilentinc.com/reference/programmable-logic/arty/reference-manual?redirect=1 + # 4 switches then 4 buttons + set sw_but "A8 C11 C10 A10 D9 C9 B9 B8" + # 4 LEDs then 4 RGB LEDs (green only) + set leds "H5 J5 T9 T10 F6 J4 J2 H6" + + # 100 MHz CLK onboard + set pin "E3" + set net2pin(clk) $pin + + # DIN + for {set i 0} {$i < $DIN_N} {incr i} { + set pin [lindex $sw_but $i] + set net2pin(din[$i]) $pin + } + + # DOUT + for {set i 0} {$i < $DOUT_N} {incr i} { + set pin [lindex $leds $i] + set net2pin(dout[$i]) $pin + } + # Arty A7 pmod + # Disabled per above + } elseif {$pincfg eq "ARTY-A7-PMOD"} { + # https://reference.digilentinc.com/reference/programmable-logic/arty/reference-manual?redirect=1 + set pmod_ja "G13 B11 A11 D12 D13 B18 A18 K16" + set pmod_jb "E15 E16 D15 C15 J17 J18 K15 J15" + set pmod_jc "U12 V12 V10 V11 U14 V14 T13 U13" + + # CLK on Pmod JA + set pin [lindex $pmod_ja 0] + set net2pin(clk) $pin + + # DIN on Pmod JB + for {set i 0} {$i < $DIN_N} {incr i} { + set pin [lindex $pmod_jb $i] + set net2pin(din[$i]) $pin + } + + # DOUT on Pmod JC + for {set i 0} {$i < $DOUT_N} {incr i} { + set pin [lindex $pmod_jc $i] + set net2pin(dout[$i]) $pin + } + } else { + error "Unsupported config $pincfg" + } +} elseif {$part eq "xc7a35tcpg236-1"} { + if {$pincfg eq "BASYS3-SWBUT"} { + # https://raw.githubusercontent.com/Digilent/digilent-xdc/master/Basys-3-Master.xdc + + # Slide switches + set sws "V17 V16 W16 W17 W15 V15 W14 W13 V2 T3 T2 R3 W2 U1 T1 R2" + set leds "U16 E19 U19 V19 W18 U15 U14 V14 V13 V3 W3 U3 P3 N3 P1 L1" + + # 100 MHz CLK onboard + set pin "W5" + set net2pin(clk) $pin + + # DIN + for {set i 0} {$i < $DIN_N} {incr i} { + set pin [lindex $sws $i] + set net2pin(din[$i]) $pin + } + + # DOUT + for {set i 0} {$i < $DOUT_N} {incr i} { + set pin [lindex $leds $i] + set net2pin(dout[$i]) $pin + } + } else { + error "Unsupported config $pincfg" + } +} else { + error "Pins: unsupported part $part" +} + +# Now actually apply the pin definitions +puts "Applying pin definitions" +foreach {net pin} [array get net2pin] { + puts " Net $net to pin $pin" + set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" [get_ports $net] +} + +set_property HD.RECONFIGURABLE TRUE [get_cells roi] + +read_checkpoint -cell roi roi_inv.dcp + +opt_design +place_design +route_design + +write_checkpoint -force roi_inv_w_harness_routed.dcp + +# Routed design of roi cell only +write_checkpoint -force -cell roi roi_inv_routed.dcp + +# Replace roi cell with a black box and write the rest of the design +update_design -cell roi -black_box +lock_design -level routing +write_checkpoint -force harness_routed.dcp diff --git a/minitests/partial_reconfig_flow/roi_noninv.fasm b/minitests/partial_reconfig_flow/roi_noninv.fasm new file mode 100644 index 00000000..7eaf102b --- /dev/null +++ b/minitests/partial_reconfig_flow/roi_noninv.fasm @@ -0,0 +1,228 @@ +INT_L_X10Y107.CENTER_INTER_L.SE6BEG0 NN6END0 +INT_L_X10Y104.CENTER_INTER_L.WL1BEG0 NW2END2 +INT_L_X10Y103.CENTER_INTER_L.EL1BEG0 NR1END1 +INT_L_X10Y103.CENTER_INTER_L.EL1BEG_N3 NW2END0 +INT_L_X10Y103.CENTER_INTER_L.FAN_ALT4 NR1END0 +INT_L_X10Y103.CENTER_INTER_L.NE2BEG3 NL1BEG_N3 +INT_L_X10Y103.CENTER_INTER_L.NL1BEG_N3 NL1END0 +INT_L_X10Y103.CENTER_INTER_L.SE2BEG2 EL1END2 +INT_L_X10Y103.CENTER_INTER_L.WW2BEG2 WL1END2 +CLBLM_L_X10Y102.SLICE_X13Y102.ALUT.INIT[01] 1 +CLBLM_L_X10Y102.SLICE_X13Y102.BLUT.INIT[01] 1 +CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[01] 1 +CLBLM_L_X10Y102.SLICE_X12Y102.BLUT.INIT[01] 1 +INT_L_X10Y102.CENTER_INTER_L.BYP_ALT5 NN2END2 +INT_L_X10Y102.CENTER_INTER_L.EE2BEG2 NL1END2 +INT_L_X10Y102.CENTER_INTER_L.EL1BEG_N3 NL1END0 +INT_L_X10Y102.CENTER_INTER_L.GFAN0 GND_WIRE +INT_L_X10Y102.CENTER_INTER_L.GFAN1 GND_WIRE +INT_L_X10Y102.CENTER_INTER_L.IMUX_L0 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L1 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L10 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L11 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L12 GFAN1 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L13 GFAN1 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L14 NL1BEG_N3 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L15 FAN_BOUNCE_S3_4 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L16 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L17 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L18 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L19 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L2 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L24 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L25 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L26 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L27 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L3 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L4 GFAN1 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L5 GFAN1 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L6 WR1END3 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L7 BYP_BOUNCE5 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L8 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.IMUX_L9 GFAN0 +INT_L_X10Y102.CENTER_INTER_L.NL1BEG0 LOGIC_OUTS_L9 +INT_L_X10Y102.CENTER_INTER_L.NL1BEG_N3 LOGIC_OUTS_L8 +INT_L_X10Y102.CENTER_INTER_L.NR1BEG0 LOGIC_OUTS_L12 +INT_L_X10Y102.CENTER_INTER_L.NR1BEG1 LOGIC_OUTS_L13 +INT_L_X10Y102.CENTER_INTER_L.SE2BEG2 EL1END2 +INT_L_X10Y102.CENTER_INTER_L.SR1BEG2 WL1END1 +INT_L_X10Y102.CENTER_INTER_L.SW2BEG3 WL1END3 +INT_L_X10Y102.CENTER_INTER_L.WW2BEG2 WL1END2 +CLBLM_L_X10Y101.SLICE_X13Y101.ALUT.INIT[01] 1 +CLBLM_L_X10Y101.SLICE_X13Y101.BLUT.INIT[01] 1 +CLBLM_L_X10Y101.SLICE_X12Y101.ALUT.INIT[01] 1 +CLBLM_L_X10Y101.SLICE_X12Y101.BLUT.INIT[01] 1 +INT_L_X10Y101.CENTER_INTER_L.BYP_ALT3 NL1BEG_N3 +INT_L_X10Y101.CENTER_INTER_L.BYP_ALT4 NW2END1 +INT_L_X10Y101.CENTER_INTER_L.ER1BEG2 LOGIC_OUTS_L13 +INT_L_X10Y101.CENTER_INTER_L.GFAN0 GND_WIRE +INT_L_X10Y101.CENTER_INTER_L.GFAN1 GND_WIRE +INT_L_X10Y101.CENTER_INTER_L.IMUX_L0 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L1 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L10 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L11 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L12 GFAN1 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L13 GFAN1 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L14 SR1END2 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L15 BYP_BOUNCE3 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L16 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L17 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L18 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L19 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L2 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L24 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L25 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L26 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L27 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L3 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L4 GFAN1 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L5 GFAN1 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L6 BYP_BOUNCE4 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L7 NW2END_S0_0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L8 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.IMUX_L9 GFAN0 +INT_L_X10Y101.CENTER_INTER_L.LV_L18 SR1BEG_S0 +INT_L_X10Y101.CENTER_INTER_L.NE2BEG1 NR1END1 +INT_L_X10Y101.CENTER_INTER_L.NE2BEG3 NN6END3 +INT_L_X10Y101.CENTER_INTER_L.NL1BEG0 LOGIC_OUTS_L9 +INT_L_X10Y101.CENTER_INTER_L.NL1BEG2 WL1END2 +INT_L_X10Y101.CENTER_INTER_L.NL1BEG_N3 LOGIC_OUTS_L8 +INT_L_X10Y101.CENTER_INTER_L.NN6BEG0 LOGIC_OUTS_L12 +INT_L_X10Y101.CENTER_INTER_L.SE2BEG2 EE2END2 +INT_L_X10Y101.CENTER_INTER_L.SR1BEG_S0 WL1END3 +CLBLM_L_X10Y100.SLICE_X13Y100.ALUT.INIT[01] 1 +CLBLM_L_X10Y100.SLICE_X13Y100.BLUT.INIT[01] 1 +CLBLM_L_X10Y100.SLICE_X12Y100.ALUT.INIT[01] 1 +INT_L_X10Y100.CENTER_INTER_L.BYP_ALT1 LOGIC_OUTS_L8 +INT_L_X10Y100.CENTER_INTER_L.BYP_ALT2 BYP_BOUNCE1 +INT_L_X10Y100.CENTER_INTER_L.BYP_ALT3 NL1BEG_N3 +INT_L_X10Y100.CENTER_INTER_L.EE2BEG3 NN6END3 +INT_L_X10Y100.CENTER_INTER_L.ER1BEG1 SR1BEG_S0 +INT_L_X10Y100.CENTER_INTER_L.GFAN0 GND_WIRE +INT_L_X10Y100.CENTER_INTER_L.GFAN1 GND_WIRE +INT_L_X10Y100.CENTER_INTER_L.IMUX_L0 GFAN0 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L1 GFAN0 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L10 GFAN0 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L11 GFAN0 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L13 GFAN1 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L14 BYP_BOUNCE2 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L16 GFAN0 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L19 GFAN0 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L2 GFAN0 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L25 GFAN0 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L26 GFAN0 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L3 GFAN0 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L4 GFAN1 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L5 GFAN1 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L6 SW2END2 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L7 BYP_BOUNCE3 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L8 GFAN0 +INT_L_X10Y100.CENTER_INTER_L.IMUX_L9 GFAN0 +INT_L_X10Y100.CENTER_INTER_L.NE2BEG0 LOGIC_OUTS_L12 +INT_L_X10Y100.CENTER_INTER_L.NE2BEG3 NE6END3 +INT_L_X10Y100.CENTER_INTER_L.NL1BEG_N3 WL1END_N1_3 +INT_L_X10Y100.CENTER_INTER_L.NN2BEG2 WL1END1 +INT_L_X10Y100.CENTER_INTER_L.NR1BEG1 LOGIC_OUTS_L9 +INT_L_X10Y100.CENTER_INTER_L.SR1BEG_S0 WL1END3 +INT_R_X11Y104.CENTER_INTER_R.SL1BEG3 NE2END3 +INT_R_X11Y103.CENTER_INTER_R.NW2BEG2 NN2END2 +INT_R_X11Y103.CENTER_INTER_R.SL1BEG0 EL1END0 +INT_R_X11Y103.CENTER_INTER_R.WL1BEG2 SL1END3 +INT_R_X11Y103.CENTER_INTER_R.WL1BEG_N3 WR1END1 +CLBLM_R_X11Y102.SLICE_X14Y102.ALUT.INIT[01] 1 +CLBLM_R_X11Y102.SLICE_X14Y102.BLUT.INIT[01] 1 +INT_R_X11Y102.CENTER_INTER_R.EL1BEG0 LOGIC_OUTS13 +INT_R_X11Y102.CENTER_INTER_R.GFAN0 GND_WIRE +INT_R_X11Y102.CENTER_INTER_R.GFAN1 GND_WIRE +INT_R_X11Y102.CENTER_INTER_R.IMUX1 GFAN0 +INT_R_X11Y102.CENTER_INTER_R.IMUX11 GFAN0 +INT_R_X11Y102.CENTER_INTER_R.IMUX12 GFAN1 +INT_R_X11Y102.CENTER_INTER_R.IMUX15 EL1END3 +INT_R_X11Y102.CENTER_INTER_R.IMUX17 GFAN0 +INT_R_X11Y102.CENTER_INTER_R.IMUX18 GFAN0 +INT_R_X11Y102.CENTER_INTER_R.IMUX2 GFAN0 +INT_R_X11Y102.CENTER_INTER_R.IMUX24 GFAN0 +INT_R_X11Y102.CENTER_INTER_R.IMUX27 GFAN0 +INT_R_X11Y102.CENTER_INTER_R.IMUX4 GFAN1 +INT_R_X11Y102.CENTER_INTER_R.IMUX7 WR1END3 +INT_R_X11Y102.CENTER_INTER_R.IMUX8 GFAN0 +INT_R_X11Y102.CENTER_INTER_R.NW2BEG0 LOGIC_OUTS12 +INT_R_X11Y102.CENTER_INTER_R.SE2BEG1 NE2END1 +INT_R_X11Y102.CENTER_INTER_R.SL1BEG2 SE2END2 +INT_R_X11Y102.CENTER_INTER_R.SL1BEG3 NE2END3 +INT_R_X11Y102.CENTER_INTER_R.WL1BEG1 NW2END3 +INT_R_X11Y102.CENTER_INTER_R.WL1BEG2 WL1END3 +INT_R_X11Y102.CENTER_INTER_R.WL1BEG_N3 SL1END0 +INT_R_X11Y102.CENTER_INTER_R.WR1BEG3 NR1END2 +CLBLM_R_X11Y101.SLICE_X14Y101.ALUT.INIT[01] 1 +CLBLM_R_X11Y101.SLICE_X14Y101.AMUX.O6 1 +CLBLM_R_X11Y101.SLICE_X14Y101.BLUT.INIT[01] 1 +INT_R_X11Y101.CENTER_INTER_R.EE2BEG2 ER1END2 +INT_R_X11Y101.CENTER_INTER_R.EL1BEG0 LOGIC_OUTS13 +INT_R_X11Y101.CENTER_INTER_R.GFAN0 GND_WIRE +INT_R_X11Y101.CENTER_INTER_R.GFAN1 GND_WIRE +INT_R_X11Y101.CENTER_INTER_R.IMUX1 GFAN0 +INT_R_X11Y101.CENTER_INTER_R.IMUX11 GFAN0 +INT_R_X11Y101.CENTER_INTER_R.IMUX12 GFAN1 +INT_R_X11Y101.CENTER_INTER_R.IMUX15 EL1END3 +INT_R_X11Y101.CENTER_INTER_R.IMUX17 GFAN0 +INT_R_X11Y101.CENTER_INTER_R.IMUX18 GFAN0 +INT_R_X11Y101.CENTER_INTER_R.IMUX2 GFAN0 +INT_R_X11Y101.CENTER_INTER_R.IMUX24 GFAN0 +INT_R_X11Y101.CENTER_INTER_R.IMUX27 GFAN0 +INT_R_X11Y101.CENTER_INTER_R.IMUX4 GFAN1 +INT_R_X11Y101.CENTER_INTER_R.IMUX7 NR1END3 +INT_R_X11Y101.CENTER_INTER_R.IMUX8 GFAN0 +INT_R_X11Y101.CENTER_INTER_R.NN2BEG2 LOGIC_OUTS20 +INT_R_X11Y101.CENTER_INTER_R.NR1BEG2 SE2END2 +INT_R_X11Y101.CENTER_INTER_R.NW2BEG0 NE2END0 +INT_R_X11Y101.CENTER_INTER_R.SL1BEG3 NE2END3 +INT_R_X11Y101.CENTER_INTER_R.SR1BEG_S0 SL1END3 +INT_R_X11Y101.CENTER_INTER_R.SW2BEG2 SL1END2 +INT_R_X11Y101.CENTER_INTER_R.WL1BEG2 WR1END_S1_0 +INT_R_X11Y101.CENTER_INTER_R.WL1BEG_N3 SR1BEG_S0 +INT_R_X11Y101.CENTER_INTER_R.WW2BEG0 WL1END0 +INT_R_X11Y101.CENTER_INTER_R.WW2BEG1 WL1END1 +CLBLM_R_X11Y100.SLICE_X14Y100.ALUT.INIT[01] 1 +INT_R_X11Y100.CENTER_INTER_R.BYP_ALT5 ER1END1 +INT_R_X11Y100.CENTER_INTER_R.GFAN0 GND_WIRE +INT_R_X11Y100.CENTER_INTER_R.GFAN1 GND_WIRE +INT_R_X11Y100.CENTER_INTER_R.IMUX1 GFAN0 +INT_R_X11Y100.CENTER_INTER_R.IMUX11 GFAN0 +INT_R_X11Y100.CENTER_INTER_R.IMUX2 GFAN0 +INT_R_X11Y100.CENTER_INTER_R.IMUX4 GFAN1 +INT_R_X11Y100.CENTER_INTER_R.IMUX7 BYP_BOUNCE5 +INT_R_X11Y100.CENTER_INTER_R.IMUX8 GFAN0 +INT_R_X11Y100.CENTER_INTER_R.NL1BEG_N3 LOGIC_OUTS12 +INT_R_X11Y100.CENTER_INTER_R.NR1BEG3 NL1BEG_N3 +INT_R_X11Y100.CENTER_INTER_R.NW2BEG1 WL1END0 +INT_R_X11Y100.CENTER_INTER_R.SR1BEG_S0 SL1END3 +INT_R_X11Y100.CENTER_INTER_R.WL1BEG1 SE2END2 +INT_R_X11Y100.CENTER_INTER_R.WL1BEG_N3 SR1BEG_S0 +INT_L_X12Y103.CENTER_INTER_L.WL1BEG_N3 SE6END0 +INT_L_X12Y103.CENTER_INTER_L.WR1BEG1 NR1END0 +INT_L_X12Y102.CENTER_INTER_L.NR1BEG0 EL1END0 +INT_L_X12Y102.CENTER_INTER_L.WR1BEG3 EE2END2 +INT_L_X12Y101.CENTER_INTER_L.NW2BEG3 NR1END3 +INT_L_X12Y101.CENTER_INTER_L.SE2BEG0 EL1END0 +INT_L_X12Y101.CENTER_INTER_L.WL1BEG0 SE2END1 +INT_L_X12Y101.CENTER_INTER_L.WL1BEG1 WR1END3 +INT_L_X12Y101.CENTER_INTER_L.WR1BEG_S0 NE6END3 +INT_L_X12Y100.CENTER_INTER_L.EL1BEG2 NE6END3 +INT_L_X12Y100.CENTER_INTER_L.LV_L18 WR1END0 +INT_L_X12Y100.CENTER_INTER_L.NR1BEG3 EE2END3 +INT_L_X12Y100.CENTER_INTER_L.SW6BEG3 LV_L18 +INT_L_X12Y100.CENTER_INTER_L.WL1BEG0 WR1END2 +INT_R_X13Y101.CENTER_INTER_R.WR1BEG3 EE2END2 +INT_R_X13Y100.CENTER_INTER_R.SL1BEG2 EL1END2 +INT_R_X13Y100.CENTER_INTER_R.WL1BEG_N3 SE2END0 +INT_R_X13Y100.CENTER_INTER_R.WR1BEG2 NR1END1 +INT_L_X16Y100.CENTER_INTER_L.ER1BEG1 SR1BEG_S0 +INT_L_X16Y100.CENTER_INTER_L.SR1BEG_S0 WL1END3 +INT_R_X17Y101.CENTER_INTER_R.WL1BEG_N3 WW2END0 +CLBLL_R_X17Y100.SLICE_X27Y100.AFF.DMUX.AX 1 +CLBLL_R_X17Y100.SLICE_X27Y100.AFF.ZINI 1 +CLBLL_R_X17Y100.SLICE_X27Y100.AFF.ZRST 1 +CLBLL_R_X17Y100.SLICE_X27Y100.FFSYNC 1 +INT_R_X17Y100.CENTER_INTER_R.BYP_ALT0 LOGIC_OUTS0 +INT_R_X17Y100.CENTER_INTER_R.CLK0 ER1END1 diff --git a/minitests/partial_reconfig_flow/top.v b/minitests/partial_reconfig_flow/top.v new file mode 100644 index 00000000..997231a9 --- /dev/null +++ b/minitests/partial_reconfig_flow/top.v @@ -0,0 +1,14 @@ +//See README and tcl for more info + +`include "defines.v" + +module top(input wire clk, + input [DIN_N-1:0] din, output [DOUT_N-1:0] dout); + parameter DIN_N = `DIN_N; + parameter DOUT_N = `DOUT_N; + + roi #(.DIN_N(DIN_N), .DOUT_N(DOUT_N)) roi ( + .clk(clk), + .din(din), .dout(dout)); +endmodule + diff --git a/minitests/partial_reconfig_flow/write_bitstream.tcl b/minitests/partial_reconfig_flow/write_bitstream.tcl new file mode 100644 index 00000000..62beef9e --- /dev/null +++ b/minitests/partial_reconfig_flow/write_bitstream.tcl @@ -0,0 +1,27 @@ +open_checkpoint [lindex $argv 0] + +# Disabling CRC just replaces the CRC register writes with Reset CRC commands. +# This seems to work via JTAG as it works in combination with PERFRAMECRC +# either when applied via Vivado (this setting) or by manually patching the +# bitstream later. +# +set_property BITSTREAM.GENERAL.CRC Disable [current_design] + +# Debug bitstreams write to LOUT which is only valid on serial master/slave +# programming methods. If those are replaced with NOPs, Reset CRC commands, or +# removed entirely, the bitstream will program (DONE light goes active) but the +# configuration doesn't start. The JTAG status register shows BAD_PACKET_ERROR +# when this happens. I'm guessing that the individual frame writes require the +# PERFRAMECRC approach to work at all via JTAG. +# +#set_property BITSTREAM.GENERAL.DEBUGBITSTREAM YES [current_design] + +# PERFRAMECRC bitstreams can be directly loaded via JTAG. They also use an +# undocumented bit to disable autoincrement which seems to be required if doing +# individual frame writes instead of a bulk write. The CRC chceks after each +# frame are _required_ for this bitstream to program. +# +#set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] + + +write_bitstream -force [lindex $argv 1]