From 4161c79920ecd06cccb784ebe944720691b2d575 Mon Sep 17 00:00:00 2001 From: Maik Ender <39553798+mander1000@users.noreply.github.com> Date: Thu, 9 Mar 2023 20:48:19 +0100 Subject: [PATCH] Add Support for Xilinx KCU116 (#322) * initial kcu116 support * add kintex ultrascale plus family to xilinx.cpp * add docs * combine xcku and xcvu check * rebuild bitstream for -1 speedgrade --- doc/boards.yml | 7 +++++++ doc/vendors/xilinx.rst | 2 +- spiOverJtag/Makefile | 1 + spiOverJtag/build.py | 11 +++++----- spiOverJtag/constr_xcku5p_ffvb676.xdc | 19 ++++++++++++++++++ spiOverJtag/spiOverJtag_xcku5p-ffvb676.bit.gz | Bin 0 -> 131399 bytes src/board.hpp | 1 + src/mcsParser.cpp | 1 + src/part.hpp | 1 + src/xilinx.cpp | 7 +++++-- src/xilinx.hpp | 1 + 11 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 spiOverJtag/constr_xcku5p_ffvb676.xdc create mode 100644 spiOverJtag/spiOverJtag_xcku5p-ffvb676.bit.gz diff --git a/doc/boards.yml b/doc/boards.yml index 615759a..e3ad4f6 100644 --- a/doc/boards.yml +++ b/doc/boards.yml @@ -725,3 +725,10 @@ FPGA: Virtex UltraScale+ xcvu37p-fsvh2892 Memory: OK Flash: OK + +- ID: kcu116 + Description: Xilinx KCU116 + URL: https://www.xilinx.com/products/boards-and-kits/kcu116.html + FPGA: Kintex UltraScale+ xcku5p-ffvb676 + Memory: OK + Flash: OK diff --git a/doc/vendors/xilinx.rst b/doc/vendors/xilinx.rst index 1228ced..8215d56 100644 --- a/doc/vendors/xilinx.rst +++ b/doc/vendors/xilinx.rst @@ -97,7 +97,7 @@ File load: device/package format is something like xc7a35tcsg324 (arty model). See :ghsrc:`src/board.hpp `, or :ghsrc:`spiOverJtag ` directory for examples. -Some boards with UltraScale FPGAs, like the VCU118, support the SPIx8 (Dual Quad SPI) configuration. +Some boards with UltraScale FPGAs, like the VCU118 and KCU16, support the SPIx8 (Dual Quad SPI) configuration. In this case, the ``spix8`` option ``write_cfgmem`` on the above example can be used to generate two ``.mcs`` files, to fit bigger designs or for faster programming. Only ``.mcs`` files can be used to program the FPGA in this case. diff --git a/spiOverJtag/Makefile b/spiOverJtag/Makefile index 8f72773..050faaf 100644 --- a/spiOverJtag/Makefile +++ b/spiOverJtag/Makefile @@ -8,6 +8,7 @@ XILINX_PARTS := xc3s500evq100 xc6slx9tqg144 xc6slx16ftg256 xc6slx16csg324 xc6slx xc7k160tffg676 \ xc7k325tffg676 xc7k325tffg900 \ xc7k420tffg901 \ + xcku5p-ffvb676 \ xcvu9p-flga2104 xcvu37p-fsvh2892 XILINX_BIT_FILES := $(addsuffix .bit.gz,$(addprefix spiOverJtag_, $(XILINX_PARTS))) diff --git a/spiOverJtag/build.py b/spiOverJtag/build.py index f112e0e..214ac36 100755 --- a/spiOverJtag/build.py +++ b/spiOverJtag/build.py @@ -55,8 +55,8 @@ elif subpart == "xc3s": family = "Spartan3E" tool = "ise" speed = -4 -elif subpart == "xcvu": - family = "Virtex UltraScale" +elif subpart in ["xcvu", "xcku"]: + family = "Xilinx UltraScale" tool = "vivado" else: print("Error: unknown device") @@ -92,6 +92,7 @@ if tool in ["ise", "vivado"]: "xc7s50csga324" : "xc7s_csga324", "xcvu9p-flga2104" : "xcvu9p_flga2104", "xcvu37p-fsvh2892" : "xcvu37p_fsvh2892", + "xcku5p-ffvb676" : "xcku5p_ffvb676", }[part] if tool == "ise": cst_type = "UCF" @@ -126,9 +127,9 @@ if tool in ["ise", "vivado"]: } else: cst_type = "xdc" - if family == "Virtex UltraScale": - tool_options = {'part': part + '-1-e'} - if part == "xcvu9p-flga2104": + if family == "Xilinx UltraScale": + if part in ["xcvu9p-flga2104", "xcku5p-ffvb676"]: + tool_options = {'part': part + '-1-e'} parameters["secondaryflash"]= { 'datatype': 'int', 'paramtype': 'vlogdefine', diff --git a/spiOverJtag/constr_xcku5p_ffvb676.xdc b/spiOverJtag/constr_xcku5p_ffvb676.xdc new file mode 100644 index 0000000..e3cb4e1 --- /dev/null +++ b/spiOverJtag/constr_xcku5p_ffvb676.xdc @@ -0,0 +1,19 @@ +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 + +# Secondary QSPI flash +set_property PACKAGE_PIN N23 [get_ports "sdi_sec_dq0"] ;# Bank 65 VCCO - VCC1V8 - IO_L22P_T3U_N6_DBC_AD0P_D04_65 +set_property IOSTANDARD LVCMOS18 [get_ports "sdi_sec_dq0"] ;# Bank 65 VCCO - VCC1V8 - IO_L22P_T3U_N6_DBC_AD0P_D04_65 +set_property PACKAGE_PIN P23 [get_ports "sdo_sec_dq1"] ;# Bank 65 VCCO - VCC1V8 - IO_L22N_T3U_N7_DBC_AD0N_D05_65 +set_property IOSTANDARD LVCMOS18 [get_ports "sdo_sec_dq1"] ;# Bank 65 VCCO - VCC1V8 - IO_L22N_T3U_N7_DBC_AD0N_D05_65 +set_property PACKAGE_PIN R20 [get_ports "wpn_sec_dq2"] ;# Bank 65 VCCO - VCC1V8 - IO_L21P_T3L_N4_AD8P_D06_65 +set_property IOSTANDARD LVCMOS18 [get_ports "wpn_sec_dq2"] ;# Bank 65 VCCO - VCC1V8 - IO_L21P_T3L_N4_AD8P_D06_65 +set_property PACKAGE_PIN R21 [get_ports "hldn_sec_dq3"] ;# Bank 65 VCCO - VCC1V8 - IO_L21N_T3L_N5_AD8N_D07_65 +set_property IOSTANDARD LVCMOS18 [get_ports "hldn_sec_dq3"] ;# Bank 65 VCCO - VCC1V8 - IO_L21N_T3L_N5_AD8N_D07_65 +set_property PACKAGE_PIN U22 [get_ports "csn_sec"] ;# Bank 65 VCCO - VCC1V8 - IO_L2N_T0L_N3_FWE_FCS2_B_65 +set_property IOSTANDARD LVCMOS18 [get_ports "csn_sec"] ;# Bank 65 VCCO - VCC1V8 - IO_L2N_T0L_N3_FWE_FCS2_B_65 \ No newline at end of file diff --git a/spiOverJtag/spiOverJtag_xcku5p-ffvb676.bit.gz b/spiOverJtag/spiOverJtag_xcku5p-ffvb676.bit.gz new file mode 100644 index 0000000000000000000000000000000000000000..cea2b4e00858435133b801c9e70bd5a3b8375558 GIT binary patch literal 131399 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 e-t8aKuf5yPZTau(2K9`0Kl1rcE63@HDgOc board_list = { JTAG_BOARD("zc706", "xc7z045ffg900", "jtag-smt2-nc", 0, 0, CABLE_DEFAULT), JTAG_BOARD("zcu102", "xczu9egffvb1156", "jtag-smt2-nc", 0, 0, CABLE_DEFAULT), JTAG_BOARD("zcu106", "xczu7evffvc1156", "jtag-smt2-nc", 0, 0, CABLE_DEFAULT), + JTAG_BOARD("kcu116", "xcku5p-ffvb676", "jtag-smt2-nc", 0, 0, CABLE_DEFAULT), JTAG_BOARD("zedboard", "xc7z020clg484", "digilent_hs2", 0, 0, CABLE_DEFAULT), JTAG_BOARD("zybo_z7_10", "xc7z010clg400", "digilent", 0, 0, CABLE_DEFAULT), JTAG_BOARD("zybo_z7_20", "xc7z020clg400", "digilent", 0, 0, CABLE_DEFAULT) diff --git a/src/mcsParser.cpp b/src/mcsParser.cpp index bc980c3..db4db44 100644 --- a/src/mcsParser.cpp +++ b/src/mcsParser.cpp @@ -43,6 +43,7 @@ int McsParser::parse() { string str; istringstream lineStream(_raw_data); + _bit_data.resize(_file_size); while (std::getline(lineStream, str, '\n')) { char *ptr; diff --git a/src/part.hpp b/src/part.hpp index b2ce2d5..1c770b9 100644 --- a/src/part.hpp +++ b/src/part.hpp @@ -65,6 +65,7 @@ static std::map fpga_list = { {0x03727093, {"xilinx", "zynq", "xc7z020", 6}}, {0x23731093, {"xilinx", "zynq", "xc7z045", 6}}, + {0x04a62093, {"xilinx", "kintexusp", "xcku5p", 6}}, {0x04A64093, {"xilinx", "artixusp", "xcau25p", 6}}, {0x04b31093, {"xilinx", "virtexusp", "xcvu9p", 18}}, diff --git a/src/xilinx.cpp b/src/xilinx.cpp index a52e878..6a4cc6f 100644 --- a/src/xilinx.cpp +++ b/src/xilinx.cpp @@ -59,7 +59,8 @@ static std::map>> "default", { { "USER1", {0x02} }, - { "CFG_IN", {0x05}}, + { "USER2", {0x03} }, + { "CFG_IN", {0x05} }, { "USERCODE", {0x08} }, { "IDCODE", {0x09} }, { "ISC_ENABLE", {0x10} }, @@ -169,7 +170,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") { + if (!(_device_package == "xcvu9p-flga2104" || _device_package == "xcku5p-ffvb676")) { throw std::runtime_error("Error: secondary flash unavailable"); } } @@ -198,6 +199,8 @@ Xilinx::Xilinx(Jtag *jtag, const std::string &filename, _fpga_family = KINTEX_FAMILY; } else if (family == "kintexus") { _fpga_family = KINTEXUS_FAMILY; + } else if (family == "kintexusp") { + _fpga_family = KINTEXUSP_FAMILY; } else if (family == "artixusp") { _fpga_family = ARTIXUSP_FAMILY; } else if (family == "virtexusp") { diff --git a/src/xilinx.hpp b/src/xilinx.hpp index 6ed120d..34b2f22 100644 --- a/src/xilinx.hpp +++ b/src/xilinx.hpp @@ -161,6 +161,7 @@ class Xilinx: public Device, SPIInterface { ARTIX_FAMILY, KINTEX_FAMILY, KINTEXUS_FAMILY, + KINTEXUSP_FAMILY, ZYNQ_FAMILY, ZYNQMP_FAMILY, XCF_FAMILY,