Add a single RV32M enum parameter to select multiplier implementation

This commit replaces the previous combination of `RV32M` bit parameter
used to en/disable the M extension and the `MultiplierImplementation`
used to select the multiplier implementation by a single enum parameter.

Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
This commit is contained in:
Pirmin Vogel 2020-08-19 11:12:35 +02:00
parent 4127a5464b
commit 2ef5e5e3f2
27 changed files with 288 additions and 343 deletions

View file

@ -116,10 +116,12 @@ The Multiplier/Divider (MULT/DIV) is a state machine driven block to perform mul
The fast and slow versions differ in multiplier only. All versions implement the same form of long division algorithm. The ALU block is used by the long division algorithm in all versions.
Multiplier
The multiplier can be implemented in three variants controlled via the parameter ``MultiplierImplementation``.
The multiplier can be implemented in three variants controlled via the enumerated parameter ``RV32M`` defined in :file:`rtl/ibex_pkg.sv`.
Single-Cycle Multiplier
This implementation is chosen by setting the ``MultiplierImplementation`` parameter to "single-cycle". The single-cycle multiplier makes use of three parallel multiplier units, designed to be mapped to hardware multiplier primitives on FPGAs. It is therefore the **first choice for FPGA synthesis**.
This implementation is chosen by setting the ``RV32M`` parameter to "ibex_pkg::RV32MSingleCycle".
The single-cycle multiplier makes use of three parallel multiplier units, designed to be mapped to hardware multiplier primitives on FPGAs.
It is therefore the **first choice for FPGA synthesis**.
- Using three parallel 17-bit x 17-bit multiplication units and a 34-bit accumulator, it completes a MUL instruction in 1 cycle. MULH is completed in 2 cycles.
- This MAC is internal to the mult/div block (no external ALU use).
@ -127,7 +129,8 @@ Multiplier
- ASIC synthesis has not yet been tested but is expected to consume 3-4x the area of the fast multiplier for ASIC.
Fast Multi-Cycle Multiplier
This implementation is chosen by setting the ``MultiplierImplementation`` parameter to "fast". The fast multi-cycle multiplier provides a reasonable trade-off between area and performance. It is the **first choice for ASIC synthesis**.
This implementation is chosen by setting the ``RV32M`` parameter to "ibex_pkg::RV32MFast".
The fast multi-cycle multiplier provides a reasonable trade-off between area and performance. It is the **first choice for ASIC synthesis**.
- Completes multiply in 3-4 cycles using a MAC (multiply accumulate) which is capable of a 17-bit x 17-bit multiplication with a 34-bit accumulator.
- A MUL instruction takes 3 cycles, MULH takes 4.
@ -136,7 +139,7 @@ Multiplier
- In some cases it may be desirable to replace this with a specific implementation such as an explicit gate level implementation.
Slow Multi-Cycle Multiplier
To select the slow multi-cycle multiplier, set the ``MultiplierImplementation`` parameter to "slow".
To select the slow multi-cycle multiplier, set the ``RV32M`` parameter to "ibex_pkg::RV32MSlow".
- Completes multiply in clog2(``op_b``) + 1 cycles (for MUL) or 33 cycles (for MULH) using a Baugh-Wooley multiplier.
- The ALU block is used to compute additions.
@ -149,6 +152,8 @@ Divider
- Cycle 2: Compute absolute value of operand B
- Cycles 4 - 36: Perform long division as described here: https://en.wikipedia.org/wiki/Division_algorithm#Integer_division_(unsigned)_with_remainder.
By setting the ``RV32M`` parameter to "ibex_pkg::RV32MNone", the M-extension can be disabled completely.
Control and Status Register Block (CSR)
---------------------------------------
Source File: :file:`rtl/ibex_cs_registers.sv`

View file

@ -18,9 +18,8 @@ Instantiation Template
.MHPMCounterNum ( 0 ),
.MHPMCounterWidth ( 40 ),
.RV32E ( 0 ),
.RV32M ( 1 ),
.RV32M ( ibex_pkg::RV32MFast ),
.RV32B ( ibex_pkg::RV32BNone ),
.MultiplierImplementation ( "fast" ),
.ICache ( 0 ),
.ICacheECC ( 0 ),
.SecureIbex ( 0 ),
@ -76,54 +75,53 @@ Instantiation Template
Parameters
----------
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| Name | Type/Range | Default | Description |
+==============================+===================+============+=================================================================+
+==============================+===================+============+=======================================================================+
| ``PMPEnable`` | bit | 0 | Enable PMP support |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``PMPGranularity`` | int (0..31) | 0 | Minimum granularity of PMP address matching |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``PMPNumRegions`` | int (1..16) | 4 | Number implemented PMP regions (ignored if PMPEnable == 0) |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``MHPMCounterNum`` | int (0..10) | 0 | Number of performance monitor event counters |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``MHPMCounterWidth`` | int (64..1) | 40 | Bit width of performance monitor event counters |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``RV32E`` | bit | 0 | RV32E mode enable (16 integer registers only) |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
| ``RV32M`` | bit | 1 | M(ultiply) extension enable |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``RV32M`` | ibex_pkg::rv32m_e | RV32MFast | M(ultiply) extension select: |
| | | | "ibex_pkg::RV32MNone": No M-extension |
| | | | "ibex_pkg::RV32MSlow": Slow multi-cycle multiplier, iterative divider |
| | | | "ibex_pkg::RV32MFast": 3-4 cycle multiplier, iterative divider |
| | | | "ibex_pkg::RV32MSingleCycle": 1-2 cycle multiplier, iterative divider |
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``RV32B`` | ibex_pkg::rv32b_e | RV32BNone | B(itmanipulation) extension select: |
| | | | "ibex_pkg::RV32BNone": No B-extension |
| | | | "ibex_pkg::RV32BBalanced": Sub-extensions Zbb, Zbs, Zbf and Zbt |
| | | | "ibex_pkg::RV32Full": All sub-extensions |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``BranchTargetALU`` | bit | 0 | *EXPERIMENTAL* - Enables branch target ALU removing a stall |
| | | | cycle from taken branches |
+------------------------------+------------------ +------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``WritebackStage`` | bit | 0 | *EXPERIMENTAL* - Enables third pipeline stage (writeback) |
| | | | improving performance of loads and stores |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
| ``MultiplierImplementation`` | string | "fast" | Multiplicator type: |
| | | | "slow": multi-cycle slow, |
| | | | "fast": multi-cycle fast, |
| | | | "single-cycle": single-cycle |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``ICache`` | bit | 0 | *EXPERIMENTAL* Enable instruction cache instead of prefetch |
| | | | buffer |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``ICacheECC`` | bit | 0 | *EXPERIMENTAL* Enable SECDED ECC protection in ICache (if |
| | | | ICache == 1) |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``SecureIbex`` | bit | 0 | *EXPERIMENTAL* Enable various additional features targeting |
| | | | secure code execution. |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``DbgTriggerEn`` | bit | 0 | Enable debug trigger support (one trigger only) |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``DmHaltAddr`` | int | 0x1A110800 | Address to jump to when entering Debug Mode |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
| ``DmExceptionAddr`` | int | 0x1A110808 | Address to jump to when an exception occurs while in Debug Mode |
+------------------------------+-------------------+------------+-----------------------------------------------------------------+
+------------------------------+-------------------+------------+-----------------------------------------------------------------------+
Any parameter marked *EXPERIMENTAL* when enabled is not verified to the same standard as the rest of the Ibex core.

View file

@ -19,7 +19,7 @@
// We use boolean top-level parameters.
// When building with fusesoc, these get set with defines like
// -GRV32M=1 (rather than -GRV32M=1'b1), leading to warnings like:
// -GRV32E=1 (rather than -GRV32E=1'b1), leading to warnings like:
//
// Operator VAR '<varname>' expects 1 bits on the Initial value, but
// Initial value's CONST '32'h1' generates 32 bits.

View file

@ -11,7 +11,7 @@ module tb_cs_registers #(
parameter int unsigned PMPGranularity = 0,
parameter int unsigned PMPNumRegions = 4,
parameter bit RV32E = 1'b0,
parameter bit RV32M = 1'b0
parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast
) (
// Clock and Reset
inout wire clk_i,

View file

@ -37,7 +37,7 @@ How to run RISC-V Compliance on Ibex
```sh
cd $IBEX_REPO_BASE
fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_riscv_compliance --RV32M=1 --RV32E=0
fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_riscv_compliance --RV32E=0 --RV32M=ibex_pkg::RV32MNone
```
You can use the two compile-time options `--RV32M` and `--RV32E` to

View file

@ -24,30 +24,24 @@ filesets:
parameters:
RV32M:
datatype: int
paramtype: vlogparam
default: 1
description: "Enable the M ISA extension (hardware multiply/divide) [0/1]"
RV32E:
datatype: int
paramtype: vlogparam
default: 0
description: "Enable the E ISA extension (reduced register set) [0/1]"
RV32M:
datatype: str
default: ibex_pkg::RV32MFast
paramtype: vlogdefine
description: "RV32M implementation parameter enum. See the ibex_pkg::rv32m_e enum in ibex_pkg.sv for permitted values."
RV32B:
datatype: str
default: ibex_pkg::RV32BNone
paramtype: vlogdefine
description: "Bitmanip implementation parameter enum. See the ibex_pkg::rv32b_e enum in ibex_pkg.sv for permitted values."
MultiplierImplementation:
datatype: str
paramtype: vlogparam
description: "Multiplier implementation. Valid values: fast, slow, single-cycle"
default: "fast"
BranchTargetALU:
datatype: int
paramtype: vlogparam
@ -85,10 +79,9 @@ targets:
- tool_verilator ? (files_verilator_waiver)
- files_sim_verilator
parameters:
- RV32M
- RV32E
- RV32M
- RV32B
- MultiplierImplementation
- BranchTargetALU
- WritebackStage
- PMPEnable

View file

@ -19,7 +19,7 @@
// We have some boolean top-level parameters in e.g. simple_system.sv.
// When building with fusesoc, these get set with defines like
// -GRV32M=1 (rather than -GRV32M=1'b1), leading to warnings like:
// -GRV32E=1 (rather than -GRV32E=1'b1), leading to warnings like:
//
// Operator VAR '<varname>' expects 1 bits on the Initial value, but
// Initial value's CONST '32'h1' generates 32 bits.

View file

@ -19,9 +19,8 @@ module ibex_riscv_compliance (
parameter int unsigned PMPGranularity = 0;
parameter int unsigned PMPNumRegions = 4;
parameter bit RV32E = 1'b0;
parameter bit RV32M = 1'b1;
parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast;
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone;
parameter MultiplierImplementation = "fast";
parameter bit BranchTargetALU = 1'b0;
parameter bit WritebackStage = 1'b0;
@ -116,7 +115,6 @@ module ibex_riscv_compliance (
.RV32E (RV32E ),
.RV32M (RV32M ),
.RV32B (RV32B ),
.MultiplierImplementation (MultiplierImplementation),
.BranchTargetALU (BranchTargetALU ),
.WritebackStage (WritebackStage ),
.DmHaltAddr (32'h00000000 ),

View file

@ -31,8 +31,8 @@ module core_ibex_tb_top;
// You cannot override string parameters in VCS via the command line so a `define is used instead
// that can be set from the command line. If no value has been specified this gives a default.
`ifndef IBEX_MULTIPLIER_IMPLEMENTATION
`define IBEX_MULTIPLIER_IMPLEMENTATION fast
`ifndef IBEX_CFG_RV32M
`define IBEX_CFG_RV32M ibex_pkg::RV32MFast
`endif
`ifndef IBEX_CFG_RV32B
@ -43,15 +43,11 @@ module core_ibex_tb_top;
parameter int unsigned PMPGranularity = 0;
parameter int unsigned PMPNumRegions = 4;
parameter bit RV32E = 1'b0;
parameter bit RV32M = 1'b1;
parameter ibex_pkg::rv32m_e RV32M = `IBEX_CFG_RV32M;
parameter ibex_pkg::rv32b_e RV32B = `IBEX_CFG_RV32B;
parameter bit BranchTargetALU = 1'b0;
parameter bit WritebackStage = 1'b0;
// VCS has issues taking a string as a define, so we have to build up the string via the
// pre-processor.
parameter MultiplierImplementation = `PRIM_STRINGIFY(`IBEX_CFG_MultiplierImplementation);
ibex_core_tracing #(
.DmHaltAddr (`BOOT_ADDR + 'h0 ),
.DmExceptionAddr (`BOOT_ADDR + 'h4 ),
@ -62,8 +58,7 @@ module core_ibex_tb_top;
.RV32M (RV32M ),
.RV32B (RV32B ),
.BranchTargetALU (BranchTargetALU ),
.WritebackStage (WritebackStage ),
.MultiplierImplementation (MultiplierImplementation)
.WritebackStage (WritebackStage )
) dut (
.clk_i (clk ),
.rst_ni (rst_n ),

View file

@ -28,7 +28,7 @@ The Simple System simulator binary can be built via FuseSoC. From the Ibex
repository root run:
```
fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_simple_system --RV32M=1 --RV32E=0
fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_simple_system --RV32E=0 --RV32M=ibex_pkg::RV32MFast
```
## Building Software
@ -103,7 +103,7 @@ The simulator produces several output files
Similar to the Verilator flow the Simple System simulator binary can be built using:
```
fusesoc --cores-root=. run --target=sim --tool=vcs --setup --build lowrisc:ibex:ibex_simple_system --RV32M=1 --RV32E=0 --SRAMInitFile=`<sw_vmem_file>`
fusesoc --cores-root=. run --target=sim --tool=vcs --setup --build lowrisc:ibex:ibex_simple_system --RV32E=0 --RV32M=ibex_pkg::RV32MFast --SRAMInitFile=`<sw_vmem_file>`
```
`<sw_vmem_file>` should be a path to a vmem file built as described above, use
@ -123,7 +123,7 @@ Pass `-gui` to use the DVE GUI.
To build and run Simple System run:
```
fusesoc --cores-root=. run --target=sim --tool=rivierapro lowrisc:ibex:ibex_simple_system --RV32M=1 --RV32E=0 --SRAMInitFile=\"$(readlink -f <sw_vmem_file>)\"
fusesoc --cores-root=. run --target=sim --tool=rivierapro lowrisc:ibex:ibex_simple_system --RV32E=0 --RV32M=ibex_pkg::RV32MFast --SRAMInitFile=\"$(readlink -f <sw_vmem_file>)\"
```
`<sw_vmem_file>` should be a path to a vmem file built as described above, use

View file

@ -23,18 +23,18 @@ filesets:
- lint/verilator_waiver.vlt: {file_type: vlt}
parameters:
RV32M:
datatype: int
paramtype: vlogparam
default: 1
description: "Enable the M ISA extension (hardware multiply/divide) [0/1]"
RV32E:
datatype: int
paramtype: vlogparam
default: 0
description: "Enable the E ISA extension (reduced register set) [0/1]"
RV32M:
datatype: str
default: ibex_pkg::RV32MFast
paramtype: vlogdefine
description: "RV32M implementation parameter enum. See the ibex_pkg::rv32m_e enum in ibex_pkg.sv for permitted values."
RV32B:
datatype: str
default: ibex_pkg::RV32BNone
@ -46,12 +46,6 @@ parameters:
paramtype: vlogparam
description: "Path to a vmem file to initialize the RAM with"
MultiplierImplementation:
datatype: str
paramtype: vlogparam
description: "Multiplier implementation. Valid values: fast, slow, single-cycle"
default: "fast"
BranchTargetALU:
datatype: int
paramtype: vlogparam
@ -95,10 +89,9 @@ targets:
- files_sim
toplevel: ibex_simple_system
parameters:
- RV32M
- RV32E
- RV32M
- RV32B
- MultiplierImplementation
- BranchTargetALU
- WritebackStage
- SecureIbex

View file

@ -19,7 +19,7 @@
// We have some boolean top-level parameters in e.g. simple_system.sv.
// When building with fusesoc, these get set with defines like
// -GRV32M=1 (rather than -GRV32M=1'b1), leading to warnings like:
// -GRV32E=1 (rather than -GRV32E=1'b1), leading to warnings like:
//
// Operator VAR '<varname>' expects 1 bits on the Initial value, but
// Initial value's CONST '32'h1' generates 32 bits.

View file

@ -2,6 +2,10 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
`ifndef RV32M
`define RV32M ibex_pkg::RV32MFast
`endif
`ifndef RV32B
`define RV32B ibex_pkg::RV32BNone
`endif
@ -28,11 +32,10 @@ module ibex_simple_system (
parameter int unsigned PMPGranularity = 0;
parameter int unsigned PMPNumRegions = 4;
parameter bit RV32E = 1'b0;
parameter bit RV32M = 1'b1;
parameter ibex_pkg::rv32m_e RV32M = `RV32M;
parameter ibex_pkg::rv32b_e RV32B = `RV32B;
parameter bit BranchTargetALU = 1'b0;
parameter bit WritebackStage = 1'b0;
parameter MultiplierImplementation = "fast";
parameter SRAMInitFile = "";
logic clk_sys = 1'b0, rst_sys_n;
@ -157,7 +160,6 @@ module ibex_simple_system (
.RV32B ( RV32B ),
.BranchTargetALU ( BranchTargetALU ),
.WritebackStage ( WritebackStage ),
.MultiplierImplementation ( MultiplierImplementation ),
.DmHaltAddr ( 32'h00100000 ),
.DmExceptionAddr ( 32'h00100000 )
) u_core (

View file

@ -11,7 +11,7 @@ All of these benchmarks run on Simple System. A verilator simulation suitable
for running them can be built with:
```
fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_simple_system --RV32M=1 --RV32E=0
fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_simple_system --RV32E=0 --RV32M=ibex_pkg::RV32MFast
```
See examples/simple_system/README.md for full details.

View file

@ -9,11 +9,10 @@
# (4 cycles for mulh), resulting in 2 stall cycles for mul (3 for mulh)
small:
RV32E : 0
RV32M : 1
RV32M : "ibex_pkg::RV32MFast"
RV32B : "ibex_pkg::RV32BNone"
BranchTargetALU : 0
WritebackStage : 0
MultiplierImplementation : "fast"
PMPEnable : 0
PMPGranularity : 0
PMPNumRegions : 4
@ -27,11 +26,10 @@ small:
# maximum performance configuration.
experimental-maxperf:
RV32E : 0
RV32M : 1
RV32M : "ibex_pkg::RV32MSingleCycle"
RV32B : "ibex_pkg::RV32BNone"
BranchTargetALU : 1
WritebackStage : 1
MultiplierImplementation : "single-cycle"
PMPEnable : 0
PMPGranularity : 0
PMPNumRegions : 4
@ -39,11 +37,10 @@ experimental-maxperf:
# experimental-maxperf config above plus PMP enabled with 16 regions.
experimental-maxperf-pmp:
RV32E : 0
RV32M : 1
RV32M : "ibex_pkg::RV32MSingleCycle"
RV32B : "ibex_pkg::RV32BNone"
BranchTargetALU : 1
WritebackStage : 1
MultiplierImplementation : "single-cycle"
PMPEnable : 1
PMPGranularity : 0
PMPNumRegions : 16
@ -51,11 +48,10 @@ experimental-maxperf-pmp:
# experimental-maxperf-pmp config above with balanced bitmanip extension
experimental-maxperf-pmp-bmbalanced:
RV32E : 0
RV32M : 1
RV32M : "ibex_pkg::RV32MSingleCycle"
RV32B : "ibex_pkg::RV32BBalanced"
BranchTargetALU : 1
WritebackStage : 1
MultiplierImplementation : "single-cycle"
PMPEnable : 1
PMPGranularity : 0
PMPNumRegions : 16
@ -63,11 +59,10 @@ experimental-maxperf-pmp-bmbalanced:
# experimental-maxperf-pmp config above with full bitmanip extension
experimental-maxperf-pmp-bmfull:
RV32E : 0
RV32M : 1
RV32M : "ibex_pkg::RV32MSingleCycle"
RV32B : "ibex_pkg::RV32BFull"
BranchTargetALU : 1
WritebackStage : 1
MultiplierImplementation : "single-cycle"
PMPEnable : 1
PMPGranularity : 0
PMPNumRegions : 16

View file

@ -72,9 +72,10 @@ parameters:
paramtype: vlogparam
RV32M:
datatype: int
default: 1
paramtype: vlogparam
datatype: str
default: ibex_pkg::RV32MFast
paramtype: vlogdefine
description: "RV32M implementation parameter enum. See the ibex_pkg::rv32m_e enum in ibex_pkg.sv for permitted values."
RV32B:
datatype: str
@ -82,12 +83,6 @@ parameters:
paramtype: vlogdefine
description: "Bitmanip implementation parameter enum. See the ibex_pkg::rv32b_e enum in ibex_pkg.sv for permitted values."
MultiplierImplementation:
datatype: str
paramtype: vlogparam
description: "Multiplier implementation. Valid values: fast, slow, single-cycle"
default: "fast"
ICache:
datatype: int
default: 0

View file

@ -30,9 +30,10 @@ parameters:
paramtype: vlogparam
RV32M:
datatype: int
default: 1
paramtype: vlogparam
datatype: str
default: ibex_pkg::RV32MFast
paramtype: vlogdefine
description: "RV32M implementation parameter enum. See the ibex_pkg::rv32m_e enum in ibex_pkg.sv for permitted values."
RV32B:
datatype: str
@ -40,12 +41,6 @@ parameters:
paramtype: vlogdefine
description: "Bitmanip implementation parameter enum. See the ibex_pkg::rv32b_e enum in ibex_pkg.sv for permitted values."
MultiplierImplementation:
datatype: str
paramtype: vlogparam
description: "Multiplier implementation. Valid values: fast, slow, single-cycle"
default: "fast"
ICache:
datatype: int
default: 0
@ -107,12 +102,11 @@ targets:
parameters:
- RVFI=true
- SYNTHESIS=true
- RV32M
- RV32E
- RV32M
- RV32B
- BranchTargetALU
- WritebackStage
- MultiplierImplementation
- SecureIbex
- PMPEnable
- PMPGranularity

View file

@ -19,11 +19,10 @@ module ibex_core #(
parameter int unsigned MHPMCounterNum = 0,
parameter int unsigned MHPMCounterWidth = 40,
parameter bit RV32E = 1'b0,
parameter bit RV32M = 1'b1,
parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast,
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone,
parameter bit BranchTargetALU = 1'b0,
parameter bit WritebackStage = 1'b0,
parameter MultiplierImplementation = "fast",
parameter bit ICache = 1'b0,
parameter bit ICacheECC = 1'b0,
parameter bit DbgTriggerEn = 1'b0,
@ -624,8 +623,7 @@ module ibex_core #(
ibex_ex_block #(
.RV32M ( RV32M ),
.RV32B ( RV32B ),
.BranchTargetALU ( BranchTargetALU ),
.MultiplierImplementation ( MultiplierImplementation )
.BranchTargetALU ( BranchTargetALU )
) ex_block_i (
.clk_i ( clk ),
.rst_ni ( rst_ni ),

View file

@ -13,11 +13,10 @@ module ibex_core_tracing #(
parameter int unsigned MHPMCounterNum = 0,
parameter int unsigned MHPMCounterWidth = 40,
parameter bit RV32E = 1'b0,
parameter bit RV32M = 1'b1,
parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast,
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone,
parameter bit BranchTargetALU = 1'b0,
parameter bit WritebackStage = 1'b0,
parameter MultiplierImplementation = "fast",
parameter bit ICache = 1'b0,
parameter bit ICacheECC = 1'b0,
parameter bit DbgTriggerEn = 1'b0,
@ -112,7 +111,6 @@ module ibex_core_tracing #(
.RV32M ( RV32M ),
.RV32B ( RV32B ),
.BranchTargetALU ( BranchTargetALU ),
.MultiplierImplementation ( MultiplierImplementation ),
.ICache ( ICache ),
.ICacheECC ( ICacheECC ),
.DbgTriggerEn ( DbgTriggerEn ),

View file

@ -23,7 +23,7 @@ module ibex_cs_registers #(
parameter int unsigned PMPGranularity = 0,
parameter int unsigned PMPNumRegions = 4,
parameter bit RV32E = 0,
parameter bit RV32M = 0
parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast
) (
// Clock and Reset
input logic clk_i,
@ -116,6 +116,8 @@ module ibex_cs_registers #(
import ibex_pkg::*;
localparam int unsigned RV32MEnabled = (RV32M == RV32MNone) ? 0 : 1;
// misa
localparam logic [31:0] MISA_VALUE =
(0 << 0) // A - Atomic Instructions extension
@ -124,7 +126,7 @@ module ibex_cs_registers #(
| (32'(RV32E) << 4) // E - RV32E base ISA
| (0 << 5) // F - Single precision floating-point extension
| (32'(!RV32E) << 8) // I - RV32I/64I/128I base ISA
| (32'(RV32M) << 12) // M - Integer Multiply/Divide extension
| (RV32MEnabled << 12) // M - Integer Multiply/Divide extension
| (0 << 13) // N - User level interrupts supported
| (0 << 18) // S - Supervisor mode implemented
| (1 << 20) // U - User mode implemented

View file

@ -15,9 +15,9 @@
module ibex_decoder #(
parameter bit RV32E = 0,
parameter bit RV32M = 1,
parameter bit BranchTargetALU = 0,
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone
parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast,
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone,
parameter bit BranchTargetALU = 0
) (
input logic clk_i,
input logic rst_ni,
@ -486,42 +486,42 @@ module ibex_decoder #(
{7'b000_0001, 3'b000}: begin // mul
multdiv_operator_o = MD_OP_MULL;
multdiv_signed_mode_o = 2'b00;
illegal_insn = RV32M ? 1'b0 : 1'b1;
illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
end
{7'b000_0001, 3'b001}: begin // mulh
multdiv_operator_o = MD_OP_MULH;
multdiv_signed_mode_o = 2'b11;
illegal_insn = RV32M ? 1'b0 : 1'b1;
illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
end
{7'b000_0001, 3'b010}: begin // mulhsu
multdiv_operator_o = MD_OP_MULH;
multdiv_signed_mode_o = 2'b01;
illegal_insn = RV32M ? 1'b0 : 1'b1;
illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
end
{7'b000_0001, 3'b011}: begin // mulhu
multdiv_operator_o = MD_OP_MULH;
multdiv_signed_mode_o = 2'b00;
illegal_insn = RV32M ? 1'b0 : 1'b1;
illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
end
{7'b000_0001, 3'b100}: begin // div
multdiv_operator_o = MD_OP_DIV;
multdiv_signed_mode_o = 2'b11;
illegal_insn = RV32M ? 1'b0 : 1'b1;
illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
end
{7'b000_0001, 3'b101}: begin // divu
multdiv_operator_o = MD_OP_DIV;
multdiv_signed_mode_o = 2'b00;
illegal_insn = RV32M ? 1'b0 : 1'b1;
illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
end
{7'b000_0001, 3'b110}: begin // rem
multdiv_operator_o = MD_OP_REM;
multdiv_signed_mode_o = 2'b11;
illegal_insn = RV32M ? 1'b0 : 1'b1;
illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
end
{7'b000_0001, 3'b111}: begin // remu
multdiv_operator_o = MD_OP_REM;
multdiv_signed_mode_o = 2'b00;
illegal_insn = RV32M ? 1'b0 : 1'b1;
illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
end
default: begin
illegal_insn = 1'b1;
@ -1037,35 +1037,35 @@ module ibex_decoder #(
// RV32M instructions, all use the same ALU operation
{7'b000_0001, 3'b000}: begin // mul
alu_operator_o = ALU_ADD;
mult_sel_o = RV32M ? 1'b1 : 1'b0;
mult_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
end
{7'b000_0001, 3'b001}: begin // mulh
alu_operator_o = ALU_ADD;
mult_sel_o = RV32M ? 1'b1 : 1'b0;
mult_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
end
{7'b000_0001, 3'b010}: begin // mulhsu
alu_operator_o = ALU_ADD;
mult_sel_o = RV32M ? 1'b1 : 1'b0;
mult_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
end
{7'b000_0001, 3'b011}: begin // mulhu
alu_operator_o = ALU_ADD;
mult_sel_o = RV32M ? 1'b1 : 1'b0;
mult_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
end
{7'b000_0001, 3'b100}: begin // div
alu_operator_o = ALU_ADD;
div_sel_o = RV32M ? 1'b1 : 1'b0;
div_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
end
{7'b000_0001, 3'b101}: begin // divu
alu_operator_o = ALU_ADD;
div_sel_o = RV32M ? 1'b1 : 1'b0;
div_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
end
{7'b000_0001, 3'b110}: begin // rem
alu_operator_o = ALU_ADD;
div_sel_o = RV32M ? 1'b1 : 1'b0;
div_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
end
{7'b000_0001, 3'b111}: begin // remu
alu_operator_o = ALU_ADD;
div_sel_o = RV32M ? 1'b1 : 1'b0;
div_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
end
default: ;

View file

@ -9,10 +9,9 @@
* Execution block: Hosts ALU and MUL/DIV unit
*/
module ibex_ex_block #(
parameter bit RV32M = 1,
parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast,
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone,
parameter bit BranchTargetALU = 0,
parameter MultiplierImplementation = "fast"
parameter bit BranchTargetALU = 0
) (
input logic clk_i,
input logic rst_ni,
@ -70,11 +69,11 @@ module ibex_ex_block #(
logic [ 1:0] multdiv_imd_val_we;
/*
The multdiv_i output is never selected if RV32M=0
The multdiv_i output is never selected if RV32M=RV32MNone
At synthesis time, all the combinational and sequential logic
from the multdiv_i module are eliminated
*/
if (RV32M) begin : gen_multdiv_m
if (RV32M != RV32MNone) begin : gen_multdiv_m
assign multdiv_sel = mult_sel_i | div_sel_i;
end else begin : gen_multdiv_no_m
assign multdiv_sel = 1'b0;
@ -138,7 +137,7 @@ module ibex_ex_block #(
// Multiplier //
////////////////
if (MultiplierImplementation == "slow") begin : gen_multdiv_slow
if (RV32M == RV32MSlow) begin : gen_multdiv_slow
ibex_multdiv_slow multdiv_i (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
@ -163,36 +162,9 @@ module ibex_ex_block #(
.multdiv_ready_id_i ( multdiv_ready_id_i ),
.multdiv_result_o ( multdiv_result )
);
end else if (MultiplierImplementation == "fast") begin : gen_multdiv_fast
end else if (RV32M == RV32MFast || RV32M == RV32MSingleCycle) begin : gen_multdiv_fast
ibex_multdiv_fast # (
.SingleCycleMultiply (0)
) multdiv_i (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.mult_en_i ( mult_en_i ),
.div_en_i ( div_en_i ),
.mult_sel_i ( mult_sel_i ),
.div_sel_i ( div_sel_i ),
.operator_i ( multdiv_operator_i ),
.signed_mode_i ( multdiv_signed_mode_i ),
.op_a_i ( multdiv_operand_a_i ),
.op_b_i ( multdiv_operand_b_i ),
.alu_operand_a_o ( multdiv_alu_operand_a ),
.alu_operand_b_o ( multdiv_alu_operand_b ),
.alu_adder_ext_i ( alu_adder_result_ext ),
.alu_adder_i ( alu_adder_result_ex_o ),
.equal_to_zero_i ( alu_is_equal_result ),
.data_ind_timing_i ( data_ind_timing_i ),
.imd_val_q_i ( imd_val_q_i ),
.imd_val_d_o ( multdiv_imd_val_d ),
.imd_val_we_o ( multdiv_imd_val_we ),
.multdiv_ready_id_i ( multdiv_ready_id_i ),
.valid_o ( multdiv_valid ),
.multdiv_result_o ( multdiv_result )
);
end else if (MultiplierImplementation == "single-cycle") begin: gen_multdiv_single_cycle
ibex_multdiv_fast #(
.SingleCycleMultiply(1)
.RV32M ( RV32M )
) multdiv_i (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),

View file

@ -18,7 +18,7 @@
module ibex_id_stage #(
parameter bit RV32E = 0,
parameter bit RV32M = 1,
parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast,
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone,
parameter bit DataIndTiming = 1'b0,
parameter bit BranchTargetALU = 0,

View file

@ -15,7 +15,7 @@
`include "prim_assert.sv"
module ibex_multdiv_fast #(
parameter bit SingleCycleMultiply = 0
parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast
) (
input logic clk_i,
input logic rst_ni,
@ -132,7 +132,7 @@ module ibex_multdiv_fast #(
// The single cycle multiplier uses three 17 bit multipliers to compute MUL instructions in a
// single cycle and MULH instructions in two cycles.
if (SingleCycleMultiply) begin : gen_multiv_single_cycle
if (RV32M == RV32MSingleCycle) begin : gen_mult_single_cycle
typedef enum logic {
MULL, MULH
@ -249,7 +249,7 @@ module ibex_multdiv_fast #(
// The fast multiplier uses one 17 bit multiplier to compute MUL instructions in 3 cycles
// and MULH instructions in 4 cycles.
end else begin : gen_multdiv_fast
end else begin : gen_mult_fast
logic [15:0] mult_op_a;
logic [15:0] mult_op_b;
@ -365,7 +365,7 @@ module ibex_multdiv_fast #(
// States must be knwon/valid.
`ASSERT_KNOWN(IbexMultStateKnown, mult_state_q)
end // gen_multdiv_fast
end // gen_mult_fast
// Divider
assign res_adder_h = alu_adder_ext_i[33:1];

View file

@ -8,9 +8,16 @@
*/
package ibex_pkg;
/////////////////////////
// RV32B Paramter Enum //
/////////////////////////
/////////////////////
// Parameter Enums //
/////////////////////
typedef enum integer {
RV32MNone = 0,
RV32MSlow = 1,
RV32MFast = 2,
RV32MSingleCycle = 3
} rv32m_e;
typedef enum integer {
RV32BNone = 0,

View file

@ -16,7 +16,7 @@ set_flow_bool_var timing_run 0 "timing run"
set_flow_bool_var ibex_branch_target_alu 0 "Enable branch target ALU in Ibex"
set_flow_bool_var ibex_writeback_stage 0 "Enable writeback stage in Ibex"
set_flow_var ibex_bitmanip 0 "Bitmanip extenion setting for Ibex (see ibex_pkg::rv32b_e for permitted values. Enum names are not supported in Yosys.)"
set_flow_var ibex_multiplier "fast" "Multiplier implementation for Ibex (slow/fast/single-cycle)"
set_flow_var ibex_multiplier 2 "Multiplier extension setting for Ibex (see ibex_pkg::rv32m_e for permitted values. Enum names are not supported in Yosys.)"
source $lr_synth_config_file

View file

@ -26,7 +26,7 @@ if { $lr_synth_ibex_writeback_stage } {
yosys "chparam -set RV32B $lr_synth_ibex_bitmanip ibex_core"
yosys "chparam -set MultiplierImplementation \"$lr_synth_ibex_multiplier\" ibex_core"
yosys "chparam -set RV32M $lr_synth_ibex_multiplier ibex_core"
yosys "synth $flatten_opt -top $lr_synth_top_module"
yosys "opt -purge"