cores/cpu: add optional add_soc_components method and use it to add VexRiscv-SMP's PLIC/CLINT and Microwatt's XCIS.

Also shorten XCIS name on Microwatt from HOSTXICS to XCIS.
This commit is contained in:
Florent Kermarrec 2020-12-30 15:35:27 +01:00
parent 49217ec6ea
commit 74844db3b9
4 changed files with 51 additions and 37 deletions

View File

@ -31,7 +31,11 @@ class Microwatt(CPU):
@property
def mem_map(self):
return {"csr": 0xc0000000}
return {
"csr": 0xc0000000,
"xicsicp": 0xc3ff0000,
"xicsics": 0xc3ff1000
}
@property
def gcc_flags(self):
@ -112,7 +116,7 @@ class Microwatt(CPU):
self.reset_address = reset_address
assert reset_address == 0x00000000
def add_xics(self, soc, soc_region_cls):
def add_soc_components(self, soc, soc_region_cls):
self.submodules.xics = XICSSlave(
platform = self.platform,
variant = self.variant,
@ -120,10 +124,10 @@ class Microwatt(CPU):
int_level_in = self.interrupt,
endianness = self.endianness
)
xicsicp_region = soc_region_cls(origin=soc.mem_map.get("hostxicsicp", 0xc3ff0000), size=4096, cached=False)
xicsics_region = soc_region_cls(origin=soc.mem_map.get("hostxicsics", 0xc3ff1000), size=4096, cached=False)
soc.bus.add_slave(name="hostxicsicp", slave=self.xics.icp_bus, region=xicsicp_region)
soc.bus.add_slave(name="hostxicsics", slave=self.xics.ics_bus, region=xicsics_region)
xicsicp_region = soc_region_cls(origin=soc.mem_map.get("xicsicp"), size=4096, cached=False)
xicsics_region = soc_region_cls(origin=soc.mem_map.get("xicsics"), size=4096, cached=False)
soc.bus.add_slave(name="xicsicp", slave=self.xics.icp_bus, region=xicsicp_region)
soc.bus.add_slave(name="xicsics", slave=self.xics.ics_bus, region=xicsics_region)
@staticmethod
def add_sources(platform, use_ghdl_yosys_plugin=False):

View File

@ -35,32 +35,32 @@ void isr(uint64_t vec);
uint8_t inline xics_icp_readb(int reg)
{
return *((uint8_t*)(HOSTXICSICP_BASE + reg));
return *((uint8_t*)(XICSICP_BASE + reg));
}
void inline xics_icp_writeb(int reg, uint8_t value)
{
*((uint8_t*)(HOSTXICSICP_BASE + reg)) = value;
*((uint8_t*)(XICSICP_BASE + reg)) = value;
}
uint32_t inline xics_icp_readw(int reg)
{
return *((uint32_t*)(HOSTXICSICP_BASE + reg));
return *((uint32_t*)(XICSICP_BASE + reg));
}
void inline xics_icp_writew(int reg, uint32_t value)
{
*((uint32_t*)(HOSTXICSICP_BASE + reg)) = value;
*((uint32_t*)(XICSICP_BASE + reg)) = value;
}
uint32_t inline xics_ics_read_xive(int irq_number)
{
return *((uint32_t*)(HOSTXICSICS_BASE + 0x800 + (irq_number << 2)));
return *((uint32_t*)(XICSICS_BASE + 0x800 + (irq_number << 2)));
}
void inline xics_ics_write_xive(int irq_number, uint32_t priority)
{
*((uint32_t*)(HOSTXICSICS_BASE + 0x800 + (irq_number << 2))) = priority;
*((uint32_t*)(XICSICS_BASE + 0x800 + (irq_number << 2))) = priority;
}
void inline mtmsrd(uint64_t val)

View File

@ -90,6 +90,7 @@ class VexRiscvSMP(CPU):
"main_ram": 0x40000000,
"csr": 0xf0000000,
"clint": 0xf0010000,
"plic": 0xf0c00000,
}
@property
@ -211,8 +212,6 @@ class VexRiscvSMP(CPU):
self.jtag_tdi = Signal()
self.interrupt = Signal(32)
self.pbus = pbus = wishbone.Interface()
self.cbus = cbus = wishbone.Interface()
self.plicbus = plicbus = wishbone.Interface()
self.periph_buses = [pbus]
self.memory_buses = [] # Added dynamically
@ -247,25 +246,7 @@ class VexRiscvSMP(CPU):
o_peripheral_SEL = pbus.sel,
i_peripheral_ERR = pbus.err,
o_peripheral_CTI = pbus.cti,
o_peripheral_BTE = pbus.bte,
# CLINT Bus (Slave)
i_clintWishbone_CYC = cbus.cyc,
i_clintWishbone_STB = cbus.stb,
o_clintWishbone_ACK = cbus.ack,
i_clintWishbone_WE = cbus.we,
i_clintWishbone_ADR = cbus.adr,
o_clintWishbone_DAT_MISO = cbus.dat_r,
i_clintWishbone_DAT_MOSI = cbus.dat_w,
# PLIC Bus (Slave)
i_plicWishbone_CYC = plicbus.cyc,
i_plicWishbone_STB = plicbus.stb,
o_plicWishbone_ACK = plicbus.ack,
i_plicWishbone_WE = plicbus.we,
i_plicWishbone_ADR = plicbus.adr,
o_plicWishbone_DAT_MISO = plicbus.dat_r,
i_plicWishbone_DAT_MOSI = plicbus.dat_w
o_peripheral_BTE = pbus.bte
)
if VexRiscvSMP.coherent_dma:
@ -306,6 +287,36 @@ class VexRiscvSMP(CPU):
platform.add_source(os.path.join(vdir, "RamXilinx.v"), "verilog")
platform.add_source(os.path.join(vdir, self.cluster_name + ".v"), "verilog")
def add_soc_components(self, soc, soc_region_cls):
# Define number of CPUs
soc.add_config("CPU_COUNT", VexRiscvSMP.cpu_count)
# Add PLIC as Bus Slave
self.plicbus = plicbus = wishbone.Interface()
self.cpu_params.update(
i_plicWishbone_CYC = plicbus.cyc,
i_plicWishbone_STB = plicbus.stb,
o_plicWishbone_ACK = plicbus.ack,
i_plicWishbone_WE = plicbus.we,
i_plicWishbone_ADR = plicbus.adr,
o_plicWishbone_DAT_MISO = plicbus.dat_r,
i_plicWishbone_DAT_MOSI = plicbus.dat_w
)
soc.bus.add_slave("plic", self.plicbus, region=soc_region_cls(origin=soc.mem_map.get("plic"), size=0x400000, cached=False))
# Add CLINT as Bus Slave
self.clintbus = clintbus = wishbone.Interface()
self.cpu_params.update(
i_clintWishbone_CYC = clintbus.cyc,
i_clintWishbone_STB = clintbus.stb,
o_clintWishbone_ACK = clintbus.ack,
i_clintWishbone_WE = clintbus.we,
i_clintWishbone_ADR = clintbus.adr,
o_clintWishbone_DAT_MISO = clintbus.dat_r,
i_clintWishbone_DAT_MOSI = clintbus.dat_w,
)
soc.bus.add_slave("clint", clintbus, region=soc_region_cls(origin=soc.mem_map.get("clint"), size=0x10000, cached=False))
def add_memory_buses(self, address_width, data_width):
VexRiscvSMP.litedram_width = data_width
@ -344,7 +355,6 @@ class VexRiscvSMP(CPU):
i_dBridge_dram_rdata_payload_data = dbus.rdata.data,
)
def do_finalize(self):
assert hasattr(self, "reset_address")
self.specials += Instance(self.cluster_name, **self.cpu_params)

View File

@ -896,9 +896,9 @@ class SoC(Module):
self.comb += self.cpu.reset.eq(self.ctrl.reset)
self.add_config("CPU_RESET_ADDR", reset_address)
# Specific Microwatt IROs integration FIXME (remove or provide generic integration method)
if isinstance(self.cpu, cpu.Microwatt) and "irq" in variant:
self.cpu.add_xics(self, SoCRegion)
# Add CPU's SoC components (if any)
if hasattr(self.cpu, "add_soc_components"):
self.cpu.add_soc_components(soc=self, soc_region_cls=SoCRegion) # FIXME: avoid passing SoCRegion.
# Add constants
self.add_config("CPU_TYPE", str(name))