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

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 69 to Rev 70
    Reverse comparison

Rev 69 → Rev 70

/neorv32/trunk/docs/datasheet/cpu.adoc
39,7 → 39,7
CPU. Simply disable all the processor-internal modules via the generics and you will get a "CPU
wrapper" that provides a minimal CPU environment and an external bus interface (like AXI4). This
setup also allows to further use the default bootloader and software framework. From this base you
can start building your own SoC. Of course you can also use the CPU in it’s true stand-alone mode.
can start building your own SoC. Of course you can also use the CPU in it's true stand-alone mode.
 
[NOTE]
This documentation assumes the reader is familiar with the official RISC-V "User" and "Privileged Architecture" specifications.
197,8 → 197,9
Check sw-align-01 ... OK
Check xor-01 ... OK
Check xori-01 ... OK
Check fence-01 ... OK
--------------------------------
OK: 38/38 RISCV_TARGET=neorv32 RISCV_DEVICE=I XLEN=32
OK: 39/39 RISCV_TARGET=neorv32 RISCV_DEVICE=I XLEN=32
...................................
 
.**RISC-V `rv32_m/M` Tests**
260,7 → 261,7
 
.Physical Memory Protection
[IMPORTANT]
The physical memory protection (see section <<_machine_physical_memory_protection>>)
The physical memory protection (see section <<_machine_physical_memory_protection_csrs>>)
only supports the modes _OFF_ and _NAPOT_ yet and a minimal granularity of 8 bytes per region.
 
.Atomic Memory Operations
426,18 → 427,18
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:
The `Zbb` sub-extension adds the following instructions:
 
* `andn`, `orn`, `xnor`
* `clz`, `ctz`, `cpop`
* `max`, `maxu`, `min`, `minu`
* `sext.b`, `sext.h`, `zext.h`
* `rol`, `ror`, `rori`
* `orc.b`, `rev8`
* `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:
The `Zba` sub-extension adds the following instructions:
 
* `sh1add`, `sh2add`, `sh3add`
* `sh1add` `sh2add` `sh3add`
 
[TIP]
By default, the bit-manipulation unit uses an _iterative_ approach to compute shift-related operations
458,8 → 459,8
The `C` extension is available when the `CPU_EXTENSION_RISCV_C` configuration generic is _true_.
In this case the following instructions are available:
 
* `c.addi4spn`, `c.lw`, `c.sw`, `c.nop`, `c.addi`, `c.jal`, `c.li`, `c.addi16sp`, `c.lui`, `c.srli`, `c.srai` `c.andi`, `c.sub`,
`c.xor`, `c.or`, `c.and`, `c.j`, `c.beqz`, `c.bnez`, `c.slli`, `c.lwsp`, `c.jr`, `c.mv`, `c.ebreak`, `c.jalr`, `c.add`, `c.swsp`
* `c.addi4spn` `c.lw` `c.sw` `c.nop` `c.addi` `c.jal` `c.li` `c.addi16sp` `c.lui` `c.srli` `c.srai` `c.andi` `c.sub`
`c.xor` `c.or` `c.and` `c.j` `c.beqz` `c.bnez` `c.slli` `c.lwsp` `c.jr` `c.mv` `c.ebreak` `c.jalr` `c.add` `c.swsp`
 
[NOTE]
When the compressed instructions extension is enabled, branches to an _unaligned_ and _uncompressed_ instruction require
475,7 → 476,7
configuration generic is _true_. Accesses to registers beyond `x15` will raise and _illegal instruction exception_.
This extension does not add any additional instructions or features.
 
[IMPORTANT]
[NOTE]
Due to the reduced register file size an alternate toolchain ABI (**`ilp32e`**) is required.
 
 
485,22 → 486,22
regardless of the setting of the remaining exceptions. The base instruction set includes the following
instructions:
 
* immediate: `lui`, `auipc`
* jumps: `jal`, `jalr`
* branches: `beq`, `bne`, `blt`, `bge`, `bltu`, `bgeu`
* memory: `lb`, `lh`, `lw`, `lbu`, `lhu`, `sb`, `sh`, `sw`
* alu: `addi`, `slti`, `sltiu`, `xori`, `ori`, `andi`, `slli`, `srli`, `srai`, `add`, `sub`, `sll`, `slt`, `sltu`, `xor`, `srl`, `sra`, `or`, `and`
* environment: `ecall`, `ebreak`, `fence`
* immediate: `lui` `auipc`
* jumps: `jal` `jalr`
* branches: `beq` `bne` `blt` `bge` `bltu` `bgeu`
* memory: `lb` `lh` `lw` `lbu` `lhu` `sb` `sh` `sw`
* alu: `addi` `slti` `sltiu` `xori` `ori` `andi` `slli` `srli` `srai` `add` `sub` `sll` `slt` `sltu` `xor` `srl` `sra` `or` `and`
* environment: `ecall` `ebreak` `fence`
 
[NOTE]
In order to keep the hardware footprint low, the CPU's shift unit uses a bit-serial serial approach. Hence, shift operations
In order to keep the hardware footprint low, the CPU's shift unit uses a bit-serial approach. Hence, shift operations
take up to 32 cycles (plus overhead) depending on the actual shift amount. Alternatively, the shift operations can be processed
completely in parallels by a fast (but large) barrel shifter when the `FAST_SHIFT_EN` generic is _true_. In that case, shift operations
completely in parallel by a fast (but large) barrel shifter if the `FAST_SHIFT_EN` generic is _true_. In that case, shift operations
complete within 2 cycles (plus overhead) regardless of the actual shift amount.
 
[NOTE]
Internally, the `fence` instruction does not perform any operation inside the CPU. It only sets the
top’s `d_bus_fence_o` signal high for one cycle to inform the memory system a `fence` instruction has been
top's `d_bus_fence_o` signal high for one cycle to inform the memory system a `fence` instruction has been
executed. Any flags within the `fence` instruction word are ignore by the hardware.
 
 
510,8 → 511,8
`CPU_EXTENSION_RISCV_M` configuration generic is _true_. In this case the following instructions are
available:
 
* multiplication: `mul`, `mulh`, `mulhsu`, `mulhu`
* division: `div`, `divu`, `rem`, `remu`
* multiplication: `mul` `mulh` `mulhsu` `mulhu`
* division: `div` `divu` `rem` `remu`
 
[NOTE]
By default, multiplication and division operations are executed in a bit-serial approach.
527,7 → 528,7
integer multiplications but not hardware-based divisions, which will be computed entirely in software.
This extension requires only ~50% of the hardware utilization of the "full" `M` extension.
 
* multiplication: `mul`, `mulh`, `mulhsu`, `mulhu`
* multiplication: `mul` `mulh` `mulhsu` `mulhu`
 
If `Zmmul` is enabled, executing any division instruction from the `M` ISA extension (`div`, `divu`, `rem`, `remu`)
will raise an _illegal instruction exception_.
569,7 → 570,7
register file-related load/store or move instructions.
The official RISC-V specifications can be found here: https://github.com/riscv/riscv-zfinx
 
[TIP]
[NOTE]
The NEORV32 floating-point unit used by the `Zfinx` extension is compatible to the _IEEE-754_ specifications.
 
The `Zfinx` extensions only supports single-precision (`.s` instruction suffix), so it is a direct alternative
576,13 → 577,13
to the `F` extension. The `Zfinx` extension is implemented when the `CPU_EXTENSION_RISCV_Zfinx` configuration
generic is _true_. In this case the following instructions and CSRs are available:
 
* conversion: `fcvt.s.w`, `fcvt.s.wu`, `fcvt.w.s`, `fcvt.wu.s`
* comparison: `fmin.s`, `fmax.s`, `feq.s`, `flt.s`, `fle.s`
* computational: `fadd.s`, `fsub.s`, `fmul.s`
* sign-injection: `fsgnj.s`, `fsgnjn.s`, `fsgnjx.s`
* conversion: `fcvt.s.w` `fcvt.s.wu` `fcvt.w.s` `fcvt.wu.s`
* comparison: `fmin.s` `fmax.s` `feq.s` `flt.s` `fle.s`
* computational: `fadd.s` `fsub.s` `fmul.s`
* sign-injection: `fsgnj.s` `fsgnjn.s` `fsgnjx.s`
* number classification: `fclass.s`
 
* additional CSRs: `fcsr`, `frm`, `fflags`
* additional CSRs: `fcsr` `frm` `fflags`
 
[WARNING]
Fused multiply-add instructions `f[n]m[add/sub].s` are not supported!
609,12 → 610,12
[IMPORTANT]
If the `Zicsr` extension is disabled the CPU does not provide any _privileged architecture_ features at all!
In order to provide the full set of privileged functions that are required to run more complex tasks like
operating system and to allow a secure execution environment the `Zicsr` extension should always be enabled.
operating system and to allow a secure execution environment the `Zicsr` extension should be always enabled.
 
In this case the following instructions are available:
 
* CSR access: `csrrw`, `csrrs`, `csrrc`, `csrrwi`, `csrrsi`, `csrrci`
* environment: `mret`, `wfi`
* CSR access: `csrrw` `csrrs` `csrrc` `csrrwi` `csrrsi` `csrrci`
* environment: `mret` `wfi`
 
[NOTE]
If `rd=x0` for the `csrrw[i]` instructions there will be no actual read access to the according CSR.
699,7 → 700,7
* `pmpaddr*` (0..63, depending on configuration): PMP address registers
 
[TIP]
See section <<_machine_physical_memory_protection>> for more information regarding the PMP CSRs.
See section <<_machine_physical_memory_protection_csrs>> for more information regarding the PMP CSRs.
 
The actual number of regions and the minimal region granularity are defined via the top entity
`PMP_MIN_GRANULARITY` and `PMP_NUM_REGIONS` generics. `PMP_MIN_GRANULARITY` defines the minimal available
823,12 → 824,13
Whenever an exception or interrupt is triggered, the CPU transfers control to the address stored in `mtvec`
CSR. The cause of the according interrupt or exception can be determined via the content of `mcause`
CSR. The address that reflects the current program counter when a trap was taken is stored to `mepc` CSR.
Additional information regarding the cause of the trap can be retrieved from `mtval` CSR.
Additional information regarding the cause of the trap can be retrieved from `mtval` CSR and the processor's
<<_internal_bus_monitor_buskeeper>> (for memory access exceptions)
 
The traps are prioritized. If several _exceptions_ occur at once only the one with highest priority is triggered
while all remaining exceptions are ignored. If several _interrupts_ trigger at once, the one with highest priority
The traps are prioritized. If several _synchronous exceptions_ occur at once only the one with highest priority is triggered
while all remaining exceptions are ignored. If several _asynchronous exceptions_ (interrupts) trigger at once, the one with highest priority
is serviced first while the remaining ones stay _pending_. After completing the interrupt handler the interrupt with
the second highest priority will get serviced and so on until no further interrupt are pending.
the second highest priority will get serviced and so on until no further interrupts are pending.
 
.Interrupt Signal Requirements - Standard RISC-V Interrupts
[IMPORTANT]
837,24 → 839,24
 
.Interrupt Signal Requirements - Fast Interrupt Requests
[IMPORTANT]
The NEORV32-specific FIRQ request lines are triggered by a rising edge. Each request is buffered in the CPU control
The NEORV32-specific FIRQ request lines are triggered by a one-shot high-level (i.e. rising edge). Each request is buffered in the CPU control
unit until the channel is either disabled (by clearing the according `mie` CSR bit) or the request is explicitly cleared (by setting
the according `mip` CSR bit).
 
.Instruction Atomicity
[NOTE]
All instructions execute as atomic operations - interrupts can only trigger between two instructions.
So if there is a permanent interrupt request, exactly one instruction from the interrupt program will be executed before
a new interrupt handler can start.
All instructions execute as atomic operations - interrupts can only trigger _between_ two instructions.
So even if there is a permanent interrupt request, exactly one instruction from the interrupt program will be executed before
another interrupt handler can start. This allows program progress even if there are permanent interrupt requests.
 
 
:sectnums:
==== Memory Access Exceptions**
==== Memory Access Exceptions
 
If a load operation causes any exception, the instruction's destination register is
_not written_ at all. Load exceptions caused by a misalignment or a physical memory protection fault do not
trigger a bus read-operation at all. Exceptions caused by a store address misalignment or a store physical
memory protection fault do not trigger a bus write-operation at all.
trigger a bus/memory read-operation at all. Vice versa, exceptions caused by a store address misalignment or a store physical
memory protection fault do not trigger a bus/memory write-operation at all.
 
 
:sectnums:
882,7 → 884,7
 
The "Prio." column shows the priority of each trap. The highest priority is 1. The "`mcause`" column shows the
cause ID of the according trap that is written to `mcause` CSR. The "[RISC-V]" columns show the interrupt/exception code value from the
official RISC-V privileged architecture manual. The "[C]" names are defined by the NEORV32 core library (`sw/lib/include/neorv32.h`) and can
official RISC-V privileged architecture manual. The "[C]" names are defined by the NEORV32 core library (the runtime environment _RTE_) and can
be used in plain C code. The "`mepc`" and "`mtval`" columns show the value written to
`mepc` and `mtval` CSRs when a trap is triggered:
 
935,7 → 937,7
[cols="<3,<7"]
[options="header",grid="rows"]
|=======================
| Trap ID | Triggered when ...
| Trap ID [C] | Triggered when ...
| _TRAP_CODE_I_MISALIGNED_ | fetching an 32-bit instruction word that is not 32-bit-aligned (_see note below!_)
| _TRAP_CODE_I_ACCESS_ | bus timeout or bus error during instruction word fetch
| _TRAP_CODE_I_ILLEGAL_ | trying to execute an invalid instruction word (malformed or not supported) or on a privilege violation
1003,7 → 1005,7
 
[NOTE]
Currently, there a no pipelined or overlapping operations implemented within the same bus interface.
So only a single transfer request can be "on the fly".
So only a single transfer request can be "on the fly" (pending) at once.
 
:sectnums:
===== Protocol
1107,7 → 1109,7
dedicated hardware reset**. "Uncritical registers" in this context means that the initial value of these registers
after power-up is not relevant for a defined CPU boot process.
 
**Rational**
**Rationale**
 
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
1114,7 → 1116,7
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
the pipeline's data register. Therefore, the pipeline data register do no require a dedicated reset as they do not
control the actual operation (in contrast to the status register). This makes the pipeline data registers from
this example "uncritical registers".
 
1122,7 → 1124,7
 
In terms of the NEORV32 CPU, there are several pipeline registers, state machine registers and even status
and control registers (CSRs) that do not require a defined initial state to ensure a correct boot process. The
pipeline register will get initialized by the CPU’s internal state machines, which are initialized from the main
pipeline register will get initialized by the CPU's internal state machines, which are initialized from the main
control engine that actually features a defined reset. The initialization of most of the CPU's core CSRs (like
interrupt control) is done by the software (to be more specific, this is done by the `crt0.S` start-up code).
 
1129,21 → 1131,19
During the very early boot process (where `crt0.S` is running) there is no chance for undefined behavior due to
the lack of dedicated hardware resets of certain CSRs. For example the machine interrupt-enable CSR (`mie`)
does not provide a dedicated reset. The value after reset of this register is uncritical as interrupts cannot fire
because the global interrupt enabled flag in the status register (`mstatsus(mie)`) provides a dedicated
hardware reset setting it to low (globally disabling interrupts).
because the global interrupt enabled flag in the status register (`mstatsus(mie)`) _do_ provide a dedicated
hardware reset setting this bit to low (globally disabling interrupts).
 
**Reset Configuration**
 
Most CPU-internal register do feature an asynchronous reset in the VHDL code, but the "don't care" value
(VHDL `'-'`) is used for initialization of the uncritical register, effectively generating a flip-flop without a
Most CPU-internal register do provide an asynchronous reset in the VHDL code, but the "don't care" value
(VHDL `'-'`) is used for initialization of all uncritical registers, effectively generating a flip-flop without a
reset. However, certain applications or situations (like advanced gate-level / timing simulations) might
require a more deterministic reset state. For this case, a defined reset level (reset-to-low) of all registers can
be enabled via a constant in the main VHDL package file (`rtl/core/neorv32_package.vhd`):
require a more deterministic reset state. For this case, a defined reset level (reset-to-low) of all CPU registers can
be enabled ba enabling a constant in the main VHDL package file (`rtl/core/neorv32_package.vhd`):
 
[source,vhdl]
----
-- "critical" number of PMP regions --
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 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)
----
/neorv32/trunk/docs/datasheet/cpu_csr.adoc
473,13 → 473,13
_PMP_MIN_GRANULARITY_ top entity generics. _PMP_NUM_REGIONS_ defines the number of implemented
protection regions and thus, the availability of the according `pmpcfg*` and `pmpaddr*` CSRs.
 
[TIP]
[NOTE]
If trying to access an PMP-related CSR beyond _PMP_NUM_REGIONS_ **no illegal instruction
exception** is triggered. The according CSRs are read-only (writes are ignored) and always return zero.
 
[IMPORTANT]
The RISC-V-compatible NEORV32 physical memory protection only implements the _NAPOT_
(naturally aligned power-of-two region) mode with a minimal region granularity of 8 bytes.
The RISC-V-compatible NEORV32 physical memory protection only implements the **NAPOT**
(naturally aligned power-of-two region) mode yet with a minimal region granularity of 8 bytes.
 
 
:sectnums!:
500,7 → 500,7
[options="header",grid="rows"]
|=======================
| Bit | RISC-V name | R/W | Function
| 7 | _L_ | r/w | lock bit, can be set - but not be cleared again (only via CPU reset)
| 7 | _L_ | r/w | lock bit, can only be cleared by CPU reset
| 6:5 | - | r/- | reserved, read as zero
| 4:3 | _A_ | r/w | mode configuration; only OFF (`00`) and NAPOT (`11`) are supported
| 2 | _X_ | r/w | execute permission
515,9 → 515,9
[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x3b0 - 0x3ef| **Physical memory protection configuration registers** | `pmpaddr0` - `pmpaddr63`
| 0x3b0 - 0x3ef| **Physical memory protection address registers** | `pmpaddr0` - `pmpaddr63`
3+| Reset value: _UNDEFINED_
3+| The `pmpaddr*` CSRs are compatible to the RISC-V specifications. They are used to configure the base
3+| The `pmpaddr*` CSRs are compatible to the RISC-V specifications. They are used to configure the PMP region's base
address and the region size.
|======
 
611,7 → 611,7
| 0xb80 | **Machine cycle counter - high word** | `mcycleh`
3+| Reset value: _UNDEFINED_
3+| The `mcycle[h]` CSR is compatible to the RISC-V specifications. It shows the lower/upper 32-bit of the 64-bit cycle
counter. The `mcycle[h]` CSR can also be written when in machine mode and is copied to the `cycle[h]` CSR.
counter. The `mcycle[h]` CSR can also be written when in machine mode and is mirrored to the `cycle[h]` CSR.
|======
 
 
625,7 → 625,7
| 0xb82 | **Machine instructions-retired counter - high word** | `minstreth`
3+| Reset value: _UNDEFINED_
3+| The `minstret[h]` CSR is compatible to the RISC-V specifications. It shows the lower/upper 32-bit of the 64-bit retired
instructions counter. The `minstret[h]` CSR also be written when in machine mode and is copied to the `instret[h]` CSR.
instructions counter. The `minstret[h]` CSR also be written when in machine mode and is mirrored to the `instret[h]` CSR.
|======
 
 
/neorv32/trunk/docs/datasheet/overview.adoc
21,9 → 21,7
 
[TIP]
Check out the processor's **https://stnolting.github.io/neorv32/ug[online User Guide]**
that provides hands-on tutorial to get you started.
 
[TIP]
that provides hands-on tutorials to get you started.
The project's change log is available in https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md[CHANGELOG.md]
in the root directory of the NEORV32 repository. Please also check out the <<_legal>> section.
 
36,11 → 34,8
. <<_software_framework>>
. <<_on_chip_debugger_ocd>>
 
[TIP]
Links in this document are <<_overview,highlighted>>.
 
 
 
<<<
// ####################################################################################################################
:sectnums:
135,6 → 130,7
** optional general purpose IO and PWM and native NeoPixel (c) compatible smart LED interface
** optional embedded memories / caches for data, instructions and bootloader
** optional external memory interface (Wishbone / AXI4-Lite) and stream link interface (AXI4-Stream) for custom connectivity
** optional execute in place (XIP) module
** on-chip debugger compatible with OpenOCD and gdb
* **Software framework**
** GCC-based toolchain - prebuilt toolchains available; application compilation based on GNU makefiles
248,6 → 244,7
├neorv32_uart.vhd - Universal async. receiver/transmitter
├neorv32_wdt.vhd - Watchdog timer
├neorv32_wishbone.vhd - External (Wishbone) bus interface
├neorv32_xip.vhd - Execute in place module
├neorv32_xirq.vhd - External interrupt controller
├mem/neorv32_dmem.default.vhd - _Default_ data memory (architecture-only)
276,10 → 273,9
[cols="<2,<8"]
[grid="topbot"]
|=======================
| Hardware version: | `1.5.7.10`
| Top entity: | `rtl/core/neorv32_cpu.vhd`
| FPGA: | Intel Cyclone IV E `EP4CE22F17C6`
| Toolchain: | Quartus Prime 20.1.0
| Top entity: | `rtl/core/neorv32_cpu.vhd`
| FPGA: | Intel Cyclone IV E `EP4CE22F17C6`
| Toolchain: | Quartus Prime 20.1.0
|=======================
 
[cols="<5,>1,>1,>1,>1,>1"]
310,10 → 306,9
[cols="<2,<8"]
[grid="topbot"]
|=======================
| Hardware version: | `1.5.7.15`
| Top entity: | `rtl/core/neorv32_top.vhd`
| FPGA: | Intel Cyclone IV E `EP4CE22F17C6`
| Toolchain: | Quartus Prime 20.1.0
| Top entity: | `rtl/core/neorv32_top.vhd`
| FPGA: | Intel Cyclone IV E `EP4CE22F17C6`
| Toolchain: | Quartus Prime 20.1.0
|=======================
 
.Hardware utilization by the processor modules (mandatory core modules in **bold**)
323,7 → 318,7
| Module | Description | LEs | FFs | MEM bits | DSPs
| Boot ROM | Bootloader ROM (4kB) | 2 | 1 | 32768 | 0
| **BUSKEEPER** | Processor-internal bus monitor | 9 | 6 | 0 | 0
| **BUSSWITCH** | Bus mux for CPU instr. and data interface | 63 | 8 | 0 | 0
| **BUSSWITCH** | Bus multiplexer for CPU instr. and data interface | 63 | 8 | 0 | 0
| CFS | Custom functions subsystemfootnote:[Resource utilization depends on actually implemented custom functionality.] | - | - | - | -
| DMEM | Processor-internal data memory (8kB) | 19 | 2 | 65536 | 0
| DM | On-chip debugger - debug module | 493 | 240 | 0 | 0
344,6 → 339,7
| WISHBONE | External memory interface | 114 | 110 | 0 | 0
| XIRQ | External interrupt controller (32 channels) | 241 | 201 | 0 | 0
| GPTMR | General Purpose Timer | 153 | 107 | 0 | 0
| XIP | Execute in place module | 305 | 243 | 0 | 0
|=======================
 
 
/neorv32/trunk/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_ general purpose 32-bit timer (<<_general_purpose_timer_gptmr,**GPTMR**>>)
* _optional_ execute in place module (<<_execute_in_place_module_xip,**XIP**>>)
* _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**>>)
39,12 → 40,21
The following table shows signals of the processor top entity (`rtl/core/neorv32_top.vhd`).
The type of all signals is `std_ulogic` or `std_ulogic_vector`, respectively.
 
[IMPORTAN]
.Default Values of Ports
[IMPORTANT]
All _input signals_ provide default values in case they are not explicitly assigned during instantiation.
For control signals the value `L` (weak pull-down) is used. For serial and parallel data signals
the value `U` (unknown) is used. Pulled-down signals will not cause "accidental" system crashes
since all control signals have defined level.
 
.Configurable Amount of Channels
[IMPORTANT]
Some peripherals allow to configure the number of channels to-be-implemented by a generic (for example the number
of PWM or SLINK channels). The according input/output signals have a fixed sized regardless of the actually configured
amount of channels. If less than the maximum number of channels is configured, only the LSB-aligned channels are used:
in case of an _input port_ the remaining bits/channels are left unconnected; in case of an _output port_ the remaining
bits/channels are hardwired to zero.
 
[cols="<3,^2,^2,<11"]
[options="header",grid="rows"]
|=======================
73,6 → 83,11
4+^| **Advanced Memory Control Signals**
| `fence_o` | 1 | out | indicates an executed _fence_ instruction
| `fencei_o` | 1 | out | indicates an executed _fencei_ instruction
4+^| **Execute In Place Interface (<<_execute_in_place_module_xip,**XIP**>>)**
| `xip_csn_o` | 1 | out | chi select, low-active
| `xip_clk_o` | 1 | out | serial clock
| `xip_sdi_i` | 1 | in | serial data input
| `xip_sdo_o` | 1 | out | serial data output
4+^| **Stream Link Interface (<<_stream_link_interface_slink,SLINK>>)**
| `slink_tx_dat_o` | 8x32 | out | TX link _n_ data
| `slink_tx_val_o` | 8 | out | TX link _n_ data valid
102,7 → 117,7
| `twi_sda_io` | 1 | inout | TWI serial data line
| `twi_scl_io` | 1 | inout | TWI serial clock line
4+^| **Pulse-Width Modulation Channels (<<_pulse_width_modulation_controller_pwm,PWM>>)**
| `pwm_o` | 0..60 | out | pulse-width modulated channels
| `pwm_o` | 60 | out | pulse-width modulated channels
4+^| **Custom Functions Subsystem (<<_custom_functions_subsystem_cfs,CFS>>)**
| `cfs_in_i` | 32 | in | custom CFS input signal conduit
| `cfs_out_o` | 32 | out | custom CFS output signal conduit
140,6 → 155,10
Privileged software can determine the actual CPU and processor configuration via the `misa` and the
<<_system_configuration_information_memory_sysinfo, SYSINFO>> registers.
 
[TIP]
Run a quick simulation using the provided simulation/GHDL scripts (https://stnolting.github.io/neorv32/ug/#_hello_world)
to verify the configuration of the processor generics is valid.
 
[NOTE]
If optional modules (like CPU extensions or peripheral devices) are *not enabled* the according circuitry
**will not be synthesized at all**. Hence, the disabled modules do not increase area and power requirements
425,7 → 444,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.
The maximum value is 64, the minimum value is 0. See section <<_machine_counter_and_timer_csrs>> 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.
|======
586,7 → 605,7
 
 
:sectnums!:
===== _ICACHE_NUM_BLOCK_
===== _ICACHE_NUM_BLOCKS_
 
[cols="4,4,2"]
[frame="all",grid="none"]
593,7 → 612,7
|======
| **ICACHE_NUM_BLOCKS** | _natural_ | 4
3+| Number of blocks (cache "pages" or "lines") in the instruction cache. Has to be a power of two. Has no
effect when <<_icache_dmem_en>> is false.
effect when <<_icache_en>> is false.
|======
 
 
605,7 → 624,7
|======
| **ICACHE_BLOCK_SIZE** | _natural_ | 64
3+| Size in bytes of each block in the instruction cache. Has to be a power of two. Has no effect when
<<_icache_dmem_en>> is _false_.
<<_icache_en>> is _false_.
|======
 
 
617,7 → 636,7
|======
| **ICACHE_ASSOCIATIVITY** | _natural_ | 1
3+| Associativity (= number of sets) of the instruction cache. Has to be a power of two. Allowed configurations:
`1` = 1 set, direct mapped; `2` = 2-way set-associative. Has no effect when <<_icache_dmem_en>> is _false_.
`1` = 1 set, direct mapped; `2` = 2-way set-associative. Has no effect when <<_icache_en>> is _false_.
|======
 
 
1029,7 → 1048,19
|======
 
 
:sectnums!:
===== _IO_XIP_EN_
 
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_XIP_EN** | _boolean_ | false
3+| Implement the execute in place module (XIP) when _true_.
See section <<_execute_in_place_module_xip>> for more information.
|======
 
 
 
<<<
// ####################################################################################################################
:sectnums:
1167,7 → 1198,7
accessed from programs running in less-privileged user mode. For example, if the system relies on
a periodic interrupt from the _MTIME_ timer unit, user-level programs could alter the _MTIME_
configuration corrupting this interrupt. This kind of security issues can be compensated using the
PMP system (see <<_machine_physical_memory_protection>>).
PMP system (see <<_machine_physical_memory_protection_csrs>>).
 
 
:sectnums:
1221,7 → 1252,7
[TIP]
The following table shows the _default hardware-defined_ physical memory attributes of each main address space region.
Additional user-defined attributes (for example certain read/write/execute rights for specific address space regions) can be
provided using the RISC-V <<_machine_physical_memory_protection>>.
provided using the RISC-V <<_machine_physical_memory_protection_csrs>>.
 
[cols="^1,^2,^2,^3,^2"]
[options="header",grid="rows"]
1280,8 → 1311,12
 
* access to the processor-internal IMEM and processor-internal IMEM is implemented
* access to the processor-internal DMEM and processor-internal DMEM is implemented
* access to the bootloader ROM and beyond → addresses >= _BOOTROM_BASE_ (default 0xFFFF0000) will never be forwarded to the external memory interface
* access to the bootloader ROM and beyond -> addresses >= _BOOTROM_BASE_ (default 0xFFFF0000) will never be forwarded to the external memory interface
 
[NOTE]
If the Execute In Place module (XIP) is implemented accesses map to this module are not forwarded to the
external memory interface. See section <<_execute_in_place_module_xip>> for more information.
 
If no (or not all) processor-internal memories are implemented, the according base addresses are mapped to external memories.
For example, if the processor-internal IMEM is not implemented (<<_mem_int_imem_en>> = _false_), the processor will forward
any access to the instruction address space (starting at `ispace_base_c`) via the external bus interface to the external
1407,7 → 1442,7
has to be a power of two (minimum 4 bytes)! Address spaces must not overlap!
 
[IMPORTANT]
When accessing an IO device that hast not been implemented (via the according _IO_x_EN_ generic), a
When accessing an IO device that hast not been implemented (via the according generic), a
load/store access fault exception is triggered.
 
[IMPORTANT]
1416,6 → 1451,11
Processor-internal memories as well as modules connected to the external memory interface can still
be written with a byte-wide granularity.
 
[NOTE]
Most of the IO devices do not have a hardware reset. Instead, the devices are reset via software by
writing zero to the unit's control register. A general software-based reset of all devices is done by the
application start-up code `crt0.S`.
 
[TIP]
You should use the provided core software library to interact with the peripheral devices. This
prevents incompatibilities with future versions, since the hardware driver functions handle all the
1424,11 → 1464,6
[TIP]
A CMSIS-SVD-compatible **System View Description (SVD)** file including all peripherals is available in `sw/svd`.
 
[TIP]
Most of the IO devices do not have a hardware reset. Instead, the devices are reset via software by
writing zero to the unit's control register. A general software-based reset of all devices is done by the
application start-up code `crt0.S`.
 
**Interrupts of Processor-Internal Modules**
 
Most peripheral/IO devices provide some kind of interrupt (for example to signal available incoming data). These
1460,12 → 1495,12
* `r/-` registers / bits are read-only; any write access to them has no effect
* `-/w` these registers / bits are write-only; they auto-clear in the next cycle and are always read as zero
 
[TIP]
[NOTE]
Bits / registers that are not listed in the register map tables are not (yet) implemented. These registers
/ bits are always read as zero. A write access to them has no effect, but user programs should only
write zero to them to keep compatible with future extension.
 
[TIP]
[NOTE]
When writing to read-only registers, the access is nevertheless acknowledged, but no actual data is
written. When reading data from a write-only register the result is undefined.
 
1508,4 → 1543,6
 
include::soc_gptmr.adoc[]
 
include::soc_xip.adoc[]
 
include::soc_sysinfo.adoc[]
/neorv32/trunk/docs/datasheet/soc_buskeeper.adoc
6,7 → 6,7
[frame="topbot",grid="none"]
|=======================
| Hardware source file(s): | neorv32_buskeeper.vhd |
| Software driver file(s): | none | explicitly used
| Software driver file(s): | none |
| Top entity port: | none |
| Configuration generics: | none |
| Package constants: | `max_proc_int_response_time_c` | Access time window (#cycles)
32,24 → 32,42
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 and is automatically cleared when reading or
writing the `NEORV32_BUSKEEPER.CTRL` register. The _BUSKEEPER_ERR_TYPE_ indicated the tape of the bus fault:
writing the `NEORV32_BUSKEEPER.CTRL` register. The _BUSKEEPER_ERR_TYPE_ bit defines the type of the bus fault:
 
* _BUSKEEPER_ERR_TYPE_ = `0` - "Device Error": The bus access exception was cause by the memory-mapped device that
* `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
* `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 that this error type can also be raised
by the optional timeout feature of the <<_processor_external_memory_interface_wishbone_axi4_lite>>).
 
[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.
Bus access fault exceptions are also raised if a physical memory protection (PMP) rule is violated. In this case
the _BUSKEEPER_ERR_FLAG_ bit remains zero (since the error signal is not triggered by the BUSKEEPER but by
the CPU's PMP logic).
 
 
**NULL Address Check**
 
The bus keeper can ensure that no accesses are permitted to NULL addresses (`addr = 0x00000000`). These kind of
access often occur when using uninitialized pointers. If the _BUSKEEPER_NULL_CHECK_EN_ bit is set, any access to
address zero (instruction fetch, load data, store data) will raise an according bus exception. This flag
automatically clears on a hardware reset.
 
If a NULL address access has been detected the _BUSKEEPER_ERR_FLAG_ flag is set and the _BUSKEEPER_ERR_TYPE_
flag is cleared indicating a "Device Error".
 
[NOTE]
Address 0 is normally used by the IMEM and contains boot code instructions that are executed _once_ right after
hardware reset. Hence, activating the bus keeper's NULL check in application code will not corrupt code execution
at all.
 
 
.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
.2+<| `0xffffff7C` .2+<| `NEORV32_BUSKEEPER.CTRL` <|`0` _BUSKEEPER_ERR_TYPE_ ^| r/- <| Bus error type, valid if _BUSKEEPER_ERR_FLAG_ is set: `0`=device error, `1`=access timeout
<|`31` _BUSKEEPER_ERR_FLAG_ ^| r/- <| Sticky error flag, clears after read or write access
.3+<| `0xffffff7C` .3+<| `NEORV32_BUSKEEPER.CTRL` <|`0` _BUSKEEPER_ERR_TYPE_ ^| r/- | Bus error type, valid if _BUSKEEPER_ERR_FLAG_
<|`16` _BUSKEEPER_NULL_CHECK_EN_ ^| r/w <| Enable NULL address check when set
<|`31` _BUSKEEPER_ERR_FLAG_ ^| r/- <| Sticky error flag, clears after read or write access
|=======================
/neorv32/trunk/docs/datasheet/soc_dmem.adoc
14,6 → 14,11
| CPU interrupts: | none |
|=======================
 
Implementation of the processor-internal data memory is enabled via the processor's _MEM_INT_DMEM_EN_
generic. The size in bytes is defined via the _MEM_INT_DMEM_SIZE_ generic. If the DMEM is implemented,
the memory is mapped into the data memory space and located right at the beginning of the data memory
space (default `dspace_base_c` = 0x80000000). The DMEM is always implemented as true RAM.
 
[NOTE]
The actual DMEM is split into two design files: a plain entity definition (`neorv32_dmem.entity.vhd`) and the actual
architecture definition (`mem/neorv32_dmem.default.vhd`). This **default architecture** provides a _generic_ and
20,8 → 25,3
_platform independent_ memory design that (should) infers embedded memory block. You can replace/modify the architecture
source file in order to use platform-specific features (like advanced memory resources) or to improve technology mapping
and/or timing.
 
Implementation of the processor-internal data memory is enabled via the processor's _MEM_INT_DMEM_EN_
generic. The size in bytes is defined via the _MEM_INT_DMEM_SIZE_ generic. If the DMEM is implemented,
the memory is mapped into the data memory space and located right at the beginning of the data memory
space (default `dspace_base_c` = 0x80000000). The DMEM is always implemented as RAM.
/neorv32/trunk/docs/datasheet/soc_gpio.adoc
14,26 → 14,30
| CPU interrupts: | none |
|=======================
 
**Theory of Operation**
 
The general purpose parallel IO port unit provides a simple 64-bit parallel input port and a 64-bit parallel
output port. These ports can be used chip-externally (for example to drive status LEDs, connect buttons, etc.)
or system-internally to provide control signals for other IP modules. The component is disabled for
implementation when the _IO_GPIO_EN_ generic is set _false_. In this case GPIO output port is tied to all-zero.
or chip-internally to provide control signals for other IP modules. The component is disabled for
implementation when the _IO_GPIO_EN_ generic is set _false_. In this case the GPIO output port `gpio_o` is tied to all-zero.
 
.Access atomicity
.Access Atomicity
[NOTE]
The GPIO modules uses two memory-mapped registers (each 32-bit) each for accessing the input and
output signals. Since the CPU can only process 32-bit "at once" updating the entire output cannot
be performed within a single clock cycle.
 
.INPUT is read-only
[NOTE]
Write accesses to the `NEORV32_GPIO.INPUT_LO` and `NEORV32_GPIO.INPUT_HI` registers will raise a store bus
error exception. The BUSKEEPER will indicate a "DEVICE_ERR" in this case.
 
 
.GPIO unit register map (`struct NEORV32_GPIO`)
[cols="<2,<2,^1,^1,<6"]
[options="header",grid="rows"]
|=======================
| Address | Name [C] | Bit(s) | R/W | Function
| `0xffffffc0` | `NEORV32_GPIO.INPUT_LO` | 31:0 | r/- | parallel input port pins 31:0 (write accesses are ignored)
| `0xffffffc4` | `NEORV32_GPIO.INPUT_HI` | 31:0 | r/- | parallel input port pins 63:32 (write accesses are ignored)
| Address | Name [C] | Bit(s) | R/W | Function
| `0xffffffc0` | `NEORV32_GPIO.INPUT_LO` | 31:0 | r/- | parallel input port pins 31:0
| `0xffffffc4` | `NEORV32_GPIO.INPUT_HI` | 31:0 | r/- | parallel input port pins 63:32
| `0xffffffc8` | `NEORV32_GPIO.OUTPUT_LO` | 31:0 | r/w | parallel output port pins 31:0
| `0xffffffcc` | `NEORV32_GPIO.OUTPUT_HI` | 31:0 | r/w | parallel output port pins 63:32
|=======================
/neorv32/trunk/docs/datasheet/soc_icache.adoc
15,21 → 15,10
| CPU interrupts: | none |
|=======================
 
[NOTE]
The default `neorv32_icache.vhd` HDL source file provides a _generic_ memory design that infers embedded
memory. You might need to replace/modify the source file in order to use platform-specific features
(like advanced memory resources) or to improve technology mapping and/or timing.
The processor features an optional cache for instructions to improve performance when using memories with high
access latencies. The cache is directly connected to the CPU's instruction fetch interface and provides
full-transparent buffering of instruction fetch accesses to the entire address space.
 
The processor features an optional cache for instructions to compensate memories with high latency. The
cache is directly connected to the CPU's instruction fetch interface and provides a full-transparent buffering
of instruction fetch accesses to the entire 4GB address space.
 
[IMPORTANT]
The instruction cache is intended to accelerate instruction fetch via the external memory interface.
Since all processor-internal memories provide an access latency of one cycle (by default), caching
internal memories does not bring any performance gain. However, it _might_ reduce traffic on the
processor-internal bus.
 
The cache is implemented if the _ICACHE_EN_ generic is true. The size of the cache memory is defined via
_ICACHE_BLOCK_SIZE_ (the size of a single cache block/page/line in bytes; has to be a power of two and >=
4 bytes), _ICACHE_NUM_BLOCKS_ (the total amount of cache blocks; has to be a power of two and >= 1) and
36,20 → 25,33
the actual cache associativity _ICACHE_ASSOCIATIVITY_ (number of sets; 1 = direct-mapped, 2 = 2-way set-associative,
has to be a power of two and >= 1).
 
If the cache associativity (_ICACHE_ASSOCIATIVITY_) is > 1 the LRU replacement policy (least recently
If the cache associativity (_ICACHE_ASSOCIATIVITY_) is greater than 1 the LRU replacement policy (least recently
used) is used.
 
[TIP]
Keep the features of the targeted FPGA's memory resources (block RAM) in mind when configuring
.Cache Memory HDL
[NOTE]
The default `neorv32_icache.vhd` HDL source file provides a _generic_ memory design that infers embedded
memory. You might need to replace/modify the source file in order to use platform-specific features
(like advanced memory resources) or to improve technology mapping and/or timing. Also, keep the features
of the targeted FPGA's memory resources (block RAM) in mind when configuring
the cache size/layout to maximize and optimize resource utilization.
 
.Caching Internal Memories
[NOTE]
The instruction cache is intended to accelerate instruction fetches from _processor-external_ memories.
Since all processor-internal memories provide an access latency of one cycle (by default), caching
internal memories does not bring a relevant performance gain. However, it will slightly reduce traffic on the
processor-internal bus.
 
.Manual Cache Clear/Reload
[NOTE]
By executing the `ifence.i` instruction (`Zifencei` CPU extension) the cache is cleared and a reload from
main memory is forced. Among other things, this allows to implement self-modifying code.
main memory is triggered. Among other things this allows to implement self-modifying code.
 
**Bus Access Fault Handling**
 
The cache always loads a complete cache block (_ICACHE_BLOCK_SIZE_ bytes) aligned to the size of a cache
block if a miss is detected. If any of the accessed addresses within a single block do not successfully
acknowledge (i.e. issuing an error signal or timing out) the whole cache block is invalidate and any access to
an address within this cache block will also raise an instruction fetch bus error fault exception.
The cache always loads a complete cache block (_ICACHE_BLOCK_SIZE_ bytes) aligned to it's size every time a
cache miss is detected. If any of the accessed addresses within a single block do not successfully
acknowledge the transfer (i.e. issuing an error signal or timing out) the whole cache block is invalidated and
any access to an address within this cache block will raise an instruction fetch bus error exception.
 
/neorv32/trunk/docs/datasheet/soc_imem.adoc
15,25 → 15,25
| CPU interrupts: | none |
|=======================
 
[NOTE]
The actual IMEM is split into two design files: a plain entity definition (`neorv32_imem.entity.vhd`) and the actual
architecture definition (`mem/neorv32_imem.default.vhd`). This **default architecture** provides a _generic_ and
_platform independent_ memory design that (should) infers embedded memory block. You can replace/modify the architecture
source file in order to use platform-specific features (like advanced memory resources) or to improve technology mapping
and/or timing.
 
Implementation of the processor-internal instruction memory is enabled via the processor's
_MEM_INT_IMEM_EN_ generic. The size in bytes is defined via the _MEM_INT_IMEM_SIZE_ generic. If the
IMEM is implemented, the memory is mapped into the instruction memory space and located right at the
beginning of the instruction memory space (default `ispace_base_c` = 0x00000000).
 
By default, the IMEM is implemented as RAM, so the content can be modified during run time. This is
By default the IMEM is implemented as true RAM so the content can be modified during run time. This is
required when using a bootloader that can update the content of the IMEM at any time. If you do not need
the bootloader anymore - since your application development has completed and you want the program to
permanently reside in the internal instruction memory - the IMEM is automatically implemented as _pre-intialized_
ROM when the processor-internal bootloader is disabled (_INT_BOOTLOADER_EN_ = _false_).
 
When the IMEM is implemented as ROM, it will be initialized during synthesis with the actual application
program image. The compiler toolchain will generate a VHDL initialization
When the IMEM is implemented as ROM, it will be initialized during synthesis (actually, by the bitstream)
with the actual application program image. The compiler toolchain will generate a VHDL initialization
file `rtl/core/neorv32_application_image.vhd`, which is automatically inserted into the IMEM. If
the IMEM is implemented as RAM (default), the memory will **not be initialized** at all.
the IMEM is implemented as RAM (default), the memory will **not be initialized at all**.
 
[NOTE]
The actual IMEM is split into two design files: a plain entity definition (`neorv32_imem.entity.vhd`) and the actual
architecture definition (`mem/neorv32_imem.default.vhd`). This **default architecture** provides a _generic_ and
_platform independent_ memory design that (should) infers embedded memory block. You can replace/modify the architecture
source file in order to use platform-specific features (like advanced memory resources) or to improve technology mapping
and/or timing.
/neorv32/trunk/docs/datasheet/soc_mtime.adoc
14,22 → 14,23
| CPU interrupts: | `MTI` | machine timer interrupt (see <<_processor_interrupts>>)
|=======================
 
**Theory of Operation**
The MTIME module implements the memory-mapped MTIME machine timer from the official RISC-V
specifications. This module features a 64-bit system timer incrementing with the primary processor clock.
Besides accessing the MTIME register via memory operation the current system time can also be obtained using
the `time[h]` CSRs. Furthermore, the current system time is made available for processor-external
usage via the top's `mtime_o` signal.
 
The MTIME machine system timer implements the memory-mapped MTIME timer from the official RISC-V
specifications. This unit features a 64-bit system timer incremented with the primary processor clock.
The current system time can also be obtained using the `time[h]` CSRs and is made available for processor-external
use via the top's `mtime_o` signal.
The 64-bit system time can be accessed via the `TIME_LO` and `TIME_HI` memory-mapped registers (read/write) and also via
the CPU's `time[h]` CSRs (read-only). A 64-bit time compare register - accessible via the memory-mapped `TIMECMP_LO` and `TIMECMP_HI`
registers - is used to configure the CPU's MTI (machine timer interrupt). The interrupt is triggered
whenever `TIME` (high & low part) is greater than or equal to `TIMECMP` (high & low part).
The interrupt remain active (=pending) until `TIME` becomes less `TIMECMP` again (either by modifying `TIME` or `TIMECMP`).
 
[NOTE]
If the processor-internal **MTIME unit is NOT implemented**, the top's `mtime_i` input signal is used to update the `time[h]` CSRs
and the `MTI` machine timer CPU interrupt (`MTI`) is directly connected to the top's `mtime_irq_i` input.
If the processor-internal **MTIME module is NOT implemented**, the top's `mtime_i` input signal is used to update the `time[h]` CSRs
and the `MTI` machine timer CPU interrupt (`MTI`) is directly connected to the top's `mtime_irq_i` input. The `mtime_o` signal
is hardwired to zero in this case.
 
The 64-bit system time can be accessed via the `TIME_LO` and `TIME_HI` memory-mapped registers (read/write) and also via
the CPU's `time[h]` CSRs (read-only). A 64-bit time compare register - accessible via memory-mapped `TIMECMP_LO` and `TIMECMP_HI`
registers - is used to configure an interrupt to the CPU. The interrupt is triggered
whenever `TIME` (high & low part) >= `TIMECMP` (high & low part) and is directly forwarded to the CPU's `MTI` interrupt.
The interrupt remain active (=pending) until `TIME` < `TIMECMP` (either by modifying `TIME` or `TIMECMP`).
 
.MTIME register map (`struct NEORV32_MTIME`)
[cols="<3,<3,^1,^1,<6"]
/neorv32/trunk/docs/datasheet/soc_pwm.adoc
8,7 → 8,7
| Hardware source file(s): | neorv32_pwm.vhd |
| Software driver file(s): | neorv32_pwm.c |
| | neorv32_pwm.h |
| Top entity port: | `pwm_o` | up to 60 PWM output channels (1-bit per channel)
| Top entity port: | `pwm_o` | up to 60 PWM output channels (60-bit, fixed)
| Configuration generics: | _IO_PWM_NUM_CH_ | number of PWM channels to implement (0..60)
| CPU interrupts: | none |
|=======================
17,6 → 17,10
bit resolution per channel. The actual number of implemented channels is defined by the _IO_PWM_NUM_CH_ generic.
Setting this generic to zero will completely remove the PWM controller from the design.
 
[NOTE]
The `pwm_o` has a static size of 60-bit. Is less than 60 PWM channels are configured, only the LSB-aligned channels
(bits) are used while the remaining bits are hardwired to zero.
 
The PWM controller is based on an 8-bit base counter with a programmable threshold comparators for each channel
that defines the actual duty cycle. The controller can be used to drive fancy RGB-LEDs with 24-
bit true color, to dim LCD back-lights or even for "analog" control. An external integrator (RC low-pass filter)
/neorv32/trunk/docs/datasheet/soc_spi.adoc
104,7 → 104,13
 
Hence, the maximum SPI clock is f~main~ / 4.
 
.High-Speed SPI mode
[TIP]
The module provides a "high-speed" SPI mode. In this mode the clock prescaler configuration (SPI_CTRL_PRSCx) is ignored
and the SPI clock operates at f~main~ / 2 (half of the processor's main clock). High speed SPI mode is enabled by setting
the control register's _SPI_CTRL_HIGHSPEED_ bit.
 
 
**SPI Interrupt**
 
The SPI module provides a single interrupt to signal "transmission done" to the CPU. Whenever the SPI
117,23 → 123,24
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.18+<| `0xffffffa8` .18+<| `NEORV32_SPI.CTRL` <|`0` _SPI_CTRL_CS0_ ^| r/w .8+<| Direct chip-select 0..7; setting `spi_csn_o(x)` low when set
<|`1` _SPI_CTRL_CS1_ ^| r/w
<|`2` _SPI_CTRL_CS2_ ^| r/w
<|`3` _SPI_CTRL_CS3_ ^| r/w
<|`4` _SPI_CTRL_CS4_ ^| r/w
<|`5` _SPI_CTRL_CS5_ ^| r/w
<|`6` _SPI_CTRL_CS6_ ^| r/w
<|`7` _SPI_CTRL_CS7_ ^| r/w
<|`8` _SPI_CTRL_EN_ ^| r/w <| SPI enable
<|`9` _SPI_CTRL_CPHA_ ^| r/w <| clock phase (`0`=sample RX on rising edge & update TX on falling edge; `1`=sample RX on falling edge & update TX on rising edge)
<|`10` _SPI_CTRL_PRSC0_ ^| r/w .3+| 3-bit clock prescaler select
<|`11` _SPI_CTRL_PRSC1_ ^| r/w
<|`12` _SPI_CTRL_PRSC2_ ^| r/w
<|`13` _SPI_CTRL_SIZE0_ ^| r/w .2+<| transfer size (`00`=8-bit, `01`=16-bit, `10`=24-bit, `11`=32-bit)
<|`14` _SPI_CTRL_SIZE1_ ^| r/w
<|`15` _SPI_CTRL_CPOL_ ^| r/w <| clock polarity
<|`16` .. `30` ^| r/- <| _reserved, read as zero
<|`31` _SPI_CTRL_BUSY_ ^| r/- <| transmission in progress when set
.19+<| `0xffffffa8` .19+<| `NEORV32_SPI.CTRL` <|`0` _SPI_CTRL_CS0_ ^| r/w .8+<| Direct chip-select 0..7; setting `spi_csn_o(x)` low when set
<|`1` _SPI_CTRL_CS1_ ^| r/w
<|`2` _SPI_CTRL_CS2_ ^| r/w
<|`3` _SPI_CTRL_CS3_ ^| r/w
<|`4` _SPI_CTRL_CS4_ ^| r/w
<|`5` _SPI_CTRL_CS5_ ^| r/w
<|`6` _SPI_CTRL_CS6_ ^| r/w
<|`7` _SPI_CTRL_CS7_ ^| r/w
<|`8` _SPI_CTRL_EN_ ^| r/w <| SPI enable
<|`9` _SPI_CTRL_CPHA_ ^| r/w <| clock phase (`0`=sample RX on rising edge & update TX on falling edge; `1`=sample RX on falling edge & update TX on rising edge)
<|`10` _SPI_CTRL_PRSC0_ ^| r/w .3+| 3-bit clock prescaler select
<|`11` _SPI_CTRL_PRSC1_ ^| r/w
<|`12` _SPI_CTRL_PRSC2_ ^| r/w
<|`13` _SPI_CTRL_SIZE0_ ^| r/w .2+<| transfer size (`00`=8-bit, `01`=16-bit, `10`=24-bit, `11`=32-bit)
<|`14` _SPI_CTRL_SIZE1_ ^| r/w
<|`15` _SPI_CTRL_CPOL_ ^| r/w <| clock polarity
<|`16` _SPI_CTRL_HIGHSPEED_ ^| r/w <| enable SPI high-speed mode (ignoring _SPI_CTRL_PRSC_)
<|`17:30` ^| r/- <| _reserved, read as zero
<|`31` _SPI_CTRL_BUSY_ ^| r/- <| transmission in progress when set
| `0xffffffac` | `NEORV32_SPI.DATA` |`31:0` | r/w | receive/transmit data, LSB-aligned
|=======================
/neorv32/trunk/docs/datasheet/soc_sysinfo.adoc
21,6 → 21,11
as the NEORV32 software runtime environment require information from this device (like memory layout
and default clock speed) for correct operation.
 
[NOTE]
Any write access to the SYSINFO module will raise a store bus error exception. The <<_internal_bus_monitor_buskeeper>>
will signal a "DEVICE ERROR" in this case.
 
 
.SYSINFO register map (`struct NEORV32_SYSINFO`)
[cols="<2,<4,<7"]
[options="header",grid="all"]
50,9 → 55,9
| `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)
| `8` | _SYSINFO_CPU_PMP_ | `PMP` (physical memory protection) extension available when set (via top's <<_>> generic)
| `9` | _SYSINFO_CPU_HPM_ | `HPM` (hardware performance monitors) extension available when set (via top's <<_>> generic)
| `10` | _SYSINFO_CPU_DEBUGMODE_ | RISC-V CPU `debug_mode` available when set (via top's <<_>> generic)
| `8` | _SYSINFO_CPU_PMP_ | `PMP` (physical memory protection) extension available when set (via top's <<_pmp_num_regions>> generic)
| `9` | _SYSINFO_CPU_HPM_ | `HPM` (hardware performance monitors) extension available when set (via top's <<_cpu_extension_riscv_zihpm>> generic)
| `10` | _SYSINFO_CPU_DEBUGMODE_ | RISC-V CPU `debug_mode` available when set (via top's <<_on_chip_debugger_en>> generic)
| `30 | _SYSINFO_CPU_FASTMUL_ | fast multiplication available when set (via top's <<_fast_mul_en>> generic)
| `31` | _SYSINFO_CPU_FASTSHIFT_ | fast shifts available when set (via top's <<_fast_shift_en>> generic)
|=======================
79,7 → 84,7
| `18` | _SYSINFO_SOC_IO_UART0_ | set if the primary UART0 is implemented (via top's <<_io_uart0_en>> generic)
| `19` | _SYSINFO_SOC_IO_SPI_ | set if the SPI is implemented (via top's <<_io_spi_en>> generic)
| `20` | _SYSINFO_SOC_IO_TWI_ | set if the TWI is implemented (via top's <<_io_twi_en>> generic)
| `21` | _SYSINFO_SOC_IO_PWM_ | set if the PWM is implemented (via top's <<_io_pwm_en>> generic)
| `21` | _SYSINFO_SOC_IO_PWM_ | set if the PWM is implemented (via top's <<_io_pwm_num_ch>> generic)
| `22` | _SYSINFO_SOC_IO_WDT_ | set if the WDT is implemented (via top's <<_io_wdt_en>> generic)
| `23` | _SYSINFO_SOC_IO_CFS_ | set if the custom functions subsystem is implemented (via top's <<_io_cfs_en>> generic)
| `24` | _SYSINFO_SOC_IO_TRNG_ | set if the TRNG is implemented (via top's _IO_TRNG_EN_ generic)
86,6 → 91,9
| `25` | _SYSINFO_SOC_IO_SLINK_ | set if the SLINK is implemented (via top's <<_slink_num_tx>> and/or <<_slink_num_rx>> generics)
| `26` | _SYSINFO_SOC_IO_UART1_ | set if the secondary UART1 is implemented (via top's <<_io_uart1_en>> generic)
| `27` | _SYSINFO_SOC_IO_NEOLED_ | set if the NEOLED is implemented (via top's <<_io_neoled_en>> generic)
| `28` | _SYSINFO_SOC_IO_XIRQ_ | set if the XIRQ is implemented (via top's <<_xirq_num_ch>> generic)
| `29` | _SYSINFO_SOC_IO_GPTMR_ | set if the GPTMR is implemented (via top's <<_io_gptmr_en>> generic)
| `30` | _SYSINFO_SOC_IO_XIP_ | set if the XIP module is implemented (via top's <<_io_xip_en>> generic)
|=======================
 
 
/neorv32/trunk/docs/datasheet/soc_wishbone.adoc
42,6 → 42,10
. **and** it does not target the internal bootloader ROM or any of the IO devices - regardless if one or more of these components are
actually implemented or not.
 
[NOTE]
If the Execute In Place module (XIP) is implemented accesses map to this module are not forwarded to the
external memory interface. See section <<_execute_in_place_module_xip>> for more information.
 
[TIP]
See section <<_address_space>> for more information.
 
/neorv32/trunk/docs/datasheet/soc_xip.adoc
0,0 → 1,195
<<<
:sectnums:
==== Execute In Place Module (XIP)
 
[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source file(s): | neorv32_xip.vhd |
| Software driver file(s): | neorv32_xip.c |
| | neorv32_xip.h |
| Top entity port: | `xip_csn_o` | 1-bit chip select, low-active
| | `xip_clk_o` | 1-bit serial clock output
| | `xip_sdi_i` | 1-bit serial data input
| | `xip_sdo_o` | 1-bit serial data output
| Configuration generics: | _IO_XIP_EN_ | implement XIP module when _true_
| CPU interrupts: | none |
|=======================
 
 
**Overview**
 
The execute in place (XIP) module is probably one of the more complicated modules of the NEORV32. The module
allows to execute code (and read constant data) directly from a SPI flash memory. Hence, it uses the standard
serial peripheral interface (SPI) as transfer protocol under the hood.
 
The XIP flash is not mapped to a specific region of the processor's address space. Instead, the XIP module
provides a programmable mapping scheme to allow a flexible user-defined mapping of the flash to _any section_
of the address space.
 
From the CPU side, the modules provides two different interfaces: one for transparently accessing the XIP flash and another
one for accessing the module's control and status registers. The first interface provides a _transparent_
gateway to the SPI flash, so the CPU can directly fetch and execute instructions (and/or read constant _data_).
Note that this interface is read-only. Any write access will raise a bus error exception.
The second interface is mapped to the processor's IO space and allows data accesses to the XIP module's
configuration registers.
 
[TIP]
An example program for the XIP module is available in `sw/example/demo_xip`.
 
[WARNING]
Debugging XIP code execution using the on-chip debugger is constrained. The debugger cannot insert breakpoints
(`ebreak` instructions) into XIP code as the XIP access is read-only.
 
[NOTE]
Quad-SPI (QSPI) support, which is about 4x times faster, is planned for the future. 😉
 
 
**SPI Protocol**
 
The XIP module accesses external flash using the standard SPI protocol. The module always sends data MSB-first and
provides all of the standard four clock modes (0..3), which are configured via the _XIP_CTRL_CPOL_ (clock polarity)
and _XIP_CTRL_CPHA_ (clock phase) control register bits, respectively. The clock speed of the interface (`xip_clk_o`)
is defined by a three-bit clock pre-scaler configured using the _XIP_CTRL_PRSCx_ bits:
 
.XIP prescaler configuration
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
[options="header",grid="rows"]
|=======================
| **`XIP_CTRL_PRSCx`** | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
| Resulting `clock_prescaler` | 2 | 4 | 8 | 64 | 128 | 1024 | 2048 | 4096
|=======================
 
Based on the _XIP_CTRL_PRSCx_ configuration the actual XIP SPI clock frequency f~XIP~ is derived from the processor's
main clock f~main~ and is determined by:
 
_**f~XIP~**_ = _f~main~[Hz]_ / (2 * `clock_prescaler`)
 
Hence, the maximum XIP clock speed is f~main~ / 4.
 
.High-Speed SPI mode
[TIP]
The module provides a "high-speed" SPI mode. In this mode the clock prescaler configuration (_XIP_CTRL_PRSCx_) is ignored
and the SPI clock operates at f~main~ / 2 (half of the processor's main clock). High speed SPI mode is enabled by setting
the control register's _XIP_CTRL_HIGHSPEED_ bit.
 
The flash's "read command", which initiates a read access, is defined by the _XIP_CTRL_RD_CMD_ control register bits.
For most SPI flash memories this is `0x03` for normal SPI mode.
 
 
**Direct SPI Access**
 
The XIP module allows to initiate _direct_ SPI transactions. This feature can be used to configure the attached SPI
flash or to perform direct read and write accesses to the flash memory. Two data registers `NEORV32_XIP.DATA_LO` and
`NEORV32_XIP.DATA_HI` are provided to send up to 64-bit of SPI data. The `NEORV32_XIP.DATA_HI` register is write-only,
so a total of 32-bit receive data is provided. Note that the module handles the chip-select
line (`xip_csn_o`) by itself so it is not possible to construct larger consecutive transfers.
 
The actual data transmission size in bytes is defined by the control register's _XIP_CTRL_SPI_NBYTES_ bits.
Any configuration from 1 byte to 8 bytes is valid. Other value will result in unpredictable behavior.
 
Since data is always transferred MSB-first, the data in `DATA_HI:DATA_LO` also has to be MSB-aligned. Receive data is
available in `DATA_LO` only - `DATA_HI` is write-only. Writing to `DATA_HI` triggers the actual SPI transmission.
The _XIP_CTRL_PHY_BUSY_ control register flag indicates a transmission being in progress.
 
The chip-select line of the XIP module (`xip_csn_o`) will only become asserted (enabled, pulled low) if the
_XIP_CTRL_SPI_CSEN_ control register bit is set. If this bit is cleared, `xip_csn_o` is always disabled
(pulled high).
 
[NOTE]
Direct SPI mode is only possible when the module is enabled (setting _XIP_CTRL_EN_) but **before** the actual
XIP mode is enabled via _XIP_CTRL_XIP_EN_.
 
[TIP]
When the XIP mode is not enabled, the XIP module can also be used as additional general purpose SPI controller
with a transfer size of up to 64 bits per transmission.
 
 
**Address Mapping**
 
The address mapping of the XIP flash is not fixed by design. It can be mapped to _any section_ within the processor's
address space. A _section_ refers to one out of 16 naturally aligned 256MB wide memory segments. This segment
is defined by the four most significant bits of the address (`31:28`) and the XIP's segment is programmed by the
four _XIP_CTRL_XIP_PAGE_ bits in the unit's control register. All accesses within this page will be mapped to the XIP flash.
 
[NOTE]
Care must be taken when programming the page mapping to prevent access collisions with other modules (like internal memories
or modules attached to the external memory interface).
 
Example: to map the XIP flash to the address space starting at `0x20000000` write a "2" (`0b0010`) to the _XIP_CTRL_XIP_PAGE_
control register bits. Any access within `0x20000000 .. 0x2fffffff` will be forwarded to the XIP flash.
Note that the SPI access address might wrap around.
 
 
**Using the XIP Mode**
 
The XIP module is globally enabled by setting the _XIP_CTRL_EN_ bit in the device's `CTRL` control register.
Clearing this bit will reset the whole module and will also terminate any pending SPI transfer.
 
Since there is a wide variety of SPI flash components with different sizes, the XIP module allows to specify
the address width of the flash: the number of address bytes used for addressing flash memory content has to be
configured using the control register's _XIP_CTRL_XIP_ABYTES_ bits. These two bits contain the number of SPI
address bytes (**minus one**). For example for a SPI flash with 24-bit addresses these bits have to be set to
`0b10`.
 
The transparent XIP accesses are transformed into SPI transmissions with the following format (starting with the MSB):
 
* 8-bit command: configured by the _XIP_CTRL_RD_CMD_ control register bits ("SPI read command")
* 8 to 32 bits address: defined by the _XIP_CTRL_XIP_ABYTES_ control register bits ("number of address bytes")
* 32-bit data: sending zeros and receiving the according flash word (32-bit)
 
Hence, the maximum XIP transmission size is 72-bit, which has to be configured via the _XIP_CTRL_SPI_NBYTES_
control register bits. Note that the 72-bit transmission size is only available in XIP mode. The transmission
size of the direct SPI accesses is limited to 64-bit.
 
[NOTE]
There is no _continuous read_ feature (i.e. a burst SPI transmission fetching several data words at once) implemented yet.
 
[NOTE]
When using four SPI flash address bytes, the most significant 4 bits of the address are always hardwired
to zero allowing a maximum **accessible** flash size of 256MB.
 
After the SPI properties (including the amount of address bytes **and** the total amount of SPI transfer bytes)
and XIP address mapping are configured, the actual XIP mode can be enabled by setting
the control register's _XIP_CTRL_XIP_EN_ bit. This will enable the "transparent SPI access port" of the module and thus,
the _transparent_ conversion of access requests into proper SPI flash transmissions. Make sure _XIP_CTRL_SPI_CSEN_
is also set so the module can actually select/enable the attached SPI flash.
No more direct SPI accesses via `DATA_HI:DATA_LO` are possible when the XIP mode is enabled. However, the
XIP mode can be disabled at any time.
 
[NOTE]
If the XIP module is disabled (_XIP_CTRL_EN_ = `0`) any accesses to the programmed XIP memory segment are ignored
by the module and might be forwarded to the processor's external memory interface (if implemented) or will cause a bus
exception. If the XIP module is enabled (_XIP_CTRL_EN_ = `1`) but XIP mode is not enabled yet (_XIP_CTRL_XIP_EN_ = '0')
any access to the programmed XIP memory segment will raise a bus exception.
 
[TIP]
It is highly recommended to enable the <<_processor_internal_instruction_cache_icache>> to cover some
of the SPI access latency.
 
 
.XIP register map (`struct NEORV32_XIP`)
[cols="<2,<2,<4,^1,<7"]
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.16+<| `0xffffff40` .16+<| `NEORV32_XIP.CTRL` <|`0` _XIP_CTRL_EN_ ^| r/w <| XIP module enable
<|`1` _XIP_CTRL_PRSC0_ ^| r/w .3+| 3-bit SPI clock prescaler select
<|`2` _XIP_CTRL_PRSC1_ ^| r/w
<|`3` _XIP_CTRL_PRSC2_ ^| r/w
<|`4` _XIP_CTRL_CPOL_ ^| r/w <| SPI clock polarity
<|`5` _XIP_CTRL_CPHA_ ^| r/w <| SPI clock phase
<|`9:6` _XIP_CTRL_SPI_NBYTES_MSB_ : _XIP_CTRL_SPI_NBYTES_LSB_ ^| r/w <| Number of bytes in SPI transaction (1..9)
<|`10` _XIP_CTRL_XIP_EN_ ^| r/w <| XIP mode enable
<|`12:11` _XIP_CTRL_XIP_ABYTES_MSB_ : _XIP_CTRL_XIP_ABYTES_LSB_ ^| r/w <| Number of address bytes for XIP flash (minus 1)
<|`20:13` _XIP_CTRL_RD_CMD_MSB_ : _XIP_CTRL_RD_CMD_LSB_ ^| r/w <| Flash read command
<|`24:21` _XIP_CTRL_XIP_PAGE_MSB_ : _XIP_CTRL_XIP_PAGE_LSB_ ^| r/w <| XIP memory page
<|`25` _XIP_CTRL_SPI_CSEN_ ^| r/w <| Allow SPI chip-select to be actually asserted when set
<|`26` _XIP_CTRL_HIGHSPEED_ ^| r/w <| enable SPI high-speed mode (ignoring _XIP_CTRL_PRSC_)
<|`29:27` ^| r/- <| _reserved_, read as zero
<|`30` _XIP_CTRL_PHY_BUSY_ ^| r/- <| SPI PHY busy when set
<|`31` _XIP_CTRL_XIP_BUSY_ ^| r/- <| XIP access in progress when set
| `0xffffff44` | _reserved_ |`31:0` | r/- | _reserved_, read as zero
| `0xffffff48` | `NEORV32_XIP.DATA_LO` |`31:0` | r/w | Direct SPI access - data register low
| `0xffffff4C` | `NEORV32_XIP.DATA_HI` |`31:0` | -/w | Direct SPI access - data register high; write access triggers SPI transfer
|=======================
/neorv32/trunk/docs/datasheet/soc_xirq.adoc
8,7 → 8,7
| Hardware source file(s): | neorv32_xirq.vhd |
| Software driver file(s): | neorv32_xirq.c |
| | neorv32_xirq.h |
| Top entity port: | `xirq_i` | IRQ input (up to 32-bit)
| Top entity port: | `xirq_i` | IRQ input (32-bit, fixed)
| Configuration generics: | _XIRQ_NUM_CH_ | Number of IRQs to implement (0..32)
| | _XIRQ_TRIGGER_TYPE_ | IRQ trigger type configuration
| | _XIRQ_TRIGGER_POLARITY_ | IRQ trigger polarity configuration
22,7 → 22,8
**Theory of Operation**
 
The XIRQ provides up to 32 interrupt _channels_ (configured via the _XIRQ_NUM_CH_ generic). Each bit in the `xirq_i`
input signal vector represents one interrupt channel. An interrupt channel is enabled by setting the according bit in the
input signal vector represents one interrupt channel. If less than 32 channels are configure, only the LSB-aligned channels
are used while the remaining bits are left unconnected. An interrupt channel is enabled by setting the according bit in the
interrupt enable register `IER`.
 
If the configured trigger (see below) of an enabled channel fires, the request is stored into an internal buffer.
/neorv32/trunk/docs/datasheet/software.adoc
79,6 → 79,7
| `neorv32_twi.c` | `neorv32_twi.h` | HW driver functions for the **TWI**
| `neorv32_uart.c` | `neorv32_uart.h` | HW driver functions for the **UART0** and **UART1**
| `neorv32_wdt.c` | `neorv32_wdt.h` | HW driver functions for the **WDT**
| `neorv32_xip.c` | `neorv32_xip.h` | HW driver functions for the **XIP**
| `neorv32_xirq.c` | `neorv32_xirq.h` | HW driver functions for the **XIRQ**
|=======================
 
201,7 → 202,6
| _MABI_ | The default 32-bit integer ABI.
| _USER_FLAGS_ | Additional flags that will be forwarded to the compiler tools
| _NEORV32_HOME_ | Relative or absolute path to the NEORV32 project home folder. Adapt this if the makefile/project is not in the project's `sw/example folder`.
| _COM_PORT_ | Default serial port for executable upload to bootloader.
|=======================
 
:sectnums:
384,7 → 384,7
`__neorv32_crt0_after_main` function is irrelevant as there is no further "software instance" executed afterwards that can check this.
However, the on-chip debugger could still evaluate the return value of the after-main handler.
 
A simple `printf` can be used to inform the user when the application main function return
A simple `printf` can be used to inform the user when the application's main function returns
(this example assumes that UART0 has been already properly configured in the actual application):
 
.After-main handler - example
448,6 → 448,12
* newline on `\r\n` (carriage return, newline)
* no transfer protocol / control flow protocol - just the raw byte stuff
 
[IMPORTANT]
_Any_ terminal program that can connect to a serial port should work. However, make sure the program
can transfer data in _raw_ byte mode without any protocol overhead around it. Some terminal programs struggle with
transmitting files larger than 4kB (see https://github.com/stnolting/neorv32/pull/215). Try a different program
if uploading a binary does not work (terminal stall).
 
The bootloader uses the LSB of the top entity's `gpio_o` output port as high-active status LED (all other
output pin are set to low level by the bootloader). After reset, this LED will start blinking at ~2Hz and the
following intro screen should show up in your terminal:
/neorv32/trunk/docs/figures/neorv32_processor.png Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/neorv32/trunk/docs/userguide/executable_upload.adoc
19,10 → 19,11
from https://ttssh2.osdn.jp/index.html.en . On Linux you could use GTKTerm, which you can get here
https://github.com/Jeija/gtkterm.git (or install via your package manager).
 
 
[NOTE]
[IMPORTANT]
_Any_ terminal program that can connect to a serial port should work. However, make sure the program
can transfer data in _raw_ byte mode without any protocol overhead around it.
can transfer data in _raw_ byte mode without any protocol overhead around it. Some terminal programs struggle with
transmitting files larger than 4kB (see https://github.com/stnolting/neorv32/pull/215). Try a different program
if uploading a binary does not work (terminal stall).
 
[start=3]
. Open a connection to the the serial port your UART is connected to. Configure the terminal setting according to the
/neorv32/trunk/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.5
:revnumber: v1.6.6
:doctype: book
:sectnums:
:stem:
/neorv32/trunk/docs/impressum.md
6,7 → 6,7
 
Hannover, Germany
 
E-Mail: stnolting@gmail.com
E-Mail: [stnolting@gmail.com](mailto:stnolting@gmail.com)
 
### Haftungsausschluss – Disclaimer
 
36,7 → 36,8
nur bestehen, wenn wir von den Inhalten Kenntnis erlangen und es uns technisch möglich und zumutbar wäre, die Nutzung im
Falle rechtswidriger Inhalte zu verhindern.
 
Diese Haftungsausschlusserklärung gilt auch innerhalb des eigenen Internetauftrittes https://github.com/stnolting/neorv32
Diese Haftungsausschlusserklärung gilt auch innerhalb des eigenen Internetauftrittes https://github.com/stnolting/neorv32 bzw.
https://github.com/stnolting (sowie aller Unterseiten)
gesetzten Links und Verweise von Fragestellern, Blogeinträgern, Gästen des Diskussionsforums. Für illegale, fehlerhafte
oder unvollständige Inhalte und insbesondere für Schäden, die aus der Nutzung oder Nichtnutzung solcherart dargestellten
Informationen entstehen, haftet allein der Diensteanbieter der Seite, auf welche verwiesen wurde, nicht derjenige,
43,6 → 44,7
der über Links auf die jeweilige Veröffentlichung lediglich verweist.
 
Werden uns Rechtsverletzungen bekannt, werden die externen Links durch uns unverzüglich entfernt.
Kontaktieren Sie uns über [stnolting@gmail.com](mailto:stnolting@gmail.com).
 
#### Urheberrecht
 
57,4 → 59,4
Urheberrechtsverletzung aufmerksam werden, bitten wir um einen entsprechenden Hinweis. Bei Bekanntwerden
von Rechtsverletzungen werden wir derartige Inhalte unverzüglich entfernen.
 
Dieses Impressum wurde freundlicherweise von jurarat.de zur Verfügung gestellt.
Dieses Impressum wurde freundlicherweise von https://jurarat.de zur Verfügung gestellt.
/neorv32/trunk/docs/legal.adoc
8,7 → 8,7
 
**BSD 3-Clause License**
 
Copyright (c) 2021, Stephan Nolting. All rights reserved.
Copyright (c) 2022, Stephan Nolting. All rights reserved.
 
Redistribution and use in source and binary forms, with or without modification, are permitted provided that
the following conditions are met:
34,13 → 34,12
 
==========================
**The NEORV32 RISC-V Processor** +
Copyright (c) 2021, by Dipl.-Ing. Stephan Nolting. All rights reserved. +
Copyright (c) 2022, by Dipl.-Ing. Stephan Nolting. All rights reserved. +
HQ: https://github.com/stnolting/neorv32 +
Contact: stnolting@gmail.com +
_made in Hanover, Germany_
==========================
 
 
<<<
// ####################################################################################################################
:sectnums!:
54,9 → 53,11
* "iCE40", "UltraPlus" and "Radiant" are trademarks of Lattice Semiconductor Corporation.
* "Windows" is a trademark of Microsoft Corporation.
* "Tera Term" copyright by T. Teranishi.
* Timing diagrams made with WaveDrom Editor.
* "NeoPixel" is a trademark of Adafruit Industries.
* Documentation made with `asciidoctor`.
* Images/figures made with _Microsoft Power Point_.
* Timing diagrams made with _WaveDrom Editor_.
* Documentation proudly made with `asciidoctor`.
* All further/unreferenced products belong to their according copyright holders.
 
PDF icons from https://www.flaticon.com and made by
link:https://www.freepik.com[Freepik], link:https://www.flaticon.com/authors/good-ware[Good Ware],
83,20 → 84,24
:sectnums!:
=== Citing
 
If you are using the NEORV32 or parts of the project in some kind of publication, please cite it as follows:
[NOTE]
This is an open-source project that is free of charge. Use this project in any way you like
(as long as it complies to the permissive license). Please quote it appropriately. 👍
 
.Contributors ❤️
[NOTE]
Please add as many https://github.com/stnolting/neorv32/graphs/contributors[contributors] as possible to the `authors` field. +
Please add as many https://github.com/stnolting/neorv32/graphs/contributors[contributors] as possible to the `author` field. +
This project would not be where it is without them.
 
If you are using the NEORV32 or parts of the project in some kind of publication, please cite it as follows:
 
.BibTeX
[source]
----
@misc{nolting20,
@misc{nolting22,
author = {Nolting, S. and ...},
title = {The NEORV32 RISC-V Processor},
year = {2020},
year = {2022},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/stnolting/neorv32}}
117,10 → 122,9
 
https://riscv.org[RISC-V] - instruction sets want to be free!
 
Continuous integration provided by https://github.com/features/actions[GitHub Actions] and powered by https://github.com/ghdl/ghdl[GHDL].
 
 
=== Impressum (Imprint)
 
See https://github.com/stnolting/neorv32/blob/master/docs/impressum.md[`docs/impressum.md`].
 
 
 
/neorv32/trunk/rtl/core/mem/README.md
7,7 → 7,7
For the first implementation the `*.default.vhd` files should be selected. The HDL style for describing
memories used by these files has proven **platform-independence** across several FPGA architectures and toolchains.
 
If synthesis fails to infer actual block RAM resources from these default files, try the legacy `*.cyclone2.vhd` files, which
If synthesis fails to infer actual block RAM resources from these default files, try the legacy `*.legacy.vhd` files, which
provide a different HDL style. These files are intended for legacy support of older Intel/Altera Quartus versions (13.0 and older). However,
these files do **not** use platform-specific macros or primitives - so they might also work for other FPGAs and toolchains.
 
/neorv32/trunk/rtl/core/mem/neorv32_dmem.legacy.vhd
0,0 → 1,130
-- #################################################################################################
-- # << NEORV32 - Processor-internal data memory (DMEM) >> #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 1. Redistributions of source code must retain the above copyright notice, this list of #
-- # conditions and the following disclaimer. #
-- # #
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
-- # conditions and the following disclaimer in the documentation and/or other materials #
-- # provided with the distribution. #
-- # #
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
-- # endorse or promote products derived from this software without specific prior written #
-- # permission. #
-- # #
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
-- # OF THE POSSIBILITY OF SUCH DAMAGE. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
 
architecture neorv32_dmem_rtl of neorv32_dmem is
 
-- IO space: module base address --
constant hi_abb_c : natural := 31; -- high address boundary bit
constant lo_abb_c : natural := index_size_f(DMEM_SIZE); -- low address boundary bit
 
-- local signals --
signal acc_en : std_ulogic;
signal rdata : std_ulogic_vector(31 downto 0);
signal rden : std_ulogic;
signal addr : std_ulogic_vector(index_size_f(DMEM_SIZE/4)-1 downto 0);
signal addr_ff : std_ulogic_vector(index_size_f(DMEM_SIZE/4)-1 downto 0);
 
-- -------------------------------------------------------------------------------------------------------------- --
-- The memory (RAM) is built from 4 individual byte-wide memories b0..b3, since some synthesis tools have --
-- problems with 32-bit memories that provide dedicated byte-enable signals AND/OR with multi-dimensional arrays. --
-- -------------------------------------------------------------------------------------------------------------- --
 
-- RAM - not initialized at all --
signal mem_ram_b0 : mem8_t(0 to DMEM_SIZE/4-1);
signal mem_ram_b1 : mem8_t(0 to DMEM_SIZE/4-1);
signal mem_ram_b2 : mem8_t(0 to DMEM_SIZE/4-1);
signal mem_ram_b3 : mem8_t(0 to DMEM_SIZE/4-1);
 
-- read data --
signal mem_ram_b0_rd, mem_ram_b1_rd, mem_ram_b2_rd, mem_ram_b3_rd : std_ulogic_vector(7 downto 0);
 
begin
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert false report "NEORV32 PROCESSOR CONFIG NOTE: Using legacy HDL style DMEM." severity note;
assert false report "NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal DMEM (RAM, " & natural'image(DMEM_SIZE) & " bytes)." severity note;
 
 
-- Access Control -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = DMEM_BASE(hi_abb_c downto lo_abb_c)) else '0';
addr <= addr_i(index_size_f(DMEM_SIZE/4)+1 downto 2); -- word aligned
 
 
-- Memory Access --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
mem_access: process(clk_i)
begin
if rising_edge(clk_i) then
addr_ff <= addr;
if (acc_en = '1') then -- reduce switching activity when not accessed
if (wren_i = '1') and (ben_i(0) = '1') then -- byte 0
mem_ram_b0(to_integer(unsigned(addr))) <= data_i(07 downto 00);
end if;
if (wren_i = '1') and (ben_i(1) = '1') then -- byte 1
mem_ram_b1(to_integer(unsigned(addr))) <= data_i(15 downto 08);
end if;
if (wren_i = '1') and (ben_i(2) = '1') then -- byte 2
mem_ram_b2(to_integer(unsigned(addr))) <= data_i(23 downto 16);
end if;
if (wren_i = '1') and (ben_i(3) = '1') then -- byte 3
mem_ram_b3(to_integer(unsigned(addr))) <= data_i(31 downto 24);
end if;
end if;
end if;
end process mem_access;
 
-- sync(!) read - alternative HDL style --
mem_ram_b0_rd <= mem_ram_b0(to_integer(unsigned(addr_ff)));
mem_ram_b1_rd <= mem_ram_b1(to_integer(unsigned(addr_ff)));
mem_ram_b2_rd <= mem_ram_b2(to_integer(unsigned(addr_ff)));
mem_ram_b3_rd <= mem_ram_b3(to_integer(unsigned(addr_ff)));
 
 
-- Bus Feedback ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
bus_feedback: process(clk_i)
begin
if rising_edge(clk_i) then
rden <= acc_en and rden_i;
ack_o <= acc_en and (rden_i or wren_i);
end if;
end process bus_feedback;
 
-- pack --
rdata <= mem_ram_b3_rd & mem_ram_b2_rd & mem_ram_b1_rd & mem_ram_b0_rd;
 
-- output gate --
data_o <= rdata when (rden = '1') else (others => '0');
 
 
end neorv32_dmem_rtl;
/neorv32/trunk/rtl/core/mem/neorv32_imem.legacy.vhd
0,0 → 1,176
-- #################################################################################################
-- # << NEORV32 - Processor-internal instruction memory (IMEM) >> #
-- # ********************************************************************************************* #
-- # This memory optionally includes the in-place executable image of the application. See the #
-- # processor's documentary to get more information. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 1. Redistributions of source code must retain the above copyright notice, this list of #
-- # conditions and the following disclaimer. #
-- # #
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
-- # conditions and the following disclaimer in the documentation and/or other materials #
-- # provided with the distribution. #
-- # #
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
-- # endorse or promote products derived from this software without specific prior written #
-- # permission. #
-- # #
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
-- # OF THE POSSIBILITY OF SUCH DAMAGE. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
use neorv32.neorv32_application_image.all; -- this file is generated by the image generator
 
architecture neorv32_imem_rtl of neorv32_imem is
 
-- IO space: module base address --
constant hi_abb_c : natural := 31; -- high address boundary bit
constant lo_abb_c : natural := index_size_f(IMEM_SIZE); -- low address boundary bit
 
-- local signals --
signal acc_en : std_ulogic;
signal rdata : std_ulogic_vector(31 downto 0);
signal rden : std_ulogic;
signal addr : std_ulogic_vector(index_size_f(IMEM_SIZE/4)-1 downto 0);
signal addr_ff : std_ulogic_vector(index_size_f(IMEM_SIZE/4)-1 downto 0);
 
-- --------------------------- --
-- IMEM as pre-initialized ROM --
-- --------------------------- --
 
-- application (image) size in bytes --
constant imem_app_size_c : natural := (application_init_image'length)*4;
 
-- ROM - initialized with executable code --
constant mem_rom : mem32_t(0 to IMEM_SIZE/4-1) := mem32_init_f(application_init_image, IMEM_SIZE/4);
 
-- read data --
signal mem_rom_rd : std_ulogic_vector(31 downto 0);
 
-- -------------------------------------------------------------------------------------------------------------- --
-- The memory (RAM) is built from 4 individual byte-wide memories b0..b3, since some synthesis tools have --
-- problems with 32-bit memories that provide dedicated byte-enable signals AND/OR with multi-dimensional arrays. --
-- -------------------------------------------------------------------------------------------------------------- --
 
-- RAM - not initialized at all --
signal mem_ram_b0 : mem8_t(0 to IMEM_SIZE/4-1);
signal mem_ram_b1 : mem8_t(0 to IMEM_SIZE/4-1);
signal mem_ram_b2 : mem8_t(0 to IMEM_SIZE/4-1);
signal mem_ram_b3 : mem8_t(0 to IMEM_SIZE/4-1);
 
-- read data --
signal mem_b0_rd, mem_b1_rd, mem_b2_rd, mem_b3_rd : std_ulogic_vector(7 downto 0);
 
begin
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert false report "NEORV32 PROCESSOR CONFIG NOTE: Using legacy HDL style IMEM." severity note;
assert not (IMEM_AS_IROM = true) report "NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal IMEM as ROM (" & natural'image(IMEM_SIZE) &
" bytes), pre-initialized with application (" & natural'image(imem_app_size_c) & " bytes)." severity note;
--
assert not (IMEM_AS_IROM = false) report "NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal IMEM as blank RAM (" & natural'image(IMEM_SIZE) &
" bytes)." severity note;
--
assert not ((IMEM_AS_IROM = true) and (imem_app_size_c > IMEM_SIZE)) report "NEORV32 PROCESSOR CONFIG ERROR: Application (image = " & natural'image(imem_app_size_c) &
" bytes) does not fit into processor-internal IMEM (ROM = " & natural'image(IMEM_SIZE) & " bytes)!" severity error;
 
 
-- Access Control -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = IMEM_BASE(hi_abb_c downto lo_abb_c)) else '0';
addr <= addr_i(index_size_f(IMEM_SIZE/4)+1 downto 2); -- word aligned
 
 
-- Implement IMEM as pre-initialized ROM --------------------------------------------------
-- -------------------------------------------------------------------------------------------
imem_rom:
if (IMEM_AS_IROM = true) generate
mem_access: process(clk_i)
begin
if rising_edge(clk_i) then
if (acc_en = '1') then -- reduce switching activity when not accessed
mem_rom_rd <= mem_rom(to_integer(unsigned(addr)));
end if;
end if;
end process mem_access;
-- read data --
rdata <= mem_rom_rd;
end generate;
 
 
-- Implement IMEM as not-initialized RAM --------------------------------------------------
-- -------------------------------------------------------------------------------------------
imem_ram:
if (IMEM_AS_IROM = false) generate
mem_access: process(clk_i)
begin
if rising_edge(clk_i) then
addr_ff <= addr;
if (acc_en = '1') then -- reduce switching activity when not accessed
if (wren_i = '1') and (ben_i(0) = '1') then -- byte 0
mem_ram_b0(to_integer(unsigned(addr))) <= data_i(07 downto 00);
end if;
if (wren_i = '1') and (ben_i(1) = '1') then -- byte 1
mem_ram_b1(to_integer(unsigned(addr))) <= data_i(15 downto 08);
end if;
if (wren_i = '1') and (ben_i(2) = '1') then -- byte 2
mem_ram_b2(to_integer(unsigned(addr))) <= data_i(23 downto 16);
end if;
if (wren_i = '1') and (ben_i(3) = '1') then -- byte 3
mem_ram_b3(to_integer(unsigned(addr))) <= data_i(31 downto 24);
end if;
end if;
end if;
end process mem_access;
-- sync(!) read - alternative HDL style --
mem_b0_rd <= mem_ram_b0(to_integer(unsigned(addr_ff)));
mem_b1_rd <= mem_ram_b1(to_integer(unsigned(addr_ff)));
mem_b2_rd <= mem_ram_b2(to_integer(unsigned(addr_ff)));
mem_b3_rd <= mem_ram_b3(to_integer(unsigned(addr_ff)));
-- pack --
rdata <= mem_b3_rd & mem_b2_rd & mem_b1_rd & mem_b0_rd;
end generate;
 
 
-- Bus Feedback ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
bus_feedback: process(clk_i)
begin
if rising_edge(clk_i) then
rden <= acc_en and rden_i;
if (IMEM_AS_IROM = true) then
ack_o <= acc_en and rden_i;
else
ack_o <= acc_en and (rden_i or wren_i);
end if;
end if;
end process bus_feedback;
 
-- output gate --
data_o <= rdata when (rden = '1') else (others => '0');
 
 
end neorv32_imem_rtl;
/neorv32/trunk/rtl/core/neorv32_application_image.vhd
1,6 → 1,6
-- The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32
-- Auto-generated memory init file (for APPLICATION) from source file <blink_led/main.bin>
-- Size: 3468 bytes
-- Size: 3448 bytes
 
library ieee;
use ieee.std_logic_1164.all;
67,7 → 67,7
00000053 => x"00158593",
00000054 => x"ff5ff06f",
00000055 => x"00001597",
00000056 => x"cb058593",
00000056 => x"c9c58593",
00000057 => x"80000617",
00000058 => x"f1c60613",
00000059 => x"80000697",
114,15 → 114,15
00000100 => x"b0050513",
00000101 => x"00112623",
00000102 => x"088000ef",
00000103 => x"780000ef",
00000103 => x"768000ef",
00000104 => x"00050c63",
00000105 => x"730000ef",
00000105 => x"714000ef",
00000106 => x"00001537",
00000107 => x"ac850513",
00000107 => x"ab050513",
00000108 => x"134000ef",
00000109 => x"020000ef",
00000110 => x"00001537",
00000111 => x"aa450513",
00000111 => x"a8c50513",
00000112 => x"124000ef",
00000113 => x"00c12083",
00000114 => x"00100513",
133,12 → 133,12
00000119 => x"00000593",
00000120 => x"00112623",
00000121 => x"00812423",
00000122 => x"744000ef",
00000122 => x"72c000ef",
00000123 => x"00000513",
00000124 => x"00150413",
00000125 => x"00000593",
00000126 => x"0ff57513",
00000127 => x"730000ef",
00000127 => x"718000ef",
00000128 => x"0c800513",
00000129 => x"164000ef",
00000130 => x"00040513",
157,7 → 157,7
00000143 => x"00151593",
00000144 => x"00078513",
00000145 => x"00060493",
00000146 => x"7b0000ef",
00000146 => x"798000ef",
00000147 => x"01051513",
00000148 => x"000017b7",
00000149 => x"01055513",
238,11 → 238,11
00000224 => x"02912223",
00000225 => x"03212023",
00000226 => x"01312e23",
00000227 => x"66c000ef",
00000227 => x"654000ef",
00000228 => x"00c12603",
00000229 => x"00000693",
00000230 => x"00000593",
00000231 => x"5c4000ef",
00000231 => x"5ac000ef",
00000232 => x"00050413",
00000233 => x"00058993",
00000234 => x"f95ff0ef",
276,608 → 276,603
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"ae470713",
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"b1470713",
00000332 => x"00e787b3",
00000333 => x"0007a783",
00000334 => x"00078067",
00000265 => x"fc010113",
00000266 => x"02112e23",
00000267 => x"02512c23",
00000268 => x"02612a23",
00000269 => x"02712823",
00000270 => x"02a12623",
00000271 => x"02b12423",
00000272 => x"02c12223",
00000273 => x"02d12023",
00000274 => x"00e12e23",
00000275 => x"00f12c23",
00000276 => x"01012a23",
00000277 => x"01112823",
00000278 => x"01c12623",
00000279 => x"01d12423",
00000280 => x"01e12223",
00000281 => x"01f12023",
00000282 => x"34102773",
00000283 => x"34071073",
00000284 => x"342027f3",
00000285 => x"0407c463",
00000286 => x"00071683",
00000287 => x"00300593",
00000288 => x"0036f693",
00000289 => x"00270613",
00000290 => x"00b69463",
00000291 => x"00470613",
00000292 => x"34161073",
00000293 => x"00b00713",
00000294 => x"00f77663",
00000295 => x"69000793",
00000296 => x"0500006f",
00000297 => x"00001737",
00000298 => x"00279793",
00000299 => x"acc70713",
00000300 => x"00e787b3",
00000301 => x"0007a783",
00000302 => x"00078067",
00000303 => x"80000737",
00000304 => x"ffd74713",
00000305 => x"00e787b3",
00000306 => x"01c00713",
00000307 => x"fcf768e3",
00000308 => x"00001737",
00000309 => x"00279793",
00000310 => x"afc70713",
00000311 => x"00e787b3",
00000312 => x"0007a783",
00000313 => x"00078067",
00000314 => x"800007b7",
00000315 => x"0007a783",
00000316 => x"000780e7",
00000317 => x"03c12083",
00000318 => x"03812283",
00000319 => x"03412303",
00000320 => x"03012383",
00000321 => x"02c12503",
00000322 => x"02812583",
00000323 => x"02412603",
00000324 => x"02012683",
00000325 => x"01c12703",
00000326 => x"01812783",
00000327 => x"01412803",
00000328 => x"01012883",
00000329 => x"00c12e03",
00000330 => x"00812e83",
00000331 => x"00412f03",
00000332 => x"00012f83",
00000333 => x"04010113",
00000334 => x"30200073",
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"b8850513",
00000405 => x"000014b7",
00000406 => x"00812c23",
00000407 => x"01312623",
00000408 => x"00112e23",
00000409 => x"01c00413",
00000410 => x"c7dff0ef",
00000411 => x"d7c48493",
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"1c050863",
00000433 => x"00001537",
00000434 => x"b8c50513",
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"d4c70713",
00000447 => x"00e787b3",
00000448 => x"0007a783",
00000449 => x"00078067",
00000450 => x"800007b7",
00000451 => x"00b78713",
00000452 => x"14e40e63",
00000453 => x"02876a63",
00000454 => x"00378713",
00000455 => x"12e40c63",
00000456 => x"00778793",
00000457 => x"12f40e63",
00000458 => x"00001537",
00000459 => x"cec50513",
00000460 => x"bb5ff0ef",
00000461 => x"00040513",
00000462 => x"f05ff0ef",
00000463 => x"00100793",
00000464 => x"08f40c63",
00000465 => x"0280006f",
00000466 => x"ff07c793",
00000467 => x"00f407b3",
00000468 => x"00f00713",
00000469 => x"fcf76ae3",
00000470 => x"00001537",
00000471 => x"cdc50513",
00000472 => x"b85ff0ef",
00000473 => x"00048513",
00000474 => x"b65ff0ef",
00000475 => x"ffd47413",
00000476 => x"00500793",
00000477 => x"06f40263",
00000478 => x"00001537",
00000479 => x"d3050513",
00000480 => x"b65ff0ef",
00000481 => x"34002573",
00000482 => x"eb5ff0ef",
00000483 => x"00001537",
00000484 => x"d3850513",
00000485 => x"b51ff0ef",
00000486 => x"34302573",
00000487 => x"ea1ff0ef",
00000488 => x"00812403",
00000489 => x"00c12083",
00000490 => x"00412483",
00000491 => x"00001537",
00000492 => x"d4450513",
00000493 => x"01010113",
00000494 => x"b2dff06f",
00000495 => x"00001537",
00000496 => x"b9450513",
00000497 => x"b21ff0ef",
00000498 => x"fb1ff06f",
00000336 => x"0047a783",
00000337 => x"fadff06f",
00000338 => x"8081a783",
00000339 => x"fa5ff06f",
00000340 => x"80c1a783",
00000341 => x"f9dff06f",
00000342 => x"8101a783",
00000343 => x"f95ff06f",
00000344 => x"8141a783",
00000345 => x"f8dff06f",
00000346 => x"8181a783",
00000347 => x"f85ff06f",
00000348 => x"81c1a783",
00000349 => x"f7dff06f",
00000350 => x"8201a783",
00000351 => x"f75ff06f",
00000352 => x"8241a783",
00000353 => x"f6dff06f",
00000354 => x"8281a783",
00000355 => x"f65ff06f",
00000356 => x"82c1a783",
00000357 => x"f5dff06f",
00000358 => x"8301a783",
00000359 => x"f55ff06f",
00000360 => x"8341a783",
00000361 => x"f4dff06f",
00000362 => x"8381a783",
00000363 => x"f45ff06f",
00000364 => x"83c1a783",
00000365 => x"f3dff06f",
00000366 => x"8401a783",
00000367 => x"f35ff06f",
00000368 => x"8441a783",
00000369 => x"f2dff06f",
00000370 => x"8481a783",
00000371 => x"f25ff06f",
00000372 => x"84c1a783",
00000373 => x"f1dff06f",
00000374 => x"8501a783",
00000375 => x"f15ff06f",
00000376 => x"8541a783",
00000377 => x"f0dff06f",
00000378 => x"8581a783",
00000379 => x"f05ff06f",
00000380 => x"85c1a783",
00000381 => x"efdff06f",
00000382 => x"8601a783",
00000383 => x"ef5ff06f",
00000384 => x"8641a783",
00000385 => x"eedff06f",
00000386 => x"8681a783",
00000387 => x"ee5ff06f",
00000388 => x"86c1a783",
00000389 => x"eddff06f",
00000390 => x"8701a783",
00000391 => x"ed5ff06f",
00000392 => x"fe010113",
00000393 => x"01212823",
00000394 => x"00050913",
00000395 => x"00001537",
00000396 => x"00912a23",
00000397 => x"b7050513",
00000398 => x"000014b7",
00000399 => x"00812c23",
00000400 => x"01312623",
00000401 => x"00112e23",
00000402 => x"01c00413",
00000403 => x"c99ff0ef",
00000404 => x"d6848493",
00000405 => x"ffc00993",
00000406 => x"008957b3",
00000407 => x"00f7f793",
00000408 => x"00f487b3",
00000409 => x"0007c503",
00000410 => x"ffc40413",
00000411 => x"c61ff0ef",
00000412 => x"ff3414e3",
00000413 => x"01c12083",
00000414 => x"01812403",
00000415 => x"01412483",
00000416 => x"01012903",
00000417 => x"00c12983",
00000418 => x"02010113",
00000419 => x"00008067",
00000420 => x"ff010113",
00000421 => x"00112623",
00000422 => x"00812423",
00000423 => x"00912223",
00000424 => x"b71ff0ef",
00000425 => x"1c050863",
00000426 => x"00001537",
00000427 => x"b7450513",
00000428 => x"c35ff0ef",
00000429 => x"34202473",
00000430 => x"00900713",
00000431 => x"00f47793",
00000432 => x"03078493",
00000433 => x"00f77463",
00000434 => x"05778493",
00000435 => x"00b00793",
00000436 => x"0087ee63",
00000437 => x"00001737",
00000438 => x"00241793",
00000439 => x"d3870713",
00000440 => x"00e787b3",
00000441 => x"0007a783",
00000442 => x"00078067",
00000443 => x"800007b7",
00000444 => x"00b78713",
00000445 => x"14e40e63",
00000446 => x"02876a63",
00000447 => x"00378713",
00000448 => x"12e40c63",
00000449 => x"00778793",
00000450 => x"12f40e63",
00000451 => x"00001537",
00000452 => x"cd450513",
00000453 => x"bd1ff0ef",
00000454 => x"00040513",
00000455 => x"f05ff0ef",
00000456 => x"00100793",
00000457 => x"08f40c63",
00000458 => x"0280006f",
00000459 => x"ff07c793",
00000460 => x"00f407b3",
00000461 => x"00f00713",
00000462 => x"fcf76ae3",
00000463 => x"00001537",
00000464 => x"cc450513",
00000465 => x"ba1ff0ef",
00000466 => x"00048513",
00000467 => x"b81ff0ef",
00000468 => x"ffd47413",
00000469 => x"00500793",
00000470 => x"06f40263",
00000471 => x"00001537",
00000472 => x"d1850513",
00000473 => x"b81ff0ef",
00000474 => x"34002573",
00000475 => x"eb5ff0ef",
00000476 => x"00001537",
00000477 => x"d2050513",
00000478 => x"b6dff0ef",
00000479 => x"34302573",
00000480 => x"ea1ff0ef",
00000481 => x"00812403",
00000482 => x"00c12083",
00000483 => x"00412483",
00000484 => x"00001537",
00000485 => x"d2c50513",
00000486 => x"01010113",
00000487 => x"b49ff06f",
00000488 => x"00001537",
00000489 => x"b7c50513",
00000490 => x"b3dff0ef",
00000491 => x"fb1ff06f",
00000492 => x"00001537",
00000493 => x"b9c50513",
00000494 => x"b2dff0ef",
00000495 => x"f7c02783",
00000496 => x"0a07d463",
00000497 => x"0017f793",
00000498 => x"08078a63",
00000499 => x"00001537",
00000500 => x"bb450513",
00000501 => x"b11ff0ef",
00000502 => x"f7c02783",
00000503 => x"0a07d463",
00000504 => x"0017f793",
00000505 => x"08078a63",
00000506 => x"00001537",
00000507 => x"d0450513",
00000508 => x"fd5ff06f",
00000509 => x"00001537",
00000510 => x"bd050513",
00000511 => x"fc9ff06f",
00000512 => x"00001537",
00000513 => x"be450513",
00000514 => x"fbdff06f",
00000515 => x"00001537",
00000516 => x"bf050513",
00000517 => x"fb1ff06f",
00000518 => x"00001537",
00000519 => x"c0850513",
00000520 => x"fb5ff06f",
00000521 => x"00001537",
00000522 => x"c1c50513",
00000523 => x"f99ff06f",
00000524 => x"00001537",
00000525 => x"c3850513",
00000526 => x"f9dff06f",
00000527 => x"00001537",
00000528 => x"c4c50513",
00000529 => x"f81ff06f",
00000530 => x"00001537",
00000531 => x"c6c50513",
00000532 => x"f75ff06f",
00000533 => x"00001537",
00000534 => x"c8c50513",
00000535 => x"f69ff06f",
00000536 => x"00001537",
00000537 => x"ca850513",
00000538 => x"f5dff06f",
00000539 => x"00001537",
00000540 => x"cc050513",
00000541 => x"f51ff06f",
00000542 => x"00001537",
00000543 => x"d1450513",
00000544 => x"f45ff06f",
00000545 => x"00001537",
00000546 => x"d2450513",
00000547 => x"f39ff06f",
00000548 => x"00c12083",
00000549 => x"00812403",
00000550 => x"00412483",
00000551 => x"01010113",
00000552 => x"00008067",
00000553 => x"01f00793",
00000554 => x"02a7e263",
00000555 => x"800007b7",
00000556 => x"00078793",
00000557 => x"00251513",
00000558 => x"00a78533",
00000559 => x"6ac00793",
00000560 => x"00f52023",
00000561 => x"00000513",
00000562 => x"00008067",
00000563 => x"00100513",
00000564 => x"00008067",
00000565 => x"ff010113",
00000566 => x"00112623",
00000567 => x"00812423",
00000568 => x"00912223",
00000569 => x"43000793",
00000570 => x"30579073",
00000571 => x"00000413",
00000572 => x"01d00493",
00000573 => x"00040513",
00000574 => x"00140413",
00000575 => x"0ff47413",
00000576 => x"fa5ff0ef",
00000577 => x"fe9418e3",
00000578 => x"00c12083",
00000579 => x"00812403",
00000580 => x"00412483",
00000581 => x"01010113",
00000582 => x"00008067",
00000583 => x"fe802503",
00000584 => x"01055513",
00000585 => x"00157513",
00000586 => x"00008067",
00000587 => x"fc000793",
00000588 => x"00a7a423",
00000589 => x"00b7a623",
00000590 => x"00008067",
00000591 => x"00050613",
00000592 => x"00000513",
00000593 => x"0015f693",
00000594 => x"00068463",
00000595 => x"00c50533",
00000596 => x"0015d593",
00000597 => x"00161613",
00000598 => x"fe0596e3",
00000599 => x"00008067",
00000600 => x"00050313",
00000601 => x"ff010113",
00000602 => x"00060513",
00000603 => x"00068893",
00000604 => x"00112623",
00000605 => x"00030613",
00000606 => x"00050693",
00000607 => x"00000713",
00000608 => x"00000793",
00000609 => x"00000813",
00000610 => x"0016fe13",
00000611 => x"00171e93",
00000612 => x"000e0c63",
00000613 => x"01060e33",
00000614 => x"010e3833",
00000615 => x"00e787b3",
00000616 => x"00f807b3",
00000617 => x"000e0813",
00000618 => x"01f65713",
00000619 => x"0016d693",
00000620 => x"00eee733",
00000621 => x"00161613",
00000622 => x"fc0698e3",
00000623 => x"00058663",
00000624 => x"f7dff0ef",
00000625 => x"00a787b3",
00000626 => x"00088a63",
00000627 => x"00030513",
00000628 => x"00088593",
00000629 => x"f69ff0ef",
00000630 => x"00f507b3",
00000631 => x"00c12083",
00000632 => x"00080513",
00000633 => x"00078593",
00000634 => x"01010113",
00000635 => x"00008067",
00000636 => x"06054063",
00000637 => x"0605c663",
00000638 => x"00058613",
00000639 => x"00050593",
00000640 => x"fff00513",
00000641 => x"02060c63",
00000642 => x"00100693",
00000643 => x"00b67a63",
00000644 => x"00c05863",
00000645 => x"00161613",
00000646 => x"00169693",
00000647 => x"feb66ae3",
00000648 => x"00000513",
00000649 => x"00c5e663",
00000650 => x"40c585b3",
00000651 => x"00d56533",
00000652 => x"0016d693",
00000653 => x"00165613",
00000654 => x"fe0696e3",
00000655 => x"00008067",
00000656 => x"00008293",
00000657 => x"fb5ff0ef",
00000658 => x"00058513",
00000659 => x"00028067",
00000660 => x"40a00533",
00000661 => x"00b04863",
00000662 => x"40b005b3",
00000663 => x"f9dff06f",
00000664 => x"40b005b3",
00000665 => x"00008293",
00000666 => x"f91ff0ef",
00000667 => x"40a00533",
00000500 => x"cec50513",
00000501 => x"fd5ff06f",
00000502 => x"00001537",
00000503 => x"bb850513",
00000504 => x"fc9ff06f",
00000505 => x"00001537",
00000506 => x"bcc50513",
00000507 => x"fbdff06f",
00000508 => x"00001537",
00000509 => x"bd850513",
00000510 => x"fb1ff06f",
00000511 => x"00001537",
00000512 => x"bf050513",
00000513 => x"fb5ff06f",
00000514 => x"00001537",
00000515 => x"c0450513",
00000516 => x"f99ff06f",
00000517 => x"00001537",
00000518 => x"c2050513",
00000519 => x"f9dff06f",
00000520 => x"00001537",
00000521 => x"c3450513",
00000522 => x"f81ff06f",
00000523 => x"00001537",
00000524 => x"c5450513",
00000525 => x"f75ff06f",
00000526 => x"00001537",
00000527 => x"c7450513",
00000528 => x"f69ff06f",
00000529 => x"00001537",
00000530 => x"c9050513",
00000531 => x"f5dff06f",
00000532 => x"00001537",
00000533 => x"ca850513",
00000534 => x"f51ff06f",
00000535 => x"00001537",
00000536 => x"cfc50513",
00000537 => x"f45ff06f",
00000538 => x"00001537",
00000539 => x"d0c50513",
00000540 => x"f39ff06f",
00000541 => x"00c12083",
00000542 => x"00812403",
00000543 => x"00412483",
00000544 => x"01010113",
00000545 => x"00008067",
00000546 => x"01f00793",
00000547 => x"02a7e263",
00000548 => x"800007b7",
00000549 => x"00078793",
00000550 => x"00251513",
00000551 => x"00a78533",
00000552 => x"69000793",
00000553 => x"00f52023",
00000554 => x"00000513",
00000555 => x"00008067",
00000556 => x"00100513",
00000557 => x"00008067",
00000558 => x"ff010113",
00000559 => x"00112623",
00000560 => x"00812423",
00000561 => x"00912223",
00000562 => x"42400793",
00000563 => x"30579073",
00000564 => x"00000413",
00000565 => x"01d00493",
00000566 => x"00040513",
00000567 => x"00140413",
00000568 => x"0ff47413",
00000569 => x"fa5ff0ef",
00000570 => x"fe9418e3",
00000571 => x"00c12083",
00000572 => x"00812403",
00000573 => x"f6002e23",
00000574 => x"00412483",
00000575 => x"01010113",
00000576 => x"00008067",
00000577 => x"fe802503",
00000578 => x"01055513",
00000579 => x"00157513",
00000580 => x"00008067",
00000581 => x"fc000793",
00000582 => x"00a7a423",
00000583 => x"00b7a623",
00000584 => x"00008067",
00000585 => x"00050613",
00000586 => x"00000513",
00000587 => x"0015f693",
00000588 => x"00068463",
00000589 => x"00c50533",
00000590 => x"0015d593",
00000591 => x"00161613",
00000592 => x"fe0596e3",
00000593 => x"00008067",
00000594 => x"00050313",
00000595 => x"ff010113",
00000596 => x"00060513",
00000597 => x"00068893",
00000598 => x"00112623",
00000599 => x"00030613",
00000600 => x"00050693",
00000601 => x"00000713",
00000602 => x"00000793",
00000603 => x"00000813",
00000604 => x"0016fe13",
00000605 => x"00171e93",
00000606 => x"000e0c63",
00000607 => x"01060e33",
00000608 => x"010e3833",
00000609 => x"00e787b3",
00000610 => x"00f807b3",
00000611 => x"000e0813",
00000612 => x"01f65713",
00000613 => x"0016d693",
00000614 => x"00eee733",
00000615 => x"00161613",
00000616 => x"fc0698e3",
00000617 => x"00058663",
00000618 => x"f7dff0ef",
00000619 => x"00a787b3",
00000620 => x"00088a63",
00000621 => x"00030513",
00000622 => x"00088593",
00000623 => x"f69ff0ef",
00000624 => x"00f507b3",
00000625 => x"00c12083",
00000626 => x"00080513",
00000627 => x"00078593",
00000628 => x"01010113",
00000629 => x"00008067",
00000630 => x"06054063",
00000631 => x"0605c663",
00000632 => x"00058613",
00000633 => x"00050593",
00000634 => x"fff00513",
00000635 => x"02060c63",
00000636 => x"00100693",
00000637 => x"00b67a63",
00000638 => x"00c05863",
00000639 => x"00161613",
00000640 => x"00169693",
00000641 => x"feb66ae3",
00000642 => x"00000513",
00000643 => x"00c5e663",
00000644 => x"40c585b3",
00000645 => x"00d56533",
00000646 => x"0016d693",
00000647 => x"00165613",
00000648 => x"fe0696e3",
00000649 => x"00008067",
00000650 => x"00008293",
00000651 => x"fb5ff0ef",
00000652 => x"00058513",
00000653 => x"00028067",
00000654 => x"40a00533",
00000655 => x"00b04863",
00000656 => x"40b005b3",
00000657 => x"f9dff06f",
00000658 => x"40b005b3",
00000659 => x"00008293",
00000660 => x"f91ff0ef",
00000661 => x"40a00533",
00000662 => x"00028067",
00000663 => x"00008293",
00000664 => x"0005ca63",
00000665 => x"00054c63",
00000666 => x"f79ff0ef",
00000667 => x"00058513",
00000668 => x"00028067",
00000669 => x"00008293",
00000670 => x"0005ca63",
00000671 => x"00054c63",
00000672 => x"f79ff0ef",
00000673 => x"00058513",
00000669 => x"40b005b3",
00000670 => x"fe0558e3",
00000671 => x"40a00533",
00000672 => x"f61ff0ef",
00000673 => x"40b00533",
00000674 => x"00028067",
00000675 => x"40b005b3",
00000676 => x"fe0558e3",
00000677 => x"40a00533",
00000678 => x"f61ff0ef",
00000679 => x"40b00533",
00000680 => x"00028067",
00000681 => x"6f727245",
00000682 => x"4e202172",
00000683 => x"5047206f",
00000684 => x"75204f49",
00000685 => x"2074696e",
00000686 => x"746e7973",
00000687 => x"69736568",
00000688 => x"2164657a",
00000689 => x"0000000a",
00000690 => x"6e696c42",
00000691 => x"676e696b",
00000692 => x"44454c20",
00000693 => x"6d656420",
00000694 => x"7270206f",
00000695 => x"6172676f",
00000696 => x"00000a6d",
00000697 => x"0000053c",
00000698 => x"00000548",
00000699 => x"00000554",
00000700 => x"00000560",
00000701 => x"0000056c",
00000702 => x"00000574",
00000703 => x"0000057c",
00000704 => x"00000584",
00000705 => x"0000058c",
00000706 => x"000004a8",
00000707 => x"000004a8",
00000708 => x"00000594",
00000709 => x"0000059c",
00000710 => x"000004a8",
00000711 => x"000004a8",
00000712 => x"000004a8",
00000713 => x"000005a4",
00000714 => x"000004a8",
00000715 => x"000004a8",
00000716 => x"000004a8",
00000717 => x"000005ac",
00000718 => x"000004a8",
00000719 => x"000004a8",
00000720 => x"000004a8",
00000721 => x"000004a8",
00000722 => x"000005b4",
00000723 => x"000005bc",
00000724 => x"000005c4",
00000725 => x"000005cc",
00000726 => x"000005d4",
00000727 => x"000005dc",
00000728 => x"000005e4",
00000729 => x"000005ec",
00000730 => x"000005f4",
00000731 => x"000005fc",
00000732 => x"00000604",
00000733 => x"0000060c",
00000734 => x"00000614",
00000735 => x"0000061c",
00000736 => x"00000624",
00000737 => x"0000062c",
00000738 => x"00007830",
00000739 => x"4554523c",
00000740 => x"0000203e",
00000741 => x"74736e49",
00000742 => x"74637572",
00000743 => x"206e6f69",
00000744 => x"72646461",
00000745 => x"20737365",
00000746 => x"6173696d",
00000747 => x"6e67696c",
00000748 => x"00006465",
00000749 => x"74736e49",
00000750 => x"74637572",
00000751 => x"206e6f69",
00000752 => x"65636361",
00000753 => x"66207373",
00000754 => x"746c7561",
00000755 => x"00000000",
00000756 => x"656c6c49",
00000757 => x"206c6167",
00000758 => x"74736e69",
00000759 => x"74637572",
00000760 => x"006e6f69",
00000761 => x"61657242",
00000762 => x"696f706b",
00000763 => x"0000746e",
00000675 => x"6f727245",
00000676 => x"4e202172",
00000677 => x"5047206f",
00000678 => x"75204f49",
00000679 => x"2074696e",
00000680 => x"746e7973",
00000681 => x"69736568",
00000682 => x"2164657a",
00000683 => x"0000000a",
00000684 => x"6e696c42",
00000685 => x"676e696b",
00000686 => x"44454c20",
00000687 => x"6d656420",
00000688 => x"7270206f",
00000689 => x"6172676f",
00000690 => x"00000a6d",
00000691 => x"000004e8",
00000692 => x"0000053c",
00000693 => x"00000548",
00000694 => x"00000550",
00000695 => x"00000558",
00000696 => x"00000560",
00000697 => x"00000568",
00000698 => x"00000570",
00000699 => x"00000578",
00000700 => x"0000049c",
00000701 => x"0000049c",
00000702 => x"00000580",
00000703 => x"00000588",
00000704 => x"0000049c",
00000705 => x"0000049c",
00000706 => x"0000049c",
00000707 => x"00000590",
00000708 => x"0000049c",
00000709 => x"0000049c",
00000710 => x"0000049c",
00000711 => x"00000598",
00000712 => x"0000049c",
00000713 => x"0000049c",
00000714 => x"0000049c",
00000715 => x"0000049c",
00000716 => x"000005a0",
00000717 => x"000005a8",
00000718 => x"000005b0",
00000719 => x"000005b8",
00000720 => x"000005c0",
00000721 => x"000005c8",
00000722 => x"000005d0",
00000723 => x"000005d8",
00000724 => x"000005e0",
00000725 => x"000005e8",
00000726 => x"000005f0",
00000727 => x"000005f8",
00000728 => x"00000600",
00000729 => x"00000608",
00000730 => x"00000610",
00000731 => x"00000618",
00000732 => x"00007830",
00000733 => x"4554523c",
00000734 => x"0000203e",
00000735 => x"74736e49",
00000736 => x"74637572",
00000737 => x"206e6f69",
00000738 => x"72646461",
00000739 => x"20737365",
00000740 => x"6173696d",
00000741 => x"6e67696c",
00000742 => x"00006465",
00000743 => x"74736e49",
00000744 => x"74637572",
00000745 => x"206e6f69",
00000746 => x"65636361",
00000747 => x"66207373",
00000748 => x"746c7561",
00000749 => x"00000000",
00000750 => x"656c6c49",
00000751 => x"206c6167",
00000752 => x"74736e69",
00000753 => x"74637572",
00000754 => x"006e6f69",
00000755 => x"61657242",
00000756 => x"696f706b",
00000757 => x"0000746e",
00000758 => x"64616f4c",
00000759 => x"64646120",
00000760 => x"73736572",
00000761 => x"73696d20",
00000762 => x"67696c61",
00000763 => x"0064656e",
00000764 => x"64616f4c",
00000765 => x"64646120",
00000766 => x"73736572",
00000767 => x"73696d20",
00000768 => x"67696c61",
00000769 => x"0064656e",
00000770 => x"64616f4c",
00000771 => x"63636120",
00000772 => x"20737365",
00000773 => x"6c756166",
00000774 => x"00000074",
00000775 => x"726f7453",
00000776 => x"64612065",
00000777 => x"73657264",
00000778 => x"696d2073",
00000779 => x"696c6173",
00000780 => x"64656e67",
00000781 => x"00000000",
00000782 => x"726f7453",
00000783 => x"63612065",
00000784 => x"73736563",
00000785 => x"75616620",
00000786 => x"0000746c",
00000787 => x"69766e45",
00000788 => x"6d6e6f72",
00000789 => x"20746e65",
00000790 => x"6c6c6163",
00000791 => x"6f726620",
00000792 => x"2d55206d",
00000793 => x"65646f6d",
00000794 => x"00000000",
00000795 => x"69766e45",
00000796 => x"6d6e6f72",
00000797 => x"20746e65",
00000798 => x"6c6c6163",
00000799 => x"6f726620",
00000800 => x"2d4d206d",
00000801 => x"65646f6d",
00000802 => x"00000000",
00000803 => x"6863614d",
00000804 => x"20656e69",
00000805 => x"74666f73",
00000806 => x"65726177",
00000807 => x"746e6920",
00000808 => x"75727265",
00000809 => x"00007470",
00000765 => x"63636120",
00000766 => x"20737365",
00000767 => x"6c756166",
00000768 => x"00000074",
00000769 => x"726f7453",
00000770 => x"64612065",
00000771 => x"73657264",
00000772 => x"696d2073",
00000773 => x"696c6173",
00000774 => x"64656e67",
00000775 => x"00000000",
00000776 => x"726f7453",
00000777 => x"63612065",
00000778 => x"73736563",
00000779 => x"75616620",
00000780 => x"0000746c",
00000781 => x"69766e45",
00000782 => x"6d6e6f72",
00000783 => x"20746e65",
00000784 => x"6c6c6163",
00000785 => x"6f726620",
00000786 => x"2d55206d",
00000787 => x"65646f6d",
00000788 => x"00000000",
00000789 => x"69766e45",
00000790 => x"6d6e6f72",
00000791 => x"20746e65",
00000792 => x"6c6c6163",
00000793 => x"6f726620",
00000794 => x"2d4d206d",
00000795 => x"65646f6d",
00000796 => x"00000000",
00000797 => x"6863614d",
00000798 => x"20656e69",
00000799 => x"74666f73",
00000800 => x"65726177",
00000801 => x"746e6920",
00000802 => x"75727265",
00000803 => x"00007470",
00000804 => x"6863614d",
00000805 => x"20656e69",
00000806 => x"656d6974",
00000807 => x"6e692072",
00000808 => x"72726574",
00000809 => x"00747075",
00000810 => x"6863614d",
00000811 => x"20656e69",
00000812 => x"656d6974",
00000813 => x"6e692072",
00000814 => x"72726574",
00000815 => x"00747075",
00000816 => x"6863614d",
00000817 => x"20656e69",
00000818 => x"65747865",
00000819 => x"6c616e72",
00000820 => x"746e6920",
00000821 => x"75727265",
00000822 => x"00007470",
00000823 => x"74736146",
00000824 => x"746e6920",
00000825 => x"75727265",
00000826 => x"00207470",
00000827 => x"6e6b6e55",
00000828 => x"206e776f",
00000829 => x"70617274",
00000830 => x"75616320",
00000831 => x"203a6573",
00000832 => x"00000000",
00000833 => x"49545b20",
00000834 => x"554f454d",
00000835 => x"52455f54",
00000836 => x"00005d52",
00000837 => x"45445b20",
00000838 => x"45434956",
00000839 => x"5252455f",
00000840 => x"0000005d",
00000841 => x"4d505b20",
00000842 => x"52455f50",
00000843 => x"00005d52",
00000844 => x"50204020",
00000845 => x"00003d43",
00000846 => x"544d202c",
00000847 => x"3d4c4156",
00000848 => x"00000000",
00000849 => x"522f3c20",
00000850 => x"003e4554",
00000851 => x"000007bc",
00000852 => x"000007cc",
00000853 => x"000007f4",
00000854 => x"00000800",
00000855 => x"0000080c",
00000856 => x"00000818",
00000857 => x"00000824",
00000858 => x"00000830",
00000859 => x"0000083c",
00000860 => x"00000728",
00000861 => x"00000728",
00000862 => x"00000848",
00000863 => x"33323130",
00000864 => x"37363534",
00000865 => x"42413938",
00000866 => x"46454443"
00000812 => x"65747865",
00000813 => x"6c616e72",
00000814 => x"746e6920",
00000815 => x"75727265",
00000816 => x"00007470",
00000817 => x"74736146",
00000818 => x"746e6920",
00000819 => x"75727265",
00000820 => x"00207470",
00000821 => x"6e6b6e55",
00000822 => x"206e776f",
00000823 => x"70617274",
00000824 => x"75616320",
00000825 => x"203a6573",
00000826 => x"00000000",
00000827 => x"49545b20",
00000828 => x"554f454d",
00000829 => x"52455f54",
00000830 => x"00005d52",
00000831 => x"45445b20",
00000832 => x"45434956",
00000833 => x"5252455f",
00000834 => x"0000005d",
00000835 => x"4d505b20",
00000836 => x"52455f50",
00000837 => x"00005d52",
00000838 => x"50204020",
00000839 => x"00003d43",
00000840 => x"544d202c",
00000841 => x"3d4c4156",
00000842 => x"00000000",
00000843 => x"522f3c20",
00000844 => x"0a3e4554",
00000845 => x"00000000",
00000846 => x"000007a0",
00000847 => x"000007b0",
00000848 => x"000007d8",
00000849 => x"000007e4",
00000850 => x"000007f0",
00000851 => x"000007fc",
00000852 => x"00000808",
00000853 => x"00000814",
00000854 => x"00000820",
00000855 => x"0000070c",
00000856 => x"0000070c",
00000857 => x"0000082c",
00000858 => x"33323130",
00000859 => x"37363534",
00000860 => x"42413938",
00000861 => x"46454443"
);
 
end neorv32_application_image;
/neorv32/trunk/rtl/core/neorv32_bus_keeper.vhd
2,12 → 2,12
-- # << NEORV32 - Bus Keeper (BUSKEEPER) >> #
-- # ********************************************************************************************* #
-- # This unit monitors the processor-internal bus. If the accessed module does not respond within #
-- # the defined number of cycles (VHDL package: max_proc_int_response_time_c) or issues an ERROR #
-- # conditions the BUS KEEPER asserts the error signal to inform the CPU. #
-- # the defined number of cycles (VHDL package: max_proc_int_response_time_c) or issues an ERROR #
-- # condition, the BUS KEEPER asserts the error signal to inform the CPU. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
51,6 → 51,7
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_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic; -- transfer acknowledge
err_o : out std_ulogic; -- transfer error
61,7 → 62,8
bus_ack_i : in std_ulogic; -- transfer acknowledge from bus system
bus_err_i : in std_ulogic; -- transfer error from bus system
bus_tmo_i : in std_ulogic; -- transfer timeout (external interface)
bus_ext_i : in std_ulogic -- external bus access
bus_ext_i : in std_ulogic; -- external bus access
bus_xip_i : in std_ulogic -- pending XIP access
);
end neorv32_bus_keeper;
 
72,13 → 74,23
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_flag_c : natural := 31; -- r/c: bus error encountered, sticky; cleared by writing zero
constant ctrl_err_type_c : natural := 0; -- r/-: error type LSB: 0=device error, 1=access timeout
constant ctrl_nul_check_en_c : natural := 16; -- r/w: enable NULL address check
constant ctrl_err_flag_c : natural := 31; -- r/c: bus error encountered, sticky; cleared by writing zero
--
signal ctrl_null_check_en : std_ulogic;
 
-- error codes --
constant err_device_c : std_ulogic := '0'; -- device access error
constant err_timeout_c : std_ulogic := '1'; -- timeout error
 
-- sticky error flags --
signal err_flag : std_ulogic;
signal err_type : std_ulogic;
 
-- NULL address check --
signal null_check : std_ulogic;
 
-- access control --
signal acc_en : std_ulogic; -- module access enable
signal wren : std_ulogic; -- word write enable
109,25 → 121,38
 
-- Read/Write Access ----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
rw_access: process(clk_i)
rw_access: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
ack_o <= '-';
data_o <= (others => '-');
ctrl_null_check_en <= '0'; -- required
err_flag <= '0'; -- required
err_type <= '0';
elsif rising_edge(clk_i) then
-- bus handshake --
ack_o <= wren or rden;
 
-- write access --
if (wren = '1') then
ctrl_null_check_en <= data_i(ctrl_nul_check_en_c);
end if;
 
-- read access --
data_o <= (others => '0');
if (rden = '1') then
data_o(ctrl_err_type_c) <= err_type;
data_o(ctrl_err_flag_c) <= err_flag;
data_o(ctrl_err_type_c) <= err_type;
data_o(ctrl_nul_check_en_c) <= ctrl_null_check_en;
data_o(ctrl_err_flag_c) <= err_flag;
end if;
--
if (control.bus_err = '1') then -- sticky error flag
err_flag <= '1';
err_type <= control.err_type;
elsif ((wren or rden) = '1') then -- clear on or read or write
err_flag <= '0';
err_type <= '0';
else
if ((wren or rden) = '1') then -- clear on read or write access
err_flag <= '0';
end if;
end if;
end if;
end process rw_access;
138,10 → 163,10
keeper_control: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
control.pending <= '0';
control.bus_err <= '0';
control.err_type <= def_rst_val_c;
control.timeout <= (others => def_rst_val_c);
control.pending <= '0'; -- required
control.bus_err <= '0'; -- required
control.err_type <= '-';
control.timeout <= (others => '-');
elsif rising_edge(clk_i) then
-- defaults --
control.bus_err <= '0';
151,17 → 176,20
control.timeout <= std_ulogic_vector(to_unsigned(max_proc_int_response_time_c, index_size_f(max_proc_int_response_time_c)+1));
if (bus_rden_i = '1') or (bus_wren_i = '1') then
control.pending <= '1';
if (null_check = '1') then -- invalid access to NULL address
control.bus_err <= '1';
end if;
end if;
-- access monitor: PENDING --
else
control.timeout <= std_ulogic_vector(unsigned(control.timeout) - 1); -- countdown timer
if (bus_err_i = '1') then -- error termination by bus system
control.err_type <= '0'; -- device error
if (bus_err_i = '1') or (control.bus_err = '1') then -- error termination by bus system
control.err_type <= err_device_c; -- device error
control.bus_err <= '1';
control.pending <= '0';
elsif ((or_reduce_f(control.timeout) = '0') and (bus_ext_i = '0')) or -- internal access timeout
elsif ((or_reduce_f(control.timeout) = '0') and (bus_ext_i = '0') and (bus_xip_i = '0')) or -- valid internal access timeout
(bus_tmo_i = '1') then -- external access timeout
control.err_type <= '1'; -- timeout error
control.err_type <= err_timeout_c; -- timeout error
control.bus_err <= '1';
control.pending <= '0';
elsif (bus_ack_i = '1') then -- normal termination by bus system
173,6 → 201,9
end if;
end process keeper_control;
 
-- NULL address check --
null_check <= '1' when (ctrl_null_check_en = '1') and (or_reduce_f(addr_i) = '0') else '0';
 
-- signal bus error to CPU --
err_o <= control.bus_err;
 
/neorv32/trunk/rtl/core/neorv32_busswitch.vhd
1,12 → 1,12
-- #################################################################################################
-- # << NEORV32 - Bus Switch >> #
-- # ********************************************************************************************* #
-- # Allows to access a single peripheral bus ("p_bus") by two controller busses. Controller port #
-- # A ("ca_bus") has priority over controller port B ("cb_bus"). #
-- # Allows to access a single peripheral bus ("p_bus") by two controller buses. Controller port A #
-- # ("ca_bus") has priority over controller port B ("cb_bus"). #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
49,39 → 49,39
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
-- controller interface a --
ca_bus_addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
ca_bus_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
ca_bus_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
ca_bus_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable
ca_bus_we_i : in std_ulogic; -- write enable
ca_bus_re_i : in std_ulogic; -- read enable
ca_bus_lock_i : in std_ulogic; -- exclusive access request
ca_bus_ack_o : out std_ulogic; -- bus transfer acknowledge
ca_bus_err_o : out std_ulogic; -- bus transfer error
ca_bus_addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
ca_bus_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
ca_bus_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
ca_bus_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable
ca_bus_we_i : in std_ulogic; -- write enable
ca_bus_re_i : in std_ulogic; -- read enable
ca_bus_lock_i : in std_ulogic; -- exclusive access request
ca_bus_ack_o : out std_ulogic; -- bus transfer acknowledge
ca_bus_err_o : out std_ulogic; -- bus transfer error
-- controller interface b --
cb_bus_addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
cb_bus_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
cb_bus_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
cb_bus_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable
cb_bus_we_i : in std_ulogic; -- write enable
cb_bus_re_i : in std_ulogic; -- read enable
cb_bus_lock_i : in std_ulogic; -- exclusive access request
cb_bus_ack_o : out std_ulogic; -- bus transfer acknowledge
cb_bus_err_o : out std_ulogic; -- bus transfer error
cb_bus_addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
cb_bus_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
cb_bus_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
cb_bus_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable
cb_bus_we_i : in std_ulogic; -- write enable
cb_bus_re_i : in std_ulogic; -- read enable
cb_bus_lock_i : in std_ulogic; -- exclusive access request
cb_bus_ack_o : out std_ulogic; -- bus transfer acknowledge
cb_bus_err_o : out std_ulogic; -- bus transfer error
-- peripheral bus --
p_bus_src_o : out std_ulogic; -- access source: 0 = A, 1 = B
p_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
p_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
p_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
p_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
p_bus_we_o : out std_ulogic; -- write enable
p_bus_re_o : out std_ulogic; -- read enable
p_bus_lock_o : out std_ulogic; -- exclusive access request
p_bus_ack_i : in std_ulogic; -- bus transfer acknowledge
p_bus_err_i : in std_ulogic -- bus transfer error
p_bus_src_o : out std_ulogic; -- access source: 0 = A, 1 = B
p_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
p_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
p_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
p_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
p_bus_we_o : out std_ulogic; -- write enable
p_bus_re_o : out std_ulogic; -- read enable
p_bus_lock_o : out std_ulogic; -- exclusive access request
p_bus_ack_i : in std_ulogic; -- bus transfer acknowledge
p_bus_err_i : in std_ulogic -- bus transfer error
);
end neorv32_busswitch;
 
/neorv32/trunk/rtl/core/neorv32_cfs.vhd
1,13 → 1,16
-- #################################################################################################
-- # << NEORV32 - Custom Functions Subsystem (CFS) >> #
-- # ********************************************************************************************* #
-- # For tightly-coupled custom co-processors. Provides 32x32-bit memory-mapped registers. #
-- # This is just an "example/illustration template". Modify this file to implement your own #
-- # custom design logic. #
-- # Intended for tightly-coupled, application-specific custom co-processors. This module provides #
-- # 32x 32-bit memory-mapped interface registers, one interrupt request signal and custom IO #
-- # conduits for processor-external or chip-external interface. #
-- # #
-- # NOTE: This is just an example/illustration template. Modify/replace this file to implement #
-- # your own custom design logic. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
92,36 → 95,30
 
-- Access Control -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- These assignments are required to check if the CFS is accessed at all.
-- This logic is required to handle the CPU accesses.
-- DO NOT MODIFY this unless you really know what you are doing.
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = cfs_base_c(hi_abb_c downto lo_abb_c)) else '0';
addr <= cfs_base_c(31 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 2) & "00"; -- word aligned
wren <= acc_en and wren_i; -- full 32-bit word write enable
rden <= acc_en and rden_i; -- the read access is always a full 32-bit word wide; if required, the byte/half-word select/masking is done in the CPU
wren <= acc_en and wren_i; -- write accesses always write a full 32-bit word
rden <= acc_en and rden_i; -- read accesses always return a full 32-bit word
 
-- NOTE: Do not modify the CFS base address or the CFS' occupied address space as this might cause access
-- collisions with other modules.
 
-- This module provides an ERROR signal to signal a faulty access operation to the CPU.
-- It can be used to indicate an invalid access (for example to an unused CFS register address) or to signal
-- a faulty state (like "not operational yet"). The error signal can be checked be checked by the applications
-- "bus access fault" exception handler (provided by the system's BUSKEEPER module).
-- This signal may only be set when the module is actually accessed! Tie to zero if not explicitly used.
err_o <= '0';
 
 
-- CFS Generics ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- In its default version, the CFS provides the configuration generics. single generic:
-- CFS_IN_SIZE configures the size (in bits) of the CFS input conduit cfs_in_i
-- CFS_OUT_SIZE configures the size (in bits) of the CFS output conduit cfs_out_o
-- CFS_CONFIG is a blank 32-bit generic. It is intended as a "generic conduit" to propagate custom configuration flags from the top entity down to this entiy.
-- In it's default version the CFS provides three configuration generics:
-- CFS_IN_SIZE - configures the size (in bits) of the CFS input conduit cfs_in_i
-- CFS_OUT_SIZE - configures the size (in bits) of the CFS output conduit cfs_out_o
-- CFS_CONFIG - is a blank 32-bit generic. It is intended as a "generic conduit" to propagate
-- custom configuration flags from the top entity down to this module.
 
 
-- CFS IOs --------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- By default, the CFS provides two IO signals (cfs_in_i and cfs_out_o) that are available at the processor top entity.
-- These are intended as "conduits" to propagate custom signals this entity <=> processor top entity.
-- By default, the CFS provides two IO signals (cfs_in_i and cfs_out_o) that are available at the processor's top entity.
-- These are intended as "conduits" to propagate custom signals from this module and the processor top entity.
 
cfs_out_o <= (others => '0'); -- not used for this minimal example
 
129,29 → 126,29
-- Reset System ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- The CFS can be reset using the global rstn_i signal. This signal should be used as asynchronous reset and is active-low.
-- Note that rstn_i can be asserted by an external reset and also by a watchdog-cause reset.
-- Note that rstn_i can be asserted by a processor-external reset, the on-chip debugger and also by the watchdog.
--
-- Most default peripheral devices of the NEORV32 do NOT use a dedicated reset at all. Instead, these units are reset by writing ZERO
-- to a specific "control register" located right at the beginning of the device's address space (so this register is cleared at first).
-- The crt0 start-up code write ZERO to every single address in the processor's IO space - including the CFS.
-- Make sure that this clearing does not cause any unintended actions in the CFS.
-- Most default peripheral devices of the NEORV32 do NOT use a dedicated hardware reset at all. Instead, these units are
-- reset by writing ZERO to a specific "control register" located right at the beginning of the device's address space
-- (so this register is cleared at first). The crt0 start-up code writes ZERO to every single address in the processor's
-- IO space - including the CFS. Make sure that this initial clearing does not cause any unintended CFS actions.
 
 
-- Clock System ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- The processor top unit implements a clock generator providing 8 "derived clocks"
-- The processor top unit implements a clock generator providing 8 "derived clocks".
-- Actually, these signals should not be used as direct clock signals, but as *clock enable* signals.
-- clkgen_i is always synchronous to the main system clock (clk_i).
--
-- The following clock divider rates are available:
-- clkgen_i(clk_div2_c) -> MAIN_CLK/2
-- clkgen_i(clk_div4_c) -> MAIN_CLK/4
-- clkgen_i(clk_div8_c) -> MAIN_CLK/8
-- clkgen_i(clk_div64_c) -> MAIN_CLK/64
-- clkgen_i(clk_div128_c) -> MAIN_CLK/128
-- clkgen_i(clk_div1024_c) -> MAIN_CLK/1024
-- clkgen_i(clk_div2048_c) -> MAIN_CLK/2048
-- clkgen_i(clk_div4096_c) -> MAIN_CLK/4096
-- The following clock dividers are available:
-- + clkgen_i(clk_div2_c) -> MAIN_CLK/2
-- + clkgen_i(clk_div4_c) -> MAIN_CLK/4
-- + clkgen_i(clk_div8_c) -> MAIN_CLK/8
-- + clkgen_i(clk_div64_c) -> MAIN_CLK/64
-- + clkgen_i(clk_div128_c) -> MAIN_CLK/128
-- + clkgen_i(clk_div1024_c) -> MAIN_CLK/1024
-- + clkgen_i(clk_div2048_c) -> MAIN_CLK/2048
-- + clkgen_i(clk_div4096_c) -> MAIN_CLK/4096
--
-- For instance, if you want to drive a clock process at MAIN_CLK/8 clock speed you can use the following construct:
--
163,10 → 160,11
-- end if;
-- end if;
--
-- The clkgen_i input clocks are available when at least one IO/peripheral device (for example the SPI) requires the clocks generated by the
-- clock generator. The CFS can enable the clock generator by itself by setting the clkgen_en_o signal high.
-- The CFS cannot ensure to deactivate the clock generator by setting the clkgen_en_o signal low as other peripherals might still keep the generator activated.
-- Make sure to deactivate the CFS's clkgen_en_o if no clocks are required in here to reduce dynamic power consumption.
-- The clkgen_i input clocks are available when at least one IO/peripheral device (for example the UART) requires the clocks
-- generated by the clock generator. The CFS can enable the clock generator by itself by setting the clkgen_en_o signal high.
-- The CFS cannot ensure to deactivate the clock generator by setting the clkgen_en_o signal low as other peripherals might
-- still keep the generator activated. Make sure to deactivate the CFS's clkgen_en_o if no clocks are required in here to
-- reduce dynamic power consumption.
 
clkgen_en_o <= '0'; -- not used for this minimal example
 
173,11 → 171,10
 
-- Interrupt ------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- The CFS features a single interrupt signal, which is connected to the CPU's "fast interrupt" channel 1.
-- The interrupt is triggered by a one-shot rising edge. After triggering, the interrupt appears as "pending" in the CPU's mie register
-- ready to trigger execution of the according interrupt handler. The interrupt request signal should be triggered
-- whenever an interrupt condition is fulfilled. It is the task of the application to programmer to enable/clear the CFS interrupt
-- using the CPU's mie and mip registers when reuqired.
-- The CFS features a single interrupt signal, which is connected to the CPU's "fast interrupt" channel 1 (FIRQ1).
-- The interrupt is triggered by a one-cycle high-level. After triggering, the interrupt appears as "pending" in the CPU's
-- mip CSR ready to trigger execution of the according interrupt handler. It is the task of the application to programmer
-- to enable/clear the CFS interrupt using the CPU's mie and mip registers when required.
 
irq_o <= '0'; -- not used for this minimal example
 
184,50 → 181,55
 
-- Read/Write Access ----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- Here we are reading/writing from/to the interface registers of the module. Please note that the peripheral/IO
-- modules of the NEORV32 can only be written in full word mode (32-bit). Any other write access (half-word or byte)
-- will trigger a store bus access fault exception.
-- Here we are reading/writing from/to the interface registers of the module. Please note that the peripheral/IO modules
-- of the NEORV32 can only be written in full word mode (32-bit). Any other write accesses (half-word or byte) will raise
-- a store bus access fault exception.
--
-- The CFS provides up to 32 memory-mapped 32-bit interface register. For instance, these could be used to provide
-- a <control register> for global control of the unit, a <data register> for reading/writing from/to a data FIFO, a <command register>
-- for issuing commands and a <status register> for status information.
-- The CFS provides up to 32 memory-mapped 32-bit interface register. For instance, these could be used to provide a
-- <control register> for global control of the unit, a <data register> for reading/writing from/to a data FIFO, a
-- <command register> for issuing commands and a <status register> for status information.
--
-- Following the interface protocol, each read or write access has to be acknowledged in the following cycle using the ack_o signal (or even later
-- if the module needs additional time; the maximum latency until an unacknowledged access will trigger a bus exception is defined via the package's
-- global "bus_timeout_c" constant). If no ACK is generated at all, the bus access will time out and cause a bus access fault exception.
-- Following the interface protocol, each read or write access has to be acknowledged in the following cycle using the ack_o
-- signal (or even later if the module needs additional time; exceeding the maximum ACK latency will raise a bus exception).
-- If no ACK is generated at all, the bus access will time out and cause a bus access fault exception.
--
-- This module also provides an optional ERROR signal to indicate a faulty access operation (for example when accessing an
-- unused, read-only or "locked" CFS register address). This signal may only be set when the module is actually accessed
-- and is asserted INSTEAD of the ACK signal. Setting the ERR signal will raise a bus access exception that can be handled
-- by the application software.
 
-- Host access: Read and write access to the interface registers + bus transfer acknowledge.
-- This example only implements four physical r/w register (the four lowest CF register). The remaining addresses of the CFS are not
-- associated with any writable or readable register - an access to those is simply ignored but still acknowledged.
err_o <= '0'; -- Tie to zero if not explicitly used.
 
-- Host access: Read and write access to the interface registers + bus transfer acknowledge. This example only implements
-- four physical r/w register (the four lowest CFS registers). The remaining addresses of the CFS are not associated with
-- any physical registers - any access to those is simply ignored but still acknowledged.
 
host_access: process(clk_i)
begin
if rising_edge(clk_i) then -- synchronous interface for reads and writes
if rising_edge(clk_i) then -- synchronous interface for read and write accesses
-- transfer/access acknowledge --
ack_o <= rden or wren; -- default: required for the CPU to check the CFS is answering a bus read OR write request; all r/w accesses (to any cfs_reg) will succeed
-- ack_o <= rden; -- use this construct if your CFS is read-only
-- ack_o <= wren; -- use this construct if your CFS is write-only
-- ack_o <= ... -- or define the ACK by yourself (example: some registers are read-only, some others can only be written, ...)
ack_o <= rden or wren; -- default: required for the CPU to check the CFS is answering a bus read OR write request;
-- all r/w accesses (to any cfs_reg) will succeed
 
-- write access --
if (wren = '1') then -- word-wide write-access only!
if (wren = '1') then
if (addr = cfs_reg0_addr_c) then -- make sure to use the internal "addr" signal for the read/write interface
cfs_reg_wr(0) <= data_i; -- for example: control register
cfs_reg_wr(0) <= data_i; -- physical register, for example: control register
end if;
if (addr = cfs_reg1_addr_c) then
cfs_reg_wr(1) <= data_i; -- for example: data in/out fifo
cfs_reg_wr(1) <= data_i; -- physical register, for example: data in/out fifo
end if;
if (addr = cfs_reg2_addr_c) then
cfs_reg_wr(2) <= data_i; -- for example: command fifo
cfs_reg_wr(2) <= data_i; -- physical register, for example: command fifo
end if;
if (addr = cfs_reg3_addr_c) then
cfs_reg_wr(3) <= data_i; -- for example: status register
cfs_reg_wr(3) <= data_i; -- physical register, for example: status register
end if;
end if;
 
-- read access --
data_o <= (others => '0'); -- the output has to be zero if there is no actual read access
if (rden = '1') then -- the read access is always a full 32-bit word wide; if required, the byte/half-word select/masking is done in the CPU
if (rden = '1') then -- the read access is always a full 32-bit word wide
case addr is -- make sure to use the internal 'addr' signal for the read/write interface
when cfs_reg0_addr_c => data_o <= cfs_reg_rd(0);
when cfs_reg1_addr_c => data_o <= cfs_reg_rd(1);
245,13 → 247,13
-- This is where the actual functionality can be implemented.
-- In this example we are just implementing four r/w registers that invert any value written to them.
 
cfs_core: process(cfs_reg_wr)
cfs_core_logic: process(cfs_reg_wr)
begin
cfs_reg_rd(0) <= not cfs_reg_wr(0); -- just invert the written value
cfs_reg_rd(0) <= not cfs_reg_wr(0);
cfs_reg_rd(1) <= not cfs_reg_wr(1);
cfs_reg_rd(2) <= not cfs_reg_wr(2);
cfs_reg_rd(3) <= not cfs_reg_wr(3);
end process cfs_core;
end process cfs_core_logic;
 
 
end neorv32_cfs_rtl;
/neorv32/trunk/rtl/core/neorv32_cpu.vhd
21,7 → 21,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
182,7 → 182,7
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", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_DEBUG, "_Debug", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_DEBUG, "_DEBUG", "") &
""
severity note;
 
190,7 → 190,7
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- hardware reset notifier --
assert not (dedicated_reset_c = false) report "NEORV32 CPU CONFIG NOTE: Implementing NO dedicated hardware reset for uncritical registers (default, might reduce area). Set package constant <dedicated_reset_c> = TRUE to configure a DEFINED reset value for all CPU registers." severity note;
assert not (dedicated_reset_c = false) report "NEORV32 CPU CONFIG NOTE: Implementing NO dedicated hardware reset for uncritical registers (default)." severity note;
assert not (dedicated_reset_c = true) report "NEORV32 CPU CONFIG NOTE: Implementing defined hardware reset for uncritical registers (non-default, reset-to-zero, might increase area)." severity note;
assert not ((def_rst_val_c /= '-') and (def_rst_val_c /= '0')) report "NEORV32 CPU CONFIG ERROR! Invalid configuration of package <def_rst_val_c> constant (has to be '-' or '0')." severity error;
 
329,14 → 329,14
)
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
ctrl_i => ctrl, -- main control bus
clk_i => clk_i, -- global clock, rising edge
ctrl_i => ctrl, -- main control bus
-- data input --
mem_i => mem_rdata, -- memory read data
alu_i => alu_res, -- ALU result
mem_i => mem_rdata, -- memory read data
alu_i => alu_res, -- ALU result
-- data output --
rs1_o => rs1, -- operand 1
rs2_o => rs2 -- operand 2
rs1_o => rs1, -- operand 1
rs2_o => rs2 -- operand 2
);
 
 
355,23 → 355,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, -- main control bus
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl, -- main control bus
-- data input --
rs1_i => rs1, -- rf source 1
rs2_i => rs2, -- rf source 2
pc_i => curr_pc, -- current PC
pc2_i => next_pc, -- next PC
imm_i => imm, -- immediate
csr_i => csr_rdata, -- CSR read data
rs1_i => rs1, -- rf source 1
rs2_i => rs2, -- rf source 2
pc_i => curr_pc, -- current PC
pc2_i => next_pc, -- next PC
imm_i => imm, -- immediate
csr_i => csr_rdata, -- CSR read data
-- data output --
cmp_o => comparator, -- comparator status
res_o => alu_res, -- ALU result
add_o => alu_add, -- address computation result
fpu_flags_o => fpu_flags, -- FPU exception flags
cmp_o => comparator, -- comparator status
res_o => alu_res, -- ALU result
add_o => alu_add, -- address computation result
fpu_flags_o => fpu_flags, -- FPU exception flags
-- status --
idone_o => alu_idone -- iterative processing units done?
idone_o => alu_idone -- iterative processing units done?
);
 
 
387,53 → 387,53
)
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl, -- main control bus
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl, -- main control bus
-- cpu instruction fetch interface --
fetch_pc_i => fetch_pc, -- PC for instruction fetch
instr_o => instr, -- instruction
i_wait_o => bus_i_wait, -- wait for fetch to complete
fetch_pc_i => fetch_pc, -- PC for instruction fetch
instr_o => instr, -- instruction
i_wait_o => bus_i_wait, -- wait for fetch to complete
--
ma_instr_o => ma_instr, -- misaligned instruction address
be_instr_o => be_instr, -- bus error on instruction access
ma_instr_o => ma_instr, -- misaligned instruction address
be_instr_o => be_instr, -- bus error on instruction access
-- cpu data access interface --
addr_i => alu_add, -- ALU.add result -> access address
wdata_i => rs2, -- write data
rdata_o => mem_rdata, -- read data
mar_o => mar, -- current memory address register
d_wait_o => bus_d_wait, -- wait for access to complete
addr_i => alu_add, -- ALU.add result -> access address
wdata_i => rs2, -- write data
rdata_o => mem_rdata, -- read data
mar_o => mar, -- current memory address register
d_wait_o => bus_d_wait, -- wait for access to complete
--
excl_state_o => excl_state, -- atomic/exclusive access status
ma_load_o => ma_load, -- misaligned load data address
ma_store_o => ma_store, -- misaligned store data address
be_load_o => be_load, -- bus error on load data access
be_store_o => be_store, -- bus error on store data access
excl_state_o => excl_state, -- atomic/exclusive access status
ma_load_o => ma_load, -- misaligned load data address
ma_store_o => ma_store, -- misaligned store data address
be_load_o => be_load, -- bus error on load data access
be_store_o => be_store, -- bus error on store data access
-- physical memory protection --
pmp_addr_i => pmp_addr, -- addresses
pmp_ctrl_i => pmp_ctrl, -- configurations
pmp_addr_i => pmp_addr, -- addresses
pmp_ctrl_i => pmp_ctrl, -- configurations
-- instruction bus --
i_bus_addr_o => i_bus_addr_o, -- bus access address
i_bus_rdata_i => i_bus_rdata_i, -- bus read data
i_bus_wdata_o => i_bus_wdata_o, -- bus write data
i_bus_ben_o => i_bus_ben_o, -- byte enable
i_bus_we_o => i_bus_we_o, -- write enable
i_bus_re_o => i_bus_re_o, -- read enable
i_bus_lock_o => i_bus_lock_o, -- exclusive access request
i_bus_ack_i => i_bus_ack_i, -- bus transfer acknowledge
i_bus_err_i => i_bus_err_i, -- bus transfer error
i_bus_fence_o => i_bus_fence_o, -- fence operation
i_bus_addr_o => i_bus_addr_o, -- bus access address
i_bus_rdata_i => i_bus_rdata_i, -- bus read data
i_bus_wdata_o => i_bus_wdata_o, -- bus write data
i_bus_ben_o => i_bus_ben_o, -- byte enable
i_bus_we_o => i_bus_we_o, -- write enable
i_bus_re_o => i_bus_re_o, -- read enable
i_bus_lock_o => i_bus_lock_o, -- exclusive access request
i_bus_ack_i => i_bus_ack_i, -- bus transfer acknowledge
i_bus_err_i => i_bus_err_i, -- bus transfer error
i_bus_fence_o => i_bus_fence_o, -- fence operation
-- data bus --
d_bus_addr_o => d_bus_addr_o, -- bus access address
d_bus_rdata_i => d_bus_rdata_i, -- bus read data
d_bus_wdata_o => d_bus_wdata_o, -- bus write data
d_bus_ben_o => d_bus_ben_o, -- byte enable
d_bus_we_o => d_bus_we_o, -- write enable
d_bus_re_o => d_bus_re_o, -- read enable
d_bus_lock_o => d_bus_lock_o, -- exclusive access request
d_bus_ack_i => d_bus_ack_i, -- bus transfer acknowledge
d_bus_err_i => d_bus_err_i, -- bus transfer error
d_bus_fence_o => d_bus_fence_o -- fence operation
d_bus_addr_o => d_bus_addr_o, -- bus access address
d_bus_rdata_i => d_bus_rdata_i, -- bus read data
d_bus_wdata_o => d_bus_wdata_o, -- bus write data
d_bus_ben_o => d_bus_ben_o, -- byte enable
d_bus_we_o => d_bus_we_o, -- write enable
d_bus_re_o => d_bus_re_o, -- read enable
d_bus_lock_o => d_bus_lock_o, -- exclusive access request
d_bus_ack_i => d_bus_ack_i, -- bus transfer acknowledge
d_bus_err_i => d_bus_err_i, -- bus transfer error
d_bus_fence_o => d_bus_fence_o -- fence operation
);
 
-- current privilege level --
/neorv32/trunk/rtl/core/neorv32_cpu_alu.vhd
5,7 → 5,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
240,16 → 240,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(0), -- 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(0), -- trigger operation
-- data input --
rs1_i => rs1_i, -- rf source 1
rs1_i => rs1_i, -- rf source 1
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
res_o => cp_result(0), -- operation result
valid_o => cp_valid(0) -- data output valid
);
 
 
264,16 → 264,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;
 
/neorv32/trunk/rtl/core/neorv32_cpu_bus.vhd
5,7 → 5,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
51,53 → 51,53
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
-- cpu instruction fetch interface --
fetch_pc_i : in std_ulogic_vector(data_width_c-1 downto 0); -- PC for instruction fetch
instr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- instruction
i_wait_o : out std_ulogic; -- wait for fetch to complete
fetch_pc_i : in std_ulogic_vector(data_width_c-1 downto 0); -- PC for instruction fetch
instr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- instruction
i_wait_o : out std_ulogic; -- wait for fetch to complete
--
ma_instr_o : out std_ulogic; -- misaligned instruction address
be_instr_o : out std_ulogic; -- bus error on instruction access
ma_instr_o : out std_ulogic; -- misaligned instruction address
be_instr_o : out std_ulogic; -- bus error on instruction access
-- cpu data access interface --
addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- ALU result -> access address
wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- write data
rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- read data
mar_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current memory address register
d_wait_o : out std_ulogic; -- wait for access to complete
addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- ALU result -> access address
wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- write data
rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- read data
mar_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current memory address register
d_wait_o : out std_ulogic; -- wait for access to complete
--
excl_state_o : out std_ulogic; -- atomic/exclusive access status
ma_load_o : out std_ulogic; -- misaligned load data address
ma_store_o : out std_ulogic; -- misaligned store data address
be_load_o : out std_ulogic; -- bus error on load data access
be_store_o : out std_ulogic; -- bus error on store data access
excl_state_o : out std_ulogic; -- atomic/exclusive access status
ma_load_o : out std_ulogic; -- misaligned load data address
ma_store_o : out std_ulogic; -- misaligned store data address
be_load_o : out std_ulogic; -- bus error on load data access
be_store_o : out std_ulogic; -- bus error on store data access
-- physical memory protection --
pmp_addr_i : in pmp_addr_if_t; -- addresses
pmp_ctrl_i : in pmp_ctrl_if_t; -- configs
pmp_addr_i : in pmp_addr_if_t; -- addresses
pmp_ctrl_i : in pmp_ctrl_if_t; -- configs
-- instruction bus --
i_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
i_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
i_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
i_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
i_bus_we_o : out std_ulogic; -- write enable
i_bus_re_o : out std_ulogic; -- read enable
i_bus_lock_o : out std_ulogic; -- exclusive access request
i_bus_ack_i : in std_ulogic; -- bus transfer acknowledge
i_bus_err_i : in std_ulogic; -- bus transfer error
i_bus_fence_o : out std_ulogic; -- fence operation
i_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
i_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
i_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
i_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
i_bus_we_o : out std_ulogic; -- write enable
i_bus_re_o : out std_ulogic; -- read enable
i_bus_lock_o : out std_ulogic; -- exclusive access request
i_bus_ack_i : in std_ulogic; -- bus transfer acknowledge
i_bus_err_i : in std_ulogic; -- bus transfer error
i_bus_fence_o : out std_ulogic; -- fence operation
-- data bus --
d_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
d_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
d_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
d_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
d_bus_we_o : out std_ulogic; -- write enable
d_bus_re_o : out std_ulogic; -- read enable
d_bus_lock_o : out std_ulogic; -- exclusive access request
d_bus_ack_i : in std_ulogic; -- bus transfer acknowledge
d_bus_err_i : in std_ulogic; -- bus transfer error
d_bus_fence_o : out std_ulogic -- fence operation
d_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
d_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
d_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
d_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
d_bus_we_o : out std_ulogic; -- write enable
d_bus_re_o : out std_ulogic; -- read enable
d_bus_lock_o : out std_ulogic; -- exclusive access request
d_bus_ack_i : in std_ulogic; -- bus transfer acknowledge
d_bus_err_i : in std_ulogic; -- bus transfer error
d_bus_fence_o : out std_ulogic -- fence operation
);
end neorv32_cpu_bus;
 
321,7 → 321,7
d_arbiter.err_align <= (d_arbiter.err_align or d_misaligned) and (not ctrl_i(ctrl_bus_derr_ack_c));
d_arbiter.err_bus <= (d_arbiter.err_bus or d_bus_err_i or (st_pmp_fault and d_arbiter.wr_req) or (ld_pmp_fault and d_arbiter.rd_req)) and
(not ctrl_i(ctrl_bus_derr_ack_c));
if (d_bus_ack_i = '1') or (ctrl_i(ctrl_bus_derr_ack_c) = '1') then -- wait for normal termination / CPU abort
if ((d_bus_ack_i = '1') and (d_bus_err_i = '0')) or (ctrl_i(ctrl_bus_derr_ack_c) = '1') then -- wait for normal termination / CPU abort
d_arbiter.wr_req <= '0';
d_arbiter.rd_req <= '0';
end if;
410,7 → 410,7
else -- in progres
i_arbiter.err_align <= (i_arbiter.err_align or i_misaligned) and (not ctrl_i(ctrl_bus_ierr_ack_c));
i_arbiter.err_bus <= (i_arbiter.err_bus or i_bus_err_i or if_pmp_fault) and (not ctrl_i(ctrl_bus_ierr_ack_c));
if (i_bus_ack_i = '1') or (ctrl_i(ctrl_bus_ierr_ack_c) = '1') then -- wait for normal termination / CPU abort
if ((i_bus_ack_i = '1') and (i_bus_err_i = '0')) or (ctrl_i(ctrl_bus_ierr_ack_c) = '1') then -- wait for normal termination / CPU abort
i_arbiter.rd_req <= '0';
end if;
end if;
/neorv32/trunk/rtl/core/neorv32_cpu_control.vhd
9,7 → 9,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
395,7 → 395,7
fetch_engine.state <= fetch_engine.state_nxt;
fetch_engine.state_prev <= fetch_engine.state;
fetch_engine.restart <= fetch_engine.restart_nxt or fetch_engine.reset;
if (fetch_engine.restart = '1') then
if (fetch_engine.restart = '1') and (fetch_engine.state = IFETCH_REQUEST) then -- only update PC if no fetch request is pending
fetch_engine.pc <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- initialize with "real" application PC
else
fetch_engine.pc <= fetch_engine.pc_nxt;
421,7 → 421,7
-- instruction prefetch buffer defaults --
ipb.we <= '0';
ipb.wdata <= be_instr_i & ma_instr_i & instr_i(31 downto 0); -- store exception info and instruction word
ipb.clear <= fetch_engine.restart;
ipb.clear <= fetch_engine.restart; -- clear instruction buffer while being reset
 
-- state machine --
case fetch_engine.state is
438,10 → 438,9
-- ------------------------------------------------------------
fetch_engine.bus_err_ack <= be_instr_i or ma_instr_i; -- ACK bus/alignment errors
if (bus_i_wait_i = '0') or (be_instr_i = '1') or (ma_instr_i = '1') then -- wait for bus response
fetch_engine.pc_nxt <= std_ulogic_vector(unsigned(fetch_engine.pc) + 4);
ipb.we <= not fetch_engine.restart; -- write to IPB if not being reset
fetch_engine.restart_nxt <= '0';
fetch_engine.state_nxt <= IFETCH_REQUEST;
fetch_engine.pc_nxt <= std_ulogic_vector(unsigned(fetch_engine.pc) + 4);
ipb.we <= not fetch_engine.restart; -- write to IPB if not being reset
fetch_engine.state_nxt <= IFETCH_REQUEST;
end if;
 
when others => -- undefined
725,7 → 724,7
execute_engine.i_reg_last <= execute_engine.i_reg;
end if;
 
-- next PC --
-- next PC logic --
case execute_engine.state is
when TRAP_ENTER => -- ENTERING trap environment
if (CPU_EXTENSION_RISCV_DEBUG = false) then -- normal trapping
2405,8 → 2404,8
 
-- counter event trigger - RISC-V-specific --
cnt_event(hpmcnt_event_cy_c) <= not execute_engine.sleep; -- active cycle
cnt_event(hpmcnt_event_never_c) <= '0'; -- undefined (never)
cnt_event(hpmcnt_event_ir_c) <= '1' when (execute_engine.state = EXECUTE) else '0'; -- retired instruction
cnt_event(hpmcnt_event_never_c) <= '0'; -- "never"
cnt_event(hpmcnt_event_ir_c) <= '1' when (execute_engine.state = EXECUTE) else '0'; -- (any) retired instruction
 
-- counter event trigger - custom / NEORV32-specific --
cnt_event(hpmcnt_event_cir_c) <= '1' when (execute_engine.state = EXECUTE) and (execute_engine.is_ci = '1') else '0'; -- retired compressed instruction
/neorv32/trunk/rtl/core/neorv32_gpio.vhd
1,11 → 1,12
-- #################################################################################################
-- # << NEORV32 - General Purpose Parallel Input/Output Port (GPIO) >> #
-- # ********************************************************************************************* #
-- # 64-bit general purpose parallel input & output port unit. #
-- # 64-bit general purpose parallel input & output port unit. Input/outputs are split into two #
-- # 32-bit memory-mapped registers each. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
51,6 → 52,7
data_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic; -- transfer acknowledge
err_o : out std_ulogic; -- transfer error
-- parallel io --
gpio_o : out std_ulogic_vector(63 downto 0);
gpio_i : in std_ulogic_vector(63 downto 0)
70,8 → 72,8
signal rden : std_ulogic; -- read enable
 
-- accessible regs --
signal din_lo, din_hi : std_ulogic_vector(31 downto 0); -- r/-
signal dout_lo, dout_hi : std_ulogic_vector(31 downto 0); -- r/w
signal din_hi, din_lo : std_ulogic_vector(31 downto 0); -- r/-: parallel input hi/lo
signal dout_hi, dout_lo : std_ulogic_vector(31 downto 0); -- r/w: parallel output hi/lo
 
begin
 
89,7 → 91,8
begin
if rising_edge(clk_i) then
-- bus handshake --
ack_o <= wren or rden;
ack_o <= (wren and addr(3)) or rden;
err_o <= wren and (not addr(3)); -- INPUT registers are read only!
 
-- write access --
if (wren = '1') then
101,7 → 104,7
end if;
end if;
 
-- input buffer --
-- input buffer (prevent metastability) --
din_lo <= gpio_i(31 downto 00);
din_hi <= gpio_i(63 downto 32);
 
/neorv32/trunk/rtl/core/neorv32_icache.vhd
6,7 → 6,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
50,27 → 50,27
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
clear_i : in std_ulogic; -- cache clear
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
clear_i : in std_ulogic; -- cache clear
-- host controller interface --
host_addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
host_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
host_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
host_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable
host_we_i : in std_ulogic; -- write enable
host_re_i : in std_ulogic; -- read enable
host_ack_o : out std_ulogic; -- bus transfer acknowledge
host_err_o : out std_ulogic; -- bus transfer error
host_addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
host_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
host_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
host_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable
host_we_i : in std_ulogic; -- write enable
host_re_i : in std_ulogic; -- read enable
host_ack_o : out std_ulogic; -- bus transfer acknowledge
host_err_o : out std_ulogic; -- bus transfer error
-- peripheral bus interface --
bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
bus_we_o : out std_ulogic; -- write enable
bus_re_o : out std_ulogic; -- read enable
bus_ack_i : in std_ulogic; -- bus transfer acknowledge
bus_err_i : in std_ulogic -- bus transfer error
bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
bus_we_o : out std_ulogic; -- write enable
bus_re_o : out std_ulogic; -- read enable
bus_ack_i : in std_ulogic; -- bus transfer acknowledge
bus_err_i : in std_ulogic -- bus transfer error
);
end neorv32_icache;
 
112,12 → 112,9
-- cache interface --
type cache_if_t is record
clear : std_ulogic; -- cache clear
--
host_addr : std_ulogic_vector(31 downto 0); -- cpu access address
host_rdata : std_ulogic_vector(31 downto 0); -- cpu read data
--
hit : std_ulogic; -- hit access
--
ctrl_en : std_ulogic; -- control access enable
ctrl_addr : std_ulogic_vector(31 downto 0); -- control access address
ctrl_we : std_ulogic; -- control write enable
136,10 → 133,8
state_nxt : ctrl_engine_state_t; -- next state
addr_reg : std_ulogic_vector(31 downto 0); -- address register for block download
addr_reg_nxt : std_ulogic_vector(31 downto 0);
--
re_buf : std_ulogic; -- read request buffer
re_buf_nxt : std_ulogic;
--
clear_buf : std_ulogic; -- clear request buffer
clear_buf_nxt : std_ulogic;
end record;
160,26 → 155,19
 
-- Control Engine FSM Sync ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- registers that REQUIRE a specific reset state --
ctrl_engine_fsm_sync_rst: process(rstn_i, clk_i)
ctrl_engine_fsm_sync: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
ctrl.state <= S_CACHE_CLEAR;
ctrl.re_buf <= '0';
ctrl.clear_buf <= '0';
ctrl.addr_reg <= (others => '-');
elsif rising_edge(clk_i) then
ctrl.state <= ctrl.state_nxt;
ctrl.re_buf <= ctrl.re_buf_nxt;
ctrl.clear_buf <= ctrl.clear_buf_nxt;
ctrl.addr_reg <= ctrl.addr_reg_nxt;
end if;
end process ctrl_engine_fsm_sync_rst;
 
-- registers that do not require a specific reset state --
ctrl_engine_fsm_sync: process(clk_i)
begin
if rising_edge(clk_i) then
ctrl.addr_reg <= ctrl.addr_reg_nxt;
end if;
end process ctrl_engine_fsm_sync;
 
 
302,28 → 290,28
-- -------------------------------------------------------------------------------------------
neorv32_icache_memory_inst: neorv32_icache_memory
generic map (
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- block size in bytes (min 4), has to be a power of 2
ICACHE_NUM_SETS => ICACHE_NUM_SETS -- associativity; 0=direct-mapped, 1=2-way set-associative
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- block size in bytes (min 4), has to be a power of 2
ICACHE_NUM_SETS => ICACHE_NUM_SETS -- associativity; 0=direct-mapped, 1=2-way set-associative
)
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
invalidate_i => cache.clear, -- invalidate whole cache
-- host cache access (read-only) --
host_addr_i => cache.host_addr, -- access address
host_re_i => host_re_i, -- read enable
host_rdata_o => cache.host_rdata, -- read data
clk_i => clk_i, -- global clock, rising edge
invalidate_i => cache.clear, -- invalidate whole cache
-- host cache access (read-only) --
host_addr_i => cache.host_addr, -- access address
host_re_i => host_re_i, -- read enable
host_rdata_o => cache.host_rdata, -- read data
-- access status (1 cycle delay to access) --
hit_o => cache.hit, -- hit access
hit_o => cache.hit, -- hit access
-- ctrl cache access (write-only) --
ctrl_en_i => cache.ctrl_en, -- control interface enable
ctrl_addr_i => cache.ctrl_addr, -- access address
ctrl_we_i => cache.ctrl_we, -- write enable (full-word)
ctrl_wdata_i => cache.ctrl_wdata, -- write data
ctrl_tag_we_i => cache.ctrl_tag_we, -- write tag to selected block
ctrl_valid_i => cache.ctrl_valid_we, -- make selected block valid
ctrl_invalid_i => cache.ctrl_invalid_we -- make selected block invalid
ctrl_en_i => cache.ctrl_en, -- control interface enable
ctrl_addr_i => cache.ctrl_addr, -- access address
ctrl_we_i => cache.ctrl_we, -- write enable (full-word)
ctrl_wdata_i => cache.ctrl_wdata, -- write data
ctrl_tag_we_i => cache.ctrl_tag_we, -- write tag to selected block
ctrl_valid_i => cache.ctrl_valid_we, -- make selected block valid
ctrl_invalid_i => cache.ctrl_invalid_we -- make selected block invalid
);
 
end neorv32_icache_rtl;
345,7 → 333,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
389,22 → 377,22
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
invalidate_i : in std_ulogic; -- invalidate whole cache
clk_i : in std_ulogic; -- global clock, rising edge
invalidate_i : in std_ulogic; -- invalidate whole cache
-- host cache access (read-only) --
host_addr_i : in std_ulogic_vector(31 downto 0); -- access address
host_re_i : in std_ulogic; -- read enable
host_rdata_o : out std_ulogic_vector(31 downto 0); -- read data
host_addr_i : in std_ulogic_vector(31 downto 0); -- access address
host_re_i : in std_ulogic; -- read enable
host_rdata_o : out std_ulogic_vector(31 downto 0); -- read data
-- access status (1 cycle delay to access) --
hit_o : out std_ulogic; -- hit access
hit_o : out std_ulogic; -- hit access
-- ctrl cache access (write-only) --
ctrl_en_i : in std_ulogic; -- control interface enable
ctrl_addr_i : in std_ulogic_vector(31 downto 0); -- access address
ctrl_we_i : in std_ulogic; -- write enable (full-word)
ctrl_wdata_i : in std_ulogic_vector(31 downto 0); -- write data
ctrl_tag_we_i : in std_ulogic; -- write tag to selected block
ctrl_valid_i : in std_ulogic; -- make selected block valid
ctrl_invalid_i : in std_ulogic -- make selected block invalid
ctrl_en_i : in std_ulogic; -- control interface enable
ctrl_addr_i : in std_ulogic_vector(31 downto 0); -- access address
ctrl_we_i : in std_ulogic; -- write enable (full-word)
ctrl_wdata_i : in std_ulogic_vector(31 downto 0); -- write data
ctrl_tag_we_i : in std_ulogic; -- write tag to selected block
ctrl_valid_i : in std_ulogic; -- make selected block valid
ctrl_invalid_i : in std_ulogic -- make selected block invalid
);
end neorv32_icache_memory;
 
413,7 → 401,7
-- cache layout --
constant cache_offset_size_c : natural := index_size_f(ICACHE_BLOCK_SIZE/4); -- offset addresses full 32-bit words
constant cache_index_size_c : natural := index_size_f(ICACHE_NUM_BLOCKS);
constant cache_tag_size_c : natural := 32 - (cache_offset_size_c + cache_index_size_c + 2); -- 2 additonal bits for byte offset
constant cache_tag_size_c : natural := 32 - (cache_offset_size_c + cache_index_size_c + 2); -- 2 additional bits for byte offset
constant cache_entries_c : natural := ICACHE_NUM_BLOCKS * (ICACHE_BLOCK_SIZE/4); -- number of 32-bit entries (per set)
 
-- status flag memory --
/neorv32/trunk/rtl/core/neorv32_package.vhd
3,7 → 3,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
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"01060500"; -- no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01060600"; -- no touchy!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
 
-- Check if we're inside the Matrix -------------------------------------------------------
122,7 → 122,7
 
-- Internal (auto-generated) Configurations -----------------------------------------------
-- -------------------------------------------------------------------------------------------
constant def_rst_val_c : std_ulogic := cond_sel_stdulogic_f(dedicated_reset_c, '0', '-');
constant def_rst_val_c : std_ulogic; -- Use a deferred constant, prevents compile error with Questa, see IEEE 1076-2008 14.4.2.1
 
-- Processor-Internal Address Space Layout ------------------------------------------------
-- -------------------------------------------------------------------------------------------
149,7 → 149,7
constant dm_sreg_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffff980";
 
-- IO: Peripheral Devices ("IO") Area --
-- Control register(s) (including the device-enable) should be located at the base address of each device
-- Control register(s) (including the device-enable flag) should be located at the base address of each device
constant io_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffe00";
constant io_size_c : natural := 512; -- IO address space size in bytes, fixed!
 
217,9 → 217,17
--constant reserved_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff00"; -- base address
--constant reserved_size_c : natural := 16*4; -- module's address space size in bytes
 
-- Execute In Place Module (XIP) --
constant xip_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff40"; -- base address
constant xip_size_c : natural := 4*4; -- module's address space size in bytes
constant xip_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff40";
constant xip_map_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff44";
constant xip_data_lo_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff48";
constant xip_data_hi_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff4C";
 
-- reserved --
--constant reserved_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff40"; -- base address
--constant reserved_size_c : natural := 8*4; -- module's address space size in bytes
--constant reserved_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff50"; -- base address
--constant reserved_size_c : natural := 4*4; -- module's address space size in bytes
 
-- General Purpose Timer (GPTMR) --
constant gptmr_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff60"; -- base address
949,7 → 957,7
-- Internal Data memory (DMEM) --
MEM_INT_DMEM_EN : boolean := false; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
-- Internal Cache memory (iCACHE) --
-- Internal Instruction Cache (iCACHE) --
ICACHE_EN : boolean := false; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2
989,7 → 997,8
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits
IO_NEOLED_EN : boolean := false; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_NEOLED_TX_FIFO : natural := 1; -- NEOLED TX FIFO depth, 1..32k, has to be a power of two
IO_GPTMR_EN : boolean := false -- implement general purpose timer (GPTMR)?
IO_GPTMR_EN : boolean := false; -- implement general purpose timer (GPTMR)?
IO_XIP_EN : boolean := false -- implement execute in place module (XIP)?
);
port (
-- Global control --
1016,6 → 1025,11
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o : out std_ulogic; -- indicates an executed FENCE operation
fencei_o : out std_ulogic; -- indicates an executed FENCEI operation
-- XIP (execute in place via SPI) signals (available if IO_XIP_EN = true) --
xip_csn_o : out std_ulogic; -- chip-select, low-active
xip_clk_o : out std_ulogic; -- serial clock
xip_sdi_i : in std_ulogic := 'L'; -- device data input
xip_sdo_o : out std_ulogic; -- controller data output
-- TX stream interfaces (available if SLINK_NUM_TX > 0) --
slink_tx_dat_o : out sdata_8x32_t; -- output data
slink_tx_val_o : out std_ulogic_vector(7 downto 0); -- valid output
1046,7 → 1060,7
twi_sda_io : inout std_logic := 'U'; -- twi serial data line
twi_scl_io : inout std_logic := 'U'; -- twi serial clock line
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels
pwm_o : out std_ulogic_vector(59 downto 0); -- pwm channels
-- Custom Functions Subsystem IO --
cfs_in_i : in std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0) := (others => 'U'); -- custom CFS inputs conduit
cfs_out_o : out std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom CFS outputs conduit
1056,7 → 1070,7
mtime_i : in std_ulogic_vector(63 downto 0) := (others => 'U'); -- current system time from ext. MTIME (if IO_MTIME_EN = false)
mtime_o : out std_ulogic_vector(63 downto 0); -- current system time from int. MTIME (if IO_MTIME_EN = true)
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i : in std_ulogic_vector(XIRQ_NUM_CH-1 downto 0) := (others => 'L'); -- IRQ channels
xirq_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); -- IRQ channels
-- CPU Interrupts --
mtime_irq_i : in std_ulogic := 'L'; -- machine timer interrupt, available if IO_MTIME_EN = false
msw_irq_i : in std_ulogic := 'L'; -- machine software interrupt
1146,7 → 1160,7
component neorv32_cpu_control
generic (
-- General --
HW_THREAD_ID : natural; -- hardware thread id (32-bit)
HW_THREAD_ID : natural; -- hardware thread id (32-bit)
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0); -- cpu boot address
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0); -- cpu debug mode start address
-- RISC-V CPU Extensions --
1372,53 → 1386,53
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
-- cpu instruction fetch interface --
fetch_pc_i : in std_ulogic_vector(data_width_c-1 downto 0); -- PC for instruction fetch
instr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- instruction
i_wait_o : out std_ulogic; -- wait for fetch to complete
fetch_pc_i : in std_ulogic_vector(data_width_c-1 downto 0); -- PC for instruction fetch
instr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- instruction
i_wait_o : out std_ulogic; -- wait for fetch to complete
--
ma_instr_o : out std_ulogic; -- misaligned instruction address
be_instr_o : out std_ulogic; -- bus error on instruction access
ma_instr_o : out std_ulogic; -- misaligned instruction address
be_instr_o : out std_ulogic; -- bus error on instruction access
-- cpu data access interface --
addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- ALU result -> access address
wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- write data
rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- read data
mar_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current memory address register
d_wait_o : out std_ulogic; -- wait for access to complete
addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- ALU result -> access address
wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- write data
rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- read data
mar_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current memory address register
d_wait_o : out std_ulogic; -- wait for access to complete
--
excl_state_o : out std_ulogic; -- atomic/exclusive access status
ma_load_o : out std_ulogic; -- misaligned load data address
ma_store_o : out std_ulogic; -- misaligned store data address
be_load_o : out std_ulogic; -- bus error on load data access
be_store_o : out std_ulogic; -- bus error on store data access
excl_state_o : out std_ulogic; -- atomic/exclusive access status
ma_load_o : out std_ulogic; -- misaligned load data address
ma_store_o : out std_ulogic; -- misaligned store data address
be_load_o : out std_ulogic; -- bus error on load data access
be_store_o : out std_ulogic; -- bus error on store data access
-- physical memory protection --
pmp_addr_i : in pmp_addr_if_t; -- addresses
pmp_ctrl_i : in pmp_ctrl_if_t; -- configs
pmp_addr_i : in pmp_addr_if_t; -- addresses
pmp_ctrl_i : in pmp_ctrl_if_t; -- configs
-- instruction bus --
i_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
i_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
i_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
i_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
i_bus_we_o : out std_ulogic; -- write enable
i_bus_re_o : out std_ulogic; -- read enable
i_bus_lock_o : out std_ulogic; -- exclusive access request
i_bus_ack_i : in std_ulogic; -- bus transfer acknowledge
i_bus_err_i : in std_ulogic; -- bus transfer error
i_bus_fence_o : out std_ulogic; -- fence operation
i_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
i_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
i_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
i_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
i_bus_we_o : out std_ulogic; -- write enable
i_bus_re_o : out std_ulogic; -- read enable
i_bus_lock_o : out std_ulogic; -- exclusive access request
i_bus_ack_i : in std_ulogic; -- bus transfer acknowledge
i_bus_err_i : in std_ulogic; -- bus transfer error
i_bus_fence_o : out std_ulogic; -- fence operation
-- data bus --
d_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
d_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
d_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
d_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
d_bus_we_o : out std_ulogic; -- write enable
d_bus_re_o : out std_ulogic; -- read enable
d_bus_lock_o : out std_ulogic; -- exclusive access request
d_bus_ack_i : in std_ulogic; -- bus transfer acknowledge
d_bus_err_i : in std_ulogic; -- bus transfer error
d_bus_fence_o : out std_ulogic -- fence operation
d_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
d_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
d_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
d_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
d_bus_we_o : out std_ulogic; -- write enable
d_bus_re_o : out std_ulogic; -- read enable
d_bus_lock_o : out std_ulogic; -- exclusive access request
d_bus_ack_i : in std_ulogic; -- bus transfer acknowledge
d_bus_err_i : in std_ulogic; -- bus transfer error
d_bus_fence_o : out std_ulogic -- fence operation
);
end component;
 
1432,6 → 1446,7
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_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic; -- transfer acknowledge
err_o : out std_ulogic; -- transfer error
1442,7 → 1457,8
bus_ack_i : in std_ulogic; -- transfer acknowledge from bus system
bus_err_i : in std_ulogic; -- transfer error from bus system
bus_tmo_i : in std_ulogic; -- transfer timeout (external interface)
bus_ext_i : in std_ulogic -- external bus access
bus_ext_i : in std_ulogic; -- external bus access
bus_xip_i : in std_ulogic -- pending XIP access
);
end component;
 
1456,27 → 1472,27
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
clear_i : in std_ulogic; -- cache clear
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
clear_i : in std_ulogic; -- cache clear
-- host controller interface --
host_addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
host_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
host_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
host_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable
host_we_i : in std_ulogic; -- write enable
host_re_i : in std_ulogic; -- read enable
host_ack_o : out std_ulogic; -- bus transfer acknowledge
host_err_o : out std_ulogic; -- bus transfer error
host_addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
host_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
host_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
host_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable
host_we_i : in std_ulogic; -- write enable
host_re_i : in std_ulogic; -- read enable
host_ack_o : out std_ulogic; -- bus transfer acknowledge
host_err_o : out std_ulogic; -- bus transfer error
-- peripheral bus interface --
bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
bus_we_o : out std_ulogic; -- write enable
bus_re_o : out std_ulogic; -- read enable
bus_ack_i : in std_ulogic; -- bus transfer acknowledge
bus_err_i : in std_ulogic -- bus transfer error
bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
bus_we_o : out std_ulogic; -- write enable
bus_re_o : out std_ulogic; -- read enable
bus_ack_i : in std_ulogic; -- bus transfer acknowledge
bus_err_i : in std_ulogic -- bus transfer error
);
end component;
 
1489,43 → 1505,43
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
-- controller interface a --
ca_bus_addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
ca_bus_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
ca_bus_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
ca_bus_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable
ca_bus_we_i : in std_ulogic; -- write enable
ca_bus_re_i : in std_ulogic; -- read enable
ca_bus_lock_i : in std_ulogic; -- exclusive access request
ca_bus_ack_o : out std_ulogic; -- bus transfer acknowledge
ca_bus_err_o : out std_ulogic; -- bus transfer error
ca_bus_addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
ca_bus_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
ca_bus_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
ca_bus_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable
ca_bus_we_i : in std_ulogic; -- write enable
ca_bus_re_i : in std_ulogic; -- read enable
ca_bus_lock_i : in std_ulogic; -- exclusive access request
ca_bus_ack_o : out std_ulogic; -- bus transfer acknowledge
ca_bus_err_o : out std_ulogic; -- bus transfer error
-- controller interface b --
cb_bus_addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
cb_bus_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
cb_bus_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
cb_bus_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable
cb_bus_we_i : in std_ulogic; -- write enable
cb_bus_re_i : in std_ulogic; -- read enable
cb_bus_lock_i : in std_ulogic; -- exclusive access request
cb_bus_ack_o : out std_ulogic; -- bus transfer acknowledge
cb_bus_err_o : out std_ulogic; -- bus transfer error
cb_bus_addr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
cb_bus_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
cb_bus_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
cb_bus_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable
cb_bus_we_i : in std_ulogic; -- write enable
cb_bus_re_i : in std_ulogic; -- read enable
cb_bus_lock_i : in std_ulogic; -- exclusive access request
cb_bus_ack_o : out std_ulogic; -- bus transfer acknowledge
cb_bus_err_o : out std_ulogic; -- bus transfer error
-- peripheral bus --
p_bus_src_o : out std_ulogic; -- access source: 0 = A, 1 = B
p_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
p_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
p_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
p_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
p_bus_we_o : out std_ulogic; -- write enable
p_bus_re_o : out std_ulogic; -- read enable
p_bus_lock_o : out std_ulogic; -- exclusive access request
p_bus_ack_i : in std_ulogic; -- bus transfer acknowledge
p_bus_err_i : in std_ulogic -- bus transfer error
p_bus_src_o : out std_ulogic; -- access source: 0 = A, 1 = B
p_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
p_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
p_bus_wdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
p_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable
p_bus_we_o : out std_ulogic; -- write enable
p_bus_re_o : out std_ulogic; -- read enable
p_bus_lock_o : out std_ulogic; -- exclusive access request
p_bus_ack_i : in std_ulogic; -- bus transfer acknowledge
p_bus_err_i : in std_ulogic -- bus transfer error
);
end component;
 
-- Component: CPU Compressed Instructions Decompressor ------------------------------------
-- Component: CPU Compressed Instructions De-Compressor -----------------------------------
-- -------------------------------------------------------------------------------------------
component neorv32_cpu_decompressor
port (
1622,6 → 1638,7
data_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic; -- transfer acknowledge
err_o : out std_ulogic; -- transfer error
-- parallel io --
gpio_o : out std_ulogic_vector(63 downto 0);
gpio_i : in std_ulogic_vector(63 downto 0)
1754,7 → 1771,7
clkgen_en_o : out std_ulogic; -- enable clock generator
clkgen_i : in std_ulogic_vector(07 downto 0);
-- pwm output channels --
pwm_o : out std_ulogic_vector(NUM_CHANNELS-1 downto 0)
pwm_o : out std_ulogic_vector(59 downto 0)
);
end component;
 
1791,34 → 1808,37
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active
-- host access --
src_i : in std_ulogic; -- access type (0: data, 1:instruction)
addr_i : in std_ulogic_vector(31 downto 0); -- address
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
ben_i : in std_ulogic_vector(03 downto 0); -- byte write enable
data_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
lock_i : in std_ulogic; -- exclusive access request
ack_o : out std_ulogic; -- transfer acknowledge
err_o : out std_ulogic; -- transfer error
tmo_o : out std_ulogic; -- transfer timeout
priv_i : in std_ulogic_vector(01 downto 0); -- current CPU privilege level
ext_o : out std_ulogic; -- active external access
src_i : in std_ulogic; -- access type (0: data, 1:instruction)
addr_i : in std_ulogic_vector(31 downto 0); -- address
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
ben_i : in std_ulogic_vector(03 downto 0); -- byte write enable
data_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
lock_i : in std_ulogic; -- exclusive access request
ack_o : out std_ulogic; -- transfer acknowledge
err_o : out std_ulogic; -- transfer error
tmo_o : out std_ulogic; -- transfer timeout
priv_i : in std_ulogic_vector(01 downto 0); -- current CPU privilege level
ext_o : out std_ulogic; -- active external access
-- xip configuration --
xip_en_i : in std_ulogic; -- XIP module enabled
xip_page_i : in std_ulogic_vector(03 downto 0); -- XIP memory page
-- wishbone interface --
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address
wb_dat_i : in std_ulogic_vector(31 downto 0); -- read data
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data
wb_we_o : out std_ulogic; -- read/write
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable
wb_stb_o : out std_ulogic; -- strobe
wb_cyc_o : out std_ulogic; -- valid cycle
wb_lock_o : out std_ulogic; -- exclusive access request
wb_ack_i : in std_ulogic; -- transfer acknowledge
wb_err_i : in std_ulogic -- transfer error
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address
wb_dat_i : in std_ulogic_vector(31 downto 0); -- read data
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data
wb_we_o : out std_ulogic; -- read/write
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable
wb_stb_o : out std_ulogic; -- strobe
wb_cyc_o : out std_ulogic; -- valid cycle
wb_lock_o : out std_ulogic; -- exclusive access request
wb_ack_i : in std_ulogic; -- transfer acknowledge
wb_err_i : in std_ulogic -- transfer error
);
end component;
 
1927,7 → 1947,7
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic; -- transfer acknowledge
-- external interrupt lines --
xirq_i : in std_ulogic_vector(XIRQ_NUM_CH-1 downto 0);
xirq_i : in std_ulogic_vector(31 downto 0);
-- CPU interrupt --
cpu_irq_o : out std_ulogic
);
1953,6 → 1973,40
);
end component;
 
-- Component: Execute In Place Module (XIP) -----------------------------------------------
-- -------------------------------------------------------------------------------------------
component neorv32_xip
port (
-- globals --
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active
-- host access: control register access port --
ct_addr_i : in std_ulogic_vector(31 downto 0); -- address
ct_rden_i : in std_ulogic; -- read enable
ct_wren_i : in std_ulogic; -- write enable
ct_data_i : in std_ulogic_vector(31 downto 0); -- data in
ct_data_o : out std_ulogic_vector(31 downto 0); -- data out
ct_ack_o : out std_ulogic; -- transfer acknowledge
-- host access: instruction fetch access port (read-only) --
if_addr_i : in std_ulogic_vector(31 downto 0); -- address
if_rden_i : in std_ulogic; -- read enable
if_data_o : out std_ulogic_vector(31 downto 0); -- data out
if_ack_o : out std_ulogic; -- transfer acknowledge
-- status --
xip_en_o : out std_ulogic; -- XIP enable
xip_acc_o : out std_ulogic; -- pending XIP access
xip_page_o : out std_ulogic_vector(03 downto 0); -- XIP page
-- clock generator --
clkgen_en_o : out std_ulogic; -- enable clock generator
clkgen_i : in std_ulogic_vector(07 downto 0);
-- SPI device interface --
spi_csn_o : out std_ulogic; -- chip-select, low-active
spi_clk_o : out std_ulogic; -- serial clock
spi_data_i : in std_ulogic; -- device data output
spi_data_o : out std_ulogic -- controller data output
);
end component;
 
-- Component: System Configuration Information Memory (SYSINFO) ---------------------------
-- -------------------------------------------------------------------------------------------
component neorv32_sysinfo
2004,7 → 2058,8
IO_SLINK_EN : boolean; -- implement stream link interface?
IO_NEOLED_EN : boolean; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_XIRQ_NUM_CH : natural; -- number of external interrupt (XIRQ) channels to implement
IO_GPTMR_EN : boolean -- implement general purpose timer (GPTMR)?
IO_GPTMR_EN : boolean; -- implement general purpose timer (GPTMR)?
IO_XIP_EN : boolean -- implement execute in place module (XIP)?
);
port (
-- host access --
2011,8 → 2066,10
clk_i : in std_ulogic; -- global clock line
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
ack_o : out std_ulogic; -- transfer acknowledge
err_o : out std_ulogic -- transfer error
);
end component;
 
2423,4 → 2480,9
end function mem32_init_f;
 
 
-- Finally set deferred constant, see IEEE 1076-2008 14.4.2.1 (NEORV32 Issue #242) --------
-- -------------------------------------------------------------------------------------------
constant def_rst_val_c : std_ulogic := cond_sel_stdulogic_f(dedicated_reset_c, '0', '-');
 
 
end neorv32_package;
/neorv32/trunk/rtl/core/neorv32_pwm.vhd
59,7 → 59,7
clkgen_en_o : out std_ulogic; -- enable clock generator
clkgen_i : in std_ulogic_vector(07 downto 0);
-- pwm output channels --
pwm_o : out std_ulogic_vector(NUM_CHANNELS-1 downto 0)
pwm_o : out std_ulogic_vector(59 downto 0)
);
end neorv32_pwm;
 
186,6 → 186,7
end if;
 
-- channels --
pwm_o <= (others => '0');
for i in 0 to NUM_CHANNELS-1 loop
if (unsigned(pwm_cnt) >= unsigned(pwm_ch(i))) or (enable = '0') then
pwm_o(i) <= '0';
/neorv32/trunk/rtl/core/neorv32_spi.vhd
7,7 → 7,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
73,27 → 73,27
constant lo_abb_c : natural := index_size_f(spi_size_c); -- low address boundary bit
 
-- control register --
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_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_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_highspeed_c : natural := 16; -- r/w: spi high-speed mode enable (ignoring ctrl_prsc)
--
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_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);
signal ctrl : std_ulogic_vector(16 downto 0);
 
-- access control --
signal acc_en : std_ulogic; -- module access enable
112,7 → 112,7
sreg : std_ulogic_vector(31 downto 0);
bitcnt : std_ulogic_vector(05 downto 0);
bytecnt : std_ulogic_vector(02 downto 0);
sdi_sync : std_ulogic_vector(01 downto 0);
sdi_sync : std_ulogic;
end record;
signal rtx_engine : rtx_engine_t;
 
137,23 → 137,23
-- write access --
if (wren = '1') then
if (addr = spi_ctrl_addr_c) then -- control register
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_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);
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_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);
ctrl(ctrl_highspeed_c) <= data_i(ctrl_highspeed_c);
end if;
end if;
 
161,25 → 161,25
data_o <= (others => '0');
if (rden = '1') then
if (addr = spi_ctrl_addr_c) then -- control register
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_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_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_highspeed_c) <= ctrl(ctrl_highspeed_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_busy_c) <= rtx_engine.busy;
data_o(ctrl_busy_c) <= rtx_engine.busy;
else -- data register (spi_rtx_addr_c)
data_o <= rtx_engine.sreg;
end if;
197,7 → 197,7
-- 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
spi_clk_en <= clkgen_i(to_integer(unsigned(ctrl(ctrl_prsc2_c downto ctrl_prsc0_c)))) or ctrl(ctrl_highspeed_c); -- clock select
 
 
-- Transmission Data Size -----------------------------------------------------------------
219,16 → 219,8
begin
if rising_edge(clk_i) then
-- input (sdi) synchronizer --
rtx_engine.sdi_sync <= rtx_engine.sdi_sync(0) & spi_sdi_i;
rtx_engine.sdi_sync <= 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);
irq_o <= '0';
263,7 → 255,7
-- ------------------------------------------------------------
spi_sck_o <= ctrl(ctrl_cpha_c) xnor ctrl(ctrl_cpol_c);
if (spi_clk_en = '1') then
rtx_engine.sreg <= rtx_engine.sreg(30 downto 0) & rtx_engine.sdi_sync(rtx_engine.sdi_sync'left);
rtx_engine.sreg <= rtx_engine.sreg(30 downto 0) & rtx_engine.sdi_sync;
if (rtx_engine.bitcnt(5 downto 3) = rtx_engine.bytecnt) then -- all bits transferred?
irq_o <= '1'; -- interrupt!
rtx_engine.state(1 downto 0) <= "00"; -- transmission done
283,5 → 275,16
-- busy flag --
rtx_engine.busy <= '0' when (rtx_engine.state(1 downto 0) = "00") else '1';
 
-- output bit select --
spi_output: process(ctrl, rtx_engine)
begin
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;
end process spi_output;
 
 
end neorv32_spi_rtl;
/neorv32/trunk/rtl/core/neorv32_sysinfo.vhd
6,7 → 6,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
91,7 → 91,8
IO_SLINK_EN : boolean; -- implement stream link interface?
IO_NEOLED_EN : boolean; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_XIRQ_NUM_CH : natural; -- number of external interrupt (XIRQ) channels to implement
IO_GPTMR_EN : boolean -- implement general purpose timer (GPTMR)?
IO_GPTMR_EN : boolean; -- implement general purpose timer (GPTMR)?
IO_XIP_EN : boolean -- implement execute in place module (XIP)?
);
port (
-- host access --
98,8 → 99,10
clk_i : in std_ulogic; -- global clock line
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
ack_o : out std_ulogic; -- transfer acknowledge
err_o : out std_ulogic -- transfer error
);
end neorv32_sysinfo;
 
110,10 → 113,10
constant lo_abb_c : natural := index_size_f(sysinfo_size_c); -- low address boundary bit
 
-- access control --
signal acc_en : std_ulogic; -- module access enable
signal addr : std_ulogic_vector(31 downto 0);
signal rden : std_ulogic;
signal info_addr : std_ulogic_vector(02 downto 0);
signal acc_en : std_ulogic; -- module access enable
signal rden : std_ulogic;
signal wren : std_ulogic;
signal iaddr : std_ulogic_vector(02 downto 0);
 
-- system information ROM --
type info_mem_t is array (0 to 7) of std_ulogic_vector(31 downto 0);
123,15 → 126,14
 
-- Access Control -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = sysinfo_base_c(hi_abb_c downto lo_abb_c)) else '0';
rden <= acc_en and rden_i; -- valid read access
addr <= sysinfo_base_c(31 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 2) & "00"; -- word aligned
info_addr <= addr(index_size_f(sysinfo_size_c)-1 downto 2);
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = sysinfo_base_c(hi_abb_c downto lo_abb_c)) else '0';
rden <= acc_en and rden_i; -- read access
wren <= acc_en and wren_i; -- write access
iaddr <= addr_i(index_size_f(sysinfo_size_c)-1 downto 2);
 
 
-- Construct Info ROM ---------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
 
-- SYSINFO(0): Processor (primary) clock frequency --
sysinfo_mem(0) <= std_ulogic_vector(to_unsigned(CLOCK_FREQUENCY, 32));
 
183,8 → 185,9
sysinfo_mem(2)(27) <= bool_to_ulogic_f(IO_NEOLED_EN); -- NeoPixel-compatible smart LED interface (NEOLED) implemented?
sysinfo_mem(2)(28) <= bool_to_ulogic_f(boolean(IO_XIRQ_NUM_CH > 0)); -- external interrupt controller (XIRQ) implemented?
sysinfo_mem(2)(29) <= bool_to_ulogic_f(IO_GPTMR_EN); -- general purpose timer (GPTMR) implemented?
sysinfo_mem(2)(30) <= bool_to_ulogic_f(IO_XIP_EN); -- execute in place module (XIP) implemented?
--
sysinfo_mem(2)(31 downto 30) <= (others => '0'); -- reserved
sysinfo_mem(2)(31) <= '0'; -- reserved
 
-- SYSINFO(3): Cache configuration --
sysinfo_mem(3)(03 downto 00) <= std_ulogic_vector(to_unsigned(index_size_f(ICACHE_BLOCK_SIZE), 4)) when (ICACHE_EN = true) else (others => '0'); -- i-cache: log2(block_size_in_bytes)
216,9 → 219,10
begin
if rising_edge(clk_i) then
ack_o <= rden;
err_o <= wren;
data_o <= (others => '0');
if (rden = '1') then
data_o <= sysinfo_mem(to_integer(unsigned(info_addr)));
data_o <= sysinfo_mem(to_integer(unsigned(iaddr)));
end if;
end if;
end process read_access;
/neorv32/trunk/rtl/core/neorv32_top.vhd
8,7 → 8,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
90,7 → 90,7
MEM_INT_DMEM_EN : boolean := false; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
 
-- Internal Cache memory (iCACHE) --
-- Internal Instruction Cache (iCACHE) --
ICACHE_EN : boolean := false; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2
134,7 → 134,8
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits
IO_NEOLED_EN : boolean := false; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_NEOLED_TX_FIFO : natural := 1; -- NEOLED TX FIFO depth, 1..32k, has to be a power of two
IO_GPTMR_EN : boolean := false -- implement general purpose timer (GPTMR)?
IO_GPTMR_EN : boolean := false; -- implement general purpose timer (GPTMR)?
IO_XIP_EN : boolean := false -- implement execute in place module (XIP)?
);
port (
-- Global control --
165,6 → 166,12
fence_o : out std_ulogic; -- indicates an executed FENCE operation
fencei_o : out std_ulogic; -- indicates an executed FENCEI operation
 
-- XIP (execute in place via SPI) signals (available if IO_XIP_EN = true) --
xip_csn_o : out std_ulogic; -- chip-select, low-active
xip_clk_o : out std_ulogic; -- serial clock
xip_sdi_i : in std_ulogic := 'L'; -- device data input
xip_sdo_o : out std_ulogic; -- controller data output
 
-- TX stream interfaces (available if SLINK_NUM_TX > 0) --
slink_tx_dat_o : out sdata_8x32_t; -- output data
slink_tx_val_o : out std_ulogic_vector(7 downto 0); -- valid output
202,7 → 209,7
twi_scl_io : inout std_logic := 'U'; -- twi serial clock line
 
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels
pwm_o : out std_ulogic_vector(59 downto 0); -- pwm channels
 
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
cfs_in_i : in std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0) := (others => 'U'); -- custom CFS inputs conduit
216,7 → 223,7
mtime_o : out std_ulogic_vector(63 downto 0); -- current system time from int. MTIME (if IO_MTIME_EN = true)
 
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i : in std_ulogic_vector(XIRQ_NUM_CH-1 downto 0) := (others => 'L'); -- IRQ channels
xirq_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); -- IRQ channels
 
-- CPU interrupts --
mtime_irq_i : in std_ulogic := 'L'; -- machine timer interrupt, available if IO_MTIME_EN = false
238,16 → 245,17
constant io_slink_en_c : boolean := boolean(SLINK_NUM_RX > 0) or boolean(SLINK_NUM_TX > 0); -- implement slink at all?
 
-- reset generator --
signal rstn_gen : std_ulogic_vector(7 downto 0) := (others => '0'); -- initialize (=reset) via (for FPGAs only)
signal rstn_gen : std_ulogic_vector(7 downto 0) := (others => '0'); -- initialize (=reset) via bitstream (for FPGAs only)
signal ext_rstn : std_ulogic;
signal sys_rstn : std_ulogic;
signal wdt_rstn : std_ulogic;
 
-- clock generator --
signal clk_div : std_ulogic_vector(11 downto 0);
signal clk_div_ff : std_ulogic_vector(11 downto 0);
signal clk_gen : std_ulogic_vector(07 downto 0);
signal clk_gen_en : std_ulogic_vector(08 downto 0);
signal clk_div : std_ulogic_vector(11 downto 0);
signal clk_div_ff : std_ulogic_vector(11 downto 0);
signal clk_gen : std_ulogic_vector(07 downto 0);
signal clk_gen_en : std_ulogic_vector(09 downto 0);
signal clk_gen_en_ff : std_ulogic;
--
signal wdt_cg_en : std_ulogic;
signal uart0_cg_en : std_ulogic;
258,21 → 266,22
signal cfs_cg_en : std_ulogic;
signal neoled_cg_en : std_ulogic;
signal gptmr_cg_en : std_ulogic;
signal xip_cg_en : std_ulogic;
 
-- bus interface --
type bus_interface_t is record
addr : std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
rdata : std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
wdata : std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
ben : std_ulogic_vector(03 downto 0); -- byte enable
we : std_ulogic; -- write enable
re : std_ulogic; -- read enable
ack : std_ulogic; -- bus transfer acknowledge
err : std_ulogic; -- bus transfer error
fence : std_ulogic; -- fence(i) instruction executed
priv : std_ulogic_vector(1 downto 0); -- current privilege level
src : std_ulogic; -- access source (1=instruction fetch, 0=data access)
lock : std_ulogic; -- exclusive access request
addr : std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
rdata : std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
wdata : std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
ben : std_ulogic_vector(03 downto 0); -- byte enable
we : std_ulogic; -- write enable
re : std_ulogic; -- read enable
ack : std_ulogic; -- bus transfer acknowledge
err : std_ulogic; -- bus transfer error
fence : std_ulogic; -- fence(i) instruction executed
priv : std_ulogic_vector(1 downto 0); -- current privilege level
src : std_ulogic; -- access source (1=instruction fetch, 0=data access)
lock : std_ulogic; -- exclusive access request
end record;
signal cpu_i, i_cache, cpu_d, p_bus : bus_interface_t;
 
312,8 → 321,9
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_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, RESP_GPTMR);
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, RESP_GPTMR, RESP_XIP_CT, RESP_XIP_IF);
 
-- module response bus --
type resp_bus_t is array (resp_bus_id_t) of resp_bus_entry_t;
340,6 → 350,9
signal mtime_time : std_ulogic_vector(63 downto 0); -- current system time from MTIME
signal ext_timeout : std_ulogic;
signal ext_access : std_ulogic;
signal xip_access : std_ulogic;
signal xip_enable : std_ulogic;
signal xip_page : std_ulogic_vector(3 downto 0);
signal debug_mode : std_ulogic;
 
begin
362,7 → 375,8
cond_sel_string_f(IO_NEOLED_EN, "NEOLED ", "") &
cond_sel_string_f(boolean(XIRQ_NUM_CH > 0), "XIRQ ", "") &
cond_sel_string_f(IO_GPTMR_EN, "GPTMR ", "") &
""
cond_sel_string_f(IO_XIP_EN, "XIP ", "") &
""
severity note;
 
 
421,23 → 435,14
clock_generator: process(sys_rstn, clk_i)
begin
if (sys_rstn = '0') then
clk_gen_en <= (others => '-');
clk_div <= (others => '0');
clk_div_ff <= (others => '-');
clk_gen <= (others => '-');
clk_gen_en_ff <= '-';
clk_div <= (others => '0'); -- reset required
clk_div_ff <= (others => '-');
clk_gen <= (others => '-');
elsif rising_edge(clk_i) then
-- fresh clocks anyone? --
clk_gen_en(0) <= wdt_cg_en;
clk_gen_en(1) <= uart0_cg_en;
clk_gen_en(2) <= uart1_cg_en;
clk_gen_en(3) <= spi_cg_en;
clk_gen_en(4) <= twi_cg_en;
clk_gen_en(5) <= pwm_cg_en;
clk_gen_en(6) <= cfs_cg_en;
clk_gen_en(7) <= neoled_cg_en;
clk_gen_en(8) <= gptmr_cg_en;
clk_gen_en_ff <= or_reduce_f(clk_gen_en);
-- actual clock generator --
if (or_reduce_f(clk_gen_en) = '1') then
if (clk_gen_en_ff = '1') then
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
end if;
-- clock enables: rising edge detectors --
453,21 → 458,33
end if;
end process clock_generator;
 
-- fresh clocks anyone? --
clk_gen_en(0) <= wdt_cg_en;
clk_gen_en(1) <= uart0_cg_en;
clk_gen_en(2) <= uart1_cg_en;
clk_gen_en(3) <= spi_cg_en;
clk_gen_en(4) <= twi_cg_en;
clk_gen_en(5) <= pwm_cg_en;
clk_gen_en(6) <= cfs_cg_en;
clk_gen_en(7) <= neoled_cg_en;
clk_gen_en(8) <= gptmr_cg_en;
clk_gen_en(9) <= xip_cg_en;
 
 
-- CPU Core -------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_inst: neorv32_cpu
generic map (
-- General --
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id
CPU_BOOT_ADDR => cpu_boot_addr_c, -- cpu boot address
CPU_DEBUG_ADDR => dm_base_c, -- cpu debug mode start address
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id
CPU_BOOT_ADDR => cpu_boot_addr_c, -- cpu boot address
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_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension?
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 reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
477,57 → 494,57
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?
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
CPU_IPB_ENTRIES => CPU_IPB_ENTRIES, -- entries is instruction prefetch buffer, has to be a power of 2
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
CPU_IPB_ENTRIES => CPU_IPB_ENTRIES, -- entries is instruction prefetch buffer, has to be a power of 2
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => HPM_CNT_WIDTH -- total size of HPM counters (0..64)
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => HPM_CNT_WIDTH -- total size of HPM counters (0..64)
)
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => sys_rstn, -- global reset, low-active, async
sleep_o => open, -- cpu is in sleep mode when set
debug_o => debug_mode, -- cpu is in debug mode when set
clk_i => clk_i, -- global clock, rising edge
rstn_i => sys_rstn, -- global reset, low-active, async
sleep_o => open, -- cpu is in sleep mode when set
debug_o => debug_mode, -- cpu is in debug mode when set
-- instruction bus interface --
i_bus_addr_o => cpu_i.addr, -- bus access address
i_bus_rdata_i => cpu_i.rdata, -- bus read data
i_bus_wdata_o => cpu_i.wdata, -- bus write data
i_bus_ben_o => cpu_i.ben, -- byte enable
i_bus_we_o => cpu_i.we, -- write enable
i_bus_re_o => cpu_i.re, -- read enable
i_bus_lock_o => cpu_i.lock, -- exclusive access request
i_bus_ack_i => cpu_i.ack, -- bus transfer acknowledge
i_bus_err_i => cpu_i.err, -- bus transfer error
i_bus_fence_o => cpu_i.fence, -- executed FENCEI operation
i_bus_priv_o => cpu_i.priv, -- privilege level
i_bus_addr_o => cpu_i.addr, -- bus access address
i_bus_rdata_i => cpu_i.rdata, -- bus read data
i_bus_wdata_o => cpu_i.wdata, -- bus write data
i_bus_ben_o => cpu_i.ben, -- byte enable
i_bus_we_o => cpu_i.we, -- write enable
i_bus_re_o => cpu_i.re, -- read enable
i_bus_lock_o => cpu_i.lock, -- exclusive access request
i_bus_ack_i => cpu_i.ack, -- bus transfer acknowledge
i_bus_err_i => cpu_i.err, -- bus transfer error
i_bus_fence_o => cpu_i.fence, -- executed FENCEI operation
i_bus_priv_o => cpu_i.priv, -- privilege level
-- data bus interface --
d_bus_addr_o => cpu_d.addr, -- bus access address
d_bus_rdata_i => cpu_d.rdata, -- bus read data
d_bus_wdata_o => cpu_d.wdata, -- bus write data
d_bus_ben_o => cpu_d.ben, -- byte enable
d_bus_we_o => cpu_d.we, -- write enable
d_bus_re_o => cpu_d.re, -- read enable
d_bus_lock_o => cpu_d.lock, -- exclusive access request
d_bus_ack_i => cpu_d.ack, -- bus transfer acknowledge
d_bus_err_i => cpu_d.err, -- bus transfer error
d_bus_fence_o => cpu_d.fence, -- executed FENCE operation
d_bus_priv_o => cpu_d.priv, -- privilege level
d_bus_addr_o => cpu_d.addr, -- bus access address
d_bus_rdata_i => cpu_d.rdata, -- bus read data
d_bus_wdata_o => cpu_d.wdata, -- bus write data
d_bus_ben_o => cpu_d.ben, -- byte enable
d_bus_we_o => cpu_d.we, -- write enable
d_bus_re_o => cpu_d.re, -- read enable
d_bus_lock_o => cpu_d.lock, -- exclusive access request
d_bus_ack_i => cpu_d.ack, -- bus transfer acknowledge
d_bus_err_i => cpu_d.err, -- bus transfer error
d_bus_fence_o => cpu_d.fence, -- executed FENCE operation
d_bus_priv_o => cpu_d.priv, -- privilege level
-- system time input from MTIME --
time_i => mtime_time, -- current system time
time_i => mtime_time, -- current system time
-- non-maskable interrupt --
msw_irq_i => msw_irq_i, -- machine software interrupt
mext_irq_i => mext_irq_i, -- machine external interrupt request
mtime_irq_i => mtime_irq, -- machine timer interrupt
msw_irq_i => msw_irq_i, -- machine software interrupt
mext_irq_i => mext_irq_i, -- machine external interrupt request
mtime_irq_i => mtime_irq, -- machine timer interrupt
-- fast interrupts (custom) --
firq_i => fast_irq, -- fast interrupt trigger
firq_i => fast_irq, -- fast interrupt trigger
-- debug mode (halt) request --
db_halt_req_i => dci_halt_req
db_halt_req_i => dci_halt_req
);
 
-- misc --
538,8 → 555,7
fence_o <= cpu_d.fence; -- indicates an executed FENCE operation
fencei_o <= cpu_i.fence; -- indicates an executed FENCEI operation
 
-- fast interrupt requests (FIRQs) --
-- these signals are single-shot --
-- fast interrupt requests (FIRQs) - triggers are SINGLE-SHOT --
fast_irq(00) <= wdt_irq; -- HIGHEST PRIORITY - watchdog
fast_irq(01) <= cfs_irq; -- custom functions subsystem
fast_irq(02) <= uart0_rxd_irq; -- primary UART (UART0) RX
546,17 → 562,17
fast_irq(03) <= uart0_txd_irq; -- primary UART (UART0) TX
fast_irq(04) <= uart1_rxd_irq; -- secondary UART (UART1) RX
fast_irq(05) <= uart1_txd_irq; -- secondary UART (UART1) TX
fast_irq(06) <= spi_irq; -- SPI
fast_irq(07) <= twi_irq; -- TWI
fast_irq(06) <= spi_irq; -- SPI transfer done
fast_irq(07) <= twi_irq; -- TWI transfer done
fast_irq(08) <= xirq_irq; -- external interrupt controller
fast_irq(09) <= neoled_irq; -- NEOLED buffer free
fast_irq(09) <= neoled_irq; -- NEOLED buffer IRQ
fast_irq(10) <= slink_rx_irq; -- SLINK RX
fast_irq(11) <= slink_tx_irq; -- SLINK TX
fast_irq(12) <= gptmr_irq; -- general purpose timer
--
fast_irq(13) <= '0'; -- reserved
fast_irq(14) <= '0'; -- reserved
fast_irq(15) <= '0'; -- LOWEST PRIORITY - reserved
fast_irq(13) <= '0'; -- reserved
fast_irq(14) <= '0'; -- reserved
fast_irq(15) <= '0'; -- LOWEST PRIORITY - reserved
 
 
-- CPU Instruction Cache ------------------------------------------------------------------
571,27 → 587,27
)
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => sys_rstn, -- global reset, low-active, async
clear_i => cpu_i.fence, -- cache clear
clk_i => clk_i, -- global clock, rising edge
rstn_i => sys_rstn, -- global reset, low-active, async
clear_i => cpu_i.fence, -- cache clear
-- host controller interface --
host_addr_i => cpu_i.addr, -- bus access address
host_rdata_o => cpu_i.rdata, -- bus read data
host_wdata_i => cpu_i.wdata, -- bus write data
host_ben_i => cpu_i.ben, -- byte enable
host_we_i => cpu_i.we, -- write enable
host_re_i => cpu_i.re, -- read enable
host_ack_o => cpu_i.ack, -- bus transfer acknowledge
host_err_o => cpu_i.err, -- bus transfer error
host_addr_i => cpu_i.addr, -- bus access address
host_rdata_o => cpu_i.rdata, -- bus read data
host_wdata_i => cpu_i.wdata, -- bus write data
host_ben_i => cpu_i.ben, -- byte enable
host_we_i => cpu_i.we, -- write enable
host_re_i => cpu_i.re, -- read enable
host_ack_o => cpu_i.ack, -- bus transfer acknowledge
host_err_o => cpu_i.err, -- bus transfer error
-- peripheral bus interface --
bus_addr_o => i_cache.addr, -- bus access address
bus_rdata_i => i_cache.rdata, -- bus read data
bus_wdata_o => i_cache.wdata, -- bus write data
bus_ben_o => i_cache.ben, -- byte enable
bus_we_o => i_cache.we, -- write enable
bus_re_o => i_cache.re, -- read enable
bus_ack_i => i_cache.ack, -- bus transfer acknowledge
bus_err_i => i_cache.err -- bus transfer error
bus_addr_o => i_cache.addr, -- bus access address
bus_rdata_i => i_cache.rdata, -- bus read data
bus_wdata_o => i_cache.wdata, -- bus write data
bus_ben_o => i_cache.ben, -- byte enable
bus_we_o => i_cache.we, -- write enable
bus_re_o => i_cache.re, -- read enable
bus_ack_i => i_cache.ack, -- bus transfer acknowledge
bus_err_i => i_cache.err -- bus transfer error
);
end generate;
 
620,39 → 636,39
)
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => sys_rstn, -- global reset, low-active, async
clk_i => clk_i, -- global clock, rising edge
rstn_i => sys_rstn, -- global reset, low-active, async
-- controller interface a --
ca_bus_addr_i => cpu_d.addr, -- bus access address
ca_bus_rdata_o => cpu_d.rdata, -- bus read data
ca_bus_wdata_i => cpu_d.wdata, -- bus write data
ca_bus_ben_i => cpu_d.ben, -- byte enable
ca_bus_we_i => cpu_d.we, -- write enable
ca_bus_re_i => cpu_d.re, -- read enable
ca_bus_lock_i => cpu_d.lock, -- exclusive access request
ca_bus_ack_o => cpu_d.ack, -- bus transfer acknowledge
ca_bus_err_o => cpu_d.err, -- bus transfer error
ca_bus_addr_i => cpu_d.addr, -- bus access address
ca_bus_rdata_o => cpu_d.rdata, -- bus read data
ca_bus_wdata_i => cpu_d.wdata, -- bus write data
ca_bus_ben_i => cpu_d.ben, -- byte enable
ca_bus_we_i => cpu_d.we, -- write enable
ca_bus_re_i => cpu_d.re, -- read enable
ca_bus_lock_i => cpu_d.lock, -- exclusive access request
ca_bus_ack_o => cpu_d.ack, -- bus transfer acknowledge
ca_bus_err_o => cpu_d.err, -- bus transfer error
-- controller interface b --
cb_bus_addr_i => i_cache.addr, -- bus access address
cb_bus_rdata_o => i_cache.rdata, -- bus read data
cb_bus_wdata_i => i_cache.wdata, -- bus write data
cb_bus_ben_i => i_cache.ben, -- byte enable
cb_bus_we_i => i_cache.we, -- write enable
cb_bus_re_i => i_cache.re, -- read enable
cb_bus_lock_i => i_cache.lock, -- exclusive access request
cb_bus_ack_o => i_cache.ack, -- bus transfer acknowledge
cb_bus_err_o => i_cache.err, -- bus transfer error
cb_bus_addr_i => i_cache.addr, -- bus access address
cb_bus_rdata_o => i_cache.rdata, -- bus read data
cb_bus_wdata_i => i_cache.wdata, -- bus write data
cb_bus_ben_i => i_cache.ben, -- byte enable
cb_bus_we_i => i_cache.we, -- write enable
cb_bus_re_i => i_cache.re, -- read enable
cb_bus_lock_i => i_cache.lock, -- exclusive access request
cb_bus_ack_o => i_cache.ack, -- bus transfer acknowledge
cb_bus_err_o => i_cache.err, -- bus transfer error
-- peripheral bus --
p_bus_src_o => p_bus.src, -- access source: 0 = A (data), 1 = B (instructions)
p_bus_addr_o => p_bus.addr, -- bus access address
p_bus_rdata_i => p_bus.rdata, -- bus read data
p_bus_wdata_o => p_bus.wdata, -- bus write data
p_bus_ben_o => p_bus.ben, -- byte enable
p_bus_we_o => p_bus.we, -- write enable
p_bus_re_o => p_bus.re, -- read enable
p_bus_lock_o => p_bus.lock, -- exclusive access request
p_bus_ack_i => p_bus.ack, -- bus transfer acknowledge
p_bus_err_i => bus_error -- bus transfer error
p_bus_src_o => p_bus.src, -- access source: 0 = A (data), 1 = B (instructions)
p_bus_addr_o => p_bus.addr, -- bus access address
p_bus_rdata_i => p_bus.rdata, -- bus read data
p_bus_wdata_o => p_bus.wdata, -- bus write data
p_bus_ben_o => p_bus.ben, -- byte enable
p_bus_we_o => p_bus.we, -- write enable
p_bus_re_o => p_bus.re, -- read enable
p_bus_lock_o => p_bus.lock, -- exclusive access request
p_bus_ack_i => p_bus.ack, -- bus transfer acknowledge
p_bus_err_i => bus_error -- bus transfer error
);
 
-- current CPU privilege level --
691,6 → 707,7
addr_i => p_bus.addr, -- address
rden_i => io_rden, -- read enable
wren_i => io_wren, -- byte write enable
data_i => p_bus.wdata, -- data in
data_o => resp_bus(RESP_BUSKEEPER).rdata, -- data out
ack_o => resp_bus(RESP_BUSKEEPER).ack, -- transfer acknowledge
err_o => bus_error, -- transfer error
701,7 → 718,8
bus_ack_i => p_bus.ack, -- transfer acknowledge from bus system
bus_err_i => p_bus.err, -- transfer error from bus system
bus_tmo_i => ext_timeout, -- transfer timeout (external interface)
bus_ext_i => ext_access -- external bus access
bus_ext_i => ext_access, -- external bus access
bus_xip_i => xip_access -- pending XIP access
);
 
-- unused, BUSKEEPER **directly** issues error to the CPU --
809,34 → 827,37
)
port map (
-- global control --
clk_i => clk_i, -- global clock line
rstn_i => sys_rstn, -- global reset line, low-active
clk_i => clk_i, -- global clock line
rstn_i => sys_rstn, -- global reset line, low-active
-- host access --
src_i => p_bus.src, -- access type (0: data, 1:instruction)
addr_i => p_bus.addr, -- address
rden_i => p_bus.re, -- read enable
wren_i => p_bus.we, -- write enable
ben_i => p_bus.ben, -- byte write enable
data_i => p_bus.wdata, -- data in
data_o => resp_bus(RESP_WISHBONE).rdata, -- data out
lock_i => p_bus.lock, -- exclusive access request
ack_o => resp_bus(RESP_WISHBONE).ack, -- transfer acknowledge
err_o => resp_bus(RESP_WISHBONE).err, -- transfer error
tmo_o => ext_timeout, -- transfer timeout
priv_i => p_bus.priv, -- current CPU privilege level
ext_o => ext_access, -- active external access
src_i => p_bus.src, -- access type (0: data, 1:instruction)
addr_i => p_bus.addr, -- address
rden_i => p_bus.re, -- read enable
wren_i => p_bus.we, -- write enable
ben_i => p_bus.ben, -- byte write enable
data_i => p_bus.wdata, -- data in
data_o => resp_bus(RESP_WISHBONE).rdata, -- data out
lock_i => p_bus.lock, -- exclusive access request
ack_o => resp_bus(RESP_WISHBONE).ack, -- transfer acknowledge
err_o => resp_bus(RESP_WISHBONE).err, -- transfer error
tmo_o => ext_timeout, -- transfer timeout
priv_i => p_bus.priv, -- current CPU privilege level
ext_o => ext_access, -- active external access
-- xip configuration --
xip_en_i => xip_enable, -- XIP module enabled
xip_page_i => xip_page, -- XIP memory page
-- wishbone interface --
wb_tag_o => wb_tag_o, -- request tag
wb_adr_o => wb_adr_o, -- address
wb_dat_i => wb_dat_i, -- read data
wb_dat_o => wb_dat_o, -- write data
wb_we_o => wb_we_o, -- read/write
wb_sel_o => wb_sel_o, -- byte enable
wb_stb_o => wb_stb_o, -- strobe
wb_cyc_o => wb_cyc_o, -- valid cycle
wb_lock_o => wb_lock_o, -- exclusive access request
wb_ack_i => wb_ack_i, -- transfer acknowledge
wb_err_i => wb_err_i -- transfer error
wb_tag_o => wb_tag_o, -- request tag
wb_adr_o => wb_adr_o, -- address
wb_dat_i => wb_dat_i, -- read data
wb_dat_o => wb_dat_o, -- write data
wb_we_o => wb_we_o, -- read/write
wb_sel_o => wb_sel_o, -- byte enable
wb_stb_o => wb_stb_o, -- strobe
wb_cyc_o => wb_cyc_o, -- valid cycle
wb_lock_o => wb_lock_o, -- exclusive access request
wb_ack_i => wb_ack_i, -- transfer acknowledge
wb_err_i => wb_err_i -- transfer error
);
end generate;
 
857,6 → 878,64
end generate;
 
 
-- Execute In Place Module (XIP) ----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_xip_inst_true:
if (IO_XIP_EN = true) generate
neorv32_xip_inst: neorv32_xip
port map (
-- global control --
clk_i => clk_i, -- global clock line
rstn_i => sys_rstn, -- global reset line, low-active
-- host access: control register access port --
ct_addr_i => p_bus.addr, -- address
ct_rden_i => io_rden, -- read enable
ct_wren_i => io_wren, -- write enable
ct_data_i => p_bus.wdata, -- data in
ct_data_o => resp_bus(RESP_XIP_CT).rdata, -- data out
ct_ack_o => resp_bus(RESP_XIP_CT).ack, -- transfer acknowledge
-- host access: instruction fetch access port (read-only) --
if_addr_i => p_bus.addr, -- address
if_rden_i => p_bus.re, -- read enable
if_data_o => resp_bus(RESP_XIP_IF).rdata, -- data out
if_ack_o => resp_bus(RESP_XIP_IF).ack, -- transfer acknowledge
-- status --
xip_en_o => xip_enable, -- XIP enable
xip_acc_o => xip_access, -- pending XIP access
xip_page_o => xip_page, -- XIP page
-- clock generator --
clkgen_en_o => xip_cg_en, -- enable clock generator
clkgen_i => clk_gen,
-- SPI device interface --
spi_csn_o => xip_csn_o, -- chip-select, low-active
spi_clk_o => xip_clk_o, -- serial clock
spi_data_i => xip_sdi_i, -- device data output
spi_data_o => xip_sdo_o -- controller data output
);
resp_bus(RESP_XIP_CT).err <= '0'; -- no access error possible
resp_bus(RESP_XIP_IF).err <= '0'; -- no access error possible
end generate;
 
neorv32_xip_inst_false:
if (IO_XIP_EN = false) generate
resp_bus(RESP_XIP_CT) <= resp_bus_entry_terminate_c;
resp_bus(RESP_XIP_IF) <= resp_bus_entry_terminate_c;
--
xip_enable <= '0';
xip_access <= '0';
xip_page <= (others => '0');
xip_cg_en <= '0';
xip_csn_o <= '1';
xip_clk_o <= '0';
xip_sdo_o <= '0';
end generate;
 
 
-- ****************************************************************************************************************************
-- IO/Peripheral Modules
-- ****************************************************************************************************************************
 
 
-- IO Access? -----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
io_acc <= '1' when (p_bus.addr(data_width_c-1 downto index_size_f(io_size_c)) = io_base_c(data_width_c-1 downto index_size_f(io_size_c))) else '0';
900,6 → 979,7
neorv32_cfs_inst_false:
if (IO_CFS_EN = false) generate
resp_bus(RESP_CFS) <= resp_bus_entry_terminate_c;
--
cfs_cg_en <= '0';
cfs_irq <= '0';
cfs_out_o <= (others => '0');
920,16 → 1000,17
data_i => p_bus.wdata, -- data in
data_o => resp_bus(RESP_GPIO).rdata, -- data out
ack_o => resp_bus(RESP_GPIO).ack, -- transfer acknowledge
err_o => resp_bus(RESP_GPIO).err, -- transfer error
-- parallel io --
gpio_o => gpio_o,
gpio_i => gpio_i
);
resp_bus(RESP_GPIO).err <= '0'; -- no access error possible
end generate;
 
neorv32_gpio_inst_false:
if (IO_GPIO_EN = false) generate
resp_bus(RESP_GPIO) <= resp_bus_entry_terminate_c;
--
gpio_o <= (others => '0');
end generate;
 
967,6 → 1048,7
neorv32_wdt_inst_false:
if (IO_WDT_EN = false) generate
resp_bus(RESP_WDT) <= resp_bus_entry_terminate_c;
--
wdt_irq <= '0';
wdt_rstn <= '1';
wdt_cg_en <= '0';
998,6 → 1080,7
neorv32_mtime_inst_false:
if (IO_MTIME_EN = false) generate
resp_bus(RESP_MTIME) <= resp_bus_entry_terminate_c;
--
mtime_time <= mtime_i; -- use external machine timer time signal
mtime_irq <= mtime_irq_i; -- use external machine timer interrupt
end generate;
1061,6 → 1144,7
neorv32_uart0_inst_false:
if (IO_UART0_EN = false) generate
resp_bus(RESP_UART0) <= resp_bus_entry_terminate_c;
--
uart0_txd_o <= '0';
uart0_rts_o <= '0';
uart0_cg_en <= '0';
1107,6 → 1191,7
neorv32_uart1_inst_false:
if (IO_UART1_EN = false) generate
resp_bus(RESP_UART1) <= resp_bus_entry_terminate_c;
--
uart1_txd_o <= '0';
uart1_rts_o <= '0';
uart1_cg_en <= '0';
1146,6 → 1231,7
neorv32_spi_inst_false:
if (IO_SPI_EN = false) generate
resp_bus(RESP_SPI) <= resp_bus_entry_terminate_c;
--
spi_sck_o <= '0';
spi_sdo_o <= '0';
spi_csn_o <= (others => '1'); -- CSn lines are low-active
1183,6 → 1269,7
neorv32_twi_inst_false:
if (IO_TWI_EN = false) generate
resp_bus(RESP_TWI) <= resp_bus_entry_terminate_c;
--
twi_sda_io <= 'Z';
twi_scl_io <= 'Z';
twi_cg_en <= '0';
1219,6 → 1306,7
neorv32_pwm_inst_false:
if (IO_PWM_NUM_CH = 0) generate
resp_bus(RESP_PWM) <= resp_bus_entry_terminate_c;
--
pwm_cg_en <= '0';
pwm_o <= (others => '0');
end generate;
1279,6 → 1367,7
neorv32_neoled_inst_false:
if (IO_NEOLED_EN = false) generate
resp_bus(RESP_NEOLED) <= resp_bus_entry_terminate_c;
--
neoled_cg_en <= '0';
neoled_irq <= '0';
neoled_o <= '0';
1323,6 → 1412,7
neorv32_slink_inst_false:
if (io_slink_en_c = false) generate
resp_bus(RESP_SLINK) <= resp_bus_entry_terminate_c;
--
slink_tx_irq <= '0';
slink_rx_irq <= '0';
slink_tx_dat_o <= (others => (others => '0'));
1361,6 → 1451,7
neorv32_xirq_inst_false:
if (XIRQ_NUM_CH = 0) generate
resp_bus(RESP_XIRQ) <= resp_bus_entry_terminate_c;
--
xirq_irq <= '0';
end generate;
 
1391,6 → 1482,7
neorv32_gptmr_inst_false:
if (IO_GPTMR_EN = false) generate
resp_bus(RESP_GPTMR) <= resp_bus_entry_terminate_c;
--
gptmr_cg_en <= '0';
gptmr_irq <= '0';
end generate;
1447,7 → 1539,8
IO_SLINK_EN => io_slink_en_c, -- implement stream link interface?
IO_NEOLED_EN => IO_NEOLED_EN, -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_XIRQ_NUM_CH => XIRQ_NUM_CH, -- number of external interrupt (XIRQ) channels to implement
IO_GPTMR_EN => IO_GPTMR_EN -- implement general purpose timer (GPTMR)?
IO_GPTMR_EN => IO_GPTMR_EN, -- implement general purpose timer (GPTMR)?
IO_XIP_EN => IO_XIP_EN -- implement execute in place module (XIP)?
)
port map (
-- host access --
1454,13 → 1547,13
clk_i => clk_i, -- global clock line
addr_i => p_bus.addr, -- address
rden_i => io_rden, -- read enable
wren_i => io_wren, -- write enable
data_o => resp_bus(RESP_SYSINFO).rdata, -- data out
ack_o => resp_bus(RESP_SYSINFO).ack -- transfer acknowledge
ack_o => resp_bus(RESP_SYSINFO).ack, -- transfer acknowledge
err_o => resp_bus(RESP_SYSINFO).err -- transfer error
);
 
resp_bus(RESP_SYSINFO).err <= '0'; -- no access error possible
 
 
-- **************************************************************************************************************************
-- On-Chip Debugger Complex
-- **************************************************************************************************************************
1502,6 → 1595,7
 
neorv32_debug_dm_false:
if (ON_CHIP_DEBUGGER_EN = false) generate
--
dmi.req_ready <= '0';
dmi.resp_valid <= '0';
dmi.resp_data <= (others => '0');
/neorv32/trunk/rtl/core/neorv32_wishbone.vhd
11,7 → 11,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
63,34 → 63,37
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active
-- host access --
src_i : in std_ulogic; -- access type (0: data, 1:instruction)
addr_i : in std_ulogic_vector(31 downto 0); -- address
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
ben_i : in std_ulogic_vector(03 downto 0); -- byte write enable
data_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
lock_i : in std_ulogic; -- exclusive access request
ack_o : out std_ulogic; -- transfer acknowledge
err_o : out std_ulogic; -- transfer error
tmo_o : out std_ulogic; -- transfer timeout
priv_i : in std_ulogic_vector(01 downto 0); -- current CPU privilege level
ext_o : out std_ulogic; -- active external access
src_i : in std_ulogic; -- access type (0: data, 1:instruction)
addr_i : in std_ulogic_vector(31 downto 0); -- address
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
ben_i : in std_ulogic_vector(03 downto 0); -- byte write enable
data_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
lock_i : in std_ulogic; -- exclusive access request
ack_o : out std_ulogic; -- transfer acknowledge
err_o : out std_ulogic; -- transfer error
tmo_o : out std_ulogic; -- transfer timeout
priv_i : in std_ulogic_vector(01 downto 0); -- current CPU privilege level
ext_o : out std_ulogic; -- active external access
-- xip configuration --
xip_en_i : in std_ulogic; -- XIP module enabled
xip_page_i : in std_ulogic_vector(03 downto 0); -- XIP memory page
-- wishbone interface --
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address
wb_dat_i : in std_ulogic_vector(31 downto 0); -- read data
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data
wb_we_o : out std_ulogic; -- read/write
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable
wb_stb_o : out std_ulogic; -- strobe
wb_cyc_o : out std_ulogic; -- valid cycle
wb_lock_o : out std_ulogic; -- exclusive access request
wb_ack_i : in std_ulogic; -- transfer acknowledge
wb_err_i : in std_ulogic -- transfer error
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address
wb_dat_i : in std_ulogic_vector(31 downto 0); -- read data
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data
wb_we_o : out std_ulogic; -- read/write
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable
wb_stb_o : out std_ulogic; -- strobe
wb_cyc_o : out std_ulogic; -- valid cycle
wb_lock_o : out std_ulogic; -- exclusive access request
wb_ack_i : in std_ulogic; -- transfer acknowledge
wb_err_i : in std_ulogic -- transfer error
);
end neorv32_wishbone;
 
103,6 → 106,7
signal int_imem_acc : std_ulogic;
signal int_dmem_acc : std_ulogic;
signal int_boot_acc : std_ulogic;
signal xip_acc : std_ulogic;
signal xbus_access : std_ulogic;
 
-- bus arbiter
160,8 → 164,10
int_dmem_acc <= '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 to processor-internal BOOTROM or IO devices? --
int_boot_acc <= '1' when (addr_i(31 downto 16) = boot_rom_base_c(31 downto 16)) else '0'; -- hacky!
-- XIP access? --
xip_acc <= '1' when (xip_en_i = '1') and (addr_i(31 downto 28) = xip_page_i) else '0';
-- actual external bus access? --
xbus_access <= (not int_imem_acc) and (not int_dmem_acc) and (not int_boot_acc);
xbus_access <= (not int_imem_acc) and (not int_dmem_acc) and (not int_boot_acc) and (not xip_acc);
 
 
-- Bus Arbiter -----------------------------------------------------------------------------
/neorv32/trunk/rtl/core/neorv32_xip.vhd
0,0 → 1,563
-- #################################################################################################
-- # << NEORV32 - Execute In Place (XIP) Module >> #
-- # ********************************************************************************************* #
-- # This module allows the CPU to execute code (and read constant data) directly from an SPI #
-- # flash memory. Two host ports are implemented: one for accessing the control and status #
-- # registers (mapped to the processor's IO space) and one for the actual instruction/data fetch. #
-- # The actual address space mapping of the "instruction/data interface" is done by programming #
-- # special control register bits. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 1. Redistributions of source code must retain the above copyright notice, this list of #
-- # conditions and the following disclaimer. #
-- # #
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
-- # conditions and the following disclaimer in the documentation and/or other materials #
-- # provided with the distribution. #
-- # #
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
-- # endorse or promote products derived from this software without specific prior written #
-- # permission. #
-- # #
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
-- # OF THE POSSIBILITY OF SUCH DAMAGE. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
 
entity neorv32_xip is
port (
-- global control --
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active
-- host access: control register access port --
ct_addr_i : in std_ulogic_vector(31 downto 0); -- address
ct_rden_i : in std_ulogic; -- read enable
ct_wren_i : in std_ulogic; -- write enable
ct_data_i : in std_ulogic_vector(31 downto 0); -- data in
ct_data_o : out std_ulogic_vector(31 downto 0); -- data out
ct_ack_o : out std_ulogic; -- transfer acknowledge
-- host access: instruction fetch access port (read-only) --
if_addr_i : in std_ulogic_vector(31 downto 0); -- address
if_rden_i : in std_ulogic; -- read enable
if_data_o : out std_ulogic_vector(31 downto 0); -- data out
if_ack_o : out std_ulogic; -- transfer acknowledge
-- status --
xip_en_o : out std_ulogic; -- XIP enable
xip_acc_o : out std_ulogic; -- pending XIP access
xip_page_o : out std_ulogic_vector(03 downto 0); -- XIP page
-- clock generator --
clkgen_en_o : out std_ulogic; -- enable clock generator
clkgen_i : in std_ulogic_vector(07 downto 0);
-- SPI device interface --
spi_csn_o : out std_ulogic; -- chip-select, low-active
spi_clk_o : out std_ulogic; -- serial clock
spi_data_i : in std_ulogic; -- device data output
spi_data_o : out std_ulogic -- controller data output
);
end neorv32_xip;
 
architecture neorv32_xip_rtl of neorv32_xip is
 
-- 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(xip_size_c); -- low address boundary bit
 
-- CT register access control --
signal ct_acc_en : std_ulogic; -- module access enable
signal ct_addr : std_ulogic_vector(31 downto 0); -- access address
signal ct_wren : std_ulogic; -- word write enable
signal ct_rden : std_ulogic; -- read enable
 
-- control register --
constant ctrl_enable_c : natural := 0; -- r/w: module enable
constant ctrl_spi_prsc0_c : natural := 1; -- r/w: SPI clock prescaler select - bit 0
constant ctrl_spi_prsc1_c : natural := 2; -- r/w: SPI clock prescaler select - bit 1
constant ctrl_spi_prsc2_c : natural := 3; -- r/w: SPI clock prescaler select - bit 2
constant ctrl_spi_cpol_c : natural := 4; -- r/w: SPI (idle) clock polarity
constant ctrl_spi_cpha_c : natural := 5; -- r/w: SPI clock phase
constant ctrl_spi_nbytes0_c : natural := 6; -- r/w: SPI number of bytes in transmission (1..9) - bit 0
constant ctrl_spi_nbytes3_c : natural := 9; -- r/w: SPI number of bytes in transmission (1..9) - bit 3
constant ctrl_xip_enable_c : natural := 10; -- r/w: XIP access mode enable
constant ctrl_xip_abytes0_c : natural := 11; -- r/w: XIP number of address bytes (0=1,1=2,2=3,3=4) - bit 0
constant ctrl_xip_abytes1_c : natural := 12; -- r/w: XIP number of address bytes (0=1,1=2,2=3,3=4) - bit 1
constant ctrl_rd_cmd0_c : natural := 13; -- r/w: SPI flash read command - bit 0
constant ctrl_rd_cmd7_c : natural := 20; -- r/w: SPI flash read command - bit 7
constant ctrl_page0_c : natural := 21; -- r/w: XIP memory page - bit 0
constant ctrl_page3_c : natural := 24; -- r/w: XIP memory page - bit 3
constant ctrl_spi_csen_c : natural := 25; -- r/w: SPI chip-select enabled
constant ctrl_highspeed_c : natural := 26; -- r/w: SPI high-speed mode enable (ignoring ctrl_spi_prsc)
--
constant ctrl_phy_busy_c : natural := 30; -- r/-: SPI PHY is busy when set
constant ctrl_xip_busy_c : natural := 31; -- r/-: XIP access in progress
--
signal ctrl : std_ulogic_vector(26 downto 0);
 
-- Direct SPI access registers --
signal spi_data_lo : std_ulogic_vector(31 downto 0);
signal spi_data_hi : std_ulogic_vector(31 downto 0); -- write-only!
signal spi_trigger : std_ulogic; -- trigger direct SPI operation
 
-- XIP access address --
signal xip_addr : std_ulogic_vector(31 downto 0);
 
-- SPI access fetch arbiter --
type arbiter_state_t is (S_DIRECT, S_IDLE, S_TRIG, S_BUSY);
type arbiter_t is record
state : arbiter_state_t;
state_nxt : arbiter_state_t;
addr : std_ulogic_vector(31 downto 0);
busy : std_ulogic;
end record;
signal arbiter : arbiter_t;
 
-- SPI clock --
signal spi_clk_en : std_ulogic;
 
-- Component: SPI PHY --
component neorv32_xip_phy
port (
-- global control --
clk_i : in std_ulogic; -- clock
spi_clk_en_i : in std_ulogic; -- pre-scaled SPI clock-enable
-- operation configuration --
cf_enable_i : in std_ulogic; -- module enable (reset if low)
cf_cpha_i : in std_ulogic; -- clock phase
cf_cpol_i : in std_ulogic; -- clock idle polarity
-- operation control --
op_start_i : in std_ulogic; -- trigger new transmission
op_csen_i : in std_ulogic; -- actually enabled device for transmission
op_busy_o : out std_ulogic; -- transmission in progress when set
op_nbytes_i : in std_ulogic_vector(03 downto 0); -- actual number of bytes to transmit (1..9)
op_wdata_i : in std_ulogic_vector(71 downto 0); -- write data
op_rdata_o : out std_ulogic_vector(31 downto 0); -- read data
-- SPI interface --
spi_csn_o : out std_ulogic;
spi_clk_o : out std_ulogic;
spi_data_i : in std_ulogic;
spi_data_o : out std_ulogic
);
end component;
 
-- PHY interface --
type phy_if_t is record
start : std_ulogic; -- trigger new transmission
busy : std_ulogic; -- transmission in progress when set
wdata : std_ulogic_vector(71 downto 0); -- write data
rdata : std_ulogic_vector(31 downto 0); -- read data
end record;
signal phy_if : phy_if_t;
 
begin
 
-- Access Control (IO/CTRL port) ----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
ct_acc_en <= '1' when (ct_addr_i(hi_abb_c downto lo_abb_c) = xip_base_c(hi_abb_c downto lo_abb_c)) else '0';
ct_addr <= xip_base_c(31 downto lo_abb_c) & ct_addr_i(lo_abb_c-1 downto 2) & "00"; -- word aligned
ct_wren <= ct_acc_en and ct_wren_i;
ct_rden <= ct_acc_en and ct_rden_i;
 
 
-- Control Read/Write Access --------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
ctrl_rw_access : process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
ctrl <= (others => '-');
ctrl(ctrl_enable_c) <= '0'; -- required
ctrl(ctrl_xip_enable_c) <= '0'; -- required
spi_data_lo <= (others => '-');
spi_data_hi <= (others => '-');
spi_trigger <= '-';
--
ct_data_o <= (others => '-');
ct_ack_o <= '-';
elsif rising_edge(clk_i) then
-- access acknowledge --
ct_ack_o <= ct_wren or ct_rden;
 
-- defaults --
spi_trigger <= '0';
 
-- write access --
if (ct_wren = '1') then -- only full-word writes!
 
-- control register --
if (ct_addr = xip_ctrl_addr_c) then
ctrl(ctrl_enable_c) <= ct_data_i(ctrl_enable_c);
ctrl(ctrl_spi_prsc2_c downto ctrl_spi_prsc0_c) <= ct_data_i(ctrl_spi_prsc2_c downto ctrl_spi_prsc0_c);
ctrl(ctrl_spi_cpol_c) <= ct_data_i(ctrl_spi_cpol_c);
ctrl(ctrl_spi_cpha_c) <= ct_data_i(ctrl_spi_cpha_c);
ctrl(ctrl_spi_nbytes3_c downto ctrl_spi_nbytes0_c) <= ct_data_i(ctrl_spi_nbytes3_c downto ctrl_spi_nbytes0_c);
ctrl(ctrl_xip_enable_c) <= ct_data_i(ctrl_xip_enable_c);
ctrl(ctrl_xip_abytes1_c downto ctrl_xip_abytes0_c) <= ct_data_i(ctrl_xip_abytes1_c downto ctrl_xip_abytes0_c);
ctrl(ctrl_rd_cmd7_c downto ctrl_rd_cmd0_c) <= ct_data_i(ctrl_rd_cmd7_c downto ctrl_rd_cmd0_c);
ctrl(ctrl_page3_c downto ctrl_page0_c) <= ct_data_i(ctrl_page3_c downto ctrl_page0_c);
ctrl(ctrl_spi_csen_c) <= ct_data_i(ctrl_spi_csen_c);
ctrl(ctrl_highspeed_c) <= ct_data_i(ctrl_highspeed_c);
end if;
 
-- SPI direct data access register lo --
if (ct_addr = xip_data_lo_addr_c) then
spi_data_lo <= ct_data_i;
end if;
 
-- SPI direct data access register hi --
if (ct_addr = xip_data_hi_addr_c) then
spi_data_hi <= ct_data_i;
spi_trigger <= '1'; -- trigger direct SPI transaction
end if;
end if;
 
-- read access --
ct_data_o <= (others => '0');
if (ct_rden = '1') then
case ct_addr(3 downto 2) is
when "00" => -- 'xip_ctrl_addr_c' - control register
ct_data_o(ctrl_enable_c) <= ctrl(ctrl_enable_c);
ct_data_o(ctrl_spi_prsc2_c downto ctrl_spi_prsc0_c) <= ctrl(ctrl_spi_prsc2_c downto ctrl_spi_prsc0_c);
ct_data_o(ctrl_spi_cpol_c) <= ctrl(ctrl_spi_cpol_c);
ct_data_o(ctrl_spi_cpha_c) <= ctrl(ctrl_spi_cpha_c);
ct_data_o(ctrl_spi_nbytes3_c downto ctrl_spi_nbytes0_c) <= ctrl(ctrl_spi_nbytes3_c downto ctrl_spi_nbytes0_c);
ct_data_o(ctrl_xip_enable_c) <= ctrl(ctrl_xip_enable_c);
ct_data_o(ctrl_xip_abytes1_c downto ctrl_xip_abytes0_c) <= ctrl(ctrl_xip_abytes1_c downto ctrl_xip_abytes0_c);
ct_data_o(ctrl_rd_cmd7_c downto ctrl_rd_cmd0_c) <= ctrl(ctrl_rd_cmd7_c downto ctrl_rd_cmd0_c);
ct_data_o(ctrl_page3_c downto ctrl_page0_c) <= ctrl(ctrl_page3_c downto ctrl_page0_c);
ct_data_o(ctrl_spi_csen_c) <= ctrl(ctrl_spi_csen_c);
ct_data_o(ctrl_highspeed_c) <= ctrl(ctrl_highspeed_c);
--
ct_data_o(ctrl_phy_busy_c) <= phy_if.busy;
ct_data_o(ctrl_xip_busy_c) <= arbiter.busy;
when "10" => -- 'xip_data_lo_addr_c' - SPI direct data access register lo
ct_data_o <= phy_if.rdata;
when others => -- unavailable (not implemented or write-only)
ct_data_o <= (others => '0');
end case;
end if;
end if;
end process ctrl_rw_access;
 
-- XIP enabled --
xip_en_o <= ctrl(ctrl_enable_c);
 
-- XIP page output --
xip_page_o <= ctrl(ctrl_page3_c downto ctrl_page0_c);
 
 
-- XIP Address Computation Logic ----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
xip_access_logic: process(arbiter.addr, ctrl)
variable tmp_v : std_ulogic_vector(31 downto 0);
begin
tmp_v(31 downto 28) := "0000";
tmp_v(27 downto 00) := arbiter.addr(27 downto 00);
case ctrl(ctrl_xip_abytes1_c downto ctrl_xip_abytes0_c) is -- shift address bits to be MSB-aligned
when "00" => xip_addr <= tmp_v(07 downto 0) & x"000000"; -- 1 address byte
when "01" => xip_addr <= tmp_v(15 downto 0) & x"0000"; -- 2 address bytes
when "10" => xip_addr <= tmp_v(23 downto 0) & x"00"; -- 3 address bytes
when others => xip_addr <= tmp_v(31 downto 0); -- 4 address bytes
end case;
end process xip_access_logic;
 
 
-- SPI Access Arbiter ---------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
arbiter_sync: process(clk_i)
begin
if rising_edge(clk_i) then
if (ctrl(ctrl_enable_c) = '0') or (ctrl(ctrl_xip_enable_c) = '0') then -- sync reset
arbiter.state <= S_DIRECT;
else
arbiter.state <= arbiter.state_nxt;
end if;
arbiter.addr <= if_addr_i; -- buffer address (reducing fan-out on CPU's address net)
end if;
end process arbiter_sync;
 
 
-- FSM - combinatorial part --
arbiter_comb: process(arbiter, ctrl, xip_addr, phy_if, if_rden_i, if_addr_i, spi_data_hi, spi_data_lo, spi_trigger)
begin
-- arbiter defaults --
arbiter.state_nxt <= arbiter.state;
 
-- bus interface defaults --
if_data_o <= (others => '0');
if_ack_o <= '0';
 
-- SPI PHY interface defaults --
phy_if.start <= '0';
phy_if.wdata <= ctrl(ctrl_rd_cmd7_c downto ctrl_rd_cmd0_c) & xip_addr & x"00000000"; -- MSB-aligned: CMD + address + 32-bit zero data
 
-- fsm --
case arbiter.state is
 
when S_DIRECT => -- XIP access disabled: allow direct SPI access
-- ------------------------------------------------------------
phy_if.wdata <= spi_data_hi & spi_data_lo & x"00"; -- MSB-aligned data
phy_if.start <= spi_trigger;
arbiter.state_nxt <= S_IDLE;
 
when S_IDLE => -- XIP: wait for new bus request
-- ------------------------------------------------------------
if (if_rden_i = '1') and (if_addr_i(31 downto 28) = ctrl(ctrl_page3_c downto ctrl_page0_c)) then
arbiter.state_nxt <= S_TRIG;
end if;
 
when S_TRIG => -- XIP: trigger flash read
-- ------------------------------------------------------------
phy_if.start <= '1';
arbiter.state_nxt <= S_BUSY;
 
when S_BUSY => -- XIP: wait for PHY to complete operation
-- ------------------------------------------------------------
if (phy_if.busy = '0') then
if_data_o <= phy_if.rdata;
if_ack_o <= '1';
arbiter.state_nxt <= S_IDLE;
end if;
 
when others => -- undefined
-- ------------------------------------------------------------
arbiter.state_nxt <= S_IDLE;
 
end case;
end process arbiter_comb;
 
-- arbiter status --
arbiter.busy <= '1' when (arbiter.state = S_TRIG) or (arbiter.state = S_BUSY) else '0'; -- actual XIP access in progress
 
-- status output --
xip_acc_o <= arbiter.busy;
 
 
-- SPI Clock Generator --------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- enable clock generator --
clkgen_en_o <= ctrl(ctrl_enable_c);
 
-- clock select --
spi_clk_en <= clkgen_i(to_integer(unsigned(ctrl(ctrl_spi_prsc2_c downto ctrl_spi_prsc0_c)))) or ctrl(ctrl_highspeed_c);
 
 
-- SPI Physical Interface -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_xip_phy_inst: neorv32_xip_phy
port map (
-- global control --
clk_i => clk_i,
spi_clk_en_i => spi_clk_en,
-- operation configuration --
cf_enable_i => ctrl(ctrl_enable_c), -- module enable (reset if low)
cf_cpha_i => ctrl(ctrl_spi_cpha_c), -- clock phase
cf_cpol_i => ctrl(ctrl_spi_cpol_c), -- clock idle polarity
-- operation control --
op_start_i => phy_if.start, -- trigger new transmission
op_csen_i => ctrl(ctrl_spi_csen_c), -- actually enabled device for transmission
op_busy_o => phy_if.busy, -- transmission in progress when set
op_nbytes_i => ctrl(ctrl_spi_nbytes3_c downto ctrl_spi_nbytes0_c), -- actual number of bytes to transmit
op_wdata_i => phy_if.wdata, -- write data
op_rdata_o => phy_if.rdata, -- read data
-- SPI interface --
spi_csn_o => spi_csn_o,
spi_clk_o => spi_clk_o,
spi_data_i => spi_data_i,
spi_data_o => spi_data_o
);
 
 
end neorv32_xip_rtl;
 
 
-- ############################################################################################################################
-- ############################################################################################################################
 
 
-- #################################################################################################
-- # << NEORV32 - XIP Module - SPI Physical Interface >> #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 1. Redistributions of source code must retain the above copyright notice, this list of #
-- # conditions and the following disclaimer. #
-- # #
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
-- # conditions and the following disclaimer in the documentation and/or other materials #
-- # provided with the distribution. #
-- # #
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
-- # endorse or promote products derived from this software without specific prior written #
-- # permission. #
-- # #
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
-- # OF THE POSSIBILITY OF SUCH DAMAGE. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
 
entity neorv32_xip_phy is
port (
-- global control --
clk_i : in std_ulogic; -- clock
spi_clk_en_i : in std_ulogic; -- pre-scaled SPI clock-enable
-- operation configuration --
cf_enable_i : in std_ulogic; -- module enable (reset if low)
cf_cpha_i : in std_ulogic; -- clock phase
cf_cpol_i : in std_ulogic; -- clock idle polarity
-- operation control --
op_start_i : in std_ulogic; -- trigger new transmission
op_csen_i : in std_ulogic; -- actually enabled device for transmission
op_busy_o : out std_ulogic; -- transmission in progress when set
op_nbytes_i : in std_ulogic_vector(03 downto 0); -- actual number of bytes to transmit (1..9)
op_wdata_i : in std_ulogic_vector(71 downto 0); -- write data
op_rdata_o : out std_ulogic_vector(31 downto 0); -- read data
-- SPI interface --
spi_csn_o : out std_ulogic;
spi_clk_o : out std_ulogic;
spi_data_i : in std_ulogic;
spi_data_o : out std_ulogic
);
end neorv32_xip_phy;
 
architecture neorv32_xip_phy_rtl of neorv32_xip_phy is
 
-- controller --
type ctrl_state_t is (S_IDLE, S_START, S_RTX_A, S_RTX_B, S_DONE);
type ctrl_t is record
state : ctrl_state_t;
sreg : std_ulogic_vector(71 downto 0); -- only the lowest 32-bit are used as RX data
bitcnt : std_ulogic_vector(06 downto 0);
di_sync : std_ulogic;
csen : std_ulogic;
end record;
signal ctrl : ctrl_t;
 
begin
 
-- Serial Interface Control Unit ----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
control_unit: process(clk_i)
begin
if rising_edge(clk_i) then
if (cf_enable_i = '0') then
spi_clk_o <= '0';
spi_csn_o <= '1';
--
ctrl.state <= S_IDLE;
ctrl.csen <= '-';
ctrl.sreg <= (others => '-');
ctrl.bitcnt <= (others => '-');
ctrl.di_sync <= '-';
else
-- defaults --
spi_clk_o <= cf_cpol_i;
spi_csn_o <= '1'; -- de-selected by default
ctrl.di_sync <= spi_data_i;
 
-- fsm --
case ctrl.state is
 
when S_IDLE => -- wait for new transmission trigger
-- ------------------------------------------------------------
ctrl.bitcnt <= op_nbytes_i & "000"; -- number of bytes
ctrl.csen <= op_csen_i;
if (op_start_i = '1') then
ctrl.sreg <= op_wdata_i;
ctrl.state <= S_START;
end if;
 
when S_START => -- sync start of transmission
-- ------------------------------------------------------------
spi_csn_o <= not ctrl.csen;
if (spi_clk_en_i = '1') then
ctrl.state <= S_RTX_A;
end if;
 
when S_RTX_A => -- first half of bit transmission
-- ------------------------------------------------------------
spi_csn_o <= not ctrl.csen;
spi_clk_o <= cf_cpha_i xor cf_cpol_i;
if (spi_clk_en_i = '1') then
ctrl.bitcnt <= std_ulogic_vector(unsigned(ctrl.bitcnt) - 1);
ctrl.state <= S_RTX_B;
end if;
 
when S_RTX_B => -- second half of bit transmission
-- ------------------------------------------------------------
spi_csn_o <= not ctrl.csen;
spi_clk_o <= not (cf_cpha_i xor cf_cpol_i);
if (spi_clk_en_i = '1') then
ctrl.sreg <= ctrl.sreg(ctrl.sreg'left-1 downto 0) & ctrl.di_sync;
if (or_reduce_f(ctrl.bitcnt) = '0') then -- all bits transferred?
ctrl.state <= S_DONE; -- transmission done
else
ctrl.state <= S_RTX_A; -- next bit
end if;
end if;
 
when S_DONE => -- transmission done
-- ------------------------------------------------------------
spi_csn_o <= not ctrl.csen;
if (spi_clk_en_i = '1') then
ctrl.state <= S_IDLE;
end if;
 
when others => -- undefined
-- ------------------------------------------------------------
ctrl.state <= S_IDLE;
 
end case;
end if;
end if;
end process control_unit;
 
-- serial unit busy --
op_busy_o <= '0' when (ctrl.state = S_IDLE) else '1';
 
-- serial data output --
spi_data_o <= ctrl.sreg(ctrl.sreg'left);
 
-- RX data --
op_rdata_o <= ctrl.sreg(31 downto 0);
 
 
end neorv32_xip_phy_rtl;
/neorv32/trunk/rtl/core/neorv32_xirq.vhd
62,7 → 62,7
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic; -- transfer acknowledge
-- external interrupt lines --
xirq_i : in std_ulogic_vector(XIRQ_NUM_CH-1 downto 0);
xirq_i : in std_ulogic_vector(31 downto 0);
-- CPU interrupt --
cpu_irq_o : out std_ulogic
);
155,7 → 155,7
irq_trigger: process(clk_i)
begin
if rising_edge(clk_i) then
irq_sync <= xirq_i;
irq_sync <= xirq_i(XIRQ_NUM_CH-1 downto 0);
irq_sync2 <= irq_sync;
end if;
end process irq_trigger;
/neorv32/trunk/rtl/processor_templates/neorv32_ProcessorTop_Minimal.vhd
96,8 → 96,18
 
architecture neorv32_ProcessorTop_Minimal_rtl of neorv32_ProcessorTop_Minimal is
 
-- internal IO connection --
signal con_pwm_o : std_ulogic_vector(59 downto 0);
 
begin
 
-- IO Connection --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
 
-- PWM --
pwm_o <= con_pwm_o(IO_PWM_NUM_CH-1 downto 0);
 
 
-- The core of the problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_inst: entity neorv32.neorv32_top
224,7 → 234,7
twi_scl_io => open, -- twi serial clock line
 
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o => pwm_o, -- pwm channels
pwm_o => con_pwm_o, -- pwm channels
 
-- Custom Functions Subsystem IO --
cfs_in_i => (others => '0'), -- custom CFS inputs conduit
/neorv32/trunk/rtl/processor_templates/neorv32_ProcessorTop_MinimalBoot.vhd
110,6 → 110,7
 
-- internal IO connection --
signal con_gpio_o : std_ulogic_vector(63 downto 0);
signal con_pwm_o : std_ulogic_vector(59 downto 0);
 
begin
 
119,6 → 120,10
-- GPIO --
gpio_o <= con_gpio_o(3 downto 0);
 
-- PWM --
pwm_o <= con_pwm_o(IO_PWM_NUM_CH-1 downto 0);
 
 
-- The core of the problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_inst: entity neorv32.neorv32_top
245,7 → 250,7
twi_scl_io => open, -- twi serial clock line
 
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o => pwm_o, -- pwm channels
pwm_o => con_pwm_o, -- pwm channels
 
-- Custom Functions Subsystem IO --
cfs_in_i => (others => '0'), -- custom CFS inputs conduit
/neorv32/trunk/rtl/processor_templates/neorv32_ProcessorTop_UP5KDemo.vhd
132,6 → 132,7
-- internal IO connection --
signal con_gpio_o : std_ulogic_vector(63 downto 0);
signal con_gpio_i : std_ulogic_vector(63 downto 0);
signal con_pwm_o : std_ulogic_vector(59 downto 0);
signal con_spi_sck : std_ulogic;
signal con_spi_sdi : std_ulogic;
signal con_spi_sdo : std_ulogic;
159,6 → 160,10
con_gpio_i(03 downto 0) <= gpio_i;
con_gpio_i(63 downto 4) <= (others => '0');
 
-- PWM --
pwm_o <= con_pwm_o(IO_PWM_NUM_CH-1 downto 0);
 
 
-- The core of the problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_inst: entity neorv32.neorv32_top
285,7 → 290,7
twi_scl_io => twi_scl_io, -- twi serial clock line
 
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o => pwm_o, -- pwm channels
pwm_o => con_pwm_o, -- pwm channels
 
-- Custom Functions Subsystem IO --
cfs_in_i => (others => '0'), -- custom CFS inputs conduit
/neorv32/trunk/rtl/system_integration/neorv32_ProcessorTop_stdlogic.vhd
3,7 → 3,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
114,7 → 114,8
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits
IO_NEOLED_EN : boolean := true; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_GPTMR_EN : boolean := false -- implement general purpose timer (GPTMR)?
IO_GPTMR_EN : boolean := false; -- implement general purpose timer (GPTMR)?
IO_XIP_EN : boolean := false -- implement execute in place module (XIP)?
);
port (
-- Global control --
141,6 → 142,11
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o : out std_logic; -- indicates an executed FENCE operation
fencei_o : out std_logic; -- indicates an executed FENCEI operation
-- XIP (execute in place via SPI) signals (available if IO_XIP_EN = true) --
xip_csn_o : out std_logic; -- chip-select, low-active
xip_clk_o : out std_logic; -- serial clock
xip_sdi_i : in std_logic := 'L'; -- device data input
xip_sdo_o : out std_logic; -- controller data output
-- TX stream interfaces (available if SLINK_NUM_TX > 0) --
slink_tx_dat_o : out sdata_8x32r_t; -- output data
slink_tx_val_o : out std_logic_vector(7 downto 0); -- valid output
171,7 → 177,7
twi_sda_io : inout std_logic; -- twi serial data line
twi_scl_io : inout std_logic; -- twi serial clock line
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o : out std_logic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels
pwm_o : out std_logic_vector(59 downto 0); -- pwm channels
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
cfs_in_i : in std_logic_vector(IO_CFS_IN_SIZE-1 downto 0); -- custom inputs
cfs_out_o : out std_logic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom outputs
181,7 → 187,7
mtime_i : in std_logic_vector(63 downto 0) := (others => '0'); -- current system time from ext. MTIME (if IO_MTIME_EN = false)
mtime_o : out std_logic_vector(63 downto 0); -- current system time from int. MTIME (if IO_MTIME_EN = true)
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i : in std_logic_vector(XIRQ_NUM_CH-1 downto 0) := (others => '0'); -- IRQ channels
xirq_i : in std_logic_vector(31 downto 0) := (others => '0'); -- IRQ channels
-- CPU Interrupts --
mtime_irq_i : in std_logic := '0'; -- machine timer interrupt, available if IO_MTIME_EN = false
msw_irq_i : in std_logic := '0'; -- machine software interrupt
220,6 → 226,11
signal fence_o_int : std_ulogic;
signal fencei_o_int : std_ulogic;
--
signal xip_csn_o_int : std_ulogic;
signal xip_clk_o_int : std_ulogic;
signal xip_sdi_i_int : std_ulogic;
signal xip_sdo_o_int : std_ulogic;
--
signal slink_tx_dat_o_int : sdata_8x32_t;
signal slink_tx_val_o_int : std_logic_vector(7 downto 0);
signal slink_tx_rdy_i_int : std_logic_vector(7 downto 0);
245,7 → 256,7
signal spi_sdi_i_int : std_ulogic;
signal spi_csn_o_int : std_ulogic_vector(07 downto 0);
--
signal pwm_o_int : std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0);
signal pwm_o_int : std_ulogic_vector(59 downto 0);
--
signal cfs_in_i_int : std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0);
signal cfs_out_o_int : std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0);
255,7 → 266,7
signal mtime_i_int : std_ulogic_vector(63 downto 0);
signal mtime_o_int : std_ulogic_vector(63 downto 0);
--
signal xirq_i_int : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0);
signal xirq_i_int : std_ulogic_vector(31 downto 0);
--
signal mtime_irq_i_int : std_ulogic;
signal msw_irq_i_int : std_ulogic;
340,7 → 351,8
IO_CFS_IN_SIZE => IO_CFS_IN_SIZE, -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE => IO_CFS_OUT_SIZE, -- size of CFS output conduit in bits
IO_NEOLED_EN => IO_NEOLED_EN, -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_GPTMR_EN => IO_GPTMR_EN -- implement general purpose timer (GPTMR)?
IO_GPTMR_EN => IO_GPTMR_EN, -- implement general purpose timer (GPTMR)?
IO_XIP_EN => IO_XIP_EN -- implement execute in place module (XIP)?
)
port map (
-- Global control --
367,6 → 379,11
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o => fence_o_int, -- indicates an executed FENCE operation
fencei_o => fencei_o_int, -- indicates an executed FENCEI operation
-- XIP (execute in place via SPI) signals (available if IO_XIP_EN = true) --
xip_csn_o => xip_csn_o_int, -- chip-select, low-active
xip_clk_o => xip_clk_o_int, -- serial clock
xip_sdi_i => xip_sdi_i_int, -- device data input
xip_sdo_o => xip_sdo_o_int, -- controller data output
-- TX stream interfaces (available if SLINK_NUM_TX > 0) --
slink_tx_dat_o => slink_tx_dat_o_int, -- output data
slink_tx_val_o => slink_tx_val_o_int, -- valid output
439,6 → 456,11
fence_o <= std_logic(fence_o_int);
fencei_o <= std_logic(fencei_o_int);
 
xip_csn_o <= std_logic(xip_csn_o_int);
xip_clk_o <= std_logic(xip_clk_o_int);
xip_sdi_i_int <= std_ulogic(xip_sdi_i);
xip_sdo_o <= std_logic(xip_sdo_o_int);
 
slink_tx_val_o <= std_logic_vector(slink_tx_val_o_int);
slink_tx_rdy_i_int <= std_ulogic_vector(slink_tx_rdy_i);
slink_rx_val_i_int <= std_ulogic_vector(slink_rx_val_i);
/neorv32/trunk/rtl/system_integration/neorv32_SystemTop_AvalonMM.vhd
6,7 → 6,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
125,7 → 125,8
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits
IO_NEOLED_EN : boolean := false; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_NEOLED_TX_FIFO : natural := 1; -- NEOLED TX FIFO depth, 1..32k, has to be a power of two
IO_GPTMR_EN : boolean := false -- implement general purpose timer (GPTMR)?
IO_GPTMR_EN : boolean := false; -- implement general purpose timer (GPTMR)?
IO_XIP_EN : boolean := false -- implement execute in place module (XIP)?
);
port (
-- Global control --
142,16 → 143,22
-- AvalonMM interface
read_o : out std_logic;
write_o : out std_logic;
waitrequest_i : in std_logic := '0';
waitrequest_i : in std_logic := '0';
byteenable_o : out std_logic_vector(3 downto 0);
address_o : out std_logic_vector(31 downto 0);
writedata_o : out std_logic_vector(31 downto 0);
readdata_i : in std_logic_vector(31 downto 0) := (others => '0');
readdata_i : in std_logic_vector(31 downto 0) := (others => '0');
 
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o : out std_ulogic; -- indicates an executed FENCE operation
fencei_o : out std_ulogic; -- indicates an executed FENCEI operation
 
-- XIP (execute in place via SPI) signals (available if IO_XIP_EN = true) --
xip_csn_o : out std_ulogic; -- chip-select, low-active
xip_clk_o : out std_ulogic; -- serial clock
xip_sdi_i : in std_ulogic := 'L'; -- device data input
xip_sdo_o : out std_ulogic; -- controller data output
 
-- TX stream interfaces (available if SLINK_NUM_TX > 0) --
slink_tx_dat_o : out sdata_8x32_t; -- output data
slink_tx_val_o : out std_ulogic_vector(7 downto 0); -- valid output
189,7 → 196,7
twi_scl_io : inout std_logic := 'U'; -- twi serial clock line
 
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels
pwm_o : out std_ulogic_vector(59 downto 0); -- pwm channels
 
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
cfs_in_i : in std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0) := (others => 'U'); -- custom CFS inputs conduit
203,7 → 210,7
mtime_o : out std_ulogic_vector(63 downto 0); -- current system time from int. MTIME (if IO_MTIME_EN = true)
 
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i : in std_ulogic_vector(XIRQ_NUM_CH-1 downto 0) := (others => 'L'); -- IRQ channels
xirq_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); -- IRQ channels
 
-- CPU interrupts --
mtime_irq_i : in std_ulogic := 'L'; -- machine timer interrupt, available if IO_MTIME_EN = false
319,7 → 326,8
IO_CFS_OUT_SIZE => IO_CFS_OUT_SIZE,
IO_NEOLED_EN => IO_NEOLED_EN,
IO_NEOLED_TX_FIFO => IO_NEOLED_TX_FIFO,
IO_GPTMR_EN => IO_GPTMR_EN
IO_GPTMR_EN => IO_GPTMR_EN,
IO_XIP_EN => IO_XIP_EN
)
port map (
-- Global control --
350,6 → 358,12
fence_o => fence_o,
fencei_o => fencei_o,
 
-- XIP (execute in place via SPI) signals (available if IO_XIP_EN = true) --
xip_csn_o => xip_csn_o,
xip_clk_o => xip_clk_o,
xip_sdi_i => xip_sdi_i,
xip_sdo_o => xip_sdo_o,
 
-- TX stream interfaces (available if SLINK_NUM_TX > 0) --
slink_tx_dat_o => slink_tx_dat_o,
slink_tx_val_o => slink_tx_val_o,
/neorv32/trunk/rtl/system_integration/neorv32_SystemTop_axi4lite.vhd
6,7 → 6,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
110,7 → 110,8
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits
IO_NEOLED_EN : boolean := true; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_NEOLED_TX_FIFO : natural := 1; -- NEOLED TX FIFO depth, 1..32k, has to be a power of two
IO_GPTMR_EN : boolean := false -- implement general purpose timer (GPTMR)?
IO_GPTMR_EN : boolean := false; -- implement general purpose timer (GPTMR)?
IO_XIP_EN : boolean := false -- implement execute in place module (XIP)?
);
port (
-- ------------------------------------------------------------
154,6 → 155,11
-- ------------------------------------------------------------
-- Processor IO --
-- ------------------------------------------------------------
-- XIP (execute in place via SPI) signals (available if IO_XIP_EN = true) --
xip_csn_o : out std_logic; -- chip-select, low-active
xip_clk_o : out std_logic; -- serial clock
xip_sdi_i : in std_logic := 'L'; -- device data input
xip_sdo_o : out std_logic; -- controller data output
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o : out std_logic_vector(63 downto 0); -- parallel output
gpio_i : in std_logic_vector(63 downto 0) := (others => '0'); -- parallel input
176,7 → 182,7
twi_sda_io : inout std_logic; -- twi serial data line
twi_scl_io : inout std_logic; -- twi serial clock line
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o : out std_logic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels
pwm_o : out std_logic_vector(59 downto 0); -- pwm channels
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
cfs_in_i : in std_logic_vector(IO_CFS_IN_SIZE-1 downto 0); -- custom inputs
cfs_out_o : out std_logic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom outputs
183,7 → 189,7
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
neoled_o : out std_logic; -- async serial data line
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i : in std_logic_vector(XIRQ_NUM_CH-1 downto 0) := (others => '0'); -- IRQ channels
xirq_i : in std_logic_vector(31 downto 0) := (others => '0'); -- IRQ channels
-- CPU Interrupts --
msw_irq_i : in std_logic := '0'; -- machine software interrupt
mext_irq_i : in std_logic := '0' -- machine external interrupt
206,6 → 212,11
signal jtag_tdo_o_int :std_ulogic;
signal jtag_tms_i_int :std_ulogic;
--
signal xip_csn_o_int : std_ulogic;
signal xip_clk_o_int : std_ulogic;
signal xip_sdi_i_int : std_ulogic;
signal xip_sdo_o_int : std_ulogic;
--
signal gpio_o_int : std_ulogic_vector(63 downto 0);
signal gpio_i_int : std_ulogic_vector(63 downto 0);
--
224,7 → 235,7
signal spi_sdi_i_int : std_ulogic;
signal spi_csn_o_int : std_ulogic_vector(07 downto 0);
--
signal pwm_o_int : std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0);
signal pwm_o_int : std_ulogic_vector(59 downto 0);
--
signal cfs_in_i_int : std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0);
signal cfs_out_o_int : std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0);
231,7 → 242,7
--
signal neoled_o_int : std_ulogic;
--
signal xirq_i_int : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0);
signal xirq_i_int : std_ulogic_vector(31 downto 0);
--
signal msw_irq_i_int : std_ulogic;
signal mext_irq_i_int : std_ulogic;
343,7 → 354,8
IO_CFS_OUT_SIZE => IO_CFS_OUT_SIZE, -- size of CFS output conduit in bits
IO_NEOLED_EN => IO_NEOLED_EN, -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_NEOLED_TX_FIFO => IO_NEOLED_TX_FIFO, -- NEOLED TX FIFO depth, 1..32k, has to be a power of two
IO_GPTMR_EN => IO_GPTMR_EN -- implement general purpose timer (GPTMR)?
IO_GPTMR_EN => IO_GPTMR_EN, -- implement general purpose timer (GPTMR)?
IO_XIP_EN => IO_XIP_EN -- implement execute in place module (XIP)?
)
port map (
-- Global control --
370,6 → 382,11
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o => open, -- indicates an executed FENCE operation
fencei_o => open, -- indicates an executed FENCEI operation
-- XIP (execute in place via SPI) signals (available if IO_XIP_EN = true) --
xip_csn_o => xip_csn_o_int, -- chip-select, low-active
xip_clk_o => xip_clk_o_int, -- serial clock
xip_sdi_i => xip_sdi_i_int, -- device data input
xip_sdo_o => xip_sdo_o_int, -- controller data output
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o => gpio_o_int, -- parallel output
gpio_i => gpio_i_int, -- parallel input
410,6 → 427,11
);
 
-- type conversion --
xip_csn_o <= std_logic(xip_csn_o_int);
xip_clk_o <= std_logic(xip_clk_o_int);
xip_sdi_i_int <= std_ulogic(xip_sdi_i);
xip_sdo_o <= std_logic(xip_sdo_o_int);
 
gpio_o <= std_logic_vector(gpio_o_int);
gpio_i_int <= std_ulogic_vector(gpio_i);
 
/neorv32/trunk/setups/osflow/synthesis.mk
7,10 → 7,16
work-obj08.cf: neorv32-obj08.cf ${DESIGN_SRC} ${BOARD_SRC}
ghdl -a $(GHDL_FLAGS) --work=work ${DESIGN_SRC} ${BOARD_SRC}
 
ifeq ($(strip $(NEORV32_VERILOG_ALL)),)
READ_VERILOG =
else
READ_VERILOG = read_verilog ${NEORV32_VERILOG_ALL};
endif
 
${IMPL}.json: work-obj08.cf $(NEORV32_VERILOG_ALL)
$(YOSYS) $(YOSYSFLAGS) \
-p \
"$(GHDLSYNTH) $(GHDL_FLAGS) --no-formal $(TOP); \
synth_${YOSYSSYNTH} \
$(READ_VERILOG) synth_${YOSYSSYNTH} \
-top $(TOP) $(YOSYSPIPE) \
-json $@" $(NEORV32_VERILOG_ALL) 2>&1 | tee yosys-report.txt
-json $@" 2>&1 | tee yosys-report.txt
/neorv32/trunk/setups/radiant/UPduino_v3/neorv32_upduino_v3.rdf
126,6 → 126,9
<Source name="system_pll/system_pll.ipx" type="IPX_Module" type_short="IPX">
<Options/>
</Source>
<Source name="../../../rtl/core/neorv32_xip.vhd" type="VHDL" type_short="VHDL">
<Options lib="neorv32"/>
</Source>
<Source name="neorv32_upduino_v3.pdc" type="Physical Constraints File" type_short="PDC">
<Options/>
</Source>
/neorv32/trunk/setups/radiant/UPduino_v3/neorv32_upduino_v3_top.vhd
98,7 → 98,7
signal cpu_rstn : std_ulogic;
 
-- internal IO connection --
signal con_pwm : std_ulogic_vector(02 downto 0);
signal con_pwm : std_ulogic_vector(59 downto 0);
signal con_spi_sck : std_ulogic;
signal con_spi_sdi : std_ulogic;
signal con_spi_sdo : std_ulogic;
/neorv32/trunk/sim/simple/neorv32_imem.simple.vhd
7,7 → 7,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
60,6 → 60,8
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert false report "NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal [SIM-only!] IMEM as ROM (" & natural'image(IMEM_SIZE) &
" bytes), pre-initialized with application (" & natural'image(application_init_image'length * 4) & " bytes)." severity note;
assert not (IMEM_AS_IROM = false) report "NEORV32 PROCESSOR CONFIG ERROR! Simulation-optimized IMEM can only be used as pre-initialized ROM!" severity error;
 
 
72,18 → 74,16
-- Memory Access --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
imem_file_access: process(clk_i)
variable addr_v : integer;
variable addr_v : integer range 0 to (IMEM_SIZE/4)-1;
begin
if rising_edge(clk_i) then
rden <= acc_en and rden_i;
ack_o <= acc_en and (rden_i or wren_i);
if (acc_en = '1') then -- reduce switching activity when not accessed
addr_v := to_integer(unsigned(addr));
if (addr_v > application_init_image'length) then
rdata <= (others => '0');
else
rdata <= application_init_image(addr_v);
end if;
rden <= acc_en and rden_i;
ack_o <= acc_en and (rden_i or wren_i);
addr_v := to_integer(unsigned(addr));
--
rdata <= (others => '0');
if (addr_v <= application_init_image'length) then
rdata <= application_init_image(addr_v);
end if;
end if;
end process imem_file_access;
/neorv32/trunk/sim/simple/neorv32_tb.simple.vhd
7,7 → 7,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
240,7 → 240,8
IO_CFS_OUT_SIZE => 32, -- size of CFS output conduit in bits
IO_NEOLED_EN => true, -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_NEOLED_TX_FIFO => 8, -- NEOLED TX FIFO depth, 1..32k, has to be a power of two
IO_GPTMR_EN => true -- implement general purpose timer (GPTMR)?
IO_GPTMR_EN => true, -- implement general purpose timer (GPTMR)?
IO_XIP_EN => true -- implement execute in place module (XIP)?
)
port map (
-- Global control --
267,6 → 268,11
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o => open, -- indicates an executed FENCE operation
fencei_o => open, -- indicates an executed FENCEI operation
-- XIP (execute in place via SPI) signals (available if IO_XIP_EN = true) --
xip_csn_o => open, -- chip-select, low-active
xip_clk_o => open, -- serial clock
xip_sdi_i => '0', -- device data input
xip_sdo_o => open, -- controller data output
-- TX stream interfaces (available if SLINK_NUM_TX > 0) --
slink_tx_dat_o => slink_dat, -- output data
slink_tx_val_o => slink_val, -- valid output
/neorv32/trunk/sim/neorv32_tb.vhd
7,7 → 7,7
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
219,7 → 219,7
if ci_mode then
-- No need to send the full expectation in one big chunk
check_uart(net, uart1_rx_handle, nul & nul);
check_uart(net, uart1_rx_handle, "0/46" & cr & lf);
check_uart(net, uart1_rx_handle, "0/45" & cr & lf);
end if;
 
-- Apply some random data on each SLINK inputs and expect it to
347,7 → 347,8
IO_CFS_OUT_SIZE => 32, -- size of CFS output conduit in bits
IO_NEOLED_EN => true, -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_NEOLED_TX_FIFO => 8, -- NEOLED TX FIFO depth, 1..32k, has to be a power of two
IO_GPTMR_EN => true -- implement general purpose timer (GPTMR)?
IO_GPTMR_EN => true, -- implement general purpose timer (GPTMR)?
IO_XIP_EN => true -- implement execute in place module (XIP)?
)
port map (
-- Global control --
374,6 → 375,11
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o => open, -- indicates an executed FENCE operation
fencei_o => open, -- indicates an executed FENCEI operation
-- XIP (execute in place via SPI) signals (available if IO_XIP_EN = true) --
xip_csn_o => open, -- chip-select, low-active
xip_clk_o => open, -- serial clock
xip_sdi_i => '1', -- device data input
xip_sdo_o => open, -- controller data output
-- TX stream interfaces (available if SLINK_NUM_TX > 0) --
slink_tx_dat_o => slink_dat, -- output data
slink_tx_val_o => slink_val, -- valid output
/neorv32/trunk/sim/run_riscv_arch_test.sh
33,6 → 33,7
 
rm -rf "$NEORV32_LOCAL_RTL"
cp -r ../rtl "$NEORV32_LOCAL_RTL"
rm -f $NEORV32_LOCAL_RTL/core/mem/*.legacy.vhd
 
header "Starting RISC-V architecture tests"
 
39,7 → 40,7
./simple/ghdl.setup.sh
 
# work in progress FIXME
printf "\n\e[1;33mWARNING! 'rv32e/*' tests are work in progress! \e[0m\n\n"
printf "\n\e[1;33mWARNING! 'I/jal-01' test is currently disabled (GHDL simulation issue)! \e[0m\n\n"
 
makeArgs="-C $(pwd)/../sw/isa-test/riscv-arch-test NEORV32_ROOT=$(pwd)/.. XLEN=32 RISCV_TARGET=neorv32"
makeTargets='clean build run verify'
48,7 → 49,46
 
for suite in $SUITES; do
case "$suite" in
I) make --silent $makeArgs SIM_TIME=850us RISCV_DEVICE=I $makeTargets;;
I) make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=I clean build;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='add-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='addi-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='and-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='andi-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='auipc-01' run;
make --silent $makeArgs SIM_TIME=850us RISCV_DEVICE=I RISCV_TEST='beq-01' run;
make --silent $makeArgs SIM_TIME=850us RISCV_DEVICE=I RISCV_TEST='bge-01' run;
make --silent $makeArgs SIM_TIME=850us RISCV_DEVICE=I RISCV_TEST='bgeu-01' run;
make --silent $makeArgs SIM_TIME=850us RISCV_DEVICE=I RISCV_TEST='blt-01' run;
make --silent $makeArgs SIM_TIME=850us RISCV_DEVICE=I RISCV_TEST='bltu-01' run;
make --silent $makeArgs SIM_TIME=850us RISCV_DEVICE=I RISCV_TEST='bne-01' run;
# make --silent $makeArgs SIM_TIME=850us RISCV_DEVICE=I RISCV_TEST='jal-01' run;
make --silent $makeArgs SIM_TIME=850us RISCV_DEVICE=I RISCV_TEST='jalr-01' run;
make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=I RISCV_TEST='lb-align-01' run;
make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=I RISCV_TEST='lbu-align-01' run;
make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=I RISCV_TEST='lh-align-01' run;
make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=I RISCV_TEST='lhu-align-01' run;
make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=I RISCV_TEST='lui-01' run;
make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=I RISCV_TEST='lw-align-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='or-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='ori-01' run;
make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=I RISCV_TEST='sb-align-01' run;
make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=I RISCV_TEST='sh-align-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='sll-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='slli-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='slt-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='slti-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='sltiu-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='sltu-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='sra-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='srai-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='srl-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='srli-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='sub-01' run;
make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=I RISCV_TEST='sw-align-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='xor-01' run;
make --silent $makeArgs SIM_TIME=600us RISCV_DEVICE=I RISCV_TEST='xori-01' run;
make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=I RISCV_TEST='fence-01' run;
make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=I RISCV_TEST='fence-01' verify;;
C) make --silent $makeArgs SIM_TIME=400us RISCV_DEVICE=C $makeTargets;;
M) make --silent $makeArgs SIM_TIME=800us RISCV_DEVICE=M $makeTargets;;
privilege) make --silent $makeArgs SIM_TIME=200us RISCV_DEVICE=privilege $makeTargets;;
/neorv32/trunk/sw/example/demo_xip/main.c
0,0 → 1,219
// #################################################################################################
// # << NEORV32 - Demo for the Execute In Place (XIP) Module >> #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
// # #
// # 1. Redistributions of source code must retain the above copyright notice, this list of #
// # conditions and the following disclaimer. #
// # #
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
// # conditions and the following disclaimer in the documentation and/or other materials #
// # provided with the distribution. #
// # #
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
// # endorse or promote products derived from this software without specific prior written #
// # permission. #
// # #
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
// # OF THE POSSIBILITY OF SUCH DAMAGE. #
// # ********************************************************************************************* #
// # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
// #################################################################################################
 
 
/**********************************************************************//**
* @file demo_xip/main.c
* @author Stephan Nolting
* @brief Demo for the the execute in place (XIP) module.
**************************************************************************/
 
#include <neorv32.h>
 
 
/**********************************************************************//**
* @name User configuration
**************************************************************************/
/**@{*/
/** UART BAUD rate */
#define BAUD_RATE 19200
/**@}*/
 
 
/**********************************************************************//**
* @name Prototypes
**************************************************************************/
int program_xip_flash(void);
 
 
/**********************************************************************//**
* @name Simple program to be stored to the XIP flash.
* This is the "blink_led_asm" from the rv32i-version "blink_led" demo program.
**************************************************************************/
const uint32_t xip_program[] = {
0xfc800513,
0x00052023,
0x00000313,
0x0ff37313,
0x00652023,
0x00130313,
0x008000ef,
0xff1ff06f,
0x001003b7,
0xfff38393,
0x00038a63,
0xfff38393,
0x00000013,
0x00000013,
0xff1ff06f,
0x00008067
};
 
 
/**********************************************************************//**
* Main function: configure the XIP module, program a small program to the attached flash
* and run that program **from there**. The program shows an incrementing counter at the lowest
* 8-bits of the GPIO output port. This demo is meant for a SPI flash/EEPROM with 16-bit addresses.
*
* @note This program requires the XIP module, UART0 and the GPIO module.
*
* @return 0 if execution was successful
**************************************************************************/
int main() {
 
// init UART at default baud rate, no parity bits, no HW flow control
neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
 
// capture all exceptions and give debug info via UART
// this is not required, but keeps us safe
neorv32_rte_setup();
 
// check if XIP module is implemented at all
if (neorv32_xip_available() == 0) {
neorv32_uart0_printf("Error! XIP module not synthesized!\n");
return 1;
}
 
 
// intro
neorv32_uart0_printf("<< XIP Demo Program >>\n\n");
 
 
// warning if i-cache is not implemented
if ((NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_ICACHE)) == 0) {
neorv32_uart0_printf("WARNING! No instruction cache implemented. The XIP program will run awfully slow...\n");
}
 
 
// reset XIP module and configure basic SPI properties
// * 1/64 clock divider
// * clock mode 0 (cpol = 0, cpha = 0)
// * flash read command = 0x03
// -> this function will also send 64 dummy clock cycles via the XIP's SPI port (with CS disabled)
if (neorv32_xip_init(CLK_PRSC_64, 0, 0, 0x03)) {
neorv32_uart0_printf("Error! XIP module setup error!\n");
return 1;
}
 
// use a helper function to store a small example program to the XIP flash
// NOTE: this (direct SPI access via the XIP module) has to be done before the actual XIP mode is enabled!
neorv32_uart0_printf("Programming XIP flash...\n");
if (program_xip_flash()) {
neorv32_uart0_printf("Error! XIP flash programming error!\n");
return 1;
}
 
// configure and enable the actual XIP mode
// * configure 2 address bytes send to the SPI flash for addressing
// * map the XIP flash to the address space starting at 0x20000000
if (neorv32_xip_start(2, 0x20000000)) {
neorv32_uart0_printf("Error! XIP mode configuration error!\n");
return 1;
}
 
// finally, jump to the XIP flash's base address we have configured to start execution **from there**
neorv32_uart0_printf("Starting Execute-In-Place program...\n");
asm volatile ("call %[dest]" : : [dest] "i" (0x20000000));
 
return 0;
}
 
 
/**********************************************************************//**
* Helper function to program the XIP flash via the direct SPI feature of the XIP module.
*
* @warning This function can only be used BEFORE the XIP-mode is activated!
* @note This function is blocking.
*
* @return Returns 0 if write was successful.
**************************************************************************/
int program_xip_flash(void) {
 
int error = 0;
uint32_t data_byte = 0;
uint32_t cnt = 0;
uint32_t flash_addr = 0;
uint32_t tmp = 0;
 
union {
uint64_t uint64;
uint32_t uint32[sizeof(uint64_t)/2];
} data;
 
while (1) {
 
// get data byte
data_byte = xip_program[cnt/4];
data_byte >>= (3-(cnt & 3)) * 8;
data_byte &= 0x000000FF;
 
//DEBUGGING
//neorv32_uart0_printf("Data byte %u: 0x%x\n", cnt, data_byte);
 
// set write-enable latch
// 1 byte command
data.uint32[0] = 0; // irrelevant, TX packet is MSB-aligned
data.uint32[1] = 0x06 << 24; // command: set write-enable latch
error += neorv32_xip_spi_trans(1, &data.uint64);
 
// write word
// 1 byte command, 2 bytes address, 1 byte data
tmp = 0x02 << 24; // command: byte write
tmp |= (flash_addr & 0x0000FFFF) << 8; // address
tmp |= data_byte << 0; // data byte
data.uint32[0] = 0; // irrelevant, TX packet is MSB-aligned
data.uint32[1] = tmp;
error += neorv32_xip_spi_trans(4, &data.uint64);
flash_addr++;
 
// check status register: WIP bit has to clear
while(1) {
tmp = 0x05 << 24; // read status register command
data.uint32[0] = 0; // irrelevant, TX packet is MSB-aligned
data.uint32[1] = tmp;
error += neorv32_xip_spi_trans(2, &data.uint64);
if ((data.uint32[0] & 0x01) == 0) { // WIP bit cleared?
break;
}
}
 
// done?
cnt++;
if ((cnt == ((uint32_t)sizeof(xip_program))) || (error != 0)) {
break;
}
}
 
return error;
}
/neorv32/trunk/sw/example/demo_xip/makefile
0,0 → 1,40
#################################################################################################
# << NEORV32 - Application Makefile >> #
# ********************************************************************************************* #
# Make sure to add the RISC-V GCC compiler's bin folder to your PATH environment variable. #
# ********************************************************************************************* #
# BSD 3-Clause License #
# #
# Copyright (c) 2021, Stephan Nolting. All rights reserved. #
# #
# Redistribution and use in source and binary forms, with or without modification, are #
# permitted provided that the following conditions are met: #
# #
# 1. Redistributions of source code must retain the above copyright notice, this list of #
# conditions and the following disclaimer. #
# #
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
# conditions and the following disclaimer in the documentation and/or other materials #
# provided with the distribution. #
# #
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
# endorse or promote products derived from this software without specific prior written #
# permission. #
# #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
# OF THE POSSIBILITY OF SUCH DAMAGE. #
# ********************************************************************************************* #
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
# Modify this variable to fit your NEORV32 setup (neorv32 home folder)
NEORV32_HOME ?= ../../..
 
include $(NEORV32_HOME)/sw/common/common.mk
/neorv32/trunk/sw/example/game_of_life/main.c
3,7 → 3,7
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
// # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
36,7 → 36,7
/**********************************************************************//**
* @file game_of_life/main.c
* @author Stephan Nolting
* @brief Simple blinking LED demo program using the lowest 8 bits of the GPIO.output port.
* @brief Conway's game of life in a UART terminal.
**************************************************************************/
 
#include <neorv32.h>
/neorv32/trunk/sw/example/hardware_info/main.c
0,0 → 1,85
// #################################################################################################
// # << NEORV32 - Show all available hardware configuration information >> #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
// # #
// # 1. Redistributions of source code must retain the above copyright notice, this list of #
// # conditions and the following disclaimer. #
// # #
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
// # conditions and the following disclaimer in the documentation and/or other materials #
// # provided with the distribution. #
// # #
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
// # endorse or promote products derived from this software without specific prior written #
// # permission. #
// # #
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
// # OF THE POSSIBILITY OF SUCH DAMAGE. #
// # ********************************************************************************************* #
// # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
// #################################################################################################
 
 
/**********************************************************************//**
* @file hardware_info/main.c
* @author Stephan Nolting
* @brief Show all available hardware configuration information.
**************************************************************************/
 
#include <neorv32.h>
 
 
/**********************************************************************//**
* @name User configuration
**************************************************************************/
/**@{*/
/** UART BAUD rate */
#define BAUD_RATE 19200
/**@}*/
 
 
 
/**********************************************************************//**
* Main function
*
* @note This program requires the UART interface to be synthesized.
*
* @return 0 if execution was successful
**************************************************************************/
int main() {
 
// capture all exceptions and give debug info via UART
// this is not required, but keeps us safe
neorv32_rte_setup();
 
// abort if UART0 is not implemented
if (neorv32_uart0_available() == 0) {
return 1;
}
 
// init UART at default baud rate, no parity bits, ho hw flow control
neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
 
// check available hardware extensions and compare with compiler flags
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch
 
// show full HW config report
neorv32_rte_print_hw_config();
 
neorv32_uart0_printf("\nExecution completed.\n");
 
return 0;
}
/neorv32/trunk/sw/example/hardware_info/makefile
0,0 → 1,40
#################################################################################################
# << NEORV32 - Application Makefile >> #
# ********************************************************************************************* #
# Make sure to add the RISC-V GCC compiler's bin folder to your PATH environment variable. #
# ********************************************************************************************* #
# BSD 3-Clause License #
# #
# Copyright (c) 2021, Stephan Nolting. All rights reserved. #
# #
# Redistribution and use in source and binary forms, with or without modification, are #
# permitted provided that the following conditions are met: #
# #
# 1. Redistributions of source code must retain the above copyright notice, this list of #
# conditions and the following disclaimer. #
# #
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
# conditions and the following disclaimer in the documentation and/or other materials #
# provided with the distribution. #
# #
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
# endorse or promote products derived from this software without specific prior written #
# permission. #
# #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
# OF THE POSSIBILITY OF SUCH DAMAGE. #
# ********************************************************************************************* #
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
# Modify this variable to fit your NEORV32 setup (neorv32 home folder)
NEORV32_HOME ?= ../../..
 
include $(NEORV32_HOME)/sw/common/common.mk
/neorv32/trunk/sw/example/processor_check/main.c
3,7 → 3,7
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
// # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
55,6 → 55,8
#define ADDR_UNALIGNED_2 (0x00000002)
//** Unreachable word-aligned address */
#define ADDR_UNREACHABLE (IO_BASE_ADDRESS-4)
//**Read-only word-aligned address */
#define ADDR_READONLY ((uint32_t)&NEORV32_SYSINFO.CLK)
//** external memory base address */
#define EXT_MEM_BASE (0xF0000000)
/**@}*/
285,32 → 287,32
//}
 
 
// ----------------------------------------------------------
// Test standard RISC-V performance counter [m]instret[h]
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] instret counter: ", cnt_test);
//// ----------------------------------------------------------
//// Test standard RISC-V performance counter [m]instret[h]
//// ----------------------------------------------------------
//neorv32_cpu_csr_write(CSR_MCAUSE, 0);
//PRINT_STANDARD("[%i] instret counter: ", cnt_test);
//
//cnt_test++;
//
//// make sure counter is enabled
//asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_IR));
//
//// prepare overflow
//neorv32_cpu_set_minstret(0x00000000FFFFFFFFULL);
//
//// get instruction counter HIGH
//tmp_a = neorv32_cpu_csr_read(CSR_INSTRETH);
//
//// make sure instruction counter high has incremented and there was no exception during access
//if ((tmp_a == 1) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
// test_ok();
//}
//else {
// test_fail();
//}
 
cnt_test++;
 
// make sure counter is enabled
asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_IR));
 
// prepare overflow
neorv32_cpu_set_minstret(0x00000000FFFFFFFFULL);
 
// get instruction counter HIGH
tmp_a = neorv32_cpu_csr_read(CSR_INSTRETH);
 
// make sure instruction counter high has incremented and there was no exception during access
if ((tmp_a == 1) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
}
else {
test_fail();
}
 
 
// ----------------------------------------------------------
// Test mcountinhibt: inhibit auto-inc of [m]cycle
// ----------------------------------------------------------
651,10 → 653,13
PRINT_STANDARD("[%i] L_ACC (load bus access) EXC: ", cnt_test);
cnt_test++;
 
tmp_a = (1 << BUSKEEPER_ERR_FLAG) | (1 << BUSKEEPER_ERR_TYPE);
 
// load from unreachable aligned address
neorv32_cpu_load_unsigned_word(ADDR_UNREACHABLE);
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_L_ACCESS) {
if ((neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_L_ACCESS) && // load bus access error exception
(NEORV32_BUSKEEPER.CTRL = tmp_a)) { // buskeeper: error flag + timeout error
test_ok();
}
else {
687,10 → 692,13
PRINT_STANDARD("[%i] S_ACC (store bus access) EXC: ", cnt_test);
cnt_test++;
 
tmp_a = (1 << BUSKEEPER_ERR_FLAG) | (0 << BUSKEEPER_ERR_TYPE);
 
// store to unreachable aligned address
neorv32_cpu_store_unsigned_word(ADDR_UNREACHABLE, 0);
neorv32_cpu_store_unsigned_word(ADDR_READONLY, 0);
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_ACCESS) {
if ((neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_ACCESS) && // store bus access error exception
(NEORV32_BUSKEEPER.CTRL == tmp_a)) { // buskeeper: error flag + device error
test_ok();
}
else {
1471,7 → 1479,6
}
else {
test_fail();
PRINT_STANDARD("answer: 0x%x", neorv32_cpu_csr_read(CSR_MCAUSE));
}
 
// restore original handler
1733,21 → 1740,21
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCOUNTINHIBIT, -1); // stop all counters
PRINT_STANDARD("\n\n-- HPM reports LOW (%u HPMs available) --\n", num_hpm_cnts_global);
PRINT_STANDARD("#IR - Instr.: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_INSTRET)); // = "HPM_0"
//PRINT_STANDARD("#TM - Time: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_TIME)); // = "HPM_1"
PRINT_STANDARD("#CY - CLKs: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_CYCLE)); // = "HPM_2"
PRINT_STANDARD("#03 - Compr.: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER3));
PRINT_STANDARD("#04 - IF wait: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER4));
PRINT_STANDARD("#05 - II wait: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER5));
PRINT_STANDARD("#06 - ALU wait: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER6));
PRINT_STANDARD("#07 - Loads: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER7));
PRINT_STANDARD("#08 - Stores: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER8));
PRINT_STANDARD("#09 - MEM wait: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER9));
PRINT_STANDARD("#10 - Jumps: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER10));
PRINT_STANDARD("#11 - Branches: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER11));
PRINT_STANDARD("#12 - Taken: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER12));
PRINT_STANDARD("#13 - Traps: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER13));
PRINT_STANDARD("#14 - Illegals: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER14));
PRINT_STANDARD("#IR Instr.: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_INSTRET)); // = "HPM_0"
//PRINT_STANDARD("#TM Time: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_TIME)); // = "HPM_1"
PRINT_STANDARD("#CY CLKs: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_CYCLE)); // = "HPM_2"
PRINT_STANDARD("#03 Compr.: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER3));
PRINT_STANDARD("#04 IF wait: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER4));
PRINT_STANDARD("#05 II wait: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER5));
PRINT_STANDARD("#06 ALU wait: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER6));
PRINT_STANDARD("#07 Loads: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER7));
PRINT_STANDARD("#08 Stores: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER8));
PRINT_STANDARD("#09 MEM wait: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER9));
PRINT_STANDARD("#10 Jumps: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER10));
PRINT_STANDARD("#11 Branches: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER11));
PRINT_STANDARD("#12 - Taken: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER12));
PRINT_STANDARD("#13 Traps: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER13));
PRINT_STANDARD("#14 Illegals: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER14));
 
 
// ----------------------------------------------------------
/neorv32/trunk/sw/example/processor_check/run_check.sh
0,0 → 1,21
make USER_FLAGS+="-DRUN_CHECK -DUART0_SIM_MODE -DUART1_SIM_MODE -g" MARCH=rv32imac clean_all sim
/neorv32/trunk/sw/lib/include/neorv32.h
3,7 → 3,7
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
// # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
60,7 → 60,7
enum NEORV32_CSR_enum {
CSR_FFLAGS = 0x001, /**< 0x001 - fflags (r/w): Floating-point accrued exception flags */
CSR_FRM = 0x002, /**< 0x002 - frm (r/w): Floating-point dynamic rounding mode */
CSR_FCSR = 0x003, /**< 0x003 - fcsr (r/w): Floating-point control/staturs register (frm + fflags) */
CSR_FCSR = 0x003, /**< 0x003 - fcsr (r/w): Floating-point control/status register (frm + fflags) */
 
CSR_MSTATUS = 0x300, /**< 0x300 - mstatus (r/w): Machine status register */
CSR_MISA = 0x301, /**< 0x301 - misa (r/-): CPU ISA and extensions (read-only in NEORV32) */
827,6 → 827,47
 
 
/**********************************************************************//**
* @name IO Device: Execute In Place Module (XIP)
**************************************************************************/
/**@{*/
/** XIP module prototype */
typedef struct __attribute__((packed,aligned(4))) {
uint32_t CTRL; /**< offset 0: control register (#NEORV32_XIP_CTRL_enum) */
const uint32_t reserved; /**< offset 4: reserved */
uint32_t DATA_LO; /**< offset 8: SPI data register low */
uint32_t DATA_HI; /**< offset 12: SPI data register high */
} neorv32_xip_t;
 
/** XIP module hardware access (#neorv32_xip_t) */
#define NEORV32_XIP (*((volatile neorv32_xip_t*) (0xFFFFFF40UL)))
 
/** XIP control/data register bits */
enum NEORV32_XIP_CTRL_enum {
XIP_CTRL_EN = 0, /**< XIP control register( 0) (r/w): XIP module enable */
XIP_CTRL_PRSC0 = 1, /**< XIP control register( 1) (r/w): Clock prescaler select bit 0 */
XIP_CTRL_PRSC1 = 2, /**< XIP control register( 2) (r/w): Clock prescaler select bit 1 */
XIP_CTRL_PRSC2 = 3, /**< XIP control register( 3) (r/w): Clock prescaler select bit 2 */
XIP_CTRL_CPOL = 4, /**< XIP control register( 4) (r/w): SPI (idle) clock polarity */
XIP_CTRL_CPHA = 5, /**< XIP control register( 5) (r/w): SPI clock phase */
XIP_CTRL_SPI_NBYTES_LSB = 6, /**< XIP control register( 6) (r/w): Number of bytes in SPI transmission, LSB */
XIP_CTRL_SPI_NBYTES_MSB = 9, /**< XIP control register( 9) (r/w): Number of bytes in SPI transmission, MSB */
XIP_CTRL_XIP_EN = 10, /**< XIP control register(10) (r/w): XIP access enable */
XIP_CTRL_XIP_ABYTES_LSB = 11, /**< XIP control register(11) (r/w): Number XIP address bytes (minus 1), LSB */
XIP_CTRL_XIP_ABYTES_MSB = 12, /**< XIP control register(12) (r/w): Number XIP address bytes (minus 1), MSB */
XIP_CTRL_RD_CMD_LSB = 13, /**< XIP control register(13) (r/w): SPI flash read command, LSB */
XIP_CTRL_RD_CMD_MSB = 20, /**< XIP control register(20) (r/w): SPI flash read command, MSB */
XIP_CTRL_PAGE_LSB = 21, /**< XIP control register(21) (r/w): XIP memory page, LSB */
XIP_CTRL_PAGE_MSB = 24, /**< XIP control register(24) (r/w): XIP memory page, MSB */
XIP_CTRL_SPI_CSEN = 25, /**< XIP control register(25) (r/w): SPI chip-select enable */
XIP_CTRL_HIGHSPEED = 26, /**< XIP control register(26) (r/w): SPI high-speed mode enable (ignoring XIP_CTRL_PRSC) */
 
XIP_CTRL_PHY_BUSY = 30, /**< XIP control register(20) (r/-): SPI PHY is busy */
XIP_CTRL_XIP_BUSY = 31 /**< XIP control register(31) (r/-): XIP access in progress */
};
/**@}*/
 
 
/**********************************************************************//**
* @name IO Device: General Purpose Timer (GPTMR)
**************************************************************************/
/**@{*/
866,8 → 907,9
 
/** 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_FLAG = 31 /**< BUSKEEPER control register(31) (r/c): Sticky error flag, clears after read or write access */
BUSKEEPER_ERR_TYPE = 0, /**< BUSKEEPER control register( 0) (r/-): Bus error type: 0=device error, 1=access timeout */
BUSKEEPER_NULL_CHECK_EN = 16, /**< BUSKEEPER control register(16) (r/w): Enable NULL address check */
BUSKEEPER_ERR_FLAG = 31 /**< BUSKEEPER control register(31) (r/-): Sticky error flag, clears after read or write access */
};
/**@}*/
 
1007,24 → 1049,25
 
/** SPI control register bits */
enum NEORV32_SPI_CTRL_enum {
SPI_CTRL_CS0 = 0, /**< SPI control register(0) (r/w): Direct chip select line 0 (output is low when set) */
SPI_CTRL_CS1 = 1, /**< SPI control register(1) (r/w): Direct chip select line 1 (output is low when set) */
SPI_CTRL_CS2 = 2, /**< SPI control register(2) (r/w): Direct chip select line 2 (output is low when set) */
SPI_CTRL_CS3 = 3, /**< SPI control register(3) (r/w): Direct chip select line 3 (output is low when set) */
SPI_CTRL_CS4 = 4, /**< SPI control register(4) (r/w): Direct chip select line 4 (output is low when set) */
SPI_CTRL_CS5 = 5, /**< SPI control register(5) (r/w): Direct chip select line 5 (output is low when set) */
SPI_CTRL_CS6 = 6, /**< SPI control register(6) (r/w): Direct chip select line 6 (output is low when set) */
SPI_CTRL_CS7 = 7, /**< SPI control register(7) (r/w): Direct chip select line 7 (output is low when set) */
SPI_CTRL_EN = 8, /**< SPI control register(8) (r/w): SPI unit enable */
SPI_CTRL_CPHA = 9, /**< SPI control register(9) (r/w): Clock phase */
SPI_CTRL_PRSC0 = 10, /**< SPI control register(10) (r/w): Clock prescaler select bit 0 */
SPI_CTRL_PRSC1 = 11, /**< SPI control register(11) (r/w): Clock prescaler select bit 1 */
SPI_CTRL_PRSC2 = 12, /**< SPI control register(12) (r/w): Clock prescaler select bit 2 */
SPI_CTRL_SIZE0 = 13, /**< SPI control register(13) (r/w): Transfer data size lsb (00: 8-bit, 01: 16-bit, 10: 24-bit, 11: 32-bit) */
SPI_CTRL_SIZE1 = 14, /**< SPI control register(14) (r/w): Transfer data size msb (00: 8-bit, 01: 16-bit, 10: 24-bit, 11: 32-bit) */
SPI_CTRL_CPOL = 15, /**< SPI control register(15) (r/w): Clock polarity */
SPI_CTRL_CS0 = 0, /**< SPI control register(0) (r/w): Direct chip select line 0 (output is low when set) */
SPI_CTRL_CS1 = 1, /**< SPI control register(1) (r/w): Direct chip select line 1 (output is low when set) */
SPI_CTRL_CS2 = 2, /**< SPI control register(2) (r/w): Direct chip select line 2 (output is low when set) */
SPI_CTRL_CS3 = 3, /**< SPI control register(3) (r/w): Direct chip select line 3 (output is low when set) */
SPI_CTRL_CS4 = 4, /**< SPI control register(4) (r/w): Direct chip select line 4 (output is low when set) */
SPI_CTRL_CS5 = 5, /**< SPI control register(5) (r/w): Direct chip select line 5 (output is low when set) */
SPI_CTRL_CS6 = 6, /**< SPI control register(6) (r/w): Direct chip select line 6 (output is low when set) */
SPI_CTRL_CS7 = 7, /**< SPI control register(7) (r/w): Direct chip select line 7 (output is low when set) */
SPI_CTRL_EN = 8, /**< SPI control register(8) (r/w): SPI unit enable */
SPI_CTRL_CPHA = 9, /**< SPI control register(9) (r/w): Clock phase */
SPI_CTRL_PRSC0 = 10, /**< SPI control register(10) (r/w): Clock prescaler select bit 0 */
SPI_CTRL_PRSC1 = 11, /**< SPI control register(11) (r/w): Clock prescaler select bit 1 */
SPI_CTRL_PRSC2 = 12, /**< SPI control register(12) (r/w): Clock prescaler select bit 2 */
SPI_CTRL_SIZE0 = 13, /**< SPI control register(13) (r/w): Transfer data size lsb (00: 8-bit, 01: 16-bit, 10: 24-bit, 11: 32-bit) */
SPI_CTRL_SIZE1 = 14, /**< SPI control register(14) (r/w): Transfer data size msb (00: 8-bit, 01: 16-bit, 10: 24-bit, 11: 32-bit) */
SPI_CTRL_CPOL = 15, /**< SPI control register(15) (r/w): Clock polarity */
SPI_CTRL_HIGHSPEED = 16, /**< SPI control register(16) (r/w): SPI high-speed mode enable (ignoring SPI_CTRL_PRSC) */
 
SPI_CTRL_BUSY = 31 /**< SPI control register(31) (r/-): SPI busy flag */
SPI_CTRL_BUSY = 31 /**< SPI control register(31) (r/-): SPI busy flag */
};
/**@}*/
 
1122,8 → 1165,8
/**@{*/
/** GPIO module prototype */
typedef struct __attribute__((packed,aligned(4))) {
const uint32_t INPUT_LO; /**< offset 0: parallel input port lower 32-bit */
const uint32_t INPUT_HI; /**< offset 4: parallel input port upper 32-bit */
const uint32_t INPUT_LO; /**< offset 0: parallel input port lower 32-bit, read-only */
const uint32_t INPUT_HI; /**< offset 4: parallel input port upper 32-bit, read-only */
uint32_t OUTPUT_LO; /**< offset 8: parallel output port lower 32-bit */
uint32_t OUTPUT_HI; /**< offset 12: parallel output port upper 32-bit */
} neorv32_gpio_t;
1191,7 → 1234,7
* @name IO Device: System Configuration Information Memory (SYSINFO)
**************************************************************************/
/**@{*/
/** SYSINFO module prototype */
/** SYSINFO module prototype - whole module is read-only */
typedef struct __attribute__((packed,aligned(4))) {
const uint32_t CLK; /**< offset 0: clock speed in Hz */
const uint32_t CPU; /**< offset 4: CPU core features (#NEORV32_SYSINFO_CPU_enum) */
1249,7 → 1292,8
SYSINFO_SOC_IO_UART1 = 26, /**< SYSINFO_FEATURES (26) (r/-): Secondary universal asynchronous receiver/transmitter 1 implemented when 1 (via IO_UART1_EN generic) */
SYSINFO_SOC_IO_NEOLED = 27, /**< SYSINFO_FEATURES (27) (r/-): NeoPixel-compatible smart LED interface implemented when 1 (via IO_NEOLED_EN generic) */
SYSINFO_SOC_IO_XIRQ = 28, /**< SYSINFO_FEATURES (28) (r/-): External interrupt controller implemented when 1 (via XIRQ_NUM_IO generic) */
SYSINFO_SOC_IO_GPTMR = 29 /**< SYSINFO_FEATURES (29) (r/-): General purpose timer implemented when 1 (via IO_GPTMR_EN generic) */
SYSINFO_SOC_IO_GPTMR = 29, /**< SYSINFO_FEATURES (29) (r/-): General purpose timer implemented when 1 (via IO_GPTMR_EN generic) */
SYSINFO_SOC_IO_XIP = 30 /**< SYSINFO_FEATURES (30) (r/-): Execute in place module implemented when 1 (via IO_XIP_EN generic) */
};
 
/** NEORV32_SYSINFO.CACHE (r/-): Cache configuration */
1302,6 → 1346,7
#include "neorv32_twi.h"
#include "neorv32_uart.h"
#include "neorv32_wdt.h"
#include "neorv32_xip.h"
#include "neorv32_xirq.h"
 
#ifdef __cplusplus
/neorv32/trunk/sw/lib/include/neorv32_spi.h
3,7 → 3,7
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
// # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
49,6 → 49,8
void neorv32_spi_setup(uint8_t prsc, uint8_t clk_phase, uint8_t clk_polarity, uint8_t data_size);
void neorv32_spi_disable(void);
void neorv32_spi_enable(void);
void neorv32_spi_highspeed_enable(void);
void neorv32_spi_highspeed_disable(void);
void neorv32_spi_cs_en(uint8_t cs);
void neorv32_spi_cs_dis(uint8_t cs);
uint32_t neorv32_spi_trans(uint32_t tx_data);
/neorv32/trunk/sw/lib/include/neorv32_xip.h
0,0 → 1,55
// #################################################################################################
// # << NEORV32: neorv32_xip.h - Execute In Place (XIP) Module HW Driver (Header) >> #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
// # #
// # 1. Redistributions of source code must retain the above copyright notice, this list of #
// # conditions and the following disclaimer. #
// # #
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
// # conditions and the following disclaimer in the documentation and/or other materials #
// # provided with the distribution. #
// # #
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
// # endorse or promote products derived from this software without specific prior written #
// # permission. #
// # #
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
// # OF THE POSSIBILITY OF SUCH DAMAGE. #
// # ********************************************************************************************* #
// # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
// #################################################################################################
 
 
/**********************************************************************//**
* @file neorv32_xip.h
* @author Stephan Nolting
* @brief Execute in place module (XIP) HW driver header file.
*
* @note These functions should only be used if the XIP module was synthesized (IO_XIP_EN = true).
**************************************************************************/
 
#ifndef neorv32_xip_h
#define neorv32_xip_h
 
// prototypes
int neorv32_xip_available(void);
int neorv32_xip_init(uint8_t prsc, uint8_t cpol, uint8_t cpha, uint8_t rd_cmd);
int neorv32_xip_start(uint8_t abytes, uint32_t page_base);
void neorv32_xip_highspeed_enable(void);
void neorv32_xip_highspeed_disable(void);
int neorv32_xip_spi_trans(uint8_t nbytes, uint64_t *rtx_data);
 
#endif // neorv32_xip_h
/neorv32/trunk/sw/lib/source/neorv32_rte.c
3,7 → 3,7
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
// # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
272,7 → 272,7
// additional info
neorv32_uart0_print(", MTVAL=");
__neorv32_rte_print_hex_word(neorv32_cpu_csr_read(CSR_MTVAL));
neorv32_uart0_print(" </RTE>");
neorv32_uart0_print(" </RTE>\n");
}
 
 
479,6 → 479,7
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_NEOLED)); neorv32_uart0_printf(" NEOLED\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_XIRQ)); neorv32_uart0_printf(" XIRQ\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_GPTMR)); neorv32_uart0_printf(" GPTMR\n");
__neorv32_rte_print_checkbox(tmp & (1 << SYSINFO_SOC_IO_XIP)); neorv32_uart0_printf(" XIP\n");
}
 
 
/neorv32/trunk/sw/lib/source/neorv32_spi.c
3,7 → 3,7
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
// # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
111,6 → 111,28
 
 
/**********************************************************************//**
* Enable high-speed SPI mode (running at half of the processor clock).
*
* @note High-speed SPI mode ignores the programmed clock prescaler configuration.
**************************************************************************/
void neorv32_spi_highspeed_enable(void) {
 
NEORV32_SPI.CTRL |= 1 << SPI_CTRL_HIGHSPEED;
}
 
 
/**********************************************************************//**
* Disable high-speed SPI mode.
*
* @note High-speed SPI mode ignores the programmed clock prescaler configuration.
**************************************************************************/
void neorv32_spi_highspeed_disable(void) {
 
NEORV32_SPI.CTRL &= ~(1 << SPI_CTRL_HIGHSPEED);
}
 
 
/**********************************************************************//**
* Activate SPI chip select signal.
*
* @note The chip select output lines are LOW when activated.
/neorv32/trunk/sw/lib/source/neorv32_xip.c
0,0 → 1,216
// #################################################################################################
// # << NEORV32: neorv32_xip.c - Execute In Place (XIP) Module HW Driver (Source) >> #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
// # #
// # 1. Redistributions of source code must retain the above copyright notice, this list of #
// # conditions and the following disclaimer. #
// # #
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
// # conditions and the following disclaimer in the documentation and/or other materials #
// # provided with the distribution. #
// # #
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
// # endorse or promote products derived from this software without specific prior written #
// # permission. #
// # #
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
// # OF THE POSSIBILITY OF SUCH DAMAGE. #
// # ********************************************************************************************* #
// # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
// #################################################################################################
 
 
/**********************************************************************//**
* @file neorv32_xip.c
* @author Stephan Nolting
* @brief Execute in place module (XIP) HW driver source file.
*
* @note These functions should only be used if the XIP module was synthesized (IO_XIP_EN = true).
**************************************************************************/
 
#include "neorv32.h"
#include "neorv32_xip.h"
 
 
/**********************************************************************//**
* Check if XIP module was synthesized.
*
* @return 0 if XIP was not synthesized, 1 if XIP is available.
**************************************************************************/
int neorv32_xip_available(void) {
 
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_XIP)) {
return 1;
}
else {
return 0;
}
}
 
 
/**********************************************************************//**
* Configure XIP module: configure SPI properties.
*
* @warning This will reset the XIP module overriding the CTRL register.
* @note This function will also send 64 dummy clocks via the SPI port (with chip-select disabled).
*
* @param[in] prsc SPI clock prescaler select (0..7).
* @param[in] cpol SPI clock polarity (0/1).
* @param[in] cpha SPI clock phase(0/1).
* @param[in] rd_cmd SPI flash read command.
* @return 0 if configuration is OK, 1 if configuration error.
**************************************************************************/
int neorv32_xip_init(uint8_t prsc, uint8_t cpol, uint8_t cpha, uint8_t rd_cmd) {
 
// configuration check
if ((prsc > 7) || (cpol > 1) || (cpha > 1)) {
return 1;
}
 
// reset module
NEORV32_XIP.CTRL = 0;
 
uint32_t ctrl = 0;
 
ctrl |= ((uint32_t)(1 )) << XIP_CTRL_EN; // enable module
ctrl |= ((uint32_t)(prsc & 0x07)) << XIP_CTRL_PRSC0;
ctrl |= ((uint32_t)(cpol & 0x01)) << XIP_CTRL_CPOL;
ctrl |= ((uint32_t)(cpha & 0x01)) << XIP_CTRL_CPHA;
ctrl |= ((uint32_t)(8 )) << XIP_CTRL_SPI_NBYTES_LSB; // set 8 bytes transfer size as default
ctrl |= ((uint32_t)(rd_cmd & 0xff)) << XIP_CTRL_RD_CMD_LSB;
NEORV32_XIP.CTRL = ctrl;
 
// send 64 dummy clocks
NEORV32_XIP.DATA_LO = 0;
NEORV32_XIP.DATA_HI = 0; // trigger SPI transfer
 
// wait for transfer to complete
while(NEORV32_XIP.CTRL & (1 << XIP_CTRL_PHY_BUSY));
 
NEORV32_XIP.CTRL |= 1 << XIP_CTRL_SPI_CSEN; // finally enable SPI chip-select
 
return 0;
}
 
 
/**********************************************************************//**
* Enable XIP mode (to allow CPU to _transparently_ fetch instructions).
*
* @warning This function is blocking until the XIP mode is ready.
*
* @param[in] abytes Number of address bytes used to access the SPI flash (1,2,3,4).
* @param[in] page_base XIP memory page base address (top 4 address bits, 0..15).
* @return 0 if XIP configuration is OK, 1 if configuration error.
**************************************************************************/
int neorv32_xip_start(uint8_t abytes, uint32_t page_base) {
 
if ((abytes < 1) || (abytes > 4)) {
return 1;
}
 
if (page_base & 0x0FFFFFFF) {
return 1;
}
page_base >>= 28;
 
 
uint32_t ctrl = NEORV32_XIP.CTRL;
 
// address bytes send to SPI flash
ctrl &= ~(3 << XIP_CTRL_XIP_ABYTES_LSB); // clear old configuration
ctrl |= ((uint32_t)(abytes-1)) << XIP_CTRL_XIP_ABYTES_LSB; // set new configuration
 
// total number of bytes to transfer via SPI
// 'abytes' address bytes + 1 command byte + 4 bytes RX data (one 32-bit word)
ctrl &= ~(0xF << XIP_CTRL_SPI_NBYTES_LSB); // clear old configuration
ctrl |= ((uint32_t)(abytes+1+4)) << XIP_CTRL_SPI_NBYTES_LSB; // set new configuration
 
// XIP memory page
ctrl &= ~(0xF << XIP_CTRL_PAGE_LSB); // clear old configuration
ctrl |= ((uint32_t)(page_base & 0xf)) << XIP_CTRL_PAGE_LSB; // set new configuration
 
ctrl |= 1 << XIP_CTRL_XIP_EN; // enable XIP mode
 
NEORV32_XIP.CTRL = ctrl;
 
return 0;
}
 
 
/**********************************************************************//**
* Enable high-speed SPI mode (running at half of the processor clock).
*
* @note High-speed SPI mode ignores the programmed clock prescaler configuration.
**************************************************************************/
void neorv32_xip_highspeed_enable(void) {
 
NEORV32_XIP.CTRL |= 1 << XIP_CTRL_HIGHSPEED;
}
 
 
/**********************************************************************//**
* Disable high-speed SPI mode.
*
* @note High-speed SPI mode ignores the programmed clock prescaler configuration.
**************************************************************************/
void neorv32_xip_highspeed_disable(void) {
 
NEORV32_XIP.CTRL &= ~(1 << XIP_CTRL_HIGHSPEED);
}
 
 
/**********************************************************************//**
* Direct SPI access to the XIP flash.
*
* @warning This function can only be used BEFORE the XIP-mode is activated!
* @note This function is blocking.
*
* @param[in] nbytes Number of bytes to transfer (1..8).
* @param[in,out] rtx_data Pointer to 64-bit TX/RX data (MSB-aligned for sending, LSB-aligned for receiving (only 32-bit)).
* @return 0 if valid transfer, 1 if transfer configuration error.
**************************************************************************/
int neorv32_xip_spi_trans(uint8_t nbytes, uint64_t *rtx_data) {
 
if ((nbytes == 0) || (nbytes > 8)) {
return 1;
}
 
// configure number of bytes to transfer
uint32_t ctrl = NEORV32_XIP.CTRL;
ctrl &= ~(0xF << XIP_CTRL_SPI_NBYTES_LSB); // clear old configuration
ctrl |= nbytes << XIP_CTRL_SPI_NBYTES_LSB; // set new configuration
NEORV32_XIP.CTRL = ctrl;
 
union {
uint64_t uint64;
uint32_t uint32[sizeof(uint64_t)/2];
} data;
 
data.uint64 = *rtx_data;
NEORV32_XIP.DATA_LO = data.uint32[0];
NEORV32_XIP.DATA_HI = data.uint32[1]; // trigger SPI transfer
 
// wait for transfer to complete
while(NEORV32_XIP.CTRL & (1 << XIP_CTRL_PHY_BUSY));
 
data.uint32[0] = NEORV32_XIP.DATA_LO;
data.uint32[1] = 0; // RX data is always 32-bit
*rtx_data = data.uint64;
 
return 0;
}
 
/neorv32/trunk/sw/svd/neorv32.svd
344,6 → 344,107
</registers>
</peripheral>
 
<!-- XIP -->
<peripheral>
<name>XIP</name>
<description>Execute In Place Module</description>
<groupName>CIP</groupName>
<baseAddress>0xFFFFFF40</baseAddress>
 
<addressBlock>
<offset>0</offset>
<size>0x10</size>
<usage>registers</usage>
</addressBlock>
 
<registers>
<register>
<name>CTRL</name>
<description>Control register</description>
<addressOffset>0x00</addressOffset>
<fields>
<field>
<name>XIP_CTRL_EN</name>
<bitRange>[0:0]</bitRange>
<description>XIP module enable flag</description>
</field>
<field>
<name>XIP_CTRL_PRSC</name>
<bitRange>[3:1]</bitRange>
<description>SPI clock prescaler select</description>
</field>
<field>
<name>XIP_CTRL_CPOL</name>
<bitRange>[4:4]</bitRange>
<description>SPI clock (idle) polarity</description>
</field>
<field>
<name>XIP_CTRL_CPHA</name>
<bitRange>[5:5]</bitRange>
<description>SPI clock phase</description>
</field>
<field>
<name>XIP_CTRL_SPI_NBYTES</name>
<bitRange>[9:6]</bitRange>
<description>Number of bytes in SPI transmission</description>
</field>
<field>
<name>XIP_CTRL_XIP_EN</name>
<bitRange>[10:10]</bitRange>
<description>XIP mode enable</description>
</field>
<field>
<name>XIP_CTRL_XIP_ABYTES</name>
<bitRange>[12:11]</bitRange>
<description>Number of XIP address bytes (minus 1)</description>
</field>
<field>
<name>XIP_CTRL_RD_CMD</name>
<bitRange>[20:13]</bitRange>
<description>SPI flash read command</description>
</field>
<field>
<name>XIP_CTRL_XIP_PAGE</name>
<bitRange>[24:21]</bitRange>
<description>XIP memory page</description>
</field>
<field>
<name>XIP_CTRL_SPI_CSEN</name>
<bitRange>[25:25]</bitRange>
<description>SPI chip-select enable</description>
</field>
<field>
<name>XIP_CTRL_HIGHSPEED</name>
<bitRange>[26:26]</bitRange>
<description>SPI high-speed mode enable (ignoring XIP_CTRL_PRSC)</description>
</field>
<field>
<name>XIP_CTRL_PHY_BUSY</name>
<bitRange>[30:30]</bitRange>
<access>read-only</access>
<description>SPI PHY busy</description>
</field>
<field>
<name>XIP_CTRL_XIP_BUSY</name>
<bitRange>[31:31]</bitRange>
<access>read-only</access>
<description>XIP access in progress</description>
</field>
</fields>
</register>
<register>
<name>DATA_LO</name>
<description>Direct SPI access - data register low</description>
<addressOffset>0x08</addressOffset>
</register>
<register>
<name>DATA_HI</name>
<description>Direct SPI access - data register high</description>
<addressOffset>0x0C</addressOffset>
</register>
</registers>
</peripheral>
 
<!-- GPTMR -->
<peripheral>
<name>GPTMR</name>
421,6 → 522,11
<description>Bus error type: 0=device error, 1=access timeout</description>
</field>
<field>
<name>BUSKEEPER_NULL_CHECK_EN</name>
<bitRange>[16:16]</bitRange>
<description>Enable NULL address check when set</description>
</field>
<field>
<name>BUSKEEPER_ERR_FLAG</name>
<bitRange>[31:31]</bitRange>
<description>Sticky error flag, clears after read or write access</description>
732,6 → 838,11
<description>Clock polarity</description>
</field>
<field>
<name>SPI_CTRL_HIGHSPEED</name>
<bitRange>[16:16]</bitRange>
<description>SPI high-speed mode enable (ignoring SPI_CTRL_PRSC)</description>
</field>
<field>
<name>SPI_CTRL_BUSY</name>
<bitRange>[31:31]</bitRange>
<access>read-only</access>
1144,6 → 1255,7
<field><name>SYSINFO_SOC_IO_NEOLED</name><bitRange>[27:27]</bitRange><description>NeoPixel-compatible smart LED interface implemented</description></field>
<field><name>SYSINFO_SOC_IO_XIRQ</name><bitRange>[28:28]</bitRange><description>External interrupt controller implemented</description></field>
<field><name>SYSINFO_SOC_IO_GPTMR</name><bitRange>[29:29]</bitRange><description>General purpose timer implemented</description></field>
<field><name>SYSINFO_SOC_IO_XIP</name><bitRange>[30:30]</bitRange><description>Execute in place module implemented</description></field>
</fields>
</register>
<register>
/neorv32/trunk/CHANGELOG.md
6,8 → 6,8
A list of all releases can be found [here](https://github.com/stnolting/neorv32/releases). The most recent version of the *NEORV32 data sheet*
can be found [online at GitHub-pages](https://stnolting.github.io/neorv32).
 
:information_source: Starting with version `1.5.7` this project uses [semantic versioning](https://semver.org) syntax for official releases.
The _hardware version identifier_ uses an additional custom version element (i.e. `MAJOR.MINOR.PATCH.individual`) to track individual changes.
:information_source: Starting with version `1.5.7` this project uses [semantic versioning](https://semver.org) for official releases.
The _hardware version identifier_ uses an additional custom version element (i.e. `MAJOR.MINOR.PATCH.individual`) to track _individual_ changes.
The identifier number is incremented with every core RTL modification and also by major framework modifications.
 
:information_source: The processor can determine its version from the `mimpid` CSR (at CSR address 0xf13). A 8x4-bit BCD representation is used.
26,6 → 26,15
 
| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
| 17.01.2022 |[**:rocket:1.6.6**](https://github.com/stnolting/neorv32/releases/tag/v1.6.6) | **New release** |
| 14.01.2022 | 1.6.5.9 | **GPIO** module: write accesses to the GPIO module's "input" registers will now raise a bus exception; [PR #255](https://github.com/stnolting/neorv32/pull/255) |
| 11.01.2022 | 1.6.5.8 | minor rtl code clean-ups and edits in `rtl/core`; any write access to the SYSINFO module will now show up as a BUSKEEPER's "DEVICE_ERR" |
| 08.01.2022 | 1.6.5.7 | :bug: fixed bug in BUSKEEPER's error type logic (introduced in version `1.6.5.4`); removed "unexpected ERR/ACK" error codes; [PR #253](https://github.com/stnolting/neorv32/pull/253) |
| 07.01.2022 | 1.6.5.6 | :sparkles: **XIP & SPI: added high-speed SPI mode** (SPI clocking at half of the processor clock), see [PR #251](https://github.com/stnolting/neorv32/pull/251) |
| 06.01.2022 | 1.6.5.5 | :warning: optimized/reworked XIP (execute in place) module, see [PR #249](https://github.com/stnolting/neorv32/pull/249) |
| 04.01.2022 | 1.6.5.4 | **BUSKEEPER** can now optionally check for NULL address accesses (address `0x00000000`), see [PR #247](https://github.com/stnolting/neorv32/pull/247) |
| 02.01.2022 | 1.6.5.3 | :sparkles: **added Execute In Place (XIP) module** allowing code to be directly executed from an external SPI flash, see [PR #244](https://github.com/stnolting/neorv32/pull/244) |
| 02.01.2022 | 1.6.5.2 | :bug: fixed minor bug in CPU's instruction fetch unit (only issue new instruction fetch request when the previous one has been completed) |
| 16.12.2021 |[**:rocket:1.6.5**](https://github.com/stnolting/neorv32/releases/tag/v1.6.5) | **New release** |
| 15.12.2021 | 1.6.4.10 | minor logic optimization of CPU's pipeline front-end (instruction fetch and instruction issue) |
| 14.12.2021 | 1.6.4.9 | optimized CPU's multiplication/division co-processor: divisions are 1 cycle faster, fast-multiplications (when using DSPs) are 1 cycle faster, slightly less resource utilization, see [PR #240](https://github.com/stnolting/neorv32/pull/240) |
/neorv32/trunk/CODE_OF_CONDUCT.md
55,7 → 55,7
## Enforcement
 
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at stnolting@gmail.com. All
reported by contacting the project team at [stnolting@gmail.com](mailto:stnolting@gmail.com). All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
/neorv32/trunk/LICENSE
1,6 → 1,6
BSD 3-Clause License
 
Copyright (c) 2021, Stephan Nolting
Copyright (c) 2022, Stephan Nolting
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
/neorv32/trunk/README.md
35,7 → 35,7
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 precise and resumable hardware exceptions.
 
:thinking: Want to know more? Check out the [project's rationale](https://stnolting.github.io/neorv32/#_rationale).
:interrobang: 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](https://stnolting.github.io/neorv32/) (online at GitHub-pages).
 
59,10 → 59,10
 
### Project Key Features
 
- [x] all-in-one package: [CPU](#3-NEORV32-CPU-Features) plus [SoC](#2-NEORV32-Processor-Features) plus [Software Framework & Tooling](#4-Software-Framework-and-Tooling)
- [x] all-in-one package: **CPU** plus **SoC** plus **Software Framework & Tooling**
- [x] completely described in behavioral, platform-independent VHDL - no primitives, macros, etc.
- [x] be as small as possible while being as RISC-V-compliant as possible
- [x] from zero to *printf("hello world!");* - completely open source and documented
- [x] from zero to `printf("hello world!");` - completely open source and documented
- [x] easy to use even for FPGA/RISC-V starters – intended to work *out of the box*
 
 
82,9 → 82,8
 
## 2. NEORV32 Processor Features
 
The NEORV32 Processor (top entity: [`rtl/core/neorv32_top.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_top.vhd))
provides a full-featured SoC build around the NEORV32 CPU. It is highly configurable via generics
to allow a flexible customization according to your needs. Note that all modules listed below are _optional_.
The NEORV32 Processor provides a full-featured microcontroller-like SoC build around the NEORV32 CPU. It is highly configurable
via generics to allow a flexible customization according to your needs. Note that all modules listed below are _optional_.
 
**Memory**
 
91,7 → 90,7
* processor-internal data and instruction memories ([DMEM](https://stnolting.github.io/neorv32/#_data_memory_dmem) /
[IMEM](https://stnolting.github.io/neorv32/#_instruction_memory_imem)) &
cache ([iCACHE](https://stnolting.github.io/neorv32/#_processor_internal_instruction_cache_icache))
* bootloader ([BOOTLDROM](https://stnolting.github.io/neorv32/#_bootloader_rom_bootrom)) with serial user interface
* pre-installed bootloader ([BOOTLDROM](https://stnolting.github.io/neorv32/#_bootloader_rom_bootrom)) with serial user interface
* allows booting application code via UART or from external SPI flash
 
**Timers**
105,10 → 104,10
* standard serial interfaces
([UART](https://stnolting.github.io/neorv32/#_primary_universal_asynchronous_receiver_and_transmitter_uart0),
[SPI](https://stnolting.github.io/neorv32/#_serial_peripheral_interface_controller_spi),
[TWI / I²C](https://stnolting.github.io/neorv32/#_two_wire_serial_interface_controller_twi))
[TWI](https://stnolting.github.io/neorv32/#_two_wire_serial_interface_controller_twi))
* general purpose [GPIO](https://stnolting.github.io/neorv32/#_general_purpose_input_and_output_port_gpio) and
[PWM](https://stnolting.github.io/neorv32/#_pulse_width_modulation_controller_pwm)
* smart LED interface ([NEOLED](https://stnolting.github.io/neorv32/#_smart_led_interface_neoled)) to directly drive _NeoPixel(TM)_ LEDs
* smart LED interface ([NEOLED](https://stnolting.github.io/neorv32/#_smart_led_interface_neoled)) to directly control NeoPixel(TM) LEDs
 
**SoC Connectivity**
 
121,16 → 120,15
* AXI4-Stream compatible
* external interrupt controller with up to 32 channels
([XIRQ](https://stnolting.github.io/neorv32/#_external_interrupt_controller_xirq))
* custom functions subsystem ([CFS](https://stnolting.github.io/neorv32/#_custom_functions_subsystem_cfs))
for tightly-coupled custom co-processor extensions
 
**Advanced**
 
* on-chip debugger ([OCD](https://stnolting.github.io/neorv32/#_on_chip_debugger_ocd)) accessible via JTAG interface - implementing
the "Minimal RISC-V Debug Specification Version 0.13.2" and compatible with **OpenOCD** + **gdb** and **Segger Embedded Studio**
* _true random_ number generator ([TRNG](https://stnolting.github.io/neorv32/#_true_random_number_generator_trng))
* on-chip debugger ([OCD](https://stnolting.github.io/neorv32/#_on_chip_debugger_ocd)) accessible via JTAG interface - 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 the CPU's bus transactions ([BUSKEEPER](https://stnolting.github.io/neorv32/#_internal_bus_monitor_buskeeper))
* execute in place module ([XIP](https://stnolting.github.io/neorv32/#_execute_in_place_module_xip)) to directly execute code from SPI flash
* custom functions subsystem ([CFS](https://stnolting.github.io/neorv32/#_custom_functions_subsystem_cfs))
for tightly-coupled custom co-processor extensions and interfaces
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
154,12 → 152,10
 
## 3. NEORV32 CPU Features
 
The CPU (top entity: [`rtl/core/neorv32_cpu.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_cpu.vhd))
implements the RISC-V 32-bit `rv32` ISA with optional extensions (see below). It is compatible to subsets of the
The NEORV32 CPU implements the RISC-V 32-bit `rv32i` ISA with optional extensions (see below). It is compatible to subsets of the
*Unprivileged ISA Specification* [(Version 2.2)](https://github.com/stnolting/neorv32/blob/master/docs/references/riscv-spec.pdf)
and the *Privileged Architecture Specification* [(Version 1.12-draft)](https://github.com/stnolting/neorv32/blob/master/docs/references/riscv-privileged.pdf).
Compatibility is checked by passing the [official RISC-V architecture tests](https://github.com/riscv/riscv-arch-test)
(see [`sim/README`](sim/README.md)).
Compatibility is checked by passing the [official RISC-V architecture tests](https://github.com/riscv/riscv-arch-test).
 
The core is a little-endian Von-Neumann machine implemented as multi-cycle architecture.
However, the CPU's _front end_ (instruction fetch) and _back end_ (instruction execution) can work independently to increase performance.
206,7 → 202,7
Implementation results for _exemplary_ CPU configuration generated for an **Intel Cyclone IV EP4CE22F17C6N FPGA**
using **Intel Quartus Prime Lite 20.1** ("balanced implementation, Slow 1200mV 0C Model").
 
| CPU Configuration (version [1.5.7.10](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md)) | LEs | FFs | Memory bits | DSPs (9-bit) | f_max |
| CPU Configuration (version [1.5.7.10](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md)) | LEs | FFs | Memory bits | DSPs | f_max |
|:------------------------|:----:|:----:|:----:|:-:|:-------:|
| `rv32i` | 806 | 359 | 1024 | 0 | 125 MHz |
| `rv32i_Zicsr_Zicntr` | 1729 | 813 | 1024 | 0 | 124 MHz |
215,10 → 211,6
:information_source: An incremental list of CPU extension's hardware utilization can found in the
[_Data Sheet: FPGA Implementation Results - CPU_](https://stnolting.github.io/neorv32/#_cpu).
 
:information_source: The CPU and SoC provide advanced options to optimize for performance, area or energy.
See [_User Guide: Application-Specific Processor Configuration_](https://stnolting.github.io/neorv32/ug/#_application_specific_processor_configuration)
for more information.
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
315,7 → 307,7
 
### :copyright: Legal
 
[![license](https://img.shields.io/github/license/stnolting/neorv32?longCache=true&style=flat-square)](https://github.com/stnolting/neorv32/blob/master/LICENSE)
[![license](https://img.shields.io/github/license/stnolting/neorv32?longCache=true&style=flat)](https://github.com/stnolting/neorv32/blob/master/LICENSE)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.5018888.svg)](https://doi.org/10.5281/zenodo.5018888)
 
* [Overview](https://stnolting.github.io/neorv32/#_legal) - license, disclaimer, limitation of liability for external links, proprietary notice, ...
322,6 → 314,14
* [Citing](https://stnolting.github.io/neorv32/#_citing) - citing information
* [Impressum](https://github.com/stnolting/neorv32/blob/master/docs/impressum.md) - imprint
 
This is an open-source project that is free of charge. Use this project in any way you like
(as long as it complies to the permissive [license](https://github.com/stnolting/neorv32/blob/master/LICENSE)).
Please quote it appropriately. :+1:
 
We (the community) and I highly appreciate _any_ kind of feedback! Feel free to start a new "show & tell"
[discussion](https://github.com/stnolting/neorv32/discussions), write some lines on our [gitter channel](https://gitter.im/neorv32/community)
or directly get in [contact](mailto:stnolting@gmail.com) with me.
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 

powered by: WebSVN 2.1.0

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