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

View File

@ -90,6 +90,7 @@ class VexRiscvSMP(CPU):
"main_ram": 0x40000000, "main_ram": 0x40000000,
"csr": 0xf0000000, "csr": 0xf0000000,
"clint": 0xf0010000, "clint": 0xf0010000,
"plic": 0xf0c00000,
} }
@property @property
@ -211,8 +212,6 @@ class VexRiscvSMP(CPU):
self.jtag_tdi = Signal() self.jtag_tdi = Signal()
self.interrupt = Signal(32) self.interrupt = Signal(32)
self.pbus = pbus = wishbone.Interface() self.pbus = pbus = wishbone.Interface()
self.cbus = cbus = wishbone.Interface()
self.plicbus = plicbus = wishbone.Interface()
self.periph_buses = [pbus] self.periph_buses = [pbus]
self.memory_buses = [] # Added dynamically self.memory_buses = [] # Added dynamically
@ -247,25 +246,7 @@ class VexRiscvSMP(CPU):
o_peripheral_SEL = pbus.sel, o_peripheral_SEL = pbus.sel,
i_peripheral_ERR = pbus.err, i_peripheral_ERR = pbus.err,
o_peripheral_CTI = pbus.cti, o_peripheral_CTI = pbus.cti,
o_peripheral_BTE = pbus.bte, 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
) )
if VexRiscvSMP.coherent_dma: 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, "RamXilinx.v"), "verilog")
platform.add_source(os.path.join(vdir, self.cluster_name + ".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): def add_memory_buses(self, address_width, data_width):
VexRiscvSMP.litedram_width = data_width VexRiscvSMP.litedram_width = data_width
@ -344,7 +355,6 @@ class VexRiscvSMP(CPU):
i_dBridge_dram_rdata_payload_data = dbus.rdata.data, i_dBridge_dram_rdata_payload_data = dbus.rdata.data,
) )
def do_finalize(self): def do_finalize(self):
assert hasattr(self, "reset_address") assert hasattr(self, "reset_address")
self.specials += Instance(self.cluster_name, **self.cpu_params) 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.comb += self.cpu.reset.eq(self.ctrl.reset)
self.add_config("CPU_RESET_ADDR", reset_address) self.add_config("CPU_RESET_ADDR", reset_address)
# Specific Microwatt IROs integration FIXME (remove or provide generic integration method) # Add CPU's SoC components (if any)
if isinstance(self.cpu, cpu.Microwatt) and "irq" in variant: if hasattr(self.cpu, "add_soc_components"):
self.cpu.add_xics(self, SoCRegion) self.cpu.add_soc_components(soc=self, soc_region_cls=SoCRegion) # FIXME: avoid passing SoCRegion.
# Add constants # Add constants
self.add_config("CPU_TYPE", str(name)) self.add_config("CPU_TYPE", str(name))