soc/cores/cpu: add initial Microwatt gateware support

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
This commit is contained in:
Florent Kermarrec 2019-12-13 23:58:14 +01:00
parent c34255d2ab
commit 1b963bb2d5
4 changed files with 240 additions and 0 deletions

View 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 ---------------------------------------------------------------

View File

@ -0,0 +1 @@
from litex.soc.cores.cpu.microwatt.core import Microwatt

View File

@ -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)

View File

@ -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;