Compare commits
19 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
b76840b20d | |
|
|
530b7a9993 | |
|
|
648a4a833a | |
|
|
03be134cdd | |
|
|
617cd29dff | |
|
|
205e6f9ea5 | |
|
|
f8ae76e771 | |
|
|
8694b3c295 | |
|
|
a7b72321fe | |
|
|
8e6eb1085c | |
|
|
13cf0c59b9 | |
|
|
6935936a92 | |
|
|
39b3ca5871 | |
|
|
fdc9edc6cb | |
|
|
29a5bc3515 | |
|
|
6df4bce1fd | |
|
|
1ccc2a0d5b | |
|
|
5e67fee9f5 | |
|
|
06b4e2f143 |
|
|
@ -308,6 +308,14 @@ Xilinx:
|
||||||
Memory: OK
|
Memory: OK
|
||||||
Flash: OK (primary)
|
Flash: OK (primary)
|
||||||
|
|
||||||
|
- Description: Kintex UltraScale+
|
||||||
|
Model:
|
||||||
|
- xcku3p
|
||||||
|
- xcku5p
|
||||||
|
URL: https://www.xilinx.com/products/silicon-devices/fpga/kintex-ultrascale-plus.html#productTable
|
||||||
|
Memory: OK
|
||||||
|
Flash: OK
|
||||||
|
|
||||||
- Description: Virtex 6
|
- Description: Virtex 6
|
||||||
Model:
|
Model:
|
||||||
- xc6vlx130t
|
- xc6vlx130t
|
||||||
|
|
@ -329,6 +337,13 @@ Xilinx:
|
||||||
Memory: OK
|
Memory: OK
|
||||||
Flash: OK
|
Flash: OK
|
||||||
|
|
||||||
|
- Description: Spartan UltraScale+
|
||||||
|
Model:
|
||||||
|
- xcsu35p
|
||||||
|
URL: https://www.amd.com/en/products/adaptive-socs-and-fpgas/fpga/spartan-ultrascale-plus.html#productTable
|
||||||
|
Memory: OK
|
||||||
|
Flash: TBD
|
||||||
|
|
||||||
- Description: Spartan 3
|
- Description: Spartan 3
|
||||||
Model:
|
Model:
|
||||||
- xc3s200
|
- xc3s200
|
||||||
|
|
|
||||||
|
|
@ -401,6 +401,13 @@
|
||||||
Memory: OK
|
Memory: OK
|
||||||
Flash: NA
|
Flash: NA
|
||||||
|
|
||||||
|
- ID: hyvision_opt01
|
||||||
|
Description: HyVision PCIe OPT01 rev.F
|
||||||
|
URL: NA
|
||||||
|
FPGA: Kintex7 xc7k70tfbg676
|
||||||
|
Memory: OK
|
||||||
|
Flash: OK
|
||||||
|
|
||||||
- ID: honeycomb
|
- ID: honeycomb
|
||||||
Description: honeycomb
|
Description: honeycomb
|
||||||
URL: https://github.com/Disasm/honeycomb-pcb
|
URL: https://github.com/Disasm/honeycomb-pcb
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
from edalize.edatool import get_edatool
|
from edalize.edatool import get_edatool
|
||||||
|
|
||||||
|
|
@ -15,6 +16,17 @@ packages = {
|
||||||
"xc7a100t" : ["csg324", "ftg256", "fgg484", "fgg676"],
|
"xc7a100t" : ["csg324", "ftg256", "fgg484", "fgg676"],
|
||||||
"xc7a200t" : ["sbg484", "fbg484", "fbg676", "ffg1156"],
|
"xc7a200t" : ["sbg484", "fbg484", "fbg676", "ffg1156"],
|
||||||
},
|
},
|
||||||
|
# Added but seems not possible to use same bitstream
|
||||||
|
# for all Kintex with the same size but different package.
|
||||||
|
"Kintex 7": {
|
||||||
|
"xc7k70t" : ["fbg484", "fbg676"],
|
||||||
|
"xc7k160t" : ["fbg484", "fbg676", "ffg676"],
|
||||||
|
"xc7k325t" : ["fbg676", "ffg676", "fbg900", "ffg900"],
|
||||||
|
"xc7k355t" : ["ffg901"],
|
||||||
|
"xc7k410t" : ["fbg676", "ffg676", "fbg900", "ffg900"],
|
||||||
|
"xc7k420t" : ["ffg901", "ffg1156"],
|
||||||
|
"xc7k480t" : ["ffg901", "ffg1156"],
|
||||||
|
},
|
||||||
"Spartan 7": {
|
"Spartan 7": {
|
||||||
"xc7s6" : ["ftgb196", "cpga196", "csga225"],
|
"xc7s6" : ["ftgb196", "cpga196", "csga225"],
|
||||||
"xc7s15" : ["ftgb196", "cpga196", "csga225"],
|
"xc7s15" : ["ftgb196", "cpga196", "csga225"],
|
||||||
|
|
@ -43,6 +55,7 @@ currDir = os.path.abspath(os.path.curdir) + '/'
|
||||||
files = []
|
files = []
|
||||||
parameters = {}
|
parameters = {}
|
||||||
pkg_name = None
|
pkg_name = None
|
||||||
|
pkg = None
|
||||||
model = ""
|
model = ""
|
||||||
|
|
||||||
subpart = part[0:4].lower()
|
subpart = part[0:4].lower()
|
||||||
|
|
@ -78,6 +91,7 @@ elif subpart == "xc7k":
|
||||||
family = "Kintex7"
|
family = "Kintex7"
|
||||||
tool = "ise"
|
tool = "ise"
|
||||||
speed = -2
|
speed = -2
|
||||||
|
model = subpart
|
||||||
elif subpart == "xc7s":
|
elif subpart == "xc7s":
|
||||||
family = "Spartan 7"
|
family = "Spartan 7"
|
||||||
tool = "vivado"
|
tool = "vivado"
|
||||||
|
|
@ -104,6 +118,12 @@ else:
|
||||||
if model in ["xc7a", "xc7s"]:
|
if model in ["xc7a", "xc7s"]:
|
||||||
pkg = packages[family][part][0]
|
pkg = packages[family][part][0]
|
||||||
pkg_name = f"{model}_{pkg}"
|
pkg_name = f"{model}_{pkg}"
|
||||||
|
if model in ["xc7k"]:
|
||||||
|
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)
|
||||||
|
|
||||||
if tool in ["ise", "vivado"]:
|
if tool in ["ise", "vivado"]:
|
||||||
pkg_name = {
|
pkg_name = {
|
||||||
|
|
@ -120,12 +140,6 @@ if tool in ["ise", "vivado"]:
|
||||||
"xc6slx150tcsg484" : "xc6s_csg484",
|
"xc6slx150tcsg484" : "xc6s_csg484",
|
||||||
"xc6slx150tfgg484" : "xc6s_t_fgg484",
|
"xc6slx150tfgg484" : "xc6s_t_fgg484",
|
||||||
"xc6vlx130tff784" : "xc6v_ff784",
|
"xc6vlx130tff784" : "xc6v_ff784",
|
||||||
"xc7k70tfbg484" : "xc7k_fbg484",
|
|
||||||
"xc7k70tfbg676" : "xc7k_fbg676",
|
|
||||||
"xc7k160tffg676" : "xc7k_ffg676",
|
|
||||||
"xc7k325tffg676" : "xc7k_ffg676",
|
|
||||||
"xc7k325tffg900" : "xc7k_ffg900",
|
|
||||||
"xc7k420tffg901" : "xc7k_ffg901",
|
|
||||||
"xc7vx330tffg1157" : "xc7v_ffg1157",
|
"xc7vx330tffg1157" : "xc7v_ffg1157",
|
||||||
"xcku040-ffva1156" : "xcku040_ffva1156",
|
"xcku040-ffva1156" : "xcku040_ffva1156",
|
||||||
"xcku060-ffva1156" : "xcku060_ffva1156",
|
"xcku060-ffva1156" : "xcku060_ffva1156",
|
||||||
|
|
@ -152,10 +166,7 @@ if tool in ["ise", "vivado"]:
|
||||||
"xc6slx150tcsg484": "xc6slx150t",
|
"xc6slx150tcsg484": "xc6slx150t",
|
||||||
"xc6slx150tfgg484": "xc6slx150t",
|
"xc6slx150tfgg484": "xc6slx150t",
|
||||||
"xc6vlx130tff784": "xc6vlx130t",
|
"xc6vlx130tff784": "xc6vlx130t",
|
||||||
"xc7k325tffg676": "xc7k325t",
|
}.get(part, model),
|
||||||
"xc7k325tffg900": "xc7k325t",
|
|
||||||
"xc7k420tffg901": "xc7k420t",
|
|
||||||
}[part],
|
|
||||||
'package': {
|
'package': {
|
||||||
"xc3s500evq100": "vq100",
|
"xc3s500evq100": "vq100",
|
||||||
"xc6slx9tqg144": "tqg144",
|
"xc6slx9tqg144": "tqg144",
|
||||||
|
|
@ -170,10 +181,7 @@ if tool in ["ise", "vivado"]:
|
||||||
"xc6slx150tcsg484": "csg484",
|
"xc6slx150tcsg484": "csg484",
|
||||||
"xc6slx150tfgg484": "fgg484",
|
"xc6slx150tfgg484": "fgg484",
|
||||||
"xc6vlx130tff784": "ff784",
|
"xc6vlx130tff784": "ff784",
|
||||||
"xc7k325tffg676": "ffg676",
|
}.get(part, pkg),
|
||||||
"xc7k325tffg900": "ffg900",
|
|
||||||
"xc7k420tffg901": "ffg901",
|
|
||||||
}[part],
|
|
||||||
'speed' : speed
|
'speed' : speed
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
|
|
@ -254,7 +262,7 @@ backend = get_edatool(tool)(edam=edam, work_root=build_dir)
|
||||||
backend.configure()
|
backend.configure()
|
||||||
backend.build()
|
backend.build()
|
||||||
|
|
||||||
if tool == "vivado":
|
if tool in ["vivado", "ise"]:
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import gzip
|
import gzip
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -10,10 +10,14 @@ module spiOverJtag
|
||||||
`ifdef spartan3e
|
`ifdef spartan3e
|
||||||
output wire sck,
|
output wire sck,
|
||||||
`endif
|
`endif
|
||||||
|
`ifdef virtex6
|
||||||
|
output wire sdi_dq0
|
||||||
|
`else
|
||||||
output wire sdi_dq0,
|
output wire sdi_dq0,
|
||||||
input wire sdo_dq1,
|
input wire sdo_dq1,
|
||||||
output wire wpn_dq2,
|
output wire wpn_dq2,
|
||||||
output wire hldn_dq3
|
output wire hldn_dq3
|
||||||
|
`endif
|
||||||
`endif // xilinxultrascale
|
`endif // xilinxultrascale
|
||||||
|
|
||||||
`ifdef secondaryflash
|
`ifdef secondaryflash
|
||||||
|
|
@ -27,11 +31,12 @@ module spiOverJtag
|
||||||
|
|
||||||
wire capture, drck, sel, update, shift;
|
wire capture, drck, sel, update, shift;
|
||||||
wire tdi, tdo;
|
wire tdi, tdo;
|
||||||
wire spi_clk;
|
|
||||||
|
|
||||||
`ifndef spartan3e
|
`ifndef spartan3e
|
||||||
|
`ifndef virtex6
|
||||||
/* Version Interface. */
|
/* Version Interface. */
|
||||||
wire ver_sel, ver_cap, ver_shift, ver_drck, ver_tdi, ver_tdo;
|
wire ver_sel, ver_cap, ver_shift, ver_drck, ver_tdi, ver_tdo;
|
||||||
|
wire spi_clk;
|
||||||
|
|
||||||
spiOverJtag_core spiOverJtag_core_prim (
|
spiOverJtag_core spiOverJtag_core_prim (
|
||||||
/* JTAG state/controls */
|
/* JTAG state/controls */
|
||||||
|
|
@ -59,13 +64,14 @@ module spiOverJtag
|
||||||
.wpn_dq2(wpn_dq2),
|
.wpn_dq2(wpn_dq2),
|
||||||
.hldn_dq3(hldn_dq3)
|
.hldn_dq3(hldn_dq3)
|
||||||
);
|
);
|
||||||
`endif
|
`endif /* !virtex6 */
|
||||||
|
`endif /* !spartan3e */
|
||||||
|
|
||||||
`ifdef spartan6
|
`ifdef spartan6
|
||||||
assign sck = spi_clk;
|
assign sck = spi_clk;
|
||||||
`else // !spartan6
|
`else // !spartan6
|
||||||
`ifdef spartan3e
|
`ifdef spartan3e
|
||||||
assign sck = spi_clk;
|
assign sck = drck;
|
||||||
`else // !spartan6 && !spartan3e
|
`else // !spartan6 && !spartan3e
|
||||||
`ifdef xilinxultrascale
|
`ifdef xilinxultrascale
|
||||||
assign sck = drck;
|
assign sck = drck;
|
||||||
|
|
@ -100,7 +106,52 @@ module spiOverJtag
|
||||||
.USRDONEO (1'b1), // 1-bit input: User DONE pin output control.
|
.USRDONEO (1'b1), // 1-bit input: User DONE pin output control.
|
||||||
.USRDONETS(1'b1) // 1-bit input: User DONE 3-state enable output.
|
.USRDONETS(1'b1) // 1-bit input: User DONE 3-state enable output.
|
||||||
);
|
);
|
||||||
`else // !spartan6 && !spartan3e && !xilinxultrascale
|
`elsif virtex6 // !spartan6 && !spartan3e && !xilinxultrascale
|
||||||
|
wire di;
|
||||||
|
|
||||||
|
wire runtest;
|
||||||
|
reg fsm_csn;
|
||||||
|
// jtag -> spi flash
|
||||||
|
assign sdi_dq0 = tdi;
|
||||||
|
assign tdo = (sel) ? di : tdi;
|
||||||
|
assign csn = fsm_csn;
|
||||||
|
|
||||||
|
wire tmp_cap_s = capture && sel;
|
||||||
|
wire tmp_up_s = update && sel;
|
||||||
|
|
||||||
|
always @(posedge drck, posedge runtest) begin
|
||||||
|
if (runtest) begin
|
||||||
|
fsm_csn <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
if (tmp_cap_s) begin
|
||||||
|
fsm_csn <= 1'b0;
|
||||||
|
end else if (tmp_up_s) begin
|
||||||
|
fsm_csn <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
fsm_csn <= fsm_csn;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
STARTUP_VIRTEX6 #(
|
||||||
|
.PROG_USR("FALSE")
|
||||||
|
) startup_virtex6_inst (
|
||||||
|
.CFGCLK(), // unused
|
||||||
|
.CFGMCLK(), // unused
|
||||||
|
.CLK(1'b0), // unused
|
||||||
|
.DINSPI(di), // data from SPI flash
|
||||||
|
.EOS(),
|
||||||
|
.GSR(1'b0), // unused
|
||||||
|
.GTS(1'b0), // unused
|
||||||
|
.KEYCLEARB(1'b0), // not used
|
||||||
|
.PACK(1'b1), // tied low for 'safe' operations
|
||||||
|
.PREQ(), // unused
|
||||||
|
.TCKSPI(), // echo of CCLK from TCK pin
|
||||||
|
.USRCCLKO (drck), // user FPGA -> CCLK pin
|
||||||
|
.USRCCLKTS(1'b0), // drive CCLK not in high-Z
|
||||||
|
.USRDONEO (1'b1), // why both USRDONE are high?
|
||||||
|
.USRDONETS(1'b1) // ??
|
||||||
|
);
|
||||||
|
`else // !spartan6 && !spartan3e && !xilinxultrascale && !virtex6
|
||||||
STARTUPE2 #(
|
STARTUPE2 #(
|
||||||
.PROG_USR("FALSE"), // Activate program event security feature. Requires encrypted bitstreams.
|
.PROG_USR("FALSE"), // Activate program event security feature. Requires encrypted bitstreams.
|
||||||
.SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency(ns) for simulation.
|
.SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency(ns) for simulation.
|
||||||
|
|
@ -130,7 +181,7 @@ module spiOverJtag
|
||||||
assign hldn_dq3 = 1'b1;
|
assign hldn_dq3 = 1'b1;
|
||||||
// jtag -> spi flash
|
// jtag -> spi flash
|
||||||
assign sdi_dq0 = tdi;
|
assign sdi_dq0 = tdi;
|
||||||
wire tdo = (sel) ? sdo_dq1 : tdi;
|
assign tdo = (sel) ? sdo_dq1 : tdi;
|
||||||
assign csn = fsm_csn;
|
assign csn = fsm_csn;
|
||||||
|
|
||||||
wire tmp_cap_s = capture && sel;
|
wire tmp_cap_s = capture && sel;
|
||||||
|
|
@ -169,7 +220,9 @@ module spiOverJtag
|
||||||
.TDO2 () // 1-bit input: USER2 function
|
.TDO2 () // 1-bit input: USER2 function
|
||||||
);
|
);
|
||||||
`else
|
`else
|
||||||
`ifdef spartan6
|
`ifdef virtex6
|
||||||
|
BSCAN_VIRTEX6 #(
|
||||||
|
`elsif spartan6
|
||||||
BSCAN_SPARTAN6 #(
|
BSCAN_SPARTAN6 #(
|
||||||
`else
|
`else
|
||||||
BSCANE2 #(
|
BSCANE2 #(
|
||||||
|
|
@ -181,8 +234,12 @@ module spiOverJtag
|
||||||
// is asserted, DRCK toggles when
|
// is asserted, DRCK toggles when
|
||||||
// CAPTURE or SHIFT are asserted.
|
// CAPTURE or SHIFT are asserted.
|
||||||
.RESET (), // 1-bit output: Reset output for TAP controller.
|
.RESET (), // 1-bit output: Reset output for TAP controller.
|
||||||
|
`ifdef virtex6
|
||||||
|
.RUNTEST(runtest),
|
||||||
|
`else
|
||||||
.RUNTEST(), // 1-bit output: Output asserted when TAP
|
.RUNTEST(), // 1-bit output: Output asserted when TAP
|
||||||
// controller is in Run Test/Idle state.
|
// controller is in Run Test/Idle state.
|
||||||
|
`endif
|
||||||
.SEL (sel), // 1-bit output: USER instruction active output.
|
.SEL (sel), // 1-bit output: USER instruction active output.
|
||||||
.SHIFT (shift), // 1-bit output: SHIFT output from TAP controller.
|
.SHIFT (shift), // 1-bit output: SHIFT output from TAP controller.
|
||||||
.TCK (), // 1-bit output: Test Clock output.
|
.TCK (), // 1-bit output: Test Clock output.
|
||||||
|
|
@ -197,6 +254,7 @@ module spiOverJtag
|
||||||
);
|
);
|
||||||
|
|
||||||
/* BSCAN for Version Interface. */
|
/* BSCAN for Version Interface. */
|
||||||
|
`ifndef virtex6
|
||||||
`ifdef spartan6
|
`ifdef spartan6
|
||||||
BSCAN_SPARTAN6 #(
|
BSCAN_SPARTAN6 #(
|
||||||
`else
|
`else
|
||||||
|
|
@ -217,6 +275,7 @@ module spiOverJtag
|
||||||
.TDO (ver_tdo)
|
.TDO (ver_tdo)
|
||||||
);
|
);
|
||||||
`endif
|
`endif
|
||||||
|
`endif /* !virtex6 */
|
||||||
|
|
||||||
`ifdef secondaryflash
|
`ifdef secondaryflash
|
||||||
wire drck_sec;
|
wire drck_sec;
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,7 @@ static std::map <std::string, target_board_t> board_list = {
|
||||||
JTAG_BOARD("genesys2", "xc7k325tffg900", "digilent_b", 0, 0, CABLE_DEFAULT),
|
JTAG_BOARD("genesys2", "xc7k325tffg900", "digilent_b", 0, 0, CABLE_DEFAULT),
|
||||||
JTAG_BOARD("gr740-mini", "", "ft4232hp_b", 0, 0, CABLE_MHZ(1)),
|
JTAG_BOARD("gr740-mini", "", "ft4232hp_b", 0, 0, CABLE_MHZ(1)),
|
||||||
JTAG_BOARD("hseda-xc6slx16", "xc6slx16ftg256", "", 0, 0, CABLE_DEFAULT),
|
JTAG_BOARD("hseda-xc6slx16", "xc6slx16ftg256", "", 0, 0, CABLE_DEFAULT),
|
||||||
|
JTAG_BOARD("hyvision_opt01", "xc7k70tfbg676", "", 0, 0, CABLE_DEFAULT),
|
||||||
/* most ice40 boards uses the same pinout */
|
/* most ice40 boards uses the same pinout */
|
||||||
SPI_BOARD("ice40_generic", "lattice", "ice40", "ft2232",
|
SPI_BOARD("ice40_generic", "lattice", "ice40", "ft2232",
|
||||||
DBUS7, DBUS6, 0,
|
DBUS7, DBUS6, 0,
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,11 @@ class ConfigBitstreamParser {
|
||||||
const uint8_t *getData() const {return _bit_data.data();}
|
const uint8_t *getData() const {return _bit_data.data();}
|
||||||
int getLength() {return _bit_length;}
|
int getLength() {return _bit_length;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief return bitstream file name
|
||||||
|
*/
|
||||||
|
std::string getFilename() const {return _filename;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief display header informations
|
* \brief display header informations
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,9 @@ static std::map <uint32_t, fpga_model> fpga_list = {
|
||||||
{0x04b31093, {"xilinx", "virtexusp", "xcvu9p", 18}},
|
{0x04b31093, {"xilinx", "virtexusp", "xcvu9p", 18}},
|
||||||
{0x14b79093, {"xilinx", "virtexusp", "xcvu37p", 18}},
|
{0x14b79093, {"xilinx", "virtexusp", "xcvu37p", 18}},
|
||||||
|
|
||||||
|
/* Xilinx Ultrascale+ / Spartan */
|
||||||
|
{0x04e80093, {"xilinx", "spartanusp", "xcsu35p", 6}},
|
||||||
|
|
||||||
/* Xilinx Ultrascale+ / ZynqMP */
|
/* Xilinx Ultrascale+ / ZynqMP */
|
||||||
/* When powering a zynq ultrascale+ MPSoC, PL Tap and ARM dap
|
/* When powering a zynq ultrascale+ MPSoC, PL Tap and ARM dap
|
||||||
* are disabled and only PS tap with a specific IDCODE is seen.
|
* are disabled and only PS tap with a specific IDCODE is seen.
|
||||||
|
|
@ -301,6 +304,7 @@ static std::map <uint32_t, fpga_model> fpga_list = {
|
||||||
|
|
||||||
/* Lattice ECP3 */
|
/* Lattice ECP3 */
|
||||||
{0x01014043, {"lattice", "ECP3", "LFE3-70E", 8}},
|
{0x01014043, {"lattice", "ECP3", "LFE3-70E", 8}},
|
||||||
|
{0x01015043, {"lattice", "ECP3", "LFE3-150EA", 8}},
|
||||||
|
|
||||||
/* Lattice ECP5 */
|
/* Lattice ECP5 */
|
||||||
{0x21111043, {"lattice", "ECP5", "LFE5U-12", 8}},
|
{0x21111043, {"lattice", "ECP5", "LFE5U-12", 8}},
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,8 @@ SPIInterface::SPIInterface(const std::string &filename, int8_t verbose,
|
||||||
bool SPIInterface::detect_flash()
|
bool SPIInterface::detect_flash()
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
printInfo("protect_flash: ", false);
|
|
||||||
|
printInfo("Detect flash:");
|
||||||
|
|
||||||
/* move device to spi access */
|
/* move device to spi access */
|
||||||
if (!prepare_flash_access()) {
|
if (!prepare_flash_access()) {
|
||||||
|
|
@ -55,7 +56,7 @@ bool SPIInterface::detect_flash()
|
||||||
bool SPIInterface::protect_flash(uint32_t len)
|
bool SPIInterface::protect_flash(uint32_t len)
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
printInfo("protect_flash: ", false);
|
printInfo("protect_flash:");
|
||||||
|
|
||||||
/* move device to spi access */
|
/* move device to spi access */
|
||||||
if (!prepare_flash_access()) {
|
if (!prepare_flash_access()) {
|
||||||
|
|
@ -98,7 +99,7 @@ bool SPIInterface::unprotect_flash()
|
||||||
SPIFlash flash(this, false, _spif_verbose);
|
SPIFlash flash(this, false, _spif_verbose);
|
||||||
|
|
||||||
/* configure flash protection */
|
/* configure flash protection */
|
||||||
printInfo("unprotect_flash: ", false);
|
printInfo("unprotect_flash:");
|
||||||
ret = (flash.disable_protection() == 0);
|
ret = (flash.disable_protection() == 0);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
printError("Fail");
|
printError("Fail");
|
||||||
|
|
@ -129,7 +130,7 @@ bool SPIInterface::set_quad_bit(bool set_quad)
|
||||||
SPIFlash flash(this, false, _spif_verbose);
|
SPIFlash flash(this, false, _spif_verbose);
|
||||||
|
|
||||||
/* configure flash protection */
|
/* configure flash protection */
|
||||||
printInfo("set_quad_bit: ", false);
|
printInfo("set_quad_bit:");
|
||||||
ret = flash.set_quad_bit(set_quad);
|
ret = flash.set_quad_bit(set_quad);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
printError("Fail");
|
printError("Fail");
|
||||||
|
|
@ -148,7 +149,7 @@ bool SPIInterface::set_quad_bit(bool set_quad)
|
||||||
bool SPIInterface::bulk_erase_flash()
|
bool SPIInterface::bulk_erase_flash()
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
printInfo("bulk_erase: ", false);
|
printInfo("bulk_erase:");
|
||||||
|
|
||||||
/* move device to spi access */
|
/* move device to spi access */
|
||||||
if (!prepare_flash_access()) {
|
if (!prepare_flash_access()) {
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,7 @@ static std::map<std::string, std::map<std::string, std::vector<uint8_t>>>
|
||||||
{ "JSHUTDOWN", {0x0D} },
|
{ "JSHUTDOWN", {0x0D} },
|
||||||
{ "ISC_PROGRAM", {0x11} },
|
{ "ISC_PROGRAM", {0x11} },
|
||||||
{ "ISC_DISABLE", {0x16} },
|
{ "ISC_DISABLE", {0x16} },
|
||||||
|
{ "STATUS", {0x1F} },
|
||||||
{ "BYPASS", {0xff} },
|
{ "BYPASS", {0xff} },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -294,6 +295,8 @@ Xilinx::Xilinx(Jtag *jtag, const std::string &filename,
|
||||||
_mode = Device::SPI_MODE;
|
_mode = Device::SPI_MODE;
|
||||||
} else if (_file_extension == "jed") {
|
} else if (_file_extension == "jed") {
|
||||||
_mode = Device::FLASH_MODE;
|
_mode = Device::FLASH_MODE;
|
||||||
|
} else if (_file_extension == "pdi") {
|
||||||
|
_mode = Device::MEM_MODE;
|
||||||
} else {
|
} else {
|
||||||
_mode = Device::SPI_MODE;
|
_mode = Device::SPI_MODE;
|
||||||
}
|
}
|
||||||
|
|
@ -358,6 +361,14 @@ Xilinx::Xilinx(Jtag *jtag, const std::string &filename,
|
||||||
_fpga_family = KINTEXUSP_FAMILY;
|
_fpga_family = KINTEXUSP_FAMILY;
|
||||||
} else if (family == "artixusp") {
|
} else if (family == "artixusp") {
|
||||||
_fpga_family = ARTIXUSP_FAMILY;
|
_fpga_family = ARTIXUSP_FAMILY;
|
||||||
|
} else if (family == "spartanusp") {
|
||||||
|
if (_file_extension != "pdi") {
|
||||||
|
char mess[256];
|
||||||
|
snprintf(mess, 256, "Error: only volatile PDI programing for "
|
||||||
|
"Spartan Ultrascale+ devices\n");
|
||||||
|
throw std::runtime_error(mess);
|
||||||
|
}
|
||||||
|
_fpga_family = SPARTANUSP_FAMILY;
|
||||||
} else if (family == "virtexus") {
|
} else if (family == "virtexus") {
|
||||||
_fpga_family = VIRTEXUS_FAMILY;
|
_fpga_family = VIRTEXUS_FAMILY;
|
||||||
} else if (family == "virtexusp") {
|
} else if (family == "virtexusp") {
|
||||||
|
|
@ -365,9 +376,6 @@ Xilinx::Xilinx(Jtag *jtag, const std::string &filename,
|
||||||
_ircode_map = ircode_mapping.at("virtexusp");
|
_ircode_map = ircode_mapping.at("virtexusp");
|
||||||
} else if (family.substr(0, 8) == "spartan3") {
|
} else if (family.substr(0, 8) == "spartan3") {
|
||||||
_fpga_family = SPARTAN3_FAMILY;
|
_fpga_family = SPARTAN3_FAMILY;
|
||||||
if (_mode != Device::MEM_MODE) {
|
|
||||||
throw std::runtime_error("Error: Only load to mem is supported");
|
|
||||||
}
|
|
||||||
} else if (family == "xcf") {
|
} else if (family == "xcf") {
|
||||||
_fpga_family = XCF_FAMILY;
|
_fpga_family = XCF_FAMILY;
|
||||||
if (_mode == Device::MEM_MODE) {
|
if (_mode == Device::MEM_MODE) {
|
||||||
|
|
@ -612,6 +620,9 @@ void Xilinx::program(unsigned int offset, bool unprotect_flash)
|
||||||
if (_mode == Device::MEM_MODE || _fpga_family == XCF_FAMILY)
|
if (_mode == Device::MEM_MODE || _fpga_family == XCF_FAMILY)
|
||||||
reverse = true;
|
reverse = true;
|
||||||
|
|
||||||
|
if (_file_extension == "pdi")
|
||||||
|
reverse = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (_flash_chips & PRIMARY_FLASH) {
|
if (_flash_chips & PRIMARY_FLASH) {
|
||||||
open_bitfile(_filename, _file_extension, &bit, reverse, _verbose);
|
open_bitfile(_filename, _file_extension, &bit, reverse, _verbose);
|
||||||
|
|
@ -715,11 +726,11 @@ bool Xilinx::load_bridge()
|
||||||
bitname = PathHelper::absolutePath(bitname);
|
bitname = PathHelper::absolutePath(bitname);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::cout << "use: " << bitname << std::endl;
|
|
||||||
|
|
||||||
/* first: load spi over jtag */
|
/* first: load spi over jtag */
|
||||||
try {
|
try {
|
||||||
BitParser bridge(bitname, true, _verbose);
|
BitParser bridge(bitname, true, _verbose);
|
||||||
|
printSuccess("Use: " + bridge.getFilename());
|
||||||
|
|
||||||
bridge.parse();
|
bridge.parse();
|
||||||
if (_fpga_family == SPARTAN3_FAMILY)
|
if (_fpga_family == SPARTAN3_FAMILY)
|
||||||
xc3s_flow_program(&bridge);
|
xc3s_flow_program(&bridge);
|
||||||
|
|
@ -852,6 +863,24 @@ void Xilinx::program_mem(ConfigBitstreamParser *bitfile)
|
||||||
* 16: Move into RTI state. X 0 1
|
* 16: Move into RTI state. X 0 1
|
||||||
*/
|
*/
|
||||||
_jtag->set_state(Jtag::RUN_TEST_IDLE);
|
_jtag->set_state(Jtag::RUN_TEST_IDLE);
|
||||||
|
|
||||||
|
if (_file_extension == "pdi") {
|
||||||
|
_jtag->toggleClk(2000);
|
||||||
|
/*
|
||||||
|
* 17: For PDI devices, use the STATUS instruction
|
||||||
|
* to verify successful configuration.
|
||||||
|
*/
|
||||||
|
unsigned char tx_data[6]= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
unsigned char rx_data[6];
|
||||||
|
_jtag->shiftIR(get_ircode(_ircode_map, "STATUS"), NULL, _irlen);
|
||||||
|
_jtag->shiftDR(tx_data, rx_data, 48);
|
||||||
|
if ((rx_data[4] & 0x04) != 0x04) {
|
||||||
|
printError("PDI programing failed");
|
||||||
|
} else {
|
||||||
|
printSuccess("PDI programing success");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
/*
|
/*
|
||||||
* 17: Enter the SELECT-IR state. X 1 2
|
* 17: Enter the SELECT-IR state. X 1 2
|
||||||
* 18: Move to the SHIFT-IR state. X 0 2
|
* 18: Move to the SHIFT-IR state. X 0 2
|
||||||
|
|
@ -889,6 +918,7 @@ void Xilinx::program_mem(ConfigBitstreamParser *bitfile)
|
||||||
read_register("STAT");
|
read_register("STAT");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t char_array_to_word(uint8_t *in)
|
static uint32_t char_array_to_word(uint8_t *in)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,7 @@ class Xilinx: public Device, SPIInterface {
|
||||||
ZYNQMP_FAMILY,
|
ZYNQMP_FAMILY,
|
||||||
XCF_FAMILY,
|
XCF_FAMILY,
|
||||||
ARTIXUSP_FAMILY,
|
ARTIXUSP_FAMILY,
|
||||||
|
SPARTANUSP_FAMILY,
|
||||||
VIRTEXUS_FAMILY,
|
VIRTEXUS_FAMILY,
|
||||||
VIRTEXUSP_FAMILY,
|
VIRTEXUSP_FAMILY,
|
||||||
UNKNOWN_FAMILY = 999
|
UNKNOWN_FAMILY = 999
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue