cores/cpu: Add KianV CPU (RV32IMA) initial support.

litex_sim --cpu-type=kianv:

        __   _ __      _  __
       / /  (_) /____ | |/_/
      / /__/ / __/ -_)>  <
     /____/_/\__/\__/_/|_|
   Build your hardware, easily!

 (c) Copyright 2012-2023 Enjoy-Digital
 (c) Copyright 2007-2015 M-Labs

 BIOS built on Nov  8 2023 11:14:03
 BIOS CRC passed (6984e675)

 LiteX git sha1: c1e4b3a8

--=============== SoC ==================--
CPU:		KianV-STANDARD @ 1MHz
BUS:		WISHBONE 32-bit @ 4GiB
CSR:		32-bit data
ROM:		128.0KiB
SRAM:		8.0KiB


--============== Boot ==================--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
Timeout
No boot medium found

--============= Console ================--

litex> ident
Ident: LiteX Simulation 2023-11-08 11:14:00
litex>
This commit is contained in:
Florent Kermarrec 2023-11-08 11:14:28 +01:00
parent c1e4b3a850
commit 6598fe9c12
7 changed files with 239 additions and 0 deletions

View File

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

View File

@ -0,0 +1 @@
from litex.soc.cores.cpu.kianv.core import KianV

View File

@ -0,0 +1,4 @@
.section .text, "ax", @progbits
.global boot_helper
boot_helper:
jr x13

View File

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

View File

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

View File

@ -0,0 +1,4 @@
#ifndef __IRQ_H
#define __IRQ_H
#endif /* __IRQ_H */

View File

@ -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 */