generate linker memory map, move all generated files into the same folder
[litex.git] / make.py
diff --git a/make.py b/make.py
index feb0141abfb0930c7ebc3015d75934184d4f7401..fea284f3df503395d51909ee82ecc8082efa80c0 100755 (executable)
--- a/make.py
+++ b/make.py
@@ -1,73 +1,84 @@
 #!/usr/bin/env python3
 
-import argparse, os, importlib, subprocess
+import argparse, importlib, subprocess
 
 from mibuild.tools import write_to_file
 
-from milkymist import cif
-import top, jtag
+from misoclib.gensoc import cpuif
+from misoclib.s6ddrphy import initsequence
+import jtag
 
-def build(platform_name, build_bitstream, build_header, *soc_args, **soc_kwargs):
-       platform_module = importlib.import_module("mibuild.platforms."+platform_name)
-       platform = platform_module.Platform()
-       soc = top.SoC(platform, platform_name, *soc_args, **soc_kwargs)
+def _get_args():
+       parser = argparse.ArgumentParser(description="MiSoC - a high performance SoC based on Migen.")
+
+       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("-s", "--sub-target", default="", help="variant of the SoC type to build")
+       parser.add_argument("-o", "--option", default=[], nargs=2, action="append", help="set target-specific option")
+       parser.add_argument("-Xp", "--external-platform", default="", help="use external platform file in the specified path")
+       parser.add_argument("-Xt", "--external-target", default="", help="use external target file in the specified path")
        
-       platform.add_platform_command("""
-INST "mxcrg/wr_bufpll" LOC = "BUFPLL_X0Y2";
-INST "mxcrg/rd_bufpll" LOC = "BUFPLL_X0Y3";
+       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")
 
-PIN "mxcrg/bufg_x1.O" CLOCK_DEDICATED_ROUTE = FALSE;
-PIN "dviout_pix_bufg.O" CLOCK_DEDICATED_ROUTE = FALSE;
-""")
+       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")
+
+       return parser.parse_args()
+
+def _misoc_import(default, external, name):
+       if external:
+               loader = importlib.find_loader(name, [external])
+               if loader is None:
+                       raise ImportError("Module not found: "+name)
+               return loader.load_module()
+       else:
+               return importlib.import_module(default + "." + name)
 
-       if hasattr(soc, "fb"):
-               platform.add_platform_command("""
-NET "{vga_clk}" TNM_NET = "GRPvga_clk";
-NET "sys_clk" TNM_NET = "GRPsys_clk";
-TIMESPEC "TSise_sucks1" = FROM "GRPvga_clk" TO "GRPsys_clk" TIG;
-TIMESPEC "TSise_sucks2" = FROM "GRPsys_clk" TO "GRPvga_clk" TIG;
-""", vga_clk=soc.fb.driver.clocking.cd_pix.clk)
+def main():
+       args = _get_args()
 
-       for d in ["mxcrg", "minimac3"]:
-               platform.add_source_dir(os.path.join("verilog", d))
-       platform.add_sources(os.path.join("verilog", "lm32", "submodule", "rtl"), 
-               "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
-               "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
-               "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v",
-               "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
-               "lm32_dcache.v", "lm32_top.v", "lm32_debug.v", "lm32_jtag.v", "jtag_cores.v",
-               "jtag_tap_spartan6.v", "lm32_itlb.v", "lm32_dtlb.v")
-       platform.add_sources(os.path.join("verilog", "lm32"), "lm32_config.v")
+       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()
+       if args.sub_target:
+               top_class = getattr(target_module, args.sub_target)
+       else:
+               top_class = target_module.get_default_subtarget(platform)
+       build_name = top_class.__name__.lower() + "-" + args.platform
+       top_kwargs = dict((k, eval(v)) for k, v in args.option)
+       soc = top_class(platform, **top_kwargs)
 
-       if build_bitstream:
-               build_name = "soc-"+platform_name
+       if not args.no_bitstream:
                platform.build(soc, build_name=build_name)
-               subprocess.call(["tools/byteswap", "build/"+build_name+".bin", "build/"+build_name+".fpg"])
+               subprocess.call(["tools/byteswap",
+                       "build/" + build_name + ".bin",
+                       "build/" + build_name + ".fpg"])
        else:
                soc.finalize()
-       if build_header:
-               csr_header = cif.get_csr_header(soc.csr_base, soc.csrbankarray, soc.interrupt_map)
-               write_to_file("software/include/hw/csr.h", csr_header)
-               
-               sdram_phy_header = cif.get_sdram_phy_header(soc.ddrphy)
-               write_to_file("software/include/hw/sdram_phy.h", sdram_phy_header)
-
+       if not args.no_header:
+               boilerplate = """/*
+ * Platform: {}
+ * Target: {}
+ * Subtarget: {}
+ */
 
-def main():
-       parser = argparse.ArgumentParser(description="milkymist-ng - a high performance SoC built on Migen technology.")
-       parser.add_argument("-p", "--platform", default="mixxeo", help="platform to build for")
-       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 defs")
-       parser.add_argument("-l", "--load", default=False, action="store_true", help="load bitstream to SRAM")
-       parser.add_argument("-f", "--flash", default=False, action="store_true", help="load bitstream to flash")
-       parser.add_argument("-m", "--with-memtest", default=False, action="store_true", help="include memtest cores")
-       args = parser.parse_args()
+""".format(args.platform, args.target, top_class.__name__)
+               linker_header = cpuif.get_linker_regions(soc.cpu_memory_regions)
+               write_to_file("software/include/generated/regions.ld", boilerplate + linker_header)
+               csr_header = cpuif.get_csr_header(soc.csr_base, soc.csrbankarray, soc.interrupt_map)
+               write_to_file("software/include/generated/csr.h", boilerplate + csr_header)
+               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:
+               csr_csv = cpuif.get_csr_csv(soc.csr_base, soc.csrbankarray)
+               write_to_file(args.csr_csv, csr_csv)
 
-       build(args.platform, not args.no_bitstream, not args.no_header, args.with_memtest)
        if args.load:
-               jtag.load("build/soc-"+args.platform+".bit")
+               jtag.load("build/" + build_name + ".bit")
        if args.flash:
-               jtag.flash("build/soc-"+args.platform+".fpg")
+               jtag.flash("build/" + build_name + ".fpg")
 
 if __name__ == "__main__":
        main()