Add initial CVA5 support
This commit is contained in:
parent
4401b5a5e8
commit
5c617d139c
|
@ -0,0 +1 @@
|
|||
from litex.soc.cores.cpu.cva5.core import CVA5
|
|
@ -0,0 +1,4 @@
|
|||
.section .text, "ax", @progbits
|
||||
.global boot_helper
|
||||
boot_helper:
|
||||
jr x13
|
|
@ -0,0 +1,129 @@
|
|||
#
|
||||
# This file is part of LiteX.
|
||||
#
|
||||
# Copyright (c) 2022 Eric Matthews <eric.charles.matthews@gmail.com>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
import os
|
||||
|
||||
from migen import *
|
||||
|
||||
from litex import get_data_mod
|
||||
from litex.soc.interconnect import wishbone
|
||||
from litex.soc.interconnect.csr import *
|
||||
from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV32
|
||||
|
||||
# Variants -----------------------------------------------------------------------------------------
|
||||
|
||||
CPU_VARIANTS = ["minimal", "standard"]
|
||||
|
||||
# GCC Flags ----------------------------------------------------------------------------------------
|
||||
|
||||
GCC_FLAGS = {
|
||||
"minimal" : "-march=rv32i -mabi=ilp32 ",
|
||||
"standard" : "-march=rv32im -mabi=ilp32 "
|
||||
}
|
||||
|
||||
# CVA5 -----------------------------------------------------------------------------------------
|
||||
|
||||
class CVA5(CPU):
|
||||
category = "softcore"
|
||||
family = "riscv"
|
||||
name = "cva5"
|
||||
human_name = "CVA5"
|
||||
variants = CPU_VARIANTS
|
||||
data_width = 32
|
||||
endianness = "little"
|
||||
gcc_triple = CPU_GCC_TRIPLE_RISCV32
|
||||
linker_output_format = "elf32-littleriscv"
|
||||
nop = "nop"
|
||||
io_regions = {0x80000000: 0x80000000} # origin, length
|
||||
|
||||
# GCC Flags.
|
||||
@property
|
||||
def gcc_flags(self):
|
||||
flags = GCC_FLAGS[self.variant]
|
||||
flags += "-D__cva5__"
|
||||
return flags
|
||||
|
||||
def __init__(self, platform, variant="standard"):
|
||||
self.platform = platform
|
||||
self.variant = variant
|
||||
self.reset = Signal()
|
||||
self.ibus = ibus = wishbone.Interface()
|
||||
self.dbus = dbus = wishbone.Interface()
|
||||
self.idbus = idbus = wishbone.Interface()
|
||||
self.periph_buses = [ibus, dbus] if (variant == "minimal") else [idbus]
|
||||
self.memory_buses = []
|
||||
self.interrupt = Signal(2)
|
||||
|
||||
self.cpu_params = dict(
|
||||
p_LITEX_VARIANT = CPU_VARIANTS.index(variant),
|
||||
p_RESET_VEC = 0,
|
||||
p_NON_CACHABLE_L = 0x80000000,
|
||||
p_NON_CACHABLE_H = 0xFFFFFFFF,
|
||||
|
||||
i_clk = ClockSignal("sys"),
|
||||
i_rst = ResetSignal("sys"),
|
||||
i_litex_interrupt = self.interrupt
|
||||
)
|
||||
if variant == "minimal" :
|
||||
self.cpu_params.update(
|
||||
o_ibus_adr = ibus.adr,
|
||||
o_ibus_dat_w = ibus.dat_w,
|
||||
o_ibus_sel = ibus.sel,
|
||||
o_ibus_cyc = ibus.cyc,
|
||||
o_ibus_stb = ibus.stb,
|
||||
o_ibus_we = ibus.we,
|
||||
o_ibus_cti = ibus.cti,
|
||||
o_ibus_bte = ibus.bte,
|
||||
i_ibus_dat_r = ibus.dat_r,
|
||||
i_ibus_ack = ibus.ack,
|
||||
i_ibus_err = ibus.err,
|
||||
|
||||
o_dbus_adr = dbus.adr,
|
||||
o_dbus_dat_w = dbus.dat_w,
|
||||
o_dbus_sel = dbus.sel,
|
||||
o_dbus_cyc = dbus.cyc,
|
||||
o_dbus_stb = dbus.stb,
|
||||
o_dbus_we = dbus.we,
|
||||
o_dbus_cti = dbus.cti,
|
||||
o_dbus_bte = dbus.bte,
|
||||
i_dbus_dat_r = dbus.dat_r,
|
||||
i_dbus_ack = dbus.ack,
|
||||
i_dbus_err = dbus.err
|
||||
)
|
||||
else :
|
||||
self.cpu_params.update(
|
||||
o_idbus_adr = idbus.adr,
|
||||
o_idbus_dat_w = idbus.dat_w,
|
||||
o_idbus_sel = idbus.sel,
|
||||
o_idbus_cyc = idbus.cyc,
|
||||
o_idbus_stb = idbus.stb,
|
||||
o_idbus_we = idbus.we,
|
||||
o_idbus_cti = idbus.cti,
|
||||
o_idbus_bte = idbus.bte,
|
||||
i_idbus_dat_r = idbus.dat_r,
|
||||
i_idbus_ack = idbus.ack,
|
||||
i_idbus_err = idbus.err,
|
||||
)
|
||||
self.add_sources(platform)
|
||||
|
||||
def set_reset_address(self, reset_address):
|
||||
assert not hasattr(self, "reset_address")
|
||||
self.reset_address = reset_address
|
||||
self.cpu_params.update(p_RESET_VEC = reset_address)
|
||||
|
||||
@staticmethod
|
||||
def add_sources(platform):
|
||||
cva5_path = get_data_mod("cpu", "cva5").data_location
|
||||
with open(os.path.join(cva5_path, 'tools/compile_order'), 'r') as f:
|
||||
for line in f:
|
||||
if line.strip() != '':
|
||||
platform.add_source(os.path.join(cva5_path, line.strip()))
|
||||
platform.add_source(os.path.join(cva5_path, 'examples/litex/l1_to_wishbone.sv'))
|
||||
platform.add_source(os.path.join(cva5_path, 'examples/litex/litex_wrapper.sv'))
|
||||
|
||||
def do_finalize(self):
|
||||
assert hasattr(self, "reset_address")
|
||||
self.specials += Instance("litex_wrapper", **self.cpu_params)
|
|
@ -0,0 +1,89 @@
|
|||
.global main
|
||||
.global isr
|
||||
.global _start
|
||||
|
||||
_start:
|
||||
j crt_init
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
.global trap_entry
|
||||
trap_entry:
|
||||
sw x1, - 1*4(sp)
|
||||
sw x5, - 2*4(sp)
|
||||
sw x6, - 3*4(sp)
|
||||
sw x7, - 4*4(sp)
|
||||
sw x10, - 5*4(sp)
|
||||
sw x11, - 6*4(sp)
|
||||
sw x12, - 7*4(sp)
|
||||
sw x13, - 8*4(sp)
|
||||
sw x14, - 9*4(sp)
|
||||
sw x15, -10*4(sp)
|
||||
sw x16, -11*4(sp)
|
||||
sw x17, -12*4(sp)
|
||||
sw x28, -13*4(sp)
|
||||
sw x29, -14*4(sp)
|
||||
sw x30, -15*4(sp)
|
||||
sw x31, -16*4(sp)
|
||||
addi sp,sp,-16*4
|
||||
call isr
|
||||
lw x1 , 15*4(sp)
|
||||
lw x5, 14*4(sp)
|
||||
lw x6, 13*4(sp)
|
||||
lw x7, 12*4(sp)
|
||||
lw x10, 11*4(sp)
|
||||
lw x11, 10*4(sp)
|
||||
lw x12, 9*4(sp)
|
||||
lw x13, 8*4(sp)
|
||||
lw x14, 7*4(sp)
|
||||
lw x15, 6*4(sp)
|
||||
lw x16, 5*4(sp)
|
||||
lw x17, 4*4(sp)
|
||||
lw x28, 3*4(sp)
|
||||
lw x29, 2*4(sp)
|
||||
lw x30, 1*4(sp)
|
||||
lw x31, 0*4(sp)
|
||||
addi sp,sp,16*4
|
||||
mret
|
||||
.text
|
||||
|
||||
|
||||
crt_init:
|
||||
la sp, _fstack
|
||||
la a0, trap_entry
|
||||
csrw mtvec, a0
|
||||
|
||||
data_init:
|
||||
la a0, _fdata
|
||||
la a1, _edata
|
||||
la a2, _fdata_rom
|
||||
data_loop:
|
||||
beq a0,a1,data_done
|
||||
lw a3,0(a2)
|
||||
sw a3,0(a0)
|
||||
add a0,a0,4
|
||||
add a2,a2,4
|
||||
j data_loop
|
||||
data_done:
|
||||
|
||||
bss_init:
|
||||
la a0, _fbss
|
||||
la a1, _ebss
|
||||
bss_loop:
|
||||
beq a0,a1,bss_done
|
||||
sw zero,0(a0)
|
||||
add a0,a0,4
|
||||
j bss_loop
|
||||
bss_done:
|
||||
|
||||
li a0, 0x880 //880 enable timer + external interrupt (until mstatus.MIE is set, they will never trigger an interrupt)
|
||||
csrw mie,a0
|
||||
|
||||
call main
|
||||
infinit_loop:
|
||||
j infinit_loop
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef CSR_DEFS__H
|
||||
#define CSR_DEFS__H
|
||||
|
||||
#define CSR_MSTATUS_MIE 0x8
|
||||
|
||||
#define CSR_IRQ_EXTERNAL_OFFSET 0xB
|
||||
|
||||
#endif /* CSR_DEFS__H */
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef __IRQ_H
|
||||
#define __IRQ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <system.h>
|
||||
#include <generated/csr.h>
|
||||
#include <generated/soc.h>
|
||||
|
||||
static inline unsigned int irq_getie(void)
|
||||
{
|
||||
return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0;
|
||||
}
|
||||
|
||||
static inline void irq_setie(unsigned int ie)
|
||||
{
|
||||
if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE);
|
||||
}
|
||||
|
||||
static inline unsigned int irq_getmask(void)
|
||||
{
|
||||
return (csrr(mie) >> CSR_IRQ_EXTERNAL_OFFSET);
|
||||
}
|
||||
|
||||
static inline void irq_setmask(unsigned int mask)
|
||||
{
|
||||
if (mask) csrs(mie,CSR_IRQ_EXTERNAL_OFFSET); else csrc(mie,CSR_IRQ_EXTERNAL_OFFSET);
|
||||
}
|
||||
|
||||
static inline unsigned int irq_pending(void)
|
||||
{
|
||||
return ((csrr(mie) | csrr(mip)) >> CSR_IRQ_EXTERNAL_OFFSET) & 0x1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __IRQ_H */
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef __SYSTEM_H
|
||||
#define __SYSTEM_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <csr-defs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CSR_ACCESSORS_DEFINED
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
#define MMPTR(x) x
|
||||
#else /* ! __ASSEMBLER__ */
|
||||
#define MMPTR(a) (*((volatile uint32_t *)(a)))
|
||||
|
||||
//As CVA5 will attempt to re-order loads before stores, a fence after I/O writes is required to ensure
|
||||
//that subsequent loads (to different addresses) are not completed before this store
|
||||
static inline void csr_write_simple(unsigned long v, unsigned long a)
|
||||
{
|
||||
MMPTR(a) = v;
|
||||
asm volatile ("fence;");
|
||||
}
|
||||
|
||||
static inline unsigned long csr_read_simple(unsigned long a)
|
||||
{
|
||||
return MMPTR(a);
|
||||
}
|
||||
#endif /* ! __ASSEMBLER__ */
|
||||
|
||||
__attribute__((unused)) static void flush_cpu_icache(void) { };
|
||||
__attribute__((unused)) static void flush_cpu_dcache(void) { };
|
||||
|
||||
void flush_l2_cache(void);
|
||||
|
||||
void busy_wait(unsigned int ms);
|
||||
void busy_wait_us(unsigned int us);
|
||||
|
||||
#define csrr(reg) ({ unsigned long __tmp; \
|
||||
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
|
||||
__tmp; })
|
||||
|
||||
#define csrw(reg, val) ({ \
|
||||
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
|
||||
asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
|
||||
else \
|
||||
asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
|
||||
|
||||
#define csrs(reg, bit) ({ \
|
||||
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
|
||||
asm volatile ("csrrs x0, " #reg ", %0" :: "i"(bit)); \
|
||||
else \
|
||||
asm volatile ("csrrs x0, " #reg ", %0" :: "r"(bit)); })
|
||||
|
||||
#define csrc(reg, bit) ({ \
|
||||
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
|
||||
asm volatile ("csrrc x0, " #reg ", %0" :: "i"(bit)); \
|
||||
else \
|
||||
asm volatile ("csrrc x0, " #reg ", %0" :: "r"(bit)); })
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYSTEM_H */
|
|
@ -106,6 +106,7 @@ git_repos = {
|
|||
"pythondata-cpu-blackparrot": GitRepo(url="https://github.com/litex-hub/"),
|
||||
"pythondata-cpu-cv32e40p": GitRepo(url="https://github.com/litex-hub/", clone="recursive"),
|
||||
"pythondata-cpu-cv32e41p": GitRepo(url="https://github.com/litex-hub/", clone="recursive"),
|
||||
"pythondata-cpu-cva5": GitRepo(url="https://github.com/litex-hub/"),
|
||||
"pythondata-cpu-ibex": GitRepo(url="https://github.com/litex-hub/", clone="recursive", sha1=0xd3d53df),
|
||||
"pythondata-cpu-marocchino": GitRepo(url="https://github.com/litex-hub/"),
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue