Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental Support for 64-bit RocketChip #186

Merged
merged 2 commits into from
May 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it not be better to keep the original sys_clk_freq; and only switch down to 50MHz if using Rocket?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, i agree, i already reverted it: cf369c4 and the others changes that were introducing change to others targets.

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