first version of litex core (to be submitted upstream once tested)
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 22 Jul 2020 15:30:35 +0000 (16:30 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 22 Jul 2020 15:30:35 +0000 (16:30 +0100)
src/soc/litex/__init__.py [new file with mode: 0644]
src/soc/litex/core.py [new file with mode: 0644]

diff --git a/src/soc/litex/__init__.py b/src/soc/litex/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/soc/litex/core.py b/src/soc/litex/core.py
new file mode 100644 (file)
index 0000000..16e28d9
--- /dev/null
@@ -0,0 +1,141 @@
+# Copyright (c) 2018 Jean-François Nguyen <jf@lambdaconcept.fr>
+# Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
+# License: BSD
+
+import os
+import subprocess
+
+from migen import *
+
+from litex import get_data_mod
+from litex.soc.interconnect import wishbone
+from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV32
+
+CPU_VARIANTS = ["standard"]
+
+
+class LibreSOC(CPU):
+    name                 = "libre-soc"
+    human_name           = "Libre-SOC"
+    variants             = CPU_VARIANTS
+    data_width           = 64
+    endianness           = "little"
+    gcc_triple           = ("powerpc64le-linux", "powerpc64le-linux-gnu")
+    linker_output_format = "elf64-powerpcle"
+    nop                  = "nop"
+    io_regions           = {0xc0000000: 0x10000000} # origin, length
+
+    @property
+    def mem_map(self):
+        return {"csr": 0xc0000000}
+
+    @property
+    def gcc_flags(self):
+        flags  = "-m64 "
+        flags += "-mabi=elfv2 "
+        flags += "-msoft-float "
+        flags += "-mno-string "
+        flags += "-mno-multiple "
+        flags += "-mno-vsx "
+        flags += "-mno-altivec "
+        flags += "-mlittle-endian "
+        flags += "-mstrict-align "
+        flags += "-fno-stack-protector "
+        flags += "-D__microwatt__ "
+        return flags
+
+    def __init__(self, platform, variant="standard"):
+        self.platform     = platform
+        self.variant      = variant
+        self.reset        = Signal()
+        self.interrupt    = Signal(32)
+
+        self.pc           = Signal(64) # new program counter
+        self.pc_ok        = Signal()   # change PC
+        self.core_start   = Signal()   # stop the core
+        self.core_stop    = Signal()   # start the core
+        self.bigendian    = Signal()   # set to 1 for bigendian
+        self.core_halted  = Signal()   # core is halted
+        self.core_busy    = Signal()   # core is running (busy)
+
+        # instruction and data bus: 64-bit, 48 bit addressing
+        self.ibus         = wishbone.Interface(data_width=64, adr_width=48)
+        self.dbus         = wishbone.Interface(data_width=64, adr_width=48)
+
+        self.periph_buses = [self.ibus, self.dbus]
+        self.memory_buses = []
+
+        # TODO: create variants
+
+        # # #
+
+        self.cpu_params = dict(
+            # clock / reset
+            i_clk=ClockSignal(),
+            i_rst=ResetSignal() | self.reset,
+
+            # TODO interrupts
+            #i_timer_interrupt    = 0,
+            #i_software_interrupt = 0,
+            #i_external_interrupt = self.interrupt,
+
+            # ibus
+            o_ibus__stb   = self.ibus.stb,
+            o_ibus__cyc   = self.ibus.cyc,
+            o_ibus__cti   = self.ibus.cti,
+            o_ibus__bte   = self.ibus.bte,
+            o_ibus__we    = self.ibus.we,
+            o_ibus__adr   = Cat(Signal(3), self.ibus.adr), # 64-bit
+            o_ibus__dat_w = self.ibus.dat_w,
+            o_ibus__sel   = self.ibus.sel,
+            i_ibus__ack   = self.ibus.ack,
+            i_ibus__err   = self.ibus.err,
+            i_ibus__dat_r = self.ibus.dat_r,
+
+            # dbus
+            o_dbus__stb   = self.dbus.stb,
+            o_dbus__cyc   = self.dbus.cyc,
+            o_dbus__cti   = self.dbus.cti,
+            o_dbus__bte   = self.dbus.bte,
+            o_dbus__we    = self.dbus.we,
+            o_dbus__adr   = Cat(Signal(3), self.dbus.adr), # 64-bit
+            o_dbus__dat_w = self.dbus.dat_w,
+            o_dbus__sel   = self.dbus.sel,
+            i_dbus__ack   = self.dbus.ack,
+            i_dbus__err   = self.dbus.err,
+            i_dbus__dat_r = self.dbus.dat_r,
+
+            # monitoring / debugging
+            i_go_insn_i        = 1,  # set to "always running"
+            i_pc_i             = self.pc,
+            i_ pc_i_ok         = self.pc_ok,
+            i_core_start_i     = self.core_start,
+            i_core_stop_i      = self.core_stop,
+            i_core_bigendian_i = self.bigendian,
+            o_halted_o         = self.core_halted,
+            o_busy_o           = self.core_busy
+        )
+
+    def set_reset_address(self, reset_address):
+        assert not hasattr(self, "reset_address")
+        self.reset_address = reset_address
+        assert reset_address == 0x00000000
+
+    @staticmethod
+    def elaborate(verilog_filename):
+        cli_params = []
+        sdir = get_data_mod("cpu", "libre-soc").data_location
+        if subprocess.call(["python3", os.path.join(sdir, "cli.py"),
+                            *cli_params, verilog_filename],
+                            ):
+            raise OSError("Unable to elaborate Libre-SOC CPU, "
+                          "please check your nMigen/Yosys install")
+
+    def do_finalize(self):
+        verilog_filename = os.path.join(self.platform.output_dir,
+                                        "gateware", "libre-soc.v")
+        self.elaborate(
+            verilog_filename = verilog_filename)
+        self.platform.add_source(verilog_filename)
+        self.specials += Instance("test_issuer", **self.cpu_params)
+