From 6598fe9c12c8fa6634a6aa32641d92f7a3110d9c Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 8 Nov 2023 11:14:28 +0100 Subject: [PATCH] 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> --- CHANGES.md | 1 + litex/soc/cores/cpu/kianv/__init__.py | 1 + litex/soc/cores/cpu/kianv/boot-helper.S | 4 + litex/soc/cores/cpu/kianv/core.py | 135 ++++++++++++++++++++++++ litex/soc/cores/cpu/kianv/crt0.S | 75 +++++++++++++ litex/soc/cores/cpu/kianv/irq.h | 4 + litex/soc/cores/cpu/kianv/system.h | 19 ++++ 7 files changed, 239 insertions(+) create mode 100644 litex/soc/cores/cpu/kianv/__init__.py create mode 100644 litex/soc/cores/cpu/kianv/boot-helper.S create mode 100644 litex/soc/cores/cpu/kianv/core.py create mode 100644 litex/soc/cores/cpu/kianv/crt0.S create mode 100644 litex/soc/cores/cpu/kianv/irq.h create mode 100644 litex/soc/cores/cpu/kianv/system.h diff --git a/CHANGES.md b/CHANGES.md index 0e91a7adb..f5dea39ab 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -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 ---------- diff --git a/litex/soc/cores/cpu/kianv/__init__.py b/litex/soc/cores/cpu/kianv/__init__.py new file mode 100644 index 000000000..d488e5a2c --- /dev/null +++ b/litex/soc/cores/cpu/kianv/__init__.py @@ -0,0 +1 @@ +from litex.soc.cores.cpu.kianv.core import KianV diff --git a/litex/soc/cores/cpu/kianv/boot-helper.S b/litex/soc/cores/cpu/kianv/boot-helper.S new file mode 100644 index 000000000..336a4d4f3 --- /dev/null +++ b/litex/soc/cores/cpu/kianv/boot-helper.S @@ -0,0 +1,4 @@ + .section .text, "ax", @progbits + .global boot_helper +boot_helper: + jr x13 diff --git a/litex/soc/cores/cpu/kianv/core.py b/litex/soc/cores/cpu/kianv/core.py new file mode 100644 index 000000000..449d41bc4 --- /dev/null +++ b/litex/soc/cores/cpu/kianv/core.py @@ -0,0 +1,135 @@ +# +# This file is part of LiteX. +# +# Copyright (c) 2023 Florent Kermarrec +# 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) diff --git a/litex/soc/cores/cpu/kianv/crt0.S b/litex/soc/cores/cpu/kianv/crt0.S new file mode 100644 index 000000000..683f6ad78 --- /dev/null +++ b/litex/soc/cores/cpu/kianv/crt0.S @@ -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 diff --git a/litex/soc/cores/cpu/kianv/irq.h b/litex/soc/cores/cpu/kianv/irq.h new file mode 100644 index 000000000..1aa55bc8e --- /dev/null +++ b/litex/soc/cores/cpu/kianv/irq.h @@ -0,0 +1,4 @@ +#ifndef __IRQ_H +#define __IRQ_H + +#endif /* __IRQ_H */ diff --git a/litex/soc/cores/cpu/kianv/system.h b/litex/soc/cores/cpu/kianv/system.h new file mode 100644 index 000000000..828c87bc1 --- /dev/null +++ b/litex/soc/cores/cpu/kianv/system.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 */