OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neorv32/trunk
    from Rev 39 to Rev 40
    Reverse comparison

Rev 39 → Rev 40

/docs/figures/neorv32_logo_transparent_bg.png Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
docs/figures/neorv32_logo_transparent_bg.png Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: docs/figures/PDF_32.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/figures/PDF_32.png =================================================================== --- docs/figures/PDF_32.png (revision 39) +++ docs/figures/PDF_32.png (nonexistent)
docs/figures/PDF_32.png Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: docs/figures/neorv32_logo_inverse_black_bg.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/figures/neorv32_logo_inverse_black_bg.png =================================================================== --- docs/figures/neorv32_logo_inverse_black_bg.png (revision 39) +++ docs/figures/neorv32_logo_inverse_black_bg.png (nonexistent)
docs/figures/neorv32_logo_inverse_black_bg.png Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: docs/figures/neorv32_logo_inverse_transparent_bg.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/figures/neorv32_logo_inverse_transparent_bg.png =================================================================== --- docs/figures/neorv32_logo_inverse_transparent_bg.png (revision 39) +++ docs/figures/neorv32_logo_inverse_transparent_bg.png (nonexistent)
docs/figures/neorv32_logo_inverse_transparent_bg.png Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: docs/figures/neorv32_logo_white_bg.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/figures/neorv32_logo_white_bg.png =================================================================== --- docs/figures/neorv32_logo_white_bg.png (revision 39) +++ docs/figures/neorv32_logo_white_bg.png (nonexistent)
docs/figures/neorv32_logo_white_bg.png Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: docs/figures/neorv32_logo.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/figures/neorv32_logo.png =================================================================== --- docs/figures/neorv32_logo.png (nonexistent) +++ docs/figures/neorv32_logo.png (revision 40)
docs/figures/neorv32_logo.png Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: docs/figures/neorv32_logo_inverse.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/figures/neorv32_logo_inverse.png =================================================================== --- docs/figures/neorv32_logo_inverse.png (nonexistent) +++ docs/figures/neorv32_logo_inverse.png (revision 40)
docs/figures/neorv32_logo_inverse.png Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: docs/figures/neorv32_logo_transparent.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/figures/neorv32_logo_transparent.png =================================================================== --- docs/figures/neorv32_logo_transparent.png (nonexistent) +++ docs/figures/neorv32_logo_transparent.png (revision 40)
docs/figures/neorv32_logo_transparent.png Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: docs/figures/neorv32_processor.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/figures/neorv32_test_setup.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/figures/neorv32_test_setup.png =================================================================== --- docs/figures/neorv32_test_setup.png (nonexistent) +++ docs/figures/neorv32_test_setup.png (revision 40)
docs/figures/neorv32_test_setup.png Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: docs/figures/oshw_logo.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/NEORV32.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/riscv-privileged.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: docs/riscv-spec.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/.ld_script/link.ld =================================================================== --- riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/.ld_script/link.ld (nonexistent) +++ riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/.ld_script/link.ld (revision 40) @@ -0,0 +1,28 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY(_start) + +SECTIONS +{ + + . = 0x00000000; + .text : { + *(.text.trap) + *(.text.init) + + . = ALIGN(0x1000); + *(.tohost) + + . = ALIGN(0x1000); + *(.text) + _etext = .; + + *(.data) + *(.data.string) + _edata = .; + + *(.bss) + _end = .; + + } + +} Index: riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32Zicsr/Makefile.include =================================================================== --- riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32Zicsr/Makefile.include (nonexistent) +++ riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32Zicsr/Makefile.include (revision 40) @@ -0,0 +1,39 @@ +ifndef NEORV32_HOME + $(error NEORV32_HOME is undefined) +endif + +LDSCRIPT = $(ROOTDIR)/riscv-target/neorv32/device/.ld_script/link.ld +TARGET_SIM ?= ghdl +TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) + + +ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) + $(error Target simulator executable '$(TARGET_SIM)` not found) +endif + +RUN_TARGET=\ + cd $(work_dir_isa); \ + rm -f $(work_dir_isa)/*.out; \ + sed -i '/CPU_EXTENSION_RISCV_Zicsr/c\ CPU_EXTENSION_RISCV_Zicsr => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_HOME)/sim/neorv32_tb.vhd; \ + make -C $(NEORV32_HOME)/sw/example/blink_led main.elf; \ + cp -f $< $(NEORV32_HOME)/sw/example/blink_led/main.elf; \ + make -C $(NEORV32_HOME)/sw/example/blink_led main.bin; \ + make -C $(NEORV32_HOME)/sw/example/blink_led install; \ + sh $(NEORV32_HOME)/sim/ghdl/ghdl_sim.sh --stop-time=100us >> /dev/null; \ + cp $(work_dir_isa)/neorv32.uart.sim_mode.data.out $(*).signature.output; + + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy +RISCV_READELF ?= $(RISCV_PREFIX)readelf +RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -march=rv32i + +COMPILE_TARGET=\ + $$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) \ + -I$(ROOTDIR)/riscv-test-env/ \ + -I$(ROOTDIR)/riscv-test-env/p/ \ + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ + -T$(LDSCRIPT) $$< \ + -o $$@; Index: riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32Zifencei/Makefile.include =================================================================== --- riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32Zifencei/Makefile.include (nonexistent) +++ riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32Zifencei/Makefile.include (revision 40) @@ -0,0 +1,40 @@ +ifndef NEORV32_HOME + $(error NEORV32_HOME is undefined) +endif + +LDSCRIPT = $(ROOTDIR)/riscv-target/neorv32/device/.ld_script/link.ld +TARGET_SIM ?= ghdl +TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) + + +ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) + $(error Target simulator executable '$(TARGET_SIM)` not found) +endif + +RUN_TARGET=\ + cd $(work_dir_isa); \ + rm -f $(work_dir_isa)/*.out; \ + sed -i '/CPU_EXTENSION_RISCV_Zicsr/c\ CPU_EXTENSION_RISCV_Zicsr => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_HOME)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zifencei/c\ CPU_EXTENSION_RISCV_Zifencei => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_HOME)/sim/neorv32_tb.vhd; \ + make -C $(NEORV32_HOME)/sw/example/blink_led main.elf; \ + cp -f $< $(NEORV32_HOME)/sw/example/blink_led/main.elf; \ + make -C $(NEORV32_HOME)/sw/example/blink_led main.bin; \ + make -C $(NEORV32_HOME)/sw/example/blink_led install; \ + sh $(NEORV32_HOME)/sim/ghdl/ghdl_sim.sh --stop-time=100us >> /dev/null; \ + cp $(work_dir_isa)/neorv32.uart.sim_mode.data.out $(*).signature.output; + + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy +RISCV_READELF ?= $(RISCV_PREFIX)readelf +RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -march=rv32i + +COMPILE_TARGET=\ + $$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) \ + -I$(ROOTDIR)/riscv-test-env/ \ + -I$(ROOTDIR)/riscv-test-env/p/ \ + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ + -T$(LDSCRIPT) $$< \ + -o $$@; Index: riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32i/Makefile.include =================================================================== --- riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32i/Makefile.include (nonexistent) +++ riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32i/Makefile.include (revision 40) @@ -0,0 +1,40 @@ +ifndef NEORV32_HOME + $(error NEORV32_HOME is undefined) +endif + +LDSCRIPT = $(ROOTDIR)/riscv-target/neorv32/device/.ld_script/link.ld +TARGET_SIM ?= ghdl +TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) + + +ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) + $(error Target simulator executable '$(TARGET_SIM)` not found) +endif + +RUN_TARGET=\ + cd $(work_dir_isa); \ + rm -f $(work_dir_isa)/*.out; \ + sed -i '/CPU_EXTENSION_RISCV_C/c\ CPU_EXTENSION_RISCV_C => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_HOME)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zicsr/c\ CPU_EXTENSION_RISCV_Zicsr => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_HOME)/sim/neorv32_tb.vhd; \ + make -C $(NEORV32_HOME)/sw/example/blink_led main.elf; \ + cp -f $< $(NEORV32_HOME)/sw/example/blink_led/main.elf; \ + make -C $(NEORV32_HOME)/sw/example/blink_led main.bin; \ + make -C $(NEORV32_HOME)/sw/example/blink_led install; \ + sh $(NEORV32_HOME)/sim/ghdl/ghdl_sim.sh --stop-time=100us >> /dev/null; \ + cp $(work_dir_isa)/neorv32.uart.sim_mode.data.out $(*).signature.output; + + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy +RISCV_READELF ?= $(RISCV_PREFIX)readelf +RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -march=rv32i + +COMPILE_TARGET=\ + $$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) \ + -I$(ROOTDIR)/riscv-test-env/ \ + -I$(ROOTDIR)/riscv-test-env/p/ \ + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ + -T$(LDSCRIPT) $$< \ + -o $$@; Index: riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32im/Makefile.include =================================================================== --- riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32im/Makefile.include (nonexistent) +++ riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32im/Makefile.include (revision 40) @@ -0,0 +1,40 @@ +ifndef NEORV32_HOME + $(error NEORV32_HOME is undefined) +endif + +LDSCRIPT = $(ROOTDIR)/riscv-target/neorv32/device/.ld_script/link.ld +TARGET_SIM ?= ghdl +TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) + + +ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) + $(error Target simulator executable '$(TARGET_SIM)` not found) +endif + +RUN_TARGET=\ + cd $(work_dir_isa); \ + rm -f $(work_dir_isa)/*.out; \ + sed -i '/CPU_EXTENSION_RISCV_M/c\ CPU_EXTENSION_RISCV_M => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_HOME)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zicsr/c\ CPU_EXTENSION_RISCV_Zicsr => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_HOME)/sim/neorv32_tb.vhd; \ + make -C $(NEORV32_HOME)/sw/example/blink_led main.elf; \ + cp -f $< $(NEORV32_HOME)/sw/example/blink_led/main.elf; \ + make -C $(NEORV32_HOME)/sw/example/blink_led main.bin; \ + make -C $(NEORV32_HOME)/sw/example/blink_led install; \ + sh $(NEORV32_HOME)/sim/ghdl/ghdl_sim.sh --stop-time=100us >> /dev/null; \ + cp $(work_dir_isa)/neorv32.uart.sim_mode.data.out $(*).signature.output; + + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy +RISCV_READELF ?= $(RISCV_PREFIX)readelf +RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -march=rv32im + +COMPILE_TARGET=\ + $$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) \ + -I$(ROOTDIR)/riscv-test-env/ \ + -I$(ROOTDIR)/riscv-test-env/p/ \ + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ + -T$(LDSCRIPT) $$< \ + -o $$@; Index: riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32imc/Makefile.include =================================================================== --- riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32imc/Makefile.include (nonexistent) +++ riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/device/rv32imc/Makefile.include (revision 40) @@ -0,0 +1,41 @@ +ifndef NEORV32_HOME + $(error NEORV32_HOME is undefined) +endif + +LDSCRIPT = $(ROOTDIR)/riscv-target/neorv32/device/.ld_script/link.ld +TARGET_SIM ?= ghdl +TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) + + +ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) + $(error Target simulator executable '$(TARGET_SIM)` not found) +endif + +RUN_TARGET=\ + cd $(work_dir_isa); \ + rm -f $(work_dir_isa)/*.out; \ + sed -i '/CPU_EXTENSION_RISCV_C/c\ CPU_EXTENSION_RISCV_C => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_HOME)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_M/c\ CPU_EXTENSION_RISCV_M => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_HOME)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zicsr/c\ CPU_EXTENSION_RISCV_Zicsr => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_HOME)/sim/neorv32_tb.vhd; \ + make -C $(NEORV32_HOME)/sw/example/blink_led main.elf; \ + cp -f $< $(NEORV32_HOME)/sw/example/blink_led/main.elf; \ + make -C $(NEORV32_HOME)/sw/example/blink_led main.bin; \ + make -C $(NEORV32_HOME)/sw/example/blink_led install; \ + sh $(NEORV32_HOME)/sim/ghdl/ghdl_sim.sh --stop-time=100us >> /dev/null; \ + cp $(work_dir_isa)/neorv32.uart.sim_mode.data.out $(*).signature.output; + + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy +RISCV_READELF ?= $(RISCV_PREFIX)readelf +RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -march=rv32imc + +COMPILE_TARGET=\ + $$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) \ + -I$(ROOTDIR)/riscv-test-env/ \ + -I$(ROOTDIR)/riscv-test-env/p/ \ + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ + -T$(LDSCRIPT) $$< \ + -o $$@; Index: riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/README.md =================================================================== --- riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/README.md (nonexistent) +++ riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/README.md (revision 40) @@ -0,0 +1,18 @@ +# Simulation + +The NEORV32 Processor is simulated using the its default testbench. + +Each architecture-specific makefile in the `device` folder uses an _uncool hack_: `sed` is used to +enable/disable the required `CPU_EXTENSION_RISCV_xxx` VHDL configuration generics in the testbench (`neorv32/sim/neorv32_tb.vhd`). + +For instance, the `rv32i` tests requires the `C`-extensions to be disabled - which is enabled by default in the testbench. + +GHDL is used for simulating the processor. + +The results are dumped via the SIM_MODE feature of the UART. The according code can be found in the `RV_COMPLIANCE_HALT` +macro in `compliance_test.h`. + +The `RVTEST_IO_INIT` macro in `compliance_io.h` is used to configure +the UART for SIM_MODE. + +The final data (plain 8-hex char data) is dumped to the `neorv32.uart.sim_mode.data.out` file. Index: riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/compliance_io.h =================================================================== --- riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/compliance_io.h (nonexistent) +++ riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/compliance_io.h (revision 40) @@ -0,0 +1,47 @@ +// RISC-V Compliance IO Test Header File + +/* + * Copyright (c) 2005-2018 Imperas Software Ltd., www.imperas.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Modified by Stephan Nolting for the NEORV32 Processor + +#ifndef _COMPLIANCE_IO_H +#define _COMPLIANCE_IO_H + +//----------------------------------------------------------------------- +// RV IO Macros +//----------------------------------------------------------------------- + +// enable UART (ctrl(28)) and enable UART_SIM_MODE (ctrl(12)) +#define RVTEST_IO_INIT \ + uart_init: \ + li a0, 0xFFFFFFA0; \ + sw zero, 0(a0); \ + li a1, 1 << 28; \ + li a2, 1 << 12; \ + or a1, a1, a2; \ + sw a1, 0(a0); \ + +#define RVTEST_IO_WRITE_STR(_R, _STR) +#define RVTEST_IO_CHECK() +#define RVTEST_IO_ASSERT_GPR_EQ(_G, _R, _I) +#define RVTEST_IO_ASSERT_SFPR_EQ(_F, _R, _I) +#define RVTEST_IO_ASSERT_DFPR_EQ(_D, _R, _I) + +#endif // _COMPLIANCE_IO_H Index: riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/compliance_test.h =================================================================== --- riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/compliance_test.h (nonexistent) +++ riscv-compliance/port-neorv32/framework_v1.0/riscv-target/neorv32/compliance_test.h (revision 40) @@ -0,0 +1,47 @@ +// RISC-V Compliance Test Header File +// Copyright (c) 2017, Codasip Ltd. All Rights Reserved. +// See LICENSE for license details. +// +// Description: Common header file for RV32I tests + +// Modified by Stephan Nolting for the NEORV32 Processor + +#ifndef _COMPLIANCE_TEST_H +#define _COMPLIANCE_TEST_H + +#include "riscv_test.h" + +//----------------------------------------------------------------------- +// RV Compliance Macros +//----------------------------------------------------------------------- + +// this will dump the results via the UART_SIM_MODE data file output +#define RV_COMPLIANCE_HALT \ + la a0, begin_signature; \ + la a1, end_signature; \ + li a2, 0xFFFFFFA4; \ + copy_loop: \ + beq a0, a1, copy_loop_end; \ + lw t0, 0(a0); \ + sw t0, 0(a2); \ + addi a0, a0, 4; \ + j copy_loop; \ + copy_loop_end: \ + RVTEST_PASS \ + +#define RV_COMPLIANCE_RV32M \ + RVTEST_RV32M \ + +#define RV_COMPLIANCE_CODE_BEGIN \ + RVTEST_CODE_BEGIN \ + +#define RV_COMPLIANCE_CODE_END \ + RVTEST_CODE_END \ + +#define RV_COMPLIANCE_DATA_BEGIN \ + RVTEST_DATA_BEGIN \ + +#define RV_COMPLIANCE_DATA_END \ + RVTEST_DATA_END \ + +#endif Index: riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/C/Makefile.include =================================================================== --- riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/C/Makefile.include (nonexistent) +++ riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/C/Makefile.include (revision 40) @@ -0,0 +1,52 @@ +ifndef NEORV32_LOCAL_COPY + $(error NEORV32_LOCAL_COPY is undefined) +endif + +TARGET_SIM ?= ghdl +TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) + +ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) + $(error Target simulator executable '$(TARGET_SIM)` not found) +endif + +RUN_TARGET=\ + cd $(work_dir_isa); \ + rm -f $(work_dir_isa)/*.out; \ + echo "copying/using SIM-only IMEM (ROM!)"; \ + rm -f $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \ + cp -f $(NEORV32_LOCAL_COPY)/sim/rtl_modules/neorv32_imem.vhd $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_A/c\CPU_EXTENSION_RISCV_A => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_C/c\CPU_EXTENSION_RISCV_C => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_E/c\CPU_EXTENSION_RISCV_E => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_M/c\CPU_EXTENSION_RISCV_M => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_U/c\CPU_EXTENSION_RISCV_U => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zicsr/c\CPU_EXTENSION_RISCV_Zicsr => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zifencei/c\CPU_EXTENSION_RISCV_Zifencei => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/constant ext_imem_c/c\constant ext_imem_c : boolean := false; -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/signal ext_ram_a : ext_mem_a_ram_t/c\signal ext_ram_a : ext_mem_a_ram_t; -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_USE/c\MEM_INT_IMEM_USE => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_SIZE/c\MEM_INT_IMEM_SIZE => 2*1024*1024, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_ROM/c\MEM_INT_IMEM_ROM => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led main.elf; \ + cp -f $< $(NEORV32_LOCAL_COPY)/sw/example/blink_led/main.elf; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led main.bin; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led install; \ + sed -i '/type application_init_image_t/c\type application_init_image_t is array (0 to ((2*1024*1024)/4)-1) of std_ulogic_vector(31 downto 0); -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_application_image.vhd; \ + sh $(NEORV32_LOCAL_COPY)/sim/ghdl/ghdl_sim.sh --stop-time=600us >> /dev/null; \ + cp $(work_dir_isa)/neorv32.uart.sim_mode.data.out $(*).signature.output; + + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy +RISCV_READELF ?= $(RISCV_PREFIX)readelf +RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -march=rv32ic -mabi=ilp32 + +COMPILE_TARGET=\ + $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ + $$(RISCV_TARGET_FLAGS) \ + -I$(ROOTDIR)/riscv-test-suite/env/ \ + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ + -T$(TARGETDIR)/$(RISCV_TARGET)/link.imem_rom.ld \ + $$(<) -o $$@ Index: riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/I/Makefile.include =================================================================== --- riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/I/Makefile.include (nonexistent) +++ riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/I/Makefile.include (revision 40) @@ -0,0 +1,52 @@ +ifndef NEORV32_LOCAL_COPY + $(error NEORV32_LOCAL_COPY is undefined) +endif + +TARGET_SIM ?= ghdl +TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) + +ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) + $(error Target simulator executable '$(TARGET_SIM)` not found) +endif + +RUN_TARGET=\ + cd $(work_dir_isa); \ + rm -f $(work_dir_isa)/*.out; \ + echo "copying/using SIM-only IMEM (ROM!)"; \ + rm -f $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \ + cp -f $(NEORV32_LOCAL_COPY)/sim/rtl_modules/neorv32_imem.vhd $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_A/c\CPU_EXTENSION_RISCV_A => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_C/c\CPU_EXTENSION_RISCV_C => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_E/c\CPU_EXTENSION_RISCV_E => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_M/c\CPU_EXTENSION_RISCV_M => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_U/c\CPU_EXTENSION_RISCV_U => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zicsr/c\CPU_EXTENSION_RISCV_Zicsr => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zifencei/c\CPU_EXTENSION_RISCV_Zifencei => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/constant ext_imem_c/c\constant ext_imem_c : boolean := false; -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/signal ext_ram_a : ext_mem_a_ram_t/c\signal ext_ram_a : ext_mem_a_ram_t; -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_USE/c\MEM_INT_IMEM_USE => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_SIZE/c\MEM_INT_IMEM_SIZE => 2*1024*1024, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_ROM/c\MEM_INT_IMEM_ROM => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led main.elf; \ + cp -f $< $(NEORV32_LOCAL_COPY)/sw/example/blink_led/main.elf; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led main.bin; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led install; \ + sed -i '/type application_init_image_t/c\type application_init_image_t is array (0 to ((2*1024*1024)/4)-1) of std_ulogic_vector(31 downto 0); -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_application_image.vhd; \ + sh $(NEORV32_LOCAL_COPY)/sim/ghdl/ghdl_sim.sh --stop-time=800us >> /dev/null; \ + cp $(work_dir_isa)/neorv32.uart.sim_mode.data.out $(*).signature.output; + + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy +RISCV_READELF ?= $(RISCV_PREFIX)readelf +RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -march=rv32i -mabi=ilp32 + +COMPILE_TARGET=\ + $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ + $$(RISCV_TARGET_FLAGS) \ + -I$(ROOTDIR)/riscv-test-suite/env/ \ + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ + -T$(TARGETDIR)/$(RISCV_TARGET)/link.imem_rom.ld \ + $$(<) -o $$@ Index: riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/M/Makefile.include =================================================================== --- riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/M/Makefile.include (nonexistent) +++ riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/M/Makefile.include (revision 40) @@ -0,0 +1,52 @@ +ifndef NEORV32_LOCAL_COPY + $(error NEORV32_LOCAL_COPY is undefined) +endif + +TARGET_SIM ?= ghdl +TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) + +ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) + $(error Target simulator executable '$(TARGET_SIM)` not found) +endif + +RUN_TARGET=\ + cd $(work_dir_isa); \ + rm -f $(work_dir_isa)/*.out; \ + echo "copying/using SIM-only IMEM (ROM!)"; \ + rm -f $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \ + cp -f $(NEORV32_LOCAL_COPY)/sim/rtl_modules/neorv32_imem.vhd $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_A/c\CPU_EXTENSION_RISCV_A => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_C/c\CPU_EXTENSION_RISCV_C => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_E/c\CPU_EXTENSION_RISCV_E => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_M/c\CPU_EXTENSION_RISCV_M => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_U/c\CPU_EXTENSION_RISCV_U => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zicsr/c\CPU_EXTENSION_RISCV_Zicsr => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zifencei/c\CPU_EXTENSION_RISCV_Zifencei => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/constant ext_imem_c/c\constant ext_imem_c : boolean := false; -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/signal ext_ram_a : ext_mem_a_ram_t/c\signal ext_ram_a : ext_mem_a_ram_t; -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_USE/c\MEM_INT_IMEM_USE => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_SIZE/c\MEM_INT_IMEM_SIZE => 2*1024*1024, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_ROM/c\MEM_INT_IMEM_ROM => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led main.elf; \ + cp -f $< $(NEORV32_LOCAL_COPY)/sw/example/blink_led/main.elf; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led main.bin; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led install; \ + sed -i '/type application_init_image_t/c\type application_init_image_t is array (0 to ((2*1024*1024)/4)-1) of std_ulogic_vector(31 downto 0); -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_application_image.vhd; \ + sh $(NEORV32_LOCAL_COPY)/sim/ghdl/ghdl_sim.sh --stop-time=800us >> /dev/null; \ + cp $(work_dir_isa)/neorv32.uart.sim_mode.data.out $(*).signature.output; + + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy +RISCV_READELF ?= $(RISCV_PREFIX)readelf +RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -march=rv32im -mabi=ilp32 + +COMPILE_TARGET=\ + $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ + $$(RISCV_TARGET_FLAGS) \ + -I$(ROOTDIR)/riscv-test-suite/env/ \ + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ + -T$(TARGETDIR)/$(RISCV_TARGET)/link.imem_rom.ld \ + $$(<) -o $$@ Index: riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/Zifencei/Makefile.include =================================================================== --- riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/Zifencei/Makefile.include (nonexistent) +++ riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/Zifencei/Makefile.include (revision 40) @@ -0,0 +1,51 @@ +ifndef NEORV32_LOCAL_COPY + $(error NEORV32_LOCAL_COPY is undefined) +endif + +TARGET_SIM ?= ghdl +TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) + +ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) + $(error Target simulator executable '$(TARGET_SIM)` not found) +endif + +RUN_TARGET=\ + cd $(work_dir_isa); \ + rm -f $(work_dir_isa)/*.out; \ + echo "restoring/using original IMEM rtl file"; \ + rm -f $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \ + cp -f $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.ORIGINAL $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_A/c\CPU_EXTENSION_RISCV_A => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_C/c\CPU_EXTENSION_RISCV_C => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_E/c\CPU_EXTENSION_RISCV_E => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_M/c\CPU_EXTENSION_RISCV_M => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_U/c\CPU_EXTENSION_RISCV_U => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zicsr/c\CPU_EXTENSION_RISCV_Zicsr => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zifencei/c\CPU_EXTENSION_RISCV_Zifencei => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/constant ext_imem_c/c\constant ext_imem_c : boolean := false; -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/signal ext_ram_a : ext_mem_a_ram_t/c\signal ext_ram_a : ext_mem_a_ram_t; -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_USE/c\MEM_INT_IMEM_USE => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_SIZE/c\MEM_INT_IMEM_SIZE => 32*1024, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_ROM/c\MEM_INT_IMEM_ROM => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led main.elf; \ + cp -f $< $(NEORV32_LOCAL_COPY)/sw/example/blink_led/main.elf; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led main.bin; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led install; \ + sh $(NEORV32_LOCAL_COPY)/sim/ghdl/ghdl_sim.sh --stop-time=600us >> /dev/null; \ + cp $(work_dir_isa)/neorv32.uart.sim_mode.data.out $(*).signature.output; + + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy +RISCV_READELF ?= $(RISCV_PREFIX)readelf +RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -march=rv32i -mabi=ilp32 + +COMPILE_TARGET=\ + $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ + $$(RISCV_TARGET_FLAGS) \ + -I$(ROOTDIR)/riscv-test-suite/env/ \ + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ + -T$(TARGETDIR)/$(RISCV_TARGET)/link.imem_ram.ld \ + $$(<) -o $$@ Index: riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/privilege/Makefile.include =================================================================== --- riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/privilege/Makefile.include (nonexistent) +++ riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/device/rv32i_m/privilege/Makefile.include (revision 40) @@ -0,0 +1,52 @@ +ifndef NEORV32_LOCAL_COPY + $(error NEORV32_LOCAL_COPY is undefined) +endif + +TARGET_SIM ?= ghdl +TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) + +ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) + $(error Target simulator executable '$(TARGET_SIM)` not found) +endif + +RUN_TARGET=\ + cd $(work_dir_isa); \ + rm -f $(work_dir_isa)/*.out; \ + echo "copying/using SIM-only IMEM (ROM!)"; \ + rm -f $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \ + cp -f $(NEORV32_LOCAL_COPY)/sim/rtl_modules/neorv32_imem.vhd $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_A/c\CPU_EXTENSION_RISCV_A => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_C/c\CPU_EXTENSION_RISCV_C => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_E/c\CPU_EXTENSION_RISCV_E => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_M/c\CPU_EXTENSION_RISCV_M => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_U/c\CPU_EXTENSION_RISCV_U => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zicsr/c\CPU_EXTENSION_RISCV_Zicsr => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/CPU_EXTENSION_RISCV_Zifencei/c\CPU_EXTENSION_RISCV_Zifencei => false, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/constant ext_imem_c/c\constant ext_imem_c : boolean := false; -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/signal ext_ram_a : ext_mem_a_ram_t/c\signal ext_ram_a : ext_mem_a_ram_t; -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_USE/c\MEM_INT_IMEM_USE => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_SIZE/c\MEM_INT_IMEM_SIZE => 2*1024*1024, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + sed -i '/MEM_INT_IMEM_ROM/c\MEM_INT_IMEM_ROM => true, -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/sim/neorv32_tb.vhd; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led main.elf; \ + cp -f $< $(NEORV32_LOCAL_COPY)/sw/example/blink_led/main.elf; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led main.bin; \ + make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led install; \ + sed -i '/type application_init_image_t/c\type application_init_image_t is array (0 to ((2*1024*1024)/4)-1) of std_ulogic_vector(31 downto 0); -- MOD. BY RISCV-COMPL. TEST SCRIPT' $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_application_image.vhd; \ + sh $(NEORV32_LOCAL_COPY)/sim/ghdl/ghdl_sim.sh --stop-time=600us >> /dev/null; \ + cp $(work_dir_isa)/neorv32.uart.sim_mode.data.out $(*).signature.output; + + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy +RISCV_READELF ?= $(RISCV_PREFIX)readelf +RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -march=rv32i -mabi=ilp32 + +COMPILE_TARGET=\ + $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ + $$(RISCV_TARGET_FLAGS) \ + -I$(ROOTDIR)/riscv-test-suite/env/ \ + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ + -T$(TARGETDIR)/$(RISCV_TARGET)/link.imem_rom.ld \ + $$(<) -o $$@ Index: riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/README.md =================================================================== --- riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/README.md (nonexistent) +++ riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/README.md (revision 40) @@ -0,0 +1,22 @@ +# Running the RISC-V Compliance Framework in Simulation + + +The following tasks are executed by the device makefiles: + +* replace the original processor's IMEM rtl file by a simulation-optimized IMEM (ROM!) +* `sed` command is used to modify the default testbench (`neorv32/sim/neorv32_tb.vhd`): + * enable/disable the required `CPU_EXTENSION_RISCV_xxx` VHDL configuration generics in the testbench (`neorv32/sim/neorv32_tb.vhd`) + * configure the processor memory configuration (use internal IMEM, IMEM as ROM, IMEM size of 2MB) +* compile test code and install application image to processor's `rtl/core` folder + * compilation uses the `link.imem_rom.ld` linker script as default; code (the test code) is executed from IMEM (which is read-only); data including signatureis stored to DMEM (RAM) + * certain areas in the DMEM are initialized using port code in `model_test.h` (`RVTEST` = 0xbabecafe and `SIGNATURE` = 0xdeadbeef); can be disabled using `RISCV_TARGET_FLAGS=-DNEORV32_NO_DATA_INIT` +* `sed` command is used to modify the default application image that is generated during compilation (`neorv32/rtl/core/neorv32_application_image.vhd`): + * the array size of the application image is set to 2MB +* the processor is simulated using the default testbench using GHDL +* the results are dumped via the SIM_MODE feature of the UART + * the according code can be found in the `RVMODEL_HALT` macro in `model_test.h` + * data output (the "signature") is zero-padded to be always a multiple of 16 bytes + +:warning: The `Zifencei` test requires the r/w/e capabilities of the original IMEM rtl file. +Hence, the original file is restored for this test. Also, this test uses `link.imem_ram.ld` as linker script since the +IMEM is used as RAM to allow self-modifying code. Index: riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/link.imem_ram.ld =================================================================== --- riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/link.imem_ram.ld (nonexistent) +++ riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/link.imem_ram.ld (revision 40) @@ -0,0 +1,22 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY(rvtest_entry_point) + +SECTIONS +{ + . = 0x00000000; + .text : + { + *(.text.init) + . = ALIGN(0x1000); + *(.text) + . = ALIGN(0x1000); + *(.tohost) + *(.data) + *(.data.string) + *(.bss) + . = ALIGN(0x1000); + + _end = .; + } +} + Index: riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/link.imem_rom.ld =================================================================== --- riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/link.imem_rom.ld (nonexistent) +++ riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/link.imem_rom.ld (revision 40) @@ -0,0 +1,26 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY(rvtest_entry_point) + +SECTIONS +{ + . = 0x00000000; + .text : + { + *(.text.init) + . = ALIGN(0x1000); + *(.text) + . = ALIGN(0x1000); + _end = .; + } + + . = 0x80000000; + .data : + { + . = ALIGN(0x1000); + *(.tohost) + *(.data) + *(.data.string) + *(.bss) + } +} + Index: riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/model_test.h =================================================================== --- riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/model_test.h (nonexistent) +++ riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/model_test.h (revision 40) @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: BSD-3-Clause + +// Modified by Stephan Nolting for the NEORV32 Processor + +#ifndef _COMPLIANCE_MODEL_H +#define _COMPLIANCE_MODEL_H + +#define RVMODEL_DATA_SECTION \ + .pushsection .tohost,"aw",@progbits; \ + .align 8; .global tohost; tohost: .dword 0; \ + .align 8; .global fromhost; fromhost: .dword 0; \ + .popsection; \ + .align 8; .global begin_regstate; begin_regstate: \ + .word 128; \ + .align 8; .global end_regstate; end_regstate: \ + .word 4; + +//RV_COMPLIANCE_HALT +// neorv32: this will dump the results via the UART_SIM_MODE data file output +// neorv32: due to the modifications on "end_signature" (not 4-aligned) we need to make sure we output a 4-aligned number of data here +// neorv32: -> for zero-padding of the rest of the SIGNATURE section +#define RVMODEL_HALT \ + signature_dump: \ + la a0, begin_signature; \ + la a1, end_signature; \ + li a2, 0xFFFFFFA4; \ + signature_dump_loop: \ + beq a0, a1, signature_dump_padding; \ + lw t0, 0(a0); \ + sw t0, 0(a2); \ + addi a0, a0, 4; \ + j signature_dump_loop; \ +nop; \ +nop; \ + signature_dump_padding: \ + andi a0, a1, 0x0000000C; \ + beq a0, zero, signature_dump_end; \ + li t0, 16; \ + sub a0, t0, a0; \ + signature_dump_padding_loop: \ + beq a0, zero, signature_dump_end; \ + sw zero, 0(a2); \ + addi a0, a0, -4; \ + j signature_dump_padding_loop; \ + signature_dump_end: \ + j signature_dump_end + +//TODO: declare the start of your signature region here. Nothing else to be used here. +// The .align 4 ensures that the signature ends at a 16-byte boundary +#define RVMODEL_DATA_BEGIN \ + .align 4; .global begin_signature; begin_signature: + +//TODO: declare the end of the signature region here. Add other target specific contents here. +//neorv32: DO NOT use align_4 here! end_signature is used to indicate the actual "number" of signature words +#define RVMODEL_DATA_END \ + .global end_signature; end_signature: \ + RVMODEL_DATA_SECTION + +//RVMODEL_BOOT +// neorv32: enable UART (ctrl(28)) and enable UART_SIM_MODE (ctrl(12)) +// neorv32: initialize the complete RVTEST_DATA section in data RAM (DMEM) with 0xBABECAFE +// neorv32: initialize the complete SIGNATURE section (that is a multiple of four 32-bit entries) in data RAM (DMEM) with 0xDEADBEEF +// neorv32: this code also provides a dummy trap handler that just moves on to the next instruction +// neorv32: -> this trap handler can be overriden by the compliance-suite by modifying mtval +// neorv32: -> the dummy trap handler is required to deal with the neorv32 X extension (-> all illegal/undefined instruction trigger an exception) +#ifdef NEORV32_NO_DATA_INIT +// ------------------------- WITHOUT DATA INIT ------------------------- +#define RVMODEL_BOOT \ + core_init: \ + la x1, core_dummy_trap_handler; \ + csrw mtvec, x1; \ + j uart_sim_mode_init; \ +nop; \ +nop; \ + .balign 4; \ + core_dummy_trap_handler: \ + csrw mscratch, sp; \ + la sp, end_signature; \ + addi sp, sp, 32; \ + sw x8, 0(sp); \ + sw x9, 4(sp); \ + csrr x8, mcause; \ + blt x8, zero, core_dummy_trap_handler_irq; \ + csrr x8, mepc; \ + core_dummy_trap_handler_exc_c_check: \ + lh x9, 0(x8); \ + andi x9, x9, 3; \ + addi x8, x8, +2; \ + csrw mepc, x8; \ + addi x8, zero, 3; \ + bne x8, x9, core_dummy_trap_handler_irq; \ + core_dummy_trap_handler_exc_uncrompressed: \ + csrr x8, mepc; \ + addi x8, x8, +2; \ + csrw mepc, x8; \ + core_dummy_trap_handler_irq: \ + lw x9, 0(sp); \ + lw x8, 4(sp); \ + csrr sp, mscratch; \ + mret; \ +nop; \ +nop; \ + uart_sim_mode_init: \ + li a0, 0xFFFFFFA0; \ + sw zero, 0(a0); \ + li a1, 1 << 28; \ + li a2, 1 << 12; \ + or a1, a1, a2; \ + sw a1, 0(a0); + +#else + +// ------------------------- WITH DATA INIT ------------------------- +#define RVMODEL_BOOT \ + core_init: \ + la x1, core_dummy_trap_handler; \ + csrw mtvec, x1; \ +nop; \ +nop; \ + init_rvtest_data: \ + la a0, rvtest_data_begin; \ + la a1, rvtest_data_end; \ + li a2, 0xBABECAFE; \ + init_rvtest_data_loop: \ + beq a0, a1, init_rvtest_data_loop_end; \ + sw a2, 0(a0); \ + addi a0, a0, 4; \ + j init_rvtest_data_loop; \ + init_rvtest_data_loop_end: \ +nop; \ +nop; \ + init_signature: \ + la a0, begin_signature; \ + la a1, end_signature; \ + li a2, 0xDEADBEEF; \ + init_signature_loop: \ + beq a0, a1, init_signature_loop_end; \ + sw a2, 0(a0); \ + addi a0, a0, 4; \ + j init_signature_loop; \ + init_signature_loop_end: \ + j uart_sim_mode_init; \ +nop; \ +nop; \ + .balign 4; \ + core_dummy_trap_handler: \ + csrw mscratch, sp; \ + la sp, end_signature; \ + addi sp, sp, 32; \ + sw x8, 0(sp); \ + sw x9, 4(sp); \ + csrr x8, mcause; \ + blt x8, zero, core_dummy_trap_handler_irq; \ + csrr x8, mepc; \ + core_dummy_trap_handler_exc_c_check: \ + lh x9, 0(x8); \ + andi x9, x9, 3; \ + addi x8, x8, +2; \ + csrw mepc, x8; \ + addi x8, zero, 3; \ + bne x8, x9, core_dummy_trap_handler_irq; \ + core_dummy_trap_handler_exc_uncrompressed: \ + csrr x8, mepc; \ + addi x8, x8, +2; \ + csrw mepc, x8; \ + core_dummy_trap_handler_irq: \ + lw x9, 0(sp); \ + lw x8, 4(sp); \ + csrr sp, mscratch; \ + mret; \ +nop; \ +nop; \ + uart_sim_mode_init: \ + li a0, 0xFFFFFFA0; \ + sw zero, 0(a0); \ + li a1, 1 << 28; \ + li a2, 1 << 12; \ + or a1, a1, a2; \ + sw a1, 0(a0); + +#endif + + +//RVTEST_IO_INIT +#define RVMODEL_IO_INIT +//RVTEST_IO_WRITE_STR +#define RVMODEL_IO_WRITE_STR(_R, _STR) +//RVTEST_IO_CHECK +#define RVMODEL_IO_CHECK() + +//RVTEST_IO_ASSERT_GPR_EQ +#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I) +//RVTEST_IO_ASSERT_SFPR_EQ +#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I) +//RVTEST_IO_ASSERT_DFPR_EQ +#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I) + +// TODO: specify the routine for setting machine software interrupt +#define RVMODEL_SET_MSW_INT + +// TODO: specify the routine for clearing machine software interrupt +#define RVMODEL_CLEAR_MSW_INT + +// TODO: specify the routine for clearing machine timer interrupt +#define RVMODEL_CLEAR_MTIMER_INT + +// TODO: specify the routine for clearing machine external interrupt +#define RVMODEL_CLEAR_MEXT_INT + +#endif // _COMPLIANCE_MODEL_H Index: riscv-compliance/work/.gitignore =================================================================== --- riscv-compliance/work/.gitignore (nonexistent) +++ riscv-compliance/work/.gitignore (revision 40) @@ -0,0 +1,2 @@ +neorv32 +riscv-compliance \ No newline at end of file Index: riscv-compliance/README.md =================================================================== --- riscv-compliance/README.md (nonexistent) +++ riscv-compliance/README.md (revision 40) @@ -0,0 +1,50 @@ +# NEORV32 RISC-V-Compliance Test Framework + +**:sparkles: This setup uses the new [RISC-V Compliance Test Framework v2.1](https://github.com/riscv/riscv-compliance/releases/tag/v2.0) :sparkles:** + +## Overview + +This sub-project folder tests the [NEORV32 Processor Core](https://github.com/stnolting/neorv32) for **RISC-V compliance** by +using the [official RISC-V compliance test suite v2+](https://github.com/riscv/riscv-compliance). The core's HDL sources are *simulated* using +`GHDL` to provide a virtual execution platform for the test framework. + +The following tests are supported yet: + +* `rv32i_m/C` +* `rv32i_m/I` +* `rv32i_m/M` +* `rv32i_m/privilege` +* `rv32i_m/Zifencei` + + +## How To Run + +**Requirements:** +* `RISC-V GCC` toolchain (`riscv32-unknown-elf`) +* `GHDL` for simulating the processor + +To **execute all the supported tests** open a terminal an run (:warning: simulating everything takes quite some time): + + $ sh run_compliance_test.sh + + +## Details + +The [`run_compliance_test.sh`](https://github.com/stnolting/neorv32/blob/master/riscv-compliance/run_compliance_test.sh) +bash script does the following: + +* Copy the `rtl`, `sim` and `sw` folders of the NEORV32 into `work/neorv32/` to keep the project's core files clean +* Clone (if not already there) the [riscv-compliance repository](https://github.com/riscv/riscv-compliance) into `work/` +* Install (copy) the custom `neorv32` test target from the ``port-neorv32/framework_v2.0/riscv-target` folder to the compliance test suite's target folder +* Replace the original IMEM VHDL source file of the processor (in `work/neorv32`) by the simulation-only file (`neorv32/sim/rtl_modules/neorv32_imem.vhd` to allow faster simulation) +* Run the actual compliance tests + +More datails regarding the actual simulation process can be found in the [target's +`README`](https://github.com/stnolting/neorv32/blob/master/riscv-compliance/port-neorv32/framework_v2.0/riscv-target/neorv32/README.md). +For more information regarding the NEORV32 Processor see the :page_facing_up: +[NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf). + +:information_source: The port files for the *old framework (v1.0)* can be found in +[`port-neorv32/framework_v1.0`](https://github.com/stnolting/neorv32/tree/master/riscv-compliance/port-neorv32/framework_v1.0/riscv-target). + +:information_source: If the simulation of a test does not generate any signature outputs at all try increasing the simulation time in the NEORV32 port's device makefiles. Index: riscv-compliance/run_compliance_test.sh =================================================================== --- riscv-compliance/run_compliance_test.sh (nonexistent) +++ riscv-compliance/run_compliance_test.sh (revision 40) @@ -0,0 +1,87 @@ +#!/bin/bash + +# Abort if any command returns != 0 +set -e + +# Check GCC toolchain installation +echo "--------------------------------------------------------------------------" +echo "> Checking RISC-V GCC toolchain..." +echo "--------------------------------------------------------------------------" +riscv32-unknown-elf-gcc -v + +# Check GHDL installation +echo "--------------------------------------------------------------------------" +echo "> Checking GHDL simulator..." +echo "--------------------------------------------------------------------------" +ghdl -v + +# Clone RISC-V Compliance Test Suite GitHub repository if it not exists already +echo "--------------------------------------------------------------------------" +echo "> Checking 'RISC-V Compliance Test Suite' GitHub repository..." +echo "--------------------------------------------------------------------------" + +REPOSRC=https://github.com/riscv/riscv-compliance.git +LOCALREPO=work/riscv-compliance +LOCALREPO_VC_DIR=$LOCALREPO/.git + +if [ ! -d $LOCALREPO_VC_DIR ] +then + echo ">>> Cloning repository..." + git clone $REPOSRC $LOCALREPO +else + echo ">>> Repository already exists. Checking for updates..." + (cd work/riscv-compliance ; git status -uno) +fi + +# Copy NEORV32 files +echo "--------------------------------------------------------------------------" +echo "> Making local copy of NEORV32 'rtl', 'sim' & 'sw' folders..." +echo "--------------------------------------------------------------------------" +(cd work ; rm -rf neorv32 ; mkdir neorv32) +cp -r ../rtl/ work/neorv32/. +cp -r ../sim/ work/neorv32/. +cp -r ../sw/ work/neorv32/. + +# Copy neorv32 target folder into test suite +echo "--------------------------------------------------------------------------" +echo "> Copying neorv32 test-target into compliance framework..." +echo "--------------------------------------------------------------------------" +cp -rf port-neorv32/framework_v2.0/riscv-target/neorv32 work/riscv-compliance/riscv-target/. + +# Make a local copy of the original IMEM rtl file +echo "" +echo ">>> Making local backup if original IMEM rtl file (work/neorv32/rtl/core/neorv32_imem.vhd)..." +echo "" +cp work/neorv32/rtl/core/neorv32_imem.vhd work/neorv32/rtl/core/neorv32_imem.ORIGINAL + +# Component installation done +ls -al +echo "--------------------------------------------------------------------------" +echo "> Component installation done!" +echo "--------------------------------------------------------------------------" +echo "" + + +# Local NEORV32 copy - home folder +homedir="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +homedir=$homedir + +# neorv32 home folder +NEORV32_LOCAL_HOME=$homedir/work/neorv32 + +echo "--------------------------------------------------------------------------" +echo "> Starting RISC-V compliance tests..." +echo "--------------------------------------------------------------------------" + +# Clean everything +make -C $homedir/work/riscv-compliance NEORV32_LOCAL_COPY=$NEORV32_LOCAL_HOME XLEN=32 RISCV_TARGET=neorv32 clean + +# Run tests and check results +make --silent -C $homedir/work/riscv-compliance NEORV32_LOCAL_COPY=$NEORV32_LOCAL_HOME XLEN=32 RISCV_TARGET=neorv32 RISCV_DEVICE=I build run verify +make --silent -C $homedir/work/riscv-compliance NEORV32_LOCAL_COPY=$NEORV32_LOCAL_HOME XLEN=32 RISCV_TARGET=neorv32 RISCV_DEVICE=C build run verify +make --silent -C $homedir/work/riscv-compliance NEORV32_LOCAL_COPY=$NEORV32_LOCAL_HOME XLEN=32 RISCV_TARGET=neorv32 RISCV_DEVICE=M build run verify +make --silent -C $homedir/work/riscv-compliance NEORV32_LOCAL_COPY=$NEORV32_LOCAL_HOME XLEN=32 RISCV_TARGET=neorv32 RISCV_DEVICE=privilege build run verify +make --silent -C $homedir/work/riscv-compliance NEORV32_LOCAL_COPY=$NEORV32_LOCAL_HOME XLEN=32 RISCV_TARGET=neorv32 RISCV_DEVICE=Zifencei RISCV_TARGET_FLAGS=-DNEORV32_NO_DATA_INIT build run verify + +echo "" +echo "Compliance tests completed" Index: rtl/core/neorv32_application_image.vhd =================================================================== --- rtl/core/neorv32_application_image.vhd (revision 39) +++ rtl/core/neorv32_application_image.vhd (revision 40) @@ -6,7 +6,7 @@ package neorv32_application_image is - type application_init_image_t is array (0 to 783) of std_ulogic_vector(31 downto 0); + type application_init_image_t is array (0 to 800) of std_ulogic_vector(31 downto 0); constant application_init_image : application_init_image_t := ( 00000000 => x"00000093", 00000001 => x"00000113", @@ -46,7 +46,7 @@ 00000035 => x"80000197", 00000036 => x"77418193", 00000037 => x"00000597", - 00000038 => x"09458593", + 00000038 => x"09c58593", 00000039 => x"30559073", 00000040 => x"f8000593", 00000041 => x"0005a023", @@ -54,13 +54,13 @@ 00000043 => x"feb01ce3", 00000044 => x"80000597", 00000045 => x"f5058593", - 00000046 => x"84018613", + 00000046 => x"84418613", 00000047 => x"00c5d863", 00000048 => x"00058023", 00000049 => x"00158593", 00000050 => x"ff5ff06f", 00000051 => x"00001597", - 00000052 => x"b7058593", + 00000052 => x"bb458593", 00000053 => x"80000617", 00000054 => x"f2c60613", 00000055 => x"80000697", @@ -77,65 +77,65 @@ 00000066 => x"b8001073", 00000067 => x"b0201073", 00000068 => x"b8201073", - 00000069 => x"060000ef", - 00000070 => x"30047073", - 00000071 => x"00000013", - 00000072 => x"10500073", - 00000073 => x"0000006f", - 00000074 => x"ff810113", - 00000075 => x"00812023", - 00000076 => x"00912223", - 00000077 => x"34202473", - 00000078 => x"02044663", - 00000079 => x"34102473", - 00000080 => x"00041483", - 00000081 => x"0034f493", - 00000082 => x"00240413", - 00000083 => x"34141073", - 00000084 => x"00300413", - 00000085 => x"00941863", - 00000086 => x"34102473", - 00000087 => x"00240413", - 00000088 => x"34141073", - 00000089 => x"00012483", - 00000090 => x"00412403", - 00000091 => x"00810113", - 00000092 => x"30200073", - 00000093 => x"00005537", - 00000094 => x"ff010113", - 00000095 => x"00000613", - 00000096 => x"00000593", - 00000097 => x"b0050513", - 00000098 => x"00112623", - 00000099 => x"490000ef", - 00000100 => x"61c000ef", - 00000101 => x"00050c63", - 00000102 => x"428000ef", - 00000103 => x"00001537", - 00000104 => x"95050513", - 00000105 => x"514000ef", - 00000106 => x"020000ef", - 00000107 => x"00001537", - 00000108 => x"92c50513", - 00000109 => x"504000ef", - 00000110 => x"00c12083", - 00000111 => x"00000513", - 00000112 => x"01010113", - 00000113 => x"00008067", - 00000114 => x"ff010113", - 00000115 => x"00000513", - 00000116 => x"00812423", - 00000117 => x"00112623", - 00000118 => x"00000413", - 00000119 => x"5e0000ef", - 00000120 => x"0ff47513", - 00000121 => x"5d8000ef", - 00000122 => x"0c800513", - 00000123 => x"550000ef", - 00000124 => x"00140413", - 00000125 => x"fedff06f", - 00000126 => x"00000000", - 00000127 => x"00000000", + 00000069 => x"80000637", + 00000070 => x"34261073", + 00000071 => x"060000ef", + 00000072 => x"30047073", + 00000073 => x"00000013", + 00000074 => x"10500073", + 00000075 => x"0000006f", + 00000076 => x"ff810113", + 00000077 => x"00812023", + 00000078 => x"00912223", + 00000079 => x"34202473", + 00000080 => x"02044663", + 00000081 => x"34102473", + 00000082 => x"00041483", + 00000083 => x"0034f493", + 00000084 => x"00240413", + 00000085 => x"34141073", + 00000086 => x"00300413", + 00000087 => x"00941863", + 00000088 => x"34102473", + 00000089 => x"00240413", + 00000090 => x"34141073", + 00000091 => x"00012483", + 00000092 => x"00412403", + 00000093 => x"00810113", + 00000094 => x"30200073", + 00000095 => x"00005537", + 00000096 => x"ff010113", + 00000097 => x"00000613", + 00000098 => x"00000593", + 00000099 => x"b0050513", + 00000100 => x"00112623", + 00000101 => x"4a0000ef", + 00000102 => x"62c000ef", + 00000103 => x"00050c63", + 00000104 => x"438000ef", + 00000105 => x"00001537", + 00000106 => x"96850513", + 00000107 => x"524000ef", + 00000108 => x"020000ef", + 00000109 => x"00001537", + 00000110 => x"94450513", + 00000111 => x"514000ef", + 00000112 => x"00c12083", + 00000113 => x"00000513", + 00000114 => x"01010113", + 00000115 => x"00008067", + 00000116 => x"ff010113", + 00000117 => x"00000513", + 00000118 => x"00812423", + 00000119 => x"00112623", + 00000120 => x"00000413", + 00000121 => x"5f0000ef", + 00000122 => x"0ff47513", + 00000123 => x"5e8000ef", + 00000124 => x"0c800513", + 00000125 => x"560000ef", + 00000126 => x"00140413", + 00000127 => x"fedff06f", 00000128 => x"fc010113", 00000129 => x"02112e23", 00000130 => x"02512c23", @@ -166,7 +166,7 @@ 00000155 => x"34161073", 00000156 => x"00b00713", 00000157 => x"04f77a63", - 00000158 => x"41000793", + 00000158 => x"41c00793", 00000159 => x"000780e7", 00000160 => x"03c12083", 00000161 => x"03812283", @@ -188,7 +188,7 @@ 00000177 => x"30200073", 00000178 => x"00001737", 00000179 => x"00279793", - 00000180 => x"96c70713", + 00000180 => x"98470713", 00000181 => x"00e787b3", 00000182 => x"0007a783", 00000183 => x"00078067", @@ -199,7 +199,7 @@ 00000188 => x"f8f764e3", 00000189 => x"00001737", 00000190 => x"00279793", - 00000191 => x"99c70713", + 00000191 => x"9b470713", 00000192 => x"00e787b3", 00000193 => x"0007a783", 00000194 => x"00078067", @@ -239,558 +239,575 @@ 00000228 => x"eedff06f", 00000229 => x"83c1a783", 00000230 => x"ee5ff06f", - 00000231 => x"00000000", - 00000232 => x"fe010113", - 00000233 => x"01212823", - 00000234 => x"00050913", - 00000235 => x"00001537", - 00000236 => x"00912a23", - 00000237 => x"9e050513", - 00000238 => x"000014b7", - 00000239 => x"00812c23", - 00000240 => x"01312623", - 00000241 => x"00112e23", - 00000242 => x"01c00413", - 00000243 => x"2ec000ef", - 00000244 => x"c2c48493", - 00000245 => x"ffc00993", - 00000246 => x"008957b3", - 00000247 => x"00f7f793", - 00000248 => x"00f487b3", - 00000249 => x"0007c503", - 00000250 => x"ffc40413", - 00000251 => x"2bc000ef", - 00000252 => x"ff3414e3", - 00000253 => x"01c12083", - 00000254 => x"01812403", - 00000255 => x"01412483", - 00000256 => x"01012903", - 00000257 => x"00c12983", - 00000258 => x"02010113", - 00000259 => x"00008067", - 00000260 => x"00001537", - 00000261 => x"ff010113", - 00000262 => x"9e450513", - 00000263 => x"00112623", - 00000264 => x"00812423", - 00000265 => x"294000ef", - 00000266 => x"34202473", - 00000267 => x"00b00793", - 00000268 => x"0487f463", - 00000269 => x"800007b7", - 00000270 => x"ffd7c793", - 00000271 => x"00f407b3", - 00000272 => x"01000713", - 00000273 => x"00f77e63", - 00000274 => x"00001537", - 00000275 => x"b5850513", - 00000276 => x"268000ef", - 00000277 => x"00040513", - 00000278 => x"f49ff0ef", - 00000279 => x"0400006f", - 00000280 => x"00001737", - 00000281 => x"00279793", - 00000282 => x"b8470713", - 00000283 => x"00e787b3", - 00000284 => x"0007a783", - 00000285 => x"00078067", - 00000286 => x"00001737", - 00000287 => x"00241793", - 00000288 => x"bc870713", - 00000289 => x"00e787b3", - 00000290 => x"0007a783", - 00000291 => x"00078067", - 00000292 => x"00001537", - 00000293 => x"9ec50513", - 00000294 => x"220000ef", + 00000231 => x"8401a783", + 00000232 => x"eddff06f", + 00000233 => x"00000000", + 00000234 => x"00000000", + 00000235 => x"fe010113", + 00000236 => x"01212823", + 00000237 => x"00050913", + 00000238 => x"00001537", + 00000239 => x"00912a23", + 00000240 => x"9f850513", + 00000241 => x"000014b7", + 00000242 => x"00812c23", + 00000243 => x"01312623", + 00000244 => x"00112e23", + 00000245 => x"01c00413", + 00000246 => x"2f8000ef", + 00000247 => x"c7048493", + 00000248 => x"ffc00993", + 00000249 => x"008957b3", + 00000250 => x"00f7f793", + 00000251 => x"00f487b3", + 00000252 => x"0007c503", + 00000253 => x"ffc40413", + 00000254 => x"2c8000ef", + 00000255 => x"ff3414e3", + 00000256 => x"01c12083", + 00000257 => x"01812403", + 00000258 => x"01412483", + 00000259 => x"01012903", + 00000260 => x"00c12983", + 00000261 => x"02010113", + 00000262 => x"00008067", + 00000263 => x"00001537", + 00000264 => x"ff010113", + 00000265 => x"9fc50513", + 00000266 => x"00112623", + 00000267 => x"00812423", + 00000268 => x"2a0000ef", + 00000269 => x"34202473", + 00000270 => x"00b00793", + 00000271 => x"0487f463", + 00000272 => x"800007b7", + 00000273 => x"ffd7c793", + 00000274 => x"00f407b3", + 00000275 => x"01000713", + 00000276 => x"00f77e63", + 00000277 => x"00001537", + 00000278 => x"b9c50513", + 00000279 => x"274000ef", + 00000280 => x"00040513", + 00000281 => x"f49ff0ef", + 00000282 => x"0400006f", + 00000283 => x"00001737", + 00000284 => x"00279793", + 00000285 => x"bc870713", + 00000286 => x"00e787b3", + 00000287 => x"0007a783", + 00000288 => x"00078067", + 00000289 => x"00001737", + 00000290 => x"00241793", + 00000291 => x"c0c70713", + 00000292 => x"00e787b3", + 00000293 => x"0007a783", + 00000294 => x"00078067", 00000295 => x"00001537", - 00000296 => x"b7050513", - 00000297 => x"214000ef", - 00000298 => x"34002573", - 00000299 => x"ef5ff0ef", - 00000300 => x"00001537", - 00000301 => x"b7850513", - 00000302 => x"200000ef", - 00000303 => x"34302573", - 00000304 => x"ee1ff0ef", - 00000305 => x"00812403", - 00000306 => x"00c12083", - 00000307 => x"00001537", - 00000308 => x"c2450513", - 00000309 => x"01010113", - 00000310 => x"1e00006f", - 00000311 => x"00001537", - 00000312 => x"a0c50513", - 00000313 => x"fb5ff06f", + 00000296 => x"a0450513", + 00000297 => x"22c000ef", + 00000298 => x"00001537", + 00000299 => x"bb450513", + 00000300 => x"220000ef", + 00000301 => x"34002573", + 00000302 => x"ef5ff0ef", + 00000303 => x"00001537", + 00000304 => x"bbc50513", + 00000305 => x"20c000ef", + 00000306 => x"34302573", + 00000307 => x"ee1ff0ef", + 00000308 => x"00812403", + 00000309 => x"00c12083", + 00000310 => x"00001537", + 00000311 => x"c6850513", + 00000312 => x"01010113", + 00000313 => x"1ec0006f", 00000314 => x"00001537", - 00000315 => x"a2850513", - 00000316 => x"fa9ff06f", + 00000315 => x"a2450513", + 00000316 => x"fb5ff06f", 00000317 => x"00001537", - 00000318 => x"a3c50513", - 00000319 => x"f9dff06f", + 00000318 => x"a4050513", + 00000319 => x"fa9ff06f", 00000320 => x"00001537", - 00000321 => x"a4850513", - 00000322 => x"f91ff06f", + 00000321 => x"a5450513", + 00000322 => x"f9dff06f", 00000323 => x"00001537", 00000324 => x"a6050513", - 00000325 => x"f85ff06f", + 00000325 => x"f91ff06f", 00000326 => x"00001537", - 00000327 => x"a7450513", - 00000328 => x"f79ff06f", + 00000327 => x"a7850513", + 00000328 => x"f85ff06f", 00000329 => x"00001537", - 00000330 => x"a9050513", - 00000331 => x"f6dff06f", + 00000330 => x"a8c50513", + 00000331 => x"f79ff06f", 00000332 => x"00001537", - 00000333 => x"aa450513", - 00000334 => x"f61ff06f", + 00000333 => x"aa850513", + 00000334 => x"f6dff06f", 00000335 => x"00001537", - 00000336 => x"ab850513", - 00000337 => x"f55ff06f", + 00000336 => x"abc50513", + 00000337 => x"f61ff06f", 00000338 => x"00001537", - 00000339 => x"ad450513", - 00000340 => x"f49ff06f", + 00000339 => x"adc50513", + 00000340 => x"f55ff06f", 00000341 => x"00001537", - 00000342 => x"aec50513", - 00000343 => x"f3dff06f", + 00000342 => x"afc50513", + 00000343 => x"f49ff06f", 00000344 => x"00001537", - 00000345 => x"b0850513", - 00000346 => x"f31ff06f", + 00000345 => x"b1850513", + 00000346 => x"f3dff06f", 00000347 => x"00001537", - 00000348 => x"b1c50513", - 00000349 => x"f25ff06f", + 00000348 => x"b3050513", + 00000349 => x"f31ff06f", 00000350 => x"00001537", - 00000351 => x"b3050513", - 00000352 => x"f19ff06f", + 00000351 => x"b4c50513", + 00000352 => x"f25ff06f", 00000353 => x"00001537", - 00000354 => x"b4450513", - 00000355 => x"f0dff06f", - 00000356 => x"00f00793", - 00000357 => x"02a7e263", - 00000358 => x"800007b7", - 00000359 => x"00078793", - 00000360 => x"00251513", - 00000361 => x"00a78533", - 00000362 => x"41000793", - 00000363 => x"00f52023", - 00000364 => x"00000513", - 00000365 => x"00008067", - 00000366 => x"00100513", - 00000367 => x"00008067", - 00000368 => x"ff010113", - 00000369 => x"00112623", - 00000370 => x"00812423", - 00000371 => x"00912223", - 00000372 => x"301027f3", - 00000373 => x"00079863", - 00000374 => x"00001537", - 00000375 => x"bf850513", - 00000376 => x"0d8000ef", - 00000377 => x"20000793", - 00000378 => x"30579073", - 00000379 => x"00000413", - 00000380 => x"01000493", - 00000381 => x"00040513", - 00000382 => x"00140413", - 00000383 => x"0ff47413", - 00000384 => x"f91ff0ef", - 00000385 => x"fe9418e3", - 00000386 => x"00c12083", - 00000387 => x"00812403", - 00000388 => x"00412483", - 00000389 => x"01010113", - 00000390 => x"00008067", - 00000391 => x"fa002023", - 00000392 => x"fe002683", - 00000393 => x"00151513", - 00000394 => x"00000713", - 00000395 => x"04a6f263", - 00000396 => x"000016b7", - 00000397 => x"00000793", - 00000398 => x"ffe68693", - 00000399 => x"04e6e463", - 00000400 => x"00167613", - 00000401 => x"0015f593", - 00000402 => x"01879793", - 00000403 => x"01e61613", - 00000404 => x"00c7e7b3", - 00000405 => x"01d59593", - 00000406 => x"00b7e7b3", - 00000407 => x"00e7e7b3", - 00000408 => x"10000737", - 00000409 => x"00e7e7b3", - 00000410 => x"faf02023", - 00000411 => x"00008067", - 00000412 => x"00170793", - 00000413 => x"01079713", - 00000414 => x"40a686b3", - 00000415 => x"01075713", - 00000416 => x"fadff06f", - 00000417 => x"ffe78513", - 00000418 => x"0fd57513", - 00000419 => x"00051a63", - 00000420 => x"00375713", - 00000421 => x"00178793", - 00000422 => x"0ff7f793", - 00000423 => x"fa1ff06f", - 00000424 => x"00175713", - 00000425 => x"ff1ff06f", - 00000426 => x"fa002783", - 00000427 => x"fe07cee3", - 00000428 => x"faa02223", - 00000429 => x"00008067", - 00000430 => x"ff010113", - 00000431 => x"00812423", - 00000432 => x"01212023", - 00000433 => x"00112623", - 00000434 => x"00912223", - 00000435 => x"00050413", - 00000436 => x"00a00913", - 00000437 => x"00044483", - 00000438 => x"00140413", - 00000439 => x"00049e63", - 00000440 => x"00c12083", - 00000441 => x"00812403", - 00000442 => x"00412483", - 00000443 => x"00012903", - 00000444 => x"01010113", - 00000445 => x"00008067", - 00000446 => x"01249663", - 00000447 => x"00d00513", - 00000448 => x"fa9ff0ef", - 00000449 => x"00048513", - 00000450 => x"fa1ff0ef", - 00000451 => x"fc9ff06f", - 00000452 => x"ff010113", - 00000453 => x"c80026f3", - 00000454 => x"c0002773", - 00000455 => x"c80027f3", - 00000456 => x"fed79ae3", - 00000457 => x"00e12023", - 00000458 => x"00f12223", - 00000459 => x"00012503", - 00000460 => x"00412583", - 00000461 => x"01010113", - 00000462 => x"00008067", - 00000463 => x"fe010113", - 00000464 => x"00112e23", - 00000465 => x"00812c23", - 00000466 => x"00912a23", - 00000467 => x"00a12623", - 00000468 => x"fc1ff0ef", - 00000469 => x"00050493", - 00000470 => x"fe002503", - 00000471 => x"00058413", - 00000472 => x"3e800593", - 00000473 => x"0f8000ef", - 00000474 => x"00c12603", - 00000475 => x"00000693", - 00000476 => x"00000593", - 00000477 => x"050000ef", - 00000478 => x"009504b3", - 00000479 => x"00a4b533", - 00000480 => x"00858433", - 00000481 => x"00850433", - 00000482 => x"f89ff0ef", - 00000483 => x"fe85eee3", - 00000484 => x"00b41463", - 00000485 => x"fe956ae3", - 00000486 => x"01c12083", - 00000487 => x"01812403", - 00000488 => x"01412483", - 00000489 => x"02010113", - 00000490 => x"00008067", - 00000491 => x"fe802503", - 00000492 => x"01055513", - 00000493 => x"00157513", - 00000494 => x"00008067", - 00000495 => x"f8a02223", + 00000354 => x"b6050513", + 00000355 => x"f19ff06f", + 00000356 => x"00001537", + 00000357 => x"b7450513", + 00000358 => x"f0dff06f", + 00000359 => x"00001537", + 00000360 => x"b8850513", + 00000361 => x"f01ff06f", + 00000362 => x"01000793", + 00000363 => x"02a7e263", + 00000364 => x"800007b7", + 00000365 => x"00078793", + 00000366 => x"00251513", + 00000367 => x"00a78533", + 00000368 => x"41c00793", + 00000369 => x"00f52023", + 00000370 => x"00000513", + 00000371 => x"00008067", + 00000372 => x"00100513", + 00000373 => x"00008067", + 00000374 => x"ff010113", + 00000375 => x"00112623", + 00000376 => x"00812423", + 00000377 => x"00912223", + 00000378 => x"301027f3", + 00000379 => x"00079863", + 00000380 => x"00001537", + 00000381 => x"c3c50513", + 00000382 => x"0d8000ef", + 00000383 => x"20000793", + 00000384 => x"30579073", + 00000385 => x"00000413", + 00000386 => x"01100493", + 00000387 => x"00040513", + 00000388 => x"00140413", + 00000389 => x"0ff47413", + 00000390 => x"f91ff0ef", + 00000391 => x"fe9418e3", + 00000392 => x"00c12083", + 00000393 => x"00812403", + 00000394 => x"00412483", + 00000395 => x"01010113", + 00000396 => x"00008067", + 00000397 => x"fa002023", + 00000398 => x"fe002683", + 00000399 => x"00151513", + 00000400 => x"00000713", + 00000401 => x"04a6f263", + 00000402 => x"000016b7", + 00000403 => x"00000793", + 00000404 => x"ffe68693", + 00000405 => x"04e6e463", + 00000406 => x"00167613", + 00000407 => x"0015f593", + 00000408 => x"01879793", + 00000409 => x"01e61613", + 00000410 => x"00c7e7b3", + 00000411 => x"01d59593", + 00000412 => x"00b7e7b3", + 00000413 => x"00e7e7b3", + 00000414 => x"10000737", + 00000415 => x"00e7e7b3", + 00000416 => x"faf02023", + 00000417 => x"00008067", + 00000418 => x"00170793", + 00000419 => x"01079713", + 00000420 => x"40a686b3", + 00000421 => x"01075713", + 00000422 => x"fadff06f", + 00000423 => x"ffe78513", + 00000424 => x"0fd57513", + 00000425 => x"00051a63", + 00000426 => x"00375713", + 00000427 => x"00178793", + 00000428 => x"0ff7f793", + 00000429 => x"fa1ff06f", + 00000430 => x"00175713", + 00000431 => x"ff1ff06f", + 00000432 => x"fa002783", + 00000433 => x"fe07cee3", + 00000434 => x"faa02223", + 00000435 => x"00008067", + 00000436 => x"ff010113", + 00000437 => x"00812423", + 00000438 => x"01212023", + 00000439 => x"00112623", + 00000440 => x"00912223", + 00000441 => x"00050413", + 00000442 => x"00a00913", + 00000443 => x"00044483", + 00000444 => x"00140413", + 00000445 => x"00049e63", + 00000446 => x"00c12083", + 00000447 => x"00812403", + 00000448 => x"00412483", + 00000449 => x"00012903", + 00000450 => x"01010113", + 00000451 => x"00008067", + 00000452 => x"01249663", + 00000453 => x"00d00513", + 00000454 => x"fa9ff0ef", + 00000455 => x"00048513", + 00000456 => x"fa1ff0ef", + 00000457 => x"fc9ff06f", + 00000458 => x"ff010113", + 00000459 => x"c80026f3", + 00000460 => x"c0002773", + 00000461 => x"c80027f3", + 00000462 => x"fed79ae3", + 00000463 => x"00e12023", + 00000464 => x"00f12223", + 00000465 => x"00012503", + 00000466 => x"00412583", + 00000467 => x"01010113", + 00000468 => x"00008067", + 00000469 => x"fe010113", + 00000470 => x"00112e23", + 00000471 => x"00812c23", + 00000472 => x"00912a23", + 00000473 => x"00a12623", + 00000474 => x"fc1ff0ef", + 00000475 => x"00050493", + 00000476 => x"fe002503", + 00000477 => x"00058413", + 00000478 => x"3e800593", + 00000479 => x"0f8000ef", + 00000480 => x"00c12603", + 00000481 => x"00000693", + 00000482 => x"00000593", + 00000483 => x"050000ef", + 00000484 => x"009504b3", + 00000485 => x"00a4b533", + 00000486 => x"00858433", + 00000487 => x"00850433", + 00000488 => x"f89ff0ef", + 00000489 => x"fe85eee3", + 00000490 => x"00b41463", + 00000491 => x"fe956ae3", + 00000492 => x"01c12083", + 00000493 => x"01812403", + 00000494 => x"01412483", + 00000495 => x"02010113", 00000496 => x"00008067", - 00000497 => x"00050313", - 00000498 => x"ff010113", - 00000499 => x"00060513", - 00000500 => x"00068893", - 00000501 => x"00112623", - 00000502 => x"00030613", - 00000503 => x"00050693", - 00000504 => x"00000713", - 00000505 => x"00000793", - 00000506 => x"00000813", - 00000507 => x"0016fe13", - 00000508 => x"00171e93", - 00000509 => x"000e0c63", - 00000510 => x"01060e33", - 00000511 => x"010e3833", - 00000512 => x"00e787b3", - 00000513 => x"00f807b3", - 00000514 => x"000e0813", - 00000515 => x"01f65713", - 00000516 => x"0016d693", - 00000517 => x"00eee733", - 00000518 => x"00161613", - 00000519 => x"fc0698e3", - 00000520 => x"00058663", - 00000521 => x"0e4000ef", - 00000522 => x"00a787b3", - 00000523 => x"00088a63", - 00000524 => x"00030513", - 00000525 => x"00088593", - 00000526 => x"0d0000ef", - 00000527 => x"00f507b3", - 00000528 => x"00c12083", - 00000529 => x"00080513", - 00000530 => x"00078593", - 00000531 => x"01010113", - 00000532 => x"00008067", - 00000533 => x"06054063", - 00000534 => x"0605c663", - 00000535 => x"00058613", - 00000536 => x"00050593", - 00000537 => x"fff00513", - 00000538 => x"02060c63", - 00000539 => x"00100693", - 00000540 => x"00b67a63", - 00000541 => x"00c05863", - 00000542 => x"00161613", - 00000543 => x"00169693", - 00000544 => x"feb66ae3", - 00000545 => x"00000513", - 00000546 => x"00c5e663", - 00000547 => x"40c585b3", - 00000548 => x"00d56533", - 00000549 => x"0016d693", - 00000550 => x"00165613", - 00000551 => x"fe0696e3", - 00000552 => x"00008067", - 00000553 => x"00008293", - 00000554 => x"fb5ff0ef", - 00000555 => x"00058513", - 00000556 => x"00028067", - 00000557 => x"40a00533", - 00000558 => x"00b04863", - 00000559 => x"40b005b3", - 00000560 => x"f9dff06f", - 00000561 => x"40b005b3", - 00000562 => x"00008293", - 00000563 => x"f91ff0ef", - 00000564 => x"40a00533", - 00000565 => x"00028067", - 00000566 => x"00008293", - 00000567 => x"0005ca63", - 00000568 => x"00054c63", - 00000569 => x"f79ff0ef", - 00000570 => x"00058513", + 00000497 => x"fe802503", + 00000498 => x"01055513", + 00000499 => x"00157513", + 00000500 => x"00008067", + 00000501 => x"f8a02223", + 00000502 => x"00008067", + 00000503 => x"00050313", + 00000504 => x"ff010113", + 00000505 => x"00060513", + 00000506 => x"00068893", + 00000507 => x"00112623", + 00000508 => x"00030613", + 00000509 => x"00050693", + 00000510 => x"00000713", + 00000511 => x"00000793", + 00000512 => x"00000813", + 00000513 => x"0016fe13", + 00000514 => x"00171e93", + 00000515 => x"000e0c63", + 00000516 => x"01060e33", + 00000517 => x"010e3833", + 00000518 => x"00e787b3", + 00000519 => x"00f807b3", + 00000520 => x"000e0813", + 00000521 => x"01f65713", + 00000522 => x"0016d693", + 00000523 => x"00eee733", + 00000524 => x"00161613", + 00000525 => x"fc0698e3", + 00000526 => x"00058663", + 00000527 => x"0e4000ef", + 00000528 => x"00a787b3", + 00000529 => x"00088a63", + 00000530 => x"00030513", + 00000531 => x"00088593", + 00000532 => x"0d0000ef", + 00000533 => x"00f507b3", + 00000534 => x"00c12083", + 00000535 => x"00080513", + 00000536 => x"00078593", + 00000537 => x"01010113", + 00000538 => x"00008067", + 00000539 => x"06054063", + 00000540 => x"0605c663", + 00000541 => x"00058613", + 00000542 => x"00050593", + 00000543 => x"fff00513", + 00000544 => x"02060c63", + 00000545 => x"00100693", + 00000546 => x"00b67a63", + 00000547 => x"00c05863", + 00000548 => x"00161613", + 00000549 => x"00169693", + 00000550 => x"feb66ae3", + 00000551 => x"00000513", + 00000552 => x"00c5e663", + 00000553 => x"40c585b3", + 00000554 => x"00d56533", + 00000555 => x"0016d693", + 00000556 => x"00165613", + 00000557 => x"fe0696e3", + 00000558 => x"00008067", + 00000559 => x"00008293", + 00000560 => x"fb5ff0ef", + 00000561 => x"00058513", + 00000562 => x"00028067", + 00000563 => x"40a00533", + 00000564 => x"00b04863", + 00000565 => x"40b005b3", + 00000566 => x"f9dff06f", + 00000567 => x"40b005b3", + 00000568 => x"00008293", + 00000569 => x"f91ff0ef", + 00000570 => x"40a00533", 00000571 => x"00028067", - 00000572 => x"40b005b3", - 00000573 => x"fe0558e3", - 00000574 => x"40a00533", - 00000575 => x"f61ff0ef", - 00000576 => x"40b00533", + 00000572 => x"00008293", + 00000573 => x"0005ca63", + 00000574 => x"00054c63", + 00000575 => x"f79ff0ef", + 00000576 => x"00058513", 00000577 => x"00028067", - 00000578 => x"00050613", - 00000579 => x"00000513", - 00000580 => x"0015f693", - 00000581 => x"00068463", - 00000582 => x"00c50533", - 00000583 => x"0015d593", - 00000584 => x"00161613", - 00000585 => x"fe0596e3", - 00000586 => x"00008067", - 00000587 => x"6f727245", - 00000588 => x"4e202172", - 00000589 => x"5047206f", - 00000590 => x"75204f49", - 00000591 => x"2074696e", - 00000592 => x"746e7973", - 00000593 => x"69736568", - 00000594 => x"2164657a", - 00000595 => x"0000000a", - 00000596 => x"6e696c42", - 00000597 => x"676e696b", - 00000598 => x"44454c20", - 00000599 => x"6d656420", - 00000600 => x"7270206f", - 00000601 => x"6172676f", - 00000602 => x"00000a6d", - 00000603 => x"0000030c", - 00000604 => x"00000318", - 00000605 => x"00000324", - 00000606 => x"00000330", - 00000607 => x"0000033c", - 00000608 => x"00000344", - 00000609 => x"0000034c", - 00000610 => x"00000354", - 00000611 => x"00000278", - 00000612 => x"00000278", - 00000613 => x"00000278", - 00000614 => x"0000035c", - 00000615 => x"00000364", - 00000616 => x"00000278", - 00000617 => x"00000278", + 00000578 => x"40b005b3", + 00000579 => x"fe0558e3", + 00000580 => x"40a00533", + 00000581 => x"f61ff0ef", + 00000582 => x"40b00533", + 00000583 => x"00028067", + 00000584 => x"00050613", + 00000585 => x"00000513", + 00000586 => x"0015f693", + 00000587 => x"00068463", + 00000588 => x"00c50533", + 00000589 => x"0015d593", + 00000590 => x"00161613", + 00000591 => x"fe0596e3", + 00000592 => x"00008067", + 00000593 => x"6f727245", + 00000594 => x"4e202172", + 00000595 => x"5047206f", + 00000596 => x"75204f49", + 00000597 => x"2074696e", + 00000598 => x"746e7973", + 00000599 => x"69736568", + 00000600 => x"2164657a", + 00000601 => x"0000000a", + 00000602 => x"6e696c42", + 00000603 => x"676e696b", + 00000604 => x"44454c20", + 00000605 => x"6d656420", + 00000606 => x"7270206f", + 00000607 => x"6172676f", + 00000608 => x"00000a6d", + 00000609 => x"0000030c", + 00000610 => x"00000318", + 00000611 => x"00000324", + 00000612 => x"00000330", + 00000613 => x"0000033c", + 00000614 => x"00000344", + 00000615 => x"0000034c", + 00000616 => x"00000354", + 00000617 => x"0000035c", 00000618 => x"00000278", - 00000619 => x"0000036c", - 00000620 => x"00000278", - 00000621 => x"00000278", + 00000619 => x"00000278", + 00000620 => x"00000364", + 00000621 => x"0000036c", 00000622 => x"00000278", - 00000623 => x"00000374", + 00000623 => x"00000278", 00000624 => x"00000278", - 00000625 => x"00000278", + 00000625 => x"00000374", 00000626 => x"00000278", 00000627 => x"00000278", - 00000628 => x"0000037c", - 00000629 => x"00000384", - 00000630 => x"0000038c", - 00000631 => x"00000394", - 00000632 => x"00007830", - 00000633 => x"4554523c", - 00000634 => x"0000203e", - 00000635 => x"74736e49", - 00000636 => x"74637572", - 00000637 => x"206e6f69", - 00000638 => x"72646461", - 00000639 => x"20737365", - 00000640 => x"6173696d", - 00000641 => x"6e67696c", - 00000642 => x"00006465", - 00000643 => x"74736e49", - 00000644 => x"74637572", - 00000645 => x"206e6f69", - 00000646 => x"65636361", - 00000647 => x"66207373", - 00000648 => x"746c7561", - 00000649 => x"00000000", - 00000650 => x"656c6c49", - 00000651 => x"206c6167", - 00000652 => x"74736e69", - 00000653 => x"74637572", - 00000654 => x"006e6f69", - 00000655 => x"61657242", - 00000656 => x"696f706b", - 00000657 => x"0000746e", - 00000658 => x"64616f4c", - 00000659 => x"64646120", - 00000660 => x"73736572", - 00000661 => x"73696d20", - 00000662 => x"67696c61", - 00000663 => x"0064656e", + 00000628 => x"00000278", + 00000629 => x"0000037c", + 00000630 => x"00000278", + 00000631 => x"00000278", + 00000632 => x"00000278", + 00000633 => x"00000278", + 00000634 => x"00000384", + 00000635 => x"0000038c", + 00000636 => x"00000394", + 00000637 => x"0000039c", + 00000638 => x"00007830", + 00000639 => x"4554523c", + 00000640 => x"0000203e", + 00000641 => x"74736e49", + 00000642 => x"74637572", + 00000643 => x"206e6f69", + 00000644 => x"72646461", + 00000645 => x"20737365", + 00000646 => x"6173696d", + 00000647 => x"6e67696c", + 00000648 => x"00006465", + 00000649 => x"74736e49", + 00000650 => x"74637572", + 00000651 => x"206e6f69", + 00000652 => x"65636361", + 00000653 => x"66207373", + 00000654 => x"746c7561", + 00000655 => x"00000000", + 00000656 => x"656c6c49", + 00000657 => x"206c6167", + 00000658 => x"74736e69", + 00000659 => x"74637572", + 00000660 => x"006e6f69", + 00000661 => x"61657242", + 00000662 => x"696f706b", + 00000663 => x"0000746e", 00000664 => x"64616f4c", - 00000665 => x"63636120", - 00000666 => x"20737365", - 00000667 => x"6c756166", - 00000668 => x"00000074", - 00000669 => x"726f7453", - 00000670 => x"64612065", - 00000671 => x"73657264", - 00000672 => x"696d2073", - 00000673 => x"696c6173", - 00000674 => x"64656e67", - 00000675 => x"00000000", - 00000676 => x"726f7453", - 00000677 => x"63612065", - 00000678 => x"73736563", - 00000679 => x"75616620", - 00000680 => x"0000746c", - 00000681 => x"69766e45", - 00000682 => x"6d6e6f72", - 00000683 => x"20746e65", - 00000684 => x"6c6c6163", - 00000685 => x"00000000", - 00000686 => x"6863614d", - 00000687 => x"20656e69", - 00000688 => x"74666f73", - 00000689 => x"65726177", - 00000690 => x"746e6920", - 00000691 => x"75727265", - 00000692 => x"00007470", - 00000693 => x"6863614d", - 00000694 => x"20656e69", - 00000695 => x"656d6974", - 00000696 => x"6e692072", - 00000697 => x"72726574", - 00000698 => x"00747075", - 00000699 => x"6863614d", - 00000700 => x"20656e69", - 00000701 => x"65747865", - 00000702 => x"6c616e72", - 00000703 => x"746e6920", - 00000704 => x"75727265", - 00000705 => x"00007470", - 00000706 => x"74736146", + 00000665 => x"64646120", + 00000666 => x"73736572", + 00000667 => x"73696d20", + 00000668 => x"67696c61", + 00000669 => x"0064656e", + 00000670 => x"64616f4c", + 00000671 => x"63636120", + 00000672 => x"20737365", + 00000673 => x"6c756166", + 00000674 => x"00000074", + 00000675 => x"726f7453", + 00000676 => x"64612065", + 00000677 => x"73657264", + 00000678 => x"696d2073", + 00000679 => x"696c6173", + 00000680 => x"64656e67", + 00000681 => x"00000000", + 00000682 => x"726f7453", + 00000683 => x"63612065", + 00000684 => x"73736563", + 00000685 => x"75616620", + 00000686 => x"0000746c", + 00000687 => x"69766e45", + 00000688 => x"6d6e6f72", + 00000689 => x"20746e65", + 00000690 => x"6c6c6163", + 00000691 => x"6f726620", + 00000692 => x"2d55206d", + 00000693 => x"65646f6d", + 00000694 => x"00000000", + 00000695 => x"69766e45", + 00000696 => x"6d6e6f72", + 00000697 => x"20746e65", + 00000698 => x"6c6c6163", + 00000699 => x"6f726620", + 00000700 => x"2d4d206d", + 00000701 => x"65646f6d", + 00000702 => x"00000000", + 00000703 => x"6863614d", + 00000704 => x"20656e69", + 00000705 => x"74666f73", + 00000706 => x"65726177", 00000707 => x"746e6920", 00000708 => x"75727265", - 00000709 => x"30207470", - 00000710 => x"00000000", - 00000711 => x"74736146", - 00000712 => x"746e6920", - 00000713 => x"75727265", - 00000714 => x"31207470", - 00000715 => x"00000000", - 00000716 => x"74736146", - 00000717 => x"746e6920", - 00000718 => x"75727265", - 00000719 => x"32207470", - 00000720 => x"00000000", - 00000721 => x"74736146", - 00000722 => x"746e6920", - 00000723 => x"75727265", - 00000724 => x"33207470", - 00000725 => x"00000000", - 00000726 => x"6e6b6e55", - 00000727 => x"206e776f", - 00000728 => x"70617274", - 00000729 => x"75616320", - 00000730 => x"203a6573", - 00000731 => x"00000000", - 00000732 => x"50204020", - 00000733 => x"00003d43", - 00000734 => x"544d202c", - 00000735 => x"3d4c4156", - 00000736 => x"00000000", - 00000737 => x"0000053c", - 00000738 => x"00000448", - 00000739 => x"00000448", - 00000740 => x"00000448", - 00000741 => x"00000548", - 00000742 => x"00000448", - 00000743 => x"00000448", - 00000744 => x"00000448", - 00000745 => x"00000554", - 00000746 => x"00000448", - 00000747 => x"00000448", - 00000748 => x"00000448", - 00000749 => x"00000448", - 00000750 => x"00000560", - 00000751 => x"0000056c", - 00000752 => x"00000578", - 00000753 => x"00000584", - 00000754 => x"00000490", - 00000755 => x"000004dc", - 00000756 => x"000004e8", - 00000757 => x"000004f4", - 00000758 => x"00000500", - 00000759 => x"0000050c", - 00000760 => x"00000518", - 00000761 => x"00000524", - 00000762 => x"00000448", - 00000763 => x"00000448", - 00000764 => x"00000448", - 00000765 => x"00000530", - 00000766 => x"4554523c", - 00000767 => x"4157203e", - 00000768 => x"4e494e52", - 00000769 => x"43202147", - 00000770 => x"43205550", - 00000771 => x"73205253", - 00000772 => x"65747379", - 00000773 => x"6f6e206d", - 00000774 => x"76612074", - 00000775 => x"616c6961", - 00000776 => x"21656c62", - 00000777 => x"522f3c20", - 00000778 => x"003e4554", - 00000779 => x"33323130", - 00000780 => x"37363534", - 00000781 => x"42413938", - 00000782 => x"46454443", + 00000709 => x"00007470", + 00000710 => x"6863614d", + 00000711 => x"20656e69", + 00000712 => x"656d6974", + 00000713 => x"6e692072", + 00000714 => x"72726574", + 00000715 => x"00747075", + 00000716 => x"6863614d", + 00000717 => x"20656e69", + 00000718 => x"65747865", + 00000719 => x"6c616e72", + 00000720 => x"746e6920", + 00000721 => x"75727265", + 00000722 => x"00007470", + 00000723 => x"74736146", + 00000724 => x"746e6920", + 00000725 => x"75727265", + 00000726 => x"30207470", + 00000727 => x"00000000", + 00000728 => x"74736146", + 00000729 => x"746e6920", + 00000730 => x"75727265", + 00000731 => x"31207470", + 00000732 => x"00000000", + 00000733 => x"74736146", + 00000734 => x"746e6920", + 00000735 => x"75727265", + 00000736 => x"32207470", + 00000737 => x"00000000", + 00000738 => x"74736146", + 00000739 => x"746e6920", + 00000740 => x"75727265", + 00000741 => x"33207470", + 00000742 => x"00000000", + 00000743 => x"6e6b6e55", + 00000744 => x"206e776f", + 00000745 => x"70617274", + 00000746 => x"75616320", + 00000747 => x"203a6573", + 00000748 => x"00000000", + 00000749 => x"50204020", + 00000750 => x"00003d43", + 00000751 => x"544d202c", + 00000752 => x"3d4c4156", + 00000753 => x"00000000", + 00000754 => x"00000554", + 00000755 => x"00000454", + 00000756 => x"00000454", + 00000757 => x"00000454", + 00000758 => x"00000560", + 00000759 => x"00000454", + 00000760 => x"00000454", + 00000761 => x"00000454", + 00000762 => x"0000056c", + 00000763 => x"00000454", + 00000764 => x"00000454", + 00000765 => x"00000454", + 00000766 => x"00000454", + 00000767 => x"00000578", + 00000768 => x"00000584", + 00000769 => x"00000590", + 00000770 => x"0000059c", + 00000771 => x"0000049c", + 00000772 => x"000004e8", + 00000773 => x"000004f4", + 00000774 => x"00000500", + 00000775 => x"0000050c", + 00000776 => x"00000518", + 00000777 => x"00000524", + 00000778 => x"00000530", + 00000779 => x"0000053c", + 00000780 => x"00000454", + 00000781 => x"00000454", + 00000782 => x"00000548", + 00000783 => x"4554523c", + 00000784 => x"4157203e", + 00000785 => x"4e494e52", + 00000786 => x"43202147", + 00000787 => x"43205550", + 00000788 => x"73205253", + 00000789 => x"65747379", + 00000790 => x"6f6e206d", + 00000791 => x"76612074", + 00000792 => x"616c6961", + 00000793 => x"21656c62", + 00000794 => x"522f3c20", + 00000795 => x"003e4554", + 00000796 => x"33323130", + 00000797 => x"37363534", + 00000798 => x"42413938", + 00000799 => x"46454443", others => x"00000000" );
/rtl/core/neorv32_bootloader_image.vhd
6,7 → 6,7
 
package neorv32_bootloader_image is
 
type bootloader_init_image_t is array (0 to 974) of std_ulogic_vector(31 downto 0);
type bootloader_init_image_t is array (0 to 982) of std_ulogic_vector(31 downto 0);
constant bootloader_init_image : bootloader_init_image_t := (
00000000 => x"00000093",
00000001 => x"00000113",
30,7 → 30,7
00000019 => x"80010197",
00000020 => x"7b418193",
00000021 => x"00000597",
00000022 => x"09458593",
00000022 => x"09c58593",
00000023 => x"30559073",
00000024 => x"f8000593",
00000025 => x"0005a023",
44,7 → 44,7
00000033 => x"00158593",
00000034 => x"ff5ff06f",
00000035 => x"00001597",
00000036 => x"eac58593",
00000036 => x"ecc58593",
00000037 => x"80010617",
00000038 => x"f6c60613",
00000039 => x"80010697",
61,927 → 61,935
00000050 => x"b8001073",
00000051 => x"b0201073",
00000052 => x"b8201073",
00000053 => x"060000ef",
00000054 => x"30047073",
00000055 => x"00000013",
00000056 => x"10500073",
00000057 => x"0000006f",
00000058 => x"ff810113",
00000059 => x"00812023",
00000060 => x"00912223",
00000061 => x"34202473",
00000062 => x"02044663",
00000063 => x"34102473",
00000064 => x"00041483",
00000065 => x"0034f493",
00000066 => x"00240413",
00000067 => x"34141073",
00000068 => x"00300413",
00000069 => x"00941863",
00000070 => x"34102473",
00000071 => x"00240413",
00000072 => x"34141073",
00000073 => x"00012483",
00000074 => x"00412403",
00000075 => x"00810113",
00000076 => x"30200073",
00000077 => x"800007b7",
00000078 => x"fd010113",
00000079 => x"0007a023",
00000080 => x"ffff07b7",
00000081 => x"02112623",
00000082 => x"02812423",
00000083 => x"02912223",
00000084 => x"03212023",
00000085 => x"01312e23",
00000086 => x"01412c23",
00000087 => x"01512a23",
00000088 => x"01612823",
00000089 => x"01712623",
00000090 => x"01812423",
00000091 => x"49878793",
00000092 => x"30579073",
00000093 => x"fe002403",
00000094 => x"026267b7",
00000095 => x"9ff78793",
00000096 => x"00000693",
00000097 => x"00000613",
00000098 => x"00000593",
00000099 => x"00200513",
00000100 => x"0087f463",
00000101 => x"00400513",
00000102 => x"2dd000ef",
00000103 => x"00100513",
00000104 => x"389000ef",
00000105 => x"00005537",
00000106 => x"00000613",
00000107 => x"00000593",
00000108 => x"b0050513",
00000109 => x"1b1000ef",
00000110 => x"169000ef",
00000111 => x"00245793",
00000112 => x"00a78533",
00000113 => x"00f537b3",
00000114 => x"00b785b3",
00000115 => x"181000ef",
00000116 => x"08000793",
00000117 => x"30479073",
00000118 => x"30046073",
00000119 => x"ffff1537",
00000120 => x"e5450513",
00000121 => x"239000ef",
00000122 => x"f1302573",
00000123 => x"23c000ef",
00000124 => x"ffff1537",
00000125 => x"e8c50513",
00000126 => x"225000ef",
00000127 => x"fe002503",
00000128 => x"228000ef",
00000129 => x"ffff1537",
00000130 => x"e9450513",
00000131 => x"211000ef",
00000132 => x"fe402503",
00000133 => x"214000ef",
00000134 => x"ffff1537",
00000135 => x"ea050513",
00000136 => x"1fd000ef",
00000137 => x"30102573",
00000138 => x"200000ef",
00000139 => x"ffff1537",
00000140 => x"ea850513",
00000141 => x"1e9000ef",
00000142 => x"fe802503",
00000143 => x"ffff14b7",
00000144 => x"00341413",
00000145 => x"1e4000ef",
00000146 => x"ffff1537",
00000147 => x"eb050513",
00000148 => x"1cd000ef",
00000149 => x"ff802503",
00000150 => x"1d0000ef",
00000151 => x"eb848513",
00000152 => x"1bd000ef",
00000153 => x"ff002503",
00000154 => x"1c0000ef",
00000155 => x"ffff1537",
00000156 => x"ec450513",
00000157 => x"1a9000ef",
00000158 => x"ffc02503",
00000159 => x"1ac000ef",
00000160 => x"eb848513",
00000161 => x"199000ef",
00000162 => x"ff402503",
00000163 => x"19c000ef",
00000164 => x"ffff1537",
00000165 => x"ecc50513",
00000166 => x"185000ef",
00000167 => x"085000ef",
00000168 => x"00a404b3",
00000169 => x"0084b433",
00000170 => x"00b40433",
00000171 => x"fa402783",
00000172 => x"0207d263",
00000173 => x"ffff1537",
00000174 => x"ef450513",
00000175 => x"161000ef",
00000176 => x"151000ef",
00000177 => x"02300793",
00000178 => x"02f51263",
00000179 => x"00000513",
00000180 => x"0180006f",
00000181 => x"04d000ef",
00000182 => x"fc85eae3",
00000183 => x"00b41463",
00000184 => x"fc9566e3",
00000185 => x"00100513",
00000186 => x"5a8000ef",
00000187 => x"0b4000ef",
00000188 => x"ffff1937",
00000189 => x"ffff19b7",
00000190 => x"02300a13",
00000191 => x"07200a93",
00000192 => x"06800b13",
00000193 => x"07500b93",
00000194 => x"ffff14b7",
00000195 => x"ffff1c37",
00000196 => x"f0090513",
00000197 => x"109000ef",
00000198 => x"0e9000ef",
00000199 => x"00050413",
00000200 => x"0d1000ef",
00000201 => x"e0c98513",
00000202 => x"0f5000ef",
00000203 => x"fb4400e3",
00000204 => x"01541863",
00000205 => x"ffff02b7",
00000206 => x"00028067",
00000207 => x"fd5ff06f",
00000208 => x"01641663",
00000209 => x"05c000ef",
00000210 => x"fc9ff06f",
00000211 => x"00000513",
00000212 => x"03740063",
00000213 => x"07300793",
00000214 => x"00f41663",
00000215 => x"648000ef",
00000216 => x"fb1ff06f",
00000217 => x"06c00793",
00000218 => x"00f41863",
00000219 => x"00100513",
00000220 => x"3e4000ef",
00000221 => x"f9dff06f",
00000222 => x"06500793",
00000223 => x"00f41663",
00000224 => x"02c000ef",
00000225 => x"f8dff06f",
00000226 => x"03f00793",
00000227 => x"f08c0513",
00000228 => x"00f40463",
00000229 => x"f1c48513",
00000230 => x"085000ef",
00000231 => x"f75ff06f",
00000232 => x"ffff1537",
00000233 => x"d3050513",
00000234 => x"0750006f",
00000235 => x"800007b7",
00000236 => x"0007a783",
00000237 => x"00079863",
00000238 => x"ffff1537",
00000239 => x"d9450513",
00000240 => x"05d0006f",
00000241 => x"ff010113",
00000242 => x"00112623",
00000243 => x"30047073",
00000244 => x"ffff1537",
00000245 => x"db050513",
00000246 => x"045000ef",
00000247 => x"fa002783",
00000248 => x"fe07cee3",
00000249 => x"ff002783",
00000250 => x"00078067",
00000251 => x"0000006f",
00000252 => x"ff010113",
00000253 => x"00812423",
00000254 => x"00050413",
00000255 => x"ffff1537",
00000256 => x"dc050513",
00000257 => x"00112623",
00000258 => x"015000ef",
00000259 => x"03040513",
00000260 => x"0ff57513",
00000261 => x"7dc000ef",
00000262 => x"30047073",
00000263 => x"00100513",
00000264 => x"109000ef",
00000265 => x"0000006f",
00000266 => x"fe010113",
00000267 => x"01212823",
00000268 => x"00050913",
00000269 => x"ffff1537",
00000270 => x"00912a23",
00000271 => x"dd850513",
00000272 => x"ffff14b7",
00000273 => x"00812c23",
00000274 => x"01312623",
00000275 => x"00112e23",
00000276 => x"01c00413",
00000277 => x"7c8000ef",
00000278 => x"f2848493",
00000279 => x"ffc00993",
00000280 => x"008957b3",
00000281 => x"00f7f793",
00000282 => x"00f487b3",
00000283 => x"0007c503",
00000284 => x"ffc40413",
00000285 => x"77c000ef",
00000286 => x"ff3414e3",
00000287 => x"01c12083",
00000288 => x"01812403",
00000289 => x"01412483",
00000290 => x"01012903",
00000291 => x"00c12983",
00000292 => x"02010113",
00000293 => x"00008067",
00000294 => x"fb010113",
00000295 => x"04112623",
00000296 => x"04512423",
00000297 => x"04612223",
00000298 => x"04712023",
00000299 => x"02812e23",
00000300 => x"02a12c23",
00000301 => x"02b12a23",
00000302 => x"02c12823",
00000303 => x"02d12623",
00000304 => x"02e12423",
00000305 => x"02f12223",
00000306 => x"03012023",
00000307 => x"01112e23",
00000308 => x"01c12c23",
00000309 => x"01d12a23",
00000310 => x"01e12823",
00000311 => x"01f12623",
00000312 => x"34202473",
00000313 => x"800007b7",
00000314 => x"00778793",
00000315 => x"06f41a63",
00000316 => x"00000513",
00000317 => x"019000ef",
00000318 => x"628000ef",
00000319 => x"fe002783",
00000320 => x"0027d793",
00000321 => x"00a78533",
00000322 => x"00f537b3",
00000323 => x"00b785b3",
00000324 => x"63c000ef",
00000325 => x"03c12403",
00000326 => x"04c12083",
00000327 => x"04812283",
00000328 => x"04412303",
00000329 => x"04012383",
00000330 => x"03812503",
00000331 => x"03412583",
00000332 => x"03012603",
00000333 => x"02c12683",
00000334 => x"02812703",
00000335 => x"02412783",
00000336 => x"02012803",
00000337 => x"01c12883",
00000338 => x"01812e03",
00000339 => x"01412e83",
00000340 => x"01012f03",
00000341 => x"00c12f83",
00000342 => x"05010113",
00000343 => x"30200073",
00000344 => x"00700793",
00000345 => x"00100513",
00000346 => x"02f40863",
00000347 => x"ffff1537",
00000348 => x"dcc50513",
00000349 => x"6a8000ef",
00000350 => x"00040513",
00000351 => x"eadff0ef",
00000352 => x"ffff1537",
00000353 => x"dd450513",
00000354 => x"694000ef",
00000355 => x"34102573",
00000356 => x"e99ff0ef",
00000357 => x"00500513",
00000358 => x"e59ff0ef",
00000359 => x"ff010113",
00000360 => x"00000513",
00000361 => x"00112623",
00000362 => x"00812423",
00000363 => x"708000ef",
00000364 => x"09e00513",
00000365 => x"744000ef",
00000366 => x"00000513",
00000367 => x"73c000ef",
00000368 => x"00050413",
00000369 => x"00000513",
00000370 => x"70c000ef",
00000371 => x"00c12083",
00000372 => x"0ff47513",
00000373 => x"00812403",
00000374 => x"01010113",
00000375 => x"00008067",
00000376 => x"ff010113",
00000377 => x"00112623",
00000378 => x"00812423",
00000379 => x"00000513",
00000380 => x"6c4000ef",
00000381 => x"00500513",
00000382 => x"700000ef",
00000383 => x"00000513",
00000384 => x"6f8000ef",
00000385 => x"00050413",
00000386 => x"00147413",
00000053 => x"80000637",
00000054 => x"34261073",
00000055 => x"060000ef",
00000056 => x"30047073",
00000057 => x"00000013",
00000058 => x"10500073",
00000059 => x"0000006f",
00000060 => x"ff810113",
00000061 => x"00812023",
00000062 => x"00912223",
00000063 => x"34202473",
00000064 => x"02044663",
00000065 => x"34102473",
00000066 => x"00041483",
00000067 => x"0034f493",
00000068 => x"00240413",
00000069 => x"34141073",
00000070 => x"00300413",
00000071 => x"00941863",
00000072 => x"34102473",
00000073 => x"00240413",
00000074 => x"34141073",
00000075 => x"00012483",
00000076 => x"00412403",
00000077 => x"00810113",
00000078 => x"30200073",
00000079 => x"800007b7",
00000080 => x"fd010113",
00000081 => x"0007a023",
00000082 => x"ffff07b7",
00000083 => x"02112623",
00000084 => x"02812423",
00000085 => x"02912223",
00000086 => x"03212023",
00000087 => x"01312e23",
00000088 => x"01412c23",
00000089 => x"01512a23",
00000090 => x"01612823",
00000091 => x"01712623",
00000092 => x"01812423",
00000093 => x"4b878793",
00000094 => x"30579073",
00000095 => x"fe002403",
00000096 => x"026267b7",
00000097 => x"9ff78793",
00000098 => x"00000693",
00000099 => x"00000613",
00000100 => x"00000593",
00000101 => x"00200513",
00000102 => x"0087f463",
00000103 => x"00400513",
00000104 => x"2f5000ef",
00000105 => x"00100513",
00000106 => x"3a1000ef",
00000107 => x"00005537",
00000108 => x"00000613",
00000109 => x"00000593",
00000110 => x"b0050513",
00000111 => x"1c9000ef",
00000112 => x"181000ef",
00000113 => x"00245793",
00000114 => x"00a78533",
00000115 => x"00f537b3",
00000116 => x"00b785b3",
00000117 => x"199000ef",
00000118 => x"08000793",
00000119 => x"30479073",
00000120 => x"30046073",
00000121 => x"00000013",
00000122 => x"00000013",
00000123 => x"ffff1537",
00000124 => x"e7450513",
00000125 => x"249000ef",
00000126 => x"f1302573",
00000127 => x"24c000ef",
00000128 => x"ffff1537",
00000129 => x"eac50513",
00000130 => x"235000ef",
00000131 => x"fe002503",
00000132 => x"238000ef",
00000133 => x"ffff1537",
00000134 => x"eb450513",
00000135 => x"221000ef",
00000136 => x"fe402503",
00000137 => x"224000ef",
00000138 => x"ffff1537",
00000139 => x"ec050513",
00000140 => x"20d000ef",
00000141 => x"30102573",
00000142 => x"210000ef",
00000143 => x"ffff1537",
00000144 => x"ec850513",
00000145 => x"1f9000ef",
00000146 => x"fe802503",
00000147 => x"ffff14b7",
00000148 => x"00341413",
00000149 => x"1f4000ef",
00000150 => x"ffff1537",
00000151 => x"ed050513",
00000152 => x"1dd000ef",
00000153 => x"ff802503",
00000154 => x"1e0000ef",
00000155 => x"ed848513",
00000156 => x"1cd000ef",
00000157 => x"ff002503",
00000158 => x"1d0000ef",
00000159 => x"ffff1537",
00000160 => x"ee450513",
00000161 => x"1b9000ef",
00000162 => x"ffc02503",
00000163 => x"1bc000ef",
00000164 => x"ed848513",
00000165 => x"1a9000ef",
00000166 => x"ff402503",
00000167 => x"1ac000ef",
00000168 => x"ffff1537",
00000169 => x"eec50513",
00000170 => x"195000ef",
00000171 => x"095000ef",
00000172 => x"00a404b3",
00000173 => x"0084b433",
00000174 => x"00b40433",
00000175 => x"fa402783",
00000176 => x"0207d263",
00000177 => x"ffff1537",
00000178 => x"f1450513",
00000179 => x"171000ef",
00000180 => x"161000ef",
00000181 => x"02300793",
00000182 => x"02f51263",
00000183 => x"00000513",
00000184 => x"0180006f",
00000185 => x"05d000ef",
00000186 => x"fc85eae3",
00000187 => x"00b41463",
00000188 => x"fc9566e3",
00000189 => x"00100513",
00000190 => x"5b8000ef",
00000191 => x"0b4000ef",
00000192 => x"ffff1937",
00000193 => x"ffff19b7",
00000194 => x"02300a13",
00000195 => x"07200a93",
00000196 => x"06800b13",
00000197 => x"07500b93",
00000198 => x"ffff14b7",
00000199 => x"ffff1c37",
00000200 => x"f2090513",
00000201 => x"119000ef",
00000202 => x"0f9000ef",
00000203 => x"00050413",
00000204 => x"0e1000ef",
00000205 => x"e2c98513",
00000206 => x"105000ef",
00000207 => x"fb4400e3",
00000208 => x"01541863",
00000209 => x"ffff02b7",
00000210 => x"00028067",
00000211 => x"fd5ff06f",
00000212 => x"01641663",
00000213 => x"05c000ef",
00000214 => x"fc9ff06f",
00000215 => x"00000513",
00000216 => x"03740063",
00000217 => x"07300793",
00000218 => x"00f41663",
00000219 => x"658000ef",
00000220 => x"fb1ff06f",
00000221 => x"06c00793",
00000222 => x"00f41863",
00000223 => x"00100513",
00000224 => x"3f4000ef",
00000225 => x"f9dff06f",
00000226 => x"06500793",
00000227 => x"00f41663",
00000228 => x"02c000ef",
00000229 => x"f8dff06f",
00000230 => x"03f00793",
00000231 => x"f28c0513",
00000232 => x"00f40463",
00000233 => x"f3c48513",
00000234 => x"095000ef",
00000235 => x"f75ff06f",
00000236 => x"ffff1537",
00000237 => x"d5050513",
00000238 => x"0850006f",
00000239 => x"800007b7",
00000240 => x"0007a783",
00000241 => x"00079863",
00000242 => x"ffff1537",
00000243 => x"db450513",
00000244 => x"06d0006f",
00000245 => x"ff010113",
00000246 => x"00112623",
00000247 => x"30047073",
00000248 => x"00000013",
00000249 => x"00000013",
00000250 => x"ffff1537",
00000251 => x"dd050513",
00000252 => x"04d000ef",
00000253 => x"fa002783",
00000254 => x"fe07cee3",
00000255 => x"ff002783",
00000256 => x"00078067",
00000257 => x"0000006f",
00000258 => x"ff010113",
00000259 => x"00812423",
00000260 => x"00050413",
00000261 => x"ffff1537",
00000262 => x"de050513",
00000263 => x"00112623",
00000264 => x"01d000ef",
00000265 => x"03040513",
00000266 => x"0ff57513",
00000267 => x"7e4000ef",
00000268 => x"30047073",
00000269 => x"00000013",
00000270 => x"00000013",
00000271 => x"00100513",
00000272 => x"109000ef",
00000273 => x"0000006f",
00000274 => x"fe010113",
00000275 => x"01212823",
00000276 => x"00050913",
00000277 => x"ffff1537",
00000278 => x"00912a23",
00000279 => x"df850513",
00000280 => x"ffff14b7",
00000281 => x"00812c23",
00000282 => x"01312623",
00000283 => x"00112e23",
00000284 => x"01c00413",
00000285 => x"7c8000ef",
00000286 => x"f4848493",
00000287 => x"ffc00993",
00000288 => x"008957b3",
00000289 => x"00f7f793",
00000290 => x"00f487b3",
00000291 => x"0007c503",
00000292 => x"ffc40413",
00000293 => x"77c000ef",
00000294 => x"ff3414e3",
00000295 => x"01c12083",
00000296 => x"01812403",
00000297 => x"01412483",
00000298 => x"01012903",
00000299 => x"00c12983",
00000300 => x"02010113",
00000301 => x"00008067",
00000302 => x"fb010113",
00000303 => x"04112623",
00000304 => x"04512423",
00000305 => x"04612223",
00000306 => x"04712023",
00000307 => x"02812e23",
00000308 => x"02a12c23",
00000309 => x"02b12a23",
00000310 => x"02c12823",
00000311 => x"02d12623",
00000312 => x"02e12423",
00000313 => x"02f12223",
00000314 => x"03012023",
00000315 => x"01112e23",
00000316 => x"01c12c23",
00000317 => x"01d12a23",
00000318 => x"01e12823",
00000319 => x"01f12623",
00000320 => x"34202473",
00000321 => x"800007b7",
00000322 => x"00778793",
00000323 => x"06f41a63",
00000324 => x"00000513",
00000325 => x"019000ef",
00000326 => x"628000ef",
00000327 => x"fe002783",
00000328 => x"0027d793",
00000329 => x"00a78533",
00000330 => x"00f537b3",
00000331 => x"00b785b3",
00000332 => x"63c000ef",
00000333 => x"03c12403",
00000334 => x"04c12083",
00000335 => x"04812283",
00000336 => x"04412303",
00000337 => x"04012383",
00000338 => x"03812503",
00000339 => x"03412583",
00000340 => x"03012603",
00000341 => x"02c12683",
00000342 => x"02812703",
00000343 => x"02412783",
00000344 => x"02012803",
00000345 => x"01c12883",
00000346 => x"01812e03",
00000347 => x"01412e83",
00000348 => x"01012f03",
00000349 => x"00c12f83",
00000350 => x"05010113",
00000351 => x"30200073",
00000352 => x"00700793",
00000353 => x"00100513",
00000354 => x"02f40863",
00000355 => x"ffff1537",
00000356 => x"dec50513",
00000357 => x"6a8000ef",
00000358 => x"00040513",
00000359 => x"eadff0ef",
00000360 => x"ffff1537",
00000361 => x"df450513",
00000362 => x"694000ef",
00000363 => x"34102573",
00000364 => x"e99ff0ef",
00000365 => x"00500513",
00000366 => x"e51ff0ef",
00000367 => x"ff010113",
00000368 => x"00000513",
00000369 => x"00112623",
00000370 => x"00812423",
00000371 => x"708000ef",
00000372 => x"09e00513",
00000373 => x"744000ef",
00000374 => x"00000513",
00000375 => x"73c000ef",
00000376 => x"00050413",
00000377 => x"00000513",
00000378 => x"70c000ef",
00000379 => x"00c12083",
00000380 => x"0ff47513",
00000381 => x"00812403",
00000382 => x"01010113",
00000383 => x"00008067",
00000384 => x"ff010113",
00000385 => x"00112623",
00000386 => x"00812423",
00000387 => x"00000513",
00000388 => x"6c4000ef",
00000389 => x"fc041ce3",
00000390 => x"00c12083",
00000391 => x"00812403",
00000392 => x"01010113",
00000393 => x"00008067",
00000394 => x"ff010113",
00000389 => x"00500513",
00000390 => x"700000ef",
00000391 => x"00000513",
00000392 => x"6f8000ef",
00000393 => x"00050413",
00000394 => x"00147413",
00000395 => x"00000513",
00000396 => x"00112623",
00000397 => x"680000ef",
00000398 => x"00600513",
00000399 => x"6bc000ef",
00000400 => x"00c12083",
00000401 => x"00000513",
00000402 => x"01010113",
00000403 => x"6880006f",
00000404 => x"ff010113",
00000405 => x"00812423",
00000406 => x"00050413",
00000407 => x"01055513",
00000408 => x"0ff57513",
00000409 => x"00112623",
00000410 => x"690000ef",
00000411 => x"00845513",
00000412 => x"0ff57513",
00000413 => x"684000ef",
00000414 => x"0ff47513",
00000415 => x"00812403",
00000416 => x"00c12083",
00000417 => x"01010113",
00000418 => x"6700006f",
00000419 => x"ff010113",
00000420 => x"00812423",
00000421 => x"00050413",
00000422 => x"00000513",
00000423 => x"00112623",
00000424 => x"614000ef",
00000425 => x"00300513",
00000426 => x"650000ef",
00000427 => x"00040513",
00000428 => x"fa1ff0ef",
00000429 => x"00000513",
00000430 => x"640000ef",
00000431 => x"00050413",
00000432 => x"00000513",
00000433 => x"610000ef",
00000434 => x"00c12083",
00000435 => x"0ff47513",
00000436 => x"00812403",
00000437 => x"01010113",
00000438 => x"00008067",
00000439 => x"fd010113",
00000440 => x"02812423",
00000441 => x"02912223",
00000442 => x"03212023",
00000443 => x"01312e23",
00000444 => x"01412c23",
00000445 => x"02112623",
00000446 => x"00050913",
00000447 => x"00058993",
00000448 => x"00c10493",
00000449 => x"00000413",
00000450 => x"00400a13",
00000451 => x"02091e63",
00000452 => x"4f0000ef",
00000453 => x"00a481a3",
00000454 => x"00140413",
00000455 => x"fff48493",
00000456 => x"ff4416e3",
00000457 => x"02c12083",
00000458 => x"02812403",
00000459 => x"00c12503",
00000460 => x"02412483",
00000461 => x"02012903",
00000462 => x"01c12983",
00000463 => x"01812a03",
00000464 => x"03010113",
00000465 => x"00008067",
00000466 => x"00898533",
00000467 => x"f41ff0ef",
00000468 => x"fc5ff06f",
00000469 => x"fe802783",
00000470 => x"fd010113",
00000471 => x"02812423",
00000472 => x"02112623",
00000473 => x"02912223",
00000474 => x"03212023",
00000475 => x"01312e23",
00000476 => x"01412c23",
00000477 => x"01512a23",
00000478 => x"01612823",
00000479 => x"01712623",
00000480 => x"0087f793",
00000481 => x"00050413",
00000482 => x"00078a63",
00000483 => x"fe802783",
00000484 => x"00400513",
00000485 => x"0047f793",
00000486 => x"04079663",
00000487 => x"02041863",
00000488 => x"ffff1537",
00000489 => x"ddc50513",
00000490 => x"474000ef",
00000491 => x"008005b7",
00000492 => x"00040513",
00000493 => x"f29ff0ef",
00000494 => x"4788d7b7",
00000495 => x"afe78793",
00000496 => x"02f50463",
00000497 => x"00000513",
00000498 => x"01c0006f",
00000499 => x"ffff1537",
00000500 => x"dfc50513",
00000501 => x"448000ef",
00000502 => x"dc5ff0ef",
00000503 => x"fc0518e3",
00000504 => x"00300513",
00000505 => x"c0dff0ef",
00000506 => x"008009b7",
00000507 => x"00498593",
00000508 => x"00040513",
00000509 => x"ee9ff0ef",
00000510 => x"00050a13",
00000511 => x"00898593",
00000512 => x"00040513",
00000513 => x"ed9ff0ef",
00000514 => x"ff002b83",
00000515 => x"00050a93",
00000516 => x"ffca7b13",
00000517 => x"00000913",
00000518 => x"00000493",
00000519 => x"00c98993",
00000520 => x"013905b3",
00000521 => x"052b1863",
00000522 => x"015484b3",
00000523 => x"00200513",
00000524 => x"fa049ae3",
00000525 => x"ffff1537",
00000526 => x"e0850513",
00000527 => x"3e0000ef",
00000528 => x"02c12083",
00000529 => x"02812403",
00000530 => x"800007b7",
00000531 => x"0147a023",
00000532 => x"02412483",
00000533 => x"02012903",
00000534 => x"01c12983",
00000535 => x"01812a03",
00000536 => x"01412a83",
00000537 => x"01012b03",
00000538 => x"00c12b83",
00000539 => x"03010113",
00000540 => x"00008067",
00000541 => x"00040513",
00000542 => x"e65ff0ef",
00000543 => x"012b87b3",
00000544 => x"00a484b3",
00000545 => x"00a7a023",
00000546 => x"00490913",
00000547 => x"f95ff06f",
00000548 => x"ff010113",
00000549 => x"00112623",
00000550 => x"ebdff0ef",
00000551 => x"ffff1537",
00000552 => x"e0c50513",
00000553 => x"378000ef",
00000554 => x"b05ff0ef",
00000555 => x"0000006f",
00000396 => x"6c4000ef",
00000397 => x"fc041ce3",
00000398 => x"00c12083",
00000399 => x"00812403",
00000400 => x"01010113",
00000401 => x"00008067",
00000402 => x"ff010113",
00000403 => x"00000513",
00000404 => x"00112623",
00000405 => x"680000ef",
00000406 => x"00600513",
00000407 => x"6bc000ef",
00000408 => x"00c12083",
00000409 => x"00000513",
00000410 => x"01010113",
00000411 => x"6880006f",
00000412 => x"ff010113",
00000413 => x"00812423",
00000414 => x"00050413",
00000415 => x"01055513",
00000416 => x"0ff57513",
00000417 => x"00112623",
00000418 => x"690000ef",
00000419 => x"00845513",
00000420 => x"0ff57513",
00000421 => x"684000ef",
00000422 => x"0ff47513",
00000423 => x"00812403",
00000424 => x"00c12083",
00000425 => x"01010113",
00000426 => x"6700006f",
00000427 => x"ff010113",
00000428 => x"00812423",
00000429 => x"00050413",
00000430 => x"00000513",
00000431 => x"00112623",
00000432 => x"614000ef",
00000433 => x"00300513",
00000434 => x"650000ef",
00000435 => x"00040513",
00000436 => x"fa1ff0ef",
00000437 => x"00000513",
00000438 => x"640000ef",
00000439 => x"00050413",
00000440 => x"00000513",
00000441 => x"610000ef",
00000442 => x"00c12083",
00000443 => x"0ff47513",
00000444 => x"00812403",
00000445 => x"01010113",
00000446 => x"00008067",
00000447 => x"fd010113",
00000448 => x"02812423",
00000449 => x"02912223",
00000450 => x"03212023",
00000451 => x"01312e23",
00000452 => x"01412c23",
00000453 => x"02112623",
00000454 => x"00050913",
00000455 => x"00058993",
00000456 => x"00c10493",
00000457 => x"00000413",
00000458 => x"00400a13",
00000459 => x"02091e63",
00000460 => x"4f0000ef",
00000461 => x"00a481a3",
00000462 => x"00140413",
00000463 => x"fff48493",
00000464 => x"ff4416e3",
00000465 => x"02c12083",
00000466 => x"02812403",
00000467 => x"00c12503",
00000468 => x"02412483",
00000469 => x"02012903",
00000470 => x"01c12983",
00000471 => x"01812a03",
00000472 => x"03010113",
00000473 => x"00008067",
00000474 => x"00898533",
00000475 => x"f41ff0ef",
00000476 => x"fc5ff06f",
00000477 => x"fe802783",
00000478 => x"fd010113",
00000479 => x"02812423",
00000480 => x"02112623",
00000481 => x"02912223",
00000482 => x"03212023",
00000483 => x"01312e23",
00000484 => x"01412c23",
00000485 => x"01512a23",
00000486 => x"01612823",
00000487 => x"01712623",
00000488 => x"0087f793",
00000489 => x"00050413",
00000490 => x"00078a63",
00000491 => x"fe802783",
00000492 => x"00400513",
00000493 => x"0047f793",
00000494 => x"04079663",
00000495 => x"02041863",
00000496 => x"ffff1537",
00000497 => x"dfc50513",
00000498 => x"474000ef",
00000499 => x"008005b7",
00000500 => x"00040513",
00000501 => x"f29ff0ef",
00000502 => x"4788d7b7",
00000503 => x"afe78793",
00000504 => x"02f50463",
00000505 => x"00000513",
00000506 => x"01c0006f",
00000507 => x"ffff1537",
00000508 => x"e1c50513",
00000509 => x"448000ef",
00000510 => x"dc5ff0ef",
00000511 => x"fc0518e3",
00000512 => x"00300513",
00000513 => x"c05ff0ef",
00000514 => x"008009b7",
00000515 => x"00498593",
00000516 => x"00040513",
00000517 => x"ee9ff0ef",
00000518 => x"00050a13",
00000519 => x"00898593",
00000520 => x"00040513",
00000521 => x"ed9ff0ef",
00000522 => x"ff002b83",
00000523 => x"00050a93",
00000524 => x"ffca7b13",
00000525 => x"00000913",
00000526 => x"00000493",
00000527 => x"00c98993",
00000528 => x"013905b3",
00000529 => x"052b1863",
00000530 => x"015484b3",
00000531 => x"00200513",
00000532 => x"fa049ae3",
00000533 => x"ffff1537",
00000534 => x"e2850513",
00000535 => x"3e0000ef",
00000536 => x"02c12083",
00000537 => x"02812403",
00000538 => x"800007b7",
00000539 => x"0147a023",
00000540 => x"02412483",
00000541 => x"02012903",
00000542 => x"01c12983",
00000543 => x"01812a03",
00000544 => x"01412a83",
00000545 => x"01012b03",
00000546 => x"00c12b83",
00000547 => x"03010113",
00000548 => x"00008067",
00000549 => x"00040513",
00000550 => x"e65ff0ef",
00000551 => x"012b87b3",
00000552 => x"00a484b3",
00000553 => x"00a7a023",
00000554 => x"00490913",
00000555 => x"f95ff06f",
00000556 => x"ff010113",
00000557 => x"00112623",
00000558 => x"00812423",
00000559 => x"00912223",
00000560 => x"00058413",
00000561 => x"00050493",
00000562 => x"d61ff0ef",
00000563 => x"00000513",
00000564 => x"3e4000ef",
00000565 => x"00200513",
00000566 => x"420000ef",
00000567 => x"00048513",
00000568 => x"d71ff0ef",
00000569 => x"00040513",
00000570 => x"410000ef",
00000558 => x"ebdff0ef",
00000559 => x"ffff1537",
00000560 => x"e2c50513",
00000561 => x"378000ef",
00000562 => x"af5ff0ef",
00000563 => x"0000006f",
00000564 => x"ff010113",
00000565 => x"00112623",
00000566 => x"00812423",
00000567 => x"00912223",
00000568 => x"00058413",
00000569 => x"00050493",
00000570 => x"d61ff0ef",
00000571 => x"00000513",
00000572 => x"3e4000ef",
00000573 => x"00812403",
00000574 => x"00c12083",
00000575 => x"00412483",
00000576 => x"01010113",
00000577 => x"cddff06f",
00000578 => x"fe010113",
00000579 => x"00812c23",
00000580 => x"00912a23",
00000581 => x"01212823",
00000582 => x"00112e23",
00000583 => x"00b12623",
00000584 => x"00300413",
00000585 => x"00350493",
00000586 => x"fff00913",
00000587 => x"00c10793",
00000588 => x"008787b3",
00000589 => x"0007c583",
00000590 => x"40848533",
00000591 => x"fff40413",
00000592 => x"f71ff0ef",
00000593 => x"ff2414e3",
00000594 => x"01c12083",
00000595 => x"01812403",
00000596 => x"01412483",
00000597 => x"01012903",
00000598 => x"02010113",
00000599 => x"00008067",
00000600 => x"ff010113",
00000601 => x"00112623",
00000602 => x"00812423",
00000603 => x"00050413",
00000604 => x"cb9ff0ef",
00000605 => x"00000513",
00000606 => x"33c000ef",
00000607 => x"0d800513",
00000608 => x"378000ef",
00000609 => x"00040513",
00000610 => x"cc9ff0ef",
00000611 => x"00000513",
00000612 => x"344000ef",
00000613 => x"00812403",
00000614 => x"00c12083",
00000615 => x"01010113",
00000616 => x"c41ff06f",
00000617 => x"fe010113",
00000618 => x"800007b7",
00000619 => x"00812c23",
00000620 => x"0007a403",
00000621 => x"00112e23",
00000622 => x"00912a23",
00000623 => x"01212823",
00000624 => x"01312623",
00000625 => x"01412423",
00000626 => x"01512223",
00000627 => x"02041863",
00000628 => x"ffff1537",
00000629 => x"d9450513",
00000630 => x"01812403",
00000631 => x"01c12083",
00000632 => x"01412483",
00000633 => x"01012903",
00000634 => x"00c12983",
00000635 => x"00812a03",
00000636 => x"00412a83",
00000637 => x"02010113",
00000638 => x"2240006f",
00000639 => x"ffff1537",
00000640 => x"e1050513",
00000641 => x"218000ef",
00000642 => x"00040513",
00000643 => x"a1dff0ef",
00000644 => x"ffff1537",
00000645 => x"e1c50513",
00000646 => x"204000ef",
00000647 => x"00800537",
00000648 => x"a09ff0ef",
00000649 => x"ffff1537",
00000650 => x"e3850513",
00000651 => x"1f0000ef",
00000652 => x"1d0000ef",
00000653 => x"00050493",
00000654 => x"1b8000ef",
00000655 => x"07900793",
00000656 => x"0af49e63",
00000657 => x"b59ff0ef",
00000658 => x"00051663",
00000659 => x"00300513",
00000660 => x"9a1ff0ef",
00000661 => x"ffff1537",
00000662 => x"e4450513",
00000663 => x"01045493",
00000664 => x"1bc000ef",
00000665 => x"00148493",
00000666 => x"00800937",
00000667 => x"fff00993",
00000668 => x"00010a37",
00000669 => x"fff48493",
00000670 => x"07349063",
00000671 => x"4788d5b7",
00000672 => x"afe58593",
00000673 => x"00800537",
00000674 => x"e81ff0ef",
00000675 => x"00800537",
00000676 => x"00040593",
00000677 => x"00450513",
00000678 => x"e71ff0ef",
00000679 => x"ff002a03",
00000680 => x"008009b7",
00000681 => x"ffc47413",
00000682 => x"00000493",
00000683 => x"00000913",
00000684 => x"00c98a93",
00000685 => x"01548533",
00000686 => x"009a07b3",
00000687 => x"02849663",
00000688 => x"00898513",
00000689 => x"412005b3",
00000690 => x"e41ff0ef",
00000691 => x"ffff1537",
00000692 => x"e0850513",
00000693 => x"f05ff06f",
00000694 => x"00090513",
00000695 => x"e85ff0ef",
00000696 => x"01490933",
00000697 => x"f91ff06f",
00000698 => x"0007a583",
00000699 => x"00448493",
00000700 => x"00b90933",
00000701 => x"e15ff0ef",
00000702 => x"fbdff06f",
00000703 => x"01c12083",
00000704 => x"01812403",
00000705 => x"01412483",
00000706 => x"01012903",
00000707 => x"00c12983",
00000708 => x"00812a03",
00000709 => x"00412a83",
00000710 => x"02010113",
00000711 => x"00008067",
00000712 => x"ff010113",
00000713 => x"f9402783",
00000714 => x"f9002703",
00000715 => x"f9402683",
00000716 => x"fed79ae3",
00000717 => x"00e12023",
00000718 => x"00f12223",
00000719 => x"00012503",
00000720 => x"00412583",
00000721 => x"01010113",
00000722 => x"00008067",
00000723 => x"f9800693",
00000724 => x"fff00613",
00000725 => x"00c6a023",
00000726 => x"00a6a023",
00000727 => x"00b6a223",
00000728 => x"00008067",
00000729 => x"fa002023",
00000730 => x"fe002683",
00000731 => x"00151513",
00000732 => x"00000713",
00000733 => x"04a6f263",
00000734 => x"000016b7",
00000735 => x"00000793",
00000736 => x"ffe68693",
00000737 => x"04e6e463",
00000738 => x"00167613",
00000739 => x"0015f593",
00000740 => x"01879793",
00000741 => x"01e61613",
00000742 => x"00c7e7b3",
00000743 => x"01d59593",
00000744 => x"00b7e7b3",
00000745 => x"00e7e7b3",
00000746 => x"10000737",
00000747 => x"00e7e7b3",
00000748 => x"faf02023",
00000749 => x"00008067",
00000750 => x"00170793",
00000751 => x"01079713",
00000752 => x"40a686b3",
00000753 => x"01075713",
00000754 => x"fadff06f",
00000755 => x"ffe78513",
00000756 => x"0fd57513",
00000757 => x"00051a63",
00000758 => x"00375713",
00000759 => x"00178793",
00000760 => x"0ff7f793",
00000761 => x"fa1ff06f",
00000762 => x"00175713",
00000763 => x"ff1ff06f",
00000764 => x"fa002783",
00000765 => x"fe07cee3",
00000766 => x"faa02223",
00000767 => x"00008067",
00000768 => x"fa402503",
00000769 => x"fe055ee3",
00000770 => x"0ff57513",
00000771 => x"00008067",
00000772 => x"fa402503",
00000773 => x"0ff57513",
00000774 => x"00008067",
00000775 => x"ff010113",
00000776 => x"00812423",
00000777 => x"01212023",
00000778 => x"00112623",
00000779 => x"00912223",
00000780 => x"00050413",
00000781 => x"00a00913",
00000782 => x"00044483",
00000783 => x"00140413",
00000784 => x"00049e63",
00000785 => x"00c12083",
00000786 => x"00812403",
00000787 => x"00412483",
00000788 => x"00012903",
00000789 => x"01010113",
00000790 => x"00008067",
00000791 => x"01249663",
00000792 => x"00d00513",
00000793 => x"f8dff0ef",
00000794 => x"00048513",
00000795 => x"f85ff0ef",
00000796 => x"fc9ff06f",
00000797 => x"00757513",
00000798 => x"0016f793",
00000799 => x"00367613",
00000800 => x"00a51513",
00000801 => x"00f79793",
00000802 => x"0015f593",
00000803 => x"00f567b3",
00000804 => x"00d61613",
00000805 => x"00c7e7b3",
00000806 => x"00959593",
00000807 => x"fa800713",
00000808 => x"00b7e7b3",
00000809 => x"00072023",
00000810 => x"1007e793",
00000811 => x"00f72023",
00000812 => x"00008067",
00000813 => x"fa800713",
00000814 => x"00072683",
00000815 => x"00757793",
00000816 => x"00100513",
00000817 => x"00f51533",
00000818 => x"00d56533",
00000819 => x"00a72023",
00000573 => x"00200513",
00000574 => x"420000ef",
00000575 => x"00048513",
00000576 => x"d71ff0ef",
00000577 => x"00040513",
00000578 => x"410000ef",
00000579 => x"00000513",
00000580 => x"3e4000ef",
00000581 => x"00812403",
00000582 => x"00c12083",
00000583 => x"00412483",
00000584 => x"01010113",
00000585 => x"cddff06f",
00000586 => x"fe010113",
00000587 => x"00812c23",
00000588 => x"00912a23",
00000589 => x"01212823",
00000590 => x"00112e23",
00000591 => x"00b12623",
00000592 => x"00300413",
00000593 => x"00350493",
00000594 => x"fff00913",
00000595 => x"00c10793",
00000596 => x"008787b3",
00000597 => x"0007c583",
00000598 => x"40848533",
00000599 => x"fff40413",
00000600 => x"f71ff0ef",
00000601 => x"ff2414e3",
00000602 => x"01c12083",
00000603 => x"01812403",
00000604 => x"01412483",
00000605 => x"01012903",
00000606 => x"02010113",
00000607 => x"00008067",
00000608 => x"ff010113",
00000609 => x"00112623",
00000610 => x"00812423",
00000611 => x"00050413",
00000612 => x"cb9ff0ef",
00000613 => x"00000513",
00000614 => x"33c000ef",
00000615 => x"0d800513",
00000616 => x"378000ef",
00000617 => x"00040513",
00000618 => x"cc9ff0ef",
00000619 => x"00000513",
00000620 => x"344000ef",
00000621 => x"00812403",
00000622 => x"00c12083",
00000623 => x"01010113",
00000624 => x"c41ff06f",
00000625 => x"fe010113",
00000626 => x"800007b7",
00000627 => x"00812c23",
00000628 => x"0007a403",
00000629 => x"00112e23",
00000630 => x"00912a23",
00000631 => x"01212823",
00000632 => x"01312623",
00000633 => x"01412423",
00000634 => x"01512223",
00000635 => x"02041863",
00000636 => x"ffff1537",
00000637 => x"db450513",
00000638 => x"01812403",
00000639 => x"01c12083",
00000640 => x"01412483",
00000641 => x"01012903",
00000642 => x"00c12983",
00000643 => x"00812a03",
00000644 => x"00412a83",
00000645 => x"02010113",
00000646 => x"2240006f",
00000647 => x"ffff1537",
00000648 => x"e3050513",
00000649 => x"218000ef",
00000650 => x"00040513",
00000651 => x"a1dff0ef",
00000652 => x"ffff1537",
00000653 => x"e3c50513",
00000654 => x"204000ef",
00000655 => x"00800537",
00000656 => x"a09ff0ef",
00000657 => x"ffff1537",
00000658 => x"e5850513",
00000659 => x"1f0000ef",
00000660 => x"1d0000ef",
00000661 => x"00050493",
00000662 => x"1b8000ef",
00000663 => x"07900793",
00000664 => x"0af49e63",
00000665 => x"b59ff0ef",
00000666 => x"00051663",
00000667 => x"00300513",
00000668 => x"999ff0ef",
00000669 => x"ffff1537",
00000670 => x"e6450513",
00000671 => x"01045493",
00000672 => x"1bc000ef",
00000673 => x"00148493",
00000674 => x"00800937",
00000675 => x"fff00993",
00000676 => x"00010a37",
00000677 => x"fff48493",
00000678 => x"07349063",
00000679 => x"4788d5b7",
00000680 => x"afe58593",
00000681 => x"00800537",
00000682 => x"e81ff0ef",
00000683 => x"00800537",
00000684 => x"00040593",
00000685 => x"00450513",
00000686 => x"e71ff0ef",
00000687 => x"ff002a03",
00000688 => x"008009b7",
00000689 => x"ffc47413",
00000690 => x"00000493",
00000691 => x"00000913",
00000692 => x"00c98a93",
00000693 => x"01548533",
00000694 => x"009a07b3",
00000695 => x"02849663",
00000696 => x"00898513",
00000697 => x"412005b3",
00000698 => x"e41ff0ef",
00000699 => x"ffff1537",
00000700 => x"e2850513",
00000701 => x"f05ff06f",
00000702 => x"00090513",
00000703 => x"e85ff0ef",
00000704 => x"01490933",
00000705 => x"f91ff06f",
00000706 => x"0007a583",
00000707 => x"00448493",
00000708 => x"00b90933",
00000709 => x"e15ff0ef",
00000710 => x"fbdff06f",
00000711 => x"01c12083",
00000712 => x"01812403",
00000713 => x"01412483",
00000714 => x"01012903",
00000715 => x"00c12983",
00000716 => x"00812a03",
00000717 => x"00412a83",
00000718 => x"02010113",
00000719 => x"00008067",
00000720 => x"ff010113",
00000721 => x"f9402783",
00000722 => x"f9002703",
00000723 => x"f9402683",
00000724 => x"fed79ae3",
00000725 => x"00e12023",
00000726 => x"00f12223",
00000727 => x"00012503",
00000728 => x"00412583",
00000729 => x"01010113",
00000730 => x"00008067",
00000731 => x"f9800693",
00000732 => x"fff00613",
00000733 => x"00c6a023",
00000734 => x"00a6a023",
00000735 => x"00b6a223",
00000736 => x"00008067",
00000737 => x"fa002023",
00000738 => x"fe002683",
00000739 => x"00151513",
00000740 => x"00000713",
00000741 => x"04a6f263",
00000742 => x"000016b7",
00000743 => x"00000793",
00000744 => x"ffe68693",
00000745 => x"04e6e463",
00000746 => x"00167613",
00000747 => x"0015f593",
00000748 => x"01879793",
00000749 => x"01e61613",
00000750 => x"00c7e7b3",
00000751 => x"01d59593",
00000752 => x"00b7e7b3",
00000753 => x"00e7e7b3",
00000754 => x"10000737",
00000755 => x"00e7e7b3",
00000756 => x"faf02023",
00000757 => x"00008067",
00000758 => x"00170793",
00000759 => x"01079713",
00000760 => x"40a686b3",
00000761 => x"01075713",
00000762 => x"fadff06f",
00000763 => x"ffe78513",
00000764 => x"0fd57513",
00000765 => x"00051a63",
00000766 => x"00375713",
00000767 => x"00178793",
00000768 => x"0ff7f793",
00000769 => x"fa1ff06f",
00000770 => x"00175713",
00000771 => x"ff1ff06f",
00000772 => x"fa002783",
00000773 => x"fe07cee3",
00000774 => x"faa02223",
00000775 => x"00008067",
00000776 => x"fa402503",
00000777 => x"fe055ee3",
00000778 => x"0ff57513",
00000779 => x"00008067",
00000780 => x"fa402503",
00000781 => x"0ff57513",
00000782 => x"00008067",
00000783 => x"ff010113",
00000784 => x"00812423",
00000785 => x"01212023",
00000786 => x"00112623",
00000787 => x"00912223",
00000788 => x"00050413",
00000789 => x"00a00913",
00000790 => x"00044483",
00000791 => x"00140413",
00000792 => x"00049e63",
00000793 => x"00c12083",
00000794 => x"00812403",
00000795 => x"00412483",
00000796 => x"00012903",
00000797 => x"01010113",
00000798 => x"00008067",
00000799 => x"01249663",
00000800 => x"00d00513",
00000801 => x"f8dff0ef",
00000802 => x"00048513",
00000803 => x"f85ff0ef",
00000804 => x"fc9ff06f",
00000805 => x"00757513",
00000806 => x"0016f793",
00000807 => x"00367613",
00000808 => x"00a51513",
00000809 => x"00f79793",
00000810 => x"0015f593",
00000811 => x"00f567b3",
00000812 => x"00d61613",
00000813 => x"00c7e7b3",
00000814 => x"00959593",
00000815 => x"fa800713",
00000816 => x"00b7e7b3",
00000817 => x"00072023",
00000818 => x"1007e793",
00000819 => x"00f72023",
00000820 => x"00008067",
00000821 => x"fa800713",
00000822 => x"00072683",
00000823 => x"00757513",
00000824 => x"00100793",
00000825 => x"00a797b3",
00000826 => x"fff7c793",
00000827 => x"00d7f7b3",
00000828 => x"00f72023",
00000829 => x"00008067",
00000830 => x"faa02623",
00000831 => x"fa802783",
00000832 => x"fe07cee3",
00000833 => x"fac02503",
00000834 => x"00008067",
00000835 => x"f8400713",
00000836 => x"00072683",
00000837 => x"00100793",
00000838 => x"00a797b3",
00000839 => x"00d7c7b3",
00000840 => x"00f72023",
00000841 => x"00008067",
00000842 => x"f8a02223",
00000843 => x"00008067",
00000844 => x"69617641",
00000845 => x"6c62616c",
00000846 => x"4d432065",
00000847 => x"0a3a7344",
00000848 => x"203a6820",
00000849 => x"706c6548",
00000850 => x"3a72200a",
00000851 => x"73655220",
00000852 => x"74726174",
00000853 => x"3a75200a",
00000854 => x"6c705520",
00000855 => x"0a64616f",
00000856 => x"203a7320",
00000857 => x"726f7453",
00000858 => x"6f742065",
00000859 => x"616c6620",
00000860 => x"200a6873",
00000861 => x"4c203a6c",
00000862 => x"2064616f",
00000863 => x"6d6f7266",
00000864 => x"616c6620",
00000865 => x"200a6873",
00000866 => x"45203a65",
00000867 => x"75636578",
00000868 => x"00006574",
00000869 => x"65206f4e",
00000870 => x"75636578",
00000871 => x"6c626174",
00000872 => x"76612065",
00000873 => x"616c6961",
00000874 => x"2e656c62",
00000875 => x"00000000",
00000876 => x"746f6f42",
00000877 => x"2e676e69",
00000878 => x"0a0a2e2e",
00000879 => x"00000000",
00000880 => x"52450a07",
00000881 => x"5f524f52",
00000882 => x"00000000",
00000883 => x"58450a0a",
00000884 => x"00282043",
00000885 => x"20402029",
00000886 => x"00007830",
00000887 => x"69617741",
00000888 => x"676e6974",
00000889 => x"6f656e20",
00000890 => x"32337672",
00000891 => x"6578655f",
00000892 => x"6e69622e",
00000893 => x"202e2e2e",
00000894 => x"00000000",
00000895 => x"64616f4c",
00000896 => x"2e676e69",
00000897 => x"00202e2e",
00000898 => x"00004b4f",
00000899 => x"0000000a",
00000900 => x"74697257",
00000901 => x"78302065",
00000823 => x"00757793",
00000824 => x"00100513",
00000825 => x"00f51533",
00000826 => x"00d56533",
00000827 => x"00a72023",
00000828 => x"00008067",
00000829 => x"fa800713",
00000830 => x"00072683",
00000831 => x"00757513",
00000832 => x"00100793",
00000833 => x"00a797b3",
00000834 => x"fff7c793",
00000835 => x"00d7f7b3",
00000836 => x"00f72023",
00000837 => x"00008067",
00000838 => x"faa02623",
00000839 => x"fa802783",
00000840 => x"fe07cee3",
00000841 => x"fac02503",
00000842 => x"00008067",
00000843 => x"f8400713",
00000844 => x"00072683",
00000845 => x"00100793",
00000846 => x"00a797b3",
00000847 => x"00d7c7b3",
00000848 => x"00f72023",
00000849 => x"00008067",
00000850 => x"f8a02223",
00000851 => x"00008067",
00000852 => x"69617641",
00000853 => x"6c62616c",
00000854 => x"4d432065",
00000855 => x"0a3a7344",
00000856 => x"203a6820",
00000857 => x"706c6548",
00000858 => x"3a72200a",
00000859 => x"73655220",
00000860 => x"74726174",
00000861 => x"3a75200a",
00000862 => x"6c705520",
00000863 => x"0a64616f",
00000864 => x"203a7320",
00000865 => x"726f7453",
00000866 => x"6f742065",
00000867 => x"616c6620",
00000868 => x"200a6873",
00000869 => x"4c203a6c",
00000870 => x"2064616f",
00000871 => x"6d6f7266",
00000872 => x"616c6620",
00000873 => x"200a6873",
00000874 => x"45203a65",
00000875 => x"75636578",
00000876 => x"00006574",
00000877 => x"65206f4e",
00000878 => x"75636578",
00000879 => x"6c626174",
00000880 => x"76612065",
00000881 => x"616c6961",
00000882 => x"2e656c62",
00000883 => x"00000000",
00000884 => x"746f6f42",
00000885 => x"2e676e69",
00000886 => x"0a0a2e2e",
00000887 => x"00000000",
00000888 => x"52450a07",
00000889 => x"5f524f52",
00000890 => x"00000000",
00000891 => x"58450a0a",
00000892 => x"00282043",
00000893 => x"20402029",
00000894 => x"00007830",
00000895 => x"69617741",
00000896 => x"676e6974",
00000897 => x"6f656e20",
00000898 => x"32337672",
00000899 => x"6578655f",
00000900 => x"6e69622e",
00000901 => x"202e2e2e",
00000902 => x"00000000",
00000903 => x"74796220",
00000904 => x"74207365",
00000905 => x"5053206f",
00000906 => x"6c662049",
00000907 => x"20687361",
00000908 => x"78302040",
00000909 => x"00000000",
00000910 => x"7928203f",
00000911 => x"20296e2f",
00000912 => x"00000000",
00000913 => x"616c460a",
00000914 => x"6e696873",
00000915 => x"2e2e2e67",
00000916 => x"00000020",
00000917 => x"0a0a0a0a",
00000918 => x"4e203c3c",
00000919 => x"56524f45",
00000920 => x"42203233",
00000921 => x"6c746f6f",
00000922 => x"6564616f",
00000923 => x"3e3e2072",
00000924 => x"4c420a0a",
00000925 => x"203a5644",
00000926 => x"20636544",
00000927 => x"32203320",
00000928 => x"0a303230",
00000929 => x"3a565748",
00000930 => x"00002020",
00000931 => x"4b4c430a",
00000932 => x"0020203a",
00000933 => x"0a7a4820",
00000934 => x"52455355",
00000935 => x"0000203a",
00000936 => x"53494d0a",
00000937 => x"00203a41",
00000938 => x"4f52500a",
00000939 => x"00203a43",
00000940 => x"454d490a",
00000941 => x"00203a4d",
00000942 => x"74796220",
00000943 => x"40207365",
00000944 => x"00000020",
00000945 => x"454d440a",
00000946 => x"00203a4d",
00000947 => x"75410a0a",
00000948 => x"6f626f74",
00000949 => x"6920746f",
00000950 => x"7338206e",
00000951 => x"7250202e",
00000952 => x"20737365",
00000953 => x"2079656b",
00000954 => x"61206f74",
00000955 => x"74726f62",
00000956 => x"00000a2e",
00000957 => x"726f6241",
00000958 => x"2e646574",
00000959 => x"00000a0a",
00000960 => x"444d430a",
00000961 => x"00203e3a",
00000962 => x"53207962",
00000963 => x"68706574",
00000964 => x"4e206e61",
00000965 => x"69746c6f",
00000966 => x"0000676e",
00000967 => x"61766e49",
00000968 => x"2064696c",
00000969 => x"00444d43",
00000970 => x"33323130",
00000971 => x"37363534",
00000972 => x"42413938",
00000973 => x"46454443",
00000903 => x"64616f4c",
00000904 => x"2e676e69",
00000905 => x"00202e2e",
00000906 => x"00004b4f",
00000907 => x"0000000a",
00000908 => x"74697257",
00000909 => x"78302065",
00000910 => x"00000000",
00000911 => x"74796220",
00000912 => x"74207365",
00000913 => x"5053206f",
00000914 => x"6c662049",
00000915 => x"20687361",
00000916 => x"78302040",
00000917 => x"00000000",
00000918 => x"7928203f",
00000919 => x"20296e2f",
00000920 => x"00000000",
00000921 => x"616c460a",
00000922 => x"6e696873",
00000923 => x"2e2e2e67",
00000924 => x"00000020",
00000925 => x"0a0a0a0a",
00000926 => x"4e203c3c",
00000927 => x"56524f45",
00000928 => x"42203233",
00000929 => x"6c746f6f",
00000930 => x"6564616f",
00000931 => x"3e3e2072",
00000932 => x"4c420a0a",
00000933 => x"203a5644",
00000934 => x"20636544",
00000935 => x"32203931",
00000936 => x"0a303230",
00000937 => x"3a565748",
00000938 => x"00002020",
00000939 => x"4b4c430a",
00000940 => x"0020203a",
00000941 => x"0a7a4820",
00000942 => x"52455355",
00000943 => x"0000203a",
00000944 => x"53494d0a",
00000945 => x"00203a41",
00000946 => x"4f52500a",
00000947 => x"00203a43",
00000948 => x"454d490a",
00000949 => x"00203a4d",
00000950 => x"74796220",
00000951 => x"40207365",
00000952 => x"00000020",
00000953 => x"454d440a",
00000954 => x"00203a4d",
00000955 => x"75410a0a",
00000956 => x"6f626f74",
00000957 => x"6920746f",
00000958 => x"7338206e",
00000959 => x"7250202e",
00000960 => x"20737365",
00000961 => x"2079656b",
00000962 => x"61206f74",
00000963 => x"74726f62",
00000964 => x"00000a2e",
00000965 => x"726f6241",
00000966 => x"2e646574",
00000967 => x"00000a0a",
00000968 => x"444d430a",
00000969 => x"00203e3a",
00000970 => x"53207962",
00000971 => x"68706574",
00000972 => x"4e206e61",
00000973 => x"69746c6f",
00000974 => x"0000676e",
00000975 => x"61766e49",
00000976 => x"2064696c",
00000977 => x"00444d43",
00000978 => x"33323130",
00000979 => x"37363534",
00000980 => x"42413938",
00000981 => x"46454443",
others => x"00000000"
);
 
/rtl/core/neorv32_cpu.vhd
69,9 → 69,7
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14 -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_USE : boolean := false -- implement PMP?
);
port (
-- global control --
159,23 → 157,30
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true)) report "NEORV32 CPU CONFIG ERROR! User mode requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
-- PMP requires Zicsr extension --
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Physical memory protection (PMP) requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
-- PMP regions --
assert not ((PMP_NUM_REGIONS > pmp_max_r_c) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Number of PMP regions out of valid range." severity error;
-- PMP granulartiy --
assert not (((PMP_GRANULARITY < 1) or (PMP_GRANULARITY > 32)) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Invalid PMP granulartiy (0 < PMP_GRANULARITY < 33)." severity error;
-- RISC-V standard performance counters -
assert not ((CPU_EXTENSION_RISCV_Zicsr = true) and (zicnt_en_c = false)) report "NEORV32 CPU CONFIG WARNING! Standard RISC-V peformance counters ([m]cycle[h], [m]instret[h]) will not be implemented (not RISC-V-compliant!)." severity warning;
 
-- Instruction prefetch buffer size --
assert not (is_power_of_two_f(ipb_entries_c) = false) report "NEORV32 CPU CONFIG ERROR! Number of entries in instruction prefetch buffer <ipb_entries_c> has to be a power of two." severity error;
-- A extension - only lr.w and sc.w supported yet --
assert not (CPU_EXTENSION_RISCV_A = true) report "NEORV32 CPU CONFIG WARNING! Atomic operations extension (A) only supports >lr.w< and >sc.w< instructions yet." severity warning;
 
-- PMP regions check --
assert not ((pmp_num_regions_c > pmp_max_r_c) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! Number of PMP regions <pmp_num_regions_c> out of valid range." severity error;
-- PMP granulartiy --
assert not ((is_power_of_two_f(pmp_min_granularity_c) = false) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! PMP granulartiy has to be a power of two." severity error;
assert not ((pmp_min_granularity_c < 8) and (PMP_USE = true)) report "NEORV32 CPU CONFIG ERROR! PMP granulartiy has to be >= 8 bytes." severity error;
 
-- PMP notifier --
assert not (PMP_USE = true) report "NEORV32 CPU CONFIG NOTE: Implementing physical memory protection (PMP) with " & integer'image(pmp_num_regions_c) & " regions and " & integer'image(pmp_min_granularity_c) & " bytes minimal region size (granulartiy)." severity note;
 
-- Control Unit ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_control_inst: neorv32_cpu_control
generic map (
-- General --
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id
CPU_BOOT_ADDR => CPU_BOOT_ADDR, -- cpu boot address
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id
CPU_BOOT_ADDR => CPU_BOOT_ADDR, -- cpu boot address
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
185,9 → 190,7
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
-- Physical memory protection (PMP) --
PMP_USE => PMP_USE, -- implement physical memory protection?
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (1..4)
PMP_GRANULARITY => PMP_GRANULARITY -- granularity (0=none, 1=8B, 2=16B, 3=32B, ...)
PMP_USE => PMP_USE -- implement physical memory protection?
)
port map (
-- global control --
316,25 → 319,30
neorv32_cpu_cp_muldiv_inst_false:
if (CPU_EXTENSION_RISCV_M = false) generate
cp0_data <= (others => '0');
cp0_valid <= '0';
cp0_valid <= cp0_start; -- to make sure CPU does not get stalled if there is an accidental access
end generate;
 
 
-- Co-Processor 1: Atomic Memory Access (SC - store-conditional) --------------------------
-- -------------------------------------------------------------------------------------------
atomic_op_cp: process(ctrl, cp1_start)
atomic_op_cp: process(cp1_start, ctrl)
begin
-- "fake" co-processor for atomic operations
-- used to get the result of a store-conditional operation into the data path
if (CPU_EXTENSION_RISCV_A = true) and (cp1_start = '1') then
cp1_data <= (others => '0');
cp1_data(0) <= not ctrl(ctrl_bus_lock_c);
cp1_valid <= '1';
if (CPU_EXTENSION_RISCV_A = true) then
if (cp1_start = '1') then
cp1_data <= (others => '0');
cp1_data(0) <= not ctrl(ctrl_bus_lock_c);
cp1_valid <= '1';
else
cp1_data <= (others => '0');
cp1_valid <= '0';
end if;
else
cp1_data <= (others => '0');
cp1_valid <= '0';
cp1_valid <= cp1_start; -- to make sure CPU does not get stalled if there is an accidental access
end if;
end process;
end process atomic_op_cp;
 
 
-- Co-Processor 2: Not implemented (yet) --------------------------------------------------
342,7 → 350,7
-- control: ctrl cp2_start
-- inputs: rs1 rs2 alu_cmp alu_opb
cp2_data <= (others => '0');
cp2_valid <= '0';
cp2_valid <= cp2_start; -- to make sure CPU does not get stalled if there is an accidental access
 
 
-- Co-Processor 3: Not implemented (yet) --------------------------------------------------
350,7 → 358,7
-- control: ctrl cp3_start
-- inputs: rs1 rs2 alu_cmp alu_opb
cp3_data <= (others => '0');
cp3_valid <= '0';
cp3_valid <= cp3_start; -- to make sure CPU does not get stalled if there is an accidental access
 
 
-- Bus Interface Unit ---------------------------------------------------------------------
359,9 → 367,7
generic map (
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
-- Physical memory protection (PMP) --
PMP_USE => PMP_USE, -- implement physical memory protection?
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (1..4)
PMP_GRANULARITY => PMP_GRANULARITY -- granularity (0=none, 1=8B, 2=16B, 3=32B, ...)
PMP_USE => PMP_USE -- implement physical memory protection?
)
port map (
-- global control --
/rtl/core/neorv32_cpu_alu.vhd
306,16 → 306,11
cp_ctrl.cmd_ff <= '0';
cp_ctrl.busy <= '0';
elsif rising_edge(clk_i) then
if (CPU_EXTENSION_RISCV_M = true) then
cp_ctrl.cmd_ff <= cp_ctrl.cmd;
if ((cp0_valid_i or cp1_valid_i or cp2_valid_i or cp3_valid_i) = '1') then -- cp computation done?
cp_ctrl.busy <= '0';
elsif (cp_ctrl.start = '1') then
cp_ctrl.busy <= '1';
end if;
else -- no co-processor(s) implemented
cp_ctrl.cmd_ff <= '0';
cp_ctrl.busy <= '0';
cp_ctrl.cmd_ff <= cp_ctrl.cmd;
if ((cp0_valid_i or cp1_valid_i or cp2_valid_i or cp3_valid_i) = '1') then -- cp computation done?
cp_ctrl.busy <= '0';
elsif (cp_ctrl.start = '1') then
cp_ctrl.busy <= '1';
end if;
end if;
end process cp_arbiter;
/rtl/core/neorv32_cpu_bus.vhd
45,9 → 45,7
generic (
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension?
-- Physical memory protection (PMP) --
PMP_USE : boolean := false; -- implement physical memory protection?
PMP_NUM_REGIONS : natural := 4; -- number of regions (1..4)
PMP_GRANULARITY : natural := 16 -- granularity (1=8B, 2=16B, 3=32B, ...)
PMP_USE : boolean := false -- implement physical memory protection?
);
port (
-- global control --
110,6 → 108,9
--constant pmp_na4_mode_c : std_ulogic_vector(1 downto 0) := "10"; -- naturally aligned four-byte region
constant pmp_napot_mode_c : std_ulogic_vector(1 downto 0) := "11"; -- naturally aligned power-of-two region (>= 8 bytes)
 
-- PMP granularity --
constant pmp_g_c : natural := index_size_f(pmp_min_granularity_c);
 
-- PMP configuration register bits --
constant pmp_cfg_r_c : natural := 0; -- read permit
constant pmp_cfg_w_c : natural := 1; -- write permit
140,18 → 141,17
signal i_arbiter, d_arbiter : bus_arbiter_t;
 
-- physical memory protection --
type pmp_addr34_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c+1 downto 0);
type pmp_addr_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c-1 downto 0);
type pmp_addr_t is array (0 to pmp_num_regions_c-1) of std_ulogic_vector(data_width_c-1 downto 0);
type pmp_t is record
addr_mask : pmp_addr34_t; -- 34-bit physical address
region_base : pmp_addr_t; -- masked region base address for comparator
addr_mask : pmp_addr_t;
region_base : pmp_addr_t; -- region config base address
region_i_addr : pmp_addr_t; -- masked instruction access base address for comparator
region_d_addr : pmp_addr_t; -- masked data access base address for comparator
i_match : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region match for instruction interface
d_match : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region match for data interface
if_fault : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for fetch operation
ld_fault : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for load operation
st_fault : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for store operation
i_match : std_ulogic_vector(pmp_num_regions_c-1 downto 0); -- region match for instruction interface
d_match : std_ulogic_vector(pmp_num_regions_c-1 downto 0); -- region match for data interface
if_fault : std_ulogic_vector(pmp_num_regions_c-1 downto 0); -- region access fault for fetch operation
ld_fault : std_ulogic_vector(pmp_num_regions_c-1 downto 0); -- region access fault for load operation
st_fault : std_ulogic_vector(pmp_num_regions_c-1 downto 0); -- region access fault for store operation
end record;
signal pmp : pmp_t;
 
202,7 → 202,7
begin
if rising_edge(clk_i) then
if (ctrl_i(ctrl_bus_mo_we_c) = '1') then
mdo <= wdata_i; -- memory data out register (MDO)
mdo <= wdata_i; -- memory data output register (MDO)
end if;
end if;
end process mem_do_reg;
243,7 → 243,7
begin
if rising_edge(clk_i) then
if (ctrl_i(ctrl_bus_mi_we_c) = '1') then
mdi <= d_bus_rdata; -- memory data in register (MDI)
mdi <= d_bus_rdata; -- memory data input register (MDI)
end if;
end if;
end process mem_out_buf;
294,8 → 294,9
d_arbiter.timeout <= std_ulogic_vector(to_unsigned(bus_timeout_c, index_size_f(bus_timeout_c)));
else -- in progress
d_arbiter.timeout <= std_ulogic_vector(unsigned(d_arbiter.timeout) - 1);
d_arbiter.err_align <= (d_arbiter.err_align or d_misaligned) and (not ctrl_i(ctrl_bus_derr_ack_c));
d_arbiter.err_bus <= (d_arbiter.err_bus or (not or_all_f(d_arbiter.timeout)) or d_bus_err_i) and (not ctrl_i(ctrl_bus_derr_ack_c));
d_arbiter.err_align <= (d_arbiter.err_align or d_misaligned) and (not ctrl_i(ctrl_bus_derr_ack_c));
d_arbiter.err_bus <= (d_arbiter.err_bus or (not or_all_f(d_arbiter.timeout)) or d_bus_err_i or
(st_pmp_fault and d_arbiter.wr_req) or (ld_pmp_fault and d_arbiter.rd_req)) and (not ctrl_i(ctrl_bus_derr_ack_c));
if (d_bus_ack_i = '1') or (ctrl_i(ctrl_bus_derr_ack_c) = '1') then -- wait for normal termination / CPU abort
d_arbiter.wr_req <= '0';
d_arbiter.rd_req <= '0';
345,8 → 346,8
i_arbiter.timeout <= std_ulogic_vector(to_unsigned(bus_timeout_c, index_size_f(bus_timeout_c)));
else -- in progress
i_arbiter.timeout <= std_ulogic_vector(unsigned(i_arbiter.timeout) - 1);
i_arbiter.err_align <= (i_arbiter.err_align or i_misaligned) and (not ctrl_i(ctrl_bus_ierr_ack_c));
i_arbiter.err_bus <= (i_arbiter.err_bus or (not or_all_f(i_arbiter.timeout)) or i_bus_err_i) and (not ctrl_i(ctrl_bus_ierr_ack_c));
i_arbiter.err_align <= (i_arbiter.err_align or i_misaligned) and (not ctrl_i(ctrl_bus_ierr_ack_c));
i_arbiter.err_bus <= (i_arbiter.err_bus or (not or_all_f(i_arbiter.timeout)) or i_bus_err_i or if_pmp_fault) and (not ctrl_i(ctrl_bus_ierr_ack_c));
if (i_bus_ack_i = '1') or (ctrl_i(ctrl_bus_ierr_ack_c) = '1') then -- wait for normal termination / CPU abort
i_arbiter.rd_req <= '0';
end if;
368,7 → 369,7
 
-- instruction bus (read-only) --
i_bus_addr_o <= fetch_pc_i(data_width_c-1 downto 2) & "00"; -- instruction access is always 4-byte aligned (even for compressed instructions)
i_bus_wdata_o <= (others => '0');
i_bus_wdata_o <= (others => '0'); -- instruction fetch is read-only
i_bus_ben_o <= (others => '0');
i_bus_we_o <= '0';
i_bus_re_o <= ctrl_i(ctrl_bus_if_c) and (not i_misaligned) and (not if_pmp_fault); -- no actual read when misaligned or PMP fault
384,18 → 385,14
 
-- Physical Memory Protection (PMP) -------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- compute address masks --
-- compute address masks (ITERATIVE!!!) --
pmp_masks: process(clk_i)
begin
if rising_edge(clk_i) then -- address configuration (not the actual address check!) has a latency of +1 cycles
for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
pmp.addr_mask(r) <= (others => '0'); -- default
for i in PMP_GRANULARITY+1 to 33 loop
if (i = PMP_GRANULARITY+1) then
pmp.addr_mask(r)(i) <= '0';
else -- current bit = not AND(all previous bits)
pmp.addr_mask(r)(i) <= not and_all_f(pmp_addr_i(r)(i-1 downto PMP_GRANULARITY));
end if;
if rising_edge(clk_i) then -- address mask computation (not the actual address check!) has a latency of max +32 cycles
for r in 0 to pmp_num_regions_c-1 loop -- iterate over all regions
pmp.addr_mask(r) <= (others => '0');
for i in pmp_g_c to data_width_c-1 loop
pmp.addr_mask(r)(i) <= pmp.addr_mask(r)(i-1) or (not pmp_addr_i(r)(i-1));
end loop; -- i
end loop; -- r
end if;
402,38 → 399,22
end process pmp_masks;
 
 
-- compute operands for comparator --
pmp_prepare_check:
for r in 0 to PMP_NUM_REGIONS-1 generate -- iterate over all regions
-- ignore lowest 3 bits of access addresses -> minimal region size = 8 bytes
pmp.region_i_addr(r) <= (fetch_pc_i(31 downto 3) & "000") and pmp.addr_mask(r)(33 downto 2);
pmp.region_d_addr(r) <= (mar(31 downto 3) & "000") and pmp.addr_mask(r)(33 downto 2);
pmp.region_base(r) <= pmp_addr_i(r)(33 downto 2) and pmp.addr_mask(r)(33 downto 2);
-- address access check --
pmp_address_check:
for r in 0 to pmp_num_regions_c-1 generate -- iterate over all regions
pmp.region_i_addr(r) <= fetch_pc_i and pmp.addr_mask(r);
pmp.region_d_addr(r) <= mar and pmp.addr_mask(r);
pmp.region_base(r) <= pmp_addr_i(r)(data_width_c+1 downto 2) and pmp.addr_mask(r);
--
pmp.i_match(r) <= '1' when (pmp.region_i_addr(r)(data_width_c-1 downto pmp_g_c) = pmp.region_base(r)(data_width_c-1 downto pmp_g_c)) else '0';
pmp.d_match(r) <= '1' when (pmp.region_d_addr(r)(data_width_c-1 downto pmp_g_c) = pmp.region_base(r)(data_width_c-1 downto pmp_g_c)) else '0';
end generate; -- r
 
 
-- check for access address match --
pmp_addr_check: process (pmp)
begin
for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
-- instruction interface --
pmp.i_match(r) <= '0';
if (pmp.region_i_addr(r)(31 downto PMP_GRANULARITY+2) = pmp.region_base(r)(31 downto PMP_GRANULARITY+2)) then
pmp.i_match(r) <= '1';
end if;
-- data interface --
pmp.d_match(r) <= '0';
if (pmp.region_d_addr(r)(31 downto PMP_GRANULARITY+2) = pmp.region_base(r)(31 downto PMP_GRANULARITY+2)) then
pmp.d_match(r) <= '1';
end if;
end loop; -- r
end process pmp_addr_check;
 
 
-- check access type and regions's permissions --
pmp_check_permission: process(pmp, pmp_ctrl_i, ctrl_i)
begin
for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
for r in 0 to pmp_num_regions_c-1 loop -- iterate over all regions
if ((ctrl_i(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c) = priv_mode_u_c) or (pmp_ctrl_i(r)(pmp_cfg_l_c) = '1')) and -- user privilege level or locked pmp entry -> enforce permissions also for machine mode
(pmp_ctrl_i(r)(pmp_cfg_ah_c downto pmp_cfg_al_c) /= pmp_off_mode_c) then -- active entry
pmp.if_fault(r) <= pmp.i_match(r) and (not pmp_ctrl_i(r)(pmp_cfg_x_c)); -- fetch access match no execute permission
/rtl/core/neorv32_cpu_control.vhd
58,9 → 58,7
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Physical memory protection (PMP) --
PMP_USE : boolean := false; -- implement physical memory protection?
PMP_NUM_REGIONS : natural := 4; -- number of regions (1..4)
PMP_GRANULARITY : natural := 0 -- granularity (0=none, 1=8B, 2=16B, 3=32B, ...)
PMP_USE : boolean := false -- implement physical memory protection?
);
port (
-- global control --
167,7 → 165,6
type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP, EXECUTE, ALU_WAIT, BRANCH, FENCE_OP, LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYS_ENV, CSR_ACCESS);
type execute_engine_t is record
state : execute_engine_state_t;
state_prev : execute_engine_state_t;
state_nxt : execute_engine_state_t;
--
i_reg : std_ulogic_vector(31 downto 0);
176,8 → 173,6
--
is_ci : std_ulogic; -- current instruction is de-compressed instruction
is_ci_nxt : std_ulogic;
is_jump : std_ulogic; -- current instruction is jump instruction
is_jump_nxt : std_ulogic;
is_cp_op : std_ulogic; -- current instruction is a co-processor operation
is_cp_op_nxt : std_ulogic;
--
204,7 → 199,7
exc_ack : std_ulogic; -- acknowledge all exceptions
irq_ack : std_ulogic_vector(interrupt_width_c-1 downto 0); -- acknowledge specific interrupt
irq_ack_nxt : std_ulogic_vector(interrupt_width_c-1 downto 0);
cause : std_ulogic_vector(5 downto 0); -- trap ID (for "mcause"), only for hw
cause : std_ulogic_vector(5 downto 0); -- trap ID for mcause CSR
cause_nxt : std_ulogic_vector(5 downto 0);
--
env_start : std_ulogic; -- start trap handler env
229,15 → 224,15
end record;
signal atomic_ctrl : atomic_ctrl_t;
-- CPU control signals --
-- CPU main control bus --
signal ctrl_nxt, ctrl : std_ulogic_vector(ctrl_width_c-1 downto 0);
 
-- fast bus access --
-- fast instruction fetch access --
signal bus_fast_ir : std_ulogic;
 
-- RISC-V control and status registers (CSRs) --
type pmp_ctrl_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(7 downto 0);
type pmp_addr_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c-1 downto 0);
type pmp_ctrl_t is array (0 to pmp_max_r_c-1) of std_ulogic_vector(7 downto 0);
type pmp_addr_t is array (0 to pmp_max_r_c-1) of std_ulogic_vector(data_width_c-1 downto 0);
type csr_t is record
we : std_ulogic; -- csr write enable
we_nxt : std_ulogic;
247,25 → 242,30
rdata : std_ulogic_vector(data_width_c-1 downto 0); -- csr read data
--
mstatus_mie : std_ulogic; -- mstatus.MIE: global IRQ enable (R/W)
mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/-)
mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/W)
mstatus_mpp : std_ulogic_vector(1 downto 0); -- mstatus.MPP: machine previous privilege mode
--
mie_msie : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W)
mie_meie : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W)
mie_mtie : std_ulogic; -- mie.MEIE: machine timer interrupt enable (R/W
mie_mtie : std_ulogic; -- mie.MEIE: machine timer interrupt enable (R/W)
mie_firqe : std_ulogic_vector(3 downto 0); -- mie.firq*e: fast interrupt enabled (R/W)
--
privilege : std_ulogic_vector(1 downto 0); -- hart's current previous privilege mode
mip_status : std_ulogic_vector(interrupt_width_c-1 downto 0); -- current buffered IRQs
mip_clear : std_ulogic_vector(interrupt_width_c-1 downto 0); -- set bits clear the according buffered IRQ
--
privilege : std_ulogic_vector(1 downto 0); -- hart's current privilege mode
priv_m_mode : std_ulogic; -- CPU in M-mode
priv_u_mode : std_ulogic; -- CPU in u-mode
--
mepc : std_ulogic_vector(data_width_c-1 downto 0); -- mepc: machine exception pc (R/W)
mcause : std_ulogic_vector(data_width_c-1 downto 0); -- mcause: machine trap cause (R/-)
mcause : std_ulogic_vector(data_width_c-1 downto 0); -- mcause: machine trap cause (R/W)
mtvec : std_ulogic_vector(data_width_c-1 downto 0); -- mtvec: machine trap-handler base address (R/W), bit 1:0 == 00
mtval : std_ulogic_vector(data_width_c-1 downto 0); -- mtval: machine bad address or isntruction (R/W)
mscratch : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W)
mcycle : std_ulogic_vector(32 downto 0); -- mcycle (R/W), plus carry bit
minstret : std_ulogic_vector(32 downto 0); -- minstret (R/W), plus carry bit
mcycleh : std_ulogic_vector(31 downto 0); -- mcycleh (R/W) - REDUCED BIT-WIDTH!
minstreth : std_ulogic_vector(31 downto 0); -- minstreth (R/W) - REDUCED BIT-WIDTH!
mcycleh : std_ulogic_vector(31 downto 0); -- mcycleh (R/W)
minstreth : std_ulogic_vector(31 downto 0); -- minstreth (R/W)
pmpcfg : pmp_ctrl_t; -- physical memory protection - configuration registers
pmpaddr : pmp_addr_t; -- physical memory protection - address registers
end record;
390,7 → 390,7
ipb.rdata <= ipb.data(to_integer(unsigned(ipb.r_pnt(ipb.r_pnt'left-1 downto 0))));
 
-- status --
ipb.match <= '1' when (ipb.r_pnt(ipb.r_pnt'left-1 downto 0) = ipb.w_pnt(ipb.w_pnt'left-1 downto 0)) else '0';
ipb.match <= '1' when (ipb.r_pnt(ipb.r_pnt'left-1 downto 0) = ipb.w_pnt(ipb.w_pnt'left-1 downto 0)) else '0';
ipb.full <= '1' when (ipb.r_pnt(ipb.r_pnt'left) /= ipb.w_pnt(ipb.w_pnt'left)) and (ipb.match = '1') else '0';
ipb.empty <= '1' when (ipb.r_pnt(ipb.r_pnt'left) = ipb.w_pnt(ipb.w_pnt'left)) and (ipb.match = '1') else '0';
ipb.free <= not ipb.full;
408,7 → 408,7
begin
if (rstn_i = '0') then
issue_engine.state <= ISSUE_ACTIVE;
issue_engine.align <= CPU_BOOT_ADDR(1);
issue_engine.align <= CPU_BOOT_ADDR(1); -- 32- or 16-bit boundary
issue_engine.buf <= (others => '0');
elsif rising_edge(clk_i) then
if (ipb.clear = '1') then
539,9 → 539,9
begin
opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11";
if rising_edge(clk_i) then
if (execute_engine.state = BRANCH) then -- next_PC as immediate fro jump-and-link operations (=return address)
if (execute_engine.state = BRANCH) then -- next_PC as immediate for jump-and-link operations (=return address)
imm_o <= execute_engine.next_pc;
else -- "nromal" immediate from instruction
else -- "normal" immediate from instruction
case opcode_v is -- save some bits here, LSBs are always 11 for rv32
when opcode_store_c => -- S-immediate
imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
566,7 → 566,7
imm_o(04 downto 01) <= execute_engine.i_reg(24 downto 21);
imm_o(00) <= '0';
when opcode_atomic_c => -- atomic memory access
imm_o <= (others => '0'); -- effective address is reg + 0
imm_o <= (others => '0'); -- effective address is addr = reg + 0 = reg
when others => -- I-immediate
imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
603,10 → 603,10
execute_engine_fsm_sync_rst: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
execute_engine.pc <= CPU_BOOT_ADDR(data_width_c-1 downto 1) & '0';
execute_engine.state <= SYS_WAIT;
execute_engine.sleep <= '0';
execute_engine.if_rst <= '1'; -- instruction fetch is reset after system reset
execute_engine.pc <= CPU_BOOT_ADDR(data_width_c-1 downto 1) & '0';
execute_engine.state <= SYS_WAIT;
execute_engine.sleep <= '0';
execute_engine.if_rst <= '1'; -- instruction fetch is reset after system reset
elsif rising_edge(clk_i) then
-- PC update --
if (execute_engine.pc_we = '1') then
613,14 → 613,14
case execute_engine.pc_mux_sel is
when "00" => execute_engine.pc <= execute_engine.next_pc(data_width_c-1 downto 1) & '0'; -- normal (linear) increment
when "01" => execute_engine.pc <= alu_add_i(data_width_c-1 downto 1) & '0'; -- jump/branch
when "10" => execute_engine.pc <= csr.mtvec(data_width_c-1 downto 1) & '0'; -- trap
when "10" => execute_engine.pc <= csr.mtvec(data_width_c-1 downto 1) & '0'; -- trap enter
when others => execute_engine.pc <= csr.mepc(data_width_c-1 downto 1) & '0'; -- trap return
end case;
end if;
--
execute_engine.state <= execute_engine.state_nxt;
execute_engine.sleep <= execute_engine.sleep_nxt;
execute_engine.if_rst <= execute_engine.if_rst_nxt;
execute_engine.state <= execute_engine.state_nxt;
execute_engine.sleep <= execute_engine.sleep_nxt;
execute_engine.if_rst <= execute_engine.if_rst_nxt;
end if;
end process execute_engine_fsm_sync_rst;
 
629,20 → 629,20
execute_engine_fsm_sync: process(clk_i)
begin
if rising_edge(clk_i) then
execute_engine.state_prev <= execute_engine.state;
execute_engine.i_reg <= execute_engine.i_reg_nxt;
execute_engine.is_ci <= execute_engine.is_ci_nxt;
execute_engine.is_jump <= execute_engine.is_jump_nxt;
execute_engine.is_cp_op <= execute_engine.is_cp_op_nxt;
execute_engine.i_reg <= execute_engine.i_reg_nxt;
execute_engine.is_ci <= execute_engine.is_ci_nxt;
execute_engine.is_cp_op <= execute_engine.is_cp_op_nxt;
-- next PC (next linear instruction) --
if (execute_engine.is_ci = '1') then -- compressed instruction?
execute_engine.next_pc <= std_ulogic_vector(unsigned(execute_engine.pc) + 2);
else
execute_engine.next_pc <= std_ulogic_vector(unsigned(execute_engine.pc) + 4);
if (execute_engine.state = EXECUTE) then
if (execute_engine.is_ci = '1') then -- compressed instruction?
execute_engine.next_pc <= std_ulogic_vector(unsigned(execute_engine.pc) + 2);
else
execute_engine.next_pc <= std_ulogic_vector(unsigned(execute_engine.pc) + 4);
end if;
end if;
-- PC & IR of last "executed" instruction --
if (execute_engine.state = EXECUTE) then
execute_engine.last_pc <= execute_engine.pc;
execute_engine.last_pc <= execute_engine.pc;
execute_engine.i_reg_last <= execute_engine.i_reg;
end if;
-- main control bus --
656,7 → 656,7
 
-- CPU Control Bus Output -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
ctrl_output: process(ctrl, fetch_engine, trap_ctrl, atomic_ctrl, bus_fast_ir, execute_engine, csr.privilege)
ctrl_output: process(ctrl, fetch_engine, trap_ctrl, atomic_ctrl, bus_fast_ir, execute_engine, csr)
begin
-- signals from execute engine --
ctrl_o <= ctrl;
663,9 → 663,9
-- current privilege level --
ctrl_o(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c) <= csr.privilege;
-- register addresses --
ctrl_o(ctrl_rf_rs1_adr4_c downto ctrl_rf_rs1_adr0_c) <= execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c);
ctrl_o(ctrl_rf_rs2_adr4_c downto ctrl_rf_rs2_adr0_c) <= execute_engine.i_reg(instr_rs2_msb_c downto instr_rs2_lsb_c);
ctrl_o(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c) <= execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c);
ctrl_o(ctrl_rf_rs1_adr4_c downto ctrl_rf_rs1_adr0_c) <= execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c);
ctrl_o(ctrl_rf_rs2_adr4_c downto ctrl_rf_rs2_adr0_c) <= execute_engine.i_reg(instr_rs2_msb_c downto instr_rs2_lsb_c);
ctrl_o(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c) <= execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c);
-- fast bus access requests --
ctrl_o(ctrl_bus_if_c) <= bus_fast_ir;
-- bus error control --
692,7 → 692,6
-- arbiter defaults --
execute_engine.state_nxt <= execute_engine.state;
execute_engine.i_reg_nxt <= execute_engine.i_reg;
execute_engine.is_jump_nxt <= '0';
execute_engine.is_cp_op_nxt <= execute_engine.is_cp_op;
execute_engine.is_ci_nxt <= execute_engine.is_ci;
execute_engine.sleep_nxt <= execute_engine.sleep;
731,19 → 730,16
else -- branches
ctrl_nxt(ctrl_alu_unsigned_c) <= execute_engine.i_reg(instr_funct3_lsb_c+1); -- unsigned branches? (BLTU, BGEU)
end if;
-- memor access --
-- memory access --
ctrl_nxt(ctrl_bus_unsigned_c) <= execute_engine.i_reg(instr_funct3_msb_c); -- unsigned LOAD (LBU, LHU)
ctrl_nxt(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) <= execute_engine.i_reg(instr_funct3_lsb_c+1 downto instr_funct3_lsb_c); -- mem transfer size
-- alu.shifter --
ctrl_nxt(ctrl_alu_shift_dir_c) <= execute_engine.i_reg(instr_funct3_msb_c); -- shift direction (left/right)
ctrl_nxt(ctrl_alu_shift_ar_c) <= execute_engine.i_reg(30); -- is arithmetic shift
-- ALU control --
ctrl_nxt(ctrl_alu_addsub_c) <= '0'; -- ADD(I)
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_arith_c; -- default ALU function select: arithmetic
ctrl_nxt(ctrl_alu_arith_c) <= alu_arith_cmd_addsub_c; -- default ALU arithmetic operation: ADDSUB
ctrl_nxt(ctrl_alu_logic1_c downto ctrl_alu_logic0_c) <= alu_logic_cmd_movb_c; -- default ALU logic operation: MOVB
-- co-processor id --
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- default CP = MULDIV
-- ALU main control --
ctrl_nxt(ctrl_alu_addsub_c) <= '0'; -- ADD(I)
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_arith_c; -- default ALU function select: arithmetic
ctrl_nxt(ctrl_alu_arith_c) <= alu_arith_cmd_addsub_c; -- default ALU arithmetic operation: ADDSUB
 
-- is immediate ALU operation? --
alu_immediate_v := not execute_engine.i_reg(instr_opcode_msb_c-1);
778,19 → 774,19
when DISPATCH => -- Get new command from instruction issue engine
-- ------------------------------------------------------------
execute_engine.pc_mux_sel <= "00"; -- linear next PC
-- IR update --
execute_engine.is_ci_nxt <= cmd_issue.data(32); -- flag to indicate a de-compressed instruction beeing executed
execute_engine.i_reg_nxt <= cmd_issue.data(31 downto 0);
--
if (cmd_issue.valid = '1') then -- instruction available?
-- IR update --
execute_engine.is_ci_nxt <= cmd_issue.data(32); -- flag to indicate this is a de-compressed instruction beeing executed
execute_engine.i_reg_nxt <= cmd_issue.data(31 downto 0);
trap_ctrl.instr_ma <= cmd_issue.data(33); -- misaligned instruction fetch address
trap_ctrl.instr_be <= cmd_issue.data(34); -- bus access fault during instrucion fetch
illegal_compressed <= cmd_issue.data(35); -- invalid decompressed instruction
-- IR update - exceptions --
trap_ctrl.instr_ma <= cmd_issue.data(33); -- misaligned instruction fetch address
trap_ctrl.instr_be <= cmd_issue.data(34); -- bus access fault during instruction fetch
illegal_compressed <= cmd_issue.data(35); -- invalid decompressed instruction
-- PC update --
execute_engine.if_rst_nxt <= '0';
if (execute_engine.if_rst = '0') then -- if there was NO non-linear PC modification
execute_engine.pc_we <= '1';
end if;
-- any reason to go to trap state FAST? --
execute_engine.pc_we <= not execute_engine.if_rst; -- update PC with linear next_pc if there was NO non-linear PC modification
-- any reason to go to trap state? --
if (execute_engine.sleep = '1') or (trap_ctrl.env_start = '1') or (trap_ctrl.exc_fire = '1') or ((cmd_issue.data(33) or cmd_issue.data(34)) = '1') then
execute_engine.state_nxt <= TRAP;
else
802,10 → 798,9
when TRAP => -- Start trap environment (also used as cpu sleep state)
-- ------------------------------------------------------------
execute_engine.pc_mux_sel <= "10"; -- csr.mtvec (trap)
-- stay here for sleep
fetch_engine.reset <= '1';
execute_engine.if_rst_nxt <= '1'; -- this will be a non-linear PC modification
if (trap_ctrl.env_start = '1') then -- trap triggered?
fetch_engine.reset <= '1';
execute_engine.if_rst_nxt <= '1'; -- this is a non-linear PC modification
trap_ctrl.env_start_ack <= '1';
execute_engine.pc_we <= '1';
execute_engine.sleep_nxt <= '0'; -- waky waky
813,7 → 808,7
end if;
 
 
when EXECUTE => -- Decode and execute instruction
when EXECUTE => -- Decode and execute instruction (control has to be here for excatly 1 cyle in any case!)
-- ------------------------------------------------------------
opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11"; -- save some bits here, LSBs are always 11 for rv32
case opcode_v is
845,11 → 840,11
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is -- actual ALU.logic operation (re-coding)
when funct3_xor_c => ctrl_nxt(ctrl_alu_logic1_c downto ctrl_alu_logic0_c) <= alu_logic_cmd_xor_c; -- XOR(I)
when funct3_or_c => ctrl_nxt(ctrl_alu_logic1_c downto ctrl_alu_logic0_c) <= alu_logic_cmd_or_c; -- OR(I)
when funct3_and_c => ctrl_nxt(ctrl_alu_logic1_c downto ctrl_alu_logic0_c) <= alu_logic_cmd_and_c; -- AND(I)
when others => ctrl_nxt(ctrl_alu_logic1_c downto ctrl_alu_logic0_c) <= alu_logic_cmd_movb_c; -- undefined
when others => ctrl_nxt(ctrl_alu_logic1_c downto ctrl_alu_logic0_c) <= alu_logic_cmd_and_c; -- AND(I)
end case;
 
-- cp access? --
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- just in case a mul/div operation
if (CPU_EXTENSION_RISCV_M = true) and (execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and (execute_engine.i_reg(instr_funct7_lsb_c) = '1') then -- MULDIV CP op?
execute_engine.is_cp_op_nxt <= '1'; -- this is a CP operation
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
918,8 → 913,7
end if;
ctrl_nxt(ctrl_alu_opb_mux_c) <= '1'; -- use IMM as ALU.OPB (branch target address offset)
--
execute_engine.is_jump_nxt <= execute_engine.i_reg(instr_opcode_lsb_c+2); -- is this is a jump operation? (for JAL/JALR)
execute_engine.state_nxt <= BRANCH;
execute_engine.state_nxt <= BRANCH;
 
when opcode_fence_c => -- fence operations
-- ------------------------------------------------------------
927,7 → 921,7
 
when opcode_syscsr_c => -- system/csr access
-- ------------------------------------------------------------
csr.re_nxt <= '1'; -- always read CSR (internally), only relevant for CSR-instructions
csr.re_nxt <= csr_acc_valid; -- always read CSR if valid access, only relevant for CSR-instructions
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system/environment
execute_engine.state_nxt <= SYS_ENV;
else -- CSR access
943,7 → 937,7
 
when SYS_ENV => -- system environment operation - execution
-- ------------------------------------------------------------
execute_engine.pc_mux_sel <= "11"; -- csr.mepc (only for MRET)
execute_engine.pc_mux_sel <= "11"; -- csr.mepc (only relevant for MRET)
case execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is
when funct12_ecall_c => -- ECALL
trap_ctrl.env_call <= '1';
951,7 → 945,7
trap_ctrl.break_point <= '1';
when funct12_mret_c => -- MRET
trap_ctrl.env_end <= '1';
execute_engine.pc_we <= '1'; -- linear next PC
execute_engine.pc_we <= '1'; -- update PC from MEPC
fetch_engine.reset <= '1';
execute_engine.if_rst_nxt <= '1'; -- this is a non-linear PC modification
when funct12_wfi_c => -- WFI
1002,10 → 996,10
ctrl_nxt(ctrl_alu_logic1_c downto ctrl_alu_logic0_c) <= alu_logic_cmd_movb_c; -- MOVB
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_logic_c; -- actual ALU operation = MOVB
ctrl_nxt(ctrl_rf_in_mux_msb_c) <= '0'; -- RF input = ALU result
ctrl_nxt(ctrl_rf_wb_en_c) <= execute_engine.is_jump; -- valid RF write-back? (is jump-and-link?)
ctrl_nxt(ctrl_rf_wb_en_c) <= execute_engine.i_reg(instr_opcode_lsb_c+2); -- valid RF write-back? (is jump-and-link?)
-- destination address --
execute_engine.pc_mux_sel <= "01"; -- alu.add = branch/jump destination
if (execute_engine.is_jump = '1') or (execute_engine.branch_taken = '1') then
if (execute_engine.i_reg(instr_opcode_lsb_c+2) = '1') or (execute_engine.branch_taken = '1') then -- JAL/JALR or taken branch
execute_engine.pc_we <= '1'; -- update PC
fetch_engine.reset <= '1'; -- trigger new instruction fetch from modified PC
execute_engine.if_rst_nxt <= '1'; -- this is a non-linear PC modification
1018,7 → 1012,7
when FENCE_OP => -- fence operations - execution
-- ------------------------------------------------------------
execute_engine.state_nxt <= SYS_WAIT;
execute_engine.pc_mux_sel <= "00"; -- linear next PC = "refetch" next instruction
execute_engine.pc_mux_sel <= "00"; -- linear next PC = "refetch" next instruction (only relevant for fence.i)
-- FENCE.I --
if (execute_engine.i_reg(instr_funct3_lsb_c) = funct3_fencei_c(0)) and (CPU_EXTENSION_RISCV_Zifencei = true) then
execute_engine.pc_we <= '1';
1050,16 → 1044,17
 
when LOADSTORE_2 => -- wait for bus transaction to finish
-- ------------------------------------------------------------
if (CPU_EXTENSION_RISCV_A = true) then -- only relevant for atomic operations
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_atomic_c; -- SC: result comes from "atomic co-processor"
-- ALU control (only relevant for atomic memory operations) --
if (CPU_EXTENSION_RISCV_A = true) then
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_atomic_c; -- atomic.SC: result comes from "atomic co-processor"
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
end if;
--
-- register file write-back --
ctrl_nxt(ctrl_rf_in_mux_lsb_c) <= '0'; -- RF input = ALU.res or MEM
if (is_atomic_sc_v = '1') then
ctrl_nxt(ctrl_rf_in_mux_msb_c) <= '0'; -- RF input = ALU.res
ctrl_nxt(ctrl_rf_in_mux_msb_c) <= '0'; -- RF input = ALU.res (only relevant for atomic.SC)
else
ctrl_nxt(ctrl_rf_in_mux_msb_c) <= '1'; -- RF input = memory input (only relevant for LOAD)
ctrl_nxt(ctrl_rf_in_mux_msb_c) <= '1'; -- RF input = memory input (only relevant for LOADs)
end if;
--
ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for load operations)
1092,18 → 1087,10
 
-- Illegal CSR Access Check ---------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
invalid_csr_access_check: process(execute_engine.i_reg, csr.privilege)
variable is_m_mode_v : std_ulogic;
variable csr_wacc_v : std_ulogic; -- to check access to read-only CSRs
-- variable csr_racc_v : std_ulogic; -- to check access to write-only CSRs
invalid_csr_access_check: process(execute_engine.i_reg, csr)
variable csr_wacc_v : std_ulogic; -- to check access to read-only CSRs
-- variable csr_racc_v : std_ulogic; -- to check access to write-only CSRs
begin
-- are we in machine mode? --
if (csr.privilege = priv_mode_m_c) then
is_m_mode_v := '1';
else
is_m_mode_v := '0';
end if;
 
-- is this CSR instruction really going to write/read to/from a CSR? --
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) then
1116,48 → 1103,49
 
-- check CSR access --
case execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) is
when csr_mstatus_c => csr_acc_valid <= is_m_mode_v; -- M-mode only
when csr_misa_c => csr_acc_valid <= is_m_mode_v;-- and (not csr_wacc_v); -- M-mode only, MISA is read-only in the NEORV32 but we don't cause an exception here for compatibility
when csr_mie_c => csr_acc_valid <= is_m_mode_v; -- M-mode only
when csr_mtvec_c => csr_acc_valid <= is_m_mode_v; -- M-mode only
when csr_mscratch_c => csr_acc_valid <= is_m_mode_v; -- M-mode only
when csr_mepc_c => csr_acc_valid <= is_m_mode_v; -- M-mode only
when csr_mcause_c => csr_acc_valid <= is_m_mode_v; -- M-mode only
when csr_mtval_c => csr_acc_valid <= is_m_mode_v; -- M-mode only
when csr_mip_c => csr_acc_valid <= is_m_mode_v; -- M-mode only
when csr_mstatus_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mstatush_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_misa_c => csr_acc_valid <= csr.priv_m_mode;-- and (not csr_wacc_v); -- M-mode only, MISA is read-only in the NEORV32 but we don't cause an exception here for compatibility
when csr_mie_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mtvec_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mscratch_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mepc_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mcause_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mtval_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mip_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
--
when csr_pmpcfg0_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 1)) and is_m_mode_v; -- M-mode only
when csr_pmpcfg1_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 5)) and is_m_mode_v; -- M-mode only
when csr_pmpcfg0_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 1)) and csr.priv_m_mode; -- M-mode only
when csr_pmpcfg1_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 5)) and csr.priv_m_mode; -- M-mode only
--
when csr_pmpaddr0_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 1)) and is_m_mode_v; -- M-mode only
when csr_pmpaddr1_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 2)) and is_m_mode_v; -- M-mode only
when csr_pmpaddr2_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 3)) and is_m_mode_v; -- M-mode only
when csr_pmpaddr3_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 4)) and is_m_mode_v; -- M-mode only
when csr_pmpaddr4_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 5)) and is_m_mode_v; -- M-mode only
when csr_pmpaddr5_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 6)) and is_m_mode_v; -- M-mode only
when csr_pmpaddr6_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 7)) and is_m_mode_v; -- M-mode only
when csr_pmpaddr7_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS >= 8)) and is_m_mode_v; -- M-mode only
when csr_pmpaddr0_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 1)) and csr.priv_m_mode; -- M-mode only
when csr_pmpaddr1_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 2)) and csr.priv_m_mode; -- M-mode only
when csr_pmpaddr2_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 3)) and csr.priv_m_mode; -- M-mode only
when csr_pmpaddr3_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 4)) and csr.priv_m_mode; -- M-mode only
when csr_pmpaddr4_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 5)) and csr.priv_m_mode; -- M-mode only
when csr_pmpaddr5_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 6)) and csr.priv_m_mode; -- M-mode only
when csr_pmpaddr6_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 7)) and csr.priv_m_mode; -- M-mode only
when csr_pmpaddr7_c => csr_acc_valid <= bool_to_ulogic_f(PMP_USE) and bool_to_ulogic_f(boolean(pmp_num_regions_c >= 8)) and csr.priv_m_mode; -- M-mode only
--
when csr_mcycle_c => csr_acc_valid <= is_m_mode_v; -- M-mode only
when csr_minstret_c => csr_acc_valid <= is_m_mode_v; -- M-mode only
when csr_mcycle_c => csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(zicnt_en_c); -- M-mode only and "Zicnt" = true
when csr_minstret_c => csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(zicnt_en_c); -- M-mode only and "Zicnt" = true
--
when csr_mcycleh_c => csr_acc_valid <= is_m_mode_v; -- M-mode only
when csr_minstreth_c => csr_acc_valid <= is_m_mode_v; -- M-mode only
when csr_mcycleh_c => csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(zicnt_en_c); -- M-mode only and "Zicnt" = true
when csr_minstreth_c => csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(zicnt_en_c); -- M-mode only and "Zicnt" = true
--
when csr_cycle_c => csr_acc_valid <= (not csr_wacc_v); -- all modes, read-only
when csr_cycle_c => csr_acc_valid <= (not csr_wacc_v) and bool_to_ulogic_f(zicnt_en_c); -- all modes, read-only and "Zicnt" = true
when csr_time_c => csr_acc_valid <= (not csr_wacc_v); -- all modes, read-only
when csr_instret_c => csr_acc_valid <= (not csr_wacc_v); -- all modes, read-only
when csr_instret_c => csr_acc_valid <= (not csr_wacc_v) and bool_to_ulogic_f(zicnt_en_c); -- all modes, read-only and "Zicnt" = true
--
when csr_cycleh_c => csr_acc_valid <= (not csr_wacc_v); -- all modes, read-only
when csr_cycleh_c => csr_acc_valid <= (not csr_wacc_v) and bool_to_ulogic_f(zicnt_en_c); -- all modes, read-only and "Zicnt" = true
when csr_timeh_c => csr_acc_valid <= (not csr_wacc_v); -- all modes, read-only
when csr_instreth_c => csr_acc_valid <= (not csr_wacc_v); -- all modes, read-only
when csr_instreth_c => csr_acc_valid <= (not csr_wacc_v) and bool_to_ulogic_f(zicnt_en_c); -- all modes, read-only and "Zicnt" = true
--
when csr_mvendorid_c => csr_acc_valid <= is_m_mode_v and (not csr_wacc_v); -- M-mode only, read-only
when csr_marchid_c => csr_acc_valid <= is_m_mode_v and (not csr_wacc_v); -- M-mode only, read-only
when csr_mimpid_c => csr_acc_valid <= is_m_mode_v and (not csr_wacc_v); -- M-mode only, read-only
when csr_mhartid_c => csr_acc_valid <= is_m_mode_v and (not csr_wacc_v); -- M-mode only, read-only
when csr_mvendorid_c => csr_acc_valid <= csr.priv_m_mode and (not csr_wacc_v); -- M-mode only, read-only
when csr_marchid_c => csr_acc_valid <= csr.priv_m_mode and (not csr_wacc_v); -- M-mode only, read-only
when csr_mimpid_c => csr_acc_valid <= csr.priv_m_mode and (not csr_wacc_v); -- M-mode only, read-only
when csr_mhartid_c => csr_acc_valid <= csr.priv_m_mode and (not csr_wacc_v); -- M-mode only, read-only
--
when csr_mzext_c => csr_acc_valid <= is_m_mode_v and (not csr_wacc_v); -- M-mode only, read-only
when csr_mzext_c => csr_acc_valid <= csr.priv_m_mode and (not csr_wacc_v); -- M-mode only, read-only
--
when others => csr_acc_valid <= '0'; -- undefined, invalid access
end case;
1363,6 → 1351,7
-- Trap Controller ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
trap_controller: process(rstn_i, clk_i)
variable mode_m_v, mode_u_v : std_ulogic;
begin
if (rstn_i = '0') then
trap_ctrl.exc_buf <= (others => '0');
1369,31 → 1358,32
trap_ctrl.irq_buf <= (others => '0');
trap_ctrl.exc_ack <= '0';
trap_ctrl.irq_ack <= (others => '0');
trap_ctrl.cause <= (others => '0');
trap_ctrl.cause <= trap_reset_c;
trap_ctrl.env_start <= '0';
elsif rising_edge(clk_i) then
if (CPU_EXTENSION_RISCV_Zicsr = true) then
-- exception buffer: misaligned load/store/instruction address
trap_ctrl.exc_buf(exception_lalign_c) <= (trap_ctrl.exc_buf(exception_lalign_c) or ma_load_i) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_salign_c) <= (trap_ctrl.exc_buf(exception_salign_c) or ma_store_i) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_ialign_c) <= (trap_ctrl.exc_buf(exception_ialign_c) or trap_ctrl.instr_ma) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_lalign_c) <= (trap_ctrl.exc_buf(exception_lalign_c) or ma_load_i) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_salign_c) <= (trap_ctrl.exc_buf(exception_salign_c) or ma_store_i) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_ialign_c) <= (trap_ctrl.exc_buf(exception_ialign_c) or trap_ctrl.instr_ma) and (not trap_ctrl.exc_ack);
-- exception buffer: load/store/instruction bus access error
trap_ctrl.exc_buf(exception_laccess_c) <= (trap_ctrl.exc_buf(exception_laccess_c) or be_load_i) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_saccess_c) <= (trap_ctrl.exc_buf(exception_saccess_c) or be_store_i) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_iaccess_c) <= (trap_ctrl.exc_buf(exception_iaccess_c) or trap_ctrl.instr_be) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_laccess_c) <= (trap_ctrl.exc_buf(exception_laccess_c) or be_load_i) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_saccess_c) <= (trap_ctrl.exc_buf(exception_saccess_c) or be_store_i) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_iaccess_c) <= (trap_ctrl.exc_buf(exception_iaccess_c) or trap_ctrl.instr_be) and (not trap_ctrl.exc_ack);
-- exception buffer: illegal instruction / env call / break point
trap_ctrl.exc_buf(exception_m_envcall_c) <= (trap_ctrl.exc_buf(exception_m_envcall_c) or trap_ctrl.env_call) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_break_c) <= (trap_ctrl.exc_buf(exception_break_c) or trap_ctrl.break_point) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_iillegal_c) <= (trap_ctrl.exc_buf(exception_iillegal_c) or trap_ctrl.instr_il) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_m_envcall_c) <= (trap_ctrl.exc_buf(exception_m_envcall_c) or (trap_ctrl.env_call and csr.priv_m_mode)) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_u_envcall_c) <= (trap_ctrl.exc_buf(exception_u_envcall_c) or (trap_ctrl.env_call and csr.priv_u_mode)) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_break_c) <= (trap_ctrl.exc_buf(exception_break_c) or trap_ctrl.break_point) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_iillegal_c) <= (trap_ctrl.exc_buf(exception_iillegal_c) or trap_ctrl.instr_il) and (not trap_ctrl.exc_ack);
-- interrupt buffer: machine software/external/timer interrupt
trap_ctrl.irq_buf(interrupt_msw_irq_c) <= csr.mie_msie and (trap_ctrl.irq_buf(interrupt_msw_irq_c) or msw_irq_i) and (not trap_ctrl.irq_ack(interrupt_msw_irq_c));
trap_ctrl.irq_buf(interrupt_mext_irq_c) <= csr.mie_meie and (trap_ctrl.irq_buf(interrupt_mext_irq_c) or mext_irq_i) and (not trap_ctrl.irq_ack(interrupt_mext_irq_c));
trap_ctrl.irq_buf(interrupt_mtime_irq_c) <= csr.mie_mtie and (trap_ctrl.irq_buf(interrupt_mtime_irq_c) or mtime_irq_i) and (not trap_ctrl.irq_ack(interrupt_mtime_irq_c));
trap_ctrl.irq_buf(interrupt_msw_irq_c) <= csr.mie_msie and (trap_ctrl.irq_buf(interrupt_msw_irq_c) or msw_irq_i) and (not (trap_ctrl.irq_ack(interrupt_msw_irq_c) or csr.mip_clear(interrupt_msw_irq_c)));
trap_ctrl.irq_buf(interrupt_mext_irq_c) <= csr.mie_meie and (trap_ctrl.irq_buf(interrupt_mext_irq_c) or mext_irq_i) and (not (trap_ctrl.irq_ack(interrupt_mext_irq_c) or csr.mip_clear(interrupt_mext_irq_c)));
trap_ctrl.irq_buf(interrupt_mtime_irq_c) <= csr.mie_mtie and (trap_ctrl.irq_buf(interrupt_mtime_irq_c) or mtime_irq_i) and (not (trap_ctrl.irq_ack(interrupt_mtime_irq_c) or csr.mip_clear(interrupt_mtime_irq_c)));
-- interrupt buffer: custom fast interrupts
trap_ctrl.irq_buf(interrupt_firq_0_c) <= csr.mie_firqe(0) and (trap_ctrl.irq_buf(interrupt_firq_0_c) or firq_i(0)) and (not trap_ctrl.irq_ack(interrupt_firq_0_c));
trap_ctrl.irq_buf(interrupt_firq_1_c) <= csr.mie_firqe(1) and (trap_ctrl.irq_buf(interrupt_firq_1_c) or firq_i(1)) and (not trap_ctrl.irq_ack(interrupt_firq_1_c));
trap_ctrl.irq_buf(interrupt_firq_2_c) <= csr.mie_firqe(2) and (trap_ctrl.irq_buf(interrupt_firq_2_c) or firq_i(2)) and (not trap_ctrl.irq_ack(interrupt_firq_2_c));
trap_ctrl.irq_buf(interrupt_firq_3_c) <= csr.mie_firqe(3) and (trap_ctrl.irq_buf(interrupt_firq_3_c) or firq_i(3)) and (not trap_ctrl.irq_ack(interrupt_firq_3_c));
trap_ctrl.irq_buf(interrupt_firq_0_c) <= csr.mie_firqe(0) and (trap_ctrl.irq_buf(interrupt_firq_0_c) or firq_i(0)) and (not (trap_ctrl.irq_ack(interrupt_firq_0_c) or csr.mip_clear(interrupt_firq_0_c)));
trap_ctrl.irq_buf(interrupt_firq_1_c) <= csr.mie_firqe(1) and (trap_ctrl.irq_buf(interrupt_firq_1_c) or firq_i(1)) and (not (trap_ctrl.irq_ack(interrupt_firq_1_c) or csr.mip_clear(interrupt_firq_1_c)));
trap_ctrl.irq_buf(interrupt_firq_2_c) <= csr.mie_firqe(2) and (trap_ctrl.irq_buf(interrupt_firq_2_c) or firq_i(2)) and (not (trap_ctrl.irq_ack(interrupt_firq_2_c) or csr.mip_clear(interrupt_firq_2_c)));
trap_ctrl.irq_buf(interrupt_firq_3_c) <= csr.mie_firqe(3) and (trap_ctrl.irq_buf(interrupt_firq_3_c) or firq_i(3)) and (not (trap_ctrl.irq_ack(interrupt_firq_3_c) or csr.mip_clear(interrupt_firq_3_c)));
-- trap control --
if (trap_ctrl.env_start = '0') then -- no started trap handler
if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and -- exception/IRQ detected!
1418,7 → 1408,10
trap_ctrl.exc_fire <= or_all_f(trap_ctrl.exc_buf); -- exceptions/faults CANNOT be masked
trap_ctrl.irq_fire <= or_all_f(trap_ctrl.irq_buf) and csr.mstatus_mie; -- interrupts CAN be masked
 
-- current pending interrupts (for CSR.MIP register) --
csr.mip_status <= trap_ctrl.irq_buf;
 
 
-- Trap Priority Detector -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
trap_priority: process(trap_ctrl)
1435,17 → 1428,17
trap_ctrl.cause_nxt <= trap_mei_c;
trap_ctrl.irq_ack_nxt(interrupt_mext_irq_c) <= '1';
 
-- interrupt: 1.3 machine SW interrupt --
elsif (trap_ctrl.irq_buf(interrupt_msw_irq_c) = '1') then
trap_ctrl.cause_nxt <= trap_msi_c;
trap_ctrl.irq_ack_nxt(interrupt_msw_irq_c) <= '1';
 
-- interrupt: 1.7 machine timer interrupt --
elsif (trap_ctrl.irq_buf(interrupt_mtime_irq_c) = '1') then
trap_ctrl.cause_nxt <= trap_mti_c;
trap_ctrl.irq_ack_nxt(interrupt_mtime_irq_c) <= '1';
 
-- interrupt: 1.3 machine SW interrupt --
elsif (trap_ctrl.irq_buf(interrupt_msw_irq_c) = '1') then
trap_ctrl.cause_nxt <= trap_msi_c;
trap_ctrl.irq_ack_nxt(interrupt_msw_irq_c) <= '1';
 
 
-- interrupt: 1.16 fast interrupt channel 0 --
elsif (trap_ctrl.irq_buf(interrupt_firq_0_c) = '1') then
trap_ctrl.cause_nxt <= trap_firq0_c;
1488,6 → 1481,10
elsif (trap_ctrl.exc_buf(exception_m_envcall_c) = '1') then
trap_ctrl.cause_nxt <= trap_menv_c;
 
-- exception: 0.8 environment call from U-mode --
elsif (trap_ctrl.exc_buf(exception_u_envcall_c) = '1') then
trap_ctrl.cause_nxt <= trap_uenv_c;
 
-- exception: 0.3 breakpoint --
elsif (trap_ctrl.exc_buf(exception_break_c) = '1') then
trap_ctrl.cause_nxt <= trap_brk_c;
1527,8 → 1524,8
elsif rising_edge(clk_i) then
if (CPU_EXTENSION_RISCV_A = true) then
if (atomic_ctrl.env_end_ff = '1') or -- normal termination
(atomic_ctrl.env_abort = '1') or -- fast temrination (error)
(trap_ctrl.env_start = '1') then -- triggered trap -> failure
(atomic_ctrl.env_abort = '1') or -- fast termination (error)
(trap_ctrl.env_start = '1') then -- triggered trap -> failure
atomic_ctrl.lock <= '0';
elsif (atomic_ctrl.env_start = '1') then
atomic_ctrl.lock <= '1';
1558,7 → 1555,7
else -- register
csr_operand_v := rs1_i;
end if;
-- tiny ALU for CSR access operations --
-- tiny ALU for CSR write operations --
case execute_engine.i_reg(instr_funct3_lsb_c+1 downto instr_funct3_lsb_c) is
when "10" => csr.wdata <= csr.rdata or csr_operand_v; -- CSRRS(I)
when "11" => csr.wdata <= csr.rdata and (not csr_operand_v); -- CSRRC(I)
1572,7 → 1569,7
csr_write_access: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
csr.we <= '0';
csr.we <= '0';
--
csr.mstatus_mie <= '0';
csr.mstatus_mpie <= '0';
1585,10 → 1582,15
csr.mtvec <= (others => '0');
csr.mscratch <= x"19880704"; -- :)
csr.mepc <= (others => '0');
csr.mcause <= (others => '0');
-- mcause = TRAP_CODE_RESET (hardware reset, 0x80000000)
csr.mcause <= (others => '0');
csr.mcause(csr.mcause'left) <= trap_reset_c(trap_reset_c'left);
csr.mcause(trap_reset_c'left-1 downto 0) <= trap_reset_c(trap_reset_c'left-1 downto 0);
--
csr.mtval <= (others => '0');
csr.mip_clear <= (others => '0');
csr.pmpcfg <= (others => (others => '0'));
csr.pmpaddr <= (others => (others => '0'));
csr.pmpaddr <= (others => (others => '1'));
--
csr.mcycle <= (others => '0');
csr.minstret <= (others => '0');
1601,6 → 1603,9
csr.we <= csr.we_nxt;
if (CPU_EXTENSION_RISCV_Zicsr = true) then
 
-- defaults --
csr.mip_clear <= (others => '0');
 
-- --------------------------------------------------------------------------------
-- CSR access by application software
-- --------------------------------------------------------------------------------
1615,6 → 1620,8
if (CPU_EXTENSION_RISCV_U = true) then -- user mode implemented
csr.mstatus_mpp(0) <= csr.wdata(11) or csr.wdata(12);
csr.mstatus_mpp(1) <= csr.wdata(11) or csr.wdata(12);
else -- only machine mode is available
csr.mstatus_mpp <= priv_mode_m_c;
end if;
when csr_mie_c => -- R/W: mie - machine interrupt-enable register
csr.mie_msie <= csr.wdata(03); -- machine SW IRQ enable
1638,15 → 1645,24
csr.mcause <= (others => '0');
csr.mcause(csr.mcause'left) <= csr.wdata(31); -- 1: interrupt, 0: exception
csr.mcause(4 downto 0) <= csr.wdata(4 downto 0); -- identifier
when csr_mtval_c => -- R/W: mtval - machine bad address or instruction
when csr_mtval_c => -- R/W: mtval - machine bad address/instruction
csr.mtval <= csr.wdata;
when csr_mip_c => -- R/W: mip - machine interrupt pending
csr.mip_clear(interrupt_msw_irq_c) <= not csr.wdata(03);
csr.mip_clear(interrupt_mtime_irq_c) <= not csr.wdata(07);
csr.mip_clear(interrupt_mext_irq_c) <= not csr.wdata(11);
--
csr.mip_clear(interrupt_firq_0_c) <= not csr.wdata(16);
csr.mip_clear(interrupt_firq_1_c) <= not csr.wdata(17);
csr.mip_clear(interrupt_firq_2_c) <= not csr.wdata(18);
csr.mip_clear(interrupt_firq_3_c) <= not csr.wdata(19);
 
-- physical memory protection - configuration --
-- --------------------------------------------------------------------
when csr_pmpcfg0_c => -- R/W: pmpcfg0 - PMP configuration register 0
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 1) then
if (PMP_USE = true) and (pmp_num_regions_c >= 1) then
for j in 0 to 3 loop -- bytes in pmpcfg CSR
if ((j+1) <= PMP_NUM_REGIONS) then
if ((j+1) <= pmp_num_regions_c) then
if (csr.pmpcfg(0+j)(7) = '0') then -- unlocked pmpcfg access
csr.pmpcfg(0+j)(0) <= csr.wdata(j*8+0); -- R (rights.read)
csr.pmpcfg(0+j)(1) <= csr.wdata(j*8+1); -- W (rights.write)
1661,9 → 1677,9
end loop; -- j (bytes in CSR)
end if;
when csr_pmpcfg1_c => -- R/W: pmpcfg1 - PMP configuration register 1
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 5) then
if (PMP_USE = true) and (pmp_num_regions_c >= 5) then
for j in 0 to 3 loop -- bytes in pmpcfg CSR
if ((j+1+4) <= PMP_NUM_REGIONS) then
if ((j+1+4) <= pmp_num_regions_c) then
if (csr.pmpcfg(4+j)(7) = '0') then -- unlocked pmpcfg access
csr.pmpcfg(4+j)(0) <= csr.wdata(j*8+0); -- R (rights.read)
csr.pmpcfg(4+j)(1) <= csr.wdata(j*8+1); -- W (rights.write)
1683,9 → 1699,10
when csr_pmpaddr0_c | csr_pmpaddr1_c | csr_pmpaddr2_c | csr_pmpaddr3_c |
csr_pmpaddr4_c | csr_pmpaddr5_c | csr_pmpaddr6_c | csr_pmpaddr7_c => -- R/W: pmpaddr0..7 - PMP address register 0..7
if (PMP_USE = true) then
for i in 0 to PMP_NUM_REGIONS-1 loop
for i in 0 to pmp_num_regions_c-1 loop
if (execute_engine.i_reg(23 downto 20) = std_ulogic_vector(to_unsigned(i, 4))) and (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpaddr access
csr.pmpaddr(i) <= csr.wdata(31 downto 1) & '0'; -- min granularity is 8 bytes -> bit zero cannot be configured
csr.pmpaddr(i) <= csr.wdata;
csr.pmpaddr(i)(index_size_f(pmp_min_granularity_c)-4 downto 0) <= (others => '1');
end if;
end loop; -- i (CSRs)
end if;
1702,35 → 1719,37
-- --------------------------------------------------------------------------------
else
 
-- mepc & mtval: machine exception PC & machine trap value register --
-- mcause, mepc, mtval: machine trap cause, PC and value register --
-- --------------------------------------------------------------------
if (trap_ctrl.env_start_ack = '1') then -- trap handler starting?
-- trap cause ID code --
csr.mcause <= (others => '0');
csr.mcause(csr.mcause'left) <= trap_ctrl.cause(trap_ctrl.cause'left); -- 1: interrupt, 0: exception
csr.mcause(4 downto 0) <= trap_ctrl.cause(4 downto 0); -- identifier
-- trap PC --
if (trap_ctrl.cause(trap_ctrl.cause'left) = '1') then -- for INTERRUPTS
csr.mepc <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- this is the CURRENT pc = interrupted instruction
csr.mtval <= (others => '0'); -- mtval is zero for interrupts
else -- for EXCEPTIONS (according to their priority)
else -- for EXCEPTIONS
csr.mepc <= execute_engine.last_pc(data_width_c-1 downto 1) & '0'; -- this is the LAST pc = last executed instruction
if (trap_ctrl.cause(4 downto 0) = trap_iba_c(4 downto 0)) or -- instruction access error OR
(trap_ctrl.cause(4 downto 0) = trap_ima_c(4 downto 0)) or -- misaligned instruction address OR
(trap_ctrl.cause(4 downto 0) = trap_brk_c(4 downto 0)) or -- breakpoint OR
(trap_ctrl.cause(4 downto 0) = trap_menv_c(4 downto 0)) then -- environment call
end if;
-- trap value --
case trap_ctrl.cause is
when trap_ima_c | trap_iba_c => -- misaligned instruction address OR instruction access error
csr.mtval <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- address of faulting instruction
elsif (trap_ctrl.cause(4 downto 0) = trap_iil_c(4 downto 0)) then -- illegal instruction
when trap_brk_c => -- breakpoint
csr.mtval <= execute_engine.last_pc(data_width_c-1 downto 1) & '0'; -- address of breakpoint instruction
when trap_lma_c | trap_lbe_c | trap_sma_c | trap_sbe_c => -- misaligned load/store address OR load/store access error
csr.mtval <= mar_i; -- faulting data access address
when trap_iil_c => -- illegal instruction
csr.mtval <= execute_engine.i_reg_last; -- faulting instruction itself
else -- load/store misalignments/access errors
csr.mtval <= mar_i; -- faulting data access address
end if;
end if;
when others => -- everything else including interrupts
csr.mtval <= (others => '0');
end case;
end if;
 
-- mstatus: context switch --
-- --------------------------------------------------------------------
if (trap_ctrl.env_start_ack = '1') then -- ENTER: trap handler starting?
-- trap ID code --
csr.mcause <= (others => '0');
csr.mcause(csr.mcause'left) <= trap_ctrl.cause(trap_ctrl.cause'left); -- 1: interrupt, 0: exception
csr.mcause(4 downto 0) <= trap_ctrl.cause(4 downto 0); -- identifier
--
csr.mstatus_mie <= '0'; -- disable interrupts
csr.mstatus_mpie <= csr.mstatus_mie; -- buffer previous mie state
if (CPU_EXTENSION_RISCV_U = true) then -- implement user mode
1742,7 → 1761,7
csr.mstatus_mpie <= '1';
if (CPU_EXTENSION_RISCV_U = true) then -- implement user mode
csr.privilege <= csr.mstatus_mpp; -- go back to previous privilege mode
csr.mstatus_mpp <= priv_mode_u_c;
csr.mstatus_mpp <= priv_mode_m_c;
end if;
end if;
-- user mode NOT implemented --
1754,45 → 1773,57
end if; -- hardware csr access
 
-- --------------------------------------------------------------------------------
-- Counter CSRs
-- Counter CSRs (each counter is split in 2 32-bit counters)
-- --------------------------------------------------------------------------------
if (zicnt_en_c = true) then -- implement standard RISC-V performance counters?
-- [m]cycle --
if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_mcycle_c) then -- write access
csr.mcycle <= '0' & csr.wdata;
mcycle_msb <= '0';
elsif (execute_engine.sleep = '0') then -- automatic update (if CPU is not in sleep mode)
csr.mcycle <= std_ulogic_vector(unsigned(csr.mcycle) + 1);
mcycle_msb <= csr.mcycle(csr.mcycle'left);
end if;
 
-- mcycle (cycle) --
if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_mcycle_c) then -- write access
csr.mcycle <= '0' & csr.wdata;
mcycle_msb <= '0';
elsif (execute_engine.sleep = '0') then -- automatic update (if CPU is not in sleep mode)
csr.mcycle <= std_ulogic_vector(unsigned(csr.mcycle) + 1);
mcycle_msb <= csr.mcycle(csr.mcycle'left);
end if;
-- [m]cycleh --
if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_mcycleh_c) then -- write access
csr.mcycleh <= csr.wdata(csr.mcycleh'left downto 0);
elsif ((mcycle_msb xor csr.mcycle(csr.mcycle'left)) = '1') then -- automatic update
csr.mcycleh <= std_ulogic_vector(unsigned(csr.mcycleh) + 1);
end if;
 
-- mcycleh (cycleh) --
if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_mcycleh_c) then -- write access
csr.mcycleh <= csr.wdata(csr.mcycleh'left downto 0);
elsif ((mcycle_msb xor csr.mcycle(csr.mcycle'left)) = '1') then -- automatic update
csr.mcycleh <= std_ulogic_vector(unsigned(csr.mcycleh) + 1);
end if;
-- [m]instret --
if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_minstret_c) then -- write access
csr.minstret <= '0' & csr.wdata;
minstret_msb <= '0';
elsif (execute_engine.state = EXECUTE) then -- automatic update (if CPU actually executes an instruction)
csr.minstret <= std_ulogic_vector(unsigned(csr.minstret) + 1);
minstret_msb <= csr.minstret(csr.minstret'left);
end if;
 
-- minstret (instret) --
if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_minstret_c) then -- write access
csr.minstret <= '0' & csr.wdata;
minstret_msb <= '0';
elsif (execute_engine.state_prev /= EXECUTE) and (execute_engine.state = EXECUTE) then -- automatic update (if CPU commits an instruction)
csr.minstret <= std_ulogic_vector(unsigned(csr.minstret) + 1);
minstret_msb <= csr.minstret(csr.minstret'left);
-- [m]instreth --
if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_minstreth_c) then -- write access
csr.minstreth <= csr.wdata(csr.minstreth'left downto 0);
elsif ((minstret_msb xor csr.minstret(csr.minstret'left)) = '1') then -- automatic update
csr.minstreth <= std_ulogic_vector(unsigned(csr.minstreth) + 1);
end if;
else -- performance counters NOT implemented (not RISC-V-compliant!)
csr.mcycle <= (others => '0');
csr.minstret <= (others => '0');
csr.mcycleh <= (others => '0');
csr.minstreth <= (others => '0');
mcycle_msb <= '0';
minstret_msb <= '0';
end if;
 
-- minstreth (instreth) --
if (csr.we = '1') and (execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) = csr_minstreth_c) then -- write access
csr.minstreth <= csr.wdata(csr.minstreth'left downto 0);
elsif ((minstret_msb xor csr.minstret(csr.minstret'left)) = '1') then -- automatic update
csr.minstreth <= std_ulogic_vector(unsigned(csr.minstreth) + 1);
end if;
 
end if;
end if;
end process csr_write_access;
 
-- decode privilege mode --
csr.priv_m_mode <= '1' when (csr.privilege = priv_mode_m_c) or (CPU_EXTENSION_RISCV_U = false) else '0';
csr.priv_u_mode <= '1' when (csr.privilege = priv_mode_u_c) and (CPU_EXTENSION_RISCV_U = true) else '0';
 
-- PMP configuration output to bus unit --
pmp_output: process(csr)
begin
1799,8 → 1830,9
pmp_addr_o <= (others => (others => '0'));
pmp_ctrl_o <= (others => (others => '0'));
if (PMP_USE = true) then
for i in 0 to PMP_NUM_REGIONS-1 loop
pmp_addr_o(i) <= csr.pmpaddr(i) & "00";
for i in 0 to pmp_num_regions_c-1 loop
pmp_addr_o(i) <= csr.pmpaddr(i) & "11";
pmp_addr_o(i)(index_size_f(pmp_min_granularity_c)-4 downto 0) <= (others => '1');
pmp_ctrl_o(i) <= csr.pmpcfg(i);
end loop; -- i
end if;
1823,6 → 1855,8
csr.rdata(07) <= csr.mstatus_mpie; -- MPIE
csr.rdata(11) <= csr.mstatus_mpp(0); -- MPP: machine previous privilege mode low
csr.rdata(12) <= csr.mstatus_mpp(1); -- MPP: machine previous privilege mode high
when csr_mstatush_c => -- R/-: mstatush - machine status register - high part
csr.rdata(05) <= '1'; -- MBE: CPU/Processor is BIG-ENDIAN
when csr_misa_c => -- R/-: misa - ISA and extensions
csr.rdata(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_A); -- A CPU extension
csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension
1855,43 → 1889,43
when csr_mtval_c => -- R/W: mtval - machine bad address or instruction
csr.rdata <= csr.mtval;
when csr_mip_c => -- R/W: mip - machine interrupt pending
csr.rdata(03) <= trap_ctrl.irq_buf(interrupt_msw_irq_c);
csr.rdata(07) <= trap_ctrl.irq_buf(interrupt_mtime_irq_c);
csr.rdata(11) <= trap_ctrl.irq_buf(interrupt_mext_irq_c);
csr.rdata(03) <= csr.mip_status(interrupt_msw_irq_c);
csr.rdata(07) <= csr.mip_status(interrupt_mtime_irq_c);
csr.rdata(11) <= csr.mip_status(interrupt_mext_irq_c);
--
csr.rdata(16) <= trap_ctrl.irq_buf(interrupt_firq_0_c);
csr.rdata(17) <= trap_ctrl.irq_buf(interrupt_firq_1_c);
csr.rdata(18) <= trap_ctrl.irq_buf(interrupt_firq_2_c);
csr.rdata(19) <= trap_ctrl.irq_buf(interrupt_firq_3_c);
csr.rdata(16) <= csr.mip_status(interrupt_firq_0_c);
csr.rdata(17) <= csr.mip_status(interrupt_firq_1_c);
csr.rdata(18) <= csr.mip_status(interrupt_firq_2_c);
csr.rdata(19) <= csr.mip_status(interrupt_firq_3_c);
 
-- physical memory protection - configuration --
when csr_pmpcfg0_c => -- R/W: pmpcfg0 - physical memory protection configuration register 0
if (PMP_USE = true) then
if (PMP_NUM_REGIONS >= 1) then
if (pmp_num_regions_c >= 1) then
csr.rdata(07 downto 00) <= csr.pmpcfg(0);
end if;
if (PMP_NUM_REGIONS >= 2) then
if (pmp_num_regions_c >= 2) then
csr.rdata(15 downto 08) <= csr.pmpcfg(1);
end if;
if (PMP_NUM_REGIONS >= 3) then
if (pmp_num_regions_c >= 3) then
csr.rdata(23 downto 16) <= csr.pmpcfg(2);
end if;
if (PMP_NUM_REGIONS >= 4) then
if (pmp_num_regions_c >= 4) then
csr.rdata(31 downto 24) <= csr.pmpcfg(3);
end if;
end if;
when csr_pmpcfg1_c => -- R/W: pmpcfg1 - physical memory protection configuration register 1
if (PMP_USE = true) then
if (PMP_NUM_REGIONS >= 5) then
if (pmp_num_regions_c >= 5) then
csr.rdata(07 downto 00) <= csr.pmpcfg(4);
end if;
if (PMP_NUM_REGIONS >= 6) then
if (pmp_num_regions_c >= 6) then
csr.rdata(15 downto 08) <= csr.pmpcfg(5);
end if;
if (PMP_NUM_REGIONS >= 7) then
if (pmp_num_regions_c >= 7) then
csr.rdata(23 downto 16) <= csr.pmpcfg(6);
end if;
if (PMP_NUM_REGIONS >= 8) then
if (pmp_num_regions_c >= 8) then
csr.rdata(31 downto 24) <= csr.pmpcfg(7);
end if;
end if;
1898,75 → 1932,59
 
-- physical memory protection - addresses --
when csr_pmpaddr0_c => -- R/W: pmpaddr0 - physical memory protection address register 0
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 1) then
if (PMP_USE = true) and (pmp_num_regions_c >= 1) then
csr.rdata <= csr.pmpaddr(0);
if (csr.pmpcfg(0)(4 downto 3) = "00") then -- mode = off
csr.rdata(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
csr.rdata(PMP_GRANULARITY-2 downto 0) <= (others => '1');
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
end if;
end if;
when csr_pmpaddr1_c => -- R/W: pmpaddr1 - physical memory protection address register 1
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 2) then
if (PMP_USE = true) and (pmp_num_regions_c >= 2) then
csr.rdata <= csr.pmpaddr(1);
if (csr.pmpcfg(1)(4 downto 3) = "00") then -- mode = off
csr.rdata(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
csr.rdata(PMP_GRANULARITY-2 downto 0) <= (others => '1');
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
end if;
end if;
when csr_pmpaddr2_c => -- R/W: pmpaddr2 - physical memory protection address register 2
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 3) then
if (PMP_USE = true) and (pmp_num_regions_c >= 3) then
csr.rdata <= csr.pmpaddr(2);
if (csr.pmpcfg(2)(4 downto 3) = "00") then -- mode = off
csr.rdata(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
csr.rdata(PMP_GRANULARITY-2 downto 0) <= (others => '1');
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
end if;
end if;
when csr_pmpaddr3_c => -- R/W: pmpaddr3 - physical memory protection address register 3
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 4) then
if (PMP_USE = true) and (pmp_num_regions_c >= 4) then
csr.rdata <= csr.pmpaddr(3);
if (csr.pmpcfg(3)(4 downto 3) = "00") then -- mode = off
csr.rdata(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
csr.rdata(PMP_GRANULARITY-2 downto 0) <= (others => '1');
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
end if;
end if;
when csr_pmpaddr4_c => -- R/W: pmpaddr4 - physical memory protection address register 4
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 5) then
if (PMP_USE = true) and (pmp_num_regions_c >= 5) then
csr.rdata <= csr.pmpaddr(4);
if (csr.pmpcfg(4)(4 downto 3) = "00") then -- mode = off
csr.rdata(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
csr.rdata(PMP_GRANULARITY-2 downto 0) <= (others => '1');
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
end if;
end if;
when csr_pmpaddr5_c => -- R/W: pmpaddr5 - physical memory protection address register 5
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 6) then
if (PMP_USE = true) and (pmp_num_regions_c >= 6) then
csr.rdata <= csr.pmpaddr(5);
if (csr.pmpcfg(5)(4 downto 3) = "00") then -- mode = off
csr.rdata(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
csr.rdata(PMP_GRANULARITY-2 downto 0) <= (others => '1');
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
end if;
end if;
when csr_pmpaddr6_c => -- R/W: pmpaddr6 - physical memory protection address register 6
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 7) then
if (PMP_USE = true) and (pmp_num_regions_c >= 7) then
csr.rdata <= csr.pmpaddr(6);
if (csr.pmpcfg(6)(4 downto 3) = "00") then -- mode = off
csr.rdata(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
csr.rdata(PMP_GRANULARITY-2 downto 0) <= (others => '1');
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
end if;
end if;
when csr_pmpaddr7_c => -- R/W: pmpaddr7 - physical memory protection address register 7
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 8) then
if (PMP_USE = true) and (pmp_num_regions_c >= 8) then
csr.rdata <= csr.pmpaddr(7);
if (csr.pmpcfg(7)(4 downto 3) = "00") then -- mode = off
csr.rdata(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
else -- mode = NAPOT
csr.rdata(PMP_GRANULARITY-2 downto 0) <= (others => '1');
csr.rdata(index_size_f(pmp_min_granularity_c)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
end if;
end if;
 
1999,6 → 2017,7
csr.rdata(0) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr); -- RISC-V.Zicsr CPU extension
csr.rdata(1) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- RISC-V.Zifencei CPU extension
csr.rdata(2) <= bool_to_ulogic_f(PMP_USE); -- RISC-V physical memory protection
csr.rdata(3) <= bool_to_ulogic_f(zicnt_en_c); -- RISC-V performance counters ([m]cycle[h] & [m]instret[h]) implemented
 
-- undefined/unavailable --
when others =>
/rtl/core/neorv32_cpu_cp_muldiv.vhd
293,7 → 293,6
operation_result: process(valid, cp_op_ff, mul_product, div_res, quotient, opy_is_zero, rs1_i, remainder)
begin
if (valid = '1') then
valid_o <= '1';
case cp_op_ff is
when cp_op_mul_c =>
res_o <= mul_product(31 downto 00);
313,10 → 312,12
res_o <= remainder;
end case;
else
valid_o <= '0';
res_o <= (others => '0');
res_o <= (others => '0');
end if;
end process operation_result;
 
-- status output --
valid_o <= valid;
 
 
end neorv32_cpu_cp_muldiv_rtl;
/rtl/core/neorv32_imem.vhd
80,7 → 80,7
begin
mem_v := (others => (others => '0'));
for i in 0 to init'length-1 loop -- init only in range of source data array
mem_v(i) := init(i)(byte*8+7 downto byte*8+0);
mem_v(i) := init(i)(byte*8+7 downto byte*8+0);
end loop; -- i
return mem_v;
end function init_imem;
/rtl/core/neorv32_package.vhd
40,19 → 40,30
 
-- Architecture Configuration -------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant ispace_base_c : std_ulogic_vector(31 downto 0) := x"00000000"; -- default instruction memory address space base address
constant dspace_base_c : std_ulogic_vector(31 downto 0) := x"80000000"; -- default data memory address space base address
constant bus_timeout_c : natural := 127; -- cycles after which an *unacknowledged* bus access will timeout and trigger an access exception
constant wb_pipe_mode_c : boolean := false; -- false: classic/standard wishbone mode, true: pipelined wishbone mode
constant ipb_entries_c : natural := 2; -- entries in instruction prefetch buffer, must be a power of 2, default=2
constant rf_r0_is_reg_c : boolean := true; -- reg_file.r0 is a physical register that has to be initialized to zero by the CPU HW
-- address space --
constant ispace_base_c : std_ulogic_vector(31 downto 0) := x"00000000"; -- default instruction memory address space base address
constant dspace_base_c : std_ulogic_vector(31 downto 0) := x"80000000"; -- default data memory address space base address
 
-- Architecture Constants -----------------------------------------------------------------
-- (external) bus interface --
constant bus_timeout_c : natural := 127; -- cycles after which an *unacknowledged* bus access will timeout and trigger a bus access exception (min 3)
constant wb_pipe_mode_c : boolean := false; -- *external* bus protocol: false=classic/standard wishbone mode (default), true=pipelined wishbone mode
constant xbus_big_endian_c : boolean := true; -- external memory access byte order: true=big endian (default); false=little endian
 
-- CPU core --
constant ipb_entries_c : natural := 2; -- entries in CPU instruction prefetch buffer, must be a power of 2, default=2
constant zicnt_en_c : boolean := true; -- enable RISC-V performance counters ([m]cycle[h], [m]instret[h]), default=true
 
-- physical memory protection (PMP) --
constant pmp_num_regions_c : natural := 2; -- number of regions (1..8)
constant pmp_min_granularity_c : natural := 64*1024; -- minimal region size (granularity), min 8 bytes, has to be a power of 2
 
-- Architecture Constants (do not modify!)= -----------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- data width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01040801"; -- no touchy!
constant pmp_max_r_c : natural := 8; -- max PMP regions - FIXED!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
constant data_width_c : natural := 32; -- data width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01040900"; -- no touchy!
constant pmp_max_r_c : natural := 8; -- max PMP regions - FIXED!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
constant rf_r0_is_reg_c : boolean := true; -- reg_file.r0 is a physical register that has to be initialized to zero by the HW
 
-- Helper Functions -----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
65,8 → 76,10
function xor_all_f(a : std_ulogic_vector) return std_ulogic;
function xnor_all_f(a : std_ulogic_vector) return std_ulogic;
function to_hexchar_f(input : std_ulogic_vector(3 downto 0)) return character;
function hexchar_to_stdulogicvector_f(input : character) return std_ulogic_vector;
function bit_rev_f(input : std_ulogic_vector) return std_ulogic_vector;
function is_power_of_two_f(input : natural) return boolean;
function bswap32_f(input : std_ulogic_vector) return std_ulogic_vector;
 
-- Internal Types -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
341,6 → 354,7
constant csr_misa_c : std_ulogic_vector(11 downto 0) := x"301"; -- misa
constant csr_mie_c : std_ulogic_vector(11 downto 0) := x"304"; -- mie
constant csr_mtvec_c : std_ulogic_vector(11 downto 0) := x"305"; -- mtvec
constant csr_mstatush_c : std_ulogic_vector(11 downto 0) := x"310"; -- mstatush
--
constant csr_mscratch_c : std_ulogic_vector(11 downto 0) := x"340"; -- mscratch
constant csr_mepc_c : std_ulogic_vector(11 downto 0) := x"341"; -- mepc
425,6 → 439,7
constant trap_lbe_c : std_ulogic_vector(5 downto 0) := "0" & "00101"; -- 0.5: load access fault
constant trap_sma_c : std_ulogic_vector(5 downto 0) := "0" & "00110"; -- 0.6: store address misaligned
constant trap_sbe_c : std_ulogic_vector(5 downto 0) := "0" & "00111"; -- 0.7: store access fault
constant trap_uenv_c : std_ulogic_vector(5 downto 0) := "0" & "01000"; -- 0.8: environment call from u-mode
constant trap_menv_c : std_ulogic_vector(5 downto 0) := "0" & "01011"; -- 0.11: environment call from m-mode
-- RISC-V compliant interrupts --
constant trap_msi_c : std_ulogic_vector(5 downto 0) := "1" & "00011"; -- 1.3: machine software interrupt
431,6 → 446,7
constant trap_mti_c : std_ulogic_vector(5 downto 0) := "1" & "00111"; -- 1.7: machine timer interrupt
constant trap_mei_c : std_ulogic_vector(5 downto 0) := "1" & "01011"; -- 1.11: machine external interrupt
-- NEORV32-specific (custom) interrupts --
constant trap_reset_c : std_ulogic_vector(5 downto 0) := "1" & "00000"; -- 1.0: hardware reset
constant trap_firq0_c : std_ulogic_vector(5 downto 0) := "1" & "10000"; -- 1.16: fast interrupt 0
constant trap_firq1_c : std_ulogic_vector(5 downto 0) := "1" & "10001"; -- 1.17: fast interrupt 1
constant trap_firq2_c : std_ulogic_vector(5 downto 0) := "1" & "10010"; -- 1.18: fast interrupt 2
443,13 → 459,14
constant exception_iillegal_c : natural := 1; -- illegal instrution
constant exception_ialign_c : natural := 2; -- instrution address misaligned
constant exception_m_envcall_c : natural := 3; -- ENV call from m-mode
constant exception_break_c : natural := 4; -- breakpoint
constant exception_salign_c : natural := 5; -- store address misaligned
constant exception_lalign_c : natural := 6; -- load address misaligned
constant exception_saccess_c : natural := 7; -- store access fault
constant exception_laccess_c : natural := 8; -- load access fault
constant exception_u_envcall_c : natural := 4; -- ENV call from u-mode
constant exception_break_c : natural := 5; -- breakpoint
constant exception_salign_c : natural := 6; -- store address misaligned
constant exception_lalign_c : natural := 7; -- load address misaligned
constant exception_saccess_c : natural := 8; -- store access fault
constant exception_laccess_c : natural := 9; -- load access fault
--
constant exception_width_c : natural := 9; -- length of this list in bits
constant exception_width_c : natural := 10; -- length of this list in bits
-- interrupt source bits --
constant interrupt_msw_irq_c : natural := 0; -- machine software interrupt
constant interrupt_mtime_irq_c : natural := 1; -- machine timer interrupt
499,8 → 516,6
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Internal Instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
556,7 → 571,9
twi_sda_io : inout std_logic; -- twi serial data line
twi_scl_io : inout std_logic; -- twi serial clock line
-- PWM --
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels
-- system time input from external MTIME (available if IO_MTIME_USE = false) --
mtime_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time
-- Interrupts --
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt, available if IO_MTIME_USE = false
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt
583,9 → 600,7
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14 -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_USE : boolean := false -- implement PMP?
);
port (
-- global control --
644,9 → 659,7
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Physical memory protection (PMP) --
PMP_USE : boolean := false; -- implement physical memory protection?
PMP_NUM_REGIONS : natural := 4; -- number of regions (1..4)
PMP_GRANULARITY : natural := 0 -- granularity (0=none, 1=8B, 2=16B, 3=32B, ...)
PMP_USE : boolean := false -- implement physical memory protection?
);
port (
-- global control --
774,11 → 787,9
-- -------------------------------------------------------------------------------------------
component neorv32_cpu_bus
generic (
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension?
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension?
-- Physical memory protection (PMP) --
PMP_USE : boolean := false; -- implement physical memory protection?
PMP_NUM_REGIONS : natural := 4; -- number of regions (1..4)
PMP_GRANULARITY : natural := 0 -- granularity (1=8B, 2=16B, 3=32B, ...)
PMP_USE : boolean := false -- implement physical memory protection?
);
port (
-- global control --
1347,7 → 1358,7
return tmp_v;
end function xnor_all_f;
 
-- Function: Convert to hex char ----------------------------------------------------------
-- Function: Convert std_ulogic_vector to hex char ----------------------------------------
-- -------------------------------------------------------------------------------------------
function to_hexchar_f(input : std_ulogic_vector(3 downto 0)) return character is
variable output_v : character;
1374,6 → 1385,33
return output_v;
end function to_hexchar_f;
 
-- Function: Convert hex char to std_ulogic_vector ----------------------------------------
-- -------------------------------------------------------------------------------------------
function hexchar_to_stdulogicvector_f(input : character) return std_ulogic_vector is
variable hex_value_v : std_ulogic_vector(3 downto 0);
begin
case input is
when '0' => hex_value_v := x"0";
when '1' => hex_value_v := x"1";
when '2' => hex_value_v := x"2";
when '3' => hex_value_v := x"3";
when '4' => hex_value_v := x"4";
when '5' => hex_value_v := x"5";
when '6' => hex_value_v := x"6";
when '7' => hex_value_v := x"7";
when '8' => hex_value_v := x"8";
when '9' => hex_value_v := x"9";
when 'a' | 'A' => hex_value_v := x"a";
when 'b' | 'B' => hex_value_v := x"b";
when 'c' | 'C' => hex_value_v := x"c";
when 'd' | 'D' => hex_value_v := x"d";
when 'e' | 'E' => hex_value_v := x"e";
when 'f' | 'F' => hex_value_v := x"f";
when others => hex_value_v := (others => 'X');
end case;
return hex_value_v;
end function hexchar_to_stdulogicvector_f;
 
-- Function: Bit reversal -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
function bit_rev_f(input : std_ulogic_vector) return std_ulogic_vector is
1398,4 → 1436,16
end if;
end function is_power_of_two_f;
 
-- Function: Swap all bytes of a 32-bit word (endianness conversion) ----------------------
-- -------------------------------------------------------------------------------------------
function bswap32_f(input : std_ulogic_vector) return std_ulogic_vector is
variable output_v : std_ulogic_vector(input'range);
begin
output_v(07 downto 00) := input(31 downto 24);
output_v(15 downto 08) := input(23 downto 16);
output_v(23 downto 16) := input(15 downto 08);
output_v(31 downto 24) := input(07 downto 00);
return output_v;
end function bswap32_f;
 
end neorv32_package;
/rtl/core/neorv32_sysinfo.vhd
116,24 → 116,25
 
-- SYSINFO(2): Implemented processor devices/features --
-- Memory --
sysinfo_mem(2)(00) <= bool_to_ulogic_f(BOOTLOADER_USE); -- processor-internal bootloader implemented?
sysinfo_mem(2)(01) <= bool_to_ulogic_f(MEM_EXT_USE); -- external memory bus interface implemented?
sysinfo_mem(2)(02) <= bool_to_ulogic_f(MEM_INT_IMEM_USE); -- processor-internal instruction memory implemented?
sysinfo_mem(2)(03) <= bool_to_ulogic_f(MEM_INT_IMEM_ROM); -- processor-internal instruction memory implemented as ROM?
sysinfo_mem(2)(04) <= bool_to_ulogic_f(MEM_INT_DMEM_USE); -- processor-internal data memory implemented?
sysinfo_mem(2)(00) <= bool_to_ulogic_f(BOOTLOADER_USE); -- processor-internal bootloader implemented?
sysinfo_mem(2)(01) <= bool_to_ulogic_f(MEM_EXT_USE); -- external memory bus interface implemented?
sysinfo_mem(2)(02) <= bool_to_ulogic_f(MEM_INT_IMEM_USE); -- processor-internal instruction memory implemented?
sysinfo_mem(2)(03) <= bool_to_ulogic_f(MEM_INT_IMEM_ROM); -- processor-internal instruction memory implemented as ROM?
sysinfo_mem(2)(04) <= bool_to_ulogic_f(MEM_INT_DMEM_USE); -- processor-internal data memory implemented?
sysinfo_mem(2)(05) <= bool_to_ulogic_f(xbus_big_endian_c); -- is external memory bus interface using BIG-endian byte-order?
--
sysinfo_mem(2)(15 downto 05) <= (others => '0'); -- reserved
sysinfo_mem(2)(15 downto 06) <= (others => '0'); -- reserved
-- IO --
sysinfo_mem(2)(16) <= bool_to_ulogic_f(IO_GPIO_USE); -- general purpose input/output port unit (GPIO) implemented?
sysinfo_mem(2)(17) <= bool_to_ulogic_f(IO_MTIME_USE); -- machine system timer (MTIME) implemented?
sysinfo_mem(2)(18) <= bool_to_ulogic_f(IO_UART_USE); -- universal asynchronous receiver/transmitter (UART) implemented?
sysinfo_mem(2)(19) <= bool_to_ulogic_f(IO_SPI_USE); -- serial peripheral interface (SPI) implemented?
sysinfo_mem(2)(20) <= bool_to_ulogic_f(IO_TWI_USE); -- two-wire interface (TWI) implemented?
sysinfo_mem(2)(21) <= bool_to_ulogic_f(IO_PWM_USE); -- pulse-width modulation unit (PWM) implemented?
sysinfo_mem(2)(22) <= bool_to_ulogic_f(IO_WDT_USE); -- watch dog timer (WDT) implemented?
sysinfo_mem(2)(23) <= bool_to_ulogic_f(IO_CFU0_USE); -- custom functions unit 0 (CFU0) implemented?
sysinfo_mem(2)(24) <= bool_to_ulogic_f(IO_TRNG_USE); -- true random number generator (TRNG) implemented?
sysinfo_mem(2)(25) <= bool_to_ulogic_f(IO_CFU1_USE); -- custom functions unit 1 (CFU1) implemented?
sysinfo_mem(2)(16) <= bool_to_ulogic_f(IO_GPIO_USE); -- general purpose input/output port unit (GPIO) implemented?
sysinfo_mem(2)(17) <= bool_to_ulogic_f(IO_MTIME_USE); -- machine system timer (MTIME) implemented?
sysinfo_mem(2)(18) <= bool_to_ulogic_f(IO_UART_USE); -- universal asynchronous receiver/transmitter (UART) implemented?
sysinfo_mem(2)(19) <= bool_to_ulogic_f(IO_SPI_USE); -- serial peripheral interface (SPI) implemented?
sysinfo_mem(2)(20) <= bool_to_ulogic_f(IO_TWI_USE); -- two-wire interface (TWI) implemented?
sysinfo_mem(2)(21) <= bool_to_ulogic_f(IO_PWM_USE); -- pulse-width modulation unit (PWM) implemented?
sysinfo_mem(2)(22) <= bool_to_ulogic_f(IO_WDT_USE); -- watch dog timer (WDT) implemented?
sysinfo_mem(2)(23) <= bool_to_ulogic_f(IO_CFU0_USE); -- custom functions unit 0 (CFU0) implemented?
sysinfo_mem(2)(24) <= bool_to_ulogic_f(IO_TRNG_USE); -- true random number generator (TRNG) implemented?
sysinfo_mem(2)(25) <= bool_to_ulogic_f(IO_CFU1_USE); -- custom functions unit 1 (CFU1) implemented?
--
sysinfo_mem(2)(31 downto 26) <= (others => '0'); -- reserved
 
/rtl/core/neorv32_top.vhd
65,8 → 65,6
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Internal Instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
123,6 → 121,8
twi_scl_io : inout std_logic; -- twi serial clock line
-- PWM (available if IO_PWM_USE = true) --
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels
-- system time input from external MTIME (available if IO_MTIME_USE = false) --
mtime_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time
-- Interrupts --
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt, available if IO_MTIME_USE = false
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt
173,7 → 173,7
err : std_ulogic; -- bus transfer error
fence : std_ulogic; -- fence(i) instruction executed
priv : std_ulogic_vector(1 downto 0); -- current privilege level
src : std_ulogic; -- access source
src : std_ulogic; -- access source (1=instruction fetch, 0=data access)
lock : std_ulogic; -- locked/exclusive (=atomic) access
end record;
signal cpu_i, cpu_d, p_bus : bus_interface_t;
330,9 → 330,7
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE => PMP_USE, -- implement PMP?
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (max 8)
PMP_GRANULARITY => PMP_GRANULARITY -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_USE => PMP_USE -- implement PMP?
)
port map (
-- global control --
375,8 → 373,8
);
 
-- misc --
cpu_i.src <= '1';
cpu_d.src <= '0';
cpu_i.src <= '1'; -- initialized but unused
cpu_d.src <= '0'; -- initialized but unused
 
-- advanced memory control --
fence_o <= cpu_d.fence; -- indicates an executed FENCE operation
600,9 → 598,9
-- IO Access? -----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
io_acc <= '1' when (p_bus.addr(data_width_c-1 downto index_size_f(io_size_c)) = io_base_c(data_width_c-1 downto index_size_f(io_size_c))) else '0';
io_rden <= io_acc and p_bus.re;
io_rden <= io_acc and p_bus.re and (not p_bus.src); -- PMA: no_execute for IO region
-- the peripheral/IO devices in the IO area can only be written in word mode (reduces HW complexity)
io_wren <= io_acc and p_bus.we and p_bus.ben(3) and p_bus.ben(2) and p_bus.ben(1) and p_bus.ben(0);
io_wren <= io_acc and p_bus.we and and_all_f(p_bus.ben) and (not p_bus.src); -- PMA: no_execute for IO region
 
 
-- General Purpose Input/Output Port (GPIO) -----------------------------------------------
695,7 → 693,7
neorv32_mtime_inst_false:
if (IO_MTIME_USE = false) generate
mtime_rdata <= (others => '0');
mtime_time <= (others => '0');
mtime_time <= mtime_i; -- use external machine timer time signal
mtime_ack <= '0';
mtime_irq <= mtime_irq_i; -- use external machine timer interrupt
end generate;
/rtl/core/neorv32_wishbone.vhd
136,8 → 136,11
-- max bus timeout latency lower than recommended --
assert not (bus_timeout_c <= 32) report "NEORV32 PROCESSOR CONFIG ERROR: Bus timeout (neorv32_package.vhd:bus_timeout_c) should be >32 when using external bus interface." severity error;
-- external memory iterface protocol + max timeout latency notifier (warning) --
assert not (wb_pipe_mode_c = false) report "NEORV32 PROCESSOR CONFIG NOTE: Implementing external memory interface using STANDARD Wishbone protocol with max latency = " & integer'image(bus_timeout_c) & " cycles." severity warning;
assert not (wb_pipe_mode_c = true) report "NEORV32 PROCESSOR CONFIG NOTE: Implementing external memory interface using PIEPLINED Wishbone protocol with max latency = " & integer'image(bus_timeout_c) & " cycles." severity warning;
assert not (wb_pipe_mode_c = false) report "NEORV32 PROCESSOR CONFIG NOTE: Implementing external memory interface using STANDARD Wishbone protocol with max latency = " & integer'image(bus_timeout_c) & " cycles." severity note;
assert not (wb_pipe_mode_c = true) report "NEORV32 PROCESSOR CONFIG WARNING! Implementing external memory interface using PIEPLINED Wishbone protocol with max latency = " & integer'image(bus_timeout_c) & " cycles." severity warning;
-- endianness --
assert not (xbus_big_endian_c = false) report "NEORV32 PROCESSOR CONFIG NOTE: Using LITTLE-ENDIAN byte order for external memory interface." severity note;
assert not (xbus_big_endian_c = true) report "NEORV32 PROCESSOR CONFIG NOTE: Using BIG-ENDIAN byte order for external memory interface." severity note;
 
 
-- Access Control -------------------------------------------------------------------------
186,8 → 189,13
-- buffer all outgoing signals --
ctrl.we <= wren_i;
ctrl.adr <= addr_i;
ctrl.wdat <= data_i;
ctrl.sel <= ben_i;
if (xbus_big_endian_c = true) then -- endianness conversion
ctrl.wdat <= data_i;
ctrl.sel <= ben_i;
else
ctrl.wdat <= bswap32_f(data_i);
ctrl.sel <= bit_rev_f(ben_i);
end if;
ctrl.src <= src_i;
ctrl.lock <= lock_i;
ctrl.priv <= priv_i;
235,7 → 243,7
end process bus_arbiter;
 
-- host access --
data_o <= ctrl.rdat;
data_o <= ctrl.rdat when (xbus_big_endian_c = true) else bswap32_f(ctrl.rdat); -- endianness conversion
ack_o <= ctrl.ack;
err_o <= ctrl.err;
 
/rtl/top_templates/neorv32_cpu_stdlogic.vhd
56,9 → 56,7
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14 -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_USE : boolean := false -- implement PMP?
);
port (
-- global control --
149,9 → 147,7
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE => PMP_USE, -- implement PMP?
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (max 8)
PMP_GRANULARITY => PMP_GRANULARITY -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_USE => PMP_USE -- implement PMP?
)
port map (
-- global control --
/rtl/top_templates/neorv32_test_setup.vhd
85,9 → 85,7
FAST_MUL_EN => false, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => false, -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE => false, -- implement PMP?
PMP_NUM_REGIONS => 4, -- number of regions (max 16)
PMP_GRANULARITY => 14, -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
PMP_USE => true, -- implement PMP?
-- Internal Instruction memory --
MEM_INT_IMEM_USE => true, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => 16*1024, -- size of processor-internal instruction memory in bytes
144,6 → 142,8
twi_scl_io => open, -- twi serial clock line
-- PWM --
pwm_o => open, -- pwm channels
-- system time input from external MTIME (available if IO_MTIME_USE = false) --
mtime_i => (others => '0'), -- current system time
-- Interrupts --
mtime_irq_i => '0', -- machine timer interrupt, available if IO_MTIME_USE = false
msw_irq_i => '0', -- machine software interrupt
/rtl/top_templates/neorv32_top_axi4lite.vhd
61,8 → 61,6
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Internal Instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
217,8 → 215,6
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE => PMP_USE, -- implement PMP?
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (max 16)
PMP_GRANULARITY => PMP_GRANULARITY, -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Internal Instruction memory --
MEM_INT_IMEM_USE => MEM_INT_IMEM_USE, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
275,6 → 271,8
twi_scl_io => twi_scl_io, -- twi serial clock line
-- PWM --
pwm_o => pwm_o_int, -- pwm channels
-- system time input from external MTIME (available if IO_MTIME_USE = false) --
mtime_i => (others => '0'), -- current system time
-- Interrupts --
mtime_irq_i => mtime_irq_i_int, -- machine timer interrupt, available if IO_MTIME_USE = false
msw_irq_i => msw_irq_i_int, -- machine software interrupt
/rtl/top_templates/neorv32_top_stdlogic.vhd
59,8 → 59,6
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Internal Instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
117,6 → 115,8
twi_scl_io : inout std_logic; -- twi serial clock line
-- PWM (available if IO_PWM_USE = true) --
pwm_o : out std_logic_vector(03 downto 0); -- pwm channels
-- system time input from external MTIME (available if IO_MTIME_USE = false) --
mtime_i : in std_logic_vector(63 downto 0) := (others => '0'); -- current system time
-- Interrupts --
mtime_irq_i : in std_logic := '0'; -- machine timer interrupt, available if IO_MTIME_USE = false
msw_irq_i : in std_logic := '0'; -- machine software interrupt
161,6 → 161,8
--
signal pwm_o_int : std_ulogic_vector(03 downto 0);
--
signal mtime_i_int : std_ulogic_vector(63 downto 0);
--
signal mtime_irq_i_int : std_ulogic;
signal msw_irq_i_int : std_ulogic;
signal mext_irq_i_int : std_ulogic;
189,8 → 191,6
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE => PMP_USE, -- implement PMP?
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (max 16)
PMP_GRANULARITY => PMP_GRANULARITY, -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Internal Instruction memory --
MEM_INT_IMEM_USE => MEM_INT_IMEM_USE, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
247,6 → 247,8
twi_scl_io => twi_scl_io, -- twi serial clock line
-- PWM --
pwm_o => pwm_o_int, -- pwm channels
-- system time input from external MTIME (available if IO_MTIME_USE = false) --
mtime_i => mtime_i_int, -- current system time
-- Interrupts --
mtime_irq_i => mtime_irq_i_int, -- machine timer interrupt, available if IO_MTIME_USE = false
msw_irq_i => msw_irq_i_int, -- machine software interrupt
285,6 → 287,8
 
pwm_o <= std_logic_vector(pwm_o_int);
 
mtime_i_int <= std_ulogic_vector(mtime_i);
 
msw_irq_i_int <= std_ulogic(msw_irq_i);
mext_irq_i_int <= std_ulogic(mext_irq_i);
 
/sim/ghdl/ghdl_sim.sh
81,4 → 81,4
 
# Run simulation
ghdl -e --work=neorv32 neorv32_tb
ghdl -r --work=neorv32 neorv32_tb --max-stack-alloc=1048576 --ieee-asserts=disable --assert-level=error $SIM_CONFIG
ghdl -r --work=neorv32 neorv32_tb --max-stack-alloc=0 --ieee-asserts=disable --assert-level=error $SIM_CONFIG
/sim/rtl_modules/neorv32_imem.vhd
0,0 → 1,107
-- #################################################################################################
-- # << NEORV32 - Processor-internal instruction memory (IMEM) >> #
-- # ********************************************************************************************* #
-- # This version is intended for SIMULATION ONLY! #
-- # It only allows an implementation as ROM and is initialized using "application_init_image". #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 1. Redistributions of source code must retain the above copyright notice, this list of #
-- # conditions and the following disclaimer. #
-- # #
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
-- # conditions and the following disclaimer in the documentation and/or other materials #
-- # provided with the distribution. #
-- # #
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
-- # endorse or promote products derived from this software without specific prior written #
-- # permission. #
-- # #
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
-- # OF THE POSSIBILITY OF SUCH DAMAGE. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
use neorv32.neorv32_application_image.all; -- this file is generated by the image generator
 
entity neorv32_imem is
generic (
IMEM_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- memory base address
IMEM_SIZE : natural := 4*1024; -- processor-internal instruction memory size in bytes
IMEM_AS_ROM : boolean := false; -- implement IMEM as read-only memory?
BOOTLOADER_USE : boolean := true -- implement and use bootloader?
);
port (
clk_i : in std_ulogic; -- global clock line
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
ben_i : in std_ulogic_vector(03 downto 0); -- byte write enable
addr_i : in std_ulogic_vector(31 downto 0); -- address
data_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic -- transfer acknowledge
);
end neorv32_imem;
 
architecture neorv32_imem_rtl of neorv32_imem is
 
-- IO space: module base address --
constant hi_abb_c : natural := 31; -- high address boundary bit
constant lo_abb_c : natural := index_size_f(IMEM_SIZE); -- low address boundary bit
 
-- local signals --
signal acc_en : std_ulogic;
signal rdata : std_ulogic_vector(31 downto 0);
signal rden : std_ulogic;
signal addr : std_ulogic_vector(index_size_f(IMEM_SIZE/4)-1 downto 0);
 
begin
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert not (IMEM_AS_ROM = false) report "NEORV32 PROCESSOR CONFIG ERROR! IMEM has to be configured as ROM." severity error;
 
 
-- Access Control -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = IMEM_BASE(hi_abb_c downto lo_abb_c)) else '0';
addr <= addr_i(index_size_f(IMEM_SIZE/4)+1 downto 2); -- word aligned
 
 
-- Memory Access --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
imem_file_access: process(clk_i)
begin
if rising_edge(clk_i) then
rden <= acc_en and rden_i;
ack_o <= acc_en and rden_i;
if (acc_en = '1') then -- reduce switching activity when not accessed
rdata <= application_init_image(to_integer(unsigned(addr)));
end if;
end if;
end process imem_file_access;
 
-- output gate --
data_o <= rdata when (rden = '1') else (others => '0');
 
 
end neorv32_imem_rtl;
/sim/vivado/neorv32_tb_behav.wcfg
12,15 → 12,15
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="1325333fs"></ZoomStartTime>
<ZoomEndTime time="1342434fs"></ZoomEndTime>
<Cursor1Time time="1349733fs"></Cursor1Time>
<ZoomStartTime time="0fs"></ZoomStartTime>
<ZoomEndTime time="1111160fs"></ZoomEndTime>
<Cursor1Time time="15000fs"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="203"></NameColumnWidth>
<ValueColumnWidth column_width="103"></ValueColumnWidth>
<ValueColumnWidth column_width="95"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="111" />
<WVObjectSize size="121" />
<wvobject type="divider" fp_name="divider273">
<obj_property name="label">CPU: Control.FETCH</obj_property>
<obj_property name="DisplayName">label</obj_property>
114,8 → 114,8
<obj_property name="ObjectShortName">be_store_i</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ctrl_o" type="array">
<obj_property name="ElementShortName">ctrl_o[62:0]</obj_property>
<obj_property name="ObjectShortName">ctrl_o[62:0]</obj_property>
<obj_property name="ElementShortName">ctrl_o[61:0]</obj_property>
<obj_property name="ObjectShortName">ctrl_o[61:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ci_instr32" type="array">
<obj_property name="ElementShortName">ci_instr32[31:0]</obj_property>
145,100 → 145,6
<obj_property name="ElementShortName">execute_engine</obj_property>
<obj_property name="ObjectShortName">execute_engine</obj_property>
<obj_property name="isExpanded"></obj_property>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.state" type="other">
<obj_property name="ElementShortName">.state</obj_property>
<obj_property name="ObjectShortName">.state</obj_property>
<obj_property name="CustomSignalColor">#FFFFFF</obj_property>
<obj_property name="UseCustomSignalColor">true</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.state_prev" type="other">
<obj_property name="ElementShortName">.state_prev</obj_property>
<obj_property name="ObjectShortName">.state_prev</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.state_nxt" type="other">
<obj_property name="ElementShortName">.state_nxt</obj_property>
<obj_property name="ObjectShortName">.state_nxt</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.i_reg" type="array">
<obj_property name="ElementShortName">.i_reg[31:0]</obj_property>
<obj_property name="ObjectShortName">.i_reg[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.i_reg_nxt" type="array">
<obj_property name="ElementShortName">.i_reg_nxt[31:0]</obj_property>
<obj_property name="ObjectShortName">.i_reg_nxt[31:0]</obj_property>
<obj_property name="CustomSignalColor">#FFFFFF</obj_property>
<obj_property name="UseCustomSignalColor">true</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.i_reg_last" type="array">
<obj_property name="ElementShortName">.i_reg_last[31:0]</obj_property>
<obj_property name="ObjectShortName">.i_reg_last[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_ci" type="logic">
<obj_property name="ElementShortName">.is_ci</obj_property>
<obj_property name="ObjectShortName">.is_ci</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_ci_nxt" type="logic">
<obj_property name="ElementShortName">.is_ci_nxt</obj_property>
<obj_property name="ObjectShortName">.is_ci_nxt</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_jump" type="logic">
<obj_property name="ElementShortName">.is_jump</obj_property>
<obj_property name="ObjectShortName">.is_jump</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_jump_nxt" type="logic">
<obj_property name="ElementShortName">.is_jump_nxt</obj_property>
<obj_property name="ObjectShortName">.is_jump_nxt</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_cp_op" type="logic">
<obj_property name="ElementShortName">.is_cp_op</obj_property>
<obj_property name="ObjectShortName">.is_cp_op</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_cp_op_nxt" type="logic">
<obj_property name="ElementShortName">.is_cp_op_nxt</obj_property>
<obj_property name="ObjectShortName">.is_cp_op_nxt</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.branch_taken" type="logic">
<obj_property name="ElementShortName">.branch_taken</obj_property>
<obj_property name="ObjectShortName">.branch_taken</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.pc" type="array">
<obj_property name="ElementShortName">.pc[31:0]</obj_property>
<obj_property name="ObjectShortName">.pc[31:0]</obj_property>
<obj_property name="CustomSignalColor">#FFFFFF</obj_property>
<obj_property name="UseCustomSignalColor">true</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.pc_nxt" type="array">
<obj_property name="ElementShortName">.pc_nxt[31:0]</obj_property>
<obj_property name="ObjectShortName">.pc_nxt[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.next_pc" type="array">
<obj_property name="ElementShortName">.next_pc[31:0]</obj_property>
<obj_property name="ObjectShortName">.next_pc[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.last_pc" type="array">
<obj_property name="ElementShortName">.last_pc[31:0]</obj_property>
<obj_property name="ObjectShortName">.last_pc[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.last_pc_nxt" type="array">
<obj_property name="ElementShortName">.last_pc_nxt[31:0]</obj_property>
<obj_property name="ObjectShortName">.last_pc_nxt[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.sleep" type="logic">
<obj_property name="ElementShortName">.sleep</obj_property>
<obj_property name="ObjectShortName">.sleep</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.sleep_nxt" type="logic">
<obj_property name="ElementShortName">.sleep_nxt</obj_property>
<obj_property name="ObjectShortName">.sleep_nxt</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.if_rst" type="logic">
<obj_property name="ElementShortName">.if_rst</obj_property>
<obj_property name="ObjectShortName">.if_rst</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.if_rst_nxt" type="logic">
<obj_property name="ElementShortName">.if_rst_nxt</obj_property>
<obj_property name="ObjectShortName">.if_rst_nxt</obj_property>
</wvobject>
</wvobject>
<wvobject type="divider" fp_name="divider139">
<obj_property name="label">CPU: Control.ATOMICS</obj_property>
322,8 → 228,55
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp_ctrl" type="array">
<obj_property name="ElementShortName">cp_ctrl</obj_property>
<obj_property name="ObjectShortName">cp_ctrl</obj_property>
<obj_property name="isExpanded"></obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp0_start_o" type="logic">
<obj_property name="ElementShortName">cp0_start_o</obj_property>
<obj_property name="ObjectShortName">cp0_start_o</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp0_data_i" type="array">
<obj_property name="ElementShortName">cp0_data_i[31:0]</obj_property>
<obj_property name="ObjectShortName">cp0_data_i[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp0_valid_i" type="logic">
<obj_property name="ElementShortName">cp0_valid_i</obj_property>
<obj_property name="ObjectShortName">cp0_valid_i</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp1_start_o" type="logic">
<obj_property name="ElementShortName">cp1_start_o</obj_property>
<obj_property name="ObjectShortName">cp1_start_o</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp1_data_i" type="array">
<obj_property name="ElementShortName">cp1_data_i[31:0]</obj_property>
<obj_property name="ObjectShortName">cp1_data_i[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp1_valid_i" type="logic">
<obj_property name="ElementShortName">cp1_valid_i</obj_property>
<obj_property name="ObjectShortName">cp1_valid_i</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp2_start_o" type="logic">
<obj_property name="ElementShortName">cp2_start_o</obj_property>
<obj_property name="ObjectShortName">cp2_start_o</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp2_data_i" type="array">
<obj_property name="ElementShortName">cp2_data_i[31:0]</obj_property>
<obj_property name="ObjectShortName">cp2_data_i[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp2_valid_i" type="logic">
<obj_property name="ElementShortName">cp2_valid_i</obj_property>
<obj_property name="ObjectShortName">cp2_valid_i</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp3_start_o" type="logic">
<obj_property name="ElementShortName">cp3_start_o</obj_property>
<obj_property name="ObjectShortName">cp3_start_o</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp3_data_i" type="array">
<obj_property name="ElementShortName">cp3_data_i[31:0]</obj_property>
<obj_property name="ObjectShortName">cp3_data_i[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp3_valid_i" type="logic">
<obj_property name="ElementShortName">cp3_valid_i</obj_property>
<obj_property name="ObjectShortName">cp3_valid_i</obj_property>
</wvobject>
<wvobject type="divider" fp_name="divider367">
<obj_property name="label">CPU: BUS_UNIT</obj_property>
<obj_property name="DisplayName">label</obj_property>
398,14 → 351,6
<obj_property name="ElementShortName">PMP_USE</obj_property>
<obj_property name="ObjectShortName">PMP_USE</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/PMP_NUM_REGIONS" type="other">
<obj_property name="ElementShortName">PMP_NUM_REGIONS</obj_property>
<obj_property name="ObjectShortName">PMP_NUM_REGIONS</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/PMP_GRANULARITY" type="other">
<obj_property name="ElementShortName">PMP_GRANULARITY</obj_property>
<obj_property name="ObjectShortName">PMP_GRANULARITY</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp" type="array">
<obj_property name="ElementShortName">pmp</obj_property>
<obj_property name="ObjectShortName">pmp</obj_property>
/sim/README.md
0,0 → 1,17
## Simulation Source Folder
 
### [`ghdl`](https://github.com/stnolting/neorv32/tree/master/sim/ghdl)
 
This folder contains a script for simulating the processor using GHDL.
 
### [`rtl_modules`](https://github.com/stnolting/neorv32/tree/master/sim/rtl_modules)
 
This folder provides additional/alternative simulation components. The the comments in the according files for more information.
 
### [`vivado`](https://github.com/stnolting/neorv32/tree/master/sim/vivado)
 
This folder provides an example waveform configuration (for Xilinx ISIM simulator) for the default testbench.
 
### [`neorv32_tb.vhd`](https://github.com/stnolting/neorv32/tree/master/sim/neorv32_tb.vhd)
 
Default testbench for the NEORV32 Processor.
/sim/neorv32_tb.vhd
1,16 → 1,8
-- #################################################################################################
-- # << NEORV32 - Default Testbench >> #
-- # ********************************************************************************************* #
-- # This testbench provides a virtual UART receiver connected to the processor's uart_txd_o #
-- # signal. The received chars are shown in the simulator console and also written to a file #
-- # ("neorv32.testbench_uart.out"). #
-- # #
-- # Furthermore, this testbench provides two external memories (ext_mem_a and ext_mem_b) coupled #
-- # via Wishbone. ext_mem_a is initialized with the application_init_image and can be used as #
-- # external boot memory (external IMEM). #
-- # ext_mem_b is a small uninitialized memory that can be uased as external memory-mapped IO. #
-- # #
-- # Use the "User Configuration" section to configure the testbench according to your need. #
-- # See NEORV32 data sheet (docs/NEORV32.pdf) for more information. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
70,15 → 62,18
-- simulated external Wishbone memory A (can be used as external IMEM) --
constant ext_mem_a_base_addr_c : std_ulogic_vector(31 downto 0) := x"00000000"; -- wishbone memory base address (external IMEM base)
constant ext_mem_a_size_c : natural := imem_size_c; -- wishbone memory size in bytes
constant ext_mem_a_latency_c : natural := 8; -- latency in clock cycles (min 1, max 255), plus 1 cycle initiali delay
constant ext_mem_a_latency_c : natural := 8; -- latency in clock cycles (min 1, max 255), plus 1 cycle initial delay
-- simulated external Wishbone memory B (can be used as external DMEM) --
constant ext_mem_b_base_addr_c : std_ulogic_vector(31 downto 0) := x"80000000"; -- wishbone memory base address (external DMEM base)
constant ext_mem_b_size_c : natural := dmem_size_c; -- wishbone memory size in bytes
constant ext_mem_b_latency_c : natural := 8; -- latency in clock cycles (min 1, max 255), plus 1 cycle initiali delay
constant ext_mem_b_latency_c : natural := 8; -- latency in clock cycles (min 1, max 255), plus 1 cycle initial delay
-- simulated external Wishbone memory C (can be used as external IO) --
constant ext_mem_c_base_addr_c : std_ulogic_vector(31 downto 0) := x"F0000000"; -- wishbone memory base address (default begin of EXTERNAL IO area)
constant ext_mem_c_size_c : natural := 64; -- wishbone memory size in bytes
constant ext_mem_c_latency_c : natural := 3; -- latency in clock cycles (min 1, max 255), plus 1 cycle initiali delay
constant ext_mem_c_latency_c : natural := 3; -- latency in clock cycles (min 1, max 255), plus 1 cycle initial delay
-- machine interrupt triggers --
constant msi_trigger_c : std_ulogic_vector(31 downto 0) := x"FF000000"; -- machine software interrupt
constant mei_trigger_c : std_ulogic_vector(31 downto 0) := x"FF000004"; -- machine external interrupt
-- -------------------------------------------------------------------------------------------
 
-- internals - hands off! --
108,8 → 103,11
signal twi_scl, twi_sda : std_logic;
 
-- spi --
signal spi_data : std_logic;
signal spi_data : std_ulogic;
 
-- irq --
signal msi_ring, mei_ring : std_ulogic;
 
-- Wishbone bus --
type wishbone_t is record
addr : std_ulogic_vector(31 downto 0); -- address
124,7 → 122,7
tag : std_ulogic_vector(2 downto 0); -- tag
lock : std_ulogic; -- locked/exclusive bus access
end record;
signal wb_cpu, wb_mem_a, wb_mem_b, wb_mem_c : wishbone_t;
signal wb_cpu, wb_mem_a, wb_mem_b, wb_mem_c, wb_msi, wb_mei : wishbone_t;
 
-- Wishbone memories --
type ext_mem_a_ram_t is array (0 to ext_mem_a_size_c/4-1) of std_ulogic_vector(31 downto 0);
139,7 → 137,11
begin
mem_v := (others => (others => '0'));
for i in 0 to init'length-1 loop -- init only in range of source data array
if (xbus_big_endian_c = true) then
mem_v(i) := init(i);
else
mem_v(i) := bswap32_f(init(i));
end if;
end loop; -- i
return mem_v;
end function init_wbmem;
186,8 → 188,6
FAST_SHIFT_EN => false, -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE => true, -- implement PMP?
PMP_NUM_REGIONS => 4, -- number of regions (max 16)
PMP_GRANULARITY => 14, -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Internal Instruction memory --
MEM_INT_IMEM_USE => int_imem_c , -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => imem_size_c, -- size of processor-internal instruction memory in bytes
244,10 → 244,12
twi_scl_io => twi_scl, -- twi serial clock line
-- PWM --
pwm_o => open, -- pwm channels
-- system time input from external MTIME (available if IO_MTIME_USE = false) --
mtime_i => (others => '0'), -- current system time
-- Interrupts --
mtime_irq_i => '0', -- machine software interrupt, available if IO_MTIME_USE = false
msw_irq_i => '0', -- machine software interrupt
mext_irq_i => '0' -- machine external interrupt
msw_irq_i => msi_ring, -- machine software interrupt
mext_irq_i => mei_ring -- machine external interrupt
);
 
-- TWI termination (pull-ups) --
334,15 → 336,33
wb_mem_c.cyc <= wb_cpu.cyc;
wb_mem_c.lock <= wb_cpu.lock;
 
wb_msi.addr <= wb_cpu.addr;
wb_msi.wdata <= wb_cpu.wdata;
wb_msi.we <= wb_cpu.we;
wb_msi.sel <= wb_cpu.sel;
wb_msi.tag <= wb_cpu.tag;
wb_msi.cyc <= wb_cpu.cyc;
wb_msi.lock <= wb_cpu.lock;
 
wb_mei.addr <= wb_cpu.addr;
wb_mei.wdata <= wb_cpu.wdata;
wb_mei.we <= wb_cpu.we;
wb_mei.sel <= wb_cpu.sel;
wb_mei.tag <= wb_cpu.tag;
wb_mei.cyc <= wb_cpu.cyc;
wb_mei.lock <= wb_cpu.lock;
 
-- CPU read-back signals (no mux here since peripherals have "output gates") --
wb_cpu.rdata <= wb_mem_a.rdata or wb_mem_b.rdata or wb_mem_c.rdata;
wb_cpu.ack <= wb_mem_a.ack or wb_mem_b.ack or wb_mem_c.ack;
wb_cpu.err <= wb_mem_a.err or wb_mem_b.err or wb_mem_c.err;
wb_cpu.rdata <= wb_mem_a.rdata or wb_mem_b.rdata or wb_mem_c.rdata or wb_mei.rdata or wb_msi.rdata;
wb_cpu.ack <= wb_mem_a.ack or wb_mem_b.ack or wb_mem_c.ack or wb_mei.ack or wb_msi.ack;
wb_cpu.err <= wb_mem_a.err or wb_mem_b.err or wb_mem_c.err or wb_mei.err or wb_msi.err;
 
-- peripheral select via STROBE signal --
wb_mem_a.stb <= wb_cpu.stb when (wb_cpu.addr >= ext_mem_a_base_addr_c) and (wb_cpu.addr < std_ulogic_vector(unsigned(ext_mem_a_base_addr_c) + ext_mem_a_size_c)) else '0';
wb_mem_b.stb <= wb_cpu.stb when (wb_cpu.addr >= ext_mem_b_base_addr_c) and (wb_cpu.addr < std_ulogic_vector(unsigned(ext_mem_b_base_addr_c) + ext_mem_b_size_c)) else '0';
wb_mem_c.stb <= wb_cpu.stb when (wb_cpu.addr >= ext_mem_c_base_addr_c) and (wb_cpu.addr < std_ulogic_vector(unsigned(ext_mem_c_base_addr_c) + ext_mem_c_size_c)) else '0';
wb_msi.stb <= wb_cpu.stb when (wb_cpu.addr = msi_trigger_c) else '0';
wb_mei.stb <= wb_cpu.stb when (wb_cpu.addr = mei_trigger_c) else '0';
 
 
-- Wishbone Memory A (simulated external IMEM) --------------------------------------------
467,4 → 487,34
end process ext_mem_c_access;
 
 
-- Wishbone IRQ Triggers ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
ext_irq_trigger: process(clk_gen)
begin
if rising_edge(clk_gen) then
-- default --
msi_ring <= '0';
wb_msi.rdata <= (others => '0');
wb_msi.ack <= '0';
wb_msi.err <= '0';
mei_ring <= '0';
wb_mei.rdata <= (others => '0');
wb_mei.ack <= '0';
wb_mei.err <= '0';
 
-- machine software interrupt --
if ((wb_msi.cyc and wb_msi.stb and wb_msi.we) = '1') then
msi_ring <= '1';
wb_msi.ack <= '1';
end if;
 
-- machine external interrupt --
if ((wb_mei.cyc and wb_mei.stb and wb_mei.we) = '1') then
mei_ring <= '1';
wb_mei.ack <= '1';
end if;
end if;
end process ext_irq_trigger;
 
 
end neorv32_tb_rtl;
/sw/common/crt0.S
188,6 → 188,11
csrw minstret, zero
csrw minstreth, zero
 
// restore mcause reset value (so that 'main' knows we are coming from reset)
li x12, 0x80000000
csrw mcause, x12
 
// call actual app's main function
jal ra, main
 
 
/sw/example/cpu_test/main.c
59,6 → 59,8
 
 
// Prototypes
void sim_trigger_msi(void);
void sim_trigger_mei(void);
void global_trap_handler(void);
void test_ok(void);
void test_fail(void);
90,6 → 92,24
 
 
/**********************************************************************//**
* Simulation-based function to trigger CPU MSI (machine software interrupt).
**************************************************************************/
void sim_trigger_msi(void) {
 
*(IO_REG32 (0xFF000000)) = 1;
}
 
 
/**********************************************************************//**
* Simulation-based function to trigger CPU MEI (machine external interrupt).
**************************************************************************/
void sim_trigger_mei(void) {
 
*(IO_REG32 (0xFF000004)) = 1;
}
 
 
/**********************************************************************//**
* This program uses mostly synthetic case to trigger all implemented exceptions.
* Each exception is captured and evaluated for correct detection.
*
99,6 → 119,19
**************************************************************************/
int main() {
 
register uint32_t tmp_a, tmp_b;
int i;
volatile uint32_t dummy_dst __attribute__((unused));
 
union {
uint64_t uint64;
uint32_t uint32[sizeof(uint64_t)/2];
} cpu_systime;
 
 
// init UART at default baud rate, no rx interrupt, no tx interrupt
neorv32_uart_setup(BAUD_RATE, 0, 0);
 
// Disable cpu_test compilation by default
#ifndef RUN_CPUTEST
#warning cpu_test HAS NOT BEEN COMPILED! Use >>make USER_FLAGS+=-DRUN_CPUTEST clean_all exe<< to compile it.
109,23 → 142,24
return 0;
#endif
 
neorv32_uart_printf("\n--- PROCESSOR/CPU TEST ---\n");
neorv32_uart_printf("build: "__DATE__" "__TIME__"\n");
neorv32_uart_printf("This test suite is intended to verify the default NEORV32 processor setup using the default testbench.\n\n");
 
register uint32_t tmp_a, tmp_b, tmp_c;
uint32_t i, j;
volatile uint32_t dummy_dst __attribute__((unused));
// check if we came from hardware reset
neorv32_uart_printf("Coming from hardware reset? ");
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_RESET) {
neorv32_uart_printf("true\n");
}
else {
neorv32_uart_printf("unknown (mcause != TRAP_CODE_RESET)\n");
}
 
union {
uint64_t uint64;
uint32_t uint32[sizeof(uint64_t)/2];
} cpu_systime;
 
// reset performance counter
neorv32_cpu_set_minstret(0);
neorv32_cpu_set_mcycle(0);
 
// init UART at default baud rate, no rx interrupt, no tx interrupt
neorv32_uart_setup(BAUD_RATE, 0, 0);
 
neorv32_mtime_set_time(0);
// set CMP of machine system timer MTIME to max to prevent an IRQ
uint64_t mtime_cmp_max = 0xFFFFFFFFFFFFFFFFUL;
148,6 → 182,8
neorv32_rte_print_hw_config();
 
// configure RTE
neorv32_uart_printf("\n\nInitializing NEORV32 run-time environment (RTE)... ");
 
neorv32_rte_setup(); // this will install a full-detailed debug handler for all traps
 
int install_err = 0;
160,10 → 196,11
install_err += neorv32_rte_exception_install(RTE_TRAP_L_ACCESS, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_S_MISALIGNED, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_S_ACCESS, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_UENV_CALL, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_MENV_CALL, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_MTI, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_MSI, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_MTI, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_MEI, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_FIRQ_0, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_FIRQ_1, global_trap_handler);
install_err += neorv32_rte_exception_install(RTE_TRAP_FIRQ_2, global_trap_handler);
189,20 → 226,16
}
 
// test intro
neorv32_uart_printf("\n--- PROCESSOR/CPU TEST ---\n");
neorv32_uart_printf("build: "__DATE__" "__TIME__"\n");
neorv32_uart_printf("This test suite is intended to verify the default NEORV32 processor setup using the default testbench.\n\n");
neorv32_uart_printf("Starting tests...\n\n");
neorv32_uart_printf("\nStarting tests...\n\n");
 
// enable global interrupts
neorv32_cpu_eint();
 
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
 
// ----------------------------------------------------------
// List all accessible CSRs
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] List all accessible CSRs: ", cnt_test);
 
if ((UART_CT & (1 << UART_CT_SIM_MODE)) == 0) { // check if this is a simulation
257,24 → 290,26
 
 
// ----------------------------------------------------------
// CFU0 test (default HW)
// Test standard RISC-V performance counter [m]cycle[h]
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Default CFU0 access test: ", cnt_test);
neorv32_uart_printf("[%i] Testing [m]instret[h] counters: ", cnt_test);
 
// cfu0 implemented?
if (neorv32_cfu0_available()) {
// check if counters are implemented
if (neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_ZICNT)) {
cnt_test++;
 
// write test data
CFU0_REG_0 = 0x01234567;
CFU0_REG_1 = 0x76543210;
CFU0_REG_2 = 0xABCDABCD;
CFU0_REG_3 = 0xFFAAFFAA;
// get current cycle counter
volatile uint64_t cycle_csr_test = neorv32_cpu_get_cycle();
 
if ((CFU0_REG_0 == 0x01234567) && (CFU0_REG_1 == 0x76543210) &&
(CFU0_REG_2 == 0xABCDABCD) && (CFU0_REG_3 == 0xFFAAFFAA) && // correct read-back
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) { // no exception
// wait some time to have a nice increment
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
 
// make sure cycle counter has incremented and there was no exception during access
if ((neorv32_cpu_get_cycle() > cycle_csr_test) &&
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
}
else {
282,29 → 317,31
}
}
else {
neorv32_uart_printf("skipped (CFU0 not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
// ----------------------------------------------------------
// CFU1 test (default HW)
// Test standard RISC-V performance counter [m]instret[h]
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Default CFU1 access test: ", cnt_test);
neorv32_uart_printf("[%i] Testing [m]cycle[h] counters: ", cnt_test);
 
// cfu0 implemented?
if (neorv32_cfu1_available()) {
// check if counters are implemented
if (neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_ZICNT)) {
cnt_test++;
 
// write test data
CFU1_REG_0 = 0x22334455;
CFU1_REG_1 = 0x44782931;
CFU1_REG_2 = 0xDDAABBFF;
CFU1_REG_3 = 0xA0B0D0C0;
// get current instruction counter
volatile uint64_t instret_csr_test = neorv32_cpu_get_instret();
 
if ((CFU1_REG_0 == 0x22334455) && (CFU1_REG_1 == 0x44782931) &&
(CFU1_REG_2 == 0xDDAABBFF) && (CFU1_REG_3 == 0xA0B0D0C0) && // correct read-back
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) { // no exception
// wait some time to have a nice increment
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
 
// make sure instruction counter has incremented and there was no exception during access
if ((neorv32_cpu_get_instret() > instret_csr_test) &&
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
}
else {
312,12 → 349,12
}
}
else {
neorv32_uart_printf("skipped (CFU1 not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
// ----------------------------------------------------------
// Bus timeout latency estimation
// Bus timeout latency estimation (very unprecise!)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Estimating bus time-out latency: ", cnt_test);
324,12 → 361,12
cnt_test++;
 
// start timing
tmp_a = neorv32_cpu_csr_read(CSR_CYCLE);
neorv32_cpu_csr_write(CSR_MCYCLE, 0);
 
// this store access will timeout
MMR_UNREACHABLE = 0;
 
tmp_a = neorv32_cpu_csr_read(CSR_CYCLE) - tmp_a;
tmp_a = neorv32_cpu_csr_read(CSR_MCYCLE);
 
// make sure there was a time-out
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_ACCESS) {
381,7 → 418,7
}
}
else {
neorv32_uart_printf("skipped (external memory interface not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
}
else {
506,6 → 543,94
 
 
// ----------------------------------------------------------
// Test pending interrupt
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Pending IRQ test (from MTIME): ", cnt_test);
 
if (neorv32_mtime_available()) {
cnt_test++;
 
// disable global interrupts
neorv32_cpu_dint();
 
// force MTIME IRQ
neorv32_mtime_set_timecmp(0);
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
 
// no more mtime interrupts
neorv32_mtime_set_timecmp(-1);
 
// re-enable global interrupts
neorv32_cpu_eint();
 
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MTI) {
test_ok();
}
else {
test_fail();
}
}
else {
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
// ----------------------------------------------------------
// Test clearing pending interrupt (via mip CSR)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Clear pending IRQ (via mip CSR) test (from MTIME): ", cnt_test);
 
if (neorv32_mtime_available()) {
cnt_test++;
 
// disable global interrupts
neorv32_cpu_dint();
 
// force MTIME IRQ
neorv32_mtime_set_timecmp(0);
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
 
// no more mtime interrupts
neorv32_mtime_set_timecmp(-1);
 
 
if (neorv32_cpu_csr_read(CSR_MIP) & (1 << CPU_MIP_MTIP)) { // make sure MTIP is pending
 
neorv32_cpu_csr_write(CSR_MIP, 0); // just clear all pending IRQs
neorv32_cpu_eint(); // re-enable global interrupts
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
test_ok();
}
else {
neorv32_uart_printf("IRQ triggered! ");
test_fail();
}
}
else {
neorv32_uart_printf("MTIP not pending! ");
test_fail();
}
 
// re-enable global interrupts
neorv32_cpu_eint();
}
else {
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
// ----------------------------------------------------------
// Unaligned instruction address
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
699,10 → 824,10
 
 
// ----------------------------------------------------------
// Environment call
// Environment call from M-mode
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] ENVCALL (ecall instruction) exception test: ", cnt_test);
neorv32_uart_printf("[%i] ENVCALL (ecall instruction) from M-mode exception test: ", cnt_test);
cnt_test++;
 
asm volatile("ECALL");
716,6 → 841,37
 
 
// ----------------------------------------------------------
// Environment call from U-mode
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] ENVCALL (ecall instruction) from U-mode exception test: ", cnt_test);
 
// skip if U-mode is not implemented
if (neorv32_cpu_csr_read(CSR_MISA) & (1<<CPU_MISA_U_EXT)) {
 
cnt_test++;
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
// access to misa not allowed for user-level programs
asm volatile("ECALL");
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_UENV_CALL) {
test_ok();
}
else {
test_fail();
}
 
}
else {
neorv32_uart_printf("skipped (not possible when U-EXT disabled)\n");
}
 
 
// ----------------------------------------------------------
// Machine timer interrupt (MTIME)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
746,11 → 902,75
neorv32_mtime_set_timecmp(-1);
}
else {
neorv32_uart_printf("skipped (WDT not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
// ----------------------------------------------------------
// Machine software interrupt (MSI) via testbench
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] MSI (via testbench) interrupt test: ", cnt_test);
 
if (UART_CT & (1 << UART_CT_SIM_MODE)) { // check if this is a simulation
cnt_test++;
 
// trigger IRQ
sim_trigger_msi();
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MSI) {
test_ok();
}
else {
test_fail();
}
}
else {
neorv32_uart_printf("skipped (on real hardware)\n");
}
 
 
// ----------------------------------------------------------
// Machine external interrupt (MEI) via testbench
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] MEI (via testbench) interrupt test: ", cnt_test);
 
if (UART_CT & (1 << UART_CT_SIM_MODE)) { // check if this is a simulation
cnt_test++;
 
// trigger IRQ
sim_trigger_mei();
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MEI) {
test_ok();
}
else {
test_fail();
}
}
else {
neorv32_uart_printf("skipped (on real hardware)\n");
}
 
 
// ----------------------------------------------------------
// Fast interrupt channel 0 (WDT)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
783,7 → 1003,7
neorv32_wdt_disable();
}
else {
neorv32_uart_printf("skipped (WDT not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
829,7 → 1049,7
neorv32_gpio_port_set(0);
}
else {
neorv32_uart_printf("skipped (GPIO not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
}
else {
887,7 → 1107,7
 
}
else {
neorv32_uart_printf("skipped (UART not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
926,7 → 1146,7
neorv32_spi_disable();
}
else {
neorv32_uart_printf("skipped (SPI not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
966,7 → 1186,7
neorv32_twi_disable();
}
else {
neorv32_uart_printf("skipped (TWI not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
996,7 → 1216,7
neorv32_mtime_set_timecmp(-1);
}
else {
neorv32_uart_printf("skipped (MTIME not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
1014,12 → 1234,18
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
// access to mstatus not allowed for user mode programs
neorv32_cpu_csr_read(CSR_MSTATUS);
// access to misa not allowed for user-level programs
tmp_a = neorv32_cpu_csr_read(CSR_MISA);
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
if (tmp_a == 0) { // make sure user-level code CANNOT read machine-level CSR content!
test_ok();
}
else {
neorv32_uart_printf("SECURITY VIOLATION! ");
test_fail();
}
}
else {
test_fail();
1032,7 → 1258,7
 
 
// ----------------------------------------------------------
// Test RTE debug handler
// Test RTE debug trap handler
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] RTE (runtime environment) debug trap handler test: ", cnt_test);
1071,34 → 1297,16
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
cnt_test++;
 
// check min granulartiy
neorv32_cpu_csr_write(CSR_PMPCFG0, 0);
neorv32_cpu_csr_write(CSR_PMPADDR0, 0xffffffff);
tmp_a = neorv32_cpu_csr_read(0x3b0);
// find out mininmal region size (granulartiy)
tmp_b = neorv32_cpu_pmp_get_granularity();
 
// find least-significat set bit
for (i=31; i!=0; i--) {
if (((tmp_a >> i) & 1) == 0) {
break;
}
}
 
tmp_a = SYSINFO_DSPACE_BASE; // base address of protected region
neorv32_uart_printf("Creating protected page (NAPOT, [!X,!W,R], %u bytes) @ 0x%x: ", tmp_b, tmp_a);
 
tmp_b = 0;
for (j=i; j!=0; j--) {
tmp_b = tmp_b << 1;
tmp_b = tmp_b | 1;
}
tmp_c = tmp_a & (~tmp_b); // clear LSBs in base address
tmp_c = tmp_c | tmp_b; // set region size config
// configure
int pmp_return = neorv32_cpu_pmp_configure_region(0, tmp_a, tmp_b, 0b00011001); // NAPOT, read permission, NO write and NO execute permissions
 
neorv32_uart_printf("Creating protected page (NAPOT, [!X,!W,R], %u bytes) @ 0x%x (PMPADDR = 0x%x): ", (uint32_t)(1 << (i+1+2)), tmp_a, tmp_c);
 
neorv32_cpu_csr_write(CSR_PMPADDR0, tmp_c); // 64k area @ 0xFFFFA000
neorv32_cpu_csr_write(CSR_PMPCFG0, 0b00011001); // NAPOT, read permission, NO write and NO execute permissions
 
if ((neorv32_cpu_csr_read(CSR_PMPADDR0) == tmp_c) && (neorv32_cpu_csr_read(CSR_PMPCFG0) == 0b00011001) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
if ((pmp_return == 0) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
}
else {
1220,7 → 1428,7
 
}
else {
neorv32_uart_printf("not implemented\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
 
 
1249,7 → 1457,7
}
}
else {
neorv32_uart_printf("skipped (A extension not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
}
else {
1281,7 → 1489,7
}
}
else {
neorv32_uart_printf("skipped (A extension not implemented)\n");
neorv32_uart_printf("skipped (not implemented)\n");
}
}
else {
1289,7 → 1497,6
}
 
 
 
// ----------------------------------------------------------
// Final test reports
// ----------------------------------------------------------
/sw/example/hex_viewer/main.c
55,6 → 55,7
// Prototypes
void read_memory(void);
void write_memory(void);
void atomic_cas(void);
void dump_memory(void);
uint32_t hexstr_to_uint(char *buffer, uint8_t length);
 
103,10 → 104,11
// decode input and execute command
if (!strcmp(buffer, "help")) {
neorv32_uart_printf("Available commands:\n"
" help - show this text\n"
" read - read single word from address\n"
" write - write single word to address\n"
" dump - dumpe several words from base address\n\n");
" help - show this text\n"
" read - read single word from address\n"
" write - write single word to address\n"
" atomic - perform atomic compare-and-swap operation\n"
" dump - dumpe several words from base address\n");
}
 
else if (!strcmp(buffer, "read")) {
113,6 → 115,10
read_memory();
}
 
else if (!strcmp(buffer, "atomic")) {
atomic_cas();
}
 
else if (!strcmp(buffer, "write")) {
write_memory();
}
138,10 → 144,9
char terminal_buffer[16];
 
// enter address
neorv32_uart_printf("Enter address (8 hex chars): ");
neorv32_uart_printf("Enter address (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
mem_address = mem_address & 0xFFFFFFFCUL; // align to 32-bit boundary
 
// perform read access
neorv32_uart_printf("\n[0x%x] = ", mem_address);
169,13 → 174,12
char terminal_buffer[16];
 
// enter address
neorv32_uart_printf("Enter address (8 hex chars): ");
neorv32_uart_printf("Enter address (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
mem_address = mem_address & 0xFFFFFFFCUL; // align to 32-bit boundary
 
// enter data
neorv32_uart_printf("\nEnter data (8 hex chars): ");
neorv32_uart_printf("\nEnter data (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_data = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
197,6 → 201,45
 
 
/**********************************************************************//**
* Perform atomic compare-and-swap operation
**************************************************************************/
void atomic_cas(void) {
 
char terminal_buffer[16];
uint32_t mem_address, cas_expected, cas_desired;
 
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CPU_MISA_A_EXT)) != 0) {
 
// enter memory address
neorv32_uart_printf("Enter memory address (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
// enter expected value
neorv32_uart_printf("\nEnter expected value @0x%x (8 hex chars): 0x", mem_address);
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
cas_expected = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
// enter desired value
neorv32_uart_printf("\nEnter desired (new) value @0x%x (8 hex chars): 0x", mem_address);
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
cas_desired = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
// try to execute atomic compare-and-swap
if (neorv32_cpu_atomic_cas(mem_address, cas_expected, cas_desired)) {
neorv32_uart_printf("\nAtomic-CAS: Failed!\n");
}
else {
neorv32_uart_printf("\nAtomic-CAS: Successful!\n");
}
}
else {
neorv32_uart_printf("Atomic operations not implemented/enabled!\n");
}
}
 
 
/**********************************************************************//**
* Read several words from memory base address
**************************************************************************/
void dump_memory(void) {
204,10 → 247,9
char terminal_buffer[16];
 
// enter base address
neorv32_uart_printf("Enter base address (8 hex chars): ");
neorv32_uart_printf("Enter base address (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
mem_address = mem_address & 0xFFFFFFFCUL; // align to 32-bit boundary
 
neorv32_uart_printf("\nPress key to start dumping. Press any key to abort.\n");
 
/sw/lib/include/neorv32.h
53,10 → 53,11
* Available CPU Control and Status Registers (CSRs)
**************************************************************************/
enum NEORV32_CPU_CSRS_enum {
CSR_MSTATUS = 0x300, /**< 0x300 - mstatus (r/w): Machine status register */
CSR_MISA = 0x301, /**< 0x301 - misa (r/-): CPU ISA and extensions (read-only in NEORV32) */
CSR_MIE = 0x304, /**< 0x304 - mie (r/w): Machine interrupt-enable register */
CSR_MTVEC = 0x305, /**< 0x305 - mtvec (r/w): Machine trap-handler base address (for ALL traps) */
CSR_MSTATUS = 0x300, /**< 0x300 - mstatus (r/w): Machine status register */
CSR_MISA = 0x301, /**< 0x301 - misa (r/-): CPU ISA and extensions (read-only in NEORV32) */
CSR_MIE = 0x304, /**< 0x304 - mie (r/w): Machine interrupt-enable register */
CSR_MTVEC = 0x305, /**< 0x305 - mtvec (r/w): Machine trap-handler base address (for ALL traps) */
CSR_MSTATUSH = 0x310, /**< 0x310 - mstatush (r/-): Machine status register - high word */
 
CSR_MSCRATCH = 0x340, /**< 0x340 - mscratch (r/w): Machine scratch register */
CSR_MEPC = 0x341, /**< 0x341 - mepc (r/w): Machine exception program counter */
103,24 → 104,32
* CPU <b>mstatus</b> CSR (r/w): Machine status (RISC-V spec.)
**************************************************************************/
enum NEORV32_CPU_MSTATUS_enum {
CPU_MSTATUS_MIE = 3, /**< CPU mstatus CSR (3): Machine interrupt enable bit (r/w) */
CPU_MSTATUS_MPIE = 7, /**< CPU mstatus CSR (7): Machine previous interrupt enable bit (r/w) */
CPU_MSTATUS_MPP_L = 11, /**< CPU mstatus CSR (11): Machine previous privilege mode bit low (r/w) */
CPU_MSTATUS_MPP_H = 12 /**< CPU mstatus CSR (12): Machine previous privilege mode bit high (r/w) */
CPU_MSTATUS_MIE = 3, /**< CPU mstatus CSR (3): MIE - Machine interrupt enable bit (r/w) */
CPU_MSTATUS_MPIE = 7, /**< CPU mstatus CSR (7): MPIE - Machine previous interrupt enable bit (r/w) */
CPU_MSTATUS_MPP_L = 11, /**< CPU mstatus CSR (11): MPP_L - Machine previous privilege mode bit low (r/w) */
CPU_MSTATUS_MPP_H = 12 /**< CPU mstatus CSR (12): MPP_H - Machine previous privilege mode bit high (r/w) */
};
 
 
/**********************************************************************//**
* CPU <b>mstatush</b> CSR (r/-): Machine status - high word(RISC-V spec.)
**************************************************************************/
enum NEORV32_CPU_MSTATUSH_enum {
CPU_MSTATUSH_MBE = 5 /**< CPU mstatush CSR (5): MBE - Machine endianness (little-endian=0, big-endian=1) (r/w) */
};
 
 
/**********************************************************************//**
* CPU <b>mie</b> CSR (r/w): Machine interrupt enable (RISC-V spec.)
**************************************************************************/
enum NEORV32_CPU_MIE_enum {
CPU_MIE_MSIE = 3, /**< CPU mie CSR (3): Machine software interrupt enable (r/w) */
CPU_MIE_MTIE = 7, /**< CPU mie CSR (7): Machine timer interrupt enable bit (r/w) */
CPU_MIE_MEIE = 11, /**< CPU mie CSR (11): Machine external interrupt enable bit (r/w) */
CPU_MIE_FIRQ0E = 16, /**< CPU mie CSR (16): Fast interrupt channel 0 enable bit (r/w) */
CPU_MIE_FIRQ1E = 17, /**< CPU mie CSR (17): Fast interrupt channel 1 enable bit (r/w) */
CPU_MIE_FIRQ2E = 18, /**< CPU mie CSR (18): Fast interrupt channel 2 enable bit (r/w) */
CPU_MIE_FIRQ3E = 19 /**< CPU mie CSR (19): Fast interrupt channel 3 enable bit (r/w) */
CPU_MIE_MSIE = 3, /**< CPU mie CSR (3): MSIE - Machine software interrupt enable (r/w) */
CPU_MIE_MTIE = 7, /**< CPU mie CSR (7): MTIE - Machine timer interrupt enable bit (r/w) */
CPU_MIE_MEIE = 11, /**< CPU mie CSR (11): MEIE - Machine external interrupt enable bit (r/w) */
CPU_MIE_FIRQ0E = 16, /**< CPU mie CSR (16): FIRQ0E - Fast interrupt channel 0 enable bit (r/w) */
CPU_MIE_FIRQ1E = 17, /**< CPU mie CSR (17): FIRQ1E - Fast interrupt channel 1 enable bit (r/w) */
CPU_MIE_FIRQ2E = 18, /**< CPU mie CSR (18): FIRQ2E - Fast interrupt channel 2 enable bit (r/w) */
CPU_MIE_FIRQ3E = 19 /**< CPU mie CSR (19): FIRQ3E - Fast interrupt channel 3 enable bit (r/w) */
};
 
 
128,14 → 137,14
* CPU <b>mip</b> CSR (r/-): Machine interrupt pending (RISC-V spec.)
**************************************************************************/
enum NEORV32_CPU_MIP_enum {
CPU_MIP_MSIP = 3, /**< CPU mip CSR (3): Machine software interrupt pending (r/-) */
CPU_MIP_MTIP = 7, /**< CPU mip CSR (7): Machine timer interrupt pending (r/-) */
CPU_MIP_MEIP = 11, /**< CPU mip CSR (11): Machine external interrupt pending (r/-) */
CPU_MIP_MSIP = 3, /**< CPU mip CSR (3): MSIP - Machine software interrupt pending (r/-) */
CPU_MIP_MTIP = 7, /**< CPU mip CSR (7): MTIP - Machine timer interrupt pending (r/-) */
CPU_MIP_MEIP = 11, /**< CPU mip CSR (11): MEIP - Machine external interrupt pending (r/-) */
 
CPU_MIP_FIRQ0P = 16, /**< CPU mip CSR (16): Fast interrupt channel 0 pending (r/-) */
CPU_MIP_FIRQ1P = 17, /**< CPU mip CSR (17): Fast interrupt channel 1 pending (r/-) */
CPU_MIP_FIRQ2P = 18, /**< CPU mip CSR (18): Fast interrupt channel 2 pending (r/-) */
CPU_MIP_FIRQ3P = 19 /**< CPU mip CSR (19): Fast interrupt channel 3 pending (r/-) */
CPU_MIP_FIRQ0P = 16, /**< CPU mip CSR (16): FIRQ0P - Fast interrupt channel 0 pending (r/-) */
CPU_MIP_FIRQ1P = 17, /**< CPU mip CSR (17): FIRQ1P - Fast interrupt channel 1 pending (r/-) */
CPU_MIP_FIRQ2P = 18, /**< CPU mip CSR (18): FIRQ2P - Fast interrupt channel 2 pending (r/-) */
CPU_MIP_FIRQ3P = 19 /**< CPU mip CSR (19): FIRQ3P - Fast interrupt channel 3 pending (r/-) */
};
 
 
163,7 → 172,8
enum NEORV32_CPU_MZEXT_enum {
CPU_MZEXT_ZICSR = 0, /**< CPU mzext CSR (0): Zicsr extension available when set (r/-) */
CPU_MZEXT_ZIFENCEI = 1, /**< CPU mzext CSR (1): Zifencei extension available when set (r/-) */
CPU_MZEXT_PMP = 2 /**< CPU mzext CSR (2): PMP extension available when set (r/-) */
CPU_MZEXT_PMP = 2, /**< CPU mzext CSR (2): PMP extension available when set (r/-) */
CPU_MZEXT_ZICNT = 3 /**< CPU mzext CSR (3): Standard RISC-V performance counters ([m]cycle[h] & [m]instret[h]) available when set (r/-) */
};
 
 
179,7 → 189,9
TRAP_CODE_L_ACCESS = 0x00000005, /**< 0.5: Load (bus) access fault */
TRAP_CODE_S_MISALIGNED = 0x00000006, /**< 0.6: Store address misaligned */
TRAP_CODE_S_ACCESS = 0x00000007, /**< 0.7: Store (bus) access fault */
TRAP_CODE_UENV_CALL = 0x00000008, /**< 0.8: Environment call from user mode (ECALL instruction) */
TRAP_CODE_MENV_CALL = 0x0000000b, /**< 0.11: Environment call from machine mode (ECALL instruction) */
TRAP_CODE_RESET = 0x80000000, /**< 1.0: Hardware reset */
TRAP_CODE_MSI = 0x80000003, /**< 1.3: Machine software interrupt */
TRAP_CODE_MTI = 0x80000007, /**< 1.7: Machine timer interrupt */
TRAP_CODE_MEI = 0x8000000b, /**< 1.11: Machine external interrupt */
531,6 → 543,7
SYSINFO_FEATURES_MEM_INT_IMEM = 2, /**< SYSINFO_FEATURES (2) (r/-): Processor-internal instruction memory implemented when 1 (via MEM_INT_IMEM_USE generic) */
SYSINFO_FEATURES_MEM_INT_IMEM_ROM = 3, /**< SYSINFO_FEATURES (3) (r/-): Processor-internal instruction memory implemented as ROM when 1 (via MEM_INT_IMEM_ROM generic) */
SYSINFO_FEATURES_MEM_INT_DMEM = 4, /**< SYSINFO_FEATURES (4) (r/-): Processor-internal data memory implemented when 1 (via MEM_INT_DMEM_USE generic) */
SYSINFO_FEATURES_MEM_EXT_ENDIAN = 5, /**< SYSINFO_FEATURES (5) (r/-): External bus interface uses BIG-endian byte-order when 1 (via package.xbus_big_endian_c constant) */
 
SYSINFO_FEATURES_IO_GPIO = 16, /**< SYSINFO_FEATURES (16) (r/-): General purpose input/output port unit implemented when 1 (via IO_GPIO_USE generic) */
SYSINFO_FEATURES_IO_MTIME = 17, /**< SYSINFO_FEATURES (17) (r/-): Machine system timer implemented when 1 (via IO_MTIME_USE generic) */
/sw/lib/include/neorv32_cpu.h
53,6 → 53,8
void neorv32_cpu_delay_ms(uint32_t time_ms);
void __attribute__((naked)) neorv32_cpu_goto_user_mode(void);
int neorv32_cpu_atomic_cas(uint32_t addr, uint32_t expected, uint32_t desired);
uint32_t neorv32_cpu_pmp_get_granularity(void);
int neorv32_cpu_pmp_configure_region(uint32_t index, uint32_t base, uint32_t size, uint8_t config);
 
 
/**********************************************************************//**
107,6 → 109,8
inline void __attribute__ ((always_inline)) neorv32_cpu_eint(void) {
 
asm volatile ("csrrsi zero, mstatus, %0" : : "i" (1 << CPU_MSTATUS_MIE));
asm volatile ("nop");
asm volatile ("nop");
}
 
 
116,6 → 120,8
inline void __attribute__ ((always_inline)) neorv32_cpu_dint(void) {
 
asm volatile ("csrrci zero, mstatus, %0" : : "i" (1 << CPU_MSTATUS_MIE));
asm volatile ("nop");
asm volatile ("nop");
}
 
 
/sw/lib/include/neorv32_rte.h
54,14 → 54,15
RTE_TRAP_L_ACCESS = 5, /**< Load (bus) access fault */
RTE_TRAP_S_MISALIGNED = 6, /**< Store address misaligned */
RTE_TRAP_S_ACCESS = 7, /**< Store (bus) access fault */
RTE_TRAP_MENV_CALL = 8, /**< Environment call from machine mode (ECALL instruction) */
RTE_TRAP_MSI = 9, /**< Machine software interrupt */
RTE_TRAP_MTI = 10, /**< Machine timer interrupt */
RTE_TRAP_MEI = 11, /**< Machine external interrupt */
RTE_TRAP_FIRQ_0 = 12, /**< Fast interrupt channel 0 */
RTE_TRAP_FIRQ_1 = 13, /**< Fast interrupt channel 1 */
RTE_TRAP_FIRQ_2 = 14, /**< Fast interrupt channel 2 */
RTE_TRAP_FIRQ_3 = 15 /**< Fast interrupt channel 3 */
RTE_TRAP_UENV_CALL = 8, /**< Environment call from user mode (ECALL instruction) */
RTE_TRAP_MENV_CALL = 9, /**< Environment call from machine mode (ECALL instruction) */
RTE_TRAP_MSI = 10, /**< Machine software interrupt */
RTE_TRAP_MTI = 11, /**< Machine timer interrupt */
RTE_TRAP_MEI = 12, /**< Machine external interrupt */
RTE_TRAP_FIRQ_0 = 13, /**< Fast interrupt channel 0 */
RTE_TRAP_FIRQ_1 = 14, /**< Fast interrupt channel 1 */
RTE_TRAP_FIRQ_2 = 15, /**< Fast interrupt channel 2 */
RTE_TRAP_FIRQ_3 = 16 /**< Fast interrupt channel 3 */
};
 
// prototypes
/sw/lib/source/neorv32_cpu.c
295,3 → 295,123
return 1; // A extension not implemented -Y always fail
#endif
}
 
 
/**********************************************************************//**
* Physical memory protection (PMP): Get minimal region size (granularity).
*
* @warning This function overrides PMPCFG0[0] and PMPADDR0 CSRs.
*
* @warning This function requires the PMP CPU extension.
*
* @return Returns minimal region size in bytes; Returns 0 on failure.
**************************************************************************/
uint32_t neorv32_cpu_pmp_get_granularity(void) {
 
if ((neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_PMP)) == 0) {
return 0; // PMP not implemented
}
 
// check min granulartiy
uint32_t tmp = neorv32_cpu_csr_read(CSR_PMPCFG0);
tmp &= 0xffffff00; // disable entry 0
neorv32_cpu_csr_write(CSR_PMPCFG0, tmp);
neorv32_cpu_csr_write(CSR_PMPADDR0, 0xffffffff);
uint32_t tmp_a = neorv32_cpu_csr_read(CSR_PMPADDR0);
 
uint32_t i;
 
// find least-significat set bit
for (i=31; i!=0; i--) {
if (((tmp_a >> i) & 1) == 0) {
break;
}
}
 
return (uint32_t)(1 << (i+1+2));
}
 
 
/**********************************************************************//**
* Physical memory protection (PMP): Configure region.
*
* @note Using NAPOT mode - page base address has to be naturally aligned.
*
* @warning This function requires the PMP CPU extension.
*
* @param[in] index Region number (index, 0..max_regions-1).
* @param[in] base Region base address (has to be naturally aligned!).
* @param[in] size Region size, has to be a power of 2 (min 8 bytes or according to HW's PMP.granularity configuration).
* @param[in] config Region configuration (attributes) byte (for PMPCFGx).
* @return Returns 0 on success, 1 on failure.
**************************************************************************/
int neorv32_cpu_pmp_configure_region(uint32_t index, uint32_t base, uint32_t size, uint8_t config) {
 
if ((neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_PMP)) == 0) {
return 1; // PMP not implemented
}
 
if (size < 8) {
return 1; // minimal region size is 8 bytes
}
 
if ((size & (size - 1)) != 0) {
return 1; // region size is not a power of two
}
 
// setup configuration
uint32_t tmp;
uint32_t config_int = ((uint32_t)config) << ((index%4)*8);
uint32_t config_mask = ((uint32_t)0xFF) << ((index%4)*8);
config_mask = ~config_mask;
 
// clear old configuration
if (index < 3) {
tmp = neorv32_cpu_csr_read(CSR_PMPCFG0);
tmp &= config_mask; // clear old config
neorv32_cpu_csr_write(CSR_PMPCFG0, tmp);
}
else {
tmp = neorv32_cpu_csr_read(CSR_PMPCFG1);
tmp &= config_mask; // clear old config
neorv32_cpu_csr_write(CSR_PMPCFG1, tmp);
}
 
// set base address and region size
uint32_t addr_mask = ~((size - 1) >> 2);
uint32_t size_mask = (size - 1) >> 3;
 
tmp = base & addr_mask;
tmp = tmp | size_mask;
 
switch(index & 7) {
case 0: neorv32_cpu_csr_write(CSR_PMPADDR0, tmp); break;
case 1: neorv32_cpu_csr_write(CSR_PMPADDR1, tmp); break;
case 2: neorv32_cpu_csr_write(CSR_PMPADDR2, tmp); break;
case 3: neorv32_cpu_csr_write(CSR_PMPADDR3, tmp); break;
case 4: neorv32_cpu_csr_write(CSR_PMPADDR4, tmp); break;
case 5: neorv32_cpu_csr_write(CSR_PMPADDR5, tmp); break;
case 6: neorv32_cpu_csr_write(CSR_PMPADDR6, tmp); break;
case 7: neorv32_cpu_csr_write(CSR_PMPADDR7, tmp); break;
default: break;
}
 
// wait for HW to computer PMP-internal stuff (address masks)
for (tmp=0; tmp<16; tmp++) {
asm volatile ("nop");
}
 
// set new configuration
if (index < 3) {
tmp = neorv32_cpu_csr_read(CSR_PMPCFG0);
tmp |= config_int; // set new config
neorv32_cpu_csr_write(CSR_PMPCFG0, tmp);
}
else {
tmp = neorv32_cpu_csr_read(CSR_PMPCFG1);
tmp |= config_int; // set new config
neorv32_cpu_csr_write(CSR_PMPCFG1, tmp);
}
 
return 0;
}
/sw/lib/source/neorv32_rte.c
45,7 → 45,7
/**********************************************************************//**
* The >private< trap vector look-up table of the NEORV32 RTE.
**************************************************************************/
static uint32_t __neorv32_rte_vector_lut[16] __attribute__((unused)); // trap handler vector table
static uint32_t __neorv32_rte_vector_lut[17] __attribute__((unused)); // trap handler vector table
 
// private functions
static void __attribute__((__interrupt__)) __neorv32_rte_core(void) __attribute__((aligned(16))) __attribute__((unused));
94,8 → 94,8
 
// id valid?
if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS) || (id == RTE_TRAP_I_ILLEGAL) ||
(id == RTE_TRAP_BREAKPOINT) || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS) ||
(id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS) || (id == RTE_TRAP_MENV_CALL) ||
(id == RTE_TRAP_BREAKPOINT) || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS) ||
(id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS) || (id == RTE_TRAP_MENV_CALL) || (id == RTE_TRAP_UENV_CALL) ||
(id == RTE_TRAP_MSI) || (id == RTE_TRAP_MTI) || (id == RTE_TRAP_MEI) ||
(id == RTE_TRAP_FIRQ_0) || (id == RTE_TRAP_FIRQ_1) || (id == RTE_TRAP_FIRQ_2) || (id == RTE_TRAP_FIRQ_3)) {
 
121,8 → 121,8
 
// id valid?
if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS) || (id == RTE_TRAP_I_ILLEGAL) ||
(id == RTE_TRAP_BREAKPOINT) || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS) ||
(id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS) || (id == RTE_TRAP_MENV_CALL) ||
(id == RTE_TRAP_BREAKPOINT) || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS) ||
(id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS) || (id == RTE_TRAP_MENV_CALL) || (id == RTE_TRAP_UENV_CALL) ||
(id == RTE_TRAP_MSI) || (id == RTE_TRAP_MTI) || (id == RTE_TRAP_MEI) ||
(id == RTE_TRAP_FIRQ_0) || (id == RTE_TRAP_FIRQ_1) || (id == RTE_TRAP_FIRQ_2) || (id == RTE_TRAP_FIRQ_3)) {
 
177,6 → 177,7
case TRAP_CODE_L_ACCESS: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_L_ACCESS]; break;
case TRAP_CODE_S_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_MISALIGNED]; break;
case TRAP_CODE_S_ACCESS: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_ACCESS]; break;
case TRAP_CODE_UENV_CALL: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_UENV_CALL]; break;
case TRAP_CODE_MENV_CALL: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MENV_CALL]; break;
case TRAP_CODE_MSI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MSI]; break;
case TRAP_CODE_MTI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MTI]; break;
215,7 → 216,8
case TRAP_CODE_L_ACCESS: neorv32_uart_print("Load access fault"); break;
case TRAP_CODE_S_MISALIGNED: neorv32_uart_print("Store address misaligned"); break;
case TRAP_CODE_S_ACCESS: neorv32_uart_print("Store access fault"); break;
case TRAP_CODE_MENV_CALL: neorv32_uart_print("Environment call"); break;
case TRAP_CODE_UENV_CALL: neorv32_uart_print("Environment call from U-mode"); break;
case TRAP_CODE_MENV_CALL: neorv32_uart_print("Environment call from M-mode"); break;
case TRAP_CODE_MSI: neorv32_uart_print("Machine software interrupt"); break;
case TRAP_CODE_MTI: neorv32_uart_print("Machine timer interrupt"); break;
case TRAP_CODE_MEI: neorv32_uart_print("Machine external interrupt"); break;
249,7 → 251,7
neorv32_uart_printf("\n\n<< Hardware Configuration Overview >>\n");
 
// CPU configuration
neorv32_uart_printf("\n-- Central Processing Unit --\n");
neorv32_uart_printf("\n---- Central Processing Unit ----\n");
 
// ID
neorv32_uart_printf("Hart ID: 0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID));
285,6 → 287,15
}
// CPU extensions
neorv32_uart_printf("\nEndianness: ");
if (neorv32_cpu_csr_read(CSR_MSTATUSH) & (1<<CPU_MSTATUSH_MBE)) {
neorv32_uart_printf("big\n");
}
else {
neorv32_uart_printf("little\n");
}
// CPU extensions
neorv32_uart_printf("\nExtensions: ");
tmp = neorv32_cpu_csr_read(CSR_MISA);
for (i=0; i<26; i++) {
295,7 → 306,7
}
}
// Z* CPU extensions (from custom CSR "mzext")
// Z* CPU extensions (from custom "mzext" CSR)
tmp = neorv32_cpu_csr_read(CSR_MZEXT);
if (tmp & (1<<CPU_MZEXT_ZICSR)) {
neorv32_uart_printf("Zicsr ");
306,6 → 317,9
if (tmp & (1<<CPU_MZEXT_PMP)) {
neorv32_uart_printf("PMP ");
}
if (tmp & (1<<CPU_MZEXT_ZICNT)) {
neorv32_uart_printf("Zicnt ");
}
 
 
// check physical memory protection
312,27 → 326,9
neorv32_uart_printf("\n\nPhysical memory protection: ");
if (neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_PMP)) {
 
// check granulartiy
neorv32_cpu_csr_write(CSR_PMPCFG0, 0);
neorv32_cpu_csr_write(CSR_PMPADDR0, 0xffffffff);
uint32_t pmp_test_g = neorv32_cpu_csr_read(0x3b0);
// get minimal region siz (granulartiy)
neorv32_uart_printf("\n- Minimal granularity: %u bytes per region\n", neorv32_cpu_pmp_get_granularity());
 
// find least-significat set bit
for (i=31; i!=0; i--) {
if (((pmp_test_g >> i) & 1) == 0) {
break;
}
}
 
neorv32_uart_printf("\n- Min granularity: ");
if (i < 29) {
neorv32_uart_printf("%u bytes per region\n", (uint32_t)(1 << (i+1+2)));
}
else {
neorv32_uart_printf("2^%u bytes per region\n", i+1+2);
}
 
// test available modes
neorv32_uart_printf("- Mode TOR: ");
neorv32_cpu_csr_write(CSR_PMPCFG0, 0x08);
370,13 → 366,13
 
 
// Misc - system
neorv32_uart_printf("\n\n-- Processor --\n");
neorv32_uart_printf("\n\n---- Processor - General ----\n");
neorv32_uart_printf("Clock: %u Hz\n", SYSINFO_CLK);
neorv32_uart_printf("User ID: 0x%x\n", SYSINFO_USER_CODE);
 
 
// Memory configuration
neorv32_uart_printf("\n-- Processor Memory Configuration --\n");
neorv32_uart_printf("\n---- Processor - Memory Configuration ----\n");
 
neorv32_uart_printf("Instr. base address: 0x%x\n", SYSINFO_ISPACE_BASE);
neorv32_uart_printf("Internal IMEM: ");
385,7 → 381,7
neorv32_uart_printf("Internal IMEM as ROM: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
 
neorv32_uart_printf("Data base address: 0x%x\n", SYSINFO_DSPACE_BASE);
neorv32_uart_printf("\nData base address: 0x%x\n", SYSINFO_DSPACE_BASE);
neorv32_uart_printf("Internal DMEM: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
neorv32_uart_printf("DMEM size: %u bytes\n", SYSINFO_DMEM_SIZE);
393,11 → 389,18
neorv32_uart_printf("Bootloader: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER));
 
neorv32_uart_printf("External M interface: ");
neorv32_uart_printf("\nExternal memory bus interface: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
neorv32_uart_printf("External memory bus Endianness: ");
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT_ENDIAN)) {
neorv32_uart_printf("big\n");
}
else {
neorv32_uart_printf("little\n");
}
 
// peripherals
neorv32_uart_printf("\n-- Available Processor Peripherals --\n");
neorv32_uart_printf("\n\n---- Processor - Peripherals ----\n");
 
tmp = SYSINFO_FEATURES;
 
516,20 → 519,39
**************************************************************************/
void neorv32_rte_print_logo(void) {
 
neorv32_uart_print(
"\n"
" ##\n"
" ## ## ## ##\n"
" ## ## ######### ######## ######## ## ## ######## ######## ## ###############\n"
"#### ## ## ## ## ## ## ## ## ## ## ## ## ## #### ####\n"
"## ## ## ## ## ## ## ## ## ## ## ## ## ## ##### ##\n"
"## ## ## ######### ## ## ######### ## ## ##### ## ## #### ##### ####\n"
"## ## ## ## ## ## ## ## ## ## ## ## ## ## ##### ##\n"
"## #### ## ## ## ## ## ## ## ## ## ## ## #### ####\n"
"## ## ######### ######## ## ## ## ######## ########## ## ###############\n"
" ## ## ## ##\n"
" ##\n"
"\n");
const uint32_t logo_data_c[11][4] =
{
{0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00000000000000000000000000000000},
{0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00110001100011000000000000000000},
{0b01100000110001111111110001111111,0b10000111111110001100000011000111,0b11111000011111111000000110000000,0b11111111111111110000000000000000},
{0b11110000110011000000000011000000,0b11001100000011001100000011001100,0b00001100110000001100000110000011,0b11000000000000111100000000000000},
{0b11011000110011000000000011000000,0b11001100000011001100000011000000,0b00001100000000011000000110000000,0b11000111111000110000000000000000},
{0b11001100110011111111100011000000,0b11001111111110001100000011000000,0b11111000000001100000000110000011,0b11000111111000111100000000000000},
{0b11000110110011000000000011000000,0b11001100001100000110000110000000,0b00001100000110000000000110000000,0b11000111111000110000000000000000},
{0b11000011110011000000000011000000,0b11001100000110000011001100001100,0b00001100011000000000000110000011,0b11000000000000111100000000000000},
{0b11000001100001111111110001111111,0b10001100000011000000110000000111,0b11111000111111111100000110000000,0b11111111111111110000000000000000},
{0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00110001100011000000000000000000},
{0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00000000000000000000000000000000}
};
 
int u,v,w;
uint32_t tmp;
 
for (u=0; u<11; u++) {
neorv32_uart_print("\n");
for (v=0; v<4; v++) {
tmp = logo_data_c[u][v];
for (w=0; w<32; w++){
if (tmp & (1 << (31-w))) {
neorv32_uart_putc('#');
}
else {
neorv32_uart_putc(' ');
}
}
}
}
neorv32_uart_print("\n");
}
 
 
/CHANGELOG.md
7,7 → 7,7
can be found [here](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) (pdf).
 
The processor can determine its version from the `mimpid` CSR (at CSR address 0xf13). A 2x4-bit decimal-coded representation is used. Leading
zeros are optional. Example: `CSR(mimpid) = 0x01040312 -> 01.04.03.12 -> Version 1.4.3.12 = v1.4.3.12 = v01.04.03.12`
zeros are optional. Example: `CSR(mimpid) = 0x01040312 => 01.04.03.12 = Version 01.04.03.12 = v1.4.3.12`
 
For the HDL sources the version number is globally defined by the `hw_version_c` constant in the main VHDL package file
[`rtl/core/neorv32_package.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_package.vhd).
14,6 → 14,18
 
| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
| 19.12.2020 | 1.4.9.0 | Testbench: added memory-mapped triggers to trigger core's "machine software & external interrupts"; `sw/example/cpu_test`: removed CFU tests, added `MEI` and `MSI` tests; added **RISC-V-Compliance Test Framework** to repository (`riscv-compliance/`), core passes all `rv32` tests (riscv-compliance v2.1) |
| 18.12.2020 | 1.4.8.13 | Added additional simulation files: simulation-optimized IMEM-ROM (so far, this is only relevant for the *new* NEORV32 RISC-V Compliance test framework v2.0); **:sparkles: Processor now passes all `rv32` tests of the new [RISC-V Compliance Test Framework v2.0](https://github.com/riscv/riscv-compliance/releases/tag/v2.0) :sparkles:** |
| 16.12.2020 | 1.4.8.12 | :warning: fixed (another) bug in `mtval` CSR generation (wrong value for "breakpoint" trap); updated `mtval` value table in data sheet; fixed bug in load/store operation (intoroduced in version 1.4.8.10) |
| 16.12.2020 | 1.4.8.11 | :warning: fixed bug in `mtval` CSR generation (wrong values for some traps); fixed bug in `mip` CSR (writing zero to implemented bits now actually clears pending interrupts); fixed bug in IRQ priority encoding (machine software interrupt `MSI` comes before machine timer interrupt `MTI`) |
| 12.12.2020 | 1.4.8.10 | :warning: fixed wrong `trap_reset_c` encoding (in it's expanded form it should be 0x80000000) and reset logic: hardware `mcause` register is now set to `trap_reset_c` after a hardware reset; crt0.S start-up code now sets `mcause` to `trap_reset_c` after finishing hardware setup |
| 11.12.2020 | 1.4.8.9 | Added option to exclude standard RISC-V performance counters (`[m]cycle[h]` and `[m]instret[h]`) for size-constrained implementations; disabled by setting VHDL package's `zicnt_en_c` constant to false; software can determine state of `zicnt_en_c` via `mzext` CSR's `CPU_MZEXT_ZICNT` bit; added new signal to processor top entity: `mtime_i`, this signal is used for updateting the `time[h]` CSRs if the processor-internal MTIME unit is disabled (via `IO_MTIME_USE` = `false`) |
| 10.12.2020 | 1.4.8.8 | Added missing `mstatush` CSR (only bit `MBE` is implemented yet); added option to configure external bus interface for BIG- or little-endian byte-order, configured via VHDL package `xbus_big_endian_c` constant, default = BIG-endian, software can check endianness of the interface via SYSINFO's `SYSINFO_FEATURES(SYSINFO_FEATURES_MEM_EXT_ENDIAN)` flag; added `mstatush` CSR and endianness information to data sheet |
| 09.12.2020 | 1.4.8.7 | Added missing *environment call from U-mode* exception (via `ecall` instruction in user-mode); added environment call from U-mode to data sheet |
| 09.12.2020 | 1.4.8.6 | :warning: fixed bugs in ALU's co-processor interface: ATOMIC `A` extension could not be used without MULDIV `M` extension, CPU might have permanently stalled when executing an instruction from a disabled ISA extension; :lock: added security feature: illegal user-level CSR read access will always return zero; added new section *Execution Safety* to neorv32.pdf data sheet |
| 07.12.2020 | 1.4.8.5 | :warning: fixed bug in next-PC logic (introduced with version 1.4.8.1) that caused instruction fetch from memories with more than 1 cycle latency to fail |
| 05.12.2020 | 1.4.8.4 | :warning: fixed bug in physical memory protection (PMP): region size configuration was incorrect; removed `PMP_NUM_REGIONS` and `PMP_GRANULARITY` CPU/processor generics (PMP configuration now via package constants); reworked section *2.4. Instruction Sets and CPU Extensions* of neorv32.pdf |
| 04.12.2020 | 1.4.8.2 | Added PMA (physical memory attribute) to processor-internal IO region: `NO EXECUTE`; added *3.3.Address Space/Physical Memory Attributes (PMAs)* section to neorv32.pdf |
| 03.12.2020 | 1.4.8.1 | Optimized CPU program counter (PC) update logic and "next PC" computation (shortend critical path); updated bootloader (configuration option for direct-boot-from-SPI-flash only) and *customization* text in neorv32.pdf |
| 01.12.2020 | [**:rocket:1.4.8.0**](https://github.com/stnolting/neorv32/releases/tag/v1.4.8.0) | :warning: fixed bug in CPU-internal co-processor interface; optimized multiplier unit (~1 faster); added CPU `A` (atomic) extension support (only `lr.w` and `sc.w` instructions yet); added `lock` signal to CPU and processor's external bus interface |
| 28.11.2020 | 1.4.7.6 | Split ALU core operations: shortened critical path - replaced ALU output 8:1 mux by a 4:1 mux |
/README.md
1,4 → 1,4
[![NEORV32](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/neorv32_logo_white_bg.png)](https://github.com/stnolting/neorv32)
[![NEORV32](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/neorv32_logo.png)](https://github.com/stnolting/neorv32)
 
# The NEORV32 RISC-V Processor
 
13,7 → 13,7
* [Performance](#Performance)
* [Top Entities](#Top-Entities)
* [**Getting Started**](#Getting-Started)
* [Contribute](#Contribute)
* [Contribute/Feedback/Questions](#ContributeFeedbackQuestions)
* [Legal](#Legal)
 
 
24,7 → 24,11
on the RISC-V-compliant NEORV32 CPU. The processor is intended as *ready-to-go* auxiliary processor within a larger SoC
designs or as stand-alone custom microcontroller.
 
The project’s change log is available in the [CHANGELOG.md](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) file in the root directory of this repository.
To see the changes between releases visit the project's [release page](https://github.com/stnolting/neorv32/releases).
For more detailed information take a look at the [:page_facing_up: NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) (pdf).
 
 
### Key Features
 
* RISC-V-[compliant](#Status) 32-bit `rv32i` [**NEORV32 CPU**](#NEORV32-CPU-Features), compliant to
58,11 → 62,7
* Fully synchronous design, no latches, no gated clocks
* Small hardware footprint and high operating frequency
 
The project’s change log is available in the [CHANGELOG.md](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) file in the root directory of this repository.
To see the changes between releases visit the project's [release page](https://github.com/stnolting/neorv32/releases).
For more information take a look at the [NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) (pdf).
 
 
### Design Principles
 
* From zero to *hello_world*: Completely open source and documented.
70,7 → 70,8
* Easy to use – working out of the box.
* Clean synchronous design, no wacky combinatorial interfaces.
* Be as small as possible – but with a reasonable size-performance tradeoff.
* The processor has to fit in a Lattice iCE40 UltraPlus 5k FPGA running at 20+ MHz.
* Be as RISC-V-compliant as possible.
* The processor has to fit in a Lattice iCE40 UltraPlus 5k low-power FPGA running at 20+ MHz.
 
 
### Status
78,13 → 79,14
The processor is [synthesizable](#FPGA-Implementation-Results) (tested on *real hardware* using Intel Quartus Prime, Xilinx Vivado and Lattice Radiant/Synplify Pro) and can successfully execute
all the [provided example programs](https://github.com/stnolting/neorv32/tree/master/sw/example) including the [CoreMark benchmark](#CoreMark-Benchmark).
 
The processor passes the official `rv32i`, `rv32im`, `rv32imc`, `rv32Zicsr` and `rv32Zifencei` [RISC-V compliance tests](https://github.com/riscv/riscv-compliance).
The processor passes the official `rv32_m/C`, `rv32_m/I`, `rv32_m/M`, `rv32_m/privilege` and `rv32_m/Zifencei`
[RISC-V compliance tests (new framework v2)](https://github.com/riscv/riscv-compliance).
 
| Project component | CI status | Note |
|:--------------------------------------------------------------------------------|:----------|:---------|
| [NEORV32 processor](https://github.com/stnolting/neorv32) | [![Build Status](https://travis-ci.com/stnolting/neorv32.svg?branch=master)](https://travis-ci.com/stnolting/neorv32) | [![sw doc](https://img.shields.io/badge/SW%20documentation-gh--pages-blue)](https://stnolting.github.io/neorv32/files.html) |
| [Pre-built toolchain](https://github.com/stnolting/riscv_gcc_prebuilt) | [![Build Status](https://travis-ci.com/stnolting/riscv_gcc_prebuilt.svg?branch=master)](https://travis-ci.com/stnolting/riscv_gcc_prebuilt) | |
| [RISC-V compliance test](https://github.com/stnolting/neorv32_riscv_compliance) | [![Build Status](https://travis-ci.com/stnolting/neorv32_riscv_compliance.svg?branch=master)](https://travis-ci.com/stnolting/neorv32_riscv_compliance) | |
| Project component | CI status | Note |
|:----------------- |:----------|:---------|
| [NEORV32 processor](https://github.com/stnolting/neorv32) | [![Build Status](https://travis-ci.com/stnolting/neorv32.svg?branch=master)](https://travis-ci.com/stnolting/neorv32) | [![sw doc](https://img.shields.io/badge/SW%20documentation-gh--pages-blue)](https://stnolting.github.io/neorv32/files.html) |
| [Pre-built toolchain](https://github.com/stnolting/riscv_gcc_prebuilt) | [![Build Status](https://travis-ci.com/stnolting/riscv_gcc_prebuilt.svg?branch=master)](https://travis-ci.com/stnolting/riscv_gcc_prebuilt) | |
| RISC-V compliance test | | See [riscv-compliance/README.md](https://github.com/stnolting/neorv32/blob/master/riscv-compliance/README.md) |
 
 
### To-Do / Wish List / Help Wanted
93,13 → 95,16
* Further size and performance optimization *(work in progress)*
* A cache for the external memory/bus interface *(work in progress)*
* Burst mode for the external memory/bus interface
* RISC-V `B` extension ([bitmanipulation](https://github.com/riscv/riscv-bitmanip))
* RISC-V `B` extension ([bitmanipulation](https://github.com/riscv/riscv-bitmanip)) *(shelved)*
* Synthesis results (+ wrappers?) for more/specific platforms
* More support for FreeRTOS
* Maybe port additional RTOSs (like [Zephyr](https://github.com/zephyrproject-rtos/zephyr) or [RIOT](https://www.riot-os.org))
* Implement further RISC-V (or custom?) CPU extensions (like floating-point extension `F`)
* Port additional RTOSs (like [Zephyr](https://github.com/zephyrproject-rtos/zephyr) or [RIOT](https://www.riot-os.org))
* Single-precision floating point unit (`F`) *(planned)*
* Implement further RISC-V (or custom?) CPU extensions
* Add debugger ([RISC-V debug spec](https://github.com/riscv/riscv-debug-spec))
* Add memory-mapped trigger to testbench to quit simulation (using VHDL2008's `use std.env.finish;`) - but how? :thinking:
* ...
* [Ideas?](#Contribute)
* [Ideas?](#ContributeFeedbackQuestions)
 
 
 
106,7 → 111,7
## Features
 
The full-blown data sheet of the NEORV32 Processor and CPU is available as pdf file:
[![NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/PDF_32.png) NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf).
[:page_facing_up: NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf).
 
### NEORV32 Processor Features
 
132,12 → 137,14
 
### NEORV32 CPU Features
 
The NEORV32 CPU is [compliant](https://github.com/stnolting/neorv32_riscv_compliance) to the
The NEORV32 CPU is **compliant** to the
[official RISC-V specifications (2.2)](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/riscv-spec.pdf) including a subset of the
[RISC-V privileged architecture specifications (1.12-draft)](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/riscv-spec.pdf).
[RISC-V privileged architecture specifications (1.12-draft)](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/riscv-spec.pdf)
tested via the [official RISC-V Compliance Test Framework](https://github.com/riscv/riscv-compliance)
(see [`riscv-compliance/README`](https://github.com/stnolting/neorv32/blob/master/riscv-compliance/README.md)).
 
More information regarding the CPU including a detailed list of the instruction set and the available CSRs can be found in
the [NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf).
the [:page_facing_up: NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf).
 
 
**General**:
144,7 → 151,7
* Modified Harvard architecture (separate CPU interfaces for data and instructions; NEORV32 processor: Single processor-internal bus via I/D mux)
* Two stages in-order pipeline (FETCH, EXECUTE); each stage uses a multi-cycle processing scheme
* No hardware support of unaligned accesses - they will trigger an exception
* Little-endian byte order
* BIG-ENDIAN byte-order, processor's external memory interface allows endianness configuration to connect to system with different endianness
* All reserved or unimplemented instructions will raise an illegal instruction exception
* Privilege levels: `machine` mode, `user` mode (if enabled via `U` extension)
* Official [RISC-V open-source architecture ID](https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md)
155,6 → 162,7
* Jump and branch instructions: `JAL` `JALR` `BEQ` `BNE` `BLT` `BGE` `BLTU` `BGEU`
* Memory instructions: `LB` `LH` `LW` `LBU` `LHU` `SB` `SH` `SW`
* System instructions: `ECALL` `EBREAK` `FENCE`
* Pseudo-instructions are not listed
 
**Compressed instructions** (`C` extension):
* ALU instructions: `C.ADDI4SPN` `C.ADDI` `C.ADD` `C.ADDI16SP` `C.LI` `C.LUI` `C.SLLI` `C.SRLI` `C.SRAI` `C.ANDI` `C.SUB` `C.XOR` `C.OR` `C.AND` `C.MV` `C.NOP`
161,6 → 169,7
* Jump and branch instructions: `C.J` `C.JAL` `C.JR` `C.JALR` `C.BEQZ` `C.BNEZ`
* Memory instructions: `C.LW` `C.SW` `C.LWSP` `C.SWSP`
* System instructions: `C.EBREAK` (only with `Zicsr` extension)
* Pseudo-instructions are not listed
 
**Embedded CPU version** (`E` extension):
* Reduced register file (only the 16 lowest registers)
172,15 → 181,15
* Multiplications can be mapped to DSPs via the `FAST_MUL_EN` generic to increase performance
 
**Atomic memory access** (`A` extension):
* Supported instruction: `LR.W` `SC.W`
* By default, the multiplier and divider cores use an iterative bit-serial processing scheme
* Supported instructions: `LR.W` (load-reservate) `SC.W` (store-conditional)
 
**Privileged architecture / CSR access** (`Zicsr` extension):
* Privilege levels: `M-mode` (Machine mode)
* CSR access instructions: `CSRRW` `CSRRS` `CSRRC` `CSRRWI` `CSRRSI` `CSRRCI`
* System instructions: `MRET` `WFI`
* Pseudo-instructions are not listed
* Counter CSRs: `cycle` `cycleh` `instret` `instreth` `time` `timeh` `mcycle` `mcycleh` `minstret` `minstreth`
* Machine CSRs: `mstatus` `misa`(read-only!) `mie` `mtvec` `mscratch` `mepc` `mcause` `mtval` `mip` `mvendorid` [`marchid`](https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md) `mimpid` `mhartid` `mzext`(custom)
* Machine CSRs: `mstatus` `mstatush` `misa`(read-only!) `mie` `mtvec` `mscratch` `mepc` `mcause` `mtval` `mip` `mvendorid` [`marchid`](https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md) `mimpid` `mhartid` `mzext`(custom)
* Supported exceptions and interrupts:
* Misaligned instruction address
* Instruction access fault (via unacknowledged bus access after timeout)
190,8 → 199,9
* Load access fault (via unacknowledged bus access after timeout)
* Store address misaligned
* Store access fault (via unacknowledged bus access after timeout)
* Environment call from M-mode (via `ecall` instruction)
* Machine timer interrupt `mti` (via processor's MTIME unit)
* Environment call from U-mode (via `ecall` instruction in user mode)
* Environment call from M-mode (via `ecall` instruction in machine mode)
* Machine timer interrupt `mti` (via processor's MTIME unit / external signal)
* Machine software interrupt `msi` (via external signal)
* Machine external interrupt `mei` (via external signal)
* Four fast interrupt requests (custom extension)
199,7 → 209,7
**Privileged architecture / User mode** (`U` extension, requires `Zicsr` extension):
* Privilege levels: `M-mode` (Machine mode) + `U-mode` (User mode)
 
**Privileged architecture / FENCE.I** (`Zifencei` extension):
**Privileged architecture / instruction stream synchronization** (`Zifencei` extension):
* System instructions: `FENCE.I`
 
**Privileged architecture / Physical memory protection** (`PMP`, requires `Zicsr` extension):
208,9 → 218,11
 
### Non-RISC-V-Compliant Issues
 
* CPU and Processor are BIG-ENDIAN, but this should be no problem as the external memory bus interface provides big- and little-endian configurations
* `misa` CSR is read-only - no dynamic enabling/disabling of synthesized CPU extensions during runtime; for compatibility: write accesses (in m-mode) are ignored and do not cause an exception
* The physical memory protection (**PMP**) only supports `NAPOT` mode, a minimal granularity of 8 bytes and only up to 8 regions
* The `A` extension only implements `lr.w` and `sc.w` instructions yet. However, these instructions are sufficient to emulate all further AMO operations
* The `mcause` trap code `0x80000000` (originally reserved in the RISC-V specs) is used to indicate a hardware reset (non-maskable reset).
 
 
### NEORV32-Specific CPU Extensions
219,6 → 231,7
 
* Four *fast interrupt* request channels with according control/status bits in `mie` and `mip` and custom exception codes in `mcause`
* `mzext` CSR to check for implemented `Z*` CPU extensions (like `Zifencei`)
* All undefined/umimplemented/malformed/illegal instructions do raise an illegal instruction exception
 
 
 
229,17 → 242,18
This chapter shows exemplary implementation results of the NEORV32 CPU for an **Intel Cyclone IV EP4CE22F17C6N FPGA** on
a DE0-nano board. The design was synthesized using **Intel Quartus Prime Lite 20.1** ("balanced implementation"). The timing
information is derived from the Timing Analyzer / Slow 1200mV 0C Model. If not otherwise specified, the default configuration
of the CPU's generics is assumed (for example no PMP). No constraints were used at all.
of the CPU's generics is assumed (for example no PMP). No constraints were used at all. The `u` and `Zifencei` extensions have
a negligible impact on the hardware requirements.
 
Results generated for hardware version `1.4.8.0`.
Results generated for hardware version [`1.4.9.0`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
 
| CPU Configuration | LEs | FFs | Memory bits | DSPs | f_max |
|:----------------------------------------|:----------:|:--------:|:-----------:|:----:|:--------:|
| `rv32i` | 945 | 417 | 2048 | 0 | ~122 MHz |
| `rv32i` + `u` + `Zicsr` + `Zifencei` | 1944 | 901 | 2048 | 0 | ~119 MHz |
| `rv32im` + `u` + `Zicsr` + `Zifencei` | 2551 | 1147 | 2048 | 0 | ~117 MHz |
| `rv32imc` + `u` + `Zicsr` + `Zifencei` | 2800 | 1162 | 2048 | 0 | ~113 MHz |
| `rv32imac` + `u` + `Zicsr` + `Zifencei` | 1796 | 1165 | 2048 | 0 | ~113 MHz |
| CPU Configuration | LEs | FFs | Memory bits | DSPs | f_max |
|:----------------------------------------|:----------:|:--------:|:-----------:|:----:|:-------:|
| `rv32i` | 1190 | 512 | 2048 | 0 | 120 MHz |
| `rv32i` + `u` + `Zicsr` + `Zifencei` | 1927 | 903 | 2048 | 0 | 123 MHz |
| `rv32im` + `u` + `Zicsr` + `Zifencei` | 2471 | 1148 | 2048 | 0 | 120 MHz |
| `rv32imc` + `u` + `Zicsr` + `Zifencei` | 2716 | 1165 | 2048 | 0 | 120 MHz |
| `rv32imac` + `u` + `Zicsr` + `Zifencei` | 2736 | 1168 | 2048 | 0 | 122 MHz |
 
Setups with enabled "embedded CPU extension" `E` show the same LUT and FF utilization and identical f_max. However, the size of the register file is cut in half.
 
246,25 → 260,25
 
### NEORV32 Processor-Internal Peripherals and Memories
 
Results generated for hardware version `1.4.8.0`.
Results generated for hardware version [`1.4.9.0`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
 
| Module | Description | LEs | FFs | Memory bits | DSPs |
|:----------|:-----------------------------------------------------|----:|----:|------------:|-----:|
| BOOT ROM | Bootloader ROM (default 4kB) | 3 | 1 | 32 768 | 0 |
| BUSSWITCH | Mux for CPU I & D interfaces | 82 | 8 | 0 | 0 |
| BUSSWITCH | Mux for CPU I & D interfaces | 65 | 8 | 0 | 0 |
| CFU0 | Custom functions unit 0 | - | - | - | - |
| CFU1 | Custom functions unit 1 | - | - | - | - |
| DMEM | Processor-internal data memory (default 8kB) | 6 | 2 | 65 536 | 0 |
| GPIO | General purpose input/output ports | 66 | 65 | 0 | 0 |
| GPIO | General purpose input/output ports | 67 | 65 | 0 | 0 |
| IMEM | Processor-internal instruction memory (default 16kb) | 6 | 2 | 131 072 | 0 |
| MTIME | Machine system timer | 282 | 166 | 0 | 0 |
| MTIME | Machine system timer | 274 | 166 | 0 | 0 |
| PWM | Pulse-width modulation controller | 71 | 69 | 0 | 0 |
| SPI | Serial peripheral interface | 129 | 124 | 0 | 0 |
| SYSINFO | System configuration information memory | 9 | 9 | 0 | 0 |
| SPI | Serial peripheral interface | 138 | 124 | 0 | 0 |
| SYSINFO | System configuration information memory | 11 | 10 | 0 | 0 |
| TRNG | True random number generator | 132 | 105 | 0 | 0 |
| TWI | Two-wire interface | 77 | 44 | 0 | 0 |
| UART | Universal asynchronous receiver/transmitter | 175 | 132 | 0 | 0 |
| WDT | Watchdog timer | 59 | 45 | 0 | 0 |
| TWI | Two-wire interface | 77 | 46 | 0 | 0 |
| UART | Universal asynchronous receiver/transmitter | 176 | 132 | 0 | 0 |
| WDT | Watchdog timer | 60 | 45 | 0 | 0 |
| WISHBONE | External memory interface | 129 | 104 | 0 | 0 |
 
 
273,15 → 287,15
Exemplary processor implementation results for different FPGA platforms. The processor setup uses *the default peripheral configuration* (like no _CFUs_ and no _TRNG_),
no external memory interface and only internal instruction and data memories. IMEM uses 16kB and DMEM uses 8kB memory space. The setup's top entity connects most of the
processor's [top entity](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_top.vhd) signals
to FPGA pins - except for the Wishbone bus and the interrupt signals.
to FPGA pins - except for the Wishbone bus and the interrupt signals. The "default" strategy of each toolchain is used.
 
Results generated for hardware version `1.4.7.0`.
Results generated for hardware version [`1.4.9.0`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
 
| Vendor | FPGA | Board | Toolchain | Strategy | CPU Configuration | LUT / LE | FF / REG | DSP | Memory Bits | BRAM / EBR | SPRAM | Frequency |
|:--------|:----------------------------------|:-----------------|:---------------------------|:-------- |:-----------------------------------------------|:-----------|:-----------|:-------|:-------------|:-----------|:---------|--------------:|
| Intel | Cyclone IV `EP4CE22F17C6N` | Terasic DE0-Nano | Quartus Prime Lite 20.1 | balanced | `rv32imc` + `u` + `Zicsr` + `Zifencei` + `PMP` | 3892 (17%) | 1859 (8%) | 0 (0%) | 231424 (38%) | - | - | 113 MHz |
| Lattice | iCE40 UltraPlus `iCE40UP5K-SG48I` | Upduino v2.0 | Radiant 2.1 (Synplify Pro) | default | `rv32ic` + `u` + `Zicsr` + `Zifencei` | 4331 (82%) | 1673 (31%) | 0 (0%) | - | 12 (40%) | 4 (100%) | *c* 22.5 MHz |
| Xilinx | Artix-7 `XC7A35TICSG324-1L` | Arty A7-35T | Vivado 2019.2 | default | `rv32imc` + `u` + `Zicsr` + `Zifencei` + `PMP` | 2416 (12%) | 1900 (5%) | 0 (0%) | - | 8 (16%) | - | *c* 100 MHz |
| Vendor | FPGA | Board | Toolchain | CPU Configuration | LUT / LE | FF / REG | DSP | Memory Bits | BRAM / EBR | SPRAM | Frequency |
|:--------|:----------------------------------|:-----------------|:---------------------------|:-----------------------------------------------|:-----------|:-----------|:-------|:-------------|:-----------|:---------|--------------:|
| Intel | Cyclone IV `EP4CE22F17C6N` | Terasic DE0-Nano | Quartus Prime Lite 20.1 | `rv32imc` + `u` + `Zicsr` + `Zifencei` | 3813 (17%) | 1904 (8%) | 0 (0%) | 231424 (38%) | - | - | 119 MHz |
| Lattice | iCE40 UltraPlus `iCE40UP5K-SG48I` | Upduino v2.0 | Radiant 2.1 (Synplify Pro) | `rv32ic` + `u` + `Zicsr` + `Zifencei` | 4397 (83%) | 1679 (31%) | 0 (0%) | - | 12 (40%) | 4 (100%) | *c* 22.15 MHz |
| Xilinx | Artix-7 `XC7A35TICSG324-1L` | Arty A7-35T | Vivado 2019.2 | `rv32imc` + `u` + `Zicsr` + `Zifencei` + `PMP` | 2465 (12%) | 1912 (5%) | 0 (0%) | - | 8 (16%) | - | *c* 100 MHz |
 
**_Notes_**
* The Lattice iCE40 UltraPlus setup uses the FPGA's SPRAM memory primitives for the internal IMEM and DMEM (each 64kb).
289,7 → 303,7
* The clock frequencies marked with a "c" are constrained clocks. The remaining ones are _f_max_ results from the place and route timing reports.
* The Upduino and the Arty board have on-board SPI flash memories for storing the FPGA configuration. These device can also be used by the default NEORV32
bootloader to store and automatically boot an application program after reset (both tested successfully).
* The setups with `PMP` implement 2 regions with a minimal granularity of 32kB.
* The setups with `PMP` implement 2 regions with a minimal granularity of 64kB.
 
 
 
301,7 → 315,7
[sw/example/coremark](https://github.com/stnolting/neorv32/blob/master/sw/example/coremark) project folder. This benchmark
tests the capabilities of a CPU itself rather than the functions provided by the whole system / SoC.
 
Results generated for hardware version `1.4.7.0`.
Results generated for hardware version [`1.4.7.0`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
 
~~~
**Configuration**
341,7 → 355,7
dividing the total number of required clock cycles (only the timed core to avoid distortion due to IO wait cycles; sampled via the `cycle[h]` CSRs)
by the number of executed instructions (`instret[h]` CSRs). The executables were generated using optimization `-O3`.
 
Results generated for hardware version `1.4.7.0`.
Results generated for hardware version [`1.4.7.0`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
 
| CPU | Required Clock Cycles | Executed Instructions | Average CPI |
|:--------------------------------------------|----------------------:|----------------------:|:-----------:|
369,7 → 383,7
 
Use the top's generics to configure the system according to your needs. Each generic is initilized with the default configuration.
Detailed information regarding the interface signals and configuration generics can be found in
the [NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) (pdf).
the [:page_facing_up: NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) (pdf).
 
 
### Using the CPU in Stand-Alone Mode
377,7 → 391,7
If you do not want to use the NEORV32 processor setup, you can also use the CPU in stand-alone mode and build your own system around it.
The top entity of the stand-alone **NEORV32 CPU** is [`rtl/core/neorv32_cpu.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_cpu.vhd).
Note that the CPU uses a proprietary interface for accessing data and instruction memory. More information can be found in the
[NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf).
[:page_facing_up: NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf).
 
:warning: It is recommended to use the processor setup even if you only want to use the CPU. Simply disable all the processor-internal modules via the generics
and you will get a "CPU wrapper" that provides a minimal CPU environment and an external memory interface (like AXI4). This setup also allows to further use the default
415,7 → 429,7
 
This overview is just a short excerpt from the *Let's Get It Started* section of the NEORV32 documentary:
 
[![NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/PDF_32.png) NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf)
[:page_facing_up: NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf)
 
 
### Toolchain
430,11 → 444,10
Make sure to use the `ilp32` or `ilp32e` ABI.
 
**Alternatively**, you can download a prebuilt toolchain. I have uploaded the toolchains I am using to GitHub. These toolchains
were compiled on a 64-bit x86 Ubuntu 20.04 LTS (Ubuntu on Windows, actually). Download the toolchain of choice:
were compiled on a 64-bit x86 Ubuntu 20.04 LTS (Ubuntu on Windows, actually). Download the toolchain of choice:
[:octocat: github.com/stnolting/riscv_gcc_prebuilt](https://github.com/stnolting/riscv_gcc_prebuilt)
 
[https://github.com/stnolting/riscv_gcc_prebuilt](https://github.com/stnolting/riscv_gcc_prebuilt)
 
 
### Dowload the NEORV32 Project
 
Get the sources of the NEORV32 Processor project. The simplest way is using `git clone` (suggested for easy project updates via `git pull`):
450,10 → 463,13
Create a new project with your FPGA design tool of choice. Add all the `*.vhd` files from the [`rtl/core`](https://github.com/stnolting/neorv32/blob/master/rtl)
folder to this project. Make sure to add these files to a **new design library** called `neorv32`.
 
You can either instantiate the [processor's top entity](https://github.com/stnolting/neorv32#top-entity) or one of its
You can either instantiate the [processor's top entity](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_top.vhd) or one of its
[wrappers](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates) in your own project. If you just want to try out the processor,
you can use the simple [test setup](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_test_setup.vhd) as top entity.
 
![neorv32 test setup](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/neorv32_test_setup.png)
 
 
This test setup instantiates the processor and implements most of the peripherals and some ISA extensions. Only the UART lines, clock, reset and some GPIO output signals are
propagated as actual entity signals. Basically, it is a FPGA "hello world" example:
 
540,24 → 556,28
Blinking LED demo program
```
 
Going further: Take a look at the _Let's Get It Started!_ chapter of the [![NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/PDF_32.png) NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf).
Going further: Take a look at the _Let's Get It Started!_ chapter of the [:page_facing_up: NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf).
 
 
 
## Contribute
## Contribute/Feedback/Questions
 
I'm always thankful for help! So if you have any questions, bug reports, ideas or if you want to give some kind of feedback, feel free
to [open a new issue](https://github.com/stnolting/neorv32/issues) or directly [drop me a line](mailto:stnolting@gmail.com). If you'd like to contribute:
to [:bulb: open a new issue](https://github.com/stnolting/neorv32/issues), start a new [:sparkles: discussion on GitHub](https://github.com/stnolting/neorv32/discussions)
or directly [:e-mail: drop me a line](mailto:stnolting@gmail.com).
 
0. Check out the project's [code of conduct](https://github.com/stnolting/neorv32/tree/master/CODE_OF_CONDUCT.md)
1. [Fork](https://github.com/stnolting/neorv32/fork) this repository and clone the fork
2. Create a feature branch in your fork: `git checkout -b awesome_new_feature_branch`
3. Create a new remote for the upstream repo: `git remote add upstream https://github.com/stnolting/neorv32`
3. Commit your modifications: `git commit -m "Awesome new feature!"`
4. Push to the branch: `git push origin awesome_new_feature_branch`
5. Create a new [pull request](https://github.com/stnolting/neorv32/pulls)
If you'd like to directly contribute to this repository:
 
0. :star: this repository ;)
1. Check out the project's [code of conduct](https://github.com/stnolting/neorv32/tree/master/CODE_OF_CONDUCT.md)
2. [Fork](https://github.com/stnolting/neorv32/fork) this repository and clone the fork
3. Create a feature branch in your fork: `git checkout -b awesome_new_feature_branch`
4. Create a new remote for the upstream repo: `git remote add upstream https://github.com/stnolting/neorv32`
5. Commit your modifications: `git commit -m "Awesome new feature!"`
6. Push to the branch: `git push origin awesome_new_feature_branch`
7. Create a new [pull request](https://github.com/stnolting/neorv32/pulls)
 
 
## Legal
 
This project is released under the BSD 3-Clause license. No copyright infringement intended.
636,6 → 656,4
 
--------
 
This repository was created on June 23rd, 2020.
 
Made with :coffee: in Hannover, Germany :eu:

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.