diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index 0c5f9dcd..4d622bc4 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -45,11 +45,17 @@ module ibex_alu #( // Adder // /////////// + logic adder_op_a_shift1; + logic adder_op_a_shift2; + logic adder_op_a_shift3; logic adder_op_b_negate; logic [32:0] adder_in_a, adder_in_b; logic [31:0] adder_result; always_comb begin + adder_op_a_shift1 = 1'b0; + adder_op_a_shift2 = 1'b0; + adder_op_a_shift3 = 1'b0; adder_op_b_negate = 1'b0; unique case (operator_i) // Adder OPs @@ -65,12 +71,25 @@ module ibex_alu #( ALU_MIN, ALU_MINU, ALU_MAX, ALU_MAXU: adder_op_b_negate = 1'b1; + // Address Calculation OPs (RV32B Ops) + ALU_SH1ADD: if (RV32B != RV32BNone) adder_op_a_shift1 = 1'b1; + ALU_SH2ADD: if (RV32B != RV32BNone) adder_op_a_shift2 = 1'b1; + ALU_SH3ADD: if (RV32B != RV32BNone) adder_op_a_shift3 = 1'b1; + default:; endcase end // prepare operand a - assign adder_in_a = multdiv_sel_i ? multdiv_operand_a_i : {operand_a_i,1'b1}; + always_comb begin + unique case(1'b1) + multdiv_sel_i: adder_in_a = multdiv_operand_a_i; + adder_op_a_shift1: adder_in_a = {operand_a_i[30:0],2'b01}; + adder_op_a_shift2: adder_in_a = {operand_a_i[29:0],3'b001}; + adder_op_a_shift3: adder_in_a = {operand_a_i[28:0],4'b0001}; + default: adder_in_a = {operand_a_i,1'b1}; + endcase + end // prepare operand b assign operand_b_neg = {operand_b_i,1'b0} ^ {33{1'b1}}; @@ -1204,7 +1223,10 @@ module ibex_alu #( ALU_AND, ALU_ANDN: result_o = bwlogic_result; // Adder Operations - ALU_ADD, ALU_SUB: result_o = adder_result; + ALU_ADD, ALU_SUB, + // RV32B + ALU_SH1ADD, ALU_SH2ADD, + ALU_SH3ADD: result_o = adder_result; // Shift Operations ALU_SLL, ALU_SRL, diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index cd508aee..716b3015 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -462,6 +462,10 @@ module ibex_decoder #( {7'b000_0000, 3'b101}, {7'b010_0000, 3'b101}: illegal_insn = 1'b0; + // RV32B zba + {7'b001_0000, 3'b010}, // sh1add + {7'b001_0000, 3'b100}, // sh2add + {7'b001_0000, 3'b110}, // sh3add // RV32B zbb {7'b010_0000, 3'b111}, // andn {7'b010_0000, 3'b110}, // orn @@ -1013,6 +1017,11 @@ module ibex_decoder #( {7'b010_0000, 3'b110}: if (RV32B != RV32BNone) alu_operator_o = ALU_ORN; // orn {7'b010_0000, 3'b111}: if (RV32B != RV32BNone) alu_operator_o = ALU_ANDN; // andn + // RV32B zba + {7'b001_0000, 3'b010}: if (RV32B != RV32BNone) alu_operator_o = ALU_SH1ADD; // sh1add + {7'b001_0000, 3'b100}: if (RV32B != RV32BNone) alu_operator_o = ALU_SH2ADD; // sh2add + {7'b001_0000, 3'b110}: if (RV32B != RV32BNone) alu_operator_o = ALU_SH3ADD; // sh3add + // RV32B zbs {7'b010_0100, 3'b001}: if (RV32B != RV32BNone) alu_operator_o = ALU_SBCLR; // sbclr {7'b001_0100, 3'b001}: if (RV32B != RV32BNone) alu_operator_o = ALU_SBSET; // sbset diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 6a92be92..5875899a 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -101,6 +101,12 @@ package ibex_pkg; ALU_SHFL, ALU_UNSHFL, + // Address Calculations + // RV32B + ALU_SH1ADD, + ALU_SH2ADD, + ALU_SH3ADD, + // Comparisons ALU_LT, ALU_LTU, diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index be523686..a85a5858 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -907,6 +907,10 @@ module ibex_tracer ( // MISC-MEM INSN_FENCE: decode_fence(); INSN_FENCEI: decode_mnemonic("fence.i"); + // RV32B - ZBA + INSN_SH1ADD: decode_r_insn("sh1add"); + INSN_SH2ADD: decode_r_insn("sh2add"); + INSN_SH3ADD: decode_r_insn("sh3add"); // RV32B - ZBB INSN_SLOI: decode_i_shift_insn("sloi"); INSN_SROI: decode_i_shift_insn("sroi"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index b5972fac..214c9f84 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -71,6 +71,11 @@ package ibex_tracer_pkg; parameter logic [31:0] INSN_PMULHU = { 7'b0000001, 10'h?, 3'b011, 5'h?, {OPCODE_OP} }; // RV32B + // ZBA + parameter logic [31:0] INSN_SH1ADD = { 7'b0010000, 10'h?, 3'b010, 5'h?, {OPCODE_OP} }; + parameter logic [31:0] INSN_SH2ADD = { 7'b0010000, 10'h?, 3'b100, 5'h?, {OPCODE_OP} }; + parameter logic [31:0] INSN_SH3ADD = { 7'b0010000, 10'h?, 3'b110, 5'h?, {OPCODE_OP} }; + // ZBB parameter logic [31:0] INSN_SLOI = { 5'b00100 , 12'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; // Only log2(XLEN) bits of the immediate are used. For RV32, this means only the bits in