From 07ff056adf5361ef6e22770af69768423839b714 Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:50:29 +0200 Subject: [PATCH 01/20] [rtl] CSR MISA string X to B Signed-off-by: Thomas Benz --- rtl/ibex_cs_registers.sv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtl/ibex_cs_registers.sv b/rtl/ibex_cs_registers.sv index 641db2208..ce9f5a3d0 100644 --- a/rtl/ibex_cs_registers.sv +++ b/rtl/ibex_cs_registers.sv @@ -146,7 +146,7 @@ module ibex_cs_registers import ibex_pkg::*; #( endfunction // All bitmanip configs enable non-ratified sub-extensions - localparam int unsigned RV32BExtra = (RV32B != RV32BNone) ? 1 : 0; + localparam int unsigned RV32BEnabled = (RV32B != RV32BNone) ? 1 : 0; localparam int unsigned RV32MEnabled = (RV32M == RV32MNone) ? 0 : 1; localparam int unsigned PMPAddrWidth = (PMPGranularity > 0) ? PMP_ADDR_MSB - PMPGranularity : 32; // Base index of the first HPM counter (0=cycle, 1=time, 2=instret) @@ -155,7 +155,7 @@ module ibex_cs_registers import ibex_pkg::*; #( // misa localparam logic [31:0] MISA_VALUE = (0 << 0) // A - Atomic Instructions extension - | (0 << 1) // B - Bit-Manipulation extension + | (RV32BEnabled << 1) // B - Bit-Manipulation extension | (1 << 2) // C - Compressed extension | (0 << 3) // D - Double precision floating-point extension | (32'(RV32E) << 4) // E - RV32E base ISA @@ -165,7 +165,7 @@ module ibex_cs_registers import ibex_pkg::*; #( | (0 << 13) // N - User level interrupts supported | (0 << 18) // S - Supervisor mode implemented | (1 << 20) // U - User mode implemented - | (RV32BExtra << 23) // X - Non-standard extensions present + | (0 << 23) // X - Non-standard extensions present | (32'(CSR_MISA_MXL) << 30); // M-XLEN typedef struct packed { From 9b9d17204c9ca9227f815fc7e2eecbc75f3f8282 Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:19 +0200 Subject: [PATCH 02/20] [rtl] Remove Xzbe0p93 Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 297 +++++------------------------------------ rtl/ibex_decoder.sv | 17 --- rtl/ibex_ex_block.sv | 14 +- rtl/ibex_pkg.sv | 5 - rtl/ibex_tracer.sv | 3 - rtl/ibex_tracer_pkg.sv | 4 - 6 files changed, 37 insertions(+), 303 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index 563f571cf..855d7233e 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -20,9 +20,9 @@ module ibex_alu #( input logic multdiv_sel_i, - input logic [31:0] imd_val_q_i[2], - output logic [31:0] imd_val_d_o[2], - output logic [1:0] imd_val_we_o, + input logic [31:0] imd_val_q_i, + output logic [31:0] imd_val_d_o, + output logic imd_val_we_o, output logic [31:0] adder_result_o, output logic [33:0] adder_result_ext_o, @@ -404,8 +404,6 @@ module ibex_alu #( logic [31:0] rev_result; logic [31:0] shuffle_result; logic [31:0] xperm_result; - logic [31:0] butterfly_result; - logic [31:0] invbutterfly_result; logic [31:0] clmul_result; logic [31:0] multicycle_result; @@ -415,12 +413,9 @@ module ibex_alu #( // Bitcounting // ///////////////// - // The bit-counter structure computes the number of set bits in its operand. Partial results - // (from left to right) are needed to compute the control masks for computation of - // bcompress/bdecompress by the butterfly network, if implemented. + // The bit-counter structure computes the number of set bits in its operand. // For cpop, clz and ctz, only the end result is used. - logic zbe_op; logic bitcnt_ctz; logic bitcnt_clz; logic bitcnt_cz; @@ -428,8 +423,6 @@ module ibex_alu #( logic [31:0] bitcnt_mask_op; logic [31:0] bitcnt_bit_mask; logic [ 5:0] bitcnt_partial [32]; - logic [31:0] bitcnt_partial_lsb_d; - logic [31:0] bitcnt_partial_msb_d; assign bitcnt_ctz = operator_i == ALU_CTZ; @@ -453,11 +446,8 @@ module ibex_alu #( bitcnt_bit_mask = ~bitcnt_bit_mask; end - assign zbe_op = (operator_i == ALU_BCOMPRESS) | (operator_i == ALU_BDECOMPRESS); - always_comb begin unique case (1'b1) - zbe_op: bitcnt_bits = operand_b_i; bitcnt_cz: bitcnt_bits = bitcnt_bit_mask & ~bitcnt_mask_op; // clz / ctz default: bitcnt_bits = operand_a_i; // cpop endcase @@ -940,7 +930,7 @@ module ibex_alu #( // Select clmul input always_comb begin if (crc_op) begin - clmul_op_a = instr_first_cycle_i ? crc_operand : imd_val_q_i[0]; + clmul_op_a = instr_first_cycle_i ? crc_operand : imd_val_q_i; clmul_op_b = instr_first_cycle_i ? crc_mu_rev : crc_poly; end else begin clmul_op_a = clmul_rmode | clmul_hmode ? operand_a_rev : operand_a_i; @@ -993,208 +983,6 @@ module ibex_alu #( assign crc_hmode = '0; end - if (RV32B == RV32BFull) begin : gen_alu_rvb_full - - /////////////// - // Butterfly // - /////////////// - - // The butterfly / inverse butterfly network executing bcompress/bdecompress (zbe) - // instructions. For bdecompress, the control bits mask of a local left region is generated - // by the inverse of a n-bit left rotate and complement upon wrap (LROTC) operation by the - // number of ones in the deposit bitmask to the right of the segment. n hereby denotes the - // width of the according segment. The bitmask for a pertaining local right region is equal - // to the corresponding local left region. Bcompress uses an analogue inverse process. - // Consider the following 8-bit example. For details, see Hilewitz et al. "Fast Bit Gather, - // Bit Scatter and Bit Permuation Instructions for Commodity Microprocessors", (2008). - // - // The bcompress/bdecompress instructions are completed in 2 cycles. In the first cycle, the - // control bitmask is prepared by executing the parallel prefix bit count. In the second - // cycle, the bit swapping is executed according to the control masks. - - // 8-bit example: (Hilewitz et al.) - // Consider the instruction bdecompress operand_a_i deposit_mask - // Let operand_a_i = 8'babcd_efgh - // deposit_mask = 8'b1010_1101 - // - // control bitmask for stage 1: - // - number of ones in the right half of the deposit bitmask: 3 - // - width of the segment: 4 - // - control bitmask = ~LROTC(4'b0, 3)[3:0] = 4'b1000 - // - // control bitmask: c3 c2 c1 c0 c3 c2 c1 c0 - // 1 0 0 0 1 0 0 0 - // <- L -----> <- R -----> - // operand_a_i a b c d e f g h - // :\ | | | /: | | | - // : +|---|--|-+ : | | | - // :/ | | | \: | | | - // stage 1 e b c d a f g h - // - // control bitmask: c3 c2 c3 c2 c1 c0 c1 c0 - // 1 1 1 1 1 0 1 0 - // :\ :\ /: /: :\ | /: | - // : +:-+-:+ : : +|-+ : | - // :/ :/ \: \: :/ | \: | - // stage 2 c d e b g f a h - // L R L R L R L R - // control bitmask: c3 c3 c2 c2 c1 c1 c0 c0 - // 1 1 0 0 1 1 0 0 - // :\/: | | :\/: | | - // : : | | : : | | - // :/\: | | :/\: | | - // stage 3 d c e b f g a h - // & deposit bitmask: 1 0 1 0 1 1 0 1 - // result: d 0 e 0 f g 0 h - - logic [ 5:0] bitcnt_partial_q [32]; - - // first cycle - // Store partial bitcnts - for (genvar i = 0; i < 32; i++) begin : gen_bitcnt_reg_in_lsb - assign bitcnt_partial_lsb_d[i] = bitcnt_partial[i][0]; - end - - for (genvar i = 0; i < 16; i++) begin : gen_bitcnt_reg_in_b1 - assign bitcnt_partial_msb_d[i] = bitcnt_partial[2*i+1][1]; - end - - for (genvar i = 0; i < 8; i++) begin : gen_bitcnt_reg_in_b2 - assign bitcnt_partial_msb_d[16+i] = bitcnt_partial[4*i+3][2]; - end - - for (genvar i = 0; i < 4; i++) begin : gen_bitcnt_reg_in_b3 - assign bitcnt_partial_msb_d[24+i] = bitcnt_partial[8*i+7][3]; - end - - for (genvar i = 0; i < 2; i++) begin : gen_bitcnt_reg_in_b4 - assign bitcnt_partial_msb_d[28+i] = bitcnt_partial[16*i+15][4]; - end - - assign bitcnt_partial_msb_d[30] = bitcnt_partial[31][5]; - assign bitcnt_partial_msb_d[31] = 1'b0; // unused - - // Second cycle - // Load partial bitcnts - always_comb begin - bitcnt_partial_q = '{default: '0}; - - for (int unsigned i = 0; i < 32; i++) begin : gen_bitcnt_reg_out_lsb - bitcnt_partial_q[i][0] = imd_val_q_i[0][i]; - end - - for (int unsigned i = 0; i < 16; i++) begin : gen_bitcnt_reg_out_b1 - bitcnt_partial_q[2*i+1][1] = imd_val_q_i[1][i]; - end - - for (int unsigned i = 0; i < 8; i++) begin : gen_bitcnt_reg_out_b2 - bitcnt_partial_q[4*i+3][2] = imd_val_q_i[1][16+i]; - end - - for (int unsigned i = 0; i < 4; i++) begin : gen_bitcnt_reg_out_b3 - bitcnt_partial_q[8*i+7][3] = imd_val_q_i[1][24+i]; - end - - for (int unsigned i = 0; i < 2; i++) begin : gen_bitcnt_reg_out_b4 - bitcnt_partial_q[16*i+15][4] = imd_val_q_i[1][28+i]; - end - - bitcnt_partial_q[31][5] = imd_val_q_i[1][30]; - end - - logic [31:0] butterfly_mask_l[5]; - logic [31:0] butterfly_mask_r[5]; - logic [31:0] butterfly_mask_not[5]; - logic [31:0] lrotc_stage [5]; // left rotate and complement upon wrap - - // number of bits in local r = 32 / 2**(stage + 1) = 16/2**stage - `define _N(stg) (16 >> stg) - - // bcompress / bdecompress control bit generation - for (genvar stg = 0; stg < 5; stg++) begin : gen_butterfly_ctrl_stage - // number of segs: 2** stg - for (genvar seg=0; seg<2**stg; seg++) begin : gen_butterfly_ctrl - - assign lrotc_stage[stg][2*`_N(stg)*(seg+1)-1 : 2*`_N(stg)*seg] = - {{`_N(stg){1'b0}},{`_N(stg){1'b1}}} << - bitcnt_partial_q[`_N(stg)*(2*seg+1)-1][$clog2(`_N(stg)):0]; - - assign butterfly_mask_l[stg][`_N(stg)*(2*seg+2)-1 : `_N(stg)*(2*seg+1)] - = ~lrotc_stage[stg][`_N(stg)*(2*seg+2)-1 : `_N(stg)*(2*seg+1)]; - - assign butterfly_mask_r[stg][`_N(stg)*(2*seg+1)-1 : `_N(stg)*(2*seg)] - = ~lrotc_stage[stg][`_N(stg)*(2*seg+2)-1 : `_N(stg)*(2*seg+1)]; - - assign butterfly_mask_l[stg][`_N(stg)*(2*seg+1)-1 : `_N(stg)*(2*seg)] = '0; - assign butterfly_mask_r[stg][`_N(stg)*(2*seg+2)-1 : `_N(stg)*(2*seg+1)] = '0; - end - end - `undef _N - - for (genvar stg = 0; stg < 5; stg++) begin : gen_butterfly_not - assign butterfly_mask_not[stg] = - ~(butterfly_mask_l[stg] | butterfly_mask_r[stg]); - end - - always_comb begin - butterfly_result = operand_a_i; - - butterfly_result = butterfly_result & butterfly_mask_not[0] | - ((butterfly_result & butterfly_mask_l[0]) >> 16)| - ((butterfly_result & butterfly_mask_r[0]) << 16); - - butterfly_result = butterfly_result & butterfly_mask_not[1] | - ((butterfly_result & butterfly_mask_l[1]) >> 8)| - ((butterfly_result & butterfly_mask_r[1]) << 8); - - butterfly_result = butterfly_result & butterfly_mask_not[2] | - ((butterfly_result & butterfly_mask_l[2]) >> 4)| - ((butterfly_result & butterfly_mask_r[2]) << 4); - - butterfly_result = butterfly_result & butterfly_mask_not[3] | - ((butterfly_result & butterfly_mask_l[3]) >> 2)| - ((butterfly_result & butterfly_mask_r[3]) << 2); - - butterfly_result = butterfly_result & butterfly_mask_not[4] | - ((butterfly_result & butterfly_mask_l[4]) >> 1)| - ((butterfly_result & butterfly_mask_r[4]) << 1); - - butterfly_result = butterfly_result & operand_b_i; - end - - always_comb begin - invbutterfly_result = operand_a_i & operand_b_i; - - invbutterfly_result = invbutterfly_result & butterfly_mask_not[4] | - ((invbutterfly_result & butterfly_mask_l[4]) >> 1)| - ((invbutterfly_result & butterfly_mask_r[4]) << 1); - - invbutterfly_result = invbutterfly_result & butterfly_mask_not[3] | - ((invbutterfly_result & butterfly_mask_l[3]) >> 2)| - ((invbutterfly_result & butterfly_mask_r[3]) << 2); - - invbutterfly_result = invbutterfly_result & butterfly_mask_not[2] | - ((invbutterfly_result & butterfly_mask_l[2]) >> 4)| - ((invbutterfly_result & butterfly_mask_r[2]) << 4); - - invbutterfly_result = invbutterfly_result & butterfly_mask_not[1] | - ((invbutterfly_result & butterfly_mask_l[1]) >> 8)| - ((invbutterfly_result & butterfly_mask_r[1]) << 8); - - invbutterfly_result = invbutterfly_result & butterfly_mask_not[0] | - ((invbutterfly_result & butterfly_mask_l[0]) >> 16)| - ((invbutterfly_result & butterfly_mask_r[0]) << 16); - end - end else begin : gen_alu_rvb_not_full - logic [31:0] unused_imd_val_q_1; - assign unused_imd_val_q_1 = imd_val_q_i[1]; - assign butterfly_result = '0; - assign invbutterfly_result = '0; - // support signals - assign bitcnt_partial_lsb_d = '0; - assign bitcnt_partial_msb_d = '0; - end - ////////////////////////////////////// // Multicycle Bitmanip Instructions // ////////////////////////////////////// @@ -1205,37 +993,37 @@ module ibex_alu #( always_comb begin unique case (operator_i) ALU_CMOV: begin - multicycle_result = (operand_b_i == 32'h0) ? operand_a_i : imd_val_q_i[0]; - imd_val_d_o = '{operand_a_i, 32'h0}; + multicycle_result = (operand_b_i == 32'h0) ? operand_a_i : imd_val_q_i; + imd_val_d_o = operand_a_i; if (instr_first_cycle_i) begin - imd_val_we_o = 2'b01; + imd_val_we_o = 1'b1; end else begin - imd_val_we_o = 2'b00; + imd_val_we_o = 1'b0; end end ALU_CMIX: begin - multicycle_result = imd_val_q_i[0] | bwlogic_and_result; - imd_val_d_o = '{bwlogic_and_result, 32'h0}; + multicycle_result = imd_val_q_i | bwlogic_and_result; + imd_val_d_o = bwlogic_and_result; if (instr_first_cycle_i) begin - imd_val_we_o = 2'b01; + imd_val_we_o = 1'b1; end else begin - imd_val_we_o = 2'b00; + imd_val_we_o = 1'b0; end end ALU_FSR, ALU_FSL, ALU_ROL, ALU_ROR: begin if (shift_amt[4:0] == 5'h0) begin - multicycle_result = shift_amt[5] ? operand_a_i : imd_val_q_i[0]; + multicycle_result = shift_amt[5] ? operand_a_i : imd_val_q_i; end else begin - multicycle_result = imd_val_q_i[0] | shift_result; + multicycle_result = imd_val_q_i | shift_result; end - imd_val_d_o = '{shift_result, 32'h0}; + imd_val_d_o = shift_result; if (instr_first_cycle_i) begin - imd_val_we_o = 2'b01; + imd_val_we_o = 1'b1; end else begin - imd_val_we_o = 2'b00; + imd_val_we_o = 1'b0; end end @@ -1248,39 +1036,22 @@ module ibex_alu #( crc_hmode: multicycle_result = clmul_result_rev ^ (operand_a_i >> 16); default: multicycle_result = clmul_result_rev; endcase - imd_val_d_o = '{clmul_result_rev, 32'h0}; - if (instr_first_cycle_i) begin - imd_val_we_o = 2'b01; - end else begin - imd_val_we_o = 2'b00; - end - end else begin - imd_val_d_o = '{operand_a_i, 32'h0}; - imd_val_we_o = 2'b00; - multicycle_result = '0; - end - end - - ALU_BCOMPRESS, ALU_BDECOMPRESS: begin - if (RV32B == RV32BFull) begin - multicycle_result = (operator_i == ALU_BDECOMPRESS) ? butterfly_result : - invbutterfly_result; - imd_val_d_o = '{bitcnt_partial_lsb_d, bitcnt_partial_msb_d}; + imd_val_d_o = clmul_result_rev; if (instr_first_cycle_i) begin - imd_val_we_o = 2'b11; + imd_val_we_o = 1'b1; end else begin - imd_val_we_o = 2'b00; + imd_val_we_o = 1'b0; end end else begin - imd_val_d_o = '{operand_a_i, 32'h0}; - imd_val_we_o = 2'b00; + imd_val_d_o = operand_a_i; + imd_val_we_o = 1'b0; multicycle_result = '0; end end default: begin - imd_val_d_o = '{operand_a_i, 32'h0}; - imd_val_we_o = 2'b00; + imd_val_d_o = operand_a_i; + imd_val_we_o = 1'b0; multicycle_result = '0; end endcase @@ -1288,12 +1059,8 @@ module ibex_alu #( end else begin : g_no_alu_rvb - logic [31:0] unused_imd_val_q[2]; - assign unused_imd_val_q = imd_val_q_i; - logic [31:0] unused_butterfly_result; - assign unused_butterfly_result = butterfly_result; - logic [31:0] unused_invbutterfly_result; - assign unused_invbutterfly_result = invbutterfly_result; + logic [31:0] unused_imd_val_q; + assign unused_imd_val_q = imd_val_q_i; // RV32B result signals assign bitcnt_result = '0; assign minmax_result = '0; @@ -1303,13 +1070,11 @@ module ibex_alu #( assign rev_result = '0; assign shuffle_result = '0; assign xperm_result = '0; - assign butterfly_result = '0; - assign invbutterfly_result = '0; assign clmul_result = '0; assign multicycle_result = '0; // RV32B support signals - assign imd_val_d_o = '{default: '0}; - assign imd_val_we_o = '{default: '0}; + assign imd_val_d_o = '0; + assign imd_val_we_o = '0; end //////////////// @@ -1372,9 +1137,7 @@ module ibex_alu #( // Cyclic Redundancy Checks (RV32B) ALU_CRC32_W, ALU_CRC32C_W, ALU_CRC32_H, ALU_CRC32C_H, - ALU_CRC32_B, ALU_CRC32C_B, - // Bit Compress / Decompress (RV32B) - ALU_BCOMPRESS, ALU_BDECOMPRESS: result_o = multicycle_result; + ALU_CRC32_B, ALU_CRC32C_B: result_o = multicycle_result; // Single-Bit Bitmanip Operations (RV32B) ALU_BSET, ALU_BCLR, diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 843eb05f0..e88e29b21 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -508,9 +508,6 @@ module ibex_decoder #( {7'b000_0101, 3'b011}: begin // clmulh illegal_insn = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b0 : 1'b1; end - // RV32B zbe - {7'b010_0100, 3'b110}, // bdecompress - {7'b000_0100, 3'b110}: illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // bcompress // RV32M instructions {7'b000_0001, 3'b000}: begin // mul @@ -1082,20 +1079,6 @@ module ibex_decoder #( if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_CLMULH; end - // RV32B zbe - {7'b010_0100, 3'b110}: begin - if (RV32B == RV32BFull) begin - alu_operator_o = ALU_BDECOMPRESS; - alu_multicycle_o = 1'b1; - end - end - {7'b000_0100, 3'b110}: begin - if (RV32B == RV32BFull) begin - alu_operator_o = ALU_BCOMPRESS; - alu_multicycle_o = 1'b1; - end - end - // RV32M instructions, all use the same ALU operation {7'b000_0001, 3'b000}: begin // mul alu_operator_o = ALU_ADD; diff --git a/rtl/ibex_ex_block.sv b/rtl/ibex_ex_block.sv index 462f2fcfd..1916e9a2d 100644 --- a/rtl/ibex_ex_block.sv +++ b/rtl/ibex_ex_block.sv @@ -62,9 +62,9 @@ module ibex_ex_block #( logic alu_cmp_result, alu_is_equal_result; logic multdiv_valid; logic multdiv_sel; - logic [31:0] alu_imd_val_q[2]; - logic [31:0] alu_imd_val_d[2]; - logic [ 1:0] alu_imd_val_we; + logic [31:0] alu_imd_val_q; + logic [31:0] alu_imd_val_d; + logic alu_imd_val_we; logic [33:0] multdiv_imd_val_d[2]; logic [ 1:0] multdiv_imd_val_we; @@ -80,11 +80,11 @@ module ibex_ex_block #( end // Intermediate Value Register Mux - assign imd_val_d_o[0] = multdiv_sel ? multdiv_imd_val_d[0] : {2'b0, alu_imd_val_d[0]}; - assign imd_val_d_o[1] = multdiv_sel ? multdiv_imd_val_d[1] : {2'b0, alu_imd_val_d[1]}; - assign imd_val_we_o = multdiv_sel ? multdiv_imd_val_we : alu_imd_val_we; + assign imd_val_d_o[0] = multdiv_sel ? multdiv_imd_val_d[0] : {2'b0, alu_imd_val_d}; + assign imd_val_d_o[1] = multdiv_sel ? multdiv_imd_val_d[1] : 34'd0; + assign imd_val_we_o = multdiv_sel ? multdiv_imd_val_we : {1'b0, alu_imd_val_we}; - assign alu_imd_val_q = '{imd_val_q_i[0][31:0], imd_val_q_i[1][31:0]}; + assign alu_imd_val_q = imd_val_q_i[0][31:0]; assign result_ex_o = multdiv_sel ? multdiv_result : alu_result; diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 216aa1ab3..2505e27da 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -167,11 +167,6 @@ package ibex_pkg; ALU_BINV, ALU_BEXT, - // Bit Compress / Decompress - // RV32B - ALU_BCOMPRESS, - ALU_BDECOMPRESS, - // Bit Field Place // RV32B ALU_BFP, diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index 3c55b7161..f91584a60 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -1095,9 +1095,6 @@ module ibex_tracer ( INSN_BSET: decode_r_insn("bset"); INSN_BINV: decode_r_insn("binv"); INSN_BEXT: decode_r_insn("bext"); - // RV32B - ZBE - INSN_BDECOMPRESS: decode_r_insn("bdecompress"); - INSN_BCOMPRESS: decode_r_insn("bcompress"); // RV32B - ZBP INSN_GREV: decode_r_insn("grev"); INSN_GREVI: begin diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index b1f975e8f..58c20a40e 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -258,10 +258,6 @@ package ibex_tracer_pkg; // fsri. parameter logic [31:0] INSN_SROI = { 5'b00100 , 1'b0, 11'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - // ZBE - parameter logic [31:0] INSN_BDECOMPRESS = {7'b0100100, 10'h?, 3'b110, 5'h?, {OPCODE_OP} }; - parameter logic [31:0] INSN_BCOMPRESS = {7'b0000100, 10'h?, 3'b110, 5'h?, {OPCODE_OP} }; - // ZBT parameter logic [31:0] INSN_FSRI = { 5'h?, 1'b1, 11'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; From 0c5d7d04f0cc4a63161e5b552554681ed81ac350 Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:19 +0200 Subject: [PATCH 03/20] [rtl] Remove Xzbf0p93 Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 42 ++++-------------------------------------- rtl/ibex_decoder.sv | 7 +------ rtl/ibex_pkg.sv | 4 ---- rtl/ibex_tracer.sv | 3 --- rtl/ibex_tracer_pkg.sv | 3 --- 5 files changed, 5 insertions(+), 54 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index 855d7233e..6e3bb83bd 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -234,10 +234,6 @@ module ibex_alu #( // // For bext, the bit defined by operand_b_i[4:0] is to be returned. This is done by simply // shifting operand_a_i to the right by the required amount and returning bit [0] of the result. - // - // Bit-Field Place - // =============== - // The shifter structure is shared to compute bfp_mask << bfp_off. logic shift_left; logic shift_ones; @@ -254,39 +250,15 @@ module ibex_alu #( logic [31:0] shift_result; logic [31:0] shift_result_rev; - // zbf - logic bfp_op; - logic [4:0] bfp_len; - logic [4:0] bfp_off; - logic [31:0] bfp_mask; - logic [31:0] bfp_mask_rev; - logic [31:0] bfp_result; - - // bfp: shares the shifter structure to compute bfp_mask << bfp_off - assign bfp_op = (RV32B != RV32BNone) ? (operator_i == ALU_BFP) : 1'b0; - assign bfp_len = {~(|operand_b_i[27:24]), operand_b_i[27:24]}; // len = 0 encodes for len = 16 - assign bfp_off = operand_b_i[20:16]; - assign bfp_mask = (RV32B != RV32BNone) ? ~(32'hffff_ffff << bfp_len) : '0; - for (genvar i = 0; i < 32; i++) begin : gen_rev_bfp_mask - assign bfp_mask_rev[i] = bfp_mask[31-i]; - end - - assign bfp_result =(RV32B != RV32BNone) ? - (~shift_result & operand_a_i) | ((operand_b_i & bfp_mask) << bfp_off) : '0; - // bit shift_amt[5]: word swap bit: only considered for FSL/FSR. // if set, reverse operations in first and second cycle. assign shift_amt[5] = operand_b_i[5] & shift_funnel; assign shift_amt_compl = 32 - operand_b_i[4:0]; always_comb begin - if (bfp_op) begin - shift_amt[4:0] = bfp_off; // length field of bfp control word - end else begin - shift_amt[4:0] = instr_first_cycle_i ? - (operand_b_i[5] && shift_funnel ? shift_amt_compl[4:0] : operand_b_i[4:0]) : - (operand_b_i[5] && shift_funnel ? operand_b_i[4:0] : shift_amt_compl[4:0]); - end + shift_amt[4:0] = instr_first_cycle_i ? + (operand_b_i[5] && shift_funnel ? shift_amt_compl[4:0] : operand_b_i[4:0]) : + (operand_b_i[5] && shift_funnel ? operand_b_i[4:0] : shift_amt_compl[4:0]); end // single-bit mode: shift @@ -300,12 +272,10 @@ module ibex_alu #( // * fsl: without word-swap bit: first cycle, else: second cycle // * fsr: without word-swap bit: second cycle, else: first cycle // * a single-bit instruction: bclr, bset, binv (excluding bext) - // * bfp: bfp_mask << bfp_off always_comb begin unique case (operator_i) ALU_SLL: shift_left = 1'b1; ALU_SLO: shift_left = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b1 : 1'b0; - ALU_BFP: shift_left = (RV32B != RV32BNone) ? 1'b1 : 1'b0; ALU_ROL: shift_left = (RV32B != RV32BNone) ? instr_first_cycle_i : 0; ALU_ROR: shift_left = (RV32B != RV32BNone) ? ~instr_first_cycle_i : 0; ALU_FSL: shift_left = (RV32B != RV32BNone) ? @@ -328,12 +298,11 @@ module ibex_alu #( // shifter structure. always_comb begin // select shifter input - // for bfp, sbmode and shift_left the corresponding bit-reversed input is chosen. + // for sbmode and shift_left the corresponding bit-reversed input is chosen. if (RV32B == RV32BNone) begin shift_operand = shift_left ? operand_a_rev : operand_a_i; end else begin unique case (1'b1) - bfp_op: shift_operand = bfp_mask_rev; shift_sbmode: shift_operand = 32'h8000_0000; default: shift_operand = shift_left ? operand_a_rev : operand_a_i; endcase @@ -1146,9 +1115,6 @@ module ibex_alu #( // General Reverse / Or-combine (RV32B) ALU_GREV, ALU_GORC: result_o = rev_result; - // Bit Field Place (RV32B) - ALU_BFP: result_o = bfp_result; - // Carry-less Multiply Operations (RV32B) ALU_CLMUL, ALU_CLMULR, ALU_CLMULH: result_o = clmul_result; diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index e88e29b21..7c8f32efd 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -489,9 +489,7 @@ module ibex_decoder #( {7'b010_0100, 3'b001}, // bclr {7'b001_0100, 3'b001}, // bset {7'b011_0100, 3'b001}, // binv - {7'b010_0100, 3'b101}, // bext - // RV32B zbf - {7'b010_0100, 3'b111}: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // bfp + {7'b010_0100, 3'b101}: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // bext // RV32B zbp {7'b011_0100, 3'b101}, // grev {7'b001_0100, 3'b101}, // gorc @@ -1040,9 +1038,6 @@ module ibex_decoder #( {7'b011_0100, 3'b001}: if (RV32B != RV32BNone) alu_operator_o = ALU_BINV; {7'b010_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_BEXT; - // RV32B zbf - {7'b010_0100, 3'b111}: if (RV32B != RV32BNone) alu_operator_o = ALU_BFP; - // RV32B zbp {7'b011_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_GREV; {7'b001_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_GORC; diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 2505e27da..33917dda7 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -167,10 +167,6 @@ package ibex_pkg; ALU_BINV, ALU_BEXT, - // Bit Field Place - // RV32B - ALU_BFP, - // Carry-less Multiply // RV32B ALU_CLMUL, diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index f91584a60..ba9818988 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -1185,9 +1185,6 @@ module ibex_tracer ( INSN_FSL: decode_r_funnelshift_insn("fsl"); INSN_FSRI: decode_i_funnelshift_insn("fsri"); - // RV32B - ZBF - INSN_BFP: decode_r_insn("bfp"); - // RV32B - ZBC INSN_CLMUL: decode_r_insn("clmul"); INSN_CLMULR: decode_r_insn("clmulr"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 58c20a40e..8c404bbe2 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -266,9 +266,6 @@ package ibex_tracer_pkg; parameter logic [31:0] INSN_FSL = {5'h?, 2'b10, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_FSR = {5'h?, 2'b10, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; - // ZBF - parameter logic [31:0] INSN_BFP = {7'b0100100, 10'h?, 3'b111, 5'h?, {OPCODE_OP} }; - // ZBC parameter logic [31:0] INSN_CLMUL = {7'b0000101, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_CLMULR = {7'b0000101, 10'h?, 3'b010, 5'h?, {OPCODE_OP} }; From 571dfbcf2965535d176d0bb03967aafa82031bd1 Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:19 +0200 Subject: [PATCH 04/20] [rtl] Remove Xzbr0p93 Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 119 +++-------------------------------------- rtl/ibex_decoder.sv | 44 --------------- rtl/ibex_pkg.sv | 10 +--- rtl/ibex_tracer.sv | 8 --- rtl/ibex_tracer_pkg.sv | 14 ----- 5 files changed, 8 insertions(+), 187 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index 6e3bb83bd..ef2ef2308 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -600,8 +600,6 @@ module ibex_alu #( end end - logic crc_hmode; - logic crc_bmode; logic [31:0] clmul_result_rev; if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin : gen_alu_rvb_otearlgrey_full @@ -778,9 +776,9 @@ module ibex_alu #( end assign xperm_result = xperm_n; - /////////////////////////////////////////////////// - // Carry-less Multiply + Cyclic Redundancy Check // - /////////////////////////////////////////////////// + ///////////////////////// + // Carry-less Multiply // + ///////////////////////// // Carry-less multiplication can be understood as multiplication based on // the addition interpreted as the bit-wise xor operation. @@ -805,39 +803,6 @@ module ibex_alu #( // [ operand_b[i] ? (operand_a << i) : '0 for i in 0 ... 31 ] // is generated. The entries of the array are pairwise 'xor-ed' // together in a 5-stage binary tree. - // - // - // Cyclic Redundancy Check: - // - // CRC-32 (CRC-32/ISO-HDLC) and CRC-32C (CRC-32/ISCSI) are directly implemented. For - // documentation of the crc configuration (crc-polynomials, initialization, reflection, etc.) - // see http://reveng.sourceforge.net/crc-catalogue/all.htm - // A useful guide to crc arithmetic and algorithms is given here: - // http://www.piclist.com/techref/method/math/crcguide.html. - // - // The CRC operation solves the following equation using binary polynomial arithmetic: - // - // rev(rd)(x) = rev(rs1)(x) * x**n mod {1, P}(x) - // - // where P denotes lower 32 bits of the corresponding CRC polynomial, rev(a) the bit reversal - // of a, n = 8,16, or 32 for .b, .h, .w -variants. {a, b} denotes bit concatenation. - // - // Using Barrett reduction, one can show that - // - // M(x) mod P(x) = R(x) = - // (M(x) * x**n) & {deg(P(x)'{1'b1}}) ^ (M(x) x**-(deg(P(x) - n)) cx mu(x) cx P(x), - // - // Where mu(x) = polydiv(x**64, {1,P}) & 0xffffffff. Here, 'cx' refers to carry-less - // multiplication. Substituting rev(rd)(x) for R(x) and rev(rs1)(x) for M(x) and solving for - // rd(x) with P(x) a crc32 polynomial (deg(P(x)) = 32), we get - // - // rd = rev( (rev(rs1) << n) ^ ((rev(rs1) >> (32-n)) cx mu cx P) - // = (rs1 >> n) ^ rev(rev( (rs1 << (32-n)) cx rev(mu)) cx P) - // ^-- cycle 0--------------------^ - // ^- cycle 1 -------------------------------------------^ - // - // In the last step we used the fact that carry-less multiplication is bit-order agnostic: - // rev(a cx b) = rev(a) cx rev(b). logic clmul_rmode; logic clmul_hmode; @@ -859,52 +824,10 @@ module ibex_alu #( assign clmul_rmode = operator_i == ALU_CLMULR; assign clmul_hmode = operator_i == ALU_CLMULH; - // CRC - localparam logic [31:0] CRC32_POLYNOMIAL = 32'h04c1_1db7; - localparam logic [31:0] CRC32_MU_REV = 32'hf701_1641; - - localparam logic [31:0] CRC32C_POLYNOMIAL = 32'h1edc_6f41; - localparam logic [31:0] CRC32C_MU_REV = 32'hdea7_13f1; - - logic crc_op; - - logic crc_cpoly; - - logic [31:0] crc_operand; - logic [31:0] crc_poly; - logic [31:0] crc_mu_rev; - - assign crc_op = (operator_i == ALU_CRC32C_W) | (operator_i == ALU_CRC32_W) | - (operator_i == ALU_CRC32C_H) | (operator_i == ALU_CRC32_H) | - (operator_i == ALU_CRC32C_B) | (operator_i == ALU_CRC32_B); - - assign crc_cpoly = (operator_i == ALU_CRC32C_W) | - (operator_i == ALU_CRC32C_H) | - (operator_i == ALU_CRC32C_B); - - assign crc_hmode = (operator_i == ALU_CRC32_H) | (operator_i == ALU_CRC32C_H); - assign crc_bmode = (operator_i == ALU_CRC32_B) | (operator_i == ALU_CRC32C_B); - - assign crc_poly = crc_cpoly ? CRC32C_POLYNOMIAL : CRC32_POLYNOMIAL; - assign crc_mu_rev = crc_cpoly ? CRC32C_MU_REV : CRC32_MU_REV; - - always_comb begin - unique case (1'b1) - crc_bmode: crc_operand = {operand_a_i[7:0], 24'h0}; - crc_hmode: crc_operand = {operand_a_i[15:0], 16'h0}; - default: crc_operand = operand_a_i; - endcase - end - // Select clmul input always_comb begin - if (crc_op) begin - clmul_op_a = instr_first_cycle_i ? crc_operand : imd_val_q_i; - clmul_op_b = instr_first_cycle_i ? crc_mu_rev : crc_poly; - end else begin - clmul_op_a = clmul_rmode | clmul_hmode ? operand_a_rev : operand_a_i; - clmul_op_b = clmul_rmode | clmul_hmode ? operand_b_rev : operand_b_i; - end + clmul_op_a = clmul_rmode | clmul_hmode ? operand_a_rev : operand_a_i; + clmul_op_b = clmul_rmode | clmul_hmode ? operand_b_rev : operand_b_i; end for (genvar i = 0; i < 32; i++) begin : gen_clmul_and_op @@ -948,14 +871,12 @@ module ibex_alu #( assign clmul_result = '0; // support signals assign clmul_result_rev = '0; - assign crc_bmode = '0; - assign crc_hmode = '0; end ////////////////////////////////////// // Multicycle Bitmanip Instructions // ////////////////////////////////////// - // Ternary instructions + Shift Rotations + Bit Compress/Decompress + CRC + // Ternary instructions + Shift Rotations // For ternary instructions (zbt), operand_a_i is tied to rs1 in the first cycle and rs3 in the // second cycle. operand_b_i is always tied to rs2. @@ -996,28 +917,6 @@ module ibex_alu #( end end - ALU_CRC32_W, ALU_CRC32C_W, - ALU_CRC32_H, ALU_CRC32C_H, - ALU_CRC32_B, ALU_CRC32C_B: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin - unique case (1'b1) - crc_bmode: multicycle_result = clmul_result_rev ^ (operand_a_i >> 8); - crc_hmode: multicycle_result = clmul_result_rev ^ (operand_a_i >> 16); - default: multicycle_result = clmul_result_rev; - endcase - imd_val_d_o = clmul_result_rev; - if (instr_first_cycle_i) begin - imd_val_we_o = 1'b1; - end else begin - imd_val_we_o = 1'b0; - end - end else begin - imd_val_d_o = operand_a_i; - imd_val_we_o = 1'b0; - multicycle_result = '0; - end - end - default: begin imd_val_d_o = operand_a_i; imd_val_we_o = 1'b0; @@ -1102,11 +1001,7 @@ module ibex_alu #( ALU_CMIX, ALU_CMOV, ALU_FSL, ALU_FSR, // Rotate Shift (RV32B) - ALU_ROL, ALU_ROR, - // Cyclic Redundancy Checks (RV32B) - ALU_CRC32_W, ALU_CRC32C_W, - ALU_CRC32_H, ALU_CRC32C_H, - ALU_CRC32_B, ALU_CRC32C_B: result_o = multicycle_result; + ALU_ROL, ALU_ROR: result_o = multicycle_result; // Single-Bit Bitmanip Operations (RV32B) ALU_BSET, ALU_BCLR, diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 7c8f32efd..036239712 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -385,14 +385,6 @@ module ibex_decoder #( 7'b000_0010, // cpop 7'b000_0100, // sext.b 7'b000_0101: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // sext.h - 7'b001_0000, // crc32.b - 7'b001_0001, // crc32.h - 7'b001_0010, // crc32.w - 7'b001_1000, // crc32c.b - 7'b001_1001, // crc32c.h - 7'b001_1010: begin // crc32c.w - illegal_insn = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b0 : 1'b1; - end default: illegal_insn = 1'b1; endcase end @@ -845,42 +837,6 @@ module ibex_decoder #( 7'b000_0010: alu_operator_o = ALU_CPOP; // cpop 7'b000_0100: alu_operator_o = ALU_SEXTB; // sext.b 7'b000_0101: alu_operator_o = ALU_SEXTH; // sext.h - 7'b001_0000: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin - alu_operator_o = ALU_CRC32_B; // crc32.b - alu_multicycle_o = 1'b1; - end - end - 7'b001_0001: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin - alu_operator_o = ALU_CRC32_H; // crc32.h - alu_multicycle_o = 1'b1; - end - end - 7'b001_0010: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin - alu_operator_o = ALU_CRC32_W; // crc32.w - alu_multicycle_o = 1'b1; - end - end - 7'b001_1000: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin - alu_operator_o = ALU_CRC32C_B; // crc32c.b - alu_multicycle_o = 1'b1; - end - end - 7'b001_1001: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin - alu_operator_o = ALU_CRC32C_H; // crc32c.h - alu_multicycle_o = 1'b1; - end - end - 7'b001_1010: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin - alu_operator_o = ALU_CRC32C_W; // crc32c.w - alu_multicycle_o = 1'b1; - end - end default: ; endcase end diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 33917dda7..362ce2b3e 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -171,15 +171,7 @@ package ibex_pkg; // RV32B ALU_CLMUL, ALU_CLMULR, - ALU_CLMULH, - - // Cyclic Redundancy Check - ALU_CRC32_B, - ALU_CRC32C_B, - ALU_CRC32_H, - ALU_CRC32C_H, - ALU_CRC32_W, - ALU_CRC32C_W + ALU_CLMULH } alu_op_e; typedef enum logic [1:0] { diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index ba9818988..b72a8c553 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -1190,14 +1190,6 @@ module ibex_tracer ( INSN_CLMULR: decode_r_insn("clmulr"); INSN_CLMULH: decode_r_insn("clmulh"); - // RV32B - ZBR - INSN_CRC32_B: decode_r1_insn("crc32.b"); - INSN_CRC32_H: decode_r1_insn("crc32.h"); - INSN_CRC32_W: decode_r1_insn("crc32.w"); - INSN_CRC32C_B: decode_r1_insn("crc32c.b"); - INSN_CRC32C_H: decode_r1_insn("crc32c.h"); - INSN_CRC32C_W: decode_r1_insn("crc32c.w"); - default: decode_mnemonic("INVALID"); endcase end diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 8c404bbe2..7d081785b 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -271,20 +271,6 @@ package ibex_tracer_pkg; parameter logic [31:0] INSN_CLMULR = {7'b0000101, 10'h?, 3'b010, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_CLMULH = {7'b0000101, 10'h?, 3'b011, 5'h?, {OPCODE_OP} }; - // ZBR - parameter logic [31:0] INSN_CRC32_B = - {7'b0110000, 5'b10000, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_CRC32_H = - {7'b0110000, 5'b10001, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_CRC32_W = - {7'b0110000, 5'b10010, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_CRC32C_B = - {7'b0110000, 5'b11000, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_CRC32C_H = - {7'b0110000, 5'b11001, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_CRC32C_W = - {7'b0110000, 5'b11010, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - // LOAD & STORE parameter logic [31:0] INSN_LOAD = {25'h?, {OPCODE_LOAD } }; parameter logic [31:0] INSN_STORE = {25'h?, {OPCODE_STORE} }; From 853b0e9451b3d27a77d31287cfba942aef3b67ce Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:19 +0200 Subject: [PATCH 05/20] [rtl] Remove Xzbt0p93 Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 78 +++++------------------------------------- rtl/ibex_decoder.sv | 54 +++-------------------------- rtl/ibex_pkg.sv | 7 ---- rtl/ibex_tracer.sv | 27 --------------- rtl/ibex_tracer_pkg.sv | 8 ----- 5 files changed, 12 insertions(+), 162 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index ef2ef2308..c10cf022b 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -178,8 +178,8 @@ module ibex_alu #( // The shifter structure consists of a 33-bit shifter: 32-bit operand + 1 bit extension for // arithmetic shifts and one-shift support. - // Rotations and funnel shifts are implemented as multi-cycle instructions. - // The shifter is also used for single-bit instructions and bit-field place as detailed below. + // Rotations are implemented as multi-cycle instructions. + // The shifter is also used for single-bit instructions as detailed below. // // Standard Shifts // =============== @@ -201,28 +201,6 @@ module ibex_alu #( // multicycle_result = (rs1 >> shift_amt) | (rs1 << (32 - shift_amt)); // ^-- cycle 0 -----^ ^-- cycle 1 --------------^ // - // Funnel Shifts - // ------------- - // For funnel shifts, operand_a_i is tied to rs1 in the first cycle and rs3 in the - // second cycle. operand_b_i is always tied to rs2. The order of applying the shift amount or - // its complement is determined by bit [5] of shift_amt. - // - // Funnel shift Pseudocode: (fsl) - // shift_amt = rs2 & 63; - // shift_amt_compl = 32 - shift_amt[4:0] - // if (shift_amt >=33): - // multicycle_result = (rs1 >> shift_amt_compl[4:0]) | (rs3 << shift_amt[4:0]); - // ^-- cycle 0 ----------------^ ^-- cycle 1 ------------^ - // else if (shift_amt <= 31 && shift_amt > 0): - // multicycle_result = (rs1 << shift_amt[4:0]) | (rs3 >> shift_amt_compl[4:0]); - // ^-- cycle 0 ----------^ ^-- cycle 1 -------------------^ - // For shift_amt == 0, 32, both shift_amt[4:0] and shift_amt_compl[4:0] == '0. - // these cases need to be handled separately outside the shifting structure: - // else if (shift_amt == 32): - // multicycle_result = rs3 - // else if (shift_amt == 0): - // multicycle_result = rs1. - // // Single-Bit Instructions // ======================= // Single bit instructions operate on bit operand_b_i[4:0] of operand_a_i. @@ -238,10 +216,9 @@ module ibex_alu #( logic shift_left; logic shift_ones; logic shift_arith; - logic shift_funnel; logic shift_sbmode; - logic [5:0] shift_amt; - logic [5:0] shift_amt_compl; // complementary shift amount (32 - shift_amt) + logic [4:0] shift_amt; + logic [4:0] shift_amt_compl; // complementary shift amount (32 - shift_amt) logic [31:0] shift_operand; logic signed [32:0] shift_result_ext_signed; @@ -250,15 +227,10 @@ module ibex_alu #( logic [31:0] shift_result; logic [31:0] shift_result_rev; - // bit shift_amt[5]: word swap bit: only considered for FSL/FSR. - // if set, reverse operations in first and second cycle. - assign shift_amt[5] = operand_b_i[5] & shift_funnel; assign shift_amt_compl = 32 - operand_b_i[4:0]; always_comb begin - shift_amt[4:0] = instr_first_cycle_i ? - (operand_b_i[5] && shift_funnel ? shift_amt_compl[4:0] : operand_b_i[4:0]) : - (operand_b_i[5] && shift_funnel ? operand_b_i[4:0] : shift_amt_compl[4:0]); + shift_amt[4:0] = instr_first_cycle_i ? operand_b_i[4:0] : shift_amt_compl[4:0]; end // single-bit mode: shift @@ -269,8 +241,6 @@ module ibex_alu #( // * a standard left shift (slo, sll) // * a rol in the first cycle // * a ror in the second cycle - // * fsl: without word-swap bit: first cycle, else: second cycle - // * fsr: without word-swap bit: second cycle, else: first cycle // * a single-bit instruction: bclr, bset, binv (excluding bext) always_comb begin unique case (operator_i) @@ -278,10 +248,6 @@ module ibex_alu #( ALU_SLO: shift_left = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b1 : 1'b0; ALU_ROL: shift_left = (RV32B != RV32BNone) ? instr_first_cycle_i : 0; ALU_ROR: shift_left = (RV32B != RV32BNone) ? ~instr_first_cycle_i : 0; - ALU_FSL: shift_left = (RV32B != RV32BNone) ? - (shift_amt[5] ? ~instr_first_cycle_i : instr_first_cycle_i) : 1'b0; - ALU_FSR: shift_left = (RV32B != RV32BNone) ? - (shift_amt[5] ? instr_first_cycle_i : ~instr_first_cycle_i) : 1'b0; default: shift_left = 1'b0; endcase if (shift_sbmode) begin @@ -292,8 +258,6 @@ module ibex_alu #( assign shift_arith = (operator_i == ALU_SRA); assign shift_ones = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? (operator_i == ALU_SLO) | (operator_i == ALU_SRO) : 1'b0; - assign shift_funnel = (RV32B != RV32BNone) ? - (operator_i == ALU_FSL) | (operator_i == ALU_FSR) : 1'b0; // shifter structure. always_comb begin @@ -343,7 +307,6 @@ module ibex_alu #( ALU_XNOR, ALU_ORN, ALU_ANDN: bwlogic_op_b_negate = (RV32B != RV32BNone) ? 1'b1 : 1'b0; - ALU_CMIX: bwlogic_op_b_negate = (RV32B != RV32BNone) ? ~instr_first_cycle_i : 1'b0; default: bwlogic_op_b_negate = 1'b0; endcase end @@ -876,36 +839,14 @@ module ibex_alu #( ////////////////////////////////////// // Multicycle Bitmanip Instructions // ////////////////////////////////////// - // Ternary instructions + Shift Rotations - // For ternary instructions (zbt), operand_a_i is tied to rs1 in the first cycle and rs3 in the - // second cycle. operand_b_i is always tied to rs2. + // Shift Rotations + // operand_a_i is tied to rs1, operand_b_i is tied to rs2. always_comb begin unique case (operator_i) - ALU_CMOV: begin - multicycle_result = (operand_b_i == 32'h0) ? operand_a_i : imd_val_q_i; - imd_val_d_o = operand_a_i; - if (instr_first_cycle_i) begin - imd_val_we_o = 1'b1; - end else begin - imd_val_we_o = 1'b0; - end - end - - ALU_CMIX: begin - multicycle_result = imd_val_q_i | bwlogic_and_result; - imd_val_d_o = bwlogic_and_result; - if (instr_first_cycle_i) begin - imd_val_we_o = 1'b1; - end else begin - imd_val_we_o = 1'b0; - end - end - - ALU_FSR, ALU_FSL, ALU_ROL, ALU_ROR: begin if (shift_amt[4:0] == 5'h0) begin - multicycle_result = shift_amt[5] ? operand_a_i : imd_val_q_i; + multicycle_result = imd_val_q_i; end else begin multicycle_result = imd_val_q_i | shift_result; end @@ -997,9 +938,6 @@ module ibex_alu #( // Sign-Extend (RV32B) ALU_SEXTB, ALU_SEXTH: result_o = sext_result; - // Ternary Bitmanip Operations (RV32B) - ALU_CMIX, ALU_CMOV, - ALU_FSL, ALU_FSR, // Rotate Shift (RV32B) ALU_ROL, ALU_ROR: result_o = multicycle_result; diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 036239712..ed16885f2 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -394,7 +394,7 @@ module ibex_decoder #( 3'b101: begin if (instr[26]) begin - illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // fsri + illegal_insn = 1'b1; end else begin unique case (instr[31:27]) 5'b0_0000, // srli @@ -445,7 +445,7 @@ module ibex_decoder #( rf_ren_b_o = 1'b1; rf_we = 1'b1; if ({instr[26], instr[13:12]} == {1'b1, 2'b01}) begin - illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // cmix / cmov / fsl / fsr + illegal_insn = 1'b1; // cmix / cmov / fsl / fsr removed end else begin unique case ({instr[31:25], instr[14:12]}) // RV32I ALU operations @@ -851,13 +851,7 @@ module ibex_decoder #( 3'b101: begin if (RV32B != RV32BNone) begin if (instr_alu[26] == 1'b1) begin - alu_operator_o = ALU_FSR; - alu_multicycle_o = 1'b1; - if (instr_first_cycle_i) begin - use_rs3_d = 1'b1; - end else begin - use_rs3_d = 1'b0; - end + // fsri removed; illegal encoding. end else begin unique case (instr_alu[31:27]) 5'b0_0000: alu_operator_o = ALU_SRL; // Shift Right Logical by Immediate @@ -901,47 +895,7 @@ module ibex_decoder #( alu_op_b_mux_sel_o = OP_B_REG_B; if (instr_alu[26]) begin - if (RV32B != RV32BNone) begin - unique case ({instr_alu[26:25], instr_alu[14:12]}) - {2'b11, 3'b001}: begin - alu_operator_o = ALU_CMIX; // cmix - alu_multicycle_o = 1'b1; - if (instr_first_cycle_i) begin - use_rs3_d = 1'b1; - end else begin - use_rs3_d = 1'b0; - end - end - {2'b11, 3'b101}: begin - alu_operator_o = ALU_CMOV; // cmov - alu_multicycle_o = 1'b1; - if (instr_first_cycle_i) begin - use_rs3_d = 1'b1; - end else begin - use_rs3_d = 1'b0; - end - end - {2'b10, 3'b001}: begin - alu_operator_o = ALU_FSL; // fsl - alu_multicycle_o = 1'b1; - if (instr_first_cycle_i) begin - use_rs3_d = 1'b1; - end else begin - use_rs3_d = 1'b0; - end - end - {2'b10, 3'b101}: begin - alu_operator_o = ALU_FSR; // fsr - alu_multicycle_o = 1'b1; - if (instr_first_cycle_i) begin - use_rs3_d = 1'b1; - end else begin - use_rs3_d = 1'b0; - end - end - default: ; - endcase - end + // Ternary bitmanip ops (cmix/cmov/fsl/fsr) removed; these encodings are illegal. end else begin unique case ({instr_alu[31:25], instr_alu[14:12]}) // RV32I ALU operations diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 362ce2b3e..387c79123 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -153,13 +153,6 @@ package ibex_pkg; ALU_SLT, ALU_SLTU, - // Ternary Bitmanip Operations - // RV32B - ALU_CMOV, - ALU_CMIX, - ALU_FSL, - ALU_FSR, - // Single-Bit Operations // RV32B ALU_BSET, diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index b72a8c553..c727750be 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -448,18 +448,6 @@ module ibex_tracer ( decoded_str = $sformatf("%s\tx%0d,x%0d", mnemonic, rvfi_rd_addr, rvfi_rs1_addr); endfunction - function automatic void decode_r_cmixcmov_insn(input string mnemonic); - data_accessed = RS1 | RS2 | RS3 | RD; - decoded_str = $sformatf("%s\tx%0d,x%0d,x%0d,x%0d", mnemonic, rvfi_rd_addr, rvfi_rs2_addr, - rvfi_rs1_addr, rvfi_rs3_addr); - endfunction - - function automatic void decode_r_funnelshift_insn(input string mnemonic); - data_accessed = RS1 | RS2 | RS3 | RD; - decoded_str = $sformatf("%s\tx%0d,x%0d,x%0d,x%0d", mnemonic, rvfi_rd_addr, rvfi_rs1_addr, - rvfi_rs3_addr, rvfi_rs2_addr); - endfunction - function automatic void decode_i_insn(input string mnemonic); data_accessed = RS1 | RD; decoded_str = $sformatf("%s\tx%0d,x%0d,%0d", mnemonic, rvfi_rd_addr, rvfi_rs1_addr, @@ -474,15 +462,6 @@ module ibex_tracer ( decoded_str = $sformatf("%s\tx%0d,x%0d,0x%0x", mnemonic, rvfi_rd_addr, rvfi_rs1_addr, shamt); endfunction - function automatic void decode_i_funnelshift_insn( input string mnemonic); - // fsri - logic [5:0] shamt; - shamt = {rvfi_insn[25:20]}; - data_accessed = RS1 | RS3 | RD; - decoded_str = $sformatf("%s\tx%0d,x%0d,x%0d,0x%0x", mnemonic, rvfi_rd_addr, rvfi_rs1_addr, - rvfi_rs3_addr, shamt); - endfunction - function automatic void decode_i_jalr_insn(input string mnemonic); // JALR data_accessed = RS1 | RD; @@ -1178,12 +1157,6 @@ module ibex_tracer ( INSN_SLOI: decode_i_shift_insn("sloi"); INSN_SROI: decode_i_shift_insn("sroi"); - // RV32B - ZBT - INSN_CMIX: decode_r_cmixcmov_insn("cmix"); - INSN_CMOV: decode_r_cmixcmov_insn("cmov"); - INSN_FSR: decode_r_funnelshift_insn("fsr"); - INSN_FSL: decode_r_funnelshift_insn("fsl"); - INSN_FSRI: decode_i_funnelshift_insn("fsri"); // RV32B - ZBC INSN_CLMUL: decode_r_insn("clmul"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 7d081785b..3097242f9 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -258,14 +258,6 @@ package ibex_tracer_pkg; // fsri. parameter logic [31:0] INSN_SROI = { 5'b00100 , 1'b0, 11'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - // ZBT - parameter logic [31:0] INSN_FSRI = { 5'h?, 1'b1, 11'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - - parameter logic [31:0] INSN_CMIX = {5'h?, 2'b11, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; - parameter logic [31:0] INSN_CMOV = {5'h?, 2'b11, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; - parameter logic [31:0] INSN_FSL = {5'h?, 2'b10, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; - parameter logic [31:0] INSN_FSR = {5'h?, 2'b10, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; - // ZBC parameter logic [31:0] INSN_CLMUL = {7'b0000101, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_CLMULR = {7'b0000101, 10'h?, 3'b010, 5'h?, {OPCODE_OP} }; From 004cd48afc8f58946c7e07cc1c2913d81f8cd724 Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:19 +0200 Subject: [PATCH 06/20] [rtl] Remove `slo` `sloi` `sro` `sroi` from Xzbb0p93 Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 12 +++--------- rtl/ibex_decoder.sv | 22 ---------------------- rtl/ibex_pkg.sv | 2 -- rtl/ibex_tracer.sv | 7 +------ rtl/ibex_tracer_pkg.sv | 12 ++---------- 5 files changed, 6 insertions(+), 49 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index c10cf022b..cd0218fda 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -214,7 +214,6 @@ module ibex_alu #( // shifting operand_a_i to the right by the required amount and returning bit [0] of the result. logic shift_left; - logic shift_ones; logic shift_arith; logic shift_sbmode; logic [4:0] shift_amt; @@ -238,14 +237,13 @@ module ibex_alu #( (operator_i == ALU_BSET) | (operator_i == ALU_BCLR) | (operator_i == ALU_BINV) : 1'b0; // left shift if this is: - // * a standard left shift (slo, sll) + // * a standard left shift (sll) // * a rol in the first cycle // * a ror in the second cycle // * a single-bit instruction: bclr, bset, binv (excluding bext) always_comb begin unique case (operator_i) ALU_SLL: shift_left = 1'b1; - ALU_SLO: shift_left = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b1 : 1'b0; ALU_ROL: shift_left = (RV32B != RV32BNone) ? instr_first_cycle_i : 0; ALU_ROR: shift_left = (RV32B != RV32BNone) ? ~instr_first_cycle_i : 0; default: shift_left = 1'b0; @@ -256,8 +254,6 @@ module ibex_alu #( end assign shift_arith = (operator_i == ALU_SRA); - assign shift_ones = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? - (operator_i == ALU_SLO) | (operator_i == ALU_SRO) : 1'b0; // shifter structure. always_comb begin @@ -273,7 +269,7 @@ module ibex_alu #( end shift_result_ext_signed = - $signed({shift_ones | (shift_arith & shift_operand[31]), shift_operand}) >>> shift_amt[4:0]; + $signed({shift_arith & shift_operand[31], shift_operand}) >>> shift_amt[4:0]; shift_result_ext = $unsigned(shift_result_ext_signed); shift_result = shift_result_ext[31:0]; @@ -907,9 +903,7 @@ module ibex_alu #( // Shift Operations ALU_SLL, ALU_SRL, - ALU_SRA, - // RV32B - ALU_SLO, ALU_SRO: result_o = shift_result; + ALU_SRA: result_o = shift_result; // Shuffle Operations (RV32B) ALU_SHFL, ALU_UNSHFL: result_o = shuffle_result; diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index ed16885f2..3def2edf1 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -365,9 +365,6 @@ module ibex_decoder #( 3'b001: begin unique case (instr[31:27]) 5'b0_0000: illegal_insn = (instr[26:25] == 2'b00) ? 1'b0 : 1'b1; // slli - 5'b0_0100: begin // sloi - illegal_insn = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b0 : 1'b1; - end 5'b0_1001, // bclri 5'b0_0101, // bseti 5'b0_1101: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // binvi @@ -400,9 +397,6 @@ module ibex_decoder #( 5'b0_0000, // srli 5'b0_1000: illegal_insn = (instr[26:25] == 2'b00) ? 1'b0 : 1'b1; // srai - 5'b0_0100: begin // sroi - illegal_insn = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b0 : 1'b1; - end 5'b0_1100, // rori 5'b0_1001: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // bexti @@ -490,8 +484,6 @@ module ibex_decoder #( {7'b001_0100, 3'b010}, // xperm.n {7'b001_0100, 3'b100}, // xperm.b {7'b001_0100, 3'b110}, // xperm.h - {7'b001_0000, 3'b001}, // slo - {7'b001_0000, 3'b101}, // sro // RV32B zbc {7'b000_0101, 3'b001}, // clmul {7'b000_0101, 3'b010}, // clmulr @@ -821,10 +813,6 @@ module ibex_decoder #( if (RV32B != RV32BNone) begin unique case (instr_alu[31:27]) 5'b0_0000: alu_operator_o = ALU_SLL; // Shift Left Logical by Immediate - // Shift Left Ones by Immediate - 5'b0_0100: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_SLO; - end 5'b0_1001: alu_operator_o = ALU_BCLR; // Clear bit specified by immediate 5'b0_0101: alu_operator_o = ALU_BSET; // Set bit specified by immediate 5'b0_1101: alu_operator_o = ALU_BINV; // Invert bit specified by immediate. @@ -856,10 +844,6 @@ module ibex_decoder #( unique case (instr_alu[31:27]) 5'b0_0000: alu_operator_o = ALU_SRL; // Shift Right Logical by Immediate 5'b0_1000: alu_operator_o = ALU_SRA; // Shift Right Arithmetically by Immediate - // Shift Right Ones by Immediate - 5'b0_0100: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_SRO; - end 5'b0_1001: alu_operator_o = ALU_BEXT; // Extract bit specified by immediate. 5'b0_1100: begin alu_operator_o = ALU_ROR; // Rotate Right by Immediate @@ -966,12 +950,6 @@ module ibex_decoder #( {7'b001_0100, 3'b110}: begin if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_XPERM_H; end - {7'b001_0000, 3'b001}: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_SLO; - end - {7'b001_0000, 3'b101}: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_SRO; - end // RV32B zbc {7'b000_0101, 3'b001}: begin diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 387c79123..425c8bba9 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -101,8 +101,6 @@ package ibex_pkg; ALU_SRL, ALU_SLL, // RV32B - ALU_SRO, - ALU_SLO, ALU_ROR, ALU_ROL, ALU_GREV, diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index c727750be..e6b3a2424 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -455,7 +455,7 @@ module ibex_tracer ( endfunction function automatic void decode_i_shift_insn(input string mnemonic); - // SLLI, SRLI, SRAI, SROI, SLOI, RORI + // SLLI, SRLI, SRAI, RORI logic [4:0] shamt; shamt = {rvfi_insn[24:20]}; data_accessed = RS1 | RD; @@ -1152,11 +1152,6 @@ module ibex_tracer ( INSN_XPERM_N: decode_r_insn("xperm_n"); INSN_XPERM_B: decode_r_insn("xperm_b"); INSN_XPERM_H: decode_r_insn("xperm_h"); - INSN_SLO: decode_r_insn("slo"); - INSN_SRO: decode_r_insn("sro"); - INSN_SLOI: decode_i_shift_insn("sloi"); - INSN_SROI: decode_i_shift_insn("sroi"); - // RV32B - ZBC INSN_CLMUL: decode_r_insn("clmul"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 3097242f9..11180b520 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -78,8 +78,8 @@ package ibex_tracer_pkg; // ZBB // Only log2(XLEN) bits of the immediate are used. For RV32, this means only the bits in - // instr[24:20] are effectively used. Whenever instr[26] is set, sroi/rori is instead decoded as - // fsri. + // instr[24:20] are effectively used. instr[26] is constrained to 0 ([26]=1 encodings are + // illegal). parameter logic [31:0] INSN_RORI = { 5'b01100 , 1'b0, 11'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; parameter logic [31:0] INSN_CLZ = { 12'b011000000000, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; parameter logic [31:0] INSN_CTZ = { 12'b011000000001, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; @@ -250,14 +250,6 @@ package ibex_tracer_pkg; parameter logic [31:0] INSN_XPERM_B = { 7'b0010100, 10'h?, 3'b100, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_XPERM_H = { 7'b0010100, 10'h?, 3'b110, 5'h?, {OPCODE_OP} }; - parameter logic [31:0] INSN_SLO = { 7'b0010000, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; - parameter logic [31:0] INSN_SRO = { 7'b0010000, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; - 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 - // instr[24:20] are effectively used. Whenever instr[26] is set, sroi/rori is instead decoded as - // fsri. - parameter logic [31:0] INSN_SROI = { 5'b00100 , 1'b0, 11'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - // ZBC parameter logic [31:0] INSN_CLMUL = {7'b0000101, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_CLMULR = {7'b0000101, 10'h?, 3'b010, 5'h?, {OPCODE_OP} }; From 59c22131b75dcf98aafb96da5ac80338dd51e0c1 Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:19 +0200 Subject: [PATCH 07/20] [rtl] Remove `packu` from Xzbb0p93 Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 8 ++------ rtl/ibex_decoder.sv | 2 -- rtl/ibex_pkg.sv | 1 - rtl/ibex_tracer.sv | 1 - rtl/ibex_tracer_pkg.sv | 1 - 5 files changed, 2 insertions(+), 11 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index cd0218fda..7ddeff9ab 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -473,16 +473,13 @@ module ibex_alu #( // Pack // ////////// - logic packu; logic packh; - assign packu = operator_i == ALU_PACKU; assign packh = operator_i == ALU_PACKH; always_comb begin unique case (1'b1) - packu: pack_result = {operand_b_i[31:16], operand_a_i[31:16]}; packh: pack_result = {16'h0, operand_b_i[7:0], operand_a_i[7:0]}; - default: pack_result = {operand_b_i[15:0], operand_a_i[15:0]}; + default: pack_result = {operand_b_i[15:0], operand_a_i[15:0]}; // pack endcase end @@ -926,8 +923,7 @@ module ibex_alu #( ALU_CPOP: result_o = {26'h0, bitcnt_result}; // Pack Operations (RV32B) - ALU_PACK, ALU_PACKH, - ALU_PACKU: result_o = pack_result; + ALU_PACK, ALU_PACKH: result_o = pack_result; // Sign-Extend (RV32B) ALU_SEXTB, ALU_SEXTH: result_o = sext_result; diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 3def2edf1..30cab1977 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -469,7 +469,6 @@ module ibex_decoder #( {7'b000_0101, 3'b101}, // minu {7'b000_0101, 3'b111}, // maxu {7'b000_0100, 3'b100}, // pack - {7'b010_0100, 3'b100}, // packu {7'b000_0100, 3'b111}, // packh // RV32B zbs {7'b010_0100, 3'b001}, // bclr @@ -914,7 +913,6 @@ module ibex_decoder #( {7'b000_0101, 3'b111}: if (RV32B != RV32BNone) alu_operator_o = ALU_MAXU; {7'b000_0100, 3'b100}: if (RV32B != RV32BNone) alu_operator_o = ALU_PACK; - {7'b010_0100, 3'b100}: if (RV32B != RV32BNone) alu_operator_o = ALU_PACKU; {7'b000_0100, 3'b111}: if (RV32B != RV32BNone) alu_operator_o = ALU_PACKH; {7'b010_0000, 3'b100}: if (RV32B != RV32BNone) alu_operator_o = ALU_XNOR; diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 425c8bba9..3fd3e55f6 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -133,7 +133,6 @@ package ibex_pkg; // Pack // RV32B ALU_PACK, - ALU_PACKU, ALU_PACKH, // Sign-Extend diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index e6b3a2424..4083cd25d 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -1059,7 +1059,6 @@ module ibex_tracer ( // 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_CPOP: decode_r1_insn("cpop"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 11180b520..0921859f9 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -107,7 +107,6 @@ package ibex_tracer_pkg; parameter logic [31:0] INSN_ORN = { 7'b0100000, 10'h?, 3'b110, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_ANDN = { 7'b0100000, 10'h?, 3'b111, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_PACK = { 7'b0000100, 10'h?, 3'b100, 5'h?, {OPCODE_OP} }; - parameter logic [31:0] INSN_PACKU = { 7'b0100100, 10'h?, 3'b100, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_PACKH = { 7'b0000100, 10'h?, 3'b111, 5'h?, {OPCODE_OP} }; // ZBS From 89a1cb144d80441dde1913a8e9ccdd5c9564e22d Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:20 +0200 Subject: [PATCH 08/20] [rtl] Remove `xpermh` from Xzbb0p93 Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 23 +---------------------- rtl/ibex_decoder.sv | 4 ---- rtl/ibex_pkg.sv | 1 - rtl/ibex_tracer.sv | 1 - rtl/ibex_tracer_pkg.sv | 1 - 5 files changed, 1 insertion(+), 29 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index 7ddeff9ab..e6a5f273e 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -656,8 +656,6 @@ module ibex_alu #( logic [7:0] vld_n; // nibbles logic [3:0][1:0] sel_b; // bytes logic [3:0] vld_b; // bytes - logic [1:0][0:0] sel_h; // half words - logic [1:0] vld_h; // half words // Per nibble, 3 bits are needed for the selection. Other bits must be zero. // sel_n bit mask: 32'b0111_0111_0111_0111_0111_0111_0111_0111 @@ -675,14 +673,6 @@ module ibex_alu #( assign vld_b[i] = ~|operand_b_i[i*8 + 2 +: 6]; end - // Per half word, 1 bit is needed for the selection only. All other bits must be zero. - // sel_h bit mask: 32'b0000_0000_0000_0001_0000_0000_0000_0001 - // vld_h bit mask: 32'b1111_1111_1111_1110_1111_1111_1111_1110 - for (genvar i = 0; i < 2; i++) begin : gen_sel_vld_h - assign sel_h[i] = operand_b_i[i*16 +: 1]; - assign vld_h[i] = ~|operand_b_i[i*16 + 1 +: 15]; - end - // Convert selector indices and valid signals to control the nibble-based // crossbar logic. logic [7:0][2:0] sel; @@ -704,17 +694,6 @@ module ibex_alu #( end end - ALU_XPERM_H: begin - // Convert half-word to nibble indices. - for (int h = 0; h < 2; h++) begin - sel[h*4 + 0] = {sel_h[h], 2'b00}; - sel[h*4 + 1] = {sel_h[h], 2'b01}; - sel[h*4 + 2] = {sel_h[h], 2'b10}; - sel[h*4 + 3] = {sel_h[h], 2'b11}; - vld[h*4 +: 4] = {4{vld_h[h]}}; - end - end - default: begin // Tie valid to zero to disable the crossbar unless we need it. sel = sel_n; @@ -906,7 +885,7 @@ module ibex_alu #( ALU_SHFL, ALU_UNSHFL: result_o = shuffle_result; // Crossbar Permutation Operations (RV32B) - ALU_XPERM_N, ALU_XPERM_B, ALU_XPERM_H: result_o = xperm_result; + ALU_XPERM_N, ALU_XPERM_B: result_o = xperm_result; // Comparison Operations ALU_EQ, ALU_NE, diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 30cab1977..71b65c56a 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -482,7 +482,6 @@ module ibex_decoder #( {7'b000_0100, 3'b101}, // unshfl {7'b001_0100, 3'b010}, // xperm.n {7'b001_0100, 3'b100}, // xperm.b - {7'b001_0100, 3'b110}, // xperm.h // RV32B zbc {7'b000_0101, 3'b001}, // clmul {7'b000_0101, 3'b010}, // clmulr @@ -945,9 +944,6 @@ module ibex_decoder #( {7'b001_0100, 3'b100}: begin if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_XPERM_B; end - {7'b001_0100, 3'b110}: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_XPERM_H; - end // RV32B zbc {7'b000_0101, 3'b001}: begin diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 3fd3e55f6..2d3e28745 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -109,7 +109,6 @@ package ibex_pkg; ALU_UNSHFL, ALU_XPERM_N, ALU_XPERM_B, - ALU_XPERM_H, // Address Calculations // RV32B diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index 4083cd25d..ac6206881 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -1150,7 +1150,6 @@ module ibex_tracer ( end INSN_XPERM_N: decode_r_insn("xperm_n"); INSN_XPERM_B: decode_r_insn("xperm_b"); - INSN_XPERM_H: decode_r_insn("xperm_h"); // RV32B - ZBC INSN_CLMUL: decode_r_insn("clmul"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 0921859f9..78ec9e0d7 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -247,7 +247,6 @@ package ibex_tracer_pkg; parameter logic [31:0] INSN_XPERM_N = { 7'b0010100, 10'h?, 3'b010, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_XPERM_B = { 7'b0010100, 10'h?, 3'b100, 5'h?, {OPCODE_OP} }; - parameter logic [31:0] INSN_XPERM_H = { 7'b0010100, 10'h?, 3'b110, 5'h?, {OPCODE_OP} }; // ZBC parameter logic [31:0] INSN_CLMUL = {7'b0000101, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; From 141920a744ae20187c353e4d48cbe3f82d1586ce Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:20 +0200 Subject: [PATCH 09/20] [rtl] Remove `grev` Xzbb0p93 Signed-off-by: Thomas Benz --- rtl/ibex_decoder.sv | 2 -- rtl/ibex_tracer.sv | 1 - rtl/ibex_tracer_pkg.sv | 1 - 3 files changed, 4 deletions(-) diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 71b65c56a..9ef889c18 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -476,7 +476,6 @@ module ibex_decoder #( {7'b011_0100, 3'b001}, // binv {7'b010_0100, 3'b101}: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // bext // RV32B zbp - {7'b011_0100, 3'b101}, // grev {7'b001_0100, 3'b101}, // gorc {7'b000_0100, 3'b001}, // shfl {7'b000_0100, 3'b101}, // unshfl @@ -930,7 +929,6 @@ module ibex_decoder #( {7'b010_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_BEXT; // RV32B zbp - {7'b011_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_GREV; {7'b001_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_GORC; {7'b000_0100, 3'b001}: begin if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_SHFL; diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index ac6206881..9e777c608 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -1074,7 +1074,6 @@ module ibex_tracer ( INSN_BINV: decode_r_insn("binv"); INSN_BEXT: decode_r_insn("bext"); // RV32B - ZBP - INSN_GREV: decode_r_insn("grev"); INSN_GREVI: begin unique casez (rvfi_insn) INSN_REV_P: decode_r1_insn("rev.p"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 78ec9e0d7..0ed008e15 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -240,7 +240,6 @@ package ibex_tracer_pkg; parameter logic [31:0] INSN_UNZIP = { 6'b000010, 2'h?, 4'b1111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_GREV = { 7'b0110100, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_GORC = { 7'b0010100, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_SHFL = { 7'b0000100, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_UNSHFL = { 7'b0000100, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; From b5464a6d2093eced5e50a370ad6f75602bef4270 Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:20 +0200 Subject: [PATCH 10/20] [rtl] Remove `gorc` from Xzbb0p93 Signed-off-by: Thomas Benz --- rtl/ibex_decoder.sv | 2 -- rtl/ibex_tracer.sv | 1 - rtl/ibex_tracer_pkg.sv | 1 - 3 files changed, 4 deletions(-) diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 9ef889c18..16dcc8d14 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -476,7 +476,6 @@ module ibex_decoder #( {7'b011_0100, 3'b001}, // binv {7'b010_0100, 3'b101}: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // bext // RV32B zbp - {7'b001_0100, 3'b101}, // gorc {7'b000_0100, 3'b001}, // shfl {7'b000_0100, 3'b101}, // unshfl {7'b001_0100, 3'b010}, // xperm.n @@ -929,7 +928,6 @@ module ibex_decoder #( {7'b010_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_BEXT; // RV32B zbp - {7'b001_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_GORC; {7'b000_0100, 3'b001}: begin if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_SHFL; end diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index 9e777c608..c09a22c3f 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -1094,7 +1094,6 @@ module ibex_tracer ( default: decode_i_insn("grevi"); endcase end - INSN_GORC: decode_r_insn("gorc"); INSN_GORCI: begin unique casez (rvfi_insn) INSN_ORC_P: decode_r1_insn("orc.p"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 0ed008e15..011bbe6ff 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -240,7 +240,6 @@ package ibex_tracer_pkg; parameter logic [31:0] INSN_UNZIP = { 6'b000010, 2'h?, 4'b1111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_GORC = { 7'b0010100, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_SHFL = { 7'b0000100, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_UNSHFL = { 7'b0000100, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; From 5cb072fcb2270fd2d1ec296ba9dd9d9a998c8c3b Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:20 +0200 Subject: [PATCH 11/20] [rtl] Drop the `RV32BOTEarlGrey` enum from the `ibex_pkg` Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 10 +++++----- rtl/ibex_decoder.sv | 28 ++++++++++++++-------------- rtl/ibex_pkg.sv | 7 +++---- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index e6a5f273e..9a7c33764 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -516,9 +516,9 @@ module ibex_alu #( assign gorc_op = (operator_i == ALU_GORC); assign zbp_shift_amt[2:0] = - (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? shift_amt[2:0] : {3{shift_amt[0]}}; + (RV32B == RV32BFull) ? shift_amt[2:0] : {3{shift_amt[0]}}; assign zbp_shift_amt[4:3] = - (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? shift_amt[4:3] : {2{shift_amt[3]}}; + (RV32B == RV32BFull) ? shift_amt[4:3] : {2{shift_amt[3]}}; always_comb begin rev_result = operand_a_i; @@ -542,14 +542,14 @@ module ibex_alu #( end if (zbp_shift_amt[3]) begin - rev_result = ((RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) && + rev_result = ((RV32B == RV32BFull) && gorc_op ? rev_result : 32'h0) | ((rev_result & 32'h00ff_00ff) << 8) | ((rev_result & 32'hff00_ff00) >> 8); end if (zbp_shift_amt[4]) begin - rev_result = ((RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) && + rev_result = ((RV32B == RV32BFull) && gorc_op ? rev_result : 32'h0) | ((rev_result & 32'h0000_ffff) << 16) | ((rev_result & 32'hffff_0000) >> 16); @@ -558,7 +558,7 @@ module ibex_alu #( logic [31:0] clmul_result_rev; - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin : gen_alu_rvb_otearlgrey_full + if (RV32B == RV32BFull) begin : gen_alu_rvb_full ///////////////////////// // Shuffle / Unshuffle // diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 16dcc8d14..811fd5c7a 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -370,7 +370,7 @@ module ibex_decoder #( 5'b0_1101: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // binvi 5'b0_0001: begin if (instr[26] == 1'b0) begin // shfl - illegal_insn = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b0 : 1'b1; + illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; end else begin illegal_insn = 1'b1; end @@ -401,7 +401,7 @@ module ibex_decoder #( 5'b0_1001: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // bexti 5'b0_1101: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin + if (RV32B == RV32BFull) begin illegal_insn = 1'b0; // grevi end else if (RV32B == RV32BBalanced) begin illegal_insn = (instr[24:20] == 5'b11000) ? 1'b0 : 1'b1; // rev8 @@ -410,7 +410,7 @@ module ibex_decoder #( end end 5'b0_0101: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin + if (RV32B == RV32BFull) begin illegal_insn = 1'b0; // gorci end else if (instr[24:20] == 5'b00111) begin illegal_insn = (RV32B == RV32BBalanced) ? 1'b0 : 1'b1; // orc.b @@ -421,8 +421,8 @@ module ibex_decoder #( 5'b0_0001: begin // Since instr[26] is known to be 0, this must be the "unshfl" instruction, which // is part of the RISC-V bitmanip extension. This is supported for the - // RV32BOTEarlGrey and RV32BFull bitmanip configurations. - illegal_insn = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b0 : 1'b1; + // RV32BFull bitmanip configuration. + illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; end default: illegal_insn = 1'b1; @@ -484,7 +484,7 @@ module ibex_decoder #( {7'b000_0101, 3'b001}, // clmul {7'b000_0101, 3'b010}, // clmulr {7'b000_0101, 3'b011}: begin // clmulh - illegal_insn = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b0 : 1'b1; + illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; end // RV32M instructions @@ -849,7 +849,7 @@ module ibex_decoder #( 5'b0_0101: alu_operator_o = ALU_GORC; // General Or-combine with Imm Control Val // Unshuffle with Immediate Control Value 5'b0_0001: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin + if (RV32B == RV32BFull) begin if (instr_alu[26] == 1'b0) alu_operator_o = ALU_UNSHFL; end end @@ -929,27 +929,27 @@ module ibex_decoder #( // RV32B zbp {7'b000_0100, 3'b001}: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_SHFL; + if (RV32B == RV32BFull) alu_operator_o = ALU_SHFL; end {7'b000_0100, 3'b101}: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_UNSHFL; + if (RV32B == RV32BFull) alu_operator_o = ALU_UNSHFL; end {7'b001_0100, 3'b010}: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_XPERM_N; + if (RV32B == RV32BFull) alu_operator_o = ALU_XPERM_N; end {7'b001_0100, 3'b100}: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_XPERM_B; + if (RV32B == RV32BFull) alu_operator_o = ALU_XPERM_B; end // RV32B zbc {7'b000_0101, 3'b001}: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_CLMUL; + if (RV32B == RV32BFull) alu_operator_o = ALU_CLMUL; end {7'b000_0101, 3'b010}: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_CLMULR; + if (RV32B == RV32BFull) alu_operator_o = ALU_CLMULR; end {7'b000_0101, 3'b011}: begin - if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_CLMULH; + if (RV32B == RV32BFull) alu_operator_o = ALU_CLMULH; end // RV32M instructions, all use the same ALU operation diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 2d3e28745..6d9faf74c 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -46,10 +46,9 @@ package ibex_pkg; } rv32m_e; typedef enum integer { - RV32BNone = 0, - RV32BBalanced = 1, - RV32BOTEarlGrey = 2, - RV32BFull = 3 + RV32BNone = 0, + RV32BBalanced = 1, + RV32BFull = 2 } rv32b_e; typedef enum integer { From a6e4d497be7e26c430e209b712aeab11ca2a8587 Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:20 +0200 Subject: [PATCH 12/20] [rtl] Move and rename `xperm4` and `xperm8` from Xzbp0p93 to Zbkx Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 8 ++++---- rtl/ibex_decoder.sv | 8 ++++---- rtl/ibex_pkg.sv | 4 ++-- rtl/ibex_tracer.sv | 4 ++-- rtl/ibex_tracer_pkg.sv | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index 9a7c33764..fa6023296 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -645,7 +645,7 @@ module ibex_alu #( ////////////// // Crossbar // ////////////// - // The crossbar permutation instructions xperm.[nbh] (Zbp) can be implemented using 8 + // The crossbar permutation instructions xperm4/xperm8 (Zbkx) can be implemented using 8 // parallel 4-bit-wide, 8-input crossbars. Basically, we permute the 8 nibbles of operand_a_i // based on operand_b_i. @@ -679,13 +679,13 @@ module ibex_alu #( logic [7:0] vld; always_comb begin unique case (operator_i) - ALU_XPERM_N: begin + ALU_XPERM4: begin // No conversion needed. sel = sel_n; vld = vld_n; end - ALU_XPERM_B: begin + ALU_XPERM8: begin // Convert byte to nibble indices. for (int b = 0; b < 4; b++) begin sel[b*2 + 0] = {sel_b[b], 1'b0}; @@ -885,7 +885,7 @@ module ibex_alu #( ALU_SHFL, ALU_UNSHFL: result_o = shuffle_result; // Crossbar Permutation Operations (RV32B) - ALU_XPERM_N, ALU_XPERM_B: result_o = xperm_result; + ALU_XPERM4, ALU_XPERM8: result_o = xperm_result; // Comparison Operations ALU_EQ, ALU_NE, diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 811fd5c7a..5e0a97400 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -478,8 +478,8 @@ module ibex_decoder #( // RV32B zbp {7'b000_0100, 3'b001}, // shfl {7'b000_0100, 3'b101}, // unshfl - {7'b001_0100, 3'b010}, // xperm.n - {7'b001_0100, 3'b100}, // xperm.b + {7'b001_0100, 3'b010}, // xperm4 + {7'b001_0100, 3'b100}, // xperm8 // RV32B zbc {7'b000_0101, 3'b001}, // clmul {7'b000_0101, 3'b010}, // clmulr @@ -935,10 +935,10 @@ module ibex_decoder #( if (RV32B == RV32BFull) alu_operator_o = ALU_UNSHFL; end {7'b001_0100, 3'b010}: begin - if (RV32B == RV32BFull) alu_operator_o = ALU_XPERM_N; + if (RV32B == RV32BFull) alu_operator_o = ALU_XPERM4; end {7'b001_0100, 3'b100}: begin - if (RV32B == RV32BFull) alu_operator_o = ALU_XPERM_B; + if (RV32B == RV32BFull) alu_operator_o = ALU_XPERM8; end // RV32B zbc diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 6d9faf74c..5a4bb25fc 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -106,8 +106,8 @@ package ibex_pkg; ALU_GORC, ALU_SHFL, ALU_UNSHFL, - ALU_XPERM_N, - ALU_XPERM_B, + ALU_XPERM4, + ALU_XPERM8, // Address Calculations // RV32B diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index c09a22c3f..e9a753dae 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -1146,8 +1146,8 @@ module ibex_tracer ( default: decode_i_insn("unshfli"); endcase end - INSN_XPERM_N: decode_r_insn("xperm_n"); - INSN_XPERM_B: decode_r_insn("xperm_b"); + INSN_XPERM4: decode_r_insn("xperm4"); + INSN_XPERM8: decode_r_insn("xperm8"); // RV32B - ZBC INSN_CLMUL: decode_r_insn("clmul"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 011bbe6ff..3161cc525 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -243,8 +243,8 @@ package ibex_tracer_pkg; parameter logic [31:0] INSN_SHFL = { 7'b0000100, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_UNSHFL = { 7'b0000100, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; - parameter logic [31:0] INSN_XPERM_N = { 7'b0010100, 10'h?, 3'b010, 5'h?, {OPCODE_OP} }; - parameter logic [31:0] INSN_XPERM_B = { 7'b0010100, 10'h?, 3'b100, 5'h?, {OPCODE_OP} }; + parameter logic [31:0] INSN_XPERM4 = { 7'b0010100, 10'h?, 3'b010, 5'h?, {OPCODE_OP} }; + parameter logic [31:0] INSN_XPERM8 = { 7'b0010100, 10'h?, 3'b100, 5'h?, {OPCODE_OP} }; // ZBC parameter logic [31:0] INSN_CLMUL = {7'b0000101, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; From 25ef8752def1c07aab7321bd81fff83b0c0031be Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:20 +0200 Subject: [PATCH 13/20] [rtl] Move and rename `zip` and `unzip` from Xzbp0p93 to Zbkk Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 12 +++++----- rtl/ibex_decoder.sv | 30 +++++++++---------------- rtl/ibex_pkg.sv | 4 ++-- rtl/ibex_tracer.sv | 34 ++-------------------------- rtl/ibex_tracer_pkg.sv | 51 ++++-------------------------------------- 5 files changed, 26 insertions(+), 105 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index fa6023296..b2896ed11 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -560,9 +560,11 @@ module ibex_alu #( if (RV32B == RV32BFull) begin : gen_alu_rvb_full - ///////////////////////// - // Shuffle / Unshuffle // - ///////////////////////// + ///////////////// + // Zip / Unzip // + ///////////////// + // zip/unzip (Zbkb) are the shfli/unshfli shuffle network restricted to the + // shamt=0x0F (full) control value. localparam logic [31:0] SHUFFLE_MASK_L [4] = '{32'h00ff_0000, 32'h0f00_0f00, 32'h3030_3030, 32'h4444_4444}; @@ -580,7 +582,7 @@ module ibex_alu #( end logic shuffle_flip; - assign shuffle_flip = operator_i == ALU_UNSHFL; + assign shuffle_flip = operator_i == ALU_UNZIP; logic [3:0] shuffle_mode; @@ -882,7 +884,7 @@ module ibex_alu #( ALU_SRA: result_o = shift_result; // Shuffle Operations (RV32B) - ALU_SHFL, ALU_UNSHFL: result_o = shuffle_result; + ALU_ZIP, ALU_UNZIP: result_o = shuffle_result; // Crossbar Permutation Operations (RV32B) ALU_XPERM4, ALU_XPERM8: result_o = xperm_result; diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 5e0a97400..827596f87 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -369,7 +369,8 @@ module ibex_decoder #( 5'b0_0101, // bseti 5'b0_1101: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // binvi 5'b0_0001: begin - if (instr[26] == 1'b0) begin // shfl + // zip (Zbkb): shfli with shamt fixed to 0x0F + if (instr[26:20] == 7'b000_1111) begin // zip illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; end else begin illegal_insn = 1'b1; @@ -419,10 +420,9 @@ module ibex_decoder #( end end 5'b0_0001: begin - // Since instr[26] is known to be 0, this must be the "unshfl" instruction, which - // is part of the RISC-V bitmanip extension. This is supported for the - // RV32BFull bitmanip configuration. - illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; + // unzip (Zbkb): unshfli with shamt fixed to 0x0F + illegal_insn = (instr[26:20] == 7'b000_1111 && RV32B == RV32BFull) ? + 1'b0 : 1'b1; end default: illegal_insn = 1'b1; @@ -475,9 +475,7 @@ module ibex_decoder #( {7'b001_0100, 3'b001}, // bset {7'b011_0100, 3'b001}, // binv {7'b010_0100, 3'b101}: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // bext - // RV32B zbp - {7'b000_0100, 3'b001}, // shfl - {7'b000_0100, 3'b101}, // unshfl + // RV32B zbkx {7'b001_0100, 3'b010}, // xperm4 {7'b001_0100, 3'b100}, // xperm8 // RV32B zbc @@ -812,8 +810,8 @@ module ibex_decoder #( 5'b0_1001: alu_operator_o = ALU_BCLR; // Clear bit specified by immediate 5'b0_0101: alu_operator_o = ALU_BSET; // Set bit specified by immediate 5'b0_1101: alu_operator_o = ALU_BINV; // Invert bit specified by immediate. - // Shuffle with Immediate Control Value - 5'b0_0001: if (instr_alu[26] == 0) alu_operator_o = ALU_SHFL; + // zip (Zbkb): shfli with shamt fixed to 0x0F + 5'b0_0001: if (instr_alu[26:20] == 7'b000_1111) alu_operator_o = ALU_ZIP; 5'b0_1100: begin unique case (instr_alu[26:20]) 7'b000_0000: alu_operator_o = ALU_CLZ; // clz @@ -847,10 +845,10 @@ module ibex_decoder #( end 5'b0_1101: alu_operator_o = ALU_GREV; // General Reverse with Imm Control Val 5'b0_0101: alu_operator_o = ALU_GORC; // General Or-combine with Imm Control Val - // Unshuffle with Immediate Control Value + // unzip (Zbkb): unshfli with shamt fixed to 0x0F 5'b0_0001: begin if (RV32B == RV32BFull) begin - if (instr_alu[26] == 1'b0) alu_operator_o = ALU_UNSHFL; + if (instr_alu[26:20] == 7'b000_1111) alu_operator_o = ALU_UNZIP; end end default: ; @@ -927,13 +925,7 @@ module ibex_decoder #( {7'b011_0100, 3'b001}: if (RV32B != RV32BNone) alu_operator_o = ALU_BINV; {7'b010_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_BEXT; - // RV32B zbp - {7'b000_0100, 3'b001}: begin - if (RV32B == RV32BFull) alu_operator_o = ALU_SHFL; - end - {7'b000_0100, 3'b101}: begin - if (RV32B == RV32BFull) alu_operator_o = ALU_UNSHFL; - end + // RV32B zbkx {7'b001_0100, 3'b010}: begin if (RV32B == RV32BFull) alu_operator_o = ALU_XPERM4; end diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 5a4bb25fc..e4e3a6940 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -104,8 +104,8 @@ package ibex_pkg; ALU_ROL, ALU_GREV, ALU_GORC, - ALU_SHFL, - ALU_UNSHFL, + ALU_ZIP, + ALU_UNZIP, ALU_XPERM4, ALU_XPERM8, diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index e9a753dae..508656cd4 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -1114,38 +1114,8 @@ module ibex_tracer ( default: decode_i_insn("gorci"); endcase end - INSN_SHFL: decode_r_insn("shfl"); - INSN_SHFLI: begin - unique casez (rvfi_insn) - INSN_ZIP_N: decode_r1_insn("zip.n"); - INSN_ZIP2_B: decode_r1_insn("zip2.b"); - INSN_ZIP_B: decode_r1_insn("zip.b"); - INSN_ZIP4_H: decode_r1_insn("zip4.h"); - INSN_ZIP2_H: decode_r1_insn("zip2.h"); - INSN_ZIP_H: decode_r1_insn("zip.h"); - INSN_ZIP8: decode_r1_insn("zip8"); - INSN_ZIP4: decode_r1_insn("zip4"); - INSN_ZIP2: decode_r1_insn("zip2"); - INSN_ZIP: decode_r1_insn("zip"); - default: decode_i_insn("shfli"); - endcase - end - INSN_UNSHFL: decode_r_insn("unshfl"); - INSN_UNSHFLI: begin - unique casez (rvfi_insn) - INSN_UNZIP_N: decode_r1_insn("unzip.n"); - INSN_UNZIP2_B: decode_r1_insn("unzip2.b"); - INSN_UNZIP_B: decode_r1_insn("unzip.b"); - INSN_UNZIP4_H: decode_r1_insn("unzip4.h"); - INSN_UNZIP2_H: decode_r1_insn("unzip2.h"); - INSN_UNZIP_H: decode_r1_insn("unzip.h"); - INSN_UNZIP8: decode_r1_insn("unzip8"); - INSN_UNZIP4: decode_r1_insn("unzip4"); - INSN_UNZIP2: decode_r1_insn("unzip2"); - INSN_UNZIP: decode_r1_insn("unzip"); - default: decode_i_insn("unshfli"); - endcase - end + INSN_ZIP: decode_r1_insn("zip"); + INSN_UNZIP: decode_r1_insn("unzip"); INSN_XPERM4: decode_r_insn("xperm4"); INSN_XPERM8: decode_r_insn("xperm8"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 3161cc525..4ffc573dc 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -193,55 +193,12 @@ package ibex_tracer_pkg; { 5'b00101, 1'b0, 1'b?, 5'b11110, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; parameter logic [31:0] INSN_ORC = { 5'b00101, 1'b0, 1'b?, 5'b11111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - // shfli - parameter logic [31:0] INSN_SHFLI = { 6'b000010, 11'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - // shfli -- pseudo-instructions - parameter logic [31:0] INSN_ZIP_N = - { 6'b000010, 2'h?, 4'b0001, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ZIP2_B = - { 6'b000010, 2'h?, 4'b0010, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ZIP_B = - { 6'b000010, 2'h?, 4'b0011, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ZIP4_H = - { 6'b000010, 2'h?, 4'b0100, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ZIP2_H = - { 6'b000010, 2'h?, 4'b0110, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ZIP_H = - { 6'b000010, 2'h?, 4'b0111, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ZIP8 = - { 6'b000010, 2'h?, 4'b1000, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ZIP4 = - { 6'b000010, 2'h?, 4'b1100, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ZIP2 = - { 6'b000010, 2'h?, 4'b1110, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; + // zip / unzip (Zbkb, rv32): the shfli/unshfli shuffle restricted to the + // shamt=0x0F (full zip) control value. No other control and no reg-reg form. parameter logic [31:0] INSN_ZIP = - { 6'b000010, 2'h?, 4'b1111, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - // unshfli - parameter logic [31:0] INSN_UNSHFLI = { 6'b000010, 11'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - // unshfli -- pseudo-instructions - parameter logic [31:0] INSN_UNZIP_N = - { 6'b000010, 2'h?, 4'b0001, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_UNZIP2_B = - { 6'b000010, 2'h?, 4'b0010, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_UNZIP_B = - { 6'b000010, 2'h?, 4'b0011, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_UNZIP4_H = - { 6'b000010, 2'h?, 4'b0100, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_UNZIP2_H = - { 6'b000010, 2'h?, 4'b0110, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_UNZIP_H = - { 6'b000010, 2'h?, 4'b0111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_UNZIP8 = - { 6'b000010, 2'h?, 4'b1000, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_UNZIP4 = - { 6'b000010, 2'h?, 4'b1100, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_UNZIP2 = - { 6'b000010, 2'h?, 4'b1110, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; + { 7'b0000100, 5'b01111, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; parameter logic [31:0] INSN_UNZIP = - { 6'b000010, 2'h?, 4'b1111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - - parameter logic [31:0] INSN_SHFL = { 7'b0000100, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; - parameter logic [31:0] INSN_UNSHFL = { 7'b0000100, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; + { 7'b0000100, 5'b01111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; parameter logic [31:0] INSN_XPERM4 = { 7'b0010100, 10'h?, 3'b010, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_XPERM8 = { 7'b0010100, 10'h?, 3'b100, 5'h?, {OPCODE_OP} }; From 249129871a5511d23396f56a6e848679c6b834ff Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:20 +0200 Subject: [PATCH 14/20] [rtl] Move and rename `orgb` from Xzbp0p93 to Zbb Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 16 ++++++++-------- rtl/ibex_decoder.sv | 13 +++++-------- rtl/ibex_pkg.sv | 2 +- rtl/ibex_tracer.sv | 21 +-------------------- rtl/ibex_tracer_pkg.sv | 36 ++---------------------------------- 5 files changed, 17 insertions(+), 71 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index b2896ed11..c933485f3 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -512,9 +512,9 @@ module ibex_alu #( // (shift_amt = 5'b00111) are supported in the base extension. logic [4:0] zbp_shift_amt; - logic gorc_op; + logic orcb_op; - assign gorc_op = (operator_i == ALU_GORC); + assign orcb_op = (operator_i == ALU_ORCB); assign zbp_shift_amt[2:0] = (RV32B == RV32BFull) ? shift_amt[2:0] : {3{shift_amt[0]}}; assign zbp_shift_amt[4:3] = @@ -524,33 +524,33 @@ module ibex_alu #( rev_result = operand_a_i; if (zbp_shift_amt[0]) begin - rev_result = (gorc_op ? rev_result : 32'h0) | + rev_result = (orcb_op ? rev_result : 32'h0) | ((rev_result & 32'h5555_5555) << 1) | ((rev_result & 32'haaaa_aaaa) >> 1); end if (zbp_shift_amt[1]) begin - rev_result = (gorc_op ? rev_result : 32'h0) | + rev_result = (orcb_op ? rev_result : 32'h0) | ((rev_result & 32'h3333_3333) << 2) | ((rev_result & 32'hcccc_cccc) >> 2); end if (zbp_shift_amt[2]) begin - rev_result = (gorc_op ? rev_result : 32'h0) | + rev_result = (orcb_op ? rev_result : 32'h0) | ((rev_result & 32'h0f0f_0f0f) << 4) | ((rev_result & 32'hf0f0_f0f0) >> 4); end if (zbp_shift_amt[3]) begin rev_result = ((RV32B == RV32BFull) && - gorc_op ? rev_result : 32'h0) | + orcb_op ? rev_result : 32'h0) | ((rev_result & 32'h00ff_00ff) << 8) | ((rev_result & 32'hff00_ff00) >> 8); end if (zbp_shift_amt[4]) begin rev_result = ((RV32B == RV32BFull) && - gorc_op ? rev_result : 32'h0) | + orcb_op ? rev_result : 32'h0) | ((rev_result & 32'h0000_ffff) << 16) | ((rev_result & 32'hffff_0000) >> 16); end @@ -917,7 +917,7 @@ module ibex_alu #( ALU_BINV, ALU_BEXT: result_o = singlebit_result; // General Reverse / Or-combine (RV32B) - ALU_GREV, ALU_GORC: result_o = rev_result; + ALU_GREV, ALU_ORCB: result_o = rev_result; // Carry-less Multiply Operations (RV32B) ALU_CLMUL, ALU_CLMULR, diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 827596f87..3f47ba575 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -411,13 +411,9 @@ module ibex_decoder #( end end 5'b0_0101: begin - if (RV32B == RV32BFull) begin - illegal_insn = 1'b0; // gorci - end else if (instr[24:20] == 5'b00111) begin - illegal_insn = (RV32B == RV32BBalanced) ? 1'b0 : 1'b1; // orc.b - end else begin - illegal_insn = 1'b1; - end + // orc.b (Zbb): gorci restricted to shamt 0x07 + illegal_insn = (instr[24:20] == 5'b00111 && RV32B != RV32BNone) ? + 1'b0 : 1'b1; // orc.b end 5'b0_0001: begin // unzip (Zbkb): unshfli with shamt fixed to 0x0F @@ -844,7 +840,8 @@ module ibex_decoder #( alu_multicycle_o = 1'b1; end 5'b0_1101: alu_operator_o = ALU_GREV; // General Reverse with Imm Control Val - 5'b0_0101: alu_operator_o = ALU_GORC; // General Or-combine with Imm Control Val + // orc.b (Zbb): gorci with shamt fixed to 0x07 + 5'b0_0101: if (instr_alu[24:20] == 5'b00111) alu_operator_o = ALU_ORCB; // unzip (Zbkb): unshfli with shamt fixed to 0x0F 5'b0_0001: begin if (RV32B == RV32BFull) begin diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index e4e3a6940..d51741def 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -103,7 +103,7 @@ package ibex_pkg; ALU_ROR, ALU_ROL, ALU_GREV, - ALU_GORC, + ALU_ORCB, ALU_ZIP, ALU_UNZIP, ALU_XPERM4, diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index 508656cd4..e2d61491d 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -1094,26 +1094,7 @@ module ibex_tracer ( default: decode_i_insn("grevi"); endcase end - INSN_GORCI: begin - unique casez (rvfi_insn) - INSN_ORC_P: decode_r1_insn("orc.p"); - INSN_ORC2_N: decode_r1_insn("orc2.n"); - INSN_ORC_N: decode_r1_insn("orc.n"); - INSN_ORC4_B: decode_r1_insn("orc4.b"); - INSN_ORC2_B: decode_r1_insn("orc2.b"); - INSN_ORC_B: decode_r1_insn("orc.b"); - INSN_ORC8_H: decode_r1_insn("orc8.h"); - INSN_ORC4_H: decode_r1_insn("orc4.h"); - INSN_ORC2_H: decode_r1_insn("orc2.h"); - INSN_ORC_H: decode_r1_insn("orc.h"); - INSN_ORC16: decode_r1_insn("orc16"); - INSN_ORC8: decode_r1_insn("orc8"); - INSN_ORC4: decode_r1_insn("orc4"); - INSN_ORC2: decode_r1_insn("orc2"); - INSN_ORC: decode_r1_insn("orc"); - default: decode_i_insn("gorci"); - endcase - end + INSN_ORC_B: decode_r1_insn("orc.b"); INSN_ZIP: decode_r1_insn("zip"); INSN_UNZIP: decode_r1_insn("unzip"); INSN_XPERM4: decode_r_insn("xperm4"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 4ffc573dc..88a64071c 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -158,41 +158,9 @@ package ibex_tracer_pkg; { 5'b01101, 1'b0, 1'b?, 5'b11110, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; parameter logic [31:0] INSN_REV = { 5'b01101, 1'b0, 1'b?, 5'b11111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - // gorci - // Only log2(XLEN) bits of the immediate are used. For RV32, this means only the bits in - // instr[24:20] are effectively used. Whenever instr[26] is set, gorci is instead decoded as fsri. - parameter logic [31:0] INSN_GORCI = { 5'b00101, 1'b0, 11'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - // gorci -- pseudo-instructions - parameter logic [31:0] INSN_ORC_P = - { 5'b00101, 1'b0, 1'b?, 5'b00001, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC2_N = - { 5'b00101, 1'b0, 1'b?, 5'b00010, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC_N = - { 5'b00101, 1'b0, 1'b?, 5'b00011, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC4_B = - { 5'b00101, 1'b0, 1'b?, 5'b00100, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC2_B = - { 5'b00101, 1'b0, 1'b?, 5'b00110, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; + // orc.b (Zbb): gorci restricted to shamt 0x07 (bitwise OR-combine within each byte). parameter logic [31:0] INSN_ORC_B = - { 5'b00101, 1'b0, 1'b?, 5'b00111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC8_H = - { 5'b00101, 1'b0, 1'b?, 5'b01000, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC4_H = - { 5'b00101, 1'b0, 1'b?, 5'b01100, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC2_H = - { 5'b00101, 1'b0, 1'b?, 5'b01110, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC_H = - { 5'b00101, 1'b0, 1'b?, 5'b01111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC16 = - { 5'b00101, 1'b0, 1'b?, 5'b10000, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC8 = - { 5'b00101, 1'b0, 1'b?, 5'b11000, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC4 = - { 5'b00101, 1'b0, 1'b?, 5'b11100, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC2 = - { 5'b00101, 1'b0, 1'b?, 5'b11110, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_ORC = - { 5'b00101, 1'b0, 1'b?, 5'b11111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; + { 5'b00101, 1'b0, 1'b0, 5'b00111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; // zip / unzip (Zbkb, rv32): the shfli/unshfli shuffle restricted to the // shamt=0x0F (full zip) control value. No other control and no reg-reg form. parameter logic [31:0] INSN_ZIP = From 082c95937c7253760d9cc05848d59110e8750f39 Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:20 +0200 Subject: [PATCH 15/20] [rtl] Move and rename `rev8` and `brev8` from Xzbp0p93 to Zbkb Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 15 +++++++-------- rtl/ibex_decoder.sv | 18 +++++++++++++----- rtl/ibex_pkg.sv | 3 ++- rtl/ibex_tracer.sv | 24 +++--------------------- rtl/ibex_tracer_pkg.sv | 39 +++++---------------------------------- 5 files changed, 30 insertions(+), 69 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index c933485f3..85fec665e 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -503,13 +503,12 @@ module ibex_alu #( endcase end - //////////////////////////////////// - // General Reverse and Or-combine // - //////////////////////////////////// + //////////////////////////////// + // rev8 / brev8 / orc.b // + //////////////////////////////// - // Only a subset of the general reverse and or-combine instructions are implemented in the - // balanced version of the B extension. Currently rev8 (shift_amt = 5'b11000) and orc.b - // (shift_amt = 5'b00111) are supported in the base extension. + // The generalized-reverse / or-combine butterfly below implements the ratified + // subset only: rev8 and orc.b. logic [4:0] zbp_shift_amt; logic orcb_op; @@ -916,8 +915,8 @@ module ibex_alu #( ALU_BSET, ALU_BCLR, ALU_BINV, ALU_BEXT: result_o = singlebit_result; - // General Reverse / Or-combine (RV32B) - ALU_GREV, ALU_ORCB: result_o = rev_result; + // rev8 / brev8 / orc.b use shared reverse/or-combine datapath (RV32B) + ALU_REV8, ALU_BREV8, ALU_ORCB: result_o = rev_result; // Carry-less Multiply Operations (RV32B) ALU_CLMUL, ALU_CLMULR, diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 3f47ba575..dccb3ee28 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -402,10 +402,11 @@ module ibex_decoder #( 5'b0_1001: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // bexti 5'b0_1101: begin - if (RV32B == RV32BFull) begin - illegal_insn = 1'b0; // grevi - end else if (RV32B == RV32BBalanced) begin - illegal_insn = (instr[24:20] == 5'b11000) ? 1'b0 : 1'b1; // rev8 + // rev8 (Zbb, shamt 0x18) and brev8 (Zbkb, shamt 0x07) + if (instr[24:20] == 5'b11000) begin + illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // rev8 + end else if (instr[24:20] == 5'b00111) begin + illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // brev8 end else begin illegal_insn = 1'b1; end @@ -839,7 +840,14 @@ module ibex_decoder #( alu_operator_o = ALU_ROR; // Rotate Right by Immediate alu_multicycle_o = 1'b1; end - 5'b0_1101: alu_operator_o = ALU_GREV; // General Reverse with Imm Control Val + // rev8 (Zbb, shamt 0x18) and brev8 (Zbkb, shamt 0x07) + 5'b0_1101: begin + if (instr_alu[24:20] == 5'b11000) begin + alu_operator_o = ALU_REV8; + end else if (instr_alu[24:20] == 5'b00111 && RV32B == RV32BFull) begin + alu_operator_o = ALU_BREV8; + end + end // orc.b (Zbb): gorci with shamt fixed to 0x07 5'b0_0101: if (instr_alu[24:20] == 5'b00111) alu_operator_o = ALU_ORCB; // unzip (Zbkb): unshfli with shamt fixed to 0x0F diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index d51741def..967b642ae 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -102,7 +102,8 @@ package ibex_pkg; // RV32B ALU_ROR, ALU_ROL, - ALU_GREV, + ALU_REV8, + ALU_BREV8, ALU_ORCB, ALU_ZIP, ALU_UNZIP, diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index e2d61491d..9a53b5708 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -1073,27 +1073,9 @@ module ibex_tracer ( INSN_BSET: decode_r_insn("bset"); INSN_BINV: decode_r_insn("binv"); INSN_BEXT: decode_r_insn("bext"); - // RV32B - ZBP - INSN_GREVI: begin - unique casez (rvfi_insn) - INSN_REV_P: decode_r1_insn("rev.p"); - INSN_REV2_N: decode_r1_insn("rev2.n"); - INSN_REV_N: decode_r1_insn("rev.n"); - INSN_REV4_B: decode_r1_insn("rev4.b"); - INSN_REV2_B: decode_r1_insn("rev2.b"); - INSN_REV_B: decode_r1_insn("rev.b"); - INSN_REV8_H: decode_r1_insn("rev8.h"); - INSN_REV4_H: decode_r1_insn("rev4.h"); - INSN_REV2_H: decode_r1_insn("rev2.h"); - INSN_REV_H: decode_r1_insn("rev.h"); - INSN_REV16: decode_r1_insn("rev16"); - INSN_REV8: decode_r1_insn("rev8"); - INSN_REV4: decode_r1_insn("rev4"); - INSN_REV2: decode_r1_insn("rev2"); - INSN_REV: decode_r1_insn("rev"); - default: decode_i_insn("grevi"); - endcase - end + // RV32B - Zbb / Zbkb + INSN_BREV8: decode_r1_insn("brev8"); + INSN_REV8: decode_r1_insn("rev8"); INSN_ORC_B: decode_r1_insn("orc.b"); INSN_ZIP: decode_r1_insn("zip"); INSN_UNZIP: decode_r1_insn("unzip"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 88a64071c..411a53f40 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -123,41 +123,12 @@ package ibex_tracer_pkg; parameter logic [31:0] INSN_BEXT = { 7'b0100100, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; // ZBP - // grevi - // Only log2(XLEN) bits of the immediate are used. For RV32, this means only the bits in - // instr[24:20] are effectively used. Whenever instr[26] is set, grevi is instead decoded as fsri. - parameter logic [31:0] INSN_GREVI = { 5'b01101, 1'b0, 11'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - // grevi -- pseudo-instructions - parameter logic [31:0] INSN_REV_P = - { 5'b01101, 1'b0, 1'b?, 5'b00001, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV2_N = - { 5'b01101, 1'b0, 1'b?, 5'b00010, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV_N = - { 5'b01101, 1'b0, 1'b?, 5'b00011, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV4_B = - { 5'b01101, 1'b0, 1'b?, 5'b00100, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV2_B = - { 5'b01101, 1'b0, 1'b?, 5'b00110, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV_B = - { 5'b01101, 1'b0, 1'b?, 5'b00111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV8_H = - { 5'b01101, 1'b0, 1'b?, 5'b01000, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV4_H = - { 5'b01101, 1'b0, 1'b?, 5'b01100, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV2_H = - { 5'b01101, 1'b0, 1'b?, 5'b01110, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV_H = - { 5'b01101, 1'b0, 1'b?, 5'b01111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV16 = - { 5'b01101, 1'b0, 1'b?, 5'b10000, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; + // rev8 (Zbb, shamt 0x18: reverse byte order) and brev8 (Zbkb, shamt 0x07: + // reverse bits within each byte). grevi restricted to these two control values. parameter logic [31:0] INSN_REV8 = - { 5'b01101, 1'b0, 1'b?, 5'b11000, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV4 = - { 5'b01101, 1'b0, 1'b?, 5'b11100, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV2 = - { 5'b01101, 1'b0, 1'b?, 5'b11110, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; - parameter logic [31:0] INSN_REV = - { 5'b01101, 1'b0, 1'b?, 5'b11111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; + { 5'b01101, 1'b0, 1'b0, 5'b11000, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; + parameter logic [31:0] INSN_BREV8 = + { 5'b01101, 1'b0, 1'b0, 5'b00111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; // orc.b (Zbb): gorci restricted to shamt 0x07 (bitwise OR-combine within each byte). parameter logic [31:0] INSN_ORC_B = { 5'b00101, 1'b0, 1'b0, 5'b00111, 5'h?, 3'b101, 5'h?, {OPCODE_OP_IMM} }; From 71e83b053a8948468eabe5c65b2b702ab1a68c6b Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:20 +0200 Subject: [PATCH 16/20] [rtl] Support pseudo instruction `zexth` Signed-off-by: Thomas Benz --- rtl/ibex_decoder.sv | 23 +++++++++++++++++++---- rtl/ibex_tracer.sv | 19 +++++++------------ rtl/ibex_tracer_pkg.sv | 11 ++--------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index dccb3ee28..fd0899d0d 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -465,13 +465,21 @@ module ibex_decoder #( {7'b000_0101, 3'b110}, // max {7'b000_0101, 3'b101}, // minu {7'b000_0101, 3'b111}, // maxu - {7'b000_0100, 3'b100}, // pack - {7'b000_0100, 3'b111}, // packh // RV32B zbs {7'b010_0100, 3'b001}, // bclr {7'b001_0100, 3'b001}, // bset {7'b011_0100, 3'b001}, // binv {7'b010_0100, 3'b101}: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // bext + // RV32B zbb / zbkb + {7'b000_0100, 3'b100}: begin // pack / zext.h + // zext.h (Zbb) = pack rd, rs1, x0; general pack is Zbkb (RV32BFull only). + if (instr[24:20] == 5'b00000) begin + illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // zext.h + end else begin + illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // pack + end + end + {7'b000_0100, 3'b111}: illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // packh // RV32B zbkx {7'b001_0100, 3'b010}, // xperm4 {7'b001_0100, 3'b100}, // xperm8 @@ -912,8 +920,15 @@ module ibex_decoder #( {7'b000_0101, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_MINU; {7'b000_0101, 3'b111}: if (RV32B != RV32BNone) alu_operator_o = ALU_MAXU; - {7'b000_0100, 3'b100}: if (RV32B != RV32BNone) alu_operator_o = ALU_PACK; - {7'b000_0100, 3'b111}: if (RV32B != RV32BNone) alu_operator_o = ALU_PACKH; + {7'b000_0100, 3'b100}: begin + // zext.h (Zbb, rs2=x0) reuses the pack datapath; general pack is Zbkb. + if (instr_alu[24:20] == 5'b00000) begin + if (RV32B != RV32BNone) alu_operator_o = ALU_PACK; // zext.h + end else begin + if (RV32B == RV32BFull) alu_operator_o = ALU_PACK; // pack + end + end + {7'b000_0100, 3'b111}: if (RV32B == RV32BFull) alu_operator_o = ALU_PACKH; {7'b010_0000, 3'b100}: if (RV32B != RV32BNone) alu_operator_o = ALU_XNOR; {7'b010_0000, 3'b110}: if (RV32B != RV32BNone) alu_operator_o = ALU_ORN; diff --git a/rtl/ibex_tracer.sv b/rtl/ibex_tracer.sv index 9a53b5708..8e454f818 100644 --- a/rtl/ibex_tracer.sv +++ b/rtl/ibex_tracer.sv @@ -1046,18 +1046,13 @@ module ibex_tracer ( INSN_XNOR: decode_r_insn("xnor"); INSN_ORN: decode_r_insn("orn"); INSN_ANDN: decode_r_insn("andn"); - // The ratified v.1.0.0 bitmanip extension defines the pseudo-instruction - // zext.h rd rs = pack rd, rs, zero. - // However, for now the tracer doesn't emit this due to a lack of support in the LLVM and - // GCC toolchains. Enabling this functionality when the time is right is tracked in - // https://github.com/lowRISC/ibex/issues/1228 - 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 + // zext.h (Zbb) is the pseudo-instruction `pack rd, rs, x0` + INSN_PACK: begin + unique casez (rvfi_insn) + INSN_ZEXTH: decode_r1_insn("zext.h"); + default: decode_r_insn("pack"); + endcase + end INSN_PACKH: decode_r_insn("packh"); INSN_CLZ: decode_r1_insn("clz"); INSN_CTZ: decode_r1_insn("ctz"); diff --git a/rtl/ibex_tracer_pkg.sv b/rtl/ibex_tracer_pkg.sv index 411a53f40..616467afb 100644 --- a/rtl/ibex_tracer_pkg.sv +++ b/rtl/ibex_tracer_pkg.sv @@ -87,15 +87,8 @@ package ibex_tracer_pkg; parameter logic [31:0] INSN_SEXTB = { 12'b011000000100, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; parameter logic [31:0] INSN_SEXTH = { 12'b011000000101, 5'h?, 3'b001, 5'h?, {OPCODE_OP_IMM} }; - // The zext.h and zext.b pseudo-instructions are defined in the ratified v.1.0.0 and draft v.0.94 - // specifications of the bitmanip extension, respectively. They are currently not emitted by the - // tracer due to a lack of support in the LLVM and GCC toolchains. Enabling this functionality - // when the time is right is tracked in https://github.com/lowRISC/ibex/issues/1228 - // zext.b -- pseudo-instruction: andi rd, rs 255 - // parameter logic [31:0] INSN_ZEXTB = - // { 4'b0000, 8'b11111111, 5'h?, 3'b111, 5'h?, {OPCODE_OP_IMM} }; - // zext.h -- pseudo-instruction: pack rd, rs zero - // parameter logic [31:0] INSN_ZEXTH = { 7'b0000100, 5'b00000, 5'h?, 3'b100, 5'h?, {OPCODE_OP} }; + // zext.h (Zbb) is the pseudo-instruction `pack rd, rs, x0`. + parameter logic [31:0] INSN_ZEXTH = { 7'b0000100, 5'b00000, 5'h?, 3'b100, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_ROL = { 7'b0110000, 10'h?, 3'b001, 5'h?, {OPCODE_OP} }; parameter logic [31:0] INSN_ROR = { 7'b0110000, 10'h?, 3'b101, 5'h?, {OPCODE_OP} }; From 7dab369a489ad6be388bbe2b4e50e786c967839e Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:20 +0200 Subject: [PATCH 17/20] [rtl] Complete Zbkb Signed-off-by: Thomas Benz --- rtl/ibex_decoder.sv | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index fd0899d0d..f75fa9f85 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -844,8 +844,9 @@ module ibex_decoder #( 5'b0_0000: alu_operator_o = ALU_SRL; // Shift Right Logical by Immediate 5'b0_1000: alu_operator_o = ALU_SRA; // Shift Right Arithmetically by Immediate 5'b0_1001: alu_operator_o = ALU_BEXT; // Extract bit specified by immediate. + // rori (Zbb, also imported by Zbkb): rotate right by immediate 5'b0_1100: begin - alu_operator_o = ALU_ROR; // Rotate Right by Immediate + alu_operator_o = ALU_ROR; alu_multicycle_o = 1'b1; end // rev8 (Zbb, shamt 0x18) and brev8 (Zbkb, shamt 0x07) @@ -902,6 +903,7 @@ module ibex_decoder #( {7'b010_0000, 3'b101}: alu_operator_o = ALU_SRA; // Shift Right Arithmetic // RV32B ALU Operations + // rol / ror (Zbb, also imported by Zbkb): rotate by register amount {7'b011_0000, 3'b001}: begin if (RV32B != RV32BNone) begin alu_operator_o = ALU_ROL; From 4005e9e91e279357c491c3f5f20847160a3b90d0 Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 13:54:20 +0200 Subject: [PATCH 18/20] [rtl] Lint fix Signed-off-by: Thomas Benz --- rtl/ibex_alu.sv | 10 ++-------- rtl/ibex_decoder.sv | 32 +++++--------------------------- 2 files changed, 7 insertions(+), 35 deletions(-) diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index 85fec665e..1a4cfe7fe 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -226,7 +226,7 @@ module ibex_alu #( logic [31:0] shift_result; logic [31:0] shift_result_rev; - assign shift_amt_compl = 32 - operand_b_i[4:0]; + assign shift_amt_compl = 5'd0 - operand_b_i[4:0]; always_comb begin shift_amt[4:0] = instr_first_cycle_i ? operand_b_i[4:0] : shift_amt_compl[4:0]; @@ -555,8 +555,6 @@ module ibex_alu #( end end - logic [31:0] clmul_result_rev; - if (RV32B == RV32BFull) begin : gen_alu_rvb_full ///////////////// @@ -752,6 +750,7 @@ module ibex_alu #( logic [31:0] clmul_xor_stage4[2]; logic [31:0] clmul_result_raw; + logic [31:0] clmul_result_rev; for (genvar i = 0; i < 32; i++) begin : gen_rev_operand_b assign operand_b_rev[i] = operand_b_i[31-i]; @@ -805,8 +804,6 @@ module ibex_alu #( assign shuffle_result = '0; assign xperm_result = '0; assign clmul_result = '0; - // support signals - assign clmul_result_rev = '0; end ////////////////////////////////////// @@ -926,7 +923,4 @@ module ibex_alu #( endcase end - logic unused_shift_amt_compl; - assign unused_shift_amt_compl = shift_amt_compl[5]; - endmodule diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index f75fa9f85..bef3947ff 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -111,12 +111,8 @@ module ibex_decoder #( // Source/Destination register instruction index logic [4:0] instr_rs1; logic [4:0] instr_rs2; - logic [4:0] instr_rs3; logic [4:0] instr_rd; - logic use_rs3_d; - logic use_rs3_q; - csr_op_e csr_op; opcode_e opcode; @@ -144,32 +140,15 @@ module ibex_decoder #( // immediate for CSR manipulation (zero extended) assign zimm_rs1_type_o = { 27'b0, instr_rs1 }; // rs1 - if (RV32B != RV32BNone) begin : gen_rs3_flop - // the use of rs3 is known one cycle ahead. - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - use_rs3_q <= 1'b0; - end else begin - use_rs3_q <= use_rs3_d; - end - end - end else begin : gen_no_rs3_flop - logic unused_clk; - logic unused_rst_n; - - // Clock and reset unused when there's no rs3 flop - assign unused_clk = clk_i; - assign unused_rst_n = rst_ni; - - // always zero - assign use_rs3_q = use_rs3_d; - end + logic unused_clk; + logic unused_rst_n; + assign unused_clk = clk_i; + assign unused_rst_n = rst_ni; // source registers assign instr_rs1 = instr[19:15]; assign instr_rs2 = instr[24:20]; - assign instr_rs3 = instr[31:27]; - assign rf_raddr_a_o = (use_rs3_q & ~instr_first_cycle_i) ? instr_rs3 : instr_rs1; // rs3 / rs1 + assign rf_raddr_a_o = instr_rs1; // rs1 assign rf_raddr_b_o = instr_rs2; // rs2 // destination register @@ -662,7 +641,6 @@ module ibex_decoder #( opcode_alu = opcode_e'(instr_alu[6:0]); - use_rs3_d = 1'b0; alu_multicycle_o = 1'b0; mult_sel_o = 1'b0; div_sel_o = 1'b0; From 242bc598054062b1cbf6c8457bd4f6f21875a12d Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Mon, 13 Jul 2026 15:22:57 +0200 Subject: [PATCH 19/20] [rtl] Remove unsupported `RV32BOTEarlGrey` Signed-off-by: Thomas Benz --- doc/01_overview/compliance.rst | 15 +++--- doc/02_user/configuration.rst | 2 +- doc/02_user/integration.rst | 5 +- .../instruction_decode_execute.rst | 53 +++++++------------ .../riscv_dv_extension/ml_testlist.yaml | 8 +-- .../riscv_dv_extension/testlist.yaml | 26 ++------- dv/uvm/core_ibex/scripts/ibex_cmd.py | 7 +-- dv/uvm/core_ibex/tests/core_ibex_base_test.sv | 6 +-- examples/simple_system/ibex_simple_system.cc | 6 +-- ibex_configs.yaml | 2 +- 10 files changed, 44 insertions(+), 86 deletions(-) diff --git a/doc/01_overview/compliance.rst b/doc/01_overview/compliance.rst index 4a34db187..8846c8c62 100644 --- a/doc/01_overview/compliance.rst +++ b/doc/01_overview/compliance.rst @@ -8,7 +8,8 @@ It follows these specifications: * `RISC-V Instruction Set Manual, Volume II: Privileged Architecture, document version 20211203 (December 4, 2021) `_. Ibex implements the Machine ISA version 1.12. * `RISC-V External Debug Support, version 0.13.2 `_ -* `RISC-V Bit-Manipulation Extension, version 1.0.0 `_ and `version 0.93 (draft from January 10, 2021) `_ +* `RISC-V Bit-Manipulation Extension, version 1.0.0 `_ +* `RISC-V Scalar Cryptography Extension, version 1.0.1 `_ (Zbkb, Zbkx sub-extensions only) * `PMP Enhancements for memory access and execution prevention on Machine mode (Smepmp) version 1.0 `_ Many features in the RISC-V specification are optional, and Ibex can be parametrized to enable or disable some of them. @@ -36,7 +37,11 @@ In addition, the following instruction set extensions are available. - optional * - **B**: Standard Extension for Bit-Manipulation Instructions - - 1.0.0 + 0.93 [#B_draft]_ + - 1.0.0 [#B_draft]_ + - optional + + * - **Zbkb, Zbkx**: Scalar Cryptography Bit-Manipulation Instructions + - 1.0.1 [#B_draft]_ - optional * - **Zicsr**: Control and Status Register Instructions @@ -73,8 +78,4 @@ Ibex currently supports the following features according to the RISC-V Privilege .. rubric:: Footnotes .. [#B_draft] Ibex fully implements the ratified version 1.0.0 of the RISC-V Bit-Manipulation Extension including the Zba, Zbb, Zbc and Zbs sub-extensions. - In addition, Ibex also supports the remaining Zbe, Zbf, Zbp, Zbr and Zbt sub-extensions as defined in draft version 0.93 of the RISC-V Bit-Manipulation Extension. - Note that the latter sub-extensions may change before being ratified as a standard by the RISC-V Foundation. - Ibex will be updated to match future versions of the specification. - Prior to ratification this may involve backwards incompatible changes. - Additionally, neither GCC or Clang have committed to maintaining support upstream for unratified versions of the specification. + In addition, Ibex implements the Zbkb and Zbkx sub-extensions of the ratified RISC-V Scalar Cryptography Extension. diff --git a/doc/02_user/configuration.rst b/doc/02_user/configuration.rst index cbd59488c..4108fd6e2 100644 --- a/doc/02_user/configuration.rst +++ b/doc/02_user/configuration.rst @@ -23,7 +23,7 @@ Here is an example of using the configuration tool to get the FuseSoC options re ./util/ibex_config.py opentitan fusesoc_opts # The output of the tool - --RV32E=0 --RV32M=ibex_pkg::RV32MSingleCycle --RV32B=ibex_pkg::RV32BOTEarlGrey --RegFile=ibex_pkg::RegFileFF --BranchTargetALU=1 --WritebackStage=1 --ICache=1 --ICacheECC=1 --ICacheScramble=1 --BranchPredictor=0 --DbgTriggerEn=1 --SecureIbex=1 --PMPEnable=1 --PMPGranularity=0 --PMPNumRegions=16 --MHPMCounterNum=10 --MHPMCounterWidth=32 + --RV32E=0 --RV32M=ibex_pkg::RV32MSingleCycle --RV32B=ibex_pkg::RV32BFull --RegFile=ibex_pkg::RegFileFF --BranchTargetALU=1 --WritebackStage=1 --ICache=1 --ICacheECC=1 --ICacheScramble=1 --BranchPredictor=0 --DbgTriggerEn=1 --SecureIbex=1 --PMPEnable=1 --PMPGranularity=0 --PMPNumRegions=16 --MHPMCounterNum=10 --MHPMCounterWidth=32 For further information about using the tool check the help provided on the command line. diff --git a/doc/02_user/integration.rst b/doc/02_user/integration.rst index 2da4c53dc..3eef4b1e3 100644 --- a/doc/02_user/integration.rst +++ b/doc/02_user/integration.rst @@ -209,9 +209,8 @@ Parameters +------------------------------+---------------------+----------------+-----------------------------------------------------------------------+ | ``RV32B`` | ibex_pkg::rv32b_e | RV32BNone | B(itmanipulation) extension select: | | | | | "ibex_pkg::RV32BNone": No B-extension | -| | | | "ibex_pkg::RV32BBalanced": Sub-extensions Zba, Zbb, Zbs, Zbf and Zbt | -| | | | "ibex_pkg::RV32BOTEarlGrey": All sub-extensions except Zbe | -| | | | "ibex_pkg::RV32BFull": All sub-extensions | +| | | | "ibex_pkg::RV32BBalanced": Sub-extensions Zba, Zbb, Zbs | +| | | | "ibex_pkg::RV32BFull": Balanced plus Zbc, Zbkb, Zbkx | +------------------------------+---------------------+----------------+-----------------------------------------------------------------------+ | ``RV32ZC`` | ibex_pkg::rv32zc_e | RV32ZcaZcbZcmp | Zc code-size saving extension select: | | | | | "ibex_pkg::RV32Zca": The Zca extension | diff --git a/doc/03_reference/instruction_decode_execute.rst b/doc/03_reference/instruction_decode_execute.rst index 773408034..729dadc7a 100644 --- a/doc/03_reference/instruction_decode_execute.rst +++ b/doc/03_reference/instruction_decode_execute.rst @@ -65,44 +65,33 @@ Other blocks use the ALU for the following tasks: * The LSU uses it to increment addresses when performing two accesses to handle an unaligned access Bit-Manipulation Extension - Support for the `RISC-V Bit-Manipulation Extension version 1.0.0 `_ and `draft version 0.93 from January 10, 2021 `_ is optional. [#B_draft]_ + Support for the `RISC-V Bit-Manipulation Extension version 1.0.0 `_, together with the Zbkb and Zbkx sub-extensions of the ratified Scalar Cryptography Extension, is optional. [#B_draft]_ It can be enabled via the enumerated parameter ``RV32B`` defined in :file:`rtl/ibex_pkg.sv`. By default, this parameter is set to "ibex_pkg::RV32BNone" to disable the bit-manipulation extension. - There are three versions of the bit-manipulation extension available: + There are two versions of the bit-manipulation extension available: The balanced version comprises a set of sub-extensions aiming for good benefits at a reasonable area overhead. It can be selected by setting the ``RV32B`` parameter to "ibex_pkg::RV32BBalanced". - The OTEarlGrey version comprises all sub-extensions except for the Zbe. - This version can be selected by setting the ``RV32B`` parameter to "ibex_pkg::RV32BOTEarlGrey". - The full version comprises all sub-extensions and can be selected by setting the ``RV32B`` parameter to "ibex_pkg::RV32BFull". + The full version additionally comprises the Zbc, Zbkb and Zbkx sub-extensions and can be selected by setting the ``RV32B`` parameter to "ibex_pkg::RV32BFull". The following table gives an overview of which sub-extensions are implemented in each version and of which instructions are implemented as multi-cycle instructions. Multi-cycle instructions are completed in 2 cycles. All remaining instructions complete in a single cycle. - +--------------------------------+---------+----------+------------+------+--------------------+ - | Bit-Manipulation Sub-Extension | Spec. | Balanced | OTEarlGrey | Full | Multi-Cycle Instr. | - +================================+=========+==========+============+======+====================+ - | Zba (Address generation) | v.1.0.0 | X | X | X | None | - +--------------------------------+---------+----------+------------+------+--------------------+ - | Zbb (Base) | v.1.0.0 | X | X | X | rol, ror[i] | - +--------------------------------+---------+----------+------------+------+--------------------+ - | Zbc (Carry-less multiply) | v.1.0.0 | | X | X | None | - +--------------------------------+---------+----------+------------+------+--------------------+ - | Zbs (Single-bit) | v.1.0.0 | X | X | X | None | - +--------------------------------+---------+----------+------------+------+--------------------+ - | Zbe (Bit compress/decompress) | v.0.93 | | | X | All | - +--------------------------------+---------+----------+------------+------+--------------------+ - | Zbf (Bit-field place) | v.0.93 | X | X | X | All | - +--------------------------------+---------+----------+------------+------+--------------------+ - | Zbp (Permutation) | v.0.93 | | X | X | None | - +--------------------------------+---------+----------+------------+------+--------------------+ - | Zbr (CRC) | v.0.93 | | X | X | All | - +--------------------------------+---------+----------+------------+------+--------------------+ - | Zbt (Ternary) | v.0.93 | X | X | X | All | - +--------------------------------+---------+----------+------------+------+--------------------+ - - The implementation of the Bit-Manipulation Extension comes with an area overhead of 2.7 kGE for the balanced version, 6.1 kGE for the OTEarlGrey version, and 7.5 kGE for the full version. - These numbers were obtained by synthesizing the design with Yosys and relaxed timing constraints. + +------------------------------------+---------+----------+------+--------------------+ + | Bit-Manipulation Sub-Extension | Spec. | Balanced | Full | Multi-Cycle Instr. | + +====================================+=========+==========+======+====================+ + | Zba (Address generation) | v.1.0.0 | X | X | None | + +------------------------------------+---------+----------+------+--------------------+ + | Zbb (Base) | v.1.0.0 | X | X | rol, ror[i] | + +------------------------------------+---------+----------+------+--------------------+ + | Zbc (Carry-less multiply) | v.1.0.0 | | X | None | + +------------------------------------+---------+----------+------+--------------------+ + | Zbs (Single-bit) | v.1.0.0 | X | X | None | + +------------------------------------+---------+----------+------+--------------------+ + | Zbkb (Bit-manipulation for crypto) | v.1.0.0 | | X | None | + +------------------------------------+---------+----------+------+--------------------+ + | Zbkx (Crossbar permutation) | v.1.0.0 | | X | None | + +------------------------------------+---------+----------+------+--------------------+ .. _mult-div: @@ -173,8 +162,4 @@ See :ref:`load-store-unit` for more details. .. rubric:: Footnotes .. [#B_draft] Ibex fully implements the ratified version 1.0.0 of the RISC-V Bit-Manipulation Extension including the Zba, Zbb, Zbc and Zbs sub-extensions. - In addition, Ibex also supports the remaining Zbe, Zbf, Zbp, Zbr and Zbt sub-extensions as defined in draft version 0.93 of the RISC-V Bit-Manipulation Extension. - Note that the latter sub-extensions may change before being ratified as a standard by the RISC-V Foundation. - Ibex will be updated to match future versions of the specification. - Prior to ratification this may involve backwards incompatible changes. - Additionally, neither GCC or Clang have committed to maintaining support upstream for unratified versions of the specification. + In addition, Ibex implements the Zbkb and Zbkx sub-extensions of the ratified RISC-V Scalar Cryptography Extension. diff --git a/dv/uvm/core_ibex/riscv_dv_extension/ml_testlist.yaml b/dv/uvm/core_ibex/riscv_dv_extension/ml_testlist.yaml index a5f3158f2..203014e28 100644 --- a/dv/uvm/core_ibex/riscv_dv_extension/ml_testlist.yaml +++ b/dv/uvm/core_ibex/riscv_dv_extension/ml_testlist.yaml @@ -80,7 +80,7 @@ +disable_compressed_instr=0 +randomize_csr=0 +enable_b_extension=1 - +enable_bitmanip_groups=zbb,zb_tmp,zbt,zbs,zbp,zbf,zbe,zbc,zbr + +enable_bitmanip_groups=zbb,zb_tmp,zbs,zbp,zbc +boot_mode=u +stream_name_0=riscv_load_store_rand_instr_stream +stream_freq_0=4 @@ -175,7 +175,7 @@ +disable_compressed_instr=0 +randomize_csr=0 +enable_b_extension=1 - +enable_bitmanip_groups=zbb,zb_tmp,zbt,zbs,zbp,zbf,zbe,zbc,zbr + +enable_bitmanip_groups=zbb,zb_tmp,zbs,zbp,zbc +boot_mode=u +stream_name_0=riscv_load_store_rand_instr_stream +stream_freq_0=4 @@ -264,7 +264,7 @@ +disable_compressed_instr=0 +randomize_csr=1 +enable_b_extension=1 - +enable_bitmanip_groups=zbb,zb_tmp,zbt,zbs,zbp,zbf,zbe,zbc,zbr + +enable_bitmanip_groups=zbb,zb_tmp,zbs,zbp,zbc +boot_mode=u +stream_name_0=riscv_load_store_rand_instr_stream +stream_freq_0=4 @@ -349,7 +349,7 @@ +disable_compressed_instr=0 +randomize_csr=0 +enable_b_extension=1 - +enable_bitmanip_groups=zbb,zb_tmp,zbt,zbs,zbp,zbf,zbe,zbc,zbr + +enable_bitmanip_groups=zbb,zb_tmp,zbs,zbp,zbc +boot_mode=u +stream_name_0=riscv_load_store_rand_instr_stream +stream_freq_0=4 diff --git a/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml b/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml index 3c2a44748..be34b6963 100644 --- a/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml +++ b/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml @@ -1108,9 +1108,8 @@ PMPEnable: 1 timeout_s: 300 -# Both an updated compiler and ISS are required to verify the bitmanip v.1.00 -# and draft v.0.93 extensions. For now, disable the bitmanip tests. -# For details, refer to https://github.com/lowRISC/ibex/issues/1470 +# Ibex implements only the ratified v1.00 Zba/Zbb/Zbc/Zbs extensions plus the +# ratified Zbkb/Zbkx crypto sub-extensions - test: riscv_bitmanip_full_test desc: > Random instruction test with supported B extension instructions in full configuration @@ -1122,27 +1121,11 @@ +enable_zbc_extension=1 +enable_zbs_extension=1 +enable_b_extension=1 - +enable_bitmanip_groups=zbe,zbf,zbp,zbr,zbt + +enable_bitmanip_groups=zbp rtl_test: core_ibex_base_test rtl_params: RV32B: "ibex_pkg::RV32BFull" -- test: riscv_bitmanip_otearlgrey_test - desc: > - Random instruction test with supported B extension instructions in OTEarlGrey configuration - iterations: 10 - gen_test: riscv_rand_instr_test - gen_opts: > - +enable_zba_extension=1 - +enable_zbb_extension=1 - +enable_zbc_extension=1 - +enable_zbs_extension=1 - +enable_b_extension=1 - +enable_bitmanip_groups=zbf,zbp,zbr,zbt - rtl_test: core_ibex_base_test - rtl_params: - RV32B: ["ibex_pkg::RV32BFull", "ibex_pkg::RV32BOTEarlGrey"] - - test: riscv_bitmanip_balanced_test desc: > Random instruction test with supported B extension instructions in balanced configuration @@ -1153,7 +1136,6 @@ +enable_zbb_extension=1 +enable_zbs_extension=1 +enable_b_extension=1 - +enable_bitmanip_groups=zbf,zbt rtl_test: core_ibex_base_test rtl_params: - RV32B: ["ibex_pkg::RV32BFull", "ibex_pkg::RV32BOTEarlGrey", "ibex_pkg::RV32BBalanced"] + RV32B: ["ibex_pkg::RV32BFull", "ibex_pkg::RV32BBalanced"] diff --git a/dv/uvm/core_ibex/scripts/ibex_cmd.py b/dv/uvm/core_ibex/scripts/ibex_cmd.py index 0d8c5346e..ba263f772 100644 --- a/dv/uvm/core_ibex/scripts/ibex_cmd.py +++ b/dv/uvm/core_ibex/scripts/ibex_cmd.py @@ -101,11 +101,8 @@ def get_isas_for_config(cfg: Config) -> Tuple[str, str]: bitmanip_mapping = { 'ibex_pkg::RV32BNone': [], - 'ibex_pkg::RV32BBalanced': ['Zba', 'Zbb', 'Zbs', 'XZbf', 'XZbt'], - 'ibex_pkg::RV32BOTEarlGrey': ['Zba', 'Zbb', 'Zbc', 'Zbs', - 'XZbf', 'XZbp', 'XZbr', 'XZbt'], - 'ibex_pkg::RV32BFull': ['Zba', 'Zbb', 'Zbc', 'Zbs', - 'XZbe', 'XZbf', 'XZbp', 'XZbr', 'XZbt'] + 'ibex_pkg::RV32BBalanced': ['Zba', 'Zbb', 'Zbs'], + 'ibex_pkg::RV32BFull': ['Zba', 'Zbb', 'Zbc', 'Zbs', 'Zbkb', 'Zbkx'] } bitmanip_isa = bitmanip_mapping.get(cfg.rv32b) diff --git a/dv/uvm/core_ibex/tests/core_ibex_base_test.sv b/dv/uvm/core_ibex/tests/core_ibex_base_test.sv index 47847ad67..e6414f17c 100644 --- a/dv/uvm/core_ibex/tests/core_ibex_base_test.sv +++ b/dv/uvm/core_ibex/tests/core_ibex_base_test.sv @@ -74,11 +74,9 @@ class core_ibex_base_test extends uvm_test; RV32BNone: ; RV32BBalanced: - isa = {isa, "_Zba_Zbb_Zbs_XZbf_XZbt"}; - RV32BOTEarlGrey: - isa = {isa, "_Zba_Zbb_Zbc_Zbs_XZbf_XZbp_XZbr_XZbt"}; + isa = {isa, "_Zba_Zbb_Zbs"}; RV32BFull: - isa = {isa, "_Zba_Zbb_Zbc_Zbs_XZbe_XZbf_XZbp_XZbr_XZbt"}; + isa = {isa, "_Zba_Zbb_Zbc_Zbs_Zbkb_Zbkx"}; endcase return isa; diff --git a/examples/simple_system/ibex_simple_system.cc b/examples/simple_system/ibex_simple_system.cc index 209d3ddb6..fabc09aec 100644 --- a/examples/simple_system/ibex_simple_system.cc +++ b/examples/simple_system/ibex_simple_system.cc @@ -53,11 +53,7 @@ std::string SimpleSystem::GetIsaString() const { extensions += "_Zba_Zbb_Zbs_XZbf_XZbt"; break; - case 2: // RV32BOTEarlGrey - extensions += "_Zba_Zbb_Zbc_Zbs_XZbf_XZbp_XZbr_XZbt"; - break; - - case 3: // RV32BFull + case 2: // RV32BFull extensions += "_Zba_Zbb_Zbc_Zbs_XZbe_XZbf_XZbp_XZbr_XZbt"; break; } diff --git a/ibex_configs.yaml b/ibex_configs.yaml index f816054aa..67f8369ac 100644 --- a/ibex_configs.yaml +++ b/ibex_configs.yaml @@ -40,7 +40,7 @@ small: opentitan: RV32E : 0 RV32M : "ibex_pkg::RV32MSingleCycle" - RV32B : "ibex_pkg::RV32BOTEarlGrey" + RV32B : "ibex_pkg::RV32BFull" RV32ZC : "ibex_pkg::RV32ZcaZcbZcmp" RegFile : "ibex_pkg::RegFileFF" BranchTargetALU : 1 From 6062faa86e9b27570d5527b8d2cb964702b0a751 Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Wed, 15 Jul 2026 14:32:12 +0200 Subject: [PATCH 20/20] [dv] Fix spike cosim Signed-off-by: Thomas Benz --- dv/cosim/spike_cosim.cc | 23 +++++++++++------------ dv/cosim/spike_cosim.h | 2 +- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/dv/cosim/spike_cosim.cc b/dv/cosim/spike_cosim.cc index 32537875e..76df135e2 100644 --- a/dv/cosim/spike_cosim.cc +++ b/dv/cosim/spike_cosim.cc @@ -73,7 +73,8 @@ SpikeCosim::SpikeCosim(const std::string &isa_string, uint32_t start_pc, processor->set_ibex_flags(secure_ibex, icache_en); processor->set_debug_module_range(dm_start_addr, dm_end_addr); - initial_proc_setup(start_pc, start_mtvec, mhpm_counter_num); + bool rv32b_enabled = isa_string.find("Zb") != std::string::npos; + initial_proc_setup(start_pc, start_mtvec, mhpm_counter_num, rv32b_enabled); if (log) { processor->set_debug(true); @@ -565,13 +566,21 @@ void SpikeCosim::set_cpuctrlsts_double_fault_seen() { } void SpikeCosim::initial_proc_setup(uint32_t start_pc, uint32_t start_mtvec, - uint32_t mhpm_counter_num) { + uint32_t mhpm_counter_num, + bool rv32b_enabled) { processor->get_state()->pc = start_pc; processor->get_state()->mtvec->write(start_mtvec); processor->get_state()->csrmap[CSR_MARCHID] = std::make_shared(processor.get(), CSR_MARCHID, IBEX_MARCHID); + uint32_t misa_val = processor->get_csr(CSR_MISA); + if (rv32b_enabled) { + misa_val |= 1 << 1; + } + processor->get_state()->csrmap[CSR_MISA] = + std::make_shared(processor.get(), CSR_MISA, misa_val); + processor->set_mmu_capability(IMPL_MMU_SBARE); for (int i = 0; i < processor->TM.count(); ++i) { @@ -825,16 +834,6 @@ void SpikeCosim::fixup_csr(int csr_num, uint32_t csr_val) { processor->set_csr(csr_num, new_val); #else processor->put_csr(csr_num, new_val); -#endif - break; - } - case CSR_MISA: { - // For Ibex, misa is hardwired - reg_t new_val = 0x40901104; -#ifdef OLD_SPIKE - processor->set_csr(csr_num, new_val); -#else - processor->put_csr(csr_num, new_val); #endif break; } diff --git a/dv/cosim/spike_cosim.h b/dv/cosim/spike_cosim.h index 2849206e0..89f3773f3 100644 --- a/dv/cosim/spike_cosim.h +++ b/dv/cosim/spike_cosim.h @@ -91,7 +91,7 @@ class SpikeCosim : public simif_t, public Cosim { void handle_cpuctrl_exception_entry(); void initial_proc_setup(uint32_t start_pc, uint32_t start_mtvec, - uint32_t mhpm_counter_num); + uint32_t mhpm_counter_num, bool rv32b_enabled); void early_interrupt_handle();