diff --git a/lint/verilator_waiver.vlt b/lint/verilator_waiver.vlt index d6d672b2..065a46cd 100644 --- a/lint/verilator_waiver.vlt +++ b/lint/verilator_waiver.vlt @@ -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 diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index cb578890..a7bf21a6 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -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); diff --git a/rtl/ibex_core.sv b/rtl/ibex_core.sv index 4e99bdd0..244e4998 100644 --- a/rtl/ibex_core.sv +++ b/rtl/ibex_core.sv @@ -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 ), diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 315cd7d4..48e2a6be 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -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 diff --git a/rtl/ibex_ex_block.sv b/rtl/ibex_ex_block.sv index cd2c30de..80af41fa 100644 --- a/rtl/ibex_ex_block.sv +++ b/rtl/ibex_ex_block.sv @@ -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 ), diff --git a/rtl/ibex_id_stage.sv b/rtl/ibex_id_stage.sv index b0b68b6a..389ceeac 100644 --- a/rtl/ibex_id_stage.sv +++ b/rtl/ibex_id_stage.sv @@ -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;