diff --git a/litex/build/altera/programmer.py b/litex/build/altera/programmer.py index 84cf6882c..c797c564f 100644 --- a/litex/build/altera/programmer.py +++ b/litex/build/altera/programmer.py @@ -4,8 +4,6 @@ # Copyright (c) 2015-2018 Florent Kermarrec # SPDX-License-Identifier: BSD-2-Clause -import subprocess - from litex.build.generic_programmer import GenericProgrammer # USBBlaster --------------------------------------------------------------------------------------- @@ -18,8 +16,8 @@ class USBBlaster(GenericProgrammer): self.device_id = device_id def load_bitstream(self, bitstream_file, cable_suffix=""): - subprocess.call(["quartus_pgm", - "-m", "jtag", - "-c", "{}{}".format(self.cable_name, cable_suffix), - "-o", "p;{}@{}".format(bitstream_file, self.device_id) + self.call(["quartus_pgm", + "-m", "jtag", + "-c", "{}{}".format(self.cable_name, cable_suffix), + "-o", "p;{}@{}".format(bitstream_file, self.device_id) ]) diff --git a/litex/build/generic_programmer.py b/litex/build/generic_programmer.py index 50ae7f3a5..814f5da62 100644 --- a/litex/build/generic_programmer.py +++ b/litex/build/generic_programmer.py @@ -8,6 +8,7 @@ import os import sys +import subprocess from litex.build import tools @@ -90,4 +91,10 @@ class GenericProgrammer: def flash(self, address, data_file): raise NotImplementedError - + def call(self, command): + if subprocess.call(command) != 0: + msg = f"Error occured during {self.__class__.__name__}'s call, please check:\n" + msg += f"- {self.__class__.__name__} installation.\n" + msg += f"- access permissions.\n" + msg += f"- hardware and cable." + raise OSError(msg) diff --git a/litex/build/lattice/programmer.py b/litex/build/lattice/programmer.py index 999901850..fc2bd0f23 100644 --- a/litex/build/lattice/programmer.py +++ b/litex/build/lattice/programmer.py @@ -6,7 +6,6 @@ # SPDX-License-Identifier: BSD-2-Clause import os -import subprocess from litex.build.generic_programmer import GenericProgrammer from litex.build import tools @@ -23,7 +22,7 @@ class LatticeProgrammer(GenericProgrammer): xcf_file = bitstream_file.replace(".bit", ".xcf") xcf_content = self.xcf_template.format(bitstream_file=bitstream_file) tools.write_to_file(xcf_file, xcf_content) - subprocess.call(["pgrcmd", "-infile", xcf_file]) + self.call(["pgrcmd", "-infile", xcf_file]) # OpenOCDJTAGProgrammer -------------------------------------------------------------------------------- @@ -35,7 +34,7 @@ class OpenOCDJTAGProgrammer(GenericProgrammer): def load_bitstream(self, bitstream_file): config = self.find_config() svf_file = bitstream_file.replace(".bit", ".svf") - subprocess.call(["openocd", "-f", config, "-c", "transport select jtag; init; svf quiet progress \"{}\"; exit".format(svf_file)]) + self.call(["openocd", "-f", config, "-c", "transport select jtag; init; svf quiet progress \"{}\"; exit".format(svf_file)]) def flash(self, address, data, verify=True): config = self.find_config() @@ -52,7 +51,7 @@ class OpenOCDJTAGProgrammer(GenericProgrammer): "flash verify_bank spi0 \"{0}\" 0x{1:x}" if verify else "".format(data, address), "exit" ]) - subprocess.call(["openocd", "-f", config, "-c", script]) + self.call(["openocd", "-f", config, "-c", script]) # IceStormProgrammer ------------------------------------------------------------------------------- @@ -60,10 +59,10 @@ class IceStormProgrammer(GenericProgrammer): needs_bitreverse = False def flash(self, address, bitstream_file): - subprocess.call(["iceprog", "-o", str(address), bitstream_file]) + self.call(["iceprog", "-o", str(address), bitstream_file]) def load_bitstream(self, bitstream_file): - subprocess.call(["iceprog", "-S", bitstream_file]) + self.call(["iceprog", "-S", bitstream_file]) # IceBurnProgrammer -------------------------------------------------------------------------------- @@ -75,7 +74,7 @@ class IceBurnProgrammer(GenericProgrammer): needs_bitreverse = False def load_bitstream(self, bitstream_file): - subprocess.call([self.iceburn, "-evw", bitstream_file]) + self.call([self.iceburn, "-evw", bitstream_file]) # TinyFpgaBProgrammer ------------------------------------------------------------------------------ @@ -85,13 +84,13 @@ class TinyFpgaBProgrammer(GenericProgrammer): # The default flash address you probably want is 0x30000; the image at # address 0 is for the bootloader. def flash(self, address, bitstream_file): - subprocess.call(["tinyfpgab", "-a", str(address), "-p", + self.call(["tinyfpgab", "-a", str(address), "-p", bitstream_file]) # Force user image to boot if a user reset tinyfpga, the bootloader # is active, and the user image need not be reprogrammed. def boot(self): - subprocess.call(["tinyfpgab", "-b"]) + self.call(["tinyfpgab", "-b"]) # TinyProgProgrammer ------------------------------------------------------------------------------- @@ -108,19 +107,19 @@ class TinyProgProgrammer(GenericProgrammer): if not user_data: # tinyprog looks at spi flash metadata to figure out where to # program your bitstream. - subprocess.call(["tinyprog", "-p", bitstream_file]) + self.call(["tinyprog", "-p", bitstream_file]) else: # Ditto with user data. - subprocess.call(["tinyprog", "-u", bitstream_file]) + self.call(["tinyprog", "-u", bitstream_file]) else: # Provide override so user can program wherever they wish. - subprocess.call(["tinyprog", "-a", str(address), "-p", + self.call(["tinyprog", "-a", str(address), "-p", bitstream_file]) # Force user image to boot if a user reset tinyfpga, the bootloader # is active, and the user image need not be reprogrammed. def boot(self): - subprocess.call(["tinyprog", "-b"]) + self.call(["tinyprog", "-b"]) # MyStormProgrammer -------------------------------------------------------------------------------- @@ -140,4 +139,4 @@ class UJProg(GenericProgrammer): needs_bitreverse = False def load_bitstream(self, bitstream_file): - subprocess.call(["ujprog", bitstream_file]) + self.call(["ujprog", bitstream_file]) diff --git a/litex/build/openfpgaloader.py b/litex/build/openfpgaloader.py index 1d845505c..9d997b242 100644 --- a/litex/build/openfpgaloader.py +++ b/litex/build/openfpgaloader.py @@ -4,8 +4,6 @@ # Copyright (c) 2020 Florent Kermarrec # SPDX-License-Identifier: BSD-2-Clause -import subprocess - from litex.build.tools import write_to_file from litex.build.generic_programmer import GenericProgrammer @@ -21,4 +19,4 @@ class OpenFPGALoader(GenericProgrammer): cmd = ["openFPGALoader", "--board", self.board, "--bitstream", bitstream_file] if flash: cmd.append("--write-flash") - subprocess.call(cmd) + self.call(cmd) diff --git a/litex/build/openocd.py b/litex/build/openocd.py index 4f2b9d48c..d48047ac1 100644 --- a/litex/build/openocd.py +++ b/litex/build/openocd.py @@ -6,8 +6,6 @@ # Copyright (c) 2019 Florent Kermarrec # SPDX-License-Identifier: BSD-2-Clause -import subprocess - from litex.build.tools import write_to_file from litex.build.generic_programmer import GenericProgrammer @@ -26,7 +24,7 @@ class OpenOCD(GenericProgrammer): "pld load 0 {{{}}}".format(bitstream), "exit", ]) - subprocess.call(["openocd", "-f", config, "-c", script]) + self.call(["openocd", "-f", config, "-c", script]) def flash(self, address, data, set_qe=False): config = self.find_config() @@ -39,7 +37,7 @@ class OpenOCD(GenericProgrammer): "fpga_program", "exit" ]) - subprocess.call(["openocd", "-f", config, "-c", script]) + self.call(["openocd", "-f", config, "-c", script]) def stream(self, port=20000): @@ -144,4 +142,4 @@ proc jtagstream_serve {tap port} { "exit", ]) config = self.find_config() - subprocess.call(["openocd", "-f", config, "-f", "stream.cfg", "-c", script]) + self.call(["openocd", "-f", config, "-f", "stream.cfg", "-c", script]) diff --git a/litex/build/xilinx/programmer.py b/litex/build/xilinx/programmer.py index 32d032dc1..c03805cec 100644 --- a/litex/build/xilinx/programmer.py +++ b/litex/build/xilinx/programmer.py @@ -61,11 +61,11 @@ class XC3SProg(GenericProgrammer): self.position = position def load_bitstream(self, bitstream_file): - subprocess.call(["xc3sprog", "-v", "-c", self.cable, "-p", str(self.position), bitstream_file]) + self.call(["xc3sprog", "-v", "-c", self.cable, "-p", str(self.position), bitstream_file]) def flash(self, address, data_file): flash_proxy = self.find_flash_proxy() - subprocess.call(["xc3sprog", "-v", "-c", self.cable, "-p", str(self.position), + self.call(["xc3sprog", "-v", "-c", self.cable, "-p", str(self.position), "-I"+flash_proxy, "{}:w:0x{:x}:BIN".format(data_file, address)]) # FpgaProg ----------------------------------------------------------------------------------------- @@ -77,13 +77,13 @@ class FpgaProg(GenericProgrammer): GenericProgrammer.__init__(self, flash_proxy_basename) def load_bitstream(self, bitstream_file): - subprocess.call(["fpgaprog", "-v", "-f", bitstream_file]) + self.call(["fpgaprog", "-v", "-f", bitstream_file]) def flash(self, address, data_file): if address != 0: raise ValueError("fpga prog needs a main bitstream at address 0") flash_proxy = self.find_flash_proxy() - subprocess.call(["fpgaprog", "-v", "-sa", "-r", "-b", flash_proxy, + self.call(["fpgaprog", "-v", "-sa", "-r", "-b", flash_proxy, "-f", data_file]) # iMPACT ------------------------------------------------------------------------------------------- @@ -200,7 +200,7 @@ class Adept(GenericProgrammer): self.index = index def load_bitstream(self, bitstream_file): - subprocess.call([ + self.call([ "djtgcfg", "--verbose", "prog", "-d", self.board,