From ee89aa17e0bef126a6a8cc727185d32c7c600edf Mon Sep 17 00:00:00 2001 From: Alen Luin Date: Fri, 4 Sep 2026 10:40:53 +0200 Subject: [PATCH] Added support for xcvu9p-flgb2104 Configuration with 2 quad spi flash. Tested in multi chain configuration. As part added also a xc2c256. xilinx_spiOverJtag.v missing wire define. spiFlashdb.hpp added support for QUADSPI bit support for S25FL512S --- spiOverJtag/constr_xcvu9p_flgb2104.xdc | 26 ++++++++++++++++++++++++++ spiOverJtag/xilinx_spiOverJtag.v | 2 +- src/part.hpp | 2 ++ src/spiFlashdb.hpp | 4 ++-- src/xilinx.cpp | 8 +++++++- 5 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 spiOverJtag/constr_xcvu9p_flgb2104.xdc diff --git a/spiOverJtag/constr_xcvu9p_flgb2104.xdc b/spiOverJtag/constr_xcvu9p_flgb2104.xdc new file mode 100644 index 0000000..cc1f2c6 --- /dev/null +++ b/spiOverJtag/constr_xcvu9p_flgb2104.xdc @@ -0,0 +1,26 @@ +set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design] +set_property CONFIG_VOLTAGE 1.8 [current_design] +# Table 1-2 from UG570 +set_property CFGBVS GND [current_design] + +# Primary QSPI flash +# Connection done through the STARTUPE3 block +# sdi_dq0 - PACKAGE_PIN AP11 - QSPI0_DQ0 Bank 0 - D00_MOSI_0 +# sdo_dq1 - PACKAGE_PIN AN11 - QSPI0_DQ1 Bank 0 - D01_DIN_0 +# wpn_dq2 - PACKAGE_PIN AM11 - QSPI0_DQ2 Bank 0 - D02_0 +# hldn_dq3 - PACKAGE_PIN AL11 - QSPI0_DQ3 Bank 0 - D03_0 +# csn - PACKAGE_PIN AJ11 - QSPI0_CS_B Bank 0 - RDWR_FCS_B_0 +# sck - PACKAGE_PIN AF13 - QSPI_CCLK Bank 0 - CCLK_0 + +# Secondary QSPI flash +set_property PACKAGE_PIN AM26 [get_ports "sdi_sec_dq0"]; +set_property IOSTANDARD LVCMOS18 [get_ports "sdi_sec_dq0"]; +set_property PACKAGE_PIN AN26 [get_ports "sdo_sec_dq1"]; +set_property IOSTANDARD LVCMOS18 [get_ports "sdo_sec_dq1"]; +set_property PACKAGE_PIN AL25 [get_ports "wpn_sec_dq2"]; +set_property IOSTANDARD LVCMOS18 [get_ports "wpn_sec_dq2"]; +set_property PACKAGE_PIN AM25 [get_ports "hldn_sec_dq3"]; +set_property IOSTANDARD LVCMOS18 [get_ports "hldn_sec_dq3"]; +set_property PACKAGE_PIN BF27 [get_ports "csn_sec"]; +set_property IOSTANDARD LVCMOS18 [get_ports "csn_sec"]; + diff --git a/spiOverJtag/xilinx_spiOverJtag.v b/spiOverJtag/xilinx_spiOverJtag.v index 6d212ab..334d550 100644 --- a/spiOverJtag/xilinx_spiOverJtag.v +++ b/spiOverJtag/xilinx_spiOverJtag.v @@ -286,7 +286,7 @@ module spiOverJtag `endif /* !virtex6 */ `ifdef secondaryflash - wire drck_sec; + wire drck_sec, tdo_sec; spiOverJtag_core spiOverJtag_core_sec ( /* JTAG state/controls */ diff --git a/src/part.hpp b/src/part.hpp index 58fc51a..bbc629f 100644 --- a/src/part.hpp +++ b/src/part.hpp @@ -44,6 +44,7 @@ static std::map fpga_list = { {0x06e5d093, {"xilinx", "xc2c", "xc2c64a", 8}}, {0x06e5e093, {"xilinx", "xc2c", "xc2c64a", 8}}, {0x06e1c093, {"xilinx", "xc2c", "xc2c32a", 8}}, + {0x16d4a093, {"xilinx", "xc2c", "xc2c256", 8}}, /* Xilinx XC9 */ {0x09602093, {"xilinx", "xc9500xl", "xc9536xl", 8}}, @@ -162,6 +163,7 @@ static std::map fpga_list = { {0x14B29093, {"xilinx", "virtexusp", "xcvu7p", 12}}, {0x04B31093, {"xilinx", "virtexusp", "xcvu9p", 18}}, + {0x14B31093, {"xilinx", "virtexusp", "xcvu9p", 18}}, {0x04B35093, {"xilinx", "virtexusp", "xcvu9p", 18}}, {0x14B79093, {"xilinx", "virtexusp", "xcvu37p", 18}}, {0x04B49093, {"xilinx", "virtexusp", "xcvu11p", 18}}, diff --git a/src/spiFlashdb.hpp b/src/spiFlashdb.hpp index 14b4e19..8ca858d 100644 --- a/src/spiFlashdb.hpp +++ b/src/spiFlashdb.hpp @@ -83,8 +83,8 @@ static std::map flash_list = { .tb_register = CONFR, .bp_len = 3, .bp_offset = {(1 << 2), (1 << 3), (1 << 4), 0}, - .quad_register = NONER, - .quad_mask = 0, + .quad_register = CONFR, + .quad_mask = (1 << 1), .global_lock = false, }}, {0x012018, { diff --git a/src/xilinx.cpp b/src/xilinx.cpp index c68a365..276531c 100644 --- a/src/xilinx.cpp +++ b/src/xilinx.cpp @@ -158,11 +158,14 @@ static std::map>> { /* Xilinx Virtex UltraScale+ */ /* /data/parts/xilinx/virtexuplus/public/bsdl/xcvu9p_flga2104.bsd */ + /* SLR1 is the master SLR */ "virtexusp", { { "USER1", {0b00100100, 0b00101001, 0b00} }, { "USER2", {0b00100100, 0b00111001, 0b00} }, + { "USER4", {0b00100100, 0b00111001, 0b10} }, { "CFG_IN", {0b00100100, 0b01011001, 0b00} }, // CFG_IN_SLR1 + { "CFG_OUT", {0b00100100, 0b01001001, 0b00} }, // CFG_OUT_SLR1 { "USERCODE", {0b00100100, 0b10001001, 0b00} }, { "IDCODE", {0b01001001, 0b10010010, 0b00} }, { "ISC_ENABLE", {0b00010000, 0b00000100, 0b01} }, @@ -366,7 +369,7 @@ Xilinx::Xilinx(Jtag *jtag, const std::string &filename, _secondary_file_extension = secondary_filename.substr( secondary_filename.find_last_of(".") + 1); _mode = Device::SPI_MODE; - if (!(_device_package == "xcvu9p-flga2104" || _device_package == "xcku5p-ffvb676" || _device_package == "xcku040-ffva1156")) { + if (!(_device_package == "xcvu9p-flga2104" || _device_package == "xcvu9p-flgb2104" || _device_package == "xcku5p-ffvb676" || _device_package == "xcku040-ffva1156")) { throw std::runtime_error("Error: secondary flash unavailable"); } } @@ -908,6 +911,9 @@ float Xilinx::get_spiOverJtag_version() if (fpga_list[idcode].family == "virtexusp" & fpga_list[idcode].model == "xcvu7p") { _jtag->shiftIR(get_ircode(_ircode_map, "USER4"), NULL, _irlen); } + else if (fpga_list[idcode].family == "virtexusp" & fpga_list[idcode].model == "xcvu9p") { + _jtag->shiftIR(get_ircode(_ircode_map, "USER4"), NULL, _irlen); + } else { _jtag->shiftIR(USER4, _irlen, Jtag::UPDATE_IR); }