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")
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()
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()
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: {}
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")
--- /dev/null
+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)