예제 #1
0
def main():
    description = "Linux on LiteX-VexRiscv\n\n"
    description += "Available boards:\n"
    for name in supported_boards.keys():
        description += "- " + name + "\n"
    parser = argparse.ArgumentParser(description=description, formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("--board",          required=True,            help="FPGA board")
    parser.add_argument("--build",          action="store_true",      help="Build bitstream")
    parser.add_argument("--load",           action="store_true",      help="Load bitstream (to SRAM)")
    parser.add_argument("--flash",          action="store_true",      help="Flash bitstream/images (to SPI Flash)")
    parser.add_argument("--doc",            action="store_true",      help="Build documentation")
    parser.add_argument("--local-ip",       default="192.168.1.50",   help="Local IP address")
    parser.add_argument("--remote-ip",      default="192.168.1.100",  help="Remote IP address of TFTP server")
    parser.add_argument("--spi-data-width", type=int, default=8,      help="SPI data width (maximum transfered bits per xfer)")
    parser.add_argument("--spi-clk-freq",   type=int, default=1e6,    help="SPI clock frequency")
    parser.add_argument("--video",          default="1920x1080_60Hz", help="Video configuration")
    parser.add_argument("--fbi",            action="store_true",      help="Generate fbi images")
    args = parser.parse_args()

    # Board(s) selection ---------------------------------------------------------------------------
    if args.board == "all":
        board_names = list(supported_boards.keys())
    else:
        args.board = args.board.lower()
        args.board = args.board.replace(" ", "_")
        board_names = [args.board]

    # Board(s) iteration ---------------------------------------------------------------------------
    for board_name in board_names:
        board = supported_boards[board_name]()

        # SoC parameters (and override for boards that don't support default parameters) -----------
        soc_kwargs = {}
        soc_kwargs.update(integrated_rom_size=0x8000)
        if board_name in ["de0nano"]:
            soc_kwargs.update(l2_size=2048) # Not enough blockrams for default l2_size of 8192
        if board_name in ["kc705"]:
            soc_kwargs.update(uart_baudrate=500e3) # Set UART baudrate to 500KBauds since 1Mbauds not supported
        if "usb_fifo" in board.soc_capabilities:
            soc_kwargs.update(uart_name="usb_fifo")
        if "usb_acm" in board.soc_capabilities:
            soc_kwargs.update(uart_name="usb_acm")
        if "ethernet" in board.soc_capabilities:
            soc_kwargs.update(with_ethernet=True)

        # SoC creation -----------------------------------------------------------------------------
        soc = SoCLinux(board.soc_cls, **soc_kwargs)
        board.platform = soc.platform

        # SoC peripherals --------------------------------------------------------------------------
        if "spiflash" in board.soc_capabilities:
            soc.add_spi_flash(dummy_cycles=board.SPIFLASH_DUMMY_CYCLES)
            soc.add_constant("SPIFLASH_PAGE_SIZE", board.SPIFLASH_PAGE_SIZE)
            soc.add_constant("SPIFLASH_SECTOR_SIZE", board.SPIFLASH_SECTOR_SIZE)
        if "spisdcard" in board.soc_capabilities:
            soc.add_spi_sdcard()
        if "ethernet" in board.soc_capabilities:
            soc.configure_ethernet(local_ip=args.local_ip, remote_ip=args.remote_ip)
        #if "leds" in board.soc_capabilities:
        #    soc.add_leds()
        if "rgb_led" in board.soc_capabilities:
            soc.add_rgb_led()
        if "switches" in board.soc_capabilities:
            soc.add_switches()
        if "spi" in board.soc_capabilities:
            soc.add_spi(args.spi_data_width, args.spi_clk_freq)
        if "i2c" in board.soc_capabilities:
            soc.add_i2c()
        if "xadc" in board.soc_capabilities:
            soc.add_xadc()
        if "framebuffer" in board.soc_capabilities:
            assert args.video in video_resolutions.keys(), "Unsupported video resolution"
            video_settings = video_resolutions[args.video]
            soc.add_framebuffer(video_settings)
        if "icap_bitstream" in board.soc_capabilities:
            soc.add_icap_bitstream()
        if "mmcm" in board.soc_capabilities:
            soc.add_mmcm(2)
        soc.configure_boot()

        # Build ------------------------------------------------------------------------------------
        build_dir = os.path.join("build", board_name)
        builder   = Builder(soc, output_dir=build_dir, csr_json=os.path.join(build_dir, "csr.json"), bios_options=["TERM_MINI"])
        builder.build(run=args.build)

        # DTS --------------------------------------------------------------------------------------
        soc.generate_dts(board_name)
        soc.compile_dts(board_name)

        # Machine Mode Emulator --------------------------------------------------------------------
        soc.compile_emulator(board_name)

        # Flash Linux images -----------------------------------------------------------------------
        if args.fbi:
            os.system("python3 -m litex.soc.software.mkmscimg buildroot/Image -o buildroot/Image.fbi --fbi --little")
            os.system("python3 -m litex.soc.software.mkmscimg buildroot/rootfs.cpio -o buildroot/rootfs.cpio.fbi --fbi --little")
            os.system("python3 -m litex.soc.software.mkmscimg buildroot/rv32.dtb -o buildroot/rv32.dtb.fbi --fbi --little")
            os.system("python3 -m litex.soc.software.mkmscimg emulator/emulator.bin -o emulator/emulator.bin.fbi --fbi --little")

        # Load FPGA bitstream ----------------------------------------------------------------------
        if args.load:
            board.load()

        # Flash FPGA bitstream ---------------------------------------------------------------------
        if args.flash:
            board.flash()

        # Generate SoC documentation ---------------------------------------------------------------
        if args.doc:
            soc.generate_doc(board_name)
예제 #2
0
def main():
    description = "Linux on LiteX-VexRiscv\n\n"
    description += "Available boards:\n"
    for name in supported_boards.keys():
        description += "- " + name + "\n"
    parser = argparse.ArgumentParser(
        description=description, formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("--board", required=True, help="FPGA board")
    parser.add_argument("--device", default=None, help="FPGA device")
    parser.add_argument("--variant", default=None, help="FPGA board variant")
    parser.add_argument("--toolchain",
                        default=None,
                        help="Toolchain use to build")
    parser.add_argument("--build", action="store_true", help="Build bitstream")
    parser.add_argument("--load",
                        action="store_true",
                        help="Load bitstream (to SRAM)")
    parser.add_argument("--flash",
                        action="store_true",
                        help="Flash bitstream/images (to SPI Flash)")
    parser.add_argument("--doc",
                        action="store_true",
                        help="Build documentation")
    parser.add_argument("--local-ip",
                        default="192.168.1.50",
                        help="Local IP address")
    parser.add_argument("--remote-ip",
                        default="192.168.1.100",
                        help="Remote IP address of TFTP server")
    parser.add_argument(
        "--spi-data-width",
        type=int,
        default=8,
        help="SPI data width (maximum transfered bits per xfer)")
    parser.add_argument("--spi-clk-freq",
                        type=int,
                        default=1e6,
                        help="SPI clock frequency")
    VexRiscvSMP.args_fill(parser)
    args = parser.parse_args()

    # Board(s) selection ---------------------------------------------------------------------------
    if args.board == "all":
        board_names = list(supported_boards.keys())
    else:
        args.board = args.board.lower()
        args.board = args.board.replace(" ", "_")
        board_names = [args.board]

    # Board(s) iteration ---------------------------------------------------------------------------
    for board_name in board_names:
        board = supported_boards[board_name]()
        soc_kwargs = Board.soc_kwargs
        soc_kwargs.update(board.soc_kwargs)

        # CPU parameters ---------------------------------------------------------------------------
        # Do memory accesses through Wishbone and L2 cache when L2 size is configured.
        args.with_wishbone_memory = soc_kwargs["l2_size"] != 0
        VexRiscvSMP.args_read(args)

        # SoC parameters ---------------------------------------------------------------------------
        if args.device is not None:
            soc_kwargs.update(device=args.device)
        if args.variant is not None:
            soc_kwargs.update(variant=args.variant)
        if args.toolchain is not None:
            soc_kwargs.update(toolchain=args.toolchain)
        if "usb_fifo" in board.soc_capabilities:
            soc_kwargs.update(uart_name="usb_fifo")
        if "usb_acm" in board.soc_capabilities:
            soc_kwargs.update(uart_name="usb_acm")
        if "ethernet" in board.soc_capabilities:
            soc_kwargs.update(with_ethernet=True)
        if "sata" in board.soc_capabilities:
            soc_kwargs.update(with_sata=True)
        if "framebuffer" in board.soc_capabilities:
            soc_kwargs.update(with_video_framebuffer=True)

        # SoC creation -----------------------------------------------------------------------------
        soc = SoCLinux(board.soc_cls, **soc_kwargs)
        board.platform = soc.platform

        # SoC peripherals --------------------------------------------------------------------------
        if board_name in ["arty", "arty_a7"]:
            from litex_boards.platforms.arty import _sdcard_pmod_io
            board.platform.add_extension(_sdcard_pmod_io)

        if board_name in ["orangecrab"]:
            from litex_boards.platforms.orangecrab import feather_i2c
            board.platform.add_extension(feather_i2c)

        if "mmcm" in board.soc_capabilities:
            soc.add_mmcm(2)
        if "spiflash" in board.soc_capabilities:
            soc.add_spi_flash(dummy_cycles=board.SPIFLASH_DUMMY_CYCLES)
            soc.add_constant("SPIFLASH_PAGE_SIZE", board.SPIFLASH_PAGE_SIZE)
            soc.add_constant("SPIFLASH_SECTOR_SIZE",
                             board.SPIFLASH_SECTOR_SIZE)
        if "spisdcard" in board.soc_capabilities:
            soc.add_spi_sdcard()
        if "sdcard" in board.soc_capabilities:
            soc.add_sdcard()
        if "ethernet" in board.soc_capabilities:
            soc.configure_ethernet(local_ip=args.local_ip,
                                   remote_ip=args.remote_ip)
        #if "leds" in board.soc_capabilities:
        #    soc.add_leds()
        if "rgb_led" in board.soc_capabilities:
            soc.add_rgb_led()
        if "switches" in board.soc_capabilities:
            soc.add_switches()
        if "spi" in board.soc_capabilities:
            soc.add_spi(args.spi_data_width, args.spi_clk_freq)
        if "i2c" in board.soc_capabilities:
            soc.add_i2c()
        if "xadc" in board.soc_capabilities:
            soc.add_xadc()
        if "icap_bitstream" in board.soc_capabilities:
            soc.add_icap_bitstream()
        soc.configure_boot()

        # Build ------------------------------------------------------------------------------------
        build_dir = os.path.join("build", board_name)
        builder = Builder(soc,
                          output_dir=os.path.join("build", board_name),
                          bios_options=["TERM_MINI"],
                          csr_json=os.path.join(build_dir, "csr.json"),
                          csr_csv=os.path.join(build_dir, "csr.csv"))
        builder.build(run=args.build)

        # DTS --------------------------------------------------------------------------------------
        soc.generate_dts(board_name)
        soc.compile_dts(board_name)

        # Load FPGA bitstream ----------------------------------------------------------------------
        if args.load:
            board.load(
                filename=os.path.join(builder.gateware_dir, soc.build_name +
                                      board.bitstream_ext))

        # Flash bitstream/images (to SPI Flash) ----------------------------------------------------
        if args.flash:
            board.flash(
                filename=os.path.join(builder.gateware_dir, soc.build_name +
                                      board.bitstream_ext))

        # Generate SoC documentation ---------------------------------------------------------------
        if args.doc:
            soc.generate_doc(board_name)
예제 #3
0
def main():
    description = "Linux on LiteX-VexRiscv\n\n"
    description += "Available boards:\n"
    for name in supported_boards.keys():
        description += "- " + name + "\n"
    parser = argparse.ArgumentParser(
        description=description, formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("--board", required=True, help="FPGA board")
    parser.add_argument("--build", action="store_true", help="Build bitstream")
    parser.add_argument("--load",
                        action="store_true",
                        help="Load bitstream (to SRAM)")
    parser.add_argument("--flash",
                        action="store_true",
                        help="Flash bitstream/images (to SPI Flash)")
    parser.add_argument("--doc",
                        action="store_true",
                        help="Build documentation")
    parser.add_argument("--local-ip",
                        default="192.168.1.50",
                        help="Local IP address")
    parser.add_argument("--remote-ip",
                        default="192.168.1.100",
                        help="Remote IP address of TFTP server")
    parser.add_argument(
        "--spi-data-width",
        type=int,
        default=8,
        help="SPI data width (maximum transfered bits per xfer)")
    parser.add_argument("--spi-clk-freq",
                        type=int,
                        default=1e6,
                        help="SPI clock frequency")
    parser.add_argument("--video",
                        default="1920x1080_60Hz",
                        help="Video configuration")
    args = parser.parse_args()

    # Board(s) selection ---------------------------------------------------------------------------
    if args.board == "all":
        board_names = list(supported_boards.keys())
    else:
        args.board = args.board.lower()
        args.board = args.board.replace(" ", "_")
        board_names = [args.board]

    # Board(s) iteration ---------------------------------------------------------------------------
    for board_name in board_names:
        board = supported_boards[board_name]()

        # SoC parameters ---------------------------------------------------------------------------
        board.soc_kwargs.update(integrated_rom_size=0x10000)
        if "usb_fifo" in board.soc_capabilities:
            board.soc_kwargs.update(uart_name="usb_fifo")
        if "usb_acm" in board.soc_capabilities:
            board.soc_kwargs.update(uart_name="usb_acm")
        if "ethernet" in board.soc_capabilities:
            board.soc_kwargs.update(with_ethernet=True)

        # SoC creation -----------------------------------------------------------------------------
        soc = SoCLinux(board.soc_cls, **board.soc_kwargs)
        board.platform = soc.platform

        # SoC peripherals --------------------------------------------------------------------------
        if board_name in ["arty", "arty_a7"]:
            from litex_boards.platforms.arty import _sdcard_pmod_io
            board.platform.add_extension(_sdcard_pmod_io)

        if "mmcm" in board.soc_capabilities:
            soc.add_mmcm(2)
        if "spiflash" in board.soc_capabilities:
            soc.add_spi_flash(dummy_cycles=board.SPIFLASH_DUMMY_CYCLES)
            soc.add_constant("SPIFLASH_PAGE_SIZE", board.SPIFLASH_PAGE_SIZE)
            soc.add_constant("SPIFLASH_SECTOR_SIZE",
                             board.SPIFLASH_SECTOR_SIZE)
        if "spisdcard" in board.soc_capabilities:
            soc.add_spi_sdcard()
        if "sdcard" in board.soc_capabilities:
            soc.add_sdcard()
        if "ethernet" in board.soc_capabilities:
            soc.configure_ethernet(local_ip=args.local_ip,
                                   remote_ip=args.remote_ip)
        #if "leds" in board.soc_capabilities:
        #    soc.add_leds()
        if "rgb_led" in board.soc_capabilities:
            soc.add_rgb_led()
        if "switches" in board.soc_capabilities:
            soc.add_switches()
        if "spi" in board.soc_capabilities:
            soc.add_spi(args.spi_data_width, args.spi_clk_freq)
        if "i2c" in board.soc_capabilities:
            soc.add_i2c()
        if "xadc" in board.soc_capabilities:
            soc.add_xadc()
        if "framebuffer" in board.soc_capabilities:
            assert args.video in video_resolutions.keys(
            ), "Unsupported video resolution"
            video_settings = video_resolutions[args.video]
            soc.add_framebuffer(video_settings)
        if "icap_bitstream" in board.soc_capabilities:
            soc.add_icap_bitstream()
        soc.configure_boot()

        # Build ------------------------------------------------------------------------------------
        build_dir = os.path.join("build", board_name)
        builder = Builder(soc,
                          output_dir=build_dir,
                          csr_json=os.path.join(build_dir, "csr.json"),
                          bios_options=["TERM_MINI"])
        builder.build(build_name="top", run=args.build)

        # DTS --------------------------------------------------------------------------------------
        soc.generate_dts(board_name)
        soc.compile_dts(board_name)

        # Machine Mode Emulator --------------------------------------------------------------------
        soc.compile_emulator(board_name)

        # Load FPGA bitstream ----------------------------------------------------------------------
        if args.load:
            board.load()

        # Flash FPGA bitstream ---------------------------------------------------------------------
        if args.flash:
            board.flash()

        # Generate SoC documentation ---------------------------------------------------------------
        if args.doc:
            soc.generate_doc(board_name)
예제 #4
0
def main():
    description = "Linux on LiteX-VexRiscv\n\n"
    description += "Available boards:\n"
    for name in supported_boards.keys():
        description += "- " + name + "\n"
    parser = argparse.ArgumentParser(description=description, formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("--board",        required=True,            help="FPGA board")
    parser.add_argument("--build",        action="store_true",      help="Build bitstream")
    parser.add_argument("--load",         action="store_true",      help="Load bitstream (to SRAM)")
    parser.add_argument("--flash",        action="store_true",      help="Flash bitstream/images (to SPI Flash)")
    parser.add_argument("--doc",          action="store_true",      help="Build documentation")
    parser.add_argument("--local-ip",     default="192.168.1.50",   help="Local IP address")
    parser.add_argument("--remote-ip",    default="192.168.1.100",  help="Remote IP address of TFTP server")
    parser.add_argument("--spi-bpw",      type=int, default=8,      help="Bits per word for SPI controller")
    parser.add_argument("--spi-sck-freq", type=int, default=1e6,    help="SPI clock frequency")
    parser.add_argument("--video",        default="1920x1080_60Hz", help="Video configuration")
    parser.add_argument("--fbi",          action="store_true",      help="Generate fbi images")
    args = parser.parse_args()

    if args.board == "all":
        board_names = list(supported_boards.keys())
    else:
        args.board = args.board.lower()
        args.board = args.board.replace(" ", "_")
        board_names = [args.board]
    for board_name in board_names:
        board = supported_boards[board_name]()
        soc_kwargs = {"integrated_rom_size": 0x8000}
        if board_name in ["de0nano"]:
            soc_kwargs["l2_size"] = 2048 # Not enough blockrams for default l2_size of 8192
        if board_name in ["kc705"]:
            soc_kwargs["uart_baudrate"] = 500e3 # Set UART baudrate to 500KBauds since 1Mbauds not supported
        soc = SoCLinux(board.soc_cls, **soc_kwargs)
        if "spiflash" in board.soc_capabilities:
            soc.add_spi_flash(dummy_cycles=board.SPIFLASH_DUMMY_CYCLES)
            soc.add_constant("SPIFLASH_PAGE_SIZE", board.SPIFLASH_PAGE_SIZE)
            soc.add_constant("SPIFLASH_SECTOR_SIZE", board.SPIFLASH_SECTOR_SIZE)
        if "ethernet" in board.soc_capabilities:
            soc.configure_ethernet(local_ip=args.local_ip, remote_ip=args.remote_ip)
        if "leds" in board.soc_capabilities:
            soc.add_leds()
        if "rgb_led" in board.soc_capabilities:
            soc.add_rgb_led()
        if "switches" in board.soc_capabilities:
            soc.add_switches()
        if "spi" in board.soc_capabilities:
            soc.add_spi(args.spi_bpw, args.spi_sck_freq)
        if "i2c" in board.soc_capabilities:
            soc.add_i2c()
        if "xadc" in board.soc_capabilities:
            soc.add_xadc()
        if "framebuffer" in board.soc_capabilities:
            assert args.video in video_resolutions.keys(), "Unsupported video resolution"
            video_settings = video_resolutions[args.video]
            soc.add_framebuffer(video_settings)
        if "icap_bit" in board.soc_capabilities:
            soc.add_icap_bitstream()
        if "mmcm" in board.soc_capabilities:
            soc.add_mmcm()
        soc.configure_boot()

        build_dir = os.path.join("build", board_name)
        if args.build:
            builder = Builder(soc, output_dir=build_dir,
                csr_json=os.path.join(build_dir, "csr.json"))
        else:
            builder = Builder(soc, output_dir="build/" + board_name,
                compile_software=True, compile_gateware=False,
                csr_json=os.path.join(build_dir, "csr.json"))
        builder.build()

        soc.generate_dts(board_name)
        soc.compile_dts(board_name)
        soc.compile_emulator(board_name)

        if args.fbi:
            os.system("python3 -m litex.soc.software.mkmscimg buildroot/Image -o buildroot/Image.fbi --fbi --little")
            os.system("python3 -m litex.soc.software.mkmscimg buildroot/rootfs.cpio -o buildroot/rootfs.cpio.fbi --fbi --little")
            os.system("python3 -m litex.soc.software.mkmscimg buildroot/rv32.dtb -o buildroot/rv32.dtb.fbi --fbi --little")
            os.system("python3 -m litex.soc.software.mkmscimg emulator/emulator.bin -o emulator/emulator.bin.fbi --fbi --little")

        if args.load:
            board.load()

        if args.flash:
            board.flash()

        if args.doc:
            soc.generate_doc(board_name)
예제 #5
0
def main():
    description = "Linux on LiteX-VexRiscv\n\n"
    description += "Available boards:\n"
    for name in supported_boards.keys():
        description += "- " + name + "\n"
    parser = argparse.ArgumentParser(
        description=description, formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("--board", required=True, help="FPGA board")
    parser.add_argument("--build", action="store_true", help="build bitstream")
    parser.add_argument("--load",
                        action="store_true",
                        help="load bitstream (to SRAM)")
    parser.add_argument("--flash",
                        action="store_true",
                        help="flash bitstream/images (to SPI Flash)")
    parser.add_argument("--local-ip",
                        default="192.168.1.50",
                        help="local IP address")
    parser.add_argument("--remote-ip",
                        default="192.168.1.100",
                        help="remote IP address of TFTP server")
    parser.add_argument("--spi-bpw",
                        type=int,
                        default=8,
                        help="Bits per word for SPI controller")
    parser.add_argument("--spi-sck-freq",
                        type=int,
                        default=1e6,
                        help="SPI clock frequency")
    args = parser.parse_args()

    if args.board == "all":
        board_names = list(supported_boards.keys())
    else:
        args.board = args.board.lower()
        args.board = args.board.replace(" ", "_")
        board_names = [args.board]
    for board_name in board_names:
        board = supported_boards[board_name]()
        soc_kwargs = {}
        if board_name in ["versa_ecp5", "ulx3s"]:
            soc_kwargs["toolchain"] = "trellis"
            soc_kwargs["cpu_variant"] = "linux+no-dsp"
        if board_name in ["de0nano"]:
            soc_kwargs[
                "l2_size"] = 1024  # FIXME: Reduce l2_size, blockram not infered correctly?
        soc = SoCLinux(board.soc_cls, **soc_kwargs)
        if "spiflash" in board.soc_capabilities:
            soc.add_spi_flash()
            soc.add_constant("SPIFLASH_PAGE_SIZE", board.SPIFLASH_PAGE_SIZE)
            soc.add_constant("SPIFLASH_SECTOR_SIZE",
                             board.SPIFLASH_SECTOR_SIZE)
        if "ethernet" in board.soc_capabilities:
            soc.configure_ethernet(local_ip=args.local_ip,
                                   remote_ip=args.remote_ip)
        if "leds" in board.soc_capabilities:
            soc.add_leds()
        if "rgb_led" in board.soc_capabilities:
            soc.add_rgb_led()
        if "switches" in board.soc_capabilities:
            soc.add_switches()
        if "spi" in board.soc_capabilities:
            soc.add_spi(args.spi_bpw, args.spi_sck_freq)
        if "i2c" in board.soc_capabilities:
            soc.add_i2c()
        if "xadc" in board.soc_capabilities:
            soc.add_xadc()
        if "framebuffer" in board.soc_capabilities:
            soc.add_framebuffer()
        if "icap_bit" in board.soc_capabilities:
            soc.add_icap_bitstream()
        soc.configure_boot()

        build_dir = os.path.join("build", board_name)
        if args.build:
            builder = Builder(soc,
                              output_dir=build_dir,
                              csr_json=os.path.join(build_dir, "csr.json"))
        else:
            builder = Builder(soc,
                              output_dir="build/" + board_name,
                              compile_software=True,
                              compile_gateware=False,
                              csr_json=os.path.join(build_dir, "csr.json"))
        builder.build()

        soc.generate_dts(board_name)
        soc.compile_dts(board_name)
        soc.compile_emulator(board_name)

        if args.load:
            board.load()

        if args.flash:
            board.flash()
예제 #6
0
파일: make.py 프로젝트: diegoa314/daphne
def main():
    description = "Linux on LiteX-VexRiscv\n\n"
    description += "Available boards:\n"
    for name in supported_boards.keys():
        description += "- " + name + "\n"
    parser = argparse.ArgumentParser(
        description=description, formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("--board", required=True, help="FPGA board")
    parser.add_argument("--build", action="store_true", help="build bitstream")
    parser.add_argument("--load",
                        action="store_true",
                        help="load bitstream (to SRAM)")
    parser.add_argument("--flash",
                        action="store_true",
                        help="flash bitstream/images (to SPI Flash)")
    parser.add_argument("--local-ip",
                        default="192.168.1.50",
                        help="local IP address")
    parser.add_argument("--remote-ip",
                        default="192.168.1.100",
                        help="remote IP address of TFTP server")
    parser.add_argument("--spi-bpw",
                        type=int,
                        default=8,
                        help="Bits per word for SPI controller")
    parser.add_argument("--spi-sck-freq",
                        type=int,
                        default=1e6,
                        help="SPI clock frequency")
    parser.add_argument("--video",
                        default="1920x1080_60Hz",
                        help="video configuration")
    args = parser.parse_args()

    if args.board == "all":
        board_names = list(supported_boards.keys())
    else:
        args.board = args.board.lower()
        args.board = args.board.replace(" ", "_")
        board_names = [args.board]
    for board_name in board_names:
        board = supported_boards[board_name]()
        soc_kwargs = {"integrated_rom_size": 0x8000}
        if board_name in ["versa_ecp5", "ulx3s", "hadbadge", "orangecrab"]:
            soc_kwargs["toolchain"] = "trellis"
        if board_name in ["de0nano"]:
            soc_kwargs[
                "l2_size"] = 2048  # Not enough blockrams for default l2_size of 8192
        soc = SoCLinux(board.soc_cls, **soc_kwargs)
        if "spiflash" in board.soc_capabilities:
            soc.add_spi_flash()
            soc.add_constant("SPIFLASH_PAGE_SIZE", board.SPIFLASH_PAGE_SIZE)
            soc.add_constant("SPIFLASH_SECTOR_SIZE",
                             board.SPIFLASH_SECTOR_SIZE)
        if "ethernet" in board.soc_capabilities:
            soc.configure_ethernet(local_ip=args.local_ip,
                                   remote_ip=args.remote_ip)
        if "leds" in board.soc_capabilities:
            soc.add_leds()
        if "rgb_led" in board.soc_capabilities:
            soc.add_rgb_led()
        if "switches" in board.soc_capabilities:
            soc.add_switches()
        if "spi" in board.soc_capabilities:
            soc.add_spi(args.spi_bpw, args.spi_sck_freq)
        if "i2c" in board.soc_capabilities:
            soc.add_i2c()
        if "xadc" in board.soc_capabilities:
            soc.add_xadc()
        if "framebuffer" in board.soc_capabilities:
            assert args.video in video_resolutions.keys(
            ), "Unsupported video resolution"
            video_settings = video_resolutions[args.video]
            soc.add_framebuffer(video_settings)
        if "icap_bit" in board.soc_capabilities:
            soc.add_icap_bitstream()
        soc.configure_boot()

        build_dir = os.path.join("build", board_name)
        if args.build:
            builder = Builder(soc,
                              output_dir=build_dir,
                              csr_json=os.path.join(build_dir, "csr.json"))
        else:
            builder = Builder(soc,
                              output_dir="build/" + board_name,
                              compile_software=True,
                              compile_gateware=False,
                              csr_json=os.path.join(build_dir, "csr.json"))
        if board_name == "camlink_4k":  # FIXME
            builder.build("/usr/local/diamond/3.10_x64/bin/lin64")
        else:
            builder.build()

        soc.generate_dts(board_name)
        soc.compile_dts(board_name)
        soc.compile_emulator(board_name)

        if args.load:
            board.load()

        if args.flash:
            board.flash()