Merge pull request #1829 from enjoy-digital/kianv
cores/cpu: Add KianV CPU (RV32IMA) initial support.
This commit is contained in:
commit
862a0dbbbf
|
@ -23,6 +23,7 @@
|
|||
- cores/uart : Added 64-bit addressing support to Stream2Wishbone.
|
||||
- tools : Added 64-bit addressing support to litex_server/client.
|
||||
- cores/cpu : Added 64-bit support to CPUNone.
|
||||
- cores/cpu : Added KianV (RV32IMA) initial support.
|
||||
|
||||
[> Changed
|
||||
----------
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
from litex.soc.cores.cpu.kianv.core import KianV
|
|
@ -0,0 +1,4 @@
|
|||
.section .text, "ax", @progbits
|
||||
.global boot_helper
|
||||
boot_helper:
|
||||
jr x13
|
|
@ -0,0 +1,135 @@
|
|||
#
|
||||
# This file is part of LiteX.
|
||||
#
|
||||
# Copyright (c) 2023 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
import os
|
||||
|
||||
from migen import *
|
||||
|
||||
from litex.gen import *
|
||||
|
||||
from litex.soc.interconnect import wishbone
|
||||
from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV32
|
||||
|
||||
# Variants -----------------------------------------------------------------------------------------
|
||||
|
||||
CPU_VARIANTS = {
|
||||
"standard": "kianv",
|
||||
}
|
||||
|
||||
# GCC Flags ----------------------------------------------------------------------------------------
|
||||
|
||||
GCC_FLAGS = {
|
||||
# /------------ Base ISA
|
||||
# | /------- Hardware Multiply + Divide
|
||||
# | |/----- Atomics
|
||||
# | ||/---- Compressed ISA
|
||||
# | |||/--- Single-Precision Floating-Point
|
||||
# | ||||/-- Double-Precision Floating-Point
|
||||
# i macfd
|
||||
"standard": "-march=rv32i2p0_ma -mabi=ilp32",
|
||||
}
|
||||
|
||||
# KianV ------------------------------------------------------------------------------------------
|
||||
|
||||
class KianV(CPU):
|
||||
category = "softcore"
|
||||
family = "riscv"
|
||||
name = "kianv"
|
||||
human_name = "kianv"
|
||||
variants = CPU_VARIANTS
|
||||
data_width = 32
|
||||
endianness = "little"
|
||||
gcc_triple = CPU_GCC_TRIPLE_RISCV32
|
||||
linker_output_format = "elf32-littleriscv"
|
||||
nop = "nop"
|
||||
io_regions = {0x8000_0000: 0x8000_0000} # Origin, Length.
|
||||
|
||||
# GCC Flags.
|
||||
@property
|
||||
def gcc_flags(self):
|
||||
flags = GCC_FLAGS[self.variant]
|
||||
flags += " -D__kianv__ "
|
||||
return flags
|
||||
|
||||
def __init__(self, platform, variant="standard"):
|
||||
self.platform = platform
|
||||
self.variant = variant
|
||||
self.human_name = f"KianV-{variant.upper()}"
|
||||
self.reset = Signal()
|
||||
self.idbus = idbus = wishbone.Interface(data_width=32, address_width=32, addressing="byte")
|
||||
self.periph_buses = [idbus] # Peripheral buses (Connected to main SoC's bus).
|
||||
self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM).
|
||||
|
||||
# KianV Mem Bus.
|
||||
# ----------------
|
||||
mbus = Record([
|
||||
("valid", 1),
|
||||
("ready", 1),
|
||||
("wstrb", 4),
|
||||
("addr", 32),
|
||||
("wdata", 32),
|
||||
("rdata", 32),
|
||||
])
|
||||
|
||||
# KianV Instance.
|
||||
# -----------------
|
||||
self.cpu_params = dict(
|
||||
# Clk / Rst.
|
||||
i_clk = ClockSignal("sys"),
|
||||
i_resetn = ~(ResetSignal("sys") | self.reset),
|
||||
|
||||
# Parameters.
|
||||
p_RESET_ADDR = 0,
|
||||
p_STACKADDR = 0,
|
||||
p_RV32E = 0,
|
||||
|
||||
# Control/Status.
|
||||
o_PC = Open(),
|
||||
i_access_fault = 0,
|
||||
i_IRQ3 = 0,
|
||||
i_IRQ7 = 0,
|
||||
|
||||
# I/D Bus.
|
||||
o_mem_valid = mbus.valid,
|
||||
i_mem_ready = mbus.ready,
|
||||
o_mem_wstrb = mbus.wstrb,
|
||||
o_mem_addr = mbus.addr,
|
||||
o_mem_wdata = mbus.wdata,
|
||||
i_mem_rdata = mbus.rdata,
|
||||
)
|
||||
|
||||
# Adapt KianV Mem Bus to Wishbone.
|
||||
# --------------------------------
|
||||
self.comb += [
|
||||
idbus.stb.eq(mbus.valid),
|
||||
idbus.cyc.eq(mbus.valid),
|
||||
mbus.ready.eq(idbus.ack),
|
||||
idbus.we.eq(mbus.wstrb != 0),
|
||||
idbus.adr.eq(mbus.addr),
|
||||
idbus.sel.eq(mbus.wstrb),
|
||||
idbus.dat_w.eq(mbus.wdata),
|
||||
mbus.rdata.eq(idbus.dat_r),
|
||||
]
|
||||
|
||||
# Add Verilog sources.
|
||||
# --------------------
|
||||
self.add_sources(platform, variant)
|
||||
|
||||
def set_reset_address(self, reset_address):
|
||||
self.reset_address = reset_address
|
||||
self.cpu_params.update(p_RESET_ADDR=Constant(reset_address, 32))
|
||||
|
||||
@staticmethod
|
||||
def add_sources(platform, variant):
|
||||
if not os.path.exists("KianRiscv"):
|
||||
os.system(f"git clone https://github.com/splinedrive/kianRiscV")
|
||||
vdir = "kianRiscV/linux_socs/kianv_harris_mcycle_edition/kianv_harris_edition"
|
||||
platform.add_verilog_include_path(vdir)
|
||||
platform.add_source_dir(vdir)
|
||||
|
||||
def do_finalize(self):
|
||||
assert hasattr(self, "reset_address")
|
||||
self.specials += Instance("kianv_harris_mc_edition", **self.cpu_params)
|
|
@ -0,0 +1,75 @@
|
|||
#define MIE_MEIE 0x800
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
j reset_vector
|
||||
|
||||
reset_vector:
|
||||
la sp, _fstack
|
||||
la t0, trap_vector
|
||||
csrw mtvec, t0
|
||||
|
||||
// initialize .data
|
||||
la t0, _fdata
|
||||
la t1, _edata
|
||||
la t2, _fdata_rom
|
||||
1: beq t0, t1, 2f
|
||||
lw t3, 0(t2)
|
||||
sw t3, 0(t0)
|
||||
addi t0, t0, 4
|
||||
addi t2, t2, 4
|
||||
j 1b
|
||||
2:
|
||||
|
||||
// initialize .bss
|
||||
la t0, _fbss
|
||||
la t1, _ebss
|
||||
1: beq t0, t1, 3f
|
||||
sw zero, 0(t0)
|
||||
addi t0, t0, 4
|
||||
j 1b
|
||||
3:
|
||||
// enable external interrupts
|
||||
li t0, MIE_MEIE
|
||||
csrs mie, t0
|
||||
|
||||
call main
|
||||
1: j 1b
|
||||
|
||||
trap_vector:
|
||||
addi sp, sp, -16*4
|
||||
sw ra, 0*4(sp)
|
||||
sw t0, 1*4(sp)
|
||||
sw t1, 2*4(sp)
|
||||
sw t2, 3*4(sp)
|
||||
sw a0, 4*4(sp)
|
||||
sw a1, 5*4(sp)
|
||||
sw a2, 6*4(sp)
|
||||
sw a3, 7*4(sp)
|
||||
sw a4, 8*4(sp)
|
||||
sw a5, 9*4(sp)
|
||||
sw a6, 10*4(sp)
|
||||
sw a7, 11*4(sp)
|
||||
sw t3, 12*4(sp)
|
||||
sw t4, 13*4(sp)
|
||||
sw t5, 14*4(sp)
|
||||
sw t6, 15*4(sp)
|
||||
call isr
|
||||
lw ra, 0*4(sp)
|
||||
lw t0, 1*4(sp)
|
||||
lw t1, 2*4(sp)
|
||||
lw t2, 3*4(sp)
|
||||
lw a0, 4*4(sp)
|
||||
lw a1, 5*4(sp)
|
||||
lw a2, 6*4(sp)
|
||||
lw a3, 7*4(sp)
|
||||
lw a4, 8*4(sp)
|
||||
lw a5, 9*4(sp)
|
||||
lw a6, 10*4(sp)
|
||||
lw a7, 11*4(sp)
|
||||
lw t3, 12*4(sp)
|
||||
lw t4, 13*4(sp)
|
||||
lw t5, 14*4(sp)
|
||||
lw t6, 15*4(sp)
|
||||
addi sp, sp, 16*4
|
||||
mret
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef __IRQ_H
|
||||
#define __IRQ_H
|
||||
|
||||
#endif /* __IRQ_H */
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef __SYSTEM_H
|
||||
#define __SYSTEM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__attribute__((unused)) static void flush_cpu_icache(void){}; /* No instruction cache */
|
||||
__attribute__((unused)) static void flush_cpu_dcache(void){}; /* No instruction cache */
|
||||
void flush_l2_cache(void);
|
||||
|
||||
void busy_wait(unsigned int ms);
|
||||
void busy_wait_us(unsigned int us);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYSTEM_H */
|
Loading…
Reference in New Issue