This commit is contained in:
Nicholas Dietz 2026-06-16 09:26:28 -05:00 committed by GitHub
commit a504778eb1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 84 additions and 16 deletions

View File

@ -14,7 +14,7 @@ XILINX_PARTS := xc3s500evq100 \
xcku040-ffva1156 xcku060-ffva1156 \ xcku040-ffva1156 xcku060-ffva1156 \
xcku5p-ffvb676 \ xcku5p-ffvb676 \
xcvu9p-flga2104 xcvu37p-fsvh2892 \ xcvu9p-flga2104 xcvu37p-fsvh2892 \
xcau10p-ffvb676 \ xcau7p-sbvc484 xcau10p-ffvb676 \
xcau15p-ffvb676 xcau15p-ffvb676
XILINX_BIT_FILES := $(addsuffix .bit.gz,$(addprefix spiOverJtag_, $(XILINX_PARTS))) XILINX_BIT_FILES := $(addsuffix .bit.gz,$(addprefix spiOverJtag_, $(XILINX_PARTS)))

View File

@ -151,6 +151,7 @@ if tool in ["ise", "vivado"]:
"xcvu37p-fsvh2892" : "xcvu37p_fsvh2892", "xcvu37p-fsvh2892" : "xcvu37p_fsvh2892",
"xcku3p-ffva676" : "xcku3p_ffva676", "xcku3p-ffva676" : "xcku3p_ffva676",
"xcku5p-ffvb676" : "xcku5p_ffvb676", "xcku5p-ffvb676" : "xcku5p_ffvb676",
"xcau7p-sbvc484" : "xcau7p_sbvc484",
"xcau10p-ffvb676" : "xcau10p_ffvb676", "xcau10p-ffvb676" : "xcau10p_ffvb676",
"xcau15p-ffvb676" : "xcau15p_ffvb676", "xcau15p-ffvb676" : "xcau15p_ffvb676",
}.get(part, pkg_name) }.get(part, pkg_name)
@ -213,6 +214,8 @@ if tool in ["ise", "vivado"]:
'paramtype': 'vlogdefine', 'paramtype': 'vlogdefine',
'description': 'secondary flash', 'description': 'secondary flash',
'default': 1} 'default': 1}
elif part == "xcau7p-sbvc484":
tool_options = {'part': part + '-1-e'}
elif part == "xcau10p-ffvb676": elif part == "xcau10p-ffvb676":
tool_options = {'part': part + '-1-e'} tool_options = {'part': part + '-1-e'}
elif part == "xcau15p-ffvb676": elif part == "xcau15p-ffvb676":

View File

@ -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

View File

@ -74,7 +74,8 @@ module spiOverJtag
assign sck = drck; assign sck = drck;
`else // !spartan6 && !spartan3e `else // !spartan6 && !spartan3e
`ifdef xilinxultrascale `ifdef xilinxultrascale
assign sck = drck; wire csn;
wire sdi_dq0, sdo_dq1, wpn_dq2, hldn_dq3;
wire [3:0] di; wire [3:0] di;
assign sdo_dq1 = di[1]; 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};

View File

@ -804,14 +804,14 @@ int spi_comm(struct arguments args, const cable_t &cable,
bit = new RawParser(args.bit_file, false); bit = new RawParser(args.bit_file, false);
printSuccess("DONE"); printSuccess("DONE");
} catch (std::exception &e) { } catch (std::exception &e) {
printError("FAIL"); printError("FAIL: unable to open '" + args.bit_file + "': " + std::string(e.what()));
delete spi; delete spi;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
printInfo("Parse file ", false); printInfo("Parse file ", false);
if (bit->parse() == EXIT_FAILURE) { if (bit->parse() == EXIT_FAILURE) {
printError("FAIL"); printError("FAIL: unable to parse '" + args.bit_file + "'");
delete bit; delete bit;
delete spi; delete spi;
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@ -131,6 +131,7 @@ static std::map <uint32_t, fpga_model> fpga_list = {
{0x03842093, {"xilinx", "virtexus", "xcvu095", 6}}, {0x03842093, {"xilinx", "virtexus", "xcvu095", 6}},
/* Xilinx Ultrascale+ / Artix */ /* Xilinx Ultrascale+ / Artix */
{0x04AF6093, {"xilinx", "artixusp", "xcau7p-sbvc484", 6}},
{0x04AC4033, {"xilinx", "artixusp", "xcau10p", 6}}, {0x04AC4033, {"xilinx", "artixusp", "xcau10p", 6}},
{0x04AC4093, {"xilinx", "artixusp", "xcau10p", 6}}, {0x04AC4093, {"xilinx", "artixusp", "xcau10p", 6}},
{0x04AC2093, {"xilinx", "artixusp", "xcau15p", 6}}, {0x04AC2093, {"xilinx", "artixusp", "xcau15p", 6}},

View File

@ -651,6 +651,23 @@ static std::map <uint32_t, flash_t> flash_list = {
.quad_mask = (1 << 6), .quad_mask = (1 << 6),
.global_lock = false, .global_lock = false,
}}, }},
{0xc86019, {
/* https://www.gigadevice.com/datasheet/gd25q256e/ */
.manufacturer = "GigaDevice",
.model = "GD25Q256E",
.nr_sector = 512,
.sector_erase = true,
.subsector_erase = true,
.has_extended = false,
.tb_otp = false,
.tb_offset = (1 << 14), // CMP
.tb_register = STATR,
.bp_len = 4,
.bp_offset = {(1 << 2), (1 << 3), (1 << 4), (1 << 5)},
.quad_register = STATR,
.quad_mask = (1 << 9),
.global_lock = false,
}},
{0xc22817, { {0xc22817, {
/* https://www.macronix.com/Lists/Datasheet/Attachments/8868/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.6.pdf */ /* https://www.macronix.com/Lists/Datasheet/Attachments/8868/MX25R6435F,%20Wide%20Range,%2064Mb,%20v1.6.pdf */
.manufacturer = "Macronix", .manufacturer = "Macronix",
@ -766,6 +783,40 @@ static std::map <uint32_t, flash_t> flash_list = {
.quad_mask = 0, .quad_mask = 0,
.global_lock = false, .global_lock = false,
}}, }},
{0xef6019, {
/* Winbond W25Q256PW (1.8V), 256 Mbit / 32 MiB. Requires 4-byte addressing. */
.manufacturer = "Winbond",
.model = "W25Q256PW",
.nr_sector = 512,
.sector_erase = true,
.subsector_erase = true,
.has_extended = false,
.tb_otp = false,
.tb_offset = (1 << 5),
.tb_register = STATR,
.bp_len = 3,
.bp_offset = {(1 << 2), (1 << 3), (1 << 4), 0},
.quad_register = STATR,
.quad_mask = (1 << 9),
.global_lock = false,
}},
{0xef8019, {
/* Winbond W25Q256PW newer-gen die that reports memory-type 0x80. */
.manufacturer = "Winbond",
.model = "W25Q256PW",
.nr_sector = 512,
.sector_erase = true,
.subsector_erase = true,
.has_extended = false,
.tb_otp = false,
.tb_offset = (1 << 5),
.tb_register = STATR,
.bp_len = 3,
.bp_offset = {(1 << 2), (1 << 3), (1 << 4), 0},
.quad_register = STATR,
.quad_mask = (1 << 9),
.global_lock = false,
}},
{0x6bbb14, { {0x6bbb14, {
.manufacturer = "Everspin", .manufacturer = "Everspin",
.model = "EM008LX", .model = "EM008LX",

View File

@ -186,20 +186,24 @@ static void open_bitfile(
const std::string &filename, const std::string &extension, const std::string &filename, const std::string &extension,
ConfigBitstreamParser **parser, bool reverse, bool verbose) ConfigBitstreamParser **parser, bool reverse, bool verbose)
{ {
printInfo("Open file ", false); printInfo("Open file " + filename + " ", false);
if (extension == "bit") { try {
*parser = new BitParser(filename, reverse, verbose); if (extension == "bit") {
} else if (extension == "mcs") { *parser = new BitParser(filename, reverse, verbose);
*parser = new McsParser(filename, reverse, verbose); } else if (extension == "mcs") {
} else { *parser = new McsParser(filename, reverse, verbose);
*parser = new RawParser(filename, reverse); } else {
*parser = new RawParser(filename, reverse);
}
} catch (const std::exception &e) {
throw std::runtime_error("Unable to open '" + filename + "': " + e.what());
} }
printSuccess("DONE"); printSuccess("DONE");
printInfo("Parse file ", false); printInfo("Parse file ", false);
if ((*parser)->parse() == EXIT_FAILURE) { if ((*parser)->parse() == EXIT_FAILURE) {
throw std::runtime_error("Failed to parse bitstream"); throw std::runtime_error("Failed to parse bitstream '" + filename + "'");
} }
printSuccess("DONE"); printSuccess("DONE");
@ -634,12 +638,11 @@ void Xilinx::program(unsigned int offset, bool unprotect_flash)
&secondary_bit, reverse, _verbose); &secondary_bit, reverse, _verbose);
} }
} catch (std::exception &e) { } catch (std::exception &e) {
printError("FAIL");
if (bit) if (bit)
delete bit; delete bit;
if (secondary_bit) if (secondary_bit)
delete secondary_bit; delete secondary_bit;
return; throw std::runtime_error(e.what());
} }
if (_verbose) { if (_verbose) {
@ -842,11 +845,13 @@ void Xilinx::program_spi(ConfigBitstreamParser * bit, std::string extention,
throw std::runtime_error("called with null bitstream"); throw std::runtime_error("called with null bitstream");
if (extention == "mcs") { if (extention == "mcs") {
McsParser *parser = (McsParser *)bit; McsParser *parser = (McsParser *)bit;
FlashInterface::write(parser->getRecords(), unprotect_flash, true); if (!FlashInterface::write(parser->getRecords(), unprotect_flash, true))
throw std::runtime_error("SPI flash write failed");
} else { } else {
const uint8_t *data = bit->getData(); const uint8_t *data = bit->getData();
int length = bit->getLength() / 8; int length = bit->getLength() / 8;
FlashInterface::write(offset, data, length, unprotect_flash); if (!FlashInterface::write(offset, data, length, unprotect_flash))
throw std::runtime_error("SPI flash write failed");
} }
} }