| #!/usr/bin/env python3 |
| |
| import argparse |
| import os |
| |
| from litex.soc.integration.builder import Builder |
| |
| from linux.soc_linux import SoCLinux, video_resolutions |
| |
| kB = 1024 |
| |
| # Board definition---------------------------------------------------------------------------------- |
| |
| |
| class Board: |
| soc_kwargs = {"integrated_rom_size": 0x10000, "sys_clk_freq": int(60e6)} |
| |
| def __init__(self, soc_cls=None, soc_capabilities={}, bitstream_ext=""): |
| self.soc_cls = soc_cls |
| self.soc_capabilities = soc_capabilities |
| self.bitstream_ext = bitstream_ext |
| |
| def load(self, filename): |
| prog = self.platform.create_programmer() |
| prog.load_bitstream(filename) |
| |
| def flash(self): |
| raise NotImplementedError |
| |
| |
| # Arty support ------------------------------------------------------------------------------------- |
| |
| |
| class Arty(Board): |
| SPIFLASH_PAGE_SIZE = 256 |
| SPIFLASH_SECTOR_SIZE = 64 * kB |
| SPIFLASH_DUMMY_CYCLES = 11 |
| |
| def __init__(self): |
| from litex_boards.targets import arty |
| Board.__init__( |
| self, |
| arty.BaseSoC, |
| soc_capabilities={ |
| # Communication |
| "serial", |
| "ethernet", |
| # Storage |
| "spiflash", |
| # "sdcard", |
| # GPIOs |
| "leds", |
| "rgb_led", |
| "switches", |
| # Buses |
| "spi", |
| "i2c", |
| # Monitoring |
| # "xadc", |
| # 7-Series specific |
| # "mmcm", |
| # "icap_bitstream", |
| }, |
| bitstream_ext=".bit" |
| ) |
| |
| |
| class ArtyA7(Arty): |
| SPIFLASH_DUMMY_CYCLES = 7 |
| |
| |
| # Main --------------------------------------------------------------------------------------------- |
| |
| supported_boards = { |
| # Xilinx |
| "a7-35": ArtyA7, |
| "a7-100": ArtyA7, |
| } |
| |
| |
| 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("--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("--builddir", default="build", help="Build directory") |
| 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 --------------------------------------------------------------------------- |
| soc_kwargs = Board.soc_kwargs |
| soc_kwargs.update(board.soc_kwargs) |
| if args.device is not None: |
| soc_kwargs.update(device=args.device) |
| 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 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 = args.builddir |
| 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) |
| |
| # Don't build the devicetree or emulator in arch-defs |
| # DTS -------------------------------------------------------------------------------------- |
| # soc.generate_dts(build_dir, board_name) |
| # soc.compile_dts(build_dir, board_name) |
| |
| # Machine Mode Emulator -------------------------------------------------------------------- |
| # soc.compile_emulator(build_dir) |
| |
| # Load FPGA bitstream ---------------------------------------------------------------------- |
| if args.load: |
| board.load( |
| filename=os.path.join( |
| build_dir, board_name, "gateware", "top" + |
| board.bitstream_ext |
| ) |
| ) |
| |
| # Generate SoC documentation --------------------------------------------------------------- |
| if args.doc: |
| soc.generate_doc(board_name) |
| |
| |
| if __name__ == "__main__": |
| main() |