From: Sebastien Bourdeauducq Date: Sun, 24 Nov 2013 12:37:32 +0000 (+0100) Subject: make build system more generic X-Git-Tag: 24jan2021_ls180~2781 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fdff1ae5f85e9597c4c962ae58e08c1b01b4bdf8;p=litex.git make build system more generic --- diff --git a/make.py b/make.py index e051beae..f9c8ba95 100755 --- 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() diff --git a/misoclib/gensoc/__init__.py b/misoclib/gensoc/__init__.py index ee2efafa..71fe7c6d 100644 --- a/misoclib/gensoc/__init__.py +++ b/misoclib/gensoc/__init__.py @@ -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 index 00000000..580bcdba --- /dev/null +++ b/targets/mlabs_video.py @@ -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 index ecf3074f..00000000 --- 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