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:
parent
c34255d2ab
commit
1b963bb2d5
|
@ -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 ---------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
from litex.soc.cores.cpu.microwatt.core import Microwatt
|
|
@ -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)
|
|
@ -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;
|
Loading…
Reference in New Issue