|
| 1 | +import os |
1 | 2 | import textwrap |
2 | 3 | import subprocess |
3 | 4 |
|
|
6 | 7 | from .resources import * |
7 | 8 |
|
8 | 9 |
|
9 | | -__all__ = ["ArtysS7_25Platform", "ArtyS7_50Platform"] |
| 10 | +__all__ = ["ArtyS7_25Platform", "ArtyS7_50Platform"] |
10 | 11 |
|
11 | 12 |
|
12 | 13 | class _ArtyS7Platform(Xilinx7SeriesPlatform): |
@@ -159,18 +160,67 @@ def toolchain_prepare(self, fragment, name, **kwargs): |
159 | 160 | } |
160 | 161 | return super().toolchain_prepare(fragment, name, **overrides, **kwargs) |
161 | 162 |
|
162 | | - def toolchain_program(self, product, name): |
163 | | - with product.extract("{}.bit".format(name)) as bitstream_filename: |
164 | | - cmd = textwrap.dedent(""" |
165 | | - open_hw_manager |
166 | | - connect_hw_server |
167 | | - open_hw_target |
168 | | - current_hw_device [lindex [get_hw_devices] 0] |
169 | | - set_property PROGRAM.FILE {{{}}} [current_hw_device] |
170 | | - program_hw_devices |
171 | | - close_hw_manager |
172 | | - """).format(bitstream_filename).encode("utf-8") |
173 | | - subprocess.run(["vivado", "-nolog", "-nojournal", "-mode", "tcl"], input=cmd, check=True) |
| 163 | + def toolchain_program(self, product, name, *, programmer="vivado", flash=True): |
| 164 | + assert programmer in ("vivado", "openocd") |
| 165 | + |
| 166 | + if programmer == "vivado": |
| 167 | + if flash: |
| 168 | + # It does not appear possible to reset the FPGA via TCL after |
| 169 | + # flash programming. |
| 170 | + with product.extract("{}.bin".format(name)) as bitstream_filename: |
| 171 | + cmd = textwrap.dedent(""" |
| 172 | + open_hw_manager |
| 173 | + connect_hw_server |
| 174 | + open_hw_target |
| 175 | + current_hw_device [lindex [get_hw_devices] 0] |
| 176 | + create_hw_cfgmem -hw_device [current_hw_device] s25fl128sxxxxxx0-spi-x1_x2_x4 |
| 177 | + set_property PROGRAM.FILES {{{}}} [current_hw_cfgmem] |
| 178 | + set_property PROGRAM.ADDRESS_RANGE {{use_file}} [current_hw_cfgmem] |
| 179 | + set_property PROGRAM.BLANK_CHECK 1 [current_hw_cfgmem] |
| 180 | + set_property PROGRAM.ERASE 1 [current_hw_cfgmem] |
| 181 | + set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem] |
| 182 | + set_property PROGRAM.VERIFY 1 [current_hw_cfgmem] |
| 183 | + create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]] |
| 184 | + program_hw_devices |
| 185 | + program_hw_cfgmem |
| 186 | + close_hw_manager |
| 187 | + puts "Vivado TCL cannot reset boards. Reset or power-cycle your board now." |
| 188 | + """).format(bitstream_filename).encode("utf-8") |
| 189 | + subprocess.run(["vivado", "-nolog", "-nojournal", "-mode", "tcl"], input=cmd, check=True) |
| 190 | + else: |
| 191 | + with product.extract("{}.bit".format(name)) as bitstream_filename: |
| 192 | + cmd = textwrap.dedent(""" |
| 193 | + open_hw_manager |
| 194 | + connect_hw_server |
| 195 | + open_hw_target |
| 196 | + current_hw_device [lindex [get_hw_devices] 0] |
| 197 | + set_property PROGRAM.FILE {{{}}} [current_hw_device] |
| 198 | + program_hw_devices |
| 199 | + close_hw_manager |
| 200 | + """).format(bitstream_filename).encode("utf-8") |
| 201 | + subprocess.run(["vivado", "-nolog", "-nojournal", "-mode", "tcl"], input=cmd, check=True) |
| 202 | + else: |
| 203 | + openocd = os.environ.get("OPENOCD", "openocd") |
| 204 | + # In order, OpenOCD searches these directories for files: |
| 205 | + # * $HOME/.openocd if $HOME exists (*nix) |
| 206 | + # * Path pointed to by $OPENOCD_SCRIPTS if $OPENOCD_SCRIPTS exists |
| 207 | + # * $APPDATA/OpenOCD on Windows |
| 208 | + # Place the bscan_spi_xc7s50.bit proxy bitstream under a directory |
| 209 | + # named "proxy" in one of the above directories so OpenOCD finds it. |
| 210 | + if flash: |
| 211 | + with product.extract("{}.bin".format(name)) as fn: |
| 212 | + subprocess.check_call([openocd, "-f", "board/arty_s7.cfg", |
| 213 | + "-c", """init; |
| 214 | + jtagspi_init 0 [find proxy/bscan_spi_xc7s50.bit]; |
| 215 | + jtagspi_program {} 0; |
| 216 | + xc7_program xc7.tap; |
| 217 | + shutdown""".format(fn)]) |
| 218 | + else: |
| 219 | + with product.extract("{}.bit".format(name)) as fn: |
| 220 | + subprocess.check_call(["openocd", "-f", "board/arty_s7.cfg", |
| 221 | + "-c", """init; |
| 222 | + pld load 0 {}; |
| 223 | + shutdown""".format(fn)]) |
174 | 224 |
|
175 | 225 |
|
176 | 226 | class ArtyS7_50Platform(_ArtyS7Platform): |
|
0 commit comments