#!/usr/bin/env python3

import argparse
import os

from migen import *

from litex.boards.targets import ulx3s

from litex.soc.interconnect import wishbone
from litex.soc.integration.soc_core import mem_decoder
from litex.soc.integration.builder import Builder

# LinuxSoC -----------------------------------------------------------------------------------------

class LinuxSoC(ulx3s.BaseSoC):
    csr_map = {
        "ddrphy": 16,
        "cpu":    17,
    }
    csr_map.update(ulx3s.BaseSoC.csr_map)

    ulx3s.BaseSoC.mem_map = {
        "rom":          0x00000000,
        "sram":         0x10000000,
        "emulator_ram": 0x20000000,
        "spiflash":     0x50000000,
        "main_ram":     0xc0000000,
        "csr":          0xf0000000,
    }

    def __init__(self, toolchain="trellis"):
        ulx3s.BaseSoC.__init__(self, cpu_type="vexriscv", cpu_variant="linux", toolchain=toolchain, uart_baudrate=3e6)
        self.cpu.use_external_variant("VexRiscv.v")

        # machine mode emulator ram
        self.submodules.emulator_ram = wishbone.SRAM(0x4000)
        self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, 0x4000)

# Build --------------------------------------------------------------------------------------------

def main():
    parser = argparse.ArgumentParser(description="Linux on LiteX-VexRiscv with ULX3S board")
    parser.add_argument("--build", action="store_true", help="build bitstream")
    parser.add_argument("--load", action="store_true", help="load bitstream (SRAM)")
    parser.add_argument("--diamond", action="store_true", help="use Diamond instead of Trellis")

    args = parser.parse_args()

    if args.diamond:
        toolchain_path = "/usr/local/diamond/3.10_x64/bin/lin64"
    else:
        toolchain_path = "/usr/share/trellis"

    if args.load:
        print("Compile board device tree...")
        os.system("dtc -O dtb -o binaries/rv32.dtb buildroot/board/litex_vexriscv/litex_vexriscv_ulx3s.dts")

    if args.build:
        soc = LinuxSoC(toolchain="diamond" if args.diamond else "trellis")
        builder = Builder(soc, output_dir="build_ulx3s")
        builder.build(toolchain_path=toolchain_path)
        if args.diamond:
            os.system("python3 bit_to_svf.py build_ulx3s/gateware/top.bit build_ulx3s/gateware/top.svf")

    if args.load:
        os.system("ujprog build_ulx3s/gateware/top.svf")
        #os.system("openocd -f openocd/ulx3s.cfg -c \"transport select jtag; init; svf build_ulx3s/gateware/top.svf; exit\"")

if __name__ == "__main__":
    main()

@@ -48,29 +48,8 @@
 os%0A%0A
-from migen import *%0A%0A
 from
@@ -107,1067 +107,87 @@
 inte
-rconnect import wishbone%0Afrom litex.soc.integration.soc_core import mem_decoder%0Afrom litex.soc.integration.builder import Builder%0A%0A# LinuxSoC -----------------------------------------------------------------------------------------%0A%0Aclass LinuxSoC(ulx3s.BaseSoC):%0A    csr_map = %7B%0A        %22ddrphy%22: 16,%0A        %22cpu%22:    17,%0A    %7D%0A    csr_map.update(ulx3s.BaseSoC.csr_map)%0A%0A    ulx3s.BaseSoC.mem_map = %7B%0A        %22rom%22:          0x00000000,%0A        %22sram%22:         0x10000000,%0A        %22emulator_ram%22: 0x20000000,%0A        %22spiflash%22:     0x50000000,%0A        %22main_ram%22:     0xc0000000,%0A        %22csr%22:          0xf0000000,%0A    %7D%0A%0A    def __init__(self, toolchain=%22trellis%22):%0A        ulx3s.BaseSoC.__init__(self, cpu_type=%22vexriscv%22, cpu_variant=%22linux%22, toolchain=toolchain, uart_baudrate=3e6)%0A        self.cpu.use_external_variant(%22VexRiscv.v%22)%0A%0A        # machine mode emulator ram%0A        self.submodules.emulator_ram = wishbone.SRAM(0x4000)%0A        self.register_mem(%22emulator_ram%22, self.mem_map%5B%22emulator_ram%22%5D, self.emulator_ram.bus, 0x4000)%0A%0A# Build -------
+gration.builder import Builder%0A%0Afrom soc_linux import SoCLinux%0A%0A# Build / Load 
 ----
@@ -632,25 +632,24 @@
 f Trellis%22)%0A
-%0A
     args = p
@@ -668,16 +668,165 @@
 args()%0A%0A
+    soc = SoCLinux(ulx3s.BaseSoC, toolchain=%22diamond%22 if args.diamond else %22trellis%22)%0A    soc.configure_boot()%0A    soc.compile_device_tree(%22ulx3s%22)%0A%0A
     if a
@@ -976,263 +976,14 @@
 rgs.
-load:%0A        print(%22Compile board device tree...%22)%0A        os.system(%22dtc -O dtb -o binaries/rv32.dtb buildroot/board/litex_vexriscv/litex_vexriscv_ulx3s.dts%22)%0A%0A    if args.build:%0A        soc = LinuxSoC(toolchain=%22diamond%22 if args.diamond else %22trellis%22)
+build:
 %0A   

use SoCLinux