[bitmanip][zba] Add support for Zba (address calculation) extension

Add support for the Zba extension added in v0.93 of the bit manipulation
specification (unchanged in v1.0.0). The new instructions added are:

  - sh1add: rd = (rs1 << 1) + rs2
  - sh2add: rd = (rs1 << 2) + rs2
  - sh3add: rd = (rs1 << 3) + rs2

The instructions are single cycle and have been implemented using the
adder in the ALU.

Signed-off-by: Michael Munday <mike.munday@lowrisc.org>
This commit is contained in:
Michael Munday 2021-05-12 14:12:34 +01:00
parent d1aff2f1a4
commit c35472abb9
5 changed files with 48 additions and 2 deletions

View file

@ -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,

View file

@ -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

View file

@ -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,

View file

@ -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");

View file

@ -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