Skip to content

Commit

Permalink
Merge pull request #186 from gsomlo/gls-rocket
Browse files Browse the repository at this point in the history
Experimental Support for 64-bit RocketChip
  • Loading branch information
enjoy-digital authored May 24, 2019
2 parents 3de4911 + 019fd94 commit aa640f2
Show file tree
Hide file tree
Showing 17 changed files with 415 additions and 7 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@
[submodule "litex/soc/cores/cpu/minerva/verilog"]
path = litex/soc/cores/cpu/minerva/verilog
url = http://github.com/enjoy-digital/minerva-verilog
[submodule "litex/soc/cores/cpu/rocket/verilog"]
path = litex/soc/cores/cpu/rocket/verilog
url = https://github.com/gsomlo/rocket-litex-verilog
2 changes: 1 addition & 1 deletion litex/boards/targets/nexys4ddr.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def __init__(self, platform, sys_clk_freq):
# BaseSoC ------------------------------------------------------------------------------------------

class BaseSoC(SoCSDRAM):
def __init__(self, sys_clk_freq=int(100e6), **kwargs):
def __init__(self, sys_clk_freq=int(50e6), **kwargs):
platform = nexys4ddr.Platform()
SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq,
integrated_rom_size=0x8000,
Expand Down
2 changes: 1 addition & 1 deletion litex/boards/targets/versa_ecp5.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def __init__(self, platform, sys_clk_freq):
# BaseSoC ------------------------------------------------------------------------------------------

class BaseSoC(SoCSDRAM):
def __init__(self, sys_clk_freq=int(75e6), toolchain="diamond", **kwargs):
def __init__(self, sys_clk_freq=int(50e6), toolchain="diamond", **kwargs):
platform = versa_ecp5.Platform(toolchain=toolchain)
SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq,
integrated_rom_size=0x8000,
Expand Down
1 change: 1 addition & 0 deletions litex/build/sim/core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ $(OBJS_SIM): %.o: $(SRC_DIR)/%.c
.PHONY: sim
sim: mkdir $(OBJS_SIM)
verilator -Wno-fatal -O3 $(CC_SRCS) --top-module dut --exe \
-DPRINTF_COND=0 \
$(SRCS_SIM_CPP) $(OBJS_SIM) \
--top-module dut \
$(if $(THREADS), --threads $(THREADS),) \
Expand Down
1 change: 1 addition & 0 deletions litex/soc/cores/cpu/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
from litex.soc.cores.cpu.picorv32 import PicoRV32
from litex.soc.cores.cpu.vexriscv import VexRiscv
from litex.soc.cores.cpu.minerva import Minerva
from litex.soc.cores.cpu.rocket import RocketRV64
1 change: 1 addition & 0 deletions litex/soc/cores/cpu/rocket/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from litex.soc.cores.cpu.rocket.core import RocketRV64
242 changes: 242 additions & 0 deletions litex/soc/cores/cpu/rocket/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
# litex/soc/cores/cpu/rocket/core.py
# Rocket Chip core support for the LiteX SoC.
#
# Author: Gabriel L. Somlo <[email protected]>
# Copyright (c) 2019, Carnegie Mellon University
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os

from migen import *

from litex.soc.interconnect import axi
from litex.soc.interconnect import wishbone

CPU_VARIANTS = ["standard"]

GCC_FLAGS = {
"standard": "-march=rv64imac -mabi=lp64 ",
}

class RocketRV64(Module):
@property
def name(self):
return "rocket"

@property
def endianness(self):
return "little"

@property
def gcc_triple(self):
return ("riscv64-unknown-elf")

@property
def gcc_flags(self):
flags = "-mno-save-restore "
flags += GCC_FLAGS[self.variant]
flags += "-D__rocket__ "
return flags

@property
def linker_output_format(self):
return "elf64-littleriscv"

@property
def reserved_interrupts(self):
return {}

def __init__(self, platform, cpu_reset_addr, variant="standard"):
assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
assert cpu_reset_addr == 0x10000000, "cpu_reset_addr hardcoded in Chisel elaboration!"

self.platform = platform
self.variant = variant
self.reset = Signal()

self.interrupt = Signal(4)

self.mem_axi = mem_axi = axi.AXIInterface(
data_width=64, address_width=32, id_width=4)
self.mmio_axi = mmio_axi = axi.AXIInterface(
data_width=64, address_width=32, id_width=4)

self.mem_wb = mem_wb = wishbone.Interface(data_width=64, adr_width=29)
self.mmio_wb = mmio_wb = wishbone.Interface(data_width=64, adr_width=29)

self.ibus = ibus = wishbone.Interface()
self.dbus = dbus = wishbone.Interface()


# # #

self.specials += Instance("ExampleRocketSystem",
# clock, reset
i_clock=ClockSignal(),
i_reset=ResetSignal() | self.reset,

# debug (ignored)
#o_debug_clockeddmi_dmi_req_ready=,
i_debug_clockeddmi_dmi_req_valid=0,
i_debug_clockeddmi_dmi_req_bits_addr=0,
i_debug_clockeddmi_dmi_req_bits_data=0,
i_debug_clockeddmi_dmi_req_bits_op=0,
i_debug_clockeddmi_dmi_resp_ready=0,
#o_debug_clockeddmi_dmi_resp_valid=,
#o_debug_clockeddmi_dmi_resp_bits_data=,
#o_debug_clockeddmi_dmi_resp_bits_resp=,
i_debug_clockeddmi_dmiClock=0,
i_debug_clockeddmi_dmiReset=0,
#o_debug_ndreset=,
#o_debug_dmactive=,


# irq
i_interrupts=self.interrupt,

# axi memory (L1-cached)
i_mem_axi4_0_aw_ready=mem_axi.aw.ready,
o_mem_axi4_0_aw_valid=mem_axi.aw.valid,
o_mem_axi4_0_aw_bits_id=mem_axi.aw.id,
o_mem_axi4_0_aw_bits_addr=mem_axi.aw.addr,
o_mem_axi4_0_aw_bits_len=mem_axi.aw.len,
o_mem_axi4_0_aw_bits_size=mem_axi.aw.size,
o_mem_axi4_0_aw_bits_burst=mem_axi.aw.burst,
o_mem_axi4_0_aw_bits_lock=mem_axi.aw.lock,
o_mem_axi4_0_aw_bits_cache=mem_axi.aw.cache,
o_mem_axi4_0_aw_bits_prot=mem_axi.aw.prot,
o_mem_axi4_0_aw_bits_qos=mem_axi.aw.qos,

i_mem_axi4_0_w_ready=mem_axi.w.ready,
o_mem_axi4_0_w_valid=mem_axi.w.valid,
o_mem_axi4_0_w_bits_data=mem_axi.w.data,
o_mem_axi4_0_w_bits_strb=mem_axi.w.strb,
o_mem_axi4_0_w_bits_last=mem_axi.w.last,

o_mem_axi4_0_b_ready=mem_axi.b.ready,
i_mem_axi4_0_b_valid=mem_axi.b.valid,
i_mem_axi4_0_b_bits_id=mem_axi.b.id,
i_mem_axi4_0_b_bits_resp=mem_axi.b.resp,

i_mem_axi4_0_ar_ready=mem_axi.ar.ready,
o_mem_axi4_0_ar_valid=mem_axi.ar.valid,
o_mem_axi4_0_ar_bits_id=mem_axi.ar.id,
o_mem_axi4_0_ar_bits_addr=mem_axi.ar.addr,
o_mem_axi4_0_ar_bits_len=mem_axi.ar.len,
o_mem_axi4_0_ar_bits_size=mem_axi.ar.size,
o_mem_axi4_0_ar_bits_burst=mem_axi.ar.burst,
o_mem_axi4_0_ar_bits_lock=mem_axi.ar.lock,
o_mem_axi4_0_ar_bits_cache=mem_axi.ar.cache,
o_mem_axi4_0_ar_bits_prot=mem_axi.ar.prot,
o_mem_axi4_0_ar_bits_qos=mem_axi.ar.qos,

o_mem_axi4_0_r_ready=mem_axi.r.ready,
i_mem_axi4_0_r_valid=mem_axi.r.valid,
i_mem_axi4_0_r_bits_id=mem_axi.r.id,
i_mem_axi4_0_r_bits_data=mem_axi.r.data,
i_mem_axi4_0_r_bits_resp=mem_axi.r.resp,
i_mem_axi4_0_r_bits_last=mem_axi.r.last,

# axi mmio (not cached)
i_mmio_axi4_0_aw_ready=mmio_axi.aw.ready,
o_mmio_axi4_0_aw_valid=mmio_axi.aw.valid,
o_mmio_axi4_0_aw_bits_id=mmio_axi.aw.id,
o_mmio_axi4_0_aw_bits_addr=mmio_axi.aw.addr,
o_mmio_axi4_0_aw_bits_len=mmio_axi.aw.len,
o_mmio_axi4_0_aw_bits_size=mmio_axi.aw.size,
o_mmio_axi4_0_aw_bits_burst=mmio_axi.aw.burst,
o_mmio_axi4_0_aw_bits_lock=mmio_axi.aw.lock,
o_mmio_axi4_0_aw_bits_cache=mmio_axi.aw.cache,
o_mmio_axi4_0_aw_bits_prot=mmio_axi.aw.prot,
o_mmio_axi4_0_aw_bits_qos=mmio_axi.aw.qos,

i_mmio_axi4_0_w_ready=mmio_axi.w.ready,
o_mmio_axi4_0_w_valid=mmio_axi.w.valid,
o_mmio_axi4_0_w_bits_data=mmio_axi.w.data,
o_mmio_axi4_0_w_bits_strb=mmio_axi.w.strb,
o_mmio_axi4_0_w_bits_last=mmio_axi.w.last,

o_mmio_axi4_0_b_ready=mmio_axi.b.ready,
i_mmio_axi4_0_b_valid=mmio_axi.b.valid,
i_mmio_axi4_0_b_bits_id=mmio_axi.b.id,
i_mmio_axi4_0_b_bits_resp=mmio_axi.b.resp,

i_mmio_axi4_0_ar_ready=mmio_axi.ar.ready,
o_mmio_axi4_0_ar_valid=mmio_axi.ar.valid,
o_mmio_axi4_0_ar_bits_id=mmio_axi.ar.id,
o_mmio_axi4_0_ar_bits_addr=mmio_axi.ar.addr,
o_mmio_axi4_0_ar_bits_len=mmio_axi.ar.len,
o_mmio_axi4_0_ar_bits_size=mmio_axi.ar.size,
o_mmio_axi4_0_ar_bits_burst=mmio_axi.ar.burst,
o_mmio_axi4_0_ar_bits_lock=mmio_axi.ar.lock,
o_mmio_axi4_0_ar_bits_cache=mmio_axi.ar.cache,
o_mmio_axi4_0_ar_bits_prot=mmio_axi.ar.prot,
o_mmio_axi4_0_ar_bits_qos=mmio_axi.ar.qos,

o_mmio_axi4_0_r_ready=mmio_axi.r.ready,
i_mmio_axi4_0_r_valid=mmio_axi.r.valid,
i_mmio_axi4_0_r_bits_id=mmio_axi.r.id,
i_mmio_axi4_0_r_bits_data=mmio_axi.r.data,
i_mmio_axi4_0_r_bits_resp=mmio_axi.r.resp,
i_mmio_axi4_0_r_bits_last=mmio_axi.r.last,
)

# adapt axi interfaces to wishbone
mem_a2w = ResetInserter()(
axi.AXI2Wishbone(mem_axi, mem_wb, base_address=0))
mmio_a2w = ResetInserter()(
axi.AXI2Wishbone(mmio_axi, mmio_wb, base_address=0))
# NOTE: AXI2Wishbone FSMs must be reset with the CPU!
self.comb += [
mem_a2w.reset.eq(ResetSignal() | self.reset),
mmio_a2w.reset.eq(ResetSignal() | self.reset),
]

# down-convert wishbone from 64 to 32 bit data width
mem_dc = wishbone.Converter(mem_wb, ibus)
mmio_dc = wishbone.Converter(mmio_wb, dbus)

self.submodules += mem_a2w, mem_dc, mmio_a2w, mmio_dc

# add verilog sources
self.add_sources(platform)

@staticmethod
def add_sources(platform):
vdir = os.path.join(
os.path.abspath(os.path.dirname(__file__)), "verilog")
platform.add_sources(
os.path.join(vdir, "generated-src"),
"freechips.rocketchip.system.LitexConfig.v",
"freechips.rocketchip.system.LitexConfig.behav_srams.v",
)
platform.add_sources(
os.path.join(vdir, "vsrc"),
"plusarg_reader.v",
"AsyncResetReg.v",
"EICG_wrapper.v",
)
1 change: 1 addition & 0 deletions litex/soc/cores/cpu/rocket/verilog
Submodule verilog added at bcb12b
7 changes: 5 additions & 2 deletions litex/soc/integration/soc_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,9 @@ class SoCCore(Module):
csr_map = {}
interrupt_map = {}
mem_map = {
"rom": 0x00000000, # (default shadow @0x80000000)
"sram": 0x10000000, # (default shadow @0x90000000)
# RocketChip reserves the first 256MBytes for internal use
"rom": 0x10000000, # (default shadow @0x90000000)
"sram": 0x20000000, # (default shadow @0xa0000000)
"main_ram": 0x40000000, # (default shadow @0xc0000000)
"csr": 0x60000000, # (default shadow @0xe0000000)
}
Expand Down Expand Up @@ -267,6 +268,8 @@ def __init__(self, platform, clk_freq,
self.add_cpu(vexriscv.VexRiscv(platform, self.cpu_reset_address, self.cpu_variant))
elif cpu_type == "minerva":
self.add_cpu(minerva.Minerva(platform, self.cpu_reset_address, self.cpu_variant))
elif cpu_type == "rocket":
self.add_cpu(rocket.RocketRV64(platform, self.cpu_reset_address, self.cpu_variant))
else:
raise ValueError("Unsupported CPU type: {}".format(cpu_type))
self.add_csr("cpu", allow_user_defined=True)
Expand Down
4 changes: 4 additions & 0 deletions litex/soc/software/bios/boot-helper-rocket.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.section .text, "ax", @progbits
.global boot_helper
boot_helper:
jr x13
47 changes: 45 additions & 2 deletions litex/soc/software/bios/isr.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,57 @@
#include <generated/csr.h>
#include <irq.h>
#include <uart.h>
#include <stdio.h>

#ifdef __rocket__
void plic_init(void);
void plic_init(void)
{
int i;

// priorities for interrupt pins 1..4
for (i = 1; i <= 4; i++)
csr_writel(1, PLIC_BASE + 4*i);
// enable interrupt pins 1..4
csr_writel(0xf << 1, PLIC_ENABLED);
// set priority threshold to 0 (any priority > 0 triggers interrupt)
csr_writel(0, PLIC_THRSHLD);
}

void isr(void);
void isr(void)
{
unsigned int claim;

while ((claim = csr_readl(PLIC_CLAIM))) {
switch (claim - 1) {
case UART_INTERRUPT:
uart_isr();
break;
default:
printf("## PLIC: Unhandled claim: %d\n", claim);
printf("# plic_enabled: %08x\n", irq_getmask());
printf("# plic_pending: %08x\n", irq_pending());
printf("# mepc: %016lx\n", csrr(mepc));
printf("# mcause: %016lx\n", csrr(mcause));
printf("# mtval: %016lx\n", csrr(mtval));
printf("# mie: %016lx\n", csrr(mie));
printf("# mip: %016lx\n", csrr(mip));
printf("###########################\n\n");
break;
}
csr_writel(claim, PLIC_CLAIM);
}
}
#else
void isr(void);
void isr(void)
{
unsigned int irqs;

irqs = irq_pending() & irq_getmask();

if(irqs & (1 << UART_INTERRUPT))
uart_isr();
}
#endif
2 changes: 2 additions & 0 deletions litex/soc/software/bios/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,8 @@ int main(int i, char **c)
printf("VexRiscv");
#elif __minerva__
printf("Minerva");
#elif __rocket__
printf("RocketRV64[imac]");
#else
printf("Unknown");
#endif
Expand Down
2 changes: 2 additions & 0 deletions litex/soc/software/bios/sdram.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ __attribute__((unused)) static void cdelay(int i)
__asm__ volatile("nop");
#elif defined (__minerva__)
__asm__ volatile("nop");
#elif defined (__rocket__)
__asm__ volatile("nop");
#else
#error Unsupported architecture
#endif
Expand Down
Loading

0 comments on commit aa640f2

Please sign in to comment.