diff --git a/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml b/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml index d543d957..13d6d4b6 100644 --- a/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml +++ b/dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml @@ -719,8 +719,6 @@ # 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 -#ISA := rv32imcb -#ISA_ISS := rv32imc_Zba_Zbb_Zbc_Zbs_Xbitmanip #- test: riscv_bitmanip_full_test # desc: > # Random instruction test with supported B extension instructions in full configuration @@ -738,6 +736,23 @@ # 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 +# +disable_cosim=1 +# 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 @@ -752,4 +767,4 @@ # +disable_cosim=1 # rtl_test: core_ibex_base_test # rtl_params: -# RV32B: ["ibex_pkg::RV32BFull", "ibex_pkg::RV32BBalanced"] +# RV32B: ["ibex_pkg::RV32BFull", "ibex_pkg::RV32BOTEarlGrey", "ibex_pkg::RV32BBalanced"] diff --git a/ibex_configs.yaml b/ibex_configs.yaml index 1765c3f4..a9d3172a 100644 --- a/ibex_configs.yaml +++ b/ibex_configs.yaml @@ -26,7 +26,7 @@ small: opentitan: RV32E : 0 RV32M : "ibex_pkg::RV32MSingleCycle" - RV32B : "ibex_pkg::RV32BNone" + RV32B : "ibex_pkg::RV32BOTEarlGrey" RegFile : "ibex_pkg::RegFileFF" BranchTargetALU : 1 WritebackStage : 1 diff --git a/rtl/ibex_alu.sv b/rtl/ibex_alu.sv index ad796e21..eb6afcae 100644 --- a/rtl/ibex_alu.sv +++ b/rtl/ibex_alu.sv @@ -304,7 +304,7 @@ module ibex_alu #( always_comb begin unique case (operator_i) ALU_SLL: shift_left = 1'b1; - ALU_SLO: shift_left = (RV32B == RV32BFull) ? 1'b1 : 1'b0; + 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; @@ -320,10 +320,10 @@ module ibex_alu #( end assign shift_arith = (operator_i == ALU_SRA); - assign shift_ones = - (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; + 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 @@ -600,8 +600,10 @@ module ibex_alu #( logic gorc_op; assign gorc_op = (operator_i == ALU_GORC); - assign zbp_shift_amt[2:0] = (RV32B == RV32BFull) ? shift_amt[2:0] : {3{shift_amt[0]}}; - assign zbp_shift_amt[4:3] = (RV32B == RV32BFull) ? shift_amt[4:3] : {2{shift_amt[3]}}; + assign zbp_shift_amt[2:0] = + (RV32B == RV32BOTEarlGrey || 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]}}; always_comb begin rev_result = operand_a_i; @@ -625,13 +627,15 @@ module ibex_alu #( end if (zbp_shift_amt[3]) begin - rev_result = (gorc_op & (RV32B == RV32BFull) ? rev_result : 32'h0) | + rev_result = ((RV32B == RV32BOTEarlGrey || 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 = (gorc_op & (RV32B == RV32BFull) ? rev_result : 32'h0) | + rev_result = ((RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) && + gorc_op ? rev_result : 32'h0) | ((rev_result & 32'h0000_ffff) << 16) | ((rev_result & 32'hffff_0000) >> 16); end @@ -641,7 +645,7 @@ module ibex_alu #( logic crc_bmode; logic [31:0] clmul_result_rev; - if (RV32B == RV32BFull) begin : gen_alu_rvb_full + if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin : gen_alu_rvb_otearlgrey_full ///////////////////////// // Shuffle / Unshuffle // @@ -815,6 +819,182 @@ module ibex_alu #( end assign xperm_result = xperm_n; + /////////////////////////////////////////////////// + // Carry-less Multiply + Cyclic Redundancy Check // + /////////////////////////////////////////////////// + + // Carry-less multiplication can be understood as multiplication based on + // the addition interpreted as the bit-wise xor operation. + // + // Example: 1101 X 1011 = 1111111: + // + // 1011 X 1101 + // ----------- + // 1101 + // xor 1101 + // --------- + // 10111 + // xor 0000 + // ---------- + // 010111 + // xor 1101 + // ----------- + // 1111111 + // + // Architectural details: + // A 32 x 32-bit array + // [ 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 barret 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; + logic [31:0] clmul_op_a; + logic [31:0] clmul_op_b; + logic [31:0] operand_b_rev; + logic [31:0] clmul_and_stage[32]; + logic [31:0] clmul_xor_stage1[16]; + logic [31:0] clmul_xor_stage2[8]; + logic [31:0] clmul_xor_stage3[4]; + logic [31:0] clmul_xor_stage4[2]; + + logic [31:0] clmul_result_raw; + + for (genvar i = 0; i < 32; i++) begin : gen_rev_operand_b + assign operand_b_rev[i] = operand_b_i[31-i]; + end + + 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[0]; + 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 + end + + for (genvar i = 0; i < 32; i++) begin : gen_clmul_and_op + assign clmul_and_stage[i] = clmul_op_b[i] ? clmul_op_a << i : '0; + end + + for (genvar i = 0; i < 16; i++) begin : gen_clmul_xor_op_l1 + assign clmul_xor_stage1[i] = clmul_and_stage[2*i] ^ clmul_and_stage[2*i+1]; + end + + for (genvar i = 0; i < 8; i++) begin : gen_clmul_xor_op_l2 + assign clmul_xor_stage2[i] = clmul_xor_stage1[2*i] ^ clmul_xor_stage1[2*i+1]; + end + + for (genvar i = 0; i < 4; i++) begin : gen_clmul_xor_op_l3 + assign clmul_xor_stage3[i] = clmul_xor_stage2[2*i] ^ clmul_xor_stage2[2*i+1]; + end + + for (genvar i = 0; i < 2; i++) begin : gen_clmul_xor_op_l4 + assign clmul_xor_stage4[i] = clmul_xor_stage3[2*i] ^ clmul_xor_stage3[2*i+1]; + end + + assign clmul_result_raw = clmul_xor_stage4[0] ^ clmul_xor_stage4[1]; + + for (genvar i = 0; i < 32; i++) begin : gen_rev_clmul_result + assign clmul_result_rev[i] = clmul_result_raw[31-i]; + end + + // clmulr_result = rev(clmul(rev(a), rev(b))) + // clmulh_result = clmulr_result >> 1 + always_comb begin + case (1'b1) + clmul_rmode: clmul_result = clmul_result_rev; + clmul_hmode: clmul_result = {1'b0, clmul_result_rev[31:1]}; + default: clmul_result = clmul_result_raw; + endcase + end + end else begin : gen_alu_rvb_not_otearlgrey_full + assign shuffle_result = '0; + assign xperm_result = '0; + assign clmul_result = '0; + // support signals + assign clmul_result_rev = '0; + assign crc_bmode = '0; + assign crc_hmode = '0; + end + + if (RV32B == RV32BFull) begin : gen_alu_rvb_full + /////////////// // Butterfly // /////////////// @@ -1005,185 +1185,14 @@ module ibex_alu #( ((invbutterfly_result & butterfly_mask_l[0]) >> 16)| ((invbutterfly_result & butterfly_mask_r[0]) << 16); end - - /////////////////////////////////////////////////// - // Carry-less Multiply + Cyclic Redundancy Check // - /////////////////////////////////////////////////// - - // Carry-less multiplication can be understood as multiplication based on - // the addition interpreted as the bit-wise xor operation. - // - // Example: 1101 X 1011 = 1111111: - // - // 1011 X 1101 - // ----------- - // 1101 - // xor 1101 - // --------- - // 10111 - // xor 0000 - // ---------- - // 010111 - // xor 1101 - // ----------- - // 1111111 - // - // Architectural details: - // A 32 x 32-bit array - // [ 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 barret 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; - logic [31:0] clmul_op_a; - logic [31:0] clmul_op_b; - logic [31:0] operand_b_rev; - logic [31:0] clmul_and_stage[32]; - logic [31:0] clmul_xor_stage1[16]; - logic [31:0] clmul_xor_stage2[8]; - logic [31:0] clmul_xor_stage3[4]; - logic [31:0] clmul_xor_stage4[2]; - - logic [31:0] clmul_result_raw; - - for (genvar i = 0; i < 32; i++) begin : gen_rev_operand_b - assign operand_b_rev[i] = operand_b_i[31-i]; - end - - 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[0]; - 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 - end - - for (genvar i = 0; i < 32; i++) begin : gen_clmul_and_op - assign clmul_and_stage[i] = clmul_op_b[i] ? clmul_op_a << i : '0; - end - - for (genvar i = 0; i < 16; i++) begin : gen_clmul_xor_op_l1 - assign clmul_xor_stage1[i] = clmul_and_stage[2*i] ^ clmul_and_stage[2*i+1]; - end - - for (genvar i = 0; i < 8; i++) begin : gen_clmul_xor_op_l2 - assign clmul_xor_stage2[i] = clmul_xor_stage1[2*i] ^ clmul_xor_stage1[2*i+1]; - end - - for (genvar i = 0; i < 4; i++) begin : gen_clmul_xor_op_l3 - assign clmul_xor_stage3[i] = clmul_xor_stage2[2*i] ^ clmul_xor_stage2[2*i+1]; - end - - for (genvar i = 0; i < 2; i++) begin : gen_clmul_xor_op_l4 - assign clmul_xor_stage4[i] = clmul_xor_stage3[2*i] ^ clmul_xor_stage3[2*i+1]; - end - - assign clmul_result_raw = clmul_xor_stage4[0] ^ clmul_xor_stage4[1]; - - for (genvar i = 0; i < 32; i++) begin : gen_rev_clmul_result - assign clmul_result_rev[i] = clmul_result_raw[31-i]; - end - - // clmulr_result = rev(clmul(rev(a), rev(b))) - // clmulh_result = clmulr_result >> 1 - always_comb begin - case (1'b1) - clmul_rmode: clmul_result = clmul_result_rev; - clmul_hmode: clmul_result = {1'b0, clmul_result_rev[31:1]}; - default: clmul_result = clmul_result_raw; - endcase - end - end else begin : gen_alu_rvb_notfull + 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 shuffle_result = '0; - assign xperm_result = '0; assign butterfly_result = '0; assign invbutterfly_result = '0; - assign clmul_result = '0; // support signals assign bitcnt_partial_lsb_d = '0; assign bitcnt_partial_msb_d = '0; - assign clmul_result_rev = '0; - assign crc_bmode = '0; - assign crc_hmode = '0; end ////////////////////////////////////// @@ -1233,7 +1242,7 @@ module ibex_alu #( ALU_CRC32_W, ALU_CRC32C_W, ALU_CRC32_H, ALU_CRC32C_H, ALU_CRC32_B, ALU_CRC32C_B: begin - if (RV32B == RV32BFull) 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); diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index fbc754a1..3c87720c 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -362,14 +362,18 @@ 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: illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // sloi + 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 - 5'b0_0001: if (instr[26] == 1'b0) begin - illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // shfl - end else begin - illegal_insn = 1'b1; + 5'b0_0001: begin + if (instr[26] == 1'b0) begin // shfl + illegal_insn = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b0 : 1'b1; + end else begin + illegal_insn = 1'b1; + end end 5'b0_1100: begin unique case(instr[26:20]) @@ -383,8 +387,9 @@ module ibex_decoder #( 7'b001_0010, // crc32.w 7'b001_1000, // crc32c.b 7'b001_1001, // crc32c.h - 7'b001_1010: illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // crc32c.w - + 7'b001_1010: begin // crc32c.w + illegal_insn = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b0 : 1'b1; + end default: illegal_insn = 1'b1; endcase end @@ -400,12 +405,14 @@ 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: illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // sroi + 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 5'b0_1101: begin - if ((RV32B == RV32BFull)) begin + if (RV32B == RV32BOTEarlGrey || 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 @@ -414,7 +421,7 @@ module ibex_decoder #( end end 5'b0_0101: begin - if ((RV32B == RV32BFull)) begin + if (RV32B == RV32BOTEarlGrey || 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 @@ -423,8 +430,8 @@ module ibex_decoder #( end end 5'b0_0001: begin - if (instr[26] == 1'b0) begin - illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // unshfl + if (instr[26] == 1'b0) begin // unshfl + illegal_insn = (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) ? 1'b0 : 1'b1; end else begin illegal_insn = 1'b1; end @@ -483,9 +490,6 @@ module ibex_decoder #( {7'b010_0100, 3'b101}, // bext // RV32B zbf {7'b010_0100, 3'b111}: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // bfp - // RV32B zbe - {7'b010_0100, 3'b110}, // bdecompress - {7'b000_0100, 3'b110}, // bcompress // RV32B zbp {7'b011_0100, 3'b101}, // grev {7'b001_0100, 3'b101}, // gorc @@ -499,7 +503,12 @@ module ibex_decoder #( // RV32B zbc {7'b000_0101, 3'b001}, // clmul {7'b000_0101, 3'b010}, // clmulr - {7'b000_0101, 3'b011}: illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // clmulh + {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 @@ -824,7 +833,9 @@ module ibex_decoder #( 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: if (RV32B == RV32BFull) alu_operator_o = ALU_SLO; + 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. @@ -838,37 +849,37 @@ module ibex_decoder #( 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 == RV32BFull) 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 == RV32BFull) 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 == RV32BFull) 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 == RV32BFull) 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 == RV32BFull) 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 == RV32BFull) begin + if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin alu_operator_o = ALU_CRC32C_W; // crc32c.w alu_multicycle_o = 1'b1; end @@ -899,7 +910,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 // Shift Right Ones by Immediate - 5'b0_0100: if (RV32B == RV32BFull) alu_operator_o = ALU_SRO; + 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 @@ -909,7 +922,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 == RV32BFull) begin + if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) begin if (instr_alu[26] == 1'b0) alu_operator_o = ALU_UNSHFL; end end @@ -1034,18 +1047,38 @@ module ibex_decoder #( // RV32B zbp {7'b011_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_GREV; // grev {7'b001_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_GORC; // gorc - {7'b000_0100, 3'b001}: if (RV32B == RV32BFull) alu_operator_o = ALU_SHFL; // shfl - {7'b000_0100, 3'b101}: if (RV32B == RV32BFull) alu_operator_o = ALU_UNSHFL; // unshfl - {7'b001_0100, 3'b010}: if (RV32B == RV32BFull) alu_operator_o = ALU_XPERM_N; // xperm.n - {7'b001_0100, 3'b100}: if (RV32B == RV32BFull) alu_operator_o = ALU_XPERM_B; // xperm.b - {7'b001_0100, 3'b110}: if (RV32B == RV32BFull) alu_operator_o = ALU_XPERM_H; // xperm.h - {7'b001_0000, 3'b001}: if (RV32B == RV32BFull) alu_operator_o = ALU_SLO; // slo - {7'b001_0000, 3'b101}: if (RV32B == RV32BFull) alu_operator_o = ALU_SRO; // sro + {7'b000_0100, 3'b001}: begin + if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_SHFL; + end + {7'b000_0100, 3'b101}: begin + if (RV32B == RV32BOTEarlGrey || 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; + end + {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 + {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}: if (RV32B == RV32BFull) alu_operator_o = ALU_CLMUL; // clmul - {7'b000_0101, 3'b010}: if (RV32B == RV32BFull) alu_operator_o = ALU_CLMULR; // clmulr - {7'b000_0101, 3'b011}: if (RV32B == RV32BFull) alu_operator_o = ALU_CLMULH; // clmulh + {7'b000_0101, 3'b001}: begin + if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_CLMUL; + end + {7'b000_0101, 3'b010}: begin + if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_CLMULR; + end + {7'b000_0101, 3'b011}: begin + if (RV32B == RV32BOTEarlGrey || RV32B == RV32BFull) alu_operator_o = ALU_CLMULH; + end // RV32B zbe {7'b010_0100, 3'b110}: begin diff --git a/rtl/ibex_pkg.sv b/rtl/ibex_pkg.sv index 33d22455..c6aac9cb 100644 --- a/rtl/ibex_pkg.sv +++ b/rtl/ibex_pkg.sv @@ -45,9 +45,10 @@ package ibex_pkg; } rv32m_e; typedef enum integer { - RV32BNone = 0, - RV32BBalanced = 1, - RV32BFull = 2 + RV32BNone = 0, + RV32BBalanced = 1, + RV32BOTEarlGrey = 2, + RV32BFull = 3 } rv32b_e; /////////////