Merge pull request #543 from trabucayre/spiOverJtag_v2

SpiOverJtag v2
This commit is contained in:
Gwenhael Goavec-Merou 2025-05-29 08:41:10 +02:00 committed by GitHub
commit 5f6c1bfcd4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
92 changed files with 721 additions and 217 deletions

View File

@ -1,3 +1,6 @@
tmp_*
*.bit
*.rbf
vivado*.jou
vivado*.log
.Xil

View File

@ -3,13 +3,8 @@ XILINX_PARTS := xc3s500evq100 \
xc6slx16ftg256 xc6slx16csg324 xc6slx25csg324 xc6slx45csg324 xc6slx100fgg484 \
xc6slx25tcsg324 xc6slx45tfgg484 xc6slx150tfgg484 xc6slx150tcsg484 \
xc6vlx130tff784 \
xc7a15tcpg236 xc7a15tfgg484 \
xc7a25tcpg238 xc7a25tcsg325 \
xc7a35tcpg236 xc7a35tcsg324 xc7a35tftg256 xc7a35tfgg484 \
xc7a50tcsg324 xc7a50tfgg484 xc7a50tcpg236 xc7a50tcsg325 xc7a75tfgg484 \
xc7a100tcsg324 xc7a100tfgg484 xc7a100tfgg676\
xc7a200tsbg484 xc7a200tfbg484 xc7a200tfbg676\
xc7s6ftgb196 xc7s25csga225 xc7s25csga324 xc7s50csga324 \
xc7a12t xc7a15t xc7a25t xc7a35t xc7a50t xc7a75t xc7a100t xc7a200t \
xc7s6 xc7s15 xc7s25 xc7s50 xc7s75 xc7s100 \
xc7k70tfbg484 xc7k70tfbg676 \
xc7k160tffg676 \
xc7k325tffg676 xc7k325tffg900 \
@ -19,7 +14,7 @@ XILINX_PARTS := xc3s500evq100 \
xcku040-ffva1156 xcku060-ffva1156 \
xcku5p-ffvb676 \
xcvu9p-flga2104 xcvu37p-fsvh2892 \
xcau15p-ffvb676
xcau15p-ffvb676
XILINX_BIT_FILES := $(addsuffix .bit.gz,$(addprefix spiOverJtag_, $(XILINX_PARTS)))
ALTERA_PARTS := 10cl025256 10cl016484 10cl055484 \
@ -39,8 +34,8 @@ tmp_efinix_%/efinix_spiOverJtag.bit : efinix_spiOverJtag.v
./efinix_build.py --device $*
$(XILINX_BIT_FILES) : spiOverJtag_%.bit.gz : tmp_%/spiOverJtag.bit
gzip -9 -c $< > $@
tmp_%/spiOverJtag.bit : xilinx_spiOverJtag.v
tmp_%/spiOverJtag.bit : xilinx_spiOverJtag.v spiOverJtag_core.v
./build.py $*
$(ALTERA_BIT_FILES): spiOverJtag_%.rbf.gz: tmp_%/spiOverJtag.rbf

View File

@ -1,7 +1,30 @@
#!/usr/bin/env python3
from edalize.edatool import get_edatool
import os
from edalize.edatool import get_edatool
packages = {
"Artix": {
"xc7a12t" : ["cpg238", "csg325"],
"xc7a15t" : ["cpg236", "csg324", "csg325", "ftg256", "fgg484"],
"xc7a25t" : ["cpg238", "csg325"],
"xc7a35t" : ["cpg236", "csg324", "csg325", "ftg256", "fgg484"],
"xc7a50t" : ["cpg236", "csg324", "csg325", "ftg256", "fgg484"],
"xc7a75t" : ["csg324", "ftg256", "fgg484", "fgg676"],
"xc7a100t" : ["csg324", "ftg256", "fgg484", "fgg676"],
"xc7a200t" : ["sbg484", "fbg484", "fbg676", "ffg1156"],
},
"Spartan 7": {
"xc7s6" : ["ftgb196", "cpga196", "csga225"],
"xc7s15" : ["ftgb196", "cpga196", "csga225"],
"xc7s25" : ["ftgb196", "csga225", "csga324"],
"xc7s50" : ["ftgb196", "csga324", "fgga484"],
"xc7s75" : ["fgga484", "fgga676"],
"xc7s100" : ["fgga484", "fgga676"],
},
}
if len(os.sys.argv) != 2:
print("missing board param")
os.sys.exit()
@ -16,9 +39,10 @@ if not os.path.isdir(build_dir):
else:
print ("Successfully created the directory %s " % build_dir)
currDir = os.path.abspath(os.path.curdir) + '/'
files = []
currDir = os.path.abspath(os.path.curdir) + '/'
files = []
parameters = {}
pkg_name = None
subpart = part[0:4].lower()
if subpart == '10cl':
@ -39,7 +63,8 @@ elif subpart[0:2] == '5s':
'file_type': 'tclSource'})
elif subpart == "xc7a":
family = "Artix"
tool = "vivado"
tool = "vivado"
model = subpart
elif subpart == "xc7v":
family = "Virtex 7"
tool = "vivado"
@ -54,7 +79,8 @@ elif subpart == "xc7k":
speed = -2
elif subpart == "xc7s":
family = "Spartan 7"
tool = "vivado"
tool = "vivado"
model = subpart
elif subpart == "xc6s":
family = "Spartan6"
tool = "ise"
@ -74,6 +100,10 @@ else:
print("Error: unknown device")
os.sys.exit()
if model in ["xc7a", "xc7s"]:
pkg = packages[family][part][0]
pkg_name = f"{model}_{pkg}"
if tool in ["ise", "vivado"]:
pkg_name = {
"xc3s500evq100" : "xc3s_vq100",
@ -89,25 +119,6 @@ if tool in ["ise", "vivado"]:
"xc6slx150tcsg484" : "xc6s_csg484",
"xc6slx150tfgg484" : "xc6s_t_fgg484",
"xc6vlx130tff784" : "xc6v_ff784",
"xc7a15tcpg236" : "xc7a_cpg236",
"xc7a15tfgg484" : "xc7a_fgg484",
"xc7a25tcpg238" : "xc7a_cpg238",
"xc7a25tcsg325" : "xc7a_csg325",
"xc7a35tcpg236" : "xc7a_cpg236",
"xc7a35tcsg324" : "xc7a_csg324",
"xc7a35tftg256" : "xc7a_ftg256",
"xc7a35tfgg484" : "xc7a_fgg484",
"xc7a50tcpg236" : "xc7a_cpg236",
"xc7a50tcsg324" : "xc7a_csg324",
"xc7a50tfgg484" : "xc7a_fgg484",
"xc7a50tcsg325" : "xc7a_csg325",
"xc7a75tfgg484" : "xc7a_fgg484",
"xc7a100tcsg324" : "xc7a_csg324",
"xc7a100tfgg484" : "xc7a_fgg484",
"xc7a100tfgg676" : "xc7a_fgg676",
"xc7a200tsbg484" : "xc7a_sbg484",
"xc7a200tfbg484" : "xc7a_fbg484",
"xc7a200tfbg676" : "xc7a_fbg676",
"xc7k70tfbg484" : "xc7k_fbg484",
"xc7k70tfbg676" : "xc7k_fbg676",
"xc7k160tffg676" : "xc7k_ffg676",
@ -115,11 +126,6 @@ if tool in ["ise", "vivado"]:
"xc7k325tffg900" : "xc7k_ffg900",
"xc7k420tffg901" : "xc7k_ffg901",
"xc7vx330tffg1157" : "xc7v_ffg1157",
"xc7s6ftgb196" : "xc7s_ftgb196",
"xc7s25csga225" : "xc7s_csga225",
"xc7s25csga324" : "xc7s_csga324",
"xc7s50csga324" : "xc7s_csga324",
"xc7s75fgga676" : "xc7s_fgga676",
"xcku040-ffva1156" : "xcku040_ffva1156",
"xcku060-ffva1156" : "xcku060_ffva1156",
"xcvu9p-flga2104" : "xcvu9p_flga2104",
@ -127,7 +133,7 @@ if tool in ["ise", "vivado"]:
"xcku3p-ffva676" : "xcku3p_ffva676",
"xcku5p-ffvb676" : "xcku5p_ffvb676",
"xcau15p-ffvb676" : "xcau15p_ffvb676",
}[part]
}.get(part, pkg_name)
if tool == "ise":
cst_type = "UCF"
tool_options = {'family': family,
@ -171,7 +177,10 @@ if tool in ["ise", "vivado"]:
}
else:
cst_type = "xdc"
if family == "Xilinx UltraScale":
# Artix/Spartan 7 Specific use case:
if family in ["Artix", "Spartan 7"]:
tool_options = {'part': f"{part}{pkg}-1"}
elif family == "Xilinx UltraScale":
if part in ["xcvu9p-flga2104", "xcku5p-ffvb676"]:
tool_options = {'part': part + '-1-e'}
parameters["secondaryflash"]= {
@ -194,6 +203,7 @@ if tool in ["ise", "vivado"]:
tool_options = {'part': part + '-2-e'}
else:
tool_options = {'part': part + '-1'}
cst_file = currDir + "constr_" + pkg_name + "." + cst_type.lower()
files.append({'name': currDir + 'xilinx_spiOverJtag.v',
'file_type': 'verilogSource'})
@ -223,6 +233,9 @@ else:
'file_type': 'SDC'})
tool_options = {'device': full_part, 'family':family}
files.append({'name': currDir + 'spiOverJtag_core.v',
'file_type': 'verilogSource'})
parameters[family.lower().replace(' ', '')]= {
'datatype': 'int',
'paramtype': 'vlogdefine',
@ -242,5 +255,18 @@ backend.build()
if tool == "vivado":
import shutil
shutil.copy("tmp_" + part + "/spiOverJtag.runs/impl_1/spiOverJtag.bit",
"tmp_" + part);
import subprocess
import gzip
# Compress bitstream.
with open(f"tmp_{part}/spiOverJtag.bit", 'rb') as bit:
with gzip.open(f"spiOverJtag_{part}.bit.gz", 'wb', compresslevel=9) as bit_gz:
shutil.copyfileobj(bit, bit_gz)
# Create Symbolic links for all supported packages.
if family in ["Artix", "Spartan 7"]:
in_file = f"spiOverJtag_{part}.bit.gz"
for pkg in packages[family][part]:
out_file = f"spiOverJtag_{part}{pkg}.bit.gz"
if not os.path.exists(out_file):
subprocess.run(["ln", "-s", in_file, out_file])

View File

@ -2,9 +2,12 @@ set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH {4} [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property -dict {PACKAGE_PIN K19 IOSTANDARD LVCMOS33} [get_ports {csn}];
set_property -dict {PACKAGE_PIN D18 IOSTANDARD LVCMOS33} [get_ports {sdi_dq0}];
set_property -dict {PACKAGE_PIN D19 IOSTANDARD LVCMOS33} [get_ports {sdo_dq1}];
set_property -dict {PACKAGE_PIN G18 IOSTANDARD LVCMOS33} [get_ports {wpn_dq2}];
set_property -dict {PACKAGE_PIN F18 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}];
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK}]
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK}]

View File

@ -9,3 +9,5 @@ set_property -dict {PACKAGE_PIN D19 IOSTANDARD LVCMOS33} [get_ports {sdo_dq1}];
set_property -dict {PACKAGE_PIN E19 IOSTANDARD LVCMOS33} [get_ports {wpn_dq2}];
set_property -dict {PACKAGE_PIN F19 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}];
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK}]
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK}]

View File

@ -8,3 +8,6 @@ set_property -dict {PACKAGE_PIN K17 IOSTANDARD LVCMOS33} [get_ports {sdi_dq0}];
set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports {sdo_dq1}];
set_property -dict {PACKAGE_PIN L14 IOSTANDARD LVCMOS33} [get_ports {wpn_dq2}];
set_property -dict {PACKAGE_PIN M14 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}];
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK}]
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK}]

View File

@ -9,3 +9,5 @@ set_property -dict {PACKAGE_PIN L17 IOSTANDARD LVCMOS33} [get_ports {sdo_dq1}];
set_property -dict {PACKAGE_PIN J15 IOSTANDARD LVCMOS33} [get_ports {wpn_dq2}];
set_property -dict {PACKAGE_PIN J16 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}];
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK]}}
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK]}}

View File

@ -1,23 +1,24 @@
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 16 [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property CFGBVS GND [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR NO [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.M1PIN PULLNONE [current_design]
set_property BITSTREAM.CONFIG.M2PIN PULLNONE [current_design]
set_property BITSTREAM.CONFIG.M0PIN PULLNONE [current_design]
set_property BITSTREAM.CONFIG.USR_ACCESS TIMESTAMP [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLDOWN [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPPOWERDOWN ENABLE [current_design]
set_property -dict {PACKAGE_PIN L15 IOSTANDARD SSTL135_R} [get_ports csn]
set_property -dict {PACKAGE_PIN K16 IOSTANDARD SSTL135_R} [get_ports sdi_dq0]
set_property -dict {PACKAGE_PIN L17 IOSTANDARD SSTL135_R} [get_ports sdo_dq1]
set_property -dict {PACKAGE_PIN J15 IOSTANDARD SSTL135_R} [get_ports wpn_dq2]
set_property -dict {PACKAGE_PIN J16 IOSTANDARD SSTL135_R} [get_ports hldn_dq3]
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 16 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR NO [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.M1PIN PULLNONE [current_design]
set_property BITSTREAM.CONFIG.M2PIN PULLNONE [current_design]
set_property BITSTREAM.CONFIG.M0PIN PULLNONE [current_design]
set_property BITSTREAM.CONFIG.USR_ACCESS TIMESTAMP [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLDOWN [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPPOWERDOWN ENABLE [current_design]
set_property -dict {PACKAGE_PIN L15 IOSTANDARD SSTL135_R} [get_ports csn]
set_property -dict {PACKAGE_PIN K16 IOSTANDARD SSTL135_R} [get_ports sdi_dq0]
set_property -dict {PACKAGE_PIN L17 IOSTANDARD SSTL135_R} [get_ports sdo_dq1]
set_property -dict {PACKAGE_PIN J15 IOSTANDARD SSTL135_R} [get_ports wpn_dq2]
set_property -dict {PACKAGE_PIN J16 IOSTANDARD SSTL135_R} [get_ports hldn_dq3]
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK]}}
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK]}}

View File

@ -9,3 +9,5 @@ set_property -dict {PACKAGE_PIN R22 IOSTANDARD LVTTL} [get_ports {sdo_dq1}]
set_property -dict {PACKAGE_PIN P21 IOSTANDARD LVTTL} [get_ports {wpn_dq2}]
set_property -dict {PACKAGE_PIN R21 IOSTANDARD LVTTL} [get_ports {hldn_dq3}]
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK}]
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK}]

View File

@ -8,3 +8,6 @@ set_property -dict {PACKAGE_PIN R14 IOSTANDARD LVTTL} [get_ports {sdi_dq0}]
set_property -dict {PACKAGE_PIN R15 IOSTANDARD LVTTL} [get_ports {sdo_dq1}]
set_property -dict {PACKAGE_PIN P14 IOSTANDARD LVTTL} [get_ports {wpn_dq2}]
set_property -dict {PACKAGE_PIN N14 IOSTANDARD LVTTL} [get_ports {hldn_dq3}]
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK}]
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK}]

View File

@ -1,6 +1,7 @@
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH {4} [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property -dict {PACKAGE_PIN T19 IOSTANDARD LVTTL} [get_ports {csn}]
set_property -dict {PACKAGE_PIN P22 IOSTANDARD LVTTL} [get_ports {sdi_dq0}]
@ -8,3 +9,5 @@ set_property -dict {PACKAGE_PIN R22 IOSTANDARD LVTTL} [get_ports {sdo_dq1}]
set_property -dict {PACKAGE_PIN P21 IOSTANDARD LVTTL} [get_ports {wpn_dq2}]
set_property -dict {PACKAGE_PIN R21 IOSTANDARD LVTTL} [get_ports {hldn_dq3}]
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK}]
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK}]

View File

@ -3,9 +3,11 @@ set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH {4} [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property -dict {PACKAGE_PIN T19 IOSTANDARD LVTTL} [get_ports {csn}]
set_property -dict {PACKAGE_PIN P18 IOSTANDARD LVTTL} [get_ports {csn}]
set_property -dict {PACKAGE_PIN R14 IOSTANDARD LVTTL} [get_ports {sdi_dq0}]
set_property -dict {PACKAGE_PIN R15 IOSTANDARD LVTTL} [get_ports {sdo_dq1}]
set_property -dict {PACKAGE_PIN P14 IOSTANDARD LVTTL} [get_ports {wpn_dq2}]
set_property -dict {PACKAGE_PIN P18 IOSTANDARD LVTTL} [get_ports {hldn_dq3}]
set_property -dict {PACKAGE_PIN N14 IOSTANDARD LVTTL} [get_ports {hldn_dq3}]
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK}]
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK}]

View File

@ -8,3 +8,6 @@ set_property -dict {PACKAGE_PIN J13 IOSTANDARD LVCMOS33} [get_ports {sdi_dq0}];
set_property -dict {PACKAGE_PIN J14 IOSTANDARD LVCMOS33} [get_ports {sdo_dq1}];
set_property -dict {PACKAGE_PIN K15 IOSTANDARD LVCMOS33} [get_ports {wpn_dq2}];
set_property -dict {PACKAGE_PIN K16 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}];
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK}]
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK}]

View File

@ -6,4 +6,7 @@ set_property -dict {PACKAGE_PIN T19 IOSTANDARD LVCMOS33} [get_ports {csn}]
set_property -dict {PACKAGE_PIN P22 IOSTANDARD LVCMOS33} [get_ports {sdi_dq0}]
set_property -dict {PACKAGE_PIN R22 IOSTANDARD LVCMOS33} [get_ports {sdo_dq1}]
set_property -dict {PACKAGE_PIN P21 IOSTANDARD LVCMOS33} [get_ports {wpn_dq2}]
set_property -dict {PACKAGE_PIN R21 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}]
set_property -dict {PACKAGE_PIN R21 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}]
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK]}}
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK]}}

View File

@ -0,0 +1,13 @@
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH {4} [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property -dict {PACKAGE_PIN T19 IOSTANDARD LVTTL} [get_ports {csn}]
set_property -dict {PACKAGE_PIN P22 IOSTANDARD LVTTL} [get_ports {sdi_dq0}]
set_property -dict {PACKAGE_PIN R22 IOSTANDARD LVTTL} [get_ports {sdo_dq1}]
set_property -dict {PACKAGE_PIN P21 IOSTANDARD LVTTL} [get_ports {wpn_dq2}]
set_property -dict {PACKAGE_PIN R21 IOSTANDARD LVTTL} [get_ports {hldn_dq3}]
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK]}}
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK]}}

View File

@ -0,0 +1,13 @@
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH {4} [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property -dict {PACKAGE_PIN D13 IOSTANDARD LVCMOS33} [get_ports {csn}];
set_property -dict {PACKAGE_PIN C10 IOSTANDARD LVCMOS33} [get_ports {sdi_dq0}];
set_property -dict {PACKAGE_PIN C11 IOSTANDARD LVCMOS33} [get_ports {sdo_dq1}];
set_property -dict {PACKAGE_PIN B11 IOSTANDARD LVCMOS33} [get_ports {wpn_dq2}];
set_property -dict {PACKAGE_PIN A12 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}];
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK]}}
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK]}}

View File

@ -8,3 +8,6 @@ set_property -dict {PACKAGE_PIN H14 IOSTANDARD LVCMOS33} [get_ports {sdi_dq0}];
set_property -dict {PACKAGE_PIN H15 IOSTANDARD LVCMOS33} [get_ports {sdo_dq1}];
set_property -dict {PACKAGE_PIN J12 IOSTANDARD LVCMOS33} [get_ports {wpn_dq2}];
set_property -dict {PACKAGE_PIN K13 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}];
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK]}}
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK]}}

View File

@ -8,3 +8,6 @@ set_property -dict {PACKAGE_PIN K17 IOSTANDARD LVCMOS33} [get_ports {sdi_dq0}];
set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports {sdo_dq1}];
set_property -dict {PACKAGE_PIN L14 IOSTANDARD LVCMOS33} [get_ports {wpn_dq2}];
set_property -dict {PACKAGE_PIN M15 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}];
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK]}}
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK]}}

View File

@ -0,0 +1,13 @@
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH {4} [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property -dict {PACKAGE_PIN N17 IOSTANDARD LVCMOS33} [get_ports {csn}];
set_property -dict {PACKAGE_PIN M21 IOSTANDARD LVCMOS33} [get_ports {sdi_dq0}];
set_property -dict {PACKAGE_PIN M22 IOSTANDARD LVCMOS33} [get_ports {sdo_dq1}];
set_property -dict {PACKAGE_PIN N21 IOSTANDARD LVCMOS33} [get_ports {wpn_dq2}];
set_property -dict {PACKAGE_PIN N22 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}];
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK]}}
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK]}}

View File

@ -8,3 +8,6 @@ set_property -dict {PACKAGE_PIN N23 IOSTANDARD LVCMOS33} [get_ports {sdi_dq0}];
set_property -dict {PACKAGE_PIN N24 IOSTANDARD LVCMOS33} [get_ports {sdo_dq1}];
set_property -dict {PACKAGE_PIN P23 IOSTANDARD LVCMOS33} [get_ports {wpn_dq2}];
set_property -dict {PACKAGE_PIN R23 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}];
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK]}}
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK]}}

View File

@ -8,3 +8,6 @@ set_property -dict {PACKAGE_PIN B11 IOSTANDARD LVCMOS33} [get_ports {sdi_dq0}];
set_property -dict {PACKAGE_PIN B12 IOSTANDARD LVCMOS33} [get_ports {sdo_dq1}];
set_property -dict {PACKAGE_PIN D10 IOSTANDARD LVCMOS33} [get_ports {wpn_dq2}];
set_property -dict {PACKAGE_PIN C10 IOSTANDARD LVCMOS33} [get_ports {hldn_dq3}];
create_clock -period 33.000 -name jtag_tck -waveform {0.000 16.500} [get_pins {bscane2_inst/DRCK]}}
create_clock -period 33.000 -name vers_tck -waveform {0.000 16.500} [get_pins {bscane2_version/DRCK]}}

View File

@ -0,0 +1,250 @@
`default_nettype none
/*
* JTAG: rising edge: sampling
* falling esge: update
* SPI:
*/
module spiOverJtag_core (
/* JTAG state/controls */
input wire sel,
input wire capture,
input wire update,
input wire shift,
input wire drck,
input wire tdi,
output wire tdo,
/* JTAG endpoint to version */
input wire ver_sel,
input wire ver_cap,
input wire ver_shift,
input wire ver_drck,
input wire ver_tdi,
output wire ver_tdo,
/* phys */
output reg csn,
output wire sck,
output reg sdi_dq0,
input wire sdo_dq1,
output wire wpn_dq2,
output wire hldn_dq3,
/* debug signals */
output wire [ 6:0] dbg_header1,
output wire [13:0] dbg_header,
output wire [ 3:0] dbg_hdr_cnt,
output wire [ 2:0] dbg_jtag_state,
output wire dbg_rst,
output wire dbg_clk,
output wire dbg_start_header,
output wire dbg_ver_start,
output wire dbg_ver_rst,
output wire dbg_ver_state,
output wire [15:0] dbg_ver_cnt,
output wire [39:0] dbg_ver_shft
);
/* no global reset at start time:
* reset system at capture time (before shift)
* and at update time (after shift)
*/
wire rst = ((capture | update) & sel);
/*
* if the FPGAs executing this code is somewhere in a complex
* JTAG chain first bit isn't necessary for him
* Fortunately dummy bits sent are equal to '0' -> we sent a 'start bit'
*/
wire start_header = (tdi & shift & sel);
localparam hdr_len = 16;
reg [hdr_len-1:0] header; /* number of bits to receive / send in XFER state */
reg [hdr_len-1:0] header_d;
/* Primary header with mode and length LSB
* 6:5: mode (00: normal, 01: no header2, 10: infinite loop)
* 4:0: Byte length LSB
*/
reg [ 6:0] header1;
reg [ 6:0] header1_d;
wire [ 6:0] header1_next = {tdi, header1[6:1]};
wire [ 1:0] mode = header1[1:0];
/* Secondary header with extended length */
wire [hdr_len-1:0] header_next = {tdi, header[hdr_len-1:1]};
reg [ 3:0] hdr_cnt; /* counter of bit received in RECV_HEADERx states */
reg [ 3:0] hdr_cnt_d;
/* ---------------- */
/* FSM */
/* ---------------- */
localparam IDLE = 3'b000,
RECV_HEADER1 = 3'b001,
RECV_HEADER2 = 3'b010,
XFER = 3'b011,
WAIT_END = 3'b100;
reg [2:0] jtag_state, jtag_state_d;
/*
* 1. receives 8bits (
*/
always @(*) begin
jtag_state_d = jtag_state;
hdr_cnt_d = hdr_cnt;
header_d = header;
header1_d = header1;
case (jtag_state)
IDLE: begin /* nothing: wait for the 'start bit' */
hdr_cnt_d = 6;
if (start_header) begin
jtag_state_d = RECV_HEADER1;
end
end
RECV_HEADER1: begin /* first header with 1:0 : mode, 6:2: XFER length (LSB) */
hdr_cnt_d = hdr_cnt - 1'b1;
header1_d = header1_next;
if (hdr_cnt == 0) begin
if (header1_next[1:0] == 2'b00) begin
hdr_cnt_d = 7;
header_d = {header1_next[6:2], 3'b000, 8'd0};
jtag_state_d = RECV_HEADER2;
end else begin
header_d = {8'b0, header1_next[6:2], 3'b000};
jtag_state_d = XFER;
end
end
end
RECV_HEADER2: begin /* fill a counter with 16bits (number of bits to pass to the flash) */
hdr_cnt_d = hdr_cnt - 1'b1;
header_d = header_next;
if (hdr_cnt == 0) begin
jtag_state_d = XFER;
end
end
XFER: begin
header_d = header - 1;
if (header == 1 && mode != 2'b10)
jtag_state_d = WAIT_END;
end
WAIT_END: begin /* move to this state when header bits have been transfered to the SPI flash */
// /* nothing to do: rst will move automagically state in IDLE */
end
default: begin
jtag_state_d = IDLE;
end
endcase
end
always @(posedge drck) begin
header <= header_d;
header1 <= header1_d;
hdr_cnt <= hdr_cnt_d;
end
always @(posedge drck or posedge rst) begin
if (rst) begin
jtag_state <= IDLE;
end else begin
jtag_state <= jtag_state_d;
end
end
/* JTAG <-> phy SPI */
always @(posedge drck or posedge rst) begin
if (rst) begin
sdi_dq0 <= 1'b0;
csn <= 1'b1;
end else begin
sdi_dq0 <= tdi;
csn <= ~(jtag_state == XFER);
end
end
assign sck = ~drck;
assign tdo = sdo_dq1;
assign wpn_dq2 = 1'b1;
assign hldn_dq3 = 1'b1;
/* ------------- */
/* Version */
/* ------------- */
/* no global reset at start time: reset system at capture time (before shift) */
wire ver_rst = (ver_cap & ver_sel);
/* start bit */
wire ver_start = (ver_tdi & ver_shift & ver_sel);
localparam VER_VALUE = 40'h30_30_2E_32_30; // 02.00
reg [ 6:0] ver_cnt, ver_cnt_d;
reg [39:0] ver_shft, ver_shft_d;
reg [2:0] ver_state, ver_state_d;
always @(*) begin
ver_state_d = ver_state;
ver_cnt_d = ver_cnt;
ver_shft_d = ver_shft;
case (ver_state)
IDLE: begin /* nothing: wait for the 'start bit' */
ver_cnt_d = 6;
if (ver_start) begin
ver_state_d = RECV_HEADER1;
end
end
RECV_HEADER1: begin
ver_cnt_d = ver_cnt - 1'b1;
if (ver_cnt == 0) begin
ver_state_d = XFER;
ver_cnt_d = 39;
ver_shft_d = VER_VALUE;
end
end
XFER: begin
ver_cnt_d = ver_cnt - 1;
ver_shft_d = {1'b1, ver_shft[39:1]};
if (ver_cnt == 0)
ver_state_d = WAIT_END;
end
WAIT_END: begin /* move to this state when header bits have been transfered to the SPI flash */
// /* nothing to do: rst will move automagically state in IDLE */
end
default: begin
ver_state_d = IDLE;
end
endcase
end
always @(posedge ver_drck) begin
ver_cnt <= ver_cnt_d;
ver_shft <= ver_shft_d;
end
always @(posedge ver_drck or posedge ver_rst) begin
if (ver_rst)
ver_state <= IDLE;
else
ver_state <= ver_state_d;
end
assign ver_tdo = ver_shft[0];
/* --------- */
/* debug */
/* --------- */
assign dbg_header1 = header1;
assign dbg_header = header;
assign dbg_hdr_cnt = hdr_cnt;
assign dbg_jtag_state = jtag_state;
assign dbg_rst = rst;
assign dbg_clk = ~drck;
assign dbg_start_header = start_header;
assign dbg_ver_start = ver_start;
assign dbg_ver_state = ver_state;
assign dbg_ver_cnt = ver_cnt;
assign dbg_ver_shft = ver_shft;
assign dbg_ver_rst = ver_rst;
endmodule

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,85 +1,83 @@
`default_nettype none
module spiOverJtag
(
`ifndef xilinxultrascale
output wire csn,
`ifdef spartan6
output sck,
output csn,
output sdi_dq0,
input sdo_dq1,
output wpn_dq2,
output hldn_dq3
`define QSPI
`elsif spartan3e
output sck,
output csn,
output sdi_dq0,
input sdo_dq1
`elsif virtex6
output csn,
output sdi_dq0
`elsif xilinxultrascale
`else
// Xilinx 7 but not ultrascale
output csn,
output sdi_dq0,
input sdo_dq1,
output wpn_dq2,
output hldn_dq3
`define QSPI
output wire sck,
`endif
`ifdef spartan3e
output wire sck,
`endif
output wire sdi_dq0,
input wire sdo_dq1,
output wire wpn_dq2,
output wire hldn_dq3
`endif // xilinxultrascale
`ifdef secondaryflash
output sdi_sec_dq0,
input sdo_sec_dq1,
output wpn_sec_dq2,
output hldn_sec_dq3,
output csn_sec
output wire sdi_sec_dq0,
input wire sdo_sec_dq1,
output wire wpn_sec_dq2,
output wire hldn_sec_dq3,
output wire csn_sec
`endif // secondaryflash
);
wire capture, drck, sel, update;
wire runtest;
wire tdi;
reg fsm_csn;
wire capture, drck, sel, update, shift;
wire tdi, tdo;
wire spi_clk;
`ifdef QSPI
assign wpn_dq2 = 1'b1;
assign hldn_dq3 = 1'b1;
`ifndef spartan3e
/* Version Interface. */
wire ver_sel, ver_cap, ver_shift, ver_drck, ver_tdi, ver_tdo;
spiOverJtag_core spiOverJtag_core_prim (
/* JTAG state/controls */
.sel(sel),
.capture(capture),
.update(update),
.shift(shift),
.drck(drck),
.tdi(tdi),
.tdo(tdo),
/* JTAG endpoint to version */
.ver_sel(ver_sel),
.ver_cap(ver_cap),
.ver_shift(ver_shift),
.ver_drck(ver_drck),
.ver_tdi(ver_tdi),
.ver_tdo(ver_tdo),
/* phys */
.csn(csn),
.sck(spi_clk),
.sdi_dq0(sdi_dq0),
.sdo_dq1(sdo_dq1),
.wpn_dq2(wpn_dq2),
.hldn_dq3(hldn_dq3)
);
`endif
// jtag -> spi flash
assign sdi_dq0 = tdi;
`ifdef virtex6
wire di;
wire tdo = (sel) ? di : tdi;
`else
wire tdo = (sel) ? sdo_dq1 : tdi;
`endif
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
`ifdef spartan6
assign sck = spi_clk;
`else // !spartan6
`ifdef spartan3e
assign sck = spi_clk;
`else // !spartan6 && !spartan3e
`ifdef xilinxultrascale
assign sck = drck;
assign sck = drck;
wire [3:0] di;
assign wpn_dq2 = 1'b1;
assign hldn_dq3 = 1'b1;
assign sdo_dq1 = di[1];
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;
wire sck = (sel_sec) ? spi_clk_sec : spi_clk;
STARTUPE3 #(
.PROG_USR("FALSE"), // Activate program event security feature. Requires encrypted bitstreams.
.SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency (ns) for simulation.
@ -102,53 +100,57 @@ module spiOverJtag
.USRDONEO (1'b1), // 1-bit input: User DONE pin output control.
.USRDONETS(1'b1) // 1-bit input: User DONE 3-state enable output.
);
`elsif spartan3e
assign sck = drck;
assign runtest = tmp_up_s;
`elsif spartan6
assign sck = drck;
`elsif virtex6
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
`else // !spartan6 && !spartan3e && !xilinxultrascale
STARTUPE2 #(
.PROG_USR("FALSE"), // Activate program event security feature. Requires encrypted bitstreams.
.SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency(ns) for simulation.
) startupe2_inst (
.CFGCLK (), // 1-bit output: Configuration main clock output
.CFGMCLK (), // 1-bit output: Configuration internal oscillator clock output
.EOS (), // 1-bit output: Active high output signal indicating the End Of Startup.
.PREQ (), // 1-bit output: PROGRAM request to fabric output
.CLK (1'b0), // 1-bit input: User start-up clock input
.GSR (1'b0), // 1-bit input: Global Set/Reset input (GSR cannot be used for the port name)
.GTS (1'b0), // 1-bit input: Global 3-state input (GTS cannot be used for the port name)
.KEYCLEARB(1'b0), // 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM)
.PACK (1'b1), // 1-bit input: PROGRAM acknowledge input
.USRCCLKO (drck), // 1-bit input: User CCLK input
.USRCCLKTS(1'b0), // 1-bit input: User CCLK 3-state enable input
.USRDONEO (1'b1), // 1-bit input: User DONE pin output control
.USRDONETS(1'b1) // 1-bit input: User DONE 3-state enable output
.CFGCLK (), // 1-bit output: Configuration main clock output
.CFGMCLK (), // 1-bit output: Configuration internal oscillator clock output
.EOS (), // 1-bit output: Active high output signal indicating the End Of Startup.
.PREQ (), // 1-bit output: PROGRAM request to fabric output
.CLK (1'b0), // 1-bit input: User start-up clock input
.GSR (1'b0), // 1-bit input: Global Set/Reset input (GSR cannot be used for the port name)
.GTS (1'b0), // 1-bit input: Global 3-state input (GTS cannot be used for the port name)
.KEYCLEARB(1'b0), // 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM)
.PACK (1'b1), // 1-bit input: PROGRAM acknowledge input
.USRCCLKO (spi_clk), // 1-bit input: User CCLK input
.USRCCLKTS(1'b0), // 1-bit input: User CCLK 3-state enable input
.USRDONEO (1'b1), // 1-bit input: User DONE pin output control
.USRDONETS(1'b1) // 1-bit input: User DONE 3-state enable output
);
`endif
`endif
`endif
`ifdef spartan3e
wire runtest;
reg fsm_csn;
assign wpn_dq2 = 1'b1;
assign hldn_dq3 = 1'b1;
// jtag -> spi flash
assign sdi_dq0 = tdi;
wire tdo = (sel) ? sdo_dq1 : tdi;
assign csn = fsm_csn;
wire tmp_cap_s = capture && sel;
wire tmp_up_s = update && sel;
assign runtest = tmp_up_s;
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
BSCAN_SPARTAN3 bscane2_inst (
.CAPTURE(capture), // 1-bit output: CAPTURE output from TAP controller.
.DRCK1 (drck), // 1-bit output: Gated TCK output. When SEL
@ -167,9 +169,7 @@ module spiOverJtag
.TDO2 () // 1-bit input: USER2 function
);
`else
`ifdef virtex6
BSCAN_VIRTEX6 #(
`elsif spartan6
`ifdef spartan6
BSCAN_SPARTAN6 #(
`else
BSCANE2 #(
@ -181,10 +181,10 @@ module spiOverJtag
// is asserted, DRCK toggles when
// CAPTURE or SHIFT are asserted.
.RESET (), // 1-bit output: Reset output for TAP controller.
.RUNTEST(runtest), // 1-bit output: Output asserted when TAP
.RUNTEST(), // 1-bit output: Output asserted when TAP
// controller is in Run Test/Idle state.
.SEL (sel), // 1-bit output: USER instruction active output.
.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.
// Fabric connection to TAP Clock pin.
.TDI (tdi), // 1-bit output: Test Data Input (TDI) output
@ -195,38 +195,58 @@ module spiOverJtag
.TDO (tdo) // 1-bit input: Test Data Output (TDO) input
// for USER function.
);
/* BSCAN for Version Interface. */
`ifdef spartan6
BSCAN_SPARTAN6 #(
`else
BSCANE2 #(
`endif
.JTAG_CHAIN(4) // Value for USER command.
) bscane2_version (
.CAPTURE(ver_cap),
.DRCK (ver_drck),
.RESET (),
.RUNTEST(),
.SEL (ver_sel),
.SHIFT (ver_shift),
.TCK (),
.TDI (ver_tdi),
.TMS (),
.UPDATE (),
.TDO (ver_tdo)
);
`endif
`ifdef secondaryflash
reg fsm_csn_sec;
wire tdo_sec;
// secondary BSCANE3 signals
wire sel_sec, drck_sec;
wire drck_sec;
wire sck = (sel_sec) ? drck_sec : drck;
spiOverJtag_core spiOverJtag_core_sec (
/* JTAG state/controls */
.sel(sel_sec),
.capture(capture),
.update(update),
.shift(shift),
.drck(drck_sec),
.tdi(tdi),
.tdo(tdo_sec),
assign wpn_sec_dq2 = 1'b1;
assign hldn_sec_dq3 = 1'b1;
assign sdi_sec_dq0 = tdi;
assign tdo_sec = (sel_sec) ? sdo_sec_dq1 : tdi;
assign csn_sec = fsm_csn_sec;
/* JTAG endpoint to version (Unused) */
.ver_sel(1'b0),
.ver_cap(1'b0),
.ver_shift(1'b0),
.ver_drck(1'b0),
.ver_tdi(1'b0),
.ver_tdo(),
wire tmp_cap_sec_s = capture && sel_sec;
wire tmp_up_sec_s = update && sel_sec;
always @(posedge drck_sec, posedge runtest) begin
if (runtest) begin
fsm_csn_sec <= 1'b1;
end else begin
if (tmp_cap_sec_s) begin
fsm_csn_sec <= 1'b0;
end else if (tmp_up_sec_s) begin
fsm_csn_sec <= 1'b1;
end else begin
fsm_csn_sec <= fsm_csn_sec;
end
end
end
/* phys */
.csn(csn_sec),
.sck(spi_clk_sec),
.sdi_dq0(sdi_sec_dq0),
.sdo_dq1(sdo_sec_dq1),
.wpn_dq2(wpn_sec_dq2),
.hldn_dq3(hldn_sec_dq3)
);
BSCANE2 #(
.JTAG_CHAIN(2) // Value for USER command.

View File

@ -37,6 +37,7 @@
/* Used for xc3s */
#define USER1 0x02
#define USER4 0x23
#define CFG_IN 0x05
#define USERCODE 0x08
#define IDCODE 0x09
@ -278,7 +279,8 @@ Xilinx::Xilinx(Jtag *jtag, const std::string &filename,
SPIInterface(filename, verbose, 256, verify, skip_load_bridge,
skip_reset),
_device_package(device_package), _spiOverJtagPath(spiOverJtagPath),
_irlen(6), _secondary_filename(secondary_filename)
_irlen(6), _secondary_filename(secondary_filename), _soj_is_v2(false),
_jtag_chain_len(1)
{
if (prg_type == Device::RD_FLASH) {
_mode = Device::READ_MODE;
@ -673,11 +675,24 @@ bool Xilinx::post_flash_access()
bool Xilinx::prepare_flash_access()
{
bool ret = false;
if (_skip_load_bridge) {
printInfo("Skip loading bridge for spiOverjtag");
return true;
ret = true;
} else {
ret = load_bridge();
}
return load_bridge();
/* Get number of FPGAs in the Jtag Chain */
_jtag_chain_len = _jtag->get_chain_len();
/* check SpiOverJtag version */
if (ret) {
if (get_spiOverJtag_version() == 2.0f)
_soj_is_v2 = true;
printf("SOJ version: %f\n", _soj_is_v2 ? 2.0f : 1.0f);
}
return ret;
}
bool Xilinx::load_bridge()
@ -714,9 +729,32 @@ bool Xilinx::load_bridge()
printError(e.what());
throw std::runtime_error(e.what());
}
return true;
}
float Xilinx::get_spiOverJtag_version()
{
uint8_t jtx[6] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t jrx[7];
uint8_t rx[6];
_jtag->shiftIR(USER4, _irlen, Jtag::UPDATE_IR);
printf("jtag_chain_len: %d\n", _jtag_chain_len);
if (_jtag_chain_len > 1)
_jtag->shiftDR(jtx, NULL, _jtag_chain_len - 1, Jtag::SHIFT_DR);
_jtag->shiftDR(jtx, jrx, 6 * 8);
_jtag->flush();
memcpy(rx, &jrx[1], 5);
rx[5] = '\0';
float version = atof((const char *)rx);
if (version == 0.0f) // not supported => 1.0
return 1.0f;
return version;
}
void Xilinx::program_spi(ConfigBitstreamParser * bit, unsigned int offset,
bool unprotect_flash)
{
@ -889,7 +927,7 @@ static const std::map<std::string, std::list<reg_struct_t>> reg_content = {
REG_ENTRY("ConfigFallback", 10, 1,
{0, "Disable"}, {1, "Enable"}),
REG_ENTRY("Reserved", 11, 1),
REG_ENTRY("OverTempPwrDown",12, 1,
REG_ENTRY("OverTempPwrDown", 12, 1,
{0, "Disable"}, {1, "Enable"}),
REG_ENTRY("Reserved", 13, 17),
REG_ENTRY("ICAP Select", 30, 1,
@ -1003,7 +1041,7 @@ uint32_t Xilinx::dumpRegister(std::string reg_name)
if (code == reg_code.end()) {
printError("Unknown register " + reg_name);
printError("Known Register are:");
for (auto reg :reg_code)
for (auto reg : reg_code)
printError("\t" + reg.first);
return 0xdeadbeef;
}
@ -2023,6 +2061,10 @@ bool Xilinx::xc2c_flow_program(JedParser *jed)
int Xilinx::spi_put(uint8_t cmd,
const uint8_t *tx, uint8_t *rx, uint32_t len)
{
/* SpiOverJtag v2 */
if (_soj_is_v2)
return spi_put_v2(cmd, tx, rx, len);
int xfer_len = len + 1 + ((rx == NULL) ? 0 : 1);
uint8_t jtx[xfer_len];
jtx[0] = McsParser::reverseByte(cmd);
@ -2075,28 +2117,37 @@ int Xilinx::spi_wait(uint8_t cmd, uint8_t mask, uint8_t cond,
uint32_t timeout, bool verbose)
{
uint8_t rx[2];
uint8_t dummy[2];
memset(dummy, 0xff, sizeof(dummy));
uint8_t tx[2];
uint8_t tmp;
uint8_t tx = McsParser::reverseByte(cmd);
uint32_t count = 0;
const uint8_t shift = _jtag_chain_len;
uint8_t idx = 0;
if (_soj_is_v2)
tx[idx++] = (0x2 << 1) | 1;
tx[idx++] = McsParser::reverseByte(cmd);
_jtag->shiftIR(get_ircode(_ircode_map, _user_instruction), NULL, _irlen, Jtag::UPDATE_IR);
_jtag->shiftDR(&tx, NULL, 8, Jtag::SHIFT_DR);
_jtag->shiftDR(tx, NULL, 8 * idx, Jtag::SHIFT_DR);
do {
_jtag->shiftDR(dummy, rx, 8*2, Jtag::SHIFT_DR);
tmp = (McsParser::reverseByte(rx[0]>>1)) | (0x01 & rx[1]);
_jtag->shiftDR(tx, rx, 8*2, Jtag::SHIFT_DR);
tmp = McsParser::reverseByte(rx[0 ]>> shift);
if (shift == 1)
tmp |= (0x01 & rx[1]);
else
tmp |= McsParser::reverseByte(rx[1]) >> (8 - shift);
count++;
if (count == timeout){
printf("timeout: %x %x %x\n", tmp, rx[0], rx[1]);
break;
}
if (verbose) {
printf("%x %x %x %u\n", tmp, mask, cond, count);
printf("%x %x %x %u %02x %02x\n", tmp, mask, cond, count, rx[0], rx[1]);
}
} while ((tmp & mask) != cond);
_jtag->shiftDR(dummy, rx, 8*2, Jtag::EXIT1_DR);
_jtag->shiftDR(tx, rx, 8 * 2, Jtag::EXIT1_DR);
_jtag->go_test_logic_reset();
if (count == timeout) {
@ -2108,6 +2159,75 @@ int Xilinx::spi_wait(uint8_t cmd, uint8_t mask, uint8_t cond,
}
}
int Xilinx::spi_put_v2(uint8_t cmd, const uint8_t *tx, uint8_t *rx,
uint32_t len)
{
const uint32_t real_len = len + 1; // rx/tx length + cmd
uint32_t kPktLen = real_len + 2; // One header and +1 due to the needs of an additional bit/byte
uint8_t mode = 0x01;
if (real_len > 32) {
kPktLen++; // Additional header
mode = 0x00;
}
const uint32_t xfer_bit_len = (kPktLen - 1) * 8 + (rx ? 8 : 1);
uint8_t jrx[kPktLen];
uint8_t pkt[kPktLen];
uint32_t idx = 0;
pkt[idx++] = ((0x1f & real_len) << 3) | ((0x03 & mode) << 1) | 1;
if (mode == 0x00)
pkt[idx++] = 0xff & (real_len >> 5);
pkt[idx++] = McsParser::reverseByte(cmd);
if (tx) {
for (uint32_t i=0; i < len; i++)
pkt[idx++] = McsParser::reverseByte(tx[i]);
} else {
memset(&pkt[idx], 0, len);
idx += len;
}
/* addr BSCAN user1 */
_jtag->shiftIR(get_ircode(_ircode_map, _user_instruction), NULL, _irlen);
_jtag->shiftDR(pkt, (rx == NULL) ? NULL : jrx, xfer_bit_len);
_jtag->go_test_logic_reset();
_jtag->flush();
if (_verbose) {
for (uint32_t i = 0; i < kPktLen; i++)
printf("%02x ", pkt[i]);
printf("\n");
}
if (rx != NULL) {
if (_verbose) {
for (uint32_t i = 0; i < kPktLen; i++)
printf("%02x ", jrx[i]);
printf("\n");
for (uint32_t i = 0; i < kPktLen; i++)
printf("%02x ", McsParser::reverseByte(jrx[i]));
printf("\n");
}
idx = (mode == 0 ? 3 : 2);
const uint8_t shift = _jtag_chain_len;
for (uint32_t i = 0; i < len; i++) {
rx[i] = McsParser::reverseByte(jrx[i + idx] >> shift);
if (shift == 1)
rx[i] |= (jrx[i + idx + 1] & 0x01);
else
rx[i] |= McsParser::reverseByte(jrx[i + idx + 1]) >> (8 - shift);
if (_verbose)
printf("%02x ", rx[i]);
}
if (_verbose)
printf("\n");
}
return 0;
}
void Xilinx::select_flash_chip(xilinx_flash_chip_t flash_chip) {
switch (flash_chip) {
case SECONDARY_FLASH:

View File

@ -168,6 +168,10 @@ class Xilinx: public Device, SPIInterface {
int spi_wait(uint8_t cmd, uint8_t mask, uint8_t cond,
uint32_t timeout, bool verbose = false) override;
/* SpiOverJtag v2 specifics methods */
int spi_put_v2(uint8_t cmd, const uint8_t *tx, uint8_t *rx,
uint32_t len);
protected:
/*!
* \brief prepare SPI flash access (need to have bridge in RAM)
@ -215,6 +219,12 @@ class Xilinx: public Device, SPIInterface {
*/
bool load_bridge();
/*!
* \brief read SpiOverJtag version to select between v1 and v2
* \return 2.0 for v2 or 1.0 for v1
*/
float get_spiOverJtag_version();
enum xilinx_flash_chip_t {
PRIMARY_FLASH = 0x1,
SECONDARY_FLASH = 0x2
@ -249,6 +259,8 @@ class Xilinx: public Device, SPIInterface {
std::string _secondary_file_extension; /* file type for the secondary flash file */
int _flash_chips; /* bitfield to select the target in boards with two flash chips */
std::string _user_instruction; /* which USER bscan instruction to interface with SPI */
bool _soj_is_v2; /* SpiOverJtag version (1.0 or 2.0) */
uint32_t _jtag_chain_len; /* Jtag Chain Length */
};
#endif // SRC_XILINX_HPP_