cpu/rocket: rework variant naming convention

The naming convention for LiteX Rocket variants has become overly
complex. Simplify it while at the same time adding more flexibility.

There is a new set of instances of varying main RAM memory bus port
width (1x (64bit), 2x (128bit), 4x (256bit), and 8x (512bit)), of
each of the following principal LiteX specific Rocket models:

- small:  (rv64imac, no MMU, no S, no FPU)
- medium: (rv64imac, adds MMU and S-mode)
- linux:  (rv64imafdc, adds FPU, supports linux distros)
- full:   (rv64imafdcbkph[+], adds hypervisor support)

NOTE: before adding H support, the feature set of the old `full`
model is now represented by the `linux` model. The old `linux`
did not use to have an FPU, and is now available as `medium`.

In addition to the range of memory port widths, each model
will be instantiated in 1, 2, 4, and 8 core variants. The
naming convention is `LitexConfig_<model>_<num_cores>_<mem_width>`.

E.g. `LitexConfig_full_8_2` for an 8-core full model with
a 128bit main RAM AXI port. On the build command line, this
example would look like:

	...
	--cpu-type rocket --cpu-variant full \
	--cpu-num-cores 8 --cpu-mem-width 2 \
	...

There are a total of 4 * 4 * 4 = 64 (sub-)variants: each of the four
principal models can be fitted with one of four core counts, and one
of four memory bus widths.

Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
This commit is contained in:
Gabriel Somlo 2023-03-22 08:38:37 -04:00
parent 1c43a71970
commit c3e93620ec
1 changed files with 41 additions and 76 deletions

View File

@ -30,6 +30,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os import os
import logging
from migen import * from migen import *
@ -44,67 +45,6 @@ from litex.soc.integration.soc import SoCRegion
from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV64 from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV64
# Variants -----------------------------------------------------------------------------------------
CPU_VARIANTS = {
"standard" : "freechips.rocketchip.system.LitexConfig",
"linux" : "freechips.rocketchip.system.LitexLinuxConfig",
"linux4" : "freechips.rocketchip.system.LitexLinux4Config",
"linuxd" : "freechips.rocketchip.system.LitexLinuxDConfig",
"linux2d" : "freechips.rocketchip.system.LitexLinux2DConfig",
"linuxq" : "freechips.rocketchip.system.LitexLinuxQConfig",
"linux2q" : "freechips.rocketchip.system.LitexLinux2QConfig",
"full" : "freechips.rocketchip.system.LitexFullConfig",
"fulld" : "freechips.rocketchip.system.LitexFullDConfig",
"full4d" : "freechips.rocketchip.system.LitexFull4DConfig",
"fullq" : "freechips.rocketchip.system.LitexFullQConfig",
"full4q" : "freechips.rocketchip.system.LitexFull4QConfig",
"fullo" : "freechips.rocketchip.system.LitexFullOConfig",
"full4o" : "freechips.rocketchip.system.LitexFull4OConfig",
"full8o" : "freechips.rocketchip.system.LitexFull8OConfig",
}
# GCC Flags-----------------------------------------------------------------------------------------
GCC_FLAGS = {
"standard" : "-march=rv64i2p0_mac -mabi=lp64 ",
"linux" : "-march=rv64i2p0_mac -mabi=lp64 ",
"linux4" : "-march=rv64i2p0_mac -mabi=lp64 ",
"linuxd" : "-march=rv64i2p0_mac -mabi=lp64 ",
"linux2d" : "-march=rv64i2p0_mac -mabi=lp64 ",
"linuxq" : "-march=rv64i2p0_mac -mabi=lp64 ",
"linux2q" : "-march=rv64i2p0_mac -mabi=lp64 ",
"full" : "-march=rv64i2p0_mafdc -mabi=lp64 ",
"fulld" : "-march=rv64i2p0_mafdc -mabi=lp64 ",
"full4d" : "-march=rv64i2p0_mafdc -mabi=lp64 ",
"fullq" : "-march=rv64i2p0_mafdc -mabi=lp64 ",
"full4q" : "-march=rv64i2p0_mafdc -mabi=lp64 ",
"fullo" : "-march=rv64i2p0_mafdc -mabi=lp64 ",
"full4o" : "-march=rv64i2p0_mafdc -mabi=lp64 ",
"full8o" : "-march=rv64i2p0_mafdc -mabi=lp64 ",
}
# CPU Params ----------------------------------------------------------------------------------
CPU_PARAMS = {
# Variant : (mem_dw, mmio_dw, num_cores)
"standard" : ( 64, 64, 1),
"linux" : ( 64, 64, 1),
"linux4" : ( 64, 64, 4),
"linuxd" : ( 128, 64, 1),
"linux2d" : ( 128, 64, 2),
"linuxq" : ( 256, 64, 1),
"linux2q" : ( 256, 64, 2),
"full" : ( 64, 64, 1),
"fulld" : ( 128, 64, 1),
"full4d" : ( 128, 64, 4),
"fullq" : ( 256, 64, 1),
"full4q" : ( 256, 64, 4),
"fullo" : ( 512, 64, 1),
"full4o" : ( 512, 64, 4),
"full8o" : ( 512, 64, 8),
}
# Rocket ------------------------------------------------------------------------------------------ # Rocket ------------------------------------------------------------------------------------------
class Rocket(CPU): class Rocket(CPU):
@ -112,7 +52,7 @@ class Rocket(CPU):
family = "riscv" family = "riscv"
name = "rocket" name = "rocket"
human_name = "RocketRV64[imac]" human_name = "RocketRV64[imac]"
variants = CPU_VARIANTS variants = ["small", "medium", "linux", "full"]
data_width = 64 data_width = 64
endianness = "little" endianness = "little"
gcc_triple = CPU_GCC_TRIPLE_RISCV64 gcc_triple = CPU_GCC_TRIPLE_RISCV64
@ -120,13 +60,38 @@ class Rocket(CPU):
nop = "nop" nop = "nop"
io_regions = {0x1200_0000: 0x7000_0000} # Origin, Length. io_regions = {0x1200_0000: 0x7000_0000} # Origin, Length.
# Default parameters.
cpu_num_cores = 1
cpu_mem_width = 1
# Command line configuration arguments.
@staticmethod
def args_fill(parser):
cpu_group = parser.add_argument_group(title="CPU options")
cpu_group.add_argument("--cpu-num-cores", default=1, help="Number of cores (1, 2, 4, 8).", type=int)
cpu_group.add_argument("--cpu-mem-width", default=1, help="Width of memory port (1, 2, 4, 8).", type=int)
@staticmethod
def args_read(args):
logger = logging.getLogger("RocketArgs")
if int(args.cpu_num_cores) in [1, 2, 4, 8]:
Rocket.cpu_num_cores = int(args.cpu_num_cores)
else:
logger.error("Invalid '--cpu-num-cores {}' (should be 1, 2, 4, or 8)".format(args.cpu_num_cores))
quit()
if int(args.cpu_mem_width) in [1, 2, 4, 8]:
Rocket.cpu_mem_width = int(args.cpu_mem_width)
else:
logger.error("Invalid '--cpu-mem-width {}' (should be 1, 2, 4, or 8)".format(args.cpu_mem_width))
quit()
# Arch. # Arch.
@staticmethod @staticmethod
def get_arch(variant): def get_arch(variant):
if "full" in variant: if variant in ["linux", "full"]:
return "rv64imafdc" return "rv64i2p0_mafdc"
else: else:
return "rv64imac" return "rv64i2p0_mac"
# Memory Mapping. # Memory Mapping.
@property @property
@ -146,19 +111,20 @@ class Rocket(CPU):
@property @property
def gcc_flags(self): def gcc_flags(self):
flags = "-mno-save-restore " flags = "-mno-save-restore "
flags += GCC_FLAGS[self.variant] flags += f"-march={self.get_arch(self.variant)} -mabi=lp64 "
flags += "-D__rocket__ " flags += "-D__rocket__ "
flags += "-mcmodel=medany" flags += "-mcmodel=medany"
return flags return flags
def __init__(self, platform, variant="standard"): def __init__(self, platform, variant="linux"):
self.platform = platform self.platform = platform
self.variant = variant self.variant = variant
self.reset = Signal() self.reset = Signal()
self.interrupt = Signal(8) self.interrupt = Signal(8)
mem_dw, mmio_dw, num_cores = CPU_PARAMS[self.variant] mem_dw = 64 * Rocket.cpu_mem_width
mmio_dw = 64
self.mem_axi = mem_axi = axi.AXIInterface(data_width=mem_dw, address_width=32, id_width=4) self.mem_axi = mem_axi = axi.AXIInterface(data_width=mem_dw, address_width=32, id_width=4)
self.mmio_axi = mmio_axi = axi.AXIInterface(data_width=mmio_dw, address_width=32, id_width=4) self.mmio_axi = mmio_axi = axi.AXIInterface(data_width=mmio_dw, address_width=32, id_width=4)
@ -329,7 +295,7 @@ class Rocket(CPU):
o_l2_frontend_bus_axi4_0_r_bits_last = l2fb_axi.r.last, o_l2_frontend_bus_axi4_0_r_bits_last = l2fb_axi.r.last,
) )
# additional per-core debug signals: # additional per-core debug signals:
self.cpu_params.update({'i_resetctrl_hartIsInReset_%s'%i : Open() for i in range(num_cores)}) self.cpu_params.update({'i_resetctrl_hartIsInReset_%s'%i : Open() for i in range(Rocket.cpu_num_cores)})
# Adapt AXI interfaces to Wishbone. # Adapt AXI interfaces to Wishbone.
mmio_a2w = axi.AXI2Wishbone(mmio_axi, mmio_wb, base_address=0) mmio_a2w = axi.AXI2Wishbone(mmio_axi, mmio_wb, base_address=0)
@ -346,12 +312,14 @@ class Rocket(CPU):
assert reset_address == 0x1000_0000, "cpu_reset_addr hardcoded in during elaboration!" assert reset_address == 0x1000_0000, "cpu_reset_addr hardcoded in during elaboration!"
@staticmethod @staticmethod
def add_sources(platform, variant="standard"): def add_sources(platform, variant):
pfx = "freechips.rocketchip.system.LitexConfig"
fname = f"{pfx}_{variant}_{Rocket.cpu_num_cores}_{Rocket.cpu_mem_width}"
vdir = get_data_mod("cpu", "rocket").data_location vdir = get_data_mod("cpu", "rocket").data_location
platform.add_sources( platform.add_sources(
os.path.join(vdir, "generated-src"), os.path.join(vdir, "generated-src"),
CPU_VARIANTS[variant] + ".v", f"{fname}.v",
CPU_VARIANTS[variant] + ".behav_srams.v", f"{fname}.behav_srams.v",
) )
platform.add_sources( platform.add_sources(
os.path.join(vdir, "vsrc"), os.path.join(vdir, "vsrc"),
@ -361,16 +329,13 @@ class Rocket(CPU):
) )
def add_soc_components(self, soc): def add_soc_components(self, soc):
# Get CPU Params.
mem_dw, mmio_dw, num_cores = CPU_PARAMS[self.variant]
# Add OpenSBI/PLIC/CLINT regions. # Add OpenSBI/PLIC/CLINT regions.
soc.bus.add_region("opensbi", SoCRegion(origin=self.mem_map["main_ram"] + 0x0000_0000, size=0x20_0000, cached=False, linker=True)) soc.bus.add_region("opensbi", SoCRegion(origin=self.mem_map["main_ram"] + 0x0000_0000, size=0x20_0000, cached=False, linker=True))
soc.bus.add_region("plic", SoCRegion(origin=soc.mem_map.get("plic"), size=0x40_0000, cached=True, linker=True)) soc.bus.add_region("plic", SoCRegion(origin=soc.mem_map.get("plic"), size=0x40_0000, cached=True, linker=True))
soc.bus.add_region("clint", SoCRegion(origin=soc.mem_map.get("clint"), size= 0x1_0000, cached=True, linker=True)) soc.bus.add_region("clint", SoCRegion(origin=soc.mem_map.get("clint"), size= 0x1_0000, cached=True, linker=True))
# Define number of CPUs # Define number of CPUs
soc.add_config("CPU_COUNT", num_cores) soc.add_config("CPU_COUNT", Rocket.cpu_num_cores)
soc.add_config("CPU_ISA", self.get_arch(self.variant)) soc.add_config("CPU_ISA", self.get_arch(self.variant))
soc.add_config("CPU_MMU", "sv39") soc.add_config("CPU_MMU", "sv39")