mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-24 06:07:52 -04:00
Merge pull request #190 from stnolting/bit_manipulation_zba
[B ISA Extension] Rework and addition of Zba subset
This commit is contained in:
commit
9d5fe55b63
25 changed files with 416 additions and 196 deletions
|
@ -26,6 +26,7 @@ defined by the `hw_version_c` constant in the main VHDL package file [`rtl/core/
|
|||
|
||||
| Date (*dd.mm.yyyy*) | Version | Comment |
|
||||
|:----------:|:-------:|:--------|
|
||||
| 28.10.2021 | 1.6.2.11 | :sparkles: added `Zba` bit-manipulation sub-extension; :warning: removed configuration option for `B` sub-extensions: removed `CPU_EXTENSION_RISCV_Zbb` generic and according SYSINFO flag, added new `CPU_EXTENSION_RISCV_B` generic (to implement bit-manipulation `B` ISA extension with _all_ currently supported subsets), see [PR #190](https://github.com/stnolting/neorv32/pull/190) |
|
||||
| 27.10.2021 | 1.6.2.10 | :bug: CPU control unit: fixed _imprecise_ illegal instruction exceptions - `MEPC` and `MTAVL` did not reflect the correct exception-causing data for illegal ALU-class (non-multi-cycle like `SUB`) operations; optimized critical path of exception logic (illegal compressed instruction detection) |
|
||||
| 27.10.2021 | 1.6.2.9 | CPU control unit: minor logic optimization - `fence.i` instruction needs 1 cycle less to execute, reduced HW footprint of control engine, shortened CPU's critical path (PC update logic) |
|
||||
| 26.10.2021 | 1.6.2.8 | :bug: bootloader: fixed bug in stack pointer initialization (introduced in version `1.6.2.7`); minor SPI unit VHDL code clean-up |
|
||||
|
|
|
@ -192,11 +192,11 @@ documentation section). Note that the `X` extension is always enabled.
|
|||
[[`I`](https://stnolting.github.io/neorv32/#_i_base_integer_isa)/
|
||||
[`E`](https://stnolting.github.io/neorv32/#_e_embedded_cpu)]
|
||||
[[`A`](https://stnolting.github.io/neorv32/#_a_atomic_memory_access)]
|
||||
[[`B`](https://stnolting.github.io/neorv32/#_b_bit_manipulation_operations)]
|
||||
[[`C`](https://stnolting.github.io/neorv32/#_c_compressed_instructions)]
|
||||
[[`M`](https://stnolting.github.io/neorv32/#_m_integer_multiplication_and_division)]
|
||||
[[`U`](https://stnolting.github.io/neorv32/#_u_less_privileged_user_mode)]
|
||||
[[`X`](https://stnolting.github.io/neorv32/#_x_neorv32_specific_custom_extensions)]
|
||||
[[`Zbb`](https://stnolting.github.io/neorv32/#_zbb_basic_bit_manipulation_operations)]
|
||||
[[`Zfinx`](https://stnolting.github.io/neorv32/#_zfinx_single_precision_floating_point_operations)]
|
||||
[[`Zicsr`](https://stnolting.github.io/neorv32/#_zicsr_control_and_status_register_access_privileged_architecture)]
|
||||
[[`Zifencei`](https://stnolting.github.io/neorv32/#_zifencei_instruction_stream_synchronization)]
|
||||
|
@ -205,7 +205,7 @@ documentation section). Note that the `X` extension is always enabled.
|
|||
[[`HPM`](https://stnolting.github.io/neorv32/#_hpm_hardware_performance_monitors)]
|
||||
[[`DEBUG`](https://stnolting.github.io/neorv32/#_cpu_debug_mode)]**
|
||||
|
||||
:warning: The `Zbb`, `Zfinx` and `Zmmul` RISC-V extensions are frozen but not officially ratified yet. Hence, there is no
|
||||
:warning: The `B`, `Zfinx` and `Zmmul` RISC-V extensions are frozen but not officially ratified yet. Hence, there is no
|
||||
upstream gcc support. To circumvent this, the NEORV32 software framework provides _intrinsic_ libraries for these extensions.
|
||||
|
||||
[[back to top](#The-NEORV32-RISC-V-Processor)]
|
||||
|
|
|
@ -8,12 +8,12 @@ image::riscv_logo.png[width=350,align=center]
|
|||
* 32-bit multi-cycle in-order `rv32` RISC-V CPU
|
||||
* Optional RISC-V extensions:
|
||||
** `A` - atomic memory access operations
|
||||
** `B` - bit-manipulation instructions
|
||||
** `C` - 16-bit compressed instructions
|
||||
** `I` - integer base ISA (always enabled)
|
||||
** `E` - embedded CPU version (reduced register file size)
|
||||
** `M` - integer multiplication and division hardware
|
||||
** `U` - less-privileged _user_ mode
|
||||
** `Zbb` - basic bit-manipulation operations
|
||||
** `Zfinx` - single-precision floating-point unit
|
||||
** `Zicsr` - control and status register access (privileged architecture)
|
||||
** `Zifencei` - instruction stream synchronization
|
||||
|
@ -268,6 +268,11 @@ only supports the modes _OFF_ and _NAPOT_ yet and a minimal granularity of 8 byt
|
|||
The `A` CPU extension only implements the `lr.w` and `sc.w` instructions yet.
|
||||
However, these instructions are sufficient to emulate all further atomic memory operations.
|
||||
|
||||
.Bit-manipulation operations
|
||||
[IMPORTANT]
|
||||
The NEORV32 `B` extension only implements the _basic bit-manipulation instructions_ (`Zbb`) subset
|
||||
and the _address generation instructions_ (`Zba`) subset yet.
|
||||
|
||||
.Instruction Misalignment
|
||||
[NOTE]
|
||||
This is not a real RISC-V incompatibility, but something that might not be clear when studying the RISC-V privileged
|
||||
|
@ -276,7 +281,6 @@ is raised if bit 1 of the access address is set (i.e. not on 32-bit boundary). I
|
|||
there will be no misaligned instruction exceptions _at all_.
|
||||
In both cases bit 0 of the program counter and all related registers is hardwired to zero.
|
||||
|
||||
|
||||
<<<
|
||||
// ####################################################################################################################
|
||||
:sectnums:
|
||||
|
@ -417,6 +421,42 @@ The atomic instructions have special requirements for memory system / bus interc
|
|||
information can be found in sections <<_bus_interface>> and <<_processor_external_memory_interface_wishbone_axi4_lite>>, respectively.
|
||||
|
||||
|
||||
==== **`B`** - Bit-Manipulation Operations
|
||||
|
||||
The `B` ISA extension adds instructions for bit-manipulation operations. This extension is enabled if the
|
||||
`CPU_EXTENSION_RISCV_B` configuration generic is _true_.
|
||||
The official RISC-V specifications can be found here: https://github.com/riscv/riscv-bitmanip
|
||||
|
||||
[IMPORTANT]
|
||||
The NEORV32 `B` extension only implements the _basic bit-manipulation instructions_ (`Zbb`) subset
|
||||
and the _address generation instructions_ (`Zba`) subset yet.
|
||||
|
||||
The `Zbb` sub-extension adds the following instruction:
|
||||
|
||||
* `andn`, `orn`, `xnor`
|
||||
* `clz`, `ctz`, `cpop`
|
||||
* `max`, `maxu`, `min`, `minu`
|
||||
* `sext.b`, `sext.h`, `zext.h`
|
||||
* `rol`, `ror`, `rori`
|
||||
* `orc.b`, `rev8`
|
||||
|
||||
The `Zba` sub-extension adds the following instruction:
|
||||
|
||||
* `sh1add`, `sh2add`, `sh3add`
|
||||
|
||||
[TIP]
|
||||
By default, the bit-manipulation unit uses an _iterative_ approach to compute shift-related operations
|
||||
like `clz` and `rol`. To increase performance (at the cost of additional hardware resources) the
|
||||
<<_fast_shift_en>> generic can be enabled to implement full-parallel logic (like barrel shifters) for all
|
||||
shift-related `B` instructions.
|
||||
|
||||
[WARNING]
|
||||
The `B` extension is frozen but not officially ratified yet. There is no
|
||||
software support for this extension in the upstream GCC RISC-V port yet. However, an
|
||||
intrinsic library is provided to utilize the provided `B` extension features from C-language
|
||||
code (see `sw/example/bitmanip_test`).
|
||||
|
||||
|
||||
==== **`C`** - Compressed Instructions
|
||||
|
||||
The _compressed_ ISA extension provides 16-bit encodings of commonly used instructions to reduce code space size.
|
||||
|
@ -566,34 +606,6 @@ intrinsic library is provided to utilize the provided `Zfinx` floating-point ext
|
|||
code (see `sw/example/floating_point_test`).
|
||||
|
||||
|
||||
==== **`Zbb`** Basic Bit-Manipulation Operations
|
||||
|
||||
The `Zbb` extension implements the _basic_ sub-set of the RISC-V bit-manipulation extensions `B`.
|
||||
The official RISC-V specifications can be found here: https://github.com/riscv/riscv-bitmanip
|
||||
|
||||
The `Zbb` extension is implemented when the `CPU_EXTENSION_RISCV_Zbb` configuration
|
||||
generic is _true_. In this case the following instructions are available:
|
||||
|
||||
* `andn`, `orn`, `xnor`
|
||||
* `clz`, `ctz`, `cpop`
|
||||
* `max`, `maxu`, `min`, `minu`
|
||||
* `sext.b`, `sext.h`, `zext.h`
|
||||
* `rol`, `ror`, `rori`
|
||||
* `orc.b`, `rev8`
|
||||
|
||||
[TIP]
|
||||
By default, the bit-manipulation unit uses an _iterative_ approach to compute shift-related operations
|
||||
like `clz` and `rol`. To increase performance (at the cost of additional hardware resources) the
|
||||
<<_fast_shift_en>> generic can be enabled to implement full-parallel logic (like barrel shifters) for all
|
||||
shift-related `Zbb` instructions.
|
||||
|
||||
[WARNING]
|
||||
The `Zbb` extension is frozen but not officially ratified yet. There is no
|
||||
software support for this extension in the upstream GCC RISC-V port yet. However, an
|
||||
intrinsic library is provided to utilize the provided `Zbb` extension from C-language
|
||||
code (see `sw/example/bitmanip_test`).
|
||||
|
||||
|
||||
==== **`Zicsr`** Control and Status Register Access / Privileged Architecture
|
||||
|
||||
The CSR access instructions as well as the exception and interrupt system (= the privileged architecture)
|
||||
|
@ -759,12 +771,6 @@ configurations are presented in <<_cpu_performance>>.
|
|||
| Memory access | `A` | `lr.w` `sc.w` | 4 + ML
|
||||
| Multiplication | `M` | `mul` `mulh` `mulhsu` `mulhu` | 2+31+3; FAST_MULfootnote:[DSP-based multiplication; enabled via `FAST_MUL_EN`.]: 5
|
||||
| Division | `M` | `div` `divu` `rem` `remu` | 22+32+4
|
||||
| Bit-manipulation - arithmetic/logic | `B(Zbb)` | `sext.b` `sext.h` `min` `minu` `max` `maxu` `andn` `orn` `xnor` `zext`(pack) `rev8`(grevi) `orc.b`(gorci) | 3
|
||||
| Bit-manipulation - shifts | `B(Zbb)` | `clz` `ctz` | 3 + 0..32
|
||||
| Bit-manipulation - shifts | `B(Zbb)` | `cpop` | 3 + 32
|
||||
| Bit-manipulation - shifts | `B(Zbb)` | `rol` `ror` `rori` | 3 + SA
|
||||
| Bit-manipulation - single-bit | `B(Zbs)` | `sbset[i]` `sbclr[i]` `sbinv[i]` `sbext[i]` | 3
|
||||
| Bit-manipulation - shifted-add | `B(Zba)` | `sh1add` `sh2add` `sh3add` | 3
|
||||
| CSR access | `Zicsr` | `csrrw` `csrrs` `csrrc` `csrrwi` `csrrsi` `csrrci` | 4
|
||||
| System | `I/E`+`Zicsr` | `ecall` `ebreak` | 4
|
||||
| System | `I/E` | `fence` | 3
|
||||
|
@ -778,10 +784,13 @@ configurations are presented in <<_cpu_performance>>.
|
|||
| Floating-point - misc | `Zfinx` | `fsgnj.s` `fsgnjn.s` `fsgnjx.s` `fclass.s` | 12
|
||||
| Floating-point - conversion | `Zfinx` | `fcvt.w.s` `fcvt.wu.s` | 47
|
||||
| Floating-point - conversion | `Zfinx` | `fcvt.s.w` `fcvt.s.wu` | 48
|
||||
| Basic bit-manip - logic | `Zbb` | `andn` `orn` `xnor` | 3
|
||||
| Basic bit-manip - shift | `Zbb` | `clz` `ctz` `cpop` `rol` `ror` `rori` | 4+SA, FAST_SHIFT: 4
|
||||
| Basic bit-manip - arith | `Zbb` | `max` `maxu` `min` `minu` | 3
|
||||
| Basic bit-manip - misc | `Zbb` | `sext.b` `sext.h` `zext.h` `orc.b` `rev8` | 3
|
||||
| Bit-manipulation - arithmetic/logic | `B(Zbb)` | `sext.b` `sext.h` `min` `minu` `max` `maxu` `andn` `orn` `xnor` `zext`(pack) `rev8`(grevi) `orc.b`(gorci) | 3
|
||||
| Bit-manipulation - arithmetic/logic | `B(Zba)` | `sh1add` `sh2add` `sh3add` | 3
|
||||
| Bit-manipulation - shifts | `B(Zbb)` | `clz` `ctz` | 3 + 0..32
|
||||
| Bit-manipulation - shifts | `B(Zbb)` | `cpop` | 3 + 32
|
||||
| Bit-manipulation - shifts | `B(Zbb)` | `rol` `ror` `rori` | 3 + SA
|
||||
| Bit-manipulation - single-bit | `B(Zbs)` | `sbset[i]` `sbclr[i]` `sbinv[i]` `sbext[i]` | 3
|
||||
| Bit-manipulation - shifted-add | `B(Zba)` | `sh1add` `sh2add` `sh3add` | 3
|
||||
|=======================
|
||||
|
||||
[NOTE]
|
||||
|
|
|
@ -237,6 +237,18 @@ See section <<_a_atomic_memory_access>>.
|
|||
|======
|
||||
|
||||
|
||||
:sectnums!:
|
||||
===== _CPU_EXTENSION_RISCV_B_
|
||||
|
||||
[cols="4,4,2"]
|
||||
[frame="all",grid="none"]
|
||||
|======
|
||||
| **CPU_EXTENSION_RISCV_B** | _boolean_ | false
|
||||
3+| Implement the `B` bit-manipulation sub-extension when _true_.
|
||||
See section <<_b_bit_manipulation_operations>> for more information.
|
||||
|======
|
||||
|
||||
|
||||
:sectnums!:
|
||||
===== _CPU_EXTENSION_RISCV_C_
|
||||
|
||||
|
@ -289,18 +301,6 @@ See section <<_u_less_privileged_user_mode>> for more information.
|
|||
|======
|
||||
|
||||
|
||||
:sectnums!:
|
||||
===== _CPU_EXTENSION_RISCV_Zbb_
|
||||
|
||||
[cols="4,4,2"]
|
||||
[frame="all",grid="none"]
|
||||
|======
|
||||
| **CPU_EXTENSION_RISCV_Zbb** | _boolean_ | false
|
||||
3+| Implement the `Zbb` _basic_ bit-manipulation sub-extension when _true_.
|
||||
See section <<_zbb_basic_bit_manipulation_operations>> for more information.
|
||||
|======
|
||||
|
||||
|
||||
:sectnums!:
|
||||
===== _CPU_EXTENSION_RISCV_Zfinx_
|
||||
|
||||
|
@ -385,7 +385,7 @@ enabled (<<_cpu_extension_riscv_m>> or <<_cpu_extension_riscv_zmmul>> is _true_)
|
|||
more hardware resources but completing within two clock cycles). If it is set _false_, the CPU uses a serial shifter
|
||||
that only performs a single bit shift per cycle (requiring less hardware resources, but requires up to 32 clock
|
||||
cycles to complete - depending on shift amount). **Note that this option also implements barrel shifters for _all_
|
||||
shift-related operations of the <<_zbb_basic_bit_manipulation_operations>> extension.**
|
||||
shift-related operations of the <<_b_bit_manipulation_operations>> extension.**
|
||||
|======
|
||||
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ and default clock speed) for correct operation.
|
|||
| `0` | _SYSINFO_CPU_ZICSR_ | `Zicsr` extension (`I` sub-extension) available when set (via top's <<_cpu_extension_riscv_zicsr>> generic)
|
||||
| `1` | _SYSINFO_CPU_ZIFENCEI_ | `Zifencei` extension (`I` sub-extension) available when set (via top's <<_cpu_extension_riscv_zifencei>> generic)
|
||||
| `2` | _SYSINFO_CPU_ZMMUL_ | `Zmmul` extension (`M` sub-extension) available when set (via top's <<_cpu_extension_riscv_zmmul>> generic)
|
||||
| `3` | _SYSINFO_CPU_ZBB_ | `Zbb` extension (`B` sub-extension) available when set (via top's <<_cpu_extension_riscv_zbb>> generic)
|
||||
| `5` | _SYSINFO_CPU_ZFINX_ | `Zfinx` extension (`F` sub-/alternative-extension) available when set (via top's <<_cpu_extension_riscv_zfinx>> generic)
|
||||
| `6` | _SYSINFO_CPU_ZXSCNT_ | Custom extension - _Small_ CPU counters: `[m]cycle` & `[m]instret` CSRs have less than 64-bit when set (via top's <<_cpu_cnt_width>> generic)
|
||||
| `7` | _SYSINFO_CPU_ZXNOCNT_ | Custom extension - _NO_ CPU counters: `[m]cycle` & `[m]instret` CSRs are NOT available at all when set (via top's <<_cpu_cnt_width>> generic)
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
@ -65,11 +65,11 @@ entity neorv32_cpu is
|
|||
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0); -- cpu debug mode start address
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M : boolean; -- implement muld/div extension?
|
||||
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
|
||||
|
@ -170,8 +170,8 @@ begin
|
|||
cond_sel_string_f(CPU_EXTENSION_RISCV_M, "M", "") &
|
||||
cond_sel_string_f(CPU_EXTENSION_RISCV_A, "A", "") &
|
||||
cond_sel_string_f(CPU_EXTENSION_RISCV_C, "C", "") &
|
||||
cond_sel_string_f(CPU_EXTENSION_RISCV_B, "B", "") &
|
||||
cond_sel_string_f(CPU_EXTENSION_RISCV_U, "U", "") &
|
||||
cond_sel_string_f(CPU_EXTENSION_RISCV_Zbb, "_Zbb", "") &
|
||||
cond_sel_string_f(CPU_EXTENSION_RISCV_Zicsr, "_Zicsr", "") &
|
||||
cond_sel_string_f(CPU_EXTENSION_RISCV_Zifencei, "_Zifencei", "") &
|
||||
cond_sel_string_f(CPU_EXTENSION_RISCV_Zfinx, "_Zfinx", "") &
|
||||
|
@ -242,11 +242,11 @@ begin
|
|||
CPU_DEBUG_ADDR => CPU_DEBUG_ADDR, -- cpu debug mode start address
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension?
|
||||
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
|
||||
|
@ -335,8 +335,8 @@ begin
|
|||
neorv32_cpu_alu_inst: neorv32_cpu_alu
|
||||
generic map (
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension?
|
||||
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
|
||||
-- Extension Options --
|
||||
|
|
|
@ -44,8 +44,8 @@ use neorv32.neorv32_package.all;
|
|||
entity neorv32_cpu_alu is
|
||||
generic (
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
|
||||
-- Extension Options --
|
||||
|
@ -293,32 +293,33 @@ begin
|
|||
end generate;
|
||||
|
||||
|
||||
-- Co-Processor 2: Bit-Manipulation Unit ('B'/'Zbb' Extension) ----------------------------
|
||||
-- Co-Processor 2: Bit-Manipulation Unit ('B' Extension) ----------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
neorv32_cpu_cp_bitmanip_inst_true:
|
||||
if (CPU_EXTENSION_RISCV_Zbb = true) generate
|
||||
if (CPU_EXTENSION_RISCV_B = true) generate
|
||||
neorv32_cpu_cp_bitmanip_inst: neorv32_cpu_cp_bitmanip
|
||||
generic map (
|
||||
FAST_SHIFT_EN => FAST_SHIFT_EN -- use barrel shifter for shift operations
|
||||
)
|
||||
port map (
|
||||
-- global control --
|
||||
clk_i => clk_i, -- global clock, rising edge
|
||||
rstn_i => rstn_i, -- global reset, low-active, async
|
||||
ctrl_i => ctrl_i, -- main control bus
|
||||
start_i => cp_start(2), -- trigger operation
|
||||
clk_i => clk_i, -- global clock, rising edge
|
||||
rstn_i => rstn_i, -- global reset, low-active, async
|
||||
ctrl_i => ctrl_i, -- main control bus
|
||||
start_i => cp_start(2), -- trigger operation
|
||||
-- data input --
|
||||
cmp_i => cmp, -- comparator status
|
||||
rs1_i => rs1_i, -- rf source 1
|
||||
rs2_i => rs2_i, -- rf source 2
|
||||
cmp_i => cmp, -- comparator status
|
||||
rs1_i => rs1_i, -- rf source 1
|
||||
rs2_i => rs2_i, -- rf source 2
|
||||
shamt_i => opb(index_size_f(data_width_c)-1 downto 0), -- shift amount
|
||||
-- result and status --
|
||||
res_o => cp_result(2), -- operation result
|
||||
valid_o => cp_valid(2) -- data output valid
|
||||
res_o => cp_result(2), -- operation result
|
||||
valid_o => cp_valid(2) -- data output valid
|
||||
);
|
||||
end generate;
|
||||
|
||||
neorv32_cpu_cp_bitmanip_inst_false:
|
||||
if (CPU_EXTENSION_RISCV_Zbb = false) generate
|
||||
if (CPU_EXTENSION_RISCV_B = false) generate
|
||||
cp_result(2) <= (others => '0');
|
||||
cp_valid(2) <= cp_start(2); -- to make sure CPU does not get stalled if there is an accidental access
|
||||
end generate;
|
||||
|
|
|
@ -53,11 +53,11 @@ entity neorv32_cpu_control is
|
|||
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0); -- cpu debug mode start address
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
|
||||
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
|
||||
|
@ -860,6 +860,13 @@ begin
|
|||
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "110") or -- ORN
|
||||
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "100") -- XORN
|
||||
)
|
||||
) or
|
||||
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0010000") and
|
||||
(
|
||||
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "010") or -- SH1ADD
|
||||
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "100") or -- SH2ADD
|
||||
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "110") -- SH3ADD
|
||||
)
|
||||
) then
|
||||
decode_aux.is_bitmanip_reg <= '1';
|
||||
end if;
|
||||
|
@ -1043,7 +1050,7 @@ begin
|
|||
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- use MULDIV CP
|
||||
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
|
||||
-- co-processor bit manipulation operation? --
|
||||
elsif (CPU_EXTENSION_RISCV_Zbb = true) and
|
||||
elsif (CPU_EXTENSION_RISCV_B = true) and
|
||||
(((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and (decode_aux.is_bitmanip_reg = '1')) or -- register operation
|
||||
((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alui_c(5)) and (decode_aux.is_bitmanip_imm = '1'))) then -- immediate operation
|
||||
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_bitmanip_c; -- use BITMANIP CP
|
||||
|
@ -1066,7 +1073,7 @@ begin
|
|||
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) or -- SR shift operation?
|
||||
((CPU_EXTENSION_RISCV_M = true) and ((decode_aux.is_m_mul = '1') or (decode_aux.is_m_div = '1'))) or -- MUL/DIV
|
||||
((CPU_EXTENSION_RISCV_Zmmul = true) and (decode_aux.is_m_mul = '1')) or -- MUL
|
||||
((CPU_EXTENSION_RISCV_Zbb = true) and (
|
||||
((CPU_EXTENSION_RISCV_B = true) and (
|
||||
((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and (decode_aux.is_bitmanip_reg = '1')) or -- BITMANIP CP register operation?
|
||||
((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alui_c(5)) and (decode_aux.is_bitmanip_imm = '1'))) -- BITMANIP CP immediate operation?
|
||||
) then
|
||||
|
@ -1435,7 +1442,7 @@ begin
|
|||
illegal_instruction <= '1';
|
||||
end if;
|
||||
elsif (decode_aux.is_bitmanip_reg = '1') then -- bit manipulation
|
||||
if (CPU_EXTENSION_RISCV_Zbb = false) then -- not implemented
|
||||
if (CPU_EXTENSION_RISCV_B = false) then -- not implemented
|
||||
illegal_instruction <= '1';
|
||||
end if;
|
||||
elsif ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_subadd_c) or
|
||||
|
@ -1455,7 +1462,7 @@ begin
|
|||
when opcode_alui_c => -- check ALUI.funct7
|
||||
-- ------------------------------------------------------------
|
||||
if (decode_aux.is_bitmanip_imm = '1') then -- bit manipulation
|
||||
if (CPU_EXTENSION_RISCV_Zbb = false) then -- not implemented
|
||||
if (CPU_EXTENSION_RISCV_B = false) then -- not implemented
|
||||
illegal_instruction <= '1';
|
||||
end if;
|
||||
elsif ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and
|
||||
|
@ -2503,6 +2510,7 @@ begin
|
|||
csr.rdata(12) <= csr.mstatus_mpp(1); -- MPP: machine previous privilege mode high
|
||||
when csr_misa_c => -- misa (r/-): ISA and extensions
|
||||
csr.rdata(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_A); -- A CPU extension
|
||||
csr.rdata(01) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B); -- B CPU extension
|
||||
csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension
|
||||
csr.rdata(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- E CPU extension
|
||||
csr.rdata(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
-- # fixed value of 3 cycles latency (using barrel shifters). #
|
||||
-- # #
|
||||
-- # Supported sub-extensions (Zb*): #
|
||||
-- # - Zba: Address generation instructions #
|
||||
-- # - Zbb: Basic bit-manipulation instructions #
|
||||
-- # ********************************************************************************************* #
|
||||
-- # BSD 3-Clause License #
|
||||
|
@ -61,6 +62,7 @@ entity neorv32_cpu_cp_bitmanip is
|
|||
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status
|
||||
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
|
||||
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
|
||||
shamt_i : in std_ulogic_vector(index_size_f(data_width_c)-1 downto 0); -- shift amount
|
||||
-- result and status --
|
||||
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result
|
||||
valid_o : out std_ulogic -- data output valid
|
||||
|
@ -69,31 +71,40 @@ end neorv32_cpu_cp_bitmanip;
|
|||
|
||||
architecture neorv32_cpu_cp_bitmanip_rtl of neorv32_cpu_cp_bitmanip is
|
||||
|
||||
-- commands: logic with negate --
|
||||
constant op_andn_c : natural := 0;
|
||||
constant op_orn_c : natural := 1;
|
||||
constant op_xnor_c : natural := 2;
|
||||
-- commands: count leading/trailing zero bits --
|
||||
constant op_clz_c : natural := 3;
|
||||
constant op_ctz_c : natural := 4;
|
||||
-- commands: count population --
|
||||
constant op_cpop_c : natural := 5;
|
||||
-- commands: integer minimum/maximum --
|
||||
constant op_max_c : natural := 6; -- signed/unsigned
|
||||
constant op_min_c : natural := 7; -- signed/unsigned
|
||||
-- commands: sign- and zero-extension --
|
||||
constant op_sextb_c : natural := 8;
|
||||
constant op_sexth_c : natural := 9;
|
||||
constant op_zexth_c : natural := 10;
|
||||
-- commands: bitwise rotation --
|
||||
constant op_rol_c : natural := 11;
|
||||
constant op_ror_c : natural := 12; -- rori
|
||||
-- commands: or-combine --
|
||||
constant op_orcb_c : natural := 13;
|
||||
-- commands: byte-reverse --
|
||||
constant op_rev8_c : natural := 14;
|
||||
-- Sub-extension configuration --
|
||||
constant zbb_en_c : boolean := true;
|
||||
constant zba_en_c : boolean := true;
|
||||
-- --------------------------- --
|
||||
|
||||
-- commands: Zbb - logic with negate --
|
||||
constant op_andn_c : natural := 0;
|
||||
constant op_orn_c : natural := 1;
|
||||
constant op_xnor_c : natural := 2;
|
||||
-- commands: Zbb - count leading/trailing zero bits --
|
||||
constant op_clz_c : natural := 3;
|
||||
constant op_ctz_c : natural := 4;
|
||||
-- commands: Zbb - count population --
|
||||
constant op_cpop_c : natural := 5;
|
||||
-- commands: Zbb - integer minimum/maximum --
|
||||
constant op_max_c : natural := 6; -- signed/unsigned
|
||||
constant op_min_c : natural := 7; -- signed/unsigned
|
||||
-- commands: Zbb - sign- and zero-extension --
|
||||
constant op_sextb_c : natural := 8;
|
||||
constant op_sexth_c : natural := 9;
|
||||
constant op_zexth_c : natural := 10;
|
||||
-- commands: Zbb - bitwise rotation --
|
||||
constant op_rol_c : natural := 11;
|
||||
constant op_ror_c : natural := 12; -- rori
|
||||
-- commands: Zbb - or-combine --
|
||||
constant op_orcb_c : natural := 13;
|
||||
-- commands: Zbb - byte-reverse --
|
||||
constant op_rev8_c : natural := 14;
|
||||
-- commands: Zba - shifted add --
|
||||
constant op_sh1add_c : natural := 15;
|
||||
constant op_sh2add_c : natural := 16;
|
||||
constant op_sh3add_c : natural := 17;
|
||||
--
|
||||
constant op_width_c : natural := 15;
|
||||
constant op_width_c : natural := 18;
|
||||
|
||||
-- controller --
|
||||
type ctrl_state_t is (S_IDLE, S_START_SHIFT, S_BUSY_SHIFT);
|
||||
|
@ -104,11 +115,9 @@ architecture neorv32_cpu_cp_bitmanip_rtl of neorv32_cpu_cp_bitmanip is
|
|||
-- operand buffers --
|
||||
signal rs1_reg : std_ulogic_vector(data_width_c-1 downto 0);
|
||||
signal rs2_reg : std_ulogic_vector(data_width_c-1 downto 0);
|
||||
signal sha_reg : std_ulogic_vector(index_size_f(data_width_c)-1 downto 0);
|
||||
signal less_ff : std_ulogic;
|
||||
|
||||
-- shift amount (immediate or register) --
|
||||
signal shamt : std_ulogic_vector(index_size_f(data_width_c)-1 downto 0);
|
||||
|
||||
-- serial shifter --
|
||||
type shifter_t is record
|
||||
start : std_ulogic;
|
||||
|
@ -128,32 +137,50 @@ architecture neorv32_cpu_cp_bitmanip_rtl of neorv32_cpu_cp_bitmanip is
|
|||
type res_t is array (0 to op_width_c-1) of std_ulogic_vector(data_width_c-1 downto 0);
|
||||
signal res_int, res_out : res_t;
|
||||
|
||||
-- shifted-add unit --
|
||||
signal adder_core : std_ulogic_vector(data_width_c-1 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-- Sub-Extension Configuration ------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
assert false report
|
||||
"Implementing bit-manipulation (B) sub-extensions: " &
|
||||
cond_sel_string_f(zbb_en_c, "Zbb", "") &
|
||||
cond_sel_string_f(zba_en_c, "Zba", "") &
|
||||
""
|
||||
severity note;
|
||||
|
||||
|
||||
-- Instruction Decoding (One-Hot) ---------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
-- a minimal decoding logic is used here -> just to distinguish between B.Zbb instructions
|
||||
-- a more specific decoding and instruction check is done by the CPU control unit
|
||||
|
||||
-- Zbb - Basic bit-manipulation instructions --
|
||||
cmd(op_andn_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "11") else '0';
|
||||
cmd(op_orn_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "10") else '0';
|
||||
cmd(op_xnor_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "00") else '0';
|
||||
cmd(op_andn_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "11") else '0';
|
||||
cmd(op_orn_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "10") else '0';
|
||||
cmd(op_xnor_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "00") else '0';
|
||||
--
|
||||
cmd(op_max_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '1') and (ctrl_i(ctrl_ir_funct3_1_c) = '1') else '0';
|
||||
cmd(op_min_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '1') and (ctrl_i(ctrl_ir_funct3_1_c) = '0') else '0';
|
||||
cmd(op_zexth_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '0') else '0';
|
||||
cmd(op_max_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '1') and (ctrl_i(ctrl_ir_funct3_1_c) = '1') else '0';
|
||||
cmd(op_min_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '1') and (ctrl_i(ctrl_ir_funct3_1_c) = '0') else '0';
|
||||
cmd(op_zexth_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '0') else '0';
|
||||
--
|
||||
cmd(op_orcb_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "01") else '0';
|
||||
cmd(op_orcb_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "01") and (ctrl_i(ctrl_ir_funct12_7_c) = '1') else '0';
|
||||
--
|
||||
cmd(op_clz_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "000") else '0';
|
||||
cmd(op_ctz_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "001") else '0';
|
||||
cmd(op_cpop_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "010") else '0';
|
||||
cmd(op_sextb_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "100") else '0';
|
||||
cmd(op_sexth_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "101") else '0';
|
||||
cmd(op_rol_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "001") and (ctrl_i(ctrl_ir_opcode7_5_c) = '1') else '0';
|
||||
cmd(op_ror_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "101") else '0';
|
||||
cmd(op_rev8_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '1') else '0';
|
||||
cmd(op_clz_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "000") else '0';
|
||||
cmd(op_ctz_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "001") else '0';
|
||||
cmd(op_cpop_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "010") else '0';
|
||||
cmd(op_sextb_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "100") else '0';
|
||||
cmd(op_sexth_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "101") else '0';
|
||||
cmd(op_rol_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "001") and (ctrl_i(ctrl_ir_opcode7_5_c) = '1') else '0';
|
||||
cmd(op_ror_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "101") else '0';
|
||||
cmd(op_rev8_c) <= '1' when (zbb_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '1') else '0';
|
||||
|
||||
-- Zba - Address generation instructions --
|
||||
cmd(op_sh1add_c) <= '1' when (zba_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "01") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_1_c) = "01") else '0';
|
||||
cmd(op_sh2add_c) <= '1' when (zba_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "01") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_1_c) = "10") else '0';
|
||||
cmd(op_sh3add_c) <= '1' when (zba_en_c = true) and (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "01") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_1_c) = "11") else '0';
|
||||
|
||||
|
||||
-- Co-Processor Controller ----------------------------------------------------------------
|
||||
|
@ -165,6 +192,7 @@ begin
|
|||
cmd_buf <= (others => def_rst_val_c);
|
||||
rs1_reg <= (others => def_rst_val_c);
|
||||
rs2_reg <= (others => def_rst_val_c);
|
||||
sha_reg <= (others => def_rst_val_c);
|
||||
less_ff <= def_rst_val_c;
|
||||
shifter.start <= '0';
|
||||
valid <= '0';
|
||||
|
@ -183,6 +211,7 @@ begin
|
|||
cmd_buf <= cmd;
|
||||
rs1_reg <= rs1_i;
|
||||
rs2_reg <= rs2_i;
|
||||
sha_reg <= shamt_i;
|
||||
if ((cmd(op_clz_c) or cmd(op_ctz_c) or cmd(op_cpop_c) or cmd(op_ror_c) or cmd(op_rol_c)) = '1') then -- multi-cycle shift operation
|
||||
if (FAST_SHIFT_EN = false) then -- default: iterative computation
|
||||
shifter.start <= '1';
|
||||
|
@ -216,13 +245,6 @@ begin
|
|||
end process coprocessor_ctrl;
|
||||
|
||||
|
||||
-- Shift Amount ---------------------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
-- we could also use ALU's internal operand B - but we are having a local version here in order to allow
|
||||
-- better logic combination inside the ALU (since that is the critical path of the CPU)
|
||||
shamt <= ctrl_i(ctrl_ir_funct12_0_c+shamt'left downto ctrl_ir_funct12_0_c) when (ctrl_i(ctrl_ir_opcode7_5_c) = '0') else rs2_reg(shamt'left downto 0);
|
||||
|
||||
|
||||
-- Shifter Function Core (iterative: small but slow) --------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
serial_shifter:
|
||||
|
@ -249,7 +271,7 @@ begin
|
|||
shifter.cnt_max <= (others => '0');
|
||||
shifter.cnt_max(shifter.cnt_max'left) <= '1';
|
||||
else
|
||||
shifter.cnt_max <= '0' & shamt;
|
||||
shifter.cnt_max <= '0' & sha_reg;
|
||||
end if;
|
||||
shifter.bcnt <= (others => '0');
|
||||
elsif (shifter.run = '1') then -- right shifts only
|
||||
|
@ -313,7 +335,7 @@ begin
|
|||
-- barrel shifter array --
|
||||
barrel_shifter_async:
|
||||
if (FAST_SHIFT_EN = true) generate
|
||||
shifter_unit_async: process(rs1_reg, shamt, cmd_buf, bs_level)
|
||||
shifter_unit_async: process(rs1_reg, sha_reg, cmd_buf, bs_level)
|
||||
begin
|
||||
-- input level: convert left shifts to right shifts --
|
||||
if (cmd_buf(op_rol_c) = '1') then -- is left shift?
|
||||
|
@ -324,7 +346,7 @@ begin
|
|||
|
||||
-- shifter array --
|
||||
for i in index_size_f(data_width_c)-1 downto 0 loop
|
||||
if (shamt(i) = '1') then
|
||||
if (sha_reg(i) = '1') then
|
||||
bs_level(i)(data_width_c-1 downto data_width_c-(2**i)) <= bs_level(i+1)((2**i)-1 downto 0);
|
||||
bs_level(i)((data_width_c-(2**i))-1 downto 0) <= bs_level(i+1)(data_width_c-1 downto 2**i);
|
||||
else
|
||||
|
@ -335,6 +357,21 @@ begin
|
|||
end generate;
|
||||
|
||||
|
||||
-- Shifted-Add Core -----------------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
shift_adder: process(rs1_reg, rs2_reg, ctrl_i)
|
||||
variable opb_v : std_ulogic_vector(data_width_c-1 downto 0);
|
||||
begin
|
||||
case ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_1_c) is
|
||||
when "01" => opb_v := rs1_reg(rs1_reg'left-1 downto 0) & '0'; -- << 1
|
||||
when "10" => opb_v := rs1_reg(rs1_reg'left-2 downto 0) & "00"; -- << 2
|
||||
when "11" => opb_v := rs1_reg(rs1_reg'left-3 downto 0) & "000"; -- << 3
|
||||
when others => opb_v := rs1_reg(rs1_reg'left-1 downto 0) & '0'; -- undefined
|
||||
end case;
|
||||
adder_core <= std_ulogic_vector(unsigned(rs2_reg) + unsigned(opb_v));
|
||||
end process shift_adder;
|
||||
|
||||
|
||||
-- Operation Results ----------------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
-- logic with negate --
|
||||
|
@ -376,6 +413,11 @@ begin
|
|||
-- reversal.8 (byte swap) --
|
||||
res_int(op_rev8_c) <= bswap32_f(rs1_reg);
|
||||
|
||||
-- address generation instructions --
|
||||
res_int(op_sh1add_c) <= adder_core;
|
||||
res_int(op_sh2add_c) <= (others => '0'); -- unused/redundant
|
||||
res_int(op_sh3add_c) <= (others => '0'); -- unused/redundant
|
||||
|
||||
|
||||
-- Output Selector ------------------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
|
@ -394,6 +436,10 @@ begin
|
|||
res_out(op_rol_c) <= res_int(op_rol_c) when (cmd_buf(op_rol_c) = '1') else (others => '0');
|
||||
res_out(op_orcb_c) <= res_int(op_orcb_c) when (cmd_buf(op_orcb_c) = '1') else (others => '0');
|
||||
res_out(op_rev8_c) <= res_int(op_rev8_c) when (cmd_buf(op_rev8_c) = '1') else (others => '0');
|
||||
--
|
||||
res_out(op_sh1add_c) <= res_int(op_sh1add_c) when ((cmd_buf(op_sh1add_c) or cmd_buf(op_sh2add_c) or cmd_buf(op_sh3add_c)) = '1') else (others => '0');
|
||||
res_out(op_sh2add_c) <= (others => '0'); -- unused/redundant
|
||||
res_out(op_sh3add_c) <= (others => '0'); -- unused/redundant
|
||||
|
||||
|
||||
-- Output Gate ----------------------------------------------------------------------------
|
||||
|
@ -410,7 +456,8 @@ begin
|
|||
res_out(op_min_c) or -- res_out(op_max_c) is unused here
|
||||
res_out(op_sextb_c) or res_out(op_sexth_c) or res_out(op_zexth_c) or
|
||||
res_out(op_ror_c) or res_out(op_rol_c) or
|
||||
res_out(op_orcb_c) or res_out(op_rev8_c);
|
||||
res_out(op_orcb_c) or res_out(op_rev8_c) or
|
||||
res_out(op_sh1add_c); -- res_out(op_sh2add_c) and res_out(op_sh3add_c) are unused here
|
||||
end if;
|
||||
end if;
|
||||
end process output_gate;
|
||||
|
|
|
@ -64,7 +64,7 @@ package neorv32_package is
|
|||
-- 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"01060210"; -- no touchy!
|
||||
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01060211"; -- no touchy!
|
||||
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
|
||||
|
||||
-- External Interface Types ---------------------------------------------------------------
|
||||
|
@ -899,11 +899,11 @@ package neorv32_package is
|
|||
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
|
||||
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
|
||||
|
@ -1049,11 +1049,11 @@ package neorv32_package is
|
|||
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0); -- cpu debug mode start address
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
|
||||
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
|
||||
|
@ -1123,11 +1123,11 @@ package neorv32_package is
|
|||
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0); -- cpu debug mode start address
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
|
||||
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
|
||||
|
@ -1213,8 +1213,8 @@ package neorv32_package is
|
|||
component neorv32_cpu_alu
|
||||
generic (
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
|
||||
-- Extension Options --
|
||||
|
@ -1289,7 +1289,7 @@ package neorv32_package is
|
|||
-- -------------------------------------------------------------------------------------------
|
||||
component neorv32_cpu_cp_bitmanip is
|
||||
generic (
|
||||
FAST_SHIFT_EN : boolean -- use barrel shifter for shift operations
|
||||
FAST_SHIFT_EN : boolean -- use barrel shifter for shift operations
|
||||
);
|
||||
port (
|
||||
-- global control --
|
||||
|
@ -1301,6 +1301,7 @@ package neorv32_package is
|
|||
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status
|
||||
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
|
||||
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
|
||||
shamt_i : in std_ulogic_vector(index_size_f(data_width_c)-1 downto 0); -- shift amount
|
||||
-- result and status --
|
||||
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result
|
||||
valid_o : out std_ulogic -- data output valid
|
||||
|
@ -1902,7 +1903,6 @@ package neorv32_package is
|
|||
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
|
||||
INT_BOOTLOADER_EN : boolean; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
|
||||
|
|
|
@ -48,7 +48,6 @@ entity neorv32_sysinfo is
|
|||
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
|
||||
INT_BOOTLOADER_EN : boolean; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
|
||||
|
@ -139,9 +138,8 @@ begin
|
|||
sysinfo_mem(1)(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr); -- Zicsr
|
||||
sysinfo_mem(1)(01) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Zifencei
|
||||
sysinfo_mem(1)(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zmmul); -- Zmmul
|
||||
sysinfo_mem(1)(03) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zbb); -- Zbb
|
||||
--
|
||||
sysinfo_mem(1)(04) <= '0'; -- reserved
|
||||
sysinfo_mem(1)(04 downto 03) <= (others => '0'); -- reserved
|
||||
--
|
||||
sysinfo_mem(1)(05) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- Zfinx ("F-alternative")
|
||||
sysinfo_mem(1)(07 downto 06) <= "00" when (CPU_CNT_WIDTH = 64) else "10" when (CPU_CNT_WIDTH = 0) else "01"; -- CPU counter size: Zxscnt | Zxnocnt
|
||||
|
|
|
@ -56,11 +56,11 @@ entity neorv32_top is
|
|||
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
|
||||
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
|
||||
|
@ -452,11 +452,11 @@ begin
|
|||
CPU_DEBUG_ADDR => dm_base_c, -- cpu debug mode start address
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
|
||||
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
|
||||
|
@ -1347,7 +1347,6 @@ begin
|
|||
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
|
||||
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- implement processor-internal bootloader?
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
|
||||
|
|
|
@ -98,10 +98,10 @@ architecture neorv32_twi_rtl of neorv32_twi is
|
|||
signal twi_clk_halt : std_ulogic;
|
||||
|
||||
-- twi transceiver core --
|
||||
signal ctrl : std_ulogic_vector(7 downto 0); -- unit's control register
|
||||
signal arbiter : std_ulogic_vector(2 downto 0);
|
||||
signal twi_bitcnt : std_ulogic_vector(3 downto 0);
|
||||
signal twi_rtx_sreg : std_ulogic_vector(8 downto 0); -- main rx/tx shift reg
|
||||
signal ctrl : std_ulogic_vector(7 downto 0); -- unit's control register
|
||||
signal arbiter : std_ulogic_vector(2 downto 0);
|
||||
signal bitcnt : std_ulogic_vector(3 downto 0);
|
||||
signal rtx_sreg : std_ulogic_vector(8 downto 0); -- main rx/tx shift reg
|
||||
|
||||
-- tri-state I/O --
|
||||
signal twi_sda_i_ff0, twi_sda_i_ff1 : std_ulogic; -- sda input sync
|
||||
|
@ -142,10 +142,10 @@ begin
|
|||
data_o(ctrl_twi_mack_c) <= ctrl(ctrl_twi_mack_c);
|
||||
data_o(ctrl_twi_cksten_c) <= ctrl(ctrl_twi_cksten_c);
|
||||
--
|
||||
data_o(ctrl_twi_ack_c) <= not twi_rtx_sreg(0);
|
||||
data_o(ctrl_twi_ack_c) <= not rtx_sreg(0);
|
||||
data_o(ctrl_twi_busy_c) <= arbiter(1) or arbiter(0);
|
||||
else -- twi_rtx_addr_c =>
|
||||
data_o(7 downto 0) <= twi_rtx_sreg(8 downto 1);
|
||||
data_o(7 downto 0) <= rtx_sreg(8 downto 1);
|
||||
|
||||
end if;
|
||||
end if;
|
||||
|
@ -166,7 +166,7 @@ begin
|
|||
begin
|
||||
if rising_edge(clk_i) then
|
||||
if (arbiter(2) = '0') or (arbiter = "100") then -- offline or idle
|
||||
twi_phase_gen <= "0001"; -- make sure to start with a new phase, 0,1,2,3 stepping
|
||||
twi_phase_gen <= "0001"; -- make sure to start with a new phase, bit 0,1,2,3 stepping
|
||||
elsif (twi_clk = '1') and (twi_clk_halt = '0') then -- enabled and no clock stretching detected
|
||||
twi_phase_gen <= twi_phase_gen(2 downto 0) & twi_phase_gen(3); -- rotate left
|
||||
end if;
|
||||
|
@ -203,7 +203,7 @@ begin
|
|||
case arbiter is
|
||||
|
||||
when "100" => -- IDLE: waiting for requests, bus might be still claimed by this controller if no STOP condition was generated
|
||||
twi_bitcnt <= (others => '0');
|
||||
bitcnt <= (others => '0');
|
||||
if (wr_en = '1') then
|
||||
if (addr = twi_ctrl_addr_c) then
|
||||
if (data_i(ctrl_twi_start_c) = '1') then -- issue START condition
|
||||
|
@ -214,7 +214,7 @@ begin
|
|||
elsif (addr = twi_rtx_addr_c) then -- start a data transmission
|
||||
-- one bit extra for ack, issued by controller if ctrl_twi_mack_c is set,
|
||||
-- sampled from peripheral if ctrl_twi_mack_c is cleared
|
||||
twi_rtx_sreg <= data_i(7 downto 0) & (not ctrl(ctrl_twi_mack_c));
|
||||
rtx_sreg <= data_i(7 downto 0) & (not ctrl(ctrl_twi_mack_c));
|
||||
arbiter(1 downto 0) <= "11";
|
||||
end if;
|
||||
end if;
|
||||
|
@ -225,7 +225,7 @@ begin
|
|||
elsif (twi_clk_phase(1) = '1') then
|
||||
twi_sda_o <= '0';
|
||||
end if;
|
||||
|
||||
--
|
||||
if (twi_clk_phase(0) = '1') then
|
||||
twi_scl_o <= '1';
|
||||
elsif (twi_clk_phase(3) = '1') then
|
||||
|
@ -240,7 +240,7 @@ begin
|
|||
twi_sda_o <= '1';
|
||||
arbiter(1 downto 0) <= "00"; -- go back to IDLE
|
||||
end if;
|
||||
|
||||
--
|
||||
if (twi_clk_phase(0) = '1') then
|
||||
twi_scl_o <= '0';
|
||||
elsif (twi_clk_phase(1) = '1') then
|
||||
|
@ -249,17 +249,17 @@ begin
|
|||
|
||||
when "111" => -- TRANSMISSION: transmission in progress
|
||||
if (twi_clk_phase(0) = '1') then
|
||||
twi_bitcnt <= std_ulogic_vector(unsigned(twi_bitcnt) + 1);
|
||||
twi_scl_o <= '0';
|
||||
twi_sda_o <= twi_rtx_sreg(8); -- MSB first
|
||||
bitcnt <= std_ulogic_vector(unsigned(bitcnt) + 1);
|
||||
twi_scl_o <= '0';
|
||||
twi_sda_o <= rtx_sreg(8); -- MSB first
|
||||
elsif (twi_clk_phase(1) = '1') then -- first half + second half of valid data strobe
|
||||
twi_scl_o <= '1';
|
||||
twi_scl_o <= '1';
|
||||
elsif (twi_clk_phase(3) = '1') then
|
||||
twi_rtx_sreg <= twi_rtx_sreg(7 downto 0) & twi_sda_i_ff1; -- sample and shift left
|
||||
twi_scl_o <= '0';
|
||||
rtx_sreg <= rtx_sreg(7 downto 0) & twi_sda_i_ff1; -- sample and shift left
|
||||
twi_scl_o <= '0';
|
||||
end if;
|
||||
|
||||
if (twi_bitcnt = "1010") then -- 8 data bits + 1 bit for ACK + 1 tick delay
|
||||
--
|
||||
if (bitcnt = "1010") then -- 8 data bits + 1 bit for ACK + 1 tick delay
|
||||
arbiter(1 downto 0) <= "00"; -- go back to IDLE
|
||||
end if;
|
||||
|
||||
|
|
|
@ -49,11 +49,11 @@ entity neorv32_ProcessorTop_stdlogic is
|
|||
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
|
||||
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
|
||||
|
@ -272,11 +272,11 @@ begin
|
|||
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement on-chip debugger
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
|
||||
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
|
||||
|
|
|
@ -54,11 +54,11 @@ entity neorv32_top_avalonmm is
|
|||
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
|
||||
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
|
||||
|
@ -238,11 +238,11 @@ begin
|
|||
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A,
|
||||
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B,
|
||||
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C,
|
||||
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E,
|
||||
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M,
|
||||
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U,
|
||||
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb,
|
||||
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx,
|
||||
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr,
|
||||
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei,
|
||||
|
|
|
@ -55,11 +55,11 @@ entity neorv32_SystemTop_axi4lite is
|
|||
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
|
||||
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
|
||||
|
@ -279,11 +279,11 @@ begin
|
|||
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement on-chip debugger
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
|
||||
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
|
||||
|
|
|
@ -76,11 +76,11 @@ architecture neorv32_test_setup_avalonmm_rtl of neorv32_test_setup_avalonmm is
|
|||
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension?
|
||||
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
|
||||
|
|
|
@ -284,11 +284,11 @@ begin
|
|||
ON_CHIP_DEBUGGER_EN => true, -- implement on-chip debugger
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A => true, -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B => true, -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C => true, -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E => false, -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M => true, -- implement muld/div extension?
|
||||
CPU_EXTENSION_RISCV_U => true, -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb => true, -- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx => true, -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr => true, -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei => true, -- implement instruction stream sync.?
|
||||
|
|
|
@ -49,11 +49,11 @@ use std.textio.all;
|
|||
entity neorv32_tb_simple is
|
||||
generic (
|
||||
CPU_EXTENSION_RISCV_A : boolean := true;
|
||||
CPU_EXTENSION_RISCV_B : boolean := true;
|
||||
CPU_EXTENSION_RISCV_C : boolean := true;
|
||||
CPU_EXTENSION_RISCV_E : boolean := false;
|
||||
CPU_EXTENSION_RISCV_M : boolean := true;
|
||||
CPU_EXTENSION_RISCV_U : boolean := true;
|
||||
CPU_EXTENSION_RISCV_Zbb : boolean := true;
|
||||
CPU_EXTENSION_RISCV_Zicsr : boolean := true;
|
||||
CPU_EXTENSION_RISCV_Zifencei : boolean := true;
|
||||
EXT_IMEM_C : boolean := false; -- false: use and boot from proc-internal IMEM, true: use and boot from external (initialized) simulated IMEM (ext. mem A)
|
||||
|
@ -176,11 +176,11 @@ begin
|
|||
ON_CHIP_DEBUGGER_EN => true, -- implement on-chip debugger
|
||||
-- RISC-V CPU Extensions --
|
||||
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
|
||||
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit-manipulation extension?
|
||||
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
|
||||
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
|
||||
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
|
||||
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
|
||||
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb,-- implement basic bit-manipulation sub-extension?
|
||||
CPU_EXTENSION_RISCV_Zfinx => true, -- implement 32-bit floating-point extension (using INT reg!)
|
||||
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
|
||||
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# NEORV32 Bit-Manipulation `B` Extension (`Zbb` sub-extension)
|
||||
# NEORV32 Bit-Manipulation `B` Extension
|
||||
|
||||
:warning: The RISC-V bit-manipulation extension is frozen but not yet officially ratified.
|
||||
|
||||
:warning: The NEORV32 bit manipulation extensions only supports the `Zbb` sub-extension
|
||||
:warning: The NEORV32 bit manipulation extensions `B` only supports the `Zbb` and `Zba` sub-extension
|
||||
(basic bit-manipulation operation) yet.
|
||||
|
||||
The provided test program `main.c` verifies all currently implemented instruction by checking the results against a pure-software emulation model.
|
||||
The emulation functions as well as the available **intrinsics** for the `Zbb` extension are located in `neorv32_b_extension_intrinsics.h`.
|
||||
The emulation functions as well as the available **intrinsics** for the sub-extension are located in `neorv32_b_extension_intrinsics.h`.
|
||||
|
||||
:information_source: More information regarding the RISC-V bit manipulation extension can be found in the officail GitHub repo:
|
||||
[github.com/riscv/riscv-bitmanip](https://github.com/riscv/riscv-bitmanip).
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// #################################################################################################
|
||||
// # << NEORV32 - RISC-V Bit-Manipulation 'Zbb' Extension Test Program >> #
|
||||
// # << NEORV32 - RISC-V Bit-Manipulation 'B' Extension Test Program >> #
|
||||
// # ********************************************************************************************* #
|
||||
// # BSD 3-Clause License #
|
||||
// # #
|
||||
|
@ -36,7 +36,7 @@
|
|||
/**********************************************************************//**
|
||||
* @file bitmanip_test/main.c
|
||||
* @author Stephan Nolting
|
||||
* @brief Test program for the NEORV32 'Zbb' extension using pseudo-random
|
||||
* @brief Test program for the NEORV32 'B` extension using pseudo-random
|
||||
* data as input; compares results from hardware against pure-sw reference functions.
|
||||
**************************************************************************/
|
||||
|
||||
|
@ -64,7 +64,7 @@ void print_report(int num_err, int num_tests);
|
|||
* Main function; test all available operations of the NEORV32 'Zbb' extensions
|
||||
* using bit manipulation intrinsics and software-only reference functions (emulation).
|
||||
*
|
||||
* @note This program requires the Zbb CPU extension.
|
||||
* @note This program requires the bit-manipulation CPU extension.
|
||||
*
|
||||
* @return Irrelevant.
|
||||
**************************************************************************/
|
||||
|
@ -91,18 +91,22 @@ int main() {
|
|||
#endif
|
||||
|
||||
// intro
|
||||
neorv32_uart0_printf("NEORV32 'Zbb' Bit-Manipulation Extension Test\n\n");
|
||||
neorv32_uart0_printf("NEORV32 Bit-Manipulation Extension Test (Zba, Zbb)\n\n");
|
||||
|
||||
// check available hardware extensions and compare with compiler flags
|
||||
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch
|
||||
|
||||
// check if Zbb extension is implemented at all
|
||||
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_ZBB)) == 0) {
|
||||
neorv32_uart0_print("Error! <Zbb> extension not synthesized!\n");
|
||||
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_B)) == 0) {
|
||||
neorv32_uart0_print("Error! <B> extension not synthesized!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
neorv32_uart0_printf("Starting Zbb bit-manipulation extension tests (%i test cases per instruction)...\n", num_tests);
|
||||
neorv32_uart0_printf("Starting bit-manipulation extension tests (%i test cases per instruction)...\n\n", num_tests);
|
||||
|
||||
neorv32_uart0_printf("-----------------------------------------\n");
|
||||
neorv32_uart0_printf("Zbb - Basic bit-manipulation instructions\n");
|
||||
neorv32_uart0_printf("-----------------------------------------\n");
|
||||
|
||||
// ANDN
|
||||
neorv32_uart0_printf("\nANDN:\n");
|
||||
|
@ -326,6 +330,48 @@ int main() {
|
|||
print_report(err_cnt, num_tests);
|
||||
|
||||
|
||||
|
||||
neorv32_uart0_printf("\n\n");
|
||||
neorv32_uart0_printf("-----------------------------------------\n");
|
||||
neorv32_uart0_printf("Zba - Address generation instructions\n");
|
||||
neorv32_uart0_printf("-----------------------------------------\n");
|
||||
|
||||
// SH1ADD
|
||||
neorv32_uart0_printf("\nSH1ADD:\n");
|
||||
err_cnt = 0;
|
||||
for (i=0;i<num_tests; i++) {
|
||||
opa = xorshift32();
|
||||
opb = xorshift32();
|
||||
res_sw = riscv_emulate_sh1add(opa, opb);
|
||||
res_hw = riscv_intrinsic_sh1add(opa, opb);
|
||||
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
|
||||
}
|
||||
print_report(err_cnt, num_tests);
|
||||
|
||||
// SH2ADD
|
||||
neorv32_uart0_printf("\nSH2ADD:\n");
|
||||
err_cnt = 0;
|
||||
for (i=0;i<num_tests; i++) {
|
||||
opa = xorshift32();
|
||||
opb = xorshift32();
|
||||
res_sw = riscv_emulate_sh2add(opa, opb);
|
||||
res_hw = riscv_intrinsic_sh2add(opa, opb);
|
||||
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
|
||||
}
|
||||
print_report(err_cnt, num_tests);
|
||||
|
||||
// SH2ADD
|
||||
neorv32_uart0_printf("\nSH3ADD:\n");
|
||||
err_cnt = 0;
|
||||
for (i=0;i<num_tests; i++) {
|
||||
opa = xorshift32();
|
||||
res_sw = riscv_emulate_sh3add(opa, opb);
|
||||
res_hw = riscv_intrinsic_sh3add(opa, opb);
|
||||
err_cnt += check_result(i, opa, opb, res_sw, res_hw);
|
||||
}
|
||||
print_report(err_cnt, num_tests);
|
||||
|
||||
|
||||
neorv32_uart0_printf("\nBit manipulation extension tests done.\n");
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// #################################################################################################
|
||||
// # << NEORV32 - Intrinsics + Emulation Functions for the B CPU extensions >> #
|
||||
// # << NEORV32 - Intrinsics + Emulation Functions for the CPU B extension >> #
|
||||
// # ********************************************************************************************* #
|
||||
// # The intrinsics provided by this library allow to use the hardware bit manipulation unit of #
|
||||
// # the RISC-V B CPU extension without the need for B support by the compiler. #
|
||||
// # the RISC-V B CPU extension without the need for support by the compiler. #
|
||||
// # ********************************************************************************************* #
|
||||
// # BSD 3-Clause License #
|
||||
// # #
|
||||
|
@ -39,10 +39,10 @@
|
|||
/**********************************************************************//**
|
||||
* @file bitmanip_test/neorv32_b_extension_intrinsics.h
|
||||
* @author Stephan Nolting
|
||||
* @brief "Intrinsic" library for the NEORV32 bit manipulation Zbb extension.
|
||||
* @brief "Intrinsic" library for the NEORV32 bit manipulation B extension.
|
||||
* Also provides emulation functions for all intrinsics (functionality re-built in pure software).
|
||||
*
|
||||
* @warning This library is just a temporary fall-back until the Zbb extensions are supported by the upstream RISC-V GCC port.
|
||||
* @warning This library is just a temporary fall-back until the B extension is supported by the upstream RISC-V GCC port.
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef neorv32_b_extension_intrinsics_h
|
||||
|
@ -54,9 +54,9 @@
|
|||
// ################################################################################################
|
||||
|
||||
|
||||
// ---------------------------------------------
|
||||
// ================================================================================================
|
||||
// Zbb - Base instructions
|
||||
// ---------------------------------------------
|
||||
// ================================================================================================
|
||||
|
||||
/**********************************************************************//**
|
||||
* Intrinsic: Bit manipulation CLZ (count leading zeros) [B.Zbb]
|
||||
|
@ -455,14 +455,87 @@ inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_rev8(uint32_t rs
|
|||
}
|
||||
|
||||
|
||||
// ================================================================================================
|
||||
// Zbb - Base instructions
|
||||
// ================================================================================================
|
||||
|
||||
/**********************************************************************//**
|
||||
* Intrinsic: Address generation instructions SH1ADD (add with logical-1-shift) [B.Zba]
|
||||
*
|
||||
* @param[in] rs1 Source operand 1 (a0).
|
||||
* @param[in] rs2 Source operand 2 (a0).
|
||||
* @return Operand 2 + (Operand 1 << 1)
|
||||
**************************************************************************/
|
||||
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_sh1add(uint32_t rs1, uint32_t rs2) {
|
||||
|
||||
register uint32_t result __asm__ ("a0");
|
||||
register uint32_t tmp_a __asm__ ("a0") = rs1;
|
||||
register uint32_t tmp_b __asm__ ("a1") = rs2;
|
||||
|
||||
// dummy instruction to prevent GCC "constprop" optimization
|
||||
asm volatile ("" : [output] "=r" (result) : [input_i] "r" (tmp_a), [input_j] "r" (tmp_b));
|
||||
|
||||
// sh1add a0, a0, a1
|
||||
CUSTOM_INSTR_R2_TYPE(0b0010000, a1, a0, 0b010, a0, 0b0110011);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Intrinsic: Address generation instructions SH2ADD (add with logical-2-shift) [B.Zba]
|
||||
*
|
||||
* @param[in] rs1 Source operand 1 (a0).
|
||||
* @param[in] rs2 Source operand 2 (a0).
|
||||
* @return Operand 2 + (Operand 1 << 2)
|
||||
**************************************************************************/
|
||||
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_sh2add(uint32_t rs1, uint32_t rs2) {
|
||||
|
||||
register uint32_t result __asm__ ("a0");
|
||||
register uint32_t tmp_a __asm__ ("a0") = rs1;
|
||||
register uint32_t tmp_b __asm__ ("a1") = rs2;
|
||||
|
||||
// dummy instruction to prevent GCC "constprop" optimization
|
||||
asm volatile ("" : [output] "=r" (result) : [input_i] "r" (tmp_a), [input_j] "r" (tmp_b));
|
||||
|
||||
// sh2add a0, a0, a1
|
||||
CUSTOM_INSTR_R2_TYPE(0b0010000, a1, a0, 0b100, a0, 0b0110011);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
* Intrinsic: Address generation instructions SH1ADD (add with logical-3-shift) [B.Zba]
|
||||
*
|
||||
* @param[in] rs1 Source operand 1 (a0).
|
||||
* @param[in] rs2 Source operand 2 (a0).
|
||||
* @return Operand 2 + (Operand 1 << 3)
|
||||
**************************************************************************/
|
||||
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_sh3add(uint32_t rs1, uint32_t rs2) {
|
||||
|
||||
register uint32_t result __asm__ ("a0");
|
||||
register uint32_t tmp_a __asm__ ("a0") = rs1;
|
||||
register uint32_t tmp_b __asm__ ("a1") = rs2;
|
||||
|
||||
// dummy instruction to prevent GCC "constprop" optimization
|
||||
asm volatile ("" : [output] "=r" (result) : [input_i] "r" (tmp_a), [input_j] "r" (tmp_b));
|
||||
|
||||
// sh3add a0, a0, a1
|
||||
CUSTOM_INSTR_R2_TYPE(0b0010000, a1, a0, 0b110, a0, 0b0110011);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ################################################################################################
|
||||
// Emulation functions
|
||||
// ################################################################################################
|
||||
|
||||
|
||||
// ---------------------------------------------
|
||||
// ================================================================================================
|
||||
// Zbb - Base instructions
|
||||
// ---------------------------------------------
|
||||
// ================================================================================================
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
|
@ -783,5 +856,48 @@ uint32_t riscv_emulate_orcb(uint32_t rs1) {
|
|||
}
|
||||
|
||||
|
||||
// ================================================================================================
|
||||
// Zba - Address generation instructions
|
||||
// ================================================================================================
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Intrinsic: Address generation instructions SH1ADD (add with logical-1-shift) [emulation]
|
||||
*
|
||||
* @param[in] rs1 Source operand 1 (a0).
|
||||
* @param[in] rs2 Source operand 1 (a0).
|
||||
* @return Operand 2 + (Operand 1 << 1)
|
||||
**************************************************************************/
|
||||
uint32_t riscv_emulate_sh1add(uint32_t rs1, uint32_t rs2) {
|
||||
|
||||
return rs2 + (rs1 << 1);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Intrinsic: Address generation instructions SH2ADD (add with logical-2-shift) [emulation]
|
||||
*
|
||||
* @param[in] rs1 Source operand 1 (a0).
|
||||
* @param[in] rs2 Source operand 1 (a0).
|
||||
* @return Operand 2 + (Operand 1 << 2)
|
||||
**************************************************************************/
|
||||
uint32_t riscv_emulate_sh2add(uint32_t rs1, uint32_t rs2) {
|
||||
|
||||
return rs2 + (rs1 << 2);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Intrinsic: Address generation instructions SH3ADD (add with logical-3-shift) [emulation]
|
||||
*
|
||||
* @param[in] rs1 Source operand 1 (a0).
|
||||
* @param[in] rs2 Source operand 1 (a0).
|
||||
* @return Operand 2 + (Operand 1 << 3)
|
||||
**************************************************************************/
|
||||
uint32_t riscv_emulate_sh3add(uint32_t rs1, uint32_t rs2) {
|
||||
|
||||
return rs2 + (rs1 << 3);
|
||||
}
|
||||
|
||||
|
||||
#endif // neorv32_b_extension_intrinsics_h
|
||||
|
|
@ -1139,7 +1139,6 @@ enum NEORV32_SYSINFO_CPU_enum {
|
|||
SYSINFO_CPU_ZICSR = 0, /**< SYSINFO_CPU (0): Zicsr extension (I sub-extension) available when set (r/-) */
|
||||
SYSINFO_CPU_ZIFENCEI = 1, /**< SYSINFO_CPU (1): Zifencei extension (I sub-extension) available when set (r/-) */
|
||||
SYSINFO_CPU_ZMMUL = 2, /**< SYSINFO_CPU (2): Zmmul extension (M sub-extension) available when set (r/-) */
|
||||
SYSINFO_CPU_ZBB = 3, /**< SYSINFO_CPU (3): Zbb extension (B sub-extension) available when set (r/-) */
|
||||
|
||||
SYSINFO_CPU_ZFINX = 5, /**< SYSINFO_CPU (5): Zfinx extension (F sub-/alternative-extension) available when set (r/-) */
|
||||
SYSINFO_CPU_ZXSCNT = 6, /**< SYSINFO_CPU (6): Custom extension - Small CPU counters: "cycle" & "instret" CSRs have less than 64-bit when set (r/-) */
|
||||
|
|
|
@ -330,9 +330,6 @@ void neorv32_rte_print_hw_config(void) {
|
|||
if (tmp & (1<<SYSINFO_CPU_ZMMUL)) {
|
||||
neorv32_uart0_printf("Zmmul ");
|
||||
}
|
||||
if (tmp & (1<<SYSINFO_CPU_ZBB)) {
|
||||
neorv32_uart0_printf("Zbb ");
|
||||
}
|
||||
|
||||
if (tmp & (1<<SYSINFO_CPU_ZFINX)) {
|
||||
neorv32_uart0_printf("Zfinx ");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue