diff --git a/doc/boards.yml b/doc/boards.yml index e77df37..ac59047 100644 --- a/doc/boards.yml +++ b/doc/boards.yml @@ -13,6 +13,13 @@ Memory: OK Flash: OK +- ID: alibaba_u3p + Description: AS02MC04 (Alibaba Cloud) Kintex UltraScale+ NIC + URL: https://www.controlpaths.com/2026/01/18/as02mc04-kintex-ultrascale-plus/ + FPGA: Kintex UltraScale+ xcku3p-ffvb676 + Memory: OK + Flash: OK + - ID: alinx_ax7201 Description: AX7201 FPGA Dev Board & Kit with AMD Artix 7 URL: https://www.en.alinx.com/Product/FPGA-Development-Boards/Artix-7/AX7201.html diff --git a/spiOverJtag/Makefile b/spiOverJtag/Makefile index 0a5bf15..7ac1da4 100644 --- a/spiOverJtag/Makefile +++ b/spiOverJtag/Makefile @@ -10,6 +10,7 @@ XILINX_PARTS := xc3s500evq100 \ xc7k325tfbg900 xc7k325tffg676 xc7k325tffg900 \ xc7k420tffg901 \ xcku3p-ffva676 \ + xcku3p-ffvb676 \ xc7vx330tffg1157 \ xcku040-ffva1156 xcku060-ffva1156 \ xcku5p-ffvb676 \ diff --git a/spiOverJtag/build.py b/spiOverJtag/build.py index 595df7f..a1d1163 100755 --- a/spiOverJtag/build.py +++ b/spiOverJtag/build.py @@ -37,7 +37,7 @@ packages = { }, } -if len(os.sys.argv) != 3 : +if len(os.sys.argv) != 3: print("missing board flash type params") os.sys.exit() part = os.sys.argv[1] @@ -46,16 +46,16 @@ flash_type = os.sys.argv[2] # Check file type keyword assert flash_type in ["spi", "bpi"] -build_dir="tmp_" + part +build_dir = "tmp_" + part if not os.path.isdir(build_dir): try: os.mkdir(build_dir) except OSError: - print ("Creation of the directory %s failed" % build_dir) + print("Creation of the directory %s failed" % build_dir) else: - print ("Successfully created the directory %s " % build_dir) + print("Successfully created the directory %s " % build_dir) -currDir = os.path.abspath(os.path.curdir) + '/' +currDir = os.path.abspath(os.path.curdir) + "/" files = [] parameters = {} pkg_name = None @@ -63,22 +63,22 @@ pkg = None model = "" subpart = part[0:4].lower() -if subpart == '10cl': +if subpart == "10cl": family = "Cyclone 10 LP" tool = "quartus" -elif subpart == 'ep4c': +elif subpart == "ep4c": family = "Cyclone IV E" tool = "quartus" -elif subpart[0:2] == '5c': +elif subpart[0:2] == "5c": family = "Cyclone V" tool = "quartus" - files.append({'name': currDir + 'constr_cycloneV.tcl', - 'file_type': 'tclSource'}) -elif subpart[0:2] == '5s': + files.append({"name": currDir + "constr_cycloneV.tcl", + "file_type": "tclSource"}) +elif subpart[0:2] == "5s": family = "Stratix V" tool = "quartus" - files.append({'name': currDir + 'constr_cycloneV.tcl', - 'file_type': 'tclSource'}) + files.append({"name": currDir + "constr_cycloneV.tcl", + "file_type": "tclSource"}) elif subpart == "xc7a": family = "Artix" tool = "vivado" @@ -87,7 +87,7 @@ elif subpart == "xc7v": family = "Virtex 7" tool = "vivado" elif subpart == "xc7k": - device_size = int(part.split('k')[1].split('t')[0]) + device_size = int(part.split("k")[1].split("t")[0]) if flash_type == "bpi" or device_size <= 160: family = "Kintex 7" tool = "vivado" @@ -137,8 +137,8 @@ if model in ["xc7a", "xc7s"]: os.sys.exit() pkg_name = f"{model}_{pkg}" if model in ["xc7k"]: - m = re.match(r"(xc7k\d+t)(\w+)", part) - pkg = m.group(2) + m = re.match(r"(xc7k\d+t)(\w+)", part) + pkg = m.group(2) pkg_name = f"{model}_{pkg}" if tool == "ise": model = m.group(1) @@ -164,125 +164,136 @@ if tool in ["ise", "vivado"]: "xcvu9p-flga2104" : "xcvu9p_flga2104", "xcvu37p-fsvh2892" : "xcvu37p_fsvh2892", "xcku3p-ffva676" : "xcku3p_ffva676", + "xcku3p-ffvb676" : "xcku3p_ffvb676", "xcku5p-ffvb676" : "xcku5p_ffvb676", "xcau10p-ffvb676" : "xcau10p_ffvb676", "xcau15p-ffvb676" : "xcau15p_ffvb676", }.get(part, pkg_name) if tool == "ise": cst_type = "UCF" - tool_options = {'family': family, - 'device': { - "xc3s500evq100": "xc3s500e", - "xc6slx9tqg144": "xc6slx9", - "xc6slx9csg324": "xc6slx9", - "xc6slx16ftg256": "xc6slx16", - "xc6slx16csg324": "xc6slx16", - "xc6slx25csg324": "xc6slx25", - "xc6slx25tcsg324": "xc6slx25t", - "xc6slx45csg324": "xc6slx45", - "xc6slx45tfgg484": "xc6slx45t", - "xc6slx100fgg484": "xc6slx100", - "xc6slx150tcsg484": "xc6slx150t", - "xc6slx150tfgg484": "xc6slx150t", - "xc6vlx130tff784": "xc6vlx130t", - }.get(part, model), - 'package': { - "xc3s500evq100": "vq100", - "xc6slx9tqg144": "tqg144", - "xc6slx9csg324": "csg324", - "xc6slx16ftg256": "ftg256", - "xc6slx16csg324": "csg324", - "xc6slx25csg324": "csg324", - "xc6slx25tcsg324": "csg324", - "xc6slx45csg324": "csg324", - "xc6slx45tfgg484": "fgg484", - "xc6slx100fgg484": "fgg484", - "xc6slx150tcsg484": "csg484", - "xc6slx150tfgg484": "fgg484", - "xc6vlx130tff784": "ff784", - }.get(part, pkg), - 'speed' : speed - } + tool_options = { + "family": family, + "device": { + "xc3s500evq100" : "xc3s500e", + "xc6slx9tqg144" : "xc6slx9", + "xc6slx9csg324" : "xc6slx9", + "xc6slx16ftg256" : "xc6slx16", + "xc6slx16csg324" : "xc6slx16", + "xc6slx25csg324" : "xc6slx25", + "xc6slx25tcsg324" : "xc6slx25t", + "xc6slx45csg324" : "xc6slx45", + "xc6slx45tfgg484" : "xc6slx45t", + "xc6slx100fgg484" : "xc6slx100", + "xc6slx150tcsg484" : "xc6slx150t", + "xc6slx150tfgg484" : "xc6slx150t", + "xc6vlx130tff784" : "xc6vlx130t", + }.get(part, model), + "package": { + "xc3s500evq100" : "vq100", + "xc6slx9tqg144" : "tqg144", + "xc6slx9csg324" : "csg324", + "xc6slx16ftg256" : "ftg256", + "xc6slx16csg324" : "csg324", + "xc6slx25csg324" : "csg324", + "xc6slx25tcsg324" : "csg324", + "xc6slx45csg324" : "csg324", + "xc6slx45tfgg484" : "fgg484", + "xc6slx100fgg484" : "fgg484", + "xc6slx150tcsg484" : "csg484", + "xc6slx150tfgg484" : "fgg484", + "xc6vlx130tff784" : "ff784", + }.get(part, pkg), + "speed" : speed, + } else: cst_type = "xdc" # Artix/Spartan 7 Specific use case: if family in ["Artix", "Spartan 7"]: - tool_options = {'part': f"{device}{pkg}-1"} + tool_options = {"part": f"{device}{pkg}-1"} elif family == "Xilinx UltraScale": if part in ["xcvu9p-flga2104", "xcku5p-ffvb676"]: - tool_options = {'part': part + '-1-e'} - parameters["secondaryflash"]= { - 'datatype': 'int', - 'paramtype': 'vlogdefine', - 'description': 'secondary flash', - 'default': 1} + tool_options = {"part": part + "-1-e"} + parameters["secondaryflash"] = { + "datatype": "int", + "paramtype": "vlogdefine", + "description": "secondary flash", + "default": 1, + } elif part == "xcku3p-ffva676": - tool_options = {'part': part + '-2-e'} + tool_options = {"part": part + "-2-e"} + elif part == "xcku3p-ffvb676": + tool_options = {"part": part + "-2-e"} elif part == "xcvu37p-fsvh2892": - tool_options = {'part': part + '-2L-e'} + tool_options = {"part": part + "-2L-e"} elif part in ["xcku040-ffva1156", "xcku060-ffva1156"]: - tool_options = {'part': part + '-2-e'} - parameters["secondaryflash"]= { - 'datatype': 'int', - 'paramtype': 'vlogdefine', - 'description': 'secondary flash', - 'default': 1} + tool_options = {"part": part + "-2-e"} + parameters["secondaryflash"] = { + "datatype" : "int", + "paramtype" : "vlogdefine", + "description" : "secondary flash", + "default" : 1, + } elif part == "xcau10p-ffvb676": - tool_options = {'part': part + '-1-e'} + tool_options = {"part": part + "-1-e"} elif part == "xcau15p-ffvb676": - tool_options = {'part': part + '-2-e'} + tool_options = {"part": part + "-2-e"} else: - tool_options = {'part': part + '-1'} + tool_options = {"part": part + "-1"} cst_file = currDir + "constr_" + pkg_name + "." + cst_type.lower() - files.append({'name': os.path.join(currDir, f"xilinx_{flash_type}OverJtag.v"), - 'file_type': 'verilogSource'}) - files.append({'name': cst_file, 'file_type': cst_type}) + files.append({"name": os.path.join(currDir, f"xilinx_{flash_type}OverJtag.v"), + "file_type": "verilogSource"}) + files.append({"name": cst_file, "file_type": cst_type}) else: # Altera only support SPI mode. assert flash_type in ["spi"] full_part = { - "10cl016484" : "10CL016YU484C8G", - "10cl025256" : "10CL025YU256C8G", - "10cl055484" : "10CL055YU484C8G", - "10cl006144" : "10CL006YE144C8G", - "ep4cgx15027": "EP4CGX150DF27I7", - "ep4ce11523" : "EP4CE115F23C7", - "ep4ce2217" : "EP4CE22F17C6", - "ep4ce1523" : "EP4CE15F23C8", - "ep4ce1017" : "EP4CE10F17C8", - "ep4ce622" : "EP4CE6E22C8", - "5ce215" : "5CEBA2U15C8", - "5ce223" : "5CEFA2F23I7", - "5ce523" : "5CEFA5F23I7", - "5ce423" : "5CEBA4F23C8", - "5ce927" : "5CEBA9F27C7", - "5cse423" : "5CSEMA4U23C6", - "5cse623" : "5CSEBA6U23I7", - "5sgsd5" : "5SGSMD5K2F40I3"}[part] - files.append({'name': currDir + 'altera_spiOverJtag.v', - 'file_type': 'verilogSource'}) - files.append({'name': currDir + 'altclkctrl_inst.v', - 'file_type': 'verilogSource'}) - files.append({'name': currDir + 'altera_spiOverJtag.sdc', - 'file_type': 'SDC'}) - tool_options = {'device': full_part, 'family':family} + "10cl016484" : "10CL016YU484C8G", + "10cl025256" : "10CL025YU256C8G", + "10cl055484" : "10CL055YU484C8G", + "10cl006144" : "10CL006YE144C8G", + "ep4cgx15027" : "EP4CGX150DF27I7", + "ep4ce11523" : "EP4CE115F23C7", + "ep4ce2217" : "EP4CE22F17C6", + "ep4ce1523" : "EP4CE15F23C8", + "ep4ce1017" : "EP4CE10F17C8", + "ep4ce622" : "EP4CE6E22C8", + "5ce215" : "5CEBA2U15C8", + "5ce223" : "5CEFA2F23I7", + "5ce523" : "5CEFA5F23I7", + "5ce423" : "5CEBA4F23C8", + "5ce927" : "5CEBA9F27C7", + "5cse423" : "5CSEMA4U23C6", + "5cse623" : "5CSEBA6U23I7", + "5sgsd5" : "5SGSMD5K2F40I3", + }[part] + files.append({"name": currDir + "altera_spiOverJtag.v", + "file_type": "verilogSource"}) + files.append({"name": currDir + "altclkctrl_inst.v", + "file_type": "verilogSource"}) + files.append({"name": currDir + "altera_spiOverJtag.sdc", + "file_type": "SDC"}) + tool_options = {"device": full_part, "family": family} -files.append({'name': os.path.join(currDir, f"{flash_type}OverJtag_core.v"), - 'file_type': 'verilogSource'}) +files.append({ + "name" : os.path.join(currDir, f"{flash_type}OverJtag_core.v"), + "file_type" : "verilogSource", +}) -parameters[family.lower().replace(' ', '')]= { - 'datatype': 'int', - 'paramtype': 'vlogdefine', - 'description': 'fpga family', - 'default': 1} +parameters[family.lower().replace(" ", "")] = { + "datatype": "int", + "paramtype": "vlogdefine", + "description": "fpga family", + "default": 1 +} -edam = {'name' : f"{flash_type}OverJtag", - 'files': files, - 'tool_options': {tool: tool_options}, - 'parameters': parameters, - 'toplevel' : f"{flash_type}OverJtag", +edam = { + "name" : f"{flash_type}OverJtag", + "files" : files, + "tool_options" : {tool: tool_options}, + "parameters" : parameters, + "toplevel" : f"{flash_type}OverJtag", } backend = get_edatool(tool)(edam=edam, work_root=build_dir) @@ -290,13 +301,13 @@ backend.configure() backend.build() if tool in ["vivado", "ise"]: + import gzip import shutil import subprocess - import gzip # Compress bitstream. - with open(f"tmp_{part}/{flash_type}OverJtag.bit", 'rb') as bit: - with gzip.open(f"{flash_type}OverJtag_{part}.bit.gz", 'wb', compresslevel=9) as bit_gz: + with open(f"tmp_{part}/{flash_type}OverJtag.bit", "rb") as bit: + with gzip.open(f"{flash_type}OverJtag_{part}.bit.gz", "wb", compresslevel=9) as bit_gz: shutil.copyfileobj(bit, bit_gz) # Create Symbolic links for all supported packages — only when building diff --git a/spiOverJtag/constr_xcku3p_ffvb676.xdc b/spiOverJtag/constr_xcku3p_ffvb676.xdc new file mode 100644 index 0000000..bc4bb4a --- /dev/null +++ b/spiOverJtag/constr_xcku3p_ffvb676.xdc @@ -0,0 +1,7 @@ +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 diff --git a/spiOverJtag/spiOverJtag_xcku3p-ffvb676.bit.gz b/spiOverJtag/spiOverJtag_xcku3p-ffvb676.bit.gz new file mode 100644 index 0000000..db2f2d7 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xcku3p-ffvb676.bit.gz differ diff --git a/spiOverJtag/xilinx_spiOverJtag.v b/spiOverJtag/xilinx_spiOverJtag.v index 4406029..a3e0dd8 100644 --- a/spiOverJtag/xilinx_spiOverJtag.v +++ b/spiOverJtag/xilinx_spiOverJtag.v @@ -73,11 +73,13 @@ module spiOverJtag `ifdef spartan3e assign sck = drck; `else // !spartan6 && !spartan3e + `ifdef xilinxultrascale assign sck = drck; wire [3:0] di; assign sdo_dq1 = di[1]; - wire [3:0] do = {hldn_dq3, wpn_dq2, 1'b0, sdi_dq0}; + + wire [3:0] do = {hldn_dq3, wpn_dq2, 1'b0, sdi_dq0}; wire [3:0] dts = 4'b0010; // secondary BSCANE3 signals wire sel_sec, spi_clk_sec; diff --git a/src/board.hpp b/src/board.hpp index 9584ee0..6d56bb6 100644 --- a/src/board.hpp +++ b/src/board.hpp @@ -118,6 +118,7 @@ static std::map board_list = { JTAG_BOARD("litex-acorn-baseboard-mini", "xc7a200tsbg484", "", SPI_FLASH, 0, 0, CABLE_DEFAULT), JTAG_BOARD("alchitry_au", "xc7a35tftg256", "ft2232", SPI_FLASH, 0, 0, CABLE_DEFAULT), JTAG_BOARD("alchitry_au_plus","xc7a100tftg256", "ft2232", SPI_FLASH, 0, 0, CABLE_DEFAULT), + JTAG_BOARD("alibaba_u3p", "xcku3p-ffvb676", "", SPI_FLASH, 0, 0, CABLE_DEFAULT), JTAG_BOARD("alinx_ax516", "xc6slx16csg324", "", SPI_FLASH, 0, 0, CABLE_DEFAULT), JTAG_BOARD("alinx_ax7101", "xc7a100tfgg484", "", SPI_FLASH, 0, 0, CABLE_DEFAULT), JTAG_BOARD("alinx_ax7102", "xc7a100tfgg484", "", SPI_FLASH, 0, 0, CABLE_DEFAULT),