make build system more generic
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 24 Nov 2013 12:37:32 +0000 (13:37 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sun, 24 Nov 2013 12:37:32 +0000 (13:37 +0100)
make.py
misoclib/gensoc/__init__.py
targets/mlabs_video.py [new file with mode: 0644]
top.py [deleted file]

diff --git a/make.py b/make.py
index e051beae9ece4899633f01c58d17be579fc1a253..f9c8ba95ea903e93263ba871d53d8fccc3066073 100755 (executable)
--- a/make.py
+++ b/make.py
@@ -1,77 +1,69 @@
 #!/usr/bin/env python3
 
-import argparse, os, importlib, subprocess
+import argparse, importlib, subprocess
 
 from mibuild.tools import write_to_file
 
 from misoclib.gensoc import cpuif
 from misoclib.s6ddrphy import initsequence
-import top, jtag
+import jtag
 
-def build(platform_name, build_bitstream, build_header, csr_csv_filename, *soc_args, **soc_kwargs):
-       platform_module = importlib.import_module("mibuild.platforms."+platform_name)
-       platform = platform_module.Platform()
-       soc = top.SoC(platform, *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")
        
-       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")
 
-       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)
+       return parser.parse_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")
+def main():
+       args = _get_args()
 
-       if build_bitstream:
-               build_name = "soc-"+platform_name
+       platform_module = importlib.import_module("mibuild.platforms." + args.platform)
+       target_module = importlib.import_module("targets." + 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
+       soc = top_class(platform)
+
+       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:
+       if not args.no_header:
+               boilerplate = """/*
+ * Platform: {}
+ * Target: {}
+ * Subtarget: {}
+ */
+
+""".format(args.platform, args.target, top_class.__name__)
                csr_header = cpuif.get_csr_header(soc.csr_base, soc.csrbankarray, soc.interrupt_map)
-               write_to_file("software/include/hw/csr.h", csr_header)
-               
+               write_to_file("software/include/hw/csr.h", boilerplate + csr_header)
                sdram_phy_header = initsequence.get_sdram_phy_header(soc.ddrphy)
-               write_to_file("software/include/hw/sdram_phy.h", sdram_phy_header)
-       if csr_csv_filename:
+               write_to_file("software/include/hw/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(csr_csv_filename, csr_csv)
-
-def main():
-       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("-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("-c", "--csr-csv", default="", help="save CSR map in CSV file")
-       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()
+               write_to_file(args.csr_csv, csr_csv)
 
-       build(args.platform, not args.no_bitstream, not args.no_header, args.csr_csv, 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()
index ee2efafa16a13a9cedf8139c5d1609d0f3eb184a..71fe7c6d73fa9708ebe358adf07209e4011a6d78 100644 (file)
@@ -1,3 +1,4 @@
+import os
 from operator import itemgetter
 from collections import defaultdict
 from math import ceil
@@ -51,7 +52,17 @@ class GenSoC(Module):
                self.submodules.uart = uart.UART(platform.request("serial"), clk_freq, baud=115200)
                self.submodules.identifier = identifier.Identifier(self.known_platform_id[platform.name], int(clk_freq),
                        log2_int(l2_size) if l2_size else 0)
-               self.submodules.timer0 = timer.Timer()          
+               self.submodules.timer0 = timer.Timer()
+
+               # add LM32 verilog sources
+               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")
 
        def add_wb_master(self, wbm):
                if self.finalized:
diff --git a/targets/mlabs_video.py b/targets/mlabs_video.py
new file mode 100644 (file)
index 0000000..580bcdb
--- /dev/null
@@ -0,0 +1,147 @@
+import os
+from fractions import Fraction
+
+from migen.fhdl.std import *
+from mibuild.generic_platform import ConstraintError
+
+from misoclib import lasmicon, mxcrg, norflash, s6ddrphy, minimac3, framebuffer, dvisampler, gpio
+from misoclib.gensoc import SDRAMSoC
+
+class _MXClockPads:
+       def __init__(self, platform):
+               self.clk50 = platform.request("clk50")
+               self.trigger_reset = 0
+               try:
+                       self.trigger_reset = platform.request("user_btn", 1)
+               except ConstraintError:
+                       pass
+               self.norflash_rst_n = platform.request("norflash_rst_n")
+               ddram_clock = platform.request("ddram_clock")
+               self.ddr_clk_p = ddram_clock.p
+               self.ddr_clk_n = ddram_clock.n
+               eth_clocks = platform.request("eth_clocks")
+               self.eth_phy_clk = eth_clocks.phy
+               self.eth_rx_clk = eth_clocks.rx
+               self.eth_tx_clk = eth_clocks.tx
+
+class MiniSoC(SDRAMSoC):
+       csr_map = {
+               "minimac":                              10,
+               "fb":                                   11,
+               "dvisampler0":                  12,
+               "dvisampler0_edid_mem": 13,
+               "dvisampler1":                  14,
+               "dvisampler1_edid_mem": 15,
+       }
+       csr_map.update(SDRAMSoC.csr_map)
+
+       interrupt_map = {
+               "minimac":              2,
+               "dvisampler0":  3,
+               "dvisampler1":  4,
+       }
+       interrupt_map.update(SDRAMSoC.interrupt_map)
+
+       def __init__(self, platform, with_memtest=False):
+               SDRAMSoC.__init__(self, platform,
+                       clk_freq=(83 + Fraction(1, 3))*1000000,
+                       sram_size=4096,
+                       l2_size=8192,
+                       with_memtest=with_memtest)
+
+               sdram_geom = lasmicon.GeomSettings(
+                       bank_a=2,
+                       row_a=13,
+                       col_a=10
+               )
+               sdram_timing = lasmicon.TimingSettings(
+                       tRP=self.ns(15),
+                       tRCD=self.ns(15),
+                       tWR=self.ns(15),
+                       tWTR=2,
+                       tREFI=self.ns(7800, False),
+                       tRFC=self.ns(70),
+
+                       req_queue_size=8,
+                       read_time=32,
+                       write_time=16
+               )
+               self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"), memtype="DDR",
+                       nphases=2, cl=3, rd_bitslip=0, wr_bitslip=3, dqs_ddr_alignment="C1")
+               self.create_sdram_modules(self.ddrphy.dfi, self.ddrphy.phy_settings, sdram_geom, sdram_timing)
+
+               # Wishbone
+               self.submodules.norflash = norflash.NorFlash(platform.request("norflash"), 12)
+               self.submodules.minimac = minimac3.MiniMAC(platform.request("eth"))
+               self.add_wb_slave(lambda a: a[26:29] == 0, self.norflash.bus)
+               self.add_wb_slave(lambda a: a[26:29] == 3, self.minimac.membus)
+               
+               # CSR
+               self.submodules.crg = mxcrg.MXCRG(_MXClockPads(platform), self.clk_freq)
+               if platform.name == "mixxeo":
+                       self.submodules.leds = gpio.GPIOOut(platform.request("user_led"))
+               if platform.name == "m1":
+                       self.submodules.buttons = gpio.GPIOIn(Cat(platform.request("user_btn", 0), platform.request("user_btn", 2)))
+                       self.submodules.leds = gpio.GPIOOut(Cat(*[platform.request("user_led", i) for i in range(2)]))
+
+               # Clock glue
+               self.comb += [
+                       self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
+                       self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb)
+               ]
+               platform.add_platform_command("""
+INST "mxcrg/wr_bufpll" LOC = "BUFPLL_X0Y2";
+INST "mxcrg/rd_bufpll" LOC = "BUFPLL_X0Y3";
+
+PIN "mxcrg/bufg_x1.O" CLOCK_DEDICATED_ROUTE = FALSE;
+""")
+
+               # add Verilog sources
+               for d in ["mxcrg", "minimac3"]:
+                       platform.add_source_dir(os.path.join("verilog", d))
+               
+def _get_vga_dvi(platform):
+       try:
+               pads_vga = platform.request("vga_out")
+       except ConstraintError:
+               pads_vga = None
+       try:
+               pads_dvi = platform.request("dvi_out")
+       except ConstraintError:
+               pads_dvi = None
+       else:
+               platform.add_platform_command("""
+PIN "dviout_pix_bufg.O" CLOCK_DEDICATED_ROUTE = FALSE;
+""")
+       return pads_vga, pads_dvi
+
+def _add_vga_tig(platform, 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=fb.driver.clocking.cd_pix.clk)
+
+class FramebufferSoC(MiniSoC):
+       def __init__(self, platform, with_memtest=False):
+               MiniSoC.__init__(self, platform, with_memtest)
+               pads_vga, pads_dvi = _get_vga_dvi(platform)
+               self.submodules.fb = framebuffer.Framebuffer(pads_vga, pads_dvi, self.lasmixbar.get_master())
+               _add_vga_tig(platform, self.fb)
+
+class VideomixerSoC(MiniSoC):
+       def __init__(self, platform, with_memtest=False):
+               MiniSoC.__init__(self, platform, with_memtest)
+               pads_vga, pads_dvi = _get_vga_dvi(platform)
+               self.submodules.fb = framebuffer.MixFramebuffer(pads_vga, pads_dvi,
+                       self.lasmixbar.get_master(), self.lasmixbar.get_master())
+               _add_vga_tig(platform, self.fb)
+               self.submodules.dvisampler0 = dvisampler.DVISampler(platform.request("dvi_in", 0), self.lasmixbar.get_master())
+               self.submodules.dvisampler1 = dvisampler.DVISampler(platform.request("dvi_in", 1), self.lasmixbar.get_master())
+
+def get_default_subtarget(platform):
+       if platform.name == "mixxeo":
+               return VideomixerSoC
+       else:
+               return FramebufferSoC
diff --git a/top.py b/top.py
deleted file mode 100644 (file)
index ecf3074..0000000
--- a/top.py
+++ /dev/null
@@ -1,118 +0,0 @@
-from fractions import Fraction
-
-from migen.fhdl.std import *
-from mibuild.generic_platform import ConstraintError
-
-from misoclib import lasmicon, mxcrg, norflash, s6ddrphy, minimac3, framebuffer, dvisampler, gpio
-from misoclib.gensoc import SDRAMSoC
-
-class _MXClockPads:
-       def __init__(self, platform):
-               self.clk50 = platform.request("clk50")
-               self.trigger_reset = 0
-               try:
-                       self.trigger_reset = platform.request("user_btn", 1)
-               except ConstraintError:
-                       pass
-               self.norflash_rst_n = platform.request("norflash_rst_n")
-               ddram_clock = platform.request("ddram_clock")
-               self.ddr_clk_p = ddram_clock.p
-               self.ddr_clk_n = ddram_clock.n
-               eth_clocks = platform.request("eth_clocks")
-               self.eth_phy_clk = eth_clocks.phy
-               self.eth_rx_clk = eth_clocks.rx
-               self.eth_tx_clk = eth_clocks.tx
-
-class MiniSoC(SDRAMSoC):
-       csr_map = {
-               "minimac":                              10,
-               "fb":                                   11,
-               "dvisampler0":                  12,
-               "dvisampler0_edid_mem": 13,
-               "dvisampler1":                  14,
-               "dvisampler1_edid_mem": 15,
-       }
-       csr_map.update(SDRAMSoC.csr_map)
-
-       interrupt_map = {
-               "minimac":              2,
-               "dvisampler0":  3,
-               "dvisampler1":  4,
-       }
-       interrupt_map.update(SDRAMSoC.interrupt_map)
-
-       def __init__(self, platform, with_memtest):
-               SDRAMSoC.__init__(self, platform,
-                       clk_freq=(83 + Fraction(1, 3))*1000000,
-                       sram_size=4096,
-                       l2_size=8192,
-                       with_memtest=with_memtest)
-
-               sdram_geom = lasmicon.GeomSettings(
-                       bank_a=2,
-                       row_a=13,
-                       col_a=10
-               )
-               sdram_timing = lasmicon.TimingSettings(
-                       tRP=self.ns(15),
-                       tRCD=self.ns(15),
-                       tWR=self.ns(15),
-                       tWTR=2,
-                       tREFI=self.ns(7800, False),
-                       tRFC=self.ns(70),
-
-                       req_queue_size=8,
-                       read_time=32,
-                       write_time=16
-               )
-               self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"), memtype="DDR",
-                       nphases=2, cl=3, rd_bitslip=0, wr_bitslip=3, dqs_ddr_alignment="C1")
-               self.create_sdram_modules(self.ddrphy.dfi, self.ddrphy.phy_settings, sdram_geom, sdram_timing)
-
-               # Wishbone
-               self.submodules.norflash = norflash.NorFlash(platform.request("norflash"), 12)
-               self.submodules.minimac = minimac3.MiniMAC(platform.request("eth"))
-               self.add_wb_slave(lambda a: a[26:29] == 0, self.norflash.bus)
-               self.add_wb_slave(lambda a: a[26:29] == 3, self.minimac.membus)
-               
-               # CSR
-               self.submodules.crg = mxcrg.MXCRG(_MXClockPads(platform), self.clk_freq)
-               if platform.name == "mixxeo":
-                       self.submodules.leds = gpio.GPIOOut(platform.request("user_led"))
-               if platform.name == "m1":
-                       self.submodules.buttons = gpio.GPIOIn(Cat(platform.request("user_btn", 0), platform.request("user_btn", 2)))
-                       self.submodules.leds = gpio.GPIOOut(Cat(*[platform.request("user_led", i) for i in range(2)]))
-
-               # Clock glue
-               self.comb += [
-                       self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
-                       self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb)
-               ]
-               
-def _get_vga_dvi(platform):
-       try:
-               pads_vga = platform.request("vga_out")
-       except ConstraintError:
-               pads_vga = None
-       try:
-               pads_dvi = platform.request("dvi_out")
-       except ConstraintError:
-               pads_dvi = None
-       return pads_vga, pads_dvi
-
-class FramebufferSoC(MiniSoC):
-       def __init__(self, platform, with_memtest):
-               MiniSoC.__init__(self, platform, with_memtest)
-               pads_vga, pads_dvi = _get_vga_dvi(platform)
-               self.submodules.fb = framebuffer.Framebuffer(pads_vga, pads_dvi, self.lasmixbar.get_master())
-
-class VideomixerSoC(MiniSoC):
-       def __init__(self, platform, with_memtest):
-               MiniSoC.__init__(self, platform, with_memtest)
-               pads_vga, pads_dvi = _get_vga_dvi(platform)
-               self.submodules.fb = framebuffer.MixFramebuffer(pads_vga, pads_dvi,
-                       self.lasmixbar.get_master(), self.lasmixbar.get_master())
-               self.submodules.dvisampler0 = dvisampler.DVISampler(platform.request("dvi_in", 0), self.lasmixbar.get_master())
-               self.submodules.dvisampler1 = dvisampler.DVISampler(platform.request("dvi_in", 1), self.lasmixbar.get_master())
-
-SoC = VideomixerSoC