--- /dev/null
+from litex.soc.cores.cpu.vexriscv.core import VexRiscv
--- /dev/null
+import os
+
+from migen import *
+
+from litex.soc.interconnect import wishbone
+
+
+class VexRiscv(Module):
+ def __init__(self, platform, cpu_reset_address):
+ self.ibus = i = wishbone.Interface()
+ self.dbus = d = wishbone.Interface()
+
+ self.interrupt = Signal(32)
+
+ self.specials += Instance("VexRiscv",
+ i_clk=ClockSignal(),
+ i_reset=ResetSignal(),
+
+ i_externalResetVector=cpu_reset_address,
+ i_externalInterruptArray=self.interrupt,
+ i_timerInterrupt=0,
+
+ o_iBusWishbone_ADR=i.adr,
+ o_iBusWishbone_DAT_MOSI=i.dat_w,
+ o_iBusWishbone_SEL=i.sel,
+ o_iBusWishbone_CYC=i.cyc,
+ o_iBusWishbone_STB=i.stb,
+ o_iBusWishbone_WE=i.we,
+ o_iBusWishbone_CTI=i.cti,
+ o_iBusWishbone_BTE=i.bte,
+ i_iBusWishbone_DAT_MISO=i.dat_r,
+ i_iBusWishbone_ACK=i.ack,
+ i_iBusWishbone_ERR=i.err,
+
+ o_dBusWishbone_ADR=d.adr,
+ o_dBusWishbone_DAT_MOSI=d.dat_w,
+ o_dBusWishbone_SEL=d.sel,
+ o_dBusWishbone_CYC=d.cyc,
+ o_dBusWishbone_STB=d.stb,
+ o_dBusWishbone_WE=d.we,
+ o_dBusWishbone_CTI=d.cti,
+ o_dBusWishbone_BTE=d.bte,
+ i_dBusWishbone_DAT_MISO=d.dat_r,
+ i_dBusWishbone_ACK=d.ack,
+ i_dBusWishbone_ERR=d.err)
+
+ # add Verilog sources
+ vdir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "verilog")
+ platform.add_sources(os.path.join(vdir), "VexRiscv.v")
+ platform.add_verilog_include_path(vdir)
cpu_endianness = {
"lm32": "big",
"or1k": "big",
- "picorv32": "little"
+ "picorv32": "little",
+ "vexriscv": "little"
}
def get_cpu_mak(cpu):
triple = "riscv32-unknown-elf"
cpuflags = "-D__picorv32__ -mno-save-restore -march=rv32im -mabi=ilp32"
clang = False
+ elif cpu == "vexriscv":
+ assert not clang, "vexrisv not supported with clang."
+ triple = "riscv32-unknown-elf"
+ cpuflags = "-D__vexriscv__ -march=rv32im -mabi=ilp32"
+ clang = False
else:
raise ValueError("Unsupported CPU type: "+cpu)
linker_output_formats = {
"lm32": "elf32-lm32",
"or1k": "elf32-or1k",
- "picorv32": "elf32-littleriscv"
+ "picorv32": "elf32-littleriscv",
+ "vexriscv": "elf32-littleriscv"
}
return "OUTPUT_FORMAT(\"" + linker_output_formats[cpu_type] + "\")\n"
from migen import *
from litex.soc.cores import identifier, timer, uart
-from litex.soc.cores.cpu import lm32, mor1kx, picorv32
+from litex.soc.cores.cpu import lm32, mor1kx, picorv32, vexriscv
from litex.soc.interconnect import wishbone, csr_bus, wishbone2csr
self.add_cpu_or_bridge(mor1kx.MOR1KX(platform, self.cpu_reset_address, self.cpu_variant))
elif cpu_type == "picorv32":
self.add_cpu_or_bridge(picorv32.PicoRV32(platform, self.cpu_reset_address, self.cpu_variant))
+ elif cpu_type == "vexriscv":
+ self.add_cpu_or_bridge(vexriscv.VexRiscv(platform, self.cpu_reset_address))
else:
raise ValueError("Unsupported CPU type: {}".format(cpu_type))
self.add_wb_master(self.cpu_or_bridge.ibus)
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
chmod -x $@
+ifeq ($(CPUENDIANNESS),little)
+ $(PYTHON) -m litex.soc.tools.mkmscimg $@ --little
+else
$(PYTHON) -m litex.soc.tools.mkmscimg $@
+endif
bios.elf: $(BIOS_DIRECTORY)/linker.ld $(OBJECTS)
--- /dev/null
+.section .text, "ax", @progbits
+.global boot_helper
+boot_helper:
+ nop
printf("\e[1mMOR1K\e[0m\n");
#elif __picorv32__
printf("\e[1mPicoRV32\e[0m\n");
+#elif __vexriscv__
+ printf("\e[1mVexRiscv\e[0m\n");
#else
printf("\e[1mUnknown\e[0m\n");
#endif
__asm__ volatile("l.nop");
#elif defined (__picorv32__)
__asm__ volatile("nop");
+#elif defined (__vexriscv__)
+ __asm__ volatile("nop");
#else
#error Unsupported architecture
#endif
--- /dev/null
+#ifndef CSR_DEFS__H
+#define CSR_DEFS__H
+
+#define CSR_MSTATUS_MIE 0x8
+
+#define CSR_IRQ_MASK 0x330
+#define CSR_IRQ_PENDING 0x360
+
+#define CSR_DCACHE_INFO 0xCC0
+
+#endif /* CSR_DEFS__H */
return !!(mfspr(SPR_SR) & SPR_SR_IEE);
#elif defined (__picorv32__)
return _irq_enabled != 0;
+#elif defined (__vexriscv__)
+ return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0;
#else
#error Unsupported architecture
#endif
_irq_enable();
else
_irq_disable();
+#elif defined (__vexriscv__)
+ if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE);
#else
#error Unsupported architecture
#endif
// PicoRV32 interrupt mask bits are high-disabled. This is the inverse of how
// LiteX sees things.
return ~_irq_mask;
+#elif defined (__vexriscv__)
+ unsigned int mask;
+ asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK));
+ return mask;
#else
#error Unsupported architecture
#endif
// PicoRV32 interrupt mask bits are high-disabled. This is the inverse of how
// LiteX sees things.
_irq_setmask(~mask);
+#elif defined (__vexriscv__)
+ asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask));
#else
#error Unsupported architecture
#endif
return mfspr(SPR_PICSR);
#elif defined (__picorv32__)
return _irq_pending;
+#elif defined (__vexriscv__)
+ unsigned int pending;
+ asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING));
+ return pending;
#else
#error Unsupported architecture
#endif
}
#endif
+
+#if defined(__vexriscv__)
+#include <csr-defs.h>
+#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)); })
+#endif
+
#ifdef __cplusplus
}
#endif
--- /dev/null
+.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 + 4
+ la a0, trap_entry
+ csrw mtvec, a0
+
+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 sources (until mstatus.MIE is set, they will never trigger an interrupt)
+ csrw mie,a0
+
+ call main
+infinit_loop:
+ j infinit_loop
#include <spr-defs.h>
#endif
+#ifdef __vexriscv__
+#include <csr-defs.h>
+#endif
+
#include <system.h>
#include <generated/mem.h>
#include <generated/csr.h>
#elif defined (__picorv32__)
/* no instruction cache */
asm volatile("nop");
+#elif defined (__vexriscv__)
+ asm volatile(
+ ".word(0x400F)\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ );
#else
#error Unsupported architecture
#endif
#elif defined (__picorv32__)
/* no data cache */
asm volatile("nop");
+#elif defined (__vexriscv__)
+ unsigned long cache_info;
+ asm volatile ("csrr %0, %1" : "=r"(cache_info) : "i"(CSR_DCACHE_INFO));
+ unsigned long cache_way_size = cache_info & 0xFFFFF;
+ unsigned long cache_line_size = (cache_info >> 20) & 0xFFF;
+ for(register unsigned long idx = 0;idx < cache_way_size;idx += cache_line_size){
+ asm volatile("mv x10, %0 \n .word(0b01110000000001010101000000001111)"::"r"(idx));
+ }
#else
#error Unsupported architecture
#endif
import binascii
-def insert_crc(i_filename, fbi_mode=False, o_filename=None):
+def insert_crc(i_filename, fbi_mode=False, o_filename=None, little_endian=False):
+ endian = "little" if little_endian else "big"
+
if o_filename is None:
o_filename = i_filename
with open(i_filename, "rb") as f:
fdata = f.read()
- fcrc = binascii.crc32(fdata).to_bytes(4, byteorder="big")
- flength = len(fdata).to_bytes(4, byteorder="big")
+ fcrc = binascii.crc32(fdata).to_bytes(4, byteorder=endian)
+ flength = len(fdata).to_bytes(4, byteorder=endian)
with open(o_filename, "wb") as f:
if fbi_mode:
parser.add_argument("input", help="input file")
parser.add_argument("-o", "--output", default=None, help="output file (if not specified, use input file)")
parser.add_argument("-f", "--fbi", default=False, action="store_true", help="build flash boot image (FBI) file")
+ parser.add_argument("-l", "--little", default=False, action="store_true", help="Use little endian to write the CRC32")
args = parser.parse_args()
- insert_crc(args.input, args.fbi, args.output)
+ insert_crc(args.input, args.fbi, args.output, args.little)
if __name__ == "__main__":