From f55943ae18b9bbc6504e0ddd3612de824916876d Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sat, 15 Feb 2014 14:01:50 +0100 Subject: [PATCH] new action syntax for make.py + support xc3sprog --- jtag.py | 20 -------- make.py | 114 +++++++++++++++++++++++++++++------------ programmer.py | 65 +++++++++++++++++++++++ software/bios/Makefile | 5 +- 4 files changed, 146 insertions(+), 58 deletions(-) delete mode 100644 jtag.py create mode 100644 programmer.py diff --git a/jtag.py b/jtag.py deleted file mode 100644 index 853cf710..00000000 --- a/jtag.py +++ /dev/null @@ -1,20 +0,0 @@ -import subprocess - -cables = { - "mixxeo": "milkymist", - "m1": "milkymist", - "papilio_pro": "Flyswatter" -} - -def load(platform_name, bitstream): - cmds = """cable {cable} -detect -pld load {bitstream} -quit -""".format(cable=cables[platform_name], bitstream=bitstream) - process = subprocess.Popen("jtag", stdin=subprocess.PIPE) - process.stdin.write(cmds.encode("ASCII")) - process.communicate() - -def flash(bitstream): - subprocess.call(["m1nor-ng", bitstream]) diff --git a/make.py b/make.py index 1c030b66..3932860d 100755 --- a/make.py +++ b/make.py @@ -8,10 +8,30 @@ from migen.fhdl import simplify from misoclib.gensoc import cpuif from misoclib.s6ddrphy import initsequence -import jtag +import programmer def _get_args(): - parser = argparse.ArgumentParser(description="MiSoC - a high performance and small footprint SoC based on Migen.") + parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, + description="""\ +MiSoC - a high performance and small footprint SoC based on Migen. + +This program builds and/or loads MiSoC components. +One or several actions can be specified: + +build-bitstream build FPGA bitstream. Implies build-bios on targets with + integrated BIOS. +build-headers build software header files with CSR/IRQ/SDRAM_PHY definitions. +build-csr-csv save CSR map into CSV file. +build-bios build BIOS. Implies build-header. + +load-bitstream load bitstream into volatile storage. +flash-bitstream load bitstream into non-volatile storage. +flash-bios load BIOS into non-volatile storage. + +all build-bitstream, build-bios, flash-bitstream, flash-bios. + +Load/flash actions use the existing outputs, and do not trigger new builds. +""") parser.add_argument("-p", "--platform", default="mixxeo", help="platform to build for") parser.add_argument("-t", "--target", default="mlabs_video", help="SoC type to build") @@ -22,12 +42,8 @@ def _get_args(): parser.add_argument("-d", "--decorate", default=[], action="append", help="apply simplification decorator to top-level") parser.add_argument("-Ob", "--build-option", default=[], nargs=2, action="append", help="set build option") - parser.add_argument("-B", "--no-bitstream", default=False, action="store_true", help="do not build bitstream file") - parser.add_argument("-H", "--no-header", default=False, action="store_true", help="do not build C header files with CSR/IRQ/SDRAM_PHY definitions") - parser.add_argument("-c", "--csr-csv", default="", help="save CSR map into CSV file") - parser.add_argument("-l", "--load", default=False, action="store_true", help="load bitstream to FPGA volatile memory") - parser.add_argument("-f", "--flash", default=False, action="store_true", help="load bitstream to flash") + parser.add_argument("action", nargs="+", help="specify an action") return parser.parse_args() @@ -44,9 +60,10 @@ def _misoc_import(default, external, name): else: return importlib.import_module(default + "." + name) -def main(): +if __name__ == "__main__": args = _get_args() + # create top-level SoC object platform_module = _misoc_import("mibuild.platforms", args.external_platform, args.platform) target_module = _misoc_import("targets", args.external_target, args.target) platform = platform_module.Platform() @@ -57,10 +74,33 @@ def main(): build_name = top_class.__name__.lower() + "-" + args.platform top_kwargs = dict((k, autotype(v)) for k, v in args.target_option) soc = top_class(platform, **top_kwargs) - soc.finalize() - if not args.no_header: + # decode actions + action_list = ["build-bitstream", "build-headers", "build-csr-csv", "build-bios", + "load-bitstream", "flash-bitstream", "flash-bios", "all"] + actions = {k: False for k in action_list} + for action in args.action: + if action in actions: + actions[action] = True + else: + print("Unknown action: "+action+". Valid actions are:") + for a in action_list: + print(" "+a) + sys.exit(1) + + # dependencies + if actions["all"]: + actions["build-bitstream"] = True + actions["build-bios"] = True + actions["flash-bitstream"] = True + actions["flash-bios"] = True + if actions["build-bitstream"] and hasattr(soc, "init_bios_memory"): + actions["build-bios"] = True + if actions["build-bios"]: + actions["build-headers"] = True + + if actions["build-headers"]: boilerplate = """/* * Platform: {} * Target: {} @@ -75,38 +115,44 @@ def main(): if hasattr(soc, "ddrphy"): sdram_phy_header = initsequence.get_sdram_phy_header(soc.ddrphy) write_to_file("software/include/generated/sdram_phy.h", boilerplate + sdram_phy_header) - if args.csr_csv: + + if actions["build-csr-csv"]: csr_csv = cpuif.get_csr_csv(soc.csr_base, soc.csrbankarray) write_to_file(args.csr_csv, csr_csv) - if hasattr(soc, "init_bios_memory"): + if actions["build-bios"]: ret = subprocess.call(["make", "-C", "software/bios"]) if ret: raise OSError("BIOS build failed") - bios_file = open("software/bios/bios.bin", "rb") - bios_data = [] - while True: - w = bios_file.read(4) - if not w: - break - bios_data.append(struct.unpack(">I", w)[0]) - bios_file.close() - soc.init_bios_memory(bios_data) - for decorator in args.decorate: - soc = getattr(simplify, decorator)(soc) + if hasattr(soc, "init_bios_memory"): + with open("software/bios/bios.bin", "rb") as bios_file: + bios_data = [] + while True: + w = bios_file.read(4) + if not w: + break + bios_data.append(struct.unpack(">I", w)[0]) + soc.init_bios_memory(bios_data) - if not args.no_bitstream: + if actions["build-bitstream"]: + for decorator in args.decorate: + soc = getattr(simplify, decorator)(soc) build_kwargs = dict((k, autotype(v)) for k, v in args.build_option) platform.build(soc, build_name=build_name, **build_kwargs) - subprocess.call(["tools/byteswap", - "build/" + build_name + ".bin", - "build/" + build_name + ".fpg"]) - - if args.load: - jtag.load(platform.name, "build/" + build_name + ".bit") - if args.flash: - jtag.flash("build/" + build_name + ".fpg") -if __name__ == "__main__": - main() + if actions["load-bitstream"] or actions["flash-bitstream"] or actions["flash-bios"]: + prog = programmer.create_programmer(platform.name, None) + if actions["load-bitstream"]: + prog.load_bitstream("build/" + build_name + ".bit") + if actions["flash-bitstream"]: + if prog.needs_bitreverse: + flashbit = "build/" + build_name + ".fpg" + subprocess.call(["tools/byteswap", + "build/" + build_name + ".bin", + flashbit]) + else: + flashbit = "build/" + build_name + ".bin" + prog.flash(0, flashbit) + if actions["flash-bios"]: + prog.flash(soc.cpu_reset_address, "software/bios/bios.bin") diff --git a/programmer.py b/programmer.py new file mode 100644 index 00000000..7615fdea --- /dev/null +++ b/programmer.py @@ -0,0 +1,65 @@ +import subprocess +import os + +class Programmer: + def __init__(self, platform_name, flash_proxy_dir): + self.platform_name = platform_name + self.flash_proxy_dir = flash_proxy_dir + + def find_flash_proxy(self, name): + if self.flash_proxy_dir is not None: + search_dirs = [self.flash_proxy_dir] + else: + search_dirs = ["~/.mlabs", "/usr/local/share/mlabs", "/usr/share/mlabs"] + for d in search_dirs: + fulldir = os.path.abspath(os.path.expanduser(d)) + fullname = os.path.join(fulldir, name) + if os.path.exists(fullname): + return fullname + raise OSError("Failed to find flash proxy bitstream") + +def _run_urjtag(cmds): + with subprocess.Popen("jtag", stdin=subprocess.PIPE) as process: + process.stdin.write(cmds.encode("ASCII")) + process.communicate() + +class UrJTAG(Programmer): + needs_bitreverse = True + + def load_bitstream(self, bitstream_file): + cmds = """cable milkymist +detect +pld load {bitstream} +quit +""".format(bitstream=bitstream_file) + _run_urjtag(cmds) + + def flash(self, address, data_file): + flash_proxy = self.find_flash_proxy("fjmem-" + self.platform_name + ".bit") + cmds = """cable milkymist +detect +pld load "{flash_proxy}" +initbus fjmem opcode=000010 +frequency 6000000 +detectflash 0 +endian big +flashmem "{address}" "{data_file}" noverify +""".format(flash_proxy=flash_proxy, address=address, data_file=data_file) + _run_urjtag(cmds) + +class XC3SProg(Programmer): + needs_bitreverse = False + + def load_bitstream(self, bitstream_file): + subprocess.call(["xc3sprog", "-c", "papilio", bitstream_file]) + + def flash(self, address, data_file): + flash_proxy = self.find_flash_proxy("bscan_spi_lx9_papilio.bit") + subprocess.call(["xc3sprog", "-c", "papilio", "-I"+flash_proxy, "{}:w:0x{:x}:BIN".format(data_file, address)]) + +def create_programmer(platform_name, *args, **kwargs): + return { + "mixxeo": UrJTAG, + "m1": UrJTAG, + "papilio_pro": XC3SProg + }[platform_name](platform_name, *args, **kwargs) diff --git a/software/bios/Makefile b/software/bios/Makefile index f6d45b87..719314bd 100644 --- a/software/bios/Makefile +++ b/software/bios/Makefile @@ -40,10 +40,7 @@ libs: $(MAKE) -C $(MSCDIR)/software/libbase $(MAKE) -C $(MSCDIR)/software/libnet -flash: bios.bin - m1nor-ng bios.bin - clean: $(RM) $(OBJECTS) $(OBJECTS:.o=.d) bios.elf bios.bin .*~ *~ -.PHONY: all main.o clean libs flash +.PHONY: all main.o clean libs -- 2.30.2