[rtl] Add multdiv_sel signal to decode

multdiv_sel signals the mult/div operand should be selected for the ALU
inputs. Previously the mult_en/div_en signals were used but these factor
in whether the instruction is actually happening which is not relevant
for the mux select. The dedicated select signal gives better timing.
This commit is contained in:
Greg Chadwick 2020-01-13 15:10:10 +00:00
parent 486bf45711
commit b52aacf91b
6 changed files with 24 additions and 7 deletions

View file

@ -59,3 +59,9 @@ lint_off -msg UNUSED -file "*/rtl/ibex_register_file_fpga.sv" -lines 20
// ibex_core.cs_registers_i.mie_q
// Issue lowrisc/ibex#212
lint_off -msg UNOPTFLAT -file "*/rtl/ibex_cs_registers.sv" -lines 170
// Bits of signal are not used: instr_alu[24:15,11:7]
// instr flops are duplicated to reduce fan-out, neater to just leave unused
// bits in fully duplicated instr for synthesiser to optimise out rather than
// explicitly flopping only the bits we want.
lint_off -msg UNUSED -file "*/rtl/ibex_decoder.sv" -lines 106

View file

@ -14,7 +14,7 @@ module ibex_alu (
input logic [32:0] multdiv_operand_a_i,
input logic [32:0] multdiv_operand_b_i,
input logic multdiv_en_i,
input logic multdiv_sel_i,
output logic [31:0] adder_result_o,
output logic [33:0] adder_result_ext_o,
@ -59,11 +59,11 @@ module ibex_alu (
end
// prepare operand a
assign adder_in_a = multdiv_en_i ? multdiv_operand_a_i : {operand_a_i,1'b1};
assign adder_in_a = multdiv_sel_i ? multdiv_operand_a_i : {operand_a_i,1'b1};
// prepare operand b
assign operand_b_neg = {operand_b_i,1'b0} ^ {33{adder_op_b_negate}};
assign adder_in_b = multdiv_en_i ? multdiv_operand_b_i : operand_b_neg ;
assign adder_in_b = multdiv_sel_i ? multdiv_operand_b_i : operand_b_neg ;
// actual adder
assign adder_result_ext_o = $unsigned(adder_in_a) + $unsigned(adder_in_b);

View file

@ -147,6 +147,7 @@ module ibex_core #(
// Multiplier Control
logic mult_en_ex;
logic div_en_ex;
logic multdiv_sel_ex;
md_op_e multdiv_operator_ex;
logic [1:0] multdiv_signed_mode_ex;
logic [31:0] multdiv_operand_a_ex;
@ -415,6 +416,7 @@ module ibex_core #(
.mult_en_ex_o ( mult_en_ex ),
.div_en_ex_o ( div_en_ex ),
.multdiv_sel_ex_o ( multdiv_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 ),
@ -514,6 +516,7 @@ 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 ),
.multdiv_signed_mode_i ( multdiv_signed_mode_ex ),
.multdiv_operand_a_i ( multdiv_operand_a_ex ),
.multdiv_operand_b_i ( multdiv_operand_b_ex ),

View file

@ -72,6 +72,8 @@ module ibex_decoder #(
output logic mult_en_o, // perform integer multiplication
output logic div_en_o, // perform integer division or
// remainder
output logic multdiv_sel_o,
output ibex_pkg::md_op_e multdiv_operator_o,
output logic [1:0] multdiv_signed_mode_o,
@ -554,6 +556,8 @@ module ibex_decoder #(
jt_mux_sel_o = JT_ALU;
multdiv_sel_o = 1'b0;
opcode_alu = opcode_e'(instr_alu[6:0]);
unique case (opcode_alu)
@ -735,6 +739,7 @@ module ibex_decoder #(
{6'b00_0001, 3'b101}, // divu
{6'b00_0001, 3'b110}, // rem
{6'b00_0001, 3'b111}: begin // remu
multdiv_sel_o = 1'b1;
alu_operator_o = ALU_ADD;
end

View file

@ -31,6 +31,7 @@ module ibex_ex_block #(
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 [1:0] multdiv_signed_mode_i,
input logic [31:0] multdiv_operand_a_i,
input logic [31:0] multdiv_operand_b_i,
@ -51,7 +52,7 @@ module ibex_ex_block #(
logic [32:0] multdiv_alu_operand_b, multdiv_alu_operand_a;
logic [33:0] alu_adder_result_ext;
logic alu_cmp_result, alu_is_equal_result;
logic multdiv_valid, multdiv_en_sel;
logic multdiv_valid;
logic multdiv_en;
/*
@ -60,10 +61,8 @@ module ibex_ex_block #(
from the multdiv_i module are eliminated
*/
if (RV32M) begin : gen_multdiv_m
assign multdiv_en_sel = MultiplierImplementation == "fast" ? div_en_i : mult_en_i | div_en_i;
assign multdiv_en = mult_en_i | div_en_i;
end else begin : gen_multdiv_no_m
assign multdiv_en_sel = 1'b0;
assign multdiv_en = 1'b0;
end
@ -101,7 +100,7 @@ module ibex_ex_block #(
.operand_b_i ( alu_operand_b_i ),
.multdiv_operand_a_i ( multdiv_alu_operand_a ),
.multdiv_operand_b_i ( multdiv_alu_operand_b ),
.multdiv_en_i ( multdiv_en_sel ),
.multdiv_sel_i ( multdiv_sel_i ),
.adder_result_o ( alu_adder_result_ex_o ),
.adder_result_ext_o ( alu_adder_result_ext ),
.result_o ( alu_result ),

View file

@ -70,6 +70,7 @@ 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 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,
@ -203,6 +204,7 @@ 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;
@ -373,6 +375,7 @@ module ibex_id_stage #(
// MULT & DIV
.mult_en_o ( mult_en_dec ),
.div_en_o ( div_en_dec ),
.multdiv_sel_o ( multdiv_sel_dec ),
.multdiv_operator_o ( multdiv_operator ),
.multdiv_signed_mode_o ( multdiv_signed_mode ),
@ -525,6 +528,7 @@ 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;