From 7ef2953a3787258d218941d1ab3b91d705670248 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 22 Jul 2020 16:30:35 +0100 Subject: [PATCH] first version of litex core (to be submitted upstream once tested) --- src/soc/litex/__init__.py | 0 src/soc/litex/core.py | 141 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 src/soc/litex/__init__.py create mode 100644 src/soc/litex/core.py diff --git a/src/soc/litex/__init__.py b/src/soc/litex/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/soc/litex/core.py b/src/soc/litex/core.py new file mode 100644 index 00000000..16e28d97 --- /dev/null +++ b/src/soc/litex/core.py @@ -0,0 +1,141 @@ +# Copyright (c) 2018 Jean-François Nguyen +# Copyright (c) 2018-2019 Florent Kermarrec +# 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) + -- 2.30.2