diff --git a/spiOverJtag/.gitignore b/spiOverJtag/.gitignore index e65e5d7..69629ee 100644 --- a/spiOverJtag/.gitignore +++ b/spiOverJtag/.gitignore @@ -1,3 +1,6 @@ tmp_* *.bit *.rbf +vivado*.jou +vivado*.log +.Xil diff --git a/spiOverJtag/Makefile b/spiOverJtag/Makefile index d1dec0d..e9c94ee 100644 --- a/spiOverJtag/Makefile +++ b/spiOverJtag/Makefile @@ -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 diff --git a/spiOverJtag/build.py b/spiOverJtag/build.py index 534a350..bcbaf41 100755 --- a/spiOverJtag/build.py +++ b/spiOverJtag/build.py @@ -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]) diff --git a/spiOverJtag/constr_xc7a_cpg236.xdc b/spiOverJtag/constr_xc7a_cpg236.xdc index 7b1edbf..2ae0665 100644 --- a/spiOverJtag/constr_xc7a_cpg236.xdc +++ b/spiOverJtag/constr_xc7a_cpg236.xdc @@ -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}] diff --git a/spiOverJtag/constr_xc7a_cpg238.xdc b/spiOverJtag/constr_xc7a_cpg238.xdc index 9665243..0bd761e 100644 --- a/spiOverJtag/constr_xc7a_cpg238.xdc +++ b/spiOverJtag/constr_xc7a_cpg238.xdc @@ -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}] diff --git a/spiOverJtag/constr_xc7a_csg324.xdc b/spiOverJtag/constr_xc7a_csg324.xdc index 955a208..d4a2e89 100644 --- a/spiOverJtag/constr_xc7a_csg324.xdc +++ b/spiOverJtag/constr_xc7a_csg324.xdc @@ -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}] diff --git a/spiOverJtag/constr_xc7a_csg325.xdc b/spiOverJtag/constr_xc7a_csg325.xdc index 714880a..86ba53e 100644 --- a/spiOverJtag/constr_xc7a_csg325.xdc +++ b/spiOverJtag/constr_xc7a_csg325.xdc @@ -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]}} diff --git a/spiOverJtag/constr_xc7a_csg325_1v35.xdc b/spiOverJtag/constr_xc7a_csg325_1v35.xdc index dcde0d4..4f6927c 100644 --- a/spiOverJtag/constr_xc7a_csg325_1v35.xdc +++ b/spiOverJtag/constr_xc7a_csg325_1v35.xdc @@ -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]}} diff --git a/spiOverJtag/constr_xc7a_fbg484.xdc b/spiOverJtag/constr_xc7a_fbg484.xdc index 96b9de8..cbeef1a 100644 --- a/spiOverJtag/constr_xc7a_fbg484.xdc +++ b/spiOverJtag/constr_xc7a_fbg484.xdc @@ -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}] diff --git a/spiOverJtag/constr_xc7a_fbg676.xdc b/spiOverJtag/constr_xc7a_fbg676.xdc index fe12330..00375a5 100644 --- a/spiOverJtag/constr_xc7a_fbg676.xdc +++ b/spiOverJtag/constr_xc7a_fbg676.xdc @@ -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}] diff --git a/spiOverJtag/constr_xc7a_fgg484.xdc b/spiOverJtag/constr_xc7a_fgg484.xdc index 5e2b0e6..cbeef1a 100644 --- a/spiOverJtag/constr_xc7a_fgg484.xdc +++ b/spiOverJtag/constr_xc7a_fgg484.xdc @@ -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}] diff --git a/spiOverJtag/constr_xc7a_fgg676.xdc b/spiOverJtag/constr_xc7a_fgg676.xdc index aaf73d0..00375a5 100644 --- a/spiOverJtag/constr_xc7a_fgg676.xdc +++ b/spiOverJtag/constr_xc7a_fgg676.xdc @@ -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}] diff --git a/spiOverJtag/constr_xc7a_ftg256.xdc b/spiOverJtag/constr_xc7a_ftg256.xdc index a0dad16..32bec5a 100644 --- a/spiOverJtag/constr_xc7a_ftg256.xdc +++ b/spiOverJtag/constr_xc7a_ftg256.xdc @@ -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}] diff --git a/spiOverJtag/constr_xc7a_sbg384.xdc b/spiOverJtag/constr_xc7a_sbg384.xdc index 61cb90c..6a0a825 100644 --- a/spiOverJtag/constr_xc7a_sbg384.xdc +++ b/spiOverJtag/constr_xc7a_sbg384.xdc @@ -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}] \ No newline at end of file +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]}} diff --git a/spiOverJtag/constr_xc7a_sbg484.xdc b/spiOverJtag/constr_xc7a_sbg484.xdc new file mode 100644 index 0000000..e90d9bb --- /dev/null +++ b/spiOverJtag/constr_xc7a_sbg484.xdc @@ -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]}} diff --git a/spiOverJtag/constr_xc7s_cpga196.xdc b/spiOverJtag/constr_xc7s_cpga196.xdc new file mode 100644 index 0000000..12c103b --- /dev/null +++ b/spiOverJtag/constr_xc7s_cpga196.xdc @@ -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]}} diff --git a/spiOverJtag/constr_xc7s_csga225.xdc b/spiOverJtag/constr_xc7s_csga225.xdc index ae06441..1bc0b6c 100644 --- a/spiOverJtag/constr_xc7s_csga225.xdc +++ b/spiOverJtag/constr_xc7s_csga225.xdc @@ -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]}} diff --git a/spiOverJtag/constr_xc7s_csga324.xdc b/spiOverJtag/constr_xc7s_csga324.xdc index 0861b63..e776557 100644 --- a/spiOverJtag/constr_xc7s_csga324.xdc +++ b/spiOverJtag/constr_xc7s_csga324.xdc @@ -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]}} diff --git a/spiOverJtag/constr_xc7s_fgga484.xdc b/spiOverJtag/constr_xc7s_fgga484.xdc new file mode 100644 index 0000000..49b2853 --- /dev/null +++ b/spiOverJtag/constr_xc7s_fgga484.xdc @@ -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]}} diff --git a/spiOverJtag/constr_xc7s_fgga676.xdc b/spiOverJtag/constr_xc7s_fgga676.xdc index 77a796c..993d716 100644 --- a/spiOverJtag/constr_xc7s_fgga676.xdc +++ b/spiOverJtag/constr_xc7s_fgga676.xdc @@ -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]}} diff --git a/spiOverJtag/constr_xc7s_ftgb196.xdc b/spiOverJtag/constr_xc7s_ftgb196.xdc index 3eaa20a..a230f99 100644 --- a/spiOverJtag/constr_xc7s_ftgb196.xdc +++ b/spiOverJtag/constr_xc7s_ftgb196.xdc @@ -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]}} diff --git a/spiOverJtag/spiOverJtag_core.v b/spiOverJtag/spiOverJtag_core.v new file mode 100644 index 0000000..45c78ed --- /dev/null +++ b/spiOverJtag/spiOverJtag_core.v @@ -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 diff --git a/spiOverJtag/spiOverJtag_xc7a100t.bit.gz b/spiOverJtag/spiOverJtag_xc7a100t.bit.gz new file mode 100644 index 0000000..6910300 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a100t.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a100tcsg324.bit.gz b/spiOverJtag/spiOverJtag_xc7a100tcsg324.bit.gz index b3c12b5..6910300 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a100tcsg324.bit.gz and b/spiOverJtag/spiOverJtag_xc7a100tcsg324.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a100tfgg484.bit b/spiOverJtag/spiOverJtag_xc7a100tfgg484.bit deleted file mode 100644 index 97c0b5e..0000000 Binary files a/spiOverJtag/spiOverJtag_xc7a100tfgg484.bit and /dev/null differ diff --git a/spiOverJtag/spiOverJtag_xc7a100tfgg484.bit.gz b/spiOverJtag/spiOverJtag_xc7a100tfgg484.bit.gz new file mode 100644 index 0000000..6910300 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a100tfgg484.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a100tfgg676.bit.gz b/spiOverJtag/spiOverJtag_xc7a100tfgg676.bit.gz index f6a0fca..6910300 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a100tfgg676.bit.gz and b/spiOverJtag/spiOverJtag_xc7a100tfgg676.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a100tftg256.bit.gz b/spiOverJtag/spiOverJtag_xc7a100tftg256.bit.gz new file mode 100644 index 0000000..6910300 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a100tftg256.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a12t.bit.gz b/spiOverJtag/spiOverJtag_xc7a12t.bit.gz new file mode 100644 index 0000000..32b10a1 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a12t.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a12tcpg238.bit.gz b/spiOverJtag/spiOverJtag_xc7a12tcpg238.bit.gz new file mode 100644 index 0000000..32b10a1 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a12tcpg238.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a12tcsg325.bit.gz b/spiOverJtag/spiOverJtag_xc7a12tcsg325.bit.gz new file mode 100644 index 0000000..32b10a1 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a12tcsg325.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a15t.bit.gz b/spiOverJtag/spiOverJtag_xc7a15t.bit.gz new file mode 100644 index 0000000..75e6930 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a15t.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a15tcpg236.bit.gz b/spiOverJtag/spiOverJtag_xc7a15tcpg236.bit.gz index 04e3ce8..75e6930 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a15tcpg236.bit.gz and b/spiOverJtag/spiOverJtag_xc7a15tcpg236.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a15tcsg324.bit.gz b/spiOverJtag/spiOverJtag_xc7a15tcsg324.bit.gz new file mode 100644 index 0000000..75e6930 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a15tcsg324.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a15tcsg325.bit.gz b/spiOverJtag/spiOverJtag_xc7a15tcsg325.bit.gz new file mode 100644 index 0000000..75e6930 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a15tcsg325.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a15tfgg484.bit.gz b/spiOverJtag/spiOverJtag_xc7a15tfgg484.bit.gz index 574f920..75e6930 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a15tfgg484.bit.gz and b/spiOverJtag/spiOverJtag_xc7a15tfgg484.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a15tftg256.bit.gz b/spiOverJtag/spiOverJtag_xc7a15tftg256.bit.gz new file mode 100644 index 0000000..75e6930 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a15tftg256.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a200t.bit.gz b/spiOverJtag/spiOverJtag_xc7a200t.bit.gz new file mode 100644 index 0000000..447c38b Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a200t.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a200tfbg484.bit.gz b/spiOverJtag/spiOverJtag_xc7a200tfbg484.bit.gz index a644a8a..447c38b 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a200tfbg484.bit.gz and b/spiOverJtag/spiOverJtag_xc7a200tfbg484.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a200tfbg676.bit.gz b/spiOverJtag/spiOverJtag_xc7a200tfbg676.bit.gz index c8b381d..447c38b 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a200tfbg676.bit.gz and b/spiOverJtag/spiOverJtag_xc7a200tfbg676.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a200tffg1156.bit.gz b/spiOverJtag/spiOverJtag_xc7a200tffg1156.bit.gz new file mode 100644 index 0000000..447c38b Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a200tffg1156.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a200tsbg484.bit b/spiOverJtag/spiOverJtag_xc7a200tsbg484.bit deleted file mode 100644 index 015f5d8..0000000 Binary files a/spiOverJtag/spiOverJtag_xc7a200tsbg484.bit and /dev/null differ diff --git a/spiOverJtag/spiOverJtag_xc7a200tsbg484.bit.gz b/spiOverJtag/spiOverJtag_xc7a200tsbg484.bit.gz new file mode 100644 index 0000000..447c38b Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a200tsbg484.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a25t.bit.gz b/spiOverJtag/spiOverJtag_xc7a25t.bit.gz new file mode 100644 index 0000000..01598db Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a25t.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a25tcpg238.bit.gz b/spiOverJtag/spiOverJtag_xc7a25tcpg238.bit.gz index a77fb2a..01598db 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a25tcpg238.bit.gz and b/spiOverJtag/spiOverJtag_xc7a25tcpg238.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a25tcsg325.bit.gz b/spiOverJtag/spiOverJtag_xc7a25tcsg325.bit.gz index 47cd909..01598db 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a25tcsg325.bit.gz and b/spiOverJtag/spiOverJtag_xc7a25tcsg325.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a35t.bit.gz b/spiOverJtag/spiOverJtag_xc7a35t.bit.gz new file mode 100644 index 0000000..ef1242e Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a35t.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a35tcpg236.bit.gz b/spiOverJtag/spiOverJtag_xc7a35tcpg236.bit.gz index ebf4ba4..ef1242e 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a35tcpg236.bit.gz and b/spiOverJtag/spiOverJtag_xc7a35tcpg236.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a35tcsg324.bit b/spiOverJtag/spiOverJtag_xc7a35tcsg324.bit deleted file mode 100644 index 2af4f03..0000000 Binary files a/spiOverJtag/spiOverJtag_xc7a35tcsg324.bit and /dev/null differ diff --git a/spiOverJtag/spiOverJtag_xc7a35tcsg324.bit.gz b/spiOverJtag/spiOverJtag_xc7a35tcsg324.bit.gz new file mode 100644 index 0000000..ef1242e Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a35tcsg324.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a35tcsg325.bit.gz b/spiOverJtag/spiOverJtag_xc7a35tcsg325.bit.gz new file mode 100644 index 0000000..ef1242e Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a35tcsg325.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a35tfgg484.bit.gz b/spiOverJtag/spiOverJtag_xc7a35tfgg484.bit.gz index fc84806..ef1242e 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a35tfgg484.bit.gz and b/spiOverJtag/spiOverJtag_xc7a35tfgg484.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a35tftg256.bit b/spiOverJtag/spiOverJtag_xc7a35tftg256.bit deleted file mode 100644 index 0f69e19..0000000 Binary files a/spiOverJtag/spiOverJtag_xc7a35tftg256.bit and /dev/null differ diff --git a/spiOverJtag/spiOverJtag_xc7a35tftg256.bit.gz b/spiOverJtag/spiOverJtag_xc7a35tftg256.bit.gz new file mode 100644 index 0000000..ef1242e Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a35tftg256.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a50t.bit.gz b/spiOverJtag/spiOverJtag_xc7a50t.bit.gz new file mode 100644 index 0000000..b7cab4c Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a50t.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a50tcpg236.bit b/spiOverJtag/spiOverJtag_xc7a50tcpg236.bit deleted file mode 100644 index 4e4453b..0000000 Binary files a/spiOverJtag/spiOverJtag_xc7a50tcpg236.bit and /dev/null differ diff --git a/spiOverJtag/spiOverJtag_xc7a50tcpg236.bit.gz b/spiOverJtag/spiOverJtag_xc7a50tcpg236.bit.gz new file mode 100644 index 0000000..b7cab4c Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a50tcpg236.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a50tcsg324.bit.gz b/spiOverJtag/spiOverJtag_xc7a50tcsg324.bit.gz index e335236..b7cab4c 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a50tcsg324.bit.gz and b/spiOverJtag/spiOverJtag_xc7a50tcsg324.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a50tcsg325.bit.gz b/spiOverJtag/spiOverJtag_xc7a50tcsg325.bit.gz index eea2d91..b7cab4c 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a50tcsg325.bit.gz and b/spiOverJtag/spiOverJtag_xc7a50tcsg325.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a50tfgg484.bit.gz b/spiOverJtag/spiOverJtag_xc7a50tfgg484.bit.gz index 2903e01..b7cab4c 100644 Binary files a/spiOverJtag/spiOverJtag_xc7a50tfgg484.bit.gz and b/spiOverJtag/spiOverJtag_xc7a50tfgg484.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a50tftg256.bit.gz b/spiOverJtag/spiOverJtag_xc7a50tftg256.bit.gz new file mode 100644 index 0000000..b7cab4c Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a50tftg256.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a75t.bit.gz b/spiOverJtag/spiOverJtag_xc7a75t.bit.gz new file mode 100644 index 0000000..4a91e26 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a75t.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a75tcsg324.bit.gz b/spiOverJtag/spiOverJtag_xc7a75tcsg324.bit.gz new file mode 100644 index 0000000..4a91e26 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a75tcsg324.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a75tfgg484.bit b/spiOverJtag/spiOverJtag_xc7a75tfgg484.bit deleted file mode 100644 index da08d32..0000000 Binary files a/spiOverJtag/spiOverJtag_xc7a75tfgg484.bit and /dev/null differ diff --git a/spiOverJtag/spiOverJtag_xc7a75tfgg484.bit.gz b/spiOverJtag/spiOverJtag_xc7a75tfgg484.bit.gz new file mode 100644 index 0000000..4a91e26 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a75tfgg484.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a75tfgg676.bit.gz b/spiOverJtag/spiOverJtag_xc7a75tfgg676.bit.gz new file mode 100644 index 0000000..4a91e26 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a75tfgg676.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7a75tftg256.bit.gz b/spiOverJtag/spiOverJtag_xc7a75tftg256.bit.gz new file mode 100644 index 0000000..4a91e26 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7a75tftg256.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s100.bit.gz b/spiOverJtag/spiOverJtag_xc7s100.bit.gz new file mode 100644 index 0000000..8a1efcb Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s100.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s100fgga484.bit.gz b/spiOverJtag/spiOverJtag_xc7s100fgga484.bit.gz new file mode 100644 index 0000000..8a1efcb Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s100fgga484.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s100fgga676.bit.gz b/spiOverJtag/spiOverJtag_xc7s100fgga676.bit.gz new file mode 100644 index 0000000..8a1efcb Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s100fgga676.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s15.bit.gz b/spiOverJtag/spiOverJtag_xc7s15.bit.gz new file mode 100644 index 0000000..1c2316e Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s15.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s15cpga196.bit.gz b/spiOverJtag/spiOverJtag_xc7s15cpga196.bit.gz new file mode 100644 index 0000000..1c2316e Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s15cpga196.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s15csga225.bit.gz b/spiOverJtag/spiOverJtag_xc7s15csga225.bit.gz new file mode 100644 index 0000000..1c2316e Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s15csga225.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s15ftgb196.bit.gz b/spiOverJtag/spiOverJtag_xc7s15ftgb196.bit.gz new file mode 100644 index 0000000..1c2316e Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s15ftgb196.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s25.bit.gz b/spiOverJtag/spiOverJtag_xc7s25.bit.gz new file mode 100644 index 0000000..dae49d3 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s25.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s25csga225.bit.gz b/spiOverJtag/spiOverJtag_xc7s25csga225.bit.gz index 67f182e..dae49d3 100644 Binary files a/spiOverJtag/spiOverJtag_xc7s25csga225.bit.gz and b/spiOverJtag/spiOverJtag_xc7s25csga225.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s25csga324.bit.gz b/spiOverJtag/spiOverJtag_xc7s25csga324.bit.gz index 464d414..dae49d3 100644 Binary files a/spiOverJtag/spiOverJtag_xc7s25csga324.bit.gz and b/spiOverJtag/spiOverJtag_xc7s25csga324.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s25ftgb196.bit.gz b/spiOverJtag/spiOverJtag_xc7s25ftgb196.bit.gz new file mode 100644 index 0000000..dae49d3 Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s25ftgb196.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s50.bit.gz b/spiOverJtag/spiOverJtag_xc7s50.bit.gz new file mode 100644 index 0000000..130e69e Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s50.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s50csga324.bit.gz b/spiOverJtag/spiOverJtag_xc7s50csga324.bit.gz index ef4c8fe..130e69e 100644 Binary files a/spiOverJtag/spiOverJtag_xc7s50csga324.bit.gz and b/spiOverJtag/spiOverJtag_xc7s50csga324.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s50fgga484.bit.gz b/spiOverJtag/spiOverJtag_xc7s50fgga484.bit.gz new file mode 100644 index 0000000..130e69e Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s50fgga484.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s50ftgb196.bit.gz b/spiOverJtag/spiOverJtag_xc7s50ftgb196.bit.gz new file mode 100644 index 0000000..130e69e Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s50ftgb196.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s6.bit.gz b/spiOverJtag/spiOverJtag_xc7s6.bit.gz new file mode 100644 index 0000000..c53e56d Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s6.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s6cpga196.bit.gz b/spiOverJtag/spiOverJtag_xc7s6cpga196.bit.gz new file mode 100644 index 0000000..c53e56d Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s6cpga196.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s6csga225.bit.gz b/spiOverJtag/spiOverJtag_xc7s6csga225.bit.gz new file mode 100644 index 0000000..c53e56d Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s6csga225.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s6ftgb196.bit.gz b/spiOverJtag/spiOverJtag_xc7s6ftgb196.bit.gz index 833a28a..c53e56d 100644 Binary files a/spiOverJtag/spiOverJtag_xc7s6ftgb196.bit.gz and b/spiOverJtag/spiOverJtag_xc7s6ftgb196.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s75.bit.gz b/spiOverJtag/spiOverJtag_xc7s75.bit.gz new file mode 100644 index 0000000..741e28c Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s75.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s75fgga484.bit.gz b/spiOverJtag/spiOverJtag_xc7s75fgga484.bit.gz new file mode 100644 index 0000000..741e28c Binary files /dev/null and b/spiOverJtag/spiOverJtag_xc7s75fgga484.bit.gz differ diff --git a/spiOverJtag/spiOverJtag_xc7s75fgga676.bit.gz b/spiOverJtag/spiOverJtag_xc7s75fgga676.bit.gz index d7a7f60..741e28c 100644 Binary files a/spiOverJtag/spiOverJtag_xc7s75fgga676.bit.gz and b/spiOverJtag/spiOverJtag_xc7s75fgga676.bit.gz differ diff --git a/spiOverJtag/xilinx_spiOverJtag.v b/spiOverJtag/xilinx_spiOverJtag.v index 95baf68..4b168ff 100644 --- a/spiOverJtag/xilinx_spiOverJtag.v +++ b/spiOverJtag/xilinx_spiOverJtag.v @@ -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. diff --git a/src/xilinx.cpp b/src/xilinx.cpp index d2a7d29..5156654 100644 --- a/src/xilinx.cpp +++ b/src/xilinx.cpp @@ -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> 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: diff --git a/src/xilinx.hpp b/src/xilinx.hpp index b0fec7c..c55464c 100644 --- a/src/xilinx.hpp +++ b/src/xilinx.hpp @@ -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_