cores/cpu/microwatt: fix non irq variant, add standard+irq/"standard+gdhl+irq variants, move XICSSlave after CPU class.

This commit is contained in:
Florent Kermarrec 2020-11-09 13:29:22 +01:00
parent 3673f38d63
commit b3a42d76ce
2 changed files with 195 additions and 186 deletions

View File

@ -17,7 +17,196 @@ from litex.gen.common import reverse_bytes
from litex.soc.cores.cpu import CPU from litex.soc.cores.cpu import CPU
CPU_VARIANTS = ["standard", "standard+ghdl"] CPU_VARIANTS = ["standard", "standard+ghdl", "standard+irq", "standard+ghdl+irq"]
class Microwatt(CPU):
name = "microwatt"
human_name = "Microwatt"
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 += "-mcmodel=small "
flags += "-D__microwatt__ "
return flags
def __init__(self, platform, variant="standard"):
self.platform = platform
self.variant = variant
self.reset = Signal()
self.wb_insn = wb_insn = wishbone.Interface(data_width=64, adr_width=29)
self.wb_data = wb_data = wishbone.Interface(data_width=64, adr_width=29)
self.periph_buses = [wb_insn, wb_data]
self.memory_buses = []
if "irq" in variant:
self.interrupt = Signal(16)
self.core_ext_irq = Signal()
# # #
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 = wb_insn.cyc & ~wb_insn.ack, # No burst support
o_wishbone_insn_adr = Cat(Signal(3), 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 = wb_data.cyc & ~wb_data.ack, # No burst support
o_wishbone_data_adr = Cat(Signal(3), 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 =,
# Interrupt controller
i_core_ext_irq = self.core_ext_irq,
)
# add vhdl sources
self.add_sources(platform, use_ghdl_yosys_plugin="ghdl" in self.variant)
# add XICS controller
if "irq" in variant:
self.add_xics()
def set_reset_address(self, reset_address):
assert not hasattr(self, "reset_address")
self.reset_address = reset_address
assert reset_address == 0x00000000
def add_xics(self):
self.submodules.xics = XICSSlave(
platform = self.platform,
variant = self.variant,
core_irq_out = self.core_ext_irq,
int_level_in = self.interrupt,
endianness = self.endianness
)
@staticmethod
def add_sources(platform, use_ghdl_yosys_plugin=False):
sources = [
# Common / Types / Helpers
"decode_types.vhdl",
"wishbone_types.vhdl",
"utils.vhdl",
"common.vhdl",
"helpers.vhdl",
# Fetch
"fetch1.vhdl",
"fetch2.vhdl",
# Instruction/Data Cache
"cache_ram.vhdl",
"plru.vhdl",
"dcache.vhdl",
"icache.vhdl",
# Decode
"insn_helpers.vhdl",
"decode1.vhdl",
"gpr_hazard.vhdl",
"cr_hazard.vhdl",
"control.vhdl",
"decode2.vhdl",
# Register/CR File
"register_file.vhdl",
"crhelpers.vhdl",
"cr_file.vhdl",
# Execute
"ppc_fx_insns.vhdl",
"logical.vhdl",
"rotator.vhdl",
"countzero.vhdl",
"execute1.vhdl",
# Load/Store
"loadstore1.vhdl",
# Multiply/Divide
"multiply.vhdl",
"divider.vhdl",
# Writeback
"writeback.vhdl",
# MMU
"mmu.vhdl",
# Core
"core_debug.vhdl",
"core.vhdl",
]
sdir = get_data_mod("cpu", "microwatt").data_location
cdir = os.path.dirname(__file__)
if use_ghdl_yosys_plugin:
from litex.build import tools
import subprocess
ys = []
ys.append("ghdl --ieee=synopsys -fexplicit -frelaxed-rules --std=08 \\")
for source in sources:
ys.append(os.path.join(sdir, source) + " \\")
ys.append(os.path.join(os.path.dirname(__file__), "microwatt_wrapper.vhdl") + " \\")
ys.append("-e microwatt_wrapper")
ys.append("chformal -assert -remove")
ys.append("write_verilog {}".format(os.path.join(cdir, "microwatt.v")))
tools.write_to_file(os.path.join(cdir, "microwatt.ys"), "\n".join(ys))
if subprocess.call(["yosys", "-q", "-m", "ghdl", os.path.join(cdir, "microwatt.ys")]):
raise OSError("Unable to convert Microwatt CPU to verilog, please check your GHDL-Yosys-plugin install")
platform.add_source(os.path.join(cdir, "microwatt.v"))
else:
platform.add_sources(sdir, *sources)
platform.add_source(os.path.join(os.path.dirname(__file__), "microwatt_wrapper.vhdl"))
def do_finalize(self):
self.specials += Instance("microwatt_wrapper", **self.cpu_params)
class XICSSlave(Module, AutoCSR): class XICSSlave(Module, AutoCSR):
def __init__(self, platform, core_irq_out=Signal(), int_level_in=Signal(16), endianness="big", variant="standard"): def __init__(self, platform, core_irq_out=Signal(), int_level_in=Signal(16), endianness="big", variant="standard"):
@ -140,188 +329,3 @@ class XICSSlave(Module, AutoCSR):
def do_finalize(self): def do_finalize(self):
self.specials += Instance("xics_icp_wrapper", **self.icp_params) self.specials += Instance("xics_icp_wrapper", **self.icp_params)
self.specials += Instance("xics_ics_wrapper", **self.ics_params) self.specials += Instance("xics_ics_wrapper", **self.ics_params)
class Microwatt(CPU):
name = "microwatt"
human_name = "Microwatt"
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 += "-mcmodel=small "
flags += "-D__microwatt__ "
return flags
def __init__(self, platform, variant="standard"):
self.platform = platform
self.variant = variant
self.reset = Signal()
self.wb_insn = wb_insn = wishbone.Interface(data_width=64, adr_width=29)
self.wb_data = wb_data = wishbone.Interface(data_width=64, adr_width=29)
self.periph_buses = [wb_insn, wb_data]
self.memory_buses = []
self.interrupt = Signal(16)
self.core_ext_irq = Signal()
# # #
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 = wb_insn.cyc & ~wb_insn.ack, # No burst support
o_wishbone_insn_adr = Cat(Signal(3), 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 = wb_data.cyc & ~wb_data.ack, # No burst support
o_wishbone_data_adr = Cat(Signal(3), 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 =,
# Interrupt controller
i_core_ext_irq = self.core_ext_irq,
)
# add vhdl sources
self.add_sources(platform, use_ghdl_yosys_plugin="ghdl" in self.variant)
# add XICS controller
self.add_xics()
def set_reset_address(self, reset_address):
assert not hasattr(self, "reset_address")
self.reset_address = reset_address
assert reset_address == 0x00000000
def add_xics(self):
self.submodules.xics = XICSSlave(
platform = self.platform,
variant = self.variant,
core_irq_out = self.core_ext_irq,
int_level_in = self.interrupt,
endianness = self.endianness)
@staticmethod
def add_sources(platform, use_ghdl_yosys_plugin=False):
sources = [
# Common / Types / Helpers
"decode_types.vhdl",
"wishbone_types.vhdl",
"utils.vhdl",
"common.vhdl",
"helpers.vhdl",
# Fetch
"fetch1.vhdl",
"fetch2.vhdl",
# Instruction/Data Cache
"cache_ram.vhdl",
"plru.vhdl",
"dcache.vhdl",
"icache.vhdl",
# Decode
"insn_helpers.vhdl",
"decode1.vhdl",
"gpr_hazard.vhdl",
"cr_hazard.vhdl",
"control.vhdl",
"decode2.vhdl",
# Register/CR File
"register_file.vhdl",
"crhelpers.vhdl",
"cr_file.vhdl",
# Execute
"ppc_fx_insns.vhdl",
"logical.vhdl",
"rotator.vhdl",
"countzero.vhdl",
"execute1.vhdl",
# Load/Store
"loadstore1.vhdl",
# Multiply/Divide
"multiply.vhdl",
"divider.vhdl",
# Writeback
"writeback.vhdl",
# MMU
"mmu.vhdl",
# Core
"core_debug.vhdl",
"core.vhdl",
]
sdir = get_data_mod("cpu", "microwatt").data_location
cdir = os.path.dirname(__file__)
if use_ghdl_yosys_plugin:
from litex.build import tools
import subprocess
ys = []
ys.append("ghdl --ieee=synopsys -fexplicit -frelaxed-rules --std=08 \\")
for source in sources:
ys.append(os.path.join(sdir, source) + " \\")
ys.append(os.path.join(os.path.dirname(__file__), "microwatt_wrapper.vhdl") + " \\")
ys.append("-e microwatt_wrapper")
ys.append("chformal -assert -remove")
ys.append("write_verilog {}".format(os.path.join(cdir, "microwatt.v")))
tools.write_to_file(os.path.join(cdir, "microwatt.ys"), "\n".join(ys))
if subprocess.call(["yosys", "-q", "-m", "ghdl", os.path.join(cdir, "microwatt.ys")]):
raise OSError("Unable to convert Microwatt CPU to verilog, please check your GHDL-Yosys-plugin install")
platform.add_source(os.path.join(cdir, "microwatt.v"))
else:
platform.add_sources(sdir, *sources)
platform.add_source(os.path.join(os.path.dirname(__file__), "microwatt_wrapper.vhdl"))
def do_finalize(self):
self.specials += Instance("microwatt_wrapper", **self.cpu_params)

View File

@ -12,6 +12,8 @@ extern "C" {
#include <generated/soc.h> #include <generated/soc.h>
#include <generated/mem.h> #include <generated/mem.h>
#ifdef CONFIG_CPU_HAS_INTERRUPT
// Address of exception / IRQ handler routine // Address of exception / IRQ handler routine
extern void * __rom_isr_address; extern void * __rom_isr_address;
void isr(uint64_t vec); void isr(uint64_t vec);
@ -154,6 +156,9 @@ static inline unsigned int irq_pending(void)
return pending; return pending;
} }
#endif /* CONFIG_CPU_HAS_INTERRUPT */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif