Skip to content

Commit

Permalink
cpu/rocket: rework variant naming convention
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
gsomlo committed Mar 22, 2023
1 parent 1c43a71 commit c3e9362
Showing 1 changed file with 41 additions and 76 deletions.
117 changes: 41 additions & 76 deletions litex/soc/cores/cpu/rocket/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os
import logging

from migen import *

Expand All @@ -44,89 +45,53 @@

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 ------------------------------------------------------------------------------------------

class Rocket(CPU):
category = "softcore"
family = "riscv"
name = "rocket"
human_name = "RocketRV64[imac]"
variants = CPU_VARIANTS
variants = ["small", "medium", "linux", "full"]
data_width = 64
endianness = "little"
gcc_triple = CPU_GCC_TRIPLE_RISCV64
linker_output_format = "elf64-littleriscv"
nop = "nop"
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.
@staticmethod
def get_arch(variant):
if "full" in variant:
return "rv64imafdc"
if variant in ["linux", "full"]:
return "rv64i2p0_mafdc"
else:
return "rv64imac"
return "rv64i2p0_mac"

# Memory Mapping.
@property
Expand All @@ -146,19 +111,20 @@ def mem_map(self):
@property
def gcc_flags(self):
flags = "-mno-save-restore "
flags += GCC_FLAGS[self.variant]
flags += f"-march={self.get_arch(self.variant)} -mabi=lp64 "
flags += "-D__rocket__ "
flags += "-mcmodel=medany"
return flags

def __init__(self, platform, variant="standard"):
def __init__(self, platform, variant="linux"):
self.platform = platform
self.variant = variant

self.reset = Signal()
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.mmio_axi = mmio_axi = axi.AXIInterface(data_width=mmio_dw, address_width=32, id_width=4)
Expand Down Expand Up @@ -329,7 +295,7 @@ def __init__(self, platform, variant="standard"):
o_l2_frontend_bus_axi4_0_r_bits_last = l2fb_axi.r.last,
)
# 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.
mmio_a2w = axi.AXI2Wishbone(mmio_axi, mmio_wb, base_address=0)
Expand All @@ -346,12 +312,14 @@ def set_reset_address(self, reset_address):
assert reset_address == 0x1000_0000, "cpu_reset_addr hardcoded in during elaboration!"

@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
platform.add_sources(
os.path.join(vdir, "generated-src"),
CPU_VARIANTS[variant] + ".v",
CPU_VARIANTS[variant] + ".behav_srams.v",
f"{fname}.v",
f"{fname}.behav_srams.v",
)
platform.add_sources(
os.path.join(vdir, "vsrc"),
Expand All @@ -361,16 +329,13 @@ def add_sources(platform, variant="standard"):
)

def add_soc_components(self, soc):
# Get CPU Params.
mem_dw, mmio_dw, num_cores = CPU_PARAMS[self.variant]

# 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("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))

# 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_MMU", "sv39")

Expand Down

0 comments on commit c3e9362

Please sign in to comment.