mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
[bitmanip] Add new configuration option for OpenTitan Earl Grey
RV32BOTEarlGrey selects the Zba, Zbb, Zbc, Zbs sub-extensions from v.1.0.0 of the bitmanip spec and the Zbf, Zbp, Zbr, Zbt sub-extensions from draft v.0.93. Zbe (bcompress/bdecompress) is supported by RV32BFull only. Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
This commit is contained in:
parent
a33a91b232
commit
92a95cac32
5 changed files with 283 additions and 225 deletions
|
@ -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"]
|
||||
|
|
|
@ -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
|
||||
|
|
375
rtl/ibex_alu.sv
375
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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
/////////////
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue