You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
264 lines
9.9 KiB
264 lines
9.9 KiB
5 years ago
|
#!/usr/bin/env python3
|
||
|
|
||
|
import argparse
|
||
|
import os
|
||
|
|
||
|
from litex.soc.integration.builder import Builder
|
||
|
|
||
|
from soc_linux import SoCLinux
|
||
|
|
||
|
kB = 1024
|
||
|
|
||
|
# Board definition----------------------------------------------------------------------------------
|
||
|
|
||
|
class Board:
|
||
|
def __init__(self, soc_cls, soc_capabilities):
|
||
|
self.soc_cls = soc_cls
|
||
|
self.soc_capabilities = soc_capabilities
|
||
|
|
||
|
def load(self):
|
||
|
raise NotImplementedError
|
||
|
|
||
|
def flash(self):
|
||
|
raise NotImplementedError
|
||
|
|
||
|
# Arty support -------------------------------------------------------------------------------------
|
||
|
|
||
|
class Arty(Board):
|
||
|
SPIFLASH_PAGE_SIZE = 256
|
||
|
SPIFLASH_SECTOR_SIZE = 64*kB
|
||
|
def __init__(self):
|
||
|
from litex_boards.targets import arty
|
||
|
Board.__init__(self, arty.EthernetSoC, {"serial", "ethernet", "spiflash", "leds", "switches", "spi", "i2c", "xadc"})
|
||
|
|
||
|
def load(self):
|
||
|
from litex.build.openocd import OpenOCD
|
||
|
prog = OpenOCD("prog/openocd_xilinx.cfg")
|
||
|
prog.load_bitstream("build/arty/gateware/top.bit")
|
||
|
|
||
|
def flash(self):
|
||
|
flash_regions = {
|
||
|
"build/arty/gateware/top.bin": "0x00000000", # FPGA image: loaded at startup
|
||
|
"buildroot/Image": "0x00400000", # Linux Image: copied to 0xc0000000 by bios
|
||
|
"buildroot/rootfs.cpio": "0x00800000", # File System: copied to 0xc0800000 by bios
|
||
|
"buildroot/rv32.dtb": "0x00f00000", # Device tree: copied to 0xc1000000 by bios
|
||
|
"emulator/emulator.bin": "0x00f80000", # MM Emulator: copied to 0x20000000 by bios
|
||
|
}
|
||
|
from litex.build.openocd import OpenOCD
|
||
|
prog = OpenOCD("prog/openocd_xilinx.cfg",
|
||
|
flash_proxy_basename="prog/bscan_spi_xc7a35t.bit")
|
||
|
prog.set_flash_proxy_dir(".")
|
||
|
for filename, base in flash_regions.items():
|
||
|
base = int(base, 16)
|
||
|
print("Flashing {} at 0x{:08x}".format(filename, base))
|
||
|
prog.flash(base, filename)
|
||
|
|
||
|
# NeTV2 support ------------------------------------------------------------------------------------
|
||
|
|
||
|
class NeTV2(Board):
|
||
|
SPIFLASH_PAGE_SIZE = 256
|
||
|
SPIFLASH_SECTOR_SIZE = 64*kB
|
||
|
def __init__(self):
|
||
|
from litex_boards.targets import netv2
|
||
|
Board.__init__(self, netv2.EthernetSoC, {"serial", "ethernet", "framebuffer", "spiflash", "leds", "xadc"})
|
||
|
|
||
|
def load(self):
|
||
|
from litex.build.openocd import OpenOCD
|
||
|
prog = OpenOCD("prog/openocd_netv2_rpi.cfg")
|
||
|
prog.load_bitstream("build/netv2/gateware/top.bit")
|
||
|
|
||
|
# Genesys2 support ---------------------------------------------------------------------------------
|
||
|
|
||
|
class Genesys2(Board):
|
||
|
def __init__(self):
|
||
|
from litex_boards.targets import genesys2
|
||
|
Board.__init__(self, genesys2.BaseSoC, {"serial"})
|
||
|
|
||
|
def load(self):
|
||
|
from litex.build.xilinx import VivadoProgrammer
|
||
|
prog = VivadoProgrammer()
|
||
|
prog.load_bitstream("build/genesys2/gateware/top.bit")
|
||
|
|
||
|
# KCU105 support -----------------------------------------------------------------------------------
|
||
|
|
||
|
class KCU105(Board):
|
||
|
def __init__(self):
|
||
|
from litex_boards.targets import kcu105
|
||
|
Board.__init__(self, kcu105.EthernetSoC, {"serial", "ethernet"})
|
||
|
|
||
|
def load(self):
|
||
|
from litex.build.xilinx import VivadoProgrammer
|
||
|
prog = VivadoProgrammer()
|
||
|
prog.load_bitstream("build/kcu105/gateware/top.bit")
|
||
|
|
||
|
|
||
|
# Nexys4DDR support --------------------------------------------------------------------------------
|
||
|
|
||
|
class Nexys4DDR(Board):
|
||
|
def __init__(self):
|
||
|
from litex_boards.targets import nexys4ddr
|
||
|
Board.__init__(self, nexys4ddr.EthernetSoC, {"serial", "ethernet"})
|
||
|
|
||
|
def load(self):
|
||
|
from litex.build.xilinx import VivadoProgrammer
|
||
|
prog = VivadoProgrammer()
|
||
|
prog.load_bitstream("build/nexys4ddr/gateware/top.bit")
|
||
|
|
||
|
# NexysVideo support --------------------------------------------------------------------------------
|
||
|
|
||
|
class NexysVideo(Board):
|
||
|
def __init__(self):
|
||
|
from litex_boards.targets import nexys_video
|
||
|
Board.__init__(self, nexys_video.EthernetSoC, {"serial", "framebuffer"})
|
||
|
|
||
|
def load(self):
|
||
|
from litex.build.xilinx import VivadoProgrammer
|
||
|
prog = VivadoProgrammer()
|
||
|
prog.load_bitstream("build/nexys_video/gateware/top.bit")
|
||
|
|
||
|
# MiniSpartan6 support -----------------------------------------------------------------------------
|
||
|
|
||
|
class MiniSpartan6(Board):
|
||
|
def __init__(self):
|
||
|
from litex_boards.targets import minispartan6
|
||
|
Board.__init__(self, minispartan6.BaseSoC, {"serial"})
|
||
|
|
||
|
def load(self):
|
||
|
os.system("xc3sprog -c ftdi build/minispartan6/gateware/top.bit")
|
||
|
|
||
|
|
||
|
# Versa ECP5 support -------------------------------------------------------------------------------
|
||
|
|
||
|
class VersaECP5(Board):
|
||
|
SPIFLASH_PAGE_SIZE = 256
|
||
|
SPIFLASH_SECTOR_SIZE = 64*kB
|
||
|
def __init__(self):
|
||
|
from litex_boards.targets import versa_ecp5
|
||
|
Board.__init__(self, versa_ecp5.EthernetSoC, {"serial", "ethernet", "spiflash"})
|
||
|
|
||
|
def load(self):
|
||
|
os.system("openocd -f prog/ecp5-versa5g.cfg -c \"transport select jtag; init; svf build/versa_ecp5/gateware/top.svf; exit\"")
|
||
|
|
||
|
# ULX3S support ------------------------------------------------------------------------------------
|
||
|
|
||
|
class ULX3S(Board):
|
||
|
def __init__(self):
|
||
|
from litex_boards.targets import ulx3s
|
||
|
Board.__init__(self, ulx3s.BaseSoC, {"serial"})
|
||
|
|
||
|
def load(self):
|
||
|
os.system("ujprog build/ulx3s/gateware/top.svf")
|
||
|
|
||
|
# TrellisBoard support ------------------------------------------------------------------------------------
|
||
|
|
||
|
class Trellis(Board):
|
||
|
def __init__(self):
|
||
|
from litex_boards.targets import trellisboard
|
||
|
Board.__init__(self, trellisboard.EthernetSoC, "serial+ethernet")
|
||
|
|
||
|
def load(self):
|
||
|
os.system("openocd -f prog/trellisboard.cfg -c \"transport select jtag; init; svf build/trellisboard/gateware/top.svf; exit\"")
|
||
|
|
||
|
# De0Nano support ------------------------------------------------------------------------------------
|
||
|
|
||
|
class De0Nano(Board):
|
||
|
def __init__(self):
|
||
|
from litex_boards.targets import de0nano
|
||
|
Board.__init__(self, de0nano.BaseSoC, {"serial"})
|
||
|
|
||
|
def load(self):
|
||
|
from litex.build.altera import USBBlaster
|
||
|
prog = USBBlaster()
|
||
|
prog.load_bitstream("build/de0nano/gateware/top.sof")
|
||
|
|
||
|
# Main ---------------------------------------------------------------------------------------------
|
||
|
|
||
|
supported_boards = {
|
||
|
# Xilinx
|
||
|
"arty": Arty,
|
||
|
"netv2": NeTV2,
|
||
|
"genesys2": Genesys2,
|
||
|
"kcu105": KCU105,
|
||
|
"nexys4ddr": Nexys4DDR,
|
||
|
"nexys_video": NexysVideo,
|
||
|
"minispartan6": MiniSpartan6,
|
||
|
# Lattice
|
||
|
"versa_ecp5": VersaECP5,
|
||
|
"ulx3s": ULX3S,
|
||
|
"trellisboard": Trellis,
|
||
|
# Altera/Intel
|
||
|
"de0nano": De0Nano,
|
||
|
}
|
||
|
|
||
|
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:
|
||
|
board_names = [args.board]
|
||
|
for board_name in board_names:
|
||
|
board = supported_boards[board_name]()
|
||
|
soc_kwargs = {}
|
||
|
if board_name in ["versa_ecp5", "ulx3s", "trellisboard"]:
|
||
|
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 "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()
|
||
|
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=False, 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()
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|