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

Subversion Repositories neorv32

Compare Revisions

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

Rev 73 → Rev 74

/.gitmodules File deleted
/docs/impressum.md File deleted
/docs/datasheet/cpu.adoc
125,14 → 125,11
:sectnums:
=== RISC-V Compatibility
 
The NEORV32 CPU passes the rv32_m/I, rv32_m/M, rv32_m/C, rv32_m/privilege, and
rv32_m/Zifencei tests of the official RISC-V Architecture Tests (GitHub). The port files for the
NEORV32 processor are located in the repository's `sw/isa-test` folder.
The NEORV32 CPU passes the tests of the _RISC-V Architecture Test Framework_. This framework is used to check
RISC-V implementations for compatibility with the official RISC-V ISA specifications.
The NEORV32 port of this test framework has been moved to a separate repository:
https://github.com/stnolting/neorv32-verif
 
[NOTE]
See section https://stnolting.github.io/neorv32/ug/#_risc_v_architecture_test_framework[User Guide: RISC-V Architecture Test Framework]
for information how to run the tests on the NEORV32.
 
.**RISC-V `rv32_m/C` Tests**
...................................
Check cadd-01 ... OK
180,7 → 177,7
Check bltu-01 ... OK
Check bne-01 ... OK
Check fence-01 ... OK
Check jal-01 ... OK
Check jal-01 ... IGNORED <1>
Check jalr-01 ... OK
Check lb-align-01 ... OK
Check lbu-align-01 ... OK
210,6 → 207,7
--------------------------------
OK: 39/39 RISCV_TARGET=neorv32 RISCV_DEVICE=I XLEN=32
...................................
<1> Test is skipped due to a GHDL simulation issue.
 
.**RISC-V `rv32_m/M` Tests**
...................................
659,9 → 657,9
halted until a valid interrupt request occurs. To wake up again, at least one interrupt source has to
be enabled via the <<_mie>> CSR and the global interrupt enable flag in <<_mstatus>> has to be set.
 
If the <<_mstatus>> `TW` bis is cleared the `wfi` instruction is also allowed to execute when in user-mode.
This is always the case if user-mode is not implemented. If the `TW` bit is set the execution of `wfi` in
user-mode will raise an illegal instruction exception.
[NOTE]
Executing the `wfi` instruction is user-mode will raise an illegal instruction exception if
<<_mstatus>>.`TW` is set.
 
 
==== **`Zicntr`** CPU Base Counters
839,21 → 837,22
| ALU | `C` | `c.addi4spn` `c.nop` `c.addi` `c.li` `c.addi16sp` `c.lui` `c.andi` `c.sub` `c.xor` `c.or` `c.and` `c.add` `c.mv` | 2
| ALU | `I/E` | `slli` `srli` `srai` `sll` `srl` `sra` | 3 + SAfootnote:[Shift amount.]/4 + SA%4; FAST_SHIFTfootnote:[Barrel shift when `FAST_SHIFT_EN` is enabled.]: 4; TINY_SHIFTfootnote:[Serial shift when `TINY_SHIFT_EN` is enabled.]: 2..32
| ALU | `C` | `c.srli` `c.srai` `c.slli` | 3 + SAfootnote:[Shift amount (0..31).]; FAST_SHIFTfootnote:[Barrel shifter when `FAST_SHIFT_EN` is enabled.]:
| Branches | `I/E` | `beq` `bne` `blt` `bge` `bltu` `bgeu` | Taken: 5 + MLfootnote:[Memory latency.]; Not taken: 3
| Branches | `C` | `c.beqz` `c.bnez` | Taken: 5 + MLfootnote:[Memory latency.]; Not taken: 3
| Jumps / Calls | `I/E` | `jal` `jalr` | 4 + ML
| Jumps / Calls | `C` | `c.jal` `c.j` `c.jr` `c.jalr` | 4 + ML
| Memory access | `I/E` | `lb` `lh` `lw` `lbu` `lhu` `sb` `sh` `sw` | 4 + ML
| Memory access | `C` | `c.lw` `c.sw` `c.lwsp` `c.swsp` | 4 + ML
| Memory access | `A` | `lr.w` `sc.w` | 4 + ML
| Multiplication | `M` | `mul` `mulh` `mulhsu` `mulhu` | 2+32+2; FAST_MULfootnote:[DSP-based multiplication; enabled via `FAST_MUL_EN`.]: 4
| Division | `M` | `div` `divu` `rem` `remu` | 2+32+2
| CSR access | `Zicsr` | `csrrw` `csrrs` `csrrc` `csrrwi` `csrrsi` `csrrci` | 3
| System | `I/E` | `fence` | 3
| Branches | `I/E` | `beq` `bne` `blt` `bge` `bltu` `bgeu` | Taken: 5 + (ML-1)footnote:[Memory latency.]; Not taken: 3
| Branches | `C` | `c.beqz` `c.bnez` | Taken: 5 + (ML-1); Not taken: 3
| Jumps / Calls | `I/E` | `jal` `jalr` | 5 + (ML-1)
| Jumps / Calls | `C` | `c.jal` `c.j` `c.jr` `c.jalr` | 5 + (ML-1)
| Memory access | `I/E` | `lb` `lh` `lw` `lbu` `lhu` `sb` `sh` `sw` | 5 + (ML-2)
| Memory access | `C` | `c.lw` `c.sw` `c.lwsp` `c.swsp` | 5 + (ML-2)
| Memory access | `A` | `lr.w` `sc.w` | 5 + (ML-2)
| MulDiv | `M` | `mul` `mulh` `mulhsu` `mulhu` | 2+32+2; FAST_MULfootnote:[DSP-based multiplication; enabled via `FAST_MUL_EN`.]: 4
| MulDiv | `M` | `div` `divu` `rem` `remu` | 2+32+2
| System | `Zicsr` | `csrrw` `csrrs` `csrrc` `csrrwi` `csrrsi` `csrrci` | 3
| System | `Zicsr` | `ecall` `ebreak` | 3
| System | `Zicsr`+`C` | `c.break` | 3
| System | `Zicsr` | `mret` `wfi` | 6
| System | `Zifencei` | `fence.i` | 3 + ML
| System | `Zicsr`+`C` | `c.break` | 3
| System | `Zicsr` | `wfi` | 3
| System | `Zicsr` | `mret` `dret` | 5
| Fence | `I/E` | `fence` | 4 + ML
| Fence | `Zifencei` | `fence.i` | 4 + ML
| Floating-point - artihmetic | `Zfinx` | `fadd.s` | 110
| Floating-point - artihmetic | `Zfinx` | `fsub.s` | 112
| Floating-point - artihmetic | `Zfinx` | `fmul.s` | 22
871,7 → 870,7
| Bit-manipulation - carry-less multiply | `B(Zbc)` | `clmul` `clmulh` `clmulr` | 3 + 32
| Custom instructions (CFU) | `Zxcfu` | - | min. 4
| | | |
| _Illegal instructions_ | `Zicsr` | - | 2
| _Illegal instructions_ | `Zicsr` | - | min. 2
|=======================
 
[NOTE]
969,38 → 968,38
[cols="3,6,5,14,11,4,4"]
[options="header",grid="rows"]
|=======================
| Prio. | `mcause` | [RISC-V] | ID [C] | Cause | `mepc` | `mtval`
| Prio. | `mcause` | [RISC-V] | ID [C] | Cause | `mepc` | `mtval`
7+^| **Synchronous Exceptions**
| 1 | `0x00000000` | 0.0 | _TRAP_CODE_I_MISALIGNED_ | instruction address misaligned | **PC** | **ADR**
| 2 | `0x00000001` | 0.1 | _TRAP_CODE_I_ACCESS_ | instruction access bus fault | **PC** | **ADR**
| 3 | `0x00000002` | 0.2 | _TRAP_CODE_I_ILLEGAL_ | illegal instruction | **PC** | **INST**
| 4 | `0x0000000B` | 0.11 | _TRAP_CODE_MENV_CALL_ | environment call from M-mode | **PC** | **0**
| 5 | `0x00000008` | 0.8 | _TRAP_CODE_UENV_CALL_ | environment call from U-mode | **PC** | **0**
| 6 | `0x00000003` | 0.3 | _TRAP_CODE_BREAKPOINT_ | breakpoint instruction | **PC** | **PC**
| 7 | `0x00000006` | 0.6 | _TRAP_CODE_S_MISALIGNED_ | store address misaligned | **PC** | **ADR**
| 8 | `0x00000004` | 0.4 | _TRAP_CODE_L_MISALIGNED_ | load address misaligned | **PC** | **ADR**
| 9 | `0x00000007` | 0.7 | _TRAP_CODE_S_ACCESS_ | store access bus fault | **PC** | **ADR**
| 10 | `0x00000005` | 0.5 | _TRAP_CODE_L_ACCESS_ | load access bus fault | **PC** | **ADR**
| 1 | `0x00000000` | 0.0 | _TRAP_CODE_I_MISALIGNED_ | instruction address misaligned | **PC** | **ADR**
| 2 | `0x00000001` | 0.1 | _TRAP_CODE_I_ACCESS_ | instruction access bus fault | **PC** | **ADR**
| 3 | `0x00000002` | 0.2 | _TRAP_CODE_I_ILLEGAL_ | illegal instruction | **PC** | **INST**
| 4 | `0x0000000B` | 0.11 | _TRAP_CODE_MENV_CALL_ | environment call from M-mode (`ecall`) | **PC** | **0**
| 5 | `0x00000008` | 0.8 | _TRAP_CODE_UENV_CALL_ | environment call from U-mode (`ecall`) | **PC** | **0**
| 6 | `0x00000003` | 0.3 | _TRAP_CODE_BREAKPOINT_ | software breakpoint (`ebreak`) | **PC** | **0**
| 7 | `0x00000006` | 0.6 | _TRAP_CODE_S_MISALIGNED_ | store address misaligned | **PC** | **ADR**
| 8 | `0x00000004` | 0.4 | _TRAP_CODE_L_MISALIGNED_ | load address misaligned | **PC** | **ADR**
| 9 | `0x00000007` | 0.7 | _TRAP_CODE_S_ACCESS_ | store access bus fault | **PC** | **ADR**
| 10 | `0x00000005` | 0.5 | _TRAP_CODE_L_ACCESS_ | load access bus fault | **PC** | **ADR**
7+^| **Asynchronous Exceptions (Interrupts)**
| 11 | `0x80000010` | 1.16 | _TRAP_CODE_FIRQ_0_ | fast interrupt request channel 0 | **IPC** | **0**
| 12 | `0x80000011` | 1.17 | _TRAP_CODE_FIRQ_1_ | fast interrupt request channel 1 | **IPC** | **0**
| 13 | `0x80000012` | 1.18 | _TRAP_CODE_FIRQ_2_ | fast interrupt request channel 2 | **IPC** | **0**
| 14 | `0x80000013` | 1.19 | _TRAP_CODE_FIRQ_3_ | fast interrupt request channel 3 | **IPC** | **0**
| 15 | `0x80000014` | 1.20 | _TRAP_CODE_FIRQ_4_ | fast interrupt request channel 4 | **IPC** | **0**
| 16 | `0x80000015` | 1.21 | _TRAP_CODE_FIRQ_5_ | fast interrupt request channel 5 | **IPC** | **0**
| 17 | `0x80000016` | 1.22 | _TRAP_CODE_FIRQ_6_ | fast interrupt request channel 6 | **IPC** | **0**
| 18 | `0x80000017` | 1.23 | _TRAP_CODE_FIRQ_7_ | fast interrupt request channel 7 | **IPC** | **0**
| 19 | `0x80000018` | 1.24 | _TRAP_CODE_FIRQ_8_ | fast interrupt request channel 8 | **IPC** | **0**
| 20 | `0x80000019` | 1.25 | _TRAP_CODE_FIRQ_9_ | fast interrupt request channel 9 | **IPC** | **0**
| 21 | `0x8000001a` | 1.26 | _TRAP_CODE_FIRQ_10_ | fast interrupt request channel 10 | **IPC** | **0**
| 22 | `0x8000001b` | 1.27 | _TRAP_CODE_FIRQ_11_ | fast interrupt request channel 11 | **IPC** | **0**
| 23 | `0x8000001c` | 1.28 | _TRAP_CODE_FIRQ_12_ | fast interrupt request channel 12 | **IPC** | **0**
| 24 | `0x8000001d` | 1.29 | _TRAP_CODE_FIRQ_13_ | fast interrupt request channel 13 | **IPC** | **0**
| 25 | `0x8000001e` | 1.30 | _TRAP_CODE_FIRQ_14_ | fast interrupt request channel 14 | **IPC** | **0**
| 26 | `0x8000001f` | 1.31 | _TRAP_CODE_FIRQ_15_ | fast interrupt request channel 15 | **IPC** | **0**
| 27 | `0x8000000B` | 1.11 | _TRAP_CODE_MEI_ | machine external interrupt (MEI) | **IPC** | **0**
| 28 | `0x80000003` | 1.3 | _TRAP_CODE_MSI_ | machine software interrupt (MSI) | **IPC** | **0**
| 29 | `0x80000007` | 1.7 | _TRAP_CODE_MTI_ | machine timer interrupt (MTI) | **IPC** | **0**
| 11 | `0x80000010` | 1.16 | _TRAP_CODE_FIRQ_0_ | fast interrupt request channel 0 | **IPC** | **0**
| 12 | `0x80000011` | 1.17 | _TRAP_CODE_FIRQ_1_ | fast interrupt request channel 1 | **IPC** | **0**
| 13 | `0x80000012` | 1.18 | _TRAP_CODE_FIRQ_2_ | fast interrupt request channel 2 | **IPC** | **0**
| 14 | `0x80000013` | 1.19 | _TRAP_CODE_FIRQ_3_ | fast interrupt request channel 3 | **IPC** | **0**
| 15 | `0x80000014` | 1.20 | _TRAP_CODE_FIRQ_4_ | fast interrupt request channel 4 | **IPC** | **0**
| 16 | `0x80000015` | 1.21 | _TRAP_CODE_FIRQ_5_ | fast interrupt request channel 5 | **IPC** | **0**
| 17 | `0x80000016` | 1.22 | _TRAP_CODE_FIRQ_6_ | fast interrupt request channel 6 | **IPC** | **0**
| 18 | `0x80000017` | 1.23 | _TRAP_CODE_FIRQ_7_ | fast interrupt request channel 7 | **IPC** | **0**
| 19 | `0x80000018` | 1.24 | _TRAP_CODE_FIRQ_8_ | fast interrupt request channel 8 | **IPC** | **0**
| 20 | `0x80000019` | 1.25 | _TRAP_CODE_FIRQ_9_ | fast interrupt request channel 9 | **IPC** | **0**
| 21 | `0x8000001a` | 1.26 | _TRAP_CODE_FIRQ_10_ | fast interrupt request channel 10 | **IPC** | **0**
| 22 | `0x8000001b` | 1.27 | _TRAP_CODE_FIRQ_11_ | fast interrupt request channel 11 | **IPC** | **0**
| 23 | `0x8000001c` | 1.28 | _TRAP_CODE_FIRQ_12_ | fast interrupt request channel 12 | **IPC** | **0**
| 24 | `0x8000001d` | 1.29 | _TRAP_CODE_FIRQ_13_ | fast interrupt request channel 13 | **IPC** | **0**
| 25 | `0x8000001e` | 1.30 | _TRAP_CODE_FIRQ_14_ | fast interrupt request channel 14 | **IPC** | **0**
| 26 | `0x8000001f` | 1.31 | _TRAP_CODE_FIRQ_15_ | fast interrupt request channel 15 | **IPC** | **0**
| 27 | `0x8000000B` | 1.11 | _TRAP_CODE_MEI_ | machine external interrupt (MEI) | **IPC** | **0**
| 28 | `0x80000003` | 1.3 | _TRAP_CODE_MSI_ | machine software interrupt (MSI) | **IPC** | **0**
| 29 | `0x80000007` | 1.7 | _TRAP_CODE_MTI_ | machine timer interrupt (MTI) | **IPC** | **0**
|=======================
 
 
/docs/datasheet/cpu_csr.adoc
304,6 → 304,7
3+| The `mtvec` CSR is compatible to the RISC-V specifications. It stores the base address for ALL machine
traps. Thus, it defines the main entry point for exception/interrupt handling regardless of the actual trap
source. The lowest two bits of this register are always zero and cannot be modified (= address mode only).
Hence, the trap handler's base address has to be aligned to a 4-byte boundary.
|=======================
 
.Machine trap-handler base address
422,8 → 423,8
| 0x343 | **Machine bad address or instruction** | `mtval`
3+| Reset value: _UNDEFINED_
3+| The `mtval` CSR is compatible to the RISC-V specifications. When a trap is triggered, the CSR shows either
the faulting address (for misaligned/faulting load/stores/fetch) or the faulting instruction itself (for illegal
instructions). For interrupts the CSR is set to zero.
the faulting address (for misaligned/faulting load/store/fetch) or the faulting (decompressed) instruction word itself (for illegal
instructions). For all other exceptions (including interrupts) the CSR is set to zero.
|=======================
 
.Machine bad address or instruction register
432,15 → 433,19
|=======================
| Trap cause | `mtval` content
| misaligned instruction fetch address or instruction fetch access fault | address of faulting instruction fetch
| breakpoint | program counter (= address) of faulting instruction itself
| misaligned load address, load access fault, misaligned store address or store access fault | program counter (= address) of faulting instruction itself
| illegal instruction | actual instruction word of faulting instruction
| misaligned load address, load access fault, misaligned store address or store access fault | program counter (= address) of faulting instruction
| illegal instruction | actual instruction word of faulting instruction (decoded 32-bit instruction word if caused by a compressed instruction)
| anything else including interrupts | _0x00000000_ (always zero)
|=======================
 
[IMPORTAN]
[IMPORTANT]
The NEORV32 `mtval` CSR is read-only. However, a write access will _NOT_ raise an illegal instruction exception.
 
[NOTE]
In case an invalid compressed instruction raised an illegal instruction exception, `mtval` will show the
according de-compressed instruction word. To get the "real" 16-bit instruction that caused the exception
perform a memory load using the address stored in <<_mepc>>.
 
:sectnums!:
===== **`mip`**
 
/docs/datasheet/overview.adoc
139,10 → 139,7
├lib - Processor core library
│├include - Header files (*.h)
│└source - Source files (*.c)
├image_gen - Helper program to generate NEORV32 executables
├isa-test
│├riscv-arch-test - RISC-V spec. compatibility test framework (submodule)
│└port-neorv32 - Port files for the official RISC-V architecture tests
├image_gen - Helper program to generate NEORV32 executables^
├ocd_firmware - Source code for on-chip debugger's "park loop"
├openocd - OpenOCD on-chip debugger configuration files
â””svd - Processor system view description file (CMSIS-SVD)
236,7 → 233,7
[cols="<2,<8"]
[grid="topbot"]
|=======================
| HW version: | `1.6.8.3`
| HW version: | `1.6.9.8`
| Top entity: | `rtl/core/neorv32_cpu.vhd`
| FPGA: | Intel Cyclone IV E `EP4CE22F17C6`
| Toolchain: | Quartus Prime Lite 21.1
247,18 → 244,18
[options="header",grid="rows"]
|=======================
| CPU ISA Configuration | LEs | FFs | MEM bits | DSPs | _f~max~_
| `rv32e` | 900 | 388 | 512 | 0 | 121 MHz
| `rv32i` | 904 | 388 | 1024 | 0 | 121 MHz
| `rv32i_Zicsr` | 1425 | 673 | 1024 | 0 | 118 MHz
| `rv32i_Zicsr_Zicntr` | 1778 | 803 | 1024 | 0 | 118 MHz
| `rv32im_Zicsr_Zicntr` | 2244 | 978 | 1024 | 0 | 118 MHz
| `rv32ima_Zicsr_Zicntr` | 2267 | 982 | 1024 | 0 | 118 MHz
| `rv32imac_Zicsr_Zicntr` | 2453 | 994 | 1024 | 0 | 118 MHz
| `rv32imacb_Zicsr_Zicntr` | 3270 | 1249 | 1024 | 0 | 118 MHz
| `rv32imacbu_Zicsr_Zicntr` | 3286 | 1254 | 1024 | 0 | 118 MHz
| `rv32imacbu_Zicsr_Zicntr_Zifencei` | 3278 | 1254 | 1024 | 0 | 118 MHz
| `rv32imacbu_Zicsr_Zicntr_Zifencei_Zfinx` | 4536 | 1906 | 1024 | 7 | 115 MHz
| `rv32imacbu_Zicsr_Zicntr_Zifencei_Zfinx_DebugMode` | 5989 | 2416 | 1024 | 7 | 110 MHz
| `rv32e` | 830 | 400 | 512 | 0 | 129 MHz
| `rv32i` | 834 | 400 | 1024 | 0 | 129 MHz
| `rv32i_Zicsr` | 1328 | 678 | 1024 | 0 | 128 MHz
| `rv32i_Zicsr_Zicntr` | 1614 | 808 | 1024 | 0 | 128 MHz
| `rv32im_Zicsr_Zicntr` | 2087 | 983 | 1024 | 0 | 128 MHz
| `rv32ima_Zicsr_Zicntr` | 2129 | 987 | 1024 | 0 | 128 MHz
| `rv32imac_Zicsr_Zicntr` | 2338 | 992 | 1024 | 0 | 128 MHz
| `rv32imacb_Zicsr_Zicntr` | 3175 | 1247 | 1024 | 0 | 128 MHz
| `rv32imacbu_Zicsr_Zicntr` | 3186 | 1254 | 1024 | 0 | 128 MHz
| `rv32imacbu_Zicsr_Zicntr_Zifencei` | 3187 | 1254 | 1024 | 0 | 128 MHz
| `rv32imacbu_Zicsr_Zicntr_Zifencei_Zfinx` | 4450 | 1906 | 1024 | 7 | 123 MHz
| `rv32imacbu_Zicsr_Zicntr_Zifencei_Zfinx_DebugMode` | 4825 | 2018 | 1024 | 7 | 123 MHz
|=======================
 
.**RISC-V Compliance**
/docs/datasheet/soc.adoc
1376,18 → 1376,20
memories, an external memory interface and a bus infrastructure to interconnect all units. Additionally, the
system implements an internal reset generator and a global clock generator/divider.
 
 
**Internal Reset Generator**
 
[IMPORTANT]
Most processor-internal modules - except for the CPU and the watchdog timer - do not have a dedicated
reset signal. However, all devices can be reset by software by clearing the corresponding unit's control
register. The automatically included application start-up code (`crt0.S`) will perform a software-reset of all
modules to ensure a clean system reset state.
 
The hardware reset signal of the processor can either be
triggered via the external reset pin (`rstn_i`, low-active) or by the internal watchdog timer (if implemented).
Before the external reset signal is applied to the system, it is extended to have a minimal duration of eight
clock cycles.
The hardware reset signal of the processor can either be triggered via the external reset pin (`rstn_i`, low-active),
by the internal watchdog timer (if implemented) or by the on-chip debugger. The external reset signal `rstn_i`
is extended to be active for at least 4 cycles when triggered.
 
 
**Internal Clock Divider**
 
An internal clock divider generates 8 clock signals derived from the processor's main clock input `clk_i`.
1410,6 → 1412,7
| Resulting clock: | _f/2_ | _f/4_ | _f/8_ | _f/64_ | _f/128_ | _f/1024_| _f/2048_| _f/4096_
|=======================
 
 
**Peripheral / IO Devices**
 
The processor-internal peripheral/IO devices are located at the end of the 32-bit address space at base
1449,6 → 1452,7
[TIP]
A CMSIS-SVD-compatible **System View Description (SVD)** file including all peripherals is available in `sw/svd`.
 
 
**Interrupts of Processor-Internal Modules**
 
Most peripheral/IO devices provide some kind of interrupt (for example to signal available incoming data). These
1455,6 → 1459,7
interrupts are entirely mapped to the CPU's <<_custom_fast_interrupt_request_lines>>. Note that all these
interrupt lines are high-active and are permanently triggered until the IRQ-causing condition is resolved.
 
 
**Nomenclature for the Peripheral / IO Devices Listing**
 
Each peripheral device chapter features a register map showing accessible control and data registers of the
/docs/datasheet/soc_trng.adoc
26,11 → 26,17
`dieharder` battery of random number tests. More detailed information about the neoTRNG, it's architecture and a
detailed evaluation of the random number quality can be found it it's repository: https://github.com/stnolting/neoTRNG
 
.Platform Independent Architecture
[NOTE]
The TRNG features a platform independent architecture without FPGA-specific primitives, macros or
attributes so it can be synthesized for _any_ FPGA.
 
.Inferring Latches
[NOTE]
The synthesis tool might emit a warning like _"inferring latches for ... neorv32_trng ..."_. This is no problem
as this is what we actually want (the TRNG is based on latches).
 
 
**Using the TRNG**
 
The TRNG features a single register for status and data access. When the _TRNG_CTRL_EN_ control register (`CTRL`)
39,6 → 45,7
(_TRNG_CTRL_DATA_MSB_ : _TRNG_CTRL_DATA_LSB_). These bits always keep the latest valid data obtained from the TRNG
entropy source. The _TRNG_CTRL_VALID_ bit is automatically cleared when reading the control register.
 
.TRNG Reset
[NOTE]
The TRNG core does not provide a dedicated reset. In order to ensure correct operations, the TRNG should be
disabled (=reset) by clearing the _TRNG_CTRL_EN_ and waiting some milliseconds before re-enabling it.
/docs/datasheet/software.adoc
402,7 → 402,7
.Newlib Test/Demo Program
[TIP]
A simple test and demo program, which uses some of newlib's core functions (like `malloc`/`free` and `read`/`write`)
is available in `sw/example_newlib_demo`
is available in `sw/example/demo_newlib`
 
 
:sectnums:
445,11 → 445,12
The `crt0.S` start-up performs the following operations:
 
[start=1]
. Disable interrupts globally by clearing <<_mstatus>>`.mie`.
. Initialize all integer registers `x1 - x31` (or just `x1 - x15` when using the `E` CPU extension) to a defined value.
. Initialize all CPU core CSRs and also install a default "dummy" trap handler for _all_ traps. This handler catches all traps
** All interrupt sources are disabled and all pending interrupts are cleared.
. Initialize the global pointer `gp` and the stack pointer `sp` according to the <<_ram_layout>> provided by the linker script.
. Initialize all CPU core CSRs and also install a default "dummy" trap handler for _all_ traps. This handler catches all traps
during the early boot phase.
. All interrupt sources are disabled and all pending interrupts are cleared.
. Clear all counter CSRs and stop auto-increment.
. Clear IO area: Write zero to all memory-mapped registers within the IO region (`iodev` section). If certain devices have not
been implemented, a bus access fault exception will occur. This exception is captured by the dummy trap handler.
/docs/figures/neorv32_logo_front.png Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
docs/figures/neorv32_logo_front.png Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: docs/userguide/riscv_architecture_tests.adoc =================================================================== --- docs/userguide/riscv_architecture_tests.adoc (revision 73) +++ docs/userguide/riscv_architecture_tests.adoc (nonexistent) @@ -1,12 +0,0 @@ -<<< -:sectnums: -== RISC-V Architecture Test Framework - -The NEORV32 Processor passes the according tests provided by the official RISC-V Architecture Test Suite -(V2.0+), which is available online at GitHub: https://github.com/riscv/riscv-arch-test - -All files required for executing the test framework on a simulated instance of the processor (including port -files) are located in the `sw/isa-test` folder of the NEORV32 repository. The test framework is executed via the -`sim/run_riscv_arch_test.sh` script. Take a look at the provided `sim/README.md` -(https://github.com/stnolting/neorv32/tree/main/sim[online at GitHub]) -file for more information on how to run the tests and how testing is conducted in detail. Index: docs/userguide/adding_custom_hw_modules.adoc =================================================================== --- docs/userguide/adding_custom_hw_modules.adoc (revision 73) +++ docs/userguide/adding_custom_hw_modules.adoc (revision 74) @@ -28,7 +28,7 @@ https://stnolting.github.io/neorv32/#_external_interrupt_controller_xirq[External Interrupt Controller (XIRQ)]. Beyond simplicity, these interface only provide a very limited bandwidth and require more sophisticated -software handling ("bit-banging" for the GPIO). Hence, i is not recommend to use them for _chip-internal_ communication. +software handling ("bit-banging" for the GPIO). Hence, it is not recommend to use them for _chip-internal_ communication. === External Bus Interface @@ -54,7 +54,7 @@ === Stream Link Interface -The https://stnolting.github.io/neorv32/#_stream_link_interface_slink[Stream Link Interface (SLINK)] provides a +The link:++https://stnolting.github.io/neorv32/#_stream_link_interface_slink++[Stream Link Interface (SLINK)] provides a point-to-point, unidirectional and parallel data interface that can be used to transfer _streaming_ data. In contrast to the external bus interface, the streaming interface does not provide any kind of advanced control, so it can be seen as "constant address bursts" where data is transmitted _sequentially_ (no random accesses).
/docs/userguide/content.adoc
48,8 → 48,6
 
include::free_rtos_support.adoc[]
 
include::riscv_architecture_tests.adoc[]
 
include::debugging_with_ocd.adoc[]
 
 
/docs/userguide/debugging_with_ocd.adoc
175,7 → 175,14
(by default, this is the beginning of the instruction memory at `0x00000000`) skipping the bootloader
and halting the CPU right before executing the `blink_led` application.
 
[IMPORTANT]
After gdb has connected to the CPU, it is recommended to disable the CPU's global interrupt flag
(`mstatus.mie`, = bit #3) to prevent unintended calls of potentially outdated trap handlers. The global
interrupt flag can be cleared using the following gdb command:
`set $mstatus = ($mstatus & ~(1<<3))`. Interrupts can be enabled globally again by the following command:
`set $mstatus = ($mstatus | (1<<3))`.
 
 
:sectnums:
==== Software Breakpoints
 
/docs/attrs.adoc
1,8 → 1,6
:author: Dipl.-Ing. Stephan Nolting
:email: stnolting@gmail.com
:keywords: neorv32, risc-v, riscv, fpga, soft-core, vhdl, microcontroller, cpu, soc, processor, gcc, openocd, gdb
:description: A size-optimized, customizable and open-source full-scale 32-bit RISC-V soft-core CPU and SoC written in platform-independent VHDL.
:revnumber: v1.6.9
:description: A size-optimized, customizable and highly extensible MCU-class 32-bit RISC-V soft-core CPU and microcontroller-like SoC written in platform-independent VHDL.
:revnumber: v1.7.0
:doctype: book
:sectnums:
:stem:
/docs/legal.adoc
34,10 → 34,9
 
==========================
**The NEORV32 RISC-V Processor** +
Copyright (c) 2022, by Dipl.-Ing. Stephan Nolting. All rights reserved. +
HQ: https://github.com/stnolting/neorv32 +
By Dipl.-Ing. Stephan Nolting +
Contact: stnolting@gmail.com +
_made in Hanover, Germany_
HQ: https://github.com/stnolting/neorv32
==========================
 
<<<
123,8 → 122,3
https://riscv.org[RISC-V] - instruction sets want to be free!
 
Continuous integration provided by https://github.com/features/actions[GitHub Actions] and powered by https://github.com/ghdl/ghdl[GHDL].
 
 
=== Impressum (Imprint)
 
See https://github.com/stnolting/neorv32/blob/main/docs/impressum.md[`docs/impressum.md`].
/rtl/core/neorv32_application_image.vhd
1,6 → 1,6
-- The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32
-- Auto-generated memory init file (for APPLICATION) from source file <blink_led/main.bin>
-- Size: 3392 bytes
-- Size: 3424 bytes
 
library ieee;
use ieee.std_logic_1164.all;
11,7 → 11,7
package neorv32_application_image is
 
constant application_init_image : mem32_t := (
00000000 => x"00000037",
00000000 => x"30047073",
00000001 => x"80002117",
00000002 => x"ff810113",
00000003 => x"80000197",
58,7 → 58,7
00000044 => x"00440413",
00000045 => x"fe941ce3",
00000046 => x"00001597",
00000047 => x"c8858593",
00000047 => x"ca858593",
00000048 => x"80000617",
00000049 => x"f4060613",
00000050 => x"80000697",
111,17 → 111,17
00000097 => x"00000593",
00000098 => x"b0050513",
00000099 => x"00112623",
00000100 => x"57c000ef",
00000101 => x"694000ef",
00000100 => x"59c000ef",
00000101 => x"6b4000ef",
00000102 => x"00050c63",
00000103 => x"500000ef",
00000103 => x"514000ef",
00000104 => x"00001537",
00000105 => x"a7850513",
00000106 => x"628000ef",
00000105 => x"a9850513",
00000106 => x"648000ef",
00000107 => x"020000ef",
00000108 => x"00001537",
00000109 => x"a5450513",
00000110 => x"618000ef",
00000109 => x"a7450513",
00000110 => x"638000ef",
00000111 => x"00c12083",
00000112 => x"00100513",
00000113 => x"01010113",
131,14 → 131,14
00000117 => x"00000593",
00000118 => x"00112623",
00000119 => x"00812423",
00000120 => x"658000ef",
00000120 => x"678000ef",
00000121 => x"00000513",
00000122 => x"00150413",
00000123 => x"00000593",
00000124 => x"0ff57513",
00000125 => x"644000ef",
00000125 => x"664000ef",
00000126 => x"0c800513",
00000127 => x"64c000ef",
00000127 => x"66c000ef",
00000128 => x"00040513",
00000129 => x"fe5ff06f",
00000130 => x"fc010113",
158,707 → 158,715
00000144 => x"01d12423",
00000145 => x"01e12223",
00000146 => x"01f12023",
00000147 => x"34102773",
00000148 => x"34071073",
00000147 => x"341026f3",
00000148 => x"34069073",
00000149 => x"342027f3",
00000150 => x"0407c463",
00000151 => x"00075683",
00000152 => x"00300593",
00000153 => x"0036f693",
00000154 => x"00270613",
00000155 => x"00b69463",
00000156 => x"00470613",
00000157 => x"34161073",
00000158 => x"00b00713",
00000159 => x"00f77663",
00000160 => x"47400793",
00000161 => x"0500006f",
00000162 => x"00001737",
00000163 => x"00279793",
00000164 => x"a9470713",
00000165 => x"00e787b3",
00000166 => x"0007a783",
00000167 => x"00078067",
00000168 => x"80000737",
00000169 => x"ffd74713",
00000150 => x"0407ce63",
00000151 => x"0006d703",
00000152 => x"01071713",
00000153 => x"01075713",
00000154 => x"00468593",
00000155 => x"30102673",
00000156 => x"00467613",
00000157 => x"00060a63",
00000158 => x"00377713",
00000159 => x"00300613",
00000160 => x"00c70463",
00000161 => x"00268593",
00000162 => x"34159073",
00000163 => x"00b00713",
00000164 => x"00f77663",
00000165 => x"48800793",
00000166 => x"0500006f",
00000167 => x"00001737",
00000168 => x"00279793",
00000169 => x"ab470713",
00000170 => x"00e787b3",
00000171 => x"01c00713",
00000172 => x"fcf768e3",
00000173 => x"00001737",
00000174 => x"00279793",
00000175 => x"ac470713",
00000176 => x"00e787b3",
00000177 => x"0007a783",
00000178 => x"00078067",
00000179 => x"800007b7",
00000180 => x"0007a783",
00000181 => x"000780e7",
00000182 => x"03c12083",
00000183 => x"03812283",
00000184 => x"03412303",
00000185 => x"03012383",
00000186 => x"02c12503",
00000187 => x"02812583",
00000188 => x"02412603",
00000189 => x"02012683",
00000190 => x"01c12703",
00000191 => x"01812783",
00000192 => x"01412803",
00000193 => x"01012883",
00000194 => x"00c12e03",
00000195 => x"00812e83",
00000196 => x"00412f03",
00000197 => x"00012f83",
00000198 => x"04010113",
00000199 => x"30200073",
00000200 => x"800007b7",
00000201 => x"0047a783",
00000202 => x"fadff06f",
00000203 => x"8081a783",
00000204 => x"fa5ff06f",
00000205 => x"80c1a783",
00000206 => x"f9dff06f",
00000207 => x"8101a783",
00000208 => x"f95ff06f",
00000209 => x"8141a783",
00000210 => x"f8dff06f",
00000211 => x"8181a783",
00000212 => x"f85ff06f",
00000213 => x"81c1a783",
00000214 => x"f7dff06f",
00000215 => x"8201a783",
00000216 => x"f75ff06f",
00000217 => x"8241a783",
00000218 => x"f6dff06f",
00000219 => x"8281a783",
00000220 => x"f65ff06f",
00000221 => x"82c1a783",
00000222 => x"f5dff06f",
00000223 => x"8301a783",
00000224 => x"f55ff06f",
00000225 => x"8341a783",
00000226 => x"f4dff06f",
00000227 => x"8381a783",
00000228 => x"f45ff06f",
00000229 => x"83c1a783",
00000230 => x"f3dff06f",
00000231 => x"8401a783",
00000232 => x"f35ff06f",
00000233 => x"8441a783",
00000234 => x"f2dff06f",
00000235 => x"8481a783",
00000236 => x"f25ff06f",
00000237 => x"84c1a783",
00000238 => x"f1dff06f",
00000239 => x"8501a783",
00000240 => x"f15ff06f",
00000241 => x"8541a783",
00000242 => x"f0dff06f",
00000243 => x"8581a783",
00000244 => x"f05ff06f",
00000245 => x"85c1a783",
00000246 => x"efdff06f",
00000247 => x"8601a783",
00000248 => x"ef5ff06f",
00000249 => x"8641a783",
00000250 => x"eedff06f",
00000251 => x"8681a783",
00000252 => x"ee5ff06f",
00000253 => x"86c1a783",
00000254 => x"eddff06f",
00000255 => x"8701a783",
00000256 => x"ed5ff06f",
00000257 => x"fe010113",
00000258 => x"01212823",
00000259 => x"00050913",
00000260 => x"00001537",
00000261 => x"00912a23",
00000262 => x"b3850513",
00000263 => x"000014b7",
00000264 => x"00812c23",
00000265 => x"01312623",
00000266 => x"00112e23",
00000267 => x"01c00413",
00000268 => x"3a0000ef",
00000269 => x"d3048493",
00000270 => x"ffc00993",
00000271 => x"008957b3",
00000272 => x"00f7f793",
00000273 => x"00f487b3",
00000274 => x"0007c503",
00000275 => x"ffc40413",
00000276 => x"368000ef",
00000277 => x"ff3414e3",
00000278 => x"01c12083",
00000279 => x"01812403",
00000280 => x"01412483",
00000281 => x"01012903",
00000282 => x"00c12983",
00000283 => x"02010113",
00000284 => x"00008067",
00000285 => x"ff010113",
00000286 => x"00112623",
00000287 => x"00812423",
00000288 => x"00912223",
00000289 => x"278000ef",
00000290 => x"1c050863",
00000291 => x"00001537",
00000292 => x"b3c50513",
00000293 => x"33c000ef",
00000294 => x"34202473",
00000295 => x"00900713",
00000296 => x"00f47793",
00000297 => x"03078493",
00000298 => x"00f77463",
00000299 => x"05778493",
00000300 => x"00b00793",
00000301 => x"0087ee63",
00000302 => x"00001737",
00000303 => x"00241793",
00000304 => x"d0070713",
00000305 => x"00e787b3",
00000306 => x"0007a783",
00000307 => x"00078067",
00000308 => x"800007b7",
00000309 => x"00b78713",
00000310 => x"14e40e63",
00000311 => x"02876a63",
00000312 => x"00378713",
00000313 => x"12e40c63",
00000314 => x"00778793",
00000315 => x"12f40e63",
00000316 => x"00001537",
00000317 => x"c9c50513",
00000318 => x"2d8000ef",
00000319 => x"00040513",
00000320 => x"f05ff0ef",
00000321 => x"00100793",
00000322 => x"08f40c63",
00000323 => x"0280006f",
00000324 => x"ff07c793",
00000325 => x"00f407b3",
00000326 => x"00f00713",
00000327 => x"fcf76ae3",
00000328 => x"00001537",
00000329 => x"c8c50513",
00000330 => x"2a8000ef",
00000331 => x"00048513",
00000332 => x"288000ef",
00000333 => x"ffd47413",
00000334 => x"00500793",
00000335 => x"06f40263",
00000336 => x"00001537",
00000337 => x"ce050513",
00000338 => x"288000ef",
00000339 => x"34002573",
00000340 => x"eb5ff0ef",
00000171 => x"0007a783",
00000172 => x"00078067",
00000173 => x"80000737",
00000174 => x"ffd74713",
00000175 => x"00e787b3",
00000176 => x"01c00713",
00000177 => x"fcf768e3",
00000178 => x"00001737",
00000179 => x"00279793",
00000180 => x"ae470713",
00000181 => x"00e787b3",
00000182 => x"0007a783",
00000183 => x"00078067",
00000184 => x"800007b7",
00000185 => x"0007a783",
00000186 => x"000780e7",
00000187 => x"03c12083",
00000188 => x"03812283",
00000189 => x"03412303",
00000190 => x"03012383",
00000191 => x"02c12503",
00000192 => x"02812583",
00000193 => x"02412603",
00000194 => x"02012683",
00000195 => x"01c12703",
00000196 => x"01812783",
00000197 => x"01412803",
00000198 => x"01012883",
00000199 => x"00c12e03",
00000200 => x"00812e83",
00000201 => x"00412f03",
00000202 => x"00012f83",
00000203 => x"04010113",
00000204 => x"30200073",
00000205 => x"800007b7",
00000206 => x"0047a783",
00000207 => x"fadff06f",
00000208 => x"8081a783",
00000209 => x"fa5ff06f",
00000210 => x"80c1a783",
00000211 => x"f9dff06f",
00000212 => x"8101a783",
00000213 => x"f95ff06f",
00000214 => x"8141a783",
00000215 => x"f8dff06f",
00000216 => x"8181a783",
00000217 => x"f85ff06f",
00000218 => x"81c1a783",
00000219 => x"f7dff06f",
00000220 => x"8201a783",
00000221 => x"f75ff06f",
00000222 => x"8241a783",
00000223 => x"f6dff06f",
00000224 => x"8281a783",
00000225 => x"f65ff06f",
00000226 => x"82c1a783",
00000227 => x"f5dff06f",
00000228 => x"8301a783",
00000229 => x"f55ff06f",
00000230 => x"8341a783",
00000231 => x"f4dff06f",
00000232 => x"8381a783",
00000233 => x"f45ff06f",
00000234 => x"83c1a783",
00000235 => x"f3dff06f",
00000236 => x"8401a783",
00000237 => x"f35ff06f",
00000238 => x"8441a783",
00000239 => x"f2dff06f",
00000240 => x"8481a783",
00000241 => x"f25ff06f",
00000242 => x"84c1a783",
00000243 => x"f1dff06f",
00000244 => x"8501a783",
00000245 => x"f15ff06f",
00000246 => x"8541a783",
00000247 => x"f0dff06f",
00000248 => x"8581a783",
00000249 => x"f05ff06f",
00000250 => x"85c1a783",
00000251 => x"efdff06f",
00000252 => x"8601a783",
00000253 => x"ef5ff06f",
00000254 => x"8641a783",
00000255 => x"eedff06f",
00000256 => x"8681a783",
00000257 => x"ee5ff06f",
00000258 => x"86c1a783",
00000259 => x"eddff06f",
00000260 => x"8701a783",
00000261 => x"ed5ff06f",
00000262 => x"fe010113",
00000263 => x"01212823",
00000264 => x"00050913",
00000265 => x"00001537",
00000266 => x"00912a23",
00000267 => x"b5850513",
00000268 => x"000014b7",
00000269 => x"00812c23",
00000270 => x"01312623",
00000271 => x"00112e23",
00000272 => x"01c00413",
00000273 => x"3ac000ef",
00000274 => x"d5048493",
00000275 => x"ffc00993",
00000276 => x"008957b3",
00000277 => x"00f7f793",
00000278 => x"00f487b3",
00000279 => x"0007c503",
00000280 => x"ffc40413",
00000281 => x"374000ef",
00000282 => x"ff3414e3",
00000283 => x"01c12083",
00000284 => x"01812403",
00000285 => x"01412483",
00000286 => x"01012903",
00000287 => x"00c12983",
00000288 => x"02010113",
00000289 => x"00008067",
00000290 => x"ff010113",
00000291 => x"00112623",
00000292 => x"00812423",
00000293 => x"00912223",
00000294 => x"284000ef",
00000295 => x"1c050863",
00000296 => x"00001537",
00000297 => x"b5c50513",
00000298 => x"348000ef",
00000299 => x"34202473",
00000300 => x"00900713",
00000301 => x"00f47793",
00000302 => x"03078493",
00000303 => x"00f77463",
00000304 => x"05778493",
00000305 => x"00b00793",
00000306 => x"0087ee63",
00000307 => x"00001737",
00000308 => x"00241793",
00000309 => x"d2070713",
00000310 => x"00e787b3",
00000311 => x"0007a783",
00000312 => x"00078067",
00000313 => x"800007b7",
00000314 => x"00b78713",
00000315 => x"14e40e63",
00000316 => x"02876a63",
00000317 => x"00378713",
00000318 => x"12e40c63",
00000319 => x"00778793",
00000320 => x"12f40e63",
00000321 => x"00001537",
00000322 => x"cbc50513",
00000323 => x"2e4000ef",
00000324 => x"00040513",
00000325 => x"f05ff0ef",
00000326 => x"00100793",
00000327 => x"08f40c63",
00000328 => x"0280006f",
00000329 => x"ff07c793",
00000330 => x"00f407b3",
00000331 => x"00f00713",
00000332 => x"fcf76ae3",
00000333 => x"00001537",
00000334 => x"cac50513",
00000335 => x"2b4000ef",
00000336 => x"00048513",
00000337 => x"294000ef",
00000338 => x"ffd47413",
00000339 => x"00500793",
00000340 => x"06f40263",
00000341 => x"00001537",
00000342 => x"ce850513",
00000343 => x"274000ef",
00000344 => x"34302573",
00000345 => x"ea1ff0ef",
00000346 => x"00812403",
00000347 => x"00c12083",
00000348 => x"00412483",
00000349 => x"00001537",
00000350 => x"cf450513",
00000351 => x"01010113",
00000352 => x"2500006f",
00000353 => x"00001537",
00000354 => x"b4450513",
00000355 => x"244000ef",
00000356 => x"fb1ff06f",
00000357 => x"00001537",
00000358 => x"b6450513",
00000359 => x"234000ef",
00000360 => x"f7c02783",
00000361 => x"0a07d463",
00000362 => x"0017f793",
00000363 => x"08078a63",
00000364 => x"00001537",
00000365 => x"cb450513",
00000366 => x"fd5ff06f",
00000367 => x"00001537",
00000368 => x"b8050513",
00000369 => x"fc9ff06f",
00000370 => x"00001537",
00000371 => x"b9450513",
00000372 => x"fbdff06f",
00000373 => x"00001537",
00000374 => x"ba050513",
00000375 => x"fb1ff06f",
00000376 => x"00001537",
00000377 => x"bb850513",
00000378 => x"fb5ff06f",
00000379 => x"00001537",
00000380 => x"bcc50513",
00000381 => x"f99ff06f",
00000382 => x"00001537",
00000383 => x"be850513",
00000384 => x"f9dff06f",
00000385 => x"00001537",
00000386 => x"bfc50513",
00000387 => x"f81ff06f",
00000388 => x"00001537",
00000389 => x"c1c50513",
00000390 => x"f75ff06f",
00000391 => x"00001537",
00000392 => x"c3c50513",
00000393 => x"f69ff06f",
00000394 => x"00001537",
00000395 => x"c5850513",
00000396 => x"f5dff06f",
00000397 => x"00001537",
00000398 => x"c7050513",
00000399 => x"f51ff06f",
00000400 => x"00001537",
00000401 => x"cc450513",
00000402 => x"f45ff06f",
00000403 => x"00001537",
00000404 => x"cd450513",
00000405 => x"f39ff06f",
00000406 => x"00c12083",
00000407 => x"00812403",
00000408 => x"00412483",
00000409 => x"01010113",
00000410 => x"00008067",
00000411 => x"01f00793",
00000412 => x"02a7e263",
00000413 => x"800007b7",
00000414 => x"00078793",
00000415 => x"00251513",
00000416 => x"00a78533",
00000417 => x"47400793",
00000418 => x"00f52023",
00000419 => x"00000513",
00000420 => x"00008067",
00000421 => x"00100513",
00000422 => x"00008067",
00000423 => x"ff010113",
00000424 => x"00112623",
00000425 => x"00812423",
00000426 => x"00912223",
00000427 => x"20800793",
00000428 => x"30579073",
00000429 => x"00000413",
00000430 => x"01d00493",
00000431 => x"00040513",
00000432 => x"00140413",
00000433 => x"0ff47413",
00000434 => x"fa5ff0ef",
00000435 => x"fe9418e3",
00000436 => x"00c12083",
00000437 => x"00812403",
00000438 => x"f6002e23",
00000439 => x"00412483",
00000440 => x"01010113",
00000441 => x"00008067",
00000442 => x"f9402583",
00000443 => x"f9002503",
00000444 => x"f9402783",
00000445 => x"fef59ae3",
00000446 => x"00008067",
00000447 => x"fe802503",
00000448 => x"01255513",
00000449 => x"00157513",
00000450 => x"00008067",
00000451 => x"ff010113",
00000452 => x"00812423",
00000453 => x"00912223",
00000454 => x"00112623",
00000455 => x"fa002023",
00000456 => x"fe002783",
00000457 => x"00058413",
00000458 => x"00151593",
00000459 => x"00078513",
00000460 => x"00060493",
00000461 => x"274000ef",
00000462 => x"01051513",
00000463 => x"000017b7",
00000464 => x"01055513",
00000465 => x"00000713",
00000466 => x"ffe78793",
00000467 => x"04a7e463",
00000468 => x"0034f793",
00000469 => x"00347413",
00000470 => x"fff50513",
00000471 => x"01479793",
00000472 => x"01641413",
00000473 => x"00f567b3",
00000474 => x"0087e7b3",
00000475 => x"01871713",
00000476 => x"00c12083",
00000477 => x"00812403",
00000478 => x"00e7e7b3",
00000479 => x"10000737",
00000480 => x"00e7e7b3",
00000481 => x"faf02023",
00000482 => x"00412483",
00000483 => x"01010113",
00000484 => x"00008067",
00000485 => x"ffe70693",
00000486 => x"0fd6f693",
00000487 => x"00069a63",
00000488 => x"00355513",
00000489 => x"00170713",
00000490 => x"0ff77713",
00000491 => x"fa1ff06f",
00000492 => x"00155513",
00000493 => x"ff1ff06f",
00000494 => x"00040737",
00000495 => x"fa002783",
00000496 => x"00e7f7b3",
00000497 => x"fe079ce3",
00000498 => x"faa02223",
00000499 => x"00008067",
00000500 => x"ff010113",
00000501 => x"00812423",
00000502 => x"01212023",
00000503 => x"00112623",
00000504 => x"00912223",
00000505 => x"00050413",
00000506 => x"00a00913",
00000507 => x"00044483",
00000508 => x"00140413",
00000509 => x"00049e63",
00000510 => x"00c12083",
00000511 => x"00812403",
00000512 => x"00412483",
00000513 => x"00012903",
00000514 => x"01010113",
00000515 => x"00008067",
00000516 => x"01249663",
00000517 => x"00d00513",
00000518 => x"fa1ff0ef",
00000519 => x"00048513",
00000520 => x"f99ff0ef",
00000521 => x"fc9ff06f",
00000522 => x"fe802503",
00000523 => x"01055513",
00000524 => x"00157513",
00000525 => x"00008067",
00000526 => x"fc000793",
00000527 => x"00a7a423",
00000528 => x"00b7a623",
00000529 => x"00008067",
00000530 => x"fe010113",
00000531 => x"00a12623",
00000532 => x"fe002503",
00000533 => x"3e800593",
00000534 => x"00112e23",
00000535 => x"00812c23",
00000536 => x"00912a23",
00000537 => x"144000ef",
00000538 => x"00c12603",
00000539 => x"00000693",
00000540 => x"00000593",
00000541 => x"09c000ef",
00000542 => x"fe802783",
00000543 => x"00020737",
00000544 => x"00050413",
00000545 => x"00e7f7b3",
00000546 => x"00058493",
00000547 => x"02078e63",
00000548 => x"e59ff0ef",
00000549 => x"00850433",
00000550 => x"00a43533",
00000551 => x"009584b3",
00000552 => x"009504b3",
00000553 => x"e45ff0ef",
00000554 => x"fe95eee3",
00000555 => x"00b49463",
00000556 => x"fe856ae3",
00000557 => x"01c12083",
00000558 => x"01812403",
00000559 => x"01412483",
00000560 => x"02010113",
00000561 => x"00008067",
00000562 => x"01c59493",
00000563 => x"00455513",
00000564 => x"00a4e533",
00000565 => x"00050a63",
00000566 => x"00050863",
00000567 => x"fff50513",
00000568 => x"00000013",
00000569 => x"ff1ff06f",
00000570 => x"fcdff06f",
00000571 => x"00050613",
00000572 => x"00000513",
00000573 => x"0015f693",
00000574 => x"00068463",
00000575 => x"00c50533",
00000576 => x"0015d593",
00000577 => x"00161613",
00000578 => x"fe0596e3",
00000579 => x"00008067",
00000580 => x"00050313",
00000581 => x"ff010113",
00000582 => x"00060513",
00000583 => x"00068893",
00000584 => x"00112623",
00000585 => x"00030613",
00000586 => x"00050693",
00000587 => x"00000713",
00000588 => x"00000793",
00000589 => x"00000813",
00000590 => x"0016fe13",
00000591 => x"00171e93",
00000592 => x"000e0c63",
00000593 => x"01060e33",
00000594 => x"010e3833",
00000595 => x"00e787b3",
00000596 => x"00f807b3",
00000597 => x"000e0813",
00000598 => x"01f65713",
00000599 => x"0016d693",
00000600 => x"00eee733",
00000601 => x"00161613",
00000602 => x"fc0698e3",
00000603 => x"00058663",
00000604 => x"f7dff0ef",
00000605 => x"00a787b3",
00000606 => x"00088a63",
00000607 => x"00030513",
00000608 => x"00088593",
00000609 => x"f69ff0ef",
00000610 => x"00f507b3",
00000611 => x"00c12083",
00000612 => x"00080513",
00000613 => x"00078593",
00000614 => x"01010113",
00000615 => x"00008067",
00000616 => x"06054063",
00000617 => x"0605c663",
00000618 => x"00058613",
00000619 => x"00050593",
00000620 => x"fff00513",
00000621 => x"02060c63",
00000622 => x"00100693",
00000623 => x"00b67a63",
00000624 => x"00c05863",
00000625 => x"00161613",
00000626 => x"00169693",
00000627 => x"feb66ae3",
00000628 => x"00000513",
00000629 => x"00c5e663",
00000630 => x"40c585b3",
00000631 => x"00d56533",
00000632 => x"0016d693",
00000633 => x"00165613",
00000634 => x"fe0696e3",
00000635 => x"00008067",
00000636 => x"00008293",
00000637 => x"fb5ff0ef",
00000638 => x"00058513",
00000639 => x"00028067",
00000640 => x"40a00533",
00000641 => x"00b04863",
00000642 => x"40b005b3",
00000643 => x"f9dff06f",
00000644 => x"40b005b3",
00000645 => x"00008293",
00000646 => x"f91ff0ef",
00000647 => x"40a00533",
00000648 => x"00028067",
00000649 => x"00008293",
00000650 => x"0005ca63",
00000651 => x"00054c63",
00000652 => x"f79ff0ef",
00000653 => x"00058513",
00000654 => x"00028067",
00000655 => x"40b005b3",
00000656 => x"fe0558e3",
00000657 => x"40a00533",
00000658 => x"f61ff0ef",
00000659 => x"40b00533",
00000660 => x"00028067",
00000661 => x"6f727245",
00000662 => x"4e202172",
00000663 => x"5047206f",
00000664 => x"75204f49",
00000665 => x"2074696e",
00000666 => x"746e7973",
00000667 => x"69736568",
00000668 => x"2164657a",
00000669 => x"0000000a",
00000670 => x"6e696c42",
00000671 => x"676e696b",
00000672 => x"44454c20",
00000673 => x"6d656420",
00000674 => x"7270206f",
00000675 => x"6172676f",
00000676 => x"00000a6d",
00000677 => x"000002cc",
00000678 => x"00000320",
00000679 => x"0000032c",
00000680 => x"00000334",
00000681 => x"0000033c",
00000682 => x"00000344",
00000683 => x"0000034c",
00000684 => x"00000354",
00000685 => x"0000035c",
00000686 => x"00000280",
00000687 => x"00000280",
00000688 => x"00000364",
00000689 => x"0000036c",
00000690 => x"00000280",
00000691 => x"00000280",
00000692 => x"00000280",
00000693 => x"00000374",
00000694 => x"00000280",
00000695 => x"00000280",
00000696 => x"00000280",
00000697 => x"0000037c",
00000698 => x"00000280",
00000699 => x"00000280",
00000700 => x"00000280",
00000701 => x"00000280",
00000702 => x"00000384",
00000703 => x"0000038c",
00000704 => x"00000394",
00000705 => x"0000039c",
00000706 => x"000003a4",
00000707 => x"000003ac",
00000708 => x"000003b4",
00000709 => x"000003bc",
00000710 => x"000003c4",
00000711 => x"000003cc",
00000712 => x"000003d4",
00000713 => x"000003dc",
00000714 => x"000003e4",
00000715 => x"000003ec",
00000716 => x"000003f4",
00000717 => x"000003fc",
00000718 => x"00007830",
00000719 => x"4554523c",
00000720 => x"0000203e",
00000721 => x"74736e49",
00000722 => x"74637572",
00000723 => x"206e6f69",
00000724 => x"72646461",
00000725 => x"20737365",
00000726 => x"6173696d",
00000727 => x"6e67696c",
00000728 => x"00006465",
00000342 => x"d0050513",
00000343 => x"294000ef",
00000344 => x"34002573",
00000345 => x"eb5ff0ef",
00000346 => x"00001537",
00000347 => x"d0850513",
00000348 => x"280000ef",
00000349 => x"34302573",
00000350 => x"ea1ff0ef",
00000351 => x"00812403",
00000352 => x"00c12083",
00000353 => x"00412483",
00000354 => x"00001537",
00000355 => x"d1450513",
00000356 => x"01010113",
00000357 => x"25c0006f",
00000358 => x"00001537",
00000359 => x"b6450513",
00000360 => x"250000ef",
00000361 => x"fb1ff06f",
00000362 => x"00001537",
00000363 => x"b8450513",
00000364 => x"240000ef",
00000365 => x"f7c02783",
00000366 => x"0a07d463",
00000367 => x"0017f793",
00000368 => x"08078a63",
00000369 => x"00001537",
00000370 => x"cd450513",
00000371 => x"fd5ff06f",
00000372 => x"00001537",
00000373 => x"ba050513",
00000374 => x"fc9ff06f",
00000375 => x"00001537",
00000376 => x"bb450513",
00000377 => x"fbdff06f",
00000378 => x"00001537",
00000379 => x"bc050513",
00000380 => x"fb1ff06f",
00000381 => x"00001537",
00000382 => x"bd850513",
00000383 => x"fb5ff06f",
00000384 => x"00001537",
00000385 => x"bec50513",
00000386 => x"f99ff06f",
00000387 => x"00001537",
00000388 => x"c0850513",
00000389 => x"f9dff06f",
00000390 => x"00001537",
00000391 => x"c1c50513",
00000392 => x"f81ff06f",
00000393 => x"00001537",
00000394 => x"c3c50513",
00000395 => x"f75ff06f",
00000396 => x"00001537",
00000397 => x"c5c50513",
00000398 => x"f69ff06f",
00000399 => x"00001537",
00000400 => x"c7850513",
00000401 => x"f5dff06f",
00000402 => x"00001537",
00000403 => x"c9050513",
00000404 => x"f51ff06f",
00000405 => x"00001537",
00000406 => x"ce450513",
00000407 => x"f45ff06f",
00000408 => x"00001537",
00000409 => x"cf450513",
00000410 => x"f39ff06f",
00000411 => x"00c12083",
00000412 => x"00812403",
00000413 => x"00412483",
00000414 => x"01010113",
00000415 => x"00008067",
00000416 => x"01f00793",
00000417 => x"02a7e263",
00000418 => x"800007b7",
00000419 => x"00078793",
00000420 => x"00251513",
00000421 => x"00a78533",
00000422 => x"48800793",
00000423 => x"00f52023",
00000424 => x"00000513",
00000425 => x"00008067",
00000426 => x"00100513",
00000427 => x"00008067",
00000428 => x"ff010113",
00000429 => x"00112623",
00000430 => x"00812423",
00000431 => x"00912223",
00000432 => x"20800793",
00000433 => x"30579073",
00000434 => x"00000793",
00000435 => x"30479073",
00000436 => x"34479073",
00000437 => x"f6002e23",
00000438 => x"00000413",
00000439 => x"01d00493",
00000440 => x"00040513",
00000441 => x"00140413",
00000442 => x"0ff47413",
00000443 => x"f95ff0ef",
00000444 => x"fe9418e3",
00000445 => x"00c12083",
00000446 => x"00812403",
00000447 => x"00412483",
00000448 => x"01010113",
00000449 => x"00008067",
00000450 => x"f9402583",
00000451 => x"f9002503",
00000452 => x"f9402783",
00000453 => x"fef59ae3",
00000454 => x"00008067",
00000455 => x"fe802503",
00000456 => x"01255513",
00000457 => x"00157513",
00000458 => x"00008067",
00000459 => x"ff010113",
00000460 => x"00812423",
00000461 => x"00912223",
00000462 => x"00112623",
00000463 => x"fa002023",
00000464 => x"fe002783",
00000465 => x"00058413",
00000466 => x"00151593",
00000467 => x"00078513",
00000468 => x"00060493",
00000469 => x"274000ef",
00000470 => x"01051513",
00000471 => x"000017b7",
00000472 => x"01055513",
00000473 => x"00000713",
00000474 => x"ffe78793",
00000475 => x"04a7e463",
00000476 => x"0034f793",
00000477 => x"00347413",
00000478 => x"fff50513",
00000479 => x"01479793",
00000480 => x"01641413",
00000481 => x"00f567b3",
00000482 => x"0087e7b3",
00000483 => x"01871713",
00000484 => x"00c12083",
00000485 => x"00812403",
00000486 => x"00e7e7b3",
00000487 => x"10000737",
00000488 => x"00e7e7b3",
00000489 => x"faf02023",
00000490 => x"00412483",
00000491 => x"01010113",
00000492 => x"00008067",
00000493 => x"ffe70693",
00000494 => x"0fd6f693",
00000495 => x"00069a63",
00000496 => x"00355513",
00000497 => x"00170713",
00000498 => x"0ff77713",
00000499 => x"fa1ff06f",
00000500 => x"00155513",
00000501 => x"ff1ff06f",
00000502 => x"00040737",
00000503 => x"fa002783",
00000504 => x"00e7f7b3",
00000505 => x"fe079ce3",
00000506 => x"faa02223",
00000507 => x"00008067",
00000508 => x"ff010113",
00000509 => x"00812423",
00000510 => x"01212023",
00000511 => x"00112623",
00000512 => x"00912223",
00000513 => x"00050413",
00000514 => x"00a00913",
00000515 => x"00044483",
00000516 => x"00140413",
00000517 => x"00049e63",
00000518 => x"00c12083",
00000519 => x"00812403",
00000520 => x"00412483",
00000521 => x"00012903",
00000522 => x"01010113",
00000523 => x"00008067",
00000524 => x"01249663",
00000525 => x"00d00513",
00000526 => x"fa1ff0ef",
00000527 => x"00048513",
00000528 => x"f99ff0ef",
00000529 => x"fc9ff06f",
00000530 => x"fe802503",
00000531 => x"01055513",
00000532 => x"00157513",
00000533 => x"00008067",
00000534 => x"fc000793",
00000535 => x"00a7a423",
00000536 => x"00b7a623",
00000537 => x"00008067",
00000538 => x"fe010113",
00000539 => x"00a12623",
00000540 => x"fe002503",
00000541 => x"3e800593",
00000542 => x"00112e23",
00000543 => x"00812c23",
00000544 => x"00912a23",
00000545 => x"144000ef",
00000546 => x"00c12603",
00000547 => x"00000693",
00000548 => x"00000593",
00000549 => x"09c000ef",
00000550 => x"fe802783",
00000551 => x"00020737",
00000552 => x"00050413",
00000553 => x"00e7f7b3",
00000554 => x"00058493",
00000555 => x"02078e63",
00000556 => x"e59ff0ef",
00000557 => x"00850433",
00000558 => x"00a43533",
00000559 => x"009584b3",
00000560 => x"009504b3",
00000561 => x"e45ff0ef",
00000562 => x"fe95eee3",
00000563 => x"00b49463",
00000564 => x"fe856ae3",
00000565 => x"01c12083",
00000566 => x"01812403",
00000567 => x"01412483",
00000568 => x"02010113",
00000569 => x"00008067",
00000570 => x"01c59493",
00000571 => x"00455513",
00000572 => x"00a4e533",
00000573 => x"00050a63",
00000574 => x"00050863",
00000575 => x"fff50513",
00000576 => x"00000013",
00000577 => x"ff1ff06f",
00000578 => x"fcdff06f",
00000579 => x"00050613",
00000580 => x"00000513",
00000581 => x"0015f693",
00000582 => x"00068463",
00000583 => x"00c50533",
00000584 => x"0015d593",
00000585 => x"00161613",
00000586 => x"fe0596e3",
00000587 => x"00008067",
00000588 => x"00050313",
00000589 => x"ff010113",
00000590 => x"00060513",
00000591 => x"00068893",
00000592 => x"00112623",
00000593 => x"00030613",
00000594 => x"00050693",
00000595 => x"00000713",
00000596 => x"00000793",
00000597 => x"00000813",
00000598 => x"0016fe13",
00000599 => x"00171e93",
00000600 => x"000e0c63",
00000601 => x"01060e33",
00000602 => x"010e3833",
00000603 => x"00e787b3",
00000604 => x"00f807b3",
00000605 => x"000e0813",
00000606 => x"01f65713",
00000607 => x"0016d693",
00000608 => x"00eee733",
00000609 => x"00161613",
00000610 => x"fc0698e3",
00000611 => x"00058663",
00000612 => x"f7dff0ef",
00000613 => x"00a787b3",
00000614 => x"00088a63",
00000615 => x"00030513",
00000616 => x"00088593",
00000617 => x"f69ff0ef",
00000618 => x"00f507b3",
00000619 => x"00c12083",
00000620 => x"00080513",
00000621 => x"00078593",
00000622 => x"01010113",
00000623 => x"00008067",
00000624 => x"06054063",
00000625 => x"0605c663",
00000626 => x"00058613",
00000627 => x"00050593",
00000628 => x"fff00513",
00000629 => x"02060c63",
00000630 => x"00100693",
00000631 => x"00b67a63",
00000632 => x"00c05863",
00000633 => x"00161613",
00000634 => x"00169693",
00000635 => x"feb66ae3",
00000636 => x"00000513",
00000637 => x"00c5e663",
00000638 => x"40c585b3",
00000639 => x"00d56533",
00000640 => x"0016d693",
00000641 => x"00165613",
00000642 => x"fe0696e3",
00000643 => x"00008067",
00000644 => x"00008293",
00000645 => x"fb5ff0ef",
00000646 => x"00058513",
00000647 => x"00028067",
00000648 => x"40a00533",
00000649 => x"00b04863",
00000650 => x"40b005b3",
00000651 => x"f9dff06f",
00000652 => x"40b005b3",
00000653 => x"00008293",
00000654 => x"f91ff0ef",
00000655 => x"40a00533",
00000656 => x"00028067",
00000657 => x"00008293",
00000658 => x"0005ca63",
00000659 => x"00054c63",
00000660 => x"f79ff0ef",
00000661 => x"00058513",
00000662 => x"00028067",
00000663 => x"40b005b3",
00000664 => x"fe0558e3",
00000665 => x"40a00533",
00000666 => x"f61ff0ef",
00000667 => x"40b00533",
00000668 => x"00028067",
00000669 => x"6f727245",
00000670 => x"4e202172",
00000671 => x"5047206f",
00000672 => x"75204f49",
00000673 => x"2074696e",
00000674 => x"746e7973",
00000675 => x"69736568",
00000676 => x"2164657a",
00000677 => x"0000000a",
00000678 => x"6e696c42",
00000679 => x"676e696b",
00000680 => x"44454c20",
00000681 => x"6d656420",
00000682 => x"7270206f",
00000683 => x"6172676f",
00000684 => x"00000a6d",
00000685 => x"000002e0",
00000686 => x"00000334",
00000687 => x"00000340",
00000688 => x"00000348",
00000689 => x"00000350",
00000690 => x"00000358",
00000691 => x"00000360",
00000692 => x"00000368",
00000693 => x"00000370",
00000694 => x"00000294",
00000695 => x"00000294",
00000696 => x"00000378",
00000697 => x"00000380",
00000698 => x"00000294",
00000699 => x"00000294",
00000700 => x"00000294",
00000701 => x"00000388",
00000702 => x"00000294",
00000703 => x"00000294",
00000704 => x"00000294",
00000705 => x"00000390",
00000706 => x"00000294",
00000707 => x"00000294",
00000708 => x"00000294",
00000709 => x"00000294",
00000710 => x"00000398",
00000711 => x"000003a0",
00000712 => x"000003a8",
00000713 => x"000003b0",
00000714 => x"000003b8",
00000715 => x"000003c0",
00000716 => x"000003c8",
00000717 => x"000003d0",
00000718 => x"000003d8",
00000719 => x"000003e0",
00000720 => x"000003e8",
00000721 => x"000003f0",
00000722 => x"000003f8",
00000723 => x"00000400",
00000724 => x"00000408",
00000725 => x"00000410",
00000726 => x"00007830",
00000727 => x"4554523c",
00000728 => x"0000203e",
00000729 => x"74736e49",
00000730 => x"74637572",
00000731 => x"206e6f69",
00000732 => x"65636361",
00000733 => x"66207373",
00000734 => x"746c7561",
00000735 => x"00000000",
00000736 => x"656c6c49",
00000737 => x"206c6167",
00000738 => x"74736e69",
00000739 => x"74637572",
00000740 => x"006e6f69",
00000741 => x"61657242",
00000742 => x"696f706b",
00000743 => x"0000746e",
00000744 => x"64616f4c",
00000745 => x"64646120",
00000746 => x"73736572",
00000747 => x"73696d20",
00000748 => x"67696c61",
00000749 => x"0064656e",
00000750 => x"64616f4c",
00000751 => x"63636120",
00000752 => x"20737365",
00000753 => x"6c756166",
00000754 => x"00000074",
00000755 => x"726f7453",
00000756 => x"64612065",
00000757 => x"73657264",
00000758 => x"696d2073",
00000759 => x"696c6173",
00000760 => x"64656e67",
00000761 => x"00000000",
00000762 => x"726f7453",
00000763 => x"63612065",
00000764 => x"73736563",
00000765 => x"75616620",
00000766 => x"0000746c",
00000767 => x"69766e45",
00000768 => x"6d6e6f72",
00000769 => x"20746e65",
00000770 => x"6c6c6163",
00000771 => x"6f726620",
00000772 => x"2d55206d",
00000773 => x"65646f6d",
00000774 => x"00000000",
00000732 => x"72646461",
00000733 => x"20737365",
00000734 => x"6173696d",
00000735 => x"6e67696c",
00000736 => x"00006465",
00000737 => x"74736e49",
00000738 => x"74637572",
00000739 => x"206e6f69",
00000740 => x"65636361",
00000741 => x"66207373",
00000742 => x"746c7561",
00000743 => x"00000000",
00000744 => x"656c6c49",
00000745 => x"206c6167",
00000746 => x"74736e69",
00000747 => x"74637572",
00000748 => x"006e6f69",
00000749 => x"61657242",
00000750 => x"696f706b",
00000751 => x"0000746e",
00000752 => x"64616f4c",
00000753 => x"64646120",
00000754 => x"73736572",
00000755 => x"73696d20",
00000756 => x"67696c61",
00000757 => x"0064656e",
00000758 => x"64616f4c",
00000759 => x"63636120",
00000760 => x"20737365",
00000761 => x"6c756166",
00000762 => x"00000074",
00000763 => x"726f7453",
00000764 => x"64612065",
00000765 => x"73657264",
00000766 => x"696d2073",
00000767 => x"696c6173",
00000768 => x"64656e67",
00000769 => x"00000000",
00000770 => x"726f7453",
00000771 => x"63612065",
00000772 => x"73736563",
00000773 => x"75616620",
00000774 => x"0000746c",
00000775 => x"69766e45",
00000776 => x"6d6e6f72",
00000777 => x"20746e65",
00000778 => x"6c6c6163",
00000779 => x"6f726620",
00000780 => x"2d4d206d",
00000780 => x"2d55206d",
00000781 => x"65646f6d",
00000782 => x"00000000",
00000783 => x"6863614d",
00000784 => x"20656e69",
00000785 => x"74666f73",
00000786 => x"65726177",
00000787 => x"746e6920",
00000788 => x"75727265",
00000789 => x"00007470",
00000790 => x"6863614d",
00000791 => x"20656e69",
00000792 => x"656d6974",
00000793 => x"6e692072",
00000794 => x"72726574",
00000795 => x"00747075",
00000796 => x"6863614d",
00000797 => x"20656e69",
00000798 => x"65747865",
00000799 => x"6c616e72",
00000800 => x"746e6920",
00000801 => x"75727265",
00000802 => x"00007470",
00000803 => x"74736146",
00000804 => x"746e6920",
00000805 => x"75727265",
00000806 => x"00207470",
00000807 => x"6e6b6e55",
00000808 => x"206e776f",
00000809 => x"70617274",
00000810 => x"75616320",
00000811 => x"203a6573",
00000812 => x"00000000",
00000813 => x"49545b20",
00000814 => x"554f454d",
00000815 => x"52455f54",
00000816 => x"00005d52",
00000817 => x"45445b20",
00000818 => x"45434956",
00000819 => x"5252455f",
00000820 => x"0000005d",
00000821 => x"4d505b20",
00000822 => x"52455f50",
00000823 => x"00005d52",
00000824 => x"50204020",
00000825 => x"00003d43",
00000826 => x"544d202c",
00000827 => x"3d4c4156",
00000828 => x"00000000",
00000829 => x"522f3c20",
00000830 => x"0a3e4554",
00000831 => x"00000000",
00000832 => x"00000584",
00000833 => x"00000594",
00000834 => x"000005bc",
00000835 => x"000005c8",
00000836 => x"000005d4",
00000837 => x"000005e0",
00000838 => x"000005ec",
00000839 => x"000005f8",
00000840 => x"00000604",
00000841 => x"000004f0",
00000842 => x"000004f0",
00000843 => x"00000610",
00000844 => x"33323130",
00000845 => x"37363534",
00000846 => x"42413938",
00000847 => x"46454443"
00000783 => x"69766e45",
00000784 => x"6d6e6f72",
00000785 => x"20746e65",
00000786 => x"6c6c6163",
00000787 => x"6f726620",
00000788 => x"2d4d206d",
00000789 => x"65646f6d",
00000790 => x"00000000",
00000791 => x"6863614d",
00000792 => x"20656e69",
00000793 => x"74666f73",
00000794 => x"65726177",
00000795 => x"746e6920",
00000796 => x"75727265",
00000797 => x"00007470",
00000798 => x"6863614d",
00000799 => x"20656e69",
00000800 => x"656d6974",
00000801 => x"6e692072",
00000802 => x"72726574",
00000803 => x"00747075",
00000804 => x"6863614d",
00000805 => x"20656e69",
00000806 => x"65747865",
00000807 => x"6c616e72",
00000808 => x"746e6920",
00000809 => x"75727265",
00000810 => x"00007470",
00000811 => x"74736146",
00000812 => x"746e6920",
00000813 => x"75727265",
00000814 => x"00207470",
00000815 => x"6e6b6e55",
00000816 => x"206e776f",
00000817 => x"70617274",
00000818 => x"75616320",
00000819 => x"203a6573",
00000820 => x"00000000",
00000821 => x"49545b20",
00000822 => x"554f454d",
00000823 => x"52455f54",
00000824 => x"00005d52",
00000825 => x"45445b20",
00000826 => x"45434956",
00000827 => x"5252455f",
00000828 => x"0000005d",
00000829 => x"4d505b20",
00000830 => x"52455f50",
00000831 => x"00005d52",
00000832 => x"50204020",
00000833 => x"00003d43",
00000834 => x"544d202c",
00000835 => x"3d4c4156",
00000836 => x"00000000",
00000837 => x"522f3c20",
00000838 => x"0a3e4554",
00000839 => x"00000000",
00000840 => x"00000598",
00000841 => x"000005a8",
00000842 => x"000005d0",
00000843 => x"000005dc",
00000844 => x"000005e8",
00000845 => x"000005f4",
00000846 => x"00000600",
00000847 => x"0000060c",
00000848 => x"00000618",
00000849 => x"00000504",
00000850 => x"00000504",
00000851 => x"00000624",
00000852 => x"33323130",
00000853 => x"37363534",
00000854 => x"42413938",
00000855 => x"46454443"
);
 
end neorv32_application_image;
/rtl/core/neorv32_bootloader_image.vhd
1,6 → 1,6
-- The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32
-- Auto-generated memory init file (for BOOTLOADER) from source file <bootloader/main.bin>
-- Size: 3916 bytes
-- Size: 3936 bytes
 
library ieee;
use ieee.std_logic_1164.all;
11,7 → 11,7
package neorv32_bootloader_image is
 
constant bootloader_init_image : mem32_t := (
00000000 => x"00000037",
00000000 => x"30047073",
00000001 => x"80010117",
00000002 => x"1f810113",
00000003 => x"80010197",
42,7 → 42,7
00000028 => x"00440413",
00000029 => x"fe941ce3",
00000030 => x"00001597",
00000031 => x"ed458593",
00000031 => x"ee858593",
00000032 => x"80010617",
00000033 => x"f8060613",
00000034 => x"80010697",
66,7 → 66,7
00000052 => x"34051073",
00000053 => x"30047073",
00000054 => x"10500073",
00000055 => x"ff9ff06f",
00000055 => x"0000006f",
00000056 => x"ff810113",
00000057 => x"00812023",
00000058 => x"00912223",
152,46 → 152,46
00000138 => x"30479073",
00000139 => x"30046073",
00000140 => x"ffff1537",
00000141 => x"d2450513",
00000141 => x"d3850513",
00000142 => x"3b8000ef",
00000143 => x"f1302573",
00000144 => x"4b8000ef",
00000145 => x"ffff1537",
00000146 => x"d5c50513",
00000146 => x"d7050513",
00000147 => x"3a4000ef",
00000148 => x"fe002503",
00000149 => x"4a4000ef",
00000150 => x"ffff1537",
00000151 => x"d6450513",
00000151 => x"d7850513",
00000152 => x"390000ef",
00000153 => x"30102573",
00000154 => x"490000ef",
00000155 => x"ffff1537",
00000156 => x"d6c50513",
00000156 => x"d8050513",
00000157 => x"37c000ef",
00000158 => x"fc002573",
00000159 => x"47c000ef",
00000160 => x"ffff1537",
00000161 => x"d7050513",
00000161 => x"d8450513",
00000162 => x"368000ef",
00000163 => x"fe802503",
00000164 => x"ffff1437",
00000165 => x"464000ef",
00000166 => x"ffff1537",
00000167 => x"d7850513",
00000167 => x"d8c50513",
00000168 => x"350000ef",
00000169 => x"ff802503",
00000170 => x"450000ef",
00000171 => x"d8040513",
00000171 => x"d9440513",
00000172 => x"340000ef",
00000173 => x"ff002503",
00000174 => x"440000ef",
00000175 => x"ffff1537",
00000176 => x"d8c50513",
00000176 => x"da050513",
00000177 => x"32c000ef",
00000178 => x"ffc02503",
00000179 => x"42c000ef",
00000180 => x"d8040513",
00000180 => x"d9440513",
00000181 => x"31c000ef",
00000182 => x"ff402503",
00000183 => x"41c000ef",
200,7 → 200,7
00000186 => x"00e7f7b3",
00000187 => x"04078c63",
00000188 => x"ffff1537",
00000189 => x"d9450513",
00000189 => x"da850513",
00000190 => x"2f8000ef",
00000191 => x"f9402683",
00000192 => x"f9002703",
218,10 → 218,10
00000204 => x"fa402683",
00000205 => x"0a06de63",
00000206 => x"ffff1537",
00000207 => x"dc050513",
00000207 => x"dd450513",
00000208 => x"2b0000ef",
00000209 => x"ffff1937",
00000210 => x"dd090513",
00000210 => x"de490513",
00000211 => x"2a4000ef",
00000212 => x"ffff1a37",
00000213 => x"ffff1ab7",
230,7 → 230,7
00000216 => x"ffff1c37",
00000217 => x"ffff1cb7",
00000218 => x"ffff1d37",
00000219 => x"e34a0513",
00000219 => x"e48a0513",
00000220 => x"280000ef",
00000221 => x"fa402403",
00000222 => x"fe045ee3",
237,7 → 237,7
00000223 => x"0ff47413",
00000224 => x"00040513",
00000225 => x"254000ef",
00000226 => x"dcca8513",
00000226 => x"de0a8513",
00000227 => x"264000ef",
00000228 => x"00010737",
00000229 => x"fa002783",
273,11 → 273,11
00000259 => x"00100513",
00000260 => x"6a4000ef",
00000261 => x"ffff1537",
00000262 => x"dcc50513",
00000262 => x"de050513",
00000263 => x"1d4000ef",
00000264 => x"228000ef",
00000265 => x"06800793",
00000266 => x"dd090513",
00000266 => x"de490513",
00000267 => x"02f40263",
00000268 => x"07500793",
00000269 => x"00000513",
286,18 → 286,18
00000272 => x"14f41c63",
00000273 => x"0004a403",
00000274 => x"00041863",
00000275 => x"e3cb8513",
00000275 => x"e50b8513",
00000276 => x"1a0000ef",
00000277 => x"f19ff06f",
00000278 => x"e58c0513",
00000278 => x"e6cc0513",
00000279 => x"194000ef",
00000280 => x"00040513",
00000281 => x"294000ef",
00000282 => x"e60c8513",
00000282 => x"e74c8513",
00000283 => x"184000ef",
00000284 => x"08000537",
00000285 => x"284000ef",
00000286 => x"e78d0513",
00000286 => x"e8cd0513",
00000287 => x"174000ef",
00000288 => x"fa402d83",
00000289 => x"fe0ddee3",
311,7 → 311,7
00000297 => x"00300513",
00000298 => x"1d8000ef",
00000299 => x"ffff1537",
00000300 => x"e8450513",
00000300 => x"e9850513",
00000301 => x"01045d93",
00000302 => x"138000ef",
00000303 => x"001d8d93",
322,11 → 322,11
00000308 => x"4788d5b7",
00000309 => x"afe58593",
00000310 => x"08000537",
00000311 => x"718000ef",
00000311 => x"72c000ef",
00000312 => x"08000537",
00000313 => x"00040593",
00000314 => x"00450513",
00000315 => x"708000ef",
00000315 => x"71c000ef",
00000316 => x"ff002603",
00000317 => x"08000737",
00000318 => x"ffc47413",
338,9 → 338,9
00000324 => x"05b41c63",
00000325 => x"00870513",
00000326 => x"40f005b3",
00000327 => x"6d8000ef",
00000327 => x"6ec000ef",
00000328 => x"ffff1537",
00000329 => x"d2050513",
00000329 => x"d3450513",
00000330 => x"f29ff06f",
00000331 => x"468000ef",
00000332 => x"fa802703",
362,7 → 362,7
00000348 => x"004d8d93",
00000349 => x"00b787b3",
00000350 => x"00f12423",
00000351 => x"678000ef",
00000351 => x"68c000ef",
00000352 => x"080007b7",
00000353 => x"00c78813",
00000354 => x"00c12603",
380,10 → 380,10
00000366 => x"e8078ae3",
00000367 => x"e65ff06f",
00000368 => x"03f00793",
00000369 => x"e94b0513",
00000369 => x"ea8b0513",
00000370 => x"e8f404e3",
00000371 => x"ffff17b7",
00000372 => x"ed078513",
00000372 => x"ee478513",
00000373 => x"e7dff06f",
00000374 => x"00040737",
00000375 => x"fa002783",
417,7 → 417,7
00000403 => x"00112623",
00000404 => x"30047073",
00000405 => x"ffff1537",
00000406 => x"c8450513",
00000406 => x"c9850513",
00000407 => x"f95ff0ef",
00000408 => x"00010737",
00000409 => x"fa002783",
431,7 → 431,7
00000417 => x"00812423",
00000418 => x"00050413",
00000419 => x"ffff1537",
00000420 => x"c9450513",
00000420 => x"ca850513",
00000421 => x"00112623",
00000422 => x"f59ff0ef",
00000423 => x"03040513",
445,7 → 445,7
00000431 => x"008787b3",
00000432 => x"ffff1537",
00000433 => x"00379793",
00000434 => x"edc50513",
00000434 => x"ef050513",
00000435 => x"00f50533",
00000436 => x"f21ff0ef",
00000437 => x"30047073",
462,7 → 462,7
00000448 => x"00050913",
00000449 => x"ffff1537",
00000450 => x"00912a23",
00000451 => x"ca050513",
00000451 => x"cb450513",
00000452 => x"ffff14b7",
00000453 => x"00812c23",
00000454 => x"01312623",
469,7 → 469,7
00000455 => x"00112e23",
00000456 => x"01c00413",
00000457 => x"ecdff0ef",
00000458 => x"f3c48493",
00000458 => x"f5048493",
00000459 => x"ffc00993",
00000460 => x"008957b3",
00000461 => x"00f7f793",
563,22 → 563,22
00000549 => x"00e7f7b3",
00000550 => x"04078663",
00000551 => x"ffff1537",
00000552 => x"ca450513",
00000552 => x"cb850513",
00000553 => x"d4dff0ef",
00000554 => x"00048513",
00000555 => x"e4dff0ef",
00000556 => x"ffff1537",
00000557 => x"ccc50513",
00000557 => x"ce050513",
00000558 => x"d39ff0ef",
00000559 => x"00040513",
00000560 => x"e39ff0ef",
00000561 => x"ffff1537",
00000562 => x"cd450513",
00000562 => x"ce850513",
00000563 => x"d25ff0ef",
00000564 => x"34302573",
00000565 => x"e25ff0ef",
00000566 => x"ffff1537",
00000567 => x"cdc50513",
00000567 => x"cf050513",
00000568 => x"d11ff0ef",
00000569 => x"00440413",
00000570 => x"34141073",
715,7 → 715,7
00000701 => x"004a0a13",
00000702 => x"02051863",
00000703 => x"ffff1537",
00000704 => x"cf450513",
00000704 => x"d0850513",
00000705 => x"aedff0ef",
00000706 => x"080005b7",
00000707 => x"00040513",
722,274 → 722,279
00000708 => x"f01ff0ef",
00000709 => x"4788d7b7",
00000710 => x"afe78793",
00000711 => x"02f50463",
00000711 => x"02f50e63",
00000712 => x"00000513",
00000713 => x"01c0006f",
00000713 => x"0240006f",
00000714 => x"ffff1537",
00000715 => x"d1450513",
00000715 => x"d2850513",
00000716 => x"ac1ff0ef",
00000717 => x"dd1ff0ef",
00000718 => x"fc0518e3",
00000719 => x"00300513",
00000720 => x"b41ff0ef",
00000721 => x"080009b7",
00000722 => x"00498593",
00000723 => x"00040513",
00000724 => x"ec1ff0ef",
00000725 => x"00050a93",
00000726 => x"00898593",
00000727 => x"00040513",
00000728 => x"eb1ff0ef",
00000729 => x"ff002c03",
00000730 => x"00050b13",
00000731 => x"ffcafb93",
00000732 => x"00000913",
00000733 => x"00000493",
00000734 => x"00c98993",
00000735 => x"013905b3",
00000736 => x"05791c63",
00000737 => x"016484b3",
00000738 => x"00200513",
00000739 => x"fa049ae3",
00000740 => x"ffff1537",
00000741 => x"d2050513",
00000742 => x"a59ff0ef",
00000743 => x"02c12083",
00000744 => x"02812403",
00000745 => x"800007b7",
00000746 => x"0157a023",
00000747 => x"000a2023",
00000748 => x"02412483",
00000749 => x"02012903",
00000750 => x"01c12983",
00000751 => x"01812a03",
00000752 => x"01412a83",
00000753 => x"01012b03",
00000754 => x"00c12b83",
00000755 => x"00812c03",
00000756 => x"03010113",
00000757 => x"00008067",
00000758 => x"00040513",
00000759 => x"e35ff0ef",
00000760 => x"012c07b3",
00000761 => x"00a484b3",
00000762 => x"00a7a023",
00000763 => x"00490913",
00000764 => x"f8dff06f",
00000765 => x"fd010113",
00000766 => x"02812423",
00000767 => x"02912223",
00000768 => x"03212023",
00000769 => x"02112623",
00000770 => x"01312e23",
00000771 => x"00050413",
00000772 => x"00b12623",
00000773 => x"00c10913",
00000774 => x"00350493",
00000775 => x"00094983",
00000776 => x"d75ff0ef",
00000777 => x"fa802783",
00000778 => x"00200513",
00000779 => x"00190913",
00000780 => x"0017e793",
00000781 => x"faf02423",
00000782 => x"cb9ff0ef",
00000783 => x"00048513",
00000784 => x"d95ff0ef",
00000785 => x"00098513",
00000786 => x"ca9ff0ef",
00000787 => x"fa802783",
00000788 => x"ffe7f793",
00000789 => x"faf02423",
00000790 => x"cf9ff0ef",
00000791 => x"00048793",
00000792 => x"fff48493",
00000793 => x"faf41ce3",
00000794 => x"02c12083",
00000795 => x"02812403",
00000796 => x"02412483",
00000797 => x"02012903",
00000798 => x"01c12983",
00000799 => x"03010113",
00000800 => x"00008067",
00000801 => x"746f6f42",
00000802 => x"2e676e69",
00000803 => x"0a0a2e2e",
00000804 => x"00000000",
00000805 => x"52450a07",
00000806 => x"5f524f52",
00000807 => x"00000000",
00000808 => x"00007830",
00000809 => x"52455b0a",
00000810 => x"20524f52",
00000811 => x"6e55202d",
00000812 => x"65707865",
00000813 => x"64657463",
00000814 => x"63786520",
00000815 => x"69747065",
00000816 => x"20216e6f",
00000817 => x"7561636d",
00000818 => x"003d6573",
00000819 => x"70656d20",
00000820 => x"00003d63",
00000821 => x"76746d20",
00000822 => x"003d6c61",
00000823 => x"7274205d",
00000824 => x"676e6979",
00000825 => x"206f7420",
00000826 => x"75736572",
00000827 => x"2e2e656d",
00000828 => x"00000a2e",
00000829 => x"69617741",
00000830 => x"676e6974",
00000831 => x"6f656e20",
00000832 => x"32337672",
00000833 => x"6578655f",
00000834 => x"6e69622e",
00000835 => x"202e2e2e",
00000836 => x"00000000",
00000837 => x"64616f4c",
00000838 => x"2e676e69",
00000839 => x"00202e2e",
00000840 => x"00004b4f",
00000841 => x"3c0a0a0a",
00000842 => x"454e203c",
00000843 => x"3356524f",
00000844 => x"6f422032",
00000845 => x"6f6c746f",
00000846 => x"72656461",
00000847 => x"0a3e3e20",
00000848 => x"444c420a",
00000849 => x"46203a56",
00000850 => x"32206265",
00000851 => x"30322034",
00000852 => x"480a3232",
00000853 => x"203a5657",
00000854 => x"00000020",
00000855 => x"4b4c430a",
00000856 => x"0020203a",
00000857 => x"4153490a",
00000858 => x"0020203a",
00000859 => x"00202b20",
00000860 => x"434f530a",
00000717 => x"fe802783",
00000718 => x"00080737",
00000719 => x"00e7f7b3",
00000720 => x"00079663",
00000721 => x"00300513",
00000722 => x"b39ff0ef",
00000723 => x"db9ff0ef",
00000724 => x"fa051ce3",
00000725 => x"ff1ff06f",
00000726 => x"080009b7",
00000727 => x"00498593",
00000728 => x"00040513",
00000729 => x"eadff0ef",
00000730 => x"00050a93",
00000731 => x"00898593",
00000732 => x"00040513",
00000733 => x"e9dff0ef",
00000734 => x"ff002c03",
00000735 => x"00050b13",
00000736 => x"ffcafb93",
00000737 => x"00000913",
00000738 => x"00000493",
00000739 => x"00c98993",
00000740 => x"013905b3",
00000741 => x"05791c63",
00000742 => x"016484b3",
00000743 => x"00200513",
00000744 => x"fa0494e3",
00000745 => x"ffff1537",
00000746 => x"d3450513",
00000747 => x"a45ff0ef",
00000748 => x"02c12083",
00000749 => x"02812403",
00000750 => x"800007b7",
00000751 => x"0157a023",
00000752 => x"000a2023",
00000753 => x"02412483",
00000754 => x"02012903",
00000755 => x"01c12983",
00000756 => x"01812a03",
00000757 => x"01412a83",
00000758 => x"01012b03",
00000759 => x"00c12b83",
00000760 => x"00812c03",
00000761 => x"03010113",
00000762 => x"00008067",
00000763 => x"00040513",
00000764 => x"e21ff0ef",
00000765 => x"012c07b3",
00000766 => x"00a484b3",
00000767 => x"00a7a023",
00000768 => x"00490913",
00000769 => x"f8dff06f",
00000770 => x"fd010113",
00000771 => x"02812423",
00000772 => x"02912223",
00000773 => x"03212023",
00000774 => x"02112623",
00000775 => x"01312e23",
00000776 => x"00050413",
00000777 => x"00b12623",
00000778 => x"00c10913",
00000779 => x"00350493",
00000780 => x"00094983",
00000781 => x"d61ff0ef",
00000782 => x"fa802783",
00000783 => x"00200513",
00000784 => x"00190913",
00000785 => x"0017e793",
00000786 => x"faf02423",
00000787 => x"ca5ff0ef",
00000788 => x"00048513",
00000789 => x"d81ff0ef",
00000790 => x"00098513",
00000791 => x"c95ff0ef",
00000792 => x"fa802783",
00000793 => x"ffe7f793",
00000794 => x"faf02423",
00000795 => x"ce5ff0ef",
00000796 => x"00048793",
00000797 => x"fff48493",
00000798 => x"faf41ce3",
00000799 => x"02c12083",
00000800 => x"02812403",
00000801 => x"02412483",
00000802 => x"02012903",
00000803 => x"01c12983",
00000804 => x"03010113",
00000805 => x"00008067",
00000806 => x"746f6f42",
00000807 => x"2e676e69",
00000808 => x"0a0a2e2e",
00000809 => x"00000000",
00000810 => x"52450a07",
00000811 => x"5f524f52",
00000812 => x"00000000",
00000813 => x"00007830",
00000814 => x"52455b0a",
00000815 => x"20524f52",
00000816 => x"6e55202d",
00000817 => x"65707865",
00000818 => x"64657463",
00000819 => x"63786520",
00000820 => x"69747065",
00000821 => x"20216e6f",
00000822 => x"7561636d",
00000823 => x"003d6573",
00000824 => x"70656d20",
00000825 => x"00003d63",
00000826 => x"76746d20",
00000827 => x"003d6c61",
00000828 => x"7274205d",
00000829 => x"676e6979",
00000830 => x"206f7420",
00000831 => x"75736572",
00000832 => x"2e2e656d",
00000833 => x"00000a2e",
00000834 => x"69617741",
00000835 => x"676e6974",
00000836 => x"6f656e20",
00000837 => x"32337672",
00000838 => x"6578655f",
00000839 => x"6e69622e",
00000840 => x"202e2e2e",
00000841 => x"00000000",
00000842 => x"64616f4c",
00000843 => x"2e676e69",
00000844 => x"00202e2e",
00000845 => x"00004b4f",
00000846 => x"3c0a0a0a",
00000847 => x"454e203c",
00000848 => x"3356524f",
00000849 => x"6f422032",
00000850 => x"6f6c746f",
00000851 => x"72656461",
00000852 => x"0a3e3e20",
00000853 => x"444c420a",
00000854 => x"41203a56",
00000855 => x"20207270",
00000856 => x"30322038",
00000857 => x"480a3232",
00000858 => x"203a5657",
00000859 => x"00000020",
00000860 => x"4b4c430a",
00000861 => x"0020203a",
00000862 => x"454d490a",
00000863 => x"00203a4d",
00000864 => x"74796220",
00000865 => x"40207365",
00000866 => x"00000000",
00000867 => x"454d440a",
00000862 => x"4153490a",
00000863 => x"0020203a",
00000864 => x"00202b20",
00000865 => x"434f530a",
00000866 => x"0020203a",
00000867 => x"454d490a",
00000868 => x"00203a4d",
00000869 => x"75410a0a",
00000870 => x"6f626f74",
00000871 => x"6920746f",
00000872 => x"7338206e",
00000873 => x"7250202e",
00000874 => x"20737365",
00000875 => x"20796e61",
00000876 => x"2079656b",
00000877 => x"61206f74",
00000878 => x"74726f62",
00000879 => x"00000a2e",
00000880 => x"726f6241",
00000881 => x"2e646574",
00000882 => x"00000a0a",
00000883 => x"0000000a",
00000884 => x"69617641",
00000885 => x"6c62616c",
00000886 => x"4d432065",
00000887 => x"0a3a7344",
00000888 => x"203a6820",
00000889 => x"706c6548",
00000890 => x"3a72200a",
00000891 => x"73655220",
00000892 => x"74726174",
00000893 => x"3a75200a",
00000894 => x"6c705520",
00000895 => x"0a64616f",
00000896 => x"203a7320",
00000897 => x"726f7453",
00000898 => x"6f742065",
00000899 => x"616c6620",
00000900 => x"200a6873",
00000901 => x"4c203a6c",
00000902 => x"2064616f",
00000903 => x"6d6f7266",
00000869 => x"74796220",
00000870 => x"40207365",
00000871 => x"00000000",
00000872 => x"454d440a",
00000873 => x"00203a4d",
00000874 => x"75410a0a",
00000875 => x"6f626f74",
00000876 => x"6920746f",
00000877 => x"7338206e",
00000878 => x"7250202e",
00000879 => x"20737365",
00000880 => x"20796e61",
00000881 => x"2079656b",
00000882 => x"61206f74",
00000883 => x"74726f62",
00000884 => x"00000a2e",
00000885 => x"726f6241",
00000886 => x"2e646574",
00000887 => x"00000a0a",
00000888 => x"0000000a",
00000889 => x"69617641",
00000890 => x"6c62616c",
00000891 => x"4d432065",
00000892 => x"0a3a7344",
00000893 => x"203a6820",
00000894 => x"706c6548",
00000895 => x"3a72200a",
00000896 => x"73655220",
00000897 => x"74726174",
00000898 => x"3a75200a",
00000899 => x"6c705520",
00000900 => x"0a64616f",
00000901 => x"203a7320",
00000902 => x"726f7453",
00000903 => x"6f742065",
00000904 => x"616c6620",
00000905 => x"200a6873",
00000906 => x"45203a65",
00000907 => x"75636578",
00000908 => x"00006574",
00000909 => x"444d430a",
00000910 => x"00203e3a",
00000911 => x"65206f4e",
00000906 => x"4c203a6c",
00000907 => x"2064616f",
00000908 => x"6d6f7266",
00000909 => x"616c6620",
00000910 => x"200a6873",
00000911 => x"45203a65",
00000912 => x"75636578",
00000913 => x"6c626174",
00000914 => x"76612065",
00000915 => x"616c6961",
00000916 => x"2e656c62",
00000917 => x"00000000",
00000918 => x"74697257",
00000919 => x"00002065",
00000920 => x"74796220",
00000921 => x"74207365",
00000922 => x"5053206f",
00000923 => x"6c662049",
00000924 => x"20687361",
00000925 => x"00783040",
00000926 => x"7928203f",
00000927 => x"20296e2f",
00000928 => x"00000000",
00000929 => x"616c460a",
00000930 => x"6e696873",
00000931 => x"2e2e2e67",
00000932 => x"00000020",
00000933 => x"20296328",
00000934 => x"53207962",
00000935 => x"68706574",
00000936 => x"4e206e61",
00000937 => x"69746c6f",
00000938 => x"680a676e",
00000939 => x"73707474",
00000940 => x"672f2f3a",
00000941 => x"75687469",
00000942 => x"6f632e62",
00000943 => x"74732f6d",
00000944 => x"746c6f6e",
00000945 => x"2f676e69",
00000946 => x"726f656e",
00000947 => x"00323376",
00000948 => x"61766e49",
00000949 => x"2064696c",
00000950 => x"00444d43",
00000951 => x"20657865",
00000952 => x"6e676973",
00000953 => x"72757461",
00000954 => x"61662065",
00000955 => x"00006c69",
00000956 => x"00000000",
00000957 => x"65637865",
00000958 => x"6e696465",
00000959 => x"4d492067",
00000960 => x"63204d45",
00000961 => x"63617061",
00000962 => x"00797469",
00000963 => x"63656863",
00000964 => x"6d75736b",
00000965 => x"69616620",
00000966 => x"0000006c",
00000967 => x"00000000",
00000968 => x"00000000",
00000969 => x"20495053",
00000970 => x"73616c66",
00000971 => x"63612068",
00000972 => x"73736563",
00000973 => x"69616620",
00000974 => x"0064656c",
00000975 => x"33323130",
00000976 => x"37363534",
00000977 => x"62613938",
00000978 => x"66656463"
00000913 => x"00006574",
00000914 => x"444d430a",
00000915 => x"00203e3a",
00000916 => x"65206f4e",
00000917 => x"75636578",
00000918 => x"6c626174",
00000919 => x"76612065",
00000920 => x"616c6961",
00000921 => x"2e656c62",
00000922 => x"00000000",
00000923 => x"74697257",
00000924 => x"00002065",
00000925 => x"74796220",
00000926 => x"74207365",
00000927 => x"5053206f",
00000928 => x"6c662049",
00000929 => x"20687361",
00000930 => x"00783040",
00000931 => x"7928203f",
00000932 => x"20296e2f",
00000933 => x"00000000",
00000934 => x"616c460a",
00000935 => x"6e696873",
00000936 => x"2e2e2e67",
00000937 => x"00000020",
00000938 => x"20296328",
00000939 => x"53207962",
00000940 => x"68706574",
00000941 => x"4e206e61",
00000942 => x"69746c6f",
00000943 => x"680a676e",
00000944 => x"73707474",
00000945 => x"672f2f3a",
00000946 => x"75687469",
00000947 => x"6f632e62",
00000948 => x"74732f6d",
00000949 => x"746c6f6e",
00000950 => x"2f676e69",
00000951 => x"726f656e",
00000952 => x"00323376",
00000953 => x"61766e49",
00000954 => x"2064696c",
00000955 => x"00444d43",
00000956 => x"20657865",
00000957 => x"6e676973",
00000958 => x"72757461",
00000959 => x"61662065",
00000960 => x"00006c69",
00000961 => x"00000000",
00000962 => x"65637865",
00000963 => x"6e696465",
00000964 => x"4d492067",
00000965 => x"63204d45",
00000966 => x"63617061",
00000967 => x"00797469",
00000968 => x"63656863",
00000969 => x"6d75736b",
00000970 => x"69616620",
00000971 => x"0000006c",
00000972 => x"00000000",
00000973 => x"00000000",
00000974 => x"20495053",
00000975 => x"73616c66",
00000976 => x"63612068",
00000977 => x"73736563",
00000978 => x"69616620",
00000979 => x"0064656c",
00000980 => x"33323130",
00000981 => x"37363534",
00000982 => x"62613938",
00000983 => x"66656463"
);
 
end neorv32_bootloader_image;
/rtl/core/neorv32_cpu_bus.vhd
115,14 → 115,13
constant pmp_cfg_x_c : natural := 2; -- execute permit
constant pmp_cfg_al_c : natural := 3; -- mode bit low
constant pmp_cfg_ah_c : natural := 4; -- mode bit high
--
constant pmp_cfg_l_c : natural := 7; -- locked entry
 
-- PMP minimal granularity --
constant pmp_lsb_c : natural := index_size_f(PMP_MIN_GRANULARITY);
 
-- data interface registers --
signal mar, mdo, mdi : std_ulogic_vector(data_width_c-1 downto 0);
-- data memory address register --
signal mar : std_ulogic_vector(data_width_c-1 downto 0);
 
-- data access --
signal d_bus_wdata : std_ulogic_vector(data_width_c-1 downto 0); -- write data
197,79 → 196,77
mem_do_reg: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
mdo <= (others => def_rst_val_c);
d_bus_wdata <= (others => def_rst_val_c);
d_bus_ben <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (ctrl_i(ctrl_bus_mo_we_c) = '1') then
mdo <= wdata_i; -- memory data output register (MDO)
-- byte enable and data alignment --
case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is -- data size
when "00" => -- byte
d_bus_wdata(07 downto 00) <= wdata_i(7 downto 0);
d_bus_wdata(15 downto 08) <= wdata_i(7 downto 0);
d_bus_wdata(23 downto 16) <= wdata_i(7 downto 0);
d_bus_wdata(31 downto 24) <= wdata_i(7 downto 0);
case addr_i(1 downto 0) is
when "00" => d_bus_ben <= "0001";
when "01" => d_bus_ben <= "0010";
when "10" => d_bus_ben <= "0100";
when others => d_bus_ben <= "1000";
end case;
when "01" => -- half-word
d_bus_wdata(31 downto 16) <= wdata_i(15 downto 0);
d_bus_wdata(15 downto 00) <= wdata_i(15 downto 0);
if (addr_i(1) = '0') then
d_bus_ben <= "0011"; -- low half-word
else
d_bus_ben <= "1100"; -- high half-word
end if;
when others => -- word
d_bus_wdata <= wdata_i;
d_bus_ben <= "1111"; -- full word
end case;
end if;
end if;
end process mem_do_reg;
 
-- byte enable and output data alignment --
write_align: process(mar, mdo, ctrl_i)
begin
case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is -- data size
when "00" => -- byte
d_bus_wdata(07 downto 00) <= mdo(7 downto 0);
d_bus_wdata(15 downto 08) <= mdo(7 downto 0);
d_bus_wdata(23 downto 16) <= mdo(7 downto 0);
d_bus_wdata(31 downto 24) <= mdo(7 downto 0);
case mar(1 downto 0) is
when "00" => d_bus_ben <= "0001";
when "01" => d_bus_ben <= "0010";
when "10" => d_bus_ben <= "0100";
when others => d_bus_ben <= "1000";
end case;
when "01" => -- half-word
d_bus_wdata(31 downto 16) <= mdo(15 downto 0);
d_bus_wdata(15 downto 00) <= mdo(15 downto 0);
if (mar(1) = '0') then
d_bus_ben <= "0011"; -- low half-word
else
d_bus_ben <= "1100"; -- high half-word
end if;
when others => -- word
d_bus_wdata <= mdo;
d_bus_ben <= "1111"; -- full word
end case;
end process write_align;
 
 
-- Data Interface: Read Data --------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
mem_di_reg: process(rstn_i, clk_i)
read_align: process(rstn_i, clk_i)
variable shifted_data_v : std_ulogic_vector(31 downto 0);
begin
if (rstn_i = '0') then
mdi <= (others => def_rst_val_c);
rdata_align <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (ctrl_i(ctrl_bus_mi_we_c) = '1') then
mdi <= d_bus_rdata; -- memory data input register (MDI)
end if;
-- input data alignment and sign extension --
case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is
when "00" => -- byte
case mar(1 downto 0) is
when "00" => -- byte 0
rdata_align(07 downto 00) <= d_bus_rdata(07 downto 00);
rdata_align(31 downto 08) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and d_bus_rdata(07))); -- sign extension
when "01" => -- byte 1
rdata_align(07 downto 00) <= d_bus_rdata(15 downto 08);
rdata_align(31 downto 08) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and d_bus_rdata(15))); -- sign extension
when "10" => -- byte 2
rdata_align(07 downto 00) <= d_bus_rdata(23 downto 16);
rdata_align(31 downto 08) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and d_bus_rdata(23))); -- sign extension
when others => -- byte 3
rdata_align(07 downto 00) <= d_bus_rdata(31 downto 24);
rdata_align(31 downto 08) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and d_bus_rdata(31))); -- sign extension
end case;
when "01" => -- half-word
if (mar(1) = '0') then
rdata_align(15 downto 00) <= d_bus_rdata(15 downto 00); -- low half-word
rdata_align(31 downto 16) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and d_bus_rdata(15))); -- sign extension
else
rdata_align(15 downto 00) <= d_bus_rdata(31 downto 16); -- high half-word
rdata_align(31 downto 16) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and d_bus_rdata(31))); -- sign extension
end if;
when others => -- word
rdata_align <= d_bus_rdata; -- full word
end case;
end if;
end process mem_di_reg;
 
-- input data alignment and sign extension --
read_align: process(mdi, mar, ctrl_i)
variable shifted_data_v : std_ulogic_vector(31 downto 0);
begin
-- align input word --
case mar(1 downto 0) is
when "00" => shifted_data_v := mdi(31 downto 00);
when "01" => shifted_data_v := x"00" & mdi(31 downto 08);
when "10" => shifted_data_v := x"0000" & mdi(31 downto 16);
when others => shifted_data_v := x"000000" & mdi(31 downto 24);
end case;
-- actual data size and sign-extension --
case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is
when "00" => -- byte
rdata_align(31 downto 08) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and shifted_data_v(7))); -- sign extension
rdata_align(07 downto 00) <= shifted_data_v(07 downto 00);
when "01" => -- half-word
rdata_align(31 downto 16) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and shifted_data_v(15))); -- sign extension
rdata_align(15 downto 00) <= shifted_data_v(15 downto 00); -- high half-word
when others => -- word
rdata_align <= shifted_data_v; -- full word
end case;
end process read_align;
 
-- insert exclusive lock status for SC operations only --
276,9 → 273,8
rdata_o <= exclusive_lock_status when (CPU_EXTENSION_RISCV_A = true) and (ctrl_i(ctrl_bus_ch_lock_c) = '1') else rdata_align;
 
 
-- Data Access Arbiter --------------------------------------------------------------------
-- Data Interface: Arbiter (controlled by pipeline back-end) ------------------------------
-- -------------------------------------------------------------------------------------------
-- controlled by pipeline BACK-end --
data_access_arbiter: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
287,13 → 283,12
d_arbiter.err_align <= '0';
d_arbiter.err_bus <= '0';
elsif rising_edge(clk_i) then
-- data access request --
if (d_arbiter.wr_req = '0') and (d_arbiter.rd_req = '0') then -- idle
d_arbiter.wr_req <= ctrl_i(ctrl_bus_wr_c);
d_arbiter.rd_req <= ctrl_i(ctrl_bus_rd_c);
d_arbiter.err_align <= '0';
d_arbiter.err_bus <= '0';
else -- in progress, accumulate error
else -- in progress, accumulate errors
d_arbiter.err_align <= d_arbiter.err_align or d_misaligned;
d_arbiter.err_bus <= d_arbiter.err_bus or d_bus_err_i or (st_pmp_fault and d_arbiter.wr_req) or (ld_pmp_fault and d_arbiter.rd_req);
if (d_bus_ack_i = '1') or (ctrl_i(ctrl_trap_c) = '1') then -- wait for ACK or TRAP
327,24 → 322,19
d_bus_rdata <= d_bus_rdata_i;
 
-- check data access address alignment --
misaligned_d_check: process(mar, ctrl_i)
misaligned_d_check: process(rstn_i, clk_i)
begin
case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is -- data size
when "00" => -- byte
d_misaligned <= '0';
when "01" => -- half-word
if (mar(0) /= '0') then
d_misaligned <= '1';
else
d_misaligned <= '0';
end if;
when others => -- word
if (mar(1 downto 0) /= "00") then
d_misaligned <= '1';
else
d_misaligned <= '0';
end if;
end case;
if (rstn_i = '0') then
d_misaligned <= def_rst_val_c;
elsif rising_edge(clk_i) then
if (ctrl_i(ctrl_bus_mo_we_c) = '1') then
case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is -- data size
when "00" => d_misaligned <= '0'; -- byte
when "01" => d_misaligned <= addr_i(0); -- half-word
when others => d_misaligned <= addr_i(1) or addr_i(0); -- word
end case;
end if;
end if;
end process misaligned_d_check;
 
-- additional register stage for control signals if using PMP_NUM_REGIONS > pmp_num_regions_critical_c --
368,7 → 358,8
exclusive_lock <= '0';
elsif rising_edge(clk_i) then
if (CPU_EXTENSION_RISCV_A = true) then
if (ctrl_i(ctrl_trap_c) = '1') or (ctrl_i(ctrl_bus_de_lock_c) = '1') then -- remove lock if entering a trap or executing a non-load-reservate memory access
-- remove lock if entering a trap or executing a non-load-reservate memory access --
if (ctrl_i(ctrl_trap_c) = '1') or (ctrl_i(ctrl_bus_de_lock_c) = '1') then
exclusive_lock <= '0';
elsif (ctrl_i(ctrl_bus_lock_c) = '1') then -- set new lock
exclusive_lock <= '1';
391,9 → 382,8
d_bus_lock_o <= exclusive_lock;
 
 
-- Instruction Fetch Arbiter --------------------------------------------------------------
-- Instruction Interface: Arbiter (controlled by pipeline front-end) ----------------------
-- -------------------------------------------------------------------------------------------
-- controlled by pipeline FRONT-end --
ifetch_arbiter: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
401,7 → 391,6
i_arbiter.err_align <= '0';
i_arbiter.err_bus <= '0';
elsif rising_edge(clk_i) then
-- instruction fetch request --
if (i_arbiter.rd_req = '0') then -- idle
i_arbiter.rd_req <= ctrl_i(ctrl_bus_if_c);
i_arbiter.err_align <= '0';
452,7 → 441,8
 
-- Physical Memory Protection (PMP) -------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- check access address region --
 
-- check address region --
pmp_check_address: process(pmp_addr_i, fetch_pc_i, mar)
begin
for i in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
486,9 → 476,9
end process pmp_check_permission;
 
-- final PMP access fault signals --
if_pmp_fault <= or_reduce_f(pmp.if_fault) when (PMP_NUM_REGIONS > 0) else '0';
ld_pmp_fault <= or_reduce_f(pmp.ld_fault) when (PMP_NUM_REGIONS > 0) else '0';
st_pmp_fault <= or_reduce_f(pmp.st_fault) when (PMP_NUM_REGIONS > 0) else '0';
if_pmp_fault <= '1' when (or_reduce_f(pmp.if_fault) = '1') and (PMP_NUM_REGIONS > 0) else '0';
ld_pmp_fault <= '1' when (or_reduce_f(pmp.ld_fault) = '1') and (PMP_NUM_REGIONS > 0) else '0';
st_pmp_fault <= '1' when (or_reduce_f(pmp.st_fault) = '1') and (PMP_NUM_REGIONS > 0) else '0';
 
 
end neorv32_cpu_bus_rtl;
/rtl/core/neorv32_cpu_control.vhd
152,49 → 152,40
state_prev : fetch_engine_state_t;
restart : std_ulogic;
restart_nxt : std_ulogic;
align : std_ulogic;
align_nxt : std_ulogic;
pc : std_ulogic_vector(data_width_c-1 downto 0);
pc_nxt : std_ulogic_vector(data_width_c-1 downto 0);
reset : std_ulogic;
bus_ir : std_ulogic;
bus_if : std_ulogic;
end record;
signal fetch_engine : fetch_engine_t;
 
-- instruction prefetch buffer (FIFO) interface --
type ipb_data_t is array (0 to 1) of std_ulogic_vector((2+16)-1 downto 0); -- status (bus_error, align_error) + 16-bit instruction
type ipb_t is record
wdata : std_ulogic_vector(2+31 downto 0); -- write status (bus_error, align_error) + 32-bit instruction data
we : std_ulogic; -- trigger write
free : std_ulogic; -- free entry available?
clear : std_ulogic; -- clear all entries
--
rdata : std_ulogic_vector(2+31 downto 0); -- read data: status (bus_error, align_error) + 32-bit instruction data
re : std_ulogic; -- read enable
avail : std_ulogic; -- data available?
wdata : ipb_data_t;
we : std_ulogic_vector(1 downto 0); -- trigger write
free : std_ulogic_vector(1 downto 0); -- free entry available?
rdata : ipb_data_t;
re : std_ulogic_vector(1 downto 0); -- read enable
avail : std_ulogic_vector(1 downto 0); -- data available?
end record;
signal ipb : ipb_t;
 
-- pre-decoder --
signal ci_instr16 : std_ulogic_vector(15 downto 0);
signal ci_instr32 : std_ulogic_vector(31 downto 0);
signal ci_illegal : std_ulogic;
 
-- instruction issue engine --
type issue_engine_t is record
realign : std_ulogic;
realign_nxt : std_ulogic;
align : std_ulogic;
align_nxt : std_ulogic;
buf : std_ulogic_vector(2+15 downto 0);
buf_nxt : std_ulogic_vector(2+15 downto 0);
align : std_ulogic;
align_set : std_ulogic;
align_clr : std_ulogic;
ci_i16 : std_ulogic_vector(15 downto 0);
ci_i32 : std_ulogic_vector(31 downto 0);
ci_ill : std_ulogic;
data : std_ulogic_vector((4+32)-1 downto 0); -- 4-bit status + 32-bit instruction
valid : std_ulogic_vector(1 downto 0); -- data word is valid when != 0
end record;
signal issue_engine : issue_engine_t;
 
-- instruction issue interface --
type cmd_issue_t is record
data : std_ulogic_vector(35 downto 0); -- 4-bit status + 32-bit instruction
valid : std_ulogic; -- data word is valid when set
end record;
signal cmd_issue : cmd_issue_t;
 
-- instruction decoding helper logic --
type decode_aux_t is record
is_a_lr : std_ulogic;
211,7 → 202,7
 
-- instruction execution engine --
type execute_engine_state_t is (DISPATCH, TRAP_ENTER, TRAP_EXIT, TRAP_EXECUTE, EXECUTE, ALU_WAIT,
BRANCH, LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYS_ENV, CSR_ACCESS);
BRANCH, BRANCHED, LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYSTEM);
type execute_engine_t is record
state : execute_engine_state_t;
state_nxt : execute_engine_state_t;
280,6 → 271,8
addr : std_ulogic_vector(11 downto 0); -- csr address
we : std_ulogic; -- csr write enable
we_nxt : std_ulogic;
re : std_ulogic; -- csr read enable
re_nxt : std_ulogic;
wdata : std_ulogic_vector(data_width_c-1 downto 0); -- csr write data
rdata : std_ulogic_vector(data_width_c-1 downto 0); -- csr read data
--
377,10 → 370,8
signal hpmcnt_trigger : std_ulogic_vector(HPM_NUM_CNTS-1 downto 0);
 
-- illegal instruction check --
signal illegal_opcode_lsbs : std_ulogic; -- opcode != rv32
signal illegal_instruction : std_ulogic;
signal illegal_register : std_ulogic; -- illegal register (>x15) - E-extension
signal illegal_compressed : std_ulogic; -- illegal compressed instruction - C-extension
signal illegal_cmd : std_ulogic;
signal illegal_reg : std_ulogic; -- illegal register (>x15) - E-extension
 
-- access (privilege) check --
signal csr_acc_valid : std_ulogic; -- valid CSR access (implemented and valid access rights)
402,11 → 393,13
fetch_engine.state <= IFETCH_REQUEST;
fetch_engine.state_prev <= IFETCH_REQUEST;
fetch_engine.restart <= '1';
fetch_engine.align <= '0'; -- always start at aligned address after reset
fetch_engine.pc <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
fetch_engine.state <= fetch_engine.state_nxt;
fetch_engine.state_prev <= fetch_engine.state;
fetch_engine.restart <= fetch_engine.restart_nxt or fetch_engine.reset;
fetch_engine.align <= fetch_engine.align_nxt and bool_to_ulogic_f(CPU_EXTENSION_RISCV_C);
fetch_engine.pc <= fetch_engine.pc_nxt;
end if;
end process fetch_engine_fsm_sync;
420,41 → 413,45
fetch_engine_fsm_comb: process(fetch_engine, execute_engine, ipb, instr_i, bus_i_wait_i, be_instr_i, ma_instr_i)
begin
-- arbiter defaults --
fetch_engine.bus_ir <= '0';
fetch_engine.bus_if <= '0';
fetch_engine.state_nxt <= fetch_engine.state;
fetch_engine.pc_nxt <= fetch_engine.pc;
fetch_engine.restart_nxt <= fetch_engine.restart;
fetch_engine.align_nxt <= fetch_engine.align;
 
-- instruction prefetch buffer defaults --
ipb.we <= '0';
ipb.wdata <= be_instr_i & ma_instr_i & instr_i(31 downto 0); -- store exception info and instruction word
ipb.we <= "00";
ipb.wdata(0) <= be_instr_i & ma_instr_i & instr_i(15 downto 00);
ipb.wdata(1) <= be_instr_i & ma_instr_i & instr_i(31 downto 16);
 
-- state machine --
if (fetch_engine.state = IFETCH_REQUEST) then -- IFETCH_REQUEST: request new 32-bit-aligned instruction word
if (fetch_engine.state = IFETCH_REQUEST) then -- REQUEST: request new 32-bit-aligned instruction word
-- ------------------------------------------------------------
if (fetch_engine.restart = '1') then -- reset request
fetch_engine.pc_nxt <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- initialize with "real" application PC
elsif (ipb.free = '1') then -- free entry in buffer
fetch_engine.bus_ir <= '1'; -- instruction fetch request
fetch_engine.pc_nxt <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- initialize with "real" application PC
fetch_engine.align_nxt <= execute_engine.pc(1);
elsif (ipb.free = "11") then -- free entries in both buffers
fetch_engine.bus_if <= '1'; -- instruction fetch request
fetch_engine.state_nxt <= IFETCH_ISSUE;
end if;
fetch_engine.restart_nxt <= '0';
fetch_engine.restart_nxt <= '0'; -- restart done
 
else -- IFETCH_ISSUE: store instruction data to prefetch buffer
else -- ISSUE: store instruction data to prefetch buffer
-- ------------------------------------------------------------
if (bus_i_wait_i = '0') or (be_instr_i = '1') or (ma_instr_i = '1') then -- wait for bus response
fetch_engine.pc_nxt <= std_ulogic_vector(unsigned(fetch_engine.pc) + 4);
ipb.we <= not fetch_engine.restart; -- write to IPB if not being reset
fetch_engine.align_nxt <= '0';
fetch_engine.state_nxt <= IFETCH_REQUEST;
if (fetch_engine.restart = '0') then -- write to IPB if not being reset
ipb.we(0) <= not fetch_engine.align; -- not start at unaligned address
ipb.we(1) <= '1';
end if;
end if;
 
end if;
end process fetch_engine_fsm_comb;
 
-- clear instruction prefetch buffer while being reset --
ipb.clear <= fetch_engine.restart or fetch_engine.reset;
 
 
-- ****************************************************************************************************************************
-- Instruction Prefetch Buffer
-- ****************************************************************************************************************************
461,33 → 458,36
 
-- Instruction Prefetch Buffer (FIFO) -----------------------------------------------------
-- -------------------------------------------------------------------------------------------
instr_prefetch_buffer: neorv32_fifo
generic map (
FIFO_DEPTH => CPU_IPB_ENTRIES, -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH => ipb.wdata'length, -- size of data elements in fifo
FIFO_RSYNC => false, -- we NEED to read data asynchronously
FIFO_SAFE => false -- no safe access required (ensured by FIFO-external control)
)
port map (
-- control --
clk_i => clk_i, -- clock, rising edge
rstn_i => '1', -- async reset, low-active
clear_i => ipb.clear, -- sync reset, high-active
level_o => open,
half_o => open,
-- write port --
wdata_i => ipb.wdata, -- write data
we_i => ipb.we, -- write enable
free_o => ipb.free, -- at least one entry is free when set
-- read port --
re_i => ipb.re, -- read enable
rdata_o => ipb.rdata, -- read data
avail_o => ipb.avail -- data available when set
);
prefetch_buffer:
for i in 0 to 1 generate -- high half-word and low half-word
prefetch_buffer_inst: neorv32_fifo
generic map (
FIFO_DEPTH => CPU_IPB_ENTRIES, -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH => ipb.wdata(i)'length, -- size of data elements in fifo
FIFO_RSYNC => false, -- we NEED to read data asynchronously
FIFO_SAFE => false -- no safe access required (ensured by FIFO-external control)
)
port map (
-- control --
clk_i => clk_i, -- clock, rising edge
rstn_i => '1', -- async reset, low-active
clear_i => fetch_engine.restart, -- sync reset, high-active
level_o => open,
half_o => open,
-- write port --
wdata_i => ipb.wdata(i), -- write data
we_i => ipb.we(i), -- write enable
free_o => ipb.free(i), -- at least one entry is free when set
-- read port --
re_i => ipb.re(i), -- read enable
rdata_o => ipb.rdata(i), -- read data
avail_o => ipb.avail(i) -- data available when set
);
end generate;
 
 
-- ****************************************************************************************************************************
-- Instruction Issue (recoding of compressed instructions and 32-bit instruction word construction)
-- Instruction Issue (decompress 16-bit instructions and assemble 32-bit instruction word)
-- ****************************************************************************************************************************
 
-- Issue Engine FSM Sync ------------------------------------------------------------------
494,24 → 494,18
-- -------------------------------------------------------------------------------------------
issue_engine_fsm_sync: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then -- always start aligned after reset
issue_engine.align <= '0';
issue_engine.realign <= '0';
issue_engine.buf <= (others => def_rst_val_c);
if (rstn_i = '0') then
issue_engine.align <= '0'; -- always start aligned after reset
elsif rising_edge(clk_i) then
if (ipb.clear = '1') then
if (CPU_EXTENSION_RISCV_C = true) and (execute_engine.pc(1) = '1') then -- branch to unaligned address?
issue_engine.align <= '1'; -- aligned on 16-bit boundary
issue_engine.realign <= '1';
else
issue_engine.align <= '0'; -- aligned on 32-bit boundary
issue_engine.realign <= '0';
if (CPU_EXTENSION_RISCV_C = true) then
if (fetch_engine.restart = '1') then
issue_engine.align <= execute_engine.pc(1); -- branch to unaligned address?
elsif (execute_engine.state = DISPATCH) then
issue_engine.align <= (issue_engine.align and (not issue_engine.align_clr)) or issue_engine.align_set;
end if;
else
issue_engine.align <= issue_engine.align_nxt;
issue_engine.realign <= issue_engine.realign_nxt;
issue_engine.align <= '0'; -- always aligned
end if;
issue_engine.buf <= issue_engine.buf_nxt;
end if;
end process issue_engine_fsm_sync;
 
518,100 → 512,69
 
-- Issue Engine FSM Comb ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
issue_engine_fsm_comb: process(issue_engine, ipb, execute_engine, ci_illegal, ci_instr32)
issue_engine_fsm_comb: process(issue_engine.align, ipb)
begin
-- arbiter defaults --
issue_engine.realign_nxt <= issue_engine.realign;
issue_engine.align_nxt <= issue_engine.align;
issue_engine.buf_nxt <= issue_engine.buf;
-- defaults --
issue_engine.align_set <= '0';
issue_engine.align_clr <= '0';
issue_engine.valid <= "00";
 
-- instruction prefetch buffer interface defaults --
ipb.re <= '0';
 
-- instruction issue interface defaults --
cmd_issue.valid <= '0';
 
-- construct instruction data --
-- cmd_issue.data = <illegal_compressed_instruction> & <bus_error & alignment_error> & <is_compressed_instrucion> & <32-bit_instruction_word>
if (issue_engine.align = '0') or (CPU_EXTENSION_RISCV_C = false) then -- 32-bit aligned
if (ipb.rdata(1 downto 0) = "11") or (CPU_EXTENSION_RISCV_C = false) then -- uncompressed
cmd_issue.data <= '0' & ipb.rdata(33 downto 32) & '0' & ipb.rdata(31 downto 0);
else -- compressed
cmd_issue.data <= ci_illegal & ipb.rdata(33 downto 32) & '1' & ci_instr32;
-- start with LOW half-word --
if (issue_engine.align = '0') or (CPU_EXTENSION_RISCV_C = false) then
if (CPU_EXTENSION_RISCV_C = true) and (ipb.rdata(0)(1 downto 0) /= "11") then -- compressed
issue_engine.align_set <= ipb.avail(0); -- start of next instruction word is not 32-bit aligned
issue_engine.valid(0) <= ipb.avail(0);
issue_engine.data <= issue_engine.ci_ill & ipb.rdata(0)(17 downto 16) & '1' & issue_engine.ci_i32;
else -- aligned uncompressed
issue_engine.valid <= (others => (ipb.avail(0) and ipb.avail(1)));
issue_engine.data <= '0' & (ipb.rdata(1)(17 downto 16) or ipb.rdata(0)(17 downto 16)) &
'0' & (ipb.rdata(1)(15 downto 00) & ipb.rdata(0)(15 downto 00));
end if;
else -- not 32-bit aligned
if (issue_engine.buf(1 downto 0) = "11") then -- uncompressed
cmd_issue.data <= '0' & (ipb.rdata(33 downto 32) or issue_engine.buf(17 downto 16)) & '0' & (ipb.rdata(15 downto 0) & issue_engine.buf(15 downto 0));
else -- compressed
cmd_issue.data <= ci_illegal & ipb.rdata(33 downto 32) & '1' & ci_instr32;
-- start with HIGH half-word --
else
if (CPU_EXTENSION_RISCV_C = true) and (ipb.rdata(1)(1 downto 0) /= "11") then -- compressed
issue_engine.align_clr <= ipb.avail(1); -- start of next instruction word is 32-bit aligned again
issue_engine.valid(1) <= ipb.avail(1);
issue_engine.data <= issue_engine.ci_ill & ipb.rdata(1)(17 downto 16) & '1' & issue_engine.ci_i32;
else -- unaligned uncompressed
issue_engine.valid <= (others => (ipb.avail(0) and ipb.avail(1)));
issue_engine.data <= '0' & (ipb.rdata(0)(17 downto 16) or ipb.rdata(1)(17 downto 16)) &
'0' & (ipb.rdata(0)(15 downto 00) & ipb.rdata(1)(15 downto 00));
end if;
end if;
 
-- store high half-word - we might need it for an unaligned uncompressed instruction --
if (execute_engine.state = DISPATCH) and (ipb.avail = '1') and (CPU_EXTENSION_RISCV_C = true) then
issue_engine.buf_nxt <= ipb.rdata(33 downto 32) & ipb.rdata(31 downto 16);
end if;
 
-- state machine --
if (ipb.avail = '1') then -- instruction data available?
 
if (issue_engine.realign = '0') then -- issue instruction if available
-- ------------------------------------------------------------
cmd_issue.valid <= '1';
if (issue_engine.align = '0') or (CPU_EXTENSION_RISCV_C = false) then -- begin check in LOW instruction half-word
if (execute_engine.state = DISPATCH) then -- ready to issue new command?
ipb.re <= '1';
if (ipb.rdata(1 downto 0) /= "11") and (CPU_EXTENSION_RISCV_C = true) then -- compressed
issue_engine.align_nxt <= '1';
end if;
end if;
else -- begin check in HIGH instruction half-word
if (execute_engine.state = DISPATCH) then -- ready to issue new command?
if (issue_engine.buf(1 downto 0) = "11") then -- uncompressed and unaligned
ipb.re <= '1';
else -- compressed - do not read from ipb here!
issue_engine.align_nxt <= '0';
end if;
end if;
end if;
 
else -- re-align input fifo and half-word buffer after a branch to an unaligned address
-- ------------------------------------------------------------
ipb.re <= '1';
issue_engine.realign_nxt <= '0';
end if;
 
end if;
end process issue_engine_fsm_comb;
 
-- 16-bit instructions: half-word select --
ci_instr16 <= ipb.rdata(15 downto 0) when (issue_engine.align = '0') else issue_engine.buf(15 downto 0);
-- update IPB FIFOs (read-for-next)? --
ipb.re <= issue_engine.valid when (execute_engine.state = DISPATCH) else "00";
 
 
-- Compressed Instructions Recoding -------------------------------------------------------
-- Compressed Instructions Decoding -------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_decompressor_inst_true:
if (CPU_EXTENSION_RISCV_C = true) generate
neorv32_cpu_decompressor_inst: neorv32_cpu_decompressor
generic map (
FPU_ENABLE => CPU_EXTENSION_RISCV_Zfinx -- floating-point instruction enabled
FPU_ENABLE => CPU_EXTENSION_RISCV_Zfinx -- floating-point instructions enabled
)
port map (
-- instruction input --
ci_instr16_i => ci_instr16, -- compressed instruction input
ci_instr16_i => issue_engine.ci_i16, -- compressed instruction input
-- instruction output --
ci_illegal_o => ci_illegal, -- is an illegal compressed instruction
ci_instr32_o => ci_instr32 -- 32-bit decompressed instruction
ci_illegal_o => issue_engine.ci_ill, -- illegal compressed instruction
ci_instr32_o => issue_engine.ci_i32 -- 32-bit decompressed instruction
);
end generate;
 
neorv32_cpu_decompressor_inst_false:
if (CPU_EXTENSION_RISCV_C = false) generate
ci_instr32 <= (others => '0');
ci_illegal <= '0';
issue_engine.ci_i32 <= (others => '0');
issue_engine.ci_ill <= '0';
end generate;
 
-- 16-bit instructions: half-word select --
issue_engine.ci_i16 <= ipb.rdata(0)(15 downto 0) when (issue_engine.align = '0') else ipb.rdata(1)(15 downto 0);
 
 
-- ****************************************************************************************************************************
-- Instruction Execution
-- ****************************************************************************************************************************
688,7 → 651,7
begin
if (rstn_i = '0') then
-- no dedicated reset required --
execute_engine.state_prev <= DISPATCH; -- actual reset value is not relevant
execute_engine.state_prev <= BRANCHED; -- actual reset value is not relevant
execute_engine.i_reg <= (others => def_rst_val_c);
execute_engine.is_ci <= def_rst_val_c;
execute_engine.is_ici <= def_rst_val_c;
698,7 → 661,7
-- registers that DO require a specific RESET state --
execute_engine.pc <= CPU_BOOT_ADDR(data_width_c-1 downto 2) & "00"; -- 32-bit aligned!
execute_engine.pc_last <= CPU_BOOT_ADDR(data_width_c-1 downto 2) & "00";
execute_engine.state <= DISPATCH;
execute_engine.state <= BRANCHED;
execute_engine.sleep <= '0';
execute_engine.branched <= '1'; -- reset is a branch from "somewhere"
ctrl(ctrl_bus_rd_c) <= '0';
716,12 → 679,18
-- execute engine arbiter --
execute_engine.state <= execute_engine.state_nxt;
execute_engine.state_prev <= execute_engine.state;
execute_engine.sleep <= execute_engine.sleep_nxt;
execute_engine.branched <= execute_engine.branched_nxt;
execute_engine.i_reg <= execute_engine.i_reg_nxt;
execute_engine.is_ci <= execute_engine.is_ci_nxt;
execute_engine.is_ici <= execute_engine.is_ici_nxt;
 
-- sleep mode --
if (CPU_EXTENSION_RISCV_DEBUG = true) and ((debug_ctrl.running = '1') or (csr.dcsr_step = '1')) then
execute_engine.sleep <= '0'; -- no sleep when in debug mode
else
execute_engine.sleep <= execute_engine.sleep_nxt;
end if;
 
-- PC & IR of "last executed" instruction for trap handling --
if (execute_engine.state = EXECUTE) then
execute_engine.pc_last <= execute_engine.pc;
736,7 → 705,7
elsif (debug_ctrl.running = '1') and (CPU_EXTENSION_RISCV_DEBUG = true) then -- any other exception INSIDE debug mode
execute_engine.next_pc <= std_ulogic_vector(unsigned(CPU_DEBUG_ADDR) + 4); -- start at "parking loop" <exception_entry>
else -- normal trapping
execute_engine.next_pc <= csr.mtvec(data_width_c-1 downto 1) & '0'; -- trap enter
execute_engine.next_pc <= csr.mtvec(data_width_c-1 downto 2) & "00"; -- trap enter
end if;
when TRAP_EXIT => -- LEAVING trap environment
if (CPU_EXTENSION_RISCV_DEBUG = false) or (debug_ctrl.running = '0') then -- normal end of trap
764,10 → 733,7
curr_pc_o <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- current PC
next_pc_o <= execute_engine.next_pc(data_width_c-1 downto 1) & '0'; -- next PC
 
-- CSR access address --
csr.addr <= execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c);
 
 
-- CPU Control Bus Output -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
ctrl_output: process(ctrl, fetch_engine, trap_ctrl, execute_engine, csr, debug_ctrl)
785,13 → 751,10
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);
-- instruction fetch request --
ctrl_o(ctrl_bus_if_c) <= fetch_engine.bus_ir;
ctrl_o(ctrl_bus_if_c) <= fetch_engine.bus_if;
-- memory access size / sign --
ctrl_o(ctrl_bus_unsigned_c) <= execute_engine.i_reg(instr_funct3_msb_c); -- unsigned LOAD (LBU, LHU)
ctrl_o(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_o(ctrl_alu_shift_dir_c) <= execute_engine.i_reg(instr_funct3_msb_c); -- shift direction (left/right)
ctrl_o(ctrl_alu_shift_ar_c) <= execute_engine.i_reg(30); -- is arithmetic shift
-- instruction's function blocks (for co-processors) --
ctrl_o(ctrl_ir_opcode7_6_c downto ctrl_ir_opcode7_0_c) <= execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c);
ctrl_o(ctrl_ir_funct12_11_c downto ctrl_ir_funct12_0_c) <= execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c);
902,16 → 865,26
end if;
 
-- register/uimm5 checks --
decode_aux.rs1_zero <= not or_reduce_f(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c));
decode_aux.rd_zero <= not or_reduce_f(execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c));
if (execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then
decode_aux.rs1_zero <= '1';
else
decode_aux.rs1_zero <= '0';
end if;
if (execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c) = "00000") then
decode_aux.rd_zero <= '1';
else
decode_aux.rd_zero <= '0';
end if;
end process decode_helper;
 
-- CSR access address --
csr.addr <= execute_engine.i_reg(instr_imm12_msb_c downto instr_imm12_lsb_c);
 
 
-- Execute Engine FSM Comb ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
execute_engine_fsm_comb: process(execute_engine, debug_ctrl, trap_ctrl, decode_aux, fetch_engine, cmd_issue,
execute_engine_fsm_comb: process(execute_engine, debug_ctrl, trap_ctrl, decode_aux, fetch_engine, issue_engine,
csr, ctrl, alu_idone_i, bus_d_wait_i, excl_state_i)
variable opcode_v : std_ulogic_vector(6 downto 0);
begin
-- arbiter defaults --
execute_engine.state_nxt <= execute_engine.state;
942,6 → 915,7
 
-- CSR access --
csr.we_nxt <= '0';
csr.re_nxt <= '0';
 
-- CONTROL DEFAULTS --
ctrl_nxt <= (others => '0'); -- default: all off
962,28 → 936,25
 
when DISPATCH => -- Get new command from instruction issue engine
-- ------------------------------------------------------------
-- PC update --
-- PC & IR update --
execute_engine.pc_mux_sel <= '0'; -- linear next PC
-- IR update --
execute_engine.is_ci_nxt <= cmd_issue.data(32); -- flag to indicate a de-compressed instruction
execute_engine.i_reg_nxt <= cmd_issue.data(31 downto 0);
execute_engine.i_reg_nxt <= issue_engine.data(31 downto 0);
execute_engine.is_ci_nxt <= issue_engine.data(32); -- this is a de-compressed instruction
execute_engine.is_ici_nxt <= issue_engine.data(35); -- illegal compressed instruction
--
if (cmd_issue.valid = '1') then -- instruction available?
if (issue_engine.valid(0) = '1') or (issue_engine.valid(1) = '1') then -- instruction available?
-- PC update --
execute_engine.branched_nxt <= '0';
execute_engine.pc_we <= not execute_engine.branched; -- update PC with linear next_pc if there was no actual branch
-- IR update - exceptions --
if (CPU_EXTENSION_RISCV_C = false) then
trap_ctrl.instr_ma <= cmd_issue.data(33); -- misaligned instruction fetch address, if C disabled
end if;
trap_ctrl.instr_be <= cmd_issue.data(34); -- bus access fault during instruction fetch
execute_engine.is_ici_nxt <= cmd_issue.data(35); -- invalid decompressed instruction
trap_ctrl.instr_ma <= issue_engine.data(33) and (not bool_to_ulogic_f(CPU_EXTENSION_RISCV_C)); -- misaligned instruction fetch (if C disabled)
trap_ctrl.instr_be <= issue_engine.data(34); -- bus access fault during instruction fetch
-- any reason to go to trap state? --
if (execute_engine.sleep = '1') or -- enter sleep state
(trap_ctrl.exc_fire = '1') or -- exception during LAST instruction (e.g. illegal instruction)
(trap_ctrl.env_start = '1') or -- pending trap (IRQ or exception)
((cmd_issue.data(33) = '1') and (CPU_EXTENSION_RISCV_C = false)) or -- misaligned instruction fetch address (if C disabled)
(cmd_issue.data(34) = '1') then -- bus access fault during instruction fetch
((issue_engine.data(33) = '1') and (CPU_EXTENSION_RISCV_C = false)) or -- misaligned instruction fetch address (if C disabled)
(issue_engine.data(34) = '1') then -- bus access fault during instruction fetch
execute_engine.state_nxt <= TRAP_ENTER;
else
execute_engine.state_nxt <= EXECUTE;
991,7 → 962,7
end if;
 
 
when TRAP_ENTER => -- Start trap environment - get trap vector (depc or epc), stay here for sleep mode
when TRAP_ENTER => -- Start trap environment - get trap vector, stay here for sleep mode
-- ------------------------------------------------------------
if (trap_ctrl.env_start = '1') then -- trap triggered?
trap_ctrl.env_start_ack <= '1';
1005,19 → 976,18
execute_engine.state_nxt <= TRAP_EXECUTE;
 
 
when TRAP_EXECUTE => -- Process trap environment -> jump to xTVEC / return from trap environment -> jump to xEPC
when TRAP_EXECUTE => -- Process trap environment
-- ------------------------------------------------------------
execute_engine.pc_mux_sel <= '0'; -- next_PC
execute_engine.pc_mux_sel <= '0'; -- next_PC (or xEPC / trap vector)
fetch_engine.reset <= '1';
execute_engine.pc_we <= '1';
execute_engine.sleep_nxt <= '0'; -- disable sleep mode
execute_engine.state_nxt <= DISPATCH;
execute_engine.state_nxt <= BRANCHED;
 
 
when EXECUTE => -- Decode and execute instruction (control has to be here for exactly 1 cycle 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
case execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is
 
when opcode_alu_c | opcode_alui_c => -- (register/immediate) ALU operation
-- ------------------------------------------------------------
1044,18 → 1014,18
-- co-processor MULDIV operation (multi-cycle) --
if ((CPU_EXTENSION_RISCV_M = true) and ((decode_aux.is_m_mul = '1') or (decode_aux.is_m_div = '1'))) or -- MUL/DIV
((CPU_EXTENSION_RISCV_Zmmul = true) and (decode_aux.is_m_mul = '1')) then -- MUL
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- trigger MULDIV CP
ctrl_nxt(ctrl_cp_trig7_c downto ctrl_cp_trig0_c) <= cp_sel_muldiv_c; -- trigger MULDIV CP
execute_engine.state_nxt <= ALU_WAIT;
-- co-processor BIT-MANIPULATION operation (multi-cycle) --
elsif (CPU_EXTENSION_RISCV_B = true) and
(((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and (decode_aux.is_b_reg = '1')) or -- register operation
((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alui_c(5)) and (decode_aux.is_b_imm = '1'))) then -- immediate operation
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_bitmanip_c; -- trigger BITMANIP CP
ctrl_nxt(ctrl_cp_trig7_c downto ctrl_cp_trig0_c) <= cp_sel_bitmanip_c; -- trigger BITMANIP CP
execute_engine.state_nxt <= ALU_WAIT;
-- co-processor SHIFT operation (multi-cycle) --
elsif (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) then
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_shifter_c; -- trigger SHIFTER CP
ctrl_nxt(ctrl_cp_trig7_c downto ctrl_cp_trig0_c) <= cp_sel_shifter_c; -- trigger SHIFTER CP
execute_engine.state_nxt <= ALU_WAIT;
-- ALU CORE operation (single-cycle) --
else
1097,22 → 1067,17
 
when opcode_fence_c => -- fence operations
-- ------------------------------------------------------------
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fence_c) then -- FENCE
ctrl_nxt(ctrl_bus_fence_c) <= '1';
execute_engine.state_nxt <= DISPATCH;
elsif (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fencei_c) and (CPU_EXTENSION_RISCV_Zifencei = true) then -- FENCE.I
ctrl_nxt(ctrl_bus_fencei_c) <= '1';
execute_engine.branched_nxt <= '1'; -- this is an actual branch
execute_engine.state_nxt <= TRAP_EXECUTE; -- use TRAP_EXECUTE to "modify" PC (PC <= PC)
else -- illegal fence instruction
execute_engine.state_nxt <= DISPATCH;
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c+1) = funct3_fence_c(2 downto 1)) then -- FENCE / FENCE.I
ctrl_nxt(ctrl_bus_fence_c) <= not execute_engine.i_reg(instr_funct3_lsb_c); -- FENCE
ctrl_nxt(ctrl_bus_fencei_c) <= execute_engine.i_reg(instr_funct3_lsb_c) and bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- FENCE.I
end if;
execute_engine.state_nxt <= TRAP_EXECUTE; -- use TRAP_EXECUTE to "modify" PC (PC <= PC)
 
 
when opcode_fop_c => -- floating-point operations
-- ------------------------------------------------------------
if (CPU_EXTENSION_RISCV_Zfinx = true) then
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_fpu_c; -- trigger FPU CP
ctrl_nxt(ctrl_cp_trig7_c downto ctrl_cp_trig0_c) <= cp_sel_fpu_c; -- trigger FPU CP
execute_engine.state_nxt <= ALU_WAIT;
else
execute_engine.state_nxt <= DISPATCH;
1122,7 → 1087,7
when opcode_cust0_c => -- CFU: custom RISC-V instructions (CUSTOM0 OPCODE space)
-- ------------------------------------------------------------
if (CPU_EXTENSION_RISCV_Zxcfu = true) then
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_cfu_c; -- trigger CFU CP
ctrl_nxt(ctrl_cp_trig7_c downto ctrl_cp_trig0_c) <= cp_sel_cfu_c; -- trigger CFU CP
execute_engine.state_nxt <= ALU_WAIT;
else
execute_engine.state_nxt <= DISPATCH;
1129,60 → 1094,44
end if;
 
 
when others => -- system/csr access OR illegal opcode
when opcode_system_c => -- environment/csr access
-- ------------------------------------------------------------
csr.re_nxt <= '1'; -- always read CSR, only relevant for CSR access
if (CPU_EXTENSION_RISCV_Zicsr = true) then
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
execute_engine.state_nxt <= CSR_ACCESS;
end if;
execute_engine.state_nxt <= SYSTEM;
else
execute_engine.state_nxt <= DISPATCH;
end if;
 
end case;
 
when others => -- illegal opcode
-- ------------------------------------------------------------
execute_engine.state_nxt <= DISPATCH;
 
when SYS_ENV => -- system environment operation
-- ------------------------------------------------------------
-- MRET / DRET --
if (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_mret_c) then
execute_engine.state_nxt <= TRAP_EXIT; -- mret
elsif (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_dret_c) and
(CPU_EXTENSION_RISCV_DEBUG = true) then
debug_ctrl.dret <= '1';
execute_engine.state_nxt <= TRAP_EXIT; -- dret
else
execute_engine.state_nxt <= DISPATCH; -- default
end if;
-- ECALL / EBREAK --
if ((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c+1) = funct12_ecall_c(11 downto 1))) then
if (execute_engine.i_reg(instr_funct12_lsb_c) = funct12_ecall_c(0)) then
trap_ctrl.env_call <= '1'; -- ecall
else
trap_ctrl.break_point <= '1'; -- ebreak
end if;
end if;
-- WFI --
if (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_wfi_c) and
((CPU_EXTENSION_RISCV_DEBUG = false) or ((debug_ctrl.running = '0') and (csr.dcsr_step = '0'))) then
execute_engine.sleep_nxt <= '1'; -- not executed (NOP) when in debug-mode or during single-stepping
end if;
end case; -- /EXECUTE
 
 
when CSR_ACCESS => -- read & write status and control register (CSR) - no read/write if illegal instruction
when SYSTEM => -- system environment operation
-- ------------------------------------------------------------
-- CSR write access [invalid CSR instructions are already checked by the illegal instruction logic] --
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) or -- CSRRW(I); always write CSR
(decode_aux.rs1_zero = '0') then -- CSRRS(I) / CSRRC(I): write CSR if rs1/imm5 is NOT zero
csr.we_nxt <= '1';
ctrl_nxt(ctrl_rf_mux1_c downto ctrl_rf_mux0_c) <= rf_mux_csr_c; -- only relevant for CSR access
execute_engine.state_nxt <= DISPATCH; -- default
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) and -- ENVIRONMENT
(trap_ctrl.exc_buf(exc_iillegal_c) = '0') then -- and NOT already identified as illegal instruction
case execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is
when funct12_ecall_c => trap_ctrl.env_call <= '1'; -- ecall
when funct12_ebreak_c => trap_ctrl.break_point <= '1'; -- ebreak
when funct12_mret_c => execute_engine.state_nxt <= TRAP_EXIT; -- mret
when funct12_dret_c => execute_engine.state_nxt <= TRAP_EXIT; debug_ctrl.dret <= '1'; -- dret
when others => execute_engine.sleep_nxt <= '1'; -- "funct12_wfi_c" - wfi/sleep
end case;
else -- CSR ACCESS - there will be no state change if illegal instruction
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or -- CSRRW: always write CSR
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) or -- CSRRWI: always write CSR
(decode_aux.rs1_zero = '0') then -- CSRR(S/C)(I): write CSR if rs1/imm5 is NOT zero
csr.we_nxt <= '1';
end if;
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
end if;
-- register file write back --
ctrl_nxt(ctrl_rf_mux1_c downto ctrl_rf_mux0_c) <= rf_mux_csr_c;
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
execute_engine.state_nxt <= DISPATCH;
 
 
when ALU_WAIT => -- wait for multi-cycle ALU operation (ALU co-processor) to finish
1195,7 → 1144,7
end if;
 
 
when BRANCH => -- update PC for taken branches and jumps
when BRANCH => -- update PC on taken branches and jumps
-- ------------------------------------------------------------
-- get and store return address (only relevant for jump-and-link operations) --
ctrl_nxt(ctrl_rf_mux1_c downto ctrl_rf_mux0_c) <= rf_mux_npc_c; -- next PC
1202,39 → 1151,41
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 <= '1'; -- PC <= alu.add = branch/jump destination
execute_engine.pc_we <= '1'; -- update PC with destination; will be overridden again in DISPATCH if branch not taken
if (execute_engine.i_reg(instr_opcode_lsb_c+2) = '1') or (execute_engine.branch_taken = '1') then -- JAL/JALR or taken branch
-- no need to check for illegal instructions here; the branch condition evaluation circuit will not set "branch_taken" if funct3 is invalid
execute_engine.pc_we <= '1'; -- update PC
execute_engine.branched_nxt <= '1'; -- this is an actual branch
fetch_engine.reset <= '1'; -- trigger new instruction fetch from modified PC
fetch_engine.reset <= '1'; -- reset instruction fetch starting at modified PC
execute_engine.state_nxt <= BRANCHED;
else
execute_engine.state_nxt <= DISPATCH;
end if;
execute_engine.state_nxt <= DISPATCH;
 
 
when BRANCHED => -- delay cycle to wait for reset of pipeline front-end
-- ------------------------------------------------------------
execute_engine.branched_nxt <= '1'; -- this is an actual branch
execute_engine.state_nxt <= DISPATCH;
 
 
when LOADSTORE_0 => -- trigger memory request
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_lock_c) <= decode_aux.is_a_lr; -- atomic.LR: set lock
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or (decode_aux.is_a_lr = '1') then -- normal load or atomic load-reservate
ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- read request
else -- store
if (decode_aux.is_a_sc = '0') or (CPU_EXTENSION_RISCV_A = false) then -- (normal) write request
ctrl_nxt(ctrl_bus_wr_c) <= '1';
else -- evaluate lock state
ctrl_nxt(ctrl_bus_wr_c) <= excl_state_i; -- write request if lock is still ok
end if;
ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- bus read request
elsif (decode_aux.is_a_sc = '0') or (excl_state_i = '1') then -- normal store request or atomic store-conditional with lock still OK
ctrl_nxt(ctrl_bus_wr_c) <= '1'; -- bus write request
end if;
execute_engine.state_nxt <= LOADSTORE_1;
ctrl_nxt(ctrl_bus_lock_c) <= decode_aux.is_a_lr; -- atomic load-reservate: set lock
execute_engine.state_nxt <= LOADSTORE_1;
 
 
when LOADSTORE_1 => -- memory access latency
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- write input data to MDI (only relevant for LOADs)
ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- write input data to MDI (only relevant for load and SC.W operations)
execute_engine.state_nxt <= LOADSTORE_2;
 
 
when LOADSTORE_2 => -- wait for bus transaction to finish
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for load (and SC.W) operations)
ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for load and SC.W operations)
ctrl_nxt(ctrl_rf_mux1_c downto ctrl_rf_mux0_c) <= rf_mux_mem_c; -- memory read data
-- wait for memory response --
if (trap_ctrl.env_start = '1') and (trap_ctrl.cause(6 downto 5) = "00") then -- abort if SYNC EXCEPTION (from bus or illegal cmd) / no IRQs and NOT DEBUG-MODE-related
1368,190 → 1319,133
-- Illegal Instruction Check --------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
illegal_instruction_check: process(execute_engine, decode_aux, csr, csr_acc_valid, debug_ctrl)
variable opcode_v : std_ulogic_vector(6 downto 0);
begin
-- defaults --
illegal_instruction <= '0';
illegal_register <= '0';
illegal_cmd <= '0';
illegal_reg <= '0';
 
-- check opcode for rv32 --
if (execute_engine.i_reg(instr_opcode_lsb_c+1 downto instr_opcode_lsb_c) = "11") then
illegal_opcode_lsbs <= '0';
else
illegal_opcode_lsbs <= '1';
end if;
-- check instruction word encoding and side effects --
case execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is
 
-- check for illegal compressed instruction --
if (CPU_EXTENSION_RISCV_C = true) then
illegal_compressed <= execute_engine.is_ici;
else
illegal_compressed <= '0';
end if;
 
-- check instructions --
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
 
when opcode_lui_c | opcode_auipc_c | opcode_jal_c => -- check sufficient LUI, UIPC, JAL (only check actual OPCODE)
when opcode_lui_c | opcode_auipc_c | opcode_jal_c => -- LUI, UIPC, JAL (only check actual OPCODE)
-- ------------------------------------------------------------
illegal_instruction <= '0';
-- illegal E-CPU register? --
illegal_register <= execute_engine.i_reg(instr_rd_msb_c);
illegal_cmd <= '0';
illegal_reg <= execute_engine.i_reg(instr_rd_msb_c); -- illegal 'E' register?
 
when opcode_alu_c => -- check ALU.funct3 & ALU.funct7
when opcode_jalr_c => -- check JALR.funct3
-- ------------------------------------------------------------
if (((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_subadd_c) or (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c)) and
(execute_engine.i_reg(instr_funct7_msb_c-2 downto instr_funct7_lsb_c) = "00000") and (execute_engine.i_reg(instr_funct7_msb_c) = '0')) or
(((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_slt_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sltu_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_xor_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_or_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_and_c)) and
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000000")) then -- valid base ALUI instruction?
illegal_instruction <= '0';
elsif ((CPU_EXTENSION_RISCV_M = true) or (CPU_EXTENSION_RISCV_Zmmul = false)) and (decode_aux.is_m_mul = '1') then -- valid MUL instruction?
illegal_instruction <= '0';
elsif (CPU_EXTENSION_RISCV_M = true) and (decode_aux.is_m_div = '1') then -- valid DIV instruction?
illegal_instruction <= '0';
elsif (CPU_EXTENSION_RISCV_B = true) and (decode_aux.is_b_reg = '1') then -- valid BITMANIP instruction?
illegal_instruction <= '0';
else
illegal_instruction <= '1';
end if;
-- illegal E-CPU register? --
illegal_register <= execute_engine.i_reg(instr_rd_msb_c) or execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rs2_msb_c);
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
when "000" => illegal_cmd <= '0';
when others => illegal_cmd <= '1';
end case;
illegal_reg <= execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c); -- illegal 'E' register?
 
when opcode_alui_c => -- check ALUI.funct7
when opcode_branch_c => -- check BRANCH.funct3
-- ------------------------------------------------------------
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_subadd_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_slt_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sltu_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_xor_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_or_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_and_c) or
((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and -- shift logical left
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000000")) or
((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) and -- shift right
((execute_engine.i_reg(instr_funct7_msb_c-2 downto instr_funct7_lsb_c) = "00000") and (execute_engine.i_reg(instr_funct7_msb_c) = '0'))) then -- valid base ALUI instruction?
illegal_instruction <= '0';
elsif (CPU_EXTENSION_RISCV_B = true) and (decode_aux.is_b_imm = '1') then -- valid BITMANIP immediate instruction?
illegal_instruction <= '0';
else
illegal_instruction <= '1';
end if;
-- illegal E-CPU register? --
illegal_register <= execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c);
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
when funct3_beq_c | funct3_bne_c | funct3_blt_c | funct3_bge_c | funct3_bltu_c | funct3_bgeu_c => illegal_cmd <= '0';
when others => illegal_cmd <= '1';
end case;
illegal_reg <= execute_engine.i_reg(instr_rs2_msb_c) or execute_engine.i_reg(instr_rs1_msb_c); -- illegal 'E' register?
 
when opcode_load_c => -- check LOAD.funct3
-- ------------------------------------------------------------
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lb_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lh_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lw_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lbu_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lhu_c) then
illegal_instruction <= '0';
else
illegal_instruction <= '1';
end if;
-- illegal E-CPU register? --
illegal_register <= execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c);
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
when funct3_lb_c | funct3_lh_c | funct3_lw_c | funct3_lbu_c | funct3_lhu_c => illegal_cmd <= '0';
when others => illegal_cmd <= '1';
end case;
illegal_reg <= execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c); -- illegal 'E' register?
 
when opcode_store_c => -- check STORE.funct3
-- ------------------------------------------------------------
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sb_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sh_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sw_c) then
illegal_instruction <= '0';
else
illegal_instruction <= '1';
end if;
-- illegal E-CPU register? --
illegal_register <= execute_engine.i_reg(instr_rs2_msb_c) or execute_engine.i_reg(instr_rs1_msb_c);
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
when funct3_sb_c | funct3_sh_c | funct3_sw_c => illegal_cmd <= '0';
when others => illegal_cmd <= '1';
end case;
illegal_reg <= execute_engine.i_reg(instr_rs2_msb_c) or execute_engine.i_reg(instr_rs1_msb_c); -- illegal 'E' register?
 
when opcode_atomic_c => -- atomic instructions
when opcode_alu_c => -- check ALU.funct3 & ALU.funct7
-- ------------------------------------------------------------
if (CPU_EXTENSION_RISCV_A = true) then
if (execute_engine.i_reg(instr_funct5_msb_c downto instr_funct5_lsb_c) = "00010") then -- LR
illegal_instruction <= '0';
-- illegal E-CPU register? --
illegal_register <= execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c);
elsif (execute_engine.i_reg(instr_funct5_msb_c downto instr_funct5_lsb_c) = "00011") then -- SC
illegal_instruction <= '0';
-- illegal E-CPU register? --
illegal_register <= execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rs2_msb_c) or execute_engine.i_reg(instr_rd_msb_c);
else
illegal_instruction <= '1';
end if;
if ((((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_subadd_c) or (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c)) and
(execute_engine.i_reg(instr_funct7_msb_c-2 downto instr_funct7_lsb_c) = "00000") and (execute_engine.i_reg(instr_funct7_msb_c) = '0')) or
(((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_slt_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sltu_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_xor_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_or_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_and_c)) and
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000000"))) or -- valid base ALU instruction?
(((CPU_EXTENSION_RISCV_M = true) or (CPU_EXTENSION_RISCV_Zmmul = true)) and (decode_aux.is_m_mul = '1')) or -- valid MUL instruction?
((CPU_EXTENSION_RISCV_M = true) and (decode_aux.is_m_div = '1')) or -- valid DIV instruction?
((CPU_EXTENSION_RISCV_B = true) and (decode_aux.is_b_reg = '1')) then -- valid BITMANIP register instruction?
illegal_cmd <= '0';
else
illegal_instruction <= '1';
illegal_cmd <= '1';
end if;
illegal_reg <= execute_engine.i_reg(instr_rd_msb_c) or execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rs2_msb_c); -- illegal 'E' register?
 
when opcode_branch_c => -- check BRANCH.funct3
when opcode_alui_c => -- check ALU.funct3 & ALU.funct7
-- ------------------------------------------------------------
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_beq_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bne_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_blt_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bge_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bltu_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bgeu_c) then
illegal_instruction <= '0';
if ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_subadd_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_slt_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sltu_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_xor_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_or_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_and_c) or
((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000000")) or
((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) and
((execute_engine.i_reg(instr_funct7_msb_c-2 downto instr_funct7_lsb_c) = "00000") and (execute_engine.i_reg(instr_funct7_msb_c) = '0')))) or -- valid base ALUI instruction?
((CPU_EXTENSION_RISCV_B = true) and (decode_aux.is_b_imm = '1')) then -- valid BITMANIP immediate instruction?
illegal_cmd <= '0';
else
illegal_instruction <= '1';
illegal_cmd <= '1';
end if;
-- illegal E-CPU register? --
illegal_register <= execute_engine.i_reg(instr_rs2_msb_c) or execute_engine.i_reg(instr_rs1_msb_c);
illegal_reg <= execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c); -- illegal 'E' register?
 
when opcode_jalr_c => -- check JALR.funct3
when opcode_fence_c => -- check FENCE.funct3, ignore all remaining bit-fields
-- ------------------------------------------------------------
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "000") then
illegal_instruction <= '0';
else
illegal_instruction <= '1';
end if;
-- illegal E-CPU register? --
illegal_register <= execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c);
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
when funct3_fence_c => illegal_cmd <= '0'; -- FENCE
when funct3_fencei_c => illegal_cmd <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- FENCE.I
when others => illegal_cmd <= '1';
end case;
 
when opcode_fence_c => -- check FENCE.funct3
when opcode_atomic_c => -- check AMO.funct3 and AMO.funct5
-- ------------------------------------------------------------
if ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fencei_c) and (CPU_EXTENSION_RISCV_Zifencei = true)) or -- FENCE.I
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fence_c) then -- FENCE
illegal_instruction <= '0';
if (CPU_EXTENSION_RISCV_A = true) and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "010") and
(execute_engine.i_reg(instr_funct5_msb_c downto instr_funct5_lsb_c+1) = "0001") then -- LR/SC
illegal_cmd <= '0';
else
illegal_instruction <= '1';
illegal_cmd <= '1';
end if;
-- NOTE: ignore all remaining bit fields here
illegal_reg <= execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rs2_msb_c) or execute_engine.i_reg(instr_rd_msb_c); -- illegal 'E' register?
 
when opcode_syscsr_c => -- check system instructions
when opcode_system_c => -- check system instructions
-- ------------------------------------------------------------
-- CSR access --
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_csrrs_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrc_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrsi_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrci_c)) and
(csr_acc_valid = '1') then -- valid CSR access?
illegal_instruction <= '0';
-- illegal E-CPU register? --
if (execute_engine.i_reg(instr_funct3_msb_c) = '0') then -- reg-reg CSR
illegal_register <= execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c);
else -- reg-imm CSR
illegal_register <= execute_engine.i_reg(instr_rd_msb_c);
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system environment
if (decode_aux.rs1_zero = '1') and (decode_aux.rd_zero = '1') then
case execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is
when funct12_ecall_c | funct12_ebreak_c => illegal_cmd <= '0'; -- ECALL, EBREAK
when funct12_mret_c => illegal_cmd <= not csr.privilege; -- MRET (only allowed in ACTUAL M-mode)
when funct12_wfi_c => illegal_cmd <= (not csr.privilege) and csr.mstatus_tw; -- WFI (only allowed in ACTUAL M-mode or if mstatus.TW = 0)
when funct12_dret_c => illegal_cmd <= not debug_ctrl.running; -- DRET (only allowed in D-mode)
when others => illegal_cmd <= '1';
end case;
else
illegal_cmd <= '1';
end if;
-- system: ecall, ebreak, mret, wfi, dret --
-- > WFI is always allowed to execute in M-mode; in U-mode it is allowed to execute if mstatus.TW = 0
elsif (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "000") and
(decode_aux.rs1_zero = '1') and (decode_aux.rd_zero = '1') and
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_ecall_c) or -- ECALL
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_ebreak_c) or -- EBREAK
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_mret_c) and (csr.privilege = priv_mode_m_c)) or -- MRET (only allowed in ACTUAL M-mode)
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_dret_c) and (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1')) or -- DRET (only allowed in D-mode)
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_wfi_c) and ((csr.privilege = priv_mode_m_c) or (csr.mstatus_tw = '0')))) then -- WFI
illegal_instruction <= '0';
else
illegal_instruction <= '1';
else -- CSR access
if (csr_acc_valid = '0') then -- invalid CSR access?
illegal_cmd <= '1';
end if;
end if;
-- illegal E-CPU register? --
if (execute_engine.i_reg(instr_funct3_msb_c) = '0') then -- reg-reg CSR (or ENV where rd=rs1=zero)
illegal_reg <= execute_engine.i_reg(instr_rd_msb_c) or execute_engine.i_reg(instr_rs1_msb_c);
else -- reg-imm CSR
illegal_reg <= execute_engine.i_reg(instr_rd_msb_c);
end if;
 
when opcode_fop_c => -- floating point operations - single/dual operands
-- ------------------------------------------------------------
1558,27 → 1452,20
if (CPU_EXTENSION_RISCV_Zfinx = true) and -- F extension implemented
(execute_engine.i_reg(instr_funct7_lsb_c+1 downto instr_funct7_lsb_c) = float_single_c) and -- single-precision operations only
(decode_aux.is_f_op = '1') then -- is correct/supported floating-point instruction
illegal_instruction <= '0';
illegal_cmd <= '0';
else
illegal_instruction <= '1';
illegal_cmd <= '1';
end if;
-- illegal E-CPU register? --
-- FIXME: rs2 is not checked!
illegal_register <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx) and (execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c));
illegal_reg <= execute_engine.i_reg(instr_rs2_msb_c) or execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c); -- illegal 'E' register?
 
when opcode_cust0_c => -- CFU: custom instructions
-- ------------------------------------------------------------
if (CPU_EXTENSION_RISCV_Zxcfu = true) then -- CFU extension implemented
illegal_instruction <= '0';
else
illegal_instruction <= '1';
end if;
-- illegal E-CPU register? --
illegal_register <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zxcfu) and (execute_engine.i_reg(instr_rs2_msb_c) or execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c));
illegal_cmd <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zxcfu); -- CFU extension not implemented
illegal_reg <= execute_engine.i_reg(instr_rs2_msb_c) or execute_engine.i_reg(instr_rs1_msb_c) or execute_engine.i_reg(instr_rd_msb_c); -- illegal 'E' register?
 
when others => -- undefined instruction -> illegal!
when others => -- illegal opcode
-- ------------------------------------------------------------
illegal_instruction <= '1';
illegal_cmd <= '1';
 
end case;
end process illegal_instruction_check;
1587,11 → 1474,10
-- Illegal Operation Check ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- check in EXECUTE state: any illegal condition? --
trap_ctrl.instr_il <= (illegal_opcode_lsbs or -- illegal opcode LSB bits - not rv32
illegal_instruction or -- illegal instruction
(bool_to_ulogic_f(CPU_EXTENSION_RISCV_E) and illegal_register) or -- illegal register access in E extension
illegal_compressed) -- illegal compressed instruction
when (execute_engine.state = EXECUTE) else '0';
trap_ctrl.instr_il <= (illegal_cmd or -- illegal instruction
(bool_to_ulogic_f(CPU_EXTENSION_RISCV_E) and illegal_reg) or -- illegal register access in E extension
(bool_to_ulogic_f(CPU_EXTENSION_RISCV_C) and execute_engine.is_ici)) -- illegal compressed instruction
when (execute_engine.state = EXECUTE) else '0'; -- evaluate in EXECUTE stage only
 
 
-- ****************************************************************************************************************************
1601,7 → 1487,6
-- 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');
1667,8 → 1552,9
end process trap_controller;
 
-- any exception/interrupt? --
trap_ctrl.exc_fire <= or_reduce_f(trap_ctrl.exc_buf); -- sync. exceptions CANNOT be masked
trap_ctrl.irq_fire <= (or_reduce_f(trap_ctrl.irq_buf) and csr.mstatus_mie and trap_ctrl.db_irq_en) or trap_ctrl.db_irq_fire; -- interrupts CAN be masked (but not the DEBUG halt IRQ)
trap_ctrl.exc_fire <= '1' when (or_reduce_f(trap_ctrl.exc_buf) = '1') else '0'; -- sync. exceptions CANNOT be masked
trap_ctrl.irq_fire <= '1' when ((or_reduce_f(trap_ctrl.irq_buf) = '1') and (csr.mstatus_mie = '1') and (trap_ctrl.db_irq_en = '1')) or -- interrupts CAN be masked
(trap_ctrl.db_irq_fire = '1') else '0'; -- but not the DEBUG halt IRQ
 
-- debug mode (entry) interrupts --
trap_ctrl.db_irq_en <= '0' when (CPU_EXTENSION_RISCV_DEBUG = true) and ((debug_ctrl.running = '1') or (csr.dcsr_step = '1')) else '1'; -- no interrupts when IN debug mode or IN single-step mode
1858,7 → 1744,7
when funct3_csrrwi_c => csr.wdata <= csr_imm_v;
when funct3_csrrsi_c => csr.wdata <= csr.rdata or csr_imm_v;
when funct3_csrrci_c => csr.wdata <= csr.rdata and (not csr_imm_v);
when others => csr.wdata <= (others => '-'); -- undefined
when others => csr.wdata <= (others => '0'); -- undefined
end case;
end process csr_write_data;
 
1870,6 → 1756,7
begin
if (rstn_i = '0') then
csr.we <= '0';
csr.re <= def_rst_val_c;
--
csr.mstatus_mie <= '0';
csr.mstatus_mpie <= '0';
1916,7 → 1803,8
 
elsif rising_edge(clk_i) then
-- write access? --
csr.we <= csr.we_nxt;
csr.we <= csr.we_nxt and (not trap_ctrl.exc_buf(exc_iillegal_c)); -- write if not illegal instruction
csr.re <= csr.re_nxt;
 
-- defaults --
csr.mip_firq_nclr <= (others => '1'); -- active low
1925,7 → 1813,7
-- --------------------------------------------------------------------------------
-- CSR access by application software
-- --------------------------------------------------------------------------------
if (csr.we = '1') and (trap_ctrl.exc_buf(exc_iillegal_c) = '0') then -- manual write access and not illegal instruction
if (csr.we = '1') then -- manual write access and not illegal instruction
 
-- user floating-point CSRs --
-- --------------------------------------------------------------------
1988,8 → 1876,7
end if;
-- R/W: mcause - machine trap cause --
if (csr.addr(3 downto 0) = csr_mcause_c(3 downto 0)) then
csr.mcause(csr.mcause'left) <= csr.wdata(31); -- 1: async/interrupt, 0: sync/exception
csr.mcause(4 downto 0) <= csr.wdata(4 downto 0); -- identifier
csr.mcause <= csr.wdata(31) & csr.wdata(4 downto 0); -- type + identifier
end if;
-- R/W: mip - machine interrupt pending --
if (csr.addr(3 downto 0) = csr_mip_c(3 downto 0)) then
1997,9 → 1884,10
end if;
end if;
 
-- physical memory protection: R/W: pmpcfg* - PMP configuration registers --
-- physical memory protection --
-- --------------------------------------------------------------------
if (PMP_NUM_REGIONS > 0) then
-- R/W: pmpcfg* - PMP configuration registers --
if (csr.addr(11 downto 2) = csr_class_pmpcfg_c) then -- pmp configuration CSR class
for i in 0 to 3 loop -- 3 pmpcfg CSRs
if (csr.addr(1 downto 0) = std_ulogic_vector(to_unsigned(i, 2))) then
2018,11 → 1906,7
end if;
end loop; -- i (pmpcfg CSR)
end if;
end if;
 
-- physical memory protection: R/W: pmpaddr* - PMP address registers --
-- --------------------------------------------------------------------
if (PMP_NUM_REGIONS > 0) then
-- R/W: pmpaddr* - PMP address registers --
if (csr.addr(11 downto 4) = csr_class_pmpaddr_c) then
for i in 0 to PMP_NUM_REGIONS-1 loop
if (csr.addr(3 downto 0) = std_ulogic_vector(to_unsigned(i, 4))) and (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpaddr access
2118,8 → 2002,7
if (CPU_EXTENSION_RISCV_DEBUG = false) or ((trap_ctrl.cause(5) = '0') and (debug_ctrl.running = '0')) then
 
-- trap cause ID code --
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.mcause <= trap_ctrl.cause(trap_ctrl.cause'left) & trap_ctrl.cause(4 downto 0); -- type + identifier
 
-- trap PC --
if (trap_ctrl.cause(trap_ctrl.cause'left) = '1') then -- for INTERRUPTS (async source)
2130,16 → 2013,14
 
-- trap value --
cause_v := trap_ctrl.cause;
cause_v(5) := '0'; -- bit 5 is always zero here (= normal trapping), so we do not need to check that again
cause_v(5) := '0'; -- bit 5 is always zero here (= normal trapping / no debug-mode-entry), so we do not need to check that again
case cause_v 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
when trap_brk_c => -- breakpoint
csr.mtval <= execute_engine.pc_last(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
csr.mtval <= execute_engine.i_reg_last; -- faulting instruction word (decompressed if C-instruction)
when others => -- everything else including all interrupts
csr.mtval <= (others => '0');
end case;
2216,17 → 2097,28
 
-- Control and Status Registers - Read Access ---------------------------------------------
-- -------------------------------------------------------------------------------------------
csr_read_access: process(rstn_i, clk_i)
csr_read_access: process(clk_i)
variable csr_addr_v : std_ulogic_vector(11 downto 0);
begin
if rising_edge(clk_i) then
csr.rdata <= (others => '0'); -- default output, unimplemented CSRs are hardwired to zero
csr.rdata <= (others => '0'); -- default output, unimplemented CSRs read as zero
if (CPU_EXTENSION_RISCV_Zicsr = true) then
csr_addr_v(11 downto 10) := csr.addr(11 downto 10);
csr_addr_v(09 downto 08) := (others => csr.addr(8)); -- !!! WARNING: MACHINE (11) and USER (00) CSRs ONLY !!!
csr_addr_v(07 downto 00) := csr.addr(07 downto 00);
 
-- AND-gate CSR read address: csr.rdata is zero if csr.re is not set --
if (csr.re = '1') then
csr_addr_v(11 downto 10) := csr.addr(11 downto 10);
csr_addr_v(09 downto 08) := (others => csr.addr(8)); -- !!! WARNING: MACHINE (11) and USER (00) CSRS ONLY !!!
csr_addr_v(07 downto 00) := csr.addr(07 downto 00);
else -- reduce switching activity if not accessed
csr_addr_v := (others => '0'); -- = csr_zero_c
end if;
case csr_addr_v is
 
-- hardware-only CSRs --
-- --------------------------------------------------------------------
-- when csr_zero_c => -- zero (r/-): always returns zero, only relevant for hardware-access, not visible to ISA
-- csr.rdata <= (others => '0');
 
-- floating-point CSRs --
-- --------------------------------------------------------------------
when csr_fflags_c => -- fflags (r/w): floating-point (FPU) exception flags
2238,12 → 2130,12
 
-- machine trap setup --
-- --------------------------------------------------------------------
when csr_mstatus_c => -- mstatus (r/w): machine status register
when csr_mstatus_c => -- mstatus (r/w): machine status register - low word
csr.rdata(03) <= csr.mstatus_mie; -- MIE
csr.rdata(07) <= csr.mstatus_mpie; -- MPIE
csr.rdata(12 downto 11) <= (others => csr.mstatus_mpp); -- MPP: machine previous privilege mode
csr.rdata(21) <= csr.mstatus_tw and bool_to_ulogic_f(CPU_EXTENSION_RISCV_U); -- TW
-- when csr_mstatush_c => -- mstatush (r/w): machine status register - high, implemented but always zero
-- when csr_mstatush_c => -- mstatush (r/w): machine status register - high word, implemented but always zero
-- csr.rdata <= (others => '0');
when csr_misa_c => -- misa (r/-): ISA and extensions
csr.rdata(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_A); -- A CPU extension
2275,8 → 2167,8
when csr_mepc_c => -- mepc (r/w): machine exception program counter
csr.rdata <= csr.mepc(data_width_c-1 downto 1) & '0';
when csr_mcause_c => -- mcause (r/w): machine trap cause
csr.rdata(31) <= csr.mcause(csr.mcause'left);
csr.rdata(csr.mcause'left-1 downto 0) <= csr.mcause(csr.mcause'left-1 downto 0);
csr.rdata(31) <= csr.mcause(5);
csr.rdata(4 downto 0) <= csr.mcause(4 downto 0);
when csr_mtval_c => -- mtval (r/-): machine bad address or instruction
csr.rdata <= csr.mtval;
when csr_mip_c => -- mip (r/w): machine interrupt pending
2524,7 → 2416,6
-- -------------------------------------------------------------------------------------------
csr_counters: process(rstn_i, clk_i)
begin
-- Counter CSRs (each counter is split into two 32-bit counters - coupled via an MSB overflow FF)
if (rstn_i = '0') then
csr.mcycle <= (others => def_rst_val_c);
csr.mcycle_ovfl <= (others => def_rst_val_c);
2546,8 → 2437,8
csr.mcycle(cpu_cnt_lo_width_c-1 downto 0) <= csr.mcycle_nxt(cpu_cnt_lo_width_c-1 downto 0);
end if;
else
csr.mcycle_ovfl <= (others => '-');
csr.mcycle <= (others => '-');
csr.mcycle_ovfl <= (others => '0');
csr.mcycle <= (others => '0');
end if;
 
-- [m]cycleh --
2558,7 → 2449,7
csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0)) + unsigned(csr.mcycle_ovfl));
end if;
else
csr.mcycleh <= (others => '-');
csr.mcycleh <= (others => '0');
end if;
 
 
2571,8 → 2462,8
csr.minstret(cpu_cnt_lo_width_c-1 downto 0) <= csr.minstret_nxt(cpu_cnt_lo_width_c-1 downto 0);
end if;
else
csr.minstret_ovfl <= (others => '-');
csr.minstret <= (others => '-');
csr.minstret_ovfl <= (others => '0');
csr.minstret <= (others => '0');
end if;
 
-- [m]instreth --
2583,7 → 2474,7
csr.minstreth(cpu_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.minstreth(cpu_cnt_hi_width_c-1 downto 0)) + unsigned(csr.minstret_ovfl));
end if;
else
csr.minstreth <= (others => '-');
csr.minstreth <= (others => '0');
end if;
 
 
2599,8 → 2490,8
csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0) <= csr.mhpmcounter_nxt(i)(hpm_cnt_lo_width_c-1 downto 0);
end if;
else
csr.mhpmcounter_ovfl(i) <= (others => '-');
csr.mhpmcounter(i) <= (others => '-');
csr.mhpmcounter_ovfl(i) <= (others => '0');
csr.mhpmcounter(i) <= (others => '0');
end if;
 
-- [m]hpmcounter*h --
2611,7 → 2502,7
csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0)) + unsigned(csr.mhpmcounter_ovfl(i)));
end if;
else
csr.mhpmcounterh(i) <= (others => '-');
csr.mhpmcounterh(i) <= (others => '0');
end if;
 
end loop; -- i
2650,7 → 2541,7
end process hpm_rd_dummy;
 
 
-- Hardware Performance Monitor - Counter Event Control -----------------------------------
-- Hardware Performance Monitor - Counter Event Control (Triggers) ------------------------
-- -------------------------------------------------------------------------------------------
hpmcnt_ctrl: process(clk_i)
begin
2661,33 → 2552,40
if (HPM_NUM_CNTS /= 0) then
for i in 0 to HPM_NUM_CNTS-1 loop
-- do not increment if CPU is in debug mode --
hpmcnt_trigger(i) <= or_reduce_f(cnt_event and csr.mhpmevent(i)(cnt_event'left downto 0)) and (not debug_ctrl.running);
if (or_reduce_f(cnt_event and csr.mhpmevent(i)(cnt_event'left downto 0)) = '1') and (debug_ctrl.running = '0') then
hpmcnt_trigger(i) <= '1';
else
hpmcnt_trigger(i) <= '0';
end if;
end loop; -- i
end if;
end if;
end process hpmcnt_ctrl;
 
-- counter event trigger - RISC-V-specific --
cnt_event(hpmcnt_event_cy_c) <= not execute_engine.sleep; -- active cycle
cnt_event(hpmcnt_event_never_c) <= '0'; -- "never"
cnt_event(hpmcnt_event_ir_c) <= '1' when (execute_engine.state = EXECUTE) else '0'; -- (any) retired instruction
hpm_triggers:
if (HPM_NUM_CNTS /= 0) generate
-- counter event trigger - RISC-V-specific --
cnt_event(hpmcnt_event_cy_c) <= not execute_engine.sleep; -- active cycle
cnt_event(hpmcnt_event_never_c) <= '0'; -- "never"
cnt_event(hpmcnt_event_ir_c) <= '1' when (execute_engine.state = EXECUTE) else '0'; -- (any) retired instruction
 
-- counter event trigger - custom / NEORV32-specific --
cnt_event(hpmcnt_event_cir_c) <= '1' when (execute_engine.state = EXECUTE) and (execute_engine.is_ci = '1') else '0'; -- retired compressed instruction
cnt_event(hpmcnt_event_wait_if_c) <= '1' when (fetch_engine.state = IFETCH_ISSUE) and (fetch_engine.state_prev = IFETCH_ISSUE) else '0'; -- instruction fetch memory wait cycle
cnt_event(hpmcnt_event_wait_ii_c) <= '1' when (execute_engine.state = DISPATCH) and (execute_engine.state_prev = DISPATCH) else '0'; -- instruction issue wait cycle
cnt_event(hpmcnt_event_wait_mc_c) <= '1' when (execute_engine.state = ALU_WAIT) else '0'; -- multi-cycle alu-operation wait cycle
-- counter event trigger - custom / NEORV32-specific --
cnt_event(hpmcnt_event_cir_c) <= '1' when (execute_engine.state = EXECUTE) and (execute_engine.is_ci = '1') else '0'; -- retired compressed instruction
cnt_event(hpmcnt_event_wait_if_c) <= '1' when (fetch_engine.state = IFETCH_ISSUE) and (fetch_engine.state_prev = IFETCH_ISSUE) else '0'; -- instruction fetch memory wait cycle
cnt_event(hpmcnt_event_wait_ii_c) <= '1' when (execute_engine.state = DISPATCH) and (execute_engine.state_prev = DISPATCH) else '0'; -- instruction issue wait cycle
cnt_event(hpmcnt_event_wait_mc_c) <= '1' when (execute_engine.state = ALU_WAIT) else '0'; -- multi-cycle alu-operation wait cycle
 
cnt_event(hpmcnt_event_load_c) <= '1' when (ctrl(ctrl_bus_rd_c) = '1') else '0'; -- load operation
cnt_event(hpmcnt_event_store_c) <= '1' when (ctrl(ctrl_bus_wr_c) = '1') else '0'; -- store operation
cnt_event(hpmcnt_event_wait_ls_c) <= '1' when (execute_engine.state = LOADSTORE_2) and (execute_engine.state_prev = LOADSTORE_2) else '0'; -- load/store memory wait cycle
cnt_event(hpmcnt_event_load_c) <= '1' when (ctrl(ctrl_bus_rd_c) = '1') else '0'; -- load operation
cnt_event(hpmcnt_event_store_c) <= '1' when (ctrl(ctrl_bus_wr_c) = '1') else '0'; -- store operation
cnt_event(hpmcnt_event_wait_ls_c) <= '1' when (execute_engine.state = LOADSTORE_2) and (execute_engine.state_prev = LOADSTORE_2) else '0'; -- load/store memory wait cycle
 
cnt_event(hpmcnt_event_jump_c) <= '1' when (execute_engine.state = BRANCH) and (execute_engine.i_reg(instr_opcode_lsb_c+2) = '1') else '0'; -- jump (unconditional)
cnt_event(hpmcnt_event_branch_c) <= '1' when (execute_engine.state = BRANCH) and (execute_engine.i_reg(instr_opcode_lsb_c+2) = '0') else '0'; -- branch (conditional, taken or not taken)
cnt_event(hpmcnt_event_tbranch_c) <= '1' when (execute_engine.state = BRANCH) and (execute_engine.i_reg(instr_opcode_lsb_c+2) = '0') and (execute_engine.branch_taken = '1') else '0'; -- taken branch (conditional)
cnt_event(hpmcnt_event_jump_c) <= '1' when (execute_engine.state = BRANCH) and (execute_engine.i_reg(instr_opcode_lsb_c+2) = '1') else '0'; -- jump (unconditional)
cnt_event(hpmcnt_event_branch_c) <= '1' when (execute_engine.state = BRANCH) and (execute_engine.i_reg(instr_opcode_lsb_c+2) = '0') else '0'; -- branch (conditional, taken or not taken)
cnt_event(hpmcnt_event_tbranch_c) <= '1' when (execute_engine.state = BRANCH) and (execute_engine.i_reg(instr_opcode_lsb_c+2) = '0') and (execute_engine.branch_taken = '1') else '0'; -- taken branch (conditional)
 
cnt_event(hpmcnt_event_trap_c) <= '1' when (trap_ctrl.env_start_ack = '1') else '0'; -- entered trap
cnt_event(hpmcnt_event_illegal_c) <= '1' when (trap_ctrl.env_start_ack = '1') and (trap_ctrl.cause = trap_iil_c) else '0'; -- illegal operation
cnt_event(hpmcnt_event_trap_c) <= '1' when (trap_ctrl.env_start_ack = '1') else '0'; -- entered trap
cnt_event(hpmcnt_event_illegal_c) <= '1' when (trap_ctrl.env_start_ack = '1') and (trap_ctrl.cause = trap_iil_c) else '0'; -- illegal operation
end generate;
 
 
-- ****************************************************************************************************************************
2696,14 → 2594,14
 
-- Debug Control --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
debug_control: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
debug_ctrl.state <= DEBUG_OFFLINE;
debug_ctrl.ext_halt_req <= '0';
elsif rising_edge(clk_i) then
if (CPU_EXTENSION_RISCV_DEBUG = true) then
 
ocd_en:
if (CPU_EXTENSION_RISCV_DEBUG = true) generate
debug_control: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
debug_ctrl.state <= DEBUG_OFFLINE;
debug_ctrl.ext_halt_req <= '0';
elsif rising_edge(clk_i) then
-- external halt request (from Debug Module) --
debug_ctrl.ext_halt_req <= db_halt_req_i;
 
2737,12 → 2635,9
debug_ctrl.state <= DEBUG_OFFLINE;
 
end case;
else -- debug mode NOT implemented
debug_ctrl.state <= DEBUG_OFFLINE;
debug_ctrl.ext_halt_req <= '0';
end if;
end if;
end process debug_control;
end process debug_control;
end generate;
 
-- state decoding --
debug_ctrl.pending <= '1' when (debug_ctrl.state = DEBUG_PENDING) and (CPU_EXTENSION_RISCV_DEBUG = true) else '0';
2782,7 → 2677,8
 
-- trigger to enter debug-mode: instruction address match (fire AFTER execution) --
hw_trigger_fire <= '1' when (CPU_EXTENSION_RISCV_DEBUG = true) and (csr.tdata1_exe = '1') and
(csr.tdata2(data_width_c-1 downto 1) = execute_engine.pc(data_width_c-1 downto 1)) else '0';
(csr.tdata2(data_width_c-1 downto 1) = execute_engine.pc(data_width_c-1 downto 1)) and
(execute_engine.state = EXECUTE) else '0';
 
 
-- Match Control CSR (mcontrol @ tdata1) - Read-Back --------------------------------------
/rtl/core/neorv32_cpu_cp_bitmanip.vhd
198,10 → 198,10
cmd(op_clz_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "000") else '0';
cmd(op_ctz_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "001") else '0';
cmd(op_cpop_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "010") and (ctrl_i(ctrl_ir_opcode7_5_c) = '0') else '0';
cmd(op_sextb_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "100") else '0';
cmd(op_sexth_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "101") else '0';
cmd(op_sextb_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "100") and (ctrl_i(ctrl_ir_funct3_2_c) = '0') and (ctrl_i(ctrl_ir_opcode7_5_c) = '0') else '0';
cmd(op_sexth_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "101") and (ctrl_i(ctrl_ir_funct3_2_c) = '0') and (ctrl_i(ctrl_ir_opcode7_5_c) = '0') else '0';
cmd(op_rol_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "001") and (ctrl_i(ctrl_ir_opcode7_5_c) = '1') else '0';
cmd(op_ror_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "101") else '0';
cmd(op_ror_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "101") and (ctrl_i(ctrl_ir_funct3_2_c) = '1') else '0';
cmd(op_rev8_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '1') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "101") else '0';
 
-- Zba - Address generation instructions --
470,7 → 470,7
clmul.rs2 <= bit_rev_f(rs2_reg) when (cmd_buf(op_clmulr_c) = '1') else rs2_reg;
 
-- multiplier busy? --
clmul.busy <= or_reduce_f(clmul.cnt);
clmul.busy <= '1' when (or_reduce_f(clmul.cnt) = '1') else '0';
 
 
-- Operation Results ----------------------------------------------------------------------
522,7 → 522,7
-- single-bit instructions --
res_int(op_bclr_c) <= rs1_reg and (not one_hot_core);
res_int(op_bext_c)(data_width_c-1 downto 1) <= (others => '0');
res_int(op_bext_c)(0) <= or_reduce_f(rs1_reg and one_hot_core);
res_int(op_bext_c)(0) <= '1' when (or_reduce_f(rs1_reg and one_hot_core) = '1') else '0';
res_int(op_binv_c) <= rs1_reg xor one_hot_core;
res_int(op_bset_c) <= rs1_reg or one_hot_core;
 
/rtl/core/neorv32_cpu_cp_fpu.vhd
312,9 → 312,18
begin
for i in 0 to 1 loop -- for rs1 and rs2 inputs
-- check for all-zero/all-one --
op_m_all_zero_v := not or_reduce_f(op_data(i)(22 downto 00));
op_e_all_zero_v := not or_reduce_f(op_data(i)(30 downto 23));
op_e_all_one_v := and_reduce_f(op_data(i)(30 downto 23));
op_m_all_zero_v := '0';
op_e_all_zero_v := '0';
op_e_all_one_v := '0';
if (or_reduce_f(op_data(i)(22 downto 00)) = '0') then
op_m_all_zero_v := '1';
end if;
if (or_reduce_f(op_data(i)(30 downto 23)) = '0') then
op_e_all_zero_v := '1';
end if;
if (and_reduce_f(op_data(i)(30 downto 23)) = '1') then
op_e_all_one_v := '1';
end if;
 
-- check special cases --
op_is_zero_v := op_e_all_zero_v and op_m_all_zero_v; -- zero
343,6 → 352,7
begin
if (rstn_i = '0') then
ctrl_engine.state <= S_IDLE;
ctrl_engine.valid <= '0';
ctrl_engine.start <= '0';
fpu_operands.frm <= (others => def_rst_val_c);
fpu_operands.rs1 <= (others => def_rst_val_c);
671,12 → 681,7
variable a_snan_v, a_qnan_v, b_snan_v, b_qnan_v : std_ulogic;
begin
if (rstn_i = '0') then
multiplier.res_class(fp_class_pos_norm_c) <= def_rst_val_c;
multiplier.res_class(fp_class_neg_norm_c) <= def_rst_val_c;
multiplier.res_class(fp_class_pos_inf_c) <= def_rst_val_c;
multiplier.res_class(fp_class_neg_inf_c) <= def_rst_val_c;
multiplier.res_class(fp_class_pos_zero_c) <= def_rst_val_c;
multiplier.res_class(fp_class_neg_zero_c) <= def_rst_val_c;
multiplier.res_class <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
-- minions --
a_pos_norm_v := fpu_operands.rs1_class(fp_class_pos_norm_c); b_pos_norm_v := fpu_operands.rs2_class(fp_class_pos_norm_c);
756,13 → 761,13
(a_qnan_v or b_qnan_v) or -- nay input is qNaN
((a_pos_inf_v or a_neg_inf_v) and (b_pos_zero_v or b_neg_zero_v)) or -- +/-inf * +/-zero
((a_pos_zero_v or a_neg_zero_v) and (b_pos_inf_v or b_neg_inf_v)); -- +/-zero * +/-inf
 
-- subnormal result --
multiplier.res_class(fp_class_pos_denorm_c) <= '0'; -- is evaluated by the normalizer
multiplier.res_class(fp_class_neg_denorm_c) <= '0'; -- is evaluated by the normalizer
end if;
end process multiplier_class_core;
 
-- subnormal result --
multiplier.res_class(fp_class_pos_denorm_c) <= '0'; -- is evaluated by the normalizer
multiplier.res_class(fp_class_neg_denorm_c) <= '0'; -- is evaluated by the normalizer
 
-- unused --
fu_mul.result <= (others => '0');
fu_mul.flags <= (others => '0');
910,11 → 915,7
variable a_snan_v, a_qnan_v, b_snan_v, b_qnan_v : std_ulogic;
begin
if (rstn_i = '0') then
addsub.res_class(fp_class_pos_inf_c) <= def_rst_val_c;
addsub.res_class(fp_class_neg_inf_c) <= def_rst_val_c;
addsub.res_class(fp_class_pos_zero_c) <= def_rst_val_c;
addsub.res_class(fp_class_neg_zero_c) <= def_rst_val_c;
addsub.res_class(fp_class_qnan_c) <= def_rst_val_c;
addsub.res_class <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
-- minions --
a_pos_norm_v := fpu_operands.rs1_class(fp_class_pos_norm_c); b_pos_norm_v := fpu_operands.rs2_class(fp_class_pos_norm_c);
1039,13 → 1040,13
 
-- sNaN --
addsub.res_class(fp_class_snan_c) <= (a_snan_v or b_snan_v); -- any input is sNaN
 
-- subnormal result --
addsub.res_class(fp_class_pos_denorm_c) <= '0'; -- is evaluated by the normalizer
addsub.res_class(fp_class_neg_denorm_c) <= '0'; -- is evaluated by the normalizer
end if;
end process adder_subtractor_class_core;
 
-- subnormal result --
addsub.res_class(fp_class_pos_denorm_c) <= '0'; -- is evaluated by the normalizer
addsub.res_class(fp_class_neg_denorm_c) <= '0'; -- is evaluated by the normalizer
 
-- unused --
fu_addsub.result <= (others => '0');
fu_addsub.flags <= (others => '0');
1359,7 → 1360,11
sreg.lower <= mantissa_i(45 downto 23);
sreg.ext_g <= mantissa_i(22);
sreg.ext_r <= mantissa_i(21);
sreg.ext_s <= or_reduce_f(mantissa_i(20 downto 0));
if (or_reduce_f(mantissa_i(20 downto 0)) = '1') then
sreg.ext_s <= '1';
else
sreg.ext_s <= '0';
end if;
-- check for special cases --
if ((ctrl.class(fp_class_snan_c) or ctrl.class(fp_class_qnan_c) or -- NaN
ctrl.class(fp_class_neg_zero_c) or ctrl.class(fp_class_pos_zero_c) or -- zero
1474,10 → 1479,10
end process ctrl_engine;
 
-- stop shifting when normalized --
sreg.done <= (not or_reduce_f(sreg.upper(sreg.upper'left downto 1))) and sreg.upper(0); -- input is zero, hidden one is set
sreg.done <= '1' when (or_reduce_f(sreg.upper(sreg.upper'left downto 1)) = '0') and (sreg.upper(0) = '1') else '0'; -- input is zero, hidden one is set
 
-- all-zero including hidden bit --
sreg.zero <= not or_reduce_f(sreg.upper);
sreg.zero <= '1' when (or_reduce_f(sreg.upper) = '0') else '0';
 
-- result --
result_o(31) <= ctrl.res_sgn;
1716,7 → 1721,9
 
when S_NORMALIZE_BUSY => -- running normalization cycle
-- ------------------------------------------------------------
sreg.ext_s <= sreg.ext_s or or_reduce_f(sreg.mant(sreg.mant'left-2 downto 0)); -- sticky bit
if (or_reduce_f(sreg.mant(sreg.mant'left-2 downto 0)) = '1') then
sreg.ext_s <= '1'; -- sticky bit
end if;
if (or_reduce_f(ctrl.cnt(ctrl.cnt'left-1 downto 0)) = '0') then
if (ctrl.unsign = '0') then -- signed conversion
ctrl.over <= ctrl.over or sreg.int(sreg.int'left); -- update overrun flag again to check for numerical overflow into sign bit
/rtl/core/neorv32_cpu_cp_muldiv.vhd
91,6 → 91,7
signal rs2_is_signed : std_ulogic;
signal div_res_corr : std_ulogic;
signal out_en : std_ulogic;
signal rs2_zero : std_ulogic;
 
-- divider core --
signal remainder : std_ulogic_vector(data_width_c-1 downto 0);
152,7 → 153,7
when DIV_PREPROCESS =>
-- check relevant input signs for result sign compensation --
if (cp_op = cp_op_div_c) then -- signed div operation
div_res_corr <= (rs1_i(rs1_i'left) xor rs2_i(rs2_i'left)) and or_reduce_f(rs2_i); -- different signs AND rs2 not zero
div_res_corr <= (rs1_i(rs1_i'left) xor rs2_i(rs2_i'left)) and (not rs2_zero); -- different signs AND rs2 not zero
elsif (cp_op = cp_op_rem_c) then -- signed rem operation
div_res_corr <= rs1_i(rs1_i'left);
else
183,6 → 184,9
end if;
end process coprocessor_ctrl;
 
-- rs2 zero? --
rs2_zero <= '1' when (or_reduce_f(rs2_i) = '0') else '0';
 
-- co-processor command --
cp_op <= ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c);
 
/rtl/core/neorv32_cpu_cp_shifter.vhd
106,10 → 106,10
shifter.cnt <= shamt_i; -- shift amount
elsif (or_reduce_f(shifter.cnt) = '1') then -- running shift (cnt != 0)
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 1);
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
if (ctrl_i(ctrl_ir_funct3_2_c) = '0') then -- SLL: shift left logical
shifter.sreg <= shifter.sreg(shifter.sreg'left-1 downto 0) & '0';
else -- SRL: shift right logical / SRA: shift right arithmetical
shifter.sreg <= (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & shifter.sreg(shifter.sreg'left downto 1);
shifter.sreg <= (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_ir_funct12_10_c)) & shifter.sreg(shifter.sreg'left downto 1);
end if;
end if;
end if;
119,7 → 119,7
-- shift control/output --
serial_shifter_ctrl:
if (FAST_SHIFT_EN = false) generate
shifter.done <= not or_reduce_f(shifter.cnt(shifter.cnt'left downto 1));
shifter.done <= '1' when (or_reduce_f(shifter.cnt(shifter.cnt'left downto 1)) = '0') else '0';
valid_o <= shifter.busy and shifter.done;
res_o <= shifter.sreg when (shifter.busy = '0') and (shifter.busy_ff = '1') else (others => '0');
end generate;
132,7 → 132,7
shifter_unit_async: process(rs1_i, shamt_i, ctrl_i, bs_level)
begin
-- input level: convert left shifts to right shifts --
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- is left shift?
if (ctrl_i(ctrl_ir_funct3_2_c) = '0') then -- is left shift?
bs_level(index_size_f(data_width_c)) <= bit_rev_f(rs1_i); -- reverse bit order of input operand
else
bs_level(index_size_f(data_width_c)) <= rs1_i;
141,7 → 141,7
-- shifter array --
for i in index_size_f(data_width_c)-1 downto 0 loop
if (shamt_i(i) = '1') then
bs_level(i)(data_width_c-1 downto data_width_c-(2**i)) <= (others => (bs_level(i+1)(data_width_c-1) and ctrl_i(ctrl_alu_shift_ar_c)));
bs_level(i)(data_width_c-1 downto data_width_c-(2**i)) <= (others => (bs_level(i+1)(data_width_c-1) and ctrl_i(ctrl_ir_funct12_10_c)));
bs_level(i)((data_width_c-(2**i))-1 downto 0) <= bs_level(i+1)(data_width_c-1 downto 2**i);
else
bs_level(i) <= bs_level(i+1);
149,7 → 149,7
end loop;
 
-- re-convert original left shifts --
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then
if (ctrl_i(ctrl_ir_funct3_2_c) = '0') then
bs_result <= bit_rev_f(bs_level(0));
else
bs_result <= bs_level(0);
/rtl/core/neorv32_cpu_decompressor.vhd
117,29 → 117,6
when "00" => -- C0: Register-Based Loads and Stores
case ci_instr16_i(ci_funct3_msb_c downto ci_funct3_lsb_c) is
 
when "000" => -- Illegal_instruction, C.ADDI4SPN
-- ----------------------------------------------------------------------------------------------------------
-- C.ADDI4SPN
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c;
ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c) <= "00010"; -- stack pointer
ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c) <= "01" & ci_instr16_i(ci_rd_3_msb_c downto ci_rd_3_lsb_c);
ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_subadd_c;
ci_instr32_o(instr_imm12_msb_c downto instr_imm12_lsb_c) <= (others => '0'); -- zero extend
ci_instr32_o(instr_imm12_lsb_c + 0) <= '0';
ci_instr32_o(instr_imm12_lsb_c + 1) <= '0';
ci_instr32_o(instr_imm12_lsb_c + 2) <= ci_instr16_i(6);
ci_instr32_o(instr_imm12_lsb_c + 3) <= ci_instr16_i(5);
ci_instr32_o(instr_imm12_lsb_c + 4) <= ci_instr16_i(11);
ci_instr32_o(instr_imm12_lsb_c + 5) <= ci_instr16_i(12);
ci_instr32_o(instr_imm12_lsb_c + 6) <= ci_instr16_i(7);
ci_instr32_o(instr_imm12_lsb_c + 7) <= ci_instr16_i(8);
ci_instr32_o(instr_imm12_lsb_c + 8) <= ci_instr16_i(9);
ci_instr32_o(instr_imm12_lsb_c + 9) <= ci_instr16_i(10);
--
if (ci_instr16_i(12 downto 2) = "00000000000") then -- 12:2 = "00000000000" is official illegal instruction
ci_illegal_o <= '1';
end if;
 
when "010" | "011" => -- C.LW / C.FLW
-- ----------------------------------------------------------------------------------------------------------
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_load_c;
174,10 → 151,30
ci_illegal_o <= '1';
end if;
 
when others => -- undefined
when others => -- "000": Illegal_instruction, C.ADDI4SPN; others: illegal
-- ----------------------------------------------------------------------------------------------------------
ci_instr32_o <= (others => '-');
ci_illegal_o <= '1';
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c;
ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c) <= "00010"; -- stack pointer
ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c) <= "01" & ci_instr16_i(ci_rd_3_msb_c downto ci_rd_3_lsb_c);
ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_subadd_c;
ci_instr32_o(instr_imm12_msb_c downto instr_imm12_lsb_c) <= (others => '0'); -- zero extend
ci_instr32_o(instr_imm12_lsb_c + 0) <= '0';
ci_instr32_o(instr_imm12_lsb_c + 1) <= '0';
ci_instr32_o(instr_imm12_lsb_c + 2) <= ci_instr16_i(6);
ci_instr32_o(instr_imm12_lsb_c + 3) <= ci_instr16_i(5);
ci_instr32_o(instr_imm12_lsb_c + 4) <= ci_instr16_i(11);
ci_instr32_o(instr_imm12_lsb_c + 5) <= ci_instr16_i(12);
ci_instr32_o(instr_imm12_lsb_c + 6) <= ci_instr16_i(7);
ci_instr32_o(instr_imm12_lsb_c + 7) <= ci_instr16_i(8);
ci_instr32_o(instr_imm12_lsb_c + 8) <= ci_instr16_i(9);
ci_instr32_o(instr_imm12_lsb_c + 9) <= ci_instr16_i(10);
--
if (ci_instr16_i(12 downto 5) = "00000000") or -- canonical illegal C instruction or C.ADDI4SPN with nzuimm = 0
(ci_instr16_i(ci_funct3_msb_c downto ci_funct3_lsb_c) = "001") or -- C.FLS / C.LQ
(ci_instr16_i(ci_funct3_msb_c downto ci_funct3_lsb_c) = "100") or -- reserved
(ci_instr16_i(ci_funct3_msb_c downto ci_funct3_lsb_c) = "101") then -- C.C.FSD / C.SQ
ci_illegal_o <= '1';
end if;
 
end case;
 
184,28 → 181,27
when "01" => -- C1: Control Transfer Instructions, Integer Constant-Generation Instructions
 
case ci_instr16_i(ci_funct3_msb_c downto ci_funct3_lsb_c) is
when "101" => -- C.J
when "101" | "001" => -- C.J, C.JAL
-- ----------------------------------------------------------------------------------------------------------
if (ci_instr16_i(ci_funct3_msb_c) = '1') then -- C.J
ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c) <= "00000"; -- discard return address
else -- C.JAL
ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c) <= "00001"; -- save return address to link register
end if;
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_jal_c;
ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c) <= "00000"; -- discard return address
ci_instr32_o(19 downto 12) <= imm20_v(19 downto 12);
ci_instr32_o(20) <= imm20_v(11);
ci_instr32_o(30 downto 21) <= imm20_v(10 downto 01);
ci_instr32_o(31) <= imm20_v(20);
 
when "001" => -- C.JAL
when "110" | "111" => -- C.BEQ, C.BNEZ
-- ----------------------------------------------------------------------------------------------------------
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_jal_c;
ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c) <= "00001"; -- save return address to link register
ci_instr32_o(19 downto 12) <= imm20_v(19 downto 12);
ci_instr32_o(20) <= imm20_v(11);
ci_instr32_o(30 downto 21) <= imm20_v(10 downto 01);
ci_instr32_o(31) <= imm20_v(20);
 
when "110" => -- C.BEQ
-- ----------------------------------------------------------------------------------------------------------
if (ci_instr16_i(ci_funct3_lsb_c) = '0') then -- C.BEQ
ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_beq_c;
else -- C.BNEZ
ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_bne_c;
end if;
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_branch_c;
ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_beq_c;
ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c) <= "01" & ci_instr16_i(ci_rs1_3_msb_c downto ci_rs1_3_lsb_c);
ci_instr32_o(instr_rs2_msb_c downto instr_rs2_lsb_c) <= "00000"; -- x0
ci_instr32_o(07) <= imm12_v(11);
213,17 → 209,6
ci_instr32_o(30 downto 25) <= imm12_v(10 downto 05);
ci_instr32_o(31) <= imm12_v(12);
 
when "111" => -- C.BNEZ
-- ----------------------------------------------------------------------------------------------------------
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_branch_c;
ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_bne_c;
ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c) <= "01" & ci_instr16_i(ci_rs1_3_msb_c downto ci_rs1_3_lsb_c);
ci_instr32_o(instr_rs2_msb_c downto instr_rs2_lsb_c) <= "00000"; -- x0
ci_instr32_o(07) <= imm12_v(11);
ci_instr32_o(11 downto 08) <= imm12_v(04 downto 01);
ci_instr32_o(30 downto 25) <= imm12_v(10 downto 05);
ci_instr32_o(31) <= imm12_v(12);
 
when "010" => -- C.LI
-- ----------------------------------------------------------------------------------------------------------
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c;
268,7 → 253,7
ci_instr32_o(instr_imm20_lsb_c + 4) <= ci_instr16_i(6);
ci_instr32_o(instr_imm20_lsb_c + 5) <= ci_instr16_i(12);
end if;
if (ci_instr16_i(6 downto 2) = "00000") and (ci_instr16_i(12) = '0') then -- reserved
if (ci_instr16_i(6 downto 2) = "00000") and (ci_instr16_i(12) = '0') then -- reserved if nzimm = 0
ci_illegal_o <= '1';
end if;
 
286,34 → 271,26
ci_instr32_o(instr_imm12_lsb_c + 4) <= ci_instr16_i(6);
ci_instr32_o(instr_imm12_lsb_c + 5) <= ci_instr16_i(12);
 
when "100" => -- C.SRLI, C.SRAI, C.ANDI, C.SUB, C.XOR, C.OR, C.AND, reserved
when others => -- 100: C.SRLI, C.SRAI, C.ANDI, C.SUB, C.XOR, C.OR, C.AND, reserved
-- ----------------------------------------------------------------------------------------------------------
ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c) <= "01" & ci_instr16_i(ci_rs1_3_msb_c downto ci_rs1_3_lsb_c);
ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c) <= "01" & ci_instr16_i(ci_rs1_3_msb_c downto ci_rs1_3_lsb_c);
ci_instr32_o(instr_rs2_msb_c downto instr_rs2_lsb_c) <= "01" & ci_instr16_i(ci_rs2_3_msb_c downto ci_rs2_3_lsb_c);
case ci_instr16_i(11 downto 10) is
when "00" => -- C.SRLI
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c;
ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_sr_c;
ci_instr32_o(instr_funct7_msb_c downto instr_funct7_lsb_c) <= "0000000";
ci_instr32_o(instr_imm12_lsb_c + 0) <= ci_instr16_i(2);
ci_instr32_o(instr_imm12_lsb_c + 1) <= ci_instr16_i(3);
ci_instr32_o(instr_imm12_lsb_c + 2) <= ci_instr16_i(4);
ci_instr32_o(instr_imm12_lsb_c + 3) <= ci_instr16_i(5);
ci_instr32_o(instr_imm12_lsb_c + 4) <= ci_instr16_i(6);
if (ci_instr16_i(12) = '1') then
ci_illegal_o <= '1';
when "00" | "01" => -- C.SRLI, C.SRAI
if (ci_instr16_i(10) = '0') then -- C.SRLI
ci_instr32_o(instr_funct7_msb_c downto instr_funct7_lsb_c) <= "0000000";
else -- C.SRAI
ci_instr32_o(instr_funct7_msb_c downto instr_funct7_lsb_c) <= "0100000";
end if;
when "01" => -- C.SRAI
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c;
ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_sr_c;
ci_instr32_o(instr_funct7_msb_c downto instr_funct7_lsb_c) <= "0100000";
ci_instr32_o(instr_imm12_lsb_c + 0) <= ci_instr16_i(2);
ci_instr32_o(instr_imm12_lsb_c + 1) <= ci_instr16_i(3);
ci_instr32_o(instr_imm12_lsb_c + 2) <= ci_instr16_i(4);
ci_instr32_o(instr_imm12_lsb_c + 3) <= ci_instr16_i(5);
ci_instr32_o(instr_imm12_lsb_c + 4) <= ci_instr16_i(6);
if (ci_instr16_i(12) = '1') then
if (ci_instr16_i(12) = '1') then -- nzuimm[5] = 1 -> RV32 custom
ci_illegal_o <= '1';
end if;
when "10" => -- C.ANDI
344,14 → 321,9
end case;
end case;
 
when others => -- undefined
-- ----------------------------------------------------------------------------------------------------------
ci_instr32_o <= (others => '-');
ci_illegal_o <= '1';
 
end case;
 
when "10" => -- C2: Stack-Pointer-Based Loads and Stores, Control Transfer Instructions
when others => -- C2: Stack-Pointer-Based Loads and Stores, Control Transfer Instructions (or C3, which is not a RVC instruction)
case ci_instr16_i(ci_funct3_msb_c downto ci_funct3_lsb_c) is
 
when "000" => -- C.SLLI
366,8 → 338,8
ci_instr32_o(instr_imm12_lsb_c + 2) <= ci_instr16_i(4);
ci_instr32_o(instr_imm12_lsb_c + 3) <= ci_instr16_i(5);
ci_instr32_o(instr_imm12_lsb_c + 4) <= ci_instr16_i(6);
if (ci_instr16_i(12) = '1') then
ci_illegal_o <= ci_instr16_i(12);
if (ci_instr16_i(12) = '1') then -- nzuimm[5] = 1 -> RV32 custom
ci_illegal_o <= '1';
end if;
 
when "010" | "011" => -- C.LWSP / C.FLWSP
406,7 → 378,7
ci_illegal_o <= '1';
end if;
 
when "100" => -- C.JR, C.JALR, C.MV, C.EBREAK, C.ADD
when others => -- "100": C.JR, C.JALR, C.MV, C.EBREAK, C.ADD; others: undefined
-- ----------------------------------------------------------------------------------------------------------
if (ci_instr16_i(12) = '0') then -- C.JR, C.MV
if (ci_instr16_i(6 downto 2) = "00000") then -- C.JR
423,8 → 395,8
else -- C.EBREAK, C.JALR, C.ADD
if (ci_instr16_i(6 downto 2) = "00000") then -- C.EBREAK, C.JALR
if (ci_instr16_i(11 downto 7) = "00000") then -- C.EBREAK
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_syscsr_c;
ci_instr32_o(instr_funct12_msb_c downto instr_funct12_lsb_c) <= "000000000001";
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_system_c;
ci_instr32_o(instr_funct12_msb_c downto instr_funct12_lsb_c) <= funct12_ebreak_c;
else -- C.JALR
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_jalr_c;
ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c) <= ci_instr16_i(ci_rs1_5_msb_c downto ci_rs1_5_lsb_c);
438,19 → 410,14
ci_instr32_o(instr_rs2_msb_c downto instr_rs2_lsb_c) <= ci_instr16_i(ci_rs2_5_msb_c downto ci_rs2_5_lsb_c);
end if;
end if;
--
if (ci_instr16_i(ci_funct3_msb_c downto ci_funct3_lsb_c) = "001") or -- C.FLDSP / C.LQSP
(ci_instr16_i(ci_funct3_msb_c downto ci_funct3_lsb_c) = "101") then -- C.FSDSP / C.SQSP
ci_illegal_o <= '1';
end if;
 
when others => -- undefined
-- ----------------------------------------------------------------------------------------------------------
ci_instr32_o <= (others => '-');
ci_illegal_o <= '1';
 
end case;
 
when others => -- not a compressed instruction
-- ----------------------------------------------------------------------------------------------------------
ci_instr32_o <= (others => '-');
ci_illegal_o <= '0';
 
end case;
end process decompressor;
 
/rtl/core/neorv32_cpu_regfile.vhd
75,18 → 75,20
type reg_file_emb_t is array (15 downto 0) of std_ulogic_vector(data_width_c-1 downto 0);
signal reg_file : reg_file_t;
signal reg_file_emb : reg_file_emb_t;
signal rf_wdata : std_ulogic_vector(data_width_c-1 downto 0); -- actual write-back data
signal rd_is_x0 : std_ulogic; -- writing to x0?
signal opa_addr : std_ulogic_vector(4 downto 0); -- rs1/dst address
signal opb_addr : std_ulogic_vector(4 downto 0); -- rs2 address
 
-- access --
signal rf_wdata : std_ulogic_vector(data_width_c-1 downto 0); -- actual write-back data
signal rd_zero : std_ulogic; -- writing to x0?
signal opa_addr : std_ulogic_vector(4 downto 0); -- rs1/dst address
signal opb_addr : std_ulogic_vector(4 downto 0); -- rs2 address
 
begin
 
-- Data Input Mux -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
input_mux: process(rd_is_x0, ctrl_i, alu_i, mem_i, csr_i, pc2_i)
input_mux: process(rd_zero, ctrl_i, alu_i, mem_i, csr_i, pc2_i)
begin
if (rd_is_x0 = '1') then -- write zero if accessing x0 to "emulate" it is hardwired to zero
if (rd_zero = '1') then -- write zero if accessing x0 to "emulate" it is hardwired to zero
rf_wdata <= (others => '0'); -- TODO: FIXME! but how???
else
case ctrl_i(ctrl_rf_mux1_c downto ctrl_rf_mux0_c) is
99,7 → 101,10
end if;
end process input_mux;
 
-- writing to x0? --
rd_zero <= '1' when (ctrl_i(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c) = "00000") else '0';
 
 
-- Register File Access -------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
reg_file_rv32i: -- normal register file with 32 registers
114,9 → 119,6
rs2_o <= reg_file(to_integer(unsigned(opb_addr(4 downto 0))));
end if;
end process rf_access;
 
-- writing to x0? --
rd_is_x0 <= not or_reduce_f(ctrl_i(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c));
end generate;
 
reg_file_rv32e: -- embedded register file with 16 registers
131,9 → 133,6
rs2_o <= reg_file_emb(to_integer(unsigned(opb_addr(3 downto 0))));
end if;
end process rf_access;
 
-- writing to x0? --
rd_is_x0 <= not or_reduce_f(ctrl_i(ctrl_rf_rd_adr3_c downto ctrl_rf_rd_adr0_c));
end generate;
 
-- access addresses --
/rtl/core/neorv32_icache.vhd
545,7 → 545,7
end process comparator;
 
-- global hit --
hit_o <= or_reduce_f(hit);
hit_o <= '1' when (or_reduce_f(hit) = '1') else '0';
 
 
-- Cache Data Memory ----------------------------------------------------------------------
/rtl/core/neorv32_package.vhd
49,8 → 49,8
constant dedicated_reset_c : boolean := false;
 
-- "critical" number of implemented PMP regions --
-- if more PMP regions (> pmp_num_regions_critical_c) are defined, another register stage is automatically inserted into the memory interfaces
-- increasing instruction fetch & data access latency by +1 cycle but also reducing critical path length
-- if more PMP regions (> pmp_num_regions_critical_c) are defined, another register stage is automatically inserted into
-- the memory interfaces increasing instruction fetch & data access latency by +1 cycle but also reducing critical path length
constant pmp_num_regions_critical_c : natural := 8; -- default=8
 
-- "response time window" for processor-internal modules --
65,7 → 65,7
-- Architecture Constants (do not modify!) ------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- native data path width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01060900"; -- no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070000"; -- NEORV32 version - no touchy!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
 
-- Check if we're inside the Matrix -------------------------------------------------------
347,66 → 347,62
constant ctrl_alu_opa_mux_c : natural := 21; -- operand A select (0=rs1, 1=PC)
constant ctrl_alu_opb_mux_c : natural := 22; -- operand B select (0=rs2, 1=IMM)
constant ctrl_alu_unsigned_c : natural := 23; -- is unsigned ALU operation
constant ctrl_alu_shift_dir_c : natural := 24; -- shift direction (0=left, 1=right)
constant ctrl_alu_shift_ar_c : natural := 25; -- is arithmetic shift
constant ctrl_alu_frm0_c : natural := 26; -- FPU rounding mode bit 0
constant ctrl_alu_frm1_c : natural := 27; -- FPU rounding mode bit 1
constant ctrl_alu_frm2_c : natural := 28; -- FPU rounding mode bit 2
constant ctrl_alu_frm0_c : natural := 24; -- FPU rounding mode bit 0
constant ctrl_alu_frm1_c : natural := 25; -- FPU rounding mode bit 1
constant ctrl_alu_frm2_c : natural := 26; -- FPU rounding mode bit 2
-- bus interface --
constant ctrl_bus_size_lsb_c : natural := 29; -- transfer size lsb (00=byte, 01=half-word)
constant ctrl_bus_size_msb_c : natural := 30; -- transfer size msb (10=word, 11=?)
constant ctrl_bus_rd_c : natural := 31; -- read data request
constant ctrl_bus_wr_c : natural := 32; -- write data request
constant ctrl_bus_if_c : natural := 33; -- instruction fetch request
constant ctrl_bus_mo_we_c : natural := 34; -- memory address and data output register write enable
constant ctrl_bus_mi_we_c : natural := 35; -- memory data input register write enable
constant ctrl_bus_unsigned_c : natural := 36; -- is unsigned load
constant ctrl_bus_fence_c : natural := 37; -- executed fence operation
constant ctrl_bus_fencei_c : natural := 38; -- executed fencei operation
constant ctrl_bus_lock_c : natural := 39; -- make atomic/exclusive access lock
constant ctrl_bus_de_lock_c : natural := 40; -- remove atomic/exclusive access
constant ctrl_bus_ch_lock_c : natural := 41; -- evaluate atomic/exclusive lock (SC operation)
constant ctrl_bus_size_lsb_c : natural := 27; -- transfer size lsb (00=byte, 01=half-word)
constant ctrl_bus_size_msb_c : natural := 28; -- transfer size msb (10=word, 11=?)
constant ctrl_bus_rd_c : natural := 29; -- read data request
constant ctrl_bus_wr_c : natural := 30; -- write data request
constant ctrl_bus_if_c : natural := 31; -- instruction fetch request
constant ctrl_bus_mo_we_c : natural := 32; -- memory address and data output register write enable
constant ctrl_bus_mi_we_c : natural := 33; -- memory data input register write enable
constant ctrl_bus_unsigned_c : natural := 34; -- is unsigned load
constant ctrl_bus_fence_c : natural := 35; -- executed fence operation
constant ctrl_bus_fencei_c : natural := 36; -- executed fencei operation
constant ctrl_bus_lock_c : natural := 37; -- make atomic/exclusive access lock
constant ctrl_bus_de_lock_c : natural := 38; -- remove atomic/exclusive access
constant ctrl_bus_ch_lock_c : natural := 39; -- evaluate atomic/exclusive lock (SC operation)
-- alu co-processors --
constant ctrl_cp_id_lsb_c : natural := 42; -- cp select ID lsb [ALIAS]
constant ctrl_cp_trig0_c : natural := 42; -- trigger CP0
constant ctrl_cp_trig1_c : natural := 43; -- trigger CP1
constant ctrl_cp_trig2_c : natural := 44; -- trigger CP2
constant ctrl_cp_trig3_c : natural := 45; -- trigger CP3
constant ctrl_cp_trig4_c : natural := 46; -- trigger CP4
constant ctrl_cp_trig5_c : natural := 47; -- trigger CP5
constant ctrl_cp_trig6_c : natural := 48; -- trigger CP6
constant ctrl_cp_trig7_c : natural := 49; -- trigger CP7
constant ctrl_cp_id_msb_c : natural := 49; -- cp select ID msb [ALIAS]
constant ctrl_cp_trig0_c : natural := 40; -- trigger CP0
constant ctrl_cp_trig1_c : natural := 41; -- trigger CP1
constant ctrl_cp_trig2_c : natural := 42; -- trigger CP2
constant ctrl_cp_trig3_c : natural := 43; -- trigger CP3
constant ctrl_cp_trig4_c : natural := 44; -- trigger CP4
constant ctrl_cp_trig5_c : natural := 45; -- trigger CP5
constant ctrl_cp_trig6_c : natural := 46; -- trigger CP6
constant ctrl_cp_trig7_c : natural := 47; -- trigger CP7
-- instruction word control blocks (used by cpu co-processors) --
constant ctrl_ir_funct3_0_c : natural := 50; -- funct3 bit 0
constant ctrl_ir_funct3_1_c : natural := 51; -- funct3 bit 1
constant ctrl_ir_funct3_2_c : natural := 52; -- funct3 bit 2
constant ctrl_ir_funct12_0_c : natural := 53; -- funct12 bit 0
constant ctrl_ir_funct12_1_c : natural := 54; -- funct12 bit 1
constant ctrl_ir_funct12_2_c : natural := 55; -- funct12 bit 2
constant ctrl_ir_funct12_3_c : natural := 56; -- funct12 bit 3
constant ctrl_ir_funct12_4_c : natural := 57; -- funct12 bit 4
constant ctrl_ir_funct12_5_c : natural := 58; -- funct12 bit 5
constant ctrl_ir_funct12_6_c : natural := 59; -- funct12 bit 6
constant ctrl_ir_funct12_7_c : natural := 60; -- funct12 bit 7
constant ctrl_ir_funct12_8_c : natural := 61; -- funct12 bit 8
constant ctrl_ir_funct12_9_c : natural := 62; -- funct12 bit 9
constant ctrl_ir_funct12_10_c : natural := 63; -- funct12 bit 10
constant ctrl_ir_funct12_11_c : natural := 64; -- funct12 bit 11
constant ctrl_ir_opcode7_0_c : natural := 65; -- opcode7 bit 0
constant ctrl_ir_opcode7_1_c : natural := 66; -- opcode7 bit 1
constant ctrl_ir_opcode7_2_c : natural := 67; -- opcode7 bit 2
constant ctrl_ir_opcode7_3_c : natural := 68; -- opcode7 bit 3
constant ctrl_ir_opcode7_4_c : natural := 69; -- opcode7 bit 4
constant ctrl_ir_opcode7_5_c : natural := 70; -- opcode7 bit 5
constant ctrl_ir_opcode7_6_c : natural := 71; -- opcode7 bit 6
constant ctrl_ir_funct3_0_c : natural := 48; -- funct3 bit 0
constant ctrl_ir_funct3_1_c : natural := 49; -- funct3 bit 1
constant ctrl_ir_funct3_2_c : natural := 50; -- funct3 bit 2
constant ctrl_ir_funct12_0_c : natural := 51; -- funct12 bit 0
constant ctrl_ir_funct12_1_c : natural := 52; -- funct12 bit 1
constant ctrl_ir_funct12_2_c : natural := 53; -- funct12 bit 2
constant ctrl_ir_funct12_3_c : natural := 54; -- funct12 bit 3
constant ctrl_ir_funct12_4_c : natural := 55; -- funct12 bit 4
constant ctrl_ir_funct12_5_c : natural := 56; -- funct12 bit 5
constant ctrl_ir_funct12_6_c : natural := 57; -- funct12 bit 6
constant ctrl_ir_funct12_7_c : natural := 58; -- funct12 bit 7
constant ctrl_ir_funct12_8_c : natural := 59; -- funct12 bit 8
constant ctrl_ir_funct12_9_c : natural := 60; -- funct12 bit 9
constant ctrl_ir_funct12_10_c : natural := 61; -- funct12 bit 10
constant ctrl_ir_funct12_11_c : natural := 62; -- funct12 bit 11
constant ctrl_ir_opcode7_0_c : natural := 63; -- opcode7 bit 0
constant ctrl_ir_opcode7_1_c : natural := 64; -- opcode7 bit 1
constant ctrl_ir_opcode7_2_c : natural := 65; -- opcode7 bit 2
constant ctrl_ir_opcode7_3_c : natural := 66; -- opcode7 bit 3
constant ctrl_ir_opcode7_4_c : natural := 67; -- opcode7 bit 4
constant ctrl_ir_opcode7_5_c : natural := 68; -- opcode7 bit 5
constant ctrl_ir_opcode7_6_c : natural := 69; -- opcode7 bit 6
-- cpu status --
constant ctrl_priv_mode_c : natural := 72; -- effective privilege mode
constant ctrl_sleep_c : natural := 73; -- set when CPU is in sleep mode
constant ctrl_trap_c : natural := 74; -- set when CPU is entering trap execution
constant ctrl_debug_running_c : natural := 75; -- set when CPU is in debug mode
constant ctrl_priv_mode_c : natural := 70; -- effective privilege mode
constant ctrl_sleep_c : natural := 71; -- set when CPU is in sleep mode
constant ctrl_trap_c : natural := 72; -- set when CPU is entering trap execution
constant ctrl_debug_running_c : natural := 73; -- set when CPU is in debug mode
-- control bus size --
constant ctrl_width_c : natural := 76; -- control bus size
constant ctrl_width_c : natural := 74; -- control bus size
 
-- Comparator Bus -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
433,8 → 429,6
constant instr_imm12_msb_c : natural := 31; -- immediate12 bit 11
constant instr_imm20_lsb_c : natural := 12; -- immediate20 bit 0
constant instr_imm20_msb_c : natural := 31; -- immediate20 bit 21
constant instr_csr_id_lsb_c : natural := 20; -- csr select bit 0
constant instr_csr_id_msb_c : natural := 31; -- csr select bit 11
constant instr_funct5_lsb_c : natural := 27; -- funct5 select bit 0
constant instr_funct5_msb_c : natural := 31; -- funct5 select bit 4
 
454,7 → 448,7
constant opcode_store_c : std_ulogic_vector(6 downto 0) := "0100011"; -- store (data type via funct3)
-- system/csr --
constant opcode_fence_c : std_ulogic_vector(6 downto 0) := "0001111"; -- fence / fence.i
constant opcode_syscsr_c : std_ulogic_vector(6 downto 0) := "1110011"; -- system/csr access (type via funct3)
constant opcode_system_c : std_ulogic_vector(6 downto 0) := "1110011"; -- system/csr access (type via funct3)
-- atomic memory access (A) --
constant opcode_atomic_c : std_ulogic_vector(6 downto 0) := "0101111"; -- atomic operations (A extension)
-- floating point operations (Zfinx-only) (F/D/H/Q) --
507,8 → 501,8
-- system --
constant funct12_ecall_c : std_ulogic_vector(11 downto 0) := x"000"; -- ecall
constant funct12_ebreak_c : std_ulogic_vector(11 downto 0) := x"001"; -- ebreak
constant funct12_wfi_c : std_ulogic_vector(11 downto 0) := x"105"; -- wfi
constant funct12_mret_c : std_ulogic_vector(11 downto 0) := x"302"; -- mret
constant funct12_wfi_c : std_ulogic_vector(11 downto 0) := x"105"; -- wfi
constant funct12_dret_c : std_ulogic_vector(11 downto 0) := x"7b2"; -- dret
 
-- RISC-V Funct5 --------------------------------------------------------------------------
554,6 → 548,7
 
-- RISC-V CSR Addresses -------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant csr_zero_c : std_ulogic_vector(11 downto 0) := x"000"; -- always returns zero, only relevant for hardware access
-- <<< standard read/write CSRs >>> --
-- user floating-point CSRs --
constant csr_class_float_c : std_ulogic_vector(09 downto 0) := x"00" & "00"; -- floating point
847,7 → 842,7
--constant trap_ipf_c x : std_ulogic_vector(6 downto 0) := "0" & "0" & "01100"; -- 0.12: instruction page fault
--constant trap_lpf_c x : std_ulogic_vector(6 downto 0) := "0" & "0" & "01101"; -- 0.13: load page fault
--constant trap_???_c x : std_ulogic_vector(6 downto 0) := "0" & "0" & "01110"; -- 0.14: reserved
--constant trap_lpf_c x : std_ulogic_vector(6 downto 0) := "0" & "0" & "01111"; -- 0.15: store page fault
--constant trap_spf_c x : std_ulogic_vector(6 downto 0) := "0" & "0" & "01111"; -- 0.15: store page fault
-- NEORV32-specific (custom) synchronous exceptions --
-- none implemented yet
-- RISC-V compliant asynchronous exceptions (interrupts) --
/rtl/core/neorv32_slink.vhd
8,7 → 8,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, 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: #
208,7 → 208,9
end if;
ack_write <= '1';
else -- TX links
ack_write <= or_reduce_f(link_sel and tx_fifo_free);
if (or_reduce_f(link_sel and tx_fifo_free) = '1') then
ack_write <= '1';
end if;
end if;
end if;
 
243,8 → 245,10
data_o <= (others => '0');
end case;
else -- RX links
data_o <= rx_fifo_rdata(to_integer(unsigned(addr(4 downto 2))));
ack_read <= or_reduce_f(link_sel and rx_fifo_avail);
data_o <= rx_fifo_rdata(to_integer(unsigned(addr(4 downto 2))));
if (or_reduce_f(link_sel and rx_fifo_avail) = '1') then
ack_read <= '1';
end if;
end if;
end if;
end if;
328,8 → 332,14
irq_generator: process(clk_i)
begin
if rising_edge(clk_i) then
irq_rx_o <= or_reduce_f(rx_irq.set);
irq_tx_o <= or_reduce_f(tx_irq.set);
irq_rx_o <= '0';
irq_tx_o <= '0';
if (or_reduce_f(rx_irq.set) = '1') then
irq_rx_o <= '1';
end if;
if (or_reduce_f(tx_irq.set) = '1') then
irq_tx_o <= '1';
end if;
end if;
end process irq_generator;
 
/rtl/core/neorv32_top.vhd
246,10 → 246,10
constant io_slink_en_c : boolean := boolean(SLINK_NUM_RX > 0) or boolean(SLINK_NUM_TX > 0); -- implement slink at all?
 
-- reset generator --
signal rstn_gen : std_ulogic_vector(7 downto 0) := (others => '0'); -- initialize (=reset) via bitstream (for FPGAs only)
signal ext_rstn : std_ulogic;
signal sys_rstn : std_ulogic;
signal wdt_rstn : std_ulogic;
signal ext_rstn_sync : std_ulogic_vector(3 downto 0) := (others => '0'); -- initialize (=reset) via bitstream (for FPGAs only)
signal ext_rstn : std_ulogic;
signal sys_rstn : std_ulogic;
signal wdt_rstn : std_ulogic;
 
-- clock generator --
signal clk_div : std_ulogic_vector(11 downto 0);
417,34 → 417,40
reset_generator: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
rstn_gen <= (others => '0');
sys_rstn <= '0';
ext_rstn_sync <= (others => '0');
ext_rstn <= '0';
sys_rstn <= '0';
elsif rising_edge(clk_i) then
-- keep internal reset active for at least <rstn_gen'size> clock cycles --
rstn_gen <= rstn_gen(rstn_gen'left-1 downto 0) & '1';
-- keep internal reset active for at least <ext_rstn_sync'size> clock cycles --
ext_rstn_sync <= ext_rstn_sync(ext_rstn_sync'left-1 downto 0) & '1';
-- beautified external reset signal --
if (and_reduce_f(ext_rstn_sync) = '1') then
ext_rstn <= '1';
else
ext_rstn <= '0';
end if;
-- system reset: can also be triggered by watchdog and debug module --
sys_rstn <= ext_rstn and wdt_rstn and dci_ndmrstn;
end if;
end process reset_generator;
 
-- beautified external reset signal --
ext_rstn <= rstn_gen(rstn_gen'left);
 
 
-- Clock Generator ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
clock_generator: process(sys_rstn, clk_i)
begin
if (sys_rstn = '0') then
clk_gen_en_ff <= '-';
clk_div_ff <= (others => '-');
clk_div <= (others => '0'); -- reset required
clk_gen_en_ff <= '0';
clk_div <= (others => '0');
clk_div_ff <= (others => '0');
elsif rising_edge(clk_i) then
clk_gen_en_ff <= or_reduce_f(clk_gen_en);
clk_div_ff <= clk_div;
if (clk_gen_en_ff = '1') then -- actual clock generator
if (clk_gen_en_ff = '1') then
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
else
clk_div <= (others => '0');
end if;
clk_div_ff <= clk_div;
end if;
end process clock_generator;
 
944,8 → 950,8
-- 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_wren <= io_acc and p_bus.we and and_reduce_f(p_bus.ben); -- only full-word write accesses are allowed (reduces HW complexity)
io_rden <= '1' when (io_acc = '1') and (p_bus.re = '1') else '0';
io_wren <= '1' when (io_acc = '1') and (p_bus.we = '1') and (p_bus.ben = "1111") else '0'; -- only full-word write accesses are allowed (reduces HW complexity)
 
 
-- Custom Functions Subsystem (CFS) -------------------------------------------------------
/rtl/core/neorv32_trng.vhd
6,7 → 6,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, 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: #
198,7 → 198,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, 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: #
327,7 → 327,7
 
-- enable chain --
cell_array.en_in(0) <= ctrl.enable; -- start of chain
cell_array.en_in(NUM_CELLS-1 downto 1) <=cell_array.en_out(NUM_CELLS-2 downto 0); -- i+1 <= i
cell_array.en_in(NUM_CELLS-1 downto 1) <= cell_array.en_out(NUM_CELLS-2 downto 0); -- i+1 <= i
 
 
-- XOR All Cell's Outputs -----------------------------------------------------------------
389,6 → 389,12
ctrl.sreg <= ctrl.sreg(ctrl.sreg'left-1 downto 0) & deb.data;
end if;
 
-- data valid? --
if (ctrl.cnt = "000") and (ctrl.run = '1') and (deb.valid = '1') then
valid_o <= '1';
else
valid_o <= '0';
end if;
end if;
end process control_unit;
 
395,10 → 401,7
-- random byte output --
data_o <= ctrl.sreg;
 
-- data valid? --
valid_o <= '1' when (ctrl.cnt = "000") and (ctrl.run = '1') else '0';
 
 
end neoTRNG_rtl;
 
 
/rtl/core/neorv32_uart.vhd
28,7 → 28,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, 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: #
592,57 → 592,55
 
-- SIMULATION Transmitter -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- pragma translate_off
-- synthesis translate_off
-- RTL_SYNTHESIS OFF
sim_output: process(clk_i) -- for SIMULATION ONLY!
file file_uart_text_out : text open write_mode is sim_uart_text_file_c;
file file_uart_data_out : text open write_mode is sim_uart_data_file_c;
variable char_v : integer;
variable line_screen_v : line; -- we need several line variables here since "writeline" seems to flush the source variable
variable line_text_v : line;
variable line_data_v : line;
begin
if rising_edge(clk_i) then
if (tx_engine.state = S_TX_SIM) then -- UART simulation mode
-- print lowest byte as ASCII char --
char_v := to_integer(unsigned(tx_buffer.rdata(7 downto 0)));
if (char_v >= 128) then -- out of range?
char_v := 0;
end if;
simulation_transmitter:
if (is_simulation_c = true) generate -- for SIMULATION ONLY!
sim_output: process(clk_i)
file file_uart_text_out : text open write_mode is sim_uart_text_file_c;
file file_uart_data_out : text open write_mode is sim_uart_data_file_c;
variable char_v : integer;
variable line_screen_v : line; -- we need several line variables here since "writeline" seems to flush the source variable
variable line_text_v : line;
variable line_data_v : line;
begin
if rising_edge(clk_i) then
if (tx_engine.state = S_TX_SIM) then -- UART simulation mode
-- print lowest byte as ASCII char --
char_v := to_integer(unsigned(tx_buffer.rdata(7 downto 0)));
if (char_v >= 128) then -- out of range?
char_v := 0;
end if;
 
if (char_v /= 10) and (char_v /= 13) then -- skip line breaks - they are issued via "writeline"
if (sim_screen_output_en_c = true) then
write(line_screen_v, character'val(char_v));
if (char_v /= 10) and (char_v /= 13) then -- skip line breaks - they are issued via "writeline"
if (sim_screen_output_en_c = true) then
write(line_screen_v, character'val(char_v));
end if;
if (sim_text_output_en_c = true) then
write(line_text_v, character'val(char_v));
end if;
end if;
if (sim_text_output_en_c = true) then
write(line_text_v, character'val(char_v));
 
if (char_v = 10) then -- line break: write to screen and text file
if (sim_screen_output_en_c = true) then
writeline(output, line_screen_v);
end if;
if (sim_text_output_en_c = true) then
writeline(file_uart_text_out, line_text_v);
end if;
end if;
end if;
 
if (char_v = 10) then -- line break: write to screen and text file
if (sim_screen_output_en_c = true) then
writeline(output, line_screen_v);
-- dump raw data as 8 hex chars to file --
if (sim_data_output_en_c = true) then
for x in 7 downto 0 loop
write(line_data_v, to_hexchar_f(tx_buffer.rdata(3+x*4 downto 0+x*4))); -- write in hex form
end loop; -- x
writeline(file_uart_data_out, line_data_v);
end if;
if (sim_text_output_en_c = true) then
writeline(file_uart_text_out, line_text_v);
end if;
end if;
 
-- dump raw data as 8 hex chars to file --
if (sim_data_output_en_c = true) then
for x in 7 downto 0 loop
write(line_data_v, to_hexchar_f(tx_buffer.rdata(3+x*4 downto 0+x*4))); -- write in hex form
end loop; -- x
writeline(file_uart_data_out, line_data_v);
end if;
 
end if;
end if;
end process sim_output;
-- RTL_SYNTHESIS ON
-- synthesis translate_on
-- pragma translate_on
end process sim_output;
end generate;
 
 
end neorv32_uart_rtl;
/rtl/core/neorv32_xirq.vhd
10,7 → 10,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, 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: #
186,7 → 186,7
end process irq_buffer;
 
-- anyone firing? --
irq_fire <= or_reduce_f(irq_buf);
irq_fire <= '1' when (or_reduce_f(irq_buf) = '1') else '0';
 
 
-- IRQ Priority Encoder -----------------------------------------------------
/rtl/README.md
1,4 → 1,4
## HArdware RTL Sources
## Hardware RTL Sources
 
 
### [`core`](https://github.com/stnolting/neorv32/tree/main/rtl/core)
12,13 → 12,13
You can _replace_ inclusion of these files by platform-optimized memory architectures.
 
 
### [`processor_templates`](https://github.com/stnolting/neorv32/tree/main/rtl/processor_templates`)
### [`processor_templates`](https://github.com/stnolting/neorv32/tree/main/rtl/processor_templates)
 
Contains pre-configured "SoC" templates that instantiate the processor's top entity from `core`.
These templates can be instantiated directly within a FPGA-specific board wrapper.
 
 
### [`system_integration`](https://github.com/stnolting/neorv32/tree/main/rtl/system_integration`)
### [`system_integration`](https://github.com/stnolting/neorv32/tree/main/rtl/system_integration)
 
Top entities in this folder provide the same peripheral/IO signals and configuration generics as the default
processor top entity from `core`, but feature a different interface type.
26,7 → 26,7
or a top entity with _resolved_ port signal types.
 
 
### [`test_setups`](https://github.com/stnolting/neorv32/tree/main/rtl/test_setups`)
### [`test_setups`](https://github.com/stnolting/neorv32/tree/main/rtl/test_setups)
 
Minimal test setups (FPGA- and board-independent) for the processor. See the
[README](https://github.com/stnolting/neorv32/tree/main/rtl/test_setups)
/sim/README.md
22,37 → 22,3
- [`neorv32_tb.vhd`](neorv32_tb.vhd)
- [`uart_rx_pkg.vhd`](uart_rx_pkg.vhd)
- [`uart_rx.vhd`](uart_rx.vhd)
 
 
## [`run_riscv_arch_test.sh`](run_riscv_arch_test.sh): NEORV32 RISC-V Architecture Test Framework
 
This script tests the NEORV32 Processor for RISC-V compatibility using the
[official RISC-V architecture test suite v2+](https://github.com/riscv/riscv-arch-test).
The core's HDL sources are *simulated* using `GHDL` to provide a virtual execution platform for the test framework:
 
* `rv32i_m/C` - compressed instructions
* `rv32i_m/I` - base ISA
* `rv32i_m/M` - hardware integer multiplication and division
* `rv32i_m/privilege` - privileged architecture
* `rv32i_m/Zifencei` - instruction stream synchronization (for example for self-modifying code)
 
:warning: The RISC-V GCC toolchain (`riscv{32|64}-unknown-elf`) is required for program compilation, and the simulation
depends on `simple/ghdl_sim.sh`.
 
To execute all the supported tests open a terminal and run [`./sim/run_riscv_arch_test.sh`](run_riscv_arch_test.sh),
which does the following:
 
* Make a local copy of the NEORV32 `rtl` folder in `work/`, to keep the project's core files clean.
* Clone (as `git submodule`) the [riscv-arch-test repository](https://github.com/riscv/riscv-arch-test) into `sw/isa-test/riscv-arch-test`.
* Install (copy) the custom `neorv32` test target from `sw/isa-test/port-neorv32` to the
test suite's target folder `work/riscv-arch-test/riscv-target/neorv32`.
* Run the actual tests.
 
:warning: Simulating all the test cases takes quite some time. Some tests use an optimised description of IMEM
(`neorv32_imem.simple.vhd`), but others require the original because they execute self-modifying code.
 
:warning: If the simulation of a test does not generate any signature output at all or if the signature is truncated,
try increasing the simulation time by modiying the `SIM_TIME` variable when calling the test makefiles in `run_riscv_arch_test.sh`.
 
More datails regarding the actual simulation process can be found in the
[target's `README`](../sw/riscv-arch-test/port-neorv32/framework_v2.0/riscv-target/neorv32/README.md).
/sim/neorv32_tb.vhd
219,7 → 219,7
if ci_mode then
-- No need to send the full expectation in one big chunk
check_uart(net, uart1_rx_handle, nul & nul);
check_uart(net, uart1_rx_handle, "0/45" & cr & lf);
check_uart(net, uart1_rx_handle, "0/50" & cr & lf);
end if;
 
-- Apply some random data on each SLINK inputs and expect it to
/sw/isa-test/common.mk File deleted
/sw/bootloader/bootloader.c
565,7 → 565,8
PRINT_TEXT("Loading... ");
 
// flash checks
if (spi_flash_read_1st_id() == 0x00) { // check if flash ready (or available at all)
if (((NEORV32_SYSINFO.SOC & (1<<SYSINFO_SOC_IO_SPI)) == 0x00) || // SPI module implemented?
(spi_flash_read_1st_id() == 0x00)) { // check if flash ready (or available at all)
system_error(ERROR_FLASH);
}
}
/sw/common/crt0.S
47,8 → 47,13
// ************************************************************************************************
// This is the very first instruction that is executed after hardware reset. It ensures that x0 is
// written at least once - the CPU HW will ensure it is always set to zero on any write access.
//
// Furthermore, we have to disable ALL interrupts, which is required if this code is part of a
// program uploaded by the on-chip debugger (potentionally taking control from the bootloader).
// We setup a new stack pointer here and WE DO NOT WANT TO trap to an outdated trap handler with
// a modified stack pointer.
// ************************************************************************************************
lui zero, 0 // "dummy" instruction that uses no reg-file input operands at all
csrrci zero, mstatus, (1<<3) // disable global interrupt flag and write "anything" to x0
 
 
// ************************************************************************************************
/sw/example/demo_newlib/main.c
0,0 → 1,142
// #################################################################################################
// # << NEORV32 - Newlib Demo/Test Program >> #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2022, 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 #
// #################################################################################################
 
 
/**********************************************************************//**
* @file demo_newlib/main.c
* @author Stephan Nolting
* @brief Demo/test program for NEORV32's newlib C standard library support.
**************************************************************************/
#include <neorv32.h>
#include <unistd.h>
#include <stdlib.h>
 
 
/**********************************************************************//**
* @name User configuration
**************************************************************************/
/**@{*/
/** UART BAUD rate */
#define BAUD_RATE 19200
/**@}*/
 
 
/**********************************************************************//**
* Main function: Check some of newlib's core functions.
*
* @note This program requires UART0.
*
* @return 0 if execution was successful
**************************************************************************/
int main() {
 
// setup NEORV32 runtime environment to keep us safe
// -> catch all traps and give debug information via UART0
neorv32_rte_setup();
 
// setup UART0 at default baud rate, no parity bits, no HW flow control
neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
 
// check if UART0 is implemented at all
if (neorv32_uart0_available() == 0) {
neorv32_uart0_printf("Error! UART0 not synthesized!\n");
return 1;
}
 
 
// say hello
neorv32_uart0_printf("<<< Newlib demo/test program >>>\n\n");
 
 
// check if newlib is really available
#ifndef __NEWLIB__
neorv32_uart0_printf("ERROR! Seems like the compiler toolchain does not support newlib...\n");
return -1;
#endif
 
neorv32_uart0_printf("newlib version %i.%i\n\n", (int32_t)__NEWLIB__, (int32_t)__NEWLIB_MINOR__);
 
neorv32_uart0_printf("<rand> test... ");
srand(neorv32_cpu_csr_read(CSR_CYCLE)); // set random seed
neorv32_uart0_printf("%i, %i, %i, %i ", rand() % 100, rand() % 100, rand() % 100, rand() % 100);
neorv32_uart0_printf("ok\n");
 
 
char *char_buffer; // pointer for dynamic memory allocation
 
neorv32_uart0_printf("<malloc> test... ");
char_buffer = (char *) malloc(4 * sizeof(char)); // 4 bytes
neorv32_uart0_printf("ok\n");
 
// do not test read & write in simulation as there would be no UART RX input
if (NEORV32_SYSINFO.SOC & (1<<SYSINFO_SOC_IS_SIM)) {
neorv32_uart0_printf("Skipping <read> & <write> tests as this seems to be a simulation.\n");
}
else {
neorv32_uart0_printf("<read> test (waiting for 4 chars via UART0)... ");
read((int)STDIN_FILENO, char_buffer, 4 * sizeof(char)); // get 4 chars from "STDIN" (UART0.RX)
neorv32_uart0_printf("ok\n");
 
neorv32_uart0_printf("<write> test to 'STDOUT'... (outputting the chars you have send)\n");
write((int)STDOUT_FILENO, char_buffer, 4 * sizeof(char)); // send 4 chars to "STDOUT" (UART0.TX)
neorv32_uart0_printf("\nok\n");
 
neorv32_uart0_printf("<write> test to 'STDERR'... (outputting the chars you have send)\n");
write((int)STDERR_FILENO, char_buffer, 4 * sizeof(char)); // send 4 chars to "STDERR" (UART0.TX)
neorv32_uart0_printf("\nok\n");
}
 
neorv32_uart0_printf("<free> test... ");
free(char_buffer);
neorv32_uart0_printf("ok\n");
 
 
// NOTE: exit is highly oversized as it also includes clean-up functions (destructors), which
// is not required for bare-metal or RTOS applications... better use the simple 'return' or even better
// make sure main never returns. however, let's test that 'exit' works.
neorv32_uart0_printf("<exit> test...");
exit(0);
 
return 0; // should never be reached
}
 
 
/**********************************************************************//**
* "after-main" handler that is executed after the application's
* main function returns (called by crt0.S start-up code)
**************************************************************************/
void __neorv32_crt0_after_main(int32_t return_code) {
 
neorv32_uart0_printf("\n<RTE> main function returned with exit code %i </RTE>\n", return_code);
}
/sw/example/demo_newlib/makefile
0,0 → 1,40
#################################################################################################
# << NEORV32 - Application Makefile >> #
# ********************************************************************************************* #
# Make sure to add the RISC-V GCC compiler's bin folder to your PATH environment variable. #
# ********************************************************************************************* #
# BSD 3-Clause License #
# #
# Copyright (c) 2022, 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 #
#################################################################################################
 
# Modify this variable to fit your NEORV32 setup (neorv32 home folder)
NEORV32_HOME ?= ../../..
 
include $(NEORV32_HOME)/sw/common/common.mk
/sw/example/dhrystone/dhrystone.sh
1,2 → 1,6
#!/usr/bin/env bash
 
set -e
 
echo "Generating dhrystone executable..."
make USER_FLAGS+="-DRUN_DHRYSTONE -DDHRY_ITERS=2000000 -DNOENUM" MARCH=rv32imc EFFORT=-O3 clean_all exe
/sw/example/floating_point_test/neorv32_zfinx_extension_intrinsics.h
86,7 → 86,7
// ################################################################################################
 
/**********************************************************************//**
* Flush to zero if denormal number.
* Flush to zero if de-normal number.
*
* @warning Subnormal numbers are not supported yet! Flush them to zero.
*
97,6 → 97,7
 
float res = tmp;
 
// flush to zero if subnormal
if (fpclassify(tmp) == FP_SUBNORMAL) {
if (signbit(tmp) != 0) {
res = -0.0f;
581,6 → 582,12
float opb = subnormal_flush(rs2);
 
float res = opa + opb;
 
// make NAN canonical
if (fpclassify(res) == FP_NAN) {
res = NAN;
}
 
return subnormal_flush(res);
}
 
598,6 → 605,12
float opb = subnormal_flush(rs2);
 
float res = opa - opb;
 
// make NAN canonical
if (fpclassify(res) == FP_NAN) {
res = NAN;
}
 
return subnormal_flush(res);
}
 
/sw/example/processor_check/main.c
217,9 → 217,6
// test intro
PRINT_STANDARD("\nStarting tests.\n\n");
 
// sync (test)
asm volatile ("fence.i");
 
// enable global interrupts
neorv32_cpu_eint();
 
230,12 → 227,26
 
 
// ----------------------------------------------------------
// Test fence instructions (just make sure CPU does not crash)
// Test fence instructions
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] FENCE(.I): ", cnt_test);
 
cnt_test++;
 
asm volatile ("fence");
asm volatile ("fence.i");
asm volatile ("fence");
asm volatile ("fence.i");
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
test_ok();
}
else {
test_fail();
}
 
 
// ----------------------------------------------------------
// Test performance counter: setup as many events and counter as feasible
// ----------------------------------------------------------
275,59 → 286,59
}
 
 
//// ----------------------------------------------------------
//// Test standard RISC-V performance counter [m]cycle[h]
//// ----------------------------------------------------------
//neorv32_cpu_csr_write(CSR_MCAUSE, 0);
//PRINT_STANDARD("[%i] cycle counter: ", cnt_test);
//
//cnt_test++;
//
//// make sure counter is enabled
//asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_CY));
//
//// prepare overflow
//neorv32_cpu_set_mcycle(0x00000000FFFFFFFFULL);
//
//// get current cycle counter HIGH
//tmp_a = neorv32_cpu_csr_read(CSR_MCYCLEH);
//
//// make sure cycle counter high has incremented and there was no exception during access
//if ((tmp_a == 1) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
// test_ok();
//}
//else {
// test_fail();
//}
// ----------------------------------------------------------
// Test standard RISC-V performance counter [m]cycle[h]
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] cycle counter: ", cnt_test);
 
cnt_test++;
 
//// ----------------------------------------------------------
//// Test standard RISC-V performance counter [m]instret[h]
//// ----------------------------------------------------------
//neorv32_cpu_csr_write(CSR_MCAUSE, 0);
//PRINT_STANDARD("[%i] instret counter: ", cnt_test);
//
//cnt_test++;
//
//// make sure counter is enabled
//asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_IR));
//
//// prepare overflow
//neorv32_cpu_set_minstret(0x00000000FFFFFFFFULL);
//
//// get instruction counter HIGH
//tmp_a = neorv32_cpu_csr_read(CSR_INSTRETH);
//
//// make sure instruction counter high has incremented and there was no exception during access
//if ((tmp_a == 1) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
// test_ok();
//}
//else {
// test_fail();
//}
// make sure counter is enabled
asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_CY));
 
// prepare overflow
neorv32_cpu_set_mcycle(0x00000000FFFFFFFFULL);
 
// get current cycle counter HIGH
tmp_a = neorv32_cpu_csr_read(CSR_MCYCLEH);
 
// make sure cycle counter high has incremented and there was no exception during access
if ((tmp_a == 1) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
}
else {
test_fail();
}
 
 
// ----------------------------------------------------------
// Test standard RISC-V performance counter [m]instret[h]
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] instret counter: ", cnt_test);
 
cnt_test++;
 
// make sure counter is enabled
asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_IR));
 
// prepare overflow
neorv32_cpu_set_minstret(0x00000000FFFFFFFFULL);
 
// get instruction counter HIGH
tmp_a = neorv32_cpu_csr_read(CSR_INSTRETH);
 
// make sure instruction counter high has incremented and there was no exception during access
if ((tmp_a == 1) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
}
else {
test_fail();
}
 
 
// ----------------------------------------------------------
// Test mcountinhibt: inhibit auto-inc of [m]cycle
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
376,19 → 387,21
tmp_a &= ~(1<<CSR_MCOUNTEREN_CY); // clear access right
neorv32_cpu_csr_write(CSR_MCOUNTEREN, tmp_a);
 
neorv32_cpu_csr_write(CSR_CYCLEH, 1); // make sure CSR is != 0 for this test
neorv32_cpu_csr_write(CSR_MCYCLE, 0);
neorv32_cpu_csr_write(CSR_MCYCLEH, 123); // make sure CSR is != 0 for this test
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
goto_user_mode();
{
// access to cycle CSR is no longer allowed
asm volatile (" li %[result], 0xcc11aa22 \n" // initialize
" rdcycleh %[result] " // read CSR_CYCLE, is not allowed and should not alter [result]
: [result] "=r" (tmp_a) : );
asm volatile (" li %[result], 0xcc11aa22 \n" // initialize
" csrrw %[result], cycleh, %[input] " // read and write CSR_CYCLE, not allowed and should not alter [result] nor CSR
: [result] "=r" (tmp_a) : [input] "r" (tmp_a) );
}
 
// make sure there was an illegal instruction trap
if ((neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) &&
(neorv32_cpu_csr_read(CSR_CYCLEH) == 123) && // csr not altered
(tmp_a == 0xcc11aa22)) { // destination register not altered
test_ok();
}
499,26 → 512,26
}
 
 
//// ----------------------------------------------------------
//// No "real" CSR write access (because rs1 = r0)
//// ----------------------------------------------------------
//neorv32_cpu_csr_write(CSR_MCAUSE, 0);
//PRINT_STANDARD("[%i] Read-only CSR 'no-write' (rs1=0) access: ", cnt_test);
//
//cnt_test++;
//
//// time CSR is read-only, but no actual write is performed because rs1=r0
//// -> should cause no exception
//asm volatile("csrrs zero, time, zero");
//
//if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
// test_ok();
//}
//else {
// test_fail();
//}
// ----------------------------------------------------------
// No "real" CSR write access (because rs1 = r0)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] Read-only CSR 'no-write' (rs1=0) access: ", cnt_test);
 
cnt_test++;
 
// time CSR is read-only, but no actual write is performed because rs1=r0
// -> should cause no exception
asm volatile("csrrs zero, time, zero");
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
test_ok();
}
else {
test_fail();
}
 
 
// ----------------------------------------------------------
// Unaligned instruction address
// ----------------------------------------------------------
573,26 → 586,30
 
cnt_test++;
 
// illegal 32-bit instruction (malformed SRA)
// clear mstatus.mie and set mstatus.mpie
tmp_a = neorv32_cpu_csr_read(CSR_MSTATUS);
tmp_a &= ~(1 << CSR_MSTATUS_MIE);
tmp_a |= (1 << CSR_MSTATUS_MPIE);
neorv32_cpu_csr_write(CSR_MSTATUS, tmp_a);
 
// illegal 32-bit instruction (MRET with incorrect opcode)
asm volatile (".align 4 \n"
".word 0xC0000033");
".word 0x3020007f");
 
// make sure this has cause an illegal exception
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
// make sure this is really the instruction that caused the exception
// -> for illegal instructions MTVAL contains the faulting instruction word
if (neorv32_cpu_csr_read(CSR_MTVAL) == 0xC0000033) {
test_ok();
}
else {
test_fail();
}
if ((neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) && // illegal instruction exception
(neorv32_cpu_csr_read(CSR_MTVAL) == 0x3020007f) && // correct instruction word
((neorv32_cpu_csr_read(CSR_MSTATUS) & (1 << CSR_MSTATUS_MIE)) == 0)) { // MIE should still be cleared
test_ok();
}
else {
test_fail();
}
 
// clear mstatus.mie
neorv32_cpu_dint();
 
 
// ----------------------------------------------------------
// Illegal compressed instruction
// ----------------------------------------------------------
1439,7 → 1456,7
// Test WFI ("sleep") instruction (executed in user mode), wakeup via MTIME
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] WFI (sleep instruction, wake-up via MTIME): ", cnt_test);
PRINT_STANDARD("[%i] WFI (wake-up via MTIME): ", cnt_test);
 
cnt_test++;
 
1471,6 → 1488,31
 
 
// ----------------------------------------------------------
// Test unallowed WFI ("sleep") instruction (executed in user mode)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] WFI (not allowed in u-mode): ", cnt_test);
 
cnt_test++;
 
// set mstatus.TW to disallow execution of WFI in user-mode
neorv32_cpu_csr_write(CSR_MSTATUS, neorv32_cpu_csr_read(CSR_MSTATUS) | (1<<CSR_MSTATUS_TW));
 
// put CPU into sleep mode (from user mode)
goto_user_mode();
{
asm volatile ("wfi"); // this has to fail
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
test_fail();
}
 
 
// ----------------------------------------------------------
// Test invalid CSR access in user mode
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
/sw/example/processor_check/run_check.sh
1,2 → 1,6
#!/usr/bin/env bash
 
set -e
 
echo "Starting processor check simulation..."
make USER_FLAGS+="-DRUN_CHECK -DUART0_SIM_MODE -DUART1_SIM_MODE -g" MARCH=rv32imac clean_all sim
/sw/image_gen/uart_upload.sh
1,4 → 1,4
#!/bin/sh
#!/usr/bin/env bash
 
set -e
 
/sw/lib/include/neorv32.h
502,35 → 502,35
* Trap codes from mcause CSR.
**************************************************************************/
enum NEORV32_EXCEPTION_CODES_enum {
TRAP_CODE_I_MISALIGNED = 0x00000000, /**< 0.0: Instruction address misaligned */
TRAP_CODE_I_ACCESS = 0x00000001, /**< 0.1: Instruction (bus) access fault */
TRAP_CODE_I_ILLEGAL = 0x00000002, /**< 0.2: Illegal instruction */
TRAP_CODE_BREAKPOINT = 0x00000003, /**< 0.3: Breakpoint (EBREAK instruction) */
TRAP_CODE_L_MISALIGNED = 0x00000004, /**< 0.4: Load address misaligned */
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_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 */
TRAP_CODE_FIRQ_0 = 0x80000010, /**< 1.16: Fast interrupt channel 0 */
TRAP_CODE_FIRQ_1 = 0x80000011, /**< 1.17: Fast interrupt channel 1 */
TRAP_CODE_FIRQ_2 = 0x80000012, /**< 1.18: Fast interrupt channel 2 */
TRAP_CODE_FIRQ_3 = 0x80000013, /**< 1.19: Fast interrupt channel 3 */
TRAP_CODE_FIRQ_4 = 0x80000014, /**< 1.20: Fast interrupt channel 4 */
TRAP_CODE_FIRQ_5 = 0x80000015, /**< 1.21: Fast interrupt channel 5 */
TRAP_CODE_FIRQ_6 = 0x80000016, /**< 1.22: Fast interrupt channel 6 */
TRAP_CODE_FIRQ_7 = 0x80000017, /**< 1.23: Fast interrupt channel 7 */
TRAP_CODE_FIRQ_8 = 0x80000018, /**< 1.24: Fast interrupt channel 8 */
TRAP_CODE_FIRQ_9 = 0x80000019, /**< 1.25: Fast interrupt channel 9 */
TRAP_CODE_FIRQ_10 = 0x8000001a, /**< 1.26: Fast interrupt channel 10 */
TRAP_CODE_FIRQ_11 = 0x8000001b, /**< 1.27: Fast interrupt channel 11 */
TRAP_CODE_FIRQ_12 = 0x8000001c, /**< 1.28: Fast interrupt channel 12 */
TRAP_CODE_FIRQ_13 = 0x8000001d, /**< 1.29: Fast interrupt channel 13 */
TRAP_CODE_FIRQ_14 = 0x8000001e, /**< 1.30: Fast interrupt channel 14 */
TRAP_CODE_FIRQ_15 = 0x8000001f /**< 1.31: Fast interrupt channel 15 */
TRAP_CODE_I_MISALIGNED = 0x00000000UL, /**< 0.0: Instruction address misaligned */
TRAP_CODE_I_ACCESS = 0x00000001UL, /**< 0.1: Instruction (bus) access fault */
TRAP_CODE_I_ILLEGAL = 0x00000002UL, /**< 0.2: Illegal instruction */
TRAP_CODE_BREAKPOINT = 0x00000003UL, /**< 0.3: Breakpoint (EBREAK instruction) */
TRAP_CODE_L_MISALIGNED = 0x00000004UL, /**< 0.4: Load address misaligned */
TRAP_CODE_L_ACCESS = 0x00000005UL, /**< 0.5: Load (bus) access fault */
TRAP_CODE_S_MISALIGNED = 0x00000006UL, /**< 0.6: Store address misaligned */
TRAP_CODE_S_ACCESS = 0x00000007UL, /**< 0.7: Store (bus) access fault */
TRAP_CODE_UENV_CALL = 0x00000008UL, /**< 0.8: Environment call from user mode (ECALL instruction) */
TRAP_CODE_MENV_CALL = 0x0000000bUL, /**< 0.11: Environment call from machine mode (ECALL instruction) */
TRAP_CODE_MSI = 0x80000003UL, /**< 1.3: Machine software interrupt */
TRAP_CODE_MTI = 0x80000007UL, /**< 1.7: Machine timer interrupt */
TRAP_CODE_MEI = 0x8000000bUL, /**< 1.11: Machine external interrupt */
TRAP_CODE_FIRQ_0 = 0x80000010UL, /**< 1.16: Fast interrupt channel 0 */
TRAP_CODE_FIRQ_1 = 0x80000011UL, /**< 1.17: Fast interrupt channel 1 */
TRAP_CODE_FIRQ_2 = 0x80000012UL, /**< 1.18: Fast interrupt channel 2 */
TRAP_CODE_FIRQ_3 = 0x80000013UL, /**< 1.19: Fast interrupt channel 3 */
TRAP_CODE_FIRQ_4 = 0x80000014UL, /**< 1.20: Fast interrupt channel 4 */
TRAP_CODE_FIRQ_5 = 0x80000015UL, /**< 1.21: Fast interrupt channel 5 */
TRAP_CODE_FIRQ_6 = 0x80000016UL, /**< 1.22: Fast interrupt channel 6 */
TRAP_CODE_FIRQ_7 = 0x80000017UL, /**< 1.23: Fast interrupt channel 7 */
TRAP_CODE_FIRQ_8 = 0x80000018UL, /**< 1.24: Fast interrupt channel 8 */
TRAP_CODE_FIRQ_9 = 0x80000019UL, /**< 1.25: Fast interrupt channel 9 */
TRAP_CODE_FIRQ_10 = 0x8000001aUL, /**< 1.26: Fast interrupt channel 10 */
TRAP_CODE_FIRQ_11 = 0x8000001bUL, /**< 1.27: Fast interrupt channel 11 */
TRAP_CODE_FIRQ_12 = 0x8000001cUL, /**< 1.28: Fast interrupt channel 12 */
TRAP_CODE_FIRQ_13 = 0x8000001dUL, /**< 1.29: Fast interrupt channel 13 */
TRAP_CODE_FIRQ_14 = 0x8000001eUL, /**< 1.30: Fast interrupt channel 14 */
TRAP_CODE_FIRQ_15 = 0x8000001fUL /**< 1.31: Fast interrupt channel 15 */
};
 
 
664,7 → 664,7
 
 
// ############################################################################################################################
// On-Chip Debugger (should NOT be used by application software)
// On-Chip Debugger (should NOT be used by application software at all!)
// ############################################################################################################################
/**@{*/
/** on-chip debugger - debug module prototype */
678,8 → 678,11
const uint32_t reserved3[31]; /**< offset 388..508: reserved */
} neorv32_dm_t;
 
/** on-chip debugger debug module base address */
#define NEORV32_DM_BASE (0XFFFFF800UL)
 
/** on-chip debugger debug module hardware access (#neorv32_dm_t) */
#define NEORV32_DM (*((volatile neorv32_dm_t*) (0XFFFFF800UL)))
#define NEORV32_DM (*((volatile neorv32_dm_t*) (NEORV32_DM_BASE)))
 
/** on-chip debugger debug module control and status register bits */
enum NEORV32_OCD_DM_SREG_enum {
730,8 → 733,11
uint32_t REG[32]; /**< offset 4*0..4*31: CFS register 0..31, user-defined */
} neorv32_cfs_t;
 
/** CFS base address */
#define NEORV32_CFS_BASE (0xFFFFFE00UL)
 
/** CFS module hardware access (#neorv32_cfs_t) */
#define NEORV32_CFS (*((volatile neorv32_cfs_t*) (0xFFFFFE00UL)))
#define NEORV32_CFS (*((volatile neorv32_cfs_t*) (NEORV32_CFS_BASE)))
/**@}*/
 
 
745,8 → 751,11
uint32_t DUTY[15]; /**< offset 4..60: duty cycle register 0..14 */
} neorv32_pwm_t;
 
/** PWM module base address */
#define NEORV32_PWM_BASE (0xFFFFFE80UL)
 
/** PWM module hardware access (#neorv32_pwm_t) */
#define NEORV32_PWM (*((volatile neorv32_pwm_t*) (0xFFFFFE80UL)))
#define NEORV32_PWM (*((volatile neorv32_pwm_t*) (NEORV32_PWM_BASE)))
 
/** PWM control register bits */
enum NEORV32_PWM_CTRL_enum {
773,8 → 782,11
uint32_t DATA[8]; /**< offset 32..60: stream link data channel 0..7 */
} neorv32_slink_t;
 
/** SLINK module base address */
#define NEORV32_SLINK_BASE (0xFFFFFEC0UL)
 
/** SLINK module hardware access (#neorv32_slink_t) */
#define NEORV32_SLINK (*((volatile neorv32_slink_t*) (0xFFFFFEC0UL)))
#define NEORV32_SLINK (*((volatile neorv32_slink_t*) (NEORV32_SLINK_BASE)))
 
/** SLINK control register bits */
enum NEORV32_SLINK_CTRL_enum {
885,8 → 897,11
uint32_t DATA_HI; /**< offset 12: SPI data register high */
} neorv32_xip_t;
 
/** XIP module base address */
#define NEORV32_XIP_BASE (0xFFFFFF40UL)
 
/** XIP module hardware access (#neorv32_xip_t) */
#define NEORV32_XIP (*((volatile neorv32_xip_t*) (0xFFFFFF40UL)))
#define NEORV32_XIP (*((volatile neorv32_xip_t*) (NEORV32_XIP_BASE)))
 
/** XIP control/data register bits */
enum NEORV32_XIP_CTRL_enum {
926,8 → 941,11
const uint32_t reserved; /**< offset 12: reserved */
} neorv32_gptmr_t;
 
/** GPTMR module base address */
#define NEORV32_GPTMR_BASE (0xFFFFFF60UL)
 
/** GPTMR module hardware access (#neorv32_gptmr_t) */
#define NEORV32_GPTMR (*((volatile neorv32_gptmr_t*) (0xFFFFFF60UL)))
#define NEORV32_GPTMR (*((volatile neorv32_gptmr_t*) (NEORV32_GPTMR_BASE)))
 
/** GPTMR control/data register bits */
enum NEORV32_GPTMR_CTRL_enum {
949,8 → 967,11
uint32_t CTRL; /**< offset 0: control register (#NEORV32_BUSKEEPER_CTRL_enum) */
} neorv32_buskeeper_t;
 
/** BUSKEEPER module base address */
#define NEORV32_BUSKEEPER_BASE (0xFFFFFF7CUL)
 
/** BUSKEEPER module hardware access (#neorv32_buskeeper_t) */
#define NEORV32_BUSKEEPER (*((volatile neorv32_buskeeper_t*) (0xFFFFFF7CUL)))
#define NEORV32_BUSKEEPER (*((volatile neorv32_buskeeper_t*) (NEORV32_BUSKEEPER_BASE)))
 
/** BUSKEEPER control/data register bits */
enum NEORV32_BUSKEEPER_CTRL_enum {
972,8 → 993,11
const uint32_t reserved; /**< offset 12: reserved */
} neorv32_xirq_t;
 
/** XIRQ module base address */
#define NEORV32_XIRQ_BASE (0xFFFFFF80UL)
 
/** XIRQ module hardware access (#neorv32_xirq_t) */
#define NEORV32_XIRQ (*((volatile neorv32_xirq_t*) (0xFFFFFF80UL)))
#define NEORV32_XIRQ (*((volatile neorv32_xirq_t*) (NEORV32_XIRQ_BASE)))
/**@}*/
 
 
989,8 → 1013,11
uint32_t TIMECMP_HI; /**< offset 12: compare register high word */
} neorv32_mtime_t;
 
/** MTIME module base address */
#define NEORV32_MTIME_BASE (0xFFFFFF90UL)
 
/** MTIME module hardware access (#neorv32_mtime_t) */
#define NEORV32_MTIME (*((volatile neorv32_mtime_t*) (0xFFFFFF90UL)))
#define NEORV32_MTIME (*((volatile neorv32_mtime_t*) (NEORV32_MTIME_BASE)))
/**@}*/
 
 
1004,8 → 1031,11
uint32_t DATA; /**< offset 4: data register (#NEORV32_UART_DATA_enum) */
} neorv32_uart0_t;
 
/** UART0 module base address */
#define NEORV32_UART0_BASE (0xFFFFFFA0UL)
 
/** UART0 module hardware access (#neorv32_uart0_t) */
#define NEORV32_UART0 (*((volatile neorv32_uart0_t*) (0xFFFFFFA0UL)))
#define NEORV32_UART0 (*((volatile neorv32_uart0_t*) (NEORV32_UART0_BASE)))
 
/** UART1 module prototype */
typedef struct __attribute__((packed,aligned(4))) {
1013,8 → 1043,11
uint32_t DATA; /**< offset 4: data register (#NEORV32_UART_DATA_enum) */
} neorv32_uart1_t;
 
/** UART1 module base address */
#define NEORV32_UART1_BASE (0xFFFFFFD0UL)
 
/** UART1 module hardware access (#neorv32_uart1_t) */
#define NEORV32_UART1 (*((volatile neorv32_uart1_t*) (0xFFFFFFD0UL)))
#define NEORV32_UART1 (*((volatile neorv32_uart1_t*) (NEORV32_UART1_BASE)))
 
/** UART0/UART1 control register bits */
enum NEORV32_UART_CTRL_enum {
1090,8 → 1123,11
uint32_t DATA; /**< offset 4: data register */
} neorv32_spi_t;
 
/** SPI module base address */
#define NEORV32_SPI_BASE (0xFFFFFFA8UL)
 
/** SPI module hardware access (#neorv32_spi_t) */
#define NEORV32_SPI (*((volatile neorv32_spi_t*) (0xFFFFFFA8UL)))
#define NEORV32_SPI (*((volatile neorv32_spi_t*) (NEORV32_SPI_BASE)))
 
/** SPI control register bits */
enum NEORV32_SPI_CTRL_enum {
1128,8 → 1164,11
uint32_t DATA; /**< offset 4: data register (#NEORV32_TWI_DATA_enum) */
} neorv32_twi_t;
 
/** TWI module base address */
#define NEORV32_TWI_BASE (0xFFFFFFB0UL)
 
/** TWI module hardware access (#neorv32_twi_t) */
#define NEORV32_TWI (*((volatile neorv32_twi_t*) (0xFFFFFFB0UL)))
#define NEORV32_TWI (*((volatile neorv32_twi_t*) (NEORV32_TWI_BASE)))
 
/** TWI control register bits */
enum NEORV32_TWI_CTRL_enum {
1162,8 → 1201,11
uint32_t CTRL; /**< offset 0: control register (#NEORV32_TRNG_CTRL_enum) */
} neorv32_trng_t;
 
/** TRNG module base address */
#define NEORV32_TRNG_BASE (0xFFFFFFB8UL)
 
/** TRNG module hardware access (#neorv32_trng_t) */
#define NEORV32_TRNG (*((volatile neorv32_trng_t*) (0xFFFFFFB8UL)))
#define NEORV32_TRNG (*((volatile neorv32_trng_t*) (NEORV32_TRNG_BASE)))
 
/** TRNG control/data register bits */
enum NEORV32_TRNG_CTRL_enum {
1185,8 → 1227,11
uint32_t CTRL; /**< offset 0: control register (#NEORV32_WDT_CTRL_enum) */
} neorv32_wdt_t;
 
/** WDT module base address */
#define NEORV32_WDT_BASE (0xFFFFFFBCUL)
 
/** WDT module hardware access (#neorv32_wdt_t) */
#define NEORV32_WDT (*((volatile neorv32_wdt_t*) (0xFFFFFFBCUL)))
#define NEORV32_WDT (*((volatile neorv32_wdt_t*) (NEORV32_WDT_BASE)))
 
/** WTD control register bits */
enum NEORV32_WDT_CTRL_enum {
1217,8 → 1262,11
uint32_t OUTPUT_HI; /**< offset 12: parallel output port upper 32-bit */
} neorv32_gpio_t;
 
/** GPIO module base address */
#define NEORV32_GPIO_BASE (0xFFFFFFC0UL)
 
/** GPIO module hardware access (#neorv32_gpio_t) */
#define NEORV32_GPIO (*((volatile neorv32_gpio_t*) (0xFFFFFFC0UL)))
#define NEORV32_GPIO (*((volatile neorv32_gpio_t*) (NEORV32_GPIO_BASE)))
/**@}*/
 
 
1232,8 → 1280,11
uint32_t DATA; /**< offset 4: data register (#NEORV32_NEOLED_CTRL_enum) */
} neorv32_neoled_t;
 
/** NEOLED module base address */
#define NEORV32_NEOLED_BASE (0xFFFFFFD8UL)
 
/** NEOLED module hardware access (#neorv32_neoled_t) */
#define NEORV32_NEOLED (*((volatile neorv32_neoled_t*) (0xFFFFFFD8UL)))
#define NEORV32_NEOLED (*((volatile neorv32_neoled_t*) (NEORV32_NEOLED_BASE)))
 
/** NEOLED control register bits */
enum NEORV32_NEOLED_CTRL_enum {
1292,8 → 1343,11
const uint32_t DMEM_SIZE; /**< offset 28: internal data memory (DMEM) size in bytes */
} neorv32_sysinfo_t;
 
/** SYSINFO module base address */
#define NEORV32_SYSINFO_BASE (0xFFFFFFE0UL)
 
/** SYSINFO module hardware access (#neorv32_sysinfo_t) */
#define NEORV32_SYSINFO (*((volatile neorv32_sysinfo_t*) (0xFFFFFFE0UL)))
#define NEORV32_SYSINFO (*((volatile neorv32_sysinfo_t*) (NEORV32_SYSINFO_BASE)))
 
/** NEORV32_SYSINFO.SOC (r/-): Implemented processor devices/features */
enum NEORV32_SYSINFO_SOC_enum {
/sw/lib/include/neorv32_cfs.h
35,11 → 35,10
 
/**********************************************************************//**
* @file neorv32_cfs.h
* @author Stephan Nolting
* @brief Custom Functions Subsystem (CFS)) HW driver header file.
*
* @warning There are no "real" CFS driver functions available here, because these functions are defined by the actual hardware.
* @warning Hence, the CFS designer has to provide the actual driver functions.
* @warning The CFS designer has to provide the actual driver functions.
*
* @note These functions should only be used if the CFS was synthesized (IO_CFS_EN = true).
**************************************************************************/
/sw/lib/include/neorv32_cpu.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_cpu.h
* @author Stephan Nolting
* @brief CPU Core Functions HW driver header file.
**************************************************************************/
 
43,17 → 42,17
#define neorv32_cpu_h
 
// prototypes
int neorv32_cpu_irq_enable(uint8_t irq_sel);
int neorv32_cpu_irq_disable(uint8_t irq_sel);
int neorv32_cpu_irq_enable(uint8_t irq_sel);
int neorv32_cpu_irq_disable(uint8_t irq_sel);
uint64_t neorv32_cpu_get_cycle(void);
void neorv32_cpu_set_mcycle(uint64_t value);
void neorv32_cpu_set_mcycle(uint64_t value);
uint64_t neorv32_cpu_get_instret(void);
void neorv32_cpu_set_minstret(uint64_t value);
void neorv32_cpu_set_minstret(uint64_t value);
uint64_t neorv32_cpu_get_systime(void);
void neorv32_cpu_delay_ms(uint32_t time_ms);
void neorv32_cpu_delay_ms(uint32_t time_ms);
uint32_t neorv32_cpu_pmp_get_num_regions(void);
uint32_t neorv32_cpu_pmp_get_granularity(void);
int neorv32_cpu_pmp_configure_region(uint32_t index, uint32_t base, uint8_t config);
int neorv32_cpu_pmp_configure_region(uint32_t index, uint32_t base, uint8_t config);
uint32_t neorv32_cpu_hpm_get_counters(void);
uint32_t neorv32_cpu_hpm_get_size(void);
 
/sw/lib/include/neorv32_cpu_cfu.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_cpu_cfu.h
* @author Stephan Nolting
* @brief CPU Core custom functions unit HW driver header file.
**************************************************************************/
 
47,7 → 46,7
 
 
/**********************************************************************//**
* @name CFU custom instructions (intrinsic)
* @name CFU custom instructions ("intrinsics")
**************************************************************************/
/**@{*/
/** CFU custom instruction 0 (funct3 = 000) */
/sw/lib/include/neorv32_gpio.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_gpio.h
* @author Stephan Nolting
* @brief General purpose input/output port unit (GPIO) HW driver header file.
*
* @note These functions should only be used if the GPIO unit was synthesized (IO_GPIO_EN = true).
/sw/lib/include/neorv32_gptmr.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_gptmr.h
* @author Stephan Nolting
* @brief General purpose timer (GPTMR) HW driver header file.
*
* @note These functions should only be used if the GPTMR unit was synthesized (IO_GPTMR_EN = true).
45,7 → 44,7
#define neorv32_gptmr_h
 
// prototypes
int neorv32_gptmr_available(void);
int neorv32_gptmr_available(void);
void neorv32_gptmr_setup(uint8_t prsc, uint8_t mode, uint32_t threshold);
void neorv32_gptmr_disable(void);
void neorv32_gptmr_enable(void);
/sw/lib/include/neorv32_intrinsics.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_intrinsics.h
* @author Stephan Nolting, SaxonSoc contributors, Google-CFU
* @brief Helper functions and macros for custom "intrinsics" / instructions.
**************************************************************************/
 
/sw/lib/include/neorv32_mtime.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_mtime.h
* @author Stephan Nolting
* @brief Machine System Timer (MTIME) HW driver header file.
*
* @note These functions should only be used if the MTIME unit was synthesized (IO_MTIME_EN = true).
45,10 → 44,10
#define neorv32_mtime_h
 
// prototypes
int neorv32_mtime_available(void);
void neorv32_mtime_set_time(uint64_t time);
int neorv32_mtime_available(void);
void neorv32_mtime_set_time(uint64_t time);
uint64_t neorv32_mtime_get_time(void);
void neorv32_mtime_set_timecmp(uint64_t timecmp);
void neorv32_mtime_set_timecmp(uint64_t timecmp);
uint64_t neorv32_mtime_get_timecmp(void);
 
#endif // neorv32_mtime_h
/sw/lib/include/neorv32_neoled.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_neoled.h
* @author Stephan Nolting
* @brief Smart LED Interface (NEOLED) HW driver header file.
*
* @note These functions should only be used if the NEOLED unit was synthesized (IO_NEOLED_EN = true).
45,15 → 44,15
#define neorv32_neoled_h
 
// prototypes
int neorv32_neoled_available(void);
void neorv32_neoled_setup(uint32_t prsc, uint32_t t_total, uint32_t t_high_zero, uint32_t t_high_one);
void neorv32_neoled_setup_ws2812(void);
void neorv32_neoled_set_mode(uint32_t mode);
void neorv32_neoled_strobe_blocking(void);
void neorv32_neoled_strobe_nonblocking(void);
void neorv32_neoled_enable(void);
void neorv32_neoled_disable(void);
void neorv32_neoled_write_blocking(uint32_t data);
int neorv32_neoled_available(void);
void neorv32_neoled_setup(uint32_t prsc, uint32_t t_total, uint32_t t_high_zero, uint32_t t_high_one);
void neorv32_neoled_setup_ws2812(void);
void neorv32_neoled_set_mode(uint32_t mode);
void neorv32_neoled_strobe_blocking(void);
void neorv32_neoled_strobe_nonblocking(void);
void neorv32_neoled_enable(void);
void neorv32_neoled_disable(void);
void neorv32_neoled_write_blocking(uint32_t data);
uint32_t neorv32_neoled_get_buffer_size(void);
 
 
/sw/lib/include/neorv32_pwm.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_pwm.h
* @author Stephan Nolting
* @brief Pulse-Width Modulation Controller (PWM) HW driver header file.
*
* @note These functions should only be used if the PWM unit was synthesized (IO_PWM_EN = true).
45,12 → 44,12
#define neorv32_pwm_h
 
// prototypes
int neorv32_pwm_available(void);
void neorv32_pwm_setup(uint8_t prsc);
void neorv32_pwm_disable(void);
void neorv32_pwm_enable(void);
int neorv32_pmw_get_num_channels(void);
void neorv32_pwm_set(uint8_t channel, uint8_t duty);
int neorv32_pwm_available(void);
void neorv32_pwm_setup(uint8_t prsc);
void neorv32_pwm_disable(void);
void neorv32_pwm_enable(void);
int neorv32_pmw_get_num_channels(void);
void neorv32_pwm_set(uint8_t channel, uint8_t duty);
uint8_t neorv32_pwm_get(uint8_t channel);
 
#endif // neorv32_pwm_h
/sw/lib/include/neorv32_rte.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_rte.h
* @author Stephan Nolting
* @brief NEORV32 Runtime Environment.
**************************************************************************/
 
96,6 → 95,6
void neorv32_rte_print_license(void);
 
uint32_t neorv32_rte_get_compiler_isa(void);
int neorv32_rte_check_isa(int silent);
int neorv32_rte_check_isa(int silent);
 
#endif // neorv32_rte_h
/sw/lib/include/neorv32_slink.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_slink.h
* @author Stephan Nolting
* @brief Stream Link Interface HW driver header file.
**************************************************************************/
 
43,35 → 42,35
#define neorv32_slink_h
 
// prototypes
int neorv32_slink_available(void);
int neorv32_slink_available(void);
void neorv32_slink_enable(void);
void neorv32_slink_disable(void);
void neorv32_slink_rx_irq_config(int link_id, int irq_en, int irq_type);
void neorv32_slink_tx_irq_config(int link_id, int irq_en, int irq_type);
int neorv32_slink_get_rx_num(void);
int neorv32_slink_get_tx_num(void);
int neorv32_slink_get_rx_depth(void);
int neorv32_slink_get_tx_depth(void);
int neorv32_slink_check_rx_half_full(int link_id);
int neorv32_slink_check_tx_half_full(int link_id);
int neorv32_slink_get_rx_num(void);
int neorv32_slink_get_tx_num(void);
int neorv32_slink_get_rx_depth(void);
int neorv32_slink_get_tx_depth(void);
int neorv32_slink_check_rx_half_full(int link_id);
int neorv32_slink_check_tx_half_full(int link_id);
// non-blocking transmit
int neorv32_slink_tx0_nonblocking(uint32_t tx_data);
int neorv32_slink_tx1_nonblocking(uint32_t tx_data);
int neorv32_slink_tx2_nonblocking(uint32_t tx_data);
int neorv32_slink_tx3_nonblocking(uint32_t tx_data);
int neorv32_slink_tx4_nonblocking(uint32_t tx_data);
int neorv32_slink_tx5_nonblocking(uint32_t tx_data);
int neorv32_slink_tx6_nonblocking(uint32_t tx_data);
int neorv32_slink_tx7_nonblocking(uint32_t tx_data);
int neorv32_slink_tx0_nonblocking(uint32_t tx_data);
int neorv32_slink_tx1_nonblocking(uint32_t tx_data);
int neorv32_slink_tx2_nonblocking(uint32_t tx_data);
int neorv32_slink_tx3_nonblocking(uint32_t tx_data);
int neorv32_slink_tx4_nonblocking(uint32_t tx_data);
int neorv32_slink_tx5_nonblocking(uint32_t tx_data);
int neorv32_slink_tx6_nonblocking(uint32_t tx_data);
int neorv32_slink_tx7_nonblocking(uint32_t tx_data);
// non-blocking receive
int neorv32_slink_rx0_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx1_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx2_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx3_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx4_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx5_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx6_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx7_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx0_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx1_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx2_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx3_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx4_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx5_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx6_nonblocking(uint32_t *rx_data);
int neorv32_slink_rx7_nonblocking(uint32_t *rx_data);
 
 
/**********************************************************************//**
/sw/lib/include/neorv32_spi.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_spi.h
* @author Stephan Nolting
* @brief Serial peripheral interface controller (SPI) HW driver header file.
*
* @note These functions should only be used if the SPI unit was synthesized (IO_SPI_EN = true).
45,17 → 44,17
#define neorv32_spi_h
 
// prototypes
int neorv32_spi_available(void);
void neorv32_spi_setup(uint8_t prsc, uint8_t clk_phase, uint8_t clk_polarity, uint8_t data_size);
void neorv32_spi_disable(void);
void neorv32_spi_enable(void);
void neorv32_spi_highspeed_enable(void);
void neorv32_spi_highspeed_disable(void);
void neorv32_spi_cs_en(uint8_t cs);
void neorv32_spi_cs_dis(uint8_t cs);
int neorv32_spi_available(void);
void neorv32_spi_setup(uint8_t prsc, uint8_t clk_phase, uint8_t clk_polarity, uint8_t data_size);
void neorv32_spi_disable(void);
void neorv32_spi_enable(void);
void neorv32_spi_highspeed_enable(void);
void neorv32_spi_highspeed_disable(void);
void neorv32_spi_cs_en(uint8_t cs);
void neorv32_spi_cs_dis(uint8_t cs);
uint32_t neorv32_spi_trans(uint32_t tx_data);
void neorv32_spi_put_nonblocking(uint32_t tx_data);
void neorv32_spi_put_nonblocking(uint32_t tx_data);
uint32_t neorv32_spi_get_nonblocking(void);
int neorv32_spi_busy(void);
int neorv32_spi_busy(void);
 
#endif // neorv32_spi_h
/sw/lib/include/neorv32_trng.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_trng.h
* @author Stephan Nolting
* @brief True Random Number Generator (TRNG) HW driver header file.
*
* @note These functions should only be used if the TRNG unit was synthesized (IO_TRNG_EN = true).
45,9 → 44,9
#define neorv32_trng_h
 
// prototypes
int neorv32_trng_available(void);
int neorv32_trng_available(void);
void neorv32_trng_enable(void);
void neorv32_trng_disable(void);
int neorv32_trng_get(uint8_t *data);
int neorv32_trng_get(uint8_t *data);
 
#endif // neorv32_trng_h
/sw/lib/include/neorv32_twi.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_twi.h
* @author Stephan Nolting
* @brief Two-Wire Interface Controller (TWI) HW driver header file.
*
* @note These functions should only be used if the TWI unit was synthesized (IO_TWI_EN = true).
45,17 → 44,17
#define neorv32_twi_h
 
// prototypes
int neorv32_twi_available(void);
void neorv32_twi_setup(uint8_t prsc);
void neorv32_twi_disable(void);
void neorv32_twi_enable(void);
void neorv32_twi_mack_enable(void);
void neorv32_twi_mack_disable(void);
int neorv32_twi_busy(void);
int neorv32_twi_start_trans(uint8_t a);
int neorv32_twi_trans(uint8_t d);
int neorv32_twi_available(void);
void neorv32_twi_setup(uint8_t prsc);
void neorv32_twi_disable(void);
void neorv32_twi_enable(void);
void neorv32_twi_mack_enable(void);
void neorv32_twi_mack_disable(void);
int neorv32_twi_busy(void);
int neorv32_twi_start_trans(uint8_t a);
int neorv32_twi_trans(uint8_t d);
uint8_t neorv32_twi_get_data(void);
void neorv32_twi_generate_stop(void);
void neorv32_twi_generate_start(void);
void neorv32_twi_generate_stop(void);
void neorv32_twi_generate_start(void);
 
#endif // neorv32_twi_h
/sw/lib/include/neorv32_uart.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_uart.h
* @author Stephan Nolting
* @brief Universal asynchronous receiver/transmitter (UART0/UART1) HW driver header file
*
* @warning UART0 (primary UART) is used as default user console interface for all NEORV32 software framework/library functions.
/sw/lib/include/neorv32_wdt.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_wdt.h
* @author Stephan Nolting
* @brief Watchdog Timer (WDT) HW driver header file.
*
* @note These functions should only be used if the WDT unit was synthesized (IO_WDT_EN = true).
45,11 → 44,11
#define neorv32_wdt_h
 
// prototypes
int neorv32_wdt_available(void);
int neorv32_wdt_available(void);
void neorv32_wdt_setup(uint8_t prsc, uint8_t mode, uint8_t lock);
int neorv32_wdt_disable(void);
int neorv32_wdt_disable(void);
void neorv32_wdt_reset(void);
int neorv32_wdt_get_cause(void);
int neorv32_wdt_get_cause(void);
void neorv32_wdt_force(void);
 
#endif // neorv32_wdt_h
/sw/lib/include/neorv32_xip.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_xip.h
* @author Stephan Nolting
* @brief Execute in place module (XIP) HW driver header file.
*
* @note These functions should only be used if the XIP module was synthesized (IO_XIP_EN = true).
45,11 → 44,11
#define neorv32_xip_h
 
// prototypes
int neorv32_xip_available(void);
int neorv32_xip_init(uint8_t prsc, uint8_t cpol, uint8_t cpha, uint8_t rd_cmd);
int neorv32_xip_start(uint8_t abytes, uint32_t page_base);
int neorv32_xip_available(void);
int neorv32_xip_init(uint8_t prsc, uint8_t cpol, uint8_t cpha, uint8_t rd_cmd);
int neorv32_xip_start(uint8_t abytes, uint32_t page_base);
void neorv32_xip_highspeed_enable(void);
void neorv32_xip_highspeed_disable(void);
int neorv32_xip_spi_trans(uint8_t nbytes, uint64_t *rtx_data);
int neorv32_xip_spi_trans(uint8_t nbytes, uint64_t *rtx_data);
 
#endif // neorv32_xip_h
/sw/lib/include/neorv32_xirq.h
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_xirq.h
* @author Stephan Nolting
* @brief External Interrupt controller HW driver header file.
**************************************************************************/
 
43,17 → 42,16
#define neorv32_xirq_h
 
// prototypes
int neorv32_xirq_available(void);
int neorv32_xirq_setup(void);
int neorv32_xirq_available(void);
int neorv32_xirq_setup(void);
void neorv32_xirq_global_enable(void);
void neorv32_xirq_global_disable(void);
int neorv32_xirq_get_num(void);
int neorv32_xirq_get_num(void);
void neorv32_xirq_clear_pending(uint8_t ch);
void neorv32_xirq_channel_enable(uint8_t ch);
void neorv32_xirq_channel_disable(uint8_t ch);
int neorv32_xirq_install(uint8_t ch, void (*handler)(void));
int neorv32_xirq_uninstall(uint8_t ch);
 
int neorv32_xirq_install(uint8_t ch, void (*handler)(void));
int neorv32_xirq_uninstall(uint8_t ch);
 
 
#endif // neorv32_xirq_h
/sw/lib/source/neorv32_cfs.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_cfs.c
* @author Stephan Nolting
* @brief Custom Functions Subsystem (CFS) HW driver source file.
*
* @warning There are no "real" CFS driver functions available here, because these functions are defined by the actual hardware.
/sw/lib/source/neorv32_cpu.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_cpu.c
* @author Stephan Nolting
* @brief CPU Core Functions HW driver source file.
**************************************************************************/
 
/sw/lib/source/neorv32_cpu_cfu.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_cpu_cfu.c
* @author Stephan Nolting
* @brief CPU Core custom functions unit HW driver source file.
**************************************************************************/
 
/sw/lib/source/neorv32_gpio.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_gpio.c
* @author Stephan Nolting
* @brief General purpose input/output port unit (GPIO) HW driver source file.
*
* @note These functions should only be used if the GPIO unit was synthesized (IO_GPIO_EN = true).
/sw/lib/source/neorv32_gptmr.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_gptmr.c
* @author Stephan Nolting
* @brief General purpose timer (GPTMR) HW driver source file.
*
* @note These functions should only be used if the GPTMR unit was synthesized (IO_GPTMR_EN = true).
/sw/lib/source/neorv32_mtime.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_mtime.c
* @author Stephan Nolting
* @brief Machine System Timer (MTIME) HW driver source file.
*
* @note These functions should only be used if the MTIME unit was synthesized (IO_MTIME_EN = true).
/sw/lib/source/neorv32_neoled.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_neoled.c
* @author Stephan Nolting
* @brief Smart LED Interface (NEOLED) HW driver source file.
*
* @note These functions should only be used if the NEOLED unit was synthesized (IO_NEOLED_EN = true).
/sw/lib/source/neorv32_pwm.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_pwm.c
* @author Stephan Nolting
* @brief Pulse-Width Modulation Controller (PWM) HW driver source file.
*
* @note These functions should only be used if the PWM unit was synthesized (IO_PWM_EN = true).
/sw/lib/source/neorv32_rte.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_rte.c
* @author Stephan Nolting
* @brief NEORV32 Runtime Environment.
**************************************************************************/
 
67,14 → 66,20
// configure trap handler base address
neorv32_cpu_csr_write(CSR_MTVEC, (uint32_t)(&__neorv32_rte_core));
 
// disable all IRQ channels
neorv32_cpu_csr_write(CSR_MIE, 0);
 
// clear all pending IRQs
neorv32_cpu_csr_write(CSR_MIP, 0);
 
// clear BUSKEEPER error flags
NEORV32_BUSKEEPER.CTRL = 0;
 
// install debug handler for all sources
uint8_t id;
for (id = 0; id < (sizeof(__neorv32_rte_vector_lut)/sizeof(__neorv32_rte_vector_lut[0])); id++) {
neorv32_rte_exception_uninstall(id); // this will configure the debug handler
}
 
// clear BUSKEEPER error flags
NEORV32_BUSKEEPER.CTRL = 0;
}
 
 
131,7 → 136,7
static void __attribute__((__interrupt__)) __attribute__((aligned(4))) __neorv32_rte_core(void) {
 
register uint32_t rte_mepc = neorv32_cpu_csr_read(CSR_MEPC);
neorv32_cpu_csr_write(CSR_MSCRATCH, rte_mepc); // store for later
neorv32_cpu_csr_write(CSR_MSCRATCH, rte_mepc); // backup for later
register uint32_t rte_mcause = neorv32_cpu_csr_read(CSR_MCAUSE);
 
// compute return address
140,12 → 145,12
// get low half word of faulting instruction
register uint32_t rte_trap_inst = neorv32_cpu_load_unsigned_half(rte_mepc);
 
if ((rte_trap_inst & 3) == 3) { // faulting instruction is uncompressed instruction
rte_mepc += 4;
rte_mepc += 4; // default: faulting instruction is uncompressed
if (neorv32_cpu_csr_read(CSR_MISA) & (1 << CSR_MISA_C)) { // C extension implemented?
if ((rte_trap_inst & 3) != 3) { // faulting instruction is compressed instruction
rte_mepc -= 2;
}
}
else { // faulting instruction is compressed instruction
rte_mepc += 2;
}
 
// store new return address
neorv32_cpu_csr_write(CSR_MEPC, rte_mepc);
746,7 → 751,6
// mask hardware features that are not used by software
uint32_t check = misa_hw & misa_sw;
 
//
if (check == misa_sw) {
return 0;
}
/sw/lib/source/neorv32_slink.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_slink.c
* @author Stephan Nolting
* @brief Stream Link Interface HW driver source file.
**************************************************************************/
 
/sw/lib/source/neorv32_spi.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_spi.c
* @author Stephan Nolting
* @brief Serial peripheral interface controller (SPI) HW driver source file.
*
* @note These functions should only be used if the SPI unit was synthesized (IO_SPI_EN = true).
/sw/lib/source/neorv32_trng.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_trng.c
* @author Stephan Nolting
* @brief True Random Number Generator (TRNG) HW driver source file.
*
* @note These functions should only be used if the TRNG unit was synthesized (IO_TRNG_EN = true).
/sw/lib/source/neorv32_twi.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_twi.c
* @author Stephan Nolting
* @brief Two-Wire Interface Controller (TWI) HW driver source file.
*
* @note These functions should only be used if the TWI unit was synthesized (IO_TWI_EN = true).
/sw/lib/source/neorv32_uart.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_uart.c
* @author Stephan Nolting
* @brief Universal asynchronous receiver/transmitter (UART0/UART1) HW driver source file.
*
* @warning UART0 (primary UART) is used as default user console interface for all NEORV32 software framework/library functions.
/sw/lib/source/neorv32_wdt.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_wdt.c
* @author Stephan Nolting
* @brief Watchdog Timer (WDT) HW driver source file.
*
* @note These functions should only be used if the WDT unit was synthesized (IO_WDT_EN = true).
/sw/lib/source/neorv32_xip.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_xip.c
* @author Stephan Nolting
* @brief Execute in place module (XIP) HW driver source file.
*
* @note These functions should only be used if the XIP module was synthesized (IO_XIP_EN = true).
/sw/lib/source/neorv32_xirq.c
35,7 → 35,6
 
/**********************************************************************//**
* @file neorv32_xirq.c
* @author Stephan Nolting
* @brief External Interrupt controller HW driver source file.
**************************************************************************/
 
/sw/lib/source/syscalls.c
19,7 → 19,6
 
/**********************************************************************//**
* @file syscalls.c
* @author Modified for the NEORV32 RISC-V Processor by Stephan Nolting
* @brief Newlib system calls
*
* @warning UART0 (if available) is used to read/write console data (STDIN, STDOUT, STDERR, ...).
/sw/README.md
4,24 → 4,24
This is a short description of the main folders.
 
 
## [bootloader](bootloader)
## [`bootloader`](bootloader)
 
Source(s) of the default NEORV32 bootloader.
A pre-built image is already installed into the rtl design via the `rtl/core/neorv32_bootloader_image.vhd` file.
 
 
## [common](common)
## [`common`](common)
 
NEORV32-specific common files for all bootloader and application programs:
linker script for executable generation and processor start-up code.
 
 
## [example](example)
## [`example`](example)
 
Several example programs for testing and for getting started.
 
 
## [image_gen](image_gen)
## [`image_gen`](image_gen)
 
This folder contains a simple program that is used to create NEORV32 executables (for upload via bootloader) and VHDL
memory initialization files (for memory-persistent applications and for the bootloader).
28,28 → 28,22
This program is automatically compiled using the native GCC when invoking one of the application compilation makefiles.
 
 
## [isa-test](isa-test)
## [`lib`](lib)
 
NEORV32 RISC-V Architecture Test Framework.
See [sim/README](../sim/README.md).
 
 
## [lib](lib)
 
Core libraries (sources and header files) and helper functions for using the processor peripherals and the CPU itself.
 
 
## [ocd-firmware](ocd-firmware)
## [`ocd-firmware`](ocd-firmware)
 
Firmware (debugger "park loop") for the on-chip debugger. This folder is just for documenting the source code.
Modifying the sources is not recommended as this could break the on-chip debugger.
 
 
## [openocd](openocd)
## [`openocd`](openocd)
 
Configuration file for openOCD to connect to the NEORV32 on-chip debugger via JTAG.
 
 
## [svd](svd)
## [`svd`](svd)
 
Contains a CMSIS-SVD compatible system view description file including _all_ peripherals.
/.gitignore
33,7 → 33,3
# compiled ghdl stuff
*.cf
*.o
 
# riscv-arch-test
 
/sim/work/
/CHANGELOG.md
33,6 → 33,18
 
| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
| 08.04.2022 | [**:rocket:1.7.0**](https://github.com/stnolting/neorv32/releases/tag/v1.7.0) | **New release** |
| 08.04.2022 | 1.6.9.11 | :bug: fixed bug in interrupt setup of **`crt0` start-up code** [#297](https://github.com/stnolting/neorv32/pull/297) |
| 08.04.2022 | 1.6.9.10 | rework compressed instruction (`C` ISA extension) de-compressor: :lock: closed further illegal compressed instruction holes; code clean-ups; `mtval` CSR now shows the decompressed 32-bit instruction when executing an illegal compressed instruction; minor RTL code cleanups (removing legacy stuff); [PR #296](https://github.com/stnolting/neorv32/pull/296) |
| 07.04.2022 | 1.6.9.9 | AND-gate CSR read address: reduces **CPU switching activity** (= dynamic power consumption) and even reduces area costs; [PR #295](https://github.com/stnolting/neorv32/pull/295) |
| 06.04.2022 | 1.6.9.8 | :bug: fixed instruction decoding collision in CPU `B` extension; :lock: closed further illegal instruction encoding holes; optimized illegal instruction detection logic; [PR #294](https://github.com/stnolting/neorv32/pull/294) |
| 04.04.2022 | 1.6.9.7 | **major CPU logic optimization**: reduced area costs and shortened critical path (higher f_max!); :bug: fixed rare bug in RTE core (if C-extension is not implemented); :lock: closed further illegal instruction encoding holes; [PR #293](https://github.com/stnolting/neorv32/pull/293) |
| 01.04.2022 | 1.6.9.6 | rework **CPU front-end**: instruction issue engine; much cleaner code, slightly less HW required; [PR #292](https://github.com/stnolting/neorv32/pull/292) |
| 29.03.2022 | 1.6.9.5 | minor clock generator edits: reset **clock generator** explicitly if not being used by _any_ peripheral/IO device |
| 19.03.2022 | 1.6.9.4 | :test_tube: change usage of VHDL `*_reduce_f` functions for signals that might effect gate-level simulations; [PR #290](https://github.com/stnolting/neorv32/pull/290) |
| 19.03.2022 | 1.6.9.3 | :bug: fixed minor bug in **FPU** - incorrect/missing reset (even if reset to `'-'`) of some registers |
| 18.03.2022 | 1.6.9.2 | fixed minor bug in **TRNG** interface hand shake (that marked the _same_ RND value as "valid" for several times); minor optimization of **processor's reset generator** |
| 14.03.2022 | 1.6.9.1 | `mtval` CSR is set to zero for software breakpoints (`[c.]ebreak` instruction(s)) - this is permitted by the RISC-V machine ISA spec. v1.12; [PR #289](https://github.com/stnolting/neorv32/pull/289) |
| 09.03.2022 | [**:rocket:1.6.9**](https://github.com/stnolting/neorv32/releases/tag/v1.6.9) | **New release** |
| 09.03.2022 | 1.6.8.12 | CPU core: minor code clean-up |
| 08.03.2022 | 1.6.8.11 | clean-up of CPU's privilege mode logic |
/CODE_OF_CONDUCT.md
55,7 → 55,7
## Enforcement
 
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at [stnolting@gmail.com](mailto:stnolting@gmail.com). All
reported by contacting the project team via [https://github.com/issues](https://github.com/issues). All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
/README.md
1,4 → 1,4
[![NEORV32](https://raw.githubusercontent.com/stnolting/neorv32/main/docs/figures/neorv32_logo_dark.png)](https://github.com/stnolting/neorv32)
[![NEORV32](https://raw.githubusercontent.com/stnolting/neorv32/main/docs/figures/neorv32_logo_front.png)](https://github.com/stnolting/neorv32)
 
# The NEORV32 RISC-V Processor
 
12,14 → 12,11
1. [Overview](#1-Overview)
* [Key Features](#Project-Key-Features)
* [Status](#status)
2. [Processor/SoC Features](#2-NEORV32-Processor-Features)
* [FPGA Implementation Results](#FPGA-Implementation-Results---Processor)
3. [CPU Features](#3-NEORV32-CPU-Features)
* [Available ISA Extensions](#Available-ISA-Extensions)
* [FPGA Implementation Results](#FPGA-Implementation-Results---CPU)
* [Performance](#Performance)
4. [Software Framework & Tooling](#4-Software-Framework-and-Tooling)
5. [**Getting Started**](#5-Getting-Started) :rocket:
2. [Features](#2-Features)
3. [FPGA Implementation Results](#3-FPGA-Implementation-Results)
4. [Performance](#4-Performance)
5. [Software Framework & Tooling](#5-Software-Framework-and-Tooling)
6. [**Getting Started**](#6-Getting-Started) :rocket:
 
 
 
63,6 → 60,7
 
- [x] all-in-one package: **CPU** plus **SoC** plus **Software Framework & Tooling**
- [x] completely described in behavioral, platform-independent VHDL - no primitives, macros, etc.
- [x] highly [extensible hardware](https://stnolting.github.io/neorv32/ug/#_comparative_summary) - on CPU, SoC and system level
- [x] be as small as possible while being as RISC-V-compliant as possible
- [x] from zero to `printf("hello world!");` - completely open source and documented
- [x] easy to use even for FPGA/RISC-V starters – intended to work *out of the box*
74,17 → 72,55
[![GitHub Pages](https://img.shields.io/website.svg?label=stnolting.github.io%2Fneorv32&longCache=true&style=flat-square&url=http%3A%2F%2Fstnolting.github.io%2Fneorv32%2Findex.html&logo=GitHub)](https://stnolting.github.io/neorv32)
\
[![Documentation](https://img.shields.io/github/workflow/status/stnolting/neorv32/Documentation/main?longCache=true&style=flat-square&label=Documentation&logo=Github%20Actions&logoColor=fff)](https://github.com/stnolting/neorv32/actions?query=workflow%3ADocumentation)
[![riscv-arch-test](https://img.shields.io/github/workflow/status/stnolting/neorv32/riscv-arch-test/main?longCache=true&style=flat-square&label=riscv-arch-test&logo=Github%20Actions&logoColor=fff)](https://github.com/stnolting/neorv32/actions?query=workflow%3Ariscv-arch-test)
[![riscv-arch-test](https://img.shields.io/github/workflow/status/stnolting/neorv32-verif/riscv-arch-test/main?longCache=true&style=flat-square&label=riscv-arch-test&logo=Github%20Actions&logoColor=fff)](https://github.com/stnolting/neorv32-verif/actions?query=workflow%3Ariscv-arch-test)
[![Processor](https://img.shields.io/github/workflow/status/stnolting/neorv32/Processor/main?longCache=true&style=flat-square&label=Processor&logo=Github%20Actions&logoColor=fff)](https://github.com/stnolting/neorv32/actions?query=workflow%3AProcessor)
 
The NEORV32 is fully operational.
The processor passes the official RISC-V architecture tests, which are checked by the
[neorv32-verif](https://github.com/stnolting/neorv32-verif) repository. It can successfully run _any_ C program
(for example from the [`sw/example`](https://github.com/stnolting/neorv32/tree/main/sw/example) folder) including CoreMark
and can be synthesized for _any_ target technology - tested on Intel, Xilinx and Lattice FPGAs.
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
## 2. NEORV32 Processor Features
 
The NEORV32 Processor provides a full-featured microcontroller-like SoC build around the NEORV32 CPU. It is highly configurable
via generics to allow a flexible customization according to your needs. Note that all modules listed below are _optional_.
## 2. Features
 
The NEORV32 Processor provides a full-featured microcontroller-like SoC build around the NEORV32 CPU.
By using generics the design is highly configurable and allows a flexible customization to tailor the
setup according to your needs. The following list shows all available SoC module. Note that all those
modules are _optional_.
 
**CPU**
 
* 32-bit little-endian RISC-V single-core, pipelined/multi-cycle Von-Neumann architecture
* configurable ISA extensions
* `RV32`
[[`I`](https://stnolting.github.io/neorv32/#_i_base_integer_isa)/
[`E`](https://stnolting.github.io/neorv32/#_e_embedded_cpu)]
[[`A`](https://stnolting.github.io/neorv32/#_a_atomic_memory_access)]
[[`B`](https://stnolting.github.io/neorv32/#_b_bit_manipulation_operations)]
[[`C`](https://stnolting.github.io/neorv32/#_c_compressed_instructions)]
[[`M`](https://stnolting.github.io/neorv32/#_m_integer_multiplication_and_division)]
[[`U`](https://stnolting.github.io/neorv32/#_u_less_privileged_user_mode)]
[[`X`](https://stnolting.github.io/neorv32/#_x_neorv32_specific_custom_extensions)]
[[`Zfinx`](https://stnolting.github.io/neorv32/#_zfinx_single_precision_floating_point_operations)]
[[`Zicsr`](https://stnolting.github.io/neorv32/#_zicsr_control_and_status_register_access_privileged_architecture)]
[[`Zicntr`](https://stnolting.github.io/neorv32/#_zicntr_cpu_base_counters)]
[[`Zihpm`](https://stnolting.github.io/neorv32/#_zihpm_hardware_performance_monitors)]
[[`Zifencei`](https://stnolting.github.io/neorv32/#_zifencei_instruction_stream_synchronization)]
[[`Zmmul`](https://stnolting.github.io/neorv32/#_zmmul_integer_multiplication)]
[[`Zxcfu`](https://stnolting.github.io/neorv32/#_zxcfu_custom_instructions_extension_cfu)]
[[`PMP`](https://stnolting.github.io/neorv32/#_pmp_physical_memory_protection)]
[[`DEBUG`](https://stnolting.github.io/neorv32/#_cpu_debug_mode)]
* compatible to subsets of the
*Unprivileged ISA Specification* [(Version 2.2)](https://github.com/stnolting/neorv32/blob/main/docs/references/riscv-spec.pdf)
and the *Privileged Architecture Specification* [(Version 1.12)](https://github.com/stnolting/neorv32/blob/main/docs/references/riscv-privileged.pdf).
* `machine` and `user` modes
* implements _all_ standard RISC-V exceptions/interrupts (including MTI, MEI & MSI)
* 16-fast interrupt requests as NEORV32-specific extensions
 
**Memory**
 
* processor-internal data and instruction memories ([DMEM](https://stnolting.github.io/neorv32/#_data_memory_dmem) /
99,7 → 135,7
* general purpose 32-bit timer ([GPTMR](https://stnolting.github.io/neorv32/#_general_purpose_timer_gptmr))
* watchdog timer ([WDT](https://stnolting.github.io/neorv32/#_watchdog_timer_wdt))
 
**Input/Output**
**Input / Output**
 
* standard serial interfaces
([UART](https://stnolting.github.io/neorv32/#_primary_universal_asynchronous_receiver_and_transmitter_uart0),
113,18 → 149,14
 
* 32-bit external bus interface, Wishbone b4 compatible
([WISHBONE](https://stnolting.github.io/neorv32/#_processor_external_memory_interface_wishbone_axi4_lite))
* [wrapper](https://github.com/stnolting/neorv32/blob/main/rtl/system_integration/neorv32_SystemTop_axi4lite.vhd) for AXI4-Lite host interface
* [wrapper](https://github.com/stnolting/neorv32/blob/main/rtl/system_integration/neorv32_SystemTop_AvalonMM.vhd) for Avalon-MM host interface
* [wrappers](https://github.com/stnolting/neorv32/blob/main/rtl/system_integration) for AXI4-Lite and Avalon-MM host interfaces
* 32-bit stream link interface with up to 8 independent RX and TX links
([SLINK](https://stnolting.github.io/neorv32/#_stream_link_interface_slink))
* AXI4-Stream compatible
* external interrupt controller with up to 32 channels
([SLINK](https://stnolting.github.io/neorv32/#_stream_link_interface_slink)) - AXI4-Stream compatible
* external interrupts controller with up to 32 channels
([XIRQ](https://stnolting.github.io/neorv32/#_external_interrupt_controller_xirq))
 
**Advanced**
 
* on-chip debugger ([OCD](https://stnolting.github.io/neorv32/#_on_chip_debugger_ocd)) accessible via JTAG interface - compliant to
the "Minimal RISC-V Debug Specification Version 0.13.2" and compatible with **OpenOCD** + **gdb** and **Segger Embedded Studio**
* _true random_ number generator ([TRNG](https://stnolting.github.io/neorv32/#_true_random_number_generator_trng))
* execute in place module ([XIP](https://stnolting.github.io/neorv32/#_execute_in_place_module_xip)) to directly execute code from SPI flash
* custom functions subsystem ([CFS](https://stnolting.github.io/neorv32/#_custom_functions_subsystem_cfs))
132,12 → 164,35
* custom functions unit ([CFU](https://stnolting.github.io/neorv32/#_custom_functions_unit_cfu)) for up to 1024
_custom RISC-V instructions_
 
**Debugging**
 
* on-chip debugger ([OCD](https://stnolting.github.io/neorv32/#_on_chip_debugger_ocd)) accessible via standard JTAG interface
* compliant to the "Minimal RISC-V Debug Specification Version 0.13.2"
* compatible with **OpenOCD** + **gdb** and **Segger Embedded Studio**
 
 
:warning: The `B`, `Zfinx` and `Zmmul` RISC-V ISA extensions are frozen and officially ratified but there is no
upstream gcc support yet (will be available with GCC12). To circumvent this, the NEORV32 software framework provides
_intrinsic libraries_ for the `B` and `Zfinx` extensions.
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
### FPGA Implementation Results - Processor
## 3. FPGA Implementation Results
 
The hardware resources used by a specific processor setup is defined by the implemented CPU extensions,
Implementation results for exemplary **CPU-only** configuration generated for an Intel Cyclone IV E `EP4CE22F17C6` FPGA
using Intel Quartus Prime Lite 21.1 (no timing constrains, _balanced optimization_, f_max from _Slow 1200mV 0C Model_).
 
| CPU Configuration (version [1.6.9.8](https://github.com/stnolting/neorv32/blob/main/CHANGELOG.md)) | LEs | FFs | Memory bits | DSPs | f_max |
|:------------------------|:----:|:----:|:----:|:-:|:-------:|
| `rv32i_Zicsr` | 1328 | 678 | 1024 | 0 | 128 MHz |
| `rv32i_Zicsr_Zicntr` | 1614 | 808 | 1024 | 0 | 128 MHz |
| `rv32imac_Zicsr_Zicntr` | 2338 | 992 | 1024 | 0 | 128 MHz |
 
:bulb: An incremental list of the CPUs ISA extension's hardware utilization can found in the
[_Data Sheet: FPGA Implementation Results - CPU_](https://stnolting.github.io/neorv32/#_cpu).
 
The hardware resources used by a specific **full-processor** setup is defined by the implemented CPU extensions,
the configuration of the peripheral modules and some "glue logic".
Section [_FPGA Implementation Results - Processor Modules_](https://stnolting.github.io/neorv32/#_processor_modules)
of the online datasheet shows the resource utilization of each optional processor module to allow an
147,78 → 202,15
setups targeting various FPGA boards and toolchains. The latest bitstreams and utilization reports for those setups
can be found in the assets of the [Implementation Workflow](https://github.com/stnolting/neorv32-setups/actions/workflows/Implementation.yml).
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
:bulb: The CPU & SoC provide further "tuning" options to optimize the design for maximum performance, maximum clock speed, minimal area
or minimal power consumption:
[UG: Application-Specific Processor Configuration](https://stnolting.github.io/neorv32/ug/#_application_specific_processor_configuration)
 
 
 
## 3. NEORV32 CPU Features
 
The NEORV32 CPU implements the RISC-V 32-bit `rv32i` ISA with optional extensions (see below). It is compatible to subsets of the
*Unprivileged ISA Specification* [(Version 2.2)](https://github.com/stnolting/neorv32/blob/main/docs/references/riscv-spec.pdf)
and the *Privileged Architecture Specification* [(Version 1.12)](https://github.com/stnolting/neorv32/blob/main/docs/references/riscv-privileged.pdf).
Compatibility is checked by passing the [official RISC-V architecture tests](https://github.com/riscv/riscv-arch-test).
 
The core is a little-endian Von-Neumann machine implemented as multi-cycle architecture.
However, the CPU's_front end (instruction fetch) and back end (instruction execution) can work independently to increase performance.
Currently, two privilege levels "machine-mode" and optional "user-mode" are supported. The CPU implements all three standard RISC-V machine
interrupts (MTI, MEI, MSI) plus 16 _fast interrupt requests_ as custom extensions.
It also supports **all** standard RISC-V exceptions (instruction/load/store misaligned address & bus access fault, illegal
instruction, breakpoint, environment calls).
 
:books: In-depth detailed information regarding the CPU can be found in the
[_Data Sheet: NEORV32 Central Processing Unit_](https://stnolting.github.io/neorv32/#_neorv32_central_processing_unit_cpu).
 
 
### Available ISA Extensions
 
The following _optional_ RISC-V-compatible and NEORV32-specific ISA extensions are available (linked to the according
documentation section):
 
**RV32
[[`I`](https://stnolting.github.io/neorv32/#_i_base_integer_isa)/
[`E`](https://stnolting.github.io/neorv32/#_e_embedded_cpu)]
[[`A`](https://stnolting.github.io/neorv32/#_a_atomic_memory_access)]
[[`B`](https://stnolting.github.io/neorv32/#_b_bit_manipulation_operations)]
[[`C`](https://stnolting.github.io/neorv32/#_c_compressed_instructions)]
[[`M`](https://stnolting.github.io/neorv32/#_m_integer_multiplication_and_division)]
[[`U`](https://stnolting.github.io/neorv32/#_u_less_privileged_user_mode)]
[[`X`](https://stnolting.github.io/neorv32/#_x_neorv32_specific_custom_extensions)]
[[`Zfinx`](https://stnolting.github.io/neorv32/#_zfinx_single_precision_floating_point_operations)]
[[`Zicsr`](https://stnolting.github.io/neorv32/#_zicsr_control_and_status_register_access_privileged_architecture)]
[[`Zicntr`](https://stnolting.github.io/neorv32/#_zicntr_cpu_base_counters)]
[[`Zihpm`](https://stnolting.github.io/neorv32/#_zihpm_hardware_performance_monitors)]
[[`Zifencei`](https://stnolting.github.io/neorv32/#_zifencei_instruction_stream_synchronization)]
[[`Zmmul`](https://stnolting.github.io/neorv32/#_zmmul_integer_multiplication)]
[[`Zxcfu`](https://stnolting.github.io/neorv32/#_zxcfu_custom_instructions_extension_cfu)]
[[`PMP`](https://stnolting.github.io/neorv32/#_pmp_physical_memory_protection)]
[[`DEBUG`](https://stnolting.github.io/neorv32/#_cpu_debug_mode)]**
 
:warning: The `B`, `Zfinx` and `Zmmul` RISC-V are frozen and officially ratified but there is no
upstream gcc support yet. To circumvent this, the NEORV32 software framework provides _intrinsic libraries_ for the
`B` and `Zfinx` extensions.
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
### FPGA Implementation Results - CPU
## 4. Performance
 
Implementation results for _exemplary_ CPU configuration generated for an **Intel Cyclone IV E** `EP4CE22F17C6` FPGA
using **Intel Quartus Prime Lite 21.1** (no timing constrains, _balanced optimization_, f_max from _Slow 1200mV 0C Model_).
 
| CPU Configuration (version [1.6.8.3](https://github.com/stnolting/neorv32/blob/main/CHANGELOG.md)) | LEs | FFs | Memory bits | DSPs | f_max |
|:------------------------|:----:|:----:|:----:|:-:|:-------:|
| `rv32i_Zicsr` | 1425 | 673 | 1024 | 0 | 118 MHz |
| `rv32i_Zicsr_Zicntr` | 1778 | 803 | 1024 | 0 | 118 MHz |
| `rv32imac_Zicsr_Zicntr` | 2453 | 994 | 1024 | 0 | 118 MHz |
 
:bulb: An incremental list of the CPUs ISA extension's hardware utilization can found in the
[_Data Sheet: FPGA Implementation Results - CPU_](https://stnolting.github.io/neorv32/#_cpu).
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
### Performance
 
The NEORV32 CPU is based on a two-stages pipeline architecture (fetch and execute).
The average CPI (cycles per instruction) depends on the instruction mix of a specific applications and also on the
available CPU extensions.
240,7 → 232,7
 
 
 
## 4. Software Framework and Tooling
## 5. Software Framework and Tooling
 
* [core libraries](https://github.com/stnolting/neorv32/tree/main/sw/lib) for high-level usage of the provided functions and peripherals
* application compilation based on GNU makefiles
264,7 → 256,7
 
 
 
## 5. Getting Started
## 6. Getting Started
 
This overview provides some *quick links* to the most important sections of the
[online Data Sheet](https://stnolting.github.io/neorv32) and the
316,7 → 308,6
 
* [Overview](https://stnolting.github.io/neorv32/#_legal) - license, disclaimer, limitation of liability for external links, proprietary notice, ...
* [Citing](https://stnolting.github.io/neorv32/#_citing) - citing information
* [Impressum](https://github.com/stnolting/neorv32/blob/main/docs/impressum.md) - imprint
 
This is an open-source project that is free of charge. Use this project in any way you like
(as long as it complies to the permissive [license](https://github.com/stnolting/neorv32/blob/main/LICENSE)).
/do.py
33,35 → 33,6
}
 
 
def task_RunRISCVArchitectureTests():
return {
"actions": [CmdAction(
"./run_riscv_arch_test.sh {suite}",
cwd=ROOT / "sim"
)],
"doc": "Run RISC-V Architecture Tests",
"params": [
{
"name": "suite",
"short": "s",
"long": "suite",
"default": "M",
"choices": ((item, "") for item in [
"I",
"C",
"M",
"privilege",
"Zifencei",
"rv32e_C",
"rv32e_E",
"rv32e_M"
]),
"help": "Test suite to be executed",
}
],
}
 
 
def task_Documentation():
return {
"actions": ["make -C docs {posargs}"],

powered by: WebSVN 2.1.0

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