diff --git a/litex/soc/cores/cpu/fazyrv/__init__.py b/litex/soc/cores/cpu/fazyrv/__init__.py new file mode 100644 index 000000000..da0458128 --- /dev/null +++ b/litex/soc/cores/cpu/fazyrv/__init__.py @@ -0,0 +1 @@ +from litex.soc.cores.cpu.fazyrv.core import FazyRV diff --git a/litex/soc/cores/cpu/fazyrv/boot-helper.S b/litex/soc/cores/cpu/fazyrv/boot-helper.S new file mode 100644 index 000000000..336a4d4f3 --- /dev/null +++ b/litex/soc/cores/cpu/fazyrv/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/fazyrv/core.py b/litex/soc/cores/cpu/fazyrv/core.py new file mode 100644 index 000000000..7c4f13500 --- /dev/null +++ b/litex/soc/cores/cpu/fazyrv/core.py @@ -0,0 +1,122 @@ +# +# This file is part of LiteX. +# +# Copyright (c) 2024 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": "fazyrv", +} + +# 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 -mabi=ilp32", +} + +# FazyRV ------------------------------------------------------------------------------------------ + +class FazyRV(CPU): + category = "softcore" + family = "riscv" + name = "fazyrv" + human_name = "fazyrv" + 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__fazyrv__ " + return flags + + def __init__(self, platform, variant="standard"): + self.platform = platform + self.variant = variant + self.human_name = f"FazyRV-{variant.upper()}" + self.reset = Signal() + self.ibus = ibus = wishbone.Interface(data_width=32, address_width=32, addressing="byte") + self.dbus = dbus = wishbone.Interface(data_width=32, address_width=32, addressing="byte") + self.periph_buses = [ibus, dbus] # Peripheral buses (Connected to main SoC's bus). + self.memory_buses = [] # Memory buses (Connected directly to LiteDRAM). + + # FazyRV Instance. + # ----------------- + self.cpu_params = dict( + # Parameters. + p_CHUNKSIZE = 8, + p_CONF = "MIN", + p_MTVAL = 0, + p_BOOTADR = 0, + p_RFTYPE = "BRAM_DP_BP", + p_MEMDLY1 = 0, + + # Clk / Rst. + i_clk_i = ClockSignal("sys"), + i_rst_in = ~(ResetSignal("sys") | self.reset), + + # IRQ / Trap. + i_tirq_i = 0, + o_trap_o = Open(), + + # I Bus. + o_wb_imem_stb_o = ibus.stb, + o_wb_imem_cyc_o = ibus.cyc, + o_wb_imem_adr_o = ibus.adr, + i_wb_imem_dat_i = ibus.dat_r, + i_wb_imem_ack_i = ibus.ack, + + # D Bus. + o_wb_dmem_cyc_o = dbus.cyc, + o_wb_dmem_stb_o = dbus.stb, + o_wb_dmem_we_o = dbus.we, + i_wb_dmem_ack_i = dbus.ack, + o_wb_dmem_be_o = dbus.sel, + i_wb_dmem_dat_i = dbus.dat_r, + o_wb_dmem_adr_o = dbus.adr, + o_wb_dmem_dat_o = dbus.dat_w, + ) + + # 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_BOOTADR=Constant(reset_address, 32)) + + @staticmethod + def add_sources(platform, variant): + if not os.path.exists("FazyR"): + os.system(f"git clone https://github.com/meiniKi/FazyRV") + vdir = "/home/florent/dev/FazyRV/rtl" + platform.add_verilog_include_path(vdir) + platform.add_source_dir(vdir) + + def do_finalize(self): + assert hasattr(self, "reset_address") + self.specials += Instance("fazyrv_top", **self.cpu_params) diff --git a/litex/soc/cores/cpu/fazyrv/crt0.S b/litex/soc/cores/cpu/fazyrv/crt0.S new file mode 100644 index 000000000..683f6ad78 --- /dev/null +++ b/litex/soc/cores/cpu/fazyrv/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/fazyrv/irq.h b/litex/soc/cores/cpu/fazyrv/irq.h new file mode 100644 index 000000000..1aa55bc8e --- /dev/null +++ b/litex/soc/cores/cpu/fazyrv/irq.h @@ -0,0 +1,4 @@ +#ifndef __IRQ_H +#define __IRQ_H + +#endif /* __IRQ_H */ diff --git a/litex/soc/cores/cpu/fazyrv/system.h b/litex/soc/cores/cpu/fazyrv/system.h new file mode 100644 index 000000000..828c87bc1 --- /dev/null +++ b/litex/soc/cores/cpu/fazyrv/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 */