Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[B ISA Extension] Rework and addition of Zba subset #190

Merged
merged 11 commits into from
Oct 29, 2021
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand 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)]
Expand All @@ -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)]
Expand Down
89 changes: 49 additions & 40 deletions docs/datasheet/cpu.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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]
Expand Down
26 changes: 13 additions & 13 deletions docs/datasheet/soc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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_

Expand Down Expand Up @@ -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_

Expand Down Expand Up @@ -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.**
|======


Expand Down
1 change: 0 additions & 1 deletion docs/datasheet/soc_sysinfo.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Binary file modified docs/figures/neorv32_processor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions rtl/core/neorv32_cpu.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -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.?
Expand Down Expand Up @@ -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", "") &
Expand Down Expand Up @@ -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.?
Expand Down Expand Up @@ -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 --
Expand Down
27 changes: 14 additions & 13 deletions rtl/core/neorv32_cpu_alu.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -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 --
Expand Down Expand Up @@ -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;
Expand Down
Loading