URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
Subversion Repositories neorv32
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 73 to Rev 74
- ↔ Reverse comparison
Rev 73 → Rev 74
/neorv32/trunk/.gitmodules
File deleted
/neorv32/trunk/docs/impressum.md
File deleted
/neorv32/trunk/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** |
|======================= |
|
|
/neorv32/trunk/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`** |
|
/neorv32/trunk/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** |
/neorv32/trunk/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 |
/neorv32/trunk/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. |
/neorv32/trunk/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. |
/neorv32/trunk/docs/figures/neorv32_logo_front.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
neorv32/trunk/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: neorv32/trunk/docs/userguide/riscv_architecture_tests.adoc
===================================================================
--- neorv32/trunk/docs/userguide/riscv_architecture_tests.adoc (revision 73)
+++ neorv32/trunk/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: neorv32/trunk/docs/userguide/adding_custom_hw_modules.adoc
===================================================================
--- neorv32/trunk/docs/userguide/adding_custom_hw_modules.adoc (revision 73)
+++ neorv32/trunk/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).
/neorv32/trunk/docs/userguide/content.adoc
48,8 → 48,6
|
include::free_rtos_support.adoc[] |
|
include::riscv_architecture_tests.adoc[] |
|
include::debugging_with_ocd.adoc[] |
|
|
/neorv32/trunk/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 |
|
/neorv32/trunk/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: |
/neorv32/trunk/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`]. |
/neorv32/trunk/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; |
/neorv32/trunk/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; |
/neorv32/trunk/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; |
/neorv32/trunk/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 -------------------------------------- |
/neorv32/trunk/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; |
|
/neorv32/trunk/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 |
/neorv32/trunk/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); |
|
/neorv32/trunk/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); |
/neorv32/trunk/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; |
|
/neorv32/trunk/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 -- |
/neorv32/trunk/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 ---------------------------------------------------------------------- |
/neorv32/trunk/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) -- |
/neorv32/trunk/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; |
|
/neorv32/trunk/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) ------------------------------------------------------- |
/neorv32/trunk/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; |
|
|
/neorv32/trunk/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; |
/neorv32/trunk/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 ----------------------------------------------------- |
/neorv32/trunk/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) |
/neorv32/trunk/sim/run_riscv_arch_test.sh
File deleted
/neorv32/trunk/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). |
/neorv32/trunk/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 |
/neorv32/trunk/sw/isa-test/port-neorv32/README.md
File deleted
/neorv32/trunk/sw/isa-test/port-neorv32/model_test.h
File deleted
/neorv32/trunk/sw/isa-test/common.mk
File deleted
/neorv32/trunk/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); |
} |
} |
/neorv32/trunk/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 |
|
|
// ************************************************************************************************ |
/neorv32/trunk/sw/example/newlib_demo/main.c
File deleted
/neorv32/trunk/sw/example/newlib_demo/makefile
File deleted
/neorv32/trunk/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); |
} |
/neorv32/trunk/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 |
/neorv32/trunk/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 |
/neorv32/trunk/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); |
} |
|
/neorv32/trunk/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); |
/neorv32/trunk/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 |
/neorv32/trunk/sw/image_gen/uart_upload.sh
1,4 → 1,4
#!/bin/sh |
#!/usr/bin/env bash |
|
set -e |
|
/neorv32/trunk/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 { |
/neorv32/trunk/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). |
**************************************************************************/ |
/neorv32/trunk/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); |
|
/neorv32/trunk/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) */ |
/neorv32/trunk/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). |
/neorv32/trunk/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); |
/neorv32/trunk/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. |
**************************************************************************/ |
|
/neorv32/trunk/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 |
/neorv32/trunk/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); |
|
|
/neorv32/trunk/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 |
/neorv32/trunk/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 |
/neorv32/trunk/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); |
|
|
/**********************************************************************//** |
/neorv32/trunk/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 |
/neorv32/trunk/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 |
/neorv32/trunk/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 |
/neorv32/trunk/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. |
/neorv32/trunk/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 |
/neorv32/trunk/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 |
/neorv32/trunk/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 |
/neorv32/trunk/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. |
/neorv32/trunk/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. |
**************************************************************************/ |
|
/neorv32/trunk/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. |
**************************************************************************/ |
|
/neorv32/trunk/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). |
/neorv32/trunk/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). |
/neorv32/trunk/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). |
/neorv32/trunk/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). |
/neorv32/trunk/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). |
/neorv32/trunk/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; |
} |
/neorv32/trunk/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. |
**************************************************************************/ |
|
/neorv32/trunk/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). |
/neorv32/trunk/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). |
/neorv32/trunk/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). |
/neorv32/trunk/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. |
/neorv32/trunk/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). |
/neorv32/trunk/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). |
/neorv32/trunk/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. |
**************************************************************************/ |
|
/neorv32/trunk/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, ...). |
/neorv32/trunk/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. |
/neorv32/trunk/.gitignore
33,7 → 33,3
# compiled ghdl stuff |
*.cf |
*.o |
|
# riscv-arch-test |
|
/sim/work/ |
/neorv32/trunk/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 | |
/neorv32/trunk/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. |
/neorv32/trunk/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)). |
/neorv32/trunk/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}"], |