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

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neorv32
    from Rev 61 to Rev 62
    Reverse comparison

Rev 61 → Rev 62

/trunk/Makefile File deleted
/trunk/docs/datasheet/cpu.adoc
85,7 → 85,10
 
The NEORV32 CPU passes the rv32_m/I, rv32_m/M, rv32_m/C, rv32_m/privilege, and
rv32_m/Zifencei tests of the official RISC-V Architecture Tests (GitHub). The port files for the
NEORV32 processor are located in the repository's `riscv-arch-test` folder. See section <<_risc_v_architecture_test_framework>>
NEORV32 processor are located in the repository's `sw/isa-test` folder.
 
[NOTE]
See section https://stnolting.github.io/neorv32/ug/#_risc_v_architecture_test_framework[User Guide: RISC-V Architecture Test Framework]
for information how to run the tests on the NEORV32.
 
.**RISC-V `rv32_m/C` Tests**
403,7 → 406,7
In order to keep the hardware footprint low, the CPU's shift unit uses a bit-serial 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
complete within 2 cycles (plus overhead) regardless of the actual shift amount.
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
472,7 → 475,7
 
[NOTE]
All undefined/unimplemented/malformed/illegal instructions do raise an illegal instruction exception
(see <<_execution_safety>>).
(see <<_full_virtualization>>).
 
 
==== **`Zfinx`** Single-Precision Floating-Point Operations
513,7 → 516,11
intrinsic library is provided to utilize the provided `Zfinx` floating-point extension from C-language
code (see `sw/example/floating_point_test`).
 
[IMPORTANT]
Note that any FPU instruction including all FPU-related CSR accesses will raise an illegal instruction exception
if the FPU is not enabled via the <<_mstatus>> CSR (`FS` bits).
 
 
==== **`Zicsr`** Control and Status Register Access / Privileged Architecture
 
The CSR access instructions as well as the exception and interrupt system (= the privileged architecture) is implemented when the
533,7 → 540,11
halted until a valid interrupt request occurs. To wake up again, the according interrupt source has to
be enabled via the `mie` CSR and the global interrupt enable flag in `mstatus` has to be set.
 
[IMPORTANT]
The `wfi` instruction will raise an illegal instruction exception when executed outside of machine-mode
and <<_mstatus>> bit `TW` (timeout wait) is set.
 
 
==== **`Zifencei`** Instruction Stream Synchronization
 
The `Zifencei` CPU extension is implemented if the `CPU_EXTENSION_RISCV_Zifencei` configuration
620,7 → 631,7
CSR defines the architectural events that lead to an increment of the associated HPM counter.
 
The cycle, time and instructions-retired counters (`[m]cycle[h]`, `time[h]`, `[m]instret[h]`) are
mandatory performance monitors on every RISC-V platform and have fixed increment event. For example,
mandatory performance monitors on every RISC-V platform and have fixed increment events. For example,
the instructions-retired counter increments with each executed instructions. The actual hardware performance
monitors are optional and can be configured to increment on arbitrary hardware events. The number of
available HPM is configured via the top's `HPM_NUM_CNTS` generic at synthesis time. Assigning a zero will exclude
628,15 → 639,19
 
Depending on the configuration, the following additional CSR are available:
 
* counters: `[m]hpmcounter*[h]` (3..31, depending on configuration)
* counters: `mhpmcounter*[h]` (3..31, depending on configuration)
* event configuration: `mhpmevent*` (3..31, depending on configuration)
 
User-level access to the counter registers `hpmcounter*[h]` can be individually restricted via the `mcounteren` CSR.
[IMPORTANT]
The HPM counter CSR can only be accessed in machine-mode. Hence, the according `mcounteren` CSR bits
are always zero and read-only.
 
Auto-increment of the HPMs can be individually deactivated via the `mcountinhibit` CSR.
 
If `HPM_NUM_CNTS` is lower than the maximumg value (=29) the remaining HPMs are not implemented.
However, accessing their associated CSRs will not raise an illegal instructions exception. These CSR are
read-only and will always return 0.
If `HPM_NUM_CNTS` is lower than the maximum value (=29) the remaining HPM CSRs are not implemented and the
according `mcountinhibit` CSR bits are hardwired to zero.
However, accessing their associated CSRs will not raise an illegal instruction exception (if in machine mode).
The according CSRs are read-only and will always return 0.
 
[NOTE]
For a list of all allocated HPM-related CSRs and all provided event configurations see section <<_hardware_performance_monitors_hpm>>.
708,33 → 723,27
<<<
// ####################################################################################################################
:sectnums:
==== Execution Safety
==== Full Virtualization
 
The hardware of the NEORV32 CPU was designed for maximum *execution safety*. If the `Zicsr` CPU
extension is enabled, the core supports **all** traps specified by the official RISC-V specifications (obviously,
not the ones that are related to yet unimplemented extensions/features). Thus, the CPU provides well-defined
hardware fall-backs for (nearly) everything that can go wrong. Even if any kind of trap is triggered, the core
is always in a defined and fully synchronized state throughout the whole architecture (i.e. no need to make
out-of-order operations undone) that allows predictable execution behavior at any time.
Just like the RISC-V ISA the NEORV32 aims to support _ maximum virtualization_ capabilities
on CPU _and_ SoC level. The CPU supports **all** traps specified by the official RISC-V specifications.footnote:[If the `Zicsr` CPU
extension is enabled (implementing the full set of the privileged architecture).]
Thus, the CPU provides defined hardware fall-backs for any expected and unexpected situation (e.g. executing an
malformed instruction word or accessing a not-allocated address). For any kind of trap the core is always in a
defined and fully synchronized state throughout the whole architecture (i.e. there are no out-of-order operations that
have to be made undone). This allows predictable execution behavior - and thus, defined operations to resolve the cause
of the trap - at any time improving overall _execution safety_.
 
**Core Safety Features**
**NEORV32-Specific Virtualization Features**
 
* Due to the acknowledged memory accesses the CPU is _always_ sync with the memory system (no speculative execution / out-of-order states).
* The CPU supports all bus exceptions including bus access exceptions that are triggered if an
accessed address does not respond or encounters an internal error during access (which is a rare
feature in many open-source RISC-V cores).
* The CPU raises an illegal instruction trap for **all** unimplemented/malformed/illegal instructions (to support _full_ virtualization).
* If user-level code tries to read from machine-level-only CSRs (like `mstatus`) an illegal instruction
exception is raised. The results of this operations is always zero (though, machine-level
code handling this exception can modify the target register of the illegal access-causing
instruction to allow full virtualization). Illegal write accesses to machine CSRs will not be write any data at all.
* Illegal user-level memory accesses to protected addresses or address regions (via physical memory
protection) will not be conducted at all (no actual write and no actual read; prevents triggering of
memory-mapped devices). Illegal load operations will not return any data (the instruction's
destination register will not be written at all).
* Due to the acknowledged memory accesses the CPU is _always_ sync with the memory system
(i.e. there is no speculative execution / no out-of-order states).
* The CPU supports _all_ RISC-V bus exceptions including access exceptions that are triggered if an
accessed address does not respond or encounters an internal error during access.
* The CPU raises an illegal instruction trap for _all_ unimplemented/malformed/illegal instructions.
* To be continued...
 
 
 
<<<
// ####################################################################################################################
:sectnums:
/trunk/docs/datasheet/cpu_csr.adoc
69,11 → 69,12
| 0x002 | <<_frm>> | _CSR_FRM_ | r/w | Floating-point dynamic rounding mode |
| 0x003 | <<_fcsr>> | _CSR_FCSR_ | r/w | Floating-point control and status (`frm` + `fflags`) |
6+^| **<<_machine_trap_setup>>**
| 0x300 | <<_mstatus>> | _CSR_MSTATUS_ | r/w | Machine status register | `C`
| 0x300 | <<_mstatus>> | _CSR_MSTATUS_ | r/w | Machine status register - low word | `C`
| 0x301 | <<_misa>> | _CSR_MISA_ | r/- | Machine CPU ISA and extensions | `R`
| 0x304 | <<_mie>> | _CSR_MIE_ | r/w | Machine interrupt enable register | `X`
| 0x305 | <<_mtvec>> | _CSR_MTVEC_ | r/w | Machine trap-handler base address (for ALL traps) |
| 0x306 | <<_mcounteren>> | _CSR_MCOUNTEREN_ | r/w | Machine counter-enable register | `C`
| 0x310 | <<_mstatush>> | _CSR_MSTATUSH_ | r/- | Machine status register - high word | `C`
6+^| **<<_machine_trap_handling>>**
| 0x340 | <<_mscratch>> | _CSR_MSCRATCH_ | r/w | Machine scratch register |
| 0x341 | <<_mepc>> | _CSR_MEPC_ | r/w | Machine exception program counter |
85,7 → 86,7
| 0x3b0 .. 0x3ef | <<_pmpaddr, `pmpaddr0`>> .. <<_pmpaddr, `pmpaddr63`>> | _CSR_PMPADDR0_ .. _CSR_PMPADDR63_ | r/w | Physical memory protection addr. register region 0..63 |
6+^| **<<_machine_counters_and_timers>>**
| 0xb00 | <<_mcycleh, `mcycle`>> | _CSR_MCYCLE_ | r/w | Machine cycle counter low word |
| 0xb02 | <<_minstreth, `_minstret`>> | _CSR_MINSTRET_ | r/w | Machine instruction-retired counter low word |
| 0xb02 | <<_minstreth, `minstret`>> | _CSR_MINSTRET_ | r/w | Machine instruction-retired counter low word |
| 0xb80 | <<_mcycleh>> | _CSR_MCYCLE_ | r/w | Machine cycle counter high word |
| 0xb82 | <<_minstreth>> | _CSR_MINSTRET_ | r/w | Machine instruction-retired counter high word |
| 0xc00 | <<_cycleh, `cycle`>> | _CSR_CYCLE_ | r/- | Cycle counter low word |
101,10 → 102,11
6+^| **<<_machine_counter_setup>>**
| 0x320 | <<_mcountinhibit>> | _CSR_MCOUNTINHIBIT_ | r/w | Machine counter-enable register |
6+^| **<<_machine_information_registers>>**
| 0xf11 | <<_mvendorid>> | _CSR_MVENDORID_ | r/- | Vendor ID |
| 0xf12 | <<_marchid>> | _CSR_MARCHID_ | r/- | Architecture ID |
| 0xf13 | <<_mimpid>> | _CSR_MIMPID_ | r/- | Machine implementation ID / version |
| 0xf14 | <<_mhartid>> | _CSR_MHARTID_ | r/- | Machine thread ID |
| 0xf11 | <<_mvendorid>> | _CSR_MVENDORID_ | r/- | Vendor ID |
| 0xf12 | <<_marchid>> | _CSR_MARCHID_ | r/- | Architecture ID |
| 0xf13 | <<_mimpid>> | _CSR_MIMPID_ | r/- | Machine implementation ID / version |
| 0xf14 | <<_mhartid>> | _CSR_MHARTID_ | r/- | Machine thread ID |
| 0xf15 | <<_mconfigptr>> | _CSR_MCONFIGPTR_ | r/- | Machine configuration pointer register |
6+^| **<<_neorv32_specific_custom_csrs>>**
| 0xfc0 | <<_mzext>> | _CSR_MZEXT_ | r/- | Available `Z*` CPU extensions |
|=======================
184,6 → 186,11
[options="header",grid="rows"]
|=======================
| Bit | Name [C] | R/W | Function
| 31 | _CSR_MSTATUS_SD_ | r/- | Read-only bit that is set if the FS field is not all-zero (state _OFF_)
| 21 | _CSR_MSTATUS_TW_ | r/w | Timeout wait: raise illegal instruction exception if `WFI` instruction is executed outside of M-mode when set
| 14:13 | _CSR_MSTATUS_FS_H_ : _CSR_MSTATUS_FS_L_ | r/w | Floating-point extension state; `00` = _OFF_, `11` = _DIRTY_; writing any other value will
always set _DIRTY_; if `FS` is _off_ all FPU instructions and FPU CSR access will raise an illegal instruction exception; these status bits are hardwired
to zero if no FPU is present (_CPU_MZEXT_ZFINX_ = false)
| 12:11 | _CSR_MSTATUS_MPP_H_ : _CSR_MSTATUS_MPP_L_ | r/w | Previous machine privilege level, 11 = machine (M) level, 00 = user (U) level
| 7 | _CSR_MSTATUS_MPIE_ | r/w | Previous machine global interrupt enable flag state
| 3 | _CSR_MSTATUS_MIE_ | r/w | Machine global interrupt enable flag
298,7 → 305,7
[options="header",grid="rows"]
|=======================
| Bit | Name [C] | R/W | Function
| 31:16 | - | r/- | User-level code is **not** allowed to read HPM counter
| 31:16 | `0` | r/- | Always zero: user-level code is **not** allowed to read HPM counters
| 2 | _CSR_MCOUNTEREN_IR_ | r/w | User-level code is allowed to read `cycle[h]` CSRs when set
| 1 | _CSR_MCOUNTEREN_TM_ | r/w | User-level code is allowed to read `time[h]` CSRs when set
| 0 | _CSR_MCOUNTEREN_CY_ | r/w | User-level code is allowed to read `instret[h]` CSRs when set
305,6 → 312,25
|=======================
 
 
:sectnums!:
===== **`mstatush`**
 
[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0x310 | **Machine status register - high word** | `mstatush`
3+| Reset value: _0x00000000_
3+| The `mstatush` CSR is compatible to the RISC-V specifications. In combination with <<_mstatus>> it shows additional
execution state information. The NEORV32 `mstatush` CSR is read-only and all bits are hardwired to zero.
|======
 
[NOTE]
The NEORV32 `mstatush` CSR is not a physical register. All write access are ignored and all read accesses will always
return zero. However, any access will not raise an illegal instruction exception. The CSR address is implemented
in order to comply with the RISC-V privilege architecture specs.
 
 
 
<<<
// ####################################################################################################################
:sectnums:
606,7 → 632,7
| 0x232 -0x33f | **Machine hardware performance monitor event selector** | `mhpmevent3` - `mhpmevent31`
3+| Reset value: _UNDEFINED_
3+| The `mhpmevent*` CSRs are compatible to the RISC-V specifications. The configuration of these CSR define
the architectural events that cause the according `[m]hpmcounter*[h]` counters to increment. All available events are
the architectural events that cause the according `mhpmcounter*[h]` counters to increment. All available events are
listed in the table below. If more than one event is selected, the according counter will increment if any of
the enabled events is observed (logical OR). Note that the counter will only increment by 1 step per clock
cycle even if more than one event is observed. If the CPU is in sleep mode, no HPM counter will increment
615,7 → 641,7
 
The available hardware performance logic is configured via the _HPM_NUM_CNTS_ top entity generic.
_HPM_NUM_CNTS_ defines the number of implemented performance monitors and thus, the availability of the
according `[m]hpmcounter*[h]` and `mhpmevent*` CSRs.
according `mhpmcounter*[h]` and `mhpmevent*` CSRs.
 
.HPM event selector
[cols="^1,<3,^1,<5"]
681,7 → 707,7
| Bit | Name [C] | R/W | Event
| 0 | _CSR_MCOUNTINHIBIT_IR_ | r/w | the `[m]instret[h]` CSRs will auto-increment with each committed instruction when set
| 2 | _CSR_MCOUNTINHIBIT_IR_ | r/w | the `[m]cycle[h]` CSRs will auto-increment with each clock cycle (if CPU is not in sleep state) when set
| 3:31 | _CSR_MCOUNTINHIBIT_HPM3_ _: _CSR_MCOUNTINHIBIT_HPM31_ | r/w | the `[m]hpmcount*[h]` CSRs will auto-increment according to the configured `mhpmevent*` selector
| 3:31 | _CSR_MCOUNTINHIBIT_HPM3_ _: _CSR_MCOUNTINHIBIT_HPM31_ | r/w | the `mhpmcount*[h]` CSRs will auto-increment according to the configured `mhpmevent*` selector
|=======================
 
 
690,6 → 716,8
:sectnums:
==== Machine Information Registers
 
[NOTE]
All machine information registers can only be accessed in machine mode and are read-only.
 
:sectnums!:
===== **`mvendorid`**
742,7 → 770,21
|======
 
 
:sectnums!:
===== **`mconfigptr`**
 
[cols="4,27,>7"]
[frame="topbot",grid="none"]
|======
| 0xf15 | **Machine configuration pointer register** | `mconfigptr`
3+| Reset value: `0x00000000`
3+| This register holds a physical address (if not zero) that points to the base address of an architecture configuration structure.
Software can traverse this data structure to discover information about the harts, the platform, and their configuration.
**NOTE: Not assigned yet.**
|======
 
 
 
<<<
// ####################################################################################################################
:sectnums:
/trunk/docs/datasheet/on_chip_debugger.adoc
29,7 → 29,8
 
[TIP]
A simple example on how to use NEORV32 on-chip debugger in combination with `OpenOCD` and `gdb`
is shown in chapter <<_debugging_using_the_on_chip_debugger>>.
is shown in section https://stnolting.github.io/neorv32/ug/#_debugging_using_the_on_chip_debugger[Debugging using the On-Chip Debugger]
of the User Guide.
 
The NEORV32 on-chip debugger complex is based on three hardware modules:
 
/trunk/docs/datasheet/overview.adoc
115,6 → 115,7
** RISC-V compatibility: passes the official architecture tests
** base architecture + privileged architecture (optional) + ISA extensions (optional)
** rich set of customization options (ISA extensions, design goal: performance / area (/ energy), ...)
** aims to support <<_full_virtualization>> capabilities (CPU _and_ SoC) to increase execution safety
** official https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md[RISC-V open source architecture ID]
* **NEORV32 Processor (SoC)**: highly-configurable full-scale microcontroller-like processor system
** based on the NEORV32 CPU
143,40 → 144,43
=== Project Folder Structure
 
...................................
neorv32 - Project home folder
├.ci - Scripts for continuous integration
├setups - Example setups for various FPGA boards and toolchains
neorv32 - Project home folder
├docs - Project documentation
│├datasheet - .adoc sources for NEORV32 data sheet
│├doxygen_build - Software framework documentation (generated by doxygen)
│├figures - Figures and logos
│├icons - Misc. symbols
│├references - Data sheets and RISC-V specs.
│└src_adoc - AsciiDoc sources for this document
├rtl - VHDL sources
│├core - Core sources of the CPU & SoC
│└templates - Alternate/additional top entities & wrappers
│ ├processor - Processor SoC wrappers
│ └system - System wrappers for advanced connectivity
├setups - Example setups for various FPGAs, boards and toolchains
│└...
├CHANGELOG.md - Project change log
├docs - Project documentation
│├doxygen_build - Software framework documentation (generated by doxygen)
│├src_adoc - AsciiDoc sources for this document
│├references - Data sheets and RISC-V specs.
│└figures - Figures and logos
├riscv-arch-test - Port files for the official RISC-V architecture tests
├rtl - VHDL sources
│├core - Sources of the CPU & SoC
│└templates - Alternate/additional top entities/wrappers
│ ├processor - Processor wrappers
│ └system - System wrappers for advanced connectivity
├sim - Simulation files
│└rtl_modules - Processor modules for simulation-only
└sw - Software framework
├bootloader - Sources and scripts for the NEORV32 internal bootloader
├common - Linker script and crt0.S start-up code
├example - Various example programs
├sim - Simulation files (see User Guide)
└sw - Software framework
├bootloader - Sources and scripts for the NEORV32 internal bootloader
├common - Linker script and crt0.S start-up code
├example - Various example programs
│└...
├ocd_firmware - source code for on-chip debugger's "park loop"
├openocd - OpenOCD on-chip debugger configuration files
├image_gen - Helper program to generate NEORV32 executables
└lib - Processor core library
├include - Header files (*.h)
└source - Source files (*.c)
├isa-test
│├riscv-arch-test - RISC-V spec. compatibility test framework (submodule)
│└port-neorv32 - Port files for the official RISC-V architecture tests
├ocd_firmware - source code for on-chip debugger's "park loop"
├openocd - OpenOCD on-chip debugger configuration files
├image_gen - Helper program to generate NEORV32 executables
└lib - Processor core library
├include - Header files (*.h)
└source - Source files (*.c)
...................................
 
[NOTE]
There are further files and folders starting with a dot which – for example – contain
data/configurations only relevant for git or for the continuous integration framework (`.ci`).
 
 
<<<
211,12 → 215,12
│└neorv32_bootloader_image.vhd - Bootloader boot ROM memory image
├neorv32_busswitch.vhd - Processor bus switch for CPU buses (I&D)
├neorv32_bus_keeper.vhd - Processor-internal bus monitor
├neorv32_icache.vhd - Processor-internal instruction cache
├neorv32_cfs.vhd - Custom functions subsystem
├neorv32_debug_dm.vhd - on-chip debugger: debug module
├neorv32_debug_dtm.vhd - on-chip debugger: debug transfer module
├neorv32_dmem.vhd - Processor-internal data memory
├neorv32_gpio.vhd - General purpose input/output port unit
├neorv32_icache.vhd - Processor-internal instruction cache
├neorv32_imem.vhd - Processor-internal instruction memory
│└neor32_application_image.vhd - IMEM application initialization image
├neorv32_mtime.vhd - Machine system timer
238,9 → 242,7
:sectnums:
=== FPGA Implementation Results
 
This chapter shows exemplary implementation results of the NEORV32 CPU and Processor. Please note, that
the provided results are just a relative measure as logic functions of different modules might be merged
between entity boundaries, so the actual utilization results might vary a bit.
This chapter shows _exemplary_ implementation results of the NEORV32 CPU and NEORV32 Processor.
 
:sectnums:
==== CPU
248,7 → 250,7
[cols="<2,<8"]
[grid="topbot"]
|=======================
| Hardware version: | `1.5.5.5`
| Hardware version: | `1.5.7.10`
| Top entity: | `rtl/core/neorv32_cpu.vhd`
|=======================
 
255,19 → 257,27
[cols="<5,>1,>1,>1,>1,>1"]
[options="header",grid="rows"]
|=======================
| CPU | LEs | FFs | MEM bits | DSPs | _f~max~_
| `rv32i` | 980 | 409 | 1024 | 0 | 125 MHz
| `rv32i_Zicsr` | 1835 | 856 | 1024 | 0 | 125 MHz
| `rv32im_Zicsr` | 2443 | 1134 | 1024 | 0 | 125 MHz
| `rv32imc_Zicsr` | 2669 | 1149 | 1024 | 0 | 125 MHz
| `rv32imac_Zicsr` | 2685 | 1156 | 1024 | 0 | 125 MHz
| `rv32imac_Zicsr` + `debug_mode` | 3058 | 1225 | 1024 | 0 | 125 MHz
| `rv32imac_Zicsr` + `u` | 2698 | 1162 | 1024 | 0 | 125 MHz
| `rv32imac_Zicsr_Zifencei` + `u` | 2715 | 1162 | 1024 | 0 | 125 MHz
| `rv32imac_Zicsr_Zifencei_Zfinx` + `u` | 4004 | 1812 | 1024 | 7 | 118 MHz
| CPU | LEs | FFs | MEM bits | DSPs | _f~max~_
| `rv32i` | 806 | 359 | 1024 | 0 | 125 MHz
| `rv32i_Zicsr` | 1729 | 813 | 1024 | 0 | 124 MHz
| `rv32im_Zicsr` | 2269 | 1055 | 1024 | 0 | 124 MHz
| `rv32imc_Zicsr` | 2501 | 1070 | 1024 | 0 | 124 MHz
| `rv32imac_Zicsr` | 2511 | 1074 | 1024 | 0 | 124 MHz
| `rv32imacu_Zicsr` | 2521 | 1079 | 1024 | 0 | 124 MHz
| `rv32imacu_Zicsr_Zifencei` | 2522 | 1079 | 1024 | 0 | 122 MHz
| `rv32imacu_Zicsr_Zifencei_Zfinx` | 3807 | 1731 | 1024 | 7 | 116 MHz
| `rv32imacu_Zicsr_Zifencei_Zfinx_DebugMode` | 3974 | 1815 | 1024 | 7 | 116 MHz
|=======================
 
[NOTE]
No HPM counters and no PMP regions were implemented for generating these results.
 
[TIP]
The CPU provides further options to reduce the area footprint (for example by constraining the CPU-internal
counter sizes) or to increase performance (for example by using a barrel-shifter; at cost of extra hardware).
See section <<_processor_top_entity_generics>> for more information.
 
 
:sectnums:
==== Processor Modules
 
274,7 → 284,7
[cols="<2,<8"]
[grid="topbot"]
|=======================
| Hardware version: | `1.5.7.8`
| Hardware version: | `1.5.7.15`
| Top entity: | `rtl/core/neorv32_top.vhd`
|=======================
 
282,29 → 292,29
[cols="<2,<8,>1,>1,>2,>1"]
[options="header",grid="rows"]
|=======================
| 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
| 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
| 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
| DTM | On-chip debugger - debug transfer module (JTAG) | 254 | 218 | 0 | 0
| GPIO | General purpose input/output ports | 134 | 161 | 0 | 0
| iCACHE | Instruction cache (1x4 blocks, 256 bytes per block) | 2 21| 156 | 8192 | 0
| IMEM | Processor-internal instruction memory (16kB) | 13 | 2 | 131072 | 0
| MTIME | Machine system timer | 319 | 167 | 0 | 0
| NEOLED | Smart LED Interface (NeoPixel/WS28128) [4xFIFO] | 342 | 307 | 0 | 0
| SLINK | Stream link interface (4 links, FIFO_depth=1) | 345 | 313 | 0 | 0
| PWM | Pulse_width modulation controller (4 channels) | 71 | 69 | 0 | 0
| SPI | Serial peripheral interface | 148 | 127 | 0 | 0
| **SYSINFO** | System configuration information memory | 14 | 11 | 0 | 0
| TRNG | True random number generator | 89 | 76 | 0 | 0
| TWI | Two-wire interface | 77 | 43 | 0 | 0
| UART0/1 | Universal asynchronous receiver/transmitter 0/1 | 183 | 132 | 0 | 0
| WDT | Watchdog timer | 53 | 43 | 0 | 0
| WISHBONE | External memory interface | 114 | 110 | 0 | 0
| XIRQ | External interrupt controller (32 channels) | 241 | 201 | 0 | 0
| DMEM | Processor-internal data memory (8kB) | 19 | 2 | 65536 | 0
| DM | On-chip debugger - debug module | 493 | 240 | 0 | 0
| DTM | On-chip debugger - debug transfer module (JTAG) | 254 | 218 | 0 | 0
| GPIO | General purpose input/output ports | 134 | 161 | 0 | 0
| iCACHE | Instruction cache (1x4 blocks, 256 bytes per block) | 2 21| 156 | 8192 | 0
| IMEM | Processor-internal instruction memory (16kB) | 13 | 2 | 131072 | 0
| MTIME | Machine system timer | 319 | 167 | 0 | 0
| NEOLED | Smart LED Interface (NeoPixel/WS28128) [FIFO_depth=1] | 226 | 182 | 0 | 0
| SLINK | Stream link interface (2xRX, 2xTX, FIFO_depth=1) | 208 | 181 | 0 | 0
| PWM | Pulse_width modulation controller (4 channels) | 71 | 69 | 0 | 0
| SPI | Serial peripheral interface | 148 | 127 | 0 | 0
| **SYSINFO** | System configuration information memory | 14 | 11 | 0 | 0
| TRNG | True random number generator | 89 | 76 | 0 | 0
| TWI | Two-wire interface | 77 | 43 | 0 | 0
| UART0/1 | Universal asynchronous receiver/transmitter 0/1 | 183 | 132 | 0 | 0
| WDT | Watchdog timer | 53 | 43 | 0 | 0
| WISHBONE | External memory interface | 114 | 110 | 0 | 0
| XIRQ | External interrupt controller (32 channels) | 241 | 201 | 0 | 0
|=======================
 
 
312,7 → 322,6
:sectnums:
==== Exemplary Setups
 
[TIP]
Check out the `setups` folder (@GitHub: https://github.com/stnolting/neorv32/tree/master/setups),
which provides several demo setups for various FPGA boards and toolchains.
 
322,92 → 331,48
:sectnums:
=== CPU Performance
 
:sectnums:
==== CoreMark Benchmark
The performance of the NEORV32 was tested and evaluated using the https://www.eembc.org/coremark/[Core Mark CPU benchmark].
This benchmark focuses on testing the capabilities of the CPU core itself rather than the performance of the whole
system. The according sources can be found in the `sw/example/coremark` folder.
 
.Configuration
[cols="<2,<8"]
[grid="topbot"]
|=======================
| Hardware: | 32kB IMEM, 16kB DMEM, no caches, 100MHz clock
| CoreMark: | 2000 iterations, MEM_METHOD is MEM_STACK
| Compiler: | RISCV32-GCC 10.1.0
| Peripherals: | UART for printing the results
| Compiler flags: | default, see makefile
|=======================
 
The performance of the NEORV32 was tested and evaluated using the https://www.eembc.org/coremark/[Core Mark CPU benchmark]. This
benchmark focuses on testing the capabilities of the CPU core itself rather than the performance of the whole
system. The according source code and the SW project can be found in the `sw/example/coremark` folder.
 
The resulting CoreMark score is defined as CoreMark iterations per second.
The execution time is determined via the RISC-V `[m]cycle[h]` CSRs. The relative CoreMark score is
defined as CoreMark score divided by the CPU's clock frequency in MHz.
 
.Configuration
[cols="<2,<8"]
[grid="topbot"]
|=======================
| Hardware version: | `1.4.9.8`
| HW version: | `1.5.7.10`
| Hardware: | 32kB int. IMEM, 16kB int. DMEM, no caches, 100MHz clock
| CoreMark: | 2000 iterations, MEM_METHOD is MEM_STACK
| Compiler: | RISCV32-GCC 10.2.0
| Compiler flags: | default, see makefile
|=======================
 
.CoreMark results
[cols="<4,>1,>1,>1"]
[cols="<4,^1,^1,^1"]
[options="header",grid="rows"]
|=======================
| CPU (incl. `Zicsr`) | Executable size | CoreMark Score | CoreMarks/Mhz
| `rv32i` | 28756 bytes | 36.36 | **0.3636**
| `rv32im` | 27516 bytes | 68.97 | **0.6897**
| `rv32imc` | 22008 bytes | 68.97 | **0.6897**
| `rv32imc` + _FAST_MUL_EN_ | 22008 bytes | 86.96 | **0.8696**
| `rv32imc` + _FAST_MUL_EN_ + _FAST_SHIFT_EN_ | 22008 bytes | 90.91 | **0.9091**
| CPU | CoreMark Score | CoreMarks/Mhz | Average CPI
| _small_ (`rv32i_Zicsr`) | 33.89 | **0.3389** | **4.04**
| _medium_ (`rv32imc_Zicsr`) | 62.50 | **0.6250** | **5.34**
| _performance_(`rv32imc_Zicsr` + perf. options) | 95.23 | **0.9523** | **3.54**
|=======================
 
[NOTE]
All executable were generated using maximum optimization `-O3`.
The _FAST_MUL_EN_ configuration uses DSPs for the multiplier of the _M_ extension (enabled via the
_FAST_MUL_EN_ generic). The _FAST_SHIFT_EN_ configuration uses a barrel shifter for CPU shift
operations (enabled via the _FAST_SHIFT_EN_ generic).
The "_performance_" CPU configuration uses the <<_fast_mul_en>> and <<_fast_shift_en>> options.
 
 
<<<
:sectnums:
==== Instruction Timing
 
[NOTE]
The NEORV32 CPU is based on a multi-cycle architecture. Each instruction is executed in a sequence of
several consecutive micro operations. Hence, each instruction requires several clock cycles to execute.
several consecutive micro operations.
 
[NOTE]
The average CPI (cycles per instruction) depends on the instruction mix of a specific applications and also on
the available CPU extensions. The following table shows the performance results for successfully (!) running
2000 CoreMark iterations.
the available CPU extensions. The average CPI is computed by dividing the total number of required clock cycles
(only the timed core to avoid distortion due to IO wait cycles) by the number of executed instructions
(`[m]instret[h]` CSRs).
 
The average CPI is computed by dividing the total number of required clock cycles (only the timed core to
avoid distortion due to IO wait cycles) by the number of executed instructions (`[m]instret[h]` CSRs). The
executables were generated using optimization `-O3`.
 
[cols="<2,<8"]
[grid="topbot"]
|=======================
| Hardware version: | `1.4.9.8`
|=======================
 
.CoreMark instruction timing
[cols="<4,>2,>2,>2"]
[options="header",grid="rows"]
|=======================
| CPU (incl. `Zicsr`) | Required clock cycles | Executed instruction | Average CPI
| `rv32i` | 5595750503 | 1466028607 | **3.82**
| `rv32im` | 2966086503 | 598651143 | **4.95**
| `rv32imc` | 2981786734 | 611814918 | **4.87**
| `rv32imc` + _FAST_MUL_EN_ | 2399234734 | 611814918 | **3.92**
| `rv32imc` + _FAST_MUL_EN_ + _FAST_SHIFT_EN_ | 2265135174 | 611814948 | **3.70**
|=======================
 
[TIP]
The _FAST_MUL_EN_ configuration uses DSPs for the multiplier of the M extension (enabled via the
_FAST_MUL_EN_ generic). The _FAST_SHIFT_EN_ configuration uses a barrel shifter for CPU shift
operations (enabled via the _FAST_SHIFT_EN_ generic).
 
[TIP]
More information regarding the execution time of each implemented instruction can be found in
chapter <<_instruction_timing>>.
 
/trunk/docs/datasheet/soc.adoc
34,12 → 34,14
:sectnums:
=== Processor Top Entity - Signals
 
The following table shows all interface ports of the processor top entity (`rtl/core/neorv32_top.vhd`).
The type of all signals is _std_ulogic_ or _std_ulogic_vector_, respectively.
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.
 
[TIP]
A wrapper for the NEORV32 Processor setup providing resolved port signals can be found in
`rtl/templates/processor/neorv32_ProcessorTop_stdlogic.vhd`.
[IMPORTAN]
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.
 
[cols="<3,^2,^2,<11"]
[options="header",grid="rows"]
110,10 → 112,10
4+^| **<<_processor_interrupts, External Interrupts>>**
| `xirq_i` | 32 | in | external interrupt requests (up to 32 channels)
4+^| **<<_processor_interrupts, CPU Interrupts>>**
| `nm_irq_i` | 1 | in | non-maskable interrupt
| `mtime_irq_i` | 1 | in | machine timer interrupt13 (RISC-V)
| `msw_irq_i` | 1 | in | machine software interrupt (RISC-V)
| `mext_irq_i` | 1 | in | machine external interrupt (RISC-V)
| `nm_irq_i` | 1 | in | non-maskable interrupt, rising-edge-triggered
| `mtime_irq_i` | 1 | in | machine timer interrupt13 (RISC-V), rising-edge-triggered
| `msw_irq_i` | 1 | in | machine software interrupt (RISC-V), rising-edge-triggered
| `mext_irq_i` | 1 | in | machine external interrupt (RISC-V), rising-edge-triggered
|=======================
 
 
169,7 → 171,7
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **CLOCK_FREQUENCY** | _natural_ | 0
| **CLOCK_FREQUENCY** | _natural_ | _none_
3+| The clock frequency of the processor's `clk_i` input port in Hertz (Hz).
|======
 
180,7 → 182,7
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **INT_BOOTLOADER_EN** | _boolean_ | true
| **INT_BOOTLOADER_EN** | _boolean_ | false
3+| Implement the processor-internal boot ROM, pre-initialized with the default bootloader image when _true_.
This will also change the processor's boot address from the beginning of the instruction memory address space (default =
0x00000000) to the base address of the boot ROM. See section <<_boot_configuration>> for more information.
377,14 → 379,28
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **CPU_CNT_WIDTH** | _natural_ | 0
| **CPU_CNT_WIDTH** | _natural_ | 64
3+| This generic configures the total size of the CPU's `cycle` and `instret` CSRs (low word + high word).
The maximum value is 64, the minimal is 0. See
section <<_machine_counters_and_timers>> for more information. Note: Configurations with <<_cpu_cnt_width>>
less than 64 are not RISC-V compliant.
The maximum value is 64, the minimum value is 0. See
section <<_machine_counters_and_timers>> for more information. Note: configurations with <<_cpu_cnt_width>>
less than 64 bits do not comply to the RISC-V specs.
|======
 
 
:sectnums!:
===== _CPU_IPB_ENTRIES_
 
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **CPU_IPB_ENTRIES** | _natural_ | 2
3+| This generic configures the number of entries in the CPU's instruction prefetch buffer (a FIFO).
The value has to be a power of two and has to be greater than zero.
Long linear sequences of code can benefit from an increased IPB size. For setups that use the instruction
cache (<<_icache_en>>) this generic should be set to 1.
|======
 
 
// ####################################################################################################################
:sectnums:
==== Physical Memory Protection (PMP)
462,7 → 478,7
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **MEM_INT_IMEM_EN** | _boolean_ | true
| **MEM_INT_IMEM_EN** | _boolean_ | false
3+| Implement processor internal instruction memory (IMEM) when _true_.
|======
 
491,7 → 507,7
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **MEM_INT_DMEM_EN** | _boolean_ | true
| **MEM_INT_DMEM_EN** | _boolean_ | false
3+| Implement processor internal data memory (DMEM) when _true_.
|======
 
590,6 → 606,41
|======
 
 
:sectnums!:
===== _MEM_EXT_PIPE_MODE_
 
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **MEM_EXT_PIPE_MODE** | _boolean_ | false
3+| Use _standard_ ("classic") Wishbone protocol for external bus when _false_; use _pipelined_ Wishbone protocol when _true_.
|======
 
 
:sectnums!:
===== _MEM_EXT_BIG_ENDIAN_
 
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **MEM_EXT_BIG_ENDIAN** | _boolean_ | false
3+| Use BIG endian interface for external bus when _true_; use little endian interface when _false_.
|======
 
 
:sectnums!:
===== _MEM_EXT_ASYNC_RX_
 
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **MEM_EXT_ASYNC_RX** | _boolen_ | false
3+| By default, _MEM_EXT_ASYNC_RX_ = _false_ implements a registered read-back path (RX) for incoming data in the bus interface
in order to shorten the critical path. By setting _MEM_EXT_ASYNC_RX_ = _true_ an _asynchronous_ ("direct") read-back path is
implemented reducing access latency by one cycle.
|======
 
 
// ####################################################################################################################
:sectnums:
==== Stream Link Interface
696,7 → 747,7
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_GPIO_EN** | _boolean_ | true
| **IO_GPIO_EN** | _boolean_ | false
3+| Implement general purpose input/output port unit (GPIO) when _true_.
See section <<_general_purpose_input_and_output_port_gpio>> for more information.
|======
708,7 → 759,7
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_MTIME_EN** | _boolean_ | true
| **IO_MTIME_EN** | _boolean_ | false
3+| Implement machine system timer (MTIME) when _true_.
See section <<_machine_system_timer_mtime>> for more information.
|======
720,7 → 771,7
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_UART0_EN** | _boolean_ | true
| **IO_UART0_EN** | _boolean_ | false
3+| Implement primary universal asynchronous receiver/transmitter (UART0) when _true_.
See section <<_primary_universal_asynchronous_receiver_and_transmitter_uart0>> for
more information.
733,7 → 784,7
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_UART1_EN** | _boolean_ | true
| **IO_UART1_EN** | _boolean_ | false
3+| Implement secondary universal asynchronous receiver/transmitter (UART1) when _true_.
See section <<_secondary_universal_asynchronous_receiver_and_transmitter_uart1>> for more information.
|======
745,7 → 796,7
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_SPI_EN** | _boolean_ | true
| **IO_SPI_EN** | _boolean_ | false
3+| Implement serial peripheral interface controller (SPI) when _true_.
See section <<_serial_peripheral_interface_controller_spi>> for more information.
|======
757,7 → 808,7
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_TWI_EN** | _boolean_ | true
| **IO_TWI_EN** | _boolean_ | false
3+| Implement two-wire interface controller (TWI) when _true_.
See section <<_two_wire_serial_interface_controller_twi>> for
more information.
770,7 → 821,7
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_PWM_NUM_CH** | _natural_ | 4
| **IO_PWM_NUM_CH** | _natural_ | 0
3+| Number of pulse-width modulation (PWM) channels (0..60) to implement. The PWM controller is _not_ implemented if zero.
See section <<_pulse_width_modulation_controller_pwm>> for more information.
|======
782,7 → 833,7
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_WDT_EN** | _boolean_ | true
| **IO_WDT_EN** | _boolean_ | false
3+| Implement watchdog timer (WDT) when _true_. See section <<_watchdog_timer_wdt>> for more
information.
|======
850,12 → 901,25
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_NEOLED_EN** | _boolean_ | true
| **IO_NEOLED_EN** | _boolean_ | false
3+| Implement smart LED interface (WS2812 / NeoPixel(TM)-compatible) (NEOLED) when _true_.
See section <<_smart_led_interface_neoled>> for more information.
|======
 
 
:sectnums!:
===== _IO_NEOLED_TX_FIFO_
 
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **IO_NEOLED_TX_FIFO** | _natural_ | 1
3+| TX FIFO depth of the the NEOLED module. Minimal value is 1, maximal value is 32k, has to be a power of two.
See section <<_smart_led_interface_neoled>> for more information.
|======
 
 
 
<<<
// ####################################################################################################################
:sectnums:
867,7 → 931,7
:sectnums:
==== RISC-V Standard Interrupts
 
The processor setup features the standard RISC-V interrupt lines for "machine timer interrupt", "machine
The processor setup features the standard machine-level RISC-V interrupt lines for "machine timer interrupt", "machine
software interrupt" and "machine external interrupt". Their usage is defined by the RISC-V privileged architecture
specifications. However, bare-metal system can also repurpose these interrupts. See CPU section
<<_traps_exceptions_and_interrupts>> for more information.
881,8 → 945,8
| `mext_irq_i` | 1 | Machine external interrupt. This interrupt is used for any processor-external interrupt source (like a platform interrupt controller).
|=======================
 
[NOTE]
These IRQs trigger on high-level.
[IMPORTANT]
These IRQs trigger on a **rising-edge**.
 
 
:sectnums:
899,8 → 963,8
entity signal that can be used to signal _critical system conditions_. This interrupt source _cannot_ be masked/disabled.
See CPU section <<_traps_exceptions_and_interrupts>> for more information.
 
[NOTE]
This IRQ triggers on high-level.
[IMPORTANT]
This IRQ triggers on a **rising-edge**.
 
 
:sectnums:
918,7 → 982,7
fast interrupt request so a software handler is required to differentiate / prioritize these interrupts.
 
[NOTE]
The trigger for these interrupt can be defines via generics. See section
The trigger for these interrupt can be defined via generics. See section
<<_external_interrupt_controller_xirq>> for more information.
 
 
949,7 → 1013,7
| 9 | <<_smart_led_interface_neoled,NEOLED>> | NEOLED buffer TX empty / not full interrupt
| 10 | <<_stream_link_interface_slink,SLINK>> | RX data received
| 11 | <<_stream_link_interface_slink,SLINK>> | TX data send
| 12:15 | - | _reserved_, cannot fire
| 12:15 | - | _reserved_, will never fire
|=======================
 
 
/trunk/docs/datasheet/soc_neoled.adoc
8,8 → 8,9
| Hardware source file(s): | neorv32_neoled.vhd |
| Software driver file(s): | neorv32_neoled.c |
| | neorv32_neoled.h |
| Top entity port: | `neoled_o` | 1-bit serial data
| Configuration generics: | _IO_NEOLED_EN_ | implement NEOLED when _true_
| Top entity port: | `neoled_o` | 1-bit serial data output
| Configuration generics: | _IO_NEOLED_EN_ | implement NEOLED when _true_
| | _IO_NEOLED_TX_FIFO_ | TX FIFO depth (1..32k, has to be a power of two)
| CPU interrupts: | fast IRQ channel 9 | NEOLED interrupt (see <<_processor_interrupts>>)
|=======================
 
25,14 → 26,39
The NEOLED interface is compatible to the "Adafruit Industries NeoPixel" products, which feature
WS2812 (or older WS2811) smart LEDs (see link:https://learn.adafruit.com/adafruit-neopixel-uberguide).
 
The interface provides a single 1-bit output `neoled_o` to drive an arbitrary number of LEDs. Since the
The interface provides a single 1-bit output `neoled_o` to drive an arbitrary number of cascaded LEDs. Since the
NEOLED module provides 24-bit and 32-bit operating modes, a mixed setup with RGB LEDs (24-bit color)
and RGBW LEDs (32-bit color including a dedicated white LED chip) is also possible.
and RGBW LEDs (32-bit color including a dedicated white LED chip) is possible.
 
**Theory of Operation – NEOLED Module**
 
The NEOLED modules provides two accessible interface registers: the control register _NEOLED_CT_ and the
TX data register _NEOLED_DATA_. The NEOLED module is globally enabled via the control register's
_NEOLED_CT_EN_ bit. Clearing this bit will terminate any current operation, clear the TX buffer, reset the module
and set the `neoled_o` output to zero. The precise timing (implementing the **WS2812** protocol) and transmission
mode are fully programmable via the _NEOLED_CT_ register to provide maximum flexibility.
 
 
**RGB / RGBW Configuration**
 
NeoPixel are available in two "color" version: LEDs with three chips providing RGB color and LEDs with
four chips providing RGB color plus a dedicated white LED chip (= RGBW). Since the intensity of every
LED chip is defined via an 8-bit value the RGB LEDs require a frame of 24-bit per module and the RGBW
LEDs require a frame of 32-bit per module.
 
The data transfer quantity of the NEOLED module can be configured via the _NEOLED_MODE_EN_ control
register bit. If this bit is cleared, the NEOLED interface operates in 24-bit mode and will transmit bits `23:0` of
the data written to _NEOLED_DATA_ to the LEDs. If _NEOLED_MODE_EN_ is set, the NEOLED interface operates in 32-bit
mode and will transmit bits `31:0` of the data written to _NEOLED_DATA_ to the LEDs.
 
The mode bit can be configured before writing each new data word in order to support
an arbitrary setup of RGB and RGBW LEDs.
 
 
**Theory of Operation – Protocol**
 
The interface of the WS2812 LEDs uses an 800kHz carrier signal. Data is transmitted in a serial manner
starting with LSB-first. The intensity for each R, G & B LED chip (= color code) is defined via an 8-bit
starting with LSB-first. The intensity for each R, G & B (& W) LED chip (= color code) is defined via an 8-bit
value. The actual data bits are transferred by modifying the duty cycle of the signal (the timings for the
WS2812 are shown below). A RESET command is "send" by pulling the data line LOW for at least 50μs.
 
51,14 → 77,7
| RESET | Above 50μs | low-time for sending a RESET command
|=======================
 
**Theory of Operation – NEOLED Module**
 
The NEOLED modules provides two accessible interface register: the control register _NEOLED_CT_ and the
TX data register _NEOLED_DATA_. The NEOLED module is globally enabled via the control register's
_NEOLED_CT_EN_ bit. Clearing this bit will terminate any current operation, reset the module and
set the `neoled_o` output to zero. The precise timing (implementing the **WS2812** protocol) and transmission
mode are fully programmable via the _NEOLED_CT_ register to provide maximum flexibility.
 
**Timing Configuration**
 
The basic carrier frequency (800kHz for the WS2812 LEDs) is configured via a 3-bit main clock prescaler (_NEOLED_CT_PRSCx_, see table below)
77,6 → 96,7
timing constants allow to adapt the interface for a wide variety of smart LED protocol (for example WS2812 vs.
WS2811).
 
 
**Timing Configuration – Example (WS2812)**
 
Generate the base clock f~TX~ for the NEOLED TX engine:
103,64 → 123,56
[TIP]
The NEOLED SW driver library (`neorv32_neoled.h`) provides a simplified configuration
function that configures all timing parameters for driving WS2812 LEDs based on the processor
clock configuration.
clock frequency.
 
**RGB / RGBW Configuration**
 
NeoPixel are available in two "color" version: LEDs with three chips providing RGB color and LEDs with
four chips providing RGB color plus a dedicated white LED chip (= RGBW). Since the intensity of every
LED chip is defined via an 8-bit value the RGB LEDs require a frame of 24-bit per module and the RGBW
LEDs require a frame of 32-bit per module.
 
The data transfer quantity of the NEOLED module can be configured via the _NEOLED_MODE_EN_ control
register bit. If this bit is cleared, the NEOLED interface operates in 24-bit mode and will transmit bits `23:0` of
the data written to _NEOLED_DATA_. If _NEOLED_MODE_EN_ is set, the NEOLED interface operates in 32-bit
mode and will transmit bits `31:0` of the data written to _NEOLED_DATA_.
 
**TX Data FIFO**
 
The interface features a TX data buffer (a FIFO) to allow CPU-independent operation. The buffer depth
is configured via the `tx_buffer_entries_c` constant (default = 4 entries) in the module's VHDL source
file `rtl/core/neorv32_neoled.vhd`. The current configuration can be read via the _NEOLED_CT_BUFS_x_
control register bits, which result log2(`tx_buffer_entries_c`).
The interface features a TX data buffer (a FIFO) to allow more CPU-independent operation. The buffer depth
is configured via the _IO_NEOLED_TX_FIFO_ top generic (default = 1 entry).
The FIFO size configuration can be read via the _NEOLED_CT_BUFS_x_
control register bits, which result log2(_IO_NEOLED_TX_FIFO_).
 
When writing data to the _NEOLED_DATA_ register the data is automatically written to the TX buffer. Whenever
data is available in the buffer the serial transmission engine will take it and transmit it to the LEDs.
 
The data transfer size (_NEOLED_MODE_EN_) can be modified at every time since this control register bit is also buffered
in the FIFO. This allows to arbitrarily mixing RGB and RGBW LEDs in the chain.
 
Software can check the FIFO fill level via the control register's _NEOLED_CT_TX_EMPTY_, _NEOLED_CT_TX_HALF_
and _NEOLED_CT_TX_FULL_ flags. The _NEOLED_CT_TX_BUSY_ flags provides additional information if the the TX unit is
still busy sending data.
 
[WARNING]
Please note that the timing configurations (_NEOLED_CT_PRSCx_, _NEOLED_CT_T_TOT_x_,
_NEOLED_CT_T_ONE_H_x_ and _NEOLED_CT_T_ZERO_H_x_) are NOT stored to the buffer. Changing
these value while the buffer is not empty or the TX engine is still sending will cause data corruption.
_NEOLED_CT_T_ONE_H_x_ and _NEOLED_CT_T_ZERO_H_x_) are **NOT** stored to the buffer. Changing
these value while the buffer is not empty or the TX engine is still busy will cause data corruption.
 
**Status Configuration**
 
The NEOLED modules features two read-only status bits in the control register: _NEOLED_CT_BUSY_ and
_NEOLED_CT_TX_STATUS_.
** Strobe Command ("RESET") **
 
If the _NEOLED_CT_TX_STATUS_ is set the serial TX engine is still busy sending serial data to the LED stripes.
If the flag is cleared, the TX engine is idle and the serial data output `neoled_o` is set LOW.
According to the WS2812 specs the data written to the LED's shift registers is strobed to the actual PWM driver
registers when the data line is low for 50μs ("RESET" command, see table above). This can be implemented
using busy-wait for at least 50μs. Obviously, this concept wastes a lot of processing power.
 
The _NEOLED_CT_BUSY_ flag provides a programmable option to check for the TX buffer state. The control
register's _NEOLED_CT_BSCON_ bit is used to configure the "meaning" of the _NEOLED_CT_BUSY_ flag. The
condition for sending an interrupt request (IRQ) to the CPU is also configured via the _NEOLED_CT_BSCON_
bit.
To circumvent this, the NEOLED module provides an option to automatically issue an idle time for creating the RESET
command. If the _NEOLED_CT_STROBE_ control register bit is set, _all_ data written to the data FIFO (via _NEOLED_DATA_,
the actually written data is irrelevant) will trigger an idle phase (`neoled_o` = zero) of 127 periods (= _**T~carrier~**_).
This idle time will cause the LEDs to strobe the color data into the PWM driver registers.
 
[cols="^5,^8,^8"]
[options="header",grid="all"]
|=======================
| _NEOLED_CT_BSCON_ | _NEOLED_CT_BUSY_ | Sending an IRQ when ...
| 0 | the busy flag will clear if there **IS at least one free entry** in the TX buffer | the IRQ will fire if **at least one entry GETS free** in the TX buffer
| 1 | the busy flag will clear if the **whole TX buffer IS empty** | the IRQ will fire if the **whole TX buffer GETS empty**
|=======================
Since the _NEOLED_CT_STROBE_ flag is also buffered in the TX buffer, the RESET command is treated as just another
data word being written to the TX buffer making busy wait concepts obsolete and allowing maximum refresh rates.
 
When _NEOLED_CT_BSCON_ is set, the CPU can write up to `tx_buffer_entries_c` of new data words to
_NEOLED_DATA_ without checking the busy flag _NEOLED_CT_BUSY_. This highly relaxes time constraints for
sending a continuous data stream to the LEDs (as an idle time beyond 50μs will trigger the LED's a RESET
command).
 
**Interrupt**
 
The NEOLED modules features a single interrupt that is triggered whenever the TX FIFO's fill level
falls below _half-full_ level. In this case software can write up to _IO_NEOLED_TX_FIFO_/2 new data
words to _NEOLED_DATA_ without checking the FIFO status flags.
 
This highly relaxes time constraints for sending a continuous data stream to the LEDs
(as an idle time beyond 50μs will trigger the LED's a RESET command).
 
 
<<<
.NEOLED register map
[cols="<4,<5,<9,^2,<9"]
167,17 → 179,17
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.22+<| `0xffffffd8` .22+<| _NEOLED_CT_ <|`0` _NEOLED_CT_EN_ ^| r/w <| NEOLED enable
.25+<| `0xffffffd8` .25+<| _NEOLED_CT_ <|`0` _NEOLED_CT_EN_ ^| r/w <| NEOLED enable
<|`1` _NEOLED_CT_MODE_ ^| r/w <| data transfer size; `0`=24-bit; `1`=32-bit
<|`2` _NEOLED_CT_BSCON_ ^| r/w <| busy flag / IRQ trigger configuration (see table above)
<|`2` _NEOLED_CT_STROBE_ ^| r/w <| `0`=send normal color data; `1`=send RESET command on data write access
<|`3` _NEOLED_CT_PRSC0_ ^| r/w <| 3-bit clock prescaler, bit 0
<|`4` _NEOLED_CT_PRSC1_ ^| r/w <| 3-bit clock prescaler, bit 1
<|`5` _NEOLED_CT_PRSC2_ ^| r/w <| 3-bit clock prescaler, bit 2
<|`6` _NEOLED_CT_BUFS0_ ^| r/- .4+<| 4-bit log2(`tx_buffer_entries_c`)
<|`6` _NEOLED_CT_BUFS0_ ^| r/- .4+<| 4-bit log2(_IO_NEOLED_TX_FIFO_)
<|`7` _NEOLED_CT_BUFS1_ ^| r/-
<|`8` _NEOLED_CT_BUFS2_ ^| r/-
<|`9` _NEOLED_CT_BUFS3_ ^| r/-
<|`10` _NEOLED_CT_T_TOT_0_ ^| r/w .5+| 5-bit pulse clock ticks per total single-bit period (T~total~)
<|`10` _NEOLED_CT_T_TOT_0_ ^| r/w .5+<| 5-bit pulse clock ticks per total single-bit period (T~total~)
<|`11` _NEOLED_CT_T_TOT_1_ ^| r/w
<|`12` _NEOLED_CT_T_TOT_2_ ^| r/w
<|`13` _NEOLED_CT_T_TOT_3_ ^| r/w
188,6 → 200,9
<|`23` _NEOLED_CT_ONE_H_3_ ^| r/w
<|`24` _NEOLED_CT_ONE_H_4_ ^| r/w
<|`30` _NEOLED_CT_TX_STATUS_ ^| r/- <| transmit engine busy when `1`
<|`31` _NEOLED_CT_BUSY_ ^| r/- <| busy / buffer status flag; configured via _NEOLED_CT_BSCON_ (see table above)
<|`31` _NEOLED_CT_TX_EMPTY_ ^| r/- <| TX FIFO is empty
<|`31` _NEOLED_CT_TX_HALF_ ^| r/- <| TX FIFO is _at least_ half full
<|`31` _NEOLED_CT_TX_FULL_ ^| r/- <| TX FIFO is full
<|`31` _NEOLED_CT_TX_BUSY_ ^| r/- <| TX serial engine is busy when set
| `0xffffffdc` | _NEOLED_DATA_ <|`31:0` / `23:0` ^| -/w <| TX data (32-/24-bit)
|=======================
/trunk/docs/datasheet/soc_slink.adoc
18,8 → 18,8
| | _SLINK_NUM_RX_ | Number of RX links to implement (0..8)
| | _SLINK_TX_FIFO_ | FIFO depth (1..32k) of TX links, has to be a power of two
| | _SLINK_RX_FIFO_ | FIFO depth (1..32k) of RX links, has to be a power of two
| CPU interrupts: | fast IRQ channel 10 | RX data available (see <<_processor_interrupts>>)
| | fast IRQ channel 11 | TX data send (see <<_processor_interrupts>>)
| CPU interrupts: | fast IRQ channel 10 | SLINK RX IRQ (see <<_processor_interrupts>>)
| | fast IRQ channel 11 | SLINK TX IRQ (see <<_processor_interrupts>>)
|=======================
 
The SLINK component provides up to 8 independent RX (receiving) and TX (sending) links for transmitting
41,32 → 41,37
[NOTE]
The SLINK interface does not provide any additional tag signals (for example to define a "stream destination
address" or to indicate the last data word of a "package"). Use a custom controller connected
via the external memory bus interface or the processor's GPIO ports to implement custom data tags.
via the external memory bus interface or use some of the processor's GPIO ports to implement custom data
tag signals.
 
**Theory of Operation**
 
The SLINK is activated by setting the control register's (_SLINK_CT_) enable bit _SLINK_CT_EN_.
The SLINK provides eight data registers (_SLINK_CHx_) to access the links (read accesses will access the RX links, write
accesses will access the TX links), one control register (_SLINK_CT_) and one status register (_SLINK_STATUS_).
 
The SLINK is globally activated by setting the control register's enable bit _SLINK_CT_EN_.
The actual data links are accessed by reading or writing the according link data registers _SLINK_CH0_
to _SLINK_CH7_. For example, writing the _SLINK_CH0_ will put the according data into the FIFO of TX link 0.
Accordingly, reading from _SLINK_CH0_ will return one data word from the FIFO of RX link 0.
 
The FIFO status of each RX and TX link is available via read-only bits in the device's control register.
Bits _SLINK_CT_TX0_FREE_ to _SLINK_CT_TX7_FREE_ indicate if the FIFO of the according TX link can take another
data word. Bits _SLINK_CT_RX0_AVAIL_ to _SLINK_CT_RX7_AVAIL_ indicate if the FIFO of the according RX link
contains another data word.
The configuration (done via the SLINK generics) can be checked by software by evaluating bit fields in the
control register. The _SLINK_CT_TX_FIFO_Sx_ and _SLINK_CT_RX_FIFO_Sx_ indicate the TX & RX FIFO sizes.
The _SLINK_CT_TX_NUMx_ and _SLINK_CT_RX_NUMx_ bits represent the absolute number of implemented TX and RX links.
 
The _SLINK_CT_TX_FIFO_Sx_ and _SLINK_CT_RX_FIFO_Sx_ bits allow software to determine the total TX & RX FIFO sizes.
The _SLINK_CT_TX_NUMx_ and _SLINK_CT_RX_NUMx_ bits represent the absolute number of implemented TX and RX links
with an offset of "-1" (`0b000` = 1 link implemented, ..., `0b111` = 8 links implemented.
The status register shows the FIFO status flags of each RX and TX link. The _SLINK_CT_RXx_AVAIL_ flags indicate
that there is _at least_ one data word in the according RX link's FIFO. The _SLINK_CT_TXx_FREE_ flags indicate
there is _at least_ one free entry in the according TX link's FIFO. The _SLINK_STATUS_RXx_HALF_ and
_SLINK_STATUS_RXx_HALF_ flags show if a certain FIFO's fill level has exceeded half of its capacity.
 
 
**Blocking Link Access**
 
When directly accessing the link data registers (without checking the according FIFO status flags) the access
might be executed as _blocking_. That means the CPU access will stall until the accessed link responds. For
example, when reading RX link 0 (via _SLINK_CH0_ register) the CPU access will stall, if there is not data
available in the according FIFO. The CPU access will complete as soon as RX link0 receives new data.
is as _blocking_. That means the CPU access will stall until the accessed link responds. For
example, when reading RX link 0 (via _SLINK_CH0_ register) the CPU will stall, if there is not data
available in the according FIFO yet. The CPU access will complete as soon as RX link 0 receives new data.
 
Vice versa, writing data to TX link 0 (via _SLINK_CH0_ register) might stall the CPU access until there is
Vice versa, writing data to TX link 0 (via _SLINK_CH0_ register) will stall the CPU access until there is
at least one free entry in the link's FIFO.
 
[WARNING]
73,27 → 78,38
The NEORV32 processor ensures that _any_ CPU access to memory-mapped devices (including the SLINK module)
will **time out** after a certain number of cycles (see section <<_bus_interface>>).
Hence, blocking access to a stream link that does not complete within a certain amount of cycles will
raise a _store bus access exception_ when writing a TX link or a _load bus access exception_ when reading
an RX link.
raise a _store bus access exception_ when writing a _full_ TX link or a _load bus access exception_ when reading
from an _empty_ RX link. Hence, this concept should only be used when evaluating the half-full FIFO condition
(for example via the SLINK interrupts) before actual accessing links.
 
**Non-Blocking Link Access**
 
For a non-blocking link access concept, the FIFO status signal in _SLINK_CT_ needs to be checked before
For a non-blocking link access concept, the FIFO status flags in _SLINK_STATUS_ need to be checked _before_
reading/writing the actual link data register. For example, a non-blocking write access to a TX link 0 has
to check _SLINK_CT_TX0_FREE_ first. If the bit is set, the FIFO of TX link 0 can take another data word
to check _SLINK_STATUS_TX0_FREE_ first. If the bit is set, the FIFO of TX link 0 can take another data word
and the actual data can be written to _SLINK_CH0_. If the bit is cleared, the link's FIFO is full
and the status flag can be polled until it indicates free space in the FIFO.
and the status flag can be polled until it there is free space in the available.
 
This concept will not raise any exception as there is no "direct" access to the link data registers.
However, non-blocking accesses require additional instruction to check the according status flags prior
to the actual link access, which will reduce performance for high-bandwidth data stream.
However, non-blocking accesses require additional instructions to check the according status flags prior
to the actual link access, which will reduce performance for high-bandwidth data streams.
 
**Interrupts**
 
The stream interface provides two interrupts that are _globally_ driven by the RX and TX link's
FIFO level status. If the FIFO of **any** TX link _was full_ and _becomes empty_ again, the TX interrupt fires.
FIFO fill level status. The behavior of these interrupts differs if the FIFO depth is exactly 1 (minimal)
or if it is greater than 1.
 
When _SLINK_*X_FIFO_ is 1 a TX interrupt will fire if **any** TX link _was full_ and _becomes empty_ again.
Accordingly, if the FIFO of **any** RX link _was empty_ and a _new data word_ appears in it, the RX interrupt fires.
 
When _SLINK_*X_FIFO_ is greater than 1 the TX interrupt will fire if _any_ TX link's FIFO _falls below_ half-full fill level.
Accordingly, the RX interrupt will fire if _any_ RX link's FIFO _exceeds_ half-full fill level.
 
The interrupt service handler has to evaluate the SLINK status register is order to detect which link(s) has caused the
interrupt. No further interrupt can fire until the CPU acknowledges the last interrupt by _reading the SLINK status register_.
However, further IRQ conditions are buffered and will trigger another interrupt after the current one has been acknowledged.
 
Note that these interrupts can only fire if the SLINK module is actually enabled by setting the
_SLINK_CT_EN_ bit in the unit's control register.
 
104,18 → 120,18
wide while entries in `slink_*x_val` and `slink_*x_rdy` are are just 1-bit wide.
 
The stream link protocol is based on a simple FIFO-like interface between a source (sender) and a sink (receiver).
Each link provides two signals for implementing a simple FIFO-style handshake. The `slink_*x_val` signal is set
if the according `slink_*x_dat` contains valid data. The stream source has to ensure that both signals remain
stable until the according `slink_*x_rdy` signal is set. This signal is set by the stream source to indicate it
can accept another data word.
Each link provides two signals for implementing a simple FIFO-style handshake. The `slink_*x_val` signal is set by
the source if the according `slink_*x_dat` (also set by the source) contains valid data. The stream source has to
ensure that both signals remain stable until the according `slink_*x_rdy` signal is set by the stream sink to
indicate it can accept another data word.
 
In summary, a data word is transferred if both `slink_*x_val` and `slink_*x_rdy` are high.
In summary, a data word is transferred if both `slink_*x_val(i)` and `slink_*x_rdy(i)` are high.
 
.Exemplary stream link transfer
image::stream_link_interface.png[width=560,align=center]
 
[TIP]
The SLINK handshake protocol is compatible to the AXI4-Stream base protocol.
The SLINK handshake protocol is compatible with the https://developer.arm.com/documentation/ihi0051/a/Introduction/About-the-AXI4-Stream-protocol[AXI4-Stream] base protocol.
 
.SLINK register map
[cols="^4,<5,^2,^2,<14"]
122,15 → 138,18
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s) | R/W | Function
.8+<| `0xfffffec0` .8+<| _SLINK_CT_ <| `31` _SLINK_CT_EN_ ^| r/w | SLINK global enable
<| `30` _reserved_ ^| r/- <| reserved, read as zero
<| `29:26` _SLINK_CT_TX_FIFO_S3_ : _SLINK_CT_TX_FIFO_S0_ ^| r/- <| TX links FIFO depth, log2 of_SLINK_TX_FIFO_ generic
<| `25:22` _SLINK_CT_RX_FIFO_S3_ : _SLINK_CT_RX_FIFO_S0_ ^| r/- <| RX links FIFO depth, log2 of_SLINK_RX_FIFO_ generic
<| `21:19` _SLINK_CT_TX_NUM2_ : _SLINK_CT_TX_NUM0_ ^| r/- <| Number of implemented TX links minus 1
<| `18:16` _SLINK_CT_RX_NUM2_ : _SLINK_CT_RX_NUM0_ ^| r/- <| Number of implemented RX links minus 1
<| `15:8` _SLINK_CT_TX7_FREE_ : _SLINK_CT_TX0_FREE_ ^| r/- <| At least one free TX FIFO entry available for link 0..7
<| `7:0` _SLINK_CT_RX7_AVAIL_ : _SLINK_CT_RX0_AVAIL_ ^| r/- <| At least one data word in RX FIFO available for link 0..7
| `0xfffffec4` : `0xfffffedc` | _SLINK_CT_ |`31:0` | | _mirrored control register_
.6+<| `0xfffffec0` .6+<| _SLINK_CT_ <| `31` _SLINK_CT_EN_ ^| r/w | SLINK global enable
<| `30:16` _reserved_ ^| r/- <| reserved, read as zero
<| `15:12` _SLINK_CT_TX_FIFO_S3_ : _SLINK_CT_TX_FIFO_S0_ ^| r/- <| TX links FIFO depth, log2 of_SLINK_TX_FIFO_ generic
<| `11:8` _SLINK_CT_RX_FIFO_S3_ : _SLINK_CT_RX_FIFO_S0_ ^| r/- <| RX links FIFO depth, log2 of_SLINK_RX_FIFO_ generic
<| `7:4` _SLINK_CT_TX_NUM3_ : _SLINK_CT_TX_NUM0_ ^| r/- <| Number of implemented TX links
<| `3:0` _SLINK_CT_RX_NUM3_ : _SLINK_CT_RX_NUM0_ ^| r/- <| Number of implemented RX links
| `0xfffffec4` : `0xfffffeec` | _SLINK_CT_ |`31:0` | | _mirrored control register_
.4+<| `0xfffffed0` .4+<| _SLINK_STATUS_ <| `31:24` _SLINK_STATUS_TX7_HALF_ : _SLINK_STATUS_TX0_HALF_ ^| r/- | TX link 7..0 FIFO fill level is > half-full
<| `23:16` _SLINK_STATUS_RX7_HALF_ : _SLINK_STATUS_RX0_HALF_ ^| r/- <| RX link 7..0 FIFO fill level is >= half-full
<| `15:8` _SLINK_CT_TX7_FREE_ : _SLINK_CT_TX0_FREE_ ^| r/- <| At least one free TX FIFO entry available for link 7..0
<| `7:0` _SLINK_CT_RX7_AVAIL_ : _SLINK_CT_RX0_AVAIL_ ^| r/- <| At least one data word in RX FIFO available for link 7..0
| `0xfffffed4` : `0xfffffedc` | _SLINK_STATUS_ |`31:0` | | _mirrored status register_
| `0xfffffee0` | _SLINK_CH0_ | `31:0` | r/w | Link 0 RX/TX data
| `0xfffffee4` | _SLINK_CH1_ | `31:0` | r/w | Link 1 RX/TX data
| `0xfffffee8` | _SLINK_CH2_ | `31:0` | r/w | Link 2 RX/TX data
/trunk/docs/datasheet/soc_sysinfo.adoc
46,7 → 46,7
| `1` | _SYSINFO_FEATURES_MEM_EXT_ | set if the external Wishbone bus interface is implemented (via top's _MEM_EXT_EN_ generic)
| `2` | _SYSINFO_FEATURES_MEM_INT_IMEM_ | set if the processor-internal DMEM implemented (via top's _MEM_INT_DMEM_EN_ generic)
| `3` | _SYSINFO_FEATURES_MEM_INT_DMEM_ | set if the processor-internal IMEM is implemented (via top's _MEM_INT_IMEM_EN_ generic)
| `4` | _SYSINFO_FEATURES_MEM_EXT_ENDIAN_ | set if external bus interface uses BIG-endian byte-order (via package's `wb_big_endian_c` constant)
| `4` | _SYSINFO_FEATURES_MEM_EXT_ENDIAN_ | set if external bus interface uses BIG-endian byte-order (via top's _MEM_EXT_BIG_ENDIAN_ generic)
| `5` | _SYSINFO_FEATURES_ICACHE_ | set if processor-internal instruction cache is implemented (via _ICACHE_EN_ generic)
| `14` | _SYSINFO_FEATURES_HW_RESET_ | set if on-chip debugger implemented (via _ON_CHIP_DEBUGGER_EN_ generic)
| `15` | _SYSINFO_FEATURES_HW_RST_ | set if a dedicated hardware reset of all core registers is implemented (via package's _dedicated_reset_c_ constant)
/trunk/docs/datasheet/soc_uart.adoc
126,7 → 126,8
`uart0_txd_o`** at all. Furthermore, no interrupts (RX done or TX done) will be triggered in any situation.
 
[TIP]
More information regarding the simulation-mode of the UART0 can be found in section <<_simulating_the_processor>>.
More information regarding the simulation-mode of the UART0 can be found in the Uer Guide
section https://stnolting.github.io/neorv32/ug/#_simulating_the_processor[Simulating the Processor].
 
.UART0 register map
[cols="<6,<7,<10,^2,<18"]
/trunk/docs/datasheet/soc_wishbone.adoc
20,12 → 20,12
| | `wb_err_i` | bus error (1-bit)
| | `fence_o` | an executed `fence` instruction
| | `fencei_o` | an executed `fence.i` instruction
| Configuration generics: | _MEM_EXT_EN_ | enable external memory interface when _true_
| | _MEM_EXT_TIMEOUT_ | number of clock cycles after which an unacknowledged external bus access will auto-terminate (0 = disabled)
| Configuration constants in VHDL package file `neorv32_package.vhd`: | `wb_pipe_mode_c` | when _false_ (default): classic/standard Wishbone protocol; when _true_: pipelined Wishbone protocol
| | `wb_big_endian_c` | byte-order (Endianness) of external memory interface; true=BIG, false=little (default)
| | `wb_rx_buffer_c` | enable register buffer for RX path (default)
| CPU interrupts: | none |
| Configuration generics: | _MEM_EXT_EN_ | enable external memory interface when _true_
| | _MEM_EXT_TIMEOUT_ | number of clock cycles after which an unacknowledged external bus access will auto-terminate (0 = disabled)
| | _MEM_EXT_PIPE_MODE_ | when _false_ (default): classic/standard Wishbone protocol; when _true_: pipelined Wishbone protocol
| | _MEM_EXT_BIG_ENDIAN_ | byte-order (Endianness) of external memory interface; true=BIG, false=little (default)
| | _MEM_EXT_ASYNC_RX_ | use registered RX path when _false_ (default); use async/direct RX path when _true_
| CPU interrupts: | none |
|=======================
 
The external memory interface uses the Wishbone interface protocol. The external interface port is available
45,17 → 45,10
**Wishbone Bus Protocol**
 
The external memory interface either uses **standard** ("classic") Wishbone transactions (default) or
**pipelined** Wishbone transactions. The transaction protocol is configured via the wb_pipe_mode_c constant
in the in the main VHDL package file (`rtl/neorv32_package.vhd`):
**pipelined** Wishbone transactions. The transaction protocol is configured via the _MEM_EXT_PIPE_MODE_ generic:
 
[source,vhdl]
----
-- external bus interface --
constant wb_pipe_mode_c : boolean := false;
----
 
When `wb_pipe_mode_c` is disabled, all bus control signals including _STB_ are active (and stable) until the
transfer is acknowledged/terminated. If `wb_pipe_mode_c` is enabled, all bus control except _STB_ are active
When _MEM_EXT_PIPE_MODE_ is _false_, all bus control signals including _STB_ are active (and stable) until the
transfer is acknowledged/terminated. If _MEM_EXT_PIPE_MODE_ is _true_, all bus control except _STB_ are active
(and stable) until the transfer is acknowledged/terminated. In this case, _STB_ is active only during the very
first bus clock cycle.
 
82,15 → 75,9
via Wishbone requires 2 additional clock cycles (at least; depending on device's latency).
 
If the attached Wishbone network / peripheral already provides output registers or if the Wishbone network is not relevant
for timing closure, the default buffering of incoming ("RX") data within the gateway can be disabled.
The configuration is done via the `wb_rx_buffer_c` constant in the in the main VHDL package file (`rtl/neorv32_package.vhd`):
for timing closure, the default buffering of incoming ("RX") data within the gateway can be disabled by implementing an
"asynchronous" RX path. The configuration is done via the _MEM_EXT_ASYNC_RX_ generic.
 
[source,vhdl]
----
-- external bus interface --
constant wb_rx_buffer_c : boolean := false; -- false to implement "async" RX (non-default)
----
 
**Bus Access Timeout**
 
The Wishbone bus interface provides an option to configure a bus access timeout counter. The _MEM_EXT_TIMEOUT_
137,16 → 124,9
 
The NEORV32 CPU and the Processor setup are *little-endian* architectures. To allow direct connection
to a big-endian memory system the external bus interface provides an _Endianness configuration_. The
Endianness (of the external memory interface) can be configured via the global `wb_big_endian_c`
constant in the main VHDL package file (`rtl/neorv32_package.vhd`). By default, the external memory
interface uses little-endian byte-order.
Endianness (of the external memory interface) can be configured via the _MEM_EXT_BIG_ENDIAN_ generic.
By default, the external memory interface uses little-endian byte-order (like the rest of the processor / CPU).
 
[source,vhdl]
----
-- external bus interface --
constant wb_big_endian_c : boolean := true;
----
 
Application software can check the Endianness configuration of the external bus interface via the
_SYSINFO_FEATURES_MEM_EXT_ENDIAN_ flag in the processor's SYSINFO module (see section
<<_system_configuration_information_memory_sysinfo>> for more information).
/trunk/docs/datasheet/software.adoc
10,7 → 10,7
| Application/bootloader start-up code | `sw/common/crt0.S`
| Application/bootloader linker script | `sw/common/neorv32.ld`
| Core hardware driver libraries | `sw/lib/include/` & `sw/lib/source/`
| Makefiles | e.g. `sw/example/blink_led/makefile`
| Central makefile | `sw/common/common.mk`
| Auxiliary tool for generating NEORV32 executables | `sw/image_gen/`
| Default bootloader | `sw/bootloader/bootloader.c`
|=======================
89,15 → 89,16
:sectnums:
=== Application Makefile
 
Application compilation is based on **GNU makefiles**. Each project in the `sw/example` folder features
a makefile. All these makefiles are identical. When creating a new project, copy an existing project folder or
Application compilation is based on a single, centralized **GNU makefiles** `sw/common/common.mk`. Each project in the
`sw/example` folder features a makefile that just includes this central makefile. When creating a new project, copy an existing project folder or
at least the makefile to your new project folder. I suggest to create new projects also in `sw/example` to keep
the file dependencies. Of course, these dependencies can be manually configured via makefiles variables
when your project is located somewhere else.
 
[NOTE]
Before you can use the makefiles, you need to install the RISC-V GCC toolchain. Also, you have to add the
installation folder of the compiler to your system's `PATH` variable. More information can be found in chapter
<<_lets_get_it_started>>.
installation folder of the compiler to your system's `PATH` variable. More information can be found in
https://stnolting.github.io/neorv32/ug/#_software_toolchain_setup[User Guide: Software Toolchain Setup].
 
The makefile is invoked by simply executing make in your console:
 
109,32 → 110,39
:sectnums:
==== Targets
 
Just executing `make` will show the help menu showing all available targets. The following targets are
available:
Just executing `make` (or executing `make help`) will show the help menu listing all available targets.
 
[cols="<3,<15"]
[grid="none"]
|=======================
| `help` | Show a short help text explaining all available targets.
| `check` | Check the compiler toolchain. You should run this target at least once after installing the toolchain.
| `info` | Show the makefile configuration (see section <<_configuration>>).
| `exe` | Compile all sources and generate application executable for upload via bootloader.
| `install` | Compile all sources, generate executable (via exe target) for upload via bootloader and generate and install IMEM VHDL initialization image file `rtl/core/neorv32_application_image.vhd`.
| `all` | Execute `exe` and `install`.
| `clean` | Remove all generated files in the current folder.
| `clean_all` | Remove all generated files in the current folder and also removes the compiled core libraries and the compiled image generator tool.
| `bootloader` | Compile all sources, generate executable and generate and install BOOTROM VHDL initialization image file `rtl/core/neorv32_bootloader_image.vhd`. This target modifies the ROM origin and length in the linker script by setting the `make_bootloader` define.
| `upload` | Upload NEORV32 executable to the bootloader via serial port
|=======================
[source,makefile]
----
$ make
<<< NEORV32 Application Makefile >>>
Make sure to add the bin folder of RISC-V GCC to your PATH variable.
Targets:
help - show this text
check - check toolchain
info - show makefile/toolchain configuration
exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader
hex - compile and generate <neorv32_exe.hex> executable raw file
install - compile, generate and install VHDL IMEM boot image (for application)
all - exe + hex + install
elf_info - show ELF layout info
clean - clean up project
clean_all - clean up project, core libraries and image generator
bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)
----
 
[TIP]
An assembly listing file (`main.asm`) is created by the compilation flow for further analysis or debugging purpose.
 
:sectnums:
==== Configuration
 
The compilation flow is configured via variables right at the beginning of the makefile:
The compilation flow is configured via variables right at the beginning of the **central**
makefile (`sw/common/common.mk`):
 
[TIP]
The makefile configuration variables can be (re-)defined directly when invoking the makefile. For
example via `$ make MARCH=-march=rv32ic clean_all exe`. You can also make project-specific definitions
of all variables inside the project's actual makefile (e.g., `sw/example/blink_led/makefile`).
 
[source,makefile]
----
# *****************************************************************************
150,14 → 158,12
# Optimization
EFFORT ?= -Os
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
RISCV_PREFIX ?= riscv32-unknown-elf-
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
170,8 → 176,8
| _APP_INC_ | Include file folders; separated by white spaces; must be defined with `-I` prefix
| _ASM_INC_ | Include file folders that are used only for the assembly source files (`*.S`/`*.s`).
| _EFFORT_ | Optimization level, optimize for size (`-Os`) is default; legal values: `-O0`, `-O1`, `-O2`, `-O3`, `-Os`
| _RISCV_TOOLCHAIN_ | The toolchain prefix to be used; follows the naming convention "architecture-vendor-output"
| _MARCH_ | The targetd RISC-V architecture/ISA. Only `rv32` is supported by the NEORV32. Enable compiler support of optional CPU extension by adding the according extension letter (e.g. `rv32im` for _M_ CPU extension). See section <<_enabling_risc_v_cpu_extensions>>.
| _RISCV_PREFIX_ | The toolchain prefix to be used; follows the naming convention "architecture-vendor-output-"
| _MARCH_ | The targetd RISC-V architecture/ISA. Only `rv32` is supported by the NEORV32. Enable compiler support of optional CPU extension by adding the according extension letter (e.g. `rv32im` for _M_ CPU extension). See https://stnolting.github.io/neorv32/ug/#_enabling_risc_v_cpu_extensions[User Guide: Enabling RISC-V CPU Extensions] for more information.
| _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`.
201,12 → 207,8
| `-falign-jumps=4`
|=======================
 
[TIP]
The makefile configuration variables can be (re-)defined directly when invoking the makefile. For
example: `$ make MARCH=-march=rv32ic clean_all exe`
 
 
 
<<<
// ####################################################################################################################
:sectnums:
282,7 → 284,7
[cols="<1,<9"]
[options="header",grid="rows"]
|=======================
| Region | Description
| Region | Description
| `.text` | Executable instructions generated from the start-up code and all application sources.
| `.rodata` | Constants (like strings) from the application; also the initial data for initialized variables.
| `.data` | This section is required for the address generation of fixed (= global) variables only.
308,6 → 310,7
[grid="none"]
|=======================
| `-app_bin` | Generates an executable binary file `neorv32_exe.bin` (for UART uploading via the bootloader).
| `-app_hex` | Generates a plain ASCII hex-char file `neorv32_exe.hex` that can be used to initialize custom (instruction-) memories (in synthesis/simulation).
| `-app_img` | Generates an executable VHDL memory initialization image for the processor-internal IMEM. This option generates the `rtl/core/neorv32_application_image.vhd` file.
| `-bld_img` | Generates an executable VHDL memory initialization image for the processor-internal BOOT ROM. This option generates the `rtl/core/neorv32_bootloader_image.vhd` file.
|=======================
414,7 → 417,7
To interact with the bootloader, connect the primary UART (UART0) signals (`uart0_txd_o` and
`uart0_rxd_o`) of the processor's top entity via a serial port (-adapter) to your computer (hardware flow control is
not used so the according interface signals can be ignored.), configure your
terminal program using the following settings and perform a reset of the processor.
terminal program using the following settings and perform a reset of the processor.
 
Terminal console settings (`19200-8-N-1`):
 
533,8 → 536,8
[cols="<2,<13"]
[grid="rows"]
|=======================
| **`ERROR_0`** | If you try to transfer an invalid executable (via UART or from the external SPI flash), this error message shows up. There might be a transfer protocol configuration error in the terminal program. See section <<_uploading_and_starting_of_a_binary_executable_image_via_uart>> for more information. Also, if no SPI flash was found during an auto-boot attempt, this message will be displayed.
| **`ERROR_1`** | Your program is way too big for the internal processor’s instructions memory. Increase the memory size or reduce (optimize!) your application code.
| **`ERROR_0`** | If you try to transfer an invalid executable (via UART or from the external SPI flash), this error message shows up. There might be a transfer protocol configuration error in the terminal program. Also, if no SPI flash was found during an auto-boot attempt, this message will be displayed.
| **`ERROR_1`** | Your program is way too big for the internal processor’s instructions memory. Increase the memory size or reduce your application code.
| **`ERROR_2`** | This indicates a checksum error. Something went wrong during the transfer of the program image (upload via UART or loading from the external SPI flash). If the error was caused by a UART upload, just try it again. When the error was generated during a flash access, the stored image might be corrupted.
| **`ERROR_3`** | This error occurs if the attached SPI flash cannot be accessed. Make sure you have the right type of flash and that it is properly connected to the NEORV32 SPI port using chip select #0.
|=======================
/trunk/docs/figures/neorv32_cpu.png Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/trunk/docs/userguide/content.adoc
13,8 → 13,8
2. Download and install a prebuilt version of the toolchain; this might also done via the package manager / app store of your OS
 
[TIP]
The default toolchain prefix for this project is **`riscv32-unknown-elf`**. Of course you can use any other RISC-V
toolchain (like `riscv64-unknown-elf`) that is capable to emit code for a `rv32` architecture. Just change the _RISCV_TOOLCHAIN_ variable in the application
The default toolchain prefix for this project is **`riscv32-unknown-elf-`**. Of course you can use any other RISC-V
toolchain (like `riscv64-unknown-elf-`) that is capable to emit code for a `rv32` architecture. Just change the _RISCV_PREFIX_ variable in the application
makefile(s) according to your needs or define this variable when invoking the makefile.
 
[IMPORTANT]
264,7 → 264,7
:sectnums:
== Application Program Compilation
 
This guide shows how to compile an example C-code application into a NEORV32 executable that
This guide shows how to compile an example C-code application into a NEORV32 executable that
can be uploaded via the bootloader or the on-chip debugger.
 
[IMPORTANT]
298,7 → 298,7
3176 0 120 3296 ce0 main.elf
Compiling ../../../sw/image_gen/image_gen
Executable (neorv32_exe.bin) size in bytes:
3188
3188
----
 
[start=5]
455,7 → 455,7
 
* for this boot concept the bootloader is no longer required
* this concept only works for the internal IMEM (but can be extended to work with external memories coupled via the processor's bus interface)
* make sure that the memory components (like block RAM) the IMEM is mapped to support an initialization via the bitstream
* make sure that the memory components (like block RAM) the IMEM is mapped to support an initialization via the bitstream
 
[start=1]
. At first, make sure your processor setup actually implements the internal IMEM: the `MEM_INT_IMEM_EN` generics has to be set to `true`:
469,7 → 469,7
 
[start=2]
. For this setup we do not want the bootloader to be implemented at all. Disable implementation of the bootloader by setting the
`INT_BOOTLOADER_EN` generic to `false`. This will also modify the processor-internal IMEM so it is initialized with the executable during synthesis.
`INT_BOOTLOADER_EN` generic to `false`. This will also modify the processor-internal IMEM so it is initialized with the executable during synthesis.
 
.Processor top entity configuration - disable internal bootloader
[source,vhdl]
571,9 → 571,16
<2> MABI = Machine binary interface
 
For example, if you enable the RISC-V `C` extension (16-bit compressed instructions) via the `CPU_EXTENSION_RISCV_C`
generic (set `true`) you need to add the 'c' extension also to the `MARCH` ISA string in order to make the compiler
generic (set `true`) you need to add the `c` extension also to the `MARCH` ISA string in order to make the compiler
emit compressed instructions.
 
.Privileged Architecture Extensions
[IMPORTANT]
Privileged architecture extensions like `Zicsr` or `Zifencei` are "used" _implicitly_ by the compiler. Hence, according
instruction will only be generated when "encoded" via inline assembly or when linking according libraries. In this case,
these instruction will _always_ be emitted (even if the according extension is not specified in `MARCH`). +
**I recommend to _not_ specify any privileged architecture extensions in `MARCH`.**
 
[WARNING]
ISA extension enabled in hardware can be a superset of the extensions enabled in software, but not the other way
around. For example generating compressed instructions for a CPU configuration that has the `c` extension disabled
587,8 → 594,8
----
 
[NOTE]
The RISC-V ISA string (for _MARCH_) follows a certain _canonical_ structure:
`rev32[i/e][m][a][f][d][g][q][c][b][v][n]...` For example `rv32imac` is valid while `rv32icma` is not valid.
The RISC-V ISA string for `MARCH` follows a certain _canonical_ structure:
`rev32[i/e][m][a][f][d][g][q][c][b][v][n]...` For example `rv32imac` is valid while `rv32icma` is not.
 
 
 
691,7 → 698,7
 
[WARNING]
Note that this boot configuration does not load any executable at all! Hence,
this boot configuration is intended to be used with the on-chip debugger only.
this boot configuration is intended to be used with the on-chip debugger only.
 
 
 
786,14 → 793,28
:sectnums:
== Packaging the Processor as IP block for Xilinx Vivado Block Designer
 
.WORK IN PROGRESS
[WARNING]
This Section Is Under Construction! +
+
FIXME!
[start=1]
. Import all the core files from `rtl/core` and assign them to a _new_ design library `neorv32`.
. Instantiate the `rtl/wrappers/neorv32_top_axi4lite.vhd` module.
. Then either directly use that module in a new block-design ("Create Block Design", right-click -> "Add Module",
thats easier for a first try) or package it ("Tools", "Create and Package new IP") for the use in other projects.
. Connect your AXI-peripheral directly to the core's AXI4-Interface if you only have one, or to an AXI-Interconnect
(from the IP-catalog) if you have multiple peripherals.
. Connect ALL the `ACLK` and `ARESETN` pins of all peripherals and interconnects to the processor's clock and reset
signals to have a _unified_ clock and reset domain (easier for a first setup).
. Open the "Address Editor" tab and let Vivado assign the base-addresses for the AXI-peripherals (you can modify them
according to your needs).
. For all FPGA-external signals (like UART signals) make all the connections you need "external"
(right-click on the signal/pin -> "Make External").
. Save everything, let VIVADO create a HDL-Wrapper for the block-design and choose this as your _Top Level Design_.
. Define your constraints and generate your bitstream.
 
[NOTE]
Guide provided by GitHub user https://github.com/AWenzel83[`AWenzel83`] from
https://github.com/stnolting/neorv32/discussions/52#discussioncomment-819013
 
 
 
<<<
// ####################################################################################################################
:sectnums:
917,7 → 938,7
The documentation (datasheet + user guide) is written using `asciidoc`. The according source files
can be found in `docs/...`. The documentation of the software framework is written _in-code_ using `doxygen`.
 
A makefiles in the project's root directory is provided to build all of the documentation as HTML pages
A makefiles in the project's `docs` directory is provided to build all of the documentation as HTML pages
or as PDF documents.
 
[TIP]
928,13 → 949,13
 
[source,bash]
----
neorv32$ make help
neorv32/docs$ make help
----
 
.Example: Generate HTML documentation (data sheet) using `asciidoctor`
[source,bash]
----
neorv32$ make html
neorv32/docs$ make html
----
 
[TIP]
962,8 → 983,9
(V2.0+), which is available online at GitHub: https://github.com/riscv/riscv-arch-test
 
All files required for executing the test framework on a simulated instance of the processor (including port
files) are located in the `riscv-arch-test` folder in the root directory of the NEORV32 repository. Take a
look at the provided `riscv-arch-test/README.md` (https://github.com/stnolting/neorv32/blob/master/riscv-arch-test/README.md[online at GitHub])
files) are located in the `sw/isa-test` folder of the NEORV32 repository. The test framework is executed via the
`sim/run_riscv_arch_test.sh` script. Take a look at the provided `sim/README.md`
(https://github.com/stnolting/neorv32/tree/master/sim[online at GitHub])
file for more information on how to run the tests and how testing is conducted in detail.
 
 
/trunk/docs/Makefile
0,0 → 1,63
.DEFAULT_GOAL := help
 
all: pdf html ug-pdf ug-html
mkdir -p public/img/
cp -vr figures/* public/img/
 
# Generate PDF datasheet
pdf:
[ -f revnumber.txt ] && REVNUMBER='-a revnumber='"$$(cat revnumber.txt)" || unset REVNUMBER; \
asciidoctor-pdf $$REVNUMBER \
-a pdf-theme=neorv32-theme.yml \
-r asciidoctor-diagram \
datasheet/main.adoc \
--out-file public/pdf/NEORV32.pdf
 
# Generate HTML datasheet
html:
[ -f revnumber.txt ] && REVNUMBER='-a revnumber='"$$(cat revnumber.txt)" || unset REVNUMBER; \
asciidoctor $$REVNUMBER \
-r asciidoctor-diagram \
datasheet/index.adoc \
--out-file public/index.html
 
# Generate PDF user guide
ug-pdf:
[ -f revnumber.txt ] && REVNUMBER='-a revnumber='"$$(cat revnumber.txt)" || unset REVNUMBER; \
asciidoctor-pdf $$REVNUMBER \
-a pdf-theme=neorv32-theme.yml \
-r asciidoctor-diagram \
userguide/main.adoc \
--out-file public/pdf/NEORV32_UserGuide.pdf
 
# Generate HTML user guide
ug-html:
[ -f revnumber.txt ] && REVNUMBER='-a revnumber='"$$(cat revnumber.txt)" || unset REVNUMBER; \
asciidoctor $$REVNUMBER \
-r asciidoctor-diagram \
userguide/index.adoc \
--out-file public/ug/index.html
 
# Generate DOXYGEN software documentation
doxygen:
doxygen Doxyfile
 
# Generate revnumber.txt for overriding the revnumber attribute in 'pdf' and/or 'html'
revnumber:
if [ `git tag -l | grep nightly` ]; then git tag -d nightly; fi
git describe --long --tags | sed 's#\([^-]*-g\)#r\1#;' > revnumber.txt
cat revnumber.txt
 
# Build 'pdf' and 'html' in an 'asciidoctor-wavedrom' container
container: revnumber
docker run --rm -v /$(shell pwd)://documents/ btdi/asciidoctor make all
 
# Help
help:
@echo "Targets:"
@echo " help - show this text"
@echo " pdf - build datasheet as pdf file (public/pdf/NEORV32.pdf)"
@echo " html - build datasheet as HTML page (public/index.html)"
@echo " ug-pdf - build user guide as pdf file (public/pdf/NEORV32_UserGuide.pdf)"
@echo " ug-html - build user guide as HTML page (public/ug/index.html)"
@echo " doxygen - build software documentation as HTML page (doxygen_build/html/index.html)"
/trunk/docs/attrs.adoc
1,7 → 1,7
:author: Dipl.-Ing. Stephan Nolting
:email: stnolting@gmail.com
: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.5.7
:revnumber: v1.5.9
:doctype: book
:sectnums:
:stem:
/trunk/docs/legal.adoc
85,6 → 85,12
 
If you are using the NEORV32 or parts of the project in some kind of publication, please cite it as follows:
 
.Contributors ❤️
[NOTE]
Please add as many https://github.com/stnolting/neorv32/graphs/contributors[contributors] as possible to the `authors` field 😉. +
This project would not be where it is without them. +
Full names can be found in the repository's https://github.com/stnolting/neorv32/blob/master/.mailmap[`.mailmap`].
 
.BibTeX
[source]
----
98,9 → 104,9
}
----
 
.DOI
[TIP]
Each official release of the project (see https://github.com/stnolting/neorv32/releases[releases page]) provides
a _digital object identifiere_ (**DOI**) provided by https://zenodo.org/.
This project also provides a _digital object identifier_ provided by https://zenodo.org[zenodo]: https://zenodo.org/record/5121427
 
 
:sectnums!:
/trunk/rtl/core/neorv32_application_image.vhd
11,7 → 11,7
package neorv32_application_image is
 
constant application_init_image : mem32_t := (
00000000 => x"00000013",
00000000 => x"00000037",
00000001 => x"80002117",
00000002 => x"ff810113",
00000003 => x"80000197",
/trunk/rtl/core/neorv32_boot_rom.vhd
42,7 → 42,7
 
entity neorv32_boot_rom is
generic (
BOOTROM_BASE : std_ulogic_vector(31 downto 0) := x"FFFF0000" -- boot ROM base address
BOOTROM_BASE : std_ulogic_vector(31 downto 0) -- boot ROM base address
);
port (
clk_i : in std_ulogic; -- global clock line
/trunk/rtl/core/neorv32_bootloader_image.vhd
11,7 → 11,7
package neorv32_bootloader_image is
 
constant bootloader_init_image : mem32_t := (
00000000 => x"00000013",
00000000 => x"00000037",
00000001 => x"80010117",
00000002 => x"1f810113",
00000003 => x"80010197",
984,9 → 984,9
00000970 => x"72656461",
00000971 => x"0a3e3e20",
00000972 => x"444c420a",
00000973 => x"4a203a56",
00000974 => x"33206e75",
00000975 => x"30322030",
00000973 => x"41203a56",
00000974 => x"20206775",
00000975 => x"30322038",
00000976 => x"480a3132",
00000977 => x"203a5657",
00000978 => x"00000020",
/trunk/rtl/core/neorv32_bus_keeper.vhd
52,13 → 52,13
entity neorv32_bus_keeper is
generic (
-- External memory interface --
MEM_EXT_EN : boolean := false; -- implement external memory bus interface?
MEM_EXT_EN : boolean; -- implement external memory bus interface?
-- Internal instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_EN : boolean; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural; -- size of processor-internal instruction memory in bytes
-- Internal data memory --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 8*1024 -- size of processor-internal data memory in bytes
MEM_INT_DMEM_EN : boolean; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural -- size of processor-internal data memory in bytes
);
port (
-- host access --
/trunk/rtl/core/neorv32_busswitch.vhd
44,8 → 44,8
 
entity neorv32_busswitch is
generic (
PORT_CA_READ_ONLY : boolean := false; -- set if controller port A is read-only
PORT_CB_READ_ONLY : boolean := false -- set if controller port B is read-only
PORT_CA_READ_ONLY : boolean; -- set if controller port A is read-only
PORT_CB_READ_ONLY : boolean -- set if controller port B is read-only
);
port (
-- global control --
/trunk/rtl/core/neorv32_cfs.vhd
46,8 → 46,8
entity neorv32_cfs is
generic (
CFS_CONFIG : std_ulogic_vector(31 downto 0); -- custom CFS configuration generic
CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits
CFS_OUT_SIZE : positive := 32 -- size of CFS output conduit in bits
CFS_IN_SIZE : positive; -- size of CFS input conduit in bits
CFS_OUT_SIZE : positive -- size of CFS output conduit in bits
);
port (
-- host access --
/trunk/rtl/core/neorv32_cpu.vhd
56,72 → 56,73
entity neorv32_cpu is
generic (
-- General --
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0):= x"00000000"; -- cpu boot address
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0) := x"00000000"; -- cpu debug mode start address
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 --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean := false; -- implement CPU debug mode?
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement muld/div extension?
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
FAST_MUL_EN : boolean; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural; -- total width of CPU cycle and instret counters (0..64)
CPU_IPB_ENTRIES : natural; -- entries is instruction prefetch buffer, has to be a power of 2
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
PMP_NUM_REGIONS : natural; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40 -- total size of HPM counters (0..64)
HPM_NUM_CNTS : natural; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural -- total size of HPM counters (0..64)
);
port (
-- global control --
clk_i : in std_ulogic := '0'; -- global clock, rising edge
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
sleep_o : out std_ulogic; -- cpu is in sleep mode when set
-- instruction bus interface --
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) := (others => '0'); -- bus read data
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 := '0'; -- bus transfer acknowledge
i_bus_err_i : in std_ulogic := '0'; -- bus transfer error
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; -- executed FENCEI operation
i_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
-- data bus interface --
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) := (others => '0'); -- bus read data
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 := '0'; -- bus transfer acknowledge
d_bus_err_i : in std_ulogic := '0'; -- bus transfer error
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; -- executed FENCE operation
d_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
-- system time input from MTIME --
time_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time
time_i : in std_ulogic_vector(63 downto 0); -- current system time
-- non-maskable interrupt --
nm_irq_i : in std_ulogic := '0'; -- NMI
nm_irq_i : in std_ulogic; -- NMI
-- interrupts (risc-v compliant) --
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt
mext_irq_i : in std_ulogic := '0'; -- machine external interrupt
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt
msw_irq_i : in std_ulogic;-- machine software interrupt
mext_irq_i : in std_ulogic;-- machine external interrupt
mtime_irq_i : in std_ulogic;-- machine timer interrupt
-- fast interrupts (custom) --
firq_i : in std_ulogic_vector(15 downto 0) := (others => '0');
firq_i : in std_ulogic_vector(15 downto 0);
-- debug mode (halt) request --
db_halt_req_i : in std_ulogic := '0'
db_halt_req_i : in std_ulogic
);
end neorv32_cpu;
 
194,7 → 195,7
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true)) report "NEORV32 CPU CONFIG ERROR! User mode requires <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error;
 
-- Instruction prefetch buffer size --
assert not (is_power_of_two_f(ipb_entries_c) = false) report "NEORV32 CPU CONFIG ERROR! Number of entries in instruction prefetch buffer <ipb_entries_c> has to be a power of two." severity error;
assert not (is_power_of_two_f(CPU_IPB_ENTRIES) = false) report "NEORV32 CPU CONFIG ERROR! Number of entries in instruction prefetch buffer <CPU_IPB_ENTRIES> has to be a power of two." severity error;
 
-- Co-processor timeout counter (for debugging only) --
assert not (cp_timeout_en_c = true) report "NEORV32 CPU CONFIG WARNING! Co-processor timeout counter enabled. This should be used for debugging/simulation only." severity warning;
231,15 → 232,17
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG => CPU_EXTENSION_RISCV_DEBUG, -- implement CPU debug mode?
-- Extension Options --
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
/trunk/rtl/core/neorv32_cpu_alu.vhd
44,12 → 44,12
entity neorv32_cpu_alu is
generic (
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false -- use barrel shifter for shift operations
FAST_MUL_EN : boolean; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean -- use barrel shifter for shift operations
);
port (
-- global control --
/trunk/rtl/core/neorv32_cpu_bus.vhd
43,11 → 43,11
 
entity neorv32_cpu_bus is
generic (
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension?
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024 -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
PMP_NUM_REGIONS : natural; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
);
port (
-- global control --
118,6 → 118,7
constant pmp_cfg_x_c : natural := 2; -- execute permit
constant pmp_cfg_al_c : natural := 3; -- mode bit low
constant pmp_cfg_ah_c : natural := 4; -- mode bit high
--
constant pmp_cfg_l_c : natural := 7; -- locked entry
 
-- data interface registers --
/trunk/rtl/core/neorv32_cpu_control.vhd
48,28 → 48,29
entity neorv32_cpu_control is
generic (
-- General --
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0) := x"00000000"; -- cpu boot address
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0) := x"00000000"; -- cpu debug mode start address
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 --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean := false; -- implement CPU debug mode?
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement muld/div extension?
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
-- Extension Options --
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
CPU_CNT_WIDTH : natural; -- total width of CPU cycle and instret counters (0..64)
CPU_IPB_ENTRIES : natural; -- entries is instruction prefetch buffer, has to be a power of 2
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
PMP_NUM_REGIONS : natural; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40 -- total size of HPM counters (0..64)
HPM_NUM_CNTS : natural; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural -- total size of HPM counters (0..64)
);
port (
-- global control --
196,7 → 197,7
 
-- instruction execution engine --
type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP_ENTER, TRAP_EXIT, TRAP_EXECUTE, EXECUTE, ALU_WAIT, BRANCH,
FENCE_OP,LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYS_ENV, CSR_ACCESS);
FENCE_OP, LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYS_ENV, CSR_ACCESS);
type execute_engine_t is record
state : execute_engine_state_t;
state_nxt : execute_engine_state_t;
274,9 → 275,11
wdata : std_ulogic_vector(data_width_c-1 downto 0); -- csr write data
rdata : std_ulogic_vector(data_width_c-1 downto 0); -- csr read data
--
mstatus_fs : std_ulogic; -- mstatus.FS: FPU status (single-bit, only OFF and DIRTY states)
mstatus_mie : std_ulogic; -- mstatus.MIE: global IRQ enable (R/W)
mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/W)
mstatus_mpp : std_ulogic_vector(1 downto 0); -- mstatus.MPP: machine previous privilege mode
mstatus_tw : std_ulogic; -- mstatus:TW trigger illegal instruction exception if WFI is executed outside of M-mode
--
mie_msie : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W)
mie_meie : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W)
458,7 → 461,7
-- -------------------------------------------------------------------------------------------
instr_prefetch_buffer: neorv32_fifo
generic map (
FIFO_DEPTH => ipb_entries_c, -- number of fifo entries; has to be a power of two; min 1
FIFO_DEPTH => CPU_IPB_ENTRIES, -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH => ipb.wdata'length, -- size of data elements in fifo
FIFO_RSYNC => false, -- we NEED to read data asynchronously
FIFO_SAFE => false -- no safe access required (ensured by FIFO-external control)
614,10 → 617,9
 
-- Immediate Generator --------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
imm_gen: process(execute_engine.i_reg, rstn_i, clk_i)
imm_gen: process(rstn_i, clk_i)
variable opcode_v : std_ulogic_vector(6 downto 0);
begin
opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11";
if (rstn_i = '0') then
imm_o <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
624,6 → 626,7
if (execute_engine.state = BRANCH) then -- next_PC as immediate for jump-and-link operations (=return address) via ALU.MOV_B
imm_o <= execute_engine.next_pc;
else -- "normal" immediate from instruction word
opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11";
case opcode_v is -- save some bits here, the two LSBs are always "11" for rv32
when opcode_store_c => -- S-immediate
imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
690,7 → 693,7
execute_engine.sleep <= '0';
execute_engine.branched <= '1'; -- reset is a branch from "somewhere"
-- no dedicated RESET required --
execute_engine.state_prev <= SYS_WAIT;
execute_engine.state_prev <= SYS_WAIT; -- actual reset value is not relevant
execute_engine.i_reg <= (others => def_rst_val_c);
execute_engine.is_ci <= def_rst_val_c;
execute_engine.last_pc <= (others => def_rst_val_c);
917,14 → 920,8
-- state machine --
case execute_engine.state is
 
when SYS_WAIT => -- System delay cycle (used to wait for side effects to kick in) [and to init r0 with zero if it is a physical register]
when SYS_WAIT => -- System delay cycle (to let side effects kick in)
-- ------------------------------------------------------------
-- set reg_file's r0 to zero --
if (rf_r0_is_reg_c = true) then -- is r0 implemented as physical register, which has to be set to zero?
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_csrr_c; -- hacky! CSR read-access without a valid CSR-read -> results zero
ctrl_nxt(ctrl_rf_r0_we_c) <= '1'; -- force RF write access and force rd=r0
end if;
--
execute_engine.state_nxt <= DISPATCH;
 
 
1103,7 → 1100,7
 
when opcode_fop_c => -- floating-point operations
-- ------------------------------------------------------------
if (CPU_EXTENSION_RISCV_Zfinx = true) and (decode_aux.is_float_op = '1') then
if (CPU_EXTENSION_RISCV_Zfinx = true) and (decode_aux.is_float_op = '1') and (csr.mstatus_fs = '1') then
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_fpu_c; -- trigger FPU CP
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
execute_engine.state_nxt <= ALU_WAIT;
1120,15 → 1117,20
 
when SYS_ENV => -- system environment operation - execution
-- ------------------------------------------------------------
execute_engine.state_nxt <= SYS_WAIT;
execute_engine.state_nxt <= SYS_WAIT; -- default
case decode_aux.sys_env_cmd is -- use a simplified input here (with permanent zeros)
when funct12_ecall_c => trap_ctrl.env_call <= '1'; -- ECALL
when funct12_ebreak_c => trap_ctrl.break_point <= '1'; -- EBREAK
when funct12_mret_c => execute_engine.state_nxt <= TRAP_EXIT; -- MRET
when funct12_wfi_c => execute_engine.sleep_nxt <= '1'; -- WFI
when funct12_dret_c => -- DRET
if (CPU_EXTENSION_RISCV_DEBUG = true) then
when funct12_mret_c => -- MRET
if (CPU_EXTENSION_RISCV_U = true) and (csr.priv_m_mode = '1') then -- only allowed in M-mode
execute_engine.state_nxt <= TRAP_EXIT;
else
NULL;
end if;
when funct12_dret_c => -- DRET
if (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1') then -- only allowed in debug-mode
execute_engine.state_nxt <= TRAP_EXIT;
debug_ctrl.dret <= '1';
else
NULL;
1171,7 → 1173,7
-- get and store return address (only relevant for jump-and-link operations) --
ctrl_nxt(ctrl_alu_opb_mux_c) <= '1'; -- use IMM as ALU.OPB (next_pc from immediate generator = return address)
ctrl_nxt(ctrl_alu_logic1_c downto ctrl_alu_logic0_c) <= alu_logic_cmd_movb_c; -- MOVB
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_logic_c; -- actual ALU operation = MOVB
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_logic_c; -- actual ALU operation = MOVB
ctrl_nxt(ctrl_rf_in_mux_c) <= '0'; -- RF input = ALU result
ctrl_nxt(ctrl_rf_wb_en_c) <= execute_engine.i_reg(instr_opcode_lsb_c+2); -- valid RF write-back? (is jump-and-link?)
-- destination address --
1191,7 → 1193,7
execute_engine.state_nxt <= SYS_WAIT;
-- FENCE.I --
if (CPU_EXTENSION_RISCV_Zifencei = true) then
execute_engine.pc_mux_sel <= '0'; -- linear next PC = start *new* instruction fetch with next instruction (only relevant for fence.i)
execute_engine.pc_mux_sel <= '0'; -- linear next PC = start *new* instruction fetch with next instruction
if (execute_engine.i_reg(instr_funct3_lsb_c) = funct3_fencei_c(0)) then
execute_engine.pc_we <= '1'; -- update PC
execute_engine.branched_nxt <= '1'; -- this is an actual branch
1233,7 → 1235,8
ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for load (and SC.W) operations)
ctrl_nxt(ctrl_rf_in_mux_c) <= '1'; -- RF input = memory input (only relevant for LOADs)
-- wait for memory response / exception --
if (trap_ctrl.env_start = '1') then -- abort if exception
if (trap_ctrl.env_start = '1') and -- only abort if BUS EXCEPTION
((trap_ctrl.cause = trap_lma_c) or (trap_ctrl.cause = trap_lbe_c) or (trap_ctrl.cause = trap_sma_c) or (trap_ctrl.cause = trap_sbe_c)) then
execute_engine.state_nxt <= SYS_WAIT;
elsif (bus_d_wait_i = '0') then -- wait for bus to finish transaction
-- data write-back --
1281,14 → 1284,14
 
-- floating-point CSRs --
when csr_fflags_c | csr_frm_c | csr_fcsr_c =>
if (CPU_EXTENSION_RISCV_Zfinx = true) then
csr_acc_valid <= '1'; -- full access for everyone if Zfinx extension is implemented
if (CPU_EXTENSION_RISCV_Zfinx = true) and (csr.mstatus_fs = '1') then -- FPU implemented and enabled?
csr_acc_valid <= '1'; -- full access for everyone
else
NULL;
end if;
 
-- machine trap setup & handling --
when csr_mstatus_c | csr_misa_c | csr_mie_c | csr_mtvec_c | csr_mcounteren_c | csr_mscratch_c | csr_mepc_c | csr_mcause_c =>
when csr_mstatus_c | csr_mstatush_c | csr_misa_c | csr_mie_c | csr_mtvec_c | csr_mcounteren_c | csr_mscratch_c | csr_mepc_c | csr_mcause_c =>
csr_acc_valid <= csr.priv_m_mode; -- M-mode only, NOTE: MISA is read-only in the NEORV32 but we do not cause an exception here for compatibility
when csr_mip_c | csr_mtval_c => -- NOTE: MIP and MTVAL are read-only in the NEORV32!
csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
1355,7 → 1358,7
 
 
-- machine information registers & custom (NEORV32-specific) read-only CSRs --
when csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | csr_mhartid_c | csr_mzext_c =>
when csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | csr_mhartid_c | csr_mconfigptr_c | csr_mzext_c =>
csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
 
-- debug mode CSRs --
1375,7 → 1378,7
 
-- Illegal Instruction Check --------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
illegal_instruction_check: process(execute_engine, decode_aux, csr_acc_valid, debug_ctrl)
illegal_instruction_check: process(execute_engine, decode_aux, csr, csr_acc_valid, debug_ctrl)
variable opcode_v : std_ulogic_vector(6 downto 0);
begin
-- illegal instructions are checked in the EXECUTE stage
1541,9 → 1544,9
(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then
if (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_ecall_c) or -- ECALL
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_ebreak_c) or -- EBREAK
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_mret_c) or -- MRET
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_mret_c)and (CPU_EXTENSION_RISCV_U = true) and (csr.priv_m_mode = '1')) or -- MRET (only allowed in M-mode)
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = (funct12_dret_c)) and (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1')) or -- DRET
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_wfi_c) then -- WFI
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_wfi_c) and ((csr.priv_m_mode = '1') or (csr.mstatus_tw = '0'))) then -- WFI allowed in M-mode or if mstatus.TW=0
illegal_instruction <= '0';
else
illegal_instruction <= '1';
1564,7 → 1567,7
 
when opcode_fop_c => -- floating point operations - single/dual operands
-- ------------------------------------------------------------
if (CPU_EXTENSION_RISCV_Zfinx = true) and -- F extension enabled
if (CPU_EXTENSION_RISCV_Zfinx = true) and (csr.mstatus_fs = '1') and -- F extension implemented and enabled
(execute_engine.i_reg(instr_funct7_lsb_c+1 downto instr_funct7_lsb_c) = float_single_c) and -- single-precision operations only
(decode_aux.is_float_op = '1') then -- is correct/supported floating-point instruction
illegal_instruction <= '0';
1919,8 → 1922,10
csr.we <= '0';
--
csr.mstatus_mie <= '0';
csr.mstatus_fs <= '0';
csr.mstatus_mpie <= '0';
csr.mstatus_mpp <= (others => '0');
csr.mstatus_tw <= '0';
csr.privilege <= priv_mode_m_c; -- start in MACHINE mode
csr.mie_msie <= def_rst_val_c;
csr.mie_meie <= def_rst_val_c;
1993,9 → 1998,11
if (CPU_EXTENSION_RISCV_U = true) then -- user mode implemented
csr.mstatus_mpp(0) <= csr.wdata(11) or csr.wdata(12);
csr.mstatus_mpp(1) <= csr.wdata(11) or csr.wdata(12);
else -- only machine mode is available
csr.mstatus_mpp <= priv_mode_m_c;
csr.mstatus_tw <= csr.wdata(21);
end if;
if (CPU_EXTENSION_RISCV_Zfinx = true) then -- FPU implemented
csr.mstatus_fs <= csr.wdata(14) or csr.wdata(13);
end if;
end if;
-- R/W: mie - machine interrupt enable register --
if (csr.addr(3 downto 0) = csr_mie_c(3 downto 0)) then
2082,7 → 2089,7
csr.mcountinhibit_ir <= csr.wdata(2); -- enable auto-increment of [m]instret[h] counter
csr.mcountinhibit_hpm <= csr.wdata(csr.mcountinhibit_hpm'left+3 downto 3); -- enable auto-increment of [m]hpmcounter*[h] counter
end if;
-- machine performance-monitoring event selector --
-- machine performance-monitors event selector --
if (HPM_NUM_CNTS > 0) then
for i in 0 to HPM_NUM_CNTS-1 loop
if (csr.addr(4 downto 0) = std_ulogic_vector(to_unsigned(i+3, 5))) then
2226,6 → 2233,7
if (CPU_EXTENSION_RISCV_U = false) then
csr.privilege <= priv_mode_m_c;
csr.mstatus_mpp <= priv_mode_m_c;
csr.mstatus_tw <= '0';
csr.mcounteren_cy <= '0';
csr.mcounteren_tm <= '0';
csr.mcounteren_ir <= '0';
2255,8 → 2263,9
 
-- floating-point extension disabled --
if (CPU_EXTENSION_RISCV_Zfinx = false) then
csr.fflags <= (others => '0');
csr.frm <= (others => '0');
csr.mstatus_fs <= '0';
csr.fflags <= (others => '0');
csr.frm <= (others => '0');
end if;
 
-- debug mode disabled --
2502,6 → 2511,10
csr.rdata(07) <= csr.mstatus_mpie; -- MPIE
csr.rdata(11) <= csr.mstatus_mpp(0); -- MPP: machine previous privilege mode low
csr.rdata(12) <= csr.mstatus_mpp(1); -- MPP: machine previous privilege mode high
csr.rdata(13) <= csr.mstatus_fs; -- FS(0): FPU status - OFF or DIRTY
csr.rdata(14) <= csr.mstatus_fs; -- FS(1): FPU status - OFF or DIRTY
csr.rdata(21) <= csr.mstatus_tw; -- TW: WFI timeout wait
csr.rdata(31) <= csr.mstatus_fs; -- SD: state dirty (only FPU yet)
when csr_misa_c => -- misa (r/-): ISA and extensions
csr.rdata(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_A); -- A CPU extension
csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension
2539,7 → 2552,7
when csr_mcause_c => -- mcause (r/w): machine trap cause
csr.rdata(31) <= csr.mcause(csr.mcause'left);
csr.rdata(csr.mcause'left-1 downto 0) <= csr.mcause(csr.mcause'left-1 downto 0);
when csr_mtval_c => -- mtval (r/w): machine bad address or instruction
when csr_mtval_c => -- mtval (r/-): machine bad address or instruction
csr.rdata <= csr.mtval;
when csr_mip_c => -- mip (r/-): machine interrupt pending
csr.rdata(03) <= trap_ctrl.irq_buf(interrupt_msw_irq_c);
2753,10 → 2766,11
 
-- machine information registers --
-- --------------------------------------------------------------------
-- when csr_mvendorid_c => csr.rdata <= (others => '0'); -- mvendorid (r/-): vendor ID, implemented but always zero
when csr_marchid_c => csr.rdata(4 downto 0) <= "10011"; -- marchid (r/-): arch ID - official RISC-V open-source arch ID
when csr_mimpid_c => csr.rdata <= hw_version_c; -- mimpid (r/-): implementation ID -- NEORV32 hardware version
when csr_mhartid_c => csr.rdata <= std_ulogic_vector(to_unsigned(HW_THREAD_ID, 32)); -- mhartid (r/-): hardware thread ID
-- when csr_mvendorid_c => csr.rdata <= (others => '0'); -- mvendorid (r/-): vendor ID, implemented but always zero
when csr_marchid_c => csr.rdata(4 downto 0) <= "10011"; -- marchid (r/-): arch ID - official RISC-V open-source arch ID
when csr_mimpid_c => csr.rdata <= hw_version_c; -- mimpid (r/-): implementation ID -- NEORV32 hardware version
when csr_mhartid_c => csr.rdata <= std_ulogic_vector(to_unsigned(HW_THREAD_ID, 32)); -- mhartid (r/-): hardware thread ID
-- when csr_mconfigptr_c => csr.rdata <= (others => '0'); -- mconfigptr (r/-): machine configuration pointer register, implemented but not assigned yet
 
-- custom machine read-only CSRs --
-- --------------------------------------------------------------------
/trunk/rtl/core/neorv32_cpu_cp_muldiv.vhd
48,8 → 48,8
 
entity neorv32_cpu_cp_muldiv is
generic (
FAST_MUL_EN : boolean := false; -- use DSPs for faster multiplication
DIVISION_EN : boolean := true -- implement divider hardware
FAST_MUL_EN : boolean; -- use DSPs for faster multiplication
DIVISION_EN : boolean -- implement divider hardware
);
port (
-- global control --
/trunk/rtl/core/neorv32_cpu_cp_shifter.vhd
45,7 → 45,7
 
entity neorv32_cpu_cp_shifter is
generic (
FAST_SHIFT_EN : boolean := false -- use barrel shifter for shift operations
FAST_SHIFT_EN : boolean -- use barrel shifter for shift operations
);
port (
-- global control --
/trunk/rtl/core/neorv32_cpu_regfile.vhd
51,7 → 51,7
 
entity neorv32_cpu_regfile is
generic (
CPU_EXTENSION_RISCV_E : boolean := false -- implement embedded RF extension?
CPU_EXTENSION_RISCV_E : boolean -- implement embedded RF extension?
);
port (
-- global control --
76,11 → 76,10
signal reg_file_emb : reg_file_emb_t;
signal rf_wdata : std_ulogic_vector(data_width_c-1 downto 0); -- actual write-back data
signal rd_is_r0 : std_ulogic; -- writing to r0?
signal rf_we : std_ulogic;
signal dst_addr : std_ulogic_vector(4 downto 0); -- destination address
signal opa_addr : std_ulogic_vector(4 downto 0); -- rs1/dst address
signal opb_addr : std_ulogic_vector(4 downto 0); -- rs2 address
signal rs1, rs2 : std_ulogic_vector(data_width_c-1 downto 0);
signal rs1, rs2 : std_ulogic_vector(data_width_c-1 downto 0); -- read data
 
-- comparator --
signal cmp_opx : std_ulogic_vector(data_width_c downto 0);
90,9 → 89,23
 
-- Data Input Mux -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
rf_wdata <= alu_i when (ctrl_i(ctrl_rf_in_mux_c) = '0') else mem_i;
input_mux: process(rd_is_r0, ctrl_i, alu_i, mem_i)
begin
if (rd_is_r0 = '1') then -- write zero if accessing x0 to "emulate" it is hardwired to zero
rf_wdata <= (others => '0');
else
if (ctrl_i(ctrl_rf_in_mux_c) = '0') then
rf_wdata <= alu_i;
else
rf_wdata <= mem_i;
end if;
end if;
end process input_mux;
 
-- check if we are writing to x0 --
rd_is_r0 <= (not or_reduce_f(dst_addr(4 downto 0))) when (CPU_EXTENSION_RISCV_E = false) else (not or_reduce_f(dst_addr(3 downto 0)));
 
 
-- Register File Access -------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
rf_access: process(clk_i)
99,13 → 112,13
begin
if rising_edge(clk_i) then -- sync read and write
if (CPU_EXTENSION_RISCV_E = false) then -- normal register file with 32 entries
if (rf_we = '1') then
if (ctrl_i(ctrl_rf_wb_en_c) = '1') then
reg_file(to_integer(unsigned(opa_addr(4 downto 0)))) <= rf_wdata;
end if;
rs1 <= reg_file(to_integer(unsigned(opa_addr(4 downto 0))));
rs2 <= reg_file(to_integer(unsigned(opb_addr(4 downto 0))));
else -- embedded register file with 16 entries
if (rf_we = '1') then
if (ctrl_i(ctrl_rf_wb_en_c) = '1') then
reg_file_emb(to_integer(unsigned(opa_addr(3 downto 0)))) <= rf_wdata;
end if;
rs1 <= reg_file_emb(to_integer(unsigned(opa_addr(3 downto 0))));
114,16 → 127,9
end if;
end process rf_access;
 
-- check if we are writing to x0 --
rd_is_r0 <= not or_reduce_f(ctrl_i(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c)) when (CPU_EXTENSION_RISCV_E = false) else
not or_reduce_f(ctrl_i(ctrl_rf_rd_adr3_c downto ctrl_rf_rd_adr0_c));
 
-- valid RF write access? --
rf_we <= (ctrl_i(ctrl_rf_wb_en_c) and (not rd_is_r0)) or ctrl_i(ctrl_rf_r0_we_c);
 
-- access addresses --
dst_addr <= ctrl_i(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c) when (ctrl_i(ctrl_rf_r0_we_c) = '0') else (others => '0'); -- force dst=r0?
opa_addr <= dst_addr when (rf_we = '1') else ctrl_i(ctrl_rf_rs1_adr4_c downto ctrl_rf_rs1_adr0_c); -- rd/rs1
dst_addr <= ctrl_i(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c);
opa_addr <= dst_addr when (ctrl_i(ctrl_rf_wb_en_c) = '1') else ctrl_i(ctrl_rf_rs1_adr4_c downto ctrl_rf_rs1_adr0_c); -- rd/rs1
opb_addr <= ctrl_i(ctrl_rf_rs2_adr4_c downto ctrl_rf_rs2_adr0_c); -- rs2
 
-- data output --
/trunk/rtl/core/neorv32_debug_dm.vhd
394,8 → 394,6
dm_ctrl.hart_reset <= '1';
elsif (dm_reg.reset_ack = '1') then
dm_ctrl.hart_reset <= '0';
elsif (dm_reg.dmcontrol_ndmreset = '1') then
dm_ctrl.hart_reset <= '1';
end if;
 
end if;
/trunk/rtl/core/neorv32_debug_dtm.vhd
41,9 → 41,9
 
entity neorv32_debug_dtm is
generic (
IDCODE_VERSION : std_ulogic_vector(03 downto 0) := x"0"; -- version
IDCODE_PARTID : std_ulogic_vector(15 downto 0) := x"cafe"; -- part number
IDCODE_MANID : std_ulogic_vector(10 downto 0) := "00000000000" -- manufacturer id
IDCODE_VERSION : std_ulogic_vector(03 downto 0); -- version
IDCODE_PARTID : std_ulogic_vector(15 downto 0); -- part number
IDCODE_MANID : std_ulogic_vector(10 downto 0) -- manufacturer id
);
port (
-- global control --
/trunk/rtl/core/neorv32_dmem.vhd
41,8 → 41,8
 
entity neorv32_dmem is
generic (
DMEM_BASE : std_ulogic_vector(31 downto 0) := x"80000000"; -- memory base address
DMEM_SIZE : natural := 4*1024 -- processor-internal instruction memory size in bytes
DMEM_BASE : std_ulogic_vector(31 downto 0); -- memory base address
DMEM_SIZE : natural -- processor-internal instruction memory size in bytes
);
port (
clk_i : in std_ulogic; -- global clock line
/trunk/rtl/core/neorv32_fifo.vhd
41,10 → 41,10
 
entity neorv32_fifo is
generic (
FIFO_DEPTH : natural := 4; -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH : natural := 32; -- size of data elements in fifo
FIFO_RSYNC : boolean := false; -- false = async read; true = sync read
FIFO_SAFE : boolean := false -- true = allow read/write only if data available
FIFO_DEPTH : natural; -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH : natural; -- size of data elements in fifo
FIFO_RSYNC : boolean; -- false = async read; true = sync read
FIFO_SAFE : boolean -- true = allow read/write only if entry available
);
port (
-- control --
51,6 → 51,7
clk_i : in std_ulogic; -- clock, rising edge
rstn_i : in std_ulogic; -- async reset, low-active
clear_i : in std_ulogic; -- sync reset, high-active
level_o : out std_ulogic_vector(index_size_f(FIFO_DEPTH) downto 0); -- fill level
-- write port --
wdata_i : in std_ulogic_vector(FIFO_WIDTH-1 downto 0); -- write data
we_i : in std_ulogic; -- write enable
71,7 → 72,9
re : std_ulogic; -- read enable
w_pnt : std_ulogic_vector(index_size_f(FIFO_DEPTH) downto 0); -- write pointer
r_pnt : std_ulogic_vector(index_size_f(FIFO_DEPTH) downto 0); -- read pointer
level : std_ulogic_vector(index_size_f(FIFO_DEPTH) downto 0); -- fill count
data : fifo_data_t; -- fifo memory
datas : std_ulogic_vector(FIFO_WIDTH-1 downto 0);
match : std_ulogic;
empty : std_ulogic;
full : std_ulogic;
118,13 → 121,15
end process fifo_control;
 
-- status --
fifo.match <= '1' when (fifo.r_pnt(fifo.r_pnt'left-1 downto 0) = fifo.w_pnt(fifo.w_pnt'left-1 downto 0)) else '0';
fifo.match <= '1' when (fifo.r_pnt(fifo.r_pnt'left-1 downto 0) = fifo.w_pnt(fifo.w_pnt'left-1 downto 0)) or (FIFO_DEPTH = 1) else '0';
fifo.full <= '1' when (fifo.r_pnt(fifo.r_pnt'left) /= fifo.w_pnt(fifo.w_pnt'left)) and (fifo.match = '1') else '0';
fifo.empty <= '1' when (fifo.r_pnt(fifo.r_pnt'left) = fifo.w_pnt(fifo.w_pnt'left)) and (fifo.match = '1') else '0';
fifo.free <= not fifo.full;
fifo.avail <= not fifo.empty;
fifo.level <= std_ulogic_vector(to_unsigned(FIFO_DEPTH, fifo.level'length)) when (fifo.full = '1') else std_ulogic_vector(unsigned(fifo.w_pnt) - unsigned(fifo.r_pnt));
 
-- status output --
level_o <= fifo.level;
free_o <= fifo.free;
avail_o <= fifo.avail;
 
135,7 → 140,11
begin
if rising_edge(clk_i) then
if (fifo.we = '1') then
fifo.data(to_integer(unsigned(fifo.w_pnt(fifo.w_pnt'left-1 downto 0)))) <= wdata_i;
if (FIFO_DEPTH = 1) then
fifo.datas <= wdata_i;
else
fifo.data(to_integer(unsigned(fifo.w_pnt(fifo.w_pnt'left-1 downto 0)))) <= wdata_i;
end if;
end if;
end if;
end process fifo_memory_write;
143,7 → 152,7
-- asynchronous read --
fifo_read_async:
if (FIFO_RSYNC = false) generate
rdata_o <= fifo.data(to_integer(unsigned(fifo.r_pnt(fifo.r_pnt'left-1 downto 0))));
rdata_o <= fifo.datas when (FIFO_DEPTH = 1) else fifo.data(to_integer(unsigned(fifo.r_pnt(fifo.r_pnt'left-1 downto 0))));
end generate;
 
-- synchronous read --
153,7 → 162,11
begin
if rising_edge(clk_i) then
if (fifo.re = '1') then
rdata_o <= fifo.data(to_integer(unsigned(fifo.r_pnt(fifo.r_pnt'left-1 downto 0))));
if (FIFO_DEPTH = 1) then
rdata_o <= fifo.datas;
else
rdata_o <= fifo.data(to_integer(unsigned(fifo.r_pnt(fifo.r_pnt'left-1 downto 0))));
end if;
end if;
end if;
end process fifo_memory_read;
/trunk/rtl/core/neorv32_icache.vhd
44,9 → 44,9
 
entity neorv32_icache is
generic (
ICACHE_NUM_BLOCKS : natural := 4; -- number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE : natural := 16; -- block size in bytes (min 4), has to be a power of 2
ICACHE_NUM_SETS : natural := 1 -- associativity / number of sets (1=direct_mapped), has to be a power of 2
ICACHE_NUM_BLOCKS : natural; -- number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE : natural; -- block size in bytes (min 4), has to be a power of 2
ICACHE_NUM_SETS : natural -- associativity / number of sets (1=direct_mapped), has to be a power of 2
);
port (
-- global control --
/trunk/rtl/core/neorv32_imem.vhd
47,9 → 47,9
 
entity neorv32_imem is
generic (
IMEM_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- memory base address
IMEM_SIZE : natural := 4*1024; -- processor-internal instruction memory size in bytes
IMEM_AS_IROM : boolean := false -- implement IMEM as pre-initialized read-only memory?
IMEM_BASE : std_ulogic_vector(31 downto 0); -- memory base address
IMEM_SIZE : natural; -- processor-internal instruction memory size in bytes
IMEM_AS_IROM : boolean -- implement IMEM as pre-initialized read-only memory?
);
port (
clk_i : in std_ulogic; -- global clock line
/trunk/rtl/core/neorv32_neoled.vhd
1,22 → 1,20
-- #################################################################################################
-- # << NEORV32 - Smart LED (WS2811/WS2812) Interface (NEOLED) >> #
-- # ********************************************************************************************* #
-- # Hardware interface for direct control of "smart LEDs" using an asynchronouse serial data #
-- # Hardware interface for direct control of "smart LEDs" using an asynchronous serial data #
-- # line. Compatible with the WS2811 and WS2812 LEDs. #
-- # #
-- # NeoPixel-compatible, RGB (24-bit) and RGBW (32-bit) #
-- # (c) "NeoPixel" is a trademark of Adafruit Industries. #
-- # NeoPixel-compatible, RGB (24-bit) and RGBW (32-bit) modes supported (in "parallel") #
-- # (TM) "NeoPixel" is a trademark of Adafruit Industries. #
-- # #
-- # The interface uses a programmable carries frequency (800 KHz for the WS2812 LEDs) #
-- # The interface uses a programmable carrier frequency (800 KHz for the WS2812 LEDs) #
-- # configurable via the control register's clock prescaler bits (ctrl_clksel*_c) and the period #
-- # length configuration bits (ctrl_t_tot_*_c). "high-times" for sending a ZERO or a ONE bit are #
-- # configured using the ctrl_t_0h_*_c and ctrl_t_1h_*_c bits, respectively. 32-bit transfers #
-- # (for RGBW modules) and 24-bit transfers (for RGB modules) are supported via ctrl_mode__c. #
-- # #
-- # The device features a TX buffer with <tx_buffer_entries_c> entries. The devices busy flag and #
-- # IRQ generator can be programmed to either clear the busy flag / send an IRQ when AT LEAST ONE #
-- # FREE BUFFER ENTRY is available (ctrl_bscon_c = 0) or when the WHOLE BUFFER IS EMPTY #
-- # (ctrl_bscon_c = 1). #
-- # The device features a TX buffer (FIFO) with <FIFO_DEPTH> entries. An IRQ is triggered if the #
-- # FIFO falls below "half-full" fill level. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
57,6 → 55,9
use neorv32.neorv32_package.all;
 
entity neorv32_neoled is
generic (
FIFO_DEPTH : natural -- TX FIFO depth (1..32k, power of two)
);
port (
-- host access --
clk_i : in std_ulogic; -- global clock line
78,9 → 79,6
 
architecture neorv32_neoled_rtl of neorv32_neoled is
 
-- TX buffer size configuration --
constant tx_buffer_entries_c : natural := 4; -- number of entries in TX buffer, has to be a power of two, min=0
 
-- 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(neoled_size_c); -- low address boundary bit
94,15 → 92,16
-- Control register bits --
constant ctrl_enable_c : natural := 0; -- r/w: module enable
constant ctrl_mode_c : natural := 1; -- r/w: 0 = 24-bit RGB mode, 1 = 32-bit RGBW mode
constant ctrl_bscon_c : natural := 2; -- r/w: buffer status configuration -> busy_flag/IRQ config
constant ctrl_strobe_c : natural := 2; -- r/w: 0 = send normal data, 1 = send LED strobe command (RESET) on data write
--
constant ctrl_clksel0_c : natural := 3; -- r/w: prescaler select bit 0
constant ctrl_clksel1_c : natural := 4; -- r/w: prescaler select bit 1
constant ctrl_clksel2_c : natural := 5; -- r/w: prescaler select bit 2
--
constant ctrl_bufs_0_c : natural := 6; -- r/-: log2(tx_buffer_entries_c) bit 0
constant ctrl_bufs_1_c : natural := 7; -- r/-: log2(tx_buffer_entries_c) bit 1
constant ctrl_bufs_2_c : natural := 8; -- r/-: log2(tx_buffer_entries_c) bit 2
constant ctrl_bufs_3_c : natural := 9; -- r/-: log2(tx_buffer_entries_c) bit 3
constant ctrl_bufs_0_c : natural := 6; -- r/-: log2(FIFO_DEPTH) bit 0
constant ctrl_bufs_1_c : natural := 7; -- r/-: log2(FIFO_DEPTH) bit 1
constant ctrl_bufs_2_c : natural := 8; -- r/-: log2(FIFO_DEPTH) bit 2
constant ctrl_bufs_3_c : natural := 9; -- r/-: log2(FIFO_DEPTH) bit 3
--
constant ctrl_t_tot_0_c : natural := 10; -- r/w: pulse-clock ticks per total period bit 0
constant ctrl_t_tot_1_c : natural := 11; -- r/w: pulse-clock ticks per total period bit 1
122,16 → 121,17
constant ctrl_t_1h_3_c : natural := 23; -- r/w: pulse-clock ticks per ONE high-time bit 3
constant ctrl_t_1h_4_c : natural := 24; -- r/w: pulse-clock ticks per ONE high-time bit 4
--
constant ctrl_tx_status_c : natural := 30; -- r/-: serial TX engine busy when set
constant ctrl_busy_c : natural := 31; -- r/-: busy / buffer status flag (configured via ctrl_bscon_c)
constant ctrl_tx_empty_c : natural := 28; -- r/-: TX FIFO is empty
constant ctrl_tx_half_c : natural := 29; -- r/-: TX FIFO is at least half-full
constant ctrl_tx_full_c : natural := 30; -- r/-: TX FIFO is full
constant ctrl_tx_busy_c : natural := 31; -- r/-: serial TX engine busy when set
 
-- control register --
type ctrl_t is record
enable : std_ulogic;
bscon : std_ulogic; -- buffer/busy status flag configuration
mode : std_ulogic;
strobe : std_ulogic;
clk_prsc : std_ulogic_vector(2 downto 0);
ready : std_ulogic; -- buffer ready to accept new data
-- pulse config --
t_total : std_ulogic_vector(4 downto 0);
t0_high : std_ulogic_vector(4 downto 0);
140,41 → 140,37
signal ctrl : ctrl_t;
 
-- transmission buffer --
type tx_fifo_t is array (0 to tx_buffer_entries_c-1) of std_ulogic_vector(31+1 downto 0);
type tx_buffer_t is record
we : std_ulogic; -- write enable
re : std_ulogic; -- read enable
wdata : std_ulogic_vector(31 downto 0); -- write data (excluding mode)
rdata : std_ulogic_vector(31+1 downto 0); -- read data (including mode)
--
avail : std_ulogic; -- data available?
free : std_ulogic; -- free entry available?
free_ff : std_ulogic;
empty : std_ulogic;
empty_ff : std_ulogic;
--
data : tx_fifo_t; -- fifo memory
we : std_ulogic; -- write enable
re : std_ulogic; -- read enable
clear : std_ulogic; -- sync reset, high-active
level : std_ulogic_vector(index_size_f(FIFO_DEPTH) downto 0);
wdata : std_ulogic_vector(31+2 downto 0); -- write data (excluding mode)
rdata : std_ulogic_vector(31+2 downto 0); -- read data (including mode)
avail : std_ulogic; -- data available?
free : std_ulogic; -- free entry available?
half : std_ulogic; -- half full
half_ff : std_ulogic;
end record;
signal tx_buffer : tx_buffer_t;
signal fifo_clear : std_ulogic;
signal fifo_wdata : std_ulogic_vector(31+1 downto 0);
 
-- serial transmission engine --
type serial_state_t is (S_IDLE, S_INIT, S_GETBIT, S_PULSE);
type serial_state_t is (S_IDLE, S_INIT, S_GETBIT, S_PULSE, S_STROBE);
type serial_t is record
-- state control --
state : serial_state_t;
mode : std_ulogic;
busy : std_ulogic;
bit_cnt : std_ulogic_vector(5 downto 0);
state : serial_state_t;
mode : std_ulogic;
busy : std_ulogic;
bit_cnt : std_ulogic_vector(5 downto 0);
-- shift register --
sreg : std_ulogic_vector(31 downto 0);
next_bit : std_ulogic; -- next bit to send
sreg : std_ulogic_vector(31 downto 0);
next_bit : std_ulogic; -- next bit to send
-- pulse generator --
pulse_clk : std_ulogic; -- pulse cycle "clock"
pulse_cnt : std_ulogic_vector(4 downto 0);
t_high : std_ulogic_vector(4 downto 0);
output : std_ulogic;
pulse_clk : std_ulogic; -- pulse cycle "clock"
pulse_cnt : std_ulogic_vector(4 downto 0);
t_high : std_ulogic_vector(4 downto 0);
strobe_cnt : std_ulogic_vector(6 downto 0);
tx_out : std_ulogic;
end record;
signal serial : serial_t;
 
182,7 → 178,8
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert not ((is_power_of_two_f(tx_buffer_entries_c) = false) or (tx_buffer_entries_c > 32768)) report "NEORV32 PROCESSOR CONFIG ERROR! Invalid <IO.NEOPIX> buffer size configuration!" severity error;
assert not ((is_power_of_two_f(FIFO_DEPTH) = false) or (FIFO_DEPTH < 1) or (FIFO_DEPTH > 32768)) report
"NEORV32 PROCESSOR CONFIG ERROR! Invalid <NEOLED.FIFO_DEPTH> buffer size configuration (1..32k)!" severity error;
 
 
-- Access Control -------------------------------------------------------------------------
201,39 → 198,33
-- access acknowledge --
ack_o <= wren or rden;
 
-- write access --
tx_buffer.we <= '0';
if (wren = '1') then
-- control register --
if (addr = neoled_ctrl_addr_c) then
ctrl.enable <= data_i(ctrl_enable_c);
ctrl.mode <= data_i(ctrl_mode_c);
ctrl.bscon <= data_i(ctrl_bscon_c);
ctrl.clk_prsc <= data_i(ctrl_clksel2_c downto ctrl_clksel0_c);
ctrl.t_total <= data_i(ctrl_t_tot_4_c downto ctrl_t_tot_0_c);
ctrl.t0_high <= data_i(ctrl_t_0h_4_c downto ctrl_t_0h_0_c);
ctrl.t1_high <= data_i(ctrl_t_1h_4_c downto ctrl_t_1h_0_c);
end if;
-- tx data register (FIFO) --
if (addr = neoled_data_addr_c) then
tx_buffer.wdata <= data_i;
tx_buffer.we <= tx_buffer.free; -- only write new data if there is at least one free entry left
end if;
-- write access: control register --
if (wren = '1') and (addr = neoled_ctrl_addr_c) then
ctrl.enable <= data_i(ctrl_enable_c);
ctrl.mode <= data_i(ctrl_mode_c);
ctrl.strobe <= data_i(ctrl_strobe_c);
ctrl.clk_prsc <= data_i(ctrl_clksel2_c downto ctrl_clksel0_c);
ctrl.t_total <= data_i(ctrl_t_tot_4_c downto ctrl_t_tot_0_c);
ctrl.t0_high <= data_i(ctrl_t_0h_4_c downto ctrl_t_0h_0_c);
ctrl.t1_high <= data_i(ctrl_t_1h_4_c downto ctrl_t_1h_0_c);
end if;
 
-- read access: control register --
data_o <= (others => '0');
if (rden = '1') and (addr = neoled_ctrl_addr_c) then
if (rden = '1') then -- and (addr = neoled_ctrl_addr_c) then
data_o(ctrl_enable_c) <= ctrl.enable;
data_o(ctrl_mode_c) <= ctrl.mode;
data_o(ctrl_bscon_c) <= ctrl.bscon;
data_o(ctrl_strobe_c) <= ctrl.strobe;
data_o(ctrl_clksel2_c downto ctrl_clksel0_c) <= ctrl.clk_prsc;
data_o(ctrl_bufs_3_c downto ctrl_bufs_0_c) <= std_ulogic_vector(to_unsigned(index_size_f(tx_buffer_entries_c), 4));
data_o(ctrl_bufs_3_c downto ctrl_bufs_0_c) <= std_ulogic_vector(to_unsigned(index_size_f(FIFO_DEPTH), 4));
data_o(ctrl_t_tot_4_c downto ctrl_t_tot_0_c) <= ctrl.t_total;
data_o(ctrl_t_0h_4_c downto ctrl_t_0h_0_c) <= ctrl.t0_high;
data_o(ctrl_t_1h_4_c downto ctrl_t_1h_0_c) <= ctrl.t1_high;
data_o(ctrl_tx_status_c) <= serial.busy;
data_o(ctrl_busy_c) <= not ctrl.ready;
--
data_o(ctrl_tx_empty_c) <= not tx_buffer.avail;
data_o(ctrl_tx_half_c) <= tx_buffer.half;
data_o(ctrl_tx_full_c) <= not tx_buffer.free;
data_o(ctrl_tx_busy_c) <= serial.busy;
end if;
end if;
end process rw_access;
241,23 → 232,40
-- enable external clock generator --
clkgen_en_o <= ctrl.enable;
 
-- FIFO write access --
tx_buffer.we <= '1' when (wren = '1') and (addr = neoled_data_addr_c) else '0';
tx_buffer.wdata <= ctrl.strobe & ctrl.mode & data_i;
tx_buffer.clear <= not ctrl.enable;
 
 
-- IRQ Generator --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
irq_generator: process(clk_i)
begin
if rising_edge(clk_i) then
tx_buffer.half_ff <= tx_buffer.half;
irq_o <= ctrl.enable and tx_buffer.half and (not tx_buffer.half_ff); -- FIFO _becomes_ half-full
end if;
end process irq_generator;
 
 
-- TX Buffer (FIFO) -----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
tx_data_fifo: neorv32_fifo
generic map (
FIFO_DEPTH => tx_buffer_entries_c, -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH => 32+1, -- size of data elements in fifo
FIFO_RSYNC => true, -- sync read
FIFO_SAFE => false -- no safe access required (ensured by FIFO-external control)
FIFO_DEPTH => FIFO_DEPTH, -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH => 32+2, -- size of data elements in fifo
FIFO_RSYNC => true, -- sync read
FIFO_SAFE => true -- safe access
)
port map (
-- control --
clk_i => clk_i, -- clock, rising edge
rstn_i => '1', -- async reset, low-active
clear_i => fifo_clear, -- sync reset, high-active
clear_i => tx_buffer.clear, -- sync reset, high-active
level_o => tx_buffer.level, -- fill level
-- write port --
wdata_i => fifo_wdata, -- write data
wdata_i => tx_buffer.wdata, -- write data
we_i => tx_buffer.we, -- write enable
free_o => tx_buffer.free, -- at least one entry is free when set
-- read port --
266,54 → 274,29
avail_o => tx_buffer.avail -- data available when set
);
 
-- helper signals --
fifo_clear <= not ctrl.enable;
fifo_wdata <= ctrl.mode & tx_buffer.wdata;
tx_buffer.empty <= not tx_buffer.avail;
-- FIFO half-full? --
tx_buffer.half <= '1' when (unsigned(tx_buffer.level) >= to_unsigned(cond_sel_natural_f(boolean(FIFO_DEPTH > 1), FIFO_DEPTH/2, 1), tx_buffer.level'length)) else '0';
 
 
-- Buffer Status Flag and IRQ Generator ---------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- ctrl.bscon = 0: clear buffer/busy status flag and send IRQ if -> there is at least one free entry in buffer
-- ctrl.bscon = 1: clear buffer/busy status flag and send IRQ if -> the complete buffer is empty
irq_generator: process(clk_i)
begin
if rising_edge(clk_i) then
if (ctrl.enable = '1') then
if (ctrl.bscon = '0') then -- one entry is becoming free
irq_o <= (not tx_buffer.free_ff) and tx_buffer.free;
else -- buffer is becoming empty
irq_o <= (not tx_buffer.empty_ff) and tx_buffer.empty;
end if;
else
irq_o <= '0';
end if;
end if;
end process irq_generator;
 
-- ready flag --
ctrl.ready <= tx_buffer.free when (ctrl.bscon = '0') else tx_buffer.empty;
 
 
-- Serial TX Engine -----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
serial_engine: process(clk_i)
begin
if rising_edge(clk_i) then
-- defaults --
-- clock generator --
serial.pulse_clk <= clkgen_i(to_integer(unsigned(ctrl.clk_prsc)));
 
-- disabled --
-- FSM --
if (ctrl.enable = '0') then -- disabled
serial.output <= '0';
serial.state <= S_IDLE;
serial.state <= S_IDLE;
else
case serial.state is
 
when S_IDLE => -- waiting for new TX data
-- ------------------------------------------------------------
serial.output <= '0';
serial.pulse_cnt <= (others => '0');
serial.tx_out <= '0';
serial.pulse_cnt <= (others => '0');
serial.strobe_cnt <= (others => '0');
if (tx_buffer.avail = '1') then
serial.state <= S_INIT;
end if;
320,15 → 303,19
 
when S_INIT => -- initialize TX shift engine
-- ------------------------------------------------------------
if (tx_buffer.rdata(32) = '0') then -- mode = "RGB"
serial.mode <= '0';
serial.bit_cnt <= "011000"; -- total number of bits to send: 3x8=24
else -- mode = "RGBW"
serial.mode <= '1';
serial.bit_cnt <= "100000"; -- total number of bits to send: 4x8=32
if (tx_buffer.rdata(33) = '0') then -- send data
if (tx_buffer.rdata(32) = '0') then -- mode = "RGB"
serial.mode <= '0';
serial.bit_cnt <= "011000"; -- total number of bits to send: 3x8=24
else -- mode = "RGBW"
serial.mode <= '1';
serial.bit_cnt <= "100000"; -- total number of bits to send: 4x8=32
end if;
serial.sreg <= tx_buffer.rdata(31 downto 00);
serial.state <= S_GETBIT;
else -- send RESET command
serial.state <= S_STROBE;
end if;
serial.sreg <= tx_buffer.rdata(31 downto 00);
serial.state <= S_GETBIT;
 
when S_GETBIT => -- get next TX bit
-- ------------------------------------------------------------
344,7 → 331,7
serial.t_high <= ctrl.t1_high;
end if;
serial.state <= S_PULSE; -- transmit single pulse
serial.output <= '1';
serial.tx_out <= '1';
end if;
 
when S_PULSE => -- send pulse with specific duty cycle
355,7 → 342,7
serial.pulse_cnt <= std_ulogic_vector(unsigned(serial.pulse_cnt) + 1);
-- T_high reached? --
if (serial.pulse_cnt = serial.t_high) then
serial.output <= '0';
serial.tx_out <= '0';
end if;
-- T_total reached? --
if (serial.pulse_cnt = ctrl.t_total) then
363,6 → 350,23
end if;
end if;
 
when S_STROBE => -- strobe LED data ("RESET" command)
-- ------------------------------------------------------------
-- wait for 127 * ctrl.t_total to _ensure_ RESET
if (serial.pulse_clk = '1') then
-- T_total reached? --
if (serial.pulse_cnt = ctrl.t_total) then
serial.pulse_cnt <= (others => '0');
serial.strobe_cnt <= std_ulogic_vector(unsigned(serial.strobe_cnt) + 1);
else
serial.pulse_cnt <= std_ulogic_vector(unsigned(serial.pulse_cnt) + 1);
end if;
end if;
-- number of LOW periods reached for RESET? --
if (and_reduce_f(serial.strobe_cnt) = '1') then
serial.state <= S_IDLE;
end if;
 
when others => -- undefined
-- ------------------------------------------------------------
serial.state <= S_IDLE;
369,8 → 373,8
 
end case;
end if;
-- serial data output --
neoled_o <= serial.output; -- IOB.FF
-- serial data tx_out --
neoled_o <= serial.tx_out and ctrl.enable;
end if;
end process serial_engine;
 
/trunk/rtl/core/neorv32_package.vhd
44,13 → 44,7
constant ispace_base_c : std_ulogic_vector(31 downto 0) := x"00000000"; -- default instruction memory address space base address
constant dspace_base_c : std_ulogic_vector(31 downto 0) := x"80000000"; -- default data memory address space base address
 
-- external bus interface --
constant wb_pipe_mode_c : boolean := false; -- protocol: false=classic/standard wishbone mode (default), true=pipelined wishbone mode
constant wb_big_endian_c : boolean := false; -- byte order: true=big-endian, false=little-endian (default)
constant wb_rx_buffer_c : boolean := true; -- use register buffer for RX data when true (default)
 
-- CPU core --
constant ipb_entries_c : natural := 4; -- entries in CPU instruction prefetch buffer, has to be a power of 2, default=2
constant cp_timeout_en_c : boolean := false; -- auto-terminate pending co-processor operations after 256 cycles (for debugging only), default = false
constant dedicated_reset_c : boolean := false; -- use dedicated hardware reset value for UNCRITICAL registers (FALSE=reset value is irrelevant (might simplify HW), default; TRUE=defined LOW reset value)
 
69,10 → 63,9
 
-- 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"01050710"; -- no touchy!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
constant rf_r0_is_reg_c : boolean := true; -- x0 is a *physical register* that has to be initialized to zero by the CPU
constant data_width_c : natural := 32; -- native data path width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01050900"; -- no touchy!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
 
-- External Interface Types ---------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
107,7 → 100,7
function bit_rev_f(input : std_ulogic_vector) return std_ulogic_vector;
function is_power_of_two_f(input : natural) return boolean;
function bswap32_f(input : std_ulogic_vector) return std_ulogic_vector;
function char_tolower_f(ch : character) return character;
function char_to_lower_f(ch : character) return character;
function str_equal_f(str0 : string; str1 : string) return boolean;
impure function mem32_init_f(init : mem32_t; depth : natural) return mem32_t;
 
210,7 → 203,7
constant xirq_enable_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff80";
constant xirq_pending_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff84";
constant xirq_source_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff88";
--constant xirq_res_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff8c";
--constant xirq_reserved_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff8c";
 
-- Machine System Timer (MTIME) --
constant mtime_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff90"; -- base address
292,72 → 285,71
constant ctrl_rf_rd_adr3_c : natural := 14; -- destination register address bit 3
constant ctrl_rf_rd_adr4_c : natural := 15; -- destination register address bit 4
constant ctrl_rf_wb_en_c : natural := 16; -- write back enable
constant ctrl_rf_r0_we_c : natural := 17; -- force write access and force rd=r0
-- alu --
constant ctrl_alu_arith_c : natural := 18; -- ALU arithmetic command
constant ctrl_alu_logic0_c : natural := 19; -- ALU logic command bit 0
constant ctrl_alu_logic1_c : natural := 20; -- ALU logic command bit 1
constant ctrl_alu_func0_c : natural := 21; -- ALU function select command bit 0
constant ctrl_alu_func1_c : natural := 22; -- ALU function select command bit 1
constant ctrl_alu_addsub_c : natural := 23; -- 0=ADD, 1=SUB
constant ctrl_alu_opa_mux_c : natural := 24; -- operand A select (0=rs1, 1=PC)
constant ctrl_alu_opb_mux_c : natural := 25; -- operand B select (0=rs2, 1=IMM)
constant ctrl_alu_unsigned_c : natural := 26; -- is unsigned ALU operation
constant ctrl_alu_shift_dir_c : natural := 27; -- shift direction (0=left, 1=right)
constant ctrl_alu_shift_ar_c : natural := 28; -- is arithmetic shift
constant ctrl_alu_frm0_c : natural := 29; -- FPU rounding mode bit 0
constant ctrl_alu_frm1_c : natural := 30; -- FPU rounding mode bit 1
constant ctrl_alu_frm2_c : natural := 31; -- FPU rounding mode bit 2
constant ctrl_alu_arith_c : natural := 17; -- ALU arithmetic command
constant ctrl_alu_logic0_c : natural := 18; -- ALU logic command bit 0
constant ctrl_alu_logic1_c : natural := 19; -- ALU logic command bit 1
constant ctrl_alu_func0_c : natural := 20; -- ALU function select command bit 0
constant ctrl_alu_func1_c : natural := 21; -- ALU function select command bit 1
constant ctrl_alu_addsub_c : natural := 22; -- 0=ADD, 1=SUB
constant ctrl_alu_opa_mux_c : natural := 23; -- operand A select (0=rs1, 1=PC)
constant ctrl_alu_opb_mux_c : natural := 24; -- operand B select (0=rs2, 1=IMM)
constant ctrl_alu_unsigned_c : natural := 25; -- is unsigned ALU operation
constant ctrl_alu_shift_dir_c : natural := 26; -- shift direction (0=left, 1=right)
constant ctrl_alu_shift_ar_c : natural := 27; -- is arithmetic shift
constant ctrl_alu_frm0_c : natural := 28; -- FPU rounding mode bit 0
constant ctrl_alu_frm1_c : natural := 29; -- FPU rounding mode bit 1
constant ctrl_alu_frm2_c : natural := 30; -- FPU rounding mode bit 2
-- bus interface --
constant ctrl_bus_size_lsb_c : natural := 32; -- transfer size lsb (00=byte, 01=half-word)
constant ctrl_bus_size_msb_c : natural := 33; -- transfer size msb (10=word, 11=?)
constant ctrl_bus_rd_c : natural := 34; -- read data request
constant ctrl_bus_wr_c : natural := 35; -- write data request
constant ctrl_bus_if_c : natural := 36; -- instruction fetch request
constant ctrl_bus_mo_we_c : natural := 37; -- memory address and data output register write enable
constant ctrl_bus_mi_we_c : natural := 38; -- memory data input register write enable
constant ctrl_bus_unsigned_c : natural := 39; -- is unsigned load
constant ctrl_bus_ierr_ack_c : natural := 40; -- acknowledge instruction fetch bus exceptions
constant ctrl_bus_derr_ack_c : natural := 41; -- acknowledge data access bus exceptions
constant ctrl_bus_fence_c : natural := 42; -- executed fence operation
constant ctrl_bus_fencei_c : natural := 43; -- executed fencei operation
constant ctrl_bus_lock_c : natural := 44; -- make atomic/exclusive access lock
constant ctrl_bus_de_lock_c : natural := 45; -- remove atomic/exclusive access
constant ctrl_bus_ch_lock_c : natural := 46; -- evaluate atomic/exclusive lock (SC operation)
constant ctrl_bus_size_lsb_c : natural := 31; -- transfer size lsb (00=byte, 01=half-word)
constant ctrl_bus_size_msb_c : natural := 32; -- transfer size msb (10=word, 11=?)
constant ctrl_bus_rd_c : natural := 33; -- read data request
constant ctrl_bus_wr_c : natural := 34; -- write data request
constant ctrl_bus_if_c : natural := 35; -- instruction fetch request
constant ctrl_bus_mo_we_c : natural := 36; -- memory address and data output register write enable
constant ctrl_bus_mi_we_c : natural := 37; -- memory data input register write enable
constant ctrl_bus_unsigned_c : natural := 38; -- is unsigned load
constant ctrl_bus_ierr_ack_c : natural := 39; -- acknowledge instruction fetch bus exceptions
constant ctrl_bus_derr_ack_c : natural := 40; -- acknowledge data access bus exceptions
constant ctrl_bus_fence_c : natural := 41; -- executed fence operation
constant ctrl_bus_fencei_c : natural := 42; -- executed fencei operation
constant ctrl_bus_lock_c : natural := 43; -- make atomic/exclusive access lock
constant ctrl_bus_de_lock_c : natural := 44; -- remove atomic/exclusive access
constant ctrl_bus_ch_lock_c : natural := 45; -- evaluate atomic/exclusive lock (SC operation)
-- co-processors --
constant ctrl_cp_id_lsb_c : natural := 47; -- cp select ID lsb
constant ctrl_cp_id_msb_c : natural := 48; -- cp select ID msb
constant ctrl_cp_id_lsb_c : natural := 46; -- cp select ID lsb
constant ctrl_cp_id_msb_c : natural := 47; -- cp select ID msb
-- instruction's control blocks (used by cpu co-processors) --
constant ctrl_ir_funct3_0_c : natural := 49; -- funct3 bit 0
constant ctrl_ir_funct3_1_c : natural := 50; -- funct3 bit 1
constant ctrl_ir_funct3_2_c : natural := 51; -- funct3 bit 2
constant ctrl_ir_funct12_0_c : natural := 52; -- funct12 bit 0
constant ctrl_ir_funct12_1_c : natural := 53; -- funct12 bit 1
constant ctrl_ir_funct12_2_c : natural := 54; -- funct12 bit 2
constant ctrl_ir_funct12_3_c : natural := 55; -- funct12 bit 3
constant ctrl_ir_funct12_4_c : natural := 56; -- funct12 bit 4
constant ctrl_ir_funct12_5_c : natural := 57; -- funct12 bit 5
constant ctrl_ir_funct12_6_c : natural := 58; -- funct12 bit 6
constant ctrl_ir_funct12_7_c : natural := 59; -- funct12 bit 7
constant ctrl_ir_funct12_8_c : natural := 60; -- funct12 bit 8
constant ctrl_ir_funct12_9_c : natural := 61; -- funct12 bit 9
constant ctrl_ir_funct12_10_c : natural := 62; -- funct12 bit 10
constant ctrl_ir_funct12_11_c : natural := 63; -- funct12 bit 11
constant ctrl_ir_opcode7_0_c : natural := 64; -- opcode7 bit 0
constant ctrl_ir_opcode7_1_c : natural := 65; -- opcode7 bit 1
constant ctrl_ir_opcode7_2_c : natural := 66; -- opcode7 bit 2
constant ctrl_ir_opcode7_3_c : natural := 67; -- opcode7 bit 3
constant ctrl_ir_opcode7_4_c : natural := 68; -- opcode7 bit 4
constant ctrl_ir_opcode7_5_c : natural := 69; -- opcode7 bit 5
constant ctrl_ir_opcode7_6_c : natural := 70; -- opcode7 bit 6
constant ctrl_ir_funct3_0_c : natural := 48; -- funct3 bit 0
constant ctrl_ir_funct3_1_c : natural := 49; -- funct3 bit 1
constant ctrl_ir_funct3_2_c : natural := 50; -- funct3 bit 2
constant ctrl_ir_funct12_0_c : natural := 51; -- funct12 bit 0
constant ctrl_ir_funct12_1_c : natural := 52; -- funct12 bit 1
constant ctrl_ir_funct12_2_c : natural := 53; -- funct12 bit 2
constant ctrl_ir_funct12_3_c : natural := 54; -- funct12 bit 3
constant ctrl_ir_funct12_4_c : natural := 55; -- funct12 bit 4
constant ctrl_ir_funct12_5_c : natural := 56; -- funct12 bit 5
constant ctrl_ir_funct12_6_c : natural := 57; -- funct12 bit 6
constant ctrl_ir_funct12_7_c : natural := 58; -- funct12 bit 7
constant ctrl_ir_funct12_8_c : natural := 59; -- funct12 bit 8
constant ctrl_ir_funct12_9_c : natural := 60; -- funct12 bit 9
constant ctrl_ir_funct12_10_c : natural := 61; -- funct12 bit 10
constant ctrl_ir_funct12_11_c : natural := 62; -- funct12 bit 11
constant ctrl_ir_opcode7_0_c : natural := 63; -- opcode7 bit 0
constant ctrl_ir_opcode7_1_c : natural := 64; -- opcode7 bit 1
constant ctrl_ir_opcode7_2_c : natural := 65; -- opcode7 bit 2
constant ctrl_ir_opcode7_3_c : natural := 66; -- opcode7 bit 3
constant ctrl_ir_opcode7_4_c : natural := 67; -- opcode7 bit 4
constant ctrl_ir_opcode7_5_c : natural := 68; -- opcode7 bit 5
constant ctrl_ir_opcode7_6_c : natural := 69; -- opcode7 bit 6
-- CPU status --
constant ctrl_priv_lvl_lsb_c : natural := 71; -- privilege level lsb
constant ctrl_priv_lvl_msb_c : natural := 72; -- privilege level msb
constant ctrl_sleep_c : natural := 73; -- set when CPU is in sleep mode
constant ctrl_trap_c : natural := 74; -- set when CPU is entering trap execution
constant ctrl_debug_running_c : natural := 75; -- CPU is in debug mode when set
constant ctrl_priv_lvl_lsb_c : natural := 70; -- privilege level lsb
constant ctrl_priv_lvl_msb_c : natural := 71; -- privilege level msb
constant ctrl_sleep_c : natural := 72; -- set when CPU is in sleep mode
constant ctrl_trap_c : natural := 73; -- set when CPU is entering trap execution
constant ctrl_debug_running_c : natural := 74; -- CPU is in debug mode when set
-- control bus size --
constant ctrl_width_c : natural := 76; -- control bus size
constant ctrl_width_c : natural := 75; -- control bus size
 
-- Comparator Bus -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
515,6 → 507,8
constant csr_mie_c : std_ulogic_vector(11 downto 0) := x"304";
constant csr_mtvec_c : std_ulogic_vector(11 downto 0) := x"305";
constant csr_mcounteren_c : std_ulogic_vector(11 downto 0) := x"306";
--
constant csr_mstatush_c : std_ulogic_vector(11 downto 0) := x"310";
-- machine counter setup --
constant csr_cnt_setup_c : std_ulogic_vector(06 downto 0) := x"3" & "001"; -- counter setup
constant csr_mcountinhibit_c : std_ulogic_vector(11 downto 0) := x"320";
723,6 → 717,7
constant csr_marchid_c : std_ulogic_vector(11 downto 0) := x"f12";
constant csr_mimpid_c : std_ulogic_vector(11 downto 0) := x"f13";
constant csr_mhartid_c : std_ulogic_vector(11 downto 0) := x"f14";
constant csr_mconfigptr_c : std_ulogic_vector(11 downto 0) := x"f15";
-- <<< custom (NEORV32-specific) read-only CSRs >>> --
constant csr_mzext_c : std_ulogic_vector(11 downto 0) := x"fc0";
 
876,10 → 871,10
component neorv32_top
generic (
-- General --
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
INT_BOOTLOADER_EN : boolean := false; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
-- On-Chip Debugger (OCD) --
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
-- RISC-V CPU Extensions --
891,11 → 886,12
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
CPU_IPB_ENTRIES : natural := 2; -- entries is instruction prefetch buffer, has to be a power of 2
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
903,10 → 899,10
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64)
-- Internal Instruction memory (IMEM) --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_EN : boolean := false; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
-- Internal Data memory (DMEM) --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
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) --
ICACHE_EN : boolean := false; -- implement instruction cache
916,6 → 912,9
-- External memory interface (WISHBONE) --
MEM_EXT_EN : boolean := false; -- implement external memory bus interface?
MEM_EXT_TIMEOUT : natural := 255; -- cycles after a pending bus access auto-terminates (0 = disabled)
MEM_EXT_PIPE_MODE : boolean := false; -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
MEM_EXT_BIG_ENDIAN : boolean := false; -- byte order: true=big-endian, false=little-endian
MEM_EXT_ASYNC_RX : boolean := false; -- use register buffer for RX data when false
-- Stream link interface (SLINK) --
SLINK_NUM_TX : natural := 0; -- number of TX links (0..8)
SLINK_NUM_RX : natural := 0; -- number of TX links (0..8)
923,38 → 922,39
SLINK_RX_FIFO : natural := 1; -- RX fifo depth, has to be a power of two
-- External Interrupts Controller (XIRQ) --
XIRQ_NUM_CH : natural := 0; -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0) := (others => '1'); -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) := (others => '1'); -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0) := x"FFFFFFFF"; -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) := x"FFFFFFFF"; -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
-- Processor peripherals --
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean := true; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean := true; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean := true; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean := true; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural := 4; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
IO_GPIO_EN : boolean := false; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean := false; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean := false; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean := false; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean := false; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean := false; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural := 0; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := false; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
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_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
);
port (
-- Global control --
clk_i : in std_ulogic := '0'; -- global clock, rising edge
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
-- JTAG on-chip debugger interface --
jtag_trst_i : in std_ulogic := '0'; -- low-active TAP reset (optional)
jtag_tck_i : in std_ulogic := '0'; -- serial clock
jtag_tdi_i : in std_ulogic := '0'; -- serial data input
jtag_trst_i : in std_ulogic := 'U'; -- low-active TAP reset (optional)
jtag_tck_i : in std_ulogic := 'U'; -- serial clock
jtag_tdi_i : in std_ulogic := 'U'; -- serial data input
jtag_tdo_o : out std_ulogic; -- serial data output
jtag_tms_i : in std_ulogic := '0'; -- mode select
jtag_tms_i : in std_ulogic := 'U'; -- mode select
-- Wishbone bus interface (available if MEM_EXT_EN = true) --
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) := (others => '0'); -- read data
wb_dat_i : in std_ulogic_vector(31 downto 0) := (others => 'U'); -- 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
961,8 → 961,8
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 := '0'; -- transfer acknowledge
wb_err_i : in std_ulogic := '0'; -- transfer error
wb_ack_i : in std_ulogic := 'L'; -- transfer acknowledge
wb_err_i : in std_ulogic := 'L'; -- transfer error
-- 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
969,49 → 969,49
-- 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
slink_tx_rdy_i : in std_ulogic_vector(7 downto 0) := (others => '0'); -- ready to send
slink_tx_rdy_i : in std_ulogic_vector(7 downto 0) := (others => 'L'); -- ready to send
-- RX stream interfaces (available if SLINK_NUM_RX > 0) --
slink_rx_dat_i : in sdata_8x32_t := (others => (others => '0')); -- input data
slink_rx_val_i : in std_ulogic_vector(7 downto 0) := (others => '0'); -- valid input
slink_rx_dat_i : in sdata_8x32_t := (others => (others => 'U')); -- input data
slink_rx_val_i : in std_ulogic_vector(7 downto 0) := (others => 'L'); -- valid input
slink_rx_rdy_o : out std_ulogic_vector(7 downto 0); -- ready to receive
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o : out std_ulogic_vector(63 downto 0); -- parallel output
gpio_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- parallel input
gpio_i : in std_ulogic_vector(63 downto 0) := (others => 'U'); -- parallel input
-- primary UART0 (available if IO_UART0_EN = true) --
uart0_txd_o : out std_ulogic; -- UART0 send data
uart0_rxd_i : in std_ulogic := '0'; -- UART0 receive data
uart0_rxd_i : in std_ulogic := 'U'; -- UART0 receive data
uart0_rts_o : out std_ulogic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart0_cts_i : in std_ulogic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional
uart0_cts_i : in std_ulogic := 'L'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional
-- secondary UART1 (available if IO_UART1_EN = true) --
uart1_txd_o : out std_ulogic; -- UART1 send data
uart1_rxd_i : in std_ulogic := '0'; -- UART1 receive data
uart1_rxd_i : in std_ulogic := 'U'; -- UART1 receive data
uart1_rts_o : out std_ulogic; -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional
uart1_cts_i : in std_ulogic := '0'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional
uart1_cts_i : in std_ulogic := 'L'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional
-- SPI (available if IO_SPI_EN = true) --
spi_sck_o : out std_ulogic; -- SPI serial clock
spi_sdo_o : out std_ulogic; -- controller data out, peripheral data in
spi_sdi_i : in std_ulogic := '0'; -- controller data in, peripheral data out
spi_sdi_i : in std_ulogic := 'U'; -- controller data in, peripheral data out
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS
-- TWI (available if IO_TWI_EN = true) --
twi_sda_io : inout std_logic; -- twi serial data line
twi_scl_io : inout std_logic; -- twi serial clock line
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
-- Custom Functions Subsystem IO --
cfs_in_i : in std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0); -- custom CFS inputs conduit
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
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
neoled_o : out std_ulogic; -- async serial data line
-- System time --
mtime_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time from ext. MTIME (if IO_MTIME_EN = false)
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 => '0'); -- IRQ channels
xirq_i : in std_ulogic_vector(XIRQ_NUM_CH-1 downto 0) := (others => 'L'); -- IRQ channels
-- CPU Interrupts --
nm_irq_i : in std_ulogic := '0'; -- non-maskable interrupt
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt, available if IO_MTIME_EN = false
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt
mext_irq_i : in std_ulogic := '0' -- machine external interrupt
nm_irq_i : in std_ulogic := 'L'; -- non-maskable interrupt
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
mext_irq_i : in std_ulogic := 'L' -- machine external interrupt
);
end component;
 
1020,72 → 1020,73
component neorv32_cpu
generic (
-- General --
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0) := x"00000000"; -- cpu boot address
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0) := x"00000000"; -- cpu debug mode start address
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 --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean := false; -- implement CPU debug mode?
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
FAST_MUL_EN : boolean; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural; -- total width of CPU cycle and instret counters (0..64)
CPU_IPB_ENTRIES : natural; -- entries is instruction prefetch buffer, has to be a power of 2
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
PMP_NUM_REGIONS : natural; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40 -- total size of HPM counters (0..64)
HPM_NUM_CNTS : natural; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural -- total size of HPM counters (0..64)
);
port (
-- global control --
clk_i : in std_ulogic := '0'; -- global clock, rising edge
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
sleep_o : out std_ulogic; -- cpu is in sleep mode when set
-- instruction bus interface --
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) := (others => '0'); -- bus read data
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 := '0'; -- bus transfer acknowledge
i_bus_err_i : in std_ulogic := '0'; -- bus transfer error
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; -- executed FENCEI operation
i_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
-- data bus interface --
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) := (others => '0'); -- bus read data
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 := '0'; -- bus transfer acknowledge
d_bus_err_i : in std_ulogic := '0'; -- bus transfer error
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; -- executed FENCE operation
d_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
-- system time input from MTIME --
time_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time
time_i : in std_ulogic_vector(63 downto 0); -- current system time
-- non-maskable interrupt --
nm_irq_i : in std_ulogic := '0'; -- NMI
nm_irq_i : in std_ulogic; -- NMI
-- interrupts (risc-v compliant) --
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt
mext_irq_i : in std_ulogic := '0'; -- machine external interrupt
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt
msw_irq_i : in std_ulogic; -- machine software interrupt
mext_irq_i : in std_ulogic; -- machine external interrupt
mtime_irq_i : in std_ulogic; -- machine timer interrupt
-- fast interrupts (custom) --
firq_i : in std_ulogic_vector(15 downto 0) := (others => '0');
firq_i : in std_ulogic_vector(15 downto 0);
-- debug mode (halt) request --
db_halt_req_i : in std_ulogic := '0'
db_halt_req_i : in std_ulogic
);
end component;
 
1094,28 → 1095,29
component neorv32_cpu_control
generic (
-- General --
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0) := x"00000000"; -- cpu boot address
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0) := x"00000000"; -- cpu debug mode start address
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 --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean := false; -- implement CPU debug mode?
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
-- Extension Options --
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
CPU_CNT_WIDTH : natural; -- total width of CPU cycle and instret counters (0..64)
CPU_IPB_ENTRIES : natural; -- entries is instruction prefetch buffer, has to be a power of 2
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
PMP_NUM_REGIONS : natural; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40 -- total size of HPM counters (0..64)
HPM_NUM_CNTS : natural; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural -- total size of HPM counters (0..64)
);
port (
-- global control --
1169,7 → 1171,7
-- -------------------------------------------------------------------------------------------
component neorv32_cpu_regfile
generic (
CPU_EXTENSION_RISCV_E : boolean := false -- implement embedded RF extension?
CPU_EXTENSION_RISCV_E : boolean -- implement embedded RF extension?
);
port (
-- global control --
1190,12 → 1192,12
component neorv32_cpu_alu
generic (
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false -- use barrel shifter for shift operations
FAST_MUL_EN : boolean; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean -- use barrel shifter for shift operations
);
port (
-- global control --
1222,7 → 1224,7
-- -------------------------------------------------------------------------------------------
component neorv32_cpu_cp_shifter
generic (
FAST_SHIFT_EN : boolean := false -- use barrel shifter for shift operations
FAST_SHIFT_EN : boolean -- use barrel shifter for shift operations
);
port (
-- global control --
1244,8 → 1246,8
-- -------------------------------------------------------------------------------------------
component neorv32_cpu_cp_muldiv
generic (
FAST_MUL_EN : boolean := false; -- use DSPs for faster multiplication
DIVISION_EN : boolean := true -- implement divider hardware
FAST_MUL_EN : boolean; -- use DSPs for faster multiplication
DIVISION_EN : boolean -- implement divider hardware
);
port (
-- global control --
1286,11 → 1288,11
-- -------------------------------------------------------------------------------------------
component neorv32_cpu_bus
generic (
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension?
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024 -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
PMP_NUM_REGIONS : natural; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
);
port (
-- global control --
1349,13 → 1351,13
component neorv32_bus_keeper is
generic (
-- External memory interface --
MEM_EXT_EN : boolean := false; -- implement external memory bus interface?
MEM_EXT_EN : boolean; -- implement external memory bus interface?
-- Internal instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_EN : boolean; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural; -- size of processor-internal instruction memory in bytes
-- Internal data memory --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 8*1024 -- size of processor-internal data memory in bytes
MEM_INT_DMEM_EN : boolean; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural -- size of processor-internal data memory in bytes
);
port (
-- host access --
1374,9 → 1376,9
-- -------------------------------------------------------------------------------------------
component neorv32_icache
generic (
ICACHE_NUM_BLOCKS : natural := 4; -- number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE : natural := 16; -- block size in bytes (min 4), has to be a power of 2
ICACHE_NUM_SETS : natural := 1 -- associativity / number of sets (1=direct_mapped), has to be a power of 2
ICACHE_NUM_BLOCKS : natural; -- number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE : natural; -- block size in bytes (min 4), has to be a power of 2
ICACHE_NUM_SETS : natural -- associativity / number of sets (1=direct_mapped), has to be a power of 2
);
port (
-- global control --
1408,8 → 1410,8
-- -------------------------------------------------------------------------------------------
component neorv32_busswitch
generic (
PORT_CA_READ_ONLY : boolean := false; -- set if controller port A is read-only
PORT_CB_READ_ONLY : boolean := false -- set if controller port B is read-only
PORT_CA_READ_ONLY : boolean; -- set if controller port A is read-only
PORT_CB_READ_ONLY : boolean -- set if controller port B is read-only
);
port (
-- global control --
1465,9 → 1467,9
-- -------------------------------------------------------------------------------------------
component neorv32_imem
generic (
IMEM_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- memory base address
IMEM_SIZE : natural := 4*1024; -- processor-internal instruction memory size in bytes
IMEM_AS_IROM : boolean := false -- implement IMEM as pre-initialized read-only memory?
IMEM_BASE : std_ulogic_vector(31 downto 0); -- memory base address
IMEM_SIZE : natural; -- processor-internal instruction memory size in bytes
IMEM_AS_IROM : boolean -- implement IMEM as pre-initialized read-only memory?
);
port (
clk_i : in std_ulogic; -- global clock line
1485,8 → 1487,8
-- -------------------------------------------------------------------------------------------
component neorv32_dmem
generic (
DMEM_BASE : std_ulogic_vector(31 downto 0) := x"80000000"; -- memory base address
DMEM_SIZE : natural := 4*1024 -- processor-internal instruction memory size in bytes
DMEM_BASE : std_ulogic_vector(31 downto 0); -- memory base address
DMEM_SIZE : natural -- processor-internal instruction memory size in bytes
);
port (
clk_i : in std_ulogic; -- global clock line
1504,7 → 1506,7
-- -------------------------------------------------------------------------------------------
component neorv32_boot_rom
generic (
BOOTROM_BASE : std_ulogic_vector(31 downto 0) := x"FFFF0000" -- boot ROM base address
BOOTROM_BASE : std_ulogic_vector(31 downto 0) -- boot ROM base address
);
port (
clk_i : in std_ulogic; -- global clock line
1578,7 → 1580,7
-- -------------------------------------------------------------------------------------------
component neorv32_uart
generic (
UART_PRIMARY : boolean := true -- true = primary UART (UART0), false = secondary UART (UART1)
UART_PRIMARY : boolean -- true = primary UART (UART0), false = secondary UART (UART1)
);
port (
-- host access --
1656,7 → 1658,7
-- -------------------------------------------------------------------------------------------
component neorv32_pwm
generic (
NUM_CHANNELS : natural := 4 -- number of PWM channels (0..60)
NUM_CHANNELS : natural -- number of PWM channels (0..60)
);
port (
-- host access --
1695,13 → 1697,16
component neorv32_wishbone
generic (
-- Internal instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_EN : boolean; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural; -- size of processor-internal instruction memory in bytes
-- Internal data memory --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 4*1024; -- size of processor-internal data memory in bytes
-- Bus Timeout --
BUS_TIMEOUT : natural := 63 -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception
MEM_INT_DMEM_EN : boolean; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural; -- size of processor-internal data memory in bytes
-- Interface Configuration --
BUS_TIMEOUT : natural; -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception
PIPE_MODE : boolean; -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
BIG_ENDIAN : boolean; -- byte order: true=big-endian, false=little-endian
ASYNC_RX : boolean -- use register buffer for RX data when false
);
port (
-- global control --
1739,8 → 1744,8
component neorv32_cfs
generic (
CFS_CONFIG : std_ulogic_vector(31 downto 0); -- custom CFS configuration generic
CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits
CFS_OUT_SIZE : positive := 32 -- size of CFS output conduit in bits
CFS_IN_SIZE : positive; -- size of CFS input conduit in bits
CFS_OUT_SIZE : positive -- size of CFS output conduit in bits
);
port (
-- host access --
1760,8 → 1765,8
-- interrupt --
irq_o : out std_ulogic; -- interrupt request
-- custom io (conduit) --
cfs_in_i : in std_ulogic_vector(CFS_IN_SIZE-1 downto 0); -- custom inputs
cfs_out_o : out std_ulogic_vector(CFS_OUT_SIZE-1 downto 0) -- custom outputs
cfs_in_i : in std_ulogic_vector(CFS_IN_SIZE-1 downto 0); -- custom inputs
cfs_out_o : out std_ulogic_vector(CFS_OUT_SIZE-1 downto 0) -- custom outputs
);
end component;
 
1768,6 → 1773,9
-- Component: Smart LED (WS2811/WS2812) Interface (NEOLED) --------------------------------
-- -------------------------------------------------------------------------------------------
component neorv32_neoled
generic (
FIFO_DEPTH : natural -- TX FIFO depth (1..32k, power of two)
);
port (
-- host access --
clk_i : in std_ulogic; -- global clock line
1791,10 → 1799,10
-- -------------------------------------------------------------------------------------------
component neorv32_slink
generic (
SLINK_NUM_TX : natural := 8; -- number of TX links (0..8)
SLINK_NUM_RX : natural := 8; -- number of TX links (0..8)
SLINK_TX_FIFO : natural := 1; -- TX fifo depth, has to be a power of two
SLINK_RX_FIFO : natural := 1 -- RX fifo depth, has to be a power of two
SLINK_NUM_TX : natural; -- number of TX links (0..8)
SLINK_NUM_RX : natural; -- number of TX links (0..8)
SLINK_TX_FIFO : natural; -- TX fifo depth, has to be a power of two
SLINK_RX_FIFO : natural -- RX fifo depth, has to be a power of two
);
port (
-- host access --
1823,9 → 1831,9
-- -------------------------------------------------------------------------------------------
component neorv32_xirq
generic (
XIRQ_NUM_CH : natural := 32; -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0) := (others => '1'); -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) := (others => '1') -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
XIRQ_NUM_CH : natural; -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0); -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
);
port (
-- host access --
1848,38 → 1856,39
component neorv32_sysinfo
generic (
-- General --
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_EN : boolean; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural; -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 4*1024; -- size of processor-internal data memory in bytes
MEM_INT_DMEM_EN : boolean; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural; -- size of processor-internal data memory in bytes
-- Internal Cache memory --
ICACHE_EN : boolean := true; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 2), 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
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity (min 1), has to be a power 2
ICACHE_EN : boolean; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural; -- i-cache: number of blocks (min 2), has to be a power of 2
ICACHE_BLOCK_SIZE : natural; -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY : natural; -- i-cache: associativity (min 1), has to be a power 2
-- External memory interface --
MEM_EXT_EN : boolean := false; -- implement external memory bus interface?
MEM_EXT_EN : boolean; -- implement external memory bus interface?
MEM_EXT_BIG_ENDIAN : boolean; -- byte order: true=big-endian, false=little-endian
-- On-Chip Debugger --
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement OCD?
ON_CHIP_DEBUGGER_EN : boolean; -- implement OCD?
-- Processor peripherals --
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean := true; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean := true; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean := true; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean := true; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural := 4; -- number of PWM channels to implement
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := true; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean := true; -- implement custom functions subsystem (CFS)?
IO_SLINK_EN : boolean := true; -- implement stream link interface?
IO_NEOLED_EN : boolean := true; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_XIRQ_NUM_CH : natural := 32 -- number of external interrupt (XIRQ) channels to implement
IO_GPIO_EN : boolean; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural; -- number of PWM channels to implement
IO_WDT_EN : boolean; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean; -- implement custom functions subsystem (CFS)?
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
);
port (
-- host access --
1891,14 → 1900,14
);
end component;
 
-- Component: General Purpose FIFO .............................---------------------------
-- Component: General Purpose FIFO --------------------------------------------------------
-- -------------------------------------------------------------------------------------------
component neorv32_fifo
generic (
FIFO_DEPTH : natural := 4; -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH : natural := 32; -- size of data elements in fifo
FIFO_RSYNC : boolean := false; -- false = async read; true = sync read
FIFO_SAFE : boolean := false -- true = allow read/write only if data available
FIFO_DEPTH : natural; -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH : natural; -- size of data elements in fifo
FIFO_RSYNC : boolean; -- false = async read; true = sync read
FIFO_SAFE : boolean -- true = allow read/write only if entry available
);
port (
-- control --
1905,6 → 1914,7
clk_i : in std_ulogic; -- clock, rising edge
rstn_i : in std_ulogic; -- async reset, low-active
clear_i : in std_ulogic; -- sync reset, high-active
level_o : out std_ulogic_vector(index_size_f(FIFO_DEPTH) downto 0); -- fill level
-- write port --
wdata_i : in std_ulogic_vector(FIFO_WIDTH-1 downto 0); -- write data
we_i : in std_ulogic; -- write enable
1951,9 → 1961,9
-- -------------------------------------------------------------------------------------------
component neorv32_debug_dtm
generic (
IDCODE_VERSION : std_ulogic_vector(03 downto 0) := x"0"; -- version
IDCODE_PARTID : std_ulogic_vector(15 downto 0) := x"cafe"; -- part number
IDCODE_MANID : std_ulogic_vector(10 downto 0) := "00000000000" -- manufacturer id
IDCODE_VERSION : std_ulogic_vector(03 downto 0); -- version
IDCODE_PARTID : std_ulogic_vector(15 downto 0); -- part number
IDCODE_MANID : std_ulogic_vector(10 downto 0) -- manufacturer id
);
port (
-- global control --
2195,7 → 2205,7
 
-- Function: Convert char to lowercase ----------------------------------------------------
-- -------------------------------------------------------------------------------------------
function char_tolower_f(ch : character) return character is
function char_to_lower_f(ch : character) return character is
variable res: character;
begin
case ch is
2228,7 → 2238,7
when others => res := ch;
end case;
return res;
end function char_tolower_f;
end function char_to_lower_f;
 
-- Function: Compare strings (convert to lower case, check lengths) -----------------------
-- -------------------------------------------------------------------------------------------
2241,10 → 2251,10
else
-- convert to lower case --
for i in str0'range loop
tmp0_v(i) := char_tolower_f(str0(i));
tmp0_v(i) := char_to_lower_f(str0(i));
end loop;
for i in str1'range loop
tmp1_v(i) := char_tolower_f(str1(i));
tmp1_v(i) := char_to_lower_f(str1(i));
end loop;
-- compare lowercase strings --
if (tmp0_v = tmp1_v) then
2261,14 → 2271,15
impure function mem32_init_f(init : mem32_t; depth : natural) return mem32_t is
variable mem_v : mem32_t(0 to depth-1);
begin
mem_v := (others => (others => '0')); -- make sure remaining memory entries are set to zero
if (init'length > depth) then
return mem_v;
end if;
for idx_v in 0 to init'length-1 loop -- init only in range of source data array
mem_v(idx_v) := init(idx_v);
end loop; -- idx_v
mem_v := (others => (others => '0')); -- make sure remaining memory entries are set to zero
if (init'length > depth) then
return mem_v;
end if;
for idx_v in 0 to init'length-1 loop -- init only in range of source data array
mem_v(idx_v) := init(idx_v);
end loop; -- idx_v
return mem_v;
end function mem32_init_f;
 
 
end neorv32_package;
/trunk/rtl/core/neorv32_pwm.vhd
44,7 → 44,7
 
entity neorv32_pwm is
generic (
NUM_CHANNELS : natural := 4 -- number of PWM channels (0..60)
NUM_CHANNELS : natural -- number of PWM channels (0..60)
);
port (
-- host access --
/trunk/rtl/core/neorv32_slink.vhd
1,9 → 1,10
-- #################################################################################################
-- # << NEORV32 - Stream Link Interface (SLINK) >> #
-- # ********************************************************************************************* #
-- # Up to 8 input (RX) and up to 8 output (TX) stream links are supported. Each stream direction #
-- # provides a global interrupt to indicate that a RX link has received new data or that a TX #
-- # has finished sending data. Each link is provides an internal FIFO for buffering. #
-- # Up to 8 input (RX) and up to 8 output (TX) stream links are supported. Each link provides an #
-- # internal FIFO for buffering. Each stream direction provides a global interrupt to indicate #
-- # that a RX link has received new data or that a TX link has finished sending data #
-- # (if FIFO_DEPTH = 1) OR if RX/TX link FIFO has become half full (if FIFO_DEPTH > 1). #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
45,10 → 46,10
 
entity neorv32_slink is
generic (
SLINK_NUM_TX : natural := 8; -- number of TX links (0..8)
SLINK_NUM_RX : natural := 8; -- number of TX links (0..8)
SLINK_TX_FIFO : natural := 1; -- TX fifo depth, has to be a power of two
SLINK_RX_FIFO : natural := 1 -- RX fifo depth, has to be a power of two
SLINK_NUM_TX : natural; -- number of TX links (0..8)
SLINK_NUM_RX : natural; -- number of TX links (0..8)
SLINK_TX_FIFO : natural; -- TX fifo depth, has to be a power of two
SLINK_RX_FIFO : natural -- RX fifo depth, has to be a power of two
);
port (
-- host access --
79,43 → 80,34
constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit
constant lo_abb_c : natural := index_size_f(slink_size_c); -- low address boundary bit
 
-- control reg bits --
constant ctrl_rx0_avail_c : natural := 0; -- r/-: set if TX link 0 is ready to send
constant ctrl_rx1_avail_c : natural := 1; -- r/-: set if TX link 1 is ready to send
constant ctrl_rx2_avail_c : natural := 2; -- r/-: set if TX link 2 is ready to send
constant ctrl_rx3_avail_c : natural := 3; -- r/-: set if TX link 3 is ready to send
constant ctrl_rx4_avail_c : natural := 4; -- r/-: set if TX link 4 is ready to send
constant ctrl_rx5_avail_c : natural := 5; -- r/-: set if TX link 5 is ready to send
constant ctrl_rx6_avail_c : natural := 6; -- r/-: set if TX link 6 is ready to send
constant ctrl_rx7_avail_c : natural := 7; -- r/-: set if TX link 7 is ready to send
-- control register bits --
constant ctrl_rx_num_lsb_c : natural := 0; -- r/-: number of implemented RX links
constant ctrl_rx_num_msb_c : natural := 3;
--
constant ctrl_tx0_free_c : natural := 8; -- r/-: set if RX link 0 data available
constant ctrl_tx1_free_c : natural := 9; -- r/-: set if RX link 1 data available
constant ctrl_tx2_free_c : natural := 10; -- r/-: set if RX link 2 data available
constant ctrl_tx3_free_c : natural := 11; -- r/-: set if RX link 3 data available
constant ctrl_tx4_free_c : natural := 12; -- r/-: set if RX link 4 data available
constant ctrl_tx5_free_c : natural := 13; -- r/-: set if RX link 5 data available
constant ctrl_tx6_free_c : natural := 14; -- r/-: set if RX link 6 data available
constant ctrl_tx7_free_c : natural := 15; -- r/-: set if RX link 7 data available
constant ctrl_tx_num_lsb_c : natural := 4; -- r/-: number of implemented TX links
constant ctrl_tx_num_msb_c : natural := 7;
--
constant ctrl_rx_num0_c : natural := 16; -- r/-: number of implemented RX links -1 bit 0
constant ctrl_rx_num1_c : natural := 17; -- r/-: number of implemented RX links -1 bit 1
constant ctrl_rx_num2_c : natural := 18; -- r/-: number of implemented RX links -1 bit 2
constant ctrl_tx_num0_c : natural := 19; -- r/-: number of implemented TX links -1 bit 0
constant ctrl_tx_num1_c : natural := 20; -- r/-: number of implemented TX links -1 bit 1
constant ctrl_tx_num2_c : natural := 21; -- r/-: number of implemented TX links -1 bit 2
constant ctrl_rx_size_lsb_c : natural := 8; -- r/-: log2(RX FIFO size)
constant ctrl_rx_size_msb_c : natural := 11;
--
constant ctrl_rx_size0_c : natural := 22; -- r/-: log2(RX FIFO size) bit 0
constant ctrl_rx_size1_c : natural := 23; -- r/-: log2(RX FIFO size) bit 1
constant ctrl_rx_size2_c : natural := 24; -- r/-: log2(RX FIFO size) bit 2
constant ctrl_rx_size3_c : natural := 25; -- r/-: log2(RX FIFO size) bit 3
constant ctrl_tx_size0_c : natural := 26; -- r/-: log2(TX FIFO size) bit 0
constant ctrl_tx_size1_c : natural := 27; -- r/-: log2(TX FIFO size) bit 1
constant ctrl_tx_size2_c : natural := 28; -- r/-: log2(TX FIFO size) bit 2
constant ctrl_tx_size3_c : natural := 29; -- r/-: log2(TX FIFO size) bit 3
constant ctrl_tx_size_lsb_c : natural := 12; -- r/-: log2(TX FIFO size)
constant ctrl_tx_size_msb_c : natural := 15;
--
constant ctrl_en_c : natural := 31; -- r/w: global enable
constant ctrl_en_c : natural := 31; -- r/w: global enable
 
-- status register bits --
constant status_rx_avail_lsb_c : natural := 0; -- r/-: set if TX link 0..7 is ready to send
constant status_rx_avail_msb_c : natural := 7;
--
constant status_tx_free_lsb_c : natural := 8; -- r/-: set if RX link 0..7 data available
constant status_tx_free_msb_c : natural := 15;
--
constant status_rx_half_lsb_c : natural := 16; -- r/-: set if TX link 0..7 FIFO fill-level is >= half-full
constant status_rx_half_msb_c : natural := 23;
--
constant status_tx_half_lsb_c : natural := 24; -- r/-: set if RX link 0..7 FIFO fill-level is > half-full
constant status_tx_half_msb_c : natural := 31;
 
-- bus access control --
signal ack_read : std_ulogic;
signal ack_write : std_ulogic;
125,18 → 117,34
-- control register --
signal enable : std_ulogic; -- global enable
 
-- interrupt generator --
signal tx_fifo_free_buf : std_ulogic_vector(7 downto 0);
signal rx_fifo_avail_buf : std_ulogic_vector(7 downto 0);
 
-- stream link fifo interface --
type fifo_data_t is array (0 to 7) of std_ulogic_vector(31 downto 0);
signal rx_fifo_rdata : fifo_data_t;
signal fifo_clear : std_ulogic;
signal link_sel : std_ulogic_vector(7 downto 0);
signal tx_fifo_we, tx_fifo_free : std_ulogic_vector(7 downto 0);
signal rx_fifo_re, rx_fifo_avail : std_ulogic_vector(7 downto 0);
type fifo_rx_level_t is array (0 to 7) of std_ulogic_vector(index_size_f(SLINK_RX_FIFO) downto 0);
type fifo_tx_level_t is array (0 to 7) of std_ulogic_vector(index_size_f(SLINK_TX_FIFO) downto 0);
signal rx_fifo_rdata : fifo_data_t;
signal rx_fifo_level : fifo_rx_level_t;
signal tx_fifo_level : fifo_tx_level_t;
signal fifo_clear : std_ulogic;
signal link_sel : std_ulogic_vector(7 downto 0);
signal tx_fifo_we, rx_fifo_re : std_ulogic_vector(7 downto 0);
signal rx_fifo_avail, rx_fifo_avail_ff : std_ulogic_vector(7 downto 0);
signal tx_fifo_free, tx_fifo_free_ff : std_ulogic_vector(7 downto 0);
signal rx_fifo_half, rx_fifo_half_ff : std_ulogic_vector(7 downto 0);
signal tx_fifo_half, tx_fifo_half_ff : std_ulogic_vector(7 downto 0);
 
-- interrupt controller --
type irq_t is record
rx_pending : std_ulogic;
rx_pending_ff : std_ulogic;
rx_fire : std_ulogic;
tx_pending : std_ulogic;
tx_pending_ff : std_ulogic;
tx_fire : std_ulogic;
wr_ack : std_ulogic;
rd_ack : std_ulogic;
end record;
signal irq : irq_t;
 
begin
 
-- Sanity Checks --------------------------------------------------------------------------
166,10 → 174,15
begin
if rising_edge(clk_i) then
-- write access --
ack_write <= '0';
irq.wr_ack <= '0';
ack_write <= '0';
if (acc_en = '1') and (wren_i = '1') then
if (addr(5) = '0') then -- control register
enable <= data_i(ctrl_en_c);
if (addr(5) = '0') then -- control/status
if (addr(4) = '0') then -- control register
enable <= data_i(ctrl_en_c);
else -- status register
irq.wr_ack <= '1';
end if;
ack_write <= '1';
else -- TX links
ack_write <= or_reduce_f(link_sel and tx_fifo_free);
177,18 → 190,25
end if;
 
-- read access --
data_o <= (others => '0');
ack_read <= '0';
irq.rd_ack <= '0';
data_o <= (others => '0');
ack_read <= '0';
if (acc_en = '1') and (rden_i = '1') then
if (addr(5) = '0') then -- control register
data_o(ctrl_rx7_avail_c downto ctrl_rx0_avail_c) <= rx_fifo_avail;
data_o(ctrl_tx7_free_c downto ctrl_tx0_free_c) <= tx_fifo_free;
data_o(ctrl_rx_num2_c downto ctrl_rx_num0_c) <= std_ulogic_vector(to_unsigned(SLINK_NUM_RX-1, 3));
data_o(ctrl_tx_num2_c downto ctrl_tx_num0_c) <= std_ulogic_vector(to_unsigned(SLINK_NUM_TX-1, 3));
data_o(ctrl_rx_size3_c downto ctrl_rx_size0_c) <= std_ulogic_vector(to_unsigned(index_size_f(SLINK_RX_FIFO), 4));
data_o(ctrl_tx_size3_c downto ctrl_tx_size0_c) <= std_ulogic_vector(to_unsigned(index_size_f(SLINK_TX_FIFO), 4));
data_o(ctrl_en_c) <= enable;
if (addr(5) = '0') then -- control/status registers
ack_read <= '1';
if (addr(4) = '0') then -- control register
data_o(ctrl_rx_num_msb_c downto ctrl_rx_num_lsb_c) <= std_ulogic_vector(to_unsigned(SLINK_NUM_RX, 4));
data_o(ctrl_tx_num_msb_c downto ctrl_tx_num_lsb_c) <= std_ulogic_vector(to_unsigned(SLINK_NUM_TX, 4));
data_o(ctrl_rx_size_msb_c downto ctrl_rx_size_lsb_c) <= std_ulogic_vector(to_unsigned(index_size_f(SLINK_RX_FIFO), 4));
data_o(ctrl_tx_size_msb_c downto ctrl_tx_size_lsb_c) <= std_ulogic_vector(to_unsigned(index_size_f(SLINK_TX_FIFO), 4));
data_o(ctrl_en_c) <= enable;
else -- fifo status register
data_o(status_rx_avail_msb_c downto status_rx_avail_lsb_c) <= rx_fifo_avail;
data_o(status_tx_free_msb_c downto status_tx_free_lsb_c) <= tx_fifo_free;
data_o(status_rx_half_msb_c downto status_rx_half_lsb_c) <= rx_fifo_half;
data_o(status_tx_half_msb_c downto status_tx_half_lsb_c) <= tx_fifo_half;
irq.rd_ack <= '1';
end if;
else -- RX links
data_o <= rx_fifo_rdata(to_integer(unsigned(addr(4 downto 2))));
ack_read <= or_reduce_f(link_sel and rx_fifo_avail);
204,21 → 224,75
fifo_clear <= not enable;
 
 
-- FIFO Level Monitoring ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
level_monitor: process(rx_fifo_level, tx_fifo_level)
begin
-- RX FIFO --
rx_fifo_half <= (others => '0');
for i in 0 to SLINK_NUM_RX-1 loop
if (unsigned(rx_fifo_level(i)) >= to_unsigned(cond_sel_natural_f(boolean(SLINK_RX_FIFO > 1), SLINK_RX_FIFO/2, 1), rx_fifo_level(i)'length)) then
rx_fifo_half(i) <= '1';
end if;
end loop;
-- TX FIFO --
tx_fifo_half <= (others => '0');
for i in 0 to SLINK_NUM_TX-1 loop
if (unsigned(tx_fifo_level(i)) >= to_unsigned(cond_sel_natural_f(boolean(SLINK_TX_FIFO > 1), SLINK_TX_FIFO/2, 1), tx_fifo_level(i)'length)) then
tx_fifo_half(i) <= '1';
end if;
end loop;
end process level_monitor;
 
 
-- Interrupt Generator --------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
irq_generator: process(clk_i)
irq_arbiter: process(clk_i)
begin
if rising_edge(clk_i) then
-- buffer status --
tx_fifo_free_buf <= tx_fifo_free;
rx_fifo_avail_buf <= rx_fifo_avail;
-- rising edge detector --
irq_tx_o <= enable and or_reduce_f(tx_fifo_free and (not tx_fifo_free_buf));
irq_rx_o <= enable and or_reduce_f(rx_fifo_avail and (not rx_fifo_avail_buf));
if (enable = '0') then
irq.rx_pending <= '0';
irq.tx_pending <= '0';
else
-- RX IRQ --
if (irq.rx_pending = '0') then
irq.rx_pending <= irq.rx_fire;
elsif (irq.rd_ack = '1') or (irq.wr_ack = '1') then
irq.rx_pending <= '0';
end if;
-- TX IRQ --
if (irq.tx_pending = '0') then
irq.tx_pending <= irq.tx_fire;
elsif (irq.rd_ack = '1') or (irq.wr_ack = '1') then
irq.tx_pending <= '0';
end if;
end if;
-- CPU IRQs --
irq.rx_pending_ff <= irq.rx_pending;
irq.tx_pending_ff <= irq.tx_pending;
irq_rx_o <= irq.rx_pending and (not irq.rx_pending_ff);
irq_tx_o <= irq.tx_pending and (not irq.tx_pending_ff);
end if;
end process irq_generator;
end process irq_arbiter;
 
-- status buffer --
irq_generator_sync: process(clk_i)
begin
if rising_edge(clk_i) then
rx_fifo_avail_ff <= rx_fifo_avail;
rx_fifo_half_ff <= rx_fifo_half;
tx_fifo_free_ff <= tx_fifo_free;
tx_fifo_half_ff <= tx_fifo_half;
end if;
end process irq_generator_sync;
 
-- IRQ event detector --
-- RX interrupt: fire if any RX_FIFO gets full / fire if any RX_FIFO.level becomes half-full
irq.rx_fire <= or_reduce_f(rx_fifo_avail and (not rx_fifo_avail_ff)) when (SLINK_RX_FIFO = 1) else or_reduce_f(rx_fifo_half and (not rx_fifo_half_ff));
-- TX interrupt: fire if any TX_FIFO gets empty / fire if any TX_FIFO.level falls below half-full level
irq.tx_fire <= or_reduce_f(tx_fifo_free and (not tx_fifo_free_ff)) when (SLINK_TX_FIFO = 1) else or_reduce_f((not tx_fifo_half) and tx_fifo_half_ff);
 
 
-- Link Select ----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
link_select: process(addr)
252,7 → 326,7
FIFO_DEPTH => SLINK_TX_FIFO, -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH => 32, -- size of data elements in fifo
FIFO_RSYNC => false, -- false = async read; true = sync read
FIFO_SAFE => true -- true = allow read/write only if data available
FIFO_SAFE => true -- true = allow read/write only if entry available
)
port map (
-- control --
259,6 → 333,7
clk_i => clk_i, -- clock, rising edge
rstn_i => '1', -- async reset, low-active
clear_i => fifo_clear, -- sync reset, high-active
level_o => tx_fifo_level(i), -- fill level
-- write port --
wdata_i => data_i, -- write data
we_i => tx_fifo_we(i), -- write enable
276,6 → 351,7
tx_fifo_free(i) <= '0';
slink_tx_dat_o(i) <= (others => '0');
slink_tx_val_o(i) <= '0';
tx_fifo_level(i) <= (others => '0');
end generate;
 
 
288,7 → 364,7
FIFO_DEPTH => SLINK_RX_FIFO, -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH => 32, -- size of data elements in fifo
FIFO_RSYNC => false, -- false = async read; true = sync read
FIFO_SAFE => true -- true = allow read/write only if data available
FIFO_SAFE => true -- true = allow read/write only if entry available
)
port map (
-- control --
295,6 → 371,7
clk_i => clk_i, -- clock, rising edge
rstn_i => '1', -- async reset, low-active
clear_i => fifo_clear, -- sync reset, high-active
level_o => rx_fifo_level(i), -- fill level
-- write port --
wdata_i => slink_rx_dat_i(i), -- write data
we_i => slink_rx_val_i(i), -- write enable
312,6 → 389,7
rx_fifo_avail(i) <= '0';
slink_rx_rdy_o(i) <= '0';
rx_fifo_rdata(i) <= (others => '0');
rx_fifo_level(i) <= (others => '0');
end generate;
 
 
/trunk/rtl/core/neorv32_sysinfo.vhd
45,38 → 45,39
entity neorv32_sysinfo is
generic (
-- General --
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_EN : boolean; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural; -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 4*1024; -- size of processor-internal data memory in bytes
MEM_INT_DMEM_EN : boolean; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural; -- size of processor-internal data memory in bytes
-- Internal Cache memory --
ICACHE_EN : boolean := true; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 2), 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
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity (min 1), has to be a power 2
ICACHE_EN : boolean; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural; -- i-cache: number of blocks (min 2), has to be a power of 2
ICACHE_BLOCK_SIZE : natural; -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY : natural; -- i-cache: associativity (min 1), has to be a power 2
-- External memory interface --
MEM_EXT_EN : boolean := false; -- implement external memory bus interface?
MEM_EXT_EN : boolean; -- implement external memory bus interface?
MEM_EXT_BIG_ENDIAN : boolean; -- byte order: true=big-endian, false=little-endian
-- On-Chip Debugger --
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement OCD?
ON_CHIP_DEBUGGER_EN : boolean; -- implement OCD?
-- Processor peripherals --
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean := true; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean := true; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean := true; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean := true; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural := 4; -- number of PWM channels to implement
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := true; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean := true; -- implement custom functions subsystem (CFS)?
IO_SLINK_EN : boolean := true; -- implement stream link interface?
IO_NEOLED_EN : boolean := true; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_XIRQ_NUM_CH : natural := 32 -- number of external interrupt (XIRQ) channels to implement
IO_GPIO_EN : boolean; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural; -- number of PWM channels to implement
IO_WDT_EN : boolean; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean; -- implement custom functions subsystem (CFS)?
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
);
port (
-- host access --
129,7 → 130,7
sysinfo_mem(2)(01) <= bool_to_ulogic_f(MEM_EXT_EN); -- external memory bus interface implemented?
sysinfo_mem(2)(02) <= bool_to_ulogic_f(MEM_INT_IMEM_EN); -- processor-internal instruction memory implemented?
sysinfo_mem(2)(03) <= bool_to_ulogic_f(MEM_INT_DMEM_EN); -- processor-internal data memory implemented?
sysinfo_mem(2)(04) <= bool_to_ulogic_f(wb_big_endian_c); -- is external memory bus interface using BIG-endian byte-order?
sysinfo_mem(2)(04) <= bool_to_ulogic_f(MEM_EXT_BIG_ENDIAN); -- is external memory bus interface using BIG-endian byte-order?
sysinfo_mem(2)(05) <= bool_to_ulogic_f(ICACHE_EN); -- processor-internal instruction cache implemented?
--
sysinfo_mem(2)(13 downto 06) <= (others => '0'); -- reserved
/trunk/rtl/core/neorv32_top.vhd
48,10 → 48,10
entity neorv32_top is
generic (
-- General --
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
INT_BOOTLOADER_EN : boolean := false; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
 
-- On-Chip Debugger (OCD) --
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
71,6 → 71,7
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
CPU_IPB_ENTRIES : natural := 2; -- entries is instruction prefetch buffer, has to be a power of 2
 
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
81,11 → 82,11
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64)
 
-- Internal Instruction memory (IMEM) --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_EN : boolean := false; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
 
-- Internal Data memory (DMEM) --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
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) --
97,6 → 98,9
-- External memory interface (WISHBONE) --
MEM_EXT_EN : boolean := false; -- implement external memory bus interface?
MEM_EXT_TIMEOUT : natural := 255; -- cycles after a pending bus access auto-terminates (0 = disabled)
MEM_EXT_PIPE_MODE : boolean := false; -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
MEM_EXT_BIG_ENDIAN : boolean := false; -- byte order: true=big-endian, false=little-endian
MEM_EXT_ASYNC_RX : boolean := false; -- use register buffer for RX data when false
 
-- Stream link interface (SLINK) --
SLINK_NUM_TX : natural := 0; -- number of TX links (0..8)
106,41 → 110,42
 
-- External Interrupts Controller (XIRQ) --
XIRQ_NUM_CH : natural := 0; -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0) := (others => '1'); -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) := (others => '1'); -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0) := x"FFFFFFFF"; -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) := x"FFFFFFFF"; -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
 
-- Processor peripherals --
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean := true; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean := true; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean := true; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean := true; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural := 4; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
IO_GPIO_EN : boolean := false; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean := false; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean := false; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean := false; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean := false; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean := false; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural := 0; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := false; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
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_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
);
port (
-- Global control --
clk_i : in std_ulogic := '0'; -- global clock, rising edge
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
 
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
jtag_trst_i : in std_ulogic := '0'; -- low-active TAP reset (optional)
jtag_tck_i : in std_ulogic := '0'; -- serial clock
jtag_tdi_i : in std_ulogic := '0'; -- serial data input
jtag_trst_i : in std_ulogic := 'U'; -- low-active TAP reset (optional)
jtag_tck_i : in std_ulogic := 'U'; -- serial clock
jtag_tdi_i : in std_ulogic := 'U'; -- serial data input
jtag_tdo_o : out std_ulogic; -- serial data output
jtag_tms_i : in std_ulogic := '0'; -- mode select
jtag_tms_i : in std_ulogic := 'U'; -- mode select
 
-- Wishbone bus interface (available if MEM_EXT_EN = true) --
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) := (others => '0'); -- read data
wb_dat_i : in std_ulogic_vector(31 downto 0) := (others => 'U'); -- 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
147,8 → 152,8
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 := '0'; -- transfer acknowledge
wb_err_i : in std_ulogic := '0'; -- transfer error
wb_ack_i : in std_ulogic := 'L'; -- transfer acknowledge
wb_err_i : in std_ulogic := 'L'; -- transfer error
 
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o : out std_ulogic; -- indicates an executed FENCE operation
157,44 → 162,44
-- 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
slink_tx_rdy_i : in std_ulogic_vector(7 downto 0) := (others => '0'); -- ready to send
slink_tx_rdy_i : in std_ulogic_vector(7 downto 0) := (others => 'L'); -- ready to send
 
-- RX stream interfaces (available if SLINK_NUM_RX > 0) --
slink_rx_dat_i : in sdata_8x32_t := (others => (others => '0')); -- input data
slink_rx_val_i : in std_ulogic_vector(7 downto 0) := (others => '0'); -- valid input
slink_rx_dat_i : in sdata_8x32_t := (others => (others => 'U')); -- input data
slink_rx_val_i : in std_ulogic_vector(7 downto 0) := (others => 'L'); -- valid input
slink_rx_rdy_o : out std_ulogic_vector(7 downto 0); -- ready to receive
 
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o : out std_ulogic_vector(63 downto 0); -- parallel output
gpio_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- parallel input
gpio_i : in std_ulogic_vector(63 downto 0) := (others => 'U'); -- parallel input
 
-- primary UART0 (available if IO_UART0_EN = true) --
uart0_txd_o : out std_ulogic; -- UART0 send data
uart0_rxd_i : in std_ulogic := '0'; -- UART0 receive data
uart0_rxd_i : in std_ulogic := 'U'; -- UART0 receive data
uart0_rts_o : out std_ulogic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart0_cts_i : in std_ulogic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional
uart0_cts_i : in std_ulogic := 'L'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional
 
-- secondary UART1 (available if IO_UART1_EN = true) --
uart1_txd_o : out std_ulogic; -- UART1 send data
uart1_rxd_i : in std_ulogic := '0'; -- UART1 receive data
uart1_rxd_i : in std_ulogic := 'U'; -- UART1 receive data
uart1_rts_o : out std_ulogic; -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional
uart1_cts_i : in std_ulogic := '0'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional
uart1_cts_i : in std_ulogic := 'L'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional
 
-- SPI (available if IO_SPI_EN = true) --
spi_sck_o : out std_ulogic; -- SPI serial clock
spi_sdo_o : out std_ulogic; -- controller data out, peripheral data in
spi_sdi_i : in std_ulogic := '0'; -- controller data in, peripheral data out
spi_sdi_i : in std_ulogic := 'U'; -- controller data in, peripheral data out
spi_csn_o : out std_ulogic_vector(07 downto 0); -- chip-select
 
-- TWI (available if IO_TWI_EN = true) --
twi_sda_io : inout std_logic; -- twi serial data line
twi_scl_io : inout std_logic; -- twi serial clock line
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
 
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
cfs_in_i : in std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0); -- custom CFS inputs conduit
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
 
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
201,17 → 206,17
neoled_o : out std_ulogic; -- async serial data line
 
-- System time --
mtime_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time from ext. MTIME (if IO_MTIME_EN = false)
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 => '0'); -- IRQ channels
xirq_i : in std_ulogic_vector(XIRQ_NUM_CH-1 downto 0) := (others => 'L'); -- IRQ channels
 
-- CPU interrupts --
nm_irq_i : in std_ulogic := '0'; -- non-maskable interrupt
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt, available if IO_MTIME_EN = false
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt
mext_irq_i : in std_ulogic := '0' -- machine external interrupt
nm_irq_i : in std_ulogic := 'L'; -- non-maskable interrupt
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
mext_irq_i : in std_ulogic := 'L' -- machine external interrupt
);
end neorv32_top;
 
321,6 → 326,12
signal slink_rx_irq : std_ulogic;
signal xirq_irq : std_ulogic;
 
-- machine (CPU) interrupts --
signal x_nm_irq, nm_irq_ff : std_ulogic;
signal x_mtime_irq, mtime_irq_ff : std_ulogic;
signal x_msw_irq, msw_irq_ff : std_ulogic;
signal x_mext_irq, mext_irq_ff : std_ulogic;
 
-- misc --
signal mtime_time : std_ulogic_vector(63 downto 0); -- current system time from MTIME
signal cpu_sleep : std_ulogic; -- CPU is in sleep mode when set
351,9 → 362,6
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- clock --
assert not (CLOCK_FREQUENCY = 0) report "NEORV32 PROCESSOR CONFIG ERROR! Core clock frequency (CLOCK_FREQUENCY) not specified." severity error;
 
-- boot configuration --
assert not (INT_BOOTLOADER_EN = true) report "NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Indirect boot via bootloader (processor-internal BOOTROM)." severity note;
assert not ((INT_BOOTLOADER_EN = false) and (MEM_INT_IMEM_EN = true)) report "NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Direct boot from memory (processor-internal IMEM)." severity note;
462,6 → 470,7
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
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
501,10 → 510,9
-- system time input from MTIME --
time_i => mtime_time, -- current system time
-- non-maskable interrupt --
nm_irq_i => nm_irq_i, -- NMI
-- interrupts (risc-v compliant) --
msw_irq_i => msw_irq_i, -- machine software interrupt
mext_irq_i => mext_irq_i, -- machine external interrupt request
nm_irq_i => x_nm_irq, -- NMI
msw_irq_i => x_msw_irq, -- machine software interrupt
mext_irq_i => x_mext_irq, -- machine external interrupt request
mtime_irq_i => mtime_irq, -- machine timer interrupt
-- fast interrupts (custom) --
firq_i => fast_irq, -- fast interrupt trigger
520,6 → 528,17
fence_o <= cpu_d.fence; -- indicates an executed FENCE operation
fencei_o <= cpu_i.fence; -- indicates an executed FENCEI operation
 
-- external machine-level (CPU) interrupts --
nm_irq_ff <= nm_irq_i when rising_edge(clk_i);
mtime_irq_ff <= mtime_irq_i when rising_edge(clk_i);
msw_irq_ff <= msw_irq_i when rising_edge(clk_i);
mext_irq_ff <= mext_irq_i when rising_edge(clk_i);
-- rising-edge detector --
x_nm_irq <= nm_irq_i and (not nm_irq_ff);
x_mtime_irq <= mtime_irq_i and (not mtime_irq_ff);
x_msw_irq <= msw_irq_i and (not msw_irq_ff);
x_mext_irq <= mext_irq_i and (not mext_irq_ff);
 
-- fast interrupts --
fast_irq(00) <= wdt_irq; -- HIGHEST PRIORITY - watchdog timeout
fast_irq(01) <= cfs_irq; -- custom functions subsystem
534,7 → 553,10
fast_irq(10) <= slink_rx_irq; -- SLINK data received
fast_irq(11) <= slink_tx_irq; -- SLINK data send
--
fast_irq(15 downto 12) <= (others => '0'); -- reserved
fast_irq(12) <= '0'; -- reserved
fast_irq(13) <= '0'; -- reserved
fast_irq(14) <= '0'; -- reserved
fast_irq(15) <= '0'; -- reserved
 
 
-- CPU Instruction Cache ------------------------------------------------------------------
773,13 → 795,16
neorv32_wishbone_inst: neorv32_wishbone
generic map (
-- Internal instruction memory --
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
-- Internal data memory --
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
-- Bus Timeout --
BUS_TIMEOUT => MEM_EXT_TIMEOUT -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
-- Interface Configuration --
BUS_TIMEOUT => MEM_EXT_TIMEOUT, -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception
PIPE_MODE => MEM_EXT_PIPE_MODE, -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
BIG_ENDIAN => MEM_EXT_BIG_ENDIAN, -- byte order: true=big-endian, false=little-endian
ASYNC_RX => MEM_EXT_ASYNC_RX -- use register buffer for RX data when false
)
port map (
-- global control --
966,7 → 991,7
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
mtime_irq <= x_mtime_irq; -- use external machine timer interrupt
end generate;
 
 
1216,6 → 1241,9
neorv32_neoled_inst_true:
if (IO_NEOLED_EN = true) generate
neorv32_neoled_inst: neorv32_neoled
generic map (
FIFO_DEPTH => IO_NEOLED_TX_FIFO -- TX FIFO depth (1..32k, power of two)
)
port map (
-- host access --
clk_i => clk_i, -- global clock line
1346,6 → 1374,7
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity (min 1), has to be a power 2
-- External memory interface --
MEM_EXT_EN => MEM_EXT_EN, -- implement external memory bus interface?
MEM_EXT_BIG_ENDIAN => MEM_EXT_BIG_ENDIAN, -- byte order: true=big-endian, false=little-endian
-- On-Chip Debugger --
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement OCD?
-- Processor peripherals --
/trunk/rtl/core/neorv32_uart.vhd
66,7 → 66,7
 
entity neorv32_uart is
generic (
UART_PRIMARY : boolean := true -- true = primary UART (UART0), false = secondary UART (UART1)
UART_PRIMARY : boolean -- true = primary UART (UART0), false = secondary UART (UART1)
);
port (
-- host access --
/trunk/rtl/core/neorv32_wishbone.vhd
8,12 → 8,6
-- # #
-- # Even when all processor-internal memories and IO devices are disabled, the EXTERNAL address #
-- # space ENDS at address 0xffff0000 (begin of internal BOOTROM address space). #
-- # #
-- # The interface uses registers for ALL OUTGOING AND FOR ALL INCOMING signals. Hence, an access #
-- # latency of (at least) 2 cycles is added. #
-- # #
-- # This interface supports classic/standard Wishbone transactions (pkg.wb_pipe_mode_c = false) #
-- # and also pipelined transactions (pkg.wb_pipe_mode_c = true). #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
56,13 → 50,16
entity neorv32_wishbone is
generic (
-- Internal instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_EN : boolean; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural; -- size of processor-internal instruction memory in bytes
-- Internal data memory --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 4*1024; -- size of processor-internal data memory in bytes
-- Bus Timeout --
BUS_TIMEOUT : natural := 63 -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception
MEM_INT_DMEM_EN : boolean; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural; -- size of processor-internal data memory in bytes
-- Interface Configuration --
BUS_TIMEOUT : natural; -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception
PIPE_MODE : boolean; -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
BIG_ENDIAN : boolean; -- byte order: true=big-endian, false=little-endian
ASYNC_RX : boolean -- use register buffer for RX data when false
);
port (
-- global control --
136,8 → 133,8
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- protocol --
assert not (wb_pipe_mode_c = false) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing STANDARD Wishbone protocol." severity note;
assert not (wb_pipe_mode_c = true) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing PIEPLINED Wishbone protocol." severity note;
assert not (PIPE_MODE = false) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing STANDARD Wishbone protocol." severity note;
assert not (PIPE_MODE = true) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing PIEPLINED Wishbone protocol." severity note;
 
-- bus timeout --
assert not (BUS_TIMEOUT /= 0) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing auto-timeout (" & integer'image(BUS_TIMEOUT) & " cycles)." severity note;
144,11 → 141,12
assert not (BUS_TIMEOUT = 0) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing no auto-timeout (can cause permanent CPU stall!)." severity note;
 
-- endianness --
assert not (wb_big_endian_c = false) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing LITTLE-endian byte order." severity note;
assert not (wb_big_endian_c = true) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing BIG-endian byte." severity note;
assert not (BIG_ENDIAN = false) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing LITTLE-endian byte order." severity note;
assert not (BIG_ENDIAN = true) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing BIG-endian byte." severity note;
 
-- async RC --
assert not (wb_rx_buffer_c = false) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing ASYNC RX path." severity note;
-- async RX --
assert not (ASYNC_RX = false) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing registered RX path." severity note;
assert not (ASYNC_RX = true) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing ASYNC RX path." severity note;
 
 
-- Access Control -------------------------------------------------------------------------
194,7 → 192,7
-- buffer all outgoing signals --
ctrl.we <= wren_i;
ctrl.adr <= addr_i;
if (wb_big_endian_c = true) then -- big-endian
if (BIG_ENDIAN = true) then -- big-endian
ctrl.wdat <= bswap32_f(data_i);
ctrl.sel <= bit_rev_f(ben_i);
else -- little-endian
236,10 → 234,10
-- host access --
ack_gated <= wb_ack_i when (ctrl.state = BUSY) else '0'; -- CPU ack gate for "async" RX
rdata_gated <= wb_dat_i when (ctrl.state = BUSY) else (others => '0'); -- CPU read data gate for "async" RX
rdata <= ctrl.rdat when (wb_rx_buffer_c = true) else rdata_gated;
rdata <= ctrl.rdat when (ASYNC_RX = false) else rdata_gated;
 
data_o <= rdata when (wb_big_endian_c = false) else bswap32_f(rdata); -- endianness conversion
ack_o <= ctrl.ack when (wb_rx_buffer_c = true) else ack_gated;
data_o <= rdata when (BIG_ENDIAN = false) else bswap32_f(rdata); -- endianness conversion
ack_o <= ctrl.ack when (ASYNC_RX = false) else ack_gated;
err_o <= ctrl.err;
 
-- wishbone interface --
253,7 → 251,7
wb_dat_o <= ctrl.wdat;
wb_we_o <= ctrl.we;
wb_sel_o <= ctrl.sel;
wb_stb_o <= stb_int when (wb_pipe_mode_c = true) else cyc_int;
wb_stb_o <= stb_int when (PIPE_MODE = true) else cyc_int;
wb_cyc_o <= cyc_int;
 
stb_int <= '1' when (ctrl.state = BUSY) else '0';
/trunk/rtl/core/neorv32_xirq.vhd
2,7 → 2,7
-- # << NEORV32 - External Interrupt Controller (XIRQ) >> #
-- # ********************************************************************************************* #
-- # Simple interrupt controller for platform (processor-external) interrupts. Up to 32 channels #
-- # are supported that get prioritized into a single CPU interrupt. #
-- # are supported that get (optionally) prioritized into a single CPU interrupt. #
-- # #
-- # The actual trigger configuration has to be done before synthesis using the XIRQ_TRIGGER_TYPE #
-- # and XIRQ_TRIGGER_POLARITY generics. These allow to configure channel-independent low-level, #
48,9 → 48,9
 
entity neorv32_xirq is
generic (
XIRQ_NUM_CH : natural := 32; -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0) := (others => '1'); -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) := (others => '1') -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
XIRQ_NUM_CH : natural; -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0); -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
);
port (
-- host access --
/trunk/rtl/templates/processor/neorv32_ProcessorTop_stdlogic.vhd
81,6 → 81,9
-- External memory interface --
MEM_EXT_EN : boolean := false; -- implement external memory bus interface?
MEM_EXT_TIMEOUT : natural := 255; -- cycles after a pending bus access auto-terminates (0 = disabled)
MEM_EXT_PIPE_MODE : boolean := false; -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
MEM_EXT_BIG_ENDIAN : boolean := false; -- byte order: true=big-endian, false=little-endian
MEM_EXT_ASYNC_RX : boolean := false; -- use register buffer for RX data when false
-- Stream link interface --
SLINK_NUM_TX : natural := 0; -- number of TX links (0..8)
SLINK_NUM_RX : natural := 0; -- number of TX links (0..8)
212,10 → 215,10
signal fence_o_int : std_ulogic;
signal fencei_o_int : std_ulogic;
--
signal slink_tx_dat_o_int : sdata_8x32r_t;
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);
signal slink_rx_dat_i_int : sdata_8x32r_t;
signal slink_rx_dat_i_int : sdata_8x32_t;
signal slink_rx_val_i_int : std_logic_vector(7 downto 0);
signal slink_rx_rdy_o_int : std_logic_vector(7 downto 0);
--
300,6 → 303,9
-- External memory interface --
MEM_EXT_EN => MEM_EXT_EN, -- implement external memory bus interface?
MEM_EXT_TIMEOUT => MEM_EXT_TIMEOUT, -- cycles after a pending bus access auto-terminates (0 = disabled)
MEM_EXT_PIPE_MODE => MEM_EXT_PIPE_MODE, -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
MEM_EXT_BIG_ENDIAN => MEM_EXT_BIG_ENDIAN, -- byte order: true=big-endian, false=little-endian
MEM_EXT_ASYNC_RX => MEM_EXT_ASYNC_RX, -- use register buffer for RX data when false
-- Stream link interface --
SLINK_NUM_TX => SLINK_NUM_TX, -- number of TX links (0..8)
SLINK_NUM_RX => SLINK_NUM_RX, -- number of TX links (0..8)
/trunk/rtl/templates/system/neorv32_SystemTop_axi4lite.vhd
86,8 → 86,8
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
-- External Interrupts Controller (XIRQ) --
XIRQ_NUM_CH : natural := 0; -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE : std_logic_vector(31 downto 0) := (others => '1'); -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_logic_vector(31 downto 0) := (others => '1'); -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
XIRQ_TRIGGER_TYPE : std_logic_vector(31 downto 0) := x"FFFFFFFF"; -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_logic_vector(31 downto 0) := x"FFFFFFFF"; -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
-- Processor peripherals --
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)?
99,7 → 99,7
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_logic_vector(31 downto 0); -- custom CFS configuration generic
IO_CFS_CONFIG : std_logic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
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)?
262,7 → 262,6
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert not (wb_pipe_mode_c = true) report "NEORV32 PROCESSOR CONFIG ERROR: AXI4-Lite bridge requires STANDARD/CLASSIC Wishbone mode (package.wb_pipe_mode_c = false)." severity error;
assert not (CPU_EXTENSION_RISCV_A = true) report "NEORV32 PROCESSOR CONFIG WARNING: AXI4-Lite provides NO support for atomic memory operations. LR/SC access via AXI will raise a bus exception." severity warning;
 
 
310,6 → 309,9
-- External memory interface --
MEM_EXT_EN => true, -- implement external memory bus interface?
MEM_EXT_TIMEOUT => 0, -- cycles after a pending bus access auto-terminates (0 = disabled)
MEM_EXT_PIPE_MODE => false, -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
MEM_EXT_BIG_ENDIAN => false, -- byte order: true=big-endian, false=little-endian
MEM_EXT_ASYNC_RX => false, -- use register buffer for RX data when false
-- External Interrupts Controller (XIRQ) --
XIRQ_NUM_CH => XIRQ_NUM_CH, -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE => XIRQ_TRIGGER_TYPE_INT, -- trigger type: 0=level, 1=edge
/trunk/rtl/templates/README.md
6,30 → 6,30
If you want to use one of the provided top entities from this folder, *also* add the according file to the project's
HDL file list and select the according top_template file as top entity or instatiate the top_template within in your design.
 
## Processor
## `processor`
 
### [`neorv32_ProcessorTop_Minimal.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/processor/neorv32_ProcessorTop_Minimal.vhd)
#### [`neorv32_ProcessorTop_Minimal.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/processor/neorv32_ProcessorTop_Minimal.vhd)
 
This setup provides the minimal I/O, for testing the smallest possible design on new boards.
 
### [`neorv32_ProcessorTop_Small.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/processor/neorv32_ProcessorTop_Small.vhd)
#### [`neorv32_ProcessorTop_Small.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/processor/neorv32_ProcessorTop_Small.vhd)
 
This processor setup provides 64kB of data and instruction memory, an RTOS-capable CPU (privileged architecture) and a set of standard peripherals like UART, TWI and SPI.
 
### [`neorv32_ProcessorTop_Test.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/processor/neorv32_ProcessorTop_Test.vhd)
#### [`neorv32_ProcessorTop_Test.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/processor/neorv32_ProcessorTop_Test.vhd)
 
This entity is intended as "FPGA hello world" example for playing with the NEORV32. It uses only some of the
provided peripherals and provides a very simple and basic interface - only the clock, reset, UART and a subset
of the GPIO output port are propagated to the outer world.
 
### [`neorv32_ProcessorTop_stdlogic.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/processor/neorv32_ProcessorTop_stdlogic.vhd)
#### [`neorv32_ProcessorTop_stdlogic.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/processor/neorv32_ProcessorTop_stdlogic.vhd)
 
Same entity (generics and interface ports) as the default NEORV32 Processor top entity (`rtl/core/neorv32_top.vhd`),
but with _resolved_ port signals: All ports are of type `std_logic` or `std_logic_vector`, respectively.
 
## System
## `system`
 
### [`neorv32_ProcessorTop_axi4lite.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/system/neorv32_ProcessorTop_axi4lite)
#### [`neorv32_ProcessorTop_axi4lite.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/system/neorv32_ProcessorTop_axi4lite)
 
This setup provides all the peripheal/IO signals of the default processor top entity, but features an **AXI4-Lite**-compatible bus interface
instead of the default Wishbone b4 interface. The AXI signal naming corresponds to the Xilinx user guide. The Xilinx Vivado IP packer
/trunk/rtl/README.md
6,6 → 6,6
When creating a new synthesis/simulation project make sure that all `*.vhd` files from this folder are added to a
*new design library* called `neorv32`.
 
### [templates`](https://github.com/stnolting/neorv32/tree/master/rtl/templates)
### [`templates`](https://github.com/stnolting/neorv32/tree/master/rtl/templates)
 
Alternative top entities / wrappers for the NEORV32 Processor.
/trunk/setups/examples/Makefile
1,34 → 1,44
OSFLOW := ../osflow
EXAMPLES := ../../examples
TEMPLATES := ../../../rtl/templates
EXAMPLES := ../examples
TEMPLATES := ../../rtl/templates
MV := mv
 
.DEFAULT_GOAL := help
 
TASK := clean $(BITSTREAM)
 
FOMU_REV ?= pvt
OrangeCrab_REV ?= r02-25F
UPduino_REV ?= v3
 
ifndef BOARD
$(error BOARD needs to be set to 'Fomu' or 'UPDuino_v3'!)
endif
#ifndef BOARD
#$(error BOARD needs to be set to 'Fomu', 'iCESugar', 'UPDuino' or 'OrangeCrab' !)
#endif
 
run:
$(eval TASK ?= clean $(BITSTREAM))
$(MAKE) -C $(OSFLOW)/$(BOARD)/ \
$(MAKE) -C $(OSFLOW) -f common.mk \
BOARD_SRC=$(EXAMPLES)/neorv32_$(BOARD)_BoardTop_$(DESIGN).vhd \
TOP=neorv32_$(BOARD)_BoardTop_$(DESIGN) \
ID=$(DESIGN) \
$(TASK)
$(MV) $(OSFLOW)/$(BOARD)/$(BITSTREAM) ./
IMPL="$${BITSTREAM%%.*}"; for item in ".bit" ".svf"; do \
if [ -f "$(OSFLOW)/$$IMPL$$item" ]; then \
$(MV) "$(OSFLOW)/$$IMPL$$item" ./; \
fi \
done
 
# Boards
 
Fomu:
ifeq ($(DESIGN),Minimal)
$(eval IMEM_SRC := ../../../rtl/core/neorv32_imem.vhd)
$(eval IMEM_SRC := ../../rtl/core/neorv32_imem.vhd)
else
$(eval IMEM_SRC := ../devices/ice40/neorv32_imem.ice40up_spram.vhd)
$(eval IMEM_SRC := devices/ice40/neorv32_imem.ice40up_spram.vhd)
endif
$(MAKE) \
BITSTREAM=neorv32_$(BOARD)_$(FOMU_REV)_$(DESIGN).bit \
NEORV32_MEM_SRC="${IMEM_SRC} ../devices/ice40/neorv32_dmem.ice40up_spram.vhd" \
NEORV32_MEM_SRC="${IMEM_SRC} devices/ice40/neorv32_dmem.ice40up_spram.vhd" \
run
 
iCESugar:
36,11 → 46,19
BITSTREAM=neorv32_$(BOARD)_$(DESIGN).bit \
run
 
UPduino_v3:
UPduino:
$(MAKE) \
BITSTREAM=neorv32_$(BOARD)_$(DESIGN).bit \
BITSTREAM=neorv32_$(BOARD)_$(UPduino_REV)_$(DESIGN).bit \
run
 
OrangeCrab:
$(MAKE) \
BITSTREAM=neorv32_$(BOARD)_$(OrangeCrab_REV)_$(DESIGN).bit \
NEORV32_MEM_SRC="../../rtl/core/neorv32_imem.vhd ../../rtl/core/neorv32_dmem.vhd" \
run
 
# Designs
 
Minimal:
$(MAKE) \
DESIGN=$@ \
63,5 → 81,12
$(MAKE) \
DESIGN=$@ \
DESIGN_SRC=$(TEMPLATES)/processor/neorv32_ProcessorTop_Minimal*.vhd \
NEORV32_VERILOG_SRC='../devices/ice40/sb_ice40_components.v ../../examples/neorv32_Fomu_MixedLanguage_ClkGen.v' \
NEORV32_VERILOG_SRC='devices/ice40/sb_ice40_components.v ../examples/neorv32_Fomu_MixedLanguage_ClkGen.v' \
$(BOARD)
 
# Help
 
help:
@echo "Open-Source Synthesis, P&R, Routing and Bitstream Generation"
@echo "Usage: make BOARD=<fpga board> <board top>"
@echo "Example: make BOARD=Fomu Minimal"
/trunk/setups/examples/README.md
1,5 → 1,7
# Examples
 
### :construction: <TODO> Under Construction :construction:
 
## UPduino v3.0
 
* FPGA Board: :books: [tinyVision.ai Inc. UPduino v3 FPGA Board (GitHub)](https://github.com/tinyvision-ai-inc/UPduino-v3.0/), :credit_card: buy on [Tindie](https://www.tindie.com/products/tinyvision_ai/upduino-v30-low-cost-lattice-ice40-fpga-board/)
/trunk/setups/examples/neorv32_OrangeCrab_BoardTop_MinimalBoot.vhd
0,0 → 1,130
-- #################################################################################################
-- # << NEORV32 - Example setup including the bootloader, for the OrangeCrab (c) Board >> #
-- # ********************************************************************************************* #
-- # 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 ECP5;
use ECP5.components.all; -- for device primitives and macros
 
entity neorv32_OrangeCrab_BoardTop_MinimalBoot is
port (
-- Clock and Reset inputs
OrangeCrab_CLK : in std_logic;
OrangeCrab_RST_N : in std_logic;
-- LED outputs
OrangeCrab_LED_RGB_R : out std_logic;
OrangeCrab_LED_RGB_G : out std_logic;
OrangeCrab_LED_RGB_B : out std_logic;
-- UART0
OrangeCrab_GPIO_0 : in std_logic;
OrangeCrab_GPIO_1 : out std_logic;
OrangeCrab_GPIO_9 : out std_logic;
-- USB Pins (which should be statically driven if not being used)
OrangeCrab_USB_D_P : out std_logic;
OrangeCrab_USB_D_N : out std_logic;
OrangeCrab_USB_DP_PU : out std_logic
);
end entity;
 
architecture neorv32_OrangeCrab_BoardTop_MinimalBoot_rtl of neorv32_OrangeCrab_BoardTop_MinimalBoot is
 
-- configuration --
constant f_clock_c : natural := 24000000; -- PLL output clock frequency in Hz
 
-- Globals
signal pll_clk: std_logic;
 
-- internal IO connection --
signal con_pwm : std_logic_vector(2 downto 0);
signal con_gpio_o : std_ulogic_vector(3 downto 0);
 
begin
 
-- Assign USB pins to "0" so as to disconnect OrangeCrab from
-- the host system. Otherwise it would try to talk to
-- us over USB, which wouldn't work since we have no stack.
OrangeCrab_USB_D_P <= '0';
OrangeCrab_USB_D_N <= '0';
OrangeCrab_USB_DP_PU <= '0';
 
-- System PLL -----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
PLL_inst: EHXPLLL
generic map (
CLKI_DIV => 2, -- from `ecppll -i 48 -o 24`
CLKFB_DIV => 1,
CLKOP_DIV => 25
)
port map (
CLKI => OrangeCrab_CLK,
CLKFB => pll_clk,
ENCLKOP => '1',
CLKOP => pll_clk,
LOCK => OrangeCrab_GPIO_9
);
 
-- The core of the problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
 
neorv32_inst: entity work.neorv32_ProcessorTop_MinimalBoot
generic map (
CLOCK_FREQUENCY => f_clock_c, -- clock frequency of clk_i in Hz
MEM_INT_IMEM_SIZE => 16*1024,
MEM_INT_DMEM_SIZE => 8*1024
)
port map (
-- Global control --
clk_i => std_ulogic(pll_clk),
rstn_i => std_ulogic(OrangeCrab_RST_N),
 
-- GPIO --
gpio_o => con_gpio_o,
 
-- primary UART --
uart_txd_o => OrangeCrab_GPIO_1, -- UART0 send data
uart_rxd_i => OrangeCrab_GPIO_0, -- UART0 receive data
uart_rts_o => open, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart_cts_i => '0', -- hw flow control: UART0.TX allowed to transmit, low-active, optional
 
-- PWM (to on-board RGB LED) --
pwm_o => con_pwm
);
 
OrangeCrab_LED_RGB_R <= con_pwm(0) or not con_gpio_o(0);
OrangeCrab_LED_RGB_G <= con_pwm(1);
OrangeCrab_LED_RGB_B <= con_pwm(2);
 
end architecture;
/trunk/setups/examples/neorv32_UPduino_BoardTop_MinimalBoot.vhd
0,0 → 1,164
-- #################################################################################################
-- # << NEORV32 - Example setup for the tinyVision.ai Inc. "UPduino v3" (c) Board >> #
-- # ********************************************************************************************* #
-- # 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 iCE40;
use iCE40.components.all; -- for device primitives and macros
 
entity neorv32_UPduino_BoardTop_MinimalBoot is
port (
-- UART (uart0) --
uart_txd_o : out std_ulogic;
uart_rxd_i : in std_ulogic;
-- GPIO --
gpio_o : out std_ulogic_vector(3 downto 0);
-- PWM (to on-board RGB power LED) --
pwm_o : out std_logic_vector(2 downto 0)
);
end entity;
 
architecture neorv32_UPduino_BoardTop_MinimalBoot_rtl of neorv32_UPduino_BoardTop_MinimalBoot is
 
-- configuration --
constant f_clock_c : natural := 18000000; -- PLL output clock frequency in Hz
 
-- On-chip oscillator --
signal hf_osc_clk : std_logic;
 
-- Globals
signal pll_rstn : std_logic;
signal pll_clk : std_logic;
 
-- internal IO connection --
signal con_pwm : std_logic_vector(2 downto 0);
 
begin
 
-- On-Chip HF Oscillator ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
HSOSC_inst : SB_HFOSC
generic map (
CLKHF_DIV => "0b10" -- 12 MHz
)
port map (
CLKHFPU => '1',
CLKHFEN => '1',
CLKHF => hf_osc_clk
);
 
-- System PLL -----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- Settings generated by icepll -i 12 -o 18:
-- F_PLLIN: 12.000 MHz (given)
-- F_PLLOUT: 18.000 MHz (requested)
-- F_PLLOUT: 18.000 MHz (achieved)
-- FEEDBACK: SIMPLE
-- F_PFD: 12.000 MHz
-- F_VCO: 576.000 MHz
-- DIVR: 0 (4'b0000)
-- DIVF: 47 (7'b0101111)
-- DIVQ: 5 (3'b101)
-- FILTER_RANGE: 1 (3'b001)
Pll_inst : SB_PLL40_CORE
generic map (
FEEDBACK_PATH => "SIMPLE",
DIVR => x"0",
DIVF => 7x"2F",
DIVQ => 3x"5",
FILTER_RANGE => 3x"1"
)
port map (
REFERENCECLK => hf_osc_clk,
PLLOUTCORE => open,
PLLOUTGLOBAL => pll_clk,
EXTFEEDBACK => '0',
DYNAMICDELAY => x"00",
LOCK => pll_rstn,
BYPASS => '0',
RESETB => '1',
LATCHINPUTVALUE => '0',
SDO => open,
SDI => '0',
SCLK => '0'
);
 
-- The core of the problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_inst: entity work.neorv32_ProcessorTop_MinimalBoot
generic map (
CLOCK_FREQUENCY => f_clock_c, -- clock frequency of clk_i in Hz
USER_CODE => x"0001ce40" -- custom user code
)
port map (
-- Global control --
clk_i => std_ulogic(pll_clk),
rstn_i => std_ulogic(pll_rstn),
 
-- GPIO --
gpio_o => gpio_o,
 
-- primary UART --
uart_txd_o => uart_txd_o, -- UART0 send data
uart_rxd_i => uart_rxd_i, -- UART0 receive data
uart_rts_o => open, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart_cts_i => '0', -- hw flow control: UART0.TX allowed to transmit, low-active, optional
 
-- PWM (to on-board RGB LED) --
pwm_o => con_pwm
);
 
-- IO Connection --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
RGB_inst: SB_RGBA_DRV
generic map (
CURRENT_MODE => "0b1",
RGB0_CURRENT => "0b000011",
RGB1_CURRENT => "0b000011",
RGB2_CURRENT => "0b000011"
)
port map (
CURREN => '1', -- I
RGBLEDEN => '1', -- I
RGB0PWM => con_pwm(1), -- I - green - pwm channel 1
RGB1PWM => con_pwm(2), -- I - blue - pwm channel 2
RGB2PWM => con_pwm(0), -- I - red - pwm channel 0
RGB2 => pwm_o(2), -- O - red
RGB1 => pwm_o(1), -- O - blue
RGB0 => pwm_o(0) -- O - green
);
 
end architecture;
/trunk/setups/examples/neorv32_UPduino_BoardTop_UP5KDemo.vhd
0,0 → 1,205
-- #################################################################################################
-- # << NEORV32 - Example setup for the tinyVision.ai Inc. "UPduino v3" (c) Board >> #
-- # ********************************************************************************************* #
-- # 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 iCE40;
use iCE40.components.all; -- for device primitives and macros
 
entity neorv32_UPduino_BoardTop_UP5KDemo is
port (
-- UART (uart0) --
uart_txd_o : out std_ulogic;
uart_rxd_i : in std_ulogic;
-- SPI to on-board flash --
flash_sck_o : out std_ulogic;
flash_sdo_o : out std_ulogic;
flash_sdi_i : in std_ulogic;
flash_csn_o : out std_ulogic; -- NEORV32.SPI_CS(0)
-- SPI to IO pins --
spi_sck_o : out std_ulogic;
spi_sdo_o : out std_ulogic;
spi_sdi_i : in std_ulogic;
spi_csn_o : out std_ulogic; -- NEORV32.SPI_CS(1)
-- TWI --
twi_sda_io : inout std_logic;
twi_scl_io : inout std_logic;
-- GPIO --
gpio_i : in std_ulogic_vector(3 downto 0);
gpio_o : out std_ulogic_vector(3 downto 0);
-- PWM (to on-board RGB power LED) --
pwm_o : out std_ulogic_vector(2 downto 0)
);
end entity;
 
architecture neorv32_UPduino_BoardTop_UP5KDemo_rtl of neorv32_UPduino_BoardTop_UP5KDemo is
 
-- configuration --
constant f_clock_c : natural := 18000000; -- PLL output clock frequency in Hz
 
-- On-chip oscillator --
signal hf_osc_clk : std_logic;
 
-- Globals
signal pll_rstn : std_logic;
signal pll_clk : std_logic;
 
-- internal IO connection --
signal con_pwm : std_ulogic_vector(2 downto 0);
signal con_spi_sdi : std_ulogic;
signal con_spi_csn : std_ulogic;
 
begin
 
-- On-Chip HF Oscillator ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
HSOSC_inst : SB_HFOSC
generic map (
CLKHF_DIV => "0b10" -- 12 MHz
)
port map (
CLKHFPU => '1',
CLKHFEN => '1',
CLKHF => hf_osc_clk
);
 
 
-- System PLL -----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- Settings generated by icepll -i 12 -o 18:
-- F_PLLIN: 12.000 MHz (given)
-- F_PLLOUT: 18.000 MHz (requested)
-- F_PLLOUT: 18.000 MHz (achieved)
-- FEEDBACK: SIMPLE
-- F_PFD: 12.000 MHz
-- F_VCO: 576.000 MHz
-- DIVR: 0 (4'b0000)
-- DIVF: 47 (7'b0101111)
-- DIVQ: 5 (3'b101)
-- FILTER_RANGE: 1 (3'b001)
Pll_inst : SB_PLL40_CORE
generic map (
FEEDBACK_PATH => "SIMPLE",
DIVR => x"0",
DIVF => 7x"2F",
DIVQ => 3x"5",
FILTER_RANGE => 3x"1"
)
port map (
REFERENCECLK => hf_osc_clk,
PLLOUTCORE => open,
PLLOUTGLOBAL => pll_clk,
EXTFEEDBACK => '0',
DYNAMICDELAY => x"00",
LOCK => pll_rstn,
BYPASS => '0',
RESETB => '1',
LATCHINPUTVALUE => '0',
SDO => open,
SDI => '0',
SCLK => '0'
);
 
-- The core of the problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
 
neorv32_inst: entity work.neorv32_ProcessorTop_UP5KDemo
generic map (
CLOCK_FREQUENCY => f_clock_c, -- clock frequency of clk_i in Hz
USER_CODE => x"0001ce40" -- custom user code
)
port map (
-- Global control --
clk_i => std_ulogic(pll_clk),
rstn_i => std_ulogic(pll_rstn),
 
-- primary UART --
uart_txd_o => uart_txd_o,
uart_rxd_i => uart_rxd_i,
uart_rts_o => open,
uart_cts_i => '0',
 
-- SPI to on-board flash --
flash_sck_o => flash_sck_o,
flash_sdo_o => flash_sdo_o,
flash_sdi_i => flash_sdi_i,
flash_csn_o => flash_csn_o,
 
-- SPI to IO pins --
spi_sck_o => spi_sck_o,
spi_sdo_o => spi_sdo_o,
spi_sdi_i => con_spi_sdi,
spi_csn_o => con_spi_csn,
 
-- TWI --
twi_sda_io => twi_sda_io,
twi_scl_io => twi_scl_io,
 
-- GPIO --
gpio_i => gpio_i,
gpio_o => gpio_o,
 
-- PWM (to on-board RGB power LED) --
pwm_o => con_pwm
);
 
-- IO Connection --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
 
-- SPI sdi read-back --
spi_csn_o <= con_spi_csn;
con_spi_sdi <= flash_sdi_i when (con_spi_csn = '0') else spi_sdi_i;
 
-- RGB --
RGB_inst: SB_RGBA_DRV
generic map (
CURRENT_MODE => "0b1",
RGB0_CURRENT => "0b000001",
RGB1_CURRENT => "0b000001",
RGB2_CURRENT => "0b000001"
)
port map (
CURREN => '1', -- I
RGBLEDEN => '1', -- I
RGB0PWM => con_pwm(1), -- I - green - pwm channel 1
RGB1PWM => con_pwm(2), -- I - bluee - pwm channel 2
RGB2PWM => con_pwm(0), -- I - red - pwm channel 0
RGB2 => pwm_o(2), -- O - red
RGB1 => pwm_o(1), -- O - blue
RGB0 => pwm_o(0) -- O - green
);
 
end architecture;
/trunk/setups/osflow/boards/Fomu.mk
0,0 → 1,16
.PHONY: all
 
# Default target: run all required targets to build the DFU image.
all: $(IMPL).dfu
echo "! Built $(IMPL) for $(BOARD) $(FOMU_REV)"
 
# Use dfu-suffix to generate the DFU image from the FPGA bitstream.
${IMPL}.dfu: $(IMPL).bit
$(COPY) $< $@
dfu-suffix -v 1209 -p 70b1 -a $@
 
# Use df-util to load the DFU image onto the Fomu.
load: $(IMPL).dfu
dfu-util -D $<
 
.PHONY: load
/trunk/setups/osflow/boards/OrangeCrab.mk
0,0 → 1,4
.PHONY: all
 
all: bit
echo "! Built $(IMPL) for $(BOARD)"
/trunk/setups/osflow/boards/UPduino.mk
0,0 → 1,4
.PHONY: all
 
all: bit
echo "! Built $(IMPL) for $(BOARD)"
/trunk/setups/osflow/boards/iCESugar.mk
0,0 → 1,4
.PHONY: all
 
all: bit
echo "! Built $(IMPL) for $(BOARD)"
/trunk/setups/osflow/boards/index.mk
0,0 → 1,76
PCF_PATH ?= constraints
 
 
ifeq ($(BOARD),Fomu)
 
$(info Setting constraints and implementation args for BOARD Fomu)
 
# Different Fomu hardware revisions are wired differently and thus
# require different configurations for yosys and nextpnr.
# Configuration is performed by setting the environment variable FOMU_REV accordingly.
 
FOMU_REV ?= pvt
 
ifeq ($(FOMU_REV),evt1)
YOSYSFLAGS ?= -D EVT=1 -D EVT1=1 -D HAVE_PMOD=1
PNRFLAGS ?= --up5k --package sg48
CONSTRAINTS ?= $(PCF_PATH)/$(BOARD)-evt2.pcf
else ifeq ($(FOMU_REV),evt2)
YOSYSFLAGS ?= -D EVT=1 -D EVT2=1 -D HAVE_PMOD=1
PNRFLAGS ?= --up5k --package sg48
CONSTRAINTS ?= $(PCF_PATH)/$(BOARD)-$(FOMU_REV).pcf
else ifeq ($(FOMU_REV),evt3)
YOSYSFLAGS ?= -D EVT=1 -D EVT3=1 -D HAVE_PMOD=1
PNRFLAGS ?= --up5k --package sg48
CONSTRAINTS ?= $(PCF_PATH)/$(BOARD)-$(FOMU_REV).pcf
else ifeq ($(FOMU_REV),hacker)
YOSYSFLAGS ?= -D HACKER=1
PNRFLAGS ?= --up5k --package uwg30
CONSTRAINTS ?= $(PCF_PATH)/$(BOARD)-$(FOMU_REV).pcf
else ifeq ($(FOMU_REV),pvt)
YOSYSFLAGS ?= -D PVT=1
PNRFLAGS ?= --up5k --package uwg30
CONSTRAINTS ?= $(PCF_PATH)/$(BOARD)-$(FOMU_REV).pcf
else
$(error Unrecognized FOMU_REV value. must be "evt1", "evt2", "evt3", "pvt", or "hacker")
endif
 
IMPL := neorv32_Fomu_$(FOMU_REV)_$(ID)
 
endif
 
 
ifeq ($(BOARD),iCESugar)
$(info Setting constraints and implementation args for BOARD iCESugar)
 
CONSTRAINTS ?= $(PCF_PATH)/$(BOARD).pcf
PNRFLAGS ?= --up5k --package sg48 --ignore-loops --timing-allow-fail
IMPL ?= neorv32_$(BOARD)_$(ID)
 
endif
 
 
ifeq ($(BOARD),UPduino)
$(info Setting constraints and implementation args for BOARD UPduino)
 
UPduino_REV ?= v3
 
CONSTRAINTS ?= $(PCF_PATH)/$(BOARD)_v3.pcf
PNRFLAGS ?= --up5k --package sg48 --ignore-loops --timing-allow-fail
IMPL ?= neorv32_$(BOARD)_$(UPduino_REV)_$(ID)
 
endif
 
 
ifeq ($(BOARD),OrangeCrab)
$(info Setting constraints and implementation args for BOARD OrangeCrab)
 
DEVICE_SERIES = ecp5
 
OrangeCrab_REV ?= r02-25F
 
CONSTRAINTS ?= $(PCF_PATH)/$(BOARD).lpf
PNRFLAGS ?= --25k --package CSFBGA285 --ignore-loops --timing-allow-fail
IMPL ?= neorv32_$(BOARD)_$(OrangeCrab_REV)_$(ID)
 
endif
/trunk/setups/osflow/constraints/Fomu-evt2.pcf
0,0 → 1,34
# Configuration for the Fomu 'evt2' board
set_io clki 44
set_io clki_alt 20
set_io rgb[0] 39
set_io rgb[1] 40
set_io rgb[2] 41
set_io pmod[0] 25
set_io pmod[1] 26
set_io pmod[2] 27
set_io pmod[3] 28
set_io user[0] 48
set_io user[1] 47
set_io user[2] 46
set_io user[3] 45
set_io user[4] 42
set_io user[5] 38
set_io spi_mosi 14
set_io spi_miso 17
set_io spi_clk 15
set_io spi_cs 16
set_io spi_io2 18
set_io spi_io3 19
set_io uart_tx 21
set_io uart_rx 13
set_io usb_dn 37
set_io usb_dp 34
set_io usb_dp_pu 35
set_io usb_dn_pu 36
set_io dbg[0] 20
set_io dbg[1] 12
set_io dbg[2] 11
set_io dbg[3] 23
set_io dbg[4] 10
set_io dbg[5] 9
/trunk/setups/osflow/constraints/Fomu-evt3.pcf
0,0 → 1,34
# Configuration for the Fomu 'evt3' board
set_io rgb[0] 39
set_io rgb[1] 40
set_io rgb[2] 41
set_io pmod[0] 28
set_io pmod[1] 27
set_io pmod[2] 26
set_io pmod[3] 23
set_io clki_alt 20
set_io clki 44
set_io user[0] 48
set_io user[1] 47
set_io user[2] 46
set_io user[3] 45
set_io user[4] 42
set_io user[5] 38
set_io spi_mosi 14
set_io spi_miso 17
set_io spi_clk 15
set_io spi_io2 18
set_io spi_io3 19
set_io spi_cs 16
set_io uart_tx 21
set_io uart_rx 13
set_io usb_dn 37
set_io usb_dp 34
set_io usb_dp_pu 35
set_io usb_dn_pu 36
set_io dbg[0] 20
set_io dbg[1] 12
set_io dbg[2] 11
set_io dbg[3] 25
set_io dbg[4] 10
set_io dbg[5] 9
/trunk/setups/osflow/constraints/Fomu-hacker.pcf
0,0 → 1,16
# Configuration for the Fomu 'hacker' board
set_io clki F5 # Clock input from 48MHz Oscillator
set_io rgb[0] A5 # Blue LED
set_io rgb[1] B5 # Green LED
set_io rgb[2] C5 # Red LED
set_io user[0] F4 # User touch pad 1
set_io user[1] E5 # User touch pad 2
set_io user[2] E4 # User touch pad 3
set_io user[3] F2 # User touch pad 4
set_io spi_mosi F1 # SPI Master Out, Slave In Pin
set_io spi_miso E1 # SPI Master In, Slave Out Pin
set_io spi_clk D1 # SPI Master Clock Output Pin
set_io spi_cs C1 # SPI Chip Select
set_io usb_dn A2 # USB D- pad
set_io usb_dp A4 # USB D+ pad
set_io usb_dp_pu D5 # USB D+ pull up (indicates device connected)
/trunk/setups/osflow/constraints/Fomu-pvt.pcf
0,0 → 1,18
# Configuration for the Fomu 'pvt' board
set_io clki F4 # Clock input from 48MHz Oscillator
set_io rgb[0] A5 # Blue LED
set_io rgb[1] B5 # Green LED
set_io rgb[2] C5 # Red LED
set_io user[0] E4 # User touch pad 1
set_io user[1] D5 # User touch pad 2
set_io user[2] E5 # User touch pad 3
set_io user[3] F5 # User touch pad 4
set_io spi_mosi F1 # SPI Master Out, Slave In Pin
set_io spi_miso E1 # SPI Master In, Slave Out Pin
set_io spi_clk D1 # SPI Master Clock Output Pin
set_io spi_cs C1 # SPI Chip Select
set_io spi_io2 F2
set_io spi_io3 B1
set_io usb_dn A2 # USB D- pad
set_io usb_dp A1 # USB D+ pad
set_io usb_dp_pu A4 # USB D+ pull up (indicates device connected)
/trunk/setups/osflow/constraints/OrangeCrab.lpf
0,0 → 1,278
#| OrangeCrab-r02-25F
 
 
LOCATE COMP "OrangeCrab_CLK" SITE "A9";
IOBUF PORT "OrangeCrab_CLK" IO_TYPE=LVCMOS33;
FREQUENCY PORT "OrangeCrab_CLK" 48.0 MHz;
 
LOCATE COMP "OrangeCrab_RST_N" SITE "V17";
IOBUF PORT "OrangeCrab_RST_N" IO_TYPE=LVCMOS33;
 
LOCATE COMP "OrangeCrab_LED_RGB_R" SITE "K4";
IOBUF PORT "OrangeCrab_LED_RGB_R" IO_TYPE=LVCMOS33;
LOCATE COMP "OrangeCrab_LED_RGB_G" SITE "M3";
IOBUF PORT "OrangeCrab_LED_RGB_G" IO_TYPE=LVCMOS33;
LOCATE COMP "OrangeCrab_LED_RGB_B" SITE "J3";
IOBUF PORT "OrangeCrab_LED_RGB_B" IO_TYPE=LVCMOS33;
 
LOCATE COMP "OrangeCrab_USR_BTN" SITE "J17";
IOBUF PORT "OrangeCrab_USR_BTN" IO_TYPE=SSTL135_I;
 
LOCATE COMP "OrangeCrab_USB_D_P" SITE "N1";
IOBUF PORT "OrangeCrab_USB_D_P" IO_TYPE=LVCMOS33;
LOCATE COMP "OrangeCrab_USB_D_N" SITE "M2";
IOBUF PORT "OrangeCrab_USB_D_N" IO_TYPE=LVCMOS33;
LOCATE COMP "OrangeCrab_USB_DP_PU" SITE "N2";
IOBUF PORT "OrangeCrab_USB_DP_PU" IO_TYPE=LVCMOS33;
 
LOCATE COMP "OrangeCrab_GPIO_0" SITE "N17";
IOBUF PORT "OrangeCrab_GPIO_0" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_0" PULLMODE=DOWN;
LOCATE COMP "OrangeCrab_GPIO_1" SITE "M18";
IOBUF PORT "OrangeCrab_GPIO_1" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_1" PULLMODE=DOWN;
LOCATE COMP "OrangeCrab_GPIO_5" SITE "B10";
IOBUF PORT "OrangeCrab_GPIO_5" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_5" PULLMODE=DOWN;
LOCATE COMP "OrangeCrab_GPIO_6" SITE "B9";
IOBUF PORT "OrangeCrab_GPIO_6" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_6" PULLMODE=DOWN;
LOCATE COMP "OrangeCrab_GPIO_9" SITE "C8";
IOBUF PORT "OrangeCrab_GPIO_9" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_9" PULLMODE=DOWN;
LOCATE COMP "OrangeCrab_GPIO_10" SITE "B8";
IOBUF PORT "OrangeCrab_GPIO_10" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_10" PULLMODE=DOWN;
LOCATE COMP "OrangeCrab_GPIO_11" SITE "A8";
IOBUF PORT "OrangeCrab_GPIO_11" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_11" PULLMODE=DOWN;
LOCATE COMP "OrangeCrab_GPIO_12" SITE "H2";
IOBUF PORT "OrangeCrab_GPIO_12" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_12" PULLMODE=DOWN;
LOCATE COMP "OrangeCrab_GPIO_13" SITE "J2";
IOBUF PORT "OrangeCrab_GPIO_13" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_13" PULLMODE=DOWN;
LOCATE COMP "OrangeCrab_GPIO_A0" SITE "L4";
IOBUF PORT "OrangeCrab_GPIO_A0" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_A0" PULLMODE=DOWN;
LOCATE COMP "OrangeCrab_GPIO_A1" SITE "N3";
IOBUF PORT "OrangeCrab_GPIO_A1" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_A1" PULLMODE=DOWN;
LOCATE COMP "OrangeCrab_GPIO_A2" SITE "N4";
IOBUF PORT "OrangeCrab_GPIO_A2" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_A2" PULLMODE=DOWN;
LOCATE COMP "OrangeCrab_GPIO_A3" SITE "H4";
IOBUF PORT "OrangeCrab_GPIO_A3" IO_TYPE=LVCMOS33;
IOBUF PORT "OrangeCrab_GPIO_A3" PULLMODE=DOWN;
 
LOCATE COMP "OrangeCrab_DDRAM_A[0]" SITE "C4";
IOBUF PORT "OrangeCrab_DDRAM_A[0]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[0]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[1]" SITE "D2";
IOBUF PORT "OrangeCrab_DDRAM_A[1]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[1]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[2]" SITE "D3";
IOBUF PORT "OrangeCrab_DDRAM_A[2]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[2]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[3]" SITE "A3";
IOBUF PORT "OrangeCrab_DDRAM_A[3]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[3]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[4]" SITE "A4";
IOBUF PORT "OrangeCrab_DDRAM_A[4]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[4]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[5]" SITE "D4";
IOBUF PORT "OrangeCrab_DDRAM_A[5]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[5]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[6]" SITE "C3";
IOBUF PORT "OrangeCrab_DDRAM_A[6]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[6]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[7]" SITE "B2";
IOBUF PORT "OrangeCrab_DDRAM_A[7]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[7]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[8]" SITE "B1";
IOBUF PORT "OrangeCrab_DDRAM_A[8]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[8]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[9]" SITE "D1";
IOBUF PORT "OrangeCrab_DDRAM_A[9]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[9]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[10]" SITE "A7";
IOBUF PORT "OrangeCrab_DDRAM_A[10]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[10]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[11]" SITE "C2";
IOBUF PORT "OrangeCrab_DDRAM_A[11]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[11]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[12]" SITE "B6";
IOBUF PORT "OrangeCrab_DDRAM_A[12]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[12]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[13]" SITE "C1";
IOBUF PORT "OrangeCrab_DDRAM_A[13]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[13]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[14]" SITE "A2";
IOBUF PORT "OrangeCrab_DDRAM_A[14]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[14]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_A[15]" SITE "C7";
IOBUF PORT "OrangeCrab_DDRAM_A[15]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_A[15]" IO_TYPE=SSTL135_I;
 
LOCATE COMP "OrangeCrab_DDRAM_BA[0]" SITE "D6";
IOBUF PORT "OrangeCrab_DDRAM_BA[0]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_BA[0]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_BA[1]" SITE "B7";
IOBUF PORT "OrangeCrab_DDRAM_BA[1]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_BA[1]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_BA[2]" SITE "A6";
IOBUF PORT "OrangeCrab_DDRAM_BA[2]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_BA[2]" IO_TYPE=SSTL135_I;
 
LOCATE COMP "OrangeCrab_DDRAM_RAS_N" SITE "C12";
IOBUF PORT "OrangeCrab_DDRAM_RAS_N" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_RAS_N" IO_TYPE=SSTL135_I;
 
LOCATE COMP "OrangeCrab_DDRAM_CAS_N" SITE "D13";
IOBUF PORT "OrangeCrab_DDRAM_CAS_N" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_CAS_N" IO_TYPE=SSTL135_I;
 
LOCATE COMP "OrangeCrab_DDRAM_WE_N" SITE "B12";
IOBUF PORT "OrangeCrab_DDRAM_WE_N" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_WE_N" IO_TYPE=SSTL135_I;
 
LOCATE COMP "OrangeCrab_DDRAM_CS_N" SITE "A12";
IOBUF PORT "OrangeCrab_DDRAM_CS_N" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_CS_N" IO_TYPE=SSTL135_I;
 
LOCATE COMP "OrangeCrab_DDRAM_DM[0]" SITE "D16";
IOBUF PORT "OrangeCrab_DDRAM_DM[0]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DM[0]" IO_TYPE=SSTL135_I;
LOCATE COMP "OrangeCrab_DDRAM_DM[1]" SITE "G16";
IOBUF PORT "OrangeCrab_DDRAM_DM[1]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DM[1]" IO_TYPE=SSTL135_I;
 
LOCATE COMP "OrangeCrab_DDRAM_DQ[0]" SITE "C17";
IOBUF PORT "OrangeCrab_DDRAM_DQ[0]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[0]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[0]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[1]" SITE "D15";
IOBUF PORT "OrangeCrab_DDRAM_DQ[1]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[1]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[1]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[2]" SITE "B17";
IOBUF PORT "OrangeCrab_DDRAM_DQ[2]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[2]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[2]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[3]" SITE "C16";
IOBUF PORT "OrangeCrab_DDRAM_DQ[3]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[3]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[3]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[4]" SITE "A15";
IOBUF PORT "OrangeCrab_DDRAM_DQ[4]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[4]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[4]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[5]" SITE "B13";
IOBUF PORT "OrangeCrab_DDRAM_DQ[5]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[5]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[5]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[6]" SITE "A17";
IOBUF PORT "OrangeCrab_DDRAM_DQ[6]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[6]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[6]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[7]" SITE "A13";
IOBUF PORT "OrangeCrab_DDRAM_DQ[7]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[7]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[7]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[8]" SITE "F17";
IOBUF PORT "OrangeCrab_DDRAM_DQ[8]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[8]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[8]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[9]" SITE "F16";
IOBUF PORT "OrangeCrab_DDRAM_DQ[9]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[9]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[9]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[10]" SITE "G15";
IOBUF PORT "OrangeCrab_DDRAM_DQ[10]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[10]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[10]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[11]" SITE "F15";
IOBUF PORT "OrangeCrab_DDRAM_DQ[11]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[11]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[11]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[12]" SITE "J16";
IOBUF PORT "OrangeCrab_DDRAM_DQ[12]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[12]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[12]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[13]" SITE "C18";
IOBUF PORT "OrangeCrab_DDRAM_DQ[13]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[13]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[13]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[14]" SITE "H16";
IOBUF PORT "OrangeCrab_DDRAM_DQ[14]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[14]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[14]" TERMINATION=OFF;
LOCATE COMP "OrangeCrab_DDRAM_DQ[15]" SITE "F18";
IOBUF PORT "OrangeCrab_DDRAM_DQ[15]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQ[15]" IO_TYPE=SSTL135_I;
IOBUF PORT "OrangeCrab_DDRAM_DQ[15]" TERMINATION=OFF;
 
LOCATE COMP "OrangeCrab_DDRAM_DQS_P[0]" SITE "B15";
IOBUF PORT "OrangeCrab_DDRAM_DQS_P[0]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQS_P[0]" IO_TYPE=SSTL135D_I;
IOBUF PORT "OrangeCrab_DDRAM_DQS_P[0]" TERMINATION=OFF;
IOBUF PORT "OrangeCrab_DDRAM_DQS_P[0]" DIFFRESISTOR=100;
LOCATE COMP "OrangeCrab_DDRAM_DQS_P[1]" SITE "G18";
IOBUF PORT "OrangeCrab_DDRAM_DQS_P[1]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_DQS_P[1]" IO_TYPE=SSTL135D_I;
IOBUF PORT "OrangeCrab_DDRAM_DQS_P[1]" TERMINATION=OFF;
IOBUF PORT "OrangeCrab_DDRAM_DQS_P[1]" DIFFRESISTOR=100;
 
LOCATE COMP "OrangeCrab_DDRAM_CLK_P" SITE "J18";
IOBUF PORT "OrangeCrab_DDRAM_CLK_P" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_CLK_P" IO_TYPE=SSTL135D_I;
 
LOCATE COMP "OrangeCrab_DDRAM_CKE" SITE "D18";
IOBUF PORT "OrangeCrab_DDRAM_CKE" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_CKE" IO_TYPE=SSTL135_I;
 
LOCATE COMP "OrangeCrab_DDRAM_ODT" SITE "C13";
IOBUF PORT "OrangeCrab_DDRAM_ODT" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_ODT" IO_TYPE=SSTL135_I;
 
LOCATE COMP "OrangeCrab_DDRAM_RESET_N" SITE "L18";
IOBUF PORT "OrangeCrab_DDRAM_RESET_N" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_RESET_N" IO_TYPE=SSTL135_I;
 
LOCATE COMP "OrangeCrab_DDRAM_VCCIO[0]" SITE "K16";
IOBUF PORT "OrangeCrab_DDRAM_VCCIO[0]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_VCCIO[0]" IO_TYPE=SSTL135_II;
LOCATE COMP "OrangeCrab_DDRAM_VCCIO[1]" SITE "D17";
IOBUF PORT "OrangeCrab_DDRAM_VCCIO[1]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_VCCIO[1]" IO_TYPE=SSTL135_II;
LOCATE COMP "OrangeCrab_DDRAM_VCCIO[2]" SITE "K15";
IOBUF PORT "OrangeCrab_DDRAM_VCCIO[2]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_VCCIO[2]" IO_TYPE=SSTL135_II;
LOCATE COMP "OrangeCrab_DDRAM_VCCIO[3]" SITE "K17";
IOBUF PORT "OrangeCrab_DDRAM_VCCIO[3]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_VCCIO[3]" IO_TYPE=SSTL135_II;
LOCATE COMP "OrangeCrab_DDRAM_VCCIO[4]" SITE "B18";
IOBUF PORT "OrangeCrab_DDRAM_VCCIO[4]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_VCCIO[4]" IO_TYPE=SSTL135_II;
LOCATE COMP "OrangeCrab_DDRAM_VCCIO[5]" SITE "C6";
IOBUF PORT "OrangeCrab_DDRAM_VCCIO[5]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_VCCIO[5]" IO_TYPE=SSTL135_II;
 
LOCATE COMP "OrangeCrab_DDRAM_GND[0]" SITE "L15";
IOBUF PORT "OrangeCrab_DDRAM_GND[0]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_GND[0]" IO_TYPE=SSTL135_II;
LOCATE COMP "OrangeCrab_DDRAM_GND[1]" SITE "L16";
IOBUF PORT "OrangeCrab_DDRAM_GND[1]" SLEWRATE=FAST;
IOBUF PORT "OrangeCrab_DDRAM_GND[1]" IO_TYPE=SSTL135_II;
 
LOCATE COMP "OrangeCrab_SPIFLASH_CS_N" SITE "U17";
IOBUF PORT "OrangeCrab_SPIFLASH_CS_N" IO_TYPE=LVCMOS33;
 
LOCATE COMP "OrangeCrab_SPIFLASH_DQ[0]" SITE "U18";
IOBUF PORT "OrangeCrab_SPIFLASH_DQ[0]" IO_TYPE=LVCMOS33;
LOCATE COMP "OrangeCrab_SPIFLASH_DQ[1]" SITE "T18";
IOBUF PORT "OrangeCrab_SPIFLASH_DQ[1]" IO_TYPE=LVCMOS33;
LOCATE COMP "OrangeCrab_SPIFLASH_DQ[2]" SITE "R18";
IOBUF PORT "OrangeCrab_SPIFLASH_DQ[2]" IO_TYPE=LVCMOS33;
LOCATE COMP "OrangeCrab_SPIFLASH_DQ[3]" SITE "N18";
IOBUF PORT "OrangeCrab_SPIFLASH_DQ[3]" IO_TYPE=LVCMOS33;
/trunk/setups/osflow/constraints/UPduino_v3.pcf
0,0 → 1,36
## UART (uart0)
set_io uart_txd_o 38
set_io uart_rxd_i 28
 
## SPI - on-board flash
set_io flash_sdo_o 14
set_io flash_sck_o 15
set_io flash_csn_o 16
set_io flash_sdi_i 17
 
## SPI - user port
set_io spi_sdo_o 34
set_io spi_sck_o 43
set_io spi_csn_o 36
set_io spi_sdi_i 42
 
## TWI
set_io twi_sda_io 31
set_io twi_scl_io 37
 
## GPIO - input
set_io gpio_i[0] 44
set_io gpio_i[1] 4
set_io gpio_i[2] 3
set_io gpio_i[3] 48
 
## GPIO - output
set_io gpio_o[0] 45
set_io gpio_o[1] 47
set_io gpio_o[2] 46
set_io gpio_o[3] 2
 
## RGB power LED
set_io pwm_o[0] 39
set_io pwm_o[1] 40
set_io pwm_o[2] 41
/trunk/setups/osflow/constraints/iCESugar.pcf
0,0 → 1,69
#| iCESugar-v1.5
 
 
#> Clock (12 MHz)
set_io --warn-no-port iCESugarv15_CLK 35
 
 
#> Tri-colour LED
set_io --warn-no-port iCESugarv15_LED_G 41
set_io --warn-no-port iCESugarv15_LED_R 40
set_io --warn-no-port iCESugarv15_LED_B 39
 
 
#> UART
set_io --warn-no-port iCESugarv15_RX 4
set_io --warn-no-port iCESugarv15_TX 6
 
 
#> USB
set_io --warn-no-port iCESugarv15_USB_DN 9
set_io --warn-no-port iCESugarv15_USB_DP 10
set_io --warn-no-port iCESugarv15_USB_DP_PU 11
 
 
#> PMOD 1
set_io --warn-no-port iCESugarv15_PMOD1A_0 10
set_io --warn-no-port iCESugarv15_PMOD1A_1 6
set_io --warn-no-port iCESugarv15_PMOD1A_2 3
set_io --warn-no-port iCESugarv15_PMOD1A_3 48
set_io --warn-no-port iCESugarv15_PMOD1B_0 47
set_io --warn-no-port iCESugarv15_PMOD1B_1 2
set_io --warn-no-port iCESugarv15_PMOD1B_2 4
set_io --warn-no-port iCESugarv15_PMOD1B_3 9
 
 
#> PMOD 2
set_io --warn-no-port iCESugarv15_PMOD2A_0 46
set_io --warn-no-port iCESugarv15_PMOD2A_1 44
set_io --warn-no-port iCESugarv15_PMOD2A_2 42
set_io --warn-no-port iCESugarv15_PMOD2A_3 37
set_io --warn-no-port iCESugarv15_PMOD2B_0 36
set_io --warn-no-port iCESugarv15_PMOD2B_1 38
set_io --warn-no-port iCESugarv15_PMOD2B_2 43
set_io --warn-no-port iCESugarv15_PMOD2B_3 45
 
 
#> PMOD 3
set_io --warn-no-port iCESugarv15_PMOD3A_0 34
set_io --warn-no-port iCESugarv15_PMOD3A_1 31
set_io --warn-no-port iCESugarv15_PMOD3A_2 27
set_io --warn-no-port iCESugarv15_PMOD3A_3 25
set_io --warn-no-port iCESugarv15_PMOD3B_0 23
set_io --warn-no-port iCESugarv15_PMOD3B_1 26
set_io --warn-no-port iCESugarv15_PMOD3B_2 28
set_io --warn-no-port iCESugarv15_PMOD3B_3 32
 
 
#> PMOD 4 | Switches
set_io --warn-no-port iCESugarv15_PMOD4_0 21
set_io --warn-no-port iCESugarv15_PMOD4_1 20
set_io --warn-no-port iCESugarv15_PMOD4_2 19
set_io --warn-no-port iCESugarv15_PMOD4_3 18
 
 
#> SPI
set_io --warn-no-port iCESugarv15_SPI_SS 16
set_io --warn-no-port iCESugarv15_SPI_SCK 15
set_io --warn-no-port iCESugarv15_SPI_MOSI 17
set_io --warn-no-port iCESugarv15_SPI_MISO 14
/trunk/setups/osflow/devices/ecp5/ecp5_components.vhd
0,0 → 1,75
library ieee ;
use ieee.std_logic_1164.all;
 
package components is
 
-- Yosys wrapper components
 
component EHXPLLL
generic
(
CLKI_DIV : integer := 1;
CLKFB_DIV : integer := 1;
CLKOP_DIV : integer := 8;
CLKOS_DIV : integer := 8;
CLKOS2_DIV : integer := 8;
CLKOS3_DIV : integer := 8;
CLKOP_ENABLE : string := "ENABLED";
CLKOS_ENABLE : string := "DISABLED";
CLKOS2_ENABLE : string := "DISABLED";
CLKOS3_ENABLE : string := "DISABLED";
CLKOP_CPHASE : integer := 0;
CLKOS_CPHASE : integer := 0;
CLKOS2_CPHASE : integer := 0;
CLKOS3_CPHASE : integer := 0;
CLKOP_FPHASE : integer := 0;
CLKOS_FPHASE : integer := 0;
CLKOS2_FPHASE : integer := 0;
CLKOS3_FPHASE : integer := 0;
FEEDBK_PATH : string := "CLKOP";
CLKOP_TRIM_POL : string := "RISING";
CLKOP_TRIM_DELAY : integer := 0;
CLKOS_TRIM_POL : string := "RISING";
CLKOS_TRIM_DELAY : integer := 0;
OUTDIVIDER_MUXA : string := "DIVA";
OUTDIVIDER_MUXB : string := "DIVB";
OUTDIVIDER_MUXC : string := "DIVC";
OUTDIVIDER_MUXD : string := "DIVD";
PLL_LOCK_MODE : integer := 0;
PLL_LOCK_DELAY : integer := 200;
STDBY_ENABLE : string := "DISABLED";
REFIN_RESET : string := "DISABLED";
SYNC_ENABLE : string := "DISABLED";
INT_LOCK_STICKY : string := "ENABLED";
DPHASE_SOURCE : string := "DISABLED";
PLLRST_ENA : string := "DISABLED";
INTFB_WAKE : string := "DISABLED"
);
port
(
CLKI : IN std_logic := 'X';
CLKFB : IN std_logic := 'X';
RST : IN std_logic := 'X';
STDBY : IN std_logic := 'X';
PLLWAKESYNC : IN std_logic := 'X';
PHASESEL1 : IN std_logic := 'X';
PHASESEL0 : IN std_logic := 'X';
PHASEDIR : IN std_logic := 'X';
PHASESTEP : IN std_logic := 'X';
PHASELOADREG : IN std_logic := 'X';
ENCLKOP : IN std_logic := 'X';
ENCLKOS : IN std_logic := 'X';
ENCLKOS2 : IN std_logic := 'X';
ENCLKOS3 : IN std_logic := 'X';
CLKOP : OUT std_logic := 'X';
CLKOS : OUT std_logic := 'X';
CLKOS2 : OUT std_logic := 'X';
CLKOS3 : OUT std_logic := 'X';
LOCK : OUT std_logic := 'X';
INTLOCK : OUT std_logic := 'X';
REFCLK : OUT std_logic := 'X';
CLKINTFB : OUT std_logic := 'X'
);
end component;
 
end package;
/trunk/setups/osflow/devices/ice40/sb_ice40_components.vhd
6,10 → 6,10
-- Yosys / IceCube wrapper components
 
component SB_GB
port(
GLOBAL_BUFFER_OUTPUT : out std_logic;
USER_SIGNAL_TO_GLOBAL_BUFFER : in std_logic
);
port(
GLOBAL_BUFFER_OUTPUT : out std_logic;
USER_SIGNAL_TO_GLOBAL_BUFFER : in std_logic
);
end component;
 
component SB_HFOSC
123,4 → 123,4
);
end component;
 
end package components;
end package;
/trunk/setups/osflow/.gitignore
0,0 → 1,8
*.asc
*.bit
*.cfg
*.dfu
*.history
*.json
*.svf
*-report.txt
/trunk/setups/osflow/PnR_Bit.mk
1,9 → 1,14
${IMPL}.asc: $(IMPL).json $(PCF)
${IMPL}.${PNR2BIT_EXT}: $(IMPL).json $(CONSTRAINTS)
$(NEXTPNR) \
$(PNRFLAGS) \
--pcf $(PCF) \
--$(CONSTRAINTS_FORMAT) $(CONSTRAINTS) \
--json $(IMPL).json \
--asc $@ 2>&1 | tee nextpnr-report.txt
--${NEXTPNR_OUT} $@ 2>&1 | tee nextpnr-report.txt
 
${IMPL}.bit: $(IMPL).asc
$(ICEPACK) $< $@
${IMPL}.bit: ${IMPL}.${PNR2BIT_EXT}
$(PACKTOOL) $< $@
 
ifeq ($(DEVICE_SERIES),ecp5)
${IMPL}.svf: ${IMPL}.${PNR2BIT_EXT}
$(PACKTOOL) $(PACKARGS) --svf $@ $<
endif
/trunk/setups/osflow/README.md
0,0 → 1,26
# Exemplary FPAG Board Setups - Using Open Source Toolchains
 
This folder provides the infrastructure for generating bitstream for various FPGAs using
open source toolchains. Synthesis based on [ghdl-yosys](https://github.com/ghdl/ghdl-yosys-plugin).
 
## Folder Structure
 
* `boards`: board-specific makefiles for generating bitstreams
* `constraints`: physical constraints (mainly pin mappings)
* `devices`: FPGA-specific primitives and optimized processor modules (like memories)
 
 
## Prerequisites
 
:construction: **TODO - Under Construction** :construction:
 
 
## How To Run
 
:construction: **TODO - Under Construction** :construction:
 
```shell
make BOARD=<FPGA-board> <Board-Top-HDL>
```
 
See https://github.com/stnolting/neorv32/blob/master/.github/workflows/Implementation.yml
/trunk/setups/osflow/common.mk
0,0 → 1,39
ID ?= impl_1
 
include boards/index.mk
 
ifndef TOP
$(error TOP needs to be specified!)
endif
 
include filesets.mk
 
ifndef DESIGN_SRC
ifndef BOARD_SRC
$(error Neither DESIGN_SRC nor BOARD_SRC were set!)
endif
endif
 
include tools.mk
 
ifdef GHDL_PLUGIN_MODULE
YOSYSFLAGS += -m $(GHDL_PLUGIN_MODULE)
endif
 
include synthesis.mk
include PnR_Bit.mk
 
.PHONY: syn impl bit svf clean
 
syn: ${IMPL}.json
impl: ${IMPL}.${PNR2BIT_EXT}
bit: ${IMPL}.bit
 
ifeq ($(DEVICE_SERIES),ecp5)
svf: ${IMPL}.svf
endif
 
clean:
rm -rf *.{${PNR2BIT_EXT},bit,cf,dfu,history,json,o,svf} *-report.txt
 
include boards/$(BOARD).mk
/trunk/setups/osflow/filesets.mk
1,4 → 1,4
RTL_CORE_SRC := ../../../rtl/core
RTL_CORE_SRC := ../../rtl/core
 
NEORV32_PKG := $(RTL_CORE_SRC)/neorv32_package.vhd
 
6,8 → 6,8
$(RTL_CORE_SRC)/neorv32_application_image.vhd \
 
NEORV32_MEM_SRC := \
../devices/ice40/neorv32_imem.ice40up_spram.vhd \
../devices/ice40/neorv32_dmem.ice40up_spram.vhd
devices/ice40/neorv32_imem.ice40up_spram.vhd \
devices/ice40/neorv32_dmem.ice40up_spram.vhd
 
NEORV32_CORE_SRC := \
$(RTL_CORE_SRC)/neorv32_bootloader_image.vhd \
46,6 → 46,15
NEORV32_SRC := ${NEORV32_PKG} ${NEORV32_APP_SRC} ${NEORV32_MEM_SRC} ${NEORV32_CORE_SRC}
 
ICE40_SRC := \
../devices/ice40/sb_ice40_components.vhd
devices/ice40/sb_ice40_components.vhd
 
ECP5_SRC := \
devices/ecp5/ecp5_components.vhd
 
ifeq ($(DEVICE_SERIES),ecp5)
DEVICE_SRC := ${ECP5_SRC}
else
DEVICE_SRC := ${ICE40_SRC}
endif
 
# Optionally NEORV32_VERILOG_SRC can be set to a list of Verilog sources
/trunk/setups/osflow/synthesis.mk
1,7 → 1,7
ice40-obj08.cf: ${ICE40_SRC}
ghdl -a $(GHDL_FLAGS) --work=iCE40 ${ICE40_SRC}
${DEVICE_LIB}-obj08.cf: ${DEVICE_SRC}
ghdl -a $(GHDL_FLAGS) --work=${DEVICE_LIB} ${DEVICE_SRC}
 
neorv32-obj08.cf: ice40-obj08.cf ${NEORV32_SRC}
neorv32-obj08.cf: ${DEVICE_LIB}-obj08.cf ${NEORV32_SRC}
ghdl -a $(GHDL_FLAGS) --work=neorv32 ${NEORV32_SRC}
 
work-obj08.cf: neorv32-obj08.cf ${DESIGN_SRC} ${BOARD_SRC}
11,7 → 11,6
$(YOSYS) $(YOSYSFLAGS) \
-p \
"$(GHDLSYNTH) $(GHDL_FLAGS) --no-formal $(TOP); \
synth_ice40 \
-top $(TOP) \
-dsp \
synth_${YOSYSSYNTH} \
-top $(TOP) $(YOSYSPIPE) \
-json $@" $(NEORV32_VERILOG_SRC) 2>&1 | tee yosys-report.txt
/trunk/setups/osflow/tools.mk
2,6 → 2,27
GHDL ?= ghdl
GHDLSYNTH ?= ghdl
YOSYS ?= yosys
NEXTPNR ?= nextpnr-ice40
ICEPACK ?= icepack
ECPPACK ?= ecppack
OPENOCD ?= openocd
COPY ?= cp -a
 
DEVICE_SERIES ?= ice40
DEVICE_LIB ?= $(DEVICE_SERIES)
YOSYSSYNTH ?= $(DEVICE_SERIES)
NEXTPNR ?= nextpnr-$(DEVICE_SERIES)
 
ifeq ($(DEVICE_SERIES),ice40)
YOSYSPIPE ?= -dsp
CONSTRAINTS_FORMAT ?= pcf
NEXTPNR_OUT ?= asc
PNR2BIT_EXT ?= asc
PACKTOOL ?= $(ICEPACK)
PACKARGS ?=
else
CONSTRAINTS_FORMAT ?= lpf
NEXTPNR_OUT ?= textcfg
PNR2BIT_EXT ?= cfg
PACKTOOL ?= $(ECPPACK)
PACKARGS ?= --compress
endif
/trunk/setups/radiant/UPduino_v3/README.md
99,25 → 99,3
9. close the dialog by clicking "ok"
10. click on "Program Device"
 
 
#### NEORV32 Software Framework Modification
 
In order to use the features provided by this setup, minor *optional* changes can be made to the default NEORV32 setup.
 
To use the full 64kB capacity of the DMEM and IMEM, the linker script has to be modified. Open the linker script (`sw/common/neorv32.ld`) and change the default `LENGTH` assignments of `rom` and `ram` to 64kB (modify the RIGHT-most value only, see below):
 
```
rom (rx) : ORIGIN = DEFINED(make_bootloader) ? 0xFFFF0000 : 0x00000000, LENGTH = DEFINED(make_bootloader) ? 4*1024 : 64*1024
ram (rwx) : ORIGIN = 0x80000000, LENGTH = 64*1024
```
 
If you want to use the on-board SPI flash also for storing (and automatically booting) NEORV32 software applications you need to configure the default bootloader base address of the
software image in order to prevent overriding the FPGA bitstream. Open the bootloader source code (`sw/bootloader/bootloader.c`) and modify the following definition (see below).
You will need to re-compile (and re-install) the bootloader. This will also require to rerun synthesis.
 
```c
/** SPI flash boot image base address (warning! address might wrap-around!) */
#define SPI_FLASH_BOOT_ADR (0x00020000)
```
 
You will need to recompile the bootloader and re-do FPGA synthesis.
/trunk/setups/vivado/README.md
1,4 → 1,4
# NEORV32 Test Setups for the Digilent Boards
# NEORV32 Xilinx Vivado Example Setups
 
## How To Run
 
8,7 → 8,7
### Batch mode
 
Execute `vivado -mode batch -nojournal -nolog -source create_project.tcl` from the board subdir.
The project will be created, and implementation will be run until generation of `work/neorv32_test_setup.runs/impl_1/neorv32_test_setup.bit`.
The project will be created and implementation will be run until generation of `work/neorv32_test_setup.runs/impl_1/neorv32_test_setup.bit`.
 
### GUI
 
19,7 → 19,7
5. when the Vivado project has openend, Implementation will run and a bitstream will be generated.
6. maybe a prompt will notify about it.
 
### Testing the bitstream
### Programming the Bitstream
 
1. open the "Hardware Manager" (maybe a prompt will ask for that)
2. click on "Open target/Auto Connect"
/trunk/setups/README.md
1,23 → 1,33
# Exemplary FPGA Board Setups
 
This folder provides exemplary NEORV32 SoC setups for different FPGA platforms/boards. You can directly use one of the provided setups
or use them as starting point to build your own setup.
This folder provides exemplary NEORV32 SoC setups for different FPGA platforms/boards.
You can directly use one of the provided setups or use them as starting point to build your own setup.
Project maintainers may make pull requests against this repository to [add or link their setups](#Adding-Your-Project-Setup).
 
Project maintainers may make pull requests against this repository to add or link their setups.
 
## Setups using Commercial Toolchains
 
| Setup | Board | FPGA | Author |
|:------|:------|:------|:-------|
| :file_folder: [`de0-nano-test-setup`](https://github.com/stnolting/neorv32/tree/master/setups/quartus/de0-nano-test-setup) | [Terasic DE0-Nano](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=139&No=593) | Intel Cyclone IV `EP4CE22F17C6N` | [stnolting](https://github.com/stnolting) |
| :file_folder: [`UPduino_v3`](https://github.com/stnolting/neorv32/tree/master/setups/radiant/UPduino_v3) | [tinyVision.ai Inc. UPduino `v3.0`](https://www.tindie.com/products/tinyvision_ai/upduino-v30-low-cost-lattice-ice40-fpga-board/) | Lattice iCE40 UltraPlus `iCE40UP5K-SG48I`| [stnolting](https://github.com/stnolting) |
| :file_folder: [`UPduino_v3`](https://github.com/stnolting/neorv32/tree/master/setups/osflow/UPduino_v3) | [tinyVision.ai Inc. UPduino `v3.0`](https://www.tindie.com/products/tinyvision_ai/upduino-v30-low-cost-lattice-ice40-fpga-board/) | Lattice iCE40 UltraPlus `iCE40UP5K-SG48I` (with open source toolchain: GHDL, Yosys, nextPNR) | [tmeissner](https://github.com/tmeissner) |
| :file_folder: [`arty-a7-35-test-setup`](https://github.com/stnolting/neorv32/tree/master/setups/vivado/arty-a7-test-setup) | [Digilent Arty A7-35](https://reference.digilentinc.com/reference/programmable-logic/arty-a7/start) | Xilinx Artix-7 `XC7A35TICSG324-1L` | [stnolting](https://github.com/stnolting) |
| :file_folder: [`nexys-a7-test-setup`](https://github.com/stnolting/neorv32/tree/master/setups/vivado/nexys-a7-test-setup) | [Digilent Nexys A7](https://reference.digilentinc.com/reference/programmable-logic/nexys-a7/start) | Xilinx Artix-7 `XC7A50TCSG324-1` | [AWenzel83](https://github.com/AWenzel83) |
| :file_folder: [`nexys-a7-test-setup`](https://github.com/stnolting/neorv32/tree/master/setups/vivado/nexys-a7-test-setup) | [Digilent Nexys 4 DDR](https://reference.digilentinc.com/reference/programmable-logic/nexys-4-ddr/start) | Xilinx Artix-7 `XC7A100TCSG324-1` | [AWenzel83](https://github.com/AWenzel83) |
| Setup | Toolchain | Board | FPGA | Author(s) |
|:------|:----------|:------|:------|:----------|
| :file_folder: [`de0-nano-test-setup`](https://github.com/stnolting/neorv32/tree/master/setups/quartus/de0-nano-test-setup) | Intel Quartus Prime | [Terasic DE0-Nano](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=139&No=593) | Intel Cyclone IV `EP4CE22F17C6N` | [stnolting](https://github.com/stnolting) |
| :file_folder: [`UPduino_v3`](https://github.com/stnolting/neorv32/tree/master/setups/radiant/UPduino_v3) | Lattice Radiant | [tinyVision.ai Inc. UPduino `v3.0`](https://www.tindie.com/products/tinyvision_ai/upduino-v30-low-cost-lattice-ice40-fpga-board/) | Lattice iCE40 UltraPlus `iCE40UP5K-SG48I` | [stnolting](https://github.com/stnolting) |
| :file_folder: [`arty-a7-35-test-setup`](https://github.com/stnolting/neorv32/tree/master/setups/vivado/arty-a7-test-setup) | Xilinx Vivado | [Digilent Arty A7-35](https://reference.digilentinc.com/reference/programmable-logic/arty-a7/start) | Xilinx Artix-7 `XC7A35TICSG324-1L` | [stnolting](https://github.com/stnolting) |
| :file_folder: [`nexys-a7-test-setup`](https://github.com/stnolting/neorv32/tree/master/setups/vivado/nexys-a7-test-setup) | Xilinx Vivado | [Digilent Nexys A7](https://reference.digilentinc.com/reference/programmable-logic/nexys-a7/start) | Xilinx Artix-7 `XC7A50TCSG324-1` | [AWenzel83](https://github.com/AWenzel83) |
| :file_folder: [`nexys-a7-test-setup`](https://github.com/stnolting/neorv32/tree/master/setups/vivado/nexys-a7-test-setup) | Xilinx Vivado | [Digilent Nexys 4 DDR](https://reference.digilentinc.com/reference/programmable-logic/nexys-4-ddr/start) | Xilinx Artix-7 `XC7A100TCSG324-1` | [AWenzel83](https://github.com/AWenzel83) |
 
 
## Adding Your Project Setup
## Setups using Open-Source Toolchains (`osflow`)
 
| Setup | Toolchain | Board | FPGA | Author(s) |
|:------|:----------|:------|:------|:----------|
| :file_folder: [`UPduino v3`](https://github.com/stnolting/neorv32/tree/master/setups/osflow) | GHDL, Yosys, nextPNR | [UPduino v3.0](https://www.tindie.com/products/tinyvision_ai/upduino-v30-low-cost-lattice-ice40-fpga-board/) | Lattice iCE40 UltraPlus `iCE40UP5K-SG48I` | [tmeissner](https://github.com/tmeissner) |
| :file_folder: [`FOMU`](https://github.com/stnolting/neorv32/tree/master/setups/osflow) | GHDL, Yosys, nextPNR | [FOMU](https://tomu.im/fomu.html) | Lattice iCE40 UltraPlus `iCE40UP5K-SG48I` | [umarcor](https://github.com/umarcor) |
| :file_folder: [`iCESugar`](https://github.com/stnolting/neorv32/tree/master/setups/osflow) | GHDL, Yosys, nextPNR | [iCESugar](https://github.com/wuxx/icesugar/blob/master/README_en.md) | Lattice iCE40 UltraPlus `iCE40UP5K-SG48I` | [umarcor](https://github.com/umarcor) |
| :file_folder: [`Orange Crab`](https://github.com/stnolting/neorv32/tree/master/setups/osflow) | GHDL, Yosys, nextPNR | [Orange Crab](https://github.com/gregdavill/OrangeCrab) | Lattice ECP5-25F | [umarcor](https://github.com/umarcor), [jeremyherbert](https://github.com/jeremyherbert) |
 
 
### Adding Your Project Setup
 
Please respect the following guidelines if you'd like to add (or link) your setup to the list.
 
* check out the project's [code of conduct](https://github.com/stnolting/neorv32/tree/master/CODE_OF_CONDUCT.md)
26,7 → 36,7
* please add a `README` to give some brief information about the setup and a `.gitignore` to keep things clean; take a look at [`arty-a7-35-test-setup`](https://github.com/stnolting/neorv32/setups/boards/arty-a7-35-test-setup) to get some ideas what a project setup might look like
 
 
#### Setup-Specifc NEORV32 Software Framework Modification
### Setup-Specifc NEORV32 Software Framework Modification
 
In order to use the features provided by the setups, minor *optional* changes can be made to the default NEORV32 setup.
 
/trunk/sim/ghdl_sim.sh File deleted
/trunk/sim/README.md
1,17 → 1,52
## Simulation Source Folder
# Simulation Source Folder
 
### [`ghdl`](https://github.com/stnolting/neorv32/tree/master/sim/ghdl)
 
This folder contains a script for simulating the processor using GHDL.
## [`neorv32_tb.simple.vhd`](neorv32_tb.simple.vhd) and [`ghdl_sim.sh`](ghdl_sim)
 
### [`rtl_modules`](https://github.com/stnolting/neorv32/tree/master/sim/rtl_modules)
Simple testbench for the NEORV32 Processor and script for simulation using GHDL.
 
 
## [`rtl_modules`](rtl_modules)
 
This folder provides additional/alternative simulation components (mainly optimized memory components yet). See the comments in the according files for more information.
 
### [`neorv32_tb.vhd`](https://github.com/stnolting/neorv32/tree/master/sim/neorv32_tb.vhd)
 
VUnit testbench for the NEORV32 Processor.
## [`neorv32_tb.vhd`](neorv32_tb.vhd) and [`run.py`](run.py)
 
### [`neorv32_tb.simple.vhd`](https://github.com/stnolting/neorv32/tree/master/sim/neorv32_tb.simple.vhd)
VUnit testbench and run script for the NEORV32 Processor.
 
Simple testbench for the NEORV32 Processor.
 
## [`run_riscv_arch_test.sh`](run_riscv_arch_test.sh): NEORV32 RISC-V Architecture Test Framework
 
This script tests the NEORV32 Processor for RISC-V compatibility using the
[official RISC-V architecture test suite v2+](https://github.com/riscv/riscv-arch-test).
The core's HDL sources are *simulated* using `GHDL` to provide a virtual execution platform for the test framework:
 
* `rv32i_m/C` - compressed instructions
* `rv32i_m/I` - base ISA
* `rv32i_m/M` - hardware integer multiplication and division
* `rv32i_m/privilege` - privileged architecture
* `rv32i_m/Zifencei` - instruction stream synchronization (for example for self-modifying code)
 
:warning: The RISC-V GCC toolchain (`riscv{32|64}-unknown-elf`) is required for program compilation, and the simulation
depends on `ghdl_sim.sh`.
 
To execute all the supported tests open a terminal and run [`./sim/run_riscv_arch_test.sh`](run_riscv_arch_test.sh),
which does the following:
 
* Make local copies of the NEORV32 `rtl`, `sim` and `sw` folders in `work/`, to keep the project's core files clean.
* Clone (as `git submodule`) the [riscv-arch-test repository](https://github.com/riscv/riscv-arch-test) into `sw/isa-test/riscv-arch-test`.
* Install (copy) the custom `neorv32` test target from `sw/isa-test/port-neorv32` to the
test suite's target folder `work/riscv-arch-test/riscv-target/neorv32`
* Make a copy of the original IMEM VHDL source file of the processor (`cp work/neorv32/rtl/core/neorv32_imem.vhd work/neorv32/rtl/core/neorv32_imem.ORIGINAL`);
since the IMEM will be overriden by the device makefiles with a simulation-optimized one (`neorv32/sim/rtl_modules/neorv32_imem.vhd`).
Still, the original IMEM is required for certain tests that use self-modifying code.
* Run the actual tests.
 
:warning: Simulating all the test cases takes quite some time.
 
:warning: If the simulation of a test does not generate any signature output at all or if the signature is truncated,
try increasing the simulation time by modiying the `SIM_TIME` variable when calling the test makefiles in `run_riscv_arch_test.sh`.
 
More datails regarding the actual simulation process can be found in the
[target's `README`](../sw/riscv-arch-test/port-neorv32/framework_v2.0/riscv-target/neorv32/README.md).
/trunk/sim/ghdl.run.sh
0,0 → 1,40
#!/usr/bin/env bash
 
set -e
 
cd $(dirname "$0")
 
echo "Tip: Compile application with USER_FLAGS+=-DUART[0/1]_SIM_MODE to auto-enable UART[0/1]'s simulation mode (redirect UART output to simulator console)."
 
# Prepare simulation output files for UART0 and UART 1
# - Testbench receiver log file (neorv32.testbench_uart?.out)
# - Direct simulation output (neorv32.uart?.sim_mode.[text|data].out)
for uart in 0 1; do
for item in \
testbench_uart"$uart" \
uart"$uart".sim_mode.text \
uart"$uart".sim_mode.data; do
touch neorv32."$item".out
chmod 777 neorv32."$item".out
done
done
 
GHDL="${GHDL:-ghdl}"
 
$GHDL -m --work=neorv32 --workdir=build neorv32_tb_simple
 
GHDL_RUN_ARGS="${@:---stop-time=10ms}"
echo "Using simulation runtime args: $GHDL_RUN_ARGS";
 
runcmd="$GHDL -r --work=neorv32 --workdir=build neorv32_tb_simple \
--max-stack-alloc=0 \
--ieee-asserts=disable \
--assert-level=error $GHDL_RUN_ARGS"
 
if [ -n "$GHDL_DEVNULL" ]; then
$runcmd >> /dev/null
else
$runcmd
fi
 
cat neorv32.uart0.sim_mode.text.out | grep "CPU TEST COMPLETED SUCCESSFULLY!"
/trunk/sim/ghdl.setup.sh
0,0 → 1,14
#!/usr/bin/env bash
 
set -e
 
cd $(dirname "$0")
 
mkdir -p build
 
ghdl -i --work=neorv32 --workdir=build \
../rtl/core/*.vhd \
../rtl/templates/processor/*.vhd \
../rtl/templates/system/*.vhd \
neorv32_tb.simple.vhd \
uart_rx.simple.vhd
/trunk/sim/ghdl.sh
0,0 → 1,14
#!/usr/bin/env bash
 
# `GHDL` is used to check all VHDL files for syntax errors and to simulate the default testbench. The previously
# installed CPU test program is executed and the console output (UART0 primary UART) is dumped to a text file. After the
# simulation has finished, the text file is searched for a specific string. If the string is found, the CPU test was
# successful.
 
# Abort if any command returns != 0
set -e
 
cd $(dirname "$0")
 
./ghdl.setup.sh
./ghdl.run.sh
/trunk/sim/neorv32_imem.simple.vhd
0,0 → 1,113
-- #################################################################################################
-- # << NEORV32 - Processor-internal instruction memory (IMEM) >> #
-- # ********************************************************************************************* #
-- # This version is intended for SIMULATION ONLY! #
-- # It only allows an implementation as ROM and is initialized using "application_init_image". #
-- # Optimized for simulation to allow LARGE read-only IMEMs. #
-- # ********************************************************************************************* #
-- # 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
 
entity neorv32_imem is
generic (
IMEM_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- memory base address
IMEM_SIZE : natural := 4*1024; -- processor-internal instruction memory size in bytes
IMEM_AS_IROM : boolean := true -- implement IMEM as pre-initialized read-only memory?
);
port (
clk_i : in std_ulogic; -- global clock line
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
ben_i : in std_ulogic_vector(03 downto 0); -- byte write enable
addr_i : in std_ulogic_vector(31 downto 0); -- address
data_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic -- transfer acknowledge
);
end neorv32_imem;
 
architecture neorv32_imem_rtl of neorv32_imem is
 
-- IO space: module base address --
constant hi_abb_c : natural := 31; -- high address boundary bit
constant lo_abb_c : natural := index_size_f(IMEM_SIZE); -- low address boundary bit
 
-- local signals --
signal acc_en : std_ulogic;
signal rdata : std_ulogic_vector(31 downto 0);
signal rden : std_ulogic;
signal addr : std_ulogic_vector(index_size_f(IMEM_SIZE/4)-1 downto 0);
 
begin
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert not (IMEM_AS_IROM = false) report "NEORV32 PROCESSOR CONFIG ERROR! Simulation-optimized IMEM can only be used as pre-initialized ROM!" severity error;
 
 
-- Access Control -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = IMEM_BASE(hi_abb_c downto lo_abb_c)) else '0';
addr <= addr_i(index_size_f(IMEM_SIZE/4)+1 downto 2); -- word aligned
 
 
-- Memory Access --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
imem_file_access: process(clk_i)
variable addr_v : integer;
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;
end if;
end if;
end process imem_file_access;
 
-- output gate --
data_o <= rdata when (rden = '1') else (others => '0');
 
 
end neorv32_imem_rtl;
/trunk/sim/neorv32_tb.simple.vhd
47,6 → 47,17
use std.textio.all;
 
entity neorv32_tb_simple is
generic (
CPU_EXTENSION_RISCV_A : boolean := true;
CPU_EXTENSION_RISCV_C : boolean := true;
CPU_EXTENSION_RISCV_E : boolean := false;
CPU_EXTENSION_RISCV_M : boolean := true;
CPU_EXTENSION_RISCV_U : boolean := true;
CPU_EXTENSION_RISCV_Zicsr : boolean := true;
CPU_EXTENSION_RISCV_Zifencei : boolean := true;
EXT_IMEM_C : boolean := false; -- false: use and boot from proc-internal IMEM, true: use and boot from external (initialized) simulated IMEM (ext. mem A)
MEM_INT_IMEM_SIZE : natural := 16*1024 -- size in bytes of processor-internal IMEM / external mem A
);
end neorv32_tb_simple;
 
architecture neorv32_tb_simple_rtl of neorv32_tb_simple is
54,16 → 65,14
-- User Configuration ---------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- general --
constant ext_imem_c : boolean := false; -- false: use and boot from proc-internal IMEM, true: use and boot from external (initialized) simulated IMEM (ext. mem A)
constant ext_dmem_c : boolean := false; -- false: use proc-internal DMEM, true: use external simulated DMEM (ext. mem B)
constant imem_size_c : natural := 16*1024; -- size in bytes of processor-internal IMEM / external mem A
constant dmem_size_c : natural := 8*1024; -- size in bytes of processor-internal DMEM / external mem B
constant ext_dmem_c : boolean := false; -- false: use proc-internal DMEM, true: use external simulated DMEM (ext. mem B)
constant dmem_size_c : natural := 8*1024; -- size in bytes of processor-internal DMEM / external mem B
constant f_clock_c : natural := 100000000; -- main clock in Hz
constant baud0_rate_c : natural := 19200; -- simulation UART0 (primary UART) baud rate
constant baud1_rate_c : natural := 19200; -- simulation UART1 (secondary UART) baud rate
-- simulated external Wishbone memory A (can be used as external IMEM) --
constant ext_mem_a_base_addr_c : std_ulogic_vector(31 downto 0) := x"00000000"; -- wishbone memory base address (external IMEM base)
constant ext_mem_a_size_c : natural := imem_size_c; -- wishbone memory size in bytes
constant ext_mem_a_size_c : natural := MEM_INT_IMEM_SIZE; -- wishbone memory size in bytes
constant ext_mem_a_latency_c : natural := 8; -- latency in clock cycles (min 1, max 255), plus 1 cycle initial delay
-- simulated external Wishbone memory B (can be used as external DMEM) --
constant ext_mem_b_base_addr_c : std_ulogic_vector(31 downto 0) := x"80000000"; -- wishbone memory base address (external DMEM base)
72,13 → 81,13
-- simulated external Wishbone memory C (can be used to simulate external IO access) --
constant ext_mem_c_base_addr_c : std_ulogic_vector(31 downto 0) := x"F0000000"; -- wishbone memory base address (default begin of EXTERNAL IO area)
constant ext_mem_c_size_c : natural := 64; -- wishbone memory size in bytes
constant ext_mem_c_latency_c : natural := 3; -- latency in clock cycles (min 1, max 255), plus 1 cycle initial delay
constant ext_mem_c_latency_c : natural := 3; -- latency in clock cycles (min 1, max 255), plus 1 cycle initial delay
-- simulation interrupt trigger --
constant irq_trigger_base_addr_c : std_ulogic_vector(31 downto 0) := x"FF000000";
-- -------------------------------------------------------------------------------------------
 
-- internals - hands off! --
constant int_imem_c : boolean := not ext_imem_c;
constant int_imem_c : boolean := not EXT_IMEM_C;
constant int_dmem_c : boolean := not ext_dmem_c;
constant uart0_baud_val_c : real := real(f_clock_c) / real(baud0_rate_c);
constant uart1_baud_val_c : real := real(f_clock_c) / real(baud1_rate_c);
166,14 → 175,14
-- On-Chip Debugger (OCD) --
ON_CHIP_DEBUGGER_EN => true, -- implement on-chip debugger
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => true, -- implement atomic extension?
CPU_EXTENSION_RISCV_C => true, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => false, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => true, -- implement muld/div extension?
CPU_EXTENSION_RISCV_U => true, -- implement user mode extension?
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx => true, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => true, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => true, -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul => false, -- implement multiply-only M sub-extension?
-- Extension Options --
FAST_MUL_EN => false, -- use DSPs for M extension's multiplier
187,7 → 196,7
HPM_CNT_WIDTH => 40, -- total size of HPM counters (0..64)
-- Internal Instruction memory --
MEM_INT_IMEM_EN => int_imem_c , -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => imem_size_c, -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN => int_dmem_c, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => dmem_size_c, -- size of processor-internal data memory in bytes
207,7 → 216,7
-- External Interrupts Controller (XIRQ) --
XIRQ_NUM_CH => 32, -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE => (others => '1'), -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY => (others => '1'), -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
XIRQ_TRIGGER_POLARITY => (others => '1'), -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
-- Processor peripherals --
IO_GPIO_EN => true, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN => true, -- implement machine system timer (MTIME)?
371,7 → 380,7
-- Wishbone Memory A (simulated external IMEM) --------------------------------------------
-- -------------------------------------------------------------------------------------------
generate_ext_imem:
if (ext_imem_c = true) generate
if (EXT_IMEM_C = true) generate
ext_mem_a_access: process(clk_gen)
variable ext_ram_a : mem32_t(0 to ext_mem_a_size_c/4-1) := mem32_init_f(application_init_image, ext_mem_a_size_c/4); -- initialized, used to simulate external IMEM
begin
412,9 → 421,10
end generate;
 
generate_ext_imem_false:
if (ext_imem_c = false) generate
if (EXT_IMEM_C = false) generate
wb_mem_a.rdata <= (others => '0');
wb_mem_a.ack <= '0';
wb_mem_a.err <= '0';
end generate;
 
 
/trunk/sim/neorv32_tb.vhd
556,6 → 556,7
if (ext_imem_c = false) generate
wb_mem_a.rdata <= (others => '0');
wb_mem_a.ack <= '0';
wb_mem_a.err <= '0';
end generate;
 
 
/trunk/sim/run_riscv_arch_test.sh
0,0 → 1,69
#!/usr/bin/env bash
 
# Abort if any command returns != 0
set -e
 
cd $(dirname "$0")
 
header() {
echo "--------------------------------------------------------------------------"
echo "> $@..."
echo "--------------------------------------------------------------------------"
}
 
RISCV_PREFIX="${RISCV_PREFIX:-riscv32-unknown-elf-}"
 
header "Checking RISC-V GCC toolchain"
"$RISCV_PREFIX"gcc -v
 
header "Checking 'riscv-arch-test' GitHub repository (submodule)"
git submodule update --init
 
header "Copying neorv32 test-target into riscv-arch-test framework"
(
cd ../sw/isa-test
target_device='riscv-arch-test/riscv-target/neorv32'
if [ -d "$target_device" ]; then rm -rf "$target_device"; fi
cp -vr port-neorv32 "$target_device"
)
 
header "Making local copy of NEORV32 'rtl', 'sim' & 'sw' folders"
rm -rf work
mkdir -p work/sim
for item in 'rtl' 'sw'; do
cp -r ../"$item" work
done
for item in *.simple.vhd ghdl*.sh; do
cp -r "$item" work/sim
done
 
header "Making local backup of original IMEM rtl file (work/rtl/core/neorv32_imem.ORIGINAL)"
(
cd work/rtl/core/
cp neorv32_imem.vhd neorv32_imem.ORIGINAL
)
 
header "Starting RISC-V architecture tests"
 
./work/sim/ghdl.setup.sh
 
# work in progress FIXME
printf "\n\e[1;33mWARNING! 'Zifencei' test is currently disabled (work in progress). \e[0m\n\n"
 
makeArgs="-C ../sw/isa-test/riscv-arch-test NEORV32_ROOT=$(pwd)/.. XLEN=32 RISCV_TARGET=neorv32"
makeTargets='clean build run verify'
 
[ -n "$1" ] && SUITES="$@" || SUITES='I C M privilege'
 
for suite in $SUITES; do
case "$suite" in
I) make --silent $makeArgs SIM_TIME=850us RISCV_DEVICE=I $makeTargets;;
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;;
esac
done
 
#make $makeArgs SIM_TIME=200us RISCV_DEVICE=Zifencei RISCV_TARGET_FLAGS=-DNEORV32_NO_DATA_INIT $makeTargets
 
printf "\nRISC-V architecture tests completed successfully"
/trunk/sw/bootloader/makefile
34,305 → 34,7
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../common/common.mk
/trunk/sw/common/common.mk
0,0 → 1,299
# -----------------------------------------------------------------------------
# USER CONFIGURATION
# -----------------------------------------------------------------------------
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_PREFIX ?= riscv32-unknown-elf-
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_HEX = neorv32_exe.hex
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_PREFIX)gcc
OBJDUMP = $(RISCV_PREFIX)objdump
OBJCOPY = $(RISCV_PREFIX)objcopy
SIZE = $(RISCV_PREFIX)size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
hex: $(APP_ASM) $(APP_HEX)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG) $(APP_HEX)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
# Generate NEORV32 executable image in plain hex format
$(APP_HEX): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_hex $< $@ $(shell basename $(CURDIR))
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Configuration ----------------"
@$(CC) -v
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " hex - compile and generate <neorv32_exe.hex> executable raw file"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - exe + hex + install"
@echo " elf_info - show ELF layout info"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd *.hex
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
/trunk/sw/common/crt0.S
42,9 → 42,15
.cfi_startproc
.cfi_undefined ra
 
nop
 
// ************************************************************************************************
// This is the very first instruction that is executed after hardware reset. It ensures that x0 is
// written at least once - the CPU HW will ensure it is always set to zero on any write access.
// ************************************************************************************************
lui zero, 0 // "dummy" instruction that uses no reg-file input operands at all
 
 
// ************************************************************************************************
// Setup pointers using linker script symbols
// ************************************************************************************************
__crt0_pointer_init:
82,6 → 88,8
csrw minstreth, zero
 
#if defined(__riscv_flen)
li x11, 0x00005000 // enable FPU (state = initial)
csrs mstatus, x11
csrw fcsr, zero // reset floating-point CSR
#endif
 
/trunk/sw/common/neorv32.ld
55,7 → 55,7
/* ************************************************************************** */
MEMORY
{
/* section base addresses and sizes have to be a multiple of 4-bytes */
/* section base addresses and sizes have to be a multiple of 4 bytes */
/* ram section: first value of LENGTH => data memory used by bootloader (fixed!); second value of LENGTH => *physical* size of data memory */
/* adapt the right-most value to match the *total physical data memory size* of your setup */
 
75,31 → 75,7
/* start section on WORD boundary */
. = ALIGN(4);
 
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.init : { *(.rela.init) }
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
.rela.fini : { *(.rela.fini) }
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
.rela.data.rel.ro : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) }
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
.rela.ctors : { *(.rela.ctors) }
.rela.dtors : { *(.rela.dtors) }
.rela.got : { *(.rela.got) }
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
 
/* Actual instructions */
.text :
{
161,9 → 137,7
} > rom
 
 
/* read-only data, appended to text */
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
/* read-only data, appended to .text */
.rodata :
{
PROVIDE_HIDDEN (__init_array_start = .);
176,6 → 150,9
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
 
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
 
/* finish section on WORD boundary */
. = ALIGN(4);
} > rom
182,20 → 159,18
 
 
/* initialized read/write data, accessed in RAM, placed in ROM, copied during boot */
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.data1 : { *(.data1) }
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
.data :
{
__DATA_BEGIN__ = .;
__SDATA_BEGIN__ = .;
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
 
*(.data1)
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
 
*(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*)
*(.dynamic)
 
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
217,15 → 192,14
 
 
/* zero/non-initialized read/write data placed in RAM */
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.bss (NOLOAD):
{
__bss_start = .;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
*(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon)
*(.scommon)
 
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
 
243,12 → 217,40
 
. = ALIGN(32 / 8);
__BSS_END__ = .;
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,
MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));
__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));
_end = .; PROVIDE (end = .);
} > ram
 
 
/* Yet unused */
.jcr : { KEEP (*(.jcr)) }
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } .interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.init : { *(.rela.init) }
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
.rela.fini : { *(.rela.fini) }
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
.rela.data.rel.ro : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) }
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
.rela.ctors : { *(.rela.ctors) }
.rela.dtors : { *(.rela.dtors) }
.rela.got : { *(.rela.got) }
.rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
.rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }
.rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
.rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
 
 
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
294,12 → 296,14
 
 
/* Provide symbols for neorv32 crt0 start-up code */
PROVIDE(__crt0_stack_begin = (ORIGIN(ram) + LENGTH(ram)) - 4);
PROVIDE(__crt0_bss_start = __bss_start);
PROVIDE(__crt0_bss_end = __BSS_END__);
PROVIDE(__ctr0_imem_begin = ORIGIN(rom));
PROVIDE(__ctr0_dmem_begin = ORIGIN(ram));
PROVIDE(__crt0_stack_begin = (ORIGIN(ram) + LENGTH(ram)) - 4);
PROVIDE(__crt0_bss_start = __bss_start);
PROVIDE(__crt0_bss_end = __BSS_END__);
PROVIDE(__crt0_copy_data_src_begin = __etext + SIZEOF(.rodata));
PROVIDE(__crt0_copy_data_dst_begin = __DATA_BEGIN__);
PROVIDE(__crt0_copy_data_dst_end = __DATA_BEGIN__ + SIZEOF(.data));
PROVIDE(__ctr0_io_space_begin = ORIGIN(iodev));
PROVIDE(__ctr0_io_space_end = ORIGIN(iodev) + LENGTH(iodev));
PROVIDE(__ctr0_io_space_begin = ORIGIN(iodev));
PROVIDE(__ctr0_io_space_end = ORIGIN(iodev) + LENGTH(iodev));
}
/trunk/sw/example/blink_led/main.c
110,7 → 110,7
**************************************************************************/
void blink_led_c(void) {
 
neorv32_gpio_port_set(0); // clear gpio output put
neorv32_gpio_port_set(0); // clear gpio output
 
int cnt = 0;
 
/trunk/sw/example/blink_led/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/example/coremark/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/example/demo_freeRTOS/makefile
50,7 → 50,7
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
RISCV_PREFIX ?= riscv32-unknown-elf-
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
59,9 → 59,6
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
69,270 → 66,79
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# FreeRTOS
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
ifneq (,$(findstring RUN_FREERTOS_DEMO,$(USER_FLAGS)))
# FreeRTOS home folder (adapt this!)
FREERTOS_HOME ?= /mnt/n/Projects/FreeRTOSv10.4.1
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
# FreeRTOS RISC-V specific
APP_SRC += $(wildcard $(FREERTOS_HOME)/FreeRTOS/Source/portable/GCC/RISC-V/*.c)
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
APP_INC += -I $(FREERTOS_HOME)/FreeRTOS/Source/portable/GCC/RISC-V
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
# FreeRTOS core
APP_SRC += $(wildcard $(FREERTOS_HOME)/FreeRTOS/Source/*.c)
APP_SRC += $(wildcard $(FREERTOS_HOME)/FreeRTOS/Source/portable/MemMang/heap_4.c)
 
APP_INC += -I $(FREERTOS_HOME)/FreeRTOS/Source/include
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
# FreeRTOS sources for the full_demo
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/blocktim.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/dynamic.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/GenQTest.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/recmutex.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/TaskNotify.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/TaskNotifyArray.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS/Demo/Common/Minimal/TimerDemo.c
 
# Define all object files
OBJ = $(SRC:%=%.o)
APP_INC += -I $(FREERTOS_HOME)/FreeRTOS/Demo/Common/include
 
# NEORV32 specific
ASM_INC += -DportasmHANDLE_INTERRUPT=SystemIrqHandler
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
APP_INC += -I chip_specific_extensions/neorv32
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
ASM_INC += -I chip_specific_extensions/neorv32
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
# Demo application
APP_SRC += blinky_demo/main_blinky.c
APP_SRC += full_demo/main_full.c
APP_SRC += full_demo/RegTest.s
endif
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
# -----------------
# FreeRTOS-Plus-CLI
# -----------------
ifneq (,$(findstring FREERTOS_PLUS_CLI,$(USER_FLAGS)))
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI/FreeRTOS_CLI.c
 
APP_INC += -I $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI
endif
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
# -----------------
# FreeRTOS-Plus-TCP
# -----------------
ifneq (,$(findstring FREERTOS_PLUS_TCP,$(USER_FLAGS)))
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
APP_SRC += $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
APP_INC += -I $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include
APP_INC += -I $(FREERTOS_HOME)/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
NEORV32_HOME ?= ../../..
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
# Include central makefile
include ../../common/common.mk
/trunk/sw/example/demo_neopixel/main.c
48,19 → 48,22
/**@{*/
/** UART BAUD rate */
#define BAUD_RATE 19200
/** Number of RGB LEDs in stripe A (24-bit data) */
/** Number of RGB LEDs in stripe (24-bit data) */
#define NUM_LEDS_24BIT (12)
/** Number of RGBW LEDs in stripe B (32-bit data) */
#define NUM_LEDS_32BIT (8)
/** Max intensity (0..255) */
#define MAX_INTENSITY (16)
/**@}*/
 
 
// prototypes
uint32_t hsv2rgb(int h, int v);
 
 
/**********************************************************************//**
* Main function
* This demo uses two NeoPixel stripes: Stripe A is a 12-LED RGB ring (arranged as ring - NOT CONNECTED as ring), stripe B is a 8-LED RGBW stripe
* This demo uses a 12-LED RGB ring
*
* @note This program requires the NEOLED controller to be synthesized (UART0 is optional).
* @note NeoPixel stripe connection: NEORV32.neoled_o -> Stripe A ("NUM_LEDS_24BIT" RGB-LEDs) -> Stripe B ("NUM_LEDS_32BIT" RGBW LEDs)
*
* @return 0 if execution was successful
**************************************************************************/
71,10 → 74,8
neorv32_rte_setup();
 
 
// init UART0 at default baud rate, no parity bits, no hw flow control
// setup UART0 at default baud rate, no parity bits, no hw flow control
neorv32_uart_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
neorv32_uart0_printf("<<< NEORV32 NeoPixel (WS2812) hardware interface (NEOLED) demo >>>\n");
neorv32_uart0_printf("(c) 'NeoPixel' is a trademark of Adafruit Industries.\n");
 
 
// check if NEOLED unit is implemented at all, abort if not
84,75 → 85,110
}
 
 
// clearify setup
neorv32_uart0_printf("\nThis demo uses the following LED setup:\n");
neorv32_uart0_printf("NEORV32.neoled_o -> %u RGB-LEDs (24-bit) -> %u RGBW-LEDs (32-bit)\n\n", (uint32_t)NUM_LEDS_24BIT, (uint32_t)NUM_LEDS_32BIT);
// illustrate setup
neorv32_uart0_printf("<<< NEORV32 NeoPixel (WS2812) hardware interface (NEOLED) demo >>>\n"
"(TM) 'NeoPixel' is a trademark of Adafruit Industries.\n\n"
"This demo uses the following LED setup:\n"
"NEORV32.neoled_o -> %u RGB-LEDs (24-bit)\n\n", (uint32_t)NUM_LEDS_24BIT);
 
 
// use the "neorv32_neoled_setup_ws2812()" setup function here instead the raw "neorv32_neoled_setup_raw()"
// use the "neorv32_neoled_setup_ws2812()" setup function here instead the raw "neorv32_neoled_setup()"
// neorv32_neoled_setup_ws2812() will configure all timing parameters according to the WS2812 specs. for the current processor clock speed
neorv32_neoled_setup_ws2812(0); // use bscon = 0 (busy_flag clears / IRQ fires if at least one buffer entry is free)
neorv32_neoled_setup_ws2812();
neorv32_neoled_enable(); // enable module
neorv32_neoled_set_mode(0); // mode = 0 = 24-bit
 
 
// check NEOLED configuration
neorv32_uart0_printf("Checking NEOLED configuration:\n", neorv32_neoled_get_buffer_size());
neorv32_uart0_printf(" Hardware buffer size: %u entries\n", neorv32_neoled_get_buffer_size());
neorv32_uart0_printf(" Control register: 0x%x\n\n", NEOLED_CT);
neorv32_uart0_printf("Checking NEOLED configuration:\n"
" Hardware FIFO size: %u entries\n"
" Control register: 0x%x\n\n", neorv32_neoled_get_buffer_size(), NEOLED_CT);
 
 
// clear all LEDs
neorv32_uart0_printf("Clearing all LEDs...\n");
int i;
for (i=0; i<(NUM_LEDS_24BIT+NUM_LEDS_32BIT); i++) { // just send a lot of zeros
neorv32_neoled_send_polling(1, 0); // mode = 1 = 32-bit, -> send 32 zero bits in each iteration
for (i=0; i<NUM_LEDS_24BIT; i++) {
neorv32_neoled_write_blocking(0);
}
neorv32_cpu_delay_ms(1000);
neorv32_cpu_delay_ms(500);
 
 
// a simple (but fancy!) animation example
// a simple animation example: rotating rainbow
// this example uses BLOCKING NEOLED functions that check the FIFO flags before writing new data
// non-blocking functions should only be used when checking the FIFO flags (half-full) in advance (for example using the NEOLED interrupt)
neorv32_uart0_printf("Starting animation...\n");
int stripe_pos_rgb = 0, flash_position = 0, flash_direction = -1;
int stripe_pos_rgbw = 0, circle_position = 0;
uint32_t circle_color = 0x00000004;
 
int angle = 0, led_id = 0;
while (1) {
 
// RGB LEDs: turning circle, changes color after each completed cycle
for (stripe_pos_rgb=0; stripe_pos_rgb<NUM_LEDS_24BIT; stripe_pos_rgb++) {
if (stripe_pos_rgb == circle_position) {
neorv32_neoled_send_polling(0, circle_color);
}
else {
neorv32_neoled_send_polling(0, 0); // LED off
}
for (led_id=0; led_id<NUM_LEDS_24BIT; led_id++) {
// give every LED a different color
neorv32_neoled_write_blocking(hsv2rgb(angle + (360/NUM_LEDS_24BIT) * led_id, MAX_INTENSITY));
}
if (circle_position == (NUM_LEDS_24BIT-1)) {
circle_position = 0;
circle_color = (circle_color << 8) | ((circle_color >> 16) & 0xff);
}
else {
circle_position++;
}
angle += 1; // rotation increment per frame
 
neorv32_neoled_strobe_blocking(); // send strobe ("RESET") command
neorv32_cpu_delay_ms(10); // delay between frames
}
 
// RGBW LEDs: knight rider!
if ((flash_position == (NUM_LEDS_32BIT-1)) || (flash_position == 0)) {
flash_direction = -flash_direction;
}
for (stripe_pos_rgbw=0; stripe_pos_rgbw<NUM_LEDS_32BIT; stripe_pos_rgbw++) {
if (stripe_pos_rgbw == flash_position) {
neorv32_neoled_send_polling(1, 0x00000004); // white dot using the dedicated white LED chip
}
else {
neorv32_neoled_send_polling(1, 0); // LED off
}
}
flash_position += flash_direction;
return 0;
}
 
 
// delay between frames; also used to "send" ws2812.reset command
neorv32_cpu_delay_ms(100);
/**********************************************************************//**
* Convert HSV color to RGB.
*
* @note Very simple version: using integer arithmetic and ignoring saturation (saturation is always MAX).
*
* @param[in] h Hue (color angle), 0..359
* @param[in] v Value (intensity), 0..255
* @return LSB-aligned 24-bit RGB data [G,R,B]
**************************************************************************/
uint32_t hsv2rgb(int h, int v) {
 
h = h % 360;
int r, g, b;
int i = h / 60;
int difs = h % 60;
int rgb_adj = (v * difs) / 60;
 
switch (i) {
case 0:
r = v;
g = 0 + rgb_adj;
b = 0;
break;
case 1:
r = v - rgb_adj;
g = v;
b = 0;
break;
case 2:
r = 0;
g = v;
b = 0 + rgb_adj;
break;
case 3:
r = 0;
g = v - rgb_adj;
b = v;
break;
case 4:
r = 0 + rgb_adj;
g = 0;
b = v;
break;
default:
r = v;
g = 0;
b = v - rgb_adj;
break;
}
 
return 0;
uint32_t res = 0;
res |= (((uint32_t)g) & 0xff) << 16;
res |= (((uint32_t)r) & 0xff) << 8;
res |= (((uint32_t)b) & 0xff) << 0;
 
return res;
}
/trunk/sw/example/demo_neopixel/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/example/demo_pwm/main.c
72,18 → 72,20
// this is not required, but keeps us safe
neorv32_rte_setup();
 
// use UART0 if implemented
if (neorv32_uart0_available()) {
// init UART at default baud rate, no parity bits, ho hw flow control
neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
 
// init UART at default baud rate, no parity bits, ho hw flow control
neorv32_uart_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
 
// check available hardware extensions and compare with compiler flags
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch
// say hello
neorv32_uart0_print("PWM demo program\n");
}
 
// say hello
neorv32_uart_print("PWM demo program\n");
 
 
// deativate all PWM channels
// deactivate all PWM channels
neorv32_pwm_set(0, 0);
neorv32_pwm_set(1, 0);
neorv32_pwm_set(2, 0);
/trunk/sw/example/demo_pwm/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/example/demo_trng/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/example/demo_twi/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/example/demo_wdt/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/example/demo_xirq/main.c
36,7 → 36,7
/**********************************************************************//**
* @file demo_xirq/main.c
* @author Stephan Nolting
* @brief External interrupt controller (XIRQ) demo program.
* @brief External interrupt controller (XIRQ) demo program (using hardware-assisted prioritization).
**************************************************************************/
 
#include <neorv32.h>
139,12 → 139,17
}
 
 
// wait for interrupts
// --- wait for interrupts ---
// All incoming XIRQ interrupt requests are "prioritized" in this example. The XIRQ FIRQ handler
// reads the ID of the interrupt with the highest priority from the XIRQ controller ("source" register) and calls the according
// handler function.
// Non-prioritized handling of interrupts (or custom prioritization) can be implemented by manually reading the
// XIRQ controller's "pending" register. It is up to the software to define which pending IRQ should be served.
while(1);
 
 
// just as an example: to disable certain XIRQ interrupt channels, we can
// uninstall the according handler. this will also clear a pending interrupt for that channel
// un-install the according handler. this will also clear a pending interrupt for that channel
neorv32_xirq_uninstall(0); // disable XIRQ channel 0 and remove associated handler
neorv32_xirq_uninstall(1); // disable XIRQ channel 1 and remove associated handler
neorv32_xirq_uninstall(2); // disable XIRQ channel 2 and remove associated handler
/trunk/sw/example/demo_xirq/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/example/floating_point_test/main.c
148,9 → 148,13
neorv32_uart_printf("Test cases per instruction: %u\n", (uint32_t)NUM_TEST_CASES);
neorv32_uart_printf("NOTE: The NEORV32 FPU does not support subnormal numbers yet. Subnormal numbers are flushed to zero.\n\n");
 
// enable FPU extension
uint32_t mstatus = neorv32_cpu_csr_read(CSR_MSTATUS);
mstatus |= 1 << CSR_MSTATUS_FS_L; // state = initial
neorv32_cpu_csr_write(CSR_MSTATUS, mstatus);
 
// clear exception status word
neorv32_cpu_csr_write(CSR_FFLAGS, 0);; // real hardware
neorv32_cpu_csr_write(CSR_FFLAGS, 0); // real hardware
feclearexcept(FE_ALL_EXCEPT); // software runtime (GCC floating-point emulation)
 
 
/trunk/sw/example/floating_point_test/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/example/game_of_life/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/example/hello_world/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/example/hex_viewer/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/example/processor_check/main.c
337,7 → 337,67
neorv32_cpu_csr_write(CSR_MCOUNTEREN, tmp_a);
 
 
/*
// ----------------------------------------------------------
// Execute DRET in M-mode (has to trap!)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] DRET in M-mode: ", cnt_test);
 
// skip if U-mode is not implemented
if (neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_U)) {
 
cnt_test++;
 
asm volatile("dret");
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
test_fail();
}
 
}
else {
PRINT_STANDARD("skipped (n.a. without U-ext)\n");
}
*/
 
 
/*
// ----------------------------------------------------------
// Execute MRET in U-mode (has to trap!)
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
PRINT_STANDARD("[%i] MRET in U-mode: ", cnt_test);
 
// skip if U-mode is not implemented
if (neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CSR_MZEXT_DEBUGMODE)) {
 
cnt_test++;
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
asm volatile("mret");
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
test_fail();
}
 
}
else {
PRINT_STANDARD("skipped (n.a. without U-ext)\n");
}
*/
 
 
// ----------------------------------------------------------
// Test performance counter: setup as many events and counter as feasible
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
1291,9 → 1351,18
// program wake-up timer
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + 1000);
 
// put CPU into sleep mode
asm volatile ("wfi");
// clear timeout wait flag
tmp_a = neorv32_cpu_csr_read(CSR_MSTATUS);
tmp_a &= ~(1 << CSR_MSTATUS_TW);
neorv32_cpu_csr_write(CSR_MSTATUS, tmp_a);
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
// only when mstatus.TW = 0 executing WFI in user mode is allowed
asm volatile ("wfi"); // put CPU into sleep mode
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_MTI) {
test_fail();
}
/trunk/sw/example/processor_check/makefile
34,305 → 34,6
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ -lm
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -d -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
include ../../common/common.mk
/trunk/sw/image_gen/image_gen.cpp
47,9 → 47,10
"by Stephan Nolting\n"
"Three arguments are required.\n"
"1st: Option\n"
" -app_bin : Generate application executable binary (little-endian; with header!) \n"
" -app_img : Generate application raw executable memory image (vhdl file, no header!)\n"
" -bld_img : Generate bootloader raw executable memory image (vdhl file, no header!)\n"
" -app_bin : Generate application executable binary (binary file, little-endian, with header) \n"
" -app_hex : Generate application raw executable (hex file, no header)\n"
" -app_img : Generate application raw executable memory image (vhdl file, no header)\n"
" -bld_img : Generate bootloader raw executable memory image (vdhl file, no header)\n"
"2nd: Input file (raw binary image)\n"
"3rd: Output file\n"
"4th: Project folder (optional)\n");
70,6 → 71,8
option = 2;
else if (strcmp(argv[1], "-bld_img") == 0)
option = 3;
else if (strcmp(argv[1], "-app_hex") == 0)
option = 4;
else {
printf("Invalid option!");
return 1;
318,6 → 321,29
}
 
 
// ------------------------------------------------------------
// Generate APPLICATION's executable hex file (no header!!!)
// ------------------------------------------------------------
if (option == 4) {
 
// data
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = 0;
i = 0;
 
while(fread(&buffer, sizeof(unsigned char), 4, input) != 0) {
tmp = (uint32_t)(buffer[0] << 0);
tmp |= (uint32_t)(buffer[1] << 8);
tmp |= (uint32_t)(buffer[2] << 16);
tmp |= (uint32_t)(buffer[3] << 24);
sprintf(tmp_string, "%08x\n", (unsigned int)tmp);
fputs(tmp_string, output);
}
}
 
 
fclose(input);
fclose(output);
 
/trunk/sw/image_gen/uart_upload.sh
8,7 → 8,7
then
echo "Upload image via serial port (UART) to the NEORV32 bootloader."
echo "Reset processor before starting the upload."
echo "Usage: [sudo] sh uart_upload.sh <tty> <file>"
echo "Usage: [sudo] sh uart_upload.sh <port> <NEORV32 executable>"
echo "Example: sh uart_upload.sh /dev/ttyS6 neorv32_exe.bin"
exit
fi
20,7 → 20,7
exec 3<$1 # redirect serial output to fd 3
cat <&3 > uart_upload.response.dat & # redirect serial output to file
PID=$! # save pid to kill cat
printf "#" > $1 # send fast/silent upload to serial port
printf "u" > $1 # send upload command to serial port
sleep 0.5s # wait for bootloader response
kill $PID # kill cat process
 
/trunk/sw/isa-test/port-neorv32/device/rv32i_m/C/Makefile.include
0,0 → 1,4
NEORV32_MARCH ?= rv32ic
NEORV32_CPU_EXTENSION_RISCV_C ?= true
 
include $(NEORV32_ROOT)/sw/isa-test/common.mk
/trunk/sw/isa-test/port-neorv32/device/rv32i_m/I/Makefile.include
0,0 → 1,4
include $(NEORV32_ROOT)/sw/isa-test/common.mk
/trunk/sw/isa-test/port-neorv32/device/rv32i_m/M/Makefile.include
0,0 → 1,4
NEORV32_MARCH ?= rv32im
NEORV32_CPU_EXTENSION_RISCV_M ?= true
 
include $(NEORV32_ROOT)/sw/isa-test/common.mk
/trunk/sw/isa-test/port-neorv32/device/rv32i_m/Zifencei/Makefile.include
0,0 → 1,28
NEORV32_LINK ?= link.imem_ram.ld
 
include $(NEORV32_ROOT)/sw/isa-test/common.mk
 
RUN_TARGET=\
cd $(work_dir_isa); \
echo ">"; \
rm -f $(NEORV32_LOCAL_COPY)/*.out; \
echo "restoring/using original IMEM rtl file"; \
rm -f $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \
cp -f $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.ORIGINAL $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \
make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led main.elf; \
cp -f $< $(NEORV32_LOCAL_COPY)/sw/example/blink_led/main.elf; \
make -C $(NEORV32_LOCAL_COPY)/sw/example/blink_led main.bin install; \
touch $(NEORV32_LOCAL_COPY)/neorv32.uart0.sim_mode.data.out; \
GHDL_DEVNULL=true $(shell which time) -v $(NEORV32_LOCAL_COPY)/sim/ghdl.run.sh \
--stop-time=$(SIM_TIME) \
-gCPU_EXTENSION_RISCV_A=false \
-gCPU_EXTENSION_RISCV_C=false \
-gCPU_EXTENSION_RISCV_E=false \
-gCPU_EXTENSION_RISCV_M=false \
-gCPU_EXTENSION_RISCV_U=false \
-gCPU_EXTENSION_RISCV_Zicsr=true \
-gCPU_EXTENSION_RISCV_Zifencei=true \
-gEXT_IMEM_C=false \
-gMEM_INT_IMEM_SIZE='32768'; \
cp $(NEORV32_LOCAL_COPY)/sim/neorv32.uart0.sim_mode.data.out $(*).signature.output; \
echo "<";
/trunk/sw/isa-test/port-neorv32/device/rv32i_m/privilege/Makefile.include
0,0 → 1,3
NEORV32_CPU_EXTENSION_RISCV_C ?= true
 
include $(NEORV32_ROOT)/sw/isa-test/common.mk
/trunk/sw/isa-test/port-neorv32/README.md
0,0 → 1,28
# NEORV32 Port for running the RISC-V Architecture Tests
 
 
The following tasks are executed by the device makefiles:
 
* replace the original processor's IMEM rtl file by a simulation-optimized IMEM (ROM!)
* `sed` command is used to modify the default testbench (`neorv32/sim/neorv32_tb.simple.vhd`):
* enable/disable the required `CPU_EXTENSION_RISCV_xxx` VHDL configuration generics in the testbench (`neorv32/sim/neorv32_tb.simple.vhd`)
* set the processor memory configuration
* compile test code and install application image to processor's `rtl/core` folder
* compilation uses the `link.imem_rom.ld` linker script as default; code (the test code) is executed from simulation-optimized IMEM (which is read-only); data including signature is stored to DMEM
* certain areas in the DMEM are initialized using port code in `model_test.h` (`RVTEST` = 0xbabecafe and `SIGNATURE` = 0xdeadbeef); can be disabled using `RISCV_TARGET_FLAGS=-DNEORV32_NO_DATA_INIT`
* the processor is simulated using the default testbench
* the results are dumped via the SIM_MODE feature of UART0
* the according code can be found in the `RVMODEL_HALT` macro in `model_test.h`
* data output (the "signature") is zero-padded to be always a multiple of 16 bytes
 
 
**Notes**
 
:warning: The `Zifencei` test requires the r/w/e capabilities of the original IMEM rtl file.
Hence, the original file is restored for this test. Also, this test uses `link.imem_ram.ld` as linker script since the
IMEM is used as RAM to allow self-modifying code.
 
:information_source: The `RVMODEL_BOOT` macro in `model_test.h` provides a simple "dummy trap handler" that just advances
to the next instruction. This trap handler is required for some `C` tests as the NEORV32 will raise an illegal instruction
exception for **all** unimplemented instructions. The trap handler can be overriden (by changing `mtval` CSR) if a test
uses the defualt trap handler of the test framework.
/trunk/sw/isa-test/port-neorv32/link.imem_ram.ld
0,0 → 1,22
OUTPUT_ARCH( "riscv" )
ENTRY(rvtest_entry_point)
 
SECTIONS
{
. = 0x00000000;
.text :
{
*(.text.init)
. = ALIGN(0x1000);
*(.text)
. = ALIGN(0x1000);
*(.tohost)
*(.data)
*(.data.string)
*(.bss)
. = ALIGN(0x1000);
 
_end = .;
}
}
 
/trunk/sw/isa-test/port-neorv32/link.imem_rom.ld
0,0 → 1,26
OUTPUT_ARCH( "riscv" )
ENTRY(rvtest_entry_point)
 
SECTIONS
{
. = 0x00000000;
.text :
{
*(.text.init)
. = ALIGN(0x1000);
*(.text)
. = ALIGN(0x1000);
_end = .;
}
 
. = 0x80000000;
.data :
{
. = ALIGN(0x1000);
*(.tohost)
*(.data)
*(.data.string)
*(.bss)
}
}
 
/trunk/sw/isa-test/port-neorv32/model_test.h
0,0 → 1,210
// SPDX-License-Identifier: BSD-3-Clause
 
// Modified by Stephan Nolting for the NEORV32 Processor
 
#ifndef _COMPLIANCE_MODEL_H
#define _COMPLIANCE_MODEL_H
 
#define RVMODEL_DATA_SECTION \
.pushsection .tohost,"aw",@progbits; \
.align 8; .global tohost; tohost: .dword 0; \
.align 8; .global fromhost; fromhost: .dword 0; \
.popsection; \
.align 8; .global begin_regstate; begin_regstate: \
.word 128; \
.align 8; .global end_regstate; end_regstate: \
.word 4;
 
//RV_COMPLIANCE_HALT
// neorv32: this will dump the results via the UART0_SIM_MODE data file output
// neorv32: due to the modifications on "end_signature" (not 4-aligned) we need to make sure we output a 4-aligned number of data here
// neorv32: -> for zero-padding of the rest of the SIGNATURE section
#define RVMODEL_HALT \
signature_dump: \
la a0, begin_signature; \
la a1, end_signature; \
li a2, 0xFFFFFFA4; \
signature_dump_loop: \
beq a0, a1, signature_dump_padding; \
lw t0, 0(a0); \
sw t0, 0(a2); \
addi a0, a0, 4; \
j signature_dump_loop; \
nop; \
nop; \
signature_dump_padding: \
andi a0, a1, 0x0000000C; \
beq a0, zero, signature_dump_end; \
li t0, 16; \
sub a0, t0, a0; \
signature_dump_padding_loop: \
beq a0, zero, signature_dump_end; \
sw zero, 0(a2); \
addi a0, a0, -4; \
j signature_dump_padding_loop; \
signature_dump_end: \
j signature_dump_end
 
//TODO: declare the start of your signature region here. Nothing else to be used here.
// The .align 4 ensures that the signature ends at a 16-byte boundary
#define RVMODEL_DATA_BEGIN \
.align 4; .global begin_signature; begin_signature:
 
//TODO: declare the end of the signature region here. Add other target specific contents here.
//neorv32: DO NOT use align_4 here! end_signature is used to indicate the actual "number" of signature words
#define RVMODEL_DATA_END \
.global end_signature; end_signature: \
RVMODEL_DATA_SECTION
 
//RVMODEL_BOOT
// neorv32: enable UART0 (ctrl(28)) and enable UART0_SIM_MODE (ctrl(12))
// neorv32: initialize the complete RVTEST_DATA section in data RAM (DMEM) with 0xBABECAFE
// neorv32: initialize the complete SIGNATURE section (that is a multiple of four 32-bit entries) in data RAM (DMEM) with 0xDEADBEEF
// neorv32: this code also provides a dummy trap handler that just moves on to the next instruction
// neorv32: -> this trap handler can be overriden by the compliance-suite by modifying mtval
// neorv32: -> the dummy trap handler is required to deal with the neorv32 X extension (-> all illegal/undefined instruction trigger an exception)
#ifdef NEORV32_NO_DATA_INIT
// ------------------------- WITHOUT DATA INIT -------------------------
#define RVMODEL_BOOT \
core_init: \
la x1, core_dummy_trap_handler; \
csrw mtvec, x1; \
j uart0_sim_mode_init; \
nop; \
nop; \
.balign 4; \
core_dummy_trap_handler: \
csrw mscratch, sp; \
la sp, end_signature; \
addi sp, sp, 32; \
sw x8, 0(sp); \
sw x9, 4(sp); \
csrr x8, mcause; \
blt x8, zero, core_dummy_trap_handler_irq; \
csrr x8, mepc; \
core_dummy_trap_handler_exc_c_check: \
lh x9, 0(x8); \
andi x9, x9, 3; \
addi x8, x8, +2; \
csrw mepc, x8; \
addi x8, zero, 3; \
bne x8, x9, core_dummy_trap_handler_irq; \
core_dummy_trap_handler_exc_uncrompressed: \
csrr x8, mepc; \
addi x8, x8, +2; \
csrw mepc, x8; \
core_dummy_trap_handler_irq: \
lw x9, 0(sp); \
lw x8, 4(sp); \
csrr sp, mscratch; \
mret; \
nop; \
nop; \
uart0_sim_mode_init: \
li a0, 0xFFFFFFA0; \
sw zero, 0(a0); \
li a1, 1 << 28; \
li a2, 1 << 12; \
or a1, a1, a2; \
sw a1, 0(a0);
 
#else
 
// ------------------------- WITH DATA INIT -------------------------
#define RVMODEL_BOOT \
core_init: \
la x1, core_dummy_trap_handler; \
csrw mtvec, x1; \
nop; \
nop; \
init_rvtest_data: \
la a0, rvtest_data_begin; \
la a1, rvtest_data_end; \
li a2, 0xBABECAFE; \
init_rvtest_data_loop: \
beq a0, a1, init_rvtest_data_loop_end; \
sw a2, 0(a0); \
addi a0, a0, 4; \
j init_rvtest_data_loop; \
init_rvtest_data_loop_end: \
nop; \
nop; \
init_signature: \
la a0, begin_signature; \
la a1, end_signature; \
li a2, 0xDEADBEEF; \
init_signature_loop: \
beq a0, a1, init_signature_loop_end; \
sw a2, 0(a0); \
addi a0, a0, 4; \
j init_signature_loop; \
init_signature_loop_end: \
j uart0_sim_mode_init; \
nop; \
nop; \
.balign 4; \
core_dummy_trap_handler: \
csrw mscratch, sp; \
la sp, end_signature; \
addi sp, sp, 32; \
sw x8, 0(sp); \
sw x9, 4(sp); \
csrr x8, mcause; \
blt x8, zero, core_dummy_trap_handler_irq; \
csrr x8, mepc; \
core_dummy_trap_handler_exc_c_check: \
lh x9, 0(x8); \
andi x9, x9, 3; \
addi x8, x8, +2; \
csrw mepc, x8; \
addi x8, zero, 3; \
bne x8, x9, core_dummy_trap_handler_irq; \
core_dummy_trap_handler_exc_uncrompressed: \
csrr x8, mepc; \
addi x8, x8, +2; \
csrw mepc, x8; \
core_dummy_trap_handler_irq: \
lw x9, 0(sp); \
lw x8, 4(sp); \
csrr sp, mscratch; \
mret; \
nop; \
nop; \
uart0_sim_mode_init: \
li a0, 0xFFFFFFA0; \
sw zero, 0(a0); \
li a1, 1 << 28; \
li a2, 1 << 12; \
or a1, a1, a2; \
sw a1, 0(a0);
 
#endif
 
 
//RVTEST_IO_INIT
#define RVMODEL_IO_INIT
//RVTEST_IO_WRITE_STR
#define RVMODEL_IO_WRITE_STR(_R, _STR)
//RVTEST_IO_CHECK
#define RVMODEL_IO_CHECK()
 
//RVTEST_IO_ASSERT_GPR_EQ
#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I)
//RVTEST_IO_ASSERT_SFPR_EQ
#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I)
//RVTEST_IO_ASSERT_DFPR_EQ
#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I)
 
// TODO: specify the routine for setting machine software interrupt
#define RVMODEL_SET_MSW_INT
 
// TODO: specify the routine for clearing machine software interrupt
#define RVMODEL_CLEAR_MSW_INT
 
// TODO: specify the routine for clearing machine timer interrupt
#define RVMODEL_CLEAR_MTIMER_INT
 
// TODO: specify the routine for clearing machine external interrupt
#define RVMODEL_CLEAR_MEXT_INT
 
#endif // _COMPLIANCE_MODEL_H
/trunk/sw/isa-test/common.mk
0,0 → 1,61
ifndef NEORV32_ROOT
$(error NEORV32_ROOT is undefined)
endif
 
NEORV32_LOCAL_COPY ?= $(NEORV32_ROOT)/sim/work
 
TARGET_SIM ?= ghdl
TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS)
 
ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),)
$(error Target simulator executable '$(TARGET_SIM)` not found)
endif
 
NEORV32_MARCH ?= rv32i
 
RISCV_PREFIX ?= riscv32-unknown-elf-
RISCV_GCC ?= $(RISCV_PREFIX)gcc
RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump
RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy
RISCV_READELF ?= $(RISCV_PREFIX)readelf
RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -march=$(NEORV32_MARCH) -mabi=ilp32
 
NEORV32_LINK ?= link.imem_rom.ld
 
COMPILE_TARGET ?= \
$$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \
$$(RISCV_TARGET_FLAGS) \
-I$(ROOTDIR)/riscv-test-suite/env/ \
-I$(TARGETDIR)/$(RISCV_TARGET)/ \
-T$(TARGETDIR)/$(RISCV_TARGET)/$(NEORV32_LINK) \
$$(<) -o $$@
 
NEORV32_CPU_EXTENSION_RISCV_C ?= false
NEORV32_CPU_EXTENSION_RISCV_M ?= false
 
NEORV32_SOFTWARE_EXAMPLE ?= $(NEORV32_LOCAL_COPY)/sw/example/blink_led
 
RUN_TARGET ?= \
cd $(work_dir_isa); \
echo ">"; \
rm -f $(NEORV32_LOCAL_COPY)/*.out; \
echo "copying/using SIM-only IMEM (ROM!)"; \
rm -f $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \
cp -f $(NEORV32_LOCAL_COPY)/sim/neorv32_imem.simple.vhd $(NEORV32_LOCAL_COPY)/rtl/core/neorv32_imem.vhd; \
make -C $(NEORV32_SOFTWARE_EXAMPLE) main.elf; \
cp -f $< $(NEORV32_SOFTWARE_EXAMPLE)/main.elf; \
make -C $(NEORV32_SOFTWARE_EXAMPLE) main.bin install; \
touch $(NEORV32_LOCAL_COPY)/neorv32.uart0.sim_mode.data.out; \
GHDL_DEVNULL=true $(shell which time) -v $(NEORV32_LOCAL_COPY)/sim/ghdl.run.sh \
--stop-time=$(SIM_TIME) \
-gCPU_EXTENSION_RISCV_A=false \
-gCPU_EXTENSION_RISCV_C=$(NEORV32_CPU_EXTENSION_RISCV_C) \
-gCPU_EXTENSION_RISCV_E=false \
-gCPU_EXTENSION_RISCV_M=$(NEORV32_CPU_EXTENSION_RISCV_M) \
-gCPU_EXTENSION_RISCV_U=false \
-gCPU_EXTENSION_RISCV_Zicsr=true \
-gCPU_EXTENSION_RISCV_Zifencei=false \
-gEXT_IMEM_C=false \
-gMEM_INT_IMEM_SIZE='2097152'; \
cp $(NEORV32_LOCAL_COPY)/sim/neorv32.uart0.sim_mode.data.out $(*).signature.output; \
echo "<";
/trunk/sw/lib/include/neorv32.h
68,6 → 68,8
CSR_MTVEC = 0x305, /**< 0x305 - mtvec (r/w): Machine trap-handler base address (for ALL traps) */
CSR_MCOUNTEREN = 0x306, /**< 0x305 - mcounteren (r/w): Machine counter enable register (controls access rights from U-mode) */
 
CSR_MSTATUSH = 0x310, /**< 0x310 - mstatush (r/h): Machine status register - high word */
 
CSR_MCOUNTINHIBIT = 0x320, /**< 0x320 - mcountinhibit (r/w): Machine counter-inhibit register */
 
CSR_MHPMEVENT3 = 0x323, /**< 0x323 - mhpmevent3 (r/w): Machine hardware performance monitor event selector 3 */
262,10 → 264,11
CSR_TIMEH = 0xc81, /**< 0xc81 - timeh (r/-): Timer high word (from MTIME.TIME_HI) */
CSR_INSTRETH = 0xc82, /**< 0xc82 - instreth (r/-): Instructions-retired counter high word (from MINSTRETH) */
 
CSR_MVENDORID = 0xf11, /**< 0xf11 - mvendorid (r/-): Vendor ID */
CSR_MARCHID = 0xf12, /**< 0xf12 - marchid (r/-): Architecture ID */
CSR_MIMPID = 0xf13, /**< 0xf13 - mimpid (r/-): Implementation ID/version */
CSR_MHARTID = 0xf14, /**< 0xf14 - mhartid (r/-): Hardware thread ID (always 0) */
CSR_MVENDORID = 0xf11, /**< 0xf11 - mvendorid (r/-): Vendor ID */
CSR_MARCHID = 0xf12, /**< 0xf12 - marchid (r/-): Architecture ID */
CSR_MIMPID = 0xf13, /**< 0xf13 - mimpid (r/-): Implementation ID/version */
CSR_MHARTID = 0xf14, /**< 0xf14 - mhartid (r/-): Hardware thread ID (always 0) */
CSR_MCONFIGPTR = 0xf15, /**< 0xf15 - mconfigptr (r/-): Machine configuration pointer register */
 
CSR_MZEXT = 0xfc0 /**< 0xfc0 - mzext (custom CSR) (r/-): Available Z* CPU extensions */
};
278,7 → 281,11
CSR_MSTATUS_MIE = 3, /**< CPU mstatus CSR (3): MIE - Machine interrupt enable bit (r/w) */
CSR_MSTATUS_MPIE = 7, /**< CPU mstatus CSR (7): MPIE - Machine previous interrupt enable bit (r/w) */
CSR_MSTATUS_MPP_L = 11, /**< CPU mstatus CSR (11): MPP_L - Machine previous privilege mode bit low (r/w) */
CSR_MSTATUS_MPP_H = 12 /**< CPU mstatus CSR (12): MPP_H - Machine previous privilege mode bit high (r/w) */
CSR_MSTATUS_MPP_H = 12, /**< CPU mstatus CSR (12): MPP_H - Machine previous privilege mode bit high (r/w) */
CSR_MSTATUS_FS_L = 13, /**< CPU mstatus CSR (13): FS_L - FPU state bit low (r/w) */
CSR_MSTATUS_FS_H = 14, /**< CPU mstatus CSR (14): FS_H - FPU state bit high (r/w) */
CSR_MSTATUS_TW = 21, /**< CPU mstatus CSR (21): TW - timeout wait (trigger illegal instruction exception if WFI is executed outside of m-mode when set) (r/w) */
CSR_MSTATUS_SD = 31 /**< CPU mstatus CSR (31): SD - extension's state summary (set = non-clean) (r/-) */
};
 
 
685,63 → 692,88
#define SLINK_SIZE (16*4) // /**< SLINK address space size in bytes */
 
/** SLINK control register (r/w) */
#define SLINK_CT (*(IO_REG32 (SLINK_BASE + 0))) // r/w: control register
#define SLINK_CT (*(IO_REG32 (SLINK_BASE + 0))) // r/w: control register
/** SLINK status register (r/-) */
#define SLINK_STATUS (*(IO_REG32 (SLINK_BASE + 16))) // r/-: status register
/** stream link 0 (r/w) */
#define SLINK_CH0 (*(IO_REG32 (SLINK_BASE + 32 + 0))) // r/w: link 0
#define SLINK_CH0 (*(IO_REG32 (SLINK_BASE + 32 + 0))) // r/w: link 0
/** stream link 1 (r/w) */
#define SLINK_CH1 (*(IO_REG32 (SLINK_BASE + 32 + 4))) // r/w: link 1
#define SLINK_CH1 (*(IO_REG32 (SLINK_BASE + 32 + 4))) // r/w: link 1
/** stream link 2 (r/w) */
#define SLINK_CH2 (*(IO_REG32 (SLINK_BASE + 32 + 8))) // r/w: link 2
#define SLINK_CH2 (*(IO_REG32 (SLINK_BASE + 32 + 8))) // r/w: link 2
/** stream link 3 (r/w) */
#define SLINK_CH3 (*(IO_REG32 (SLINK_BASE + 32 + 12))) // r/w: link 3
#define SLINK_CH3 (*(IO_REG32 (SLINK_BASE + 32 + 12))) // r/w: link 3
/** stream link 4 (r/w) */
#define SLINK_CH4 (*(IO_REG32 (SLINK_BASE + 32 + 16))) // r/w: link 4
#define SLINK_CH4 (*(IO_REG32 (SLINK_BASE + 32 + 16))) // r/w: link 4
/** stream link 5 (r/w) */
#define SLINK_CH5 (*(IO_REG32 (SLINK_BASE + 32 + 20))) // r/w: link 5
#define SLINK_CH5 (*(IO_REG32 (SLINK_BASE + 32 + 20))) // r/w: link 5
/** stream link 6 (r/w) */
#define SLINK_CH6 (*(IO_REG32 (SLINK_BASE + 32 + 24))) // r/w: link 6
#define SLINK_CH6 (*(IO_REG32 (SLINK_BASE + 32 + 24))) // r/w: link 6
/** stream link 7 (r/w) */
#define SLINK_CH7 (*(IO_REG32 (SLINK_BASE + 32 + 28))) // r/w: link 7
#define SLINK_CH7 (*(IO_REG32 (SLINK_BASE + 32 + 28))) // r/w: link 7
 
/** SLINK control register bits */
enum NEORV32_SLINK_CT_enum {
SLINK_CT_RX0_AVAIL = 0, /**< SLINK control register(0) (r/-): RX link 0 data available */
SLINK_CT_RX1_AVAIL = 1, /**< SLINK control register(1) (r/-): RX link 1 data available */
SLINK_CT_RX2_AVAIL = 2, /**< SLINK control register(2) (r/-): RX link 2 data available */
SLINK_CT_RX3_AVAIL = 3, /**< SLINK control register(3) (r/-): RX link 3 data available */
SLINK_CT_RX4_AVAIL = 4, /**< SLINK control register(4) (r/-): RX link 4 data available */
SLINK_CT_RX5_AVAIL = 5, /**< SLINK control register(5) (r/-): RX link 5 data available */
SLINK_CT_RX6_AVAIL = 6, /**< SLINK control register(6) (r/-): RX link 6 data available */
SLINK_CT_RX7_AVAIL = 7, /**< SLINK control register(7) (r/-): RX link 7 data available */
SLINK_CT_RX_NUM0 = 0, /**< SLINK control register(0) (r/-): number of implemented RX links bit 0 */
SLINK_CT_RX_NUM1 = 1, /**< SLINK control register(1) (r/-): number of implemented RX links bit 1 */
SLINK_CT_RX_NUM2 = 2, /**< SLINK control register(2) (r/-): number of implemented RX links bit 2 */
SLINK_CT_RX_NUM3 = 3, /**< SLINK control register(3) (r/-): number of implemented RX links bit 3 */
 
SLINK_CT_TX0_FREE = 8, /**< SLINK control register(8) (r/-): RT link 0 ready to send */
SLINK_CT_TX1_FREE = 9, /**< SLINK control register(9) (r/-): RT link 1 ready to send */
SLINK_CT_TX2_FREE = 10, /**< SLINK control register(10) (r/-): RT link 2 ready to send */
SLINK_CT_TX3_FREE = 11, /**< SLINK control register(11) (r/-): RT link 3 ready to send */
SLINK_CT_TX4_FREE = 12, /**< SLINK control register(12) (r/-): RT link 4 ready to send */
SLINK_CT_TX5_FREE = 13, /**< SLINK control register(13) (r/-): RT link 5 ready to send */
SLINK_CT_TX6_FREE = 14, /**< SLINK control register(14) (r/-): RT link 6 ready to send */
SLINK_CT_TX7_FREE = 15, /**< SLINK control register(15) (r/-): RT link 7 ready to send */
SLINK_CT_TX_NUM0 = 4, /**< SLINK control register(4) (r/-): number of implemented TX links bit 0 */
SLINK_CT_TX_NUM1 = 5, /**< SLINK control register(5) (r/-): number of implemented TX links bit 1 */
SLINK_CT_TX_NUM2 = 6, /**< SLINK control register(6) (r/-): number of implemented TX links bit 2 */
SLINK_CT_TX_NUM3 = 7, /**< SLINK control register(7) (r/-): number of implemented TX links bit 3 */
 
SLINK_CT_RX_NUM0 = 16, /**< SLINK control register(16) (r/-): number of implemented RX links -1 bit 0 */
SLINK_CT_RX_NUM1 = 17, /**< SLINK control register(17) (r/-): number of implemented RX links -1 bit 1 */
SLINK_CT_RX_NUM2 = 18, /**< SLINK control register(18) (r/-): number of implemented RX links -1 bit 2 */
SLINK_CT_RX_FIFO_S0 = 8, /**< SLINK control register( 8) (r/-): log2(RX FIFO size) bit 0 */
SLINK_CT_RX_FIFO_S1 = 9, /**< SLINK control register( 9) (r/-): log2(RX FIFO size) bit 1 */
SLINK_CT_RX_FIFO_S2 = 10, /**< SLINK control register(10) (r/-): log2(RX FIFO size) bit 2 */
SLINK_CT_RX_FIFO_S3 = 11, /**< SLINK control register(11) (r/-): log2(RX FIFO size) bit 3 */
 
SLINK_CT_TX_NUM0 = 19, /**< SLINK control register(19) (r/-): number of implemented TX links -1bit 0 */
SLINK_CT_TX_NUM1 = 20, /**< SLINK control register(20) (r/-): number of implemented TX links -1bit 1 */
SLINK_CT_TX_NUM2 = 21, /**< SLINK control register(21) (r/-): number of implemented TX links -1bit 2 */
SLINK_CT_TX_FIFO_S0 = 12, /**< SLINK control register(12) (r/-): log2(TX FIFO size) bit 0 */
SLINK_CT_TX_FIFO_S1 = 13, /**< SLINK control register(13) (r/-): log2(TX FIFO size) bit 1 */
SLINK_CT_TX_FIFO_S2 = 14, /**< SLINK control register(14) (r/-): log2(TX FIFO size) bit 2 */
SLINK_CT_TX_FIFO_S3 = 15, /**< SLINK control register(15) (r/-): log2(TX FIFO size) bit 3 */
 
SLINK_CT_RX_FIFO_S0 = 22, /**< SLINK control register(22) (r/-): log2(RX FIFO size) bit 0 */
SLINK_CT_RX_FIFO_S1 = 23, /**< SLINK control register(23) (r/-): log2(RX FIFO size) bit 1 */
SLINK_CT_RX_FIFO_S2 = 24, /**< SLINK control register(24) (r/-): log2(RX FIFO size) bit 2 */
SLINK_CT_RX_FIFO_S3 = 25, /**< SLINK control register(25) (r/-): log2(RX FIFO size) bit 3 */
SLINK_CT_EN = 31, /**< SLINK control register(0) (r/w): SLINK controller enable */
};
 
SLINK_CT_TX_FIFO_S0 = 26, /**< SLINK control register(26) (r/-): log2(TX FIFO size) bit 0 */
SLINK_CT_TX_FIFO_S1 = 27, /**< SLINK control register(27) (r/-): log2(TX FIFO size) bit 1 */
SLINK_CT_TX_FIFO_S2 = 28, /**< SLINK control register(28) (r/-): log2(TX FIFO size) bit 2 */
SLINK_CT_TX_FIFO_S3 = 29, /**< SLINK control register(29) (r/-): log2(TX FIFO size) bit 3 */
/** SLINK status register bits */
enum NEORV32_SLINK_STATUS_enum {
SLINK_STATUS_RX0_AVAIL = 0, /**< SLINK status register(0) (r/-): RX link 0 data available */
SLINK_STATUS_RX1_AVAIL = 1, /**< SLINK status register(1) (r/-): RX link 1 data available */
SLINK_STATUS_RX2_AVAIL = 2, /**< SLINK status register(2) (r/-): RX link 2 data available */
SLINK_STATUS_RX3_AVAIL = 3, /**< SLINK status register(3) (r/-): RX link 3 data available */
SLINK_STATUS_RX4_AVAIL = 4, /**< SLINK status register(4) (r/-): RX link 4 data available */
SLINK_STATUS_RX5_AVAIL = 5, /**< SLINK status register(5) (r/-): RX link 5 data available */
SLINK_STATUS_RX6_AVAIL = 6, /**< SLINK status register(6) (r/-): RX link 6 data available */
SLINK_STATUS_RX7_AVAIL = 7, /**< SLINK status register(7) (r/-): RX link 7 data available */
 
SLINK_CT_EN = 31 /**< SLINK control register(31) (r/w): SLINK controller enable */
SLINK_STATUS_TX0_FREE = 8, /**< SLINK status register(8) (r/-): TX link 0 ready to send */
SLINK_STATUS_TX1_FREE = 9, /**< SLINK status register(9) (r/-): TX link 1 ready to send */
SLINK_STATUS_TX2_FREE = 10, /**< SLINK status register(10) (r/-): TX link 2 ready to send */
SLINK_STATUS_TX3_FREE = 11, /**< SLINK status register(11) (r/-): TX link 3 ready to send */
SLINK_STATUS_TX4_FREE = 12, /**< SLINK status register(12) (r/-): TX link 4 ready to send */
SLINK_STATUS_TX5_FREE = 13, /**< SLINK status register(13) (r/-): TX link 5 ready to send */
SLINK_STATUS_TX6_FREE = 14, /**< SLINK status register(14) (r/-): TX link 6 ready to send */
SLINK_STATUS_TX7_FREE = 15, /**< SLINK status register(15) (r/-): TX link 7 ready to send */
 
SLINK_STATUS_RX0_HALF = 16, /**< SLINK status register(16) (r/-): RX link 0 FIFO fill level is >= half-full */
SLINK_STATUS_RX1_HALF = 17, /**< SLINK status register(17) (r/-): RX link 1 FIFO fill level is >= half-full */
SLINK_STATUS_RX2_HALF = 18, /**< SLINK status register(18) (r/-): RX link 2 FIFO fill level is >= half-full */
SLINK_STATUS_RX3_HALF = 19, /**< SLINK status register(19) (r/-): RX link 3 FIFO fill level is >= half-full */
SLINK_STATUS_RX4_HALF = 20, /**< SLINK status register(20) (r/-): RX link 4 FIFO fill level is >= half-full */
SLINK_STATUS_RX5_HALF = 21, /**< SLINK status register(21) (r/-): RX link 5 FIFO fill level is >= half-full */
SLINK_STATUS_RX6_HALF = 22, /**< SLINK status register(22) (r/-): RX link 6 FIFO fill level is >= half-full */
SLINK_STATUS_RX7_HALF = 23, /**< SLINK status register(23) (r/-): RX link 7 FIFO fill level is >= half-full */
 
SLINK_STATUS_TX0_HALF = 24, /**< SLINK status register(24) (r/-): TX link 0 FIFO fill level is > half-full */
SLINK_STATUS_TX1_HALF = 25, /**< SLINK status register(25) (r/-): TX link 1 FIFO fill level is > half-full */
SLINK_STATUS_TX2_HALF = 26, /**< SLINK status register(26) (r/-): TX link 2 FIFO fill level is > half-full */
SLINK_STATUS_TX3_HALF = 27, /**< SLINK status register(27) (r/-): TX link 3 FIFO fill level is > half-full */
SLINK_STATUS_TX4_HALF = 28, /**< SLINK status register(28) (r/-): TX link 4 FIFO fill level is > half-full */
SLINK_STATUS_TX5_HALF = 29, /**< SLINK status register(29) (r/-): TX link 5 FIFO fill level is > half-full */
SLINK_STATUS_TX6_HALF = 30, /**< SLINK status register(30) (r/-): TX link 6 FIFO fill level is > half-full */
SLINK_STATUS_TX7_HALF = 31 /**< SLINK status register(31) (r/-): TX link 7 FIFO fill level is > half-full */
};
/**@}*/
 
1040,7 → 1072,7
enum NEORV32_NEOLED_CT_enum {
NEOLED_CT_EN = 0, /**< NEOLED control register(0) (r/w): NEOLED global enable */
NEOLED_CT_MODE = 1, /**< NEOLED control register(1) (r/w): TX mode (0=24-bit, 1=32-bit) */
NEOLED_CT_BSCON = 2, /**< NEOLED control register(2) (r/w): buffer status configuration -> busy_flag/IRQ config (0=at least one free entry, 1=whole buffer empty) */
NEOLED_CT_STROBE = 2, /**< NEOLED control register(2) (r/w): Strobe (0=send normal data, 1=send RESET command on data write) */
NEOLED_CT_PRSC0 = 3, /**< NEOLED control register(3) (r/w): Clock prescaler select bit 0 (pulse-clock speed select) */
NEOLED_CT_PRSC1 = 4, /**< NEOLED control register(4) (r/w): Clock prescaler select bit 1 (pulse-clock speed select) */
NEOLED_CT_PRSC2 = 5, /**< NEOLED control register(5) (r/w): Clock prescaler select bit 2 (pulse-clock speed select) */
1068,8 → 1100,10
NEOLED_CT_T_ONE_H_3 = 23, /**< NEOLED control register(23) (r/w): pulse-clock ticks per ONE high-time bit 3 */
NEOLED_CT_T_ONE_H_4 = 24, /**< NEOLED control register(24) (r/w): pulse-clock ticks per ONE high-time bit 4 */
//
NEOLED_CT_TX_STATUS = 30, /**< NEOLED control register(30) (r/-): serial transmit engine still busy when set */
NEOLED_CT_BUSY = 31 /**< NEOLED control register(31) (r/-): busy / buffer status flag (configured via #NEOLED_CT_BSCON) */
NEOLED_CT_TX_EMPTY = 28, /**< NEOLED control register(28) (r/-): TX FIFO is empty */
NEOLED_CT_TX_HALF = 29, /**< NEOLED control register(29) (r/-): TX FIFO is at least half-full */
NEOLED_CT_TX_FULL = 30, /**< NEOLED control register(30) (r/-): TX FIFO is full */
NEOLED_CT_TX_BUSY = 31 /**< NEOLED control register(31) (r/-): busy / buffer status flag (configured via #NEOLED_CT_BSCON) */
};
/**@}*/
 
1109,7 → 1143,7
SYSINFO_FEATURES_MEM_EXT = 1, /**< SYSINFO_FEATURES (1) (r/-): External bus interface implemented when 1 (via MEM_EXT_EN generic) */
SYSINFO_FEATURES_MEM_INT_IMEM = 2, /**< SYSINFO_FEATURES (2) (r/-): Processor-internal instruction memory implemented when 1 (via MEM_INT_IMEM_EN generic) */
SYSINFO_FEATURES_MEM_INT_DMEM = 3, /**< SYSINFO_FEATURES (3) (r/-): Processor-internal data memory implemented when 1 (via MEM_INT_DMEM_EN generic) */
SYSINFO_FEATURES_MEM_EXT_ENDIAN = 4, /**< SYSINFO_FEATURES (4) (r/-): External bus interface uses BIG-endian byte-order when 1 (via package.xbus_big_endian_c constant) */
SYSINFO_FEATURES_MEM_EXT_ENDIAN = 4, /**< SYSINFO_FEATURES (4) (r/-): External bus interface uses BIG-endian byte-order when 1 (via MEM_EXT_BIG_ENDIAN generic) */
SYSINFO_FEATURES_ICACHE = 5, /**< SYSINFO_FEATURES (5) (r/-): Processor-internal instruction cache implemented when 1 (via ICACHE_EN generic) */
 
SYSINFO_FEATURES_OCD = 14, /**< SYSINFO_FEATURES (14) (r/-): On-chip debugger implemented when 1 (via ON_CHIP_DEBUGGER_EN generic) */
/trunk/sw/lib/include/neorv32_cpu.h
66,7 → 66,7
* @param[in] return_code Return value of main() function.
* @return Return value is irrelevant (there is no one left to check for it...).
**************************************************************************/
extern int __neorv32_crt0_after_main(int32_t return_code);
extern int __neorv32_crt0_after_main(int32_t return_code) __attribute__ ((weak));
 
 
/**********************************************************************//**
/trunk/sw/lib/include/neorv32_neoled.h
46,12 → 46,27
 
// prototypes
int neorv32_neoled_available(void);
void neorv32_neoled_setup_raw(uint32_t bs_config, uint32_t prsc, uint32_t t_total, uint32_t t_high_zero, uint32_t t_high_one);
void neorv32_neoled_setup_ws2812(uint32_t bs_config);
void neorv32_neoled_setup(uint32_t prsc, uint32_t t_total, uint32_t t_high_zero, uint32_t t_high_one);
void neorv32_neoled_setup_ws2812(void);
void neorv32_neoled_set_mode(uint32_t mode);
void neorv32_neoled_strobe_blocking(void);
void neorv32_neoled_strobe_nonblocking(void);
void neorv32_neoled_enable(void);
void neorv32_neoled_disable(void);
void neorv32_neoled_send_polling(uint32_t mode, uint32_t data);
void neorv32_neoled_send_direct(uint32_t mode, uint32_t data);
void neorv32_neoled_write_blocking(uint32_t data);
uint32_t neorv32_neoled_get_buffer_size(void);
 
 
/**********************************************************************//**
* Send single RGB(W) data word to NEOLED module (non-blocking).
*
* @warning This function uses NO busy/flag checks at all!
*
* @param[in] data LSB-aligned 24-bit RGB or 32-bit RGBW data
**************************************************************************/
inline void __attribute__ ((always_inline)) neorv32_neoled_write_nonblocking(uint32_t data) {
 
NEOLED_DATA = data; // send new LED data
}
 
#endif // neorv32_neoled_h
/trunk/sw/lib/include/neorv32_slink.h
50,6 → 50,8
int neorv32_slink_get_tx_num(void);
int neorv32_slink_get_rx_depth(void);
int neorv32_slink_get_tx_depth(void);
int neorv32_slink_check_rx_half_full(int link_id);
int neorv32_slink_check_tx_half_full(int link_id);
// non-blocking transmit
int neorv32_slink_tx0_nonblocking(uint32_t tx_data);
int neorv32_slink_tx1_nonblocking(uint32_t tx_data);
/trunk/sw/lib/source/neorv32_neoled.c
65,13 → 65,12
* Enable and configure NEOLED controller. The NEOLED control register bits are listed in #NEORV32_NEOLED_CT_enum.
* This function performs a "raw" configuration (just configuraing the according control register bit).
*
* @param[in] bs_config Busy flag / IRQ configuration (0 = at least one free entry, 1 = whole buffer empty).
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum.
* @param[in] t_total Number of pre-scaled clock ticks for total bit period (0..31).
* @param[in] t_high_zero Number of pre-scaled clock ticks to generate high-time for sending a '0' (0..31).
* @param[in] t_high_one Number of pre-scaled clock ticks to generate high-time for sending a '1' (0..31).
**************************************************************************/
void neorv32_neoled_setup_raw(uint32_t bs_config, uint32_t prsc, uint32_t t_total, uint32_t t_high_zero, uint32_t t_high_one) {
void neorv32_neoled_setup(uint32_t prsc, uint32_t t_total, uint32_t t_high_zero, uint32_t t_high_one) {
 
NEOLED_CT = 0; // reset
 
78,9 → 77,6
// module enable
uint32_t ct_enable = 1 << NEOLED_CT_EN;
 
// busy flag / IRQ config
uint32_t ct_bs_config = (bs_config & 0x1) << NEOLED_CT_BSCON;
 
// clock pre-scaler
uint32_t ct_prsc = (prsc & 0x7) << NEOLED_CT_PRSC0;
 
94,7 → 90,7
uint32_t ct_t_one = (t_high_one & 0x1f) << NEOLED_CT_T_ONE_H_0;
 
// set new configuration
NEOLED_CT = ct_enable | ct_bs_config | ct_prsc | ct_t_total | ct_t_zero | ct_t_one;
NEOLED_CT = ct_enable | ct_prsc | ct_t_total | ct_t_zero | ct_t_one;
}
 
 
104,10 → 100,8
*
* @note WS2812 timing: T_period = 1.2us, T_high_zero = 0.4us, T_high_one = 0.8us. Change the constants if required.
* @note This function uses the SYSINFO_CLK value (from the SYSINFO HW module) to do the timing computations.
*
* @param[in] bs_config Busy flag / IRQ configuration (0 = at least one free entry, 1 = whole buffer empty).
**************************************************************************/
void neorv32_neoled_setup_ws2812(uint32_t bs_config) {
void neorv32_neoled_setup_ws2812(void) {
 
// WS2812 timing
const uint32_t T_TOTAL_C = 1200; // ns
157,62 → 151,87
}
 
// set raw configuration
neorv32_neoled_setup_raw(bs_config, clk_prsc_sel, t_total, t_high_zero, t_high_one);
neorv32_neoled_setup(clk_prsc_sel, t_total, t_high_zero, t_high_one);
}
 
 
/**********************************************************************//**
* Enable NEOLED controller.
* Set NEOLED mode (24-bit RGB / 32-bit RGBW).
*
* @param[in] mode 0 = 24-bit mode (RGB), 1 = 32-bit mode (RGBW)
**************************************************************************/
void neorv32_neoled_enable(void) {
void neorv32_neoled_set_mode(uint32_t mode) {
 
NEOLED_CT |= ((uint32_t)(1 << NEOLED_CT_EN));
uint32_t ctrl = NEOLED_CT;
ctrl &= ~(0b1 << NEOLED_CT_MODE); // clear current mode
ctrl |= ((mode & 1) << NEOLED_CT_MODE); // set new mode
NEOLED_CT = ctrl;
}
 
 
/**********************************************************************//**
* Disable NEOLED controller.
* Send strobe command ("RESET") - blocking.
**************************************************************************/
void neorv32_neoled_disable(void) {
void neorv32_neoled_strobe_blocking(void) {
 
NEOLED_CT &= ~((uint32_t)(1 << NEOLED_CT_EN));
while(1) { // wait for FIFO full flag to clear
if ((NEOLED_CT & (1 << NEOLED_CT_TX_FULL)) == 0) {
break;
}
}
 
neorv32_neoled_strobe_nonblocking();
}
 
 
/**********************************************************************//**
* Send single data word to NEOLED module.
*
* @warning This function is blocking as it polls the NEOLED busy flag.
*
* @param[in] mode 0 = 24-bit mode (RGB), 1 = 32-bit mode (RGBW)
* @param[in] data 24-bit RGB or 32-bit RGBW data
* Send strobe command ("RESET") - non-blocking.
**************************************************************************/
void neorv32_neoled_send_polling(uint32_t mode, uint32_t data) {
void neorv32_neoled_strobe_nonblocking(void) {
 
while(NEOLED_CT & (1 << NEOLED_CT_BUSY)); // wait for busy flag to clear
const uint32_t mask = 1 << NEOLED_CT_STROBE; // strobe bit
uint32_t ctrl = NEOLED_CT;
 
neorv32_neoled_send_direct(mode, data);
NEOLED_CT = ctrl | mask; // set strobe bit
NEOLED_DATA = 0; // send any data to trigger strobe command
NEOLED_CT = ctrl & (~mask); // clear strobe bit
}
 
 
/**********************************************************************//**
* Send single data word to NEOLED module.
* Enable NEOLED controller.
**************************************************************************/
void neorv32_neoled_enable(void) {
 
NEOLED_CT |= ((uint32_t)(1 << NEOLED_CT_EN));
}
 
 
/**********************************************************************//**
* Disable NEOLED controller.
**************************************************************************/
void neorv32_neoled_disable(void) {
 
NEOLED_CT &= ~((uint32_t)(1 << NEOLED_CT_EN));
}
 
 
/**********************************************************************//**
* Send single RGB(W) data word to NEOLED module (blocking).
*
* @warning This function used NO busy checks at all!
* @note This function can be called several times in a row to fill the TX buffer (when busy_flag is cleared and bscon = 1).
* @warning This function is blocking as it polls the NEOLED FIFO full flag.
*
* @param[in] mode 0 = 24-bit mode (RGB), 1 = 32-bit mode (RGBW)
* @param[in] data 24-bit RGB or 32-bit RGBW data
* @param[in] data LSB-aligned 24-bit RGB or 32-bit RGBW data
**************************************************************************/
void neorv32_neoled_send_direct(uint32_t mode, uint32_t data) {
void neorv32_neoled_write_blocking(uint32_t data) {
 
// configure TX mode (data size)
uint32_t ctrl = NEOLED_CT;
ctrl &= ~(0b1 << NEOLED_CT_MODE); // clear current mode
ctrl |= ((mode & 1) << NEOLED_CT_MODE); // set new mode
NEOLED_CT = ctrl;
while(1) { // wait for FIFO full flag to clear
if ((NEOLED_CT & (1 << NEOLED_CT_TX_FULL)) == 0) {
break;
}
}
 
NEOLED_DATA = data; // send new LED data
neorv32_neoled_write_nonblocking(data); // send new LED data
}
 
 
225,7 → 244,7
 
uint32_t tmp = NEOLED_CT;
tmp = tmp >> NEOLED_CT_BUFS_0;
tmp = tmp & 0b1111; // insulate buffer size flags
tmp = tmp & 0xf; // isolate buffer size bits
 
return (1 << tmp); // num entries = pow(2, buffer size flags)
}
/trunk/sw/lib/source/neorv32_slink.c
87,7 → 87,7
int neorv32_slink_get_rx_num(void) {
 
if (neorv32_slink_available()) {
return (int)(((SLINK_CT >> SLINK_CT_RX_NUM0) & 0x07) + 1);
return (int)((SLINK_CT >> SLINK_CT_RX_NUM0) & 0xf);
}
else {
return 0;
103,7 → 103,7
int neorv32_slink_get_tx_num(void) {
 
if (neorv32_slink_available()) {
return (int)(((SLINK_CT >> SLINK_CT_TX_NUM0) & 0x07) + 1);
return (int)((SLINK_CT >> SLINK_CT_TX_NUM0) & 0xf);
}
else {
return 0;
146,6 → 146,44
 
 
/**********************************************************************//**
* Check if RX link FIFO fill level is >= half-full
*
* @param[in] link_id Link id (0..7).
* @return 1 if fill level is >= half-full.
**************************************************************************/
int neorv32_slink_check_rx_half_full(int link_id) {
 
const uint32_t mask = 1 << SLINK_STATUS_RX0_HALF;
 
if (SLINK_STATUS & (mask << (link_id & 0x7))) {
return 1;
}
else {
return 0;
}
}
 
 
/**********************************************************************//**
* Check if TX link FIFO fill level is > half-full
*
* @param[in] link_id Link id (0..7).
* @return 1 if fill level is > half-full.
**************************************************************************/
int neorv32_slink_check_tx_half_full(int link_id) {
 
const uint32_t mask = 1 << SLINK_STATUS_TX0_HALF;
 
if (SLINK_STATUS & (mask << (link_id & 0x7))) {
return 1;
}
else {
return 0;
}
}
 
 
/**********************************************************************//**
* Write data to TX stream link 0 (non-blocking)
*
* @param[in] tx_data Data to send to link.
153,7 → 191,7
**************************************************************************/
int neorv32_slink_tx0_nonblocking(uint32_t tx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_TX0_FREE)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_TX0_FREE)) {
SLINK_CH0 = tx_data;
return 0;
}
169,7 → 207,7
**************************************************************************/
int neorv32_slink_tx1_nonblocking(uint32_t tx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_TX1_FREE)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_TX1_FREE)) {
SLINK_CH1 = tx_data;
return 0;
}
185,7 → 223,7
**************************************************************************/
int neorv32_slink_tx2_nonblocking(uint32_t tx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_TX2_FREE)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_TX2_FREE)) {
SLINK_CH2 = tx_data;
return 0;
}
201,7 → 239,7
**************************************************************************/
int neorv32_slink_tx3_nonblocking(uint32_t tx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_TX3_FREE)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_TX3_FREE)) {
SLINK_CH3 = tx_data;
return 0;
}
217,7 → 255,7
**************************************************************************/
int neorv32_slink_tx4_nonblocking(uint32_t tx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_TX4_FREE)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_TX4_FREE)) {
SLINK_CH4 = tx_data;
return 0;
}
233,7 → 271,7
**************************************************************************/
int neorv32_slink_tx5_nonblocking(uint32_t tx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_TX5_FREE)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_TX5_FREE)) {
SLINK_CH5 = tx_data;
return 0;
}
249,7 → 287,7
**************************************************************************/
int neorv32_slink_tx6_nonblocking(uint32_t tx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_TX6_FREE)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_TX6_FREE)) {
SLINK_CH6 = tx_data;
return 0;
}
265,7 → 303,7
**************************************************************************/
int neorv32_slink_tx7_nonblocking(uint32_t tx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_TX7_FREE)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_TX7_FREE)) {
SLINK_CH7 = tx_data;
return 0;
}
281,7 → 319,7
**************************************************************************/
int neorv32_slink_rx0_nonblocking(uint32_t *rx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_RX0_AVAIL)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_RX0_AVAIL)) {
*rx_data = SLINK_CH0;
return 0;
}
297,7 → 335,7
**************************************************************************/
int neorv32_slink_rx1_nonblocking(uint32_t *rx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_RX1_AVAIL)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_RX1_AVAIL)) {
*rx_data = SLINK_CH1;
return 0;
}
313,7 → 351,7
**************************************************************************/
int neorv32_slink_rx2_nonblocking(uint32_t *rx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_RX2_AVAIL)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_RX2_AVAIL)) {
*rx_data = SLINK_CH2;
return 0;
}
329,7 → 367,7
**************************************************************************/
int neorv32_slink_rx3_nonblocking(uint32_t *rx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_RX3_AVAIL)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_RX3_AVAIL)) {
*rx_data = SLINK_CH3;
return 0;
}
345,7 → 383,7
**************************************************************************/
int neorv32_slink_rx4_nonblocking(uint32_t *rx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_RX4_AVAIL)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_RX4_AVAIL)) {
*rx_data = SLINK_CH4;
return 0;
}
361,7 → 399,7
**************************************************************************/
int neorv32_slink_rx5_nonblocking(uint32_t *rx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_RX5_AVAIL)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_RX5_AVAIL)) {
*rx_data = SLINK_CH5;
return 0;
}
377,7 → 415,7
**************************************************************************/
int neorv32_slink_rx6_nonblocking(uint32_t *rx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_RX6_AVAIL)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_RX6_AVAIL)) {
*rx_data = SLINK_CH6;
return 0;
}
393,7 → 431,7
**************************************************************************/
int neorv32_slink_rx7_nonblocking(uint32_t *rx_data) {
 
if (SLINK_CT & (1 << SLINK_CT_RX7_AVAIL)) {
if (SLINK_STATUS & (1 << SLINK_STATUS_RX7_AVAIL)) {
*rx_data = SLINK_CH7;
return 0;
}
/trunk/sw/ocd-firmware/makefile
52,7 → 52,7
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
RISCV_PREFIX ?= riscv32-unknown-elf-
 
# CPU architecture and ABI
MARCH = -march=rv32i
105,10 → 105,10
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
CC = $(RISCV_PREFIX)gcc
OBJDUMP = $(RISCV_PREFIX)objdump
OBJCOPY = $(RISCV_PREFIX)objcopy
SIZE = $(RISCV_PREFIX)size
 
# Host native compiler
CC_X86 = g++ -Wall -O -g
/trunk/sw/ocd-firmware/park_loop.S
1,5 → 1,5
/* ################################################################################################# */
/* # << NEORV32 - debugger.S - Execution-Based On-Chip Debugger - Park Loop Code >> # */
/* # << NEORV32 - park_loop.S - Execution-Based On-Chip Debugger - Park Loop Code >> # */
/* # ********************************************************************************************* # */
/* # BSD 3-Clause License # */
/* # # */
57,7 → 57,7
 
_start:
 
// BASE + 0: entry for ebreak in debug-mode, halt request, or return from single-stepped instruction
// BASE + 0: entry for ebreak in debug-mode, halt request or return from single-stepped instruction
entry_normal:
jal zero, parking_loop_start
 
/trunk/sw/README.md
1,27 → 1,50
## NEORV32 Software Framework
# NEORV32 Software Framework
 
This folder provides the core of the NEORV32 software framework. This is a short description of the main folders.
This folder provides the core of the NEORV32 software framework.
This is a short description of the main folders.
 
### [`bootloader`](https://github.com/stnolting/neorv32/tree/master/sw/bootloader)
 
Source(s) of the default NEORV32 bootloader. A pre-built image is already installed into the rtl design via the
`rtl/core/neorv32_bootloader_image.vhd` file.
## [bootloader](bootloader)
 
### [`common`](https://github.com/stnolting/neorv32/tree/master/sw/common)
Source(s) of the default NEORV32 bootloader.
A pre-built image is already installed into the rtl design via the `rtl/core/neorv32_bootloader_image.vhd` file.
 
NEORV32-specific common files for all bootloader and application programs: linker script for executable generation and
processor start-up code.
 
### [`example`](https://github.com/stnolting/neorv32/tree/master/sw/example)
## [common](common)
 
NEORV32-specific common files for all bootloader and application programs:
linker script for executable generation and processor start-up code.
 
 
## [example](example)
 
Several example programs for testing and for getting started.
 
### [`image_gen`](https://github.com/stnolting/neorv32/tree/master/sw/image_gen)
 
This folder contains a simple program that is used to create NEORV32 executables (for upload via bootloader) and VHDL memory
initializiation files (for memory-persistent applications and for the bootloader). This program is automatically compiled using
the native GCC when invoking one of the application compilation makefiles.
## [image_gen](image_gen)
 
### [`lib`](https://github.com/stnolting/neorv32/tree/master/sw/lib)
This folder contains a simple program that is used to create NEORV32 executables (for upload via bootloader) and VHDL
memory initializiation files (for memory-persistent applications and for the bootloader).
This program is automatically compiled using the native GCC when invoking one of the application compilation makefiles.
 
 
## [isa-test](isa-test)
 
NEORV32 RISC-V Architecture Test Framework.
See [sim/README](../sim/README.md).
 
 
## [lib](lib)
 
Core libraries (sources and header files) and helper functions for using the processor peripherals and the CPU itself.
 
 
## [ocd-firmware](ocd-firmware)
 
Firmware (debugger "park loop") for the on-chip debugger. This folder is just for documenting the source code.
Modifying the sources is not recommended as this could break the on-chip debugger.
 
 
## [openocd](openocd)
 
Configuration file for openOCD to connect to the NEORV32 on-chip debugger via JTAG.
/trunk/.gitignore
4,6 → 4,7
*.elf
*.asm
*.out
*.hex
*_image.vhd
 
# keep default VHDL memory images
29,3 → 30,8
 
# example bitstreams
/setups/examples/*.bit
/setups/examples/*.svf
 
# riscv-arch-test
 
/sim/work/
/trunk/.gitmodules
1,3 → 1,3
[submodule "riscv-arch-test/work/riscv-arch-test"]
path = riscv-arch-test/work/riscv-arch-test
path = sw/isa-test/riscv-arch-test
url = https://github.com/riscv/riscv-arch-test.git
/trunk/CHANGELOG.md
6,9 → 6,10
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: To see a list of all commits between releases run `git log RELEASE_A..RELEASE_B` (example: `v1.4.7.0..v1.4.8.0`).
: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 addtional custom version element (i.e. `MAJOR.MINOR.PATCH.individual`) to track individual changes.
 
:information_source: The processor can determine it's version from the `mimpid` CSR (at CSR address 0xf13). A 8x4-bit BCD representation is used.
:information_source: The processor can determine its version from the `mimpid` CSR (at CSR address 0xf13). A 8x4-bit BCD representation is used.
Leading zeros are optional. Example: `CSR(mimpid) = 0x01040312 => 01.04.03.12 = Version 01.04.03.12 = v1.4.3.12`. The version number is globally
defined by the `hw_version_c` constant in the main VHDL package file [`rtl/core/neorv32_package.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_package.vhd).
 
24,7 → 25,24
 
| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
| 03.07.2021 | 1.5.7.10 | :sparkles: added new component: External Interrupt Controller (XIRQ): up to 32 external interrupt channels `xirq_i` (via `XIRQ_NUM_CH` generic), configurable trigger (via `XIRQ_TRIGGER_TYPE` and `XIRQ_TRIGGER_POLARITY` generics), prioritized or non-prioritized servicing |
| 13.08.2021 | [**:rocket:1.5.9**](https://github.com/stnolting/neorv32/releases/tag/v1.5.9) | **New release** |
| 08.08.2021 | 1.5.8.9 | reworked CPU register file logic: any write access to `x0` will be masked to actually write zero - no special treatment by the CPU control unit required anymore; slighlty less hardware ressources required; first instruction after hardware reset should write `x0` (_any_ value; implemented in start-up code `crt0.S`) |
| 07.08.2021 | 1.5.8.8 | :bug: fixed bug in execution (trapping) of `xRET` instructions: `dret` (return from debug-mode handler) has to raise an illegal instruction exception if executed outside of debug-mode, `mret` (return from machine-mode handler) has to raise an illegal instruction exception if executed in lower-privileged modes (lower than machine-mode) |
| 05.08.2021 | 1.5.8.7 | :sparkles: added `mstatus.FS` and `mstatus.SD` CSR bits: control the state of the FPU (`Zfinx`) extension; supported states for `mstatus.FS`: `00` = _off_, `11` = _dirty_; writing other states will always set _dirty_ state; note that all FPU instructions including FPU CSR access instructions will raise an illegal instrution exception if `mstatus.FS` = _off_ |
| 03.08.2021 | 1.5.8.6 | :bug: fixed bug in linker script [#134](https://github.com/stnolting/neorv32/issues/134): `.rodata.*` "sub"-sections were missing, caused wrong linking of implicit constants (like strings); added `mconfigptr` CSR (RISC-V priv. ISA spec. v1.12-draft ;read-only): holds a pointer to a platfrom/system configuration structure - not actually used yet |
| 30.07.2021 | 1.5.8.5 | fixed minor bug in top entity / AXI4 wrapper (Vivado "issue": generic defaults need a _fixed-size_ intialization value) [#113](https://github.com/stnolting/neorv32/issues/133) |
| 26.07.2021 | 1.5.8.4 | :bug: **fixed major bug in CPU interrupt system**: interrupts during memory accesses (load/store instruction) terminated those memory accesses violating the crucial "instruction atomicity" concept: traps (interrupts and exceptions) must only intervent _between_ instructions |
| 25.07.2021 | 1.5.8.3 | :sparkles: added `mstauts.TW` CSR flag (when set executing `wfi` instruction outside of machine-mode will raise an illegal instruction exception); flag is hardwired to zero if user mode is not implemented |
| 25.07.2021 | 1.5.8.2 | :bug: fixed bug in `E` ISA extension: extension could not be enabled due to missing generic propagation; clean-up of generic defaults: only the processor top entity provides defaults for the configuration generics |
| 24.07.2021 | 1.5.8.1 | machine-level interrupts (top entity signals; "external" `mext_irq_i`, "software" `msw_irq_i`, "mtime" `mtime_irq_i` and "non-maskable" `nm_irq_i`) now trigger on rising edges; exposed advanced external bus interface configuration options as new top entity generics (moved from package constants): `MEM_EXT_PIPE_MODE`, `MEM_EXT_BIG_ENDIAN`, `MEM_EXT_ASYNC_RX` |
| 22.07.2021 | [**:rocket:1.5.8**](https://github.com/stnolting/neorv32/releases/tag/v1.5.8) | **New release** |
| 22.07.2021 | 1.5.7.16 | (re-)added `mstatush` CSR (all bits are hardwired to zero: writes are ignored, reads will always return zero) - CSR address is assigned to comply with RISC-V priv. arch. spec. 1.12 |
| 21.07.2021 | 1.5.7.15 | :bug: fixed minor bug in SLINK module (signals were missing in sensitivity lists); :warning: simplified NEOLED interrupt system (now triggered if TX FIFO fill level falls below half-full), added option to send LED strobe command ("RESET"), added FIFO status signals to status register, simplified FIFO access logic, added new top generic `IO_NEOLED_TX_FIFO` to configure NEOLED FIFO depth |
| 18.07.2021 | 1.5.7.14 | exposed new generic `CPU_IPB_ENTRIES` to configure size of CPU instruction prefetch buffer |
| 18.07.2021 | 1.5.7.13 | clean-up of processor top entity: using more sophisticated default values for all input signals and generics (all generics are "off" by default; input signals use `L` for control lines and `U` for data lines by default) |
| 14.07.2021 | 1.5.7.12 | reworked SLINK interrupt concept (now using FIFO fill level "half-full" as interrupt condition, see [#122](https://github.com/stnolting/neorv32/issues/122)); added fill level output to processor FIFO component |
| 09.07.2021 | 1.5.7.11 | :bug: fixed minor bug in FIFO component (mapping might fail if `FIFO_DEPTH` = 1); fixed broken `sw/example/demo_freeRTOS` makefile (all freeRTOS includes were missing) |
| 03.07.2021 | 1.5.7.10 | :sparkles: added new component: **External Interrupt Controller (XIRQ)**: up to 32 external interrupt channels `xirq_i` (via `XIRQ_NUM_CH` generic), configurable trigger (via `XIRQ_TRIGGER_TYPE` and `XIRQ_TRIGGER_POLARITY` generics), prioritized or non-prioritized servicing |
| 02.07.2021 | 1.5.7.9 | relocated base addresses of watchdog timer (WDT) and true-random number generator (TRNG); removed CPU's `firq_ack_o` signal (was not used at all) |
| 30.06.2021 | 1.5.7.8 | :warning: increased GPIO port size from 32-bit to 64-bit; relocated GPIO base address; removed GPIO.input pin-change interrupt |
| 29.06.2021 | 1.5.7.7 | :sparkles: added new processor module **stream link interface (SLINK)**: up to 8 individual RX and TX stream links, comptaible to AXI4-Stream base protocol; added software driver files; added documentation |
33,7 → 51,7
| 27.06.2021 | 1.5.7.4 | :warning: removed top's fast IRQ (FIRQ) inputs `soc_firq_i`: the FIRQs are reserved for processor-internal usage only, use the `mext_irq_i` RISC-V external interrupt signal for all external interrupt applications (via dedicated interrupt conttoller), a follow-up version of the project will introduce a customizable external interrupt controller; sourced-out FIFOs into new HDL component `neorv32_fifo.vhd` |
| 26.06.2021 | 1.5.7.3 | edit of v1.5.7.2: RISC-V spec claims to leave destination registers of trapping load operation unchanged (do _not_ set to zero); minor CPU control logic optimizations; :sparkles: reworked bootloader to provide several new configuration and customization options |
| 25.06.2021 | 1.5.7.2 | optimized instruction execution FSM: less hardware utilization, :lock: now _ensures_ to write ZERO to destination register if there is an exception during a load operation; made default bootloader even more HW configuration independent (GPIO, SPI and MTIME are optional; UART is optional but highly recommended); |
| 24.06.2021 | 1.5.7.1 | sparkles: added RISC-V `Zmmul` ISA extension (via `CPU_EXTENSION_RISCV_Zmmul` generic; default = _false_): implements only the integer multiplication instructions sub-set of the `M` extension; for size-constrained setups, requires ~50% less hardware ressources than the `M` extension |
| 24.06.2021 | 1.5.7.1 | :sparkles: added RISC-V `Zmmul` ISA extension (via `CPU_EXTENSION_RISCV_Zmmul` generic; default = _false_): implements only the integer multiplication instructions sub-set of the `M` extension; for size-constrained setups, requires ~50% less hardware ressources than the `M` extension |
| 23.06.2021 | [**:rocket:1.5.7**](https://github.com/stnolting/neorv32/releases/tag/v1.5.7) | **New release** _one year NEORV32!_ :tada: |
| 21.06.2021 | 1.5.6.14 | :bug: fixed bug in debugger "park loop": `fence.i` instruction was missing before executing the DM's program buffer - this caused execution of outdated instructions from the program buffer if the **instruction cache** is implemented |
| 21.06.2021 | 1.5.6.13 | removed `TINY_SHIFT_EN` generic; clean-up of CPU co-processor system: removed "dummy co-processor" for CSR read access, moved CPU shifter core into new co-processor; simplified default (bit-serial) shifter logic (single bit-shifts only) and multi-cycl instructions decode logic |
/trunk/README.md
1,6 → 1,6
[![GitHub Pages](https://img.shields.io/website.svg?label=stnolting.github.io%2Fneorv32&longCache=true&style=flat-square&url=http%3A%2F%2Fstnolting.github.io%2Fneorv32%2Findex.html&logo=GitHub)](https://stnolting.github.io/neorv32)
[![Documentation](https://img.shields.io/github/workflow/status/stnolting/neorv32/Documentation/master?longCache=true&style=flat-square&label=Documentation&logo=Github%20Actions&logoColor=fff)](https://github.com/stnolting/neorv32/actions?query=workflow%3ADocumentation)
 
\
[![riscv-arch-test](https://img.shields.io/github/workflow/status/stnolting/neorv32/riscv-arch-test/master?longCache=true&style=flat-square&label=riscv-arch-test&logo=Github%20Actions&logoColor=fff)](https://github.com/stnolting/neorv32/actions?query=workflow%3Ariscv-arch-test)
[![Processor](https://img.shields.io/github/workflow/status/stnolting/neorv32/Processor/master?longCache=true&style=flat-square&label=Processor&logo=Github%20Actions&logoColor=fff)](https://github.com/stnolting/neorv32/actions?query=workflow%3AProcessor)
[![Implementation](https://img.shields.io/github/workflow/status/stnolting/neorv32/Implementation/master?longCache=true&style=flat-square&label=Implementation&logo=Github%20Actions&logoColor=fff)](https://github.com/stnolting/neorv32/actions?query=workflow%3AImplementation)
12,6 → 12,8
 
[![license](https://img.shields.io/github/license/stnolting/neorv32?longCache=true&style=flat-square)](https://github.com/stnolting/neorv32/blob/master/LICENSE)
[![release](https://img.shields.io/github/v/release/stnolting/neorv32?longCache=true&style=flat-square&logo=GitHub)](https://github.com/stnolting/neorv32/releases)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.5121427.svg)](https://doi.org/10.5281/zenodo.5121427)
 
[![datasheet (pdf)](https://img.shields.io/badge/data%20sheet-PDF-ffbd00?longCache=true&style=flat-square&logo=asciidoctor)](https://github.com/stnolting/neorv32/releases/tag/nightly)
[![datasheet (html)](https://img.shields.io/badge/-HTML-ffbd00?longCache=true&style=flat-square)](https://stnolting.github.io/neorv32)
[![userguide (pdf)](https://img.shields.io/badge/user%20guide-PDF-ffbd00?longCache=true&style=flat-square&logo=asciidoctor)](https://github.com/stnolting/neorv32/releases/tag/nightly)
54,7 → 56,8
**TODOs**, features being **planned** and **work-in-progress**.
 
:bulb: Feel free to open a [new issue](https://github.com/stnolting/neorv32/issues) or start a
[new discussion](https://github.com/stnolting/neorv32/discussions) if you have questions, comments, ideas or bug-fixes.
[new discussion](https://github.com/stnolting/neorv32/discussions) if you have questions, comments, ideas or if something is
not working as expected.
Check out how to contribute in [`CONTRIBUTE.md`](https://github.com/stnolting/neorv32/blob/master/CONTRIBUTING.md).
 
:rocket: Check out the [quick links below](#Getting-Started) or directly jump to the
141,8 → 144,9
 
The hardware resources used by a specifc processor setup is defined by the implemented CPU extensions
([see below](#FPGA-Implementation-Results---CPU)), the configuration of the peripheral modules and some "glue logic".
Section [_"Processor Modules"_](https://stnolting.github.io/neorv32/#_processor_modules) of the online datasheet shows
the ressource utilization of each optional processor module to estimate the actual setup's hardware requirements.
Section [_"FPGA Implementation Results - Processor Modules"_](https://stnolting.github.io/neorv32/#_processor_modules)
of the online datasheet shows the ressource utilization of each optional processor module to allow an
estimation of the actual setup's hardware requirements.
 
:information_source: The [`setups`](https://github.com/stnolting/neorv32/tree/master/setups) folder provides exemplary FPGA
setups targeting various FPGA boards and toolchains. These setups also provide ressource utilization reports for different
162,14 → 166,14
*Unprivileged ISA Specification* [(Version 2.2)](https://github.com/stnolting/neorv32/blob/master/docs/references/riscv-spec.pdf)
and a subset of the *Privileged Architecture Specification* [(Version 1.12-draft)](https://github.com/stnolting/neorv32/blob/master/docs/references/riscv-privileged.pdf).
Compatiility is checked by passing the [official RISC-V architecture tests](https://github.com/riscv/riscv-arch-test)
(see [`riscv-arch-test/README`](https://github.com/stnolting/neorv32/blob/master/riscv-arch-test/README.md)).
(see [`sim/README`](sim/README.md)).
 
The core implements a little-endian von-Neumann architecture using two pipeline stages. Each stage uses a multi-cycle processing
scheme. The CPU supports three privilege levels (`machine` and optional `user` and `debug_mode`), three standard RISC-V machine
interrupts (`MTI`, `MEI`, `MSI`), a single non-maskable interrupt plus 16 _fast interrupt requests_ as custom extensions.
It also supports **all** standard RISC-V exceptions (instruction/load/store misaligned address & bus access fault, illegal
instruction, breakpoint, environment call). As a special "execution safety" extension, _all_ invalid, reserved or
malformed instructions will raise an exception.
instruction, breakpoint, environment call)
(see :books: [_"Full Virtualization"_](https://stnolting.github.io/neorv32/#_full_virtualization)).
 
 
### Available ISA Extensions
200,22 → 204,24
 
### FPGA Implementation Results - CPU
 
:books: More details regarding exemplary FPGA setups including a list of resource utilization by each SoC module can be found in the
[online documentation - _"FPGA Implementation Results"_](https://stnolting.github.io/neorv32/#_fpga_implementation_results).
 
Implementation results for exemplary CPU configuration generated for an **Intel Cyclone IV EP4CE22F17C6N FPGA**
Implementation results for _exemplary_ CPU configuration generated for an **Intel Cyclone IV EP4CE22F17C6N FPGA**
using **Intel Quartus Prime Lite 20.1** ("balanced implementation"). The timing information is derived
from the Timing Analyzer / Slow 1200mV 0C Model. No constraints were used at all.
 
Results generated for hardware version [`1.5.3.2`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
Results generated for hardware version [`1.5.7.10`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
 
| CPU Configuration | LEs | FFs | Memory bits | DSPs (9-bit) | f_max |
|:--------------------------------------------------|:----:|:----:|:-----------:|:------------:|:-------:|
| `rv32i` | 980 | 409 | 1024 | 0 | 125 MHz |
| `rv32i` + `Zicsr` | 1835 | 856 | 1024 | 0 | 125 MHz |
| `rv32imac` + `Zicsr` | 2685 | 1156 | 1024 | 0 | 125 MHz |
| `rv32imac` + `Zicsr` + `u` + `Zifencei` + `Zfinx` | 4004 | 1812 | 1024 | 7 | 118 MHz |
| `rv32i` | 806 | 359 | 1024 | 0 | 125 MHz |
| `rv32i_Zicsr` | 1729 | 813 | 1024 | 0 | 124 MHz |
| `rv32imac_Zicsr` | 2511 | 1074 | 1024 | 0 | 124 MHz |
 
:information_source: An incrmental list of CPU exntension's hardware utilization can found in
[online documentation - _"FPGA Implementation Results - CPU"_](https://stnolting.github.io/neorv32/#_cpu).
 
:information_source: The CPU provides options to further reduce the footprint (for example by constraining
the CPU-internal counters). See the [online data](https://stnolting.github.io/neorv32) sheet for more information.
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
226,9 → 232,9
The average CPI (cycles per instruction) depends on the instruction mix of a specific applications and also on the
available CPU extensions.
 
The following table shows the performance results(relative CoreMark score and average cycles per instruction) for successfully
running 2000 iterations of the [CoreMark CPU benchmark](https://www.eembc.org/coremark).
The source files are available in [sw/example/coremark](https://github.com/stnolting/neorv32/blob/master/sw/example/coremark).
The following table shows the performance results (relative CoreMark score and average cycles per instruction) for
_exemplary_ CPU configuration running 2000 iterations of the [CoreMark CPU benchmark](https://www.eembc.org/coremark).
The source files are available in [`sw/example/coremark`](https://github.com/stnolting/neorv32/blob/master/sw/example/coremark).
 
~~~
**CoreMark Setup**
238,16 → 244,16
Compiler flags: default, see makefile; optimization -O3
~~~
 
Results generated for hardware version [`1.4.9.8`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
Results generated for hardware version [`1.5.7.10`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
 
| CPU (including `Zicsr` extension) | Executable Size | CoreMark Score | CoreMarks/MHz | Total Clock Cycles | Executed Instructions | Average CPI |
|:--------------------------------------------|:---------------:|:--------------:|:-------------:|-------------------:|----------------------:|:-----------:|
| `rv32i` | 28 756 bytes | 36.36 | **0.3636** | 5595750503 | 1466028607 | **3.82** |
| `rv32imc` | 22 008 bytes | 68.97 | **0.6897** | 2981786734 | 611814918 | **4.87** |
| `rv32imc` + `FAST_MUL_EN` + `FAST_SHIFT_EN` | 22 008 bytes | 90.91 | **0.9091** | 2265135174 | 611814948 | **3.70** |
| CPU Configuration | CoreMark Score | CoreMarks/MHz | Average CPI |
|:-----------------------------------------------|:--------------:|:-------------:|:-----------:|
| _small_ (`rv32i_Zicsr`) | 33.89 | **0.3389** | **4.04** |
| _medium_ (`rv32imc_Zicsr`) | 62.50 | **0.6250** | **5.34** |
| _performance_(`rv32imc_Zicsr` + perf. options) | 95.23 | **0.9523** | **3.54** |
 
:information_source: The `FAST_MUL_EN` configuration uses DSPs for the multiplier of the `M` extension.
The `FAST_SHIFT_EN` configuration uses a barrel shifter for CPU shift operations.
:information_source: More information regarding the CPU performance can be found in the
[online documentation - _"CPU Performance"_](https://stnolting.github.io/neorv32/#_cpu_performance).
 
[[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.