cores/cpu/microwatt: fix non irq variant, add standard+irq/"standard+gdhl+irq variants, move XICSSlave after CPU class.
This commit is contained in:
parent
3673f38d63
commit
b3a42d76ce
|
@ -17,7 +17,196 @@ from litex.gen.common import reverse_bytes
|
|||
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):
|
||||
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):
|
||||
self.specials += Instance("xics_icp_wrapper", **self.icp_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)
|
||||
|
|
|
@ -12,6 +12,8 @@ extern "C" {
|
|||
#include <generated/soc.h>
|
||||
#include <generated/mem.h>
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_INTERRUPT
|
||||
|
||||
// Address of exception / IRQ handler routine
|
||||
extern void * __rom_isr_address;
|
||||
void isr(uint64_t vec);
|
||||
|
@ -154,6 +156,9 @@ static inline unsigned int irq_pending(void)
|
|||
return pending;
|
||||
}
|
||||
|
||||
|
||||
#endif /* CONFIG_CPU_HAS_INTERRUPT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue