soc/cores/cpu: add initial Microwatt gateware support
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 13 Dec 2019 22:58:14 +0000 (23:58 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 13 Dec 2019 23:00:13 +0000 (00:00 +0100)
Implementation tested on arty:
cd litex/soc/cores/cpu/microwatt
git clone https://github.com/antonblanchard/microwatt
mv microwatt sources

cd litex/boards/targets
./arty --cpu-type=microwatt --no-compile-gateware

litex/soc/cores/cpu/__init__.py
litex/soc/cores/cpu/microwatt/__init__.py [new file with mode: 0644]
litex/soc/cores/cpu/microwatt/core.py [new file with mode: 0644]
litex/soc/cores/cpu/microwatt/microwatt_wrapper.vhdl [new file with mode: 0644]

index 6aeb6ba5030c218716c79b0c1ffbdd38915fe1ec..ba3963c938c5b32620602e6bfed7f809312966ef 100644 (file)
@@ -32,6 +32,7 @@ from litex.soc.cores.cpu.picorv32 import PicoRV32
 from litex.soc.cores.cpu.vexriscv import VexRiscv
 from litex.soc.cores.cpu.minerva import Minerva
 from litex.soc.cores.cpu.rocket import RocketRV64
+from litex.soc.cores.cpu.microwatt import Microwatt
 
 CPUS = {
     "lm32"       : LM32,
@@ -40,6 +41,7 @@ CPUS = {
     "vexriscv"   : VexRiscv,
     "minerva"    : Minerva,
     "rocket"     : RocketRV64,
+    "microwatt"  : Microwatt,
 }
 
 # CPU Variants/Extensions Definition ---------------------------------------------------------------
diff --git a/litex/soc/cores/cpu/microwatt/__init__.py b/litex/soc/cores/cpu/microwatt/__init__.py
new file mode 100644 (file)
index 0000000..7d06ce3
--- /dev/null
@@ -0,0 +1 @@
+from litex.soc.cores.cpu.microwatt.core import Microwatt
diff --git a/litex/soc/cores/cpu/microwatt/core.py b/litex/soc/cores/cpu/microwatt/core.py
new file mode 100644 (file)
index 0000000..a3b62a0
--- /dev/null
@@ -0,0 +1,124 @@
+# This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
+# License: BSD
+
+import os
+
+from migen import *
+
+from litex.soc.interconnect import wishbone
+from litex.soc.cores.cpu import CPU
+
+
+CPU_VARIANTS = ["standard"]
+
+
+class Microwatt(CPU):
+    name                 = "microwatt"
+    data_width           = 64
+    endianness           = "little"
+    gcc_triple           = ("powerpc64le-linux")
+    linker_output_format = "elf64-powerpc64le"
+    io_regions           = {0x80000000: 0x80000000} # origin, length FIXME: check default IO regions
+
+    @property
+    def gcc_flags(self):
+        # FIXME: add default flags
+        flags += "-D__microwatt__ "
+        return flags
+
+    def __init__(self, platform, variant="standard"):
+        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
+        self.platform = platform
+        self.variant  = variant
+        self.reset    = Signal()
+        self.wb_insn  = wb_insn = wishbone.Interface(data_width=64, adr_width=28)
+        self.wb_data  = wb_data = wishbone.Interface(data_width=64, adr_width=28)
+        self.buses    = [wb_insn, wb_data]
+
+        # # #
+
+        self.cpu_params = dict(
+            # Clock / Reset
+            i_clk                 = ClockSignal(),
+            i_rst                 = ResetSignal() | self.reset,
+
+            # Wishbone instruction bus
+            i_wishbone_insn_dat_r = wb_insn.dat_r,
+            i_wishbone_insn_ack   = wb_insn.ack,
+            i_wishbone_insn_stall = 0,
+
+            o_wishbone_insn_adr   = Cat(Signal(4), wb_insn.adr),
+            o_wishbone_insn_dat_w = wb_insn.dat_w,
+            o_wishbone_insn_cyc   = wb_insn.cyc,
+            o_wishbone_insn_stb   = wb_insn.stb,
+            o_wishbone_insn_sel   = wb_insn.sel,
+            o_wishbone_insn_we    = wb_insn.we,
+
+            # Wishbone data bus
+            i_wishbone_data_dat_r = wb_data.dat_r,
+            i_wishbone_data_ack   = wb_data.ack,
+            i_wishbone_data_stall = 0,
+
+            o_wishbone_data_adr   = Cat(Signal(4), wb_data.adr),
+            o_wishbone_data_dat_w = wb_data.dat_w,
+            o_wishbone_data_cyc   = wb_data.cyc,
+            o_wishbone_data_stb   = wb_data.stb,
+            o_wishbone_data_sel   = wb_data.sel,
+            o_wishbone_data_we    = wb_data.we,
+
+            # Debug bus
+            i_dmi_addr            = 0,
+            i_dmi_din             = 0,
+            #o_dmi_dout           =,
+            i_dmi_req             = 0,
+            i_dmi_wr              = 0,
+            #o_dmi_ack            =,
+        )
+
+        # add vhdl sources
+        self.add_sources(platform)
+
+    def set_reset_address(self, reset_address):
+        assert not hasattr(self, "reset_address")
+        self.reset_address = reset_address
+        assert reset_address == 0x00000000
+
+    @staticmethod
+    def add_sources(platform):
+        sdir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "sources")
+        platform.add_source(os.path.join(sdir, "decode_types.vhdl"))
+        platform.add_source(os.path.join(sdir, "wishbone_types.vhdl"))
+        platform.add_source(os.path.join(sdir, "common.vhdl"))
+        platform.add_source(os.path.join(sdir, "fetch1.vhdl"))
+        platform.add_source(os.path.join(sdir, "fetch2.vhdl"))
+        platform.add_source(os.path.join(sdir, "decode1.vhdl"))
+        platform.add_source(os.path.join(sdir, "helpers.vhdl"))
+        platform.add_source(os.path.join(sdir, "decode2.vhdl"))
+        platform.add_source(os.path.join(sdir, "register_file.vhdl"))
+        platform.add_source(os.path.join(sdir, "cr_file.vhdl"))
+        platform.add_source(os.path.join(sdir, "crhelpers.vhdl"))
+        platform.add_source(os.path.join(sdir, "ppc_fx_insns.vhdl"))
+        platform.add_source(os.path.join(sdir, "sim_console.vhdl"))
+        platform.add_source(os.path.join(sdir, "logical.vhdl"))
+        platform.add_source(os.path.join(sdir, "countzero.vhdl"))
+        platform.add_source(os.path.join(sdir, "gpr_hazard.vhdl"))
+        platform.add_source(os.path.join(sdir, "cr_hazard.vhdl"))
+        platform.add_source(os.path.join(sdir, "control.vhdl"))
+        platform.add_source(os.path.join(sdir, "execute1.vhdl"))
+        platform.add_source(os.path.join(sdir, "loadstore1.vhdl"))
+        platform.add_source(os.path.join(sdir, "dcache.vhdl"))
+        platform.add_source(os.path.join(sdir, "multiply.vhdl"))
+        platform.add_source(os.path.join(sdir, "divider.vhdl"))
+        platform.add_source(os.path.join(sdir, "rotator.vhdl"))
+        platform.add_source(os.path.join(sdir, "writeback.vhdl"))
+        platform.add_source(os.path.join(sdir, "insn_helpers.vhdl"))
+        platform.add_source(os.path.join(sdir, "core.vhdl"))
+        platform.add_source(os.path.join(sdir, "icache.vhdl"))
+        platform.add_source(os.path.join(sdir, "plru.vhdl"))
+        platform.add_source(os.path.join(sdir, "cache_ram.vhdl"))
+        platform.add_source(os.path.join(sdir, "core_debug.vhdl"))
+        platform.add_source(os.path.join(sdir, "utils.vhdl"))
+        platform.add_source(os.path.join(sdir, "..", "microwatt_wrapper.vhdl"))
+
+    def do_finalize(self):
+        self.specials += Instance("microwatt_wrapper", **self.cpu_params)
diff --git a/litex/soc/cores/cpu/microwatt/microwatt_wrapper.vhdl b/litex/soc/cores/cpu/microwatt/microwatt_wrapper.vhdl
new file mode 100644 (file)
index 0000000..9ee82ec
--- /dev/null
@@ -0,0 +1,113 @@
+-- This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
+-- License: BSD
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.common.all;
+use work.wishbone_types.all;
+
+entity microwatt_wrapper is
+    generic (
+        SIM             : boolean := false;
+        DISABLE_FLATTEN : boolean := false
+    );
+    port (
+        clk          : in std_logic;
+        rst          : in std_logic;
+
+        wishbone_insn_dat_r : in std_ulogic_vector(63 downto 0);
+        wishbone_insn_ack   : in std_ulogic;
+        wishbone_insn_stall : in std_ulogic;
+
+        wishbone_insn_adr   : out std_ulogic_vector(31 downto 0);
+        wishbone_insn_dat_w : out std_ulogic_vector(63 downto 0);
+        wishbone_insn_cyc   : out std_ulogic;
+        wishbone_insn_stb   : out std_ulogic;
+        wishbone_insn_sel   : out std_ulogic_vector(7 downto 0);
+        wishbone_insn_we    : out std_ulogic;
+
+        wishbone_data_dat_r : in std_ulogic_vector(63 downto 0);
+        wishbone_data_ack   : in std_ulogic;
+        wishbone_data_stall : in std_ulogic;
+
+        wishbone_data_adr   : out std_ulogic_vector(31 downto 0);
+        wishbone_data_dat_w : out std_ulogic_vector(63 downto 0);
+        wishbone_data_cyc   : out std_ulogic;
+        wishbone_data_stb   : out std_ulogic;
+        wishbone_data_sel   : out std_ulogic_vector(7 downto 0);
+        wishbone_data_we    : out std_ulogic;
+
+        dmi_addr : in  std_ulogic_vector(3 downto 0);
+        dmi_din  : in  std_ulogic_vector(63 downto 0);
+        dmi_dout : out std_ulogic_vector(63 downto 0);
+        dmi_req  : in  std_ulogic;
+        dmi_wr   : in  std_ulogic;
+        dmi_ack  : out std_ulogic;
+
+        terminated_out  : out std_logic
+        );
+end microwatt_wrapper;
+
+architecture rtl of microwatt_wrapper is
+
+    signal wishbone_insn_in  : wishbone_slave_out;
+    signal wishbone_insn_out : wishbone_master_out;
+
+    signal wishbone_data_in  : wishbone_slave_out;
+    signal wishbone_data_out : wishbone_master_out;
+
+begin
+
+    -- wishbone_insn mapping
+    wishbone_insn_in.dat   <= wishbone_insn_dat_r;
+    wishbone_insn_in.ack   <= wishbone_insn_ack;
+    wishbone_insn_in.stall <= wishbone_insn_stall;
+
+    wishbone_insn_adr      <= wishbone_insn_out.adr;
+    wishbone_insn_dat_w    <= wishbone_insn_out.dat;
+    wishbone_insn_cyc      <= wishbone_insn_out.cyc;
+    wishbone_insn_stb      <= wishbone_insn_out.stb;
+    wishbone_insn_sel      <= wishbone_insn_out.sel;
+    wishbone_insn_we       <= wishbone_insn_out.we;
+
+    -- wishbone_data mapping
+    wishbone_data_in.dat   <= wishbone_data_dat_r;
+    wishbone_data_in.ack   <= wishbone_data_ack;
+    wishbone_data_in.stall <= wishbone_data_stall;
+
+    wishbone_data_adr      <= wishbone_data_out.adr;
+    wishbone_data_dat_w    <= wishbone_data_out.dat;
+    wishbone_data_cyc      <= wishbone_data_out.cyc;
+    wishbone_data_stb      <= wishbone_data_out.stb;
+    wishbone_data_sel      <= wishbone_data_out.sel;
+    wishbone_data_we       <= wishbone_data_out.we;
+
+    microwatt_core : entity work.core
+        generic map (
+            SIM             => SIM,
+            DISABLE_FLATTEN => DISABLE_FLATTEN
+        )
+        port map (
+            clk               => clk,
+            rst               => rst,
+
+            wishbone_insn_in  => wishbone_insn_in,
+            wishbone_insn_out => wishbone_insn_out,
+
+            wishbone_data_in  => wishbone_data_in,
+            wishbone_data_out => wishbone_data_out,
+
+            dmi_addr          => dmi_addr,
+            dmi_din           => dmi_din,
+            dmi_dout          => dmi_dout,
+            dmi_req           => dmi_req,
+            dmi_wr            => dmi_wr,
+            dmi_ack           => dmi_ack,
+
+            terminated_out    => terminated_out
+        );
+
+end rtl;