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