mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
[rtl] Rework generation and use of mult/div_sel/en
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
This commit is contained in:
parent
511c59db18
commit
3922b2582f
6 changed files with 108 additions and 78 deletions
|
@ -186,7 +186,8 @@ module ibex_core #(
|
|||
// Multiplier Control
|
||||
logic mult_en_ex;
|
||||
logic div_en_ex;
|
||||
logic multdiv_sel_ex;
|
||||
logic mult_sel_ex;
|
||||
logic div_sel_ex;
|
||||
md_op_e multdiv_operator_ex;
|
||||
logic [1:0] multdiv_signed_mode_ex;
|
||||
logic [31:0] multdiv_operand_a_ex;
|
||||
|
@ -493,7 +494,8 @@ module ibex_core #(
|
|||
|
||||
.mult_en_ex_o ( mult_en_ex ),
|
||||
.div_en_ex_o ( div_en_ex ),
|
||||
.multdiv_sel_ex_o ( multdiv_sel_ex ),
|
||||
.mult_sel_ex_o ( mult_sel_ex ),
|
||||
.div_sel_ex_o ( div_sel_ex ),
|
||||
.multdiv_operator_ex_o ( multdiv_operator_ex ),
|
||||
.multdiv_signed_mode_ex_o ( multdiv_signed_mode_ex ),
|
||||
.multdiv_operand_a_ex_o ( multdiv_operand_a_ex ),
|
||||
|
@ -606,7 +608,8 @@ module ibex_core #(
|
|||
.multdiv_operator_i ( multdiv_operator_ex ),
|
||||
.mult_en_i ( mult_en_ex ),
|
||||
.div_en_i ( div_en_ex ),
|
||||
.multdiv_sel_i ( multdiv_sel_ex ),
|
||||
.mult_sel_i ( mult_sel_ex ),
|
||||
.div_sel_i ( div_sel_ex ),
|
||||
.multdiv_signed_mode_i ( multdiv_signed_mode_ex ),
|
||||
.multdiv_operand_a_i ( multdiv_operand_a_ex ),
|
||||
.multdiv_operand_b_i ( multdiv_operand_b_ex ),
|
||||
|
|
|
@ -78,9 +78,9 @@ module ibex_decoder #(
|
|||
|
||||
// MULT & DIV
|
||||
output logic mult_en_o, // perform integer multiplication
|
||||
output logic div_en_o, // perform integer division or
|
||||
// remainder
|
||||
output logic multdiv_sel_o,
|
||||
output logic div_en_o, // perform integer division or remainder
|
||||
output logic mult_sel_o, // as above but static, for data muxes
|
||||
output logic div_sel_o, // as above but static, for data muxes
|
||||
|
||||
output ibex_pkg::md_op_e multdiv_operator_o,
|
||||
output logic [1:0] multdiv_signed_mode_o,
|
||||
|
@ -176,38 +176,36 @@ module ibex_decoder #(
|
|||
/////////////
|
||||
|
||||
always_comb begin
|
||||
jump_in_dec_o = 1'b0;
|
||||
jump_set_o = 1'b0;
|
||||
branch_in_dec_o = 1'b0;
|
||||
icache_inval_o = 1'b0;
|
||||
jump_in_dec_o = 1'b0;
|
||||
jump_set_o = 1'b0;
|
||||
branch_in_dec_o = 1'b0;
|
||||
icache_inval_o = 1'b0;
|
||||
|
||||
mult_en_o = 1'b0;
|
||||
div_en_o = 1'b0;
|
||||
multdiv_operator_o = MD_OP_MULL;
|
||||
multdiv_signed_mode_o = 2'b00;
|
||||
multdiv_operator_o = MD_OP_MULL;
|
||||
multdiv_signed_mode_o = 2'b00;
|
||||
|
||||
rf_wdata_sel_o = RF_WD_EX;
|
||||
rf_we = 1'b0;
|
||||
rf_ren_a_o = 1'b0;
|
||||
rf_ren_b_o = 1'b0;
|
||||
rf_wdata_sel_o = RF_WD_EX;
|
||||
rf_we = 1'b0;
|
||||
rf_ren_a_o = 1'b0;
|
||||
rf_ren_b_o = 1'b0;
|
||||
|
||||
csr_access_o = 1'b0;
|
||||
csr_illegal = 1'b0;
|
||||
csr_op = CSR_OP_READ;
|
||||
csr_access_o = 1'b0;
|
||||
csr_illegal = 1'b0;
|
||||
csr_op = CSR_OP_READ;
|
||||
|
||||
data_we_o = 1'b0;
|
||||
data_type_o = 2'b00;
|
||||
data_sign_extension_o = 1'b0;
|
||||
data_req_o = 1'b0;
|
||||
data_we_o = 1'b0;
|
||||
data_type_o = 2'b00;
|
||||
data_sign_extension_o = 1'b0;
|
||||
data_req_o = 1'b0;
|
||||
|
||||
illegal_insn = 1'b0;
|
||||
ebrk_insn_o = 1'b0;
|
||||
mret_insn_o = 1'b0;
|
||||
dret_insn_o = 1'b0;
|
||||
ecall_insn_o = 1'b0;
|
||||
wfi_insn_o = 1'b0;
|
||||
illegal_insn = 1'b0;
|
||||
ebrk_insn_o = 1'b0;
|
||||
mret_insn_o = 1'b0;
|
||||
dret_insn_o = 1'b0;
|
||||
ecall_insn_o = 1'b0;
|
||||
wfi_insn_o = 1'b0;
|
||||
|
||||
opcode = opcode_e'(instr[6:0]);
|
||||
opcode = opcode_e'(instr[6:0]);
|
||||
|
||||
unique case (opcode)
|
||||
|
||||
|
@ -432,52 +430,44 @@ module ibex_decoder #(
|
|||
{7'b000_0100, 3'b001}, // shfl
|
||||
{7'b000_0100, 3'b101}: illegal_insn = RV32B ? 1'b0 : 1'b1; // unshfl
|
||||
|
||||
// supported RV32M instructions
|
||||
// RV32M instructions
|
||||
{7'b000_0001, 3'b000}: begin // mul
|
||||
multdiv_operator_o = MD_OP_MULL;
|
||||
mult_en_o = RV32M ? 1'b1 : 1'b0;
|
||||
multdiv_signed_mode_o = 2'b00;
|
||||
illegal_insn = RV32M ? 1'b0 : 1'b1;
|
||||
end
|
||||
{7'b000_0001, 3'b001}: begin // mulh
|
||||
multdiv_operator_o = MD_OP_MULH;
|
||||
mult_en_o = RV32M ? 1'b1 : 1'b0;
|
||||
multdiv_signed_mode_o = 2'b11;
|
||||
illegal_insn = RV32M ? 1'b0 : 1'b1;
|
||||
end
|
||||
{7'b000_0001, 3'b010}: begin // mulhsu
|
||||
multdiv_operator_o = MD_OP_MULH;
|
||||
mult_en_o = RV32M ? 1'b1 : 1'b0;
|
||||
multdiv_signed_mode_o = 2'b01;
|
||||
illegal_insn = RV32M ? 1'b0 : 1'b1;
|
||||
end
|
||||
{7'b000_0001, 3'b011}: begin // mulhu
|
||||
multdiv_operator_o = MD_OP_MULH;
|
||||
mult_en_o = RV32M ? 1'b1 : 1'b0;
|
||||
multdiv_signed_mode_o = 2'b00;
|
||||
illegal_insn = RV32M ? 1'b0 : 1'b1;
|
||||
end
|
||||
{7'b000_0001, 3'b100}: begin // div
|
||||
multdiv_operator_o = MD_OP_DIV;
|
||||
div_en_o = RV32M ? 1'b1 : 1'b0;
|
||||
multdiv_signed_mode_o = 2'b11;
|
||||
illegal_insn = RV32M ? 1'b0 : 1'b1;
|
||||
end
|
||||
{7'b000_0001, 3'b101}: begin // divu
|
||||
multdiv_operator_o = MD_OP_DIV;
|
||||
div_en_o = RV32M ? 1'b1 : 1'b0;
|
||||
multdiv_signed_mode_o = 2'b00;
|
||||
illegal_insn = RV32M ? 1'b0 : 1'b1;
|
||||
end
|
||||
{7'b000_0001, 3'b110}: begin // rem
|
||||
multdiv_operator_o = MD_OP_REM;
|
||||
div_en_o = RV32M ? 1'b1 : 1'b0;
|
||||
multdiv_signed_mode_o = 2'b11;
|
||||
illegal_insn = RV32M ? 1'b0 : 1'b1;
|
||||
end
|
||||
{7'b000_0001, 3'b111}: begin // remu
|
||||
multdiv_operator_o = MD_OP_REM;
|
||||
div_en_o = RV32M ? 1'b1 : 1'b0;
|
||||
multdiv_signed_mode_o = 2'b00;
|
||||
illegal_insn = RV32M ? 1'b0 : 1'b1;
|
||||
end
|
||||
|
@ -589,8 +579,6 @@ module ibex_decoder #(
|
|||
rf_we = 1'b0;
|
||||
data_req_o = 1'b0;
|
||||
data_we_o = 1'b0;
|
||||
mult_en_o = 1'b0;
|
||||
div_en_o = 1'b0;
|
||||
jump_in_dec_o = 1'b0;
|
||||
jump_set_o = 1'b0;
|
||||
branch_in_dec_o = 1'b0;
|
||||
|
@ -613,12 +601,13 @@ module ibex_decoder #(
|
|||
bt_a_mux_sel_o = OP_A_CURRPC;
|
||||
bt_b_mux_sel_o = IMM_B_I;
|
||||
|
||||
multdiv_sel_o = 1'b0;
|
||||
|
||||
opcode_alu = opcode_e'(instr_alu[6:0]);
|
||||
|
||||
use_rs3 = 1'b0;
|
||||
alu_multicycle_o = 1'b0;
|
||||
mult_sel_o = 1'b0;
|
||||
div_sel_o = 1'b0;
|
||||
|
||||
unique case (opcode_alu)
|
||||
|
||||
|
@ -928,17 +917,38 @@ module ibex_decoder #(
|
|||
{7'b011_0100, 3'b001}: if (RV32B) alu_operator_o = ALU_SBINV; // sbinv
|
||||
{7'b010_0100, 3'b101}: if (RV32B) alu_operator_o = ALU_SBEXT; // sbext
|
||||
|
||||
// supported RV32M instructions, all use the same ALU operation
|
||||
{7'b000_0001, 3'b000}, // mul
|
||||
{7'b000_0001, 3'b001}, // mulh
|
||||
{7'b000_0001, 3'b010}, // mulhsu
|
||||
{7'b000_0001, 3'b011}, // mulhu
|
||||
{7'b000_0001, 3'b100}, // div
|
||||
{7'b000_0001, 3'b101}, // divu
|
||||
{7'b000_0001, 3'b110}, // rem
|
||||
// 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;
|
||||
end
|
||||
{7'b000_0001, 3'b001}: begin // mulh
|
||||
alu_operator_o = ALU_ADD;
|
||||
mult_sel_o = RV32M ? 1'b1 : 1'b0;
|
||||
end
|
||||
{7'b000_0001, 3'b010}: begin // mulhsu
|
||||
alu_operator_o = ALU_ADD;
|
||||
mult_sel_o = RV32M ? 1'b1 : 1'b0;
|
||||
end
|
||||
{7'b000_0001, 3'b011}: begin // mulhu
|
||||
alu_operator_o = ALU_ADD;
|
||||
mult_sel_o = RV32M ? 1'b1 : 1'b0;
|
||||
end
|
||||
{7'b000_0001, 3'b100}: begin // div
|
||||
alu_operator_o = ALU_ADD;
|
||||
div_sel_o = RV32M ? 1'b1 : 1'b0;
|
||||
end
|
||||
{7'b000_0001, 3'b101}: begin // divu
|
||||
alu_operator_o = ALU_ADD;
|
||||
div_sel_o = RV32M ? 1'b1 : 1'b0;
|
||||
end
|
||||
{7'b000_0001, 3'b110}: begin // rem
|
||||
alu_operator_o = ALU_ADD;
|
||||
div_sel_o = RV32M ? 1'b1 : 1'b0;
|
||||
end
|
||||
{7'b000_0001, 3'b111}: begin // remu
|
||||
multdiv_sel_o = 1'b1;
|
||||
alu_operator_o = ALU_ADD;
|
||||
alu_operator_o = ALU_ADD;
|
||||
div_sel_o = RV32M ? 1'b1 : 1'b0;
|
||||
end
|
||||
|
||||
default: ;
|
||||
|
@ -999,6 +1009,10 @@ module ibex_decoder #(
|
|||
endcase
|
||||
end
|
||||
|
||||
// do not enable multdiv in case of illegal instruction exceptions
|
||||
assign mult_en_o = illegal_insn ? 1'b0 : mult_sel_o;
|
||||
assign div_en_o = illegal_insn ? 1'b0 : div_sel_o;
|
||||
|
||||
// make sure instructions accessing non-available registers in RV32E cause illegal
|
||||
// instruction exceptions
|
||||
assign illegal_insn_o = illegal_insn | illegal_reg_rv32e;
|
||||
|
|
|
@ -30,9 +30,10 @@ module ibex_ex_block #(
|
|||
|
||||
// Multiplier/Divider
|
||||
input ibex_pkg::md_op_e multdiv_operator_i,
|
||||
input logic mult_en_i,
|
||||
input logic div_en_i,
|
||||
input logic multdiv_sel_i,
|
||||
input logic mult_en_i, // dynamic enable signal, for FSM control
|
||||
input logic div_en_i, // dynamic enable signal, for FSM control
|
||||
input logic mult_sel_i, // static decoder output, for data muxes
|
||||
input logic div_sel_i, // static decoder output, for data muxes
|
||||
input logic [1:0] multdiv_signed_mode_i,
|
||||
input logic [31:0] multdiv_operand_a_i,
|
||||
input logic [31:0] multdiv_operand_b_i,
|
||||
|
@ -66,22 +67,22 @@ module ibex_ex_block #(
|
|||
logic [33:0] multdiv_imd_val_d;
|
||||
logic multdiv_imd_val_we;
|
||||
|
||||
// Intermediate Value Register Mux
|
||||
assign imd_val_d_o = multdiv_sel_i ? multdiv_imd_val_d : {2'b0, alu_imd_val_d};
|
||||
assign imd_val_we_o = multdiv_sel_i ? multdiv_imd_val_we : alu_imd_val_we;
|
||||
|
||||
/*
|
||||
The multdiv_i output is never selected if RV32M=0
|
||||
At synthesis time, all the combinational and sequential logic
|
||||
from the multdiv_i module are eliminated
|
||||
*/
|
||||
if (RV32M) begin : gen_multdiv_m
|
||||
assign multdiv_sel = multdiv_sel_i;
|
||||
assign multdiv_sel = mult_sel_i | div_sel_i;
|
||||
end else begin : gen_multdiv_no_m
|
||||
assign multdiv_sel = 1'b0;
|
||||
end
|
||||
|
||||
assign result_ex_o = multdiv_sel ? multdiv_result : alu_result;
|
||||
// Intermediate Value Register Mux
|
||||
assign imd_val_d_o = multdiv_sel ? multdiv_imd_val_d : {2'b0, alu_imd_val_d};
|
||||
assign imd_val_we_o = multdiv_sel ? multdiv_imd_val_we : alu_imd_val_we;
|
||||
|
||||
assign result_ex_o = multdiv_sel ? multdiv_result : alu_result;
|
||||
|
||||
// branch handling
|
||||
assign branch_decision_o = alu_cmp_result;
|
||||
|
@ -120,7 +121,7 @@ module ibex_ex_block #(
|
|||
.imd_val_d_o ( alu_imd_val_d ),
|
||||
.multdiv_operand_a_i ( multdiv_alu_operand_a ),
|
||||
.multdiv_operand_b_i ( multdiv_alu_operand_b ),
|
||||
.multdiv_sel_i ( multdiv_sel_i ),
|
||||
.multdiv_sel_i ( multdiv_sel ),
|
||||
.adder_result_o ( alu_adder_result_ex_o ),
|
||||
.adder_result_ext_o ( alu_adder_result_ext ),
|
||||
.result_o ( alu_result ),
|
||||
|
@ -138,6 +139,8 @@ module ibex_ex_block #(
|
|||
.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 ),
|
||||
|
@ -162,6 +165,8 @@ module ibex_ex_block #(
|
|||
.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 ),
|
||||
|
@ -186,6 +191,8 @@ module ibex_ex_block #(
|
|||
.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 ),
|
||||
|
|
|
@ -80,7 +80,8 @@ module ibex_id_stage #(
|
|||
// MUL, DIV
|
||||
output logic mult_en_ex_o,
|
||||
output logic div_en_ex_o,
|
||||
output logic multdiv_sel_ex_o,
|
||||
output logic mult_sel_ex_o,
|
||||
output logic div_sel_ex_o,
|
||||
output ibex_pkg::md_op_e multdiv_operator_ex_o,
|
||||
output logic [1:0] multdiv_signed_mode_ex_o,
|
||||
output logic [31:0] multdiv_operand_a_ex_o,
|
||||
|
@ -246,7 +247,6 @@ module ibex_id_stage #(
|
|||
// Multiplier Control
|
||||
logic mult_en_id, mult_en_dec; // use integer multiplier
|
||||
logic div_en_id, div_en_dec; // use integer division or reminder
|
||||
logic multdiv_sel_dec;
|
||||
logic multdiv_en_dec;
|
||||
md_op_e multdiv_operator;
|
||||
logic [1:0] multdiv_signed_mode;
|
||||
|
@ -442,7 +442,8 @@ module ibex_id_stage #(
|
|||
// MULT & DIV
|
||||
.mult_en_o ( mult_en_dec ),
|
||||
.div_en_o ( div_en_dec ),
|
||||
.multdiv_sel_o ( multdiv_sel_dec ),
|
||||
.mult_sel_o ( mult_sel_ex_o ),
|
||||
.div_sel_o ( div_sel_ex_o ),
|
||||
.multdiv_operator_o ( multdiv_operator ),
|
||||
.multdiv_signed_mode_o ( multdiv_signed_mode ),
|
||||
|
||||
|
@ -603,7 +604,6 @@ module ibex_id_stage #(
|
|||
|
||||
assign mult_en_ex_o = mult_en_id;
|
||||
assign div_en_ex_o = div_en_id;
|
||||
assign multdiv_sel_ex_o = multdiv_sel_dec;
|
||||
|
||||
assign multdiv_operator_ex_o = multdiv_operator;
|
||||
assign multdiv_signed_mode_ex_o = multdiv_signed_mode;
|
||||
|
|
|
@ -19,8 +19,10 @@ module ibex_multdiv_fast #(
|
|||
) (
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic mult_en_i,
|
||||
input logic div_en_i,
|
||||
input logic mult_en_i, // dynamic enable signal, for FSM control
|
||||
input logic div_en_i, // dynamic enable signal, for FSM control
|
||||
input logic mult_sel_i, // static decoder output, for data muxes
|
||||
input logic div_sel_i, // static decoder output, for data muxes
|
||||
input ibex_pkg::md_op_e operator_i,
|
||||
input logic [1:0] signed_mode_i,
|
||||
input logic [31:0] op_a_i,
|
||||
|
@ -85,6 +87,8 @@ module ibex_multdiv_fast #(
|
|||
} md_fsm_e;
|
||||
md_fsm_e md_state_q, md_state_d;
|
||||
|
||||
logic unused_mult_sel_i;
|
||||
assign unused_mult_sel_i = mult_sel_i;
|
||||
|
||||
assign mult_en_internal = mult_en_i & ~mult_hold;
|
||||
assign div_en_internal = div_en_i & ~div_hold;
|
||||
|
@ -112,11 +116,11 @@ module ibex_multdiv_fast #(
|
|||
|
||||
assign multdiv_en = mult_en_internal | div_en_internal;
|
||||
|
||||
assign imd_val_d_o = div_en_i ? op_remainder_d : mac_res_d;
|
||||
assign imd_val_d_o = div_sel_i ? op_remainder_d : mac_res_d;
|
||||
assign imd_val_we_o = multdiv_en;
|
||||
|
||||
assign signed_mult = (signed_mode_i != 2'b00);
|
||||
assign multdiv_result_o = div_en_i ? imd_val_q_i[31:0] : mac_res_d[31:0];
|
||||
assign multdiv_result_o = div_sel_i ? imd_val_q_i[31:0] : mac_res_d[31:0];
|
||||
|
||||
// The single cycle multiplier uses three 17 bit multipliers to compute MUL instructions in a
|
||||
// single cycle and MULH instructions in two cycles.
|
||||
|
|
|
@ -15,8 +15,10 @@ module ibex_multdiv_slow
|
|||
(
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
input logic mult_en_i,
|
||||
input logic div_en_i,
|
||||
input logic mult_en_i, // dynamic enable signal, for FSM control
|
||||
input logic div_en_i, // dynamic enable signal, for FSM control
|
||||
input logic mult_sel_i, // static decoder output, for data muxes
|
||||
input logic div_sel_i, // static decoder output, for data muxes
|
||||
input ibex_pkg::md_op_e operator_i,
|
||||
input logic [1:0] signed_mode_i,
|
||||
input logic [31:0] op_a_i,
|
||||
|
@ -78,7 +80,7 @@ module ibex_multdiv_slow
|
|||
|
||||
always_comb begin
|
||||
alu_operand_a_o = accum_window_q;
|
||||
multdiv_result_o = div_en_i ? accum_window_q[31:0] : res_adder_l;
|
||||
multdiv_result_o = div_sel_i ? accum_window_q[31:0] : res_adder_l;
|
||||
|
||||
unique case(operator_i)
|
||||
|
||||
|
@ -179,7 +181,7 @@ module ibex_multdiv_slow
|
|||
op_numerator_d = op_numerator_q;
|
||||
md_state_d = md_state_q;
|
||||
multdiv_hold = 1'b0;
|
||||
if (mult_en_i || div_en_i) begin
|
||||
if (mult_sel_i || div_sel_i) begin
|
||||
unique case(md_state_q)
|
||||
MD_IDLE: begin
|
||||
unique case(operator_i)
|
||||
|
@ -302,8 +304,8 @@ module ibex_multdiv_slow
|
|||
default: begin
|
||||
md_state_d = MD_IDLE;
|
||||
end
|
||||
endcase // md_state_q
|
||||
end
|
||||
endcase // md_state_q
|
||||
end // (mult_sel_i || div_sel_i)
|
||||
end
|
||||
|
||||
assign valid_o = (md_state_q == MD_FINISH) |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue