mirror of
https://github.com/lowRISC/ibex.git
synced 2025-06-28 09:17:17 -04:00
[RTL] Added seperate ALU for branch target
On branches now compute target same cycle as the condition. This removes a stall cycle from all taken conditional branches.
This commit is contained in:
parent
32a69899a9
commit
639964514c
17 changed files with 205 additions and 57 deletions
|
@ -87,6 +87,9 @@ Parameters
|
||||||
+------------------------------+-------------+------------+-----------------------------------------------------------------+
|
+------------------------------+-------------+------------+-----------------------------------------------------------------+
|
||||||
| ``RV32M`` | bit | 1 | M(ultiply) extension enable |
|
| ``RV32M`` | bit | 1 | M(ultiply) extension enable |
|
||||||
+------------------------------+-------------+------------+-----------------------------------------------------------------+
|
+------------------------------+-------------+------------+-----------------------------------------------------------------+
|
||||||
|
| ``BranchTargetALU`` | bit | 0 | *EXPERIMENTAL* - Enables branch target ALU removing a stall |
|
||||||
|
| | | | cycle from taken branches |
|
||||||
|
+------------------------------+-------------+------------+-----------------------------------------------------------------+
|
||||||
| ``MultiplierImplementation`` | string | "fast" | Multiplicator type, "slow", or "fast" |
|
| ``MultiplierImplementation`` | string | "fast" | Multiplicator type, "slow", or "fast" |
|
||||||
+------------------------------+-------------+------------+-----------------------------------------------------------------+
|
+------------------------------+-------------+------------+-----------------------------------------------------------------+
|
||||||
| ``DbgTriggerEn`` | bit | 0 | Enable debug trigger support (one trigger only) |
|
| ``DbgTriggerEn`` | bit | 0 | Enable debug trigger support (one trigger only) |
|
||||||
|
@ -96,6 +99,8 @@ Parameters
|
||||||
| ``DmExceptionAddr`` | int | 0x1A110808 | Address to jump to when an exception occurs while in 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.
|
||||||
|
|
||||||
Interfaces
|
Interfaces
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
|
|
@ -67,13 +67,17 @@ Read the description for more information.
|
||||||
+-----------------------+-----------------------+-------------------------------------------------------------+
|
+-----------------------+-----------------------+-------------------------------------------------------------+
|
||||||
| Branch (Taken) | 2 - N | Any branch where the condition is met will stall for 2 |
|
| Branch (Taken) | 2 - N | Any branch where the condition is met will stall for 2 |
|
||||||
| | | cycles as in the first cycle the branch is in ID/EX the ALU |
|
| | | cycles as in the first cycle the branch is in ID/EX the ALU |
|
||||||
| | | is used to calculate the branch condition. The following |
|
| | 1 - N (Branch Target | is used to calculate the branch condition. The following |
|
||||||
| | | cycle the ALU is used again to calculate the branch target |
|
| | ALU enabled) | cycle the ALU is used again to calculate the branch target |
|
||||||
| | | where it proceeds as Jump does above (Flush IF stage and |
|
| | | where it proceeds as Jump does above (Flush IF stage and |
|
||||||
| | | prefetch buffer, new PC on instruction-side memory |
|
| | | prefetch buffer, new PC on instruction-side memory |
|
||||||
| | | interface the same cycle it is calculated). The longer the |
|
| | | interface the same cycle it is calculated). The longer the |
|
||||||
| | | instruction-side memory interface takes to receive data the |
|
| | | instruction-side memory interface takes to receive data the |
|
||||||
| | | longer the branch will stall. |
|
| | | longer the branch will stall. With the parameter |
|
||||||
|
| | | ``BranchTargetALU`` set to ``1`` a seperate ALU calculates |
|
||||||
|
| | | the branch target simultaneously to calculating the branch |
|
||||||
|
| | | condition with the main ALU so 1 less stall cycle is |
|
||||||
|
| | | required |
|
||||||
+-----------------------+-----------------------+-------------------------------------------------------------+
|
+-----------------------+-----------------------+-------------------------------------------------------------+
|
||||||
| Instruction Fence | 1 - N | The FENCE.I instruction as defined in 'Zifencei' of the |
|
| Instruction Fence | 1 - N | The FENCE.I instruction as defined in 'Zifencei' of the |
|
||||||
| | | RISC-V specification. Internally it is implemented as a |
|
| | | RISC-V specification. Internally it is implemented as a |
|
||||||
|
|
|
@ -29,6 +29,11 @@ parameters:
|
||||||
paramtype: vlogparam
|
paramtype: vlogparam
|
||||||
default: 0
|
default: 0
|
||||||
description: Enable the E ISA extension (reduced register set) [0/1]
|
description: Enable the E ISA extension (reduced register set) [0/1]
|
||||||
|
BranchTargetALU:
|
||||||
|
datatype: int
|
||||||
|
paramtype: vlogparam
|
||||||
|
default: 0
|
||||||
|
description: Enables seperate branch target ALU (increasing branch performance EXPERIMENTAL) [0/1]
|
||||||
|
|
||||||
targets:
|
targets:
|
||||||
sim:
|
sim:
|
||||||
|
@ -38,6 +43,7 @@ targets:
|
||||||
parameters:
|
parameters:
|
||||||
- RV32M
|
- RV32M
|
||||||
- RV32E
|
- RV32E
|
||||||
|
- BranchTargetALU
|
||||||
toplevel: ibex_riscv_compliance
|
toplevel: ibex_riscv_compliance
|
||||||
tools:
|
tools:
|
||||||
verilator:
|
verilator:
|
||||||
|
|
|
@ -17,6 +17,7 @@ module ibex_riscv_compliance (
|
||||||
|
|
||||||
parameter bit RV32E = 0;
|
parameter bit RV32E = 0;
|
||||||
parameter bit RV32M = 1;
|
parameter bit RV32M = 1;
|
||||||
|
parameter bit BranchTargetALU = 0;
|
||||||
|
|
||||||
logic clk_sys, rst_sys_n;
|
logic clk_sys, rst_sys_n;
|
||||||
|
|
||||||
|
@ -104,7 +105,8 @@ module ibex_riscv_compliance (
|
||||||
.DmHaltAddr(32'h00000000),
|
.DmHaltAddr(32'h00000000),
|
||||||
.DmExceptionAddr(32'h00000000),
|
.DmExceptionAddr(32'h00000000),
|
||||||
.RV32E(RV32E),
|
.RV32E(RV32E),
|
||||||
.RV32M(RV32M)
|
.RV32M(RV32M),
|
||||||
|
.BranchTargetALU(BranchTargetALU)
|
||||||
) u_core (
|
) u_core (
|
||||||
.clk_i (clk_sys),
|
.clk_i (clk_sys),
|
||||||
.rst_ni (rst_sys_n),
|
.rst_ni (rst_sys_n),
|
||||||
|
|
|
@ -32,6 +32,11 @@ parameters:
|
||||||
datatype: str
|
datatype: str
|
||||||
paramtype: vlogdefine
|
paramtype: vlogdefine
|
||||||
description: Path to a vmem file to initialize the RAM with
|
description: Path to a vmem file to initialize the RAM with
|
||||||
|
BranchTargetALU:
|
||||||
|
datatype: int
|
||||||
|
paramtype: vlogparam
|
||||||
|
default: 0
|
||||||
|
description: Enables seperate branch target ALU (increasing branch performance EXPERIMENTAL) [0/1]
|
||||||
|
|
||||||
targets:
|
targets:
|
||||||
sim:
|
sim:
|
||||||
|
@ -41,6 +46,7 @@ targets:
|
||||||
parameters:
|
parameters:
|
||||||
- RV32M
|
- RV32M
|
||||||
- RV32E
|
- RV32E
|
||||||
|
- BranchTargetALU
|
||||||
- SRAM_INIT_FILE
|
- SRAM_INIT_FILE
|
||||||
toplevel: ibex_simple_system
|
toplevel: ibex_simple_system
|
||||||
tools:
|
tools:
|
||||||
|
|
|
@ -20,6 +20,7 @@ module ibex_simple_system (
|
||||||
|
|
||||||
parameter bit RV32E = 0;
|
parameter bit RV32E = 0;
|
||||||
parameter bit RV32M = 1;
|
parameter bit RV32M = 1;
|
||||||
|
parameter bit BranchTargetALU = 0;
|
||||||
|
|
||||||
logic clk_sys = 1'b0, rst_sys_n;
|
logic clk_sys = 1'b0, rst_sys_n;
|
||||||
|
|
||||||
|
@ -137,7 +138,8 @@ module ibex_simple_system (
|
||||||
.DmHaltAddr(32'h00100000),
|
.DmHaltAddr(32'h00100000),
|
||||||
.DmExceptionAddr(32'h00100000),
|
.DmExceptionAddr(32'h00100000),
|
||||||
.RV32E(RV32E),
|
.RV32E(RV32E),
|
||||||
.RV32M(RV32M)
|
.RV32M(RV32M),
|
||||||
|
.BranchTargetALU(BranchTargetALU)
|
||||||
) u_core (
|
) u_core (
|
||||||
.clk_i (clk_sys),
|
.clk_i (clk_sys),
|
||||||
.rst_ni (rst_sys_n),
|
.rst_ni (rst_sys_n),
|
||||||
|
|
|
@ -63,6 +63,12 @@ parameters:
|
||||||
description: "Multiplier implementation. Valid values: fast, slow"
|
description: "Multiplier implementation. Valid values: fast, slow"
|
||||||
default: fast
|
default: fast
|
||||||
|
|
||||||
|
BranchTargetALU:
|
||||||
|
datatype: int
|
||||||
|
paramtype: vlogparam
|
||||||
|
default: 0
|
||||||
|
description: "Enables seperate branch target ALU (increasing branch performance EXPERIMENTAL) [0/1]"
|
||||||
|
|
||||||
targets:
|
targets:
|
||||||
default:
|
default:
|
||||||
filesets:
|
filesets:
|
||||||
|
|
|
@ -46,6 +46,12 @@ parameters:
|
||||||
description: "Multiplier implementation. Valid values: fast, slow"
|
description: "Multiplier implementation. Valid values: fast, slow"
|
||||||
default: fast
|
default: fast
|
||||||
|
|
||||||
|
BranchTargetALU:
|
||||||
|
datatype: int
|
||||||
|
paramtype: vlogparam
|
||||||
|
default: 0
|
||||||
|
description: "Enables seperate branch target ALU (increasing branch performance EXPERIMENTAL) [0/1]"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
targets:
|
targets:
|
||||||
|
|
|
@ -47,12 +47,12 @@ lint_off -msg UNUSED -file "*/rtl/ibex_register_file_fpga.sv" -lines 22
|
||||||
// Signal is not used: clk_i
|
// Signal is not used: clk_i
|
||||||
// leaving clk and reset connected in-case we want to add assertions
|
// leaving clk and reset connected in-case we want to add assertions
|
||||||
lint_off -msg UNUSED -file "*/rtl/ibex_compressed_decoder.sv" -lines 17
|
lint_off -msg UNUSED -file "*/rtl/ibex_compressed_decoder.sv" -lines 17
|
||||||
lint_off -msg UNUSED -file "*/rtl/ibex_decoder.sv" -lines 24
|
lint_off -msg UNUSED -file "*/rtl/ibex_decoder.sv" -lines 25
|
||||||
|
|
||||||
// Signal is not used: rst_ni
|
// Signal is not used: rst_ni
|
||||||
// leaving clk and reset connected in-case we want to add assertions
|
// leaving clk and reset connected in-case we want to add assertions
|
||||||
lint_off -msg UNUSED -file "*/rtl/ibex_compressed_decoder.sv" -lines 18
|
lint_off -msg UNUSED -file "*/rtl/ibex_compressed_decoder.sv" -lines 18
|
||||||
lint_off -msg UNUSED -file "*/rtl/ibex_decoder.sv" -lines 25
|
lint_off -msg UNUSED -file "*/rtl/ibex_decoder.sv" -lines 26
|
||||||
lint_off -msg UNUSED -file "*/rtl/ibex_register_file_fpga.sv" -lines 20
|
lint_off -msg UNUSED -file "*/rtl/ibex_register_file_fpga.sv" -lines 20
|
||||||
|
|
||||||
// Signal unoptimizable: Feedback to clock or circular logic:
|
// Signal unoptimizable: Feedback to clock or circular logic:
|
||||||
|
|
|
@ -18,6 +18,7 @@ module ibex_core #(
|
||||||
parameter int unsigned MHPMCounterWidth = 40,
|
parameter int unsigned MHPMCounterWidth = 40,
|
||||||
parameter bit RV32E = 1'b0,
|
parameter bit RV32E = 1'b0,
|
||||||
parameter bit RV32M = 1'b1,
|
parameter bit RV32M = 1'b1,
|
||||||
|
parameter bit BranchTargetALU = 1'b0,
|
||||||
parameter MultiplierImplementation = "fast",
|
parameter MultiplierImplementation = "fast",
|
||||||
parameter bit DbgTriggerEn = 1'b0,
|
parameter bit DbgTriggerEn = 1'b0,
|
||||||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||||
|
@ -135,6 +136,9 @@ module ibex_core #(
|
||||||
logic [31:0] alu_operand_a_ex;
|
logic [31:0] alu_operand_a_ex;
|
||||||
logic [31:0] alu_operand_b_ex;
|
logic [31:0] alu_operand_b_ex;
|
||||||
|
|
||||||
|
jt_mux_sel_e jt_mux_sel_ex;
|
||||||
|
logic [11:0] bt_operand_imm_ex;
|
||||||
|
|
||||||
logic [31:0] alu_adder_result_ex; // Used to forward computed address to LSU
|
logic [31:0] alu_adder_result_ex; // Used to forward computed address to LSU
|
||||||
logic [31:0] regfile_wdata_ex;
|
logic [31:0] regfile_wdata_ex;
|
||||||
|
|
||||||
|
@ -357,7 +361,8 @@ module ibex_core #(
|
||||||
|
|
||||||
ibex_id_stage #(
|
ibex_id_stage #(
|
||||||
.RV32E ( RV32E ),
|
.RV32E ( RV32E ),
|
||||||
.RV32M ( RV32M )
|
.RV32M ( RV32M ),
|
||||||
|
.BranchTargetALU ( BranchTargetALU )
|
||||||
) id_stage_i (
|
) id_stage_i (
|
||||||
.clk_i ( clk ),
|
.clk_i ( clk ),
|
||||||
.rst_ni ( rst_ni ),
|
.rst_ni ( rst_ni ),
|
||||||
|
@ -401,6 +406,9 @@ module ibex_core #(
|
||||||
.alu_operand_a_ex_o ( alu_operand_a_ex ),
|
.alu_operand_a_ex_o ( alu_operand_a_ex ),
|
||||||
.alu_operand_b_ex_o ( alu_operand_b_ex ),
|
.alu_operand_b_ex_o ( alu_operand_b_ex ),
|
||||||
|
|
||||||
|
.jt_mux_sel_ex_o ( jt_mux_sel_ex ),
|
||||||
|
.bt_operand_imm_o ( bt_operand_imm_ex ),
|
||||||
|
|
||||||
.mult_en_ex_o ( mult_en_ex ),
|
.mult_en_ex_o ( mult_en_ex ),
|
||||||
.div_en_ex_o ( div_en_ex ),
|
.div_en_ex_o ( div_en_ex ),
|
||||||
.multdiv_operator_ex_o ( multdiv_operator_ex ),
|
.multdiv_operator_ex_o ( multdiv_operator_ex ),
|
||||||
|
@ -482,6 +490,7 @@ module ibex_core #(
|
||||||
|
|
||||||
ibex_ex_block #(
|
ibex_ex_block #(
|
||||||
.RV32M ( RV32M ),
|
.RV32M ( RV32M ),
|
||||||
|
.BranchTargetALU ( BranchTargetALU ),
|
||||||
.MultiplierImplementation ( MultiplierImplementation )
|
.MultiplierImplementation ( MultiplierImplementation )
|
||||||
) ex_block_i (
|
) ex_block_i (
|
||||||
.clk_i ( clk ),
|
.clk_i ( clk ),
|
||||||
|
@ -492,6 +501,11 @@ module ibex_core #(
|
||||||
.alu_operand_a_i ( alu_operand_a_ex ),
|
.alu_operand_a_i ( alu_operand_a_ex ),
|
||||||
.alu_operand_b_i ( alu_operand_b_ex ),
|
.alu_operand_b_i ( alu_operand_b_ex ),
|
||||||
|
|
||||||
|
// Branch target ALU signal from ID stage
|
||||||
|
.jt_mux_sel_i ( jt_mux_sel_ex ),
|
||||||
|
.bt_operand_imm_i ( bt_operand_imm_ex ),
|
||||||
|
.pc_id_i ( pc_id ),
|
||||||
|
|
||||||
// Multipler/Divider signal from ID stage
|
// Multipler/Divider signal from ID stage
|
||||||
.multdiv_operator_i ( multdiv_operator_ex ),
|
.multdiv_operator_i ( multdiv_operator_ex ),
|
||||||
.mult_en_i ( mult_en_ex ),
|
.mult_en_i ( mult_en_ex ),
|
||||||
|
|
|
@ -14,6 +14,7 @@ module ibex_core_tracing #(
|
||||||
parameter int unsigned MHPMCounterWidth = 40,
|
parameter int unsigned MHPMCounterWidth = 40,
|
||||||
parameter bit RV32E = 1'b0,
|
parameter bit RV32E = 1'b0,
|
||||||
parameter bit RV32M = 1'b1,
|
parameter bit RV32M = 1'b1,
|
||||||
|
parameter bit BranchTargetALU = 1'b0,
|
||||||
parameter MultiplierImplementation = "fast",
|
parameter MultiplierImplementation = "fast",
|
||||||
parameter bit DbgTriggerEn = 1'b0,
|
parameter bit DbgTriggerEn = 1'b0,
|
||||||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||||
|
@ -99,6 +100,7 @@ module ibex_core_tracing #(
|
||||||
.MHPMCounterWidth ( MHPMCounterWidth ),
|
.MHPMCounterWidth ( MHPMCounterWidth ),
|
||||||
.RV32E ( RV32E ),
|
.RV32E ( RV32E ),
|
||||||
.RV32M ( RV32M ),
|
.RV32M ( RV32M ),
|
||||||
|
.BranchTargetALU ( BranchTargetALU ),
|
||||||
.DbgTriggerEn ( DbgTriggerEn ),
|
.DbgTriggerEn ( DbgTriggerEn ),
|
||||||
.MultiplierImplementation ( MultiplierImplementation ),
|
.MultiplierImplementation ( MultiplierImplementation ),
|
||||||
.DmHaltAddr ( DmHaltAddr ),
|
.DmHaltAddr ( DmHaltAddr ),
|
||||||
|
|
|
@ -19,7 +19,8 @@
|
||||||
|
|
||||||
module ibex_decoder #(
|
module ibex_decoder #(
|
||||||
parameter bit RV32E = 0,
|
parameter bit RV32E = 0,
|
||||||
parameter bit RV32M = 1
|
parameter bit RV32M = 1,
|
||||||
|
parameter bit BranchTargetALU = 0
|
||||||
) (
|
) (
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
input logic rst_ni,
|
input logic rst_ni,
|
||||||
|
@ -42,6 +43,7 @@ module ibex_decoder #(
|
||||||
// immediates
|
// immediates
|
||||||
output ibex_pkg::imm_a_sel_e imm_a_mux_sel_o, // immediate selection for operand a
|
output ibex_pkg::imm_a_sel_e imm_a_mux_sel_o, // immediate selection for operand a
|
||||||
output ibex_pkg::imm_b_sel_e imm_b_mux_sel_o, // immediate selection for operand b
|
output ibex_pkg::imm_b_sel_e imm_b_mux_sel_o, // immediate selection for operand b
|
||||||
|
output ibex_pkg::jt_mux_sel_e jt_mux_sel_o, // jump target selection
|
||||||
output logic [31:0] imm_i_type_o,
|
output logic [31:0] imm_i_type_o,
|
||||||
output logic [31:0] imm_s_type_o,
|
output logic [31:0] imm_s_type_o,
|
||||||
output logic [31:0] imm_b_type_o,
|
output logic [31:0] imm_b_type_o,
|
||||||
|
@ -214,6 +216,8 @@ module ibex_decoder #(
|
||||||
ecall_insn_o = 1'b0;
|
ecall_insn_o = 1'b0;
|
||||||
wfi_insn_o = 1'b0;
|
wfi_insn_o = 1'b0;
|
||||||
|
|
||||||
|
jt_mux_sel_o = JT_ALU;
|
||||||
|
|
||||||
opcode = opcode_e'(instr[6:0]);
|
opcode = opcode_e'(instr[6:0]);
|
||||||
|
|
||||||
unique case (opcode)
|
unique case (opcode)
|
||||||
|
@ -224,6 +228,11 @@ module ibex_decoder #(
|
||||||
|
|
||||||
OPCODE_JAL: begin // Jump and Link
|
OPCODE_JAL: begin // Jump and Link
|
||||||
jump_in_dec_o = 1'b1;
|
jump_in_dec_o = 1'b1;
|
||||||
|
|
||||||
|
if(BranchTargetALU) begin
|
||||||
|
jt_mux_sel_o = JT_ALU;
|
||||||
|
end
|
||||||
|
|
||||||
if (instr_new_i) begin
|
if (instr_new_i) begin
|
||||||
// Calculate jump target
|
// Calculate jump target
|
||||||
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
||||||
|
@ -244,6 +253,11 @@ module ibex_decoder #(
|
||||||
|
|
||||||
OPCODE_JALR: begin // Jump and Link Register
|
OPCODE_JALR: begin // Jump and Link Register
|
||||||
jump_in_dec_o = 1'b1;
|
jump_in_dec_o = 1'b1;
|
||||||
|
|
||||||
|
if(BranchTargetALU) begin
|
||||||
|
jt_mux_sel_o = JT_ALU;
|
||||||
|
end
|
||||||
|
|
||||||
if (instr_new_i) begin
|
if (instr_new_i) begin
|
||||||
// Calculate jump target
|
// Calculate jump target
|
||||||
alu_op_a_mux_sel_o = OP_A_REG_A;
|
alu_op_a_mux_sel_o = OP_A_REG_A;
|
||||||
|
@ -277,12 +291,22 @@ module ibex_decoder #(
|
||||||
3'b111: alu_operator_o = ALU_GEU;
|
3'b111: alu_operator_o = ALU_GEU;
|
||||||
default: illegal_insn = 1'b1;
|
default: illegal_insn = 1'b1;
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
|
if (BranchTargetALU) begin
|
||||||
|
// With branch target ALU main ALU evaluates branch condition and branch target ALU
|
||||||
|
// calculates target (which is controlled in a seperate block below)
|
||||||
|
alu_op_a_mux_sel_o = OP_A_REG_A;
|
||||||
|
alu_op_b_mux_sel_o = OP_B_REG_B;
|
||||||
|
regfile_we = 1'b0;
|
||||||
|
jt_mux_sel_o = JT_BT_ALU;
|
||||||
|
end else begin
|
||||||
|
// Without branch target ALU branch is 2 stage operation using the Main ALU in both stages
|
||||||
if (instr_new_i) begin
|
if (instr_new_i) begin
|
||||||
// Evaluate branch condition
|
// First evaluates branch condition
|
||||||
alu_op_a_mux_sel_o = OP_A_REG_A;
|
alu_op_a_mux_sel_o = OP_A_REG_A;
|
||||||
alu_op_b_mux_sel_o = OP_B_REG_B;
|
alu_op_b_mux_sel_o = OP_B_REG_B;
|
||||||
end else begin
|
end else begin
|
||||||
// Calculate jump target in EX
|
// Then calculate jump target
|
||||||
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
||||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||||
imm_b_mux_sel_o = IMM_B_B;
|
imm_b_mux_sel_o = IMM_B_B;
|
||||||
|
@ -290,6 +314,7 @@ module ibex_decoder #(
|
||||||
regfile_we = 1'b0;
|
regfile_we = 1'b0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
// Load/store //
|
// Load/store //
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
*/
|
*/
|
||||||
module ibex_ex_block #(
|
module ibex_ex_block #(
|
||||||
parameter bit RV32M = 1,
|
parameter bit RV32M = 1,
|
||||||
|
parameter bit BranchTargetALU = 0,
|
||||||
parameter MultiplierImplementation = "fast"
|
parameter MultiplierImplementation = "fast"
|
||||||
) (
|
) (
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
|
@ -20,6 +21,12 @@ module ibex_ex_block #(
|
||||||
input logic [31:0] alu_operand_a_i,
|
input logic [31:0] alu_operand_a_i,
|
||||||
input logic [31:0] alu_operand_b_i,
|
input logic [31:0] alu_operand_b_i,
|
||||||
|
|
||||||
|
// Branch Target ALU
|
||||||
|
// All of these signals are unusued when BranchTargetALU == 0
|
||||||
|
input ibex_pkg::jt_mux_sel_e jt_mux_sel_i,
|
||||||
|
input logic [11:0] bt_operand_imm_i,
|
||||||
|
input logic [31:0] pc_id_i,
|
||||||
|
|
||||||
// Multiplier/Divider
|
// Multiplier/Divider
|
||||||
input ibex_pkg::md_op_e multdiv_operator_i,
|
input ibex_pkg::md_op_e multdiv_operator_i,
|
||||||
input logic mult_en_i,
|
input logic mult_en_i,
|
||||||
|
@ -64,7 +71,25 @@ module ibex_ex_block #(
|
||||||
|
|
||||||
// branch handling
|
// branch handling
|
||||||
assign branch_decision_o = alu_cmp_result;
|
assign branch_decision_o = alu_cmp_result;
|
||||||
|
|
||||||
|
if (BranchTargetALU) begin : g_branch_target_alu
|
||||||
|
logic [32:0] bt_alu_result;
|
||||||
|
|
||||||
|
assign bt_alu_result = {{19{bt_operand_imm_i[11]}}, bt_operand_imm_i, 1'b0} + pc_id_i;
|
||||||
|
|
||||||
|
assign jump_target_o = (jt_mux_sel_i == JT_ALU) ? alu_adder_result_ex_o : bt_alu_result[31:0];
|
||||||
|
end else begin : g_no_branch_target_alu
|
||||||
|
// Unused jt_mux_sel_i/bt_operand_imm_i/pc_id_i signals causes lint errors, this avoids them
|
||||||
|
ibex_pkg::jt_mux_sel_e jt_mux_sel_unused;
|
||||||
|
logic [11:0] bt_operand_imm_unused;
|
||||||
|
logic [31:0] pc_id_unused;
|
||||||
|
|
||||||
|
assign jt_mux_sel_unused = jt_mux_sel_i;
|
||||||
|
assign bt_operand_imm_unused = bt_operand_imm_i;
|
||||||
|
assign pc_id_unused = pc_id_i;
|
||||||
|
|
||||||
assign jump_target_o = alu_adder_result_ex_o;
|
assign jump_target_o = alu_adder_result_ex_o;
|
||||||
|
end
|
||||||
|
|
||||||
/////////
|
/////////
|
||||||
// ALU //
|
// ALU //
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
|
|
||||||
module ibex_id_stage #(
|
module ibex_id_stage #(
|
||||||
parameter bit RV32E = 0,
|
parameter bit RV32E = 0,
|
||||||
parameter bit RV32M = 1
|
parameter bit RV32M = 1,
|
||||||
|
parameter bit BranchTargetALU = 0
|
||||||
) (
|
) (
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
input logic rst_ni,
|
input logic rst_ni,
|
||||||
|
@ -61,6 +62,10 @@ module ibex_id_stage #(
|
||||||
output logic [31:0] alu_operand_a_ex_o,
|
output logic [31:0] alu_operand_a_ex_o,
|
||||||
output logic [31:0] alu_operand_b_ex_o,
|
output logic [31:0] alu_operand_b_ex_o,
|
||||||
|
|
||||||
|
// Branch target ALU
|
||||||
|
output ibex_pkg::jt_mux_sel_e jt_mux_sel_ex_o,
|
||||||
|
output logic [11:0] bt_operand_imm_o,
|
||||||
|
|
||||||
// MUL, DIV
|
// MUL, DIV
|
||||||
output logic mult_en_ex_o,
|
output logic mult_en_ex_o,
|
||||||
output logic div_en_ex_o,
|
output logic div_en_ex_o,
|
||||||
|
@ -149,7 +154,7 @@ module ibex_id_stage #(
|
||||||
logic wfi_insn_dec;
|
logic wfi_insn_dec;
|
||||||
|
|
||||||
logic branch_in_dec;
|
logic branch_in_dec;
|
||||||
logic branch_set_n, branch_set_q;
|
logic branch_set, branch_set_n;
|
||||||
logic jump_in_dec;
|
logic jump_in_dec;
|
||||||
logic jump_set;
|
logic jump_set;
|
||||||
|
|
||||||
|
@ -318,7 +323,8 @@ module ibex_id_stage #(
|
||||||
|
|
||||||
ibex_decoder #(
|
ibex_decoder #(
|
||||||
.RV32E ( RV32E ),
|
.RV32E ( RV32E ),
|
||||||
.RV32M ( RV32M )
|
.RV32M ( RV32M ),
|
||||||
|
.BranchTargetALU ( BranchTargetALU )
|
||||||
) decoder_i (
|
) decoder_i (
|
||||||
.clk_i ( clk_i ),
|
.clk_i ( clk_i ),
|
||||||
.rst_ni ( rst_ni ),
|
.rst_ni ( rst_ni ),
|
||||||
|
@ -340,6 +346,7 @@ module ibex_id_stage #(
|
||||||
// immediates
|
// immediates
|
||||||
.imm_a_mux_sel_o ( imm_a_mux_sel ),
|
.imm_a_mux_sel_o ( imm_a_mux_sel ),
|
||||||
.imm_b_mux_sel_o ( imm_b_mux_sel_dec ),
|
.imm_b_mux_sel_o ( imm_b_mux_sel_dec ),
|
||||||
|
.jt_mux_sel_o ( jt_mux_sel_ex_o ),
|
||||||
|
|
||||||
.imm_i_type_o ( imm_i_type ),
|
.imm_i_type_o ( imm_i_type ),
|
||||||
.imm_s_type_o ( imm_s_type ),
|
.imm_s_type_o ( imm_s_type ),
|
||||||
|
@ -430,7 +437,7 @@ module ibex_id_stage #(
|
||||||
.store_err_i ( lsu_store_err_i ),
|
.store_err_i ( lsu_store_err_i ),
|
||||||
|
|
||||||
// jump/branch control
|
// jump/branch control
|
||||||
.branch_set_i ( branch_set_q ),
|
.branch_set_i ( branch_set ),
|
||||||
.jump_set_i ( jump_set ),
|
.jump_set_i ( jump_set ),
|
||||||
|
|
||||||
// interrupt signals
|
// interrupt signals
|
||||||
|
@ -506,6 +513,14 @@ module ibex_id_stage #(
|
||||||
assign alu_operand_a_ex_o = alu_operand_a;
|
assign alu_operand_a_ex_o = alu_operand_a;
|
||||||
assign alu_operand_b_ex_o = alu_operand_b;
|
assign alu_operand_b_ex_o = alu_operand_b;
|
||||||
|
|
||||||
|
if (BranchTargetALU) begin : g_bt_operand_imm
|
||||||
|
// Branch target ALU sign-extends and inserts bottom 0 bit so only want the
|
||||||
|
// 'raw' B-type immediate bits.
|
||||||
|
assign bt_operand_imm_o = imm_b_type[12:1];
|
||||||
|
end else begin : g_no_bt_operand_imm
|
||||||
|
assign bt_operand_imm_o = '0;
|
||||||
|
end
|
||||||
|
|
||||||
assign mult_en_ex_o = mult_en_id;
|
assign mult_en_ex_o = mult_en_id;
|
||||||
assign div_en_ex_o = div_en_id;
|
assign div_en_ex_o = div_en_id;
|
||||||
|
|
||||||
|
@ -521,14 +536,32 @@ module ibex_id_stage #(
|
||||||
// ID-EX/WB Pipeline Register //
|
// ID-EX/WB Pipeline Register //
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
|
if (BranchTargetALU) begin : g_branch_set_direct
|
||||||
|
// Branch set fed straight to controller with branch target ALU
|
||||||
|
// (condition pass/fail used same cycle as generated instruction request)
|
||||||
|
assign branch_set = branch_set_n;
|
||||||
|
end else begin : g_branch_set_flopped
|
||||||
|
// Branch set flopped without branch target ALU
|
||||||
|
// (condition pass/fail used next cycle where branch target is calculated)
|
||||||
|
logic branch_set_q;
|
||||||
|
|
||||||
|
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||||
|
if (!rst_ni) begin
|
||||||
|
branch_set_q <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
branch_set_q <= branch_set_n;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign branch_set = branch_set_q;
|
||||||
|
end
|
||||||
|
|
||||||
always_ff @(posedge clk_i or negedge rst_ni) begin : id_wb_pipeline_reg
|
always_ff @(posedge clk_i or negedge rst_ni) begin : id_wb_pipeline_reg
|
||||||
if (!rst_ni) begin
|
if (!rst_ni) begin
|
||||||
id_wb_fsm_cs <= IDLE;
|
id_wb_fsm_cs <= IDLE;
|
||||||
branch_set_q <= 1'b0;
|
|
||||||
instr_multicycle_done_q <= 1'b0;
|
instr_multicycle_done_q <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
id_wb_fsm_cs <= id_wb_fsm_ns;
|
id_wb_fsm_cs <= id_wb_fsm_ns;
|
||||||
branch_set_q <= branch_set_n;
|
|
||||||
instr_multicycle_done_q <= instr_multicycle_done_n;
|
instr_multicycle_done_q <= instr_multicycle_done_n;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -132,6 +132,12 @@ typedef enum logic [2:0] {
|
||||||
IMM_B_INCR_ADDR
|
IMM_B_INCR_ADDR
|
||||||
} imm_b_sel_e;
|
} imm_b_sel_e;
|
||||||
|
|
||||||
|
// Only used when BranchTargetALU == 1
|
||||||
|
typedef enum logic {
|
||||||
|
JT_ALU, // Jump target from main ALU
|
||||||
|
JT_BT_ALU // Jump target from specialised branch ALU
|
||||||
|
} jt_mux_sel_e;
|
||||||
|
|
||||||
// Regfile write data selection
|
// Regfile write data selection
|
||||||
typedef enum logic [1:0] {
|
typedef enum logic [1:0] {
|
||||||
RF_WD_LSU,
|
RF_WD_LSU,
|
||||||
|
|
|
@ -13,6 +13,7 @@ set_flow_var config_file "${lr_synth_top_module}_lr_synth_conf.tcl" "Synth confi
|
||||||
set_flow_var rpt_out "./${lr_synth_out_dir}/reports" "Report output directory"
|
set_flow_var rpt_out "./${lr_synth_out_dir}/reports" "Report output directory"
|
||||||
set_flow_bool_var flatten 1 "flatten"
|
set_flow_bool_var flatten 1 "flatten"
|
||||||
set_flow_bool_var timing_run 0 "timing run"
|
set_flow_bool_var timing_run 0 "timing run"
|
||||||
|
set_flow_bool_var ibex_branch_target_alu 0 "Enable branch target ALU in Ibex"
|
||||||
|
|
||||||
source $lr_synth_config_file
|
source $lr_synth_config_file
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,12 @@ if { $lr_synth_timing_run } {
|
||||||
write_sdc_out $lr_synth_sdc_file_in $lr_synth_sdc_file_out
|
write_sdc_out $lr_synth_sdc_file_in $lr_synth_sdc_file_out
|
||||||
}
|
}
|
||||||
|
|
||||||
yosys "read -sv ./rtl/prim_clock_gating.v $lr_synth_out_dir/generated/*.v"
|
yosys "read_verilog -sv ./rtl/prim_clock_gating.v $lr_synth_out_dir/generated/*.v"
|
||||||
|
|
||||||
|
if { $lr_synth_ibex_branch_target_alu } {
|
||||||
|
yosys "chparam -set BranchTargetALU 1 ibex_core"
|
||||||
|
}
|
||||||
|
|
||||||
yosys "synth $flatten_opt -top $lr_synth_top_module"
|
yosys "synth $flatten_opt -top $lr_synth_top_module"
|
||||||
yosys "opt -purge"
|
yosys "opt -purge"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue