Skip to content

Commit

Permalink
[bitmanip] Add sext.b/h instructions
Browse files Browse the repository at this point in the history
This commit implements the Bit Manipulation Extension sign-extend
instructions: sext.b (sign-extend byte) and sext.h (sign-extend half
word).

The implementation is basically a one-liner, duplicating the msb of the
byte / half-word into the msb of the output register.

Signed-off-by: ganoam <[email protected]>
  • Loading branch information
ganoam authored and vogelpi committed May 14, 2020
1 parent fac404a commit 9bd3350
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 13 deletions.
21 changes: 17 additions & 4 deletions rtl/ibex_alu.sv
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ module ibex_alu #(
logic [31:0] minmax_result;
logic [5:0] bitcnt_result;
logic [31:0] pack_result;
logic [31:0] sext_result;
logic [31:0] multicycle_result;
logic [31:0] singlebit_result;

Expand Down Expand Up @@ -860,11 +861,20 @@ module ibex_alu #(
default: pack_result = {operand_b_i[15:0], operand_a_i[15:0]};
endcase
end

//////////
// Sext //
//////////

assign sext_result = (operator_i == ALU_SEXTB) ?
{ {24{operand_a_i[7]}}, operand_a_i[7:0]} : { {16{operand_a_i[15]}}, operand_a_i[15:0]};

end else begin : g_no_alu_rvb
// RV32B result signals
assign minmax_result = '0;
assign bitcnt_result = '0;
assign pack_result = '0;
assign sext_result = '0;
assign multicycle_result = '0;
assign singlebit_result = '0;
assign shuffle_result = '0;
Expand Down Expand Up @@ -894,7 +904,7 @@ module ibex_alu #(
// Shift Operations
ALU_SLL, ALU_SRL,
ALU_SRA,
// RV32B Ops
// RV32B
ALU_SLO, ALU_SRO: result_o = shift_result;

// Shuffle Operations (RV32B)
Expand All @@ -918,6 +928,9 @@ module ibex_alu #(
ALU_PACK, ALU_PACKH,
ALU_PACKU: result_o = pack_result;

// Sign-Extend (RV32B)
ALU_SEXTB, ALU_SEXTH: result_o = sext_result;

// Ternary Bitmanip Operations (RV32B)
ALU_CMIX, ALU_CMOV,
ALU_FSL, ALU_FSR,
Expand All @@ -927,14 +940,14 @@ module ibex_alu #(
ALU_SBSET, ALU_SBCLR,
ALU_SBINV, ALU_SBEXT: result_o = singlebit_result;

// Bit Extract / Deposit (RV32B Ops)
// Bit Extract / Deposit (RV32B)
ALU_BDEP: result_o = butterfly_result;
ALU_BEXT: result_o = invbutterfly_result;

// General Reverse / Or-combine (RV32B Ops)
// General Reverse / Or-combine (RV32B)
ALU_GREV, ALU_GORC: result_o = butterfly_result;

// Bit Field Place
// Bit Field Place (RV32B)
ALU_BFP: result_o = bfp_result;

default: ;
Expand Down
17 changes: 11 additions & 6 deletions rtl/ibex_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,12 @@ module ibex_decoder #(
end
5'b0_1100: begin
unique case(instr[26:20])
7'b000_0000, // clz
7'b000_0001, // ctz
7'b000_0010: illegal_insn = RV32B ? 1'b0 : 1'b1; // pcnt
7'b00_00000, // clz
7'b00_00001, // ctz
7'b00_00010, // pcnt
7'b00_00100, // sext.b
7'b00_00101: illegal_insn = RV32B ? 1'b0 : 1'b1; // sext.h

default: illegal_insn = 1'b1;
endcase
end
Expand Down Expand Up @@ -768,9 +771,11 @@ module ibex_decoder #(
5'b0_0001: if (instr_alu[26] == 0) alu_operator_o = ALU_SHFL;
5'b0_1100: begin
unique case (instr_alu[26:20])
7'b000_0000: alu_operator_o = ALU_CLZ; // Count Leading Zeros
7'b000_0001: alu_operator_o = ALU_CTZ; // Count Trailing Zeros
7'b000_0010: alu_operator_o = ALU_PCNT; // Count Set Bits
7'b000_0000: alu_operator_o = ALU_CLZ; // Count Leading Zeros
7'b000_0001: alu_operator_o = ALU_CTZ; // Count Trailing Zeros
7'b000_0010: alu_operator_o = ALU_PCNT; // Count Set Bits
7'b000_0100: alu_operator_o = ALU_SEXTB; // Sign-extend Byte
7'b000_0101: alu_operator_o = ALU_SEXTH; // Sign-extend Half-word
default: ;
endcase
end
Expand Down
5 changes: 5 additions & 0 deletions rtl/ibex_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ typedef enum logic [5:0] {
ALU_PACKU,
ALU_PACKH,

// Sign-Extend
// RV32B
ALU_SEXTB,
ALU_SEXTH,

// Bitcounting
// RV32B
ALU_CLZ,
Expand Down
20 changes: 20 additions & 0 deletions rtl/ibex_tracer.sv
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,16 @@ module ibex_tracer (
INSN_SLTIU: decode_i_insn("sltiu");
INSN_XORI: decode_i_insn("xori");
INSN_ORI: decode_i_insn("ori");
// Version 0.92 of the Bitmanip Extension defines the pseudo-instruction
// zext.b rd rs = andi rd, rs, 255.
// Currently instruction set simulators don't output this pseudo-instruction.
INSN_ANDI: decode_i_insn("andi");
// INSN_ANDI:begin
// casez (rvfi_insn)
// INSN_ZEXTB: decode_r1_insn("zext.b");
// default: decode_i_insn("andi");
// endcase
// end
INSN_SLLI: decode_i_shift_insn("slli");
INSN_SRLI: decode_i_shift_insn("srli");
INSN_SRAI: decode_i_shift_insn("srai");
Expand Down Expand Up @@ -890,12 +899,23 @@ module ibex_tracer (
INSN_XNOR: decode_r_insn("xnor");
INSN_ORN: decode_r_insn("orn");
INSN_ANDN: decode_r_insn("andn");
// Version 0.92 of the Bitmanip Extension defines the pseudo-instruction
// zext.h rd rs = pack rd, rs, zero.
// Currently instruction set simulators don't output this pseudo-instruction.
INSN_PACK: decode_r_insn("pack");
// INSN_PACK: begin
// casez (rvfi_insn)
// INSN_ZEXTH: decode_r1_insn("zext.h");
// default: decode_r_insn("pack");
// endcase
// end
INSN_PACKH: decode_r_insn("packh");
INSN_PACKU: decode_r_insn("packu");
INSN_CLZ: decode_r1_insn("clz");
INSN_CTZ: decode_r1_insn("ctz");
INSN_PCNT: decode_r1_insn("pcnt");
INSN_SEXTB: decode_r1_insn("sext.b");
INSN_SEXTH: decode_r1_insn("sext.h");
// RV32B - ZBS
INSN_SBCLRI: decode_i_insn("sbclri");
INSN_SBSETI: decode_i_insn("sbseti");
Expand Down
12 changes: 9 additions & 3 deletions rtl/ibex_tracer_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,15 @@ parameter logic [31:0] INSN_PMULHU = { 7'b0000001, 10'b?, 3'b011, 5'b?, {OPCODE
parameter logic [31:0] INSN_SLOI = { 5'b00100 , 12'b?, 3'b001, 5'b?, {OPCODE_OP_IMM} };
parameter logic [31:0] INSN_SROI = { 5'b00100 , 12'b?, 3'b101, 5'b?, {OPCODE_OP_IMM} };
parameter logic [31:0] INSN_RORI = { 5'b01100 , 12'b?, 3'b101, 5'b?, {OPCODE_OP_IMM} };
parameter logic [31:0] INSN_CLZ = { 12'b011000000000, 5'b? , 3'b001, 5'b?, {OPCODE_OP_IMM} };
parameter logic [31:0] INSN_CTZ = { 12'b011000000001, 5'b? , 3'b001, 5'b?, {OPCODE_OP_IMM} };
parameter logic [31:0] INSN_PCNT = { 12'b011000000010, 5'b? , 3'b001, 5'b?, {OPCODE_OP_IMM} };
parameter logic [31:0] INSN_CLZ = { 12'b011000000000, 5'b?, 3'b001, 5'b?, {OPCODE_OP_IMM} };
parameter logic [31:0] INSN_CTZ = { 12'b011000000001, 5'b?, 3'b001, 5'b?, {OPCODE_OP_IMM} };
parameter logic [31:0] INSN_PCNT = { 12'b011000000010, 5'b?, 3'b001, 5'b?, {OPCODE_OP_IMM} };
parameter logic [31:0] INSN_SEXTB = { 12'b011000000100, 5'b?, 3'b001, 5'b?, {OPCODE_OP_IMM} };
parameter logic [31:0] INSN_SEXTH = { 12'b011000000101, 5'b?, 3'b001, 5'b?, {OPCODE_OP_IMM} };
// sext -- pseudoinstruction: andi rd, rs 255
parameter logic [31:0] INSN_ZEXTB = { 4'b0000, 8'b11111111, 5'b?, 3'b111, 5'b?, {OPCODE_OP_IMM} };
// sext -- pseudoinstruction: pack rd, rs zero
parameter logic [31:0] INSN_ZEXTH = { 7'b0000100, 5'b00000, 5'b?, 3'b100, 5'b?, {OPCODE_OP} };

parameter logic [31:0] INSN_SLO = { 7'b0010000, 10'b?, 3'b001, 5'b?, {OPCODE_OP} };
parameter logic [31:0] INSN_SRO = { 7'b0010000, 10'b?, 3'b101, 5'b?, {OPCODE_OP} };
Expand Down

0 comments on commit 9bd3350

Please sign in to comment.