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

Subversion Repositories neorv32

Compare Revisions

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

Rev 65 → Rev 66

/docs/datasheet/cpu.adoc
5,30 → 5,31
 
**Key Features**
 
* 32-bit pipelined/multi-cycle in-order `rv32` RISC-V CPU
* 32-bit multi-cycle in-order `rv32` RISC-V CPU
* Optional RISC-V extensions:
** `A` - atomic memory access operations
** `B` - bit-manipulation instructions
** `C` - 16-bit compressed instructions
** `I` - integer base ISA (always enabled)
** `E` - embedded CPU version (reduced register file size)
** `M` - integer multiplication and division hardware
** `U` - less-privileged _user_ mode
** `Zbb` - basic bit-manipulation operations
** `Zfinx` - single-precision floating-point unit
** `Zicsr` - control and status register access (privileged architecture)
** `Zicntr` - CPU base counters
** `Zihpm` - hardware performance monitors
** `Zifencei` - instruction stream synchronization
** `Zmmul` - integer multiplication hardware
** `PMP` - physical memory protection
** `HPM` - hardware performance monitors
** `DB` - debug mode
** `Debug` - debug mode
* Compatible to the RISC-V user specifications and a subset of the RISC-V privileged architecture specifications - passes the official RISC-V Architecture Tests (v2+)
* Official RISC-V open-source architecture ID
* Standard RISC-V interrupts (_external_, _timer_, _software_) plus 16 _fast_ interrupts
* Supports most of the traps from the RISC-V specifications (including bus access exceptions) and traps on all unimplemented/illegal/malformed instructions
* Supports _all_ of the machine-level traps from the RISC-V specifications (including bus access exceptions and all unimplemented/illegal/malformed instructions)
** This is a special aspect on _execution safety_ by <<_full_virtualization>>
* Optional physical memory configuration (PMP), compatible to the RISC-V specifications
* Optional hardware performance monitors (HPM) for application benchmarking
* Separated interfaces for instruction fetch and data access (merged into single bus via a bus switch for
the NEORV32 processor)
* Separated interfaces for instruction fetch and data access (merged into a single processor bus))
* little-endian byte order
* Configurable hardware reset
* No hardware support of unaligned data/instruction accesses - they will trigger an exception.
53,34 → 54,66
 
image::neorv32_cpu.png[align=center]
 
The CPU uses a pipelined architecture with basically two main stages. The first stage (IF - instruction fetch)
is responsible for fetching new instruction data from memory via the fetch engine. The instruction data is
stored to a FIFO - the instruction prefetch buffer. The issue engine takes this data and assembles 32-bit
instruction words for the next pipeline stage. Compressed instructions - if enabled - are also decompressed
in this stage. The second stage (EX - execution) is responsible for actually executing the fetched instructions
via the execute engine.
The CPU implements a _multi-cycle_ architecture. Hence, each instruction is executed as a series of consecutive
micro-operations. In order to increase performance, the CPU's **front-end** (instruction fetch) and **back-end**
(instruction execution) are de-couples via a FIFO (the "instruction prefetch buffer"). Therefore, the
front-end can already fetch new instructions while the back-end is still processing previously-fetched instructions.
 
These two pipeline stages are based on a multi-cycle processing engine. So the processing of each stage for a
certain operations can take several cycles. Since the IF and EX stages are decoupled via the instruction
prefetch buffer, both stages can operate in parallel and with overlapping operations. Hence, the optimal CPI
(cycles per instructions) is 2, but it can be significantly higher: For instance when executing loads/stores
multi-cycle operations like divisions or when the instruction fetch engine has to reload the prefetch buffers
due to a taken branch.
The front-end is responsible for fetching 32-bit chunks of instruction words (one aligned 32-bit instruction,
two 16-bit instructions or a mixture if 32-bit instructions are not aligned to 32-bit boundaries). The instruction
data is stored to a FIFO queue - the instruction prefetch buffer.
 
The back-end is responsible for the actual execution of the instruction. It includes an "issue engine",
which takes data from the instruction prefetch buffer and assembles 32-bit instruction words (plain 32-bit
instruction or decompressed 16-bit instructions) for execution.
 
Front-end and back-end operate in parallel and with overlapping operations. Hence, the optimal CPI
(cycles per instructions) is 2, but it can be significantly higher: for instance when executing loads/stores
(accessing memory-mapped devices with high latency), executing multi-cycle ALU operations (like divisions) or
when the CPU front-end has to reload the prefetch buffer due to a taken branch.
 
Basically, the NEORV32 CPU is somewhere between a classical pipelined architecture, where each stage
requires exactly one processing cycle (if not stalled) and a classical multi-cycle architecture, which executes
every single instruction in a series of consecutive micro-operations. The combination of these two classical
design paradigms allows an increased instruction execution in contrast to a pure multi-cycle approach (due to
the pipelined approach) at a reduced hardware footprint (due to the multi-cycle approach).
every single instruction (_including_ fetch) in a series of consecutive micro-operations. The combination of
these two classical design paradigms allows an increased instruction execution in contrast to a pure multi-cycle
approach (due to overlapping operation of fetch and execute) at a reduced hardware footprint (due to the
multi-cycle concept).
 
The CPU provides independent interfaces for instruction fetch and data access. These two bus interfaces are
merged into a single processor-internal bus via a bus switch. Hence, memory locations including peripheral
devices are mapped to a single 32-bit address space making the architecture a modified Von-Neumann
Architecture.
As a Von-Neumann machine, the CPU provides independent interfaces for instruction fetch and data access.
These two bus interfaces are merged into a single processor-internal bus via a prioritizing bus switch (data accesses
have higher priority). Hence, ALL memory locations including peripheral devices are mapped to a single unified 32-bit
address space.
 
 
// ####################################################################################################################
:sectnums:
=== Full Virtualization
 
Just like the RISC-V ISA the NEORV32 aims to provide _maximum virtualization_ capabilities on CPU _and_ SoC level to
allow a high standard of **execution safety**. The CPU supports **all** traps specified by the official RISC-V specifications.
footnote:[If the `Zicsr` CPU extension is enabled (implementing the full set of the privileged architecture).]
Thus, the CPU provides defined hardware fall-backs via traps for any expected and unexpected situation (e.g. executing an
malformed instruction word or accessing a not-allocated memory address). For any kind of trap the core is always in a
defined and fully synchronized state throughout the whole architecture (i.e. there are no out-of-order operations that
might have to reverted). This allows predictable execution behavior at any time improving overall _execution safety_.
 
**Execution Safety - NEORV32 Virtualization Features**
 
* Due to the acknowledged memory accesses the CPU is _always_ sync with the memory system
(i.e. there is no speculative execution / no out-of-order states).
* The CPU supports _all_ RISC-V compatible bus exceptions including access exceptions, which are triggered if an
accessed address does not respond or encounters an internal error during access.
* Accessed memory addresses (plain memory, but also memory-mapped devices) need to respond within a fixed time
window. Otherwise a bus access exception is raised.
* The RISC-V specs. state that executing an malformed instruction results in unpredictable behavior. As an additional
execution safety feature the NEORV32 CPU ensures that _all_ unimplemented/malformed/illegal instructions do raise an
illegal instruction exceptions and do not commit any state-changing operation (like writing registers or triggering
memory operations).
* To be continued...
 
 
// ####################################################################################################################
:sectnums:
=== RISC-V Compatibility
 
The NEORV32 CPU passes the rv32_m/I, rv32_m/M, rv32_m/C, rv32_m/privilege, and
236,6 → 269,11
The `A` CPU extension only implements the `lr.w` and `sc.w` instructions yet.
However, these instructions are sufficient to emulate all further atomic memory operations.
 
.Bit-manipulation operations
[IMPORTANT]
The NEORV32 `B` extension only implements the _basic bit-manipulation instructions_ (`Zbb`) subset
and the _address generation instructions_ (`Zba`) subset yet.
 
.Instruction Misalignment
[NOTE]
This is not a real RISC-V incompatibility, but something that might not be clear when studying the RISC-V privileged
244,7 → 282,6
there will be no misaligned instruction exceptions _at all_.
In both cases bit 0 of the program counter and all related registers is hardwired to zero.
 
 
<<<
// ####################################################################################################################
:sectnums:
385,6 → 422,42
information can be found in sections <<_bus_interface>> and <<_processor_external_memory_interface_wishbone_axi4_lite>>, respectively.
 
 
==== **`B`** - Bit-Manipulation Operations
 
The `B` ISA extension adds instructions for bit-manipulation operations. This extension is enabled if the
`CPU_EXTENSION_RISCV_B` configuration generic is _true_.
The official RISC-V specifications can be found here: https://github.com/riscv/riscv-bitmanip
 
[IMPORTANT]
The NEORV32 `B` extension only implements the _basic bit-manipulation instructions_ (`Zbb`) subset
and the _address generation instructions_ (`Zba`) subset yet.
 
The `Zbb` sub-extension adds the following instruction:
 
* `andn`, `orn`, `xnor`
* `clz`, `ctz`, `cpop`
* `max`, `maxu`, `min`, `minu`
* `sext.b`, `sext.h`, `zext.h`
* `rol`, `ror`, `rori`
* `orc.b`, `rev8`
 
The `Zba` sub-extension adds the following instruction:
 
* `sh1add`, `sh2add`, `sh3add`
 
[TIP]
By default, the bit-manipulation unit uses an _iterative_ approach to compute shift-related operations
like `clz` and `rol`. To increase performance (at the cost of additional hardware resources) the
<<_fast_shift_en>> generic can be enabled to implement full-parallel logic (like barrel shifters) for all
shift-related `B` instructions.
 
[WARNING]
The `B` extension is frozen but not officially ratified yet. There is no
software support for this extension in the upstream GCC RISC-V port yet. However, an
intrinsic library is provided to utilize the provided `B` extension features from C-language
code (see `sw/example/bitmanip_test`).
 
 
==== **`C`** - Compressed Instructions
 
The _compressed_ ISA extension provides 16-bit encodings of commonly used instructions to reduce code space size.
534,34 → 607,6
code (see `sw/example/floating_point_test`).
 
 
==== **`Zbb`** Basic Bit-Manipulation Operations
 
The `Zbb` extension implements the _basic_ sub-set of the RISC-V bit-manipulation extensions `B`.
The official RISC-V specifications can be found here: https://github.com/riscv/riscv-bitmanip
 
The `Zbb` extension is implemented when the `CPU_EXTENSION_RISCV_Zbb` configuration
generic is _true_. In this case the following instructions are available:
 
* `andn`, `orn`, `xnor`
* `clz`, `ctz`, `cpop`
* `max`, `maxu`, `min`, `minu`
* `sext.b`, `sext.h`, `zext.h`
* `rol`, `ror`, `rori`
* `orc.b`, `rev8`
 
[TIP]
By default, the bit-manipulation unit uses an _iterative_ approach to compute shift-related operations
like `clz` and `rol`. To increase performance (at the cost of additional hardware resources) the
<<_fast_shift_en>> generic can be enabled to implement full-parallel logic (like barrel shifters) for all
shift-related `Zbb` instructions.
 
[WARNING]
The `Zbb` extension is frozen but not officially ratified yet. There is no
software support for this extension in the upstream GCC RISC-V port yet. However, an
intrinsic library is provided to utilize the provided `Zbb` extension from C-language
code (see `sw/example/bitmanip_test`).
 
 
==== **`Zicsr`** Control and Status Register Access / Privileged Architecture
 
The CSR access instructions as well as the exception and interrupt system (= the privileged architecture)
586,6 → 631,50
`TW` (timeout wait) is hardwired to zero.
 
 
 
 
==== **`Zicntr`** CPU Base Counters
 
The `Zicntr` ISA extension adds the basic cycle `[m]cycle[h]`), instruction-retired (`[m]instret[h]`) and time (`time[h]`)
counters. This extensions is stated is _mandatory_ by the RISC-V spec. However, size-constrained setups may remove support for
these counters. Section <<_machine_counter_and_timer_csrs>> shows a list of all `Zicntr`-related CSRs.
These are available if the `Zicntr` ISA extensions is enabled via the <<_cpu_extension_riscv_zicntr>> generic.
 
[NOTE]
Disabling the `Zicntr` extension does not remove the `time[h]`-driving MTIME unit.
 
If `Zicntr` is disabled, all accesses to the according counter CSRs will raise an illegal instruction exception.
 
 
 
==== **`Zihpm`** Hardware Performance Monitors
 
In additions to the base cycle, instructions-retired and time counters the NEORV32 CPU provides
up to 29 hardware performance monitors (HPM 3..31), which can be used to benchmark applications. Each HPM consists of an
N-bit wide counter (split in a high-word 32-bit CSR and a low-word 32-bit CSR), where N is defined via the top's
`HPM_CNT_WIDTH` generic (0..64-bit) and a corresponding event configuration CSR. The event configuration
CSR defines the architectural events that lead to an increment of the associated HPM counter.
 
The HPM counters are available if the `Zihpm` ISA extensions is enabled via the <<_cpu_extension_riscv_zihpm>> generic.
 
Depending on the configuration the following additional CSR are available:
 
* counters: `mhpmcounter*[h]` (3..31, depending on `HPM_NUM_CNTS`)
* event configuration: `mhpmevent*` (3..31, depending on `HPM_NUM_CNTS`)
 
[IMPORTANT]
The HPM counter CSR can only be accessed in machine-mode. Hence, the according `mcounteren` CSR bits
are always zero and read-only. Any access from less-privileged modes will raise an illegal instruction
exception.
 
[TIP]
Auto-increment of the HPMs can be individually deactivated via the `mcountinhibit` CSR.
 
[TIP]
For a list of all HPM-related CSRs and all provided event configurations
see section <<_hardware_performance_monitors_hpm>>.
 
 
==== **`Zifencei`** Instruction Stream Synchronization
 
The `Zifencei` CPU extension is implemented if the `CPU_EXTENSION_RISCV_Zifencei` configuration
593,7 → 682,7
 
* `fence.i`
 
The `fence.i` instruction resets the CPU's internal instruction fetch engine and flushes the prefetch buffer.
The `fence.i` instruction resets the CPU's front-end (instruction fetch) and flushes the prefetch buffer.
This allows a clean re-fetch of modified instructions from memory. Also, the top's `i_bus_fencei_o` signal is set
high for one cycle to inform the memory system (like the i-cache to perform a flush/reload.
Any additional flags within the `fence.i` instruction word are ignore by the hardware.
659,44 → 748,7
Instruction Set Manual - Volume II: Privileged Architecture_ specifications.
 
 
==== **`HPM`** Hardware Performance Monitors
 
In additions to the mandatory cycle (`[m]cycle[h]`) and instruction (`[m]instret[h]`) counters the NEORV32 CPU provides
up to 29 hardware performance monitors (HPM 3..31), which can be used to benchmark applications. Each HPM consists of an
N-bit wide counter (split in a high-word 32-bit CSR and a low-word 32-bit CSR), where N is defined via the top's
`HPM_CNT_WIDTH` generic (0..64-bit) and a corresponding event configuration CSR. The event configuration
CSR defines the architectural events that lead to an increment of the associated HPM counter.
 
The cycle, time and instructions-retired counters (`[m]cycle[h]`, `time[h]`, `[m]instret[h]`) are
mandatory performance monitors on every RISC-V platform and have fixed increment events. For example,
the instructions-retired counter increments with each executed instructions. The actual hardware performance
monitors are optional and can be configured to increment on arbitrary hardware events. The number of
available HPM is configured via the top's `HPM_NUM_CNTS` generic at synthesis time. Assigning a zero will remove
all HPM logic from the design.
 
If `HPM_NUM_CNTS` is lower than the maximum value (=29) the remaining HPM CSRs are not implemented and the
according `mcountinhibit` CSR bits are hardwired to zero.
However, accessing their associated CSRs will not raise an illegal instruction exception (if in machine mode).
The according CSRs are read-only and will always return 0.
 
Depending on the configuration the following additional CSR are available:
 
* counters: `mhpmcounter*[h]` (3..31, depending on `HPM_NUM_CNTS`)
* event configuration: `mhpmevent*` (3..31, depending on `HPM_NUM_CNTS`)
 
[IMPORTANT]
The HPM counter CSR can only be accessed in machine-mode. Hence, the according `mcounteren` CSR bits
are always zero and read-only. Any access from less-privileged modes will raise an illegal instruction
exception.
 
[TIP]
Auto-increment of the HPMs can be individually deactivated via the `mcountinhibit` CSR.
 
[TIP]
For a list of all HPM-related CSRs and all provided event configurations
see section <<_hardware_performance_monitors_hpm>>.
 
 
<<<
// ####################################################################################################################
:sectnums:
727,18 → 779,12
| Memory access | `A` | `lr.w` `sc.w` | 4 + ML
| Multiplication | `M` | `mul` `mulh` `mulhsu` `mulhu` | 2+31+3; FAST_MULfootnote:[DSP-based multiplication; enabled via `FAST_MUL_EN`.]: 5
| Division | `M` | `div` `divu` `rem` `remu` | 22+32+4
| Bit-manipulation - arithmetic/logic | `B(Zbb)` | `sext.b` `sext.h` `min` `minu` `max` `maxu` `andn` `orn` `xnor` `zext`(pack) `rev8`(grevi) `orc.b`(gorci) | 3
| Bit-manipulation - shifts | `B(Zbb)` | `clz` `ctz` | 3 + 0..32
| Bit-manipulation - shifts | `B(Zbb)` | `cpop` | 3 + 32
| Bit-manipulation - shifts | `B(Zbb)` | `rol` `ror` `rori` | 3 + SA
| Bit-manipulation - single-bit | `B(Zbs)` | `sbset[i]` `sbclr[i]` `sbinv[i]` `sbext[i]` | 3
| Bit-manipulation - shifted-add | `B(Zba)` | `sh1add` `sh2add` `sh3add` | 3
| CSR access | `Zicsr` | `csrrw` `csrrs` `csrrc` `csrrwi` `csrrsi` `csrrci` | 4
| System | `I/E`+`Zicsr` | `ecall` `ebreak` | 4
| System | `I/E` | `fence` | 3
| System | `C`+`Zicsr` | `c.break` | 4
| System | `Zicsr` | `mret` `wfi` | 5
| System | `Zifencei` | `fence.i` | 5
| System | `Zifencei` | `fence.i` | 3 + ML
| Floating-point - artihmetic | `Zfinx` | `fadd.s` | 110
| Floating-point - artihmetic | `Zfinx` | `fsub.s` | 112
| Floating-point - artihmetic | `Zfinx` | `fmul.s` | 22
746,10 → 792,13
| Floating-point - misc | `Zfinx` | `fsgnj.s` `fsgnjn.s` `fsgnjx.s` `fclass.s` | 12
| Floating-point - conversion | `Zfinx` | `fcvt.w.s` `fcvt.wu.s` | 47
| Floating-point - conversion | `Zfinx` | `fcvt.s.w` `fcvt.s.wu` | 48
| Basic bit-manip - logic | `Zbb` | `andn` `orn` `xnor` | 3
| Basic bit-manip - shift | `Zbb` | `clz` `ctz` `cpop` `rol` `ror` `rori` | 4+SA, FAST_SHIFT: 4
| Basic bit-manip - arith | `Zbb` | `max` `maxu` `min` `minu` | 3
| Basic bit-manip - misc | `Zbb` | `sext.b` `sext.h` `zext.h` `orc.b` `rev8` | 3
| Bit-manipulation - arithmetic/logic | `B(Zbb)` | `sext.b` `sext.h` `min` `minu` `max` `maxu` `andn` `orn` `xnor` `zext`(pack) `rev8`(grevi) `orc.b`(gorci) | 3
| Bit-manipulation - arithmetic/logic | `B(Zba)` | `sh1add` `sh2add` `sh3add` | 3
| Bit-manipulation - shifts | `B(Zbb)` | `clz` `ctz` | 3 + 0..32
| Bit-manipulation - shifts | `B(Zbb)` | `cpop` | 3 + 32
| Bit-manipulation - shifts | `B(Zbb)` | `rol` `ror` `rori` | 3 + SA
| Bit-manipulation - single-bit | `B(Zbs)` | `sbset[i]` `sbclr[i]` `sbinv[i]` `sbext[i]` | 3
| Bit-manipulation - shifted-add | `B(Zba)` | `sh1add` `sh2add` `sh3add` | 3
|=======================
 
[NOTE]
758,41 → 807,14
instructions (using pure-software libraries) is ~17..140 times higher.
 
 
 
<<<
// ####################################################################################################################
include::cpu_csr.adoc[]
 
 
 
<<<
// ####################################################################################################################
:sectnums:
==== Full Virtualization
 
Just like the RISC-V ISA the NEORV32 aims to support _ maximum virtualization_ capabilities
on CPU _and_ SoC level. The CPU supports **all** traps specified by the official RISC-V specifications.footnote:[If the `Zicsr` CPU
extension is enabled (implementing the full set of the privileged architecture).]
Thus, the CPU provides defined hardware fall-backs for any expected and unexpected situation (e.g. executing an
malformed instruction word or accessing a not-allocated address). For any kind of trap the core is always in a
defined and fully synchronized state throughout the whole architecture (i.e. there are no out-of-order operations that
have to be made undone). This allows predictable execution behavior - and thus, defined operations to resolve the cause
of the trap - at any time improving overall _execution safety_.
 
**NEORV32-Specific Virtualization Features**
 
* Due to the acknowledged memory accesses the CPU is _always_ sync with the memory system
(i.e. there is no speculative execution / no out-of-order states).
* The CPU supports _all_ RISC-V bus exceptions including access exceptions that are triggered if an
accessed address does not respond or encounters an internal error during access.
* The RISC-V specs. state that executing an malformed instruction results in unpredictable behavior. As an additional security feature,
the NEORV32 CPU ensures that _all_ unimplemented/malformed/illegal instructions _do raise an illegal instruction trap_ and
_do not commit any operation_ (like writing registers or triggering memory operations).
* To be continued...
 
 
<<<
// ####################################################################################################################
:sectnums:
==== Traps, Exceptions and Interrupts
 
In this document the following nomenclature regarding traps is used:
964,7 → 986,7
However, the bus transaction has to be completed (= acknowledged) within a certain **response time window**. This time window is defined
by the global `max_proc_int_response_time_c` constant (default = 15 cycles) from the processor's VHDL package file (`rtl/neorv32_package.vhd`).
It defines the maximum number of cycles after which an _unacknowledged_ processor-internal bus transfer will timeout and raise a **bus fault exception**.
The _BUSKEEPER_ hardware module (`rtl/core/neorv32_bus_keeper.vhd`) keeps track of all _internal_ bus transactions. If any bus operations times out
The _BUSKEEPER_ hardware module (see section <<_internal_bus_monitor_buskeeper>>) keeps track of all _internal_ bus transactions. If any bus operations times out
(for example when accessing "address space holes") this unit will issue a bus error to the CPU that will raise the according instruction fetch or data access bus exception.
Note that **the bus keeper does not track external accesses via the external memory bus interface**. However, the external memory bus interface also provides
an _optional_ bus timeout (see section <<_processor_external_memory_interface_wishbone_axi4_lite>>).
1049,7 → 1071,7
 
A good example to illustrate the concept of uncritical registers is a pipelined processing engine. Each stage
of the engine features an N-bit _data register_ and a 1-bit _status register_. The status register is set when the
data in the according data register is valid. At the end of the pipeline the status register might trigger a writeback
data in the according data register is valid. At the end of the pipeline the status register might trigger a write-back
of the processing result to some kind of memory. The initial status of the data registers after power-up is
irrelevant as long as the status registers are all reset to a defined value that indicates there is no valid data in
the pipeline’s data register. Therefore, the pipeline data register do no require a dedicated reset as they do not
/docs/datasheet/cpu_csr.adoc
68,10 → 68,10
| 0x001 | <<_fflags>> | _CSR_FFLAGS_ | r/w | Floating-point accrued exceptions |
| 0x002 | <<_frm>> | _CSR_FRM_ | r/w | Floating-point dynamic rounding mode |
| 0x003 | <<_fcsr>> | _CSR_FCSR_ | r/w | Floating-point control and status (`frm` + `fflags`) |
6+^| **<<_machine_configuration>>**
6+^| **<<_machine_configuration_csrs>>**
| 0x30a | <<_menvcfg>> | _CSR_MENVCFG_ | r/- | Machine environment configuration register - low word | `R`
| 0x31a | <<_menvcfgh>> | _CSR_MENVCFGH_ | r/- | Machine environment configuration register - low word | `R`
6+^| **<<_machine_trap_setup>>**
6+^| **<<_machine_trap_setup_csrs>>**
| 0x300 | <<_mstatus>> | _CSR_MSTATUS_ | r/w | Machine status register - low word | `C`
| 0x301 | <<_misa>> | _CSR_MISA_ | r/- | Machine CPU ISA and extensions | `R`
| 0x304 | <<_mie>> | _CSR_MIE_ | r/w | Machine interrupt enable register | `X`
78,16 → 78,16
| 0x305 | <<_mtvec>> | _CSR_MTVEC_ | r/w | Machine trap-handler base address (for ALL traps) |
| 0x306 | <<_mcounteren>> | _CSR_MCOUNTEREN_ | r/w | Machine counter-enable register | `C`
| 0x310 | <<_mstatush>> | _CSR_MSTATUSH_ | r/- | Machine status register - high word | `C`
6+^| **<<_machine_trap_handling>>**
6+^| **<<_machine_trap_handling_csrs>>**
| 0x340 | <<_mscratch>> | _CSR_MSCRATCH_ | r/w | Machine scratch register |
| 0x341 | <<_mepc>> | _CSR_MEPC_ | r/w | Machine exception program counter |
| 0x342 | <<_mcause>> | _CSR_MCAUSE_ | r/w | Machine trap cause | `X`
| 0x343 | <<_mtval>> | _CSR_MTVAL_ | r/- | Machine bad address or instruction | `XR`
| 0x344 | <<_mip>> | _CSR_MIP_ | r/- | Machine interrupt pending register | `XR`
6+^| **<<_machine_physical_memory_protection>>**
6+^| **<<_machine_physical_memory_protection_csrs>>**
| 0x3a0 .. 0x3af | <<_pmpcfg, `pmpcfg0`>> .. <<_pmpcfg, `pmpcfg15`>> | _CSR_PMPCFG0_ .. _CSR_PMPCFG15_ | r/w | Physical memory protection config. for region 0..63 | `C`
| 0x3b0 .. 0x3ef | <<_pmpaddr, `pmpaddr0`>> .. <<_pmpaddr, `pmpaddr63`>> | _CSR_PMPADDR0_ .. _CSR_PMPADDR63_ | r/w | Physical memory protection addr. register region 0..63 |
6+^| **<<_machine_counters_and_timers>>**
6+^| **<<_machine_counter_and_timer_csrs>>**
| 0xb00 | <<_mcycleh, `mcycle`>> | _CSR_MCYCLE_ | r/w | Machine cycle counter low word |
| 0xb02 | <<_minstreth, `minstret`>> | _CSR_MINSTRET_ | r/w | Machine instruction-retired counter low word |
| 0xb80 | <<_mcycleh>> | _CSR_MCYCLE_ | r/w | Machine cycle counter high word |
98,13 → 98,13
| 0xc80 | <<_cycleh>> | _CSR_CYCLEH_ | r/- | Cycle counter high word |
| 0xc81 | <<_timeh>> | _CSR_TIMEH_ | r/- | System time (from MTIME) high word |
| 0xc82 | <<_instreth>> | _CSR_INSTRETH_ | r/- | Instruction-retired counter high word |
6+^| **<<_hardware_performance_monitors_hpm>>**
6+^| **<<_hardware_performance_monitors_hpm_csrs>>**
| 0x323 .. 0x33f | <<_mhpmevent, `mhpmevent3`>> .. <<_mhpmevent, `mhpmevent31`>> | _CSR_MHPMEVENT3_ .. _CSR_MHPMEVENT31_ | r/w | Machine performance-monitoring event selector 3..31 | `X`
| 0xb03 .. 0xb1f | <<_mhpmcounterh, `mhpmcounter3`>> .. <<_mhpmcounterh, `mhpmcounter31`>> | _CSR_MHPMCOUNTER3_ .. _CSR_MHPMCOUNTER31_ | r/w | Machine performance-monitoring counter 3..31 low word |
| 0xb83 .. 0xb9f | <<_mhpmcounterh, `mhpmcounter3h`>> .. <<_mhpmcounterh, `mhpmcounter31h`>> | _CSR_MHPMCOUNTER3H_ .. _CSR_MHPMCOUNTER31H_ | r/w | Machine performance-monitoring counter 3..31 high word |
6+^| **<<_machine_counter_setup>>**
6+^| **<<_machine_counter_setup_csrs>>**
| 0x320 | <<_mcountinhibit>> | _CSR_MCOUNTINHIBIT_ | r/w | Machine counter-enable register |
6+^| **<<_machine_information_registers>>**
6+^| **<<_machine_information_csrs>>**
| 0xf11 | <<_mvendorid>> | _CSR_MVENDORID_ | r/- | Vendor ID |
| 0xf12 | <<_marchid>> | _CSR_MARCHID_ | r/- | Architecture ID |
| 0xf13 | <<_mimpid>> | _CSR_MIMPID_ | r/- | Machine implementation ID / version |
168,7 → 168,7
<<<
// ####################################################################################################################
:sectnums:
==== Machine Configuration
==== Machine Configuration CSRs
 
:sectnums!:
===== **`menvcfg`**
199,7 → 199,7
<<<
// ####################################################################################################################
:sectnums:
==== Machine Trap Setup
==== Machine Trap Setup CSRs
 
:sectnums!:
===== **`mstatus`**
361,7 → 361,7
<<<
// ####################################################################################################################
:sectnums:
==== Machine Trap Handling
==== Machine Trap Handling CSRs
 
:sectnums!:
===== **`mscratch`**
447,7 → 447,7
3+| Reset value: _0x00000000_
3+| The `mip` CSR is compatible to the RISC-V specifications and also provides custom extensions. It shows currently _pending_ interrupts.
Since this register is read-only, pending interrupts of processor-internal modules can only be cleared by acknowledging the interrupt-causing
device. However, pending interrupts can be ignored by clearing the accordind <<_mie>> register bits.
device. However, pending interrupts can be ignored by clearing the according <<_mie>> register bits.
The following CSR bits are implemented (all remaining bits are always zero and are read-only).
|======
 
469,7 → 469,7
<<<
// ####################################################################################################################
:sectnums:
==== Machine Physical Memory Protection
==== Machine Physical Memory Protection CSRs
 
The available physical memory protection logic is configured via the _PMP_NUM_REGIONS_ and
_PMP_MIN_GRANULARITY_ top entity generics. _PMP_NUM_REGIONS_ defines the number of implemented
532,8 → 532,11
<<<
// ####################################################################################################################
:sectnums:
==== (Machine) Counters and Timers
==== (Machine) Counter and Timer CSRs
 
The (machine) counters and timers are implemented when the `Zicntr` ISA extensions is enabled (default)
via the <<_cpu_extension_riscv_zicntr>> generic.
 
[NOTE]
The <<_cpu_cnt_width>> generic defines the total size of the CPU's <<_cycleh>> and <<_instreth>>
/ <<_mcycleh>> and <<_minstreth>>
553,8 → 556,7
the `CPU` <<_system_configuration_information_memory_sysinfo, SYSINFO>> register. +
+
If _CPU_CNT_WIDTH_ is 0, the <<_cycleh>> and <<_instreth>> / <<_mcycleh>> and <<_minstreth>> CSRs are hardwired to zero
and any write access to them is ignored. This configuration will also set the _SYSINFO_CPU_ZXNOCNT_ flag ("no counters") in the
`CPU` <<_system_configuration_information_memory_sysinfo, SYSINFO>> register.
and any write access to them is ignored.
 
 
:sectnums!:
633,23 → 635,27
<<<
// ####################################################################################################################
:sectnums:
==== Hardware Performance Monitors (HPM)
==== Hardware Performance Monitors (HPM) CSRs
 
The available hardware performance logic is configured via the <<_hpm_num_cnts>> top entity generic,
which defines the number of implemented performance monitors and thus, the availability of the
according `mhpmcounter*[h]` and `mhpmevent*` CSRs.
The hardware performance monitor CSRs are implemented when the `Zihpm` ISA extension is enabled via the
<<_cpu_extension_riscv_zihpm>> generic.
 
The actually implemented hardware performance logic is configured via the <<_hpm_num_cnts>> top entity generic,
which defines the number of implemented performance monitors. Note that always all 28 HPM counter and configuration registers
(`mhpmcounter*[h]` and `mhpmevent*`) are implemented, but only the actually configured ones are real registers and
not hardwired to zero.
 
[TIP]
If trying to access an HPM-related CSR beyond <<_hpm_num_cnts>> **no illegal instruction exception is
triggered**. The according CSRs are read-only (writes are ignored) and always return zero.
 
[IMPORTANT]
The HPM system only implements machine-mode access. Hence, `hpmcounter*[h]` CSR are not implemented
The HPM system only allows machine-mode access. Hence, `hpmcounter*[h]` CSR are not implemented
and any access (even) from machine mode will raise an exception. Furthermore, the according bits of <<_mcounteren>>
used to configure user-mode access to `hpmcounter*[h]` are hard-wired to zero.
 
The total counter size of the HPMs can be configured before synthesis via the <<_hpm_cnt_width>> generic (0..64-bit).
The total counter width of the HPMs can be configured before synthesis via the <<_hpm_cnt_width>> generic (0..64-bit).
 
[TIP]
If trying to access an HPM-related CSR beyond <<_hpm_num_cnts>> **no illegal instruction exception is
triggered**. The according CSRs are read-only (writes are ignored) and always return zero.
 
[NOTE]
The total LSB-aligned HPM counter size (low word CSR + high word CSR) is defined via the
<<_hpm_num_cnts>> generic (0..64-bit). If <<_hpm_num_cnts>> is less than 64, all unused MSB-aligned
717,7 → 723,7
<<<
// ####################################################################################################################
:sectnums:
==== Machine Counter Setup
==== Machine Counter Setup CSRs
 
:sectnums!:
===== **`mcountinhibit`**
747,7 → 753,7
<<<
// ####################################################################################################################
:sectnums:
==== Machine Information Registers
==== Machine Information CSRs
 
[NOTE]
All machine information registers can only be accessed in machine mode and are read-only.
/docs/datasheet/on_chip_debugger.adoc
358,7 → 358,7
| 31:24 | `cmdtype` | -/w | `00000000` to indicate "access register" command
| 23 | _reserved_ | -/w | reserved, has to be `0` when writing
| 22:20 | `aarsize` | -/w | `010` to indicate 32-bit accesses
| 21 | `aarpostincrement` | -/w | `0`, postincrement is not supported
| 21 | `aarpostincrement` | -/w | `0`, post-increment is not supported
| 18 | `postexec` | -/w | if set the program buffer is executed _after_ the command
| 17 | `transfer` | -/w | if set the operation in `write` is conducted
| 16 | `write` | -/w | `1`: copy `data0` to `[regno]`; `0` copy `[regno]` to `data0`
/docs/datasheet/overview.adoc
10,6 → 10,10
memories, NoCs and other peripherals. On-line and in-system debugging is supported by an OpenOCD/gdb
compatible on-chip debugger accessible via JTAG.
 
Special focus is paid on **execution safety** to provide defined and predictable behavior at any time.
Therefore, the CPU ensures that all memory access are acknowledged and no invalid/malformed instructions
are executed. Whenever an unexpected situation occurs, the application code is informed via hardware exceptions.
 
The software framework of the processor comes with application makefiles, software libraries for all CPU
and processor features, a bootloader, a runtime environment and several example programs - including a port
of the CoreMark MCU benchmark and the official RISC-V architecture test suite. RISC-V GCC is used as
148,12 → 152,11
neorv32 - Project home folder
│
├docs - Project documentation
│├datasheet - .adoc sources for NEORV32 data sheet
│├doxygen_build - Software framework documentation (generated by doxygen)
│├datasheet - AsciiDoc sources for the NEORV32 data sheet
│├figures - Figures and logos
│├icons - Misc. symbols
│├references - Data sheets and RISC-V specs.
│└src_adoc - AsciiDoc sources for this document
│└userguide - AsciiDoc sources for the NEORV32 user guide
│
├rtl - VHDL sources
│├core - Core sources of the CPU & SoC
168,14 → 171,14
├sim - Simulation files (see User Guide)
│
â””sw - Software framework
├bootloader - Sources and scripts for the NEORV32 internal bootloader
├common - Linker script and crt0.S start-up code
├bootloader - Sources of the processor-internal bootloader
├common - Linker script, crt0.S start-up code and central makefile
├example - Various example programs
│└...
├isa-test
│├riscv-arch-test - RISC-V spec. compatibility test framework (submodule)
│└port-neorv32 - Port files for the official RISC-V architecture tests
├ocd_firmware - source code for on-chip debugger's "park loop"
├ocd_firmware - Source code for on-chip debugger's "park loop"
├openocd - OpenOCD on-chip debugger configuration files
├image_gen - Helper program to generate NEORV32 executables
â””lib - Processor core library
270,16 → 273,16
[cols="<5,>1,>1,>1,>1,>1"]
[options="header",grid="rows"]
|=======================
| CPU | LEs | FFs | MEM bits | DSPs | _f~max~_
| `rv32i` | 806 | 359 | 1024 | 0 | 125 MHz
| `rv32i_Zicsr` | 1729 | 813 | 1024 | 0 | 124 MHz
| `rv32im_Zicsr` | 2269 | 1055 | 1024 | 0 | 124 MHz
| `rv32imc_Zicsr` | 2501 | 1070 | 1024 | 0 | 124 MHz
| `rv32imac_Zicsr` | 2511 | 1074 | 1024 | 0 | 124 MHz
| `rv32imacu_Zicsr` | 2521 | 1079 | 1024 | 0 | 124 MHz
| `rv32imacu_Zicsr_Zifencei` | 2522 | 1079 | 1024 | 0 | 122 MHz
| `rv32imacu_Zicsr_Zifencei_Zfinx` | 3807 | 1731 | 1024 | 7 | 116 MHz
| `rv32imacu_Zicsr_Zifencei_Zfinx_DebugMode` | 3974 | 1815 | 1024 | 7 | 116 MHz
| CPU | LEs | FFs | MEM bits | DSPs | _f~max~_
| `rv32i` | 806 | 359 | 1024 | 0 | 125 MHz
| `rv32i_Zicsr_Zicntr` | 1729 | 813 | 1024 | 0 | 124 MHz
| `rv32im_Zicsr_Zicntr` | 2269 | 1055 | 1024 | 0 | 124 MHz
| `rv32imc_Zicsr_Zicntr` | 2501 | 1070 | 1024 | 0 | 124 MHz
| `rv32imac_Zicsr_Zicntr` | 2511 | 1074 | 1024 | 0 | 124 MHz
| `rv32imacu_Zicsr_Zicntr` | 2521 | 1079 | 1024 | 0 | 124 MHz
| `rv32imacu_Zicsr_Zicntr_Zifencei` | 2522 | 1079 | 1024 | 0 | 122 MHz
| `rv32imacu_Zicsr_Zicntr_Zifencei_Zfinx` | 3807 | 1731 | 1024 | 7 | 116 MHz
| `rv32imacu_Zicsr_Zicntr_Zifencei_Zfinx_DebugMode` | 3974 | 1815 | 1024 | 7 | 116 MHz
|=======================
 
[NOTE]
372,10 → 375,10
[cols="<4,^1,^1,^1"]
[options="header",grid="rows"]
|=======================
| CPU | CoreMark Score | CoreMarks/Mhz | Average CPI
| _small_ (`rv32i_Zicsr`) | 33.89 | **0.3389** | **4.04**
| _medium_ (`rv32imc_Zicsr`) | 62.50 | **0.6250** | **5.34**
| _performance_(`rv32imc_Zicsr` + perf. options) | 95.23 | **0.9523** | **3.54**
| CPU | CoreMark Score | CoreMarks/MHz | Average CPI
| _small_ (`rv32i_Zicsr`) | 33.89 | **0.3389** | **4.04**
| _medium_ (`rv32imc_Zicsr`) | 62.50 | **0.6250** | **5.34**
| _performance_ (`rv32imc_Zicsr` + perf. options) | 95.23 | **0.9523** | **3.54**
|=======================
 
[NOTE]
/docs/datasheet/soc.adoc
26,6 → 26,7
* _optional_ NeoPixel(TM)/WS2812-compatible smart LED interface (<<_smart_led_interface_neoled,**NEOLED**>>)
* _optional_ external interrupt controller with up to 32 channels (<<_external_interrupt_controller_xirq,**XIRQ**>>)
* _optional_ on-chip debugger with JTAG TAP (<<_on_chip_debugger_ocd,**OCD**>>)
* bus keeper to monitor processor-internal bus transactions (<<_internal_bus_monitor_buskeeper,**BUSKEEPER**>>)
* system configuration information memory to check HW configuration via software (<<_system_configuration_information_memory_sysinfo,**SYSINFO**>>)
 
 
238,6 → 239,18
 
 
:sectnums!:
===== _CPU_EXTENSION_RISCV_B_
 
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **CPU_EXTENSION_RISCV_B** | _boolean_ | false
3+| Implement the `B` bit-manipulation sub-extension when _true_.
See section <<_b_bit_manipulation_operations>> for more information.
|======
 
 
:sectnums!:
===== _CPU_EXTENSION_RISCV_C_
 
[cols="4,4,2"]
290,18 → 303,6
 
 
:sectnums!:
===== _CPU_EXTENSION_RISCV_Zbb_
 
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **CPU_EXTENSION_RISCV_Zbb** | _boolean_ | false
3+| Implement the `Zbb` _basic_ bit-manipulation sub-extension when _true_.
See section <<_zbb_basic_bit_manipulation_operations>> for more information.
|======
 
 
:sectnums!:
===== _CPU_EXTENSION_RISCV_Zfinx_
 
[cols="4,4,2"]
328,6 → 329,32
 
 
:sectnums!:
===== _CPU_EXTENSION_RISCV_Zicntr_
 
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **CPU_EXTENSION_RISCV_Zicntr** | _boolean_ | true
3+| Implement the basic CPU counter CSRs (`time[h]`, `[m]cycle[h]`, `[m]instret[h]`) when true.
Enabling this extension will set the _SYSINFO_CPU_ZICNTR_ flag in the `CPU` <<_system_configuration_information_memory_sysinfo, SYSINFO>> register.
See section <<_zicntr_cpu_base_counters>> for more information.
|======
 
 
:sectnums!:
===== _CPU_EXTENSION_RISCV_Zihpm_
 
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **CPU_EXTENSION_RISCV_Zihpm** | _boolean_ | false
3+| Implement hardware performance monitor CSRs when true.
Enabling this extension will set the _SYSINFO_CPU_ZIHPM_ flag in the `CPU` <<_system_configuration_information_memory_sysinfo, SYSINFO>> register.
See section <<_zihpm_hardware_performance_monitors>> for more information.
|======
 
 
:sectnums!:
===== _CPU_EXTENSION_RISCV_Zifencei_
 
[cols="4,4,2"]
385,7 → 412,7
more hardware resources but completing within two clock cycles). If it is set _false_, the CPU uses a serial shifter
that only performs a single bit shift per cycle (requiring less hardware resources, but requires up to 32 clock
cycles to complete - depending on shift amount). **Note that this option also implements barrel shifters for _all_
shift-related operations of the <<_zbb_basic_bit_manipulation_operations>> extension.**
shift-related operations of the <<_b_bit_manipulation_operations>> extension.**
|======
 
 
398,6 → 425,7
| **CPU_CNT_WIDTH** | _natural_ | 64
3+| This generic configures the total size of the CPU's `[m]cycle` and `[m]instret` CSRs (low word + high word).
The maximum value is 64, the minimum value is 0. See section <<_machine_counters_and_timers>> for more information.
This generic is only relevant if the `Zicntr` ISa extension is enabled (<<_cpu_extension_riscv_zicntr>>).
Note: configurations with <<_cpu_cnt_width>> less than 64 bits do not comply to the RISC-V specs.
|======
 
450,7 → 478,8
:sectnums:
==== Hardware Performance Monitors (HPM)
 
See section <<_hpm_hardware_performance_monitors>> for more information.
These generics allow to customize the `Zihpm` ISA extension. Note that the following generics are ignored if the
<<_cpu_extension_riscv_zihpm>> generic is _false_. See section <<_zihpm_hardware_performance_monitors>> for more information.
 
 
:sectnums!:
461,8 → 490,7
|======
| **HPM_NUM_CNTS** | _natural_ | 0
3+| Total number of implemented hardware performance monitor counters (0..29). If this generics is zero, no
hardware performance monitor logic will be implemented at all. Setting <<_hpm_num_cnts>> > 0 will set the _SYSINFO_CPU_HPM_ flag
in the `CPU` <<_system_configuration_information_memory_sysinfo, SYSINFO>> register.
hardware performance monitor logic will be implemented at all.
|======
 
 
1017,7 → 1045,7
.Trigger type
[IMPORTANT]
The fast interrupt request channel trigger on **high-level** and have to stay asserted until explicitly acknowledged
by the software (for example by writing to a specifc memory-mapped register). Hence, pending interrupts remain pending
by the software (for example by writing to a specific memory-mapped register). Hence, pending interrupts remain pending
as long as the interrupt-causing device's state fulfills it's interrupt condition(s).
 
 
1076,7 → 1104,7
.Trigger type
[IMPORTANT]
The fast interrupt request channel trigger on **high-level** and have to stay asserted until explicitly acknowledged
by the software (for example by writing to a specifc memory-mapped register). Hence, pending interrupts remain pending
by the software (for example by writing to a specific memory-mapped register). Hence, pending interrupts remain pending
as long as the interrupt-causing device's state fulfills it's interrupt condition(s).
 
 
1387,8 → 1415,7
 
Most peripheral/IO devices provide some kind of interrupt (for example to signal available incoming data). These
interrupts are entirely mapped to the CPU's <<_custom_fast_interrupt_request_lines>>. Note that all these
interrupt lines are triggered by a "one-shot" signal (hich for exactly one cycle) and _do not_ require any
explicit acknowledgment.
interrupt lines are high-active and are permanently triggered until the IRQ-causing condition is resolved.
 
**Nomenclature for the Peripheral / IO Devices Listing**
 
1435,6 → 1462,8
 
include::soc_wishbone.adoc[]
 
include::soc_buskeeper.adoc[]
 
include::soc_slink.adoc[]
 
include::soc_gpio.adoc[]
/docs/datasheet/soc_buskeeper.adoc
0,0 → 1,64
<<<
:sectnums:
==== Internal Bus Monitor (BUSKEEPER)
 
[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source file(s): | neorv32_buskeeper.vhd |
| Software driver file(s): | none | explicitly used
| Top entity port: | none |
| Configuration generics: | none |
| Package constants: | `max_proc_int_response_time_c` | Access time window (#cycles)
| CPU interrupts: | none |
|=======================
 
**Theory of Operation**
 
The Bus Keeper is a fundamental component of the processor's internal bus system that ensures correct bus operations
to maintain execution safety. The Bus Keeper monitors every single bus transactions that is intimated by the CPU.
If an accessed device responds with an error condition or do not respond within a specific _access time window_,
the according bus access fault exception is raised. The following exceptions can be raised by the Bus Keeper
(see section <<_neorv32_trap_listing>> for all CPU exceptions):
 
* `TRAP_CODE_I_ACCESS`: error during instruction fetch bus access
* `TRAP_CODE_S_ACCESS`: error during data store bus access
* `TRAP_CODE_L_ACCESS`: error during data load bus access
 
The **access time window**, in which an accessed device has to respond, is defined by the `max_proc_int_response_time_c`
constant from the processor's VHDL package file (`rtl/neorv32_package.vhd`). The default value is **15 clock cycles**.
 
In case of a bus access fault exception application software can evaluate the Bus Keeper's control register
`NEORV32_BUSKEEPER.CTRL` to retrieve further details of the bus exception. The _BUSKEEPER_ERR_FLAG_ bit indicates
that an actual bus access fault has occurred. The bit is sticky once set is automatically cleared when reading the
`NEORV32_BUSKEEPER.CTRL` register. The _BUSKEEPER_ERR_TYPE_ indicated the tape or bus fault:
 
* _BUSKEEPER_ERR_TYPE_ = `0` - "Device Error": The bus access exception was cause by the memory-mapped device that
has been accessed (the device asserted it's `err_o`).
* _BUSKEEPER_ERR_TYPE_ = `1` - "Timeout Error": The bus access exception was caused by the Bus Keeper because the
accessed memory-mapped device did not respond within the access time window.
 
[NOTE]
Bus access fault exceptions are also raised if a physical memory protection rule is violated. In this case
the _BUSKEEPER_ERR_FLAG_ bit remains zero.
 
Furthermore, application software can determine the source of the bus access fault via the _BUSKEEPER_ERR_SRC_ bit:
 
* _BUSKEEPER_ERR_SRC_ = `0`: The error was cause during access via the <<_processor_external_memory_interface_wishbone_axi4_lite>>).
* _BUSKEEPER_ERR_SRC_ = `1`: The error was cause during access to an processor-internal module.
 
[NOTE]
The Bus Keeper does not track **timeout errors** of processor-external accesses via the external memory bus interface.
However, the external memory bus interface also provides an _optional_ and independent bus timeout feature
(see section <<_processor_external_memory_interface_wishbone_axi4_lite>>).
 
 
.BUSKEEPER register map (`struct NEORV32_BUSKEEPER`)
[cols="<2,<2,<4,^1,<4"]
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.3+<| `0xffffff7C` .3+<| `NEORV32_BUSKEEPER.CTRL` <|`0` _BUSKEEPER_ERR_TYPE_ ^| r/- <| Bus error type, valid if _BUSKEEPER_ERR_FLAG_ is set: `0`=device error, `1`=access timeout
<|`1` _BUSKEEPER_ERR_SRC_ ^| r/- <| Error source: `0`=processor-internal, `1`=processor-external (via Wishbone bus interface)
<|`31` _BUSKEEPER_ERR_FLAG_ ^| r/- <| Sticky error flag, clears after read
|=======================
/docs/datasheet/soc_imem.adoc
11,7 → 11,7
| Top entity port: | none |
| Configuration generics: | _MEM_INT_IMEM_EN_ | implement processor-internal IMEM when _true_
| | _MEM_INT_IMEM_SIZE_ | IMEM size in bytes
| | _INT_BOOTLOADER_EN_ | use internal bootlodaer when _true_ (implements IMEM as _uninitialized_ RAM)
| | _INT_BOOTLOADER_EN_ | use internal bootloader when _true_ (implements IMEM as _uninitialized_ RAM)
| CPU interrupts: | none |
|=======================
 
/docs/datasheet/soc_pwm.adoc
43,7 → 43,7
 
The base frequency of the generated PWM signals is defined by the PWM core clock. This clock is derived
from the main processor clock and divided by a prescaler via the 3-bit PWM_CTRL_PRSCx in the unit's control
register. The following prescalers are available:
register. The following pre-scalers are available:
 
.PWM prescaler configuration
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
/docs/datasheet/soc_spi.adoc
24,13 → 24,24
The unit provides 8 dedicated chip select signals via the top entity's `spi_csn_o` signal, which are
directly controlled by the SPI module (no additional GPIO required).
 
[NOTE]
The NEORV32 SPI module only supports _host mode_. Transmission are initiated only by the processor's SPI module
(and not by an external SPI module).
 
The SPI unit is enabled by setting the _SPI_CTRL_EN_ bit in the `CTRL` control register. No transfer can be initiated
and no interrupt request will be triggered if this bit is cleared. Furthermore, a transfer being in process
can be terminated at any time by clearing this bit.
 
[IMPORTANT]
Changes to the `CTRL` control register should be made only when the SPI module is idle as they directly effect
transmissions being in-progress.
 
[TIP]
A transmission can be terminated at any time by disabling the SPI module
by clearing the _SPI_CTRL_EN_ control register bit.
 
The data quantity to be transferred within a single transmission is defined via the _SPI_CTRL_SIZEx_ bits.
The SPI module supports 8-bit (`00`), 16-bit (`01`), 24-
bit (`10`) and 32-bit (`11`) transfers.
The SPI module supports 8-bit (`00`), 16-bit (`01`), 24-bit (`10`) and 32-bit (`11`) transfers.
 
A transmission is started when writing data to the `DATA` register. The data must be LSB-aligned. So if
the SPI transceiver is configured for less than 32-bit transfers data quantity, the transmit data must be placed
38,25 → 49,23
software should only actually process the amount of bits that were configured using _SPI_CTRL_SIZEx_ when
reading `DATA`.
 
The SPI controller features 8 dedicated chip-select lines. These lines are controlled via the control register's
_SPI_CTRL_CSx_ bits. When a specific _SPI_CTRL_CSx_ bit is **set**, the according chip-select line `spi_csn_o(x)`
goes **low** (low-active chip-select lines).
[NOTE]
The NEORV32 SPI module only support MSB-first mode. Data can be reversed before writing `DATA` (for TX) / after
reading `DATA` (for RX) to implement LSB-first transmissions. Note that in both cases data in ` DATA` still
needs to be LSB-aligned.
 
[IMPORTANT]
Changes to the `CTRL` control register should be made only when the SPI module is idle as they directly effect
transmissions being in-progress.
 
[TIP]
The actual transmission length is left to the user: after asserting chip-select an arbitrary amount of
transmission with arbitrary data quantity (_SPI_CTRL_SIZEx_) can be made before de-asserting chip-select again.
 
[NOTE]
The NEORV32 SPI module only supports _host mode_. Transmission are initiated only by the processor's SPI module
(and not by an external SPI module).
The SPI controller features 8 dedicated chip-select lines. These lines are controlled via the control register's
_SPI_CTRL_CSx_ bits. When a specific _SPI_CTRL_CSx_ bit is **set**, the according chip-select line `spi_csn_o(x)`
goes **low** (low-active chip-select lines).
 
[NOTE]
The NEORV32 SPI module only support MSB-first mode. Data can be reversed before writing `DATA` (for TX) / after
reading `DATA` (for RX) to provide LSB-first transmissions.
[TIP]
The dedicated SPI chip-select signals can be seen as _general purpose_ outputs. These are intended to control
the accessed device's chip-select signal but can also be use for controlling other shift register signals
(like data strobe or output-enables).
 
 
**SPI Clock Configuration**
/docs/datasheet/soc_sysinfo.adoc
47,7 → 47,6
| `0` | _SYSINFO_CPU_ZICSR_ | `Zicsr` extension (`I` sub-extension) available when set (via top's <<_cpu_extension_riscv_zicsr>> generic)
| `1` | _SYSINFO_CPU_ZIFENCEI_ | `Zifencei` extension (`I` sub-extension) available when set (via top's <<_cpu_extension_riscv_zifencei>> generic)
| `2` | _SYSINFO_CPU_ZMMUL_ | `Zmmul` extension (`M` sub-extension) available when set (via top's <<_cpu_extension_riscv_zmmul>> generic)
| `3` | _SYSINFO_CPU_ZBB_ | `Zbb` extension (`B` sub-extension) available when set (via top's <<_cpu_extension_riscv_zbb>> generic)
| `5` | _SYSINFO_CPU_ZFINX_ | `Zfinx` extension (`F` sub-/alternative-extension) available when set (via top's <<_cpu_extension_riscv_zfinx>> generic)
| `6` | _SYSINFO_CPU_ZXSCNT_ | Custom extension - _Small_ CPU counters: `[m]cycle` & `[m]instret` CSRs have less than 64-bit when set (via top's <<_cpu_cnt_width>> generic)
| `7` | _SYSINFO_CPU_ZXNOCNT_ | Custom extension - _NO_ CPU counters: `[m]cycle` & `[m]instret` CSRs are NOT available at all when set (via top's <<_cpu_cnt_width>> generic)
/docs/datasheet/soc_twi.adoc
46,6 → 46,10
* send STOP condition
* send (at least) one byte while also sampling one byte from the bus
 
[TIP]
A transmission can be terminated at any time by disabling the TWI module
by clearing the _TWI_CTRL_EN_ control register bit.
 
[IMPORTANT]
The serial clock (SCL) and the serial data (SDA) lines can only be actively driven low by the
controller. Hence, external pull-up resistors are required for these lines.
68,7 → 72,7
 
**Interrupt**
 
The TWI module provides a single interrupt to singal _idle state_ (= read for new transmission) to the CPU. Whenever TWI SPI module
The TWI module provides a single interrupt to signal _idle state_ (= read for new transmission) to the CPU. Whenever TWI SPI module
is currently idle (and enabled), the interrupt request is active. A pending interrupt request is cleared
by triggering a new TWI transmission or by disabling the device.
 
/docs/datasheet/soc_uart.adoc
38,7 → 38,7
 
**Theory of Operation**
 
UART0 is enabled by setting the _UART_CTRL_EN_ bit in the UART0 control register `CTRL`. The Baudrate
UART0 is enabled by setting the _UART_CTRL_EN_ bit in the UART0 control register `CTRL`. The Baud rate
is configured via a 12-bit _UART_CTRL_BAUDxx_ baud prescaler (`baud_prsc`) and a 3-bit _UART_CTRL_PRSCx_
clock prescaler (`clock_prescaler`) that scales the processor's primary clock (_f~main~_).
 
50,7 → 50,7
| Resulting `clock_prescaler` | 2 | 4 | 8 | 64 | 128 | 1024 | 2048 | 4096
|=======================
 
_**Baudrate**_ = (_f~main~[Hz]_ / `clock_prescaler`) / (`baud_prsc` + 1)
_**Baud rate**_ = (_f~main~[Hz]_ / `clock_prescaler`) / (`baud_prsc` + 1)
 
A new transmission is started by writing the data byte to be send to the lowest byte of the `DATA` register. The
transfer is completed when the _UART_CTRL_TX_BUSY_ control register flag returns to zero. A new received byte
58,7 → 58,11
(invalid stop bit) is indicated via the _UART_DATA_FERR_ flag in the `DATA` register. The flag is cleared by
reading the `DATA` register.
 
[TIP]
A transmission (RX or TX) can be terminated at any time by disabling the UART module
by clearing the _UART_CTRL_EN_ control register bit.
 
 
**RX and TX FIFOs**
 
UART0 provides optional FIFO buffers for the transmitter and the receiver. The _UART0_RX_FIFO_ generic defines
73,6 → 77,9
If the RX FIFO is already full and new data is received by the receiver unit, the _UART_DATA_OVERR_ flag
in the `DATA` register is set indicating an "overrun". This flag is cleared by reading the `DATA` register.
 
[NOTE]
In contrast to other FIFO-equipped peripherals, software **cannot** determine the UART's FIFO size configuration
by reading specific control register bits (simply because there are no bits left in the control register).
 
 
**Hardware Flow Control - RTS/CTS**
/docs/datasheet/soc_wdt.adoc
39,7 → 39,7
 
Whenever the internal timer overflows the watchdog executes one of two possible actions: Either a hard
processor reset is triggered or an interrupt is requested at CPU's fast interrupt channel #0. The
WDT_CTRL_MODE bit definess the action to be taken on an overflow: When cleared, the Watchdog will assert an
WDT_CTRL_MODE bit defines the action to be taken on an overflow: When cleared, the Watchdog will assert an
IRQ, when set the WDT will cause a system reset. The configured action can also be triggered manually at
any time by setting the _WDT_CTRL_FORCE_ bit. The watchdog is reset by setting the _WDT_CTRL_RESET_ bit.
 
/docs/datasheet/software.adoc
204,7 → 204,7
| `-lm` | Include/link with `math.h`.
| `-lc` | Search for the standard C library when linking.
| `-lgcc` | Make sure we have no unresolved references to internal GCC library subroutines.
| `-mno-fdiv` | Use builtin software functions for floating-point divisions and square roots (since the according instructions are not supported yet).
| `-mno-fdiv` | Use built-in software functions for floating-point divisions and square roots (since the according instructions are not supported yet).
| `-falign-functions=4` .4+| Force a 32-bit alignment of functions and labels (branch/jump/call targets). This increases performance as it simplifies instruction fetch when using the C extension. As a drawback this will also slightly increase the program code.
| `-falign-labels=4`
| `-falign-loops=4`
544,6 → 544,7
| **`ERROR_1`** | Your program is way too big for the internal processor’s instructions memory. Increase the memory size or reduce your application code.
| **`ERROR_2`** | This indicates a checksum error. Something went wrong during the transfer of the program image (upload via UART or loading from the external SPI flash). If the error was caused by a UART upload, just try it again. When the error was generated during a flash access, the stored image might be corrupted.
| **`ERROR_3`** | This error occurs if the attached SPI flash cannot be accessed. Make sure you have the right type of flash and that it is properly connected to the NEORV32 SPI port using chip select #0.
| **`ERR 0x???????? 0x???????? 0x????????`** | The bootloader encountered an exception during operation. This might be caused when it tries to access peripherals that were not implemented during synthesis. Example: executing `l` or `s` (SPI flash operations) without the SPI module beeing implemented.
|=======================
 
 
580,7 → 581,7
After the initial setup of the RTE, each entry in the trap handler's look-up table is initialized with a debug
handler, that outputs detailed hardware information via the **primary UART (UART0)** when triggered. This
is intended as a fall-back for debugging or for accidentally-triggered exceptions/interrupts.
For instance, an illegal instruction exception catched by the RTE debug handler might look like this in the UART0 output:
For instance, an illegal instruction exception caught by the RTE debug handler might look like this in the UART0 output:
 
[source]
----
/docs/figures/neorv32_boot_configurations.png Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/docs/figures/neorv32_processor.png Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/docs/references/riscv-privileged.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/docs/references/riscv-spec.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/docs/userguide/content.adoc
100,7 → 100,7
neorv32/sw/example/blink_led$ make check
----
 
This will test all the tools required for the generating NEORV32 executables.
This will test all the tools required for generating NEORV32 executables.
Everything is working fine if `Toolchain check OK` appears at the end.
 
 
272,7 → 272,7
 
To allow executables to be _actually executed_ on the NEORV32 Processor the configuration of the software framework
has to be aware to the hardware configuration. This guide focuses on the memory configuration. To enabled
certain CPU ISA festures refer to the <<_enabling_risc_v_cpu_extensions>> section.
certain CPU ISA features refer to the <<_enabling_risc_v_cpu_extensions>> section.
 
[TIP]
If you have **not** changed the _default_ memory configuration in section <<_general_hardware_setup>>
335,7 → 335,7
----
 
[start=3]
. We are using the `clean_all` taret to make sure everything is re-build.
. We are using the `clean_all` target to make sure everything is re-build.
. This will compile and link the application sources together with all the included libraries. At the end,
your application is transformed into an ELF file (`main.elf`). The _NEORV32 image generator_ (in `sw/image_gen`)
takes this file and creates a final executable. The makefile will show the resulting memory utilization and
569,7 → 569,7
. The easiest way of creating a _new_ software application project is to copy an _existing_ one. This will keep all
file dependencies. For example you can copy `sw/example/blink_led` to `sw/example/flux_capacitor`.
. If you want to place you application somewhere outside `sw/example` you need to adapt the application's makefile.
In the makefile you will find a variable that keeps the relative or absolute path to the NEORV32 repo home
In the makefile you will find a variable that keeps the relative or absolute path to the NEORV32 repository home
folder. Just modify this variable according to your new project's home location:
 
[source,makefile]
813,14 → 813,14
 
=== Custom Functions Subsystem
 
The https://stnolting.github.io/neorv32/#_custom_functions_subsystem_cfs[NEORV32 Custom Functions Subsystem]
is as "empty" template for a processor-internal module. It provides 32 32-bit memory-mapped interface
The NEORV32 https://stnolting.github.io/neorv32/#_custom_functions_subsystem_cfs[Custom Functions Subsystem] is
an "empty" template for a processor-internal module. It provides 32 32-bit memory-mapped interface
registers that can be used to communicate with any arbitrary custom design logic. The intentions of this
subsystem is to provide a simple base, where the user can concentrate on implementing the actual design logic
rather than taking care of the communication between the CPU/software and the design logic. The interface
registers are already allocated within the processor's address space and are supported by the software framework
via low-level hardware access mechanisms. Additionally, the CFS provides a direct pre-defined interrupt channel to
the CPU, which is also supported by the _NEORV32 runtime environment_.
the CPU, which is also supported by the NEORV32 runtime environment.
 
 
 
1258,7 → 1258,7
 
Testbench sources in `sim` (such as `sim/neorv32_tb.vhd` and `sim/uart_rx*.vhd`) use VUnit's VHDL libraries for testing
NEORV32 and peripherals.
The entrypoint for executing the tests is `sim/run.py`.
The entry-point for executing the tests is `sim/run.py`.
 
[source, bash]
----
/docs/attrs.adoc
2,7 → 2,7
: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.2
:revnumber: v1.6.3
:doctype: book
:sectnums:
:stem:
/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: 3320 bytes
-- Size: 3352 bytes
 
library ieee;
use ieee.std_logic_1164.all;
67,7 → 67,7
00000053 => x"00158593",
00000054 => x"ff5ff06f",
00000055 => x"00001597",
00000056 => x"c1c58593",
00000056 => x"c3c58593",
00000057 => x"80000617",
00000058 => x"f1c60613",
00000059 => x"80000697",
114,16 → 114,16
00000100 => x"b0050513",
00000101 => x"00112623",
00000102 => x"088000ef",
00000103 => x"718000ef",
00000103 => x"738000ef",
00000104 => x"00050c63",
00000105 => x"6c8000ef",
00000105 => x"6e8000ef",
00000106 => x"00001537",
00000107 => x"a6050513",
00000108 => x"118000ef",
00000107 => x"a8050513",
00000108 => x"134000ef",
00000109 => x"020000ef",
00000110 => x"00001537",
00000111 => x"a3c50513",
00000112 => x"108000ef",
00000111 => x"a5c50513",
00000112 => x"124000ef",
00000113 => x"00c12083",
00000114 => x"00100513",
00000115 => x"01010113",
133,14 → 133,14
00000119 => x"00000593",
00000120 => x"00112623",
00000121 => x"00812423",
00000122 => x"6dc000ef",
00000122 => x"6fc000ef",
00000123 => x"00000513",
00000124 => x"00150413",
00000125 => x"00000593",
00000126 => x"0ff57513",
00000127 => x"6c8000ef",
00000127 => x"6e8000ef",
00000128 => x"0c800513",
00000129 => x"148000ef",
00000129 => x"164000ef",
00000130 => x"00040513",
00000131 => x"fe5ff06f",
00000132 => x"fe802503",
147,700 → 147,708
00000133 => x"01255513",
00000134 => x"00157513",
00000135 => x"00008067",
00000136 => x"fa002023",
00000137 => x"fe002703",
00000138 => x"00151513",
00000139 => x"00000793",
00000140 => x"04a77463",
00000141 => x"000016b7",
00000142 => x"00000713",
00000143 => x"ffe68693",
00000144 => x"04f6e663",
00000145 => x"00367613",
00000146 => x"0035f593",
00000147 => x"fff78793",
00000148 => x"01461613",
00000149 => x"00c7e7b3",
00000150 => x"01659593",
00000151 => x"01871713",
00000152 => x"00b7e7b3",
00000153 => x"00e7e7b3",
00000154 => x"10000737",
00000155 => x"00e7e7b3",
00000156 => x"faf02023",
00000157 => x"00008067",
00000158 => x"00178793",
00000159 => x"01079793",
00000160 => x"40a70733",
00000161 => x"0107d793",
00000162 => x"fa9ff06f",
00000163 => x"ffe70513",
00000164 => x"0fd57513",
00000165 => x"00051a63",
00000166 => x"0037d793",
00000167 => x"00170713",
00000168 => x"0ff77713",
00000169 => x"f9dff06f",
00000170 => x"0017d793",
00000171 => x"ff1ff06f",
00000172 => x"00040737",
00000173 => x"fa002783",
00000174 => x"00e7f7b3",
00000175 => x"fe079ce3",
00000176 => x"faa02223",
00000177 => x"00008067",
00000178 => x"ff010113",
00000179 => x"00812423",
00000180 => x"01212023",
00000181 => x"00112623",
00000182 => x"00912223",
00000183 => x"00050413",
00000184 => x"00a00913",
00000185 => x"00044483",
00000186 => x"00140413",
00000187 => x"00049e63",
00000188 => x"00c12083",
00000189 => x"00812403",
00000190 => x"00412483",
00000191 => x"00012903",
00000192 => x"01010113",
00000193 => x"00008067",
00000194 => x"01249663",
00000195 => x"00d00513",
00000196 => x"fa1ff0ef",
00000197 => x"00048513",
00000198 => x"f99ff0ef",
00000199 => x"fc9ff06f",
00000200 => x"ff010113",
00000201 => x"c81026f3",
00000202 => x"c0102773",
00000203 => x"c81027f3",
00000204 => x"fed79ae3",
00000205 => x"00e12023",
00000206 => x"00f12223",
00000207 => x"00012503",
00000208 => x"00412583",
00000209 => x"01010113",
00000210 => x"00008067",
00000211 => x"fd010113",
00000212 => x"00a12623",
00000213 => x"fe002503",
00000214 => x"3e800593",
00000215 => x"02112623",
00000216 => x"02812423",
00000217 => x"02912223",
00000218 => x"03212023",
00000219 => x"01312e23",
00000220 => x"620000ef",
00000221 => x"00c12603",
00000222 => x"00000693",
00000223 => x"00000593",
00000224 => x"578000ef",
00000225 => x"00050413",
00000226 => x"00058993",
00000227 => x"f95ff0ef",
00000228 => x"00058913",
00000229 => x"00050493",
00000230 => x"f89ff0ef",
00000231 => x"00b96663",
00000232 => x"05259263",
00000233 => x"04a4f063",
00000234 => x"008484b3",
00000235 => x"0084b433",
00000236 => x"01390933",
00000237 => x"01240433",
00000238 => x"f69ff0ef",
00000239 => x"fe85eee3",
00000240 => x"00b41463",
00000241 => x"fe956ae3",
00000242 => x"02c12083",
00000243 => x"02812403",
00000244 => x"02412483",
00000245 => x"02012903",
00000246 => x"01c12983",
00000247 => x"03010113",
00000248 => x"00008067",
00000249 => x"01c99913",
00000250 => x"00445413",
00000251 => x"00896433",
00000252 => x"00040a63",
00000253 => x"00040863",
00000254 => x"fff40413",
00000255 => x"00000013",
00000256 => x"ff1ff06f",
00000257 => x"fc5ff06f",
00000258 => x"00000000",
00000259 => x"00000000",
00000260 => x"fc010113",
00000261 => x"02112e23",
00000262 => x"02512c23",
00000263 => x"02612a23",
00000264 => x"02712823",
00000265 => x"02a12623",
00000266 => x"02b12423",
00000267 => x"02c12223",
00000268 => x"02d12023",
00000269 => x"00e12e23",
00000270 => x"00f12c23",
00000271 => x"01012a23",
00000272 => x"01112823",
00000273 => x"01c12623",
00000274 => x"01d12423",
00000275 => x"01e12223",
00000276 => x"01f12023",
00000277 => x"34102773",
00000278 => x"34071073",
00000279 => x"342027f3",
00000280 => x"0807c863",
00000281 => x"00071683",
00000282 => x"00300593",
00000283 => x"0036f693",
00000284 => x"00270613",
00000285 => x"00b69463",
00000286 => x"00470613",
00000287 => x"34161073",
00000288 => x"00b00713",
00000289 => x"04f77a63",
00000290 => x"68c00793",
00000291 => x"000780e7",
00000292 => x"03c12083",
00000293 => x"03812283",
00000294 => x"03412303",
00000295 => x"03012383",
00000296 => x"02c12503",
00000297 => x"02812583",
00000298 => x"02412603",
00000299 => x"02012683",
00000300 => x"01c12703",
00000301 => x"01812783",
00000302 => x"01412803",
00000303 => x"01012883",
00000304 => x"00c12e03",
00000305 => x"00812e83",
00000306 => x"00412f03",
00000307 => x"00012f83",
00000308 => x"04010113",
00000309 => x"30200073",
00000310 => x"00001737",
00000311 => x"00279793",
00000312 => x"a7c70713",
00000313 => x"00e787b3",
00000314 => x"0007a783",
00000315 => x"00078067",
00000316 => x"80000737",
00000317 => x"ffd74713",
00000318 => x"00e787b3",
00000319 => x"01c00713",
00000320 => x"f8f764e3",
00000321 => x"00001737",
00000322 => x"00279793",
00000323 => x"aac70713",
00000324 => x"00e787b3",
00000325 => x"0007a783",
00000326 => x"00078067",
00000327 => x"800007b7",
00000328 => x"0007a783",
00000329 => x"f69ff06f",
00000330 => x"800007b7",
00000331 => x"0047a783",
00000332 => x"f5dff06f",
00000333 => x"800007b7",
00000334 => x"0087a783",
00000335 => x"f51ff06f",
00000336 => x"800007b7",
00000337 => x"00c7a783",
00000338 => x"f45ff06f",
00000339 => x"8101a783",
00000340 => x"f3dff06f",
00000341 => x"8141a783",
00000342 => x"f35ff06f",
00000343 => x"8181a783",
00000344 => x"f2dff06f",
00000345 => x"81c1a783",
00000346 => x"f25ff06f",
00000347 => x"8201a783",
00000348 => x"f1dff06f",
00000349 => x"8241a783",
00000350 => x"f15ff06f",
00000351 => x"8281a783",
00000352 => x"f0dff06f",
00000353 => x"82c1a783",
00000354 => x"f05ff06f",
00000355 => x"8301a783",
00000356 => x"efdff06f",
00000357 => x"8341a783",
00000358 => x"ef5ff06f",
00000359 => x"8381a783",
00000360 => x"eedff06f",
00000361 => x"83c1a783",
00000362 => x"ee5ff06f",
00000363 => x"8401a783",
00000364 => x"eddff06f",
00000365 => x"8441a783",
00000366 => x"ed5ff06f",
00000367 => x"8481a783",
00000368 => x"ecdff06f",
00000369 => x"84c1a783",
00000370 => x"ec5ff06f",
00000371 => x"8501a783",
00000372 => x"ebdff06f",
00000373 => x"8541a783",
00000374 => x"eb5ff06f",
00000375 => x"8581a783",
00000376 => x"eadff06f",
00000377 => x"85c1a783",
00000378 => x"ea5ff06f",
00000379 => x"8601a783",
00000380 => x"e9dff06f",
00000381 => x"8641a783",
00000382 => x"e95ff06f",
00000383 => x"8681a783",
00000384 => x"e8dff06f",
00000385 => x"86c1a783",
00000386 => x"e85ff06f",
00000387 => x"8701a783",
00000388 => x"e7dff06f",
00000389 => x"00000000",
00000390 => x"00000000",
00000391 => x"fe010113",
00000392 => x"01212823",
00000393 => x"00050913",
00000394 => x"00001537",
00000395 => x"00912a23",
00000396 => x"b2050513",
00000397 => x"000014b7",
00000398 => x"00812c23",
00000399 => x"01312623",
00000400 => x"00112e23",
00000401 => x"01c00413",
00000402 => x"c81ff0ef",
00000403 => x"ce848493",
00000404 => x"ffc00993",
00000405 => x"008957b3",
00000406 => x"00f7f793",
00000407 => x"00f487b3",
00000408 => x"0007c503",
00000409 => x"ffc40413",
00000410 => x"c49ff0ef",
00000411 => x"ff3414e3",
00000412 => x"01c12083",
00000413 => x"01812403",
00000414 => x"01412483",
00000415 => x"01012903",
00000416 => x"00c12983",
00000417 => x"02010113",
00000418 => x"00008067",
00000419 => x"ff010113",
00000420 => x"00112623",
00000421 => x"00812423",
00000422 => x"00912223",
00000423 => x"b75ff0ef",
00000424 => x"18050463",
00000425 => x"00001537",
00000426 => x"b2450513",
00000427 => x"c1dff0ef",
00000428 => x"34202473",
00000429 => x"00900713",
00000430 => x"00f47793",
00000431 => x"03078493",
00000432 => x"00f77463",
00000433 => x"05778493",
00000434 => x"00b00793",
00000435 => x"0087ee63",
00000436 => x"00001737",
00000437 => x"00241793",
00000438 => x"cb870713",
00000439 => x"00e787b3",
00000440 => x"0007a783",
00000441 => x"00078067",
00000442 => x"800007b7",
00000443 => x"00b78713",
00000444 => x"12e40663",
00000445 => x"02876663",
00000446 => x"00378713",
00000447 => x"10e40463",
00000448 => x"00778793",
00000449 => x"10f40663",
00000450 => x"00001537",
00000451 => x"c8450513",
00000452 => x"bb9ff0ef",
00000453 => x"00040513",
00000454 => x"f05ff0ef",
00000455 => x"0380006f",
00000456 => x"ff07c793",
00000457 => x"00f407b3",
00000458 => x"00f00713",
00000459 => x"fcf76ee3",
00000460 => x"00001537",
00000461 => x"c7450513",
00000462 => x"b91ff0ef",
00000463 => x"00048513",
00000464 => x"b71ff0ef",
00000465 => x"0100006f",
00000466 => x"00001537",
00000467 => x"b2c50513",
00000468 => x"b79ff0ef",
00000469 => x"00001537",
00000470 => x"c9c50513",
00000471 => x"b6dff0ef",
00000472 => x"34002573",
00000473 => x"eb9ff0ef",
00000136 => x"ff010113",
00000137 => x"00812423",
00000138 => x"00912223",
00000139 => x"00112623",
00000140 => x"fa002023",
00000141 => x"fe002783",
00000142 => x"00058413",
00000143 => x"00151593",
00000144 => x"00078513",
00000145 => x"00060493",
00000146 => x"768000ef",
00000147 => x"01051513",
00000148 => x"000017b7",
00000149 => x"01055513",
00000150 => x"00000713",
00000151 => x"ffe78793",
00000152 => x"04a7e463",
00000153 => x"0034f793",
00000154 => x"00347413",
00000155 => x"fff50513",
00000156 => x"01479793",
00000157 => x"01641413",
00000158 => x"00f567b3",
00000159 => x"0087e7b3",
00000160 => x"01871713",
00000161 => x"00c12083",
00000162 => x"00812403",
00000163 => x"00e7e7b3",
00000164 => x"10000737",
00000165 => x"00e7e7b3",
00000166 => x"faf02023",
00000167 => x"00412483",
00000168 => x"01010113",
00000169 => x"00008067",
00000170 => x"ffe70693",
00000171 => x"0fd6f693",
00000172 => x"00069a63",
00000173 => x"00355513",
00000174 => x"00170713",
00000175 => x"0ff77713",
00000176 => x"fa1ff06f",
00000177 => x"00155513",
00000178 => x"ff1ff06f",
00000179 => x"00040737",
00000180 => x"fa002783",
00000181 => x"00e7f7b3",
00000182 => x"fe079ce3",
00000183 => x"faa02223",
00000184 => x"00008067",
00000185 => x"ff010113",
00000186 => x"00812423",
00000187 => x"01212023",
00000188 => x"00112623",
00000189 => x"00912223",
00000190 => x"00050413",
00000191 => x"00a00913",
00000192 => x"00044483",
00000193 => x"00140413",
00000194 => x"00049e63",
00000195 => x"00c12083",
00000196 => x"00812403",
00000197 => x"00412483",
00000198 => x"00012903",
00000199 => x"01010113",
00000200 => x"00008067",
00000201 => x"01249663",
00000202 => x"00d00513",
00000203 => x"fa1ff0ef",
00000204 => x"00048513",
00000205 => x"f99ff0ef",
00000206 => x"fc9ff06f",
00000207 => x"ff010113",
00000208 => x"c81026f3",
00000209 => x"c0102773",
00000210 => x"c81027f3",
00000211 => x"fed79ae3",
00000212 => x"00e12023",
00000213 => x"00f12223",
00000214 => x"00012503",
00000215 => x"00412583",
00000216 => x"01010113",
00000217 => x"00008067",
00000218 => x"fd010113",
00000219 => x"00a12623",
00000220 => x"fe002503",
00000221 => x"3e800593",
00000222 => x"02112623",
00000223 => x"02812423",
00000224 => x"02912223",
00000225 => x"03212023",
00000226 => x"01312e23",
00000227 => x"624000ef",
00000228 => x"00c12603",
00000229 => x"00000693",
00000230 => x"00000593",
00000231 => x"57c000ef",
00000232 => x"00050413",
00000233 => x"00058993",
00000234 => x"f95ff0ef",
00000235 => x"00058913",
00000236 => x"00050493",
00000237 => x"f89ff0ef",
00000238 => x"00b96663",
00000239 => x"05259263",
00000240 => x"04a4f063",
00000241 => x"008484b3",
00000242 => x"0084b433",
00000243 => x"01390933",
00000244 => x"01240433",
00000245 => x"f69ff0ef",
00000246 => x"fe85eee3",
00000247 => x"00b41463",
00000248 => x"fe956ae3",
00000249 => x"02c12083",
00000250 => x"02812403",
00000251 => x"02412483",
00000252 => x"02012903",
00000253 => x"01c12983",
00000254 => x"03010113",
00000255 => x"00008067",
00000256 => x"01c99913",
00000257 => x"00445413",
00000258 => x"00896433",
00000259 => x"00040a63",
00000260 => x"00040863",
00000261 => x"fff40413",
00000262 => x"00000013",
00000263 => x"ff1ff06f",
00000264 => x"fc5ff06f",
00000265 => x"00000000",
00000266 => x"00000000",
00000267 => x"00000000",
00000268 => x"fc010113",
00000269 => x"02112e23",
00000270 => x"02512c23",
00000271 => x"02612a23",
00000272 => x"02712823",
00000273 => x"02a12623",
00000274 => x"02b12423",
00000275 => x"02c12223",
00000276 => x"02d12023",
00000277 => x"00e12e23",
00000278 => x"00f12c23",
00000279 => x"01012a23",
00000280 => x"01112823",
00000281 => x"01c12623",
00000282 => x"01d12423",
00000283 => x"01e12223",
00000284 => x"01f12023",
00000285 => x"34102773",
00000286 => x"34071073",
00000287 => x"342027f3",
00000288 => x"0807c863",
00000289 => x"00071683",
00000290 => x"00300593",
00000291 => x"0036f693",
00000292 => x"00270613",
00000293 => x"00b69463",
00000294 => x"00470613",
00000295 => x"34161073",
00000296 => x"00b00713",
00000297 => x"04f77a63",
00000298 => x"6ac00793",
00000299 => x"000780e7",
00000300 => x"03c12083",
00000301 => x"03812283",
00000302 => x"03412303",
00000303 => x"03012383",
00000304 => x"02c12503",
00000305 => x"02812583",
00000306 => x"02412603",
00000307 => x"02012683",
00000308 => x"01c12703",
00000309 => x"01812783",
00000310 => x"01412803",
00000311 => x"01012883",
00000312 => x"00c12e03",
00000313 => x"00812e83",
00000314 => x"00412f03",
00000315 => x"00012f83",
00000316 => x"04010113",
00000317 => x"30200073",
00000318 => x"00001737",
00000319 => x"00279793",
00000320 => x"a9c70713",
00000321 => x"00e787b3",
00000322 => x"0007a783",
00000323 => x"00078067",
00000324 => x"80000737",
00000325 => x"ffd74713",
00000326 => x"00e787b3",
00000327 => x"01c00713",
00000328 => x"f8f764e3",
00000329 => x"00001737",
00000330 => x"00279793",
00000331 => x"acc70713",
00000332 => x"00e787b3",
00000333 => x"0007a783",
00000334 => x"00078067",
00000335 => x"800007b7",
00000336 => x"0007a783",
00000337 => x"f69ff06f",
00000338 => x"800007b7",
00000339 => x"0047a783",
00000340 => x"f5dff06f",
00000341 => x"800007b7",
00000342 => x"0087a783",
00000343 => x"f51ff06f",
00000344 => x"800007b7",
00000345 => x"00c7a783",
00000346 => x"f45ff06f",
00000347 => x"8101a783",
00000348 => x"f3dff06f",
00000349 => x"8141a783",
00000350 => x"f35ff06f",
00000351 => x"8181a783",
00000352 => x"f2dff06f",
00000353 => x"81c1a783",
00000354 => x"f25ff06f",
00000355 => x"8201a783",
00000356 => x"f1dff06f",
00000357 => x"8241a783",
00000358 => x"f15ff06f",
00000359 => x"8281a783",
00000360 => x"f0dff06f",
00000361 => x"82c1a783",
00000362 => x"f05ff06f",
00000363 => x"8301a783",
00000364 => x"efdff06f",
00000365 => x"8341a783",
00000366 => x"ef5ff06f",
00000367 => x"8381a783",
00000368 => x"eedff06f",
00000369 => x"83c1a783",
00000370 => x"ee5ff06f",
00000371 => x"8401a783",
00000372 => x"eddff06f",
00000373 => x"8441a783",
00000374 => x"ed5ff06f",
00000375 => x"8481a783",
00000376 => x"ecdff06f",
00000377 => x"84c1a783",
00000378 => x"ec5ff06f",
00000379 => x"8501a783",
00000380 => x"ebdff06f",
00000381 => x"8541a783",
00000382 => x"eb5ff06f",
00000383 => x"8581a783",
00000384 => x"eadff06f",
00000385 => x"85c1a783",
00000386 => x"ea5ff06f",
00000387 => x"8601a783",
00000388 => x"e9dff06f",
00000389 => x"8641a783",
00000390 => x"e95ff06f",
00000391 => x"8681a783",
00000392 => x"e8dff06f",
00000393 => x"86c1a783",
00000394 => x"e85ff06f",
00000395 => x"8701a783",
00000396 => x"e7dff06f",
00000397 => x"00000000",
00000398 => x"00000000",
00000399 => x"fe010113",
00000400 => x"01212823",
00000401 => x"00050913",
00000402 => x"00001537",
00000403 => x"00912a23",
00000404 => x"b4050513",
00000405 => x"000014b7",
00000406 => x"00812c23",
00000407 => x"01312623",
00000408 => x"00112e23",
00000409 => x"01c00413",
00000410 => x"c7dff0ef",
00000411 => x"d0848493",
00000412 => x"ffc00993",
00000413 => x"008957b3",
00000414 => x"00f7f793",
00000415 => x"00f487b3",
00000416 => x"0007c503",
00000417 => x"ffc40413",
00000418 => x"c45ff0ef",
00000419 => x"ff3414e3",
00000420 => x"01c12083",
00000421 => x"01812403",
00000422 => x"01412483",
00000423 => x"01012903",
00000424 => x"00c12983",
00000425 => x"02010113",
00000426 => x"00008067",
00000427 => x"ff010113",
00000428 => x"00112623",
00000429 => x"00812423",
00000430 => x"00912223",
00000431 => x"b55ff0ef",
00000432 => x"18050463",
00000433 => x"00001537",
00000434 => x"b4450513",
00000435 => x"c19ff0ef",
00000436 => x"34202473",
00000437 => x"00900713",
00000438 => x"00f47793",
00000439 => x"03078493",
00000440 => x"00f77463",
00000441 => x"05778493",
00000442 => x"00b00793",
00000443 => x"0087ee63",
00000444 => x"00001737",
00000445 => x"00241793",
00000446 => x"cd870713",
00000447 => x"00e787b3",
00000448 => x"0007a783",
00000449 => x"00078067",
00000450 => x"800007b7",
00000451 => x"00b78713",
00000452 => x"12e40663",
00000453 => x"02876663",
00000454 => x"00378713",
00000455 => x"10e40463",
00000456 => x"00778793",
00000457 => x"10f40663",
00000458 => x"00001537",
00000459 => x"ca450513",
00000460 => x"bb5ff0ef",
00000461 => x"00040513",
00000462 => x"f05ff0ef",
00000463 => x"0380006f",
00000464 => x"ff07c793",
00000465 => x"00f407b3",
00000466 => x"00f00713",
00000467 => x"fcf76ee3",
00000468 => x"00001537",
00000469 => x"c9450513",
00000470 => x"b8dff0ef",
00000471 => x"00048513",
00000472 => x"b6dff0ef",
00000473 => x"0100006f",
00000474 => x"00001537",
00000475 => x"ca450513",
00000476 => x"b59ff0ef",
00000477 => x"34302573",
00000478 => x"ea5ff0ef",
00000479 => x"00812403",
00000480 => x"00c12083",
00000481 => x"00412483",
00000475 => x"b4c50513",
00000476 => x"b75ff0ef",
00000477 => x"00001537",
00000478 => x"cbc50513",
00000479 => x"b69ff0ef",
00000480 => x"34002573",
00000481 => x"eb9ff0ef",
00000482 => x"00001537",
00000483 => x"cb050513",
00000484 => x"01010113",
00000485 => x"b35ff06f",
00000486 => x"00001537",
00000487 => x"b4c50513",
00000488 => x"fb1ff06f",
00000489 => x"00001537",
00000490 => x"b6850513",
00000491 => x"fa5ff06f",
00000492 => x"00001537",
00000493 => x"b7c50513",
00000494 => x"f99ff06f",
00000495 => x"00001537",
00000496 => x"b8850513",
00000497 => x"f8dff06f",
00000498 => x"00001537",
00000499 => x"ba050513",
00000500 => x"f81ff06f",
00000501 => x"00001537",
00000502 => x"bb450513",
00000503 => x"f75ff06f",
00000504 => x"00001537",
00000505 => x"bd050513",
00000506 => x"f69ff06f",
00000507 => x"00001537",
00000508 => x"be450513",
00000509 => x"f5dff06f",
00000510 => x"00001537",
00000511 => x"c0450513",
00000512 => x"f51ff06f",
00000513 => x"00001537",
00000514 => x"c2450513",
00000515 => x"f45ff06f",
00000516 => x"00001537",
00000517 => x"c4050513",
00000518 => x"f39ff06f",
00000519 => x"00001537",
00000520 => x"c5850513",
00000521 => x"f2dff06f",
00000522 => x"00c12083",
00000523 => x"00812403",
00000524 => x"00412483",
00000525 => x"01010113",
00000526 => x"00008067",
00000527 => x"01f00793",
00000528 => x"02a7e263",
00000529 => x"800007b7",
00000530 => x"00078793",
00000531 => x"00251513",
00000532 => x"00a78533",
00000533 => x"68c00793",
00000534 => x"00f52023",
00000535 => x"00000513",
00000536 => x"00008067",
00000537 => x"00100513",
00000538 => x"00008067",
00000539 => x"ff010113",
00000540 => x"00112623",
00000541 => x"00812423",
00000542 => x"00912223",
00000543 => x"41000793",
00000544 => x"30579073",
00000545 => x"00000413",
00000546 => x"01d00493",
00000547 => x"00040513",
00000548 => x"00140413",
00000549 => x"0ff47413",
00000550 => x"fa5ff0ef",
00000551 => x"fe9418e3",
00000552 => x"00c12083",
00000553 => x"00812403",
00000554 => x"00412483",
00000555 => x"01010113",
00000556 => x"00008067",
00000557 => x"fe802503",
00000558 => x"01055513",
00000559 => x"00157513",
00000560 => x"00008067",
00000561 => x"fc000793",
00000562 => x"00a7a423",
00000563 => x"00b7a623",
00000483 => x"cc450513",
00000484 => x"b55ff0ef",
00000485 => x"34302573",
00000486 => x"ea5ff0ef",
00000487 => x"00812403",
00000488 => x"00c12083",
00000489 => x"00412483",
00000490 => x"00001537",
00000491 => x"cd050513",
00000492 => x"01010113",
00000493 => x"b31ff06f",
00000494 => x"00001537",
00000495 => x"b6c50513",
00000496 => x"fb1ff06f",
00000497 => x"00001537",
00000498 => x"b8850513",
00000499 => x"fa5ff06f",
00000500 => x"00001537",
00000501 => x"b9c50513",
00000502 => x"f99ff06f",
00000503 => x"00001537",
00000504 => x"ba850513",
00000505 => x"f8dff06f",
00000506 => x"00001537",
00000507 => x"bc050513",
00000508 => x"f81ff06f",
00000509 => x"00001537",
00000510 => x"bd450513",
00000511 => x"f75ff06f",
00000512 => x"00001537",
00000513 => x"bf050513",
00000514 => x"f69ff06f",
00000515 => x"00001537",
00000516 => x"c0450513",
00000517 => x"f5dff06f",
00000518 => x"00001537",
00000519 => x"c2450513",
00000520 => x"f51ff06f",
00000521 => x"00001537",
00000522 => x"c4450513",
00000523 => x"f45ff06f",
00000524 => x"00001537",
00000525 => x"c6050513",
00000526 => x"f39ff06f",
00000527 => x"00001537",
00000528 => x"c7850513",
00000529 => x"f2dff06f",
00000530 => x"00c12083",
00000531 => x"00812403",
00000532 => x"00412483",
00000533 => x"01010113",
00000534 => x"00008067",
00000535 => x"01f00793",
00000536 => x"02a7e263",
00000537 => x"800007b7",
00000538 => x"00078793",
00000539 => x"00251513",
00000540 => x"00a78533",
00000541 => x"6ac00793",
00000542 => x"00f52023",
00000543 => x"00000513",
00000544 => x"00008067",
00000545 => x"00100513",
00000546 => x"00008067",
00000547 => x"ff010113",
00000548 => x"00112623",
00000549 => x"00812423",
00000550 => x"00912223",
00000551 => x"43000793",
00000552 => x"30579073",
00000553 => x"00000413",
00000554 => x"01d00493",
00000555 => x"00040513",
00000556 => x"00140413",
00000557 => x"0ff47413",
00000558 => x"fa5ff0ef",
00000559 => x"fe9418e3",
00000560 => x"00c12083",
00000561 => x"00812403",
00000562 => x"00412483",
00000563 => x"01010113",
00000564 => x"00008067",
00000565 => x"00050613",
00000566 => x"00000513",
00000567 => x"0015f693",
00000568 => x"00068463",
00000569 => x"00c50533",
00000570 => x"0015d593",
00000571 => x"00161613",
00000572 => x"fe0596e3",
00000573 => x"00008067",
00000574 => x"00050313",
00000575 => x"ff010113",
00000576 => x"00060513",
00000577 => x"00068893",
00000578 => x"00112623",
00000579 => x"00030613",
00000580 => x"00050693",
00000581 => x"00000713",
00000582 => x"00000793",
00000583 => x"00000813",
00000584 => x"0016fe13",
00000585 => x"00171e93",
00000586 => x"000e0c63",
00000587 => x"01060e33",
00000588 => x"010e3833",
00000589 => x"00e787b3",
00000590 => x"00f807b3",
00000591 => x"000e0813",
00000592 => x"01f65713",
00000593 => x"0016d693",
00000594 => x"00eee733",
00000595 => x"00161613",
00000596 => x"fc0698e3",
00000597 => x"00058663",
00000598 => x"f7dff0ef",
00000599 => x"00a787b3",
00000600 => x"00088a63",
00000601 => x"00030513",
00000602 => x"00088593",
00000603 => x"f69ff0ef",
00000604 => x"00f507b3",
00000605 => x"00c12083",
00000606 => x"00080513",
00000607 => x"00078593",
00000608 => x"01010113",
00000609 => x"00008067",
00000610 => x"06054063",
00000611 => x"0605c663",
00000612 => x"00058613",
00000613 => x"00050593",
00000614 => x"fff00513",
00000615 => x"02060c63",
00000616 => x"00100693",
00000617 => x"00b67a63",
00000618 => x"00c05863",
00000619 => x"00161613",
00000620 => x"00169693",
00000621 => x"feb66ae3",
00000622 => x"00000513",
00000623 => x"00c5e663",
00000624 => x"40c585b3",
00000625 => x"00d56533",
00000626 => x"0016d693",
00000627 => x"00165613",
00000628 => x"fe0696e3",
00000629 => x"00008067",
00000630 => x"00008293",
00000631 => x"fb5ff0ef",
00000632 => x"00058513",
00000633 => x"00028067",
00000634 => x"40a00533",
00000635 => x"00b04863",
00000636 => x"40b005b3",
00000637 => x"f9dff06f",
00000638 => x"40b005b3",
00000639 => x"00008293",
00000640 => x"f91ff0ef",
00000641 => x"40a00533",
00000642 => x"00028067",
00000643 => x"00008293",
00000644 => x"0005ca63",
00000645 => x"00054c63",
00000646 => x"f79ff0ef",
00000647 => x"00058513",
00000648 => x"00028067",
00000649 => x"40b005b3",
00000650 => x"fe0558e3",
00000651 => x"40a00533",
00000652 => x"f61ff0ef",
00000653 => x"40b00533",
00000654 => x"00028067",
00000655 => x"6f727245",
00000656 => x"4e202172",
00000657 => x"5047206f",
00000658 => x"75204f49",
00000659 => x"2074696e",
00000660 => x"746e7973",
00000661 => x"69736568",
00000662 => x"2164657a",
00000663 => x"0000000a",
00000664 => x"6e696c42",
00000665 => x"676e696b",
00000666 => x"44454c20",
00000667 => x"6d656420",
00000668 => x"7270206f",
00000669 => x"6172676f",
00000670 => x"00000a6d",
00000671 => x"0000051c",
00000672 => x"00000528",
00000673 => x"00000534",
00000674 => x"00000540",
00000675 => x"0000054c",
00000676 => x"00000554",
00000677 => x"0000055c",
00000678 => x"00000564",
00000679 => x"0000056c",
00000680 => x"00000488",
00000681 => x"00000488",
00000682 => x"00000574",
00000683 => x"0000057c",
00000684 => x"00000488",
00000685 => x"00000488",
00000686 => x"00000488",
00000687 => x"00000584",
00000688 => x"00000488",
00000689 => x"00000488",
00000690 => x"00000488",
00000691 => x"0000058c",
00000692 => x"00000488",
00000693 => x"00000488",
00000694 => x"00000488",
00000695 => x"00000488",
00000696 => x"00000594",
00000697 => x"0000059c",
00000698 => x"000005a4",
00000565 => x"fe802503",
00000566 => x"01055513",
00000567 => x"00157513",
00000568 => x"00008067",
00000569 => x"fc000793",
00000570 => x"00a7a423",
00000571 => x"00b7a623",
00000572 => x"00008067",
00000573 => x"00050613",
00000574 => x"00000513",
00000575 => x"0015f693",
00000576 => x"00068463",
00000577 => x"00c50533",
00000578 => x"0015d593",
00000579 => x"00161613",
00000580 => x"fe0596e3",
00000581 => x"00008067",
00000582 => x"00050313",
00000583 => x"ff010113",
00000584 => x"00060513",
00000585 => x"00068893",
00000586 => x"00112623",
00000587 => x"00030613",
00000588 => x"00050693",
00000589 => x"00000713",
00000590 => x"00000793",
00000591 => x"00000813",
00000592 => x"0016fe13",
00000593 => x"00171e93",
00000594 => x"000e0c63",
00000595 => x"01060e33",
00000596 => x"010e3833",
00000597 => x"00e787b3",
00000598 => x"00f807b3",
00000599 => x"000e0813",
00000600 => x"01f65713",
00000601 => x"0016d693",
00000602 => x"00eee733",
00000603 => x"00161613",
00000604 => x"fc0698e3",
00000605 => x"00058663",
00000606 => x"f7dff0ef",
00000607 => x"00a787b3",
00000608 => x"00088a63",
00000609 => x"00030513",
00000610 => x"00088593",
00000611 => x"f69ff0ef",
00000612 => x"00f507b3",
00000613 => x"00c12083",
00000614 => x"00080513",
00000615 => x"00078593",
00000616 => x"01010113",
00000617 => x"00008067",
00000618 => x"06054063",
00000619 => x"0605c663",
00000620 => x"00058613",
00000621 => x"00050593",
00000622 => x"fff00513",
00000623 => x"02060c63",
00000624 => x"00100693",
00000625 => x"00b67a63",
00000626 => x"00c05863",
00000627 => x"00161613",
00000628 => x"00169693",
00000629 => x"feb66ae3",
00000630 => x"00000513",
00000631 => x"00c5e663",
00000632 => x"40c585b3",
00000633 => x"00d56533",
00000634 => x"0016d693",
00000635 => x"00165613",
00000636 => x"fe0696e3",
00000637 => x"00008067",
00000638 => x"00008293",
00000639 => x"fb5ff0ef",
00000640 => x"00058513",
00000641 => x"00028067",
00000642 => x"40a00533",
00000643 => x"00b04863",
00000644 => x"40b005b3",
00000645 => x"f9dff06f",
00000646 => x"40b005b3",
00000647 => x"00008293",
00000648 => x"f91ff0ef",
00000649 => x"40a00533",
00000650 => x"00028067",
00000651 => x"00008293",
00000652 => x"0005ca63",
00000653 => x"00054c63",
00000654 => x"f79ff0ef",
00000655 => x"00058513",
00000656 => x"00028067",
00000657 => x"40b005b3",
00000658 => x"fe0558e3",
00000659 => x"40a00533",
00000660 => x"f61ff0ef",
00000661 => x"40b00533",
00000662 => x"00028067",
00000663 => x"6f727245",
00000664 => x"4e202172",
00000665 => x"5047206f",
00000666 => x"75204f49",
00000667 => x"2074696e",
00000668 => x"746e7973",
00000669 => x"69736568",
00000670 => x"2164657a",
00000671 => x"0000000a",
00000672 => x"6e696c42",
00000673 => x"676e696b",
00000674 => x"44454c20",
00000675 => x"6d656420",
00000676 => x"7270206f",
00000677 => x"6172676f",
00000678 => x"00000a6d",
00000679 => x"0000053c",
00000680 => x"00000548",
00000681 => x"00000554",
00000682 => x"00000560",
00000683 => x"0000056c",
00000684 => x"00000574",
00000685 => x"0000057c",
00000686 => x"00000584",
00000687 => x"0000058c",
00000688 => x"000004a8",
00000689 => x"000004a8",
00000690 => x"00000594",
00000691 => x"0000059c",
00000692 => x"000004a8",
00000693 => x"000004a8",
00000694 => x"000004a8",
00000695 => x"000005a4",
00000696 => x"000004a8",
00000697 => x"000004a8",
00000698 => x"000004a8",
00000699 => x"000005ac",
00000700 => x"000005b4",
00000701 => x"000005bc",
00000702 => x"000005c4",
00000703 => x"000005cc",
00000704 => x"000005d4",
00000705 => x"000005dc",
00000706 => x"000005e4",
00000707 => x"000005ec",
00000708 => x"000005f4",
00000709 => x"000005fc",
00000710 => x"00000604",
00000711 => x"0000060c",
00000712 => x"00007830",
00000713 => x"4554523c",
00000714 => x"0000203e",
00000715 => x"74736e49",
00000716 => x"74637572",
00000717 => x"206e6f69",
00000718 => x"72646461",
00000719 => x"20737365",
00000720 => x"6173696d",
00000721 => x"6e67696c",
00000722 => x"00006465",
00000700 => x"000004a8",
00000701 => x"000004a8",
00000702 => x"000004a8",
00000703 => x"000004a8",
00000704 => x"000005b4",
00000705 => x"000005bc",
00000706 => x"000005c4",
00000707 => x"000005cc",
00000708 => x"000005d4",
00000709 => x"000005dc",
00000710 => x"000005e4",
00000711 => x"000005ec",
00000712 => x"000005f4",
00000713 => x"000005fc",
00000714 => x"00000604",
00000715 => x"0000060c",
00000716 => x"00000614",
00000717 => x"0000061c",
00000718 => x"00000624",
00000719 => x"0000062c",
00000720 => x"00007830",
00000721 => x"4554523c",
00000722 => x"0000203e",
00000723 => x"74736e49",
00000724 => x"74637572",
00000725 => x"206e6f69",
00000726 => x"65636361",
00000727 => x"66207373",
00000728 => x"746c7561",
00000729 => x"00000000",
00000730 => x"656c6c49",
00000731 => x"206c6167",
00000732 => x"74736e69",
00000733 => x"74637572",
00000734 => x"006e6f69",
00000735 => x"61657242",
00000736 => x"696f706b",
00000737 => x"0000746e",
00000738 => x"64616f4c",
00000739 => x"64646120",
00000740 => x"73736572",
00000741 => x"73696d20",
00000742 => x"67696c61",
00000743 => x"0064656e",
00000744 => x"64616f4c",
00000745 => x"63636120",
00000746 => x"20737365",
00000747 => x"6c756166",
00000748 => x"00000074",
00000749 => x"726f7453",
00000750 => x"64612065",
00000751 => x"73657264",
00000752 => x"696d2073",
00000753 => x"696c6173",
00000754 => x"64656e67",
00000755 => x"00000000",
00000756 => x"726f7453",
00000757 => x"63612065",
00000758 => x"73736563",
00000759 => x"75616620",
00000760 => x"0000746c",
00000761 => x"69766e45",
00000762 => x"6d6e6f72",
00000763 => x"20746e65",
00000764 => x"6c6c6163",
00000765 => x"6f726620",
00000766 => x"2d55206d",
00000767 => x"65646f6d",
00000768 => x"00000000",
00000726 => x"72646461",
00000727 => x"20737365",
00000728 => x"6173696d",
00000729 => x"6e67696c",
00000730 => x"00006465",
00000731 => x"74736e49",
00000732 => x"74637572",
00000733 => x"206e6f69",
00000734 => x"65636361",
00000735 => x"66207373",
00000736 => x"746c7561",
00000737 => x"00000000",
00000738 => x"656c6c49",
00000739 => x"206c6167",
00000740 => x"74736e69",
00000741 => x"74637572",
00000742 => x"006e6f69",
00000743 => x"61657242",
00000744 => x"696f706b",
00000745 => x"0000746e",
00000746 => x"64616f4c",
00000747 => x"64646120",
00000748 => x"73736572",
00000749 => x"73696d20",
00000750 => x"67696c61",
00000751 => x"0064656e",
00000752 => x"64616f4c",
00000753 => x"63636120",
00000754 => x"20737365",
00000755 => x"6c756166",
00000756 => x"00000074",
00000757 => x"726f7453",
00000758 => x"64612065",
00000759 => x"73657264",
00000760 => x"696d2073",
00000761 => x"696c6173",
00000762 => x"64656e67",
00000763 => x"00000000",
00000764 => x"726f7453",
00000765 => x"63612065",
00000766 => x"73736563",
00000767 => x"75616620",
00000768 => x"0000746c",
00000769 => x"69766e45",
00000770 => x"6d6e6f72",
00000771 => x"20746e65",
00000772 => x"6c6c6163",
00000773 => x"6f726620",
00000774 => x"2d4d206d",
00000774 => x"2d55206d",
00000775 => x"65646f6d",
00000776 => x"00000000",
00000777 => x"6863614d",
00000778 => x"20656e69",
00000779 => x"74666f73",
00000780 => x"65726177",
00000781 => x"746e6920",
00000782 => x"75727265",
00000783 => x"00007470",
00000784 => x"6863614d",
00000785 => x"20656e69",
00000786 => x"656d6974",
00000787 => x"6e692072",
00000788 => x"72726574",
00000789 => x"00747075",
00000790 => x"6863614d",
00000791 => x"20656e69",
00000792 => x"65747865",
00000793 => x"6c616e72",
00000794 => x"746e6920",
00000795 => x"75727265",
00000796 => x"00007470",
00000797 => x"74736146",
00000798 => x"746e6920",
00000799 => x"75727265",
00000800 => x"00207470",
00000801 => x"6e6b6e55",
00000802 => x"206e776f",
00000803 => x"70617274",
00000804 => x"75616320",
00000805 => x"203a6573",
00000806 => x"00000000",
00000807 => x"50204020",
00000808 => x"00003d43",
00000809 => x"544d202c",
00000810 => x"3d4c4156",
00000811 => x"00000000",
00000812 => x"522f3c20",
00000813 => x"003e4554",
00000814 => x"00000748",
00000815 => x"00000798",
00000816 => x"000007a4",
00000817 => x"000007b0",
00000818 => x"000007bc",
00000819 => x"000007c8",
00000820 => x"000007d4",
00000821 => x"000007e0",
00000822 => x"000007ec",
00000823 => x"00000708",
00000824 => x"00000708",
00000825 => x"000007f8",
00000826 => x"33323130",
00000827 => x"37363534",
00000828 => x"42413938",
00000829 => x"46454443"
00000777 => x"69766e45",
00000778 => x"6d6e6f72",
00000779 => x"20746e65",
00000780 => x"6c6c6163",
00000781 => x"6f726620",
00000782 => x"2d4d206d",
00000783 => x"65646f6d",
00000784 => x"00000000",
00000785 => x"6863614d",
00000786 => x"20656e69",
00000787 => x"74666f73",
00000788 => x"65726177",
00000789 => x"746e6920",
00000790 => x"75727265",
00000791 => x"00007470",
00000792 => x"6863614d",
00000793 => x"20656e69",
00000794 => x"656d6974",
00000795 => x"6e692072",
00000796 => x"72726574",
00000797 => x"00747075",
00000798 => x"6863614d",
00000799 => x"20656e69",
00000800 => x"65747865",
00000801 => x"6c616e72",
00000802 => x"746e6920",
00000803 => x"75727265",
00000804 => x"00007470",
00000805 => x"74736146",
00000806 => x"746e6920",
00000807 => x"75727265",
00000808 => x"00207470",
00000809 => x"6e6b6e55",
00000810 => x"206e776f",
00000811 => x"70617274",
00000812 => x"75616320",
00000813 => x"203a6573",
00000814 => x"00000000",
00000815 => x"50204020",
00000816 => x"00003d43",
00000817 => x"544d202c",
00000818 => x"3d4c4156",
00000819 => x"00000000",
00000820 => x"522f3c20",
00000821 => x"003e4554",
00000822 => x"00000768",
00000823 => x"000007b8",
00000824 => x"000007c4",
00000825 => x"000007d0",
00000826 => x"000007dc",
00000827 => x"000007e8",
00000828 => x"000007f4",
00000829 => x"00000800",
00000830 => x"0000080c",
00000831 => x"00000728",
00000832 => x"00000728",
00000833 => x"00000818",
00000834 => x"33323130",
00000835 => x"37363534",
00000836 => x"42413938",
00000837 => x"46454443"
);
 
end neorv32_application_image;
/rtl/core/neorv32_bootloader_image.vhd
1,6 → 1,6
-- The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32
-- Auto-generated memory init file (for BOOTLOADER) from source file <bootloader/main.bin>
-- Size: 4088 bytes
-- Size: 4068 bytes
 
library ieee;
use ieee.std_logic_1164.all;
51,7 → 51,7
00000037 => x"00158593",
00000038 => x"ff5ff06f",
00000039 => x"00001597",
00000040 => x"f5c58593",
00000040 => x"f4858593",
00000041 => x"80010617",
00000042 => x"f5c60613",
00000043 => x"80010697",
105,33 → 105,33
00000091 => x"0007a023",
00000092 => x"8001a223",
00000093 => x"ffff07b7",
00000094 => x"4bc78793",
00000094 => x"4c478793",
00000095 => x"30579073",
00000096 => x"00000693",
00000097 => x"00000613",
00000098 => x"00000593",
00000099 => x"00200513",
00000100 => x"399000ef",
00000101 => x"42d000ef",
00000100 => x"385000ef",
00000101 => x"419000ef",
00000102 => x"00048493",
00000103 => x"00050863",
00000104 => x"00100513",
00000105 => x"00000593",
00000106 => x"459000ef",
00000106 => x"445000ef",
00000107 => x"00005537",
00000108 => x"00000613",
00000109 => x"00000593",
00000110 => x"b0050513",
00000111 => x"1f9000ef",
00000112 => x"1bd000ef",
00000111 => x"1f5000ef",
00000112 => x"1b9000ef",
00000113 => x"02050a63",
00000114 => x"325000ef",
00000114 => x"321000ef",
00000115 => x"fe002783",
00000116 => x"0027d793",
00000117 => x"00a78533",
00000118 => x"00f537b3",
00000119 => x"00b785b3",
00000120 => x"1ad000ef",
00000120 => x"1a9000ef",
00000121 => x"08000793",
00000122 => x"30479073",
00000123 => x"30046073",
138,78 → 138,78
00000124 => x"00000013",
00000125 => x"00000013",
00000126 => x"ffff1537",
00000127 => x"f2850513",
00000128 => x"295000ef",
00000127 => x"f1450513",
00000128 => x"291000ef",
00000129 => x"f1302573",
00000130 => x"244000ef",
00000130 => x"24c000ef",
00000131 => x"ffff1537",
00000132 => x"f6050513",
00000133 => x"281000ef",
00000132 => x"f4c50513",
00000133 => x"27d000ef",
00000134 => x"fe002503",
00000135 => x"230000ef",
00000135 => x"238000ef",
00000136 => x"ffff1537",
00000137 => x"f6850513",
00000138 => x"26d000ef",
00000137 => x"f5450513",
00000138 => x"269000ef",
00000139 => x"30102573",
00000140 => x"21c000ef",
00000140 => x"224000ef",
00000141 => x"ffff1537",
00000142 => x"f7050513",
00000143 => x"259000ef",
00000142 => x"f5c50513",
00000143 => x"255000ef",
00000144 => x"fe402503",
00000145 => x"ffff1437",
00000146 => x"204000ef",
00000146 => x"20c000ef",
00000147 => x"ffff1537",
00000148 => x"f7850513",
00000149 => x"241000ef",
00000148 => x"f6450513",
00000149 => x"23d000ef",
00000150 => x"fe802503",
00000151 => x"1f0000ef",
00000151 => x"1f8000ef",
00000152 => x"ffff1537",
00000153 => x"f8050513",
00000154 => x"22d000ef",
00000153 => x"f6c50513",
00000154 => x"229000ef",
00000155 => x"ff802503",
00000156 => x"1dc000ef",
00000157 => x"f8840513",
00000158 => x"21d000ef",
00000156 => x"1e4000ef",
00000157 => x"f7440513",
00000158 => x"219000ef",
00000159 => x"ff002503",
00000160 => x"1cc000ef",
00000160 => x"1d4000ef",
00000161 => x"ffff1537",
00000162 => x"f9450513",
00000163 => x"209000ef",
00000162 => x"f8050513",
00000163 => x"205000ef",
00000164 => x"ffc02503",
00000165 => x"1b8000ef",
00000166 => x"f8840513",
00000167 => x"1f9000ef",
00000165 => x"1c0000ef",
00000166 => x"f7440513",
00000167 => x"1f5000ef",
00000168 => x"ff402503",
00000169 => x"1a8000ef",
00000170 => x"0d5000ef",
00000169 => x"1b0000ef",
00000170 => x"0d1000ef",
00000171 => x"06050663",
00000172 => x"ffff1537",
00000173 => x"f9c50513",
00000174 => x"1dd000ef",
00000175 => x"231000ef",
00000173 => x"f8850513",
00000174 => x"1d9000ef",
00000175 => x"22d000ef",
00000176 => x"fe002403",
00000177 => x"00341413",
00000178 => x"00a40933",
00000179 => x"00893433",
00000180 => x"00b40433",
00000181 => x"0d1000ef",
00000181 => x"0cd000ef",
00000182 => x"02051663",
00000183 => x"211000ef",
00000183 => x"20d000ef",
00000184 => x"fe85eae3",
00000185 => x"00b41463",
00000186 => x"ff2566e3",
00000187 => x"00100513",
00000188 => x"4d4000ef",
00000188 => x"4dc000ef",
00000189 => x"ffff1537",
00000190 => x"fc450513",
00000191 => x"199000ef",
00000192 => x"0cc000ef",
00000193 => x"185000ef",
00000190 => x"fb050513",
00000191 => x"195000ef",
00000192 => x"0d4000ef",
00000193 => x"181000ef",
00000194 => x"fc050ae3",
00000195 => x"ffff1537",
00000196 => x"fc850513",
00000197 => x"181000ef",
00000198 => x"0a8000ef",
00000196 => x"fb450513",
00000197 => x"17d000ef",
00000198 => x"0b0000ef",
00000199 => x"ffff19b7",
00000200 => x"ffff1a37",
00000201 => x"07200a93",
218,821 → 218,816
00000204 => x"07300c13",
00000205 => x"ffff1937",
00000206 => x"ffff1cb7",
00000207 => x"fd498513",
00000208 => x"155000ef",
00000209 => x"135000ef",
00000207 => x"fc098513",
00000208 => x"151000ef",
00000209 => x"131000ef",
00000210 => x"00050413",
00000211 => x"0f9000ef",
00000212 => x"fc4a0513",
00000213 => x"141000ef",
00000214 => x"01541863",
00000215 => x"ffff02b7",
00000216 => x"00028067",
00000217 => x"fd9ff06f",
00000218 => x"01641663",
00000219 => x"054000ef",
00000220 => x"fcdff06f",
00000221 => x"00000513",
00000222 => x"01740e63",
00000223 => x"01841663",
00000224 => x"680000ef",
00000211 => x"0f5000ef",
00000212 => x"fb0a0513",
00000213 => x"13d000ef",
00000214 => x"101000ef",
00000215 => x"fe051ee3",
00000216 => x"01541863",
00000217 => x"ffff02b7",
00000218 => x"00028067",
00000219 => x"fd1ff06f",
00000220 => x"01641663",
00000221 => x"054000ef",
00000222 => x"fc5ff06f",
00000223 => x"01741663",
00000224 => x"44c000ef",
00000225 => x"fb9ff06f",
00000226 => x"06c00793",
00000227 => x"00f41863",
00000228 => x"00100513",
00000229 => x"430000ef",
00000230 => x"fa5ff06f",
00000231 => x"06500793",
00000232 => x"00f41c63",
00000233 => x"0004a783",
00000234 => x"f4079ce3",
00000235 => x"ed0c8513",
00000236 => x"0e5000ef",
00000237 => x"f89ff06f",
00000238 => x"fdc90513",
00000239 => x"ff5ff06f",
00000240 => x"ffff1537",
00000241 => x"e1050513",
00000242 => x"0cd0006f",
00000243 => x"ff010113",
00000244 => x"00112623",
00000245 => x"30047073",
00000246 => x"00000013",
00000247 => x"00000013",
00000248 => x"ffff1537",
00000249 => x"e7450513",
00000250 => x"0ad000ef",
00000251 => x"071000ef",
00000252 => x"fe051ee3",
00000253 => x"ff002783",
00000254 => x"00078067",
00000255 => x"0000006f",
00000256 => x"ff010113",
00000257 => x"00812423",
00000258 => x"00050413",
00000259 => x"ffff1537",
00000260 => x"e8450513",
00000261 => x"00112623",
00000262 => x"07d000ef",
00000263 => x"03040513",
00000264 => x"0ff57513",
00000265 => x"021000ef",
00000266 => x"30047073",
00000267 => x"00000013",
00000268 => x"00000013",
00000269 => x"18d000ef",
00000270 => x"00050863",
00000271 => x"00100513",
00000272 => x"00000593",
00000273 => x"1bd000ef",
00000274 => x"0000006f",
00000275 => x"fe010113",
00000276 => x"01212823",
00000277 => x"00050913",
00000278 => x"ffff1537",
00000279 => x"00912a23",
00000280 => x"e9050513",
00000281 => x"ffff14b7",
00000282 => x"00812c23",
00000283 => x"01312623",
00000284 => x"00112e23",
00000285 => x"01c00413",
00000286 => x"01d000ef",
00000287 => x"fe848493",
00000288 => x"ffc00993",
00000289 => x"008957b3",
00000290 => x"00f7f793",
00000291 => x"00f487b3",
00000292 => x"0007c503",
00000293 => x"ffc40413",
00000294 => x"7ac000ef",
00000295 => x"ff3414e3",
00000296 => x"01c12083",
00000297 => x"01812403",
00000298 => x"01412483",
00000299 => x"01012903",
00000300 => x"00c12983",
00000301 => x"02010113",
00000302 => x"00008067",
00000303 => x"fb010113",
00000304 => x"04112623",
00000305 => x"04512423",
00000306 => x"04612223",
00000307 => x"04712023",
00000308 => x"02812e23",
00000309 => x"02912c23",
00000310 => x"02a12a23",
00000311 => x"02b12823",
00000312 => x"02c12623",
00000313 => x"02d12423",
00000314 => x"02e12223",
00000315 => x"02f12023",
00000316 => x"01012e23",
00000317 => x"01112c23",
00000318 => x"01c12a23",
00000319 => x"01d12823",
00000320 => x"01e12623",
00000321 => x"01f12423",
00000322 => x"342024f3",
00000323 => x"800007b7",
00000324 => x"00778793",
00000325 => x"08f49463",
00000326 => x"0a9000ef",
00000327 => x"00050663",
00000328 => x"00000513",
00000329 => x"0ad000ef",
00000330 => x"654000ef",
00000331 => x"02050063",
00000332 => x"7bc000ef",
00000333 => x"fe002783",
00000334 => x"0027d793",
00000335 => x"00a78533",
00000336 => x"00f537b3",
00000337 => x"00b785b3",
00000338 => x"644000ef",
00000339 => x"03c12403",
00000340 => x"04c12083",
00000341 => x"04812283",
00000342 => x"04412303",
00000343 => x"04012383",
00000344 => x"03812483",
00000345 => x"03412503",
00000346 => x"03012583",
00000347 => x"02c12603",
00000348 => x"02812683",
00000349 => x"02412703",
00000350 => x"02012783",
00000351 => x"01c12803",
00000352 => x"01812883",
00000353 => x"01412e03",
00000354 => x"01012e83",
00000355 => x"00c12f03",
00000356 => x"00812f83",
00000357 => x"05010113",
00000358 => x"30200073",
00000359 => x"00700793",
00000360 => x"00f49a63",
00000361 => x"8041a783",
00000362 => x"00078663",
00000363 => x"00100513",
00000364 => x"e51ff0ef",
00000365 => x"34102473",
00000366 => x"5ec000ef",
00000367 => x"04050263",
00000368 => x"ffff1537",
00000369 => x"e9450513",
00000370 => x"6cc000ef",
00000371 => x"00048513",
00000372 => x"e7dff0ef",
00000373 => x"02000513",
00000374 => x"66c000ef",
00000375 => x"00040513",
00000376 => x"e6dff0ef",
00000377 => x"02000513",
00000378 => x"65c000ef",
00000379 => x"34302573",
00000380 => x"e5dff0ef",
00000381 => x"ffff1537",
00000382 => x"e9c50513",
00000383 => x"698000ef",
00000384 => x"00440413",
00000385 => x"34141073",
00000386 => x"f45ff06f",
00000387 => x"ff010113",
00000388 => x"00000513",
00000389 => x"00112623",
00000390 => x"00812423",
00000391 => x"74c000ef",
00000392 => x"09e00513",
00000393 => x"788000ef",
00000394 => x"00000513",
00000395 => x"780000ef",
00000396 => x"00050413",
00000397 => x"00000513",
00000398 => x"750000ef",
00000399 => x"00c12083",
00000400 => x"0ff47513",
00000401 => x"00812403",
00000402 => x"01010113",
00000403 => x"00008067",
00000404 => x"ff010113",
00000405 => x"00112623",
00000406 => x"00812423",
00000407 => x"00000513",
00000408 => x"708000ef",
00000409 => x"00500513",
00000410 => x"744000ef",
00000411 => x"00000513",
00000412 => x"73c000ef",
00000413 => x"00050413",
00000414 => x"00147413",
00000415 => x"00000513",
00000416 => x"708000ef",
00000417 => x"fc041ce3",
00000418 => x"00c12083",
00000419 => x"00812403",
00000420 => x"01010113",
00000421 => x"00008067",
00000422 => x"ff010113",
00000423 => x"00000513",
00000424 => x"00112623",
00000425 => x"6c4000ef",
00000426 => x"00600513",
00000427 => x"700000ef",
00000428 => x"00c12083",
00000429 => x"00000513",
00000430 => x"01010113",
00000431 => x"6cc0006f",
00000432 => x"ff010113",
00000433 => x"00812423",
00000434 => x"00050413",
00000435 => x"01055513",
00000436 => x"0ff57513",
00000437 => x"00112623",
00000438 => x"6d4000ef",
00000439 => x"00845513",
00000440 => x"0ff57513",
00000441 => x"6c8000ef",
00000442 => x"0ff47513",
00000443 => x"00812403",
00000444 => x"00c12083",
00000445 => x"01010113",
00000446 => x"6b40006f",
00000447 => x"ff010113",
00000448 => x"00812423",
00000449 => x"00050413",
00000450 => x"00000513",
00000451 => x"00112623",
00000452 => x"658000ef",
00000453 => x"00300513",
00000454 => x"694000ef",
00000455 => x"00040513",
00000456 => x"fa1ff0ef",
00000457 => x"00000513",
00000458 => x"684000ef",
00000459 => x"00050413",
00000460 => x"00000513",
00000461 => x"654000ef",
00000462 => x"00c12083",
00000463 => x"0ff47513",
00000464 => x"00812403",
00000465 => x"01010113",
00000466 => x"00008067",
00000467 => x"fd010113",
00000468 => x"02812423",
00000469 => x"02912223",
00000470 => x"03212023",
00000471 => x"01312e23",
00000472 => x"01412c23",
00000473 => x"02112623",
00000474 => x"00050913",
00000475 => x"00058993",
00000476 => x"00c10493",
00000477 => x"00000413",
00000478 => x"00400a13",
00000479 => x"02091e63",
00000480 => x"4f8000ef",
00000481 => x"00a48023",
00000482 => x"00140413",
00000483 => x"00148493",
00000484 => x"ff4416e3",
00000485 => x"02c12083",
00000486 => x"02812403",
00000487 => x"00c12503",
00000488 => x"02412483",
00000489 => x"02012903",
00000490 => x"01c12983",
00000491 => x"01812a03",
00000492 => x"03010113",
00000493 => x"00008067",
00000494 => x"00898533",
00000495 => x"f41ff0ef",
00000496 => x"fc5ff06f",
00000497 => x"fd010113",
00000498 => x"01412c23",
00000499 => x"02812423",
00000500 => x"80418793",
00000501 => x"02112623",
00000502 => x"02912223",
00000503 => x"03212023",
00000504 => x"01312e23",
00000505 => x"01512a23",
00000506 => x"01612823",
00000507 => x"01712623",
00000508 => x"01812423",
00000509 => x"00100713",
00000510 => x"00e7a023",
00000511 => x"00050413",
00000512 => x"80418a13",
00000513 => x"02051863",
00000514 => x"ffff1537",
00000515 => x"ea050513",
00000516 => x"484000ef",
00000517 => x"080005b7",
00000518 => x"00040513",
00000519 => x"f31ff0ef",
00000520 => x"4788d7b7",
00000521 => x"afe78793",
00000522 => x"02f50a63",
00000523 => x"00000513",
00000524 => x"01c0006f",
00000525 => x"ffff1537",
00000526 => x"ec050513",
00000527 => x"458000ef",
00000528 => x"4d8000ef",
00000529 => x"00051663",
00000530 => x"00300513",
00000531 => x"bb5ff0ef",
00000532 => x"dbdff0ef",
00000533 => x"fc0510e3",
00000534 => x"ff1ff06f",
00000535 => x"080009b7",
00000536 => x"00498593",
00000537 => x"00040513",
00000538 => x"ee5ff0ef",
00000539 => x"00050a93",
00000540 => x"00898593",
00000541 => x"00040513",
00000542 => x"ed5ff0ef",
00000543 => x"ff002c03",
00000544 => x"00050b13",
00000545 => x"ffcafb93",
00000546 => x"00000913",
00000547 => x"00000493",
00000548 => x"00c98993",
00000549 => x"013905b3",
00000550 => x"052b9c63",
00000551 => x"016484b3",
00000552 => x"00200513",
00000553 => x"fa0494e3",
00000554 => x"ffff1537",
00000555 => x"ecc50513",
00000556 => x"3e4000ef",
00000557 => x"02c12083",
00000558 => x"02812403",
00000559 => x"800007b7",
00000560 => x"0157a023",
00000561 => x"000a2023",
00000562 => x"02412483",
00000563 => x"02012903",
00000564 => x"01c12983",
00000565 => x"01812a03",
00000566 => x"01412a83",
00000567 => x"01012b03",
00000568 => x"00c12b83",
00000569 => x"00812c03",
00000570 => x"03010113",
00000571 => x"00008067",
00000572 => x"00040513",
00000573 => x"e59ff0ef",
00000574 => x"012c07b3",
00000575 => x"00a484b3",
00000576 => x"00a7a023",
00000577 => x"00490913",
00000578 => x"f8dff06f",
00000579 => x"ff010113",
00000580 => x"00112623",
00000581 => x"00812423",
00000582 => x"00912223",
00000583 => x"00058413",
00000584 => x"00050493",
00000585 => x"d75ff0ef",
00000586 => x"00000513",
00000587 => x"43c000ef",
00000588 => x"00200513",
00000589 => x"478000ef",
00000590 => x"00048513",
00000591 => x"d85ff0ef",
00000592 => x"00040513",
00000593 => x"468000ef",
00000594 => x"00000513",
00000595 => x"43c000ef",
00000596 => x"00812403",
00000597 => x"00c12083",
00000598 => x"00412483",
00000599 => x"01010113",
00000600 => x"cf1ff06f",
00000601 => x"fe010113",
00000602 => x"00812c23",
00000603 => x"00912a23",
00000604 => x"01212823",
00000605 => x"00112e23",
00000606 => x"00050493",
00000607 => x"00b12623",
00000608 => x"00000413",
00000609 => x"00400913",
00000610 => x"00c10793",
00000611 => x"008787b3",
00000612 => x"0007c583",
00000613 => x"00848533",
00000614 => x"00140413",
00000615 => x"f71ff0ef",
00000616 => x"ff2414e3",
00000617 => x"01c12083",
00000618 => x"01812403",
00000619 => x"01412483",
00000620 => x"01012903",
00000621 => x"02010113",
00000622 => x"00008067",
00000623 => x"ff010113",
00000624 => x"00112623",
00000625 => x"00812423",
00000626 => x"00050413",
00000627 => x"ccdff0ef",
00000628 => x"00000513",
00000629 => x"394000ef",
00000630 => x"0d800513",
00000631 => x"3d0000ef",
00000632 => x"00040513",
00000633 => x"cddff0ef",
00000634 => x"00000513",
00000635 => x"39c000ef",
00000636 => x"00812403",
00000637 => x"00c12083",
00000638 => x"01010113",
00000639 => x"c55ff06f",
00000640 => x"fe010113",
00000641 => x"800007b7",
00000642 => x"00812c23",
00000643 => x"0007a403",
00000644 => x"00112e23",
00000645 => x"00912a23",
00000646 => x"01212823",
00000647 => x"01312623",
00000648 => x"01412423",
00000649 => x"01512223",
00000650 => x"02041863",
00000651 => x"ffff1537",
00000652 => x"ed050513",
00000653 => x"01812403",
00000654 => x"01c12083",
00000655 => x"01412483",
00000656 => x"01012903",
00000657 => x"00c12983",
00000658 => x"00812a03",
00000659 => x"00412a83",
00000660 => x"02010113",
00000661 => x"2400006f",
00000662 => x"ffff1537",
00000663 => x"eec50513",
00000664 => x"234000ef",
00000665 => x"00040513",
00000666 => x"9e5ff0ef",
00000667 => x"ffff1537",
00000668 => x"ef450513",
00000669 => x"220000ef",
00000670 => x"08000537",
00000671 => x"9d1ff0ef",
00000672 => x"ffff1537",
00000673 => x"f0c50513",
00000674 => x"20c000ef",
00000675 => x"1ec000ef",
00000676 => x"00050493",
00000677 => x"1b0000ef",
00000678 => x"07900793",
00000679 => x"0af49e63",
00000680 => x"b6dff0ef",
00000681 => x"00051663",
00000682 => x"00300513",
00000683 => x"955ff0ef",
00000684 => x"ffff1537",
00000685 => x"f1850513",
00000686 => x"01045493",
00000687 => x"1d8000ef",
00000688 => x"00148493",
00000689 => x"08000937",
00000690 => x"fff00993",
00000691 => x"00010a37",
00000692 => x"fff48493",
00000693 => x"07349063",
00000694 => x"4788d5b7",
00000695 => x"afe58593",
00000696 => x"08000537",
00000697 => x"e81ff0ef",
00000698 => x"08000537",
00000699 => x"00040593",
00000700 => x"00450513",
00000701 => x"e71ff0ef",
00000702 => x"ff002a03",
00000703 => x"080009b7",
00000704 => x"ffc47413",
00000705 => x"00000493",
00000706 => x"00000913",
00000707 => x"00c98a93",
00000708 => x"01548533",
00000709 => x"009a07b3",
00000710 => x"02849663",
00000711 => x"00898513",
00000712 => x"412005b3",
00000713 => x"e41ff0ef",
00000714 => x"ffff1537",
00000715 => x"ecc50513",
00000716 => x"f05ff06f",
00000717 => x"00090513",
00000718 => x"e85ff0ef",
00000719 => x"01490933",
00000720 => x"f91ff06f",
00000721 => x"0007a583",
00000722 => x"00448493",
00000723 => x"00b90933",
00000724 => x"e15ff0ef",
00000725 => x"fbdff06f",
00000726 => x"01c12083",
00000727 => x"01812403",
00000728 => x"01412483",
00000729 => x"01012903",
00000730 => x"00c12983",
00000731 => x"00812a03",
00000732 => x"00412a83",
00000733 => x"02010113",
00000734 => x"00008067",
00000735 => x"fe802503",
00000736 => x"01155513",
00000737 => x"00157513",
00000738 => x"00008067",
00000739 => x"f9000793",
00000740 => x"fff00713",
00000741 => x"00e7a423",
00000742 => x"00b7a623",
00000743 => x"00a7a423",
00000744 => x"00008067",
00000745 => x"fe802503",
00000746 => x"01255513",
00000747 => x"00157513",
00000748 => x"00008067",
00000749 => x"fa002023",
00000750 => x"fe002703",
00000751 => x"00151513",
00000752 => x"00000793",
00000753 => x"04a77463",
00000754 => x"000016b7",
00000755 => x"00000713",
00000756 => x"ffe68693",
00000757 => x"04f6e663",
00000758 => x"00367613",
00000759 => x"0035f593",
00000760 => x"fff78793",
00000761 => x"01461613",
00000762 => x"00c7e7b3",
00000763 => x"01659593",
00000764 => x"01871713",
00000765 => x"00b7e7b3",
00000766 => x"00e7e7b3",
00000767 => x"10000737",
00000768 => x"00e7e7b3",
00000769 => x"faf02023",
00000770 => x"00008067",
00000771 => x"00178793",
00000772 => x"01079793",
00000773 => x"40a70733",
00000774 => x"0107d793",
00000775 => x"fa9ff06f",
00000776 => x"ffe70513",
00000777 => x"0fd57513",
00000778 => x"00051a63",
00000779 => x"0037d793",
00000780 => x"00170713",
00000781 => x"0ff77713",
00000782 => x"f9dff06f",
00000783 => x"0017d793",
00000784 => x"ff1ff06f",
00000785 => x"00040737",
00000786 => x"fa002783",
00000787 => x"00e7f7b3",
00000788 => x"fe079ce3",
00000789 => x"faa02223",
00000790 => x"00008067",
00000791 => x"fa002783",
00000792 => x"00100513",
00000793 => x"0007c863",
00000794 => x"0107d513",
00000795 => x"00154513",
00000796 => x"00157513",
00000797 => x"00008067",
00000798 => x"fa402503",
00000799 => x"fe055ee3",
00000800 => x"0ff57513",
00000801 => x"00008067",
00000802 => x"fa402503",
00000803 => x"01f55513",
00000804 => x"00008067",
00000805 => x"ff010113",
00000806 => x"00812423",
00000807 => x"01212023",
00000808 => x"00112623",
00000809 => x"00912223",
00000810 => x"00050413",
00000811 => x"00a00913",
00000812 => x"00044483",
00000813 => x"00140413",
00000814 => x"00049e63",
00000815 => x"00c12083",
00000816 => x"00812403",
00000817 => x"00412483",
00000818 => x"00012903",
00000819 => x"01010113",
00000820 => x"00008067",
00000821 => x"01249663",
00000822 => x"00d00513",
00000823 => x"f69ff0ef",
00000824 => x"00048513",
00000825 => x"f61ff0ef",
00000826 => x"fc9ff06f",
00000827 => x"ff010113",
00000828 => x"c81026f3",
00000829 => x"c0102773",
00000830 => x"c81027f3",
00000831 => x"fed79ae3",
00000832 => x"00e12023",
00000833 => x"00f12223",
00000834 => x"00012503",
00000835 => x"00412583",
00000836 => x"01010113",
00000837 => x"00008067",
00000838 => x"fe802503",
00000839 => x"01355513",
00000840 => x"00157513",
00000841 => x"00008067",
00000842 => x"00757513",
00000843 => x"0036f793",
00000844 => x"00167613",
00000845 => x"00a51513",
00000846 => x"00d79793",
00000847 => x"0015f593",
00000848 => x"00f567b3",
00000849 => x"00f61613",
00000850 => x"00c7e7b3",
00000851 => x"00959593",
00000852 => x"fa800713",
00000853 => x"00b7e7b3",
00000854 => x"00072023",
00000855 => x"1007e793",
00000856 => x"00f72023",
00000857 => x"00008067",
00000858 => x"fa800713",
00000859 => x"00072683",
00000860 => x"00757793",
00000861 => x"00100513",
00000862 => x"00f51533",
00000863 => x"00d56533",
00000864 => x"00a72023",
00000865 => x"00008067",
00000866 => x"fa800713",
00000867 => x"00072683",
00000868 => x"00757513",
00000869 => x"00100793",
00000870 => x"00a797b3",
00000871 => x"fff7c793",
00000872 => x"00d7f7b3",
00000873 => x"00f72023",
00000226 => x"01841663",
00000227 => x"670000ef",
00000228 => x"fadff06f",
00000229 => x"06c00793",
00000230 => x"00f41663",
00000231 => x"00100513",
00000232 => x"fe1ff06f",
00000233 => x"06500793",
00000234 => x"00f41c63",
00000235 => x"0004a783",
00000236 => x"f40798e3",
00000237 => x"ebcc8513",
00000238 => x"0d9000ef",
00000239 => x"f81ff06f",
00000240 => x"fc890513",
00000241 => x"ff5ff06f",
00000242 => x"ffff1537",
00000243 => x"dfc50513",
00000244 => x"0c10006f",
00000245 => x"ff010113",
00000246 => x"00112623",
00000247 => x"30047073",
00000248 => x"00000013",
00000249 => x"00000013",
00000250 => x"ffff1537",
00000251 => x"e6050513",
00000252 => x"0a1000ef",
00000253 => x"065000ef",
00000254 => x"fe051ee3",
00000255 => x"ff002783",
00000256 => x"00078067",
00000257 => x"0000006f",
00000258 => x"ff010113",
00000259 => x"00812423",
00000260 => x"00050413",
00000261 => x"ffff1537",
00000262 => x"e7050513",
00000263 => x"00112623",
00000264 => x"071000ef",
00000265 => x"03040513",
00000266 => x"0ff57513",
00000267 => x"015000ef",
00000268 => x"30047073",
00000269 => x"00000013",
00000270 => x"00000013",
00000271 => x"171000ef",
00000272 => x"00050863",
00000273 => x"00100513",
00000274 => x"00000593",
00000275 => x"1a1000ef",
00000276 => x"0000006f",
00000277 => x"fe010113",
00000278 => x"01212823",
00000279 => x"00050913",
00000280 => x"ffff1537",
00000281 => x"00912a23",
00000282 => x"e7c50513",
00000283 => x"ffff14b7",
00000284 => x"00812c23",
00000285 => x"01312623",
00000286 => x"00112e23",
00000287 => x"01c00413",
00000288 => x"011000ef",
00000289 => x"fd448493",
00000290 => x"ffc00993",
00000291 => x"008957b3",
00000292 => x"00f7f793",
00000293 => x"00f487b3",
00000294 => x"0007c503",
00000295 => x"ffc40413",
00000296 => x"7a0000ef",
00000297 => x"ff3414e3",
00000298 => x"01c12083",
00000299 => x"01812403",
00000300 => x"01412483",
00000301 => x"01012903",
00000302 => x"00c12983",
00000303 => x"02010113",
00000304 => x"00008067",
00000305 => x"fb010113",
00000306 => x"04112623",
00000307 => x"04512423",
00000308 => x"04612223",
00000309 => x"04712023",
00000310 => x"02812e23",
00000311 => x"02912c23",
00000312 => x"02a12a23",
00000313 => x"02b12823",
00000314 => x"02c12623",
00000315 => x"02d12423",
00000316 => x"02e12223",
00000317 => x"02f12023",
00000318 => x"01012e23",
00000319 => x"01112c23",
00000320 => x"01c12a23",
00000321 => x"01d12823",
00000322 => x"01e12623",
00000323 => x"01f12423",
00000324 => x"342024f3",
00000325 => x"800007b7",
00000326 => x"00778793",
00000327 => x"08f49463",
00000328 => x"08d000ef",
00000329 => x"00050663",
00000330 => x"00000513",
00000331 => x"091000ef",
00000332 => x"648000ef",
00000333 => x"02050063",
00000334 => x"7b0000ef",
00000335 => x"fe002783",
00000336 => x"0027d793",
00000337 => x"00a78533",
00000338 => x"00f537b3",
00000339 => x"00b785b3",
00000340 => x"638000ef",
00000341 => x"03c12403",
00000342 => x"04c12083",
00000343 => x"04812283",
00000344 => x"04412303",
00000345 => x"04012383",
00000346 => x"03812483",
00000347 => x"03412503",
00000348 => x"03012583",
00000349 => x"02c12603",
00000350 => x"02812683",
00000351 => x"02412703",
00000352 => x"02012783",
00000353 => x"01c12803",
00000354 => x"01812883",
00000355 => x"01412e03",
00000356 => x"01012e83",
00000357 => x"00c12f03",
00000358 => x"00812f83",
00000359 => x"05010113",
00000360 => x"30200073",
00000361 => x"00700793",
00000362 => x"00f49a63",
00000363 => x"8041a783",
00000364 => x"00078663",
00000365 => x"00100513",
00000366 => x"e51ff0ef",
00000367 => x"34102473",
00000368 => x"5e0000ef",
00000369 => x"04050263",
00000370 => x"ffff1537",
00000371 => x"e8050513",
00000372 => x"6c0000ef",
00000373 => x"00048513",
00000374 => x"e7dff0ef",
00000375 => x"02000513",
00000376 => x"660000ef",
00000377 => x"00040513",
00000378 => x"e6dff0ef",
00000379 => x"02000513",
00000380 => x"650000ef",
00000381 => x"34302573",
00000382 => x"e5dff0ef",
00000383 => x"ffff1537",
00000384 => x"e8850513",
00000385 => x"68c000ef",
00000386 => x"00440413",
00000387 => x"34141073",
00000388 => x"f45ff06f",
00000389 => x"ff010113",
00000390 => x"00000513",
00000391 => x"00112623",
00000392 => x"00812423",
00000393 => x"730000ef",
00000394 => x"09e00513",
00000395 => x"76c000ef",
00000396 => x"00000513",
00000397 => x"764000ef",
00000398 => x"00050413",
00000399 => x"00000513",
00000400 => x"734000ef",
00000401 => x"00c12083",
00000402 => x"0ff47513",
00000403 => x"00812403",
00000404 => x"01010113",
00000405 => x"00008067",
00000406 => x"ff010113",
00000407 => x"00112623",
00000408 => x"00812423",
00000409 => x"00000513",
00000410 => x"6ec000ef",
00000411 => x"00500513",
00000412 => x"728000ef",
00000413 => x"00000513",
00000414 => x"720000ef",
00000415 => x"00050413",
00000416 => x"00147413",
00000417 => x"00000513",
00000418 => x"6ec000ef",
00000419 => x"fc041ce3",
00000420 => x"00c12083",
00000421 => x"00812403",
00000422 => x"01010113",
00000423 => x"00008067",
00000424 => x"ff010113",
00000425 => x"00000513",
00000426 => x"00112623",
00000427 => x"6a8000ef",
00000428 => x"00600513",
00000429 => x"6e4000ef",
00000430 => x"00c12083",
00000431 => x"00000513",
00000432 => x"01010113",
00000433 => x"6b00006f",
00000434 => x"ff010113",
00000435 => x"00812423",
00000436 => x"00050413",
00000437 => x"01055513",
00000438 => x"0ff57513",
00000439 => x"00112623",
00000440 => x"6b8000ef",
00000441 => x"00845513",
00000442 => x"0ff57513",
00000443 => x"6ac000ef",
00000444 => x"0ff47513",
00000445 => x"00812403",
00000446 => x"00c12083",
00000447 => x"01010113",
00000448 => x"6980006f",
00000449 => x"ff010113",
00000450 => x"00812423",
00000451 => x"00050413",
00000452 => x"00000513",
00000453 => x"00112623",
00000454 => x"63c000ef",
00000455 => x"00300513",
00000456 => x"678000ef",
00000457 => x"00040513",
00000458 => x"fa1ff0ef",
00000459 => x"00000513",
00000460 => x"668000ef",
00000461 => x"00050413",
00000462 => x"00000513",
00000463 => x"638000ef",
00000464 => x"00c12083",
00000465 => x"0ff47513",
00000466 => x"00812403",
00000467 => x"01010113",
00000468 => x"00008067",
00000469 => x"fd010113",
00000470 => x"02812423",
00000471 => x"02912223",
00000472 => x"03212023",
00000473 => x"01312e23",
00000474 => x"01412c23",
00000475 => x"02112623",
00000476 => x"00050913",
00000477 => x"00058993",
00000478 => x"00c10493",
00000479 => x"00000413",
00000480 => x"00400a13",
00000481 => x"02091e63",
00000482 => x"4ec000ef",
00000483 => x"00a48023",
00000484 => x"00140413",
00000485 => x"00148493",
00000486 => x"ff4416e3",
00000487 => x"02c12083",
00000488 => x"02812403",
00000489 => x"00c12503",
00000490 => x"02412483",
00000491 => x"02012903",
00000492 => x"01c12983",
00000493 => x"01812a03",
00000494 => x"03010113",
00000495 => x"00008067",
00000496 => x"00898533",
00000497 => x"f41ff0ef",
00000498 => x"fc5ff06f",
00000499 => x"fd010113",
00000500 => x"01412c23",
00000501 => x"02812423",
00000502 => x"80418793",
00000503 => x"02112623",
00000504 => x"02912223",
00000505 => x"03212023",
00000506 => x"01312e23",
00000507 => x"01512a23",
00000508 => x"01612823",
00000509 => x"01712623",
00000510 => x"01812423",
00000511 => x"00100713",
00000512 => x"00e7a023",
00000513 => x"00050413",
00000514 => x"80418a13",
00000515 => x"02051863",
00000516 => x"ffff1537",
00000517 => x"e8c50513",
00000518 => x"478000ef",
00000519 => x"080005b7",
00000520 => x"00040513",
00000521 => x"f31ff0ef",
00000522 => x"4788d7b7",
00000523 => x"afe78793",
00000524 => x"02f50463",
00000525 => x"00000513",
00000526 => x"01c0006f",
00000527 => x"ffff1537",
00000528 => x"eac50513",
00000529 => x"44c000ef",
00000530 => x"dcdff0ef",
00000531 => x"fc0518e3",
00000532 => x"00300513",
00000533 => x"bb5ff0ef",
00000534 => x"080009b7",
00000535 => x"00498593",
00000536 => x"00040513",
00000537 => x"ef1ff0ef",
00000538 => x"00050a93",
00000539 => x"00898593",
00000540 => x"00040513",
00000541 => x"ee1ff0ef",
00000542 => x"ff002c03",
00000543 => x"00050b13",
00000544 => x"ffcafb93",
00000545 => x"00000913",
00000546 => x"00000493",
00000547 => x"00c98993",
00000548 => x"013905b3",
00000549 => x"052b9c63",
00000550 => x"016484b3",
00000551 => x"00200513",
00000552 => x"fa049ae3",
00000553 => x"ffff1537",
00000554 => x"eb850513",
00000555 => x"3e4000ef",
00000556 => x"02c12083",
00000557 => x"02812403",
00000558 => x"800007b7",
00000559 => x"0157a023",
00000560 => x"000a2023",
00000561 => x"02412483",
00000562 => x"02012903",
00000563 => x"01c12983",
00000564 => x"01812a03",
00000565 => x"01412a83",
00000566 => x"01012b03",
00000567 => x"00c12b83",
00000568 => x"00812c03",
00000569 => x"03010113",
00000570 => x"00008067",
00000571 => x"00040513",
00000572 => x"e65ff0ef",
00000573 => x"012c07b3",
00000574 => x"00a484b3",
00000575 => x"00a7a023",
00000576 => x"00490913",
00000577 => x"f8dff06f",
00000578 => x"ff010113",
00000579 => x"00112623",
00000580 => x"00812423",
00000581 => x"00912223",
00000582 => x"00058413",
00000583 => x"00050493",
00000584 => x"d81ff0ef",
00000585 => x"00000513",
00000586 => x"42c000ef",
00000587 => x"00200513",
00000588 => x"468000ef",
00000589 => x"00048513",
00000590 => x"d91ff0ef",
00000591 => x"00040513",
00000592 => x"458000ef",
00000593 => x"00000513",
00000594 => x"42c000ef",
00000595 => x"00812403",
00000596 => x"00c12083",
00000597 => x"00412483",
00000598 => x"01010113",
00000599 => x"cfdff06f",
00000600 => x"fe010113",
00000601 => x"00812c23",
00000602 => x"00912a23",
00000603 => x"01212823",
00000604 => x"00112e23",
00000605 => x"00050493",
00000606 => x"00b12623",
00000607 => x"00000413",
00000608 => x"00400913",
00000609 => x"00c10793",
00000610 => x"008787b3",
00000611 => x"0007c583",
00000612 => x"00848533",
00000613 => x"00140413",
00000614 => x"f71ff0ef",
00000615 => x"ff2414e3",
00000616 => x"01c12083",
00000617 => x"01812403",
00000618 => x"01412483",
00000619 => x"01012903",
00000620 => x"02010113",
00000621 => x"00008067",
00000622 => x"ff010113",
00000623 => x"00112623",
00000624 => x"00812423",
00000625 => x"00050413",
00000626 => x"cd9ff0ef",
00000627 => x"00000513",
00000628 => x"384000ef",
00000629 => x"0d800513",
00000630 => x"3c0000ef",
00000631 => x"00040513",
00000632 => x"ce9ff0ef",
00000633 => x"00000513",
00000634 => x"38c000ef",
00000635 => x"00812403",
00000636 => x"00c12083",
00000637 => x"01010113",
00000638 => x"c61ff06f",
00000639 => x"fe010113",
00000640 => x"800007b7",
00000641 => x"00812c23",
00000642 => x"0007a403",
00000643 => x"00112e23",
00000644 => x"00912a23",
00000645 => x"01212823",
00000646 => x"01312623",
00000647 => x"01412423",
00000648 => x"01512223",
00000649 => x"02041863",
00000650 => x"ffff1537",
00000651 => x"ebc50513",
00000652 => x"01812403",
00000653 => x"01c12083",
00000654 => x"01412483",
00000655 => x"01012903",
00000656 => x"00c12983",
00000657 => x"00812a03",
00000658 => x"00412a83",
00000659 => x"02010113",
00000660 => x"2400006f",
00000661 => x"ffff1537",
00000662 => x"ed850513",
00000663 => x"234000ef",
00000664 => x"00040513",
00000665 => x"9f1ff0ef",
00000666 => x"ffff1537",
00000667 => x"ee050513",
00000668 => x"220000ef",
00000669 => x"08000537",
00000670 => x"9ddff0ef",
00000671 => x"ffff1537",
00000672 => x"ef850513",
00000673 => x"20c000ef",
00000674 => x"1ec000ef",
00000675 => x"00050493",
00000676 => x"1b0000ef",
00000677 => x"07900793",
00000678 => x"0af49e63",
00000679 => x"b79ff0ef",
00000680 => x"00051663",
00000681 => x"00300513",
00000682 => x"961ff0ef",
00000683 => x"ffff1537",
00000684 => x"f0450513",
00000685 => x"01045493",
00000686 => x"1d8000ef",
00000687 => x"00148493",
00000688 => x"08000937",
00000689 => x"fff00993",
00000690 => x"00010a37",
00000691 => x"fff48493",
00000692 => x"07349063",
00000693 => x"4788d5b7",
00000694 => x"afe58593",
00000695 => x"08000537",
00000696 => x"e81ff0ef",
00000697 => x"08000537",
00000698 => x"00040593",
00000699 => x"00450513",
00000700 => x"e71ff0ef",
00000701 => x"ff002a03",
00000702 => x"080009b7",
00000703 => x"ffc47413",
00000704 => x"00000493",
00000705 => x"00000913",
00000706 => x"00c98a93",
00000707 => x"01548533",
00000708 => x"009a07b3",
00000709 => x"02849663",
00000710 => x"00898513",
00000711 => x"412005b3",
00000712 => x"e41ff0ef",
00000713 => x"ffff1537",
00000714 => x"eb850513",
00000715 => x"f05ff06f",
00000716 => x"00090513",
00000717 => x"e85ff0ef",
00000718 => x"01490933",
00000719 => x"f91ff06f",
00000720 => x"0007a583",
00000721 => x"00448493",
00000722 => x"00b90933",
00000723 => x"e15ff0ef",
00000724 => x"fbdff06f",
00000725 => x"01c12083",
00000726 => x"01812403",
00000727 => x"01412483",
00000728 => x"01012903",
00000729 => x"00c12983",
00000730 => x"00812a03",
00000731 => x"00412a83",
00000732 => x"02010113",
00000733 => x"00008067",
00000734 => x"fe802503",
00000735 => x"01155513",
00000736 => x"00157513",
00000737 => x"00008067",
00000738 => x"f9000793",
00000739 => x"fff00713",
00000740 => x"00e7a423",
00000741 => x"00b7a623",
00000742 => x"00a7a423",
00000743 => x"00008067",
00000744 => x"fe802503",
00000745 => x"01255513",
00000746 => x"00157513",
00000747 => x"00008067",
00000748 => x"fa002023",
00000749 => x"fe002703",
00000750 => x"00151513",
00000751 => x"00000793",
00000752 => x"04a77463",
00000753 => x"000016b7",
00000754 => x"00000713",
00000755 => x"ffe68693",
00000756 => x"04f6e663",
00000757 => x"00367613",
00000758 => x"0035f593",
00000759 => x"fff78793",
00000760 => x"01461613",
00000761 => x"00c7e7b3",
00000762 => x"01659593",
00000763 => x"01871713",
00000764 => x"00b7e7b3",
00000765 => x"00e7e7b3",
00000766 => x"10000737",
00000767 => x"00e7e7b3",
00000768 => x"faf02023",
00000769 => x"00008067",
00000770 => x"00178793",
00000771 => x"01079793",
00000772 => x"40a70733",
00000773 => x"0107d793",
00000774 => x"fa9ff06f",
00000775 => x"ffe70513",
00000776 => x"0fd57513",
00000777 => x"00051a63",
00000778 => x"0037d793",
00000779 => x"00170713",
00000780 => x"0ff77713",
00000781 => x"f9dff06f",
00000782 => x"0017d793",
00000783 => x"ff1ff06f",
00000784 => x"00040737",
00000785 => x"fa002783",
00000786 => x"00e7f7b3",
00000787 => x"fe079ce3",
00000788 => x"faa02223",
00000789 => x"00008067",
00000790 => x"fa002783",
00000791 => x"00100513",
00000792 => x"0007c863",
00000793 => x"0107d513",
00000794 => x"00154513",
00000795 => x"00157513",
00000796 => x"00008067",
00000797 => x"fa402503",
00000798 => x"fe055ee3",
00000799 => x"0ff57513",
00000800 => x"00008067",
00000801 => x"fa402503",
00000802 => x"01f55513",
00000803 => x"00008067",
00000804 => x"ff010113",
00000805 => x"00812423",
00000806 => x"01212023",
00000807 => x"00112623",
00000808 => x"00912223",
00000809 => x"00050413",
00000810 => x"00a00913",
00000811 => x"00044483",
00000812 => x"00140413",
00000813 => x"00049e63",
00000814 => x"00c12083",
00000815 => x"00812403",
00000816 => x"00412483",
00000817 => x"00012903",
00000818 => x"01010113",
00000819 => x"00008067",
00000820 => x"01249663",
00000821 => x"00d00513",
00000822 => x"f69ff0ef",
00000823 => x"00048513",
00000824 => x"f61ff0ef",
00000825 => x"fc9ff06f",
00000826 => x"ff010113",
00000827 => x"c81026f3",
00000828 => x"c0102773",
00000829 => x"c81027f3",
00000830 => x"fed79ae3",
00000831 => x"00e12023",
00000832 => x"00f12223",
00000833 => x"00012503",
00000834 => x"00412583",
00000835 => x"01010113",
00000836 => x"00008067",
00000837 => x"00757513",
00000838 => x"0036f793",
00000839 => x"00167613",
00000840 => x"00a51513",
00000841 => x"00d79793",
00000842 => x"0015f593",
00000843 => x"00f567b3",
00000844 => x"00f61613",
00000845 => x"00c7e7b3",
00000846 => x"00959593",
00000847 => x"fa800713",
00000848 => x"00b7e7b3",
00000849 => x"00072023",
00000850 => x"1007e793",
00000851 => x"00f72023",
00000852 => x"00008067",
00000853 => x"fa800713",
00000854 => x"00072683",
00000855 => x"00757793",
00000856 => x"00100513",
00000857 => x"00f51533",
00000858 => x"00d56533",
00000859 => x"00a72023",
00000860 => x"00008067",
00000861 => x"fa800713",
00000862 => x"00072683",
00000863 => x"00757513",
00000864 => x"00100793",
00000865 => x"00a797b3",
00000866 => x"fff7c793",
00000867 => x"00d7f7b3",
00000868 => x"00f72023",
00000869 => x"00008067",
00000870 => x"faa02623",
00000871 => x"fa802783",
00000872 => x"fe07cee3",
00000873 => x"fac02503",
00000874 => x"00008067",
00000875 => x"faa02623",
00000876 => x"fa802783",
00000877 => x"fe07cee3",
00000878 => x"fac02503",
00000879 => x"00008067",
00000880 => x"fe802503",
00000881 => x"01055513",
00000882 => x"00157513",
00000883 => x"00008067",
00000884 => x"00100793",
00000885 => x"01f00713",
00000886 => x"00a797b3",
00000887 => x"00a74a63",
00000888 => x"fc802703",
00000889 => x"00f747b3",
00000890 => x"fcf02423",
00000891 => x"00008067",
00000892 => x"fcc02703",
00000893 => x"00f747b3",
00000894 => x"fcf02623",
00000895 => x"00008067",
00000896 => x"fc000793",
00000897 => x"00a7a423",
00000898 => x"00b7a623",
00000899 => x"00008067",
00000900 => x"69617641",
00000901 => x"6c62616c",
00000902 => x"4d432065",
00000903 => x"0a3a7344",
00000904 => x"203a6820",
00000905 => x"706c6548",
00000906 => x"3a72200a",
00000907 => x"73655220",
00000908 => x"74726174",
00000909 => x"3a75200a",
00000910 => x"6c705520",
00000911 => x"0a64616f",
00000912 => x"203a7320",
00000913 => x"726f7453",
00000914 => x"6f742065",
00000875 => x"fe802503",
00000876 => x"01055513",
00000877 => x"00157513",
00000878 => x"00008067",
00000879 => x"00100793",
00000880 => x"01f00713",
00000881 => x"00a797b3",
00000882 => x"00a74a63",
00000883 => x"fc802703",
00000884 => x"00f747b3",
00000885 => x"fcf02423",
00000886 => x"00008067",
00000887 => x"fcc02703",
00000888 => x"00f747b3",
00000889 => x"fcf02623",
00000890 => x"00008067",
00000891 => x"fc000793",
00000892 => x"00a7a423",
00000893 => x"00b7a623",
00000894 => x"00008067",
00000895 => x"69617641",
00000896 => x"6c62616c",
00000897 => x"4d432065",
00000898 => x"0a3a7344",
00000899 => x"203a6820",
00000900 => x"706c6548",
00000901 => x"3a72200a",
00000902 => x"73655220",
00000903 => x"74726174",
00000904 => x"3a75200a",
00000905 => x"6c705520",
00000906 => x"0a64616f",
00000907 => x"203a7320",
00000908 => x"726f7453",
00000909 => x"6f742065",
00000910 => x"616c6620",
00000911 => x"200a6873",
00000912 => x"4c203a6c",
00000913 => x"2064616f",
00000914 => x"6d6f7266",
00000915 => x"616c6620",
00000916 => x"200a6873",
00000917 => x"4c203a6c",
00000918 => x"2064616f",
00000919 => x"6d6f7266",
00000920 => x"616c6620",
00000921 => x"200a6873",
00000922 => x"45203a65",
00000923 => x"75636578",
00000924 => x"00006574",
00000925 => x"746f6f42",
00000926 => x"2e676e69",
00000927 => x"0a0a2e2e",
00000928 => x"00000000",
00000929 => x"52450a07",
00000930 => x"5f524f52",
00000931 => x"00000000",
00000932 => x"00007830",
00000933 => x"58455b0a",
00000934 => x"00002043",
00000935 => x"00000a5d",
00000936 => x"69617741",
00000937 => x"676e6974",
00000938 => x"6f656e20",
00000939 => x"32337672",
00000940 => x"6578655f",
00000941 => x"6e69622e",
00000942 => x"202e2e2e",
00000943 => x"00000000",
00000944 => x"64616f4c",
00000945 => x"2e676e69",
00000946 => x"00202e2e",
00000947 => x"00004b4f",
00000948 => x"65206f4e",
00000949 => x"75636578",
00000950 => x"6c626174",
00000951 => x"76612065",
00000952 => x"616c6961",
00000953 => x"2e656c62",
00000954 => x"00000000",
00000955 => x"74697257",
00000956 => x"00002065",
00000957 => x"74796220",
00000958 => x"74207365",
00000959 => x"5053206f",
00000960 => x"6c662049",
00000961 => x"20687361",
00000962 => x"00002040",
00000963 => x"7928203f",
00000964 => x"20296e2f",
00000965 => x"00000000",
00000966 => x"616c460a",
00000967 => x"6e696873",
00000968 => x"2e2e2e67",
00000969 => x"00000020",
00000970 => x"3c0a0a0a",
00000971 => x"454e203c",
00000972 => x"3356524f",
00000973 => x"6f422032",
00000974 => x"6f6c746f",
00000975 => x"72656461",
00000976 => x"0a3e3e20",
00000977 => x"444c420a",
00000978 => x"4f203a56",
00000979 => x"31207463",
00000980 => x"30322037",
00000981 => x"480a3132",
00000982 => x"203a5657",
00000983 => x"00000020",
00000984 => x"4b4c430a",
00000985 => x"0020203a",
00000986 => x"53494d0a",
00000987 => x"00203a41",
00000988 => x"5550430a",
00000989 => x"0020203a",
00000990 => x"434f530a",
00000991 => x"0020203a",
00000992 => x"454d490a",
00000917 => x"45203a65",
00000918 => x"75636578",
00000919 => x"00006574",
00000920 => x"746f6f42",
00000921 => x"2e676e69",
00000922 => x"0a0a2e2e",
00000923 => x"00000000",
00000924 => x"52450a07",
00000925 => x"5f524f52",
00000926 => x"00000000",
00000927 => x"00007830",
00000928 => x"52455b0a",
00000929 => x"00002052",
00000930 => x"00000a5d",
00000931 => x"69617741",
00000932 => x"676e6974",
00000933 => x"6f656e20",
00000934 => x"32337672",
00000935 => x"6578655f",
00000936 => x"6e69622e",
00000937 => x"202e2e2e",
00000938 => x"00000000",
00000939 => x"64616f4c",
00000940 => x"2e676e69",
00000941 => x"00202e2e",
00000942 => x"00004b4f",
00000943 => x"65206f4e",
00000944 => x"75636578",
00000945 => x"6c626174",
00000946 => x"76612065",
00000947 => x"616c6961",
00000948 => x"2e656c62",
00000949 => x"00000000",
00000950 => x"74697257",
00000951 => x"00002065",
00000952 => x"74796220",
00000953 => x"74207365",
00000954 => x"5053206f",
00000955 => x"6c662049",
00000956 => x"20687361",
00000957 => x"00783040",
00000958 => x"7928203f",
00000959 => x"20296e2f",
00000960 => x"00000000",
00000961 => x"616c460a",
00000962 => x"6e696873",
00000963 => x"2e2e2e67",
00000964 => x"00000020",
00000965 => x"3c0a0a0a",
00000966 => x"454e203c",
00000967 => x"3356524f",
00000968 => x"6f422032",
00000969 => x"6f6c746f",
00000970 => x"72656461",
00000971 => x"0a3e3e20",
00000972 => x"444c420a",
00000973 => x"4f203a56",
00000974 => x"32207463",
00000975 => x"30322037",
00000976 => x"480a3132",
00000977 => x"203a5657",
00000978 => x"00000020",
00000979 => x"4b4c430a",
00000980 => x"0020203a",
00000981 => x"53494d0a",
00000982 => x"00203a41",
00000983 => x"5550430a",
00000984 => x"0020203a",
00000985 => x"434f530a",
00000986 => x"0020203a",
00000987 => x"454d490a",
00000988 => x"00203a4d",
00000989 => x"74796220",
00000990 => x"40207365",
00000991 => x"00000000",
00000992 => x"454d440a",
00000993 => x"00203a4d",
00000994 => x"74796220",
00000995 => x"40207365",
00000996 => x"00000000",
00000997 => x"454d440a",
00000998 => x"00203a4d",
00000999 => x"75410a0a",
00001000 => x"6f626f74",
00001001 => x"6920746f",
00001002 => x"7338206e",
00001003 => x"7250202e",
00001004 => x"20737365",
00001005 => x"2079656b",
00001006 => x"61206f74",
00001007 => x"74726f62",
00001008 => x"00000a2e",
00001009 => x"0000000a",
00001010 => x"726f6241",
00001011 => x"2e646574",
00001012 => x"00000a0a",
00001013 => x"444d430a",
00001014 => x"00203e3a",
00001015 => x"61766e49",
00001016 => x"2064696c",
00001017 => x"00444d43",
00001018 => x"33323130",
00001019 => x"37363534",
00001020 => x"62613938",
00001021 => x"66656463"
00000994 => x"75410a0a",
00000995 => x"6f626f74",
00000996 => x"6920746f",
00000997 => x"7338206e",
00000998 => x"7250202e",
00000999 => x"20737365",
00001000 => x"2079656b",
00001001 => x"61206f74",
00001002 => x"74726f62",
00001003 => x"00000a2e",
00001004 => x"0000000a",
00001005 => x"726f6241",
00001006 => x"2e646574",
00001007 => x"00000a0a",
00001008 => x"444d430a",
00001009 => x"00203e3a",
00001010 => x"61766e49",
00001011 => x"2064696c",
00001012 => x"00444d43",
00001013 => x"33323130",
00001014 => x"37363534",
00001015 => x"62613938",
00001016 => x"66656463"
);
 
end neorv32_bootloader_image;
/rtl/core/neorv32_bus_keeper.vhd
62,20 → 62,43
);
port (
-- host access --
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active
addr_i : in std_ulogic_vector(31 downto 0); -- address
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
ack_i : in std_ulogic; -- transfer acknowledge from bus system
err_i : in std_ulogic; -- transfer error from bus system
err_o : out std_ulogic -- bus error
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset, low-active, async
addr_i : in std_ulogic_vector(31 downto 0); -- address
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic; -- transfer acknowledge
err_o : out std_ulogic; -- transfer error
-- bus monitoring --
bus_addr_i : in std_ulogic_vector(31 downto 0); -- address
bus_rden_i : in std_ulogic; -- read enable
bus_wren_i : in std_ulogic; -- write enable
bus_ack_i : in std_ulogic; -- transfer acknowledge from bus system
bus_err_i : in std_ulogic -- transfer error from bus system
);
end neorv32_bus_keeper;
 
architecture neorv32_bus_keeper_rtl of neorv32_bus_keeper is
 
-- access check --
-- IO space: module base address --
constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit
constant lo_abb_c : natural := index_size_f(buskeeper_size_c); -- low address boundary bit
 
-- Control register --
constant ctrl_err_type_c : natural := 0; -- r/-: error type: 0=device error, 1=access timeout
constant ctrl_err_src_c : natural := 1; -- r/-: error source: 0=processor-external, 1=processor-internal
constant ctrl_err_flag_c : natural := 31; -- r/c: bus error encountered, sticky; cleared by writing zero
 
-- sticky error flag --
signal err_flag : std_ulogic;
 
-- access control --
signal acc_en : std_ulogic; -- module access enable
signal wren : std_ulogic; -- word write enable
signal rden : std_ulogic; -- read enable
 
-- bus access check --
type access_check_t is record
int_imem : std_ulogic;
int_dmem : std_ulogic;
86,9 → 109,11
 
-- controller --
type control_t is record
pending : std_ulogic;
timeout : std_ulogic_vector(index_size_f(max_proc_int_response_time_c)-1 downto 0);
bus_err : std_ulogic;
pending : std_ulogic;
timeout : std_ulogic_vector(index_size_f(max_proc_int_response_time_c)-1 downto 0);
err_type : std_ulogic;
int_ext : std_ulogic;
bus_err : std_ulogic;
end record;
signal control : control_t;
 
101,50 → 126,96
 
-- Access Control -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = buskeeper_base_c(hi_abb_c downto lo_abb_c)) else '0';
wren <= acc_en and wren_i;
rden <= acc_en and rden_i;
 
 
-- Bus Access Check -----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- access to processor-internal IMEM or DMEM? --
access_check.int_imem <= '1' when (addr_i(31 downto index_size_f(MEM_INT_IMEM_SIZE)) = imem_base_c(31 downto index_size_f(MEM_INT_IMEM_SIZE))) and (MEM_INT_IMEM_EN = true) else '0';
access_check.int_dmem <= '1' when (addr_i(31 downto index_size_f(MEM_INT_DMEM_SIZE)) = dmem_base_c(31 downto index_size_f(MEM_INT_DMEM_SIZE))) and (MEM_INT_DMEM_EN = true) else '0';
access_check.int_imem <= '1' when (bus_addr_i(31 downto index_size_f(MEM_INT_IMEM_SIZE)) = imem_base_c(31 downto index_size_f(MEM_INT_IMEM_SIZE))) and (MEM_INT_IMEM_EN = true) else '0';
access_check.int_dmem <= '1' when (bus_addr_i(31 downto index_size_f(MEM_INT_DMEM_SIZE)) = dmem_base_c(31 downto index_size_f(MEM_INT_DMEM_SIZE))) and (MEM_INT_DMEM_EN = true) else '0';
-- access to processor-internal BOOTROM or IO devices? --
access_check.int_bootrom_io <= '1' when (addr_i(31 downto 16) = boot_rom_base_c(31 downto 16)) else '0'; -- hacky!
access_check.int_bootrom_io <= '1' when (bus_addr_i(31 downto 16) = boot_rom_base_c(31 downto 16)) else '0'; -- hacky!
-- actual internal bus access? --
access_check.valid <= access_check.int_imem or access_check.int_dmem or access_check.int_bootrom_io;
 
 
-- Read/Write Access ----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
rw_access: process(clk_i)
begin
if rising_edge(clk_i) then
-- bus handshake --
ack_o <= wren or rden;
 
-- read access --
data_o <= (others => '0');
if (rden = '1') then
data_o(ctrl_err_type_c) <= control.err_type;
data_o(ctrl_err_src_c) <= control.int_ext;
data_o(ctrl_err_flag_c) <= err_flag;
end if;
--
if (control.bus_err = '1') then
err_flag <= '1'; -- sticky error flag
elsif (rden = '1') then -- clear on read
err_flag <= '0';
end if;
end if;
end process rw_access;
 
 
-- Keeper ---------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
keeper_control: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
control.pending <= '0';
control.pending <= '0';
control.bus_err <= '0';
control.err_type <= def_rst_val_c;
control.int_ext <= def_rst_val_c;
control.timeout <= (others => def_rst_val_c);
err_o <= '0';
elsif rising_edge(clk_i) then
-- defaults --
control.bus_err <= '0';
control.timeout <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
 
-- pending access? --
control.bus_err <= '0';
if (control.pending = '0') then -- idle
if ((rden_i or wren_i) = '1') and ((access_check.valid = '1') or (MEM_EXT_EN = false)) then -- valid INTERNAL access
-- access monitor: IDLE --
if (control.pending = '0') then
control.timeout <= std_ulogic_vector(to_unsigned(max_proc_int_response_time_c, index_size_f(max_proc_int_response_time_c)));
if (bus_rden_i = '1') or (bus_wren_i = '1') then
if (access_check.valid = '1') or (MEM_EXT_EN = false) then
control.int_ext <= '1'; -- processor-internal access
else
control.int_ext <= '0'; -- processor-external access
end if;
control.pending <= '1';
end if;
else -- pending
if (ack_i = '1') or (err_i = '1') then -- termination by bus system
control.pending <= '0';
elsif (or_reduce_f(control.timeout) = '0') then -- timeout! terminate bus transfer
control.pending <= '0';
control.bus_err <= '1';
end if;
end if;
 
-- timeout counter --
if (control.pending = '0') then
control.timeout <= std_ulogic_vector(to_unsigned(max_proc_int_response_time_c, index_size_f(max_proc_int_response_time_c)));
-- access monitor: PENDING --
else
control.timeout <= std_ulogic_vector(unsigned(control.timeout) - 1); -- countdown timer
if (bus_ack_i = '1') then -- normal termination by bus system
control.err_type <= '0'; -- don't care
control.bus_err <= '0';
control.pending <= '0';
elsif (bus_err_i = '1') then -- error termination by bus system
control.err_type <= '0'; -- device error
control.bus_err <= '1';
control.pending <= '0';
elsif (or_reduce_f(control.timeout) = '0') and (control.int_ext = '1') then -- timeout! terminate bus transfer (internal accesses only!)
control.err_type <= '1'; -- timeout error
control.bus_err <= '1';
control.pending <= '0';
end if;
end if;
 
-- only output timeout errors here - device errors are already propagated by the bus system --
err_o <= control.bus_err and control.err_type;
end if;
end process keeper_control;
 
err_o <= control.bus_err;
 
 
end neorv32_bus_keeper_rtl;
/rtl/core/neorv32_busswitch.vhd
156,7 → 156,6
 
-- Access Arbiter Sync --------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- for registers that require a specific reset state --
arbiter_sync: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
177,8 → 176,6
arbiter.bus_sel <= '0';
arbiter.we_trig <= '0';
arbiter.re_trig <= '0';
--
p_bus_src_o <= '0';
 
-- state machine --
case arbiter.state is
/rtl/core/neorv32_cpu.vhd
65,13 → 65,15
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0); -- cpu debug mode start address
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement muld/div extension?
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr : boolean; -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm : boolean; -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
170,9 → 172,11
cond_sel_string_f(CPU_EXTENSION_RISCV_M, "M", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_A, "A", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_C, "C", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_B, "B", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_U, "U", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_Zbb, "_Zbb", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_Zicsr, "_Zicsr", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_Zicntr, "_Zicntr", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_Zihpm, "_Zihpm", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_Zifencei, "_Zifencei", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_Zfinx, "_Zfinx", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_Zmmul, "_Zmmul", "") &
192,8 → 196,8
assert not (CPU_EXTENSION_RISCV_Zicsr = false) report "NEORV32 CPU CONFIG WARNING! No exception/interrupt/trap/privileged features available when <CPU_EXTENSION_RISCV_Zicsr> = false." severity warning;
 
-- CPU counters (cycle and instret) --
assert not ((CPU_CNT_WIDTH < 0) or (CPU_CNT_WIDTH > 64)) report "NEORV32 CPU CONFIG ERROR! Invalid <CPU_CNT_WIDTH> configuration. Has to be 0..64." severity error;
assert not (CPU_CNT_WIDTH < 64) report "NEORV32 CPU CONFIG WARNING! Implementing CPU <cycle> and <instret> CSRs with reduced size (" & integer'image(CPU_CNT_WIDTH) & "-bit instead of 64-bit). This is not RISC-V compliant and might have unintended SW side effects." severity warning;
assert not ((CPU_EXTENSION_RISCV_Zicntr = true) and ((CPU_CNT_WIDTH < 0) or (CPU_CNT_WIDTH > 64))) report "NEORV32 CPU CONFIG ERROR! Invalid <CPU_CNT_WIDTH> configuration. Has to be 0..64." severity error;
assert not ((CPU_EXTENSION_RISCV_Zicntr = true) and (CPU_CNT_WIDTH < 64)) report "NEORV32 CPU CONFIG WARNING! Implementing CPU <cycle> and <instret> CSRs with reduced size (" & integer'image(CPU_CNT_WIDTH) & "-bit instead of 64-bit). This is not RISC-V compliant and might have unintended SW side effects." severity warning;
 
-- U-extension requires Zicsr extension --
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true)) report "NEORV32 CPU CONFIG ERROR! User mode requires <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error;
209,14 → 213,12
-- PMP granularity --
assert not ((is_power_of_two_f(PMP_MIN_GRANULARITY) = false) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! <PMP_MIN_GRANULARITY> has to be a power of two." severity error;
assert not ((PMP_MIN_GRANULARITY < 8) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! <PMP_MIN_GRANULARITY> has to be >= 8 bytes." severity error;
-- PMP requires Zicsr extension --
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! Physical memory protection (PMP) requires <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error;
 
-- HPM counters check --
assert not (HPM_NUM_CNTS > 29) report "NEORV32 CPU CONFIG ERROR! Number of HPM counters <HPM_NUM_CNTS> out of valid range (0..29)." severity error;
assert not ((HPM_CNT_WIDTH < 0) or (HPM_CNT_WIDTH > 64)) report "NEORV32 CPU CONFIG ERROR! HPM counter width <HPM_CNT_WIDTH> has to be 0..64 bit." severity error;
-- HPM CNT requires Zicsr extension --
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (HPM_NUM_CNTS > 0)) report "NEORV32 CPU CONFIG ERROR! Hardware performance monitors (HPM) require <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error;
assert not ((CPU_EXTENSION_RISCV_Zihpm = true) and (HPM_NUM_CNTS > 29)) report "NEORV32 CPU CONFIG ERROR! Number of HPM counters <HPM_NUM_CNTS> out of valid range (0..29)." severity error;
assert not ((CPU_EXTENSION_RISCV_Zihpm = true) and ((HPM_CNT_WIDTH < 0) or (HPM_CNT_WIDTH > 64))) report "NEORV32 CPU CONFIG ERROR! HPM counter width <HPM_CNT_WIDTH> has to be 0..64 bit." severity error;
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_Zihpm = true)) report "NEORV32 CPU CONFIG ERROR! Hardware performance monitors extension <CPU_EXTENSION_RISCV_Zihpm> requires <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error;
 
-- Mul-extension --
assert not ((CPU_EXTENSION_RISCV_Zmmul = true) and (CPU_EXTENSION_RISCV_M = true)) report "NEORV32 CPU CONFIG ERROR! <M> and <Zmmul> extensions cannot co-exist!" severity error;
242,13 → 244,15
CPU_DEBUG_ADDR => CPU_DEBUG_ADDR, -- cpu debug mode start address
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr => CPU_EXTENSION_RISCV_Zicntr, -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm => CPU_EXTENSION_RISCV_Zihpm, -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG => CPU_EXTENSION_RISCV_DEBUG, -- implement CPU debug mode?
335,8 → 339,8
neorv32_cpu_alu_inst: neorv32_cpu_alu
generic map (
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
-- Extension Options --
/rtl/core/neorv32_cpu_alu.vhd
44,8 → 44,8
entity neorv32_cpu_alu is
generic (
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
-- Extension Options --
255,8 → 255,7
start_i => cp_start(0), -- trigger operation
-- data input --
rs1_i => rs1_i, -- rf source 1
rs2_i => rs2_i, -- rf source 2
imm_i => imm_i, -- immediate
shamt_i => opb(index_size_f(data_width_c)-1 downto 0), -- shift amount
-- result and status --
res_o => cp_result(0), -- operation result
valid_o => cp_valid(0) -- data output valid
274,16 → 273,16
)
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl_i, -- main control bus
start_i => cp_start(1), -- trigger operation
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl_i, -- main control bus
start_i => cp_start(1), -- trigger operation
-- data input --
rs1_i => rs1_i, -- rf source 1
rs2_i => rs2_i, -- rf source 2
rs1_i => rs1_i, -- rf source 1
rs2_i => rs2_i, -- rf source 2
-- result and status --
res_o => cp_result(1), -- operation result
valid_o => cp_valid(1) -- data output valid
res_o => cp_result(1), -- operation result
valid_o => cp_valid(1) -- data output valid
);
end generate;
 
294,10 → 293,10
end generate;
 
 
-- Co-Processor 2: Bit-Manipulation Unit ('B'/'Zbb' Extension) ----------------------------
-- Co-Processor 2: Bit-Manipulation Unit ('B' Extension) ----------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_cp_bitmanip_inst_true:
if (CPU_EXTENSION_RISCV_Zbb = true) generate
if (CPU_EXTENSION_RISCV_B = true) generate
neorv32_cpu_cp_bitmanip_inst: neorv32_cpu_cp_bitmanip
generic map (
FAST_SHIFT_EN => FAST_SHIFT_EN -- use barrel shifter for shift operations
304,22 → 303,23
)
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl_i, -- main control bus
start_i => cp_start(2), -- trigger operation
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl_i, -- main control bus
start_i => cp_start(2), -- trigger operation
-- data input --
cmp_i => cmp, -- comparator status
rs1_i => rs1_i, -- rf source 1
rs2_i => rs2_i, -- rf source 2
cmp_i => cmp, -- comparator status
rs1_i => rs1_i, -- rf source 1
rs2_i => rs2_i, -- rf source 2
shamt_i => opb(index_size_f(data_width_c)-1 downto 0), -- shift amount
-- result and status --
res_o => cp_result(2), -- operation result
valid_o => cp_valid(2) -- data output valid
res_o => cp_result(2), -- operation result
valid_o => cp_valid(2) -- data output valid
);
end generate;
 
neorv32_cpu_cp_bitmanip_inst_false:
if (CPU_EXTENSION_RISCV_Zbb = false) generate
if (CPU_EXTENSION_RISCV_B = false) generate
cp_result(2) <= (others => '0');
cp_valid(2) <= cp_start(2); -- to make sure CPU does not get stalled if there is an accidental access
end generate;
332,7 → 332,7
neorv32_cpu_cp_fpu_inst: neorv32_cpu_cp_fpu
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl_i, -- main control bus
start_i => cp_start(3), -- trigger operation
/rtl/core/neorv32_cpu_control.vhd
53,13 → 53,15
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0); -- cpu debug mode start address
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement muld/div extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr : boolean; -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm : boolean; -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
109,7 → 111,7
pmp_addr_o : out pmp_addr_if_t; -- addresses
pmp_ctrl_o : out pmp_ctrl_if_t; -- configs
-- bus access exceptions --
mar_i : in std_ulogic_vector(data_width_c-1 downto 0); -- memory address register
mar_i : in std_ulogic_vector(data_width_c-1 downto 0); -- memory address register
ma_instr_i : in std_ulogic; -- misaligned instruction address
ma_load_i : in std_ulogic; -- misaligned load data address
ma_store_i : in std_ulogic; -- misaligned store data address
196,8 → 198,8
signal decode_aux : decode_aux_t;
 
-- instruction execution engine --
type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP_ENTER, TRAP_EXIT, TRAP_EXECUTE, EXECUTE, ALU_WAIT, BRANCH,
FENCE_OP, LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYS_ENV, CSR_ACCESS);
type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP_ENTER, TRAP_EXIT, TRAP_EXECUTE, EXECUTE, ALU_WAIT,
BRANCH, LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYS_ENV, CSR_ACCESS);
type execute_engine_t is record
state : execute_engine_state_t;
state_nxt : execute_engine_state_t;
209,6 → 211,8
--
is_ci : std_ulogic; -- current instruction is de-compressed instruction
is_ci_nxt : std_ulogic;
is_ici : std_ulogic; -- current instruction is illegal de-compressed instruction
is_ici_nxt : std_ulogic;
--
branch_taken : std_ulogic; -- branch condition fulfilled
pc : std_ulogic_vector(data_width_c-1 downto 0); -- actual PC, corresponding to current executed instruction
359,10 → 363,10
signal hpmcnt_trigger : std_ulogic_vector(HPM_NUM_CNTS-1 downto 0);
 
-- illegal instruction check --
signal illegal_opcode_lsbs : std_ulogic; -- if opcode != rv32
signal illegal_opcode_lsbs : std_ulogic; -- opcode != rv32
signal illegal_instruction : std_ulogic;
signal illegal_register : std_ulogic; -- only for E-extension
signal illegal_compressed : std_ulogic; -- only fir C-extension
signal illegal_register : std_ulogic; -- illegal register (>x15) - E-extension
signal illegal_compressed : std_ulogic; -- illegal compressed instruction - C-extension
 
-- access (privilege) check --
signal csr_acc_valid : std_ulogic; -- valid CSR access (implemented and valid access rights)
489,7 → 493,7
if (rstn_i = '0') then
issue_engine.state <= ISSUE_ACTIVE;
issue_engine.align <= CPU_BOOT_ADDR(1); -- 32- or 16-bit boundary
issue_engine.buf <= (others => def_rst_val_c);
issue_engine.buf <= (others => '0');
elsif rising_edge(clk_i) then
if (ipb.clear = '1') then
if (CPU_EXTENSION_RISCV_C = true) then
557,7 → 561,7
issue_engine.buf_nxt <= ipb.rdata(33 downto 32) & ipb.rdata(31 downto 16); -- store high half-word - we might need it for an unaligned uncompressed instruction
if (issue_engine.buf(1 downto 0) = "11") then -- uncompressed and "unaligned"
ipb.re <= '1';
cmd_issue.data <= '0' & issue_engine.buf(17 downto 16) & '0' & (ipb.rdata(15 downto 0) & issue_engine.buf(15 downto 0));
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
-- do not read from ipb here!
cmd_issue.data <= ci_illegal & ipb.rdata(33 downto 32) & '1' & ci_instr32;
672,7 → 676,7
execute_engine.branch_taken <= cmp_i(cmp_less_c);
when funct3_bge_c | funct3_bgeu_c => -- branch if greater or equal (signed/unsigned)
execute_engine.branch_taken <= not cmp_i(cmp_less_c);
when others => -- undefined
when others => -- invalid
execute_engine.branch_taken <= '0';
end case;
end process branch_check;
692,6 → 696,7
execute_engine.state_prev <= SYS_WAIT; -- 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;
execute_engine.last_pc <= (others => def_rst_val_c);
execute_engine.i_reg_last <= (others => def_rst_val_c);
execute_engine.next_pc <= (others => def_rst_val_c);
716,8 → 721,9
execute_engine.state_prev <= execute_engine.state;
execute_engine.i_reg <= execute_engine.i_reg_nxt;
execute_engine.is_ci <= execute_engine.is_ci_nxt;
execute_engine.is_ici <= execute_engine.is_ici_nxt;
 
-- PC & IR of "last executed" instruction --
-- PC & IR of "last executed" instruction for trap handling --
if (execute_engine.state = EXECUTE) then
execute_engine.last_pc <= execute_engine.pc;
execute_engine.i_reg_last <= execute_engine.i_reg;
856,6 → 862,13
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "110") or -- ORN
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "100") -- XORN
)
) or
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0010000") and
(
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "010") or -- SH1ADD
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "100") or -- SH2ADD
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "110") -- SH3ADD
)
) then
decode_aux.is_bitmanip_reg <= '1';
end if;
895,6 → 908,7
execute_engine.state_nxt <= execute_engine.state;
execute_engine.i_reg_nxt <= execute_engine.i_reg;
execute_engine.is_ci_nxt <= execute_engine.is_ci;
execute_engine.is_ici_nxt <= '0';
execute_engine.sleep_nxt <= execute_engine.sleep;
execute_engine.branched_nxt <= execute_engine.branched;
--
916,7 → 930,6
trap_ctrl.instr_ma <= '0';
trap_ctrl.env_call <= '0';
trap_ctrl.break_point <= '0';
illegal_compressed <= '0';
 
-- CSR access --
csr.we_nxt <= '0';
962,13 → 975,14
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 --
trap_ctrl.instr_ma <= cmd_issue.data(33); -- misaligned instruction fetch address
trap_ctrl.instr_be <= cmd_issue.data(34); -- bus access fault during instruction fetch
illegal_compressed <= cmd_issue.data(35); -- invalid decompressed instruction
trap_ctrl.instr_ma <= cmd_issue.data(33); -- misaligned instruction fetch address
trap_ctrl.instr_be <= cmd_issue.data(34); -- bus access fault during instruction fetch
execute_engine.is_ici_nxt <= cmd_issue.data(35); -- invalid decompressed instruction
-- any reason to go to trap state? --
if (execute_engine.sleep = '1') or -- WFI instruction - this will enter sleep state
(trap_ctrl.exc_fire = '1') or -- exception during LAST instruction (illegal instruction)
(trap_ctrl.env_start = '1') or -- pending trap (IRQ or exception)
((cmd_issue.data(33) or cmd_issue.data(34)) = '1') then -- exception during instruction fetch of the CURRENT instruction
((cmd_issue.data(33) or cmd_issue.data(34)) = '1') then -- exception during instruction fetch of the NEW instruction
execute_engine.state_nxt <= TRAP_ENTER;
else
execute_engine.state_nxt <= EXECUTE;
1038,7 → 1052,7
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- use MULDIV CP
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
-- co-processor bit manipulation operation? --
elsif (CPU_EXTENSION_RISCV_Zbb = true) and
elsif (CPU_EXTENSION_RISCV_B = true) and
(((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and (decode_aux.is_bitmanip_reg = '1')) or -- register operation
((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alui_c(5)) and (decode_aux.is_bitmanip_imm = '1'))) then -- immediate operation
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_bitmanip_c; -- use BITMANIP CP
1061,7 → 1075,7
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) or -- SR shift operation?
((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')) or -- MUL
((CPU_EXTENSION_RISCV_Zbb = true) and (
((CPU_EXTENSION_RISCV_B = true) and (
((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and (decode_aux.is_bitmanip_reg = '1')) or -- BITMANIP CP register operation?
((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alui_c(5)) and (decode_aux.is_bitmanip_imm = '1'))) -- BITMANIP CP immediate operation?
) then
1088,9 → 1102,9
 
when opcode_load_c | opcode_store_c | opcode_atomic_c => -- load/store / atomic memory access
-- ------------------------------------------------------------
ctrl_nxt(ctrl_alu_opa_mux_c)<= '0'; -- use RS1 as ALU.OPA
ctrl_nxt(ctrl_alu_opb_mux_c)<= '1'; -- use IMM as ALU.OPB
ctrl_nxt(ctrl_bus_mo_we_c) <= '1'; -- write to MAR and MDO (MDO only relevant for store)
ctrl_nxt(ctrl_alu_opa_mux_c) <= '0'; -- use RS1 as ALU.OPA
ctrl_nxt(ctrl_alu_opb_mux_c) <= '1'; -- use IMM as ALU.OPB
ctrl_nxt(ctrl_bus_mo_we_c) <= '1'; -- write to MAR and MDO (MDO only relevant for store)
--
if (CPU_EXTENSION_RISCV_A = false) or -- atomic extension disabled
(execute_engine.i_reg(instr_opcode_lsb_c+3 downto instr_opcode_lsb_c+2) = "00") then -- normal integer load/store
1117,7 → 1131,18
 
when opcode_fence_c => -- fence operations
-- ------------------------------------------------------------
execute_engine.state_nxt <= FENCE_OP;
if (execute_engine.i_reg(instr_funct3_lsb_c) = funct3_fence_c(0)) then -- FENCE
ctrl_nxt(ctrl_bus_fence_c) <= '1';
execute_engine.state_nxt <= SYS_WAIT;
else -- FENCE.I
if (CPU_EXTENSION_RISCV_Zifencei = true) then
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 -- fence.i not implemented
execute_engine.state_nxt <= SYS_WAIT;
end if;
end if;
 
when opcode_syscsr_c => -- system/csr access
-- ------------------------------------------------------------
1218,6 → 1243,7
-- destination address --
execute_engine.pc_mux_sel <= '1'; -- alu.add = branch/jump destination
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
1227,30 → 1253,11
end if;
 
 
when FENCE_OP => -- fence operations - execution
-- ------------------------------------------------------------
execute_engine.state_nxt <= SYS_WAIT;
-- FENCE.I --
if (CPU_EXTENSION_RISCV_Zifencei = true) then
execute_engine.pc_mux_sel <= '0'; -- linear next PC = start *new* instruction fetch with next instruction
if (execute_engine.i_reg(instr_funct3_lsb_c) = funct3_fencei_c(0)) then
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
ctrl_nxt(ctrl_bus_fencei_c) <= '1';
end if;
end if;
-- FENCE --
if (execute_engine.i_reg(instr_funct3_lsb_c) = funct3_fence_c(0)) then
ctrl_nxt(ctrl_bus_fence_c) <= '1';
end if;
 
 
when LOADSTORE_0 => -- trigger memory request
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_lock_c) <= decode_aux.is_atomic_lr; -- atomic.LR: set lock
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or (decode_aux.is_atomic_lr = '1') then -- normal load or atomic load-reservate
ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- read request
ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- read request
else -- store
if (decode_aux.is_atomic_sc = '1') then -- evaluate lock state
if (excl_state_i = '1') then -- lock is still ok - perform write access
1366,14 → 1373,14
csr_mhpmevent15_c | csr_mhpmevent16_c | csr_mhpmevent17_c | csr_mhpmevent18_c | csr_mhpmevent19_c | csr_mhpmevent20_c |
csr_mhpmevent21_c | csr_mhpmevent22_c | csr_mhpmevent23_c | csr_mhpmevent24_c | csr_mhpmevent25_c | csr_mhpmevent26_c |
csr_mhpmevent27_c | csr_mhpmevent28_c | csr_mhpmevent29_c | csr_mhpmevent30_c | csr_mhpmevent31_c =>
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(HPM_NUM_CNTS > 0)); -- M-mode only
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zihpm); -- M-mode only
 
-- user-level counters/timers --
when csr_cycle_c | csr_cycleh_c | csr_instret_c | csr_instreth_c | csr_time_c | csr_timeh_c =>
case csr.addr(1 downto 0) is
when "00" => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- cyle[h]: M-mode, U-mode if authorized, read-only
when "01" => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- time[h]: M-mode, U-mode if authorized, read-only
when "10" => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- instret[h]: M-mode, U-mode if authorized, read-only
when "00" => csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicntr) and (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- cyle[h]: M-mode, U-mode if authorized, implemented at all, read-only
when "01" => csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicntr) and (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- time[h]: M-mode, U-mode if authorized, implemented at all, read-only
when "10" => csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicntr) and (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- instret[h]: M-mode, U-mode if authorized, implemented at all read-only
when others => csr_acc_valid <= '0';
end case;
 
1407,6 → 1414,13
illegal_opcode_lsbs <= '1';
end if;
 
-- 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
1430,7 → 1444,7
illegal_instruction <= '1';
end if;
elsif (decode_aux.is_bitmanip_reg = '1') then -- bit manipulation
if (CPU_EXTENSION_RISCV_Zbb = false) then -- not implemented
if (CPU_EXTENSION_RISCV_B = false) then -- not implemented
illegal_instruction <= '1';
end if;
elsif ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_subadd_c) or
1450,7 → 1464,7
when opcode_alui_c => -- check ALUI.funct7
-- ------------------------------------------------------------
if (decode_aux.is_bitmanip_imm = '1') then -- bit manipulation
if (CPU_EXTENSION_RISCV_Zbb = false) then -- not implemented
if (CPU_EXTENSION_RISCV_B = false) then -- not implemented
illegal_instruction <= '1';
end if;
elsif ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and
1566,7 → 1580,7
(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.priv_m_mode = '1')) or -- MRET (only allowed in 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) then -- WFI (always allowed to execute)
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_wfi_c) then -- WFI (always allowed to execute)
illegal_instruction <= '0';
else
illegal_instruction <= '1';
1602,6 → 1616,7
end case;
else
illegal_opcode_lsbs <= '0';
illegal_compressed <= '0';
illegal_instruction <= '0';
illegal_register <= '0';
end if;
1608,8 → 1623,7
end process illegal_instruction_check;
 
-- any illegal condition? --
-- ignore illegal register condition in debug mode
trap_ctrl.instr_il <= illegal_instruction or illegal_opcode_lsbs or (illegal_register and (not debug_ctrl.running)) or illegal_compressed;
trap_ctrl.instr_il <= illegal_instruction or illegal_opcode_lsbs or illegal_register or illegal_compressed;
 
 
-- ****************************************************************************************************************************
1995,7 → 2009,7
if (csr.addr(2 downto 0) = csr_mtvec_c(2 downto 0)) then
csr.mtvec <= csr.wdata(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
end if;
-- R/W: machine counter enable register --
-- R/W: mcounteren - machine counter enable register --
if (CPU_EXTENSION_RISCV_U = true) then -- this CSR is hardwired to zero if user mode is not implemented
if (csr.addr(2 downto 0) = csr_mcounteren_c(2 downto 0)) then
csr.mcounteren_cy <= csr.wdata(0); -- enable user-level access to cycle[h]
2069,8 → 2083,8
csr.mcountinhibit_hpm <= csr.wdata(csr.mcountinhibit_hpm'left+3 downto 3); -- enable auto-increment of [m]hpmcounter*[h] counter
end if;
end if;
-- machine performance-monitors event selector --
if (HPM_NUM_CNTS > 0) then
-- R/W: mhpmevent - machine performance-monitors event selector --
if (HPM_NUM_CNTS > 0) and (CPU_EXTENSION_RISCV_Zihpm = true) then
for i in 0 to HPM_NUM_CNTS-1 loop
if (csr.addr(4 downto 0) = std_ulogic_vector(to_unsigned(i+3, 5))) then
csr.mhpmevent(i) <= csr.wdata(csr.mhpmevent(i)'left downto 0);
2122,6 → 2136,7
-- mcause, mepc, mtval: write machine trap cause, PC and trap value register --
-- --------------------------------------------------------------------
if (trap_ctrl.env_start_ack = '1') then -- trap handler starting?
 
if (CPU_EXTENSION_RISCV_DEBUG = false) or ((trap_ctrl.cause(5) = '0') and -- update mtval/mepc/mcause only when NOT ENTRY debug mode exception
(debug_ctrl.running = '0')) then -- and NOT IN debug mode
 
2177,7 → 2192,8
-- mstatus: context switch --
-- --------------------------------------------------------------------
-- ENTER: trap handling starting?
if (trap_ctrl.env_start_ack = '1') then
if (trap_ctrl.env_start_ack = '1') then -- trap handler starting?
 
if (CPU_EXTENSION_RISCV_DEBUG = false) or -- normal trapping (debug mode NOT implemented)
((debug_ctrl.running = '0') and (trap_ctrl.cause(5) = '0')) then -- not IN debug mode and not ENTERING debug mode
csr.mstatus_mie <= '0'; -- disable interrupts
2310,7 → 2326,7
elsif rising_edge(clk_i) then
 
-- [m]cycle --
if (cpu_cnt_lo_width_c > 0) then
if (cpu_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then
csr.mcycle_ovfl(0) <= csr.mcycle_nxt(csr.mcycle_nxt'left);
if (csr.we = '1') and (csr.addr = csr_mcycle_c) then -- write access
csr.mcycle(cpu_cnt_lo_width_c-1 downto 0) <= csr.wdata(cpu_cnt_lo_width_c-1 downto 0);
2323,7 → 2339,7
end if;
 
-- [m]cycleh --
if (cpu_cnt_hi_width_c > 0) then
if (cpu_cnt_hi_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then
if (csr.we = '1') and (csr.addr = csr_mcycleh_c) then -- write access
csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0) <= csr.wdata(cpu_cnt_hi_width_c-1 downto 0);
elsif (csr.mcountinhibit_cy = '0') and (cnt_event(hpmcnt_event_cy_c) = '1') then -- non-inhibited automatic update
2335,7 → 2351,7
 
 
-- [m]instret --
if (cpu_cnt_lo_width_c > 0) then
if (cpu_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then
csr.minstret_ovfl(0) <= csr.minstret_nxt(csr.minstret_nxt'left);
if (csr.we = '1') and (csr.addr = csr_minstret_c) then -- write access
csr.minstret(cpu_cnt_lo_width_c-1 downto 0) <= csr.wdata(cpu_cnt_lo_width_c-1 downto 0);
2348,7 → 2364,7
end if;
 
-- [m]instreth --
if (cpu_cnt_hi_width_c > 0) then
if (cpu_cnt_hi_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then
if (csr.we = '1') and (csr.addr = csr_minstreth_c) then -- write access
csr.minstreth(cpu_cnt_hi_width_c-1 downto 0) <= csr.wdata(cpu_cnt_hi_width_c-1 downto 0);
elsif (csr.mcountinhibit_ir = '0') and (cnt_event(hpmcnt_event_ir_c) = '1') then -- non-inhibited automatic update
2363,7 → 2379,7
for i in 0 to HPM_NUM_CNTS-1 loop
 
-- [m]hpmcounter* --
if (hpm_cnt_lo_width_c > 0) then
if (hpm_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zihpm = true) then
csr.mhpmcounter_ovfl(i)(0) <= csr.mhpmcounter_nxt(i)(csr.mhpmcounter_nxt(i)'left);
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3_c) + i)) then -- write access
csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0) <= csr.wdata(hpm_cnt_lo_width_c-1 downto 0);
2376,7 → 2392,7
end if;
 
-- [m]hpmcounter*h --
if (hpm_cnt_hi_width_c > 0) then
if (hpm_cnt_hi_width_c > 0) and (CPU_EXTENSION_RISCV_Zihpm = true) then
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3h_c) + i)) then -- write access
csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0) <= csr.wdata(hpm_cnt_hi_width_c-1 downto 0);
elsif (csr.mcountinhibit_hpm(i) = '0') and (hpmcnt_trigger(i) = '1') then -- non-inhibited automatic update
2408,7 → 2424,7
begin
csr.mhpmcounter_rd <= (others => (others => '0'));
csr.mhpmcounterh_rd <= (others => (others => '0'));
if (HPM_NUM_CNTS /= 0) then
if (HPM_NUM_CNTS /= 0) and (CPU_EXTENSION_RISCV_Zihpm = true) then
for i in 0 to HPM_NUM_CNTS-1 loop
if (hpm_cnt_lo_width_c > 0) then
csr.mhpmcounter_rd(i)(hpm_cnt_lo_width_c-1 downto 0) <= csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0);
2496,6 → 2512,7
csr.rdata(12) <= csr.mstatus_mpp(1); -- MPP: machine previous privilege mode high
when csr_misa_c => -- misa (r/-): ISA and extensions
csr.rdata(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_A); -- A CPU extension
csr.rdata(01) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B); -- B CPU extension
csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension
csr.rdata(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- E CPU extension
csr.rdata(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
2638,113 → 2655,115
 
-- machine performance-monitoring event selector (r/w) --
-- --------------------------------------------------------------------
when csr_mhpmevent3_c => if (HPM_NUM_CNTS > 00) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(00); else NULL; end if;
when csr_mhpmevent4_c => if (HPM_NUM_CNTS > 01) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(01); else NULL; end if;
when csr_mhpmevent5_c => if (HPM_NUM_CNTS > 02) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(02); else NULL; end if;
when csr_mhpmevent6_c => if (HPM_NUM_CNTS > 03) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(03); else NULL; end if;
when csr_mhpmevent7_c => if (HPM_NUM_CNTS > 04) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(04); else NULL; end if;
when csr_mhpmevent8_c => if (HPM_NUM_CNTS > 05) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(05); else NULL; end if;
when csr_mhpmevent9_c => if (HPM_NUM_CNTS > 06) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(06); else NULL; end if;
when csr_mhpmevent10_c => if (HPM_NUM_CNTS > 07) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(07); else NULL; end if;
when csr_mhpmevent11_c => if (HPM_NUM_CNTS > 08) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(08); else NULL; end if;
when csr_mhpmevent12_c => if (HPM_NUM_CNTS > 09) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(09); else NULL; end if;
when csr_mhpmevent13_c => if (HPM_NUM_CNTS > 10) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(10); else NULL; end if;
when csr_mhpmevent14_c => if (HPM_NUM_CNTS > 11) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(11); else NULL; end if;
when csr_mhpmevent15_c => if (HPM_NUM_CNTS > 12) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(12); else NULL; end if;
when csr_mhpmevent16_c => if (HPM_NUM_CNTS > 13) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(13); else NULL; end if;
when csr_mhpmevent17_c => if (HPM_NUM_CNTS > 14) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(14); else NULL; end if;
when csr_mhpmevent18_c => if (HPM_NUM_CNTS > 15) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(15); else NULL; end if;
when csr_mhpmevent19_c => if (HPM_NUM_CNTS > 16) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(16); else NULL; end if;
when csr_mhpmevent20_c => if (HPM_NUM_CNTS > 17) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(17); else NULL; end if;
when csr_mhpmevent21_c => if (HPM_NUM_CNTS > 18) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(18); else NULL; end if;
when csr_mhpmevent22_c => if (HPM_NUM_CNTS > 19) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(19); else NULL; end if;
when csr_mhpmevent23_c => if (HPM_NUM_CNTS > 20) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(20); else NULL; end if;
when csr_mhpmevent24_c => if (HPM_NUM_CNTS > 21) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(21); else NULL; end if;
when csr_mhpmevent25_c => if (HPM_NUM_CNTS > 22) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(22); else NULL; end if;
when csr_mhpmevent26_c => if (HPM_NUM_CNTS > 23) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(23); else NULL; end if;
when csr_mhpmevent27_c => if (HPM_NUM_CNTS > 24) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(24); else NULL; end if;
when csr_mhpmevent28_c => if (HPM_NUM_CNTS > 25) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(25); else NULL; end if;
when csr_mhpmevent29_c => if (HPM_NUM_CNTS > 26) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(26); else NULL; end if;
when csr_mhpmevent30_c => if (HPM_NUM_CNTS > 27) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(27); else NULL; end if;
when csr_mhpmevent31_c => if (HPM_NUM_CNTS > 28) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(28); else NULL; end if;
when csr_mhpmevent3_c => if (HPM_NUM_CNTS > 00) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(00); else NULL; end if;
when csr_mhpmevent4_c => if (HPM_NUM_CNTS > 01) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(01); else NULL; end if;
when csr_mhpmevent5_c => if (HPM_NUM_CNTS > 02) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(02); else NULL; end if;
when csr_mhpmevent6_c => if (HPM_NUM_CNTS > 03) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(03); else NULL; end if;
when csr_mhpmevent7_c => if (HPM_NUM_CNTS > 04) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(04); else NULL; end if;
when csr_mhpmevent8_c => if (HPM_NUM_CNTS > 05) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(05); else NULL; end if;
when csr_mhpmevent9_c => if (HPM_NUM_CNTS > 06) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(06); else NULL; end if;
when csr_mhpmevent10_c => if (HPM_NUM_CNTS > 07) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(07); else NULL; end if;
when csr_mhpmevent11_c => if (HPM_NUM_CNTS > 08) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(08); else NULL; end if;
when csr_mhpmevent12_c => if (HPM_NUM_CNTS > 09) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(09); else NULL; end if;
when csr_mhpmevent13_c => if (HPM_NUM_CNTS > 10) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(10); else NULL; end if;
when csr_mhpmevent14_c => if (HPM_NUM_CNTS > 11) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(11); else NULL; end if;
when csr_mhpmevent15_c => if (HPM_NUM_CNTS > 12) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(12); else NULL; end if;
when csr_mhpmevent16_c => if (HPM_NUM_CNTS > 13) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(13); else NULL; end if;
when csr_mhpmevent17_c => if (HPM_NUM_CNTS > 14) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(14); else NULL; end if;
when csr_mhpmevent18_c => if (HPM_NUM_CNTS > 15) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(15); else NULL; end if;
when csr_mhpmevent19_c => if (HPM_NUM_CNTS > 16) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(16); else NULL; end if;
when csr_mhpmevent20_c => if (HPM_NUM_CNTS > 17) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(17); else NULL; end if;
when csr_mhpmevent21_c => if (HPM_NUM_CNTS > 18) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(18); else NULL; end if;
when csr_mhpmevent22_c => if (HPM_NUM_CNTS > 19) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(19); else NULL; end if;
when csr_mhpmevent23_c => if (HPM_NUM_CNTS > 20) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(20); else NULL; end if;
when csr_mhpmevent24_c => if (HPM_NUM_CNTS > 21) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(21); else NULL; end if;
when csr_mhpmevent25_c => if (HPM_NUM_CNTS > 22) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(22); else NULL; end if;
when csr_mhpmevent26_c => if (HPM_NUM_CNTS > 23) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(23); else NULL; end if;
when csr_mhpmevent27_c => if (HPM_NUM_CNTS > 24) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(24); else NULL; end if;
when csr_mhpmevent28_c => if (HPM_NUM_CNTS > 25) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(25); else NULL; end if;
when csr_mhpmevent29_c => if (HPM_NUM_CNTS > 26) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(26); else NULL; end if;
when csr_mhpmevent30_c => if (HPM_NUM_CNTS > 27) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(27); else NULL; end if;
when csr_mhpmevent31_c => if (HPM_NUM_CNTS > 28) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(28); else NULL; end if;
 
-- counters and timers --
-- --------------------------------------------------------------------
when csr_cycle_c | csr_mcycle_c => -- [m]cycle (r/w): Cycle counter LOW
if (cpu_cnt_lo_width_c > 0) then csr.rdata(cpu_cnt_lo_width_c-1 downto 0) <= csr.mcycle(cpu_cnt_lo_width_c-1 downto 0); else NULL; end if;
if (cpu_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then csr.rdata(cpu_cnt_lo_width_c-1 downto 0) <= csr.mcycle(cpu_cnt_lo_width_c-1 downto 0); else NULL; end if;
when csr_cycleh_c | csr_mcycleh_c => -- [m]cycleh (r/w): Cycle counter HIGH
if (cpu_cnt_hi_width_c > 0) then csr.rdata(cpu_cnt_hi_width_c-1 downto 0) <= csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0); else NULL; end if;
if (cpu_cnt_hi_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then csr.rdata(cpu_cnt_hi_width_c-1 downto 0) <= csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0); else NULL; end if;
 
when csr_instret_c | csr_minstret_c => -- [m]instret (r/w): Instructions-retired counter LOW
if (cpu_cnt_lo_width_c > 0) then csr.rdata(cpu_cnt_lo_width_c-1 downto 0) <= csr.minstret(cpu_cnt_lo_width_c-1 downto 0); else NULL; end if;
if (cpu_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then csr.rdata(cpu_cnt_lo_width_c-1 downto 0) <= csr.minstret(cpu_cnt_lo_width_c-1 downto 0); else NULL; end if;
when csr_instreth_c | csr_minstreth_c => -- [m]instreth (r/w): Instructions-retired counter HIGH
if (cpu_cnt_hi_width_c > 0) then csr.rdata(cpu_cnt_hi_width_c-1 downto 0) <= csr.minstreth(cpu_cnt_hi_width_c-1 downto 0); else NULL; end if;
if (cpu_cnt_hi_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then csr.rdata(cpu_cnt_hi_width_c-1 downto 0) <= csr.minstreth(cpu_cnt_hi_width_c-1 downto 0); else NULL; end if;
 
when csr_time_c => csr.rdata <= time_i(31 downto 0); -- time (r/-): System time LOW (from MTIME unit)
when csr_timeh_c => csr.rdata <= time_i(63 downto 32); -- timeh (r/-): System time HIGH (from MTIME unit)
when csr_time_c => -- time (r/-): System time LOW (from MTIME unit)
if (CPU_EXTENSION_RISCV_Zicntr = true) then csr.rdata <= time_i(31 downto 00); else NULL; end if;
when csr_timeh_c => -- timeh (r/-): System time HIGH (from MTIME unit)
if (CPU_EXTENSION_RISCV_Zicntr = true) then csr.rdata <= time_i(63 downto 32); else NULL; end if;
 
-- hardware performance counters --
-- --------------------------------------------------------------------
-- low word (r/w) --
when csr_mhpmcounter3_c => if (HPM_NUM_CNTS > 00) then csr.rdata <= csr.mhpmcounter_rd(00); else NULL; end if;
when csr_mhpmcounter4_c => if (HPM_NUM_CNTS > 01) then csr.rdata <= csr.mhpmcounter_rd(01); else NULL; end if;
when csr_mhpmcounter5_c => if (HPM_NUM_CNTS > 02) then csr.rdata <= csr.mhpmcounter_rd(02); else NULL; end if;
when csr_mhpmcounter6_c => if (HPM_NUM_CNTS > 03) then csr.rdata <= csr.mhpmcounter_rd(03); else NULL; end if;
when csr_mhpmcounter7_c => if (HPM_NUM_CNTS > 04) then csr.rdata <= csr.mhpmcounter_rd(04); else NULL; end if;
when csr_mhpmcounter8_c => if (HPM_NUM_CNTS > 05) then csr.rdata <= csr.mhpmcounter_rd(05); else NULL; end if;
when csr_mhpmcounter9_c => if (HPM_NUM_CNTS > 06) then csr.rdata <= csr.mhpmcounter_rd(06); else NULL; end if;
when csr_mhpmcounter10_c => if (HPM_NUM_CNTS > 07) then csr.rdata <= csr.mhpmcounter_rd(07); else NULL; end if;
when csr_mhpmcounter11_c => if (HPM_NUM_CNTS > 08) then csr.rdata <= csr.mhpmcounter_rd(08); else NULL; end if;
when csr_mhpmcounter12_c => if (HPM_NUM_CNTS > 09) then csr.rdata <= csr.mhpmcounter_rd(09); else NULL; end if;
when csr_mhpmcounter13_c => if (HPM_NUM_CNTS > 10) then csr.rdata <= csr.mhpmcounter_rd(10); else NULL; end if;
when csr_mhpmcounter14_c => if (HPM_NUM_CNTS > 11) then csr.rdata <= csr.mhpmcounter_rd(11); else NULL; end if;
when csr_mhpmcounter15_c => if (HPM_NUM_CNTS > 12) then csr.rdata <= csr.mhpmcounter_rd(12); else NULL; end if;
when csr_mhpmcounter16_c => if (HPM_NUM_CNTS > 13) then csr.rdata <= csr.mhpmcounter_rd(13); else NULL; end if;
when csr_mhpmcounter17_c => if (HPM_NUM_CNTS > 14) then csr.rdata <= csr.mhpmcounter_rd(14); else NULL; end if;
when csr_mhpmcounter18_c => if (HPM_NUM_CNTS > 15) then csr.rdata <= csr.mhpmcounter_rd(15); else NULL; end if;
when csr_mhpmcounter19_c => if (HPM_NUM_CNTS > 16) then csr.rdata <= csr.mhpmcounter_rd(16); else NULL; end if;
when csr_mhpmcounter20_c => if (HPM_NUM_CNTS > 17) then csr.rdata <= csr.mhpmcounter_rd(17); else NULL; end if;
when csr_mhpmcounter21_c => if (HPM_NUM_CNTS > 18) then csr.rdata <= csr.mhpmcounter_rd(18); else NULL; end if;
when csr_mhpmcounter22_c => if (HPM_NUM_CNTS > 19) then csr.rdata <= csr.mhpmcounter_rd(19); else NULL; end if;
when csr_mhpmcounter23_c => if (HPM_NUM_CNTS > 20) then csr.rdata <= csr.mhpmcounter_rd(20); else NULL; end if;
when csr_mhpmcounter24_c => if (HPM_NUM_CNTS > 21) then csr.rdata <= csr.mhpmcounter_rd(21); else NULL; end if;
when csr_mhpmcounter25_c => if (HPM_NUM_CNTS > 22) then csr.rdata <= csr.mhpmcounter_rd(22); else NULL; end if;
when csr_mhpmcounter26_c => if (HPM_NUM_CNTS > 23) then csr.rdata <= csr.mhpmcounter_rd(23); else NULL; end if;
when csr_mhpmcounter27_c => if (HPM_NUM_CNTS > 24) then csr.rdata <= csr.mhpmcounter_rd(24); else NULL; end if;
when csr_mhpmcounter28_c => if (HPM_NUM_CNTS > 25) then csr.rdata <= csr.mhpmcounter_rd(25); else NULL; end if;
when csr_mhpmcounter29_c => if (HPM_NUM_CNTS > 26) then csr.rdata <= csr.mhpmcounter_rd(26); else NULL; end if;
when csr_mhpmcounter30_c => if (HPM_NUM_CNTS > 27) then csr.rdata <= csr.mhpmcounter_rd(27); else NULL; end if;
when csr_mhpmcounter31_c => if (HPM_NUM_CNTS > 28) then csr.rdata <= csr.mhpmcounter_rd(28); else NULL; end if;
when csr_mhpmcounter3_c => if (HPM_NUM_CNTS > 00) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(00); else NULL; end if;
when csr_mhpmcounter4_c => if (HPM_NUM_CNTS > 01) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(01); else NULL; end if;
when csr_mhpmcounter5_c => if (HPM_NUM_CNTS > 02) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(02); else NULL; end if;
when csr_mhpmcounter6_c => if (HPM_NUM_CNTS > 03) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(03); else NULL; end if;
when csr_mhpmcounter7_c => if (HPM_NUM_CNTS > 04) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(04); else NULL; end if;
when csr_mhpmcounter8_c => if (HPM_NUM_CNTS > 05) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(05); else NULL; end if;
when csr_mhpmcounter9_c => if (HPM_NUM_CNTS > 06) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(06); else NULL; end if;
when csr_mhpmcounter10_c => if (HPM_NUM_CNTS > 07) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(07); else NULL; end if;
when csr_mhpmcounter11_c => if (HPM_NUM_CNTS > 08) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(08); else NULL; end if;
when csr_mhpmcounter12_c => if (HPM_NUM_CNTS > 09) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(09); else NULL; end if;
when csr_mhpmcounter13_c => if (HPM_NUM_CNTS > 10) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(10); else NULL; end if;
when csr_mhpmcounter14_c => if (HPM_NUM_CNTS > 11) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(11); else NULL; end if;
when csr_mhpmcounter15_c => if (HPM_NUM_CNTS > 12) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(12); else NULL; end if;
when csr_mhpmcounter16_c => if (HPM_NUM_CNTS > 13) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(13); else NULL; end if;
when csr_mhpmcounter17_c => if (HPM_NUM_CNTS > 14) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(14); else NULL; end if;
when csr_mhpmcounter18_c => if (HPM_NUM_CNTS > 15) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(15); else NULL; end if;
when csr_mhpmcounter19_c => if (HPM_NUM_CNTS > 16) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(16); else NULL; end if;
when csr_mhpmcounter20_c => if (HPM_NUM_CNTS > 17) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(17); else NULL; end if;
when csr_mhpmcounter21_c => if (HPM_NUM_CNTS > 18) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(18); else NULL; end if;
when csr_mhpmcounter22_c => if (HPM_NUM_CNTS > 19) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(19); else NULL; end if;
when csr_mhpmcounter23_c => if (HPM_NUM_CNTS > 20) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(20); else NULL; end if;
when csr_mhpmcounter24_c => if (HPM_NUM_CNTS > 21) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(21); else NULL; end if;
when csr_mhpmcounter25_c => if (HPM_NUM_CNTS > 22) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(22); else NULL; end if;
when csr_mhpmcounter26_c => if (HPM_NUM_CNTS > 23) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(23); else NULL; end if;
when csr_mhpmcounter27_c => if (HPM_NUM_CNTS > 24) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(24); else NULL; end if;
when csr_mhpmcounter28_c => if (HPM_NUM_CNTS > 25) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(25); else NULL; end if;
when csr_mhpmcounter29_c => if (HPM_NUM_CNTS > 26) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(26); else NULL; end if;
when csr_mhpmcounter30_c => if (HPM_NUM_CNTS > 27) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(27); else NULL; end if;
when csr_mhpmcounter31_c => if (HPM_NUM_CNTS > 28) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(28); else NULL; end if;
-- high word (r/w) --
when csr_mhpmcounter3h_c => if (HPM_NUM_CNTS > 00) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(00); else NULL; end if;
when csr_mhpmcounter4h_c => if (HPM_NUM_CNTS > 01) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(01); else NULL; end if;
when csr_mhpmcounter5h_c => if (HPM_NUM_CNTS > 02) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(02); else NULL; end if;
when csr_mhpmcounter6h_c => if (HPM_NUM_CNTS > 03) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(03); else NULL; end if;
when csr_mhpmcounter7h_c => if (HPM_NUM_CNTS > 04) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(04); else NULL; end if;
when csr_mhpmcounter8h_c => if (HPM_NUM_CNTS > 05) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(05); else NULL; end if;
when csr_mhpmcounter9h_c => if (HPM_NUM_CNTS > 06) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(06); else NULL; end if;
when csr_mhpmcounter10h_c => if (HPM_NUM_CNTS > 07) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(07); else NULL; end if;
when csr_mhpmcounter11h_c => if (HPM_NUM_CNTS > 08) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(08); else NULL; end if;
when csr_mhpmcounter12h_c => if (HPM_NUM_CNTS > 09) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(09); else NULL; end if;
when csr_mhpmcounter13h_c => if (HPM_NUM_CNTS > 10) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(10); else NULL; end if;
when csr_mhpmcounter14h_c => if (HPM_NUM_CNTS > 11) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(11); else NULL; end if;
when csr_mhpmcounter15h_c => if (HPM_NUM_CNTS > 12) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(12); else NULL; end if;
when csr_mhpmcounter16h_c => if (HPM_NUM_CNTS > 13) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(13); else NULL; end if;
when csr_mhpmcounter17h_c => if (HPM_NUM_CNTS > 14) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(14); else NULL; end if;
when csr_mhpmcounter18h_c => if (HPM_NUM_CNTS > 15) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(15); else NULL; end if;
when csr_mhpmcounter19h_c => if (HPM_NUM_CNTS > 16) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(16); else NULL; end if;
when csr_mhpmcounter20h_c => if (HPM_NUM_CNTS > 17) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(17); else NULL; end if;
when csr_mhpmcounter21h_c => if (HPM_NUM_CNTS > 18) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(18); else NULL; end if;
when csr_mhpmcounter22h_c => if (HPM_NUM_CNTS > 19) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(19); else NULL; end if;
when csr_mhpmcounter23h_c => if (HPM_NUM_CNTS > 20) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(20); else NULL; end if;
when csr_mhpmcounter24h_c => if (HPM_NUM_CNTS > 21) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(21); else NULL; end if;
when csr_mhpmcounter25h_c => if (HPM_NUM_CNTS > 22) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(22); else NULL; end if;
when csr_mhpmcounter26h_c => if (HPM_NUM_CNTS > 23) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(23); else NULL; end if;
when csr_mhpmcounter27h_c => if (HPM_NUM_CNTS > 24) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(24); else NULL; end if;
when csr_mhpmcounter28h_c => if (HPM_NUM_CNTS > 25) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(25); else NULL; end if;
when csr_mhpmcounter29h_c => if (HPM_NUM_CNTS > 26) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(26); else NULL; end if;
when csr_mhpmcounter30h_c => if (HPM_NUM_CNTS > 27) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(27); else NULL; end if;
when csr_mhpmcounter31h_c => if (HPM_NUM_CNTS > 28) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(28); else NULL; end if;
when csr_mhpmcounter3h_c => if (HPM_NUM_CNTS > 00) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(00); else NULL; end if;
when csr_mhpmcounter4h_c => if (HPM_NUM_CNTS > 01) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(01); else NULL; end if;
when csr_mhpmcounter5h_c => if (HPM_NUM_CNTS > 02) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(02); else NULL; end if;
when csr_mhpmcounter6h_c => if (HPM_NUM_CNTS > 03) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(03); else NULL; end if;
when csr_mhpmcounter7h_c => if (HPM_NUM_CNTS > 04) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(04); else NULL; end if;
when csr_mhpmcounter8h_c => if (HPM_NUM_CNTS > 05) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(05); else NULL; end if;
when csr_mhpmcounter9h_c => if (HPM_NUM_CNTS > 06) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(06); else NULL; end if;
when csr_mhpmcounter10h_c => if (HPM_NUM_CNTS > 07) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(07); else NULL; end if;
when csr_mhpmcounter11h_c => if (HPM_NUM_CNTS > 08) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(08); else NULL; end if;
when csr_mhpmcounter12h_c => if (HPM_NUM_CNTS > 09) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(09); else NULL; end if;
when csr_mhpmcounter13h_c => if (HPM_NUM_CNTS > 10) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(10); else NULL; end if;
when csr_mhpmcounter14h_c => if (HPM_NUM_CNTS > 11) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(11); else NULL; end if;
when csr_mhpmcounter15h_c => if (HPM_NUM_CNTS > 12) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(12); else NULL; end if;
when csr_mhpmcounter16h_c => if (HPM_NUM_CNTS > 13) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(13); else NULL; end if;
when csr_mhpmcounter17h_c => if (HPM_NUM_CNTS > 14) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(14); else NULL; end if;
when csr_mhpmcounter18h_c => if (HPM_NUM_CNTS > 15) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(15); else NULL; end if;
when csr_mhpmcounter19h_c => if (HPM_NUM_CNTS > 16) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(16); else NULL; end if;
when csr_mhpmcounter20h_c => if (HPM_NUM_CNTS > 17) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(17); else NULL; end if;
when csr_mhpmcounter21h_c => if (HPM_NUM_CNTS > 18) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(18); else NULL; end if;
when csr_mhpmcounter22h_c => if (HPM_NUM_CNTS > 19) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(19); else NULL; end if;
when csr_mhpmcounter23h_c => if (HPM_NUM_CNTS > 20) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(20); else NULL; end if;
when csr_mhpmcounter24h_c => if (HPM_NUM_CNTS > 21) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(21); else NULL; end if;
when csr_mhpmcounter25h_c => if (HPM_NUM_CNTS > 22) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(22); else NULL; end if;
when csr_mhpmcounter26h_c => if (HPM_NUM_CNTS > 23) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(23); else NULL; end if;
when csr_mhpmcounter27h_c => if (HPM_NUM_CNTS > 24) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(24); else NULL; end if;
when csr_mhpmcounter28h_c => if (HPM_NUM_CNTS > 25) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(25); else NULL; end if;
when csr_mhpmcounter29h_c => if (HPM_NUM_CNTS > 26) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(26); else NULL; end if;
when csr_mhpmcounter30h_c => if (HPM_NUM_CNTS > 27) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(27); else NULL; end if;
when csr_mhpmcounter31h_c => if (HPM_NUM_CNTS > 28) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(28); else NULL; end if;
 
-- machine information registers --
-- --------------------------------------------------------------------
/rtl/core/neorv32_cpu_cp_bitmanip.vhd
7,6 → 7,7
-- # fixed value of 3 cycles latency (using barrel shifters). #
-- # #
-- # Supported sub-extensions (Zb*): #
-- # - Zba: Address generation instructions #
-- # - Zbb: Basic bit-manipulation instructions #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
61,6 → 62,7
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
shamt_i : in std_ulogic_vector(index_size_f(data_width_c)-1 downto 0); -- shift amount
-- result and status --
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result
valid_o : out std_ulogic -- data output valid
69,31 → 71,40
 
architecture neorv32_cpu_cp_bitmanip_rtl of neorv32_cpu_cp_bitmanip is
 
-- commands: logic with negate --
constant op_andn_c : natural := 0;
constant op_orn_c : natural := 1;
constant op_xnor_c : natural := 2;
-- commands: count leading/trailing zero bits --
constant op_clz_c : natural := 3;
constant op_ctz_c : natural := 4;
-- commands: count population --
constant op_cpop_c : natural := 5;
-- commands: integer minimum/maximum --
constant op_max_c : natural := 6; -- signed/unsigned
constant op_min_c : natural := 7; -- signed/unsigned
-- commands: sign- and zero-extension --
constant op_sextb_c : natural := 8;
constant op_sexth_c : natural := 9;
constant op_zexth_c : natural := 10;
-- commands: bitwise rotation --
constant op_rol_c : natural := 11;
constant op_ror_c : natural := 12; -- rori
-- commands: or-combine --
constant op_orcb_c : natural := 13;
-- commands: byte-reverse --
constant op_rev8_c : natural := 14;
-- Sub-extension configuration --
constant zbb_en_c : boolean := true;
constant zba_en_c : boolean := true;
-- --------------------------- --
 
-- commands: Zbb - logic with negate --
constant op_andn_c : natural := 0;
constant op_orn_c : natural := 1;
constant op_xnor_c : natural := 2;
-- commands: Zbb - count leading/trailing zero bits --
constant op_clz_c : natural := 3;
constant op_ctz_c : natural := 4;
-- commands: Zbb - count population --
constant op_cpop_c : natural := 5;
-- commands: Zbb - integer minimum/maximum --
constant op_max_c : natural := 6; -- signed/unsigned
constant op_min_c : natural := 7; -- signed/unsigned
-- commands: Zbb - sign- and zero-extension --
constant op_sextb_c : natural := 8;
constant op_sexth_c : natural := 9;
constant op_zexth_c : natural := 10;
-- commands: Zbb - bitwise rotation --
constant op_rol_c : natural := 11;
constant op_ror_c : natural := 12; -- rori
-- commands: Zbb - or-combine --
constant op_orcb_c : natural := 13;
-- commands: Zbb - byte-reverse --
constant op_rev8_c : natural := 14;
-- commands: Zba - shifted add --
constant op_sh1add_c : natural := 15;
constant op_sh2add_c : natural := 16;
constant op_sh3add_c : natural := 17;
--
constant op_width_c : natural := 15;
constant op_width_c : natural := 18;
 
-- controller --
type ctrl_state_t is (S_IDLE, S_START_SHIFT, S_BUSY_SHIFT);
104,11 → 115,9
-- operand buffers --
signal rs1_reg : std_ulogic_vector(data_width_c-1 downto 0);
signal rs2_reg : std_ulogic_vector(data_width_c-1 downto 0);
signal sha_reg : std_ulogic_vector(index_size_f(data_width_c)-1 downto 0);
signal less_ff : std_ulogic;
 
-- shift amount (immediate or register) --
signal shamt : std_ulogic_vector(index_size_f(data_width_c)-1 downto 0);
 
-- serial shifter --
type shifter_t is record
start : std_ulogic;
128,8 → 137,21
type res_t is array (0 to op_width_c-1) of std_ulogic_vector(data_width_c-1 downto 0);
signal res_int, res_out : res_t;
 
-- shifted-add unit --
signal adder_core : std_ulogic_vector(data_width_c-1 downto 0);
 
begin
 
-- Sub-Extension Configuration ------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert false report
"Implementing bit-manipulation (B) sub-extensions: " &
cond_sel_string_f(zbb_en_c, "Zbb", "") &
cond_sel_string_f(zba_en_c, "Zba", "") &
""
severity note;
 
 
-- Instruction Decoding (One-Hot) ---------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- a minimal decoding logic is used here -> just to distinguish between B.Zbb instructions
136,26 → 158,31
-- a more specific decoding and instruction check is done by the CPU control unit
 
-- Zbb - Basic bit-manipulation instructions --
cmd(op_andn_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "11") else '0';
cmd(op_orn_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "10") else '0';
cmd(op_xnor_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "00") else '0';
cmd(op_andn_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "11") else '0';
cmd(op_orn_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "10") else '0';
cmd(op_xnor_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "00") else '0';
--
cmd(op_max_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '1') and (ctrl_i(ctrl_ir_funct3_1_c) = '1') else '0';
cmd(op_min_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '1') and (ctrl_i(ctrl_ir_funct3_1_c) = '0') else '0';
cmd(op_zexth_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '0') else '0';
cmd(op_max_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '1') and (ctrl_i(ctrl_ir_funct3_1_c) = '1') else '0';
cmd(op_min_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '1') and (ctrl_i(ctrl_ir_funct3_1_c) = '0') else '0';
cmd(op_zexth_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '0') else '0';
--
cmd(op_orcb_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "01") else '0';
cmd(op_orcb_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "01") and (ctrl_i(ctrl_ir_funct12_7_c) = '1') else '0';
--
cmd(op_clz_c) <= '1' when (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 (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 (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") else '0';
cmd(op_sextb_c) <= '1' when (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 (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_rol_c) <= '1' when (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 (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_rev8_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '1') else '0';
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") 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_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_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') else '0';
 
-- Zba - Address generation instructions --
cmd(op_sh1add_c) <= '1' when (zba_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "01") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_1_c) = "01") else '0';
cmd(op_sh2add_c) <= '1' when (zba_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "01") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_1_c) = "10") else '0';
cmd(op_sh3add_c) <= '1' when (zba_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "01") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_1_c) = "11") else '0';
 
 
-- Co-Processor Controller ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
coprocessor_ctrl: process(rstn_i, clk_i)
165,6 → 192,7
cmd_buf <= (others => def_rst_val_c);
rs1_reg <= (others => def_rst_val_c);
rs2_reg <= (others => def_rst_val_c);
sha_reg <= (others => def_rst_val_c);
less_ff <= def_rst_val_c;
shifter.start <= '0';
valid <= '0';
183,6 → 211,7
cmd_buf <= cmd;
rs1_reg <= rs1_i;
rs2_reg <= rs2_i;
sha_reg <= shamt_i;
if ((cmd(op_clz_c) or cmd(op_ctz_c) or cmd(op_cpop_c) or cmd(op_ror_c) or cmd(op_rol_c)) = '1') then -- multi-cycle shift operation
if (FAST_SHIFT_EN = false) then -- default: iterative computation
shifter.start <= '1';
216,13 → 245,6
end process coprocessor_ctrl;
 
 
-- Shift Amount ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- we could also use ALU's internal operand B - but we are having a local version here in order to allow
-- better logic combination inside the ALU (since that is the critical path of the CPU)
shamt <= ctrl_i(ctrl_ir_funct12_0_c+shamt'left downto ctrl_ir_funct12_0_c) when (ctrl_i(ctrl_ir_opcode7_5_c) = '0') else rs2_reg(shamt'left downto 0);
 
 
-- Shifter Function Core (iterative: small but slow) --------------------------------------
-- -------------------------------------------------------------------------------------------
serial_shifter:
249,7 → 271,7
shifter.cnt_max <= (others => '0');
shifter.cnt_max(shifter.cnt_max'left) <= '1';
else
shifter.cnt_max <= '0' & shamt;
shifter.cnt_max <= '0' & sha_reg;
end if;
shifter.bcnt <= (others => '0');
elsif (shifter.run = '1') then -- right shifts only
313,7 → 335,7
-- barrel shifter array --
barrel_shifter_async:
if (FAST_SHIFT_EN = true) generate
shifter_unit_async: process(rs1_reg, shamt, cmd_buf, bs_level)
shifter_unit_async: process(rs1_reg, sha_reg, cmd_buf, bs_level)
begin
-- input level: convert left shifts to right shifts --
if (cmd_buf(op_rol_c) = '1') then -- is left shift?
324,7 → 346,7
 
-- shifter array --
for i in index_size_f(data_width_c)-1 downto 0 loop
if (shamt(i) = '1') then
if (sha_reg(i) = '1') then
bs_level(i)(data_width_c-1 downto data_width_c-(2**i)) <= bs_level(i+1)((2**i)-1 downto 0);
bs_level(i)((data_width_c-(2**i))-1 downto 0) <= bs_level(i+1)(data_width_c-1 downto 2**i);
else
335,6 → 357,21
end generate;
 
 
-- Shifted-Add Core -----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
shift_adder: process(rs1_reg, rs2_reg, ctrl_i)
variable opb_v : std_ulogic_vector(data_width_c-1 downto 0);
begin
case ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_1_c) is
when "01" => opb_v := rs1_reg(rs1_reg'left-1 downto 0) & '0'; -- << 1
when "10" => opb_v := rs1_reg(rs1_reg'left-2 downto 0) & "00"; -- << 2
when "11" => opb_v := rs1_reg(rs1_reg'left-3 downto 0) & "000"; -- << 3
when others => opb_v := rs1_reg(rs1_reg'left-1 downto 0) & '0'; -- undefined
end case;
adder_core <= std_ulogic_vector(unsigned(rs2_reg) + unsigned(opb_v));
end process shift_adder;
 
 
-- Operation Results ----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- logic with negate --
376,7 → 413,12
-- reversal.8 (byte swap) --
res_int(op_rev8_c) <= bswap32_f(rs1_reg);
 
-- address generation instructions --
res_int(op_sh1add_c) <= adder_core;
res_int(op_sh2add_c) <= (others => '0'); -- unused/redundant
res_int(op_sh3add_c) <= (others => '0'); -- unused/redundant
 
 
-- Output Selector ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
res_out(op_andn_c) <= res_int(op_andn_c) when (cmd_buf(op_andn_c) = '1') else (others => '0');
394,6 → 436,10
res_out(op_rol_c) <= res_int(op_rol_c) when (cmd_buf(op_rol_c) = '1') else (others => '0');
res_out(op_orcb_c) <= res_int(op_orcb_c) when (cmd_buf(op_orcb_c) = '1') else (others => '0');
res_out(op_rev8_c) <= res_int(op_rev8_c) when (cmd_buf(op_rev8_c) = '1') else (others => '0');
--
res_out(op_sh1add_c) <= res_int(op_sh1add_c) when ((cmd_buf(op_sh1add_c) or cmd_buf(op_sh2add_c) or cmd_buf(op_sh3add_c)) = '1') else (others => '0');
res_out(op_sh2add_c) <= (others => '0'); -- unused/redundant
res_out(op_sh3add_c) <= (others => '0'); -- unused/redundant
 
 
-- Output Gate ----------------------------------------------------------------------------
410,7 → 456,8
res_out(op_min_c) or -- res_out(op_max_c) is unused here
res_out(op_sextb_c) or res_out(op_sexth_c) or res_out(op_zexth_c) or
res_out(op_ror_c) or res_out(op_rol_c) or
res_out(op_orcb_c) or res_out(op_rev8_c);
res_out(op_orcb_c) or res_out(op_rev8_c) or
res_out(op_sh1add_c); -- res_out(op_sh2add_c) and res_out(op_sh3add_c) are unused here
end if;
end if;
end process output_gate;
/rtl/core/neorv32_cpu_cp_shifter.vhd
55,8 → 55,7
start_i : in std_ulogic; -- trigger operation
-- data input --
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
imm_i : in std_ulogic_vector(data_width_c-1 downto 0); -- immediate
shamt_i : in std_ulogic_vector(index_size_f(data_width_c)-1 downto 0); -- shift amount
-- result and status --
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result
valid_o : out std_ulogic -- data output valid
65,9 → 64,6
 
architecture neorv32_cpu_cp_shifter_rtl of neorv32_cpu_cp_shifter is
 
-- operands --
signal shift_amount : std_ulogic_vector(index_size_f(data_width_c)-1 downto 0);
 
-- serial shifter --
type shifter_t is record
busy : std_ulogic;
75,6 → 71,7
done : std_ulogic;
cnt : std_ulogic_vector(index_size_f(data_width_c)-1 downto 0);
sreg : std_ulogic_vector(data_width_c-1 downto 0);
res : std_ulogic_vector(data_width_c-1 downto 0);
end record;
signal shifter : shifter_t;
 
85,12 → 82,6
 
begin
 
-- Shift Amount ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
shift_amount <= imm_i(index_size_f(data_width_c)-1 downto 0) when (ctrl_i(ctrl_alu_opb_mux_c) = '1') else -- immediate source
rs2_i(index_size_f(data_width_c)-1 downto 0); -- register source
 
 
-- Iterative Shifter Core (small but slow) ------------------------------------------------
-- -------------------------------------------------------------------------------------------
serial_shifter_sync:
112,7 → 103,7
--
if (start_i = '1') then -- trigger new shift
shifter.sreg <= rs1_i; -- shift operand
shifter.cnt <= shift_amount; -- shift amount
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
125,7 → 116,7
end process shifter_unit_sync;
end generate;
 
-- shift control --
-- 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));
138,7 → 129,7
-- -------------------------------------------------------------------------------------------
barrel_shifter_async:
if (FAST_SHIFT_EN = true) generate
shifter_unit_async: process(rs1_i, shift_amount, ctrl_i, bs_level)
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?
149,7 → 140,7
 
-- shifter array --
for i in index_size_f(data_width_c)-1 downto 0 loop
if (shift_amount(i) = '1') then
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-(2**i))-1 downto 0) <= bs_level(i+1)(data_width_c-1 downto 2**i);
else
180,7 → 171,7
end process shifter_unit_sync;
end generate;
 
-- shift control --
-- shift control/output --
barrel_shifter_ctrl:
if (FAST_SHIFT_EN = true) generate
valid_o <= start_i;
/rtl/core/neorv32_gpio.vhd
66,6 → 66,8
-- access control --
signal acc_en : std_ulogic; -- module access enable
signal addr : std_ulogic_vector(31 downto 0); -- access address
signal wren : std_ulogic; -- word write enable
signal rden : std_ulogic; -- read enable
 
-- accessible regs --
signal din_lo, din_hi : std_ulogic_vector(31 downto 0); -- r/-
77,6 → 79,8
-- -------------------------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = gpio_base_c(hi_abb_c downto lo_abb_c)) else '0';
addr <= gpio_base_c(31 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 2) & "00"; -- word aligned
wren <= acc_en and wren_i;
rden <= acc_en and rden_i;
 
 
-- Read/Write Access ----------------------------------------------------------------------
85,10 → 89,10
begin
if rising_edge(clk_i) then
-- bus handshake --
ack_o <= acc_en and (rden_i or wren_i);
ack_o <= wren or rden;
 
-- write access --
if ((acc_en and wren_i) = '1') then
if (wren = '1') then
if (addr = gpio_out_lo_addr_c) then
dout_lo <= data_i;
end if;
103,13 → 107,12
 
-- read access --
data_o <= (others => '0');
if ((acc_en and rden_i) = '1') then
case addr is
when gpio_in_lo_addr_c => data_o <= din_lo;
when gpio_in_hi_addr_c => data_o <= din_hi;
when gpio_out_lo_addr_c => data_o <= dout_lo;
when gpio_out_hi_addr_c => data_o <= dout_hi;
when others => data_o <= (others => '0');
if (rden = '1') then
case addr(3 downto 2) is
when "00" => data_o <= din_lo;
when "01" => data_o <= din_hi;
when "10" => data_o <= dout_lo;
when others => data_o <= dout_hi;
end case;
end if;
 
/rtl/core/neorv32_mtime.vhd
69,6 → 69,7
signal acc_en : std_ulogic; -- module access enable
signal addr : std_ulogic_vector(31 downto 0); -- access address
signal wren : std_ulogic; -- module access enable
signal rden : std_ulogic; -- read enable
 
-- time write access buffer --
signal mtime_lo_we : std_ulogic;
95,6 → 96,7
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = mtime_base_c(hi_abb_c downto lo_abb_c)) else '0';
addr <= mtime_base_c(31 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 2) & "00"; -- word aligned
wren <= acc_en and wren_i;
rden <= acc_en and rden_i;
 
 
-- Write Access ---------------------------------------------------------------------------
143,18 → 145,14
rd_access: process(clk_i)
begin
if rising_edge(clk_i) then
ack_o <= acc_en and (rden_i or wren_i);
ack_o <= rden or wren;
data_o <= (others => '0'); -- default
if (rden_i = '1') and (acc_en = '1') then
case addr is
when mtime_time_lo_addr_c => -- mtime LOW
data_o <= mtime_lo;
when mtime_time_hi_addr_c => -- mtime HIGH
data_o <= mtime_hi;
when mtime_cmp_lo_addr_c => -- mtimecmp LOW
data_o <= mtimecmp_lo;
when others => -- mtime_cmp_hi_addr_c -- mtimecmp HIGH
data_o <= mtimecmp_hi;
if (rden = '1') then
case addr(3 downto 2) is
when "00" => data_o <= mtime_lo; -- mtime LOW
when "01" => data_o <= mtime_hi; -- mtime HIGH
when "10" => data_o <= mtimecmp_lo; -- mtimecmp LOW
when others => data_o <= mtimecmp_hi; -- mtimecmp HIGH
end case;
end if;
end if;
/rtl/core/neorv32_package.vhd
45,8 → 45,8
constant dspace_base_c : std_ulogic_vector(31 downto 0) := x"80000000"; -- default data memory address space base address
 
-- CPU core --
constant dedicated_reset_c : boolean := false; -- use dedicated hardware reset value for UNCRITICAL registers (FALSE=reset value is irrelevant (might simplify HW), default; TRUE=defined LOW reset value)
constant cp_timeout_en_c : boolean := false; -- auto-terminate pending co-processor operations after 256 cycles (for debugging only), default = false
constant dedicated_reset_c : boolean := false; -- use dedicated hardware reset value for UNCRITICAL registers (FALSE=reset value is irrelevant (might simplify HW), default; TRUE=defined LOW reset value)
 
-- "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
64,7 → 64,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"01060202"; -- no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01060300"; -- no touchy!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
 
-- External Interface Types ---------------------------------------------------------------
217,8 → 217,12
 
-- reserved --
--constant reserved_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff78"; -- base address
--constant reserved_size_c : natural := 2*4; -- module's address space size in bytes
--constant reserved_size_c : natural := 1*4; -- module's address space size in bytes
 
-- Bus Access Monitor (BUSKEEPER) --
constant buskeeper_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff7c"; -- base address
constant buskeeper_size_c : natural := 1*4; -- module's address space size in bytes
 
-- External Interrupt Controller (XIRQ) --
constant xirq_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff80"; -- base address
constant xirq_size_c : natural := 4*4; -- module's address space size in bytes
423,7 → 427,7
-- 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) --
constant opcode_fop_c : std_ulogic_vector(6 downto 0) := "1010011"; -- dual/single opearand instruction
constant opcode_fop_c : std_ulogic_vector(6 downto 0) := "1010011"; -- dual/single operand instruction
 
-- RISC-V Funct3 --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
462,7 → 466,7
constant funct3_csrrci_c : std_ulogic_vector(2 downto 0) := "111"; -- atomic read & clear bit immediate
-- fence --
constant funct3_fence_c : std_ulogic_vector(2 downto 0) := "000"; -- fence - order IO/memory access (->NOP)
constant funct3_fencei_c : std_ulogic_vector(2 downto 0) := "001"; -- fencei - instructon stream sync
constant funct3_fencei_c : std_ulogic_vector(2 downto 0) := "001"; -- fencei - instruction stream sync
 
-- RISC-V Funct12 -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
899,13 → 903,15
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr : boolean := true; -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm : boolean := false; -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
-- Extension Options --
1049,13 → 1055,15
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0); -- cpu debug mode start address
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr : boolean; -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm : boolean; -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
1123,13 → 1131,15
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0); -- cpu debug mode start address
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr : boolean; -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm : boolean; -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
1213,8 → 1223,8
component neorv32_cpu_alu
generic (
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
-- Extension Options --
1256,8 → 1266,7
start_i : in std_ulogic; -- trigger operation
-- data input --
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
imm_i : in std_ulogic_vector(data_width_c-1 downto 0); -- immediate
shamt_i : in std_ulogic_vector(index_size_f(data_width_c)-1 downto 0); -- shift amount
-- result and status --
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result
valid_o : out std_ulogic -- data output valid
1290,7 → 1299,7
-- -------------------------------------------------------------------------------------------
component neorv32_cpu_cp_bitmanip is
generic (
FAST_SHIFT_EN : boolean -- use barrel shifter for shift operations
FAST_SHIFT_EN : boolean -- use barrel shifter for shift operations
);
port (
-- global control --
1302,6 → 1311,7
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
shamt_i : in std_ulogic_vector(index_size_f(data_width_c)-1 downto 0); -- shift amount
-- result and status --
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result
valid_o : out std_ulogic -- data output valid
1405,14 → 1415,20
);
port (
-- host access --
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active
addr_i : in std_ulogic_vector(31 downto 0); -- address
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
ack_i : in std_ulogic; -- transfer acknowledge from bus system
err_i : in std_ulogic; -- transfer error from bus system
err_o : out std_ulogic -- bus error
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset, low-active, async
addr_i : in std_ulogic_vector(31 downto 0); -- address
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic; -- transfer acknowledge
err_o : out std_ulogic; -- transfer error
-- bus monitoring --
bus_addr_i : in std_ulogic_vector(31 downto 0); -- address
bus_rden_i : in std_ulogic; -- read enable
bus_wren_i : in std_ulogic; -- write enable
bus_ack_i : in std_ulogic; -- transfer acknowledge from bus system
bus_err_i : in std_ulogic -- transfer error from bus system
);
end component;
 
1903,9 → 1919,10
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr : boolean; -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm : boolean; -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
1915,8 → 1932,6
CPU_CNT_WIDTH : natural; -- total width of CPU cycle and instret counters (0..64)
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS : natural; -- number of regions (0..64)
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural; -- number of implemented HPM counters (0..29)
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural; -- size of processor-internal instruction memory in bytes
/rtl/core/neorv32_pwm.vhd
116,7 → 116,7
wr_access: process(clk_i)
begin
if rising_edge(clk_i) then
ack_o <= acc_en and (rden_i or wren_i);
ack_o <= rden or wren;
 
-- write access --
if (wren = '1') then
187,11 → 187,6
 
-- channels --
for i in 0 to NUM_CHANNELS-1 loop
--if (pwm_cnt = pwm_ch(i)) or (pwm_ch(i) = x"00") or (enable = '0') then
-- pwm_o(i) <= '0';
--elsif (pwm_cnt = x"00") then
-- pwm_o(i) <= '1';
--end if;
if (unsigned(pwm_cnt) >= unsigned(pwm_ch(i))) or (enable = '0') then
pwm_o(i) <= '0';
else
/rtl/core/neorv32_spi.vhd
73,25 → 73,25
constant lo_abb_c : natural := index_size_f(spi_size_c); -- low address boundary bit
 
-- control register --
constant ctrl_spi_cs0_c : natural := 0; -- r/w: spi CS 0
constant ctrl_spi_cs1_c : natural := 1; -- r/w: spi CS 1
constant ctrl_spi_cs2_c : natural := 2; -- r/w: spi CS 2
constant ctrl_spi_cs3_c : natural := 3; -- r/w: spi CS 3
constant ctrl_spi_cs4_c : natural := 4; -- r/w: spi CS 4
constant ctrl_spi_cs5_c : natural := 5; -- r/w: spi CS 5
constant ctrl_spi_cs6_c : natural := 6; -- r/w: spi CS 6
constant ctrl_spi_cs7_c : natural := 7; -- r/w: spi CS 7
constant ctrl_cs0_c : natural := 0; -- r/w: spi CS 0
constant ctrl_cs1_c : natural := 1; -- r/w: spi CS 1
constant ctrl_cs2_c : natural := 2; -- r/w: spi CS 2
constant ctrl_cs3_c : natural := 3; -- r/w: spi CS 3
constant ctrl_cs4_c : natural := 4; -- r/w: spi CS 4
constant ctrl_cs5_c : natural := 5; -- r/w: spi CS 5
constant ctrl_cs6_c : natural := 6; -- r/w: spi CS 6
constant ctrl_cs7_c : natural := 7; -- r/w: spi CS 7
--
constant ctrl_spi_en_c : natural := 8; -- r/w: spi enable
constant ctrl_spi_cpha_c : natural := 9; -- r/w: spi clock phase
constant ctrl_spi_prsc0_c : natural := 10; -- r/w: spi prescaler select bit 0
constant ctrl_spi_prsc1_c : natural := 11; -- r/w: spi prescaler select bit 1
constant ctrl_spi_prsc2_c : natural := 12; -- r/w: spi prescaler select bit 2
constant ctrl_spi_size0_c : natural := 13; -- r/w: data size (00: 8-bit, 01: 16-bit)
constant ctrl_spi_size1_c : natural := 14; -- r/w: data size (10: 24-bit, 11: 32-bit)
constant ctrl_spi_cpol_c : natural := 15; -- r/w: spi clock polarity
constant ctrl_en_c : natural := 8; -- r/w: spi enable
constant ctrl_cpha_c : natural := 9; -- r/w: spi clock phase
constant ctrl_prsc0_c : natural := 10; -- r/w: spi prescaler select bit 0
constant ctrl_prsc1_c : natural := 11; -- r/w: spi prescaler select bit 1
constant ctrl_prsc2_c : natural := 12; -- r/w: spi prescaler select bit 2
constant ctrl_size0_c : natural := 13; -- r/w: data size lsb (00: 8-bit, 01: 16-bit)
constant ctrl_size1_c : natural := 14; -- r/w: data size msb (10: 24-bit, 11: 32-bit)
constant ctrl_cpol_c : natural := 15; -- r/w: spi clock polarity
--
constant ctrl_spi_busy_c : natural := 31; -- r/-: spi transceiver is busy
constant ctrl_busy_c : natural := 31; -- r/-: spi transceiver is busy
--
signal ctrl : std_ulogic_vector(15 downto 0);
 
106,14 → 106,13
 
-- spi transceiver --
type rtx_engine_t is record
state : std_ulogic_vector(02 downto 0);
busy : std_ulogic;
state0 : std_ulogic;
state1 : std_ulogic;
rtx_sreg : std_ulogic_vector(31 downto 0);
start : std_ulogic;
sreg : std_ulogic_vector(31 downto 0);
bitcnt : std_ulogic_vector(05 downto 0);
bytecnt : std_ulogic_vector(02 downto 0);
sdi_ff0 : std_ulogic;
sdi_ff1 : std_ulogic;
sdi_sync : std_ulogic_vector(01 downto 0);
end record;
signal rtx_engine : rtx_engine_t;
 
138,23 → 137,23
-- write access --
if (wren = '1') then
if (addr = spi_ctrl_addr_c) then -- control register
ctrl(ctrl_spi_cs0_c) <= data_i(ctrl_spi_cs0_c);
ctrl(ctrl_spi_cs1_c) <= data_i(ctrl_spi_cs1_c);
ctrl(ctrl_spi_cs2_c) <= data_i(ctrl_spi_cs2_c);
ctrl(ctrl_spi_cs3_c) <= data_i(ctrl_spi_cs3_c);
ctrl(ctrl_spi_cs4_c) <= data_i(ctrl_spi_cs4_c);
ctrl(ctrl_spi_cs5_c) <= data_i(ctrl_spi_cs5_c);
ctrl(ctrl_spi_cs6_c) <= data_i(ctrl_spi_cs6_c);
ctrl(ctrl_spi_cs7_c) <= data_i(ctrl_spi_cs7_c);
ctrl(ctrl_cs0_c) <= data_i(ctrl_cs0_c);
ctrl(ctrl_cs1_c) <= data_i(ctrl_cs1_c);
ctrl(ctrl_cs2_c) <= data_i(ctrl_cs2_c);
ctrl(ctrl_cs3_c) <= data_i(ctrl_cs3_c);
ctrl(ctrl_cs4_c) <= data_i(ctrl_cs4_c);
ctrl(ctrl_cs5_c) <= data_i(ctrl_cs5_c);
ctrl(ctrl_cs6_c) <= data_i(ctrl_cs6_c);
ctrl(ctrl_cs7_c) <= data_i(ctrl_cs7_c);
--
ctrl(ctrl_spi_en_c) <= data_i(ctrl_spi_en_c);
ctrl(ctrl_spi_cpha_c) <= data_i(ctrl_spi_cpha_c);
ctrl(ctrl_spi_prsc0_c) <= data_i(ctrl_spi_prsc0_c);
ctrl(ctrl_spi_prsc1_c) <= data_i(ctrl_spi_prsc1_c);
ctrl(ctrl_spi_prsc2_c) <= data_i(ctrl_spi_prsc2_c);
ctrl(ctrl_spi_size0_c) <= data_i(ctrl_spi_size0_c);
ctrl(ctrl_spi_size1_c) <= data_i(ctrl_spi_size1_c);
ctrl(ctrl_spi_cpol_c) <= data_i(ctrl_spi_cpol_c);
ctrl(ctrl_en_c) <= data_i(ctrl_en_c);
ctrl(ctrl_cpha_c) <= data_i(ctrl_cpha_c);
ctrl(ctrl_prsc0_c) <= data_i(ctrl_prsc0_c);
ctrl(ctrl_prsc1_c) <= data_i(ctrl_prsc1_c);
ctrl(ctrl_prsc2_c) <= data_i(ctrl_prsc2_c);
ctrl(ctrl_size0_c) <= data_i(ctrl_size0_c);
ctrl(ctrl_size1_c) <= data_i(ctrl_size1_c);
ctrl(ctrl_cpol_c) <= data_i(ctrl_cpol_c);
end if;
end if;
 
162,27 → 161,27
data_o <= (others => '0');
if (rden = '1') then
if (addr = spi_ctrl_addr_c) then -- control register
data_o(ctrl_spi_cs0_c) <= ctrl(ctrl_spi_cs0_c);
data_o(ctrl_spi_cs1_c) <= ctrl(ctrl_spi_cs1_c);
data_o(ctrl_spi_cs2_c) <= ctrl(ctrl_spi_cs2_c);
data_o(ctrl_spi_cs3_c) <= ctrl(ctrl_spi_cs3_c);
data_o(ctrl_spi_cs4_c) <= ctrl(ctrl_spi_cs4_c);
data_o(ctrl_spi_cs5_c) <= ctrl(ctrl_spi_cs5_c);
data_o(ctrl_spi_cs6_c) <= ctrl(ctrl_spi_cs6_c);
data_o(ctrl_spi_cs7_c) <= ctrl(ctrl_spi_cs7_c);
data_o(ctrl_cs0_c) <= ctrl(ctrl_cs0_c);
data_o(ctrl_cs1_c) <= ctrl(ctrl_cs1_c);
data_o(ctrl_cs2_c) <= ctrl(ctrl_cs2_c);
data_o(ctrl_cs3_c) <= ctrl(ctrl_cs3_c);
data_o(ctrl_cs4_c) <= ctrl(ctrl_cs4_c);
data_o(ctrl_cs5_c) <= ctrl(ctrl_cs5_c);
data_o(ctrl_cs6_c) <= ctrl(ctrl_cs6_c);
data_o(ctrl_cs7_c) <= ctrl(ctrl_cs7_c);
--
data_o(ctrl_spi_en_c) <= ctrl(ctrl_spi_en_c);
data_o(ctrl_spi_cpha_c) <= ctrl(ctrl_spi_cpha_c);
data_o(ctrl_spi_prsc0_c) <= ctrl(ctrl_spi_prsc0_c);
data_o(ctrl_spi_prsc1_c) <= ctrl(ctrl_spi_prsc1_c);
data_o(ctrl_spi_prsc2_c) <= ctrl(ctrl_spi_prsc2_c);
data_o(ctrl_spi_size0_c) <= ctrl(ctrl_spi_size0_c);
data_o(ctrl_spi_size1_c) <= ctrl(ctrl_spi_size1_c);
data_o(ctrl_spi_cpol_c) <= ctrl(ctrl_spi_cpol_c);
data_o(ctrl_en_c) <= ctrl(ctrl_en_c);
data_o(ctrl_cpha_c) <= ctrl(ctrl_cpha_c);
data_o(ctrl_prsc0_c) <= ctrl(ctrl_prsc0_c);
data_o(ctrl_prsc1_c) <= ctrl(ctrl_prsc1_c);
data_o(ctrl_prsc2_c) <= ctrl(ctrl_prsc2_c);
data_o(ctrl_size0_c) <= ctrl(ctrl_size0_c);
data_o(ctrl_size1_c) <= ctrl(ctrl_size1_c);
data_o(ctrl_cpol_c) <= ctrl(ctrl_cpol_c);
--
data_o(ctrl_spi_busy_c) <= rtx_engine.busy;
data_o(ctrl_busy_c) <= rtx_engine.busy;
else -- data register (spi_rtx_addr_c)
data_o <= rtx_engine.rtx_sreg;
data_o <= rtx_engine.sreg;
end if;
end if;
end if;
189,14 → 188,23
end process rw_access;
 
-- direct chip-select (CS), output is low-active --
spi_csn_o(7 downto 0) <= not ctrl(ctrl_spi_cs7_c downto ctrl_spi_cs0_c);
spi_csn_o(7 downto 0) <= not ctrl(ctrl_cs7_c downto ctrl_cs0_c);
 
-- trigger new SPI transmission --
rtx_engine.start <= '1' when (wren = '1') and (addr = spi_rtx_addr_c) else '0';
 
 
-- Clock Selection ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
clkgen_en_o <= ctrl(ctrl_en_c); -- clock generator enable
spi_clk_en <= clkgen_i(to_integer(unsigned(ctrl(ctrl_prsc2_c downto ctrl_prsc0_c)))); -- clock select
 
 
-- Transmission Data Size -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
data_size: process(ctrl)
begin
case ctrl(ctrl_spi_size1_c downto ctrl_spi_size0_c) is
case ctrl(ctrl_size1_c downto ctrl_size0_c) is
when "00" => rtx_engine.bytecnt <= "001"; -- 1-byte mode
when "01" => rtx_engine.bytecnt <= "010"; -- 2-byte mode
when "10" => rtx_engine.bytecnt <= "011"; -- 3-byte mode
205,12 → 213,6
end process data_size;
 
 
-- Clock Selection ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
clkgen_en_o <= ctrl(ctrl_spi_en_c); -- clock generator enable
spi_clk_en <= clkgen_i(to_integer(unsigned(ctrl(ctrl_spi_prsc2_c downto ctrl_spi_prsc0_c)))); -- clock select
 
 
-- SPI Transceiver ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
spi_rtx_unit: process(clk_i)
217,69 → 219,72
begin
if rising_edge(clk_i) then
-- input (sdi) synchronizer --
rtx_engine.sdi_ff0 <= spi_sdi_i;
rtx_engine.sdi_ff1 <= rtx_engine.sdi_ff0;
rtx_engine.sdi_sync <= rtx_engine.sdi_sync(0) & spi_sdi_i;
 
-- output (sdo) buffer --
case ctrl(ctrl_size1_c downto ctrl_size0_c) is
when "00" => spi_sdo_o <= rtx_engine.sreg(07); -- 8-bit mode
when "01" => spi_sdo_o <= rtx_engine.sreg(15); -- 16-bit mode
when "10" => spi_sdo_o <= rtx_engine.sreg(23); -- 24-bit mode
when others => spi_sdo_o <= rtx_engine.sreg(31); -- 32-bit mode
end case;
 
-- defaults --
spi_sck_o <= ctrl(ctrl_cpol_c);
 
-- serial engine --
if (rtx_engine.state0 = '0') or (ctrl(ctrl_spi_en_c) = '0') then -- idle or disabled
-- --------------------------------------------------------------
spi_sck_o <= ctrl(ctrl_spi_cpol_c);
rtx_engine.bitcnt <= (others => '0');
rtx_engine.state1 <= '0';
if (ctrl(ctrl_spi_en_c) = '0') then -- disabled
rtx_engine.busy <= '0';
elsif (wren = '1') and (addr = spi_rtx_addr_c) then -- start new transmission
rtx_engine.rtx_sreg <= data_i;
rtx_engine.busy <= '1';
end if;
rtx_engine.state0 <= rtx_engine.busy and spi_clk_en; -- start with next new clock pulse
rtx_engine.state(2) <= ctrl(ctrl_en_c);
case rtx_engine.state is
 
else -- transmission in progress
-- --------------------------------------------------------------
when "100" => -- enabled but idle, waiting for new transmission trigger
-- ------------------------------------------------------------
rtx_engine.bitcnt <= (others => '0');
if (rtx_engine.start = '1') then -- trigger new transmission
rtx_engine.sreg <= data_i;
rtx_engine.state(1 downto 0) <= "01";
end if;
 
if (rtx_engine.state1 = '0') then -- first half of bit transmission
-- --------------------------------------------------------------
spi_sck_o <= ctrl(ctrl_spi_cpha_c) xor ctrl(ctrl_spi_cpol_c);
--
case ctrl(ctrl_spi_size1_c downto ctrl_spi_size0_c) is
when "00" => spi_sdo_o <= rtx_engine.rtx_sreg(07); -- 8-bit mode
when "01" => spi_sdo_o <= rtx_engine.rtx_sreg(15); -- 16-bit mode
when "10" => spi_sdo_o <= rtx_engine.rtx_sreg(23); -- 24-bit mode
when others => spi_sdo_o <= rtx_engine.rtx_sreg(31); -- 32-bit mode
end case;
--
when "101" => -- start with next new clock pulse
-- ------------------------------------------------------------
if (spi_clk_en = '1') then
if (ctrl(ctrl_spi_cpha_c) = '0') then
rtx_engine.rtx_sreg <= rtx_engine.rtx_sreg(30 downto 0) & rtx_engine.sdi_ff1;
end if;
rtx_engine.state(1 downto 0) <= "10";
end if;
 
when "110" => -- first half of bit transmission
-- ------------------------------------------------------------
spi_sck_o <= ctrl(ctrl_cpha_c) xor ctrl(ctrl_cpol_c);
if (spi_clk_en = '1') then
rtx_engine.bitcnt <= std_ulogic_vector(unsigned(rtx_engine.bitcnt) + 1);
rtx_engine.state1 <= '1';
rtx_engine.state(1 downto 0) <= "11";
end if;
 
else -- second half of bit transmission
-- --------------------------------------------------------------
spi_sck_o <= ctrl(ctrl_spi_cpha_c) xnor ctrl(ctrl_spi_cpol_c);
--
when "111" => -- second half of bit transmission
-- ------------------------------------------------------------
spi_sck_o <= ctrl(ctrl_cpha_c) xnor ctrl(ctrl_cpol_c);
if (spi_clk_en = '1') then
if (ctrl(ctrl_spi_cpha_c) = '1') then
rtx_engine.rtx_sreg <= rtx_engine.rtx_sreg(30 downto 0) & rtx_engine.sdi_ff1;
rtx_engine.sreg <= rtx_engine.sreg(30 downto 0) & rtx_engine.sdi_sync(rtx_engine.sdi_sync'left);
if (rtx_engine.bitcnt(5 downto 3) = rtx_engine.bytecnt) then -- all bits transferred?
rtx_engine.state(1 downto 0) <= "00";
else
rtx_engine.state(1 downto 0) <= "10";
end if;
if (rtx_engine.bitcnt(5 downto 3) = rtx_engine.bytecnt) then
rtx_engine.state0 <= '0';
rtx_engine.busy <= '0';
end if;
rtx_engine.state1 <= '0';
end if;
 
end if;
end if;
when others => -- "0--": SPI deactivated
-- ------------------------------------------------------------
rtx_engine.state(1 downto 0) <= "00";
 
end case;
end if;
end process spi_rtx_unit;
 
-- busy flag --
rtx_engine.busy <= '0' when (rtx_engine.state(1 downto 0) = "00") else '1';
 
 
-- Interrupt ------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
irq_o <= ctrl(ctrl_spi_en_c) and (not rtx_engine.busy); -- fire IRQ if transceiver idle
irq_o <= '1' when (rtx_engine.state = "100") else '0'; -- fire IRQ if transceiver idle and enabled
 
 
end neorv32_spi_rtl;
/rtl/core/neorv32_sysinfo.vhd
48,9 → 48,10
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr : boolean; -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm : boolean; -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
60,8 → 61,6
CPU_CNT_WIDTH : natural; -- total width of CPU cycle and instret counters (0..64)
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS : natural; -- number of regions (0..64)
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural; -- number of implemented HPM counters (0..29)
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural; -- size of processor-internal instruction memory in bytes
139,14 → 138,14
sysinfo_mem(1)(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr); -- Zicsr
sysinfo_mem(1)(01) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Zifencei
sysinfo_mem(1)(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zmmul); -- Zmmul
sysinfo_mem(1)(03) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zbb); -- Zbb
--
sysinfo_mem(1)(04) <= '0'; -- reserved
sysinfo_mem(1)(04 downto 03) <= (others => '0'); -- reserved
--
sysinfo_mem(1)(05) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- Zfinx ("F-alternative")
sysinfo_mem(1)(07 downto 06) <= "00" when (CPU_CNT_WIDTH = 64) else "10" when (CPU_CNT_WIDTH = 0) else "01"; -- CPU counter size: Zxscnt | Zxnocnt
sysinfo_mem(1)(06) <= bool_to_ulogic_f(boolean(CPU_CNT_WIDTH /= 64)); -- reduced-size CPU counters (Zxscnt)
sysinfo_mem(1)(07) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicntr); -- base CPU counter
sysinfo_mem(1)(08) <= bool_to_ulogic_f(boolean(PMP_NUM_REGIONS > 0)); -- PMP (physical memory protection)
sysinfo_mem(1)(09) <= bool_to_ulogic_f(boolean(HPM_NUM_CNTS > 0)); -- HPM (hardware performance monitors)
sysinfo_mem(1)(09) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zihpm); -- HPM (hardware performance monitors)
sysinfo_mem(1)(10) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG); -- RISC-V debug mode
--
sysinfo_mem(1)(29 downto 11) <= (others => '0'); -- reserved
/rtl/core/neorv32_top.vhd
1,10 → 1,6
-- #################################################################################################
-- # << NEORV32 - Processor Top Entity >> #
-- # << The NEORV32 RISC-V Processor - Top Entity >> #
-- # ********************************************************************************************* #
-- # This is the top entity of the NEORV32 PROCESSOR. Instantiate this unit in your own project #
-- # and define all the configuration generics according to your needs or use one of the #
-- # pre-defined template wrappers. #
-- # #
-- # Check out the processor's online documentation for more information: #
-- # HQ: https://github.com/stnolting/neorv32 #
-- # Data Sheet: https://stnolting.github.io/neorv32 #
60,13 → 56,15
 
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr : boolean := true; -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm : boolean := false; -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
 
309,7 → 307,7
constant resp_bus_entry_terminate_c : resp_bus_entry_t := (rdata => (others => '0'), ack => '0', err => '0');
 
-- module response bus - device ID --
type resp_bus_id_t is (RESP_IMEM, RESP_DMEM, RESP_BOOTROM, RESP_WISHBONE, RESP_GPIO, RESP_MTIME, RESP_UART0, RESP_UART1, RESP_SPI,
type resp_bus_id_t is (RESP_BUSKEEPER, RESP_IMEM, RESP_DMEM, RESP_BOOTROM, RESP_WISHBONE, RESP_GPIO, RESP_MTIME, RESP_UART0, RESP_UART1, RESP_SPI,
RESP_TWI, RESP_PWM, RESP_WDT, RESP_TRNG, RESP_CFS, RESP_NEOLED, RESP_SYSINFO, RESP_OCD, RESP_SLINK, RESP_XIRQ);
 
-- module response bus --
333,8 → 331,7
signal xirq_irq : std_ulogic;
 
-- misc --
signal mtime_time : std_ulogic_vector(63 downto 0); -- current system time from MTIME
signal bus_keeper_err : std_ulogic; -- bus keeper: bus access timeout
signal mtime_time : std_ulogic_vector(63 downto 0); -- current system time from MTIME
 
begin
 
456,13 → 453,15
CPU_DEBUG_ADDR => dm_base_c, -- cpu debug mode start address
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr => CPU_EXTENSION_RISCV_Zicntr, -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm => CPU_EXTENSION_RISCV_Zihpm, -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG => ON_CHIP_DEBUGGER_EN, -- implement CPU debug mode?
530,21 → 529,21
-- fast interrupts --
fast_irq(00) <= wdt_irq; -- HIGHEST PRIORITY - watchdog timeout
fast_irq(01) <= cfs_irq; -- custom functions subsystem
fast_irq(02) <= uart0_rxd_irq; -- primary UART (UART0) data received
fast_irq(03) <= uart0_txd_irq; -- primary UART (UART0) sending done
fast_irq(04) <= uart1_rxd_irq; -- secondary UART (UART1) data received
fast_irq(05) <= uart1_txd_irq; -- secondary UART (UART1) sending done
fast_irq(06) <= spi_irq; -- SPI transmission done
fast_irq(07) <= twi_irq; -- TWI transmission done
fast_irq(02) <= uart0_rxd_irq; -- primary UART (UART0) RX interrupt
fast_irq(03) <= uart0_txd_irq; -- primary UART (UART0) TX interrupt
fast_irq(04) <= uart1_rxd_irq; -- secondary UART (UART1) RX interrupt
fast_irq(05) <= uart1_txd_irq; -- secondary UART (UART1) TX interrupt
fast_irq(06) <= spi_irq; -- SPI idle
fast_irq(07) <= twi_irq; -- TWI idle
fast_irq(08) <= xirq_irq; -- external interrupt controller
fast_irq(09) <= neoled_irq; -- NEOLED buffer free
fast_irq(10) <= slink_rx_irq; -- SLINK data received
fast_irq(11) <= slink_tx_irq; -- SLINK data send
fast_irq(10) <= slink_rx_irq; -- SLINK RX interrupt
fast_irq(11) <= slink_tx_irq; -- SLINK TX interrupt
--
fast_irq(12) <= '0'; -- reserved
fast_irq(13) <= '0'; -- reserved
fast_irq(14) <= '0'; -- reserved
fast_irq(15) <= '0'; -- reserved
fast_irq(15) <= '0'; -- LOWEST PRIORITY - reserved
 
 
-- CPU Instruction Cache ------------------------------------------------------------------
650,7 → 649,7
p_bus.fence <= cpu_d.fence or cpu_i.fence;
 
-- bus response --
bus_response: process(resp_bus, bus_keeper_err)
bus_response: process(resp_bus)
variable rdata_v : std_ulogic_vector(data_width_c-1 downto 0);
variable ack_v : std_ulogic;
variable err_v : std_ulogic;
665,11 → 664,11
end loop; -- i
p_bus.rdata <= rdata_v; -- processor bus: CPU transfer data input
p_bus.ack <= ack_v; -- processor bus: CPU transfer ACK input
p_bus.err <= err_v or bus_keeper_err; -- processor bus: CPU transfer data bus error input
p_bus.err <= err_v; -- processor bus: CPU transfer data bus error input
end process;
 
 
-- Processor-Internal Bus Keeper (BUS_KEEPER) ---------------------------------------------
-- Bus Keeper (BUSKEEPER) -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_bus_keeper_inst: neorv32_bus_keeper
generic map (
684,14 → 683,20
)
port map (
-- host access --
clk_i => clk_i, -- global clock line
rstn_i => sys_rstn, -- global reset line, low-active
addr_i => p_bus.addr, -- address
rden_i => p_bus.re, -- read enable
wren_i => p_bus.we, -- write enable
ack_i => p_bus.ack, -- transfer acknowledge from bus system
err_i => p_bus.err, -- transfer error from bus system
err_o => bus_keeper_err -- bus error
clk_i => clk_i, -- global clock line
rstn_i => sys_rstn, -- global reset line, low-active, use as async
addr_i => p_bus.addr, -- address
rden_i => io_rden, -- read enable
wren_i => io_wren, -- byte write enable
data_o => resp_bus(RESP_BUSKEEPER).rdata, -- data out
ack_o => resp_bus(RESP_BUSKEEPER).ack, -- transfer acknowledge
err_o => resp_bus(RESP_BUSKEEPER).err, -- transfer error
-- bus monitoring --
bus_addr_i => p_bus.addr, -- address
bus_rden_i => p_bus.re, -- read enable
bus_wren_i => p_bus.we, -- write enable
bus_ack_i => p_bus.ack, -- transfer acknowledge from bus system
bus_err_i => p_bus.err -- transfer error from bus system
);
 
 
1351,9 → 1356,10
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- implement processor-internal bootloader?
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr => CPU_EXTENSION_RISCV_Zicntr, -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm => CPU_EXTENSION_RISCV_Zihpm, -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG => ON_CHIP_DEBUGGER_EN, -- implement CPU debug mode?
1363,8 → 1369,6
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
-- internal Instruction memory --
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
/rtl/core/neorv32_trng.vhd
125,7 → 125,7
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert not (num_roscs_c = 0) report "NEORV32 PROCESSOR CONFIG ERROR: TRNG - Total number of ring-oscillators has to be >0." severity error;
assert not ((num_inv_start_c mod 2) = 0) report "NEORV32 PROCESSOR CONFIG ERROR: TRNG - Number of inverters in fisrt ring has to be odd." severity error;
assert not ((num_inv_start_c mod 2) = 0) report "NEORV32 PROCESSOR CONFIG ERROR: TRNG - Number of inverters in first ring has to be odd." severity error;
assert not ((num_inv_inc_c mod 2) /= 0) report "NEORV32 PROCESSOR CONFIG ERROR: TRNG - Number of inverters increment for each next ring has to be even." severity error;
 
 
261,8 → 261,7
-- # The inverter chain is constructed as an "asynchronous" LFSR. The single inverters are #
-- # connected via latches that are used to enable/disable the TRNG. Also, these latches are used #
-- # as additional delay element. By using unique enable signals for each latch, the synthesis #
-- # tool cannot "optimize" (=remove) any of the inverters out of the design. Furthermore, the #
-- # latches prevent the synthesis tool from detecting combinatorial loops. #
-- # tool cannot "optimize" (=remove) any of the inverters out of the design. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
/rtl/core/neorv32_twi.vhd
2,8 → 2,8
-- # << NEORV32 - Two-Wire Interface Controller (TWI) >> #
-- # ********************************************************************************************* #
-- # Supports START and STOP conditions, 8 bit data + ACK/NACK transfers and clock stretching. #
-- # Supports ACKs by the constroller. No multi-controller support and no peripheral mode support #
-- # yet. Interrupt: TWI_transfer_done #
-- # Supports ACKs by the controller. No multi-controller support and no peripheral mode support #
-- # yet. Interrupt: TWI_idle #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
98,10 → 98,10
signal twi_clk_halt : std_ulogic;
 
-- twi transceiver core --
signal ctrl : std_ulogic_vector(7 downto 0); -- unit's control register
signal arbiter : std_ulogic_vector(2 downto 0);
signal twi_bitcnt : std_ulogic_vector(3 downto 0);
signal twi_rtx_sreg : std_ulogic_vector(8 downto 0); -- main rx/tx shift reg
signal ctrl : std_ulogic_vector(7 downto 0); -- unit's control register
signal arbiter : std_ulogic_vector(2 downto 0);
signal bitcnt : std_ulogic_vector(3 downto 0);
signal rtx_sreg : std_ulogic_vector(8 downto 0); -- main rx/tx shift reg
 
-- tri-state I/O --
signal twi_sda_i_ff0, twi_sda_i_ff1 : std_ulogic; -- sda input sync
142,10 → 142,10
data_o(ctrl_twi_mack_c) <= ctrl(ctrl_twi_mack_c);
data_o(ctrl_twi_cksten_c) <= ctrl(ctrl_twi_cksten_c);
--
data_o(ctrl_twi_ack_c) <= not twi_rtx_sreg(0);
data_o(ctrl_twi_ack_c) <= not rtx_sreg(0);
data_o(ctrl_twi_busy_c) <= arbiter(1) or arbiter(0);
else -- twi_rtx_addr_c =>
data_o(7 downto 0) <= twi_rtx_sreg(8 downto 1);
data_o(7 downto 0) <= rtx_sreg(8 downto 1);
end if;
end if;
158,7 → 158,7
-- clock generator enable --
clkgen_en_o <= ctrl(ctrl_twi_en_c);
 
-- main twi clock select --
-- twi clock select --
twi_clk <= clkgen_i(to_integer(unsigned(ctrl(ctrl_twi_prsc2_c downto ctrl_twi_prsc0_c))));
 
-- generate four non-overlapping clock ticks at twi_clk/4 --
166,13 → 166,14
begin
if rising_edge(clk_i) then
if (arbiter(2) = '0') or (arbiter = "100") then -- offline or idle
twi_phase_gen <= "0001"; -- make sure to start with a new phase, 0,1,2,3 stepping
twi_phase_gen <= "0001"; -- make sure to start with a new phase, bit 0,1,2,3 stepping
elsif (twi_clk = '1') and (twi_clk_halt = '0') then -- enabled and no clock stretching detected
twi_phase_gen <= twi_phase_gen(2 downto 0) & twi_phase_gen(3); -- shift left
twi_phase_gen <= twi_phase_gen(2 downto 0) & twi_phase_gen(3); -- rotate left
end if;
end if;
end process clock_phase_gen;
 
-- TWI bus signals are set/sampled using 4 clock phases --
twi_clk_phase(0) <= twi_phase_gen(0) and twi_clk; -- first step
twi_clk_phase(1) <= twi_phase_gen(1) and twi_clk;
twi_clk_phase(2) <= twi_phase_gen(2) and twi_clk;
197,15 → 198,12
irq_o <= '0';
end if;
 
-- defaults --
-- serial engine --
arbiter(2) <= ctrl(ctrl_twi_en_c); -- still activated?
 
-- serial engine --
-- TWI bus signals are set/sampled using 4 clock phases
case arbiter is
 
when "100" => -- IDLE: waiting for requests, bus might be still claimed by this controller if no STOP condition was generated
twi_bitcnt <= (others => '0');
bitcnt <= (others => '0');
if (wr_en = '1') then
if (addr = twi_ctrl_addr_c) then
if (data_i(ctrl_twi_start_c) = '1') then -- issue START condition
216,7 → 214,7
elsif (addr = twi_rtx_addr_c) then -- start a data transmission
-- one bit extra for ack, issued by controller if ctrl_twi_mack_c is set,
-- sampled from peripheral if ctrl_twi_mack_c is cleared
twi_rtx_sreg <= data_i(7 downto 0) & (not ctrl(ctrl_twi_mack_c));
rtx_sreg <= data_i(7 downto 0) & (not ctrl(ctrl_twi_mack_c));
arbiter(1 downto 0) <= "11";
end if;
end if;
227,7 → 225,7
elsif (twi_clk_phase(1) = '1') then
twi_sda_o <= '0';
end if;
 
--
if (twi_clk_phase(0) = '1') then
twi_scl_o <= '1';
elsif (twi_clk_phase(3) = '1') then
242,7 → 240,7
twi_sda_o <= '1';
arbiter(1 downto 0) <= "00"; -- go back to IDLE
end if;
--
if (twi_clk_phase(0) = '1') then
twi_scl_o <= '0';
elsif (twi_clk_phase(1) = '1') then
251,17 → 249,17
 
when "111" => -- TRANSMISSION: transmission in progress
if (twi_clk_phase(0) = '1') then
twi_bitcnt <= std_ulogic_vector(unsigned(twi_bitcnt) + 1);
twi_scl_o <= '0';
twi_sda_o <= twi_rtx_sreg(8); -- MSB first
bitcnt <= std_ulogic_vector(unsigned(bitcnt) + 1);
twi_scl_o <= '0';
twi_sda_o <= rtx_sreg(8); -- MSB first
elsif (twi_clk_phase(1) = '1') then -- first half + second half of valid data strobe
twi_scl_o <= '1';
twi_scl_o <= '1';
elsif (twi_clk_phase(3) = '1') then
twi_rtx_sreg <= twi_rtx_sreg(7 downto 0) & twi_sda_i_ff1; -- sample and shift left
twi_scl_o <= '0';
rtx_sreg <= rtx_sreg(7 downto 0) & twi_sda_i_ff1; -- sample and shift left
twi_scl_o <= '0';
end if;
 
if (twi_bitcnt = "1010") then -- 8 data bits + 1 bit for ACK + 1 tick delay
--
if (bitcnt = "1010") then -- 8 data bits + 1 bit for ACK + 1 tick delay
arbiter(1 downto 0) <= "00"; -- go back to IDLE
end if;
 
268,7 → 266,7
when others => -- "0--" OFFLINE: TWI deactivated
twi_sda_o <= '1';
twi_scl_o <= '1';
arbiter <= ctrl(ctrl_twi_en_c) & "00"; -- stay here, go to idle when activated
arbiter(1 downto 0) <= "00"; -- stay here, go to idle when activated
 
end case;
end if;
/rtl/core/neorv32_uart.vhd
110,7 → 110,7
-- simulation output configuration --
constant sim_screen_output_en_c : boolean := true; -- output lowest byte as char to simulator console when enabled
constant sim_text_output_en_c : boolean := true; -- output lowest byte as char to text file when enabled
constant sim_data_output_en_c : boolean := true; -- dump 32-word to file when enabled
constant sim_data_output_en_c : boolean := true; -- dump 32-bit TX word to file when enabled
constant sim_uart_text_file_c : string := cond_sel_string_f(UART_PRIMARY, "neorv32.uart0.sim_mode.text.out", "neorv32.uart1.sim_mode.text.out");
constant sim_uart_data_file_c : string := cond_sel_string_f(UART_PRIMARY, "neorv32.uart0.sim_mode.data.out", "neorv32.uart1.sim_mode.data.out");
 
170,7 → 170,7
signal uart_clk : std_ulogic;
 
-- numbers of bits in transmission frame --
signal num_bits : std_ulogic_vector(03 downto 0);
signal num_bits : std_ulogic_vector(3 downto 0);
 
-- hardware flow-control IO buffer --
signal uart_cts_ff : std_ulogic_vector(1 downto 0);
398,7 → 398,7
when S_TX_TRANSMIT => -- transmit data
-- ------------------------------------------------------------
if (uart_clk = '1') then
if (tx_engine.baud_cnt = x"000") then
if (or_reduce_f(tx_engine.baud_cnt) = '0') then -- bit done?
tx_engine.baud_cnt <= ctrl(ctrl_baud11_c downto ctrl_baud00_c);
tx_engine.bitcnt <= std_ulogic_vector(unsigned(tx_engine.bitcnt) - 1);
tx_engine.sreg <= '1' & tx_engine.sreg(tx_engine.sreg'left downto 1);
407,7 → 407,7
end if;
end if;
uart_txd_o <= tx_engine.sreg(0);
if (tx_engine.bitcnt = "0000") then -- all bits send?
if (or_reduce_f(tx_engine.bitcnt) = '0') then -- all bits send?
tx_engine.state <= S_TX_IDLE;
end if;
 
434,7 → 434,7
begin
if rising_edge(clk_i) then
-- input synchronizer --
rx_engine.sync <= uart_rxd_i & rx_engine.sync(4 downto 1);
rx_engine.sync <= uart_rxd_i & rx_engine.sync(rx_engine.sync'left downto 1);
 
-- FSM --
if (ctrl(ctrl_en_c) = '0') then -- disabled
447,7 → 447,7
-- ------------------------------------------------------------
rx_engine.baud_cnt <= '0' & ctrl(ctrl_baud11_c downto ctrl_baud01_c); -- half baud delay at the beginning to sample in the middle of each bit
rx_engine.bitcnt <= num_bits;
if (rx_engine.sync(2 downto 0) = "001") then -- start bit? (falling edge)
if (rx_engine.sync(3 downto 0) = "0011") then -- start bit? (falling edge)
rx_engine.state <= S_RX_RECEIVE;
end if;
 
454,15 → 454,15
when S_RX_RECEIVE => -- receive data
-- ------------------------------------------------------------
if (uart_clk = '1') then
if (rx_engine.baud_cnt = x"000") then
if (or_reduce_f(rx_engine.baud_cnt) = '0') then -- bit done
rx_engine.baud_cnt <= ctrl(ctrl_baud11_c downto ctrl_baud00_c);
rx_engine.bitcnt <= std_ulogic_vector(unsigned(rx_engine.bitcnt) - 1);
rx_engine.sreg <= rx_engine.sync(0) & rx_engine.sreg(rx_engine.sreg'left downto 1);
rx_engine.sreg <= rx_engine.sync(2) & rx_engine.sreg(rx_engine.sreg'left downto 1);
else
rx_engine.baud_cnt <= std_ulogic_vector(unsigned(rx_engine.baud_cnt) - 1);
end if;
end if;
if (rx_engine.bitcnt = "0000") then -- all bits received?
if (or_reduce_f(rx_engine.bitcnt) = '0') then -- all bits received?
rx_engine.state <= S_RX_IDLE;
end if;
 
/rtl/core/neorv32_wishbone.vhd
241,7 → 241,7
err_o <= ctrl.err;
 
-- wishbone interface --
wb_tag_o(0) <= '1' when (ctrl.priv = priv_mode_m_c) else '0'; -- privileged access when in machine mode
wb_tag_o(0) <= '0' when (ctrl.priv = priv_mode_u_c) else '1'; -- unprivileged access when in user mode
wb_tag_o(1) <= '0'; -- 0 = secure, 1 = non-secure
wb_tag_o(2) <= ctrl.src; -- 0 = data access, 1 = instruction access
 
/rtl/core/neorv32_xirq.vhd
4,7 → 4,7
-- # Simple interrupt controller for platform (processor-external) interrupts. Up to 32 channels #
-- # are supported that get (optionally) prioritized into a single CPU interrupt. #
-- # #
-- # The actual trigger configuration has to be done before synthesis using the XIRQ_TRIGGER_TYPE #
-- # The actual trigger configuration has to be done BEFORE synthesis using the XIRQ_TRIGGER_TYPE #
-- # and XIRQ_TRIGGER_POLARITY generics. These allow to configure channel-independent low-level, #
-- # high-level, falling-edge and rising-edge triggers. #
-- # ********************************************************************************************* #
77,6 → 77,8
-- access control --
signal acc_en : std_ulogic; -- module access enable
signal addr : std_ulogic_vector(31 downto 0); -- access address
signal wren : std_ulogic; -- word write enable
signal rden : std_ulogic; -- read enable
 
-- control registers --
signal irq_enable : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0); -- r/w: interrupt enable
96,8 → 98,7
signal irq_src_nxt : std_ulogic_vector(4 downto 0);
 
-- arbiter --
signal irq_run : std_ulogic;
signal host_ack : std_ulogic;
signal irq_run : std_ulogic;
 
begin
 
110,6 → 111,8
-- -------------------------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = xirq_base_c(hi_abb_c downto lo_abb_c)) else '0';
addr <= xirq_base_c(31 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 2) & "00"; -- word aligned
wren <= acc_en and wren_i;
rden <= acc_en and rden_i;
 
 
-- Read/Write Access ----------------------------------------------------------------------
118,12 → 121,11
begin
if rising_edge(clk_i) then
-- bus handshake --
ack_o <= acc_en and (rden_i or wren_i);
ack_o <= rden or wren;
 
-- write access --
host_ack <= '0';
clr_pending <= (others => '1');
if ((acc_en and wren_i) = '1') then
if (wren = '1') then
-- channel-enable --
if (addr = xirq_enable_addr_c) then
irq_enable <= data_i(XIRQ_NUM_CH-1 downto 0);
132,15 → 134,11
if (addr = xirq_pending_addr_c) then
clr_pending <= data_i(XIRQ_NUM_CH-1 downto 0); -- set zero to clear pending IRQ
end if;
-- acknowledge IRQ --
if (addr = xirq_source_addr_c) then -- write _any_ value to ACK
host_ack <= '1';
end if;
end if;
 
-- read access --
data_o <= (others => '0');
if ((acc_en and rden_i) = '1') then
if (rden = '1') then
case addr is
when xirq_enable_addr_c => data_o(XIRQ_NUM_CH-1 downto 0) <= irq_enable; -- channel-enable
when xirq_pending_addr_c => data_o(XIRQ_NUM_CH-1 downto 0) <= irq_buf; -- pending IRQs
218,7 → 216,7
irq_src <= irq_src_nxt;
end if;
else -- active IRQ, wait for CPU to acknowledge
if (host_ack = '1') then
if (wren = '1') and (addr = xirq_source_addr_c) then -- write _any_ value to acknowledge
irq_run <= '0';
end if;
end if;
/rtl/processor_templates/neorv32_ProcessorTop_Minimal.vhd
118,6 → 118,7
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr => true, -- implement base counters?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
 
-- Extension Options --
/rtl/processor_templates/neorv32_ProcessorTop_MinimalBoot.vhd
139,6 → 139,7
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr => true, -- implement base counters?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
 
-- Extension Options --
/rtl/processor_templates/neorv32_ProcessorTop_UP5KDemo.vhd
179,6 → 179,7
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr => true, -- implement base counters?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
 
-- Extension Options --
/rtl/system_integration/neorv32_ProcessorTop_stdlogic.vhd
49,13 → 49,15
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr : boolean := true; -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm : boolean := false; -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
272,13 → 274,15
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement on-chip debugger
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr => CPU_EXTENSION_RISCV_Zicntr, -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm => CPU_EXTENSION_RISCV_Zihpm, -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
/rtl/system_integration/neorv32_SystemTop_AvalonMM.vhd
54,13 → 54,15
 
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr : boolean := true; -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm : boolean := false; -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
 
238,13 → 240,15
 
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A,
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B,
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C,
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E,
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M,
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U,
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb,
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx,
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr,
CPU_EXTENSION_RISCV_Zicntr => CPU_EXTENSION_RISCV_Zicntr,
CPU_EXTENSION_RISCV_Zihpm => CPU_EXTENSION_RISCV_Zihpm,
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei,
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul,
 
/rtl/system_integration/neorv32_SystemTop_axi4lite.vhd
55,13 → 55,15
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr : boolean := true; -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm : boolean := false; -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
279,13 → 281,15
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement on-chip debugger
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr => CPU_EXTENSION_RISCV_Zicntr, -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm => CPU_EXTENSION_RISCV_Zihpm, -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
/rtl/test_setups/neorv32_test_setup_approm.vhd
72,6 → 72,7
CPU_EXTENSION_RISCV_C => true, -- implement compressed extension?
CPU_EXTENSION_RISCV_M => true, -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zicsr => true, -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr => true, -- implement base counters?
-- Internal Instruction memory --
MEM_INT_IMEM_EN => true, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
/rtl/test_setups/neorv32_test_setup_bootloader.vhd
75,6 → 75,7
CPU_EXTENSION_RISCV_C => true, -- implement compressed extension?
CPU_EXTENSION_RISCV_M => true, -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zicsr => true, -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr => true, -- implement base counters?
-- Internal Instruction memory --
MEM_INT_IMEM_EN => true, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
/setups/osflow/board_tops/neorv32_ULX3S_BoardTop_MinimalBoot.vhd
75,8 → 75,8
neorv32_inst: entity work.neorv32_ProcessorTop_MinimalBoot
generic map (
CLOCK_FREQUENCY => f_clock_c, -- clock frequency of clk_i in Hz
MEM_INT_IMEM_SIZE => 4*1024,
MEM_INT_DMEM_SIZE => 2*1024
MEM_INT_IMEM_SIZE => 16*1024,
MEM_INT_DMEM_SIZE => 8*1024
)
port map (
-- Global control --
/setups/quartus/de0-nano-test-setup-avalonmm-wrapper/neorv32_test_setup_avalonmm.vhd
76,11 → 76,11
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
/setups/radiant/UPduino_v3/neorv32_upduino_v3_top.vhd
160,7 → 160,8
CPU_EXTENSION_RISCV_U => false, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx => false, -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr => true, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => false, -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zicntr => true, -- implement base counters?
CPU_EXTENSION_RISCV_Zifencei => true, -- implement instruction stream sync.?
 
-- Extension Options --
FAST_MUL_EN => false, -- use DSPs for M extension's multiplier
/sim/simple/neorv32_tb.simple.vhd
49,11 → 49,11
entity neorv32_tb_simple is
generic (
CPU_EXTENSION_RISCV_A : boolean := true;
CPU_EXTENSION_RISCV_B : boolean := true;
CPU_EXTENSION_RISCV_C : boolean := true;
CPU_EXTENSION_RISCV_E : boolean := false;
CPU_EXTENSION_RISCV_M : boolean := true;
CPU_EXTENSION_RISCV_U : boolean := true;
CPU_EXTENSION_RISCV_Zbb : boolean := true;
CPU_EXTENSION_RISCV_Zicsr : boolean := true;
CPU_EXTENSION_RISCV_Zifencei : boolean := true;
EXT_IMEM_C : boolean := false; -- false: use and boot from proc-internal IMEM, true: use and boot from external (initialized) simulated IMEM (ext. mem A)
176,13 → 176,15
ON_CHIP_DEBUGGER_EN => true, -- implement on-chip debugger
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb,-- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx => true, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr => true, -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm => true, -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul => false, -- implement multiply-only M sub-extension?
-- Extension Options --
/sim/neorv32_tb.vhd
284,13 → 284,15
ON_CHIP_DEBUGGER_EN => true, -- implement on-chip debugger
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => true, -- implement atomic extension?
CPU_EXTENSION_RISCV_B => true, -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C => true, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => false, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => true, -- implement muld/div extension?
CPU_EXTENSION_RISCV_U => true, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb => true, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx => true, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => true, -- implement CSR system?
CPU_EXTENSION_RISCV_Zicntr => true, -- implement base counters?
CPU_EXTENSION_RISCV_Zihpm => true, -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zifencei => true, -- implement instruction stream sync.?
-- Extension Options --
FAST_MUL_EN => false, -- use DSPs for M extension's multiplier
/sw/bootloader/bootloader.c
411,6 → 411,7
char c = PRINT_GETC();
PRINT_PUTC(c); // echo
PRINT_TEXT("\n");
while (neorv32_uart0_tx_busy());
 
if (c == 'r') { // restart bootloader
asm volatile ("li t0, %[input_i]; jr t0" : : [input_i] "i" (BOOTLOADER_BASE_ADDRESS)); // jump to beginning of boot ROM
492,7 → 493,7
**************************************************************************/
void __attribute__((__interrupt__)) bootloader_trap_handler(void) {
 
uint32_t cause = neorv32_cpu_csr_read(CSR_MCAUSE);
register uint32_t cause = neorv32_cpu_csr_read(CSR_MCAUSE);
 
// Machine timer interrupt
if (cause == TRAP_CODE_MTI) { // raw exception code for MTI
514,10 → 515,10
 
// Anything else (that was not expected); output exception notifier and try to resume
else {
uint32_t epc = neorv32_cpu_csr_read(CSR_MEPC);
register uint32_t epc = neorv32_cpu_csr_read(CSR_MEPC);
#if (UART_EN != 0)
if (neorv32_uart0_available()) {
PRINT_TEXT("\n[EXC ");
PRINT_TEXT("\n[ERR ");
PRINT_XNUM(cause); // MCAUSE
PRINT_PUTC(' ');
PRINT_XNUM(epc); // MEPC
552,8 → 553,7
PRINT_TEXT("Loading... ");
 
// flash checks
if ((neorv32_spi_available() == 0) || // check if SPI is available at all
(spi_flash_read_1st_id() == 0x00)) { // check if flash ready (or available at all)
if (spi_flash_read_1st_id() == 0x00) { // check if flash ready (or available at all)
system_error(ERROR_FLASH);
}
}
613,7 → 613,7
// info and prompt
PRINT_TEXT("Write ");
PRINT_XNUM(size);
PRINT_TEXT(" bytes to SPI flash @ ");
PRINT_TEXT(" bytes to SPI flash @0x");
PRINT_XNUM(addr);
PRINT_TEXT("? (y/n) ");
 
/sw/common/crt0.S
57,8 → 57,8
.option push
.option norelax
 
la sp, __crt0_stack_begin // stack pointer
la gp, __global_pointer$ // global pointer
la sp, __crt0_stack_begin // stack pointer
la gp, __global_pointer$ // global pointer
 
.option pop
 
95,17 → 95,17
//addi x0, x0, 0 // hardwired to zero
addi x1, x0, 0
//addi x2, x0, 0 // stack pointer sp
//addi x3, x0, 0 // gloabl pointer gp
//addi x3, x0, 0 // global pointer gp
addi x4, x0, 0
addi x5, x0, 0
addi x6, x0, 0
addi x7, x0, 0
//addi x8, x0, 0 // initialized within crt0
//addi x9, x0, 0 // initialized within crt0
//addi x10, x0, 0 // initialized within crt0
//addi x11, x0, 0 // initialized within crt0
//addi x12, x0, 0 // initialized within crt0
//addi x13, x0, 0 // initialized within crt0
//addi x8, x0, 0 // implicitly initialized within crt0
//addi x9, x0, 0 // implicitly initialized within crt0
//addi x10, x0, 0 // implicitly initialized within crt0
//addi x11, x0, 0 // implicitly initialized within crt0
//addi x12, x0, 0 // implicitly initialized within crt0
//addi x13, x0, 0 // implicitly initialized within crt0
addi x14, x0, 0
addi x15, x0, 0
 
213,7 → 213,7
// go to endless sleep mode
// ************************************************************************************************
__crt0_main_aftermath_end:
csrci mstatus, 8 // mstatus: disable global IRQs (mstatus.mie)
csrci mstatus, 8 // mstatus: disable global IRQs (mstatus.mie)
__crt0_main_aftermath_end_loop:
wfi // try to go to sleep mode
j __crt0_main_aftermath_end_loop // endless loop
/sw/example/bitmanip_test/README.md
1,12 → 1,12
# NEORV32 Bit-Manipulation `B` Extension (`Zbb` sub-extension)
# NEORV32 Bit-Manipulation `B` Extension
 
:warning: The RISC-V bit-manipulation extension is frozen but not yet officially ratified.
 
:warning: The NEORV32 bit manipulation extensions only supports the `Zbb` sub-extension
:warning: The NEORV32 bit manipulation extensions `B` only supports the `Zbb` and `Zba` sub-extension
(basic bit-manipulation operation) yet.
 
The provided test program `main.c` verifies all currently implemented instruction by checking the results against a pure-software emulation model.
The emulation functions as well as the available **intrinsics** for the `Zbb` extension are located in `neorv32_b_extension_intrinsics.h`.
The emulation functions as well as the available **intrinsics** for the sub-extension are located in `neorv32_b_extension_intrinsics.h`.
 
:information_source: More information regarding the RISC-V bit manipulation extension can be found in the officail GitHub repo:
[github.com/riscv/riscv-bitmanip](https://github.com/riscv/riscv-bitmanip).
/sw/example/bitmanip_test/main.c
1,5 → 1,5
// #################################################################################################
// # << NEORV32 - RISC-V Bit-Manipulation 'Zbb' Extension Test Program >> #
// # << NEORV32 - RISC-V Bit-Manipulation 'B' Extension Test Program >> #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
36,7 → 36,7
/**********************************************************************//**
* @file bitmanip_test/main.c
* @author Stephan Nolting
* @brief Test program for the NEORV32 'Zbb' extension using pseudo-random
* @brief Test program for the NEORV32 'B` extension using pseudo-random
* data as input; compares results from hardware against pure-sw reference functions.
**************************************************************************/
 
64,7 → 64,7
* Main function; test all available operations of the NEORV32 'Zbb' extensions
* using bit manipulation intrinsics and software-only reference functions (emulation).
*
* @note This program requires the Zbb CPU extension.
* @note This program requires the bit-manipulation CPU extension.
*
* @return Irrelevant.
**************************************************************************/
91,19 → 91,23
#endif
 
// intro
neorv32_uart0_printf("NEORV32 'Zbb' Bit-Manipulation Extension Test\n\n");
neorv32_uart0_printf("NEORV32 Bit-Manipulation Extension Test (Zba, Zbb)\n\n");
 
// check available hardware extensions and compare with compiler flags
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch
 
// check if Zbb extension is implemented at all
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_ZBB)) == 0) {
neorv32_uart0_print("Error! <Zbb> extension not synthesized!\n");
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_B)) == 0) {
neorv32_uart0_print("Error! <B> extension not synthesized!\n");
return 1;
}
 
neorv32_uart0_printf("Starting Zbb bit-manipulation extension tests (%i test cases per instruction)...\n", num_tests);
neorv32_uart0_printf("Starting bit-manipulation extension tests (%i test cases per instruction)...\n\n", num_tests);
 
neorv32_uart0_printf("-----------------------------------------\n");
neorv32_uart0_printf("Zbb - Basic bit-manipulation instructions\n");
neorv32_uart0_printf("-----------------------------------------\n");
 
// ANDN
neorv32_uart0_printf("\nANDN:\n");
err_cnt = 0;
326,6 → 330,48
print_report(err_cnt, num_tests);
 
 
 
neorv32_uart0_printf("\n\n");
neorv32_uart0_printf("-----------------------------------------\n");
neorv32_uart0_printf("Zba - Address generation instructions\n");
neorv32_uart0_printf("-----------------------------------------\n");
 
// SH1ADD
neorv32_uart0_printf("\nSH1ADD:\n");
err_cnt = 0;
for (i=0;i<num_tests; i++) {
opa = xorshift32();
opb = xorshift32();
res_sw = riscv_emulate_sh1add(opa, opb);
res_hw = riscv_intrinsic_sh1add(opa, opb);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
// SH2ADD
neorv32_uart0_printf("\nSH2ADD:\n");
err_cnt = 0;
for (i=0;i<num_tests; i++) {
opa = xorshift32();
opb = xorshift32();
res_sw = riscv_emulate_sh2add(opa, opb);
res_hw = riscv_intrinsic_sh2add(opa, opb);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
// SH2ADD
neorv32_uart0_printf("\nSH3ADD:\n");
err_cnt = 0;
for (i=0;i<num_tests; i++) {
opa = xorshift32();
res_sw = riscv_emulate_sh3add(opa, opb);
res_hw = riscv_intrinsic_sh3add(opa, opb);
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
}
print_report(err_cnt, num_tests);
 
 
neorv32_uart0_printf("\nBit manipulation extension tests done.\n");
 
return 0;
/sw/example/bitmanip_test/neorv32_b_extension_intrinsics.h
1,8 → 1,8
// #################################################################################################
// # << NEORV32 - Intrinsics + Emulation Functions for the B CPU extensions >> #
// # << NEORV32 - Intrinsics + Emulation Functions for the CPU B extension >> #
// # ********************************************************************************************* #
// # The intrinsics provided by this library allow to use the hardware bit manipulation unit of #
// # the RISC-V B CPU extension without the need for B support by the compiler. #
// # the RISC-V B CPU extension without the need for support by the compiler. #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
39,10 → 39,10
/**********************************************************************//**
* @file bitmanip_test/neorv32_b_extension_intrinsics.h
* @author Stephan Nolting
* @brief "Intrinsic" library for the NEORV32 bit manipulation Zbb extension.
* @brief "Intrinsic" library for the NEORV32 bit manipulation B extension.
* Also provides emulation functions for all intrinsics (functionality re-built in pure software).
*
* @warning This library is just a temporary fall-back until the Zbb extensions are supported by the upstream RISC-V GCC port.
* @warning This library is just a temporary fall-back until the B extension is supported by the upstream RISC-V GCC port.
**************************************************************************/
#ifndef neorv32_b_extension_intrinsics_h
54,9 → 54,9
// ################################################################################################
 
 
// ---------------------------------------------
// ================================================================================================
// Zbb - Base instructions
// ---------------------------------------------
// ================================================================================================
 
/**********************************************************************//**
* Intrinsic: Bit manipulation CLZ (count leading zeros) [B.Zbb]
455,14 → 455,87
}
 
 
// ================================================================================================
// Zbb - Base instructions
// ================================================================================================
 
/**********************************************************************//**
* Intrinsic: Address generation instructions SH1ADD (add with logical-1-shift) [B.Zba]
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a0).
* @return Operand 2 + (Operand 1 << 1)
**************************************************************************/
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_sh1add(uint32_t rs1, uint32_t rs2) {
 
register uint32_t result __asm__ ("a0");
register uint32_t tmp_a __asm__ ("a0") = rs1;
register uint32_t tmp_b __asm__ ("a1") = rs2;
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("" : [output] "=r" (result) : [input_i] "r" (tmp_a), [input_j] "r" (tmp_b));
 
// sh1add a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0010000, a1, a0, 0b010, a0, 0b0110011);
 
return result;
}
 
 
/**********************************************************************//**
* Intrinsic: Address generation instructions SH2ADD (add with logical-2-shift) [B.Zba]
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a0).
* @return Operand 2 + (Operand 1 << 2)
**************************************************************************/
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_sh2add(uint32_t rs1, uint32_t rs2) {
 
register uint32_t result __asm__ ("a0");
register uint32_t tmp_a __asm__ ("a0") = rs1;
register uint32_t tmp_b __asm__ ("a1") = rs2;
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("" : [output] "=r" (result) : [input_i] "r" (tmp_a), [input_j] "r" (tmp_b));
 
// sh2add a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0010000, a1, a0, 0b100, a0, 0b0110011);
 
return result;
}
 
/**********************************************************************//**
* Intrinsic: Address generation instructions SH1ADD (add with logical-3-shift) [B.Zba]
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a0).
* @return Operand 2 + (Operand 1 << 3)
**************************************************************************/
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_sh3add(uint32_t rs1, uint32_t rs2) {
 
register uint32_t result __asm__ ("a0");
register uint32_t tmp_a __asm__ ("a0") = rs1;
register uint32_t tmp_b __asm__ ("a1") = rs2;
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("" : [output] "=r" (result) : [input_i] "r" (tmp_a), [input_j] "r" (tmp_b));
 
// sh3add a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0010000, a1, a0, 0b110, a0, 0b0110011);
 
return result;
}
 
 
 
// ################################################################################################
// Emulation functions
// ################################################################################################
 
 
// ---------------------------------------------
// ================================================================================================
// Zbb - Base instructions
// ---------------------------------------------
// ================================================================================================
 
 
/**********************************************************************//**
783,5 → 856,48
}
 
 
// ================================================================================================
// Zba - Address generation instructions
// ================================================================================================
 
 
/**********************************************************************//**
* Intrinsic: Address generation instructions SH1ADD (add with logical-1-shift) [emulation]
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 1 (a0).
* @return Operand 2 + (Operand 1 << 1)
**************************************************************************/
uint32_t riscv_emulate_sh1add(uint32_t rs1, uint32_t rs2) {
 
return rs2 + (rs1 << 1);
}
 
 
/**********************************************************************//**
* Intrinsic: Address generation instructions SH2ADD (add with logical-2-shift) [emulation]
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 1 (a0).
* @return Operand 2 + (Operand 1 << 2)
**************************************************************************/
uint32_t riscv_emulate_sh2add(uint32_t rs1, uint32_t rs2) {
 
return rs2 + (rs1 << 2);
}
 
 
/**********************************************************************//**
* Intrinsic: Address generation instructions SH3ADD (add with logical-3-shift) [emulation]
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 1 (a0).
* @return Operand 2 + (Operand 1 << 3)
**************************************************************************/
uint32_t riscv_emulate_sh3add(uint32_t rs1, uint32_t rs2) {
 
return rs2 + (rs1 << 3);
}
 
 
#endif // neorv32_b_extension_intrinsics_h
/sw/example/hex_viewer/main.c
51,13 → 51,17
#define BAUD_RATE 19200
/**@}*/
 
// Global variables
char access_size;
 
// Prototypes
void read_memory(void);
void setup_access(void);
void write_memory(void);
void atomic_cas(void);
void dump_memory(void);
uint32_t hexstr_to_uint(char *buffer, uint8_t length);
void aux_print_hex_byte(uint8_t byte);
 
 
/**********************************************************************//**
72,6 → 76,8
char buffer[8];
int length = 0;
 
access_size = 0;
 
// check if UART unit is implemented at all
if (neorv32_uart0_available() == 0) {
return 1;
110,12 → 116,17
if (!strcmp(buffer, "help")) {
neorv32_uart0_printf("Available commands:\n"
" help - show this text\n"
" read - read single word from address\n"
" write - write single word to address\n"
" atomic - perform atomic LR/SC access\n"
" dump - dumpe several words from base address\n");
" setup - configure memory access width (byte,half,word)\n"
" read - read from address (byte,half,word)\n"
" write - write to address (byte,half,word)\n"
" atomic - perform atomic LR/SC access (word-only)\n"
" dump - dump several bytes/halfs/words from base address\n");
}
 
else if (!strcmp(buffer, "setup")) {
setup_access();
}
 
else if (!strcmp(buffer, "read")) {
read_memory();
}
142,12 → 153,47
 
 
/**********************************************************************//**
* Read word from memory address
* Configure memory access size
**************************************************************************/
void setup_access(void) {
 
neorv32_uart0_printf("Select data size (press 'x' to abort):\n"
" 'b' - byte, 8-bit, unsigned\n"
" 'h' - half-word, 16-bit, unsigned\n"
" 'w' - word, 32-bit, unsigned\n");
 
while(1) {
neorv32_uart0_printf("selection: ");
char tmp = neorv32_uart0_getc();
neorv32_uart0_putc(tmp);
if ((tmp == 'b') || (tmp == 'h') || (tmp == 'w')) {
access_size = tmp;
neorv32_uart0_printf("\n");
return;
}
else if (tmp == 'x') {
neorv32_uart0_printf("\n");
return;
}
else {
neorv32_uart0_printf("Invalid selection!\n");
}
}
}
 
 
/**********************************************************************//**
* Read from memory address
**************************************************************************/
void read_memory(void) {
 
char terminal_buffer[16];
 
if (access_size == 0) {
neorv32_uart0_printf("Configure data size using 'setup' first.\n");
return;
}
 
// enter address
neorv32_uart0_printf("Enter address (8 hex chars): 0x");
neorv32_uart0_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
158,11 → 204,29
 
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
uint32_t mem_data = neorv32_cpu_load_unsigned_word(mem_address);
uint8_t mem_data_b = 0;
uint16_t mem_data_h = 0;
uint32_t mem_data_w = 0;
if (access_size == 'b') { mem_data_b = (uint32_t)neorv32_cpu_load_unsigned_byte(mem_address); }
if (access_size == 'h') { mem_data_h = (uint32_t)neorv32_cpu_load_unsigned_half(mem_address); }
if (access_size == 'w') { mem_data_w = (uint32_t)neorv32_cpu_load_unsigned_word(mem_address); }
 
// show memory content if there was no exception
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
neorv32_uart0_printf("0x%x", mem_data);
neorv32_uart0_printf("0x");
if (access_size == 'b') {
aux_print_hex_byte(mem_data_b);
}
if (access_size == 'h') {
aux_print_hex_byte((uint8_t)(mem_data_h >> 8));
aux_print_hex_byte((uint8_t)(mem_data_h >> 0));
}
if (access_size == 'w') {
aux_print_hex_byte((uint8_t)(mem_data_w >> 24));
aux_print_hex_byte((uint8_t)(mem_data_w >> 16));
aux_print_hex_byte((uint8_t)(mem_data_w >> 8));
aux_print_hex_byte((uint8_t)(mem_data_w >> 0));
}
}
 
neorv32_uart0_printf("\n");
170,12 → 234,17
 
 
/**********************************************************************//**
* Write word tp memory address
* Write to memory address
**************************************************************************/
void write_memory(void) {
 
char terminal_buffer[16];
 
if (access_size == 0) {
neorv32_uart0_printf("Configure data size using 'setup' first.\n");
return;
}
 
// enter address
neorv32_uart0_printf("Enter address (8 hex chars): 0x");
neorv32_uart0_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
182,28 → 251,36
uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
// enter data
neorv32_uart0_printf("\nEnter data (8 hex chars): 0x");
neorv32_uart0_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
uint32_t mem_data = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
uint8_t mem_data_b = 0;
uint16_t mem_data_h = 0;
uint32_t mem_data_w = 0;
if (access_size == 'b') {
neorv32_uart0_printf("\nEnter data (2 hex chars): 0x");
neorv32_uart0_scan(terminal_buffer, 2+1, 1); // 2 hex chars for address plus '\0'
mem_data_b = (uint8_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
}
if (access_size == 'h') {
neorv32_uart0_printf("\nEnter data (4 hex chars): 0x");
neorv32_uart0_scan(terminal_buffer, 4+1, 1); // 4 hex chars for address plus '\0'
mem_data_h = (uint16_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
}
if (access_size == 'w') {
neorv32_uart0_printf("\nEnter data (8 hex chars): 0x");
neorv32_uart0_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
mem_data_w = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
}
 
// perform write access
neorv32_uart0_printf("\n[0x%x] = ", mem_address);
if (access_size == 'b') { neorv32_cpu_store_unsigned_byte(mem_address, mem_data_b); }
if (access_size == 'h') { neorv32_cpu_store_unsigned_half(mem_address, mem_data_h); }
if (access_size == 'w') { neorv32_cpu_store_unsigned_word(mem_address, mem_data_w); }
 
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
neorv32_cpu_store_unsigned_word(mem_address, mem_data);
 
// show memory content if there was no exception
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
neorv32_uart0_printf("0x%x", mem_data);
}
 
neorv32_uart0_printf("\n");
}
 
 
/**********************************************************************//**
* Perform atomic compare-and-swap operation
* Perform atomic compare-and-swap operation, always 32-bit
**************************************************************************/
void atomic_cas(void) {
 
242,12 → 319,17
 
 
/**********************************************************************//**
* Read several words from memory base address
* Read several bytes/halfs/word from memory base address
**************************************************************************/
void dump_memory(void) {
 
char terminal_buffer[16];
 
if (access_size == 0) {
neorv32_uart0_printf("Configure data size using 'setup' first.\n");
return;
}
 
// enter base address
neorv32_uart0_printf("Enter base address (8 hex chars): 0x");
neorv32_uart0_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
258,7 → 340,6
neorv32_uart0_getc(); // wait for key
 
// perform read accesses
uint32_t mem_data = 0;
while(neorv32_uart0_char_received() == 0) {
 
neorv32_uart0_printf("[0x%x] = ", mem_address);
265,17 → 346,44
 
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
mem_data = neorv32_cpu_load_unsigned_word(mem_address);
uint8_t mem_data_b = 0;
uint16_t mem_data_h = 0;
uint32_t mem_data_w = 0;
if (access_size == 'b') { mem_data_b = (uint32_t)neorv32_cpu_load_unsigned_byte(mem_address); }
if (access_size == 'h') { mem_data_h = (uint32_t)neorv32_cpu_load_unsigned_half(mem_address); }
if (access_size == 'w') { mem_data_w = (uint32_t)neorv32_cpu_load_unsigned_word(mem_address); }
 
// show memory content if there was no exception
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
neorv32_uart0_printf("0x%x\n", mem_data);
neorv32_uart0_printf("0x");
if (access_size == 'b') {
aux_print_hex_byte(mem_data_b);
}
if (access_size == 'h') {
aux_print_hex_byte((uint8_t)(mem_data_h >> 8));
aux_print_hex_byte((uint8_t)(mem_data_h >> 0));
}
if (access_size == 'w') {
aux_print_hex_byte((uint8_t)(mem_data_w >> 24));
aux_print_hex_byte((uint8_t)(mem_data_w >> 16));
aux_print_hex_byte((uint8_t)(mem_data_w >> 8));
aux_print_hex_byte((uint8_t)(mem_data_w >> 0));
}
neorv32_uart0_printf("\n");
}
else {
break;
}
 
mem_address = mem_address + 4;
if (access_size == 'b') {
mem_address += 1;
}
else if (access_size == 'h') {
mem_address += 2;
}
else if (access_size == 'w') {
mem_address += 4;
}
 
}
neorv32_uart0_char_received_get(); // clear UART rx buffer
311,4 → 419,18
}
 
return res;
}
}
 
 
/**********************************************************************//**
* Print HEX byte.
*
* @param[in] byte Byte to be printed as 2-cahr hex value.
**************************************************************************/
void aux_print_hex_byte(uint8_t byte) {
 
static const char symbols[] = "0123456789abcdef";
 
neorv32_uart0_putc(symbols[(byte >> 4) & 0x0f]);
neorv32_uart0_putc(symbols[(byte >> 0) & 0x0f]);
}
/sw/example/processor_check/main.c
154,10 → 154,10
 
 
// reset performance counter
neorv32_cpu_csr_write(CSR_MCYCLEH, 0);
neorv32_cpu_csr_write(CSR_MCYCLE, 0);
neorv32_cpu_csr_write(CSR_MINSTRETH, 0);
neorv32_cpu_csr_write(CSR_MINSTRET, 0);
// neorv32_cpu_csr_write(CSR_MCYCLEH, 0); -> done in crt0.S
// neorv32_cpu_csr_write(CSR_MCYCLE, 0); -> done in crt0.S
// neorv32_cpu_csr_write(CSR_MINSTRETH, 0); -> done in crt0.S
// neorv32_cpu_csr_write(CSR_MINSTRET, 0); -> done in crt0.S
neorv32_cpu_csr_write(CSR_MCOUNTINHIBIT, 0); // enable performance counter auto increment (ALL counters)
neorv32_cpu_csr_write(CSR_MCOUNTEREN, 7); // allow access from user-mode code to standard counters only
 
180,7 → 180,7
 
// configure RTE
// -----------------------------------------------
PRINT_STANDARD("\n\nConfiguring NEORV32 RTE... ");
PRINT_STANDARD("\n\nRTE setup... ");
 
int install_err = 0;
// initialize ALL provided trap handler (overriding the default debug handlers)
187,9 → 187,8
for (id=0; id<NEORV32_RTE_NUM_TRAPS; id++) {
install_err += neorv32_rte_exception_install(id, global_trap_handler);
}
 
if (install_err) {
PRINT_CRITICAL("RTE install error (%i)!\n", install_err);
PRINT_CRITICAL("ERROR!\n");
return 1;
}
 
200,7 → 199,7
neorv32_cpu_csr_write(CSR_MIE, 0);
 
// test intro
PRINT_STANDARD("\nStarting tests...\n\n");
PRINT_STANDARD("\nStarting tests.\n\n");
 
// enable global interrupts
neorv32_cpu_eint();
215,7 → 214,7
// Test performance counter: setup as many events and counter as feasible
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] Configuring HPM events: ", cnt_test);
PRINT_STANDARD("[%i] Setup HPM events: ", cnt_test);
 
num_hpm_cnts_global = neorv32_cpu_hpm_get_counters();
 
254,7 → 253,7
// Test standard RISC-V performance counter [m]cycle[h]
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] [m]cycle[h] counter: ", cnt_test);
PRINT_STANDARD("[%i] cycle counter: ", cnt_test);
 
cnt_test++;
 
280,7 → 279,7
// Test standard RISC-V performance counter [m]instret[h]
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] [m]instret[h] counter: ", cnt_test);
PRINT_STANDARD("[%i] instret counter: ", cnt_test);
 
cnt_test++;
 
575,14 → 574,15
 
cnt_test++;
 
// not allowed outside of debug mode
asm volatile ("dret");
// illegal 32-bit instruction (malformed SUB)
asm volatile (".align 4 \n"
".word 0x80000033");
 
// 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 failing instruction word
if (neorv32_cpu_csr_read(CSR_MTVAL) == 0x7b200073) {
// -> for illegal instructions MTVAL contains the faulting instruction word
if (neorv32_cpu_csr_read(CSR_MTVAL) == 0x80000033) {
test_ok();
}
else {
605,15 → 605,11
 
cnt_test++;
 
// create test program in RAM
static const uint32_t dummy_sub_program_ci[2] __attribute__((aligned(8))) = {
0x00000001, // 2nd: official_illegal_op | 1st: NOP -> illegal instruction exception
0x00008067 // ret (32-bit)
};
// illegal 16-bit instruction (official UNIMP instruction)
asm volatile (".align 2 \n"
".half 0x0001 \n" // NOP
".half 0x0000"); // UNIMP
 
tmp_a = (uint32_t)&dummy_sub_program_ci; // call the dummy sub program
asm volatile ("jalr ra, %[input_i]" : : [input_i] "r" (tmp_a));
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
653,7 → 649,8
// load from unaligned address
neorv32_cpu_load_unsigned_word(ADDR_UNALIGNED_1);
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_L_MISALIGNED) {
if ((neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_L_MISALIGNED) &&
(neorv32_cpu_csr_read(CSR_MTVAL) == ADDR_UNALIGNED_1)) {
test_ok();
}
else {
/sw/lib/include/neorv32.h
492,6 → 492,89
 
 
/**********************************************************************//**
* @defgroup FIRQ_ALIASES Fast Interrupt Requests (FIRQ) Aliases (MIE, MIP, MCAUSE, RTE-ID)
* @name Fast Interrupt Requests (FIRQ) Aliases (MIE, MIP, MCAUSE, RTE-ID)
**************************************************************************/
/**@{*/
/** @name Watchdog Timer (WDT) */
/**@{*/
#define WDT_FIRQ_ENABLE CSR_MIE_FIRQ0E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */
#define WDT_FIRQ_PENDING CSR_MIP_FIRQ0P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */
#define WDT_RTE_ID RTE_TRAP_FIRQ_0 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */
#define WDT_TRAP_CODE TRAP_CODE_FIRQ_0 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */
/**@}*/
/** @name Custom Functions Subsystem (CFS) */
/**@{*/
#define CFS_FIRQ_ENABLE CSR_MIE_FIRQ1E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */
#define CFS_FIRQ_PENDING CSR_MIP_FIRQ1P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */
#define CFS_RTE_ID RTE_TRAP_FIRQ_1 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */
#define CFS_TRAP_CODE TRAP_CODE_FIRQ_1 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */
/**@}*/
/** @name Primary Universal Asynchronous Receiver/Transmitter (UART0) */
/**@{*/
#define UART0_RX_FIRQ_ENABLE CSR_MIE_FIRQ2E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */
#define UART0_RX_FIRQ_PENDING CSR_MIP_FIRQ2P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */
#define UART0_RX_RTE_ID RTE_TRAP_FIRQ_2 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */
#define UART0_RX_TRAP_CODE TRAP_CODE_FIRQ_2 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */
#define UART0_TX_FIRQ_ENABLE CSR_MIE_FIRQ3E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */
#define UART0_TX_FIRQ_PENDING CSR_MIP_FIRQ3P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */
#define UART0_TX_RTE_ID RTE_TRAP_FIRQ_3 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */
#define UART0_TX_TRAP_CODE TRAP_CODE_FIRQ_4 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */
/**@}*/
/** @name Secondary Universal Asynchronous Receiver/Transmitter (UART1) */
/**@{*/
#define UART1_RX_FIRQ_ENABLE CSR_MIE_FIRQ4E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */
#define UART1_RX_FIRQ_PENDING CSR_MIP_FIRQ4P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */
#define UART1_RX_RTE_ID RTE_TRAP_FIRQ_4 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */
#define UART1_RX_TRAP_CODE TRAP_CODE_FIRQ_4 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */
#define UART1_TX_FIRQ_ENABLE CSR_MIE_FIRQ5E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */
#define UART1_TX_FIRQ_PENDING CSR_MIP_FIRQ5P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */
#define UART1_TX_RTE_ID RTE_TRAP_FIRQ_5 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */
#define UART1_TX_TRAP_CODE TRAP_CODE_FIRQ_5 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */
/**@}*/
/** @name Serial Peripheral Interface (SPI) */
/**@{*/
#define SPI_FIRQ_ENABLE CSR_MIE_FIRQ6E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */
#define SPI_FIRQ_PENDING CSR_MIP_FIRQ6P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */
#define SPI_RTE_ID RTE_TRAP_FIRQ_6 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */
#define SPI_TRAP_CODE TRAP_CODE_FIRQ_6 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */
/**@}*/
/** @name Two-Wire Interface (TWI) */
/**@{*/
#define TWI_FIRQ_ENABLE CSR_MIE_FIRQ7E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */
#define TWI_FIRQ_PENDING CSR_MIP_FIRQ7P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */
#define TWI_RTE_ID RTE_TRAP_FIRQ_7 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */
#define TWI_TRAP_CODE TRAP_CODE_FIRQ_7 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */
/**@}*/
/** @name External Interrupt Controller (XIRQ) */
/**@{*/
#define XIRQ_FIRQ_ENABLE CSR_MIE_FIRQ8E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */
#define XIRQ_FIRQ_PENDING CSR_MIP_FIRQ8P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */
#define XIRQ_RTE_ID RTE_TRAP_FIRQ_8 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */
#define XIRQ_TRAP_CODE TRAP_CODE_FIRQ_8 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */
/**@}*/
/** @name Smart LED Controller (NEOLED) */
/**@{*/
#define NEOLED_FIRQ_ENABLE CSR_MIE_FIRQ9E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */
#define NEOLED_FIRQ_PENDING CSR_MIP_FIRQ9P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */
#define NEOLED_RTE_ID RTE_TRAP_FIRQ_9 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */
#define NEOLED_TRAP_CODE TRAP_CODE_FIRQ_9 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */
/**@}*/
/** @name Stream Link Interface (SLINK) */
/**@{*/
#define SLINK_RX_FIRQ_ENABLE CSR_MIE_FIRQ10E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */
#define SLINK_RX_FIRQ_PENDING CSR_MIP_FIRQ10P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */
#define SLINK_RX_RTE_ID RTE_TRAP_FIRQ_10 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */
#define SLINK_RX_TRAP_CODE TRAP_CODE_FIRQ_10 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */
#define SLINK_TX_FIRQ_ENABLE CSR_MIE_FIRQ11E /**< MIE CSR bit (#NEORV32_CSR_MIE_enum) */
#define SLINK_TX_FIRQ_PENDING CSR_MIP_FIRQ11P /**< MIP CSR bit (#NEORV32_CSR_MIP_enum) */
#define SLINK_TX_RTE_ID RTE_TRAP_FIRQ_11 /**< RTE entry code (#NEORV32_RTE_TRAP_enum) */
#define SLINK_TX_TRAP_CODE TRAP_CODE_FIRQ_11 /**< MCAUSE CSR trap code (#NEORV32_EXCEPTION_CODES_enum) */
/**@}*/
/**@}*/
 
 
/**********************************************************************//**
* @name Address space sections
**************************************************************************/
/**@{*/
719,6 → 802,27
 
 
/**********************************************************************//**
* @name IO Device: Bus Monitor (BUSKEEPER)
**************************************************************************/
/**@{*/
/** BUSKEEPER module prototype */
typedef struct __attribute__((packed,aligned(4))) {
uint32_t CTRL; /**< offset 0: control register (#NEORV32_BUSKEEPER_CTRL_enum) */
} neorv32_buskeeper_t;
 
/** BUSKEEPER module hardware access (#neorv32_buskeeper_t) */
#define NEORV32_BUSKEEPER (*((volatile neorv32_buskeeper_t*) (0xFFFFFF7CUL)))
 
/** BUSKEEPER control/data register bits */
enum NEORV32_BUSKEEPER_CTRL_enum {
BUSKEEPER_ERR_TYPE = 0, /**< BUSKEEPER control register(0) (r/-): Bus error type: 0=device error, 1=access timeout */
BUSKEEPER_ERR_SRC = 1, /**< BUSKEEPER control register(1) (r/-): Bus error source: 0=processor-external, 1=processor-internal */
BUSKEEPER_ERR_FLAG = 31 /**< BUSKEEPER control register(31) (r/c): Sticky error flag, clears after read */
};
/**@}*/
 
 
/**********************************************************************//**
* @name IO Device: External Interrupt Controller (XIRQ)
**************************************************************************/
/**@{*/
805,8 → 909,8
UART_CTRL_PRSC2 = 26, /**< UART control register(26) (r/w): BAUD rate clock prescaler select bit 2 */
UART_CTRL_CTS = 27, /**< UART control register(27) (r/-): current state of CTS input */
UART_CTRL_EN = 28, /**< UART control register(28) (r/w): UART global enable */
UART_CTRL_RX_IRQ = 29, /**< UART control register(29) (r/w: RX IRQ mode: 1=FIFO at least half-full; 0=FIFO not empty */
UART_CTRL_TX_IRQ = 30, /**< UART control register(30) (r/w: TX IRQ mode: 1=FIFO less than half-full; 0=FIFO not full */
UART_CTRL_RX_IRQ = 29, /**< UART control register(29) (r/w): RX IRQ mode: 1=FIFO at least half-full; 0=FIFO not empty */
UART_CTRL_TX_IRQ = 30, /**< UART control register(30) (r/w): TX IRQ mode: 1=FIFO less than half-full; 0=FIFO not full */
UART_CTRL_TX_BUSY = 31 /**< UART control register(31) (r/-): Transmitter is busy when set */
};
 
1056,13 → 1160,12
SYSINFO_CPU_ZICSR = 0, /**< SYSINFO_CPU (0): Zicsr extension (I sub-extension) available when set (r/-) */
SYSINFO_CPU_ZIFENCEI = 1, /**< SYSINFO_CPU (1): Zifencei extension (I sub-extension) available when set (r/-) */
SYSINFO_CPU_ZMMUL = 2, /**< SYSINFO_CPU (2): Zmmul extension (M sub-extension) available when set (r/-) */
SYSINFO_CPU_ZBB = 3, /**< SYSINFO_CPU (3): Zbb extension (B sub-extension) available when set (r/-) */
 
SYSINFO_CPU_ZFINX = 5, /**< SYSINFO_CPU (5): Zfinx extension (F sub-/alternative-extension) available when set (r/-) */
SYSINFO_CPU_ZXSCNT = 6, /**< SYSINFO_CPU (6): Custom extension - Small CPU counters: "cycle" & "instret" CSRs have less than 64-bit when set (r/-) */
SYSINFO_CPU_ZXNOCNT = 7, /**< SYSINFO_CPU (7): Custom extension - NO CPU counters: "cycle" & "instret" CSRs are NOT available at all when set (r/-) */
SYSINFO_CPU_ZICNTR = 7, /**< SYSINFO_CPU (7): Basie CPU counters available when set (r/-) */
SYSINFO_CPU_PMP = 8, /**< SYSINFO_CPU (8): PMP (physical memory protection) extension available when set (r/-) */
SYSINFO_CPU_HPM = 9, /**< SYSINFO_CPU (9): HPM (hardware performance monitors) extension available when set (r/-) */
SYSINFO_CPU_ZIHPM = 9, /**< SYSINFO_CPU (9): HPM (hardware performance monitors) extension available when set (r/-) */
SYSINFO_CPU_DEBUGMODE = 10, /**< SYSINFO_CPU (10): RISC-V CPU debug mode available when set (r/-) */
 
SYSINFO_CPU_FASTMUL = 30, /**< SYSINFO_CPU (30): fast multiplications (via FAST_MUL_EN generic) available when set (r/-) */
/sw/lib/include/neorv32_spi.h
52,6 → 52,8
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);
uint32_t neorv32_spi_get_nonblocking(void);
int neorv32_spi_busy(void);
 
#endif // neorv32_spi_h
/sw/lib/include/neorv32_xirq.h
36,26 → 36,12
/**********************************************************************//**
* @file neorv32_xirq.h
* @author Stephan Nolting
* @brief SExternal Interrupt controller HW driver header file.
* @brief External Interrupt controller HW driver header file.
**************************************************************************/
 
#ifndef neorv32_xirq_h
#define neorv32_xirq_h
 
 
/**********************************************************************//**
* @name XIRQ fast interrupt channel
**************************************************************************/
/**@{*/
/** XIRQ MIE FIRQ bit */
#define XIRQ_FIRQ_ENABLE CSR_MIE_FIRQ8E // MIE FIRQ bit
/** XIRQ MIP FIRQ bit */
#define XIRQ_FIRQ_PENDING CSR_MIP_FIRQ8P // MIP FIRQ bit
/** XIRQ RTE IRQ ID */
#define XIRQ_RTE_ID RTE_TRAP_FIRQ_8 // RTE IRQ ID
/**@}*/
 
 
// prototypes
int neorv32_xirq_available(void);
int neorv32_xirq_setup(void);
/sw/lib/source/neorv32_cpu.c
612,7 → 612,7
uint32_t neorv32_cpu_hpm_get_counters(void) {
 
// HPMs implemented at all?
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_HPM)) == 0) {
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_ZIHPM)) == 0) {
return 0;
}
 
695,7 → 695,7
uint32_t neorv32_cpu_hpm_get_size(void) {
 
// HPMs implemented at all?
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_HPM)) == 0) {
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_ZIHPM)) == 0) {
return 0;
}
 
/sw/lib/source/neorv32_neoled.c
96,7 → 96,7
 
/**********************************************************************//**
* Configure NEOLED controller for using WS2812 LEDs (NeoPixel-compatible). This function computes
* all the required timings and finally calls #neorv32_neoled_setup_raw.
* all the required timings and finally calls #neorv32_neoled_setup.
*
* @note WS2812 timing: T_period = 1.2us, T_high_zero = 0.4us, T_high_one = 0.8us. Change the constants if required.
* @note This function uses the SYSINFO_CLK value (from the SYSINFO HW module) to do the timing computations.
/sw/lib/source/neorv32_rte.c
202,14 → 202,12
return; // handler cannot output anything if UART0 is not implemented
}
 
char tmp;
 
// intro
neorv32_uart0_print("<RTE> ");
 
// cause
register uint32_t trap_cause = neorv32_cpu_csr_read(CSR_MCAUSE);
tmp = (char)(trap_cause & 0xf);
register char tmp = (char)(trap_cause & 0xf);
if (tmp >= 10) {
tmp = 'a' + (tmp - 10);
}
249,9 → 247,25
default: neorv32_uart0_print("Unknown trap cause: "); __neorv32_rte_print_hex_word(trap_cause); break;
}
 
// check cause if bus access fault exception
if ((trap_cause == TRAP_CODE_I_ACCESS) || (trap_cause == TRAP_CODE_L_ACCESS) || (trap_cause == TRAP_CODE_S_ACCESS)) {
register uint32_t bus_err = NEORV32_BUSKEEPER.CTRL;
if (bus_err & (1<<BUSKEEPER_ERR_FLAG)) { // exception caused by bus system?
if (bus_err & (1<<BUSKEEPER_ERR_TYPE)) {
neorv32_uart0_print(" [TIMEOUT_ERR]");
}
else {
neorv32_uart0_print(" [DEVICE_ERR]");
}
}
else { // exception was not caused by bus system -> has to be caused by PMP rule violation
neorv32_uart0_print(" [PMP_ERR]");
}
}
 
// instruction address
neorv32_uart0_print(" @ PC=");
__neorv32_rte_print_hex_word(neorv32_cpu_csr_read(CSR_MSCRATCH)); // rte core stores actual mepc to mscratch
__neorv32_rte_print_hex_word(neorv32_cpu_csr_read(CSR_MSCRATCH)); // rte core stores original mepc to mscratch
 
// additional info
neorv32_uart0_print(", MTVAL=");
324,6 → 338,12
if (tmp & (1<<SYSINFO_CPU_ZICSR)) {
neorv32_uart0_printf("Zicsr ");
}
if (tmp & (1<<SYSINFO_CPU_ZICNTR)) {
neorv32_uart0_printf("Zicntr ");
}
if (tmp & (1<<SYSINFO_CPU_ZIHPM)) {
neorv32_uart0_printf("Zihpm ");
}
if (tmp & (1<<SYSINFO_CPU_ZIFENCEI)) {
neorv32_uart0_printf("Zifencei ");
}
330,23 → 350,16
if (tmp & (1<<SYSINFO_CPU_ZMMUL)) {
neorv32_uart0_printf("Zmmul ");
}
if (tmp & (1<<SYSINFO_CPU_ZBB)) {
neorv32_uart0_printf("Zbb ");
}
 
if (tmp & (1<<SYSINFO_CPU_ZFINX)) {
neorv32_uart0_printf("Zfinx ");
}
if (tmp & (1<<SYSINFO_CPU_ZXNOCNT)) {
neorv32_uart0_printf("Zxnocnt(!) ");
}
if (tmp & (1<<SYSINFO_CPU_ZXSCNT)) {
neorv32_uart0_printf("Zxscnt(!) ");
}
 
if (tmp & (1<<SYSINFO_CPU_DEBUGMODE)) {
neorv32_uart0_printf("Debug-Mode ");
neorv32_uart0_printf("Debug ");
}
 
if (tmp & (1<<SYSINFO_CPU_FASTMUL)) {
neorv32_uart0_printf("FAST_MUL ");
}
364,14 → 377,11
neorv32_uart0_printf("not implemented\n");
}
 
// check hardware performance monitors
neorv32_uart0_printf("HPM Counters: %u counters, %u-bit wide\n", neorv32_cpu_hpm_get_counters(), neorv32_cpu_hpm_get_size());
 
 
// Memory configuration
neorv32_uart0_printf("\n=== << Memory System >> ===\n");
 
neorv32_uart0_printf("Boot Config.: Boot ");
neorv32_uart0_printf("Boot Config.: Boot ");
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_BOOTLOADER)) {
neorv32_uart0_printf("via Bootloader\n");
}
379,10 → 389,10
neorv32_uart0_printf("from memory (@ 0x%x)\n", NEORV32_SYSINFO.ISPACE_BASE);
}
 
neorv32_uart0_printf("Instr. base address: 0x%x\n", NEORV32_SYSINFO.ISPACE_BASE);
neorv32_uart0_printf("Instr. base address: 0x%x\n", NEORV32_SYSINFO.ISPACE_BASE);
 
// IMEM
neorv32_uart0_printf("Internal IMEM: ");
neorv32_uart0_printf("Internal IMEM: ");
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_INT_IMEM)) {
neorv32_uart0_printf("yes, %u bytes\n", NEORV32_SYSINFO.IMEM_SIZE);
}
391,8 → 401,8
}
 
// DMEM
neorv32_uart0_printf("Data base address: 0x%x\n", NEORV32_SYSINFO.DSPACE_BASE);
neorv32_uart0_printf("Internal DMEM: ");
neorv32_uart0_printf("Data base address: 0x%x\n", NEORV32_SYSINFO.DSPACE_BASE);
neorv32_uart0_printf("Internal DMEM: ");
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_INT_DMEM)) {
neorv32_uart0_printf("yes, %u bytes\n", NEORV32_SYSINFO.DMEM_SIZE);
}
401,7 → 411,7
}
 
// i-cache
neorv32_uart0_printf("Internal i-cache: ");
neorv32_uart0_printf("Internal i-cache: ");
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_ICACHE)) {
neorv32_uart0_printf("yes, ");
 
439,9 → 449,9
neorv32_uart0_printf("no\n");
}
 
neorv32_uart0_printf("Ext. bus interface: ");
neorv32_uart0_printf("Ext. bus interface: ");
__neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_EXT));
neorv32_uart0_printf("Ext. bus Endianness: ");
neorv32_uart0_printf("Ext. bus Endianness: ");
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_EXT_ENDIAN)) {
neorv32_uart0_printf("big\n");
}
/sw/lib/source/neorv32_slink.c
34,7 → 34,7
 
 
/**********************************************************************//**
* @file neorv32_slink.h
* @file neorv32_slink.c
* @author Stephan Nolting
* @brief Stream Link Interface HW driver source file.
**************************************************************************/
/sw/lib/source/neorv32_spi.c
143,8 → 143,6
/**********************************************************************//**
* Initiate SPI transfer.
*
* @warning The SPI always sends MSB first.
*
* @note This function is blocking.
*
* @param tx_data Transmit data (8/16/24/32-bit, LSB-aligned).
160,6 → 158,28
 
 
/**********************************************************************//**
* Initiate SPI TX transfer (non-blocking).
*
* @param tx_data Transmit data (8/16/24/32-bit, LSB-aligned).
**************************************************************************/
void neorv32_spi_put_nonblocking(uint32_t tx_data) {
 
NEORV32_SPI.DATA = tx_data; // trigger transfer
}
 
 
/**********************************************************************//**
* Get SPI RX data (non-blocking).
*
* @return Receive data (8/16/24/32-bit, LSB-aligned).
**************************************************************************/
uint32_t neorv32_spi_get_nonblocking(void) {
 
return NEORV32_SPI.DATA;
}
 
 
/**********************************************************************//**
* Check if SPI transceiver is busy.
*
* @return 0 if idle, 1 if busy
/sw/lib/source/neorv32_uart.c
256,11 → 256,10
uint8_t p = 0; // initial prsc = CLK/2
 
// raw clock prescaler
#ifdef __riscv_div
// use div instructions
#ifndef make_bootloader
i = (uint16_t)(clock / (2*baudrate));
#else
// division via repeated subtraction
// division via repeated subtraction (minimal size, only for bootloader)
while (clock >= 2*baudrate) {
clock -= 2*baudrate;
i++;
626,11 → 625,11
uint8_t p = 0; // initial prsc = CLK/2
 
// raw clock prescaler
#ifdef __riscv_div
#ifdef make_bootloader
// use div instructions
i = (uint16_t)(clock / (2*baudrate));
#else
// division via repeated subtraction
// division via repeated subtraction (minimal size, only for bootloader)
while (clock >= 2*baudrate) {
clock -= 2*baudrate;
i++;
/sw/lib/source/neorv32_xirq.c
34,7 → 34,7
 
 
/**********************************************************************//**
* @file neorv32_xirq.h
* @file neorv32_xirq.c
* @author Stephan Nolting
* @brief External Interrupt controller HW driver source file.
**************************************************************************/
/sw/lib/README.md
3,4 → 3,4
This folder provides the hardware abstraction layer (HAL) libraries for the CPU itself and the individual processor modules (peripheral/IO devices).
 
The `source` folder contains the actual C-code hardware driver functions (*.c*) while the `include` folder provides the according header files (*.h).
Application programs should only include the *main NEORV32 define file* `source/neorv32.h`. This file automatically includes all other provided header files.
Application programs should only include the *main NEORV32 define file* `include/neorv32.h`. This file automatically includes all other provided header files.
/sw/README.md
24,7 → 24,7
## [image_gen](image_gen)
 
This folder contains a simple program that is used to create NEORV32 executables (for upload via bootloader) and VHDL
memory initializiation files (for memory-persistent applications and for the bootloader).
memory initialization files (for memory-persistent applications and for the bootloader).
This program is automatically compiled using the native GCC when invoking one of the application compilation makefiles.
 
 
/CHANGELOG.md
26,6 → 26,18
 
| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
| 02.11.2021 |[**:rocket:1.6.3**](https://github.com/stnolting/neorv32/releases/tag/v1.6.3) | **New release** |
| 01.11.2021 | 1.6.2.13 | added new top generics to explicitly control implementation of `Zicntr` (CPU base counters) and `Zihpm` (hardware performance monitors, see [PR #192](https://github.com/stnolting/neorv32/pull/192) |
| 30.10.2021 | 1.6.2.12 | :sparkles: :lock: added memory-mapped register to BUSKEEPER module - software can now retrieve the actual cause of an instruction / data-load / data-store bus access fault exception (access timeout or device error); see [PR #191](https://github.com/stnolting/neorv32/pull/191) |
| 28.10.2021 | 1.6.2.11 | :sparkles: added `Zba` bit-manipulation sub-extension; :warning: removed configuration option for `B` sub-extensions: removed `CPU_EXTENSION_RISCV_Zbb` generic and according SYSINFO flag, added new `CPU_EXTENSION_RISCV_B` generic (to implement bit-manipulation `B` ISA extension with _all_ currently supported subsets), see [PR #190](https://github.com/stnolting/neorv32/pull/190) |
| 27.10.2021 | 1.6.2.10 | :bug: CPU control unit: fixed _imprecise_ illegal instruction exceptions - `MEPC` and `MTAVL` did not reflect the correct exception-causing data for illegal ALU-class (non-multi-cycle like `SUB`) operations; optimized critical path of exception logic (illegal compressed instruction detection) |
| 27.10.2021 | 1.6.2.9 | CPU control unit: minor logic optimization - `fence.i` instruction needs 1 cycle less to execute, reduced HW footprint of control engine, shortened CPU's critical path (PC update logic) |
| 26.10.2021 | 1.6.2.8 | :bug: bootloader: fixed bug in stack pointer initialization (introduced in version `1.6.2.7`); minor SPI unit VHDL code clean-up |
| 24.10.2021 | 1.6.2.7 | minor control unit fixes (add logic to check both half-words of a unaligned 32-bit instruction did not cause any bus exceptions); minor ALU logic optimization; optimized `ctr0.S`: bootloader stack pointer initialization (is now done based on the actual physical memory configuration) - bootloader is now even more independent of the actual platform configuration |
| 24.10.2021 | 1.6.2.6 | :bug: **fixed HW bug** introduced in version `1.6.2.4` (write access arbitration in BUSMUX) |
| 21.10.2021 | 1.6.2.5 | minor code edits; improved stability of UART receiver's start-bit detection (more "spike"-resistant) |
| 21.10.2021 | 1.6.2.4 | minor VHDL code fixes, clean-ups, optimizations and comment typo fixes (:lipstick:) |
| 20.10.2021 | 1.6.2.3 | SPI: minor VHDL code optimization and clean-up; NOTE: all serial interfaces (SPI, TWI, UARTs) allow to terminate a running transmission by clearing the enable flag in the module's control register |
| 18.10.2021 | 1.6.2.2 | :bug: `*_reduce_f` VHDL functions did not work for single-bit operands (see [PR #186](https://github.com/stnolting/neorv32/pull/186)) |
| 18.10.2021 | 1.6.2.1 | :sparkles: SPI: added option to configure _clock polarity_ - the SPI module now supports all standard clock modes (0,1,2,3) (see [PR #185](https://github.com/stnolting/neorv32/pull/185)); logic optimization of SPI module |
| 17.10.2021 |[**:rocket:1.6.2**](https://github.com/stnolting/neorv32/releases/tag/v1.6.2) | **New release** |
122,7 → 134,7
| 20.05.2021 | 1.5.5.5 | added system time output `mtime_o` (64-bit) driven by processor-internal _MTIME_ unit (idea [#29](https://github.com/stnolting/neorv32/discussions/29))
| 20.05.2021 | 1.5.5.4 | **on-chip debugger**: added debug memory (`DBMEM`) component |
| 20.05.2021 | 1.5.5.3 | added flag (SYSINFO.FEATURES) to allow software to discover if on-chip debugger is implemented (`SYSINFO_FEATURES_OCD`); added documentation [https://stnolting.github.io/neorv32/#_on_chip_debugger_ocd](https://stnolting.github.io/neorv32/#_on_chip_debugger_ocd) |
| 19.05.2021 | 1.5.5.2 | :sparkles: added **RISC-V CPU Debug Mode**, compatible to [RISC-V debug spec](https://github.com/riscv/riscv-debug-spec); new CSRs: `dcsr`, `dpc`, `dscratch`; new instructions: `dret`; :warning: debug mode is still **work-in-progress* and not operational yet! updated documentation CI [#26](https://github.com/stnolting/neorv32/pull/26), contributed by [umarcor](https://github.com/umarcor) :+1:; `fence.i` will not longer trap if executed but not implemented (`CPU_EXTENSION_RISCV_Zifencei` = false) |
| 19.05.2021 | 1.5.5.2 | :sparkles: added **RISC-V CPU Debug Mode**, compatible to [RISC-V debug spec](https://github.com/riscv/riscv-debug-spec); new CSRs: `dcsr`, `dpc`, `dscratch`; new instructions: `dret`; :warning: debug mode is still **work-in-progress** and not operational yet! updated documentation CI [#26](https://github.com/stnolting/neorv32/pull/26), contributed by [umarcor](https://github.com/umarcor) :+1:; `fence.i` will not longer trap if executed but not implemented (`CPU_EXTENSION_RISCV_Zifencei` = false) |
| 13.05.2021 | 1.5.5.1 | added [`UPduino_v3`](https://github.com/stnolting/neorv32/tree/master/boards/UPduino_v3) example setup; renamed signal in watchdog module (`rtl/core/neorv32_wdt.vhd`) - collision with reserved keyword in vhdl-2008 (fixing issue [#24](https://github.com/stnolting/neorv32/issues/24)) |
| 10.05.2021 | [**:rocket:1.5.5.0**](https://github.com/stnolting/neorv32/releases/tag/v1.5.5.0) | **New release** |
| 10.05.2021 | 1.5.4.12 | :warning: `mip` CSR is now read-only (pending IRQs can be cleared by disabling (and re-enabling) the according `mie` bit), writing to `mip` will raise an illegal instruction exception; :sparkles: added non-maskable interrupt (NMI), top entity port `nm_irq_i`; added new NMI to NEORV32 runtime environment |
/README.md
41,6 → 41,10
The project is intended as auxiliary processor in larger SoC designs or as *ready-to-go* stand-alone
custom / customizable microcontroller.
 
Special focus is paid on **execution safety** to provide defined and predictable behavior at any time.
Therefore, the CPU ensures that all memory access are acknowledged and no invalid/malformed instructions
are executed. Whenever an unexpected situation occurs, the application code is informed via hardware exceptions.
 
:information_source: Want to know more? Check out the [project's rationale](https://stnolting.github.io/neorv32/#_rationale).
 
:books: For detailed information take a look at the [NEORV32 documentation (online at GitHub-pages)](https://stnolting.github.io/neorv32/).
134,6 → 138,7
* on-chip debugger ([OCD](https://stnolting.github.io/neorv32/#_on_chip_debugger_ocd)) via JTGA - implementing
the [*Minimal RISC-V Debug Specification Version 0.13.2*](https://github.com/riscv/riscv-debug-spec)
and compatible with *OpenOCD* and *gdb*
* bus keeper to monitor processor-internal bus transactions ([BUSKEEPER](https://stnolting.github.io/neorv32/#_internal_bus_monitor_buskeeper))
 
:information_source: It is recommended to use the processor setup even if you want to **use the CPU in stand-alone mode**.
Just disable all optional processor-internal modules via the according generics and you will get a "CPU wrapper" that
171,12 → 176,12
Compatibility is checked by passing the [official RISC-V architecture tests](https://github.com/riscv/riscv-arch-test)
(see [`sim/README`](sim/README.md)).
 
The core implements a little-endian Von-Neumann architecture using two pipeline stages, where each stage can operate in a multi-cycle processing
scheme. The CPU supports three privilege levels (`machine` and optional `user` and `debug_mode`), the three standard RISC-V machine
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, three privilege levels (`machine` and optional `user` and `debug_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). See :books: [_"Full Virtualization"_](https://stnolting.github.io/neorv32/#_full_virtualization)
for more information.
instruction, breakpoint, environment calls).
 
 
### Available ISA Extensions
188,20 → 193,21
[[`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)]
[[`Zbb`](https://stnolting.github.io/neorv32/#_zbb_basic_bit_manipulation_operations)]
[[`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)]
[[`PMP`](https://stnolting.github.io/neorv32/#_pmp_physical_memory_protection)]
[[`HPM`](https://stnolting.github.io/neorv32/#_hpm_hardware_performance_monitors)]
[[`DEBUG`](https://stnolting.github.io/neorv32/#_cpu_debug_mode)]**
 
:warning: The `Zbb`, `Zfinx` and `Zmmul` RISC-V extensions are frozen but not officially ratified yet. Hence, there is no
:warning: The `B`, `Zfinx` and `Zmmul` RISC-V extensions are frozen but not officially ratified yet. Hence, there is no
upstream gcc support. To circumvent this, the NEORV32 software framework provides _intrinsic_ libraries for these extensions.
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
218,8 → 224,8
| CPU Configuration | LEs | FFs | Memory bits | DSPs (9-bit) | f_max |
|:--------------------------------------------------|:----:|:----:|:-----------:|:------------:|:-------:|
| `rv32i` | 806 | 359 | 1024 | 0 | 125 MHz |
| `rv32i_Zicsr` | 1729 | 813 | 1024 | 0 | 124 MHz |
| `rv32imac_Zicsr` | 2511 | 1074 | 1024 | 0 | 124 MHz |
| `rv32i_Zicsr_Zicntr` | 1729 | 813 | 1024 | 0 | 124 MHz |
| `rv32imac_Zicsr_Zicntr` | 2511 | 1074 | 1024 | 0 | 124 MHz |
 
:information_source: An incremental list of CPU extension's hardware utilization can found in
[online documentation - _"FPGA Implementation Results - CPU"_](https://stnolting.github.io/neorv32/#_cpu).
254,11 → 260,11
 
Results generated for hardware version [`1.5.7.10`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
 
| CPU Configuration | CoreMark Score | CoreMarks/MHz | Average CPI |
|:-----------------------------------------------|:--------------:|:-------------:|:-----------:|
| _small_ (`rv32i_Zicsr`) | 33.89 | **0.3389** | **4.04** |
| _medium_ (`rv32imc_Zicsr`) | 62.50 | **0.6250** | **5.34** |
| _performance_(`rv32imc_Zicsr` + perf. options) | 95.23 | **0.9523** | **3.54** |
| CPU Configuration | CoreMark Score | CoreMarks/MHz | Average CPI |
|:------------------------------------------------|:--------------:|:-------------:|:-----------:|
| _small_ (`rv32i_Zicsr`) | 33.89 | **0.3389** | **4.04** |
| _medium_ (`rv32imc_Zicsr`) | 62.50 | **0.6250** | **5.34** |
| _performance_ (`rv32imc_Zicsr` + perf. options) | 95.23 | **0.9523** | **3.54** |
 
:information_source: More information regarding the CPU performance can be found in the
[online documentation - _"CPU Performance"_](https://stnolting.github.io/neorv32/#_cpu_performance).
313,6 → 319,7
 
* [NEORV32 CPU](https://stnolting.github.io/neorv32/#_neorv32_central_processing_unit_cpu) - the CPU
* [RISC-V compatibility](https://stnolting.github.io/neorv32/#_risc_v_compatibility) - what is compatible to the specs. and what is not
* [Full Virtualization](https://stnolting.github.io/neorv32/#_full_virtualization) - hardware execution safety
* [ISA and Extensions](https://stnolting.github.io/neorv32/#_instruction_sets_and_extensions) - available RISC-V ISA extensions
* [CSRs](https://stnolting.github.io/neorv32/#_control_and_status_registers_csrs) - control and status registers
* [Traps](https://stnolting.github.io/neorv32/#_traps_exceptions_and_interrupts) - interrupts and exceptions

powered by: WebSVN 2.1.0

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