Skip to content

Commit

Permalink
Merge pull request #985 from pascalgouedo/dev_dd_pgo_rtl
Browse files Browse the repository at this point in the history
Added illegal instruction exception decoding on unused Imm6 bits for some SIMD instructions.
  • Loading branch information
pascalgouedo authored Apr 18, 2024
2 parents c7e2623 + 46dc9b5 commit cdd6955
Showing 1 changed file with 40 additions and 23 deletions.
63 changes: 40 additions & 23 deletions rtl/cv32e40p_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,6 @@ module cv32e40p_decoder
5'b00000: begin
fpu_op = cv32e40p_fpu_pkg::ADD;
fp_op_group = ADDMUL;
apu_op_o = 2'b0;
alu_op_b_mux_sel_o = OP_B_REGA_OR_FWD;
alu_op_c_mux_sel_o = OP_C_REGB_OR_FWD;
end
Expand All @@ -1066,7 +1065,6 @@ module cv32e40p_decoder
fpu_op = cv32e40p_fpu_pkg::ADD;
fpu_op_mod = 1'b1;
fp_op_group = ADDMUL;
apu_op_o = 2'b1;
alu_op_b_mux_sel_o = OP_B_REGA_OR_FWD;
alu_op_c_mux_sel_o = OP_C_REGB_OR_FWD;
end
Expand All @@ -1085,7 +1083,6 @@ module cv32e40p_decoder
regb_used_o = 1'b0;
fpu_op = cv32e40p_fpu_pkg::SQRT;
fp_op_group = DIVSQRT;
apu_op_o = 1'b1;
// rs2 must be zero
if (instr_rdata_i[24:20] != 5'b00000) illegal_insn_o = 1'b1;
end
Expand Down Expand Up @@ -1213,7 +1210,6 @@ module cv32e40p_decoder
fpu_op = cv32e40p_fpu_pkg::F2I;
fp_op_group = CONV;
fpu_op_mod = instr_rdata_i[20]; // signed/unsigned switch
apu_op_o = 2'b1;

unique case (instr_rdata_i[26:25]) //fix for casting to different formats other than FP32
2'b00: begin
Expand Down Expand Up @@ -1249,7 +1245,6 @@ module cv32e40p_decoder
fpu_op = cv32e40p_fpu_pkg::I2F;
fp_op_group = CONV;
fpu_op_mod = instr_rdata_i[20]; // signed/unsigned switch
apu_op_o = 2'b0;
// bits [21:20] used, other bits must be 0
if (instr_rdata_i[24:21]) illegal_insn_o = 1'b1; // in RV32, no casts to L allowed.
end
Expand Down Expand Up @@ -1323,20 +1318,20 @@ module cv32e40p_decoder
// check rounding mode
if (check_fprm) begin
unique case (instr_rdata_i[14:12]) inside
[3'b000:3'b100]: ; //legal rounding modes
3'b000, 3'b001, 3'b010, 3'b011, 3'b100: ; //legal rounding modes
3'b101: begin // Alternative Half-Precsision encded as fmt=10 and rm=101
if (~C_XF16ALT || fpu_dst_fmt_o != cv32e40p_fpu_pkg::FP16ALT) illegal_insn_o = 1'b1;
// actual rounding mode from frm csr
unique case (frm_i) inside
[3'b000:3'b100] : fp_rnd_mode_o = frm_i; //legal rounding modes
default : illegal_insn_o = 1'b1;
3'b000, 3'b001, 3'b010, 3'b011, 3'b100 : fp_rnd_mode_o = frm_i; //legal rounding modes
default : illegal_insn_o = 1'b1;
endcase
end
3'b111: begin
// rounding mode from frm csr
unique case (frm_i) inside
[3'b000:3'b100] : fp_rnd_mode_o = frm_i; //legal rounding modes
default : illegal_insn_o = 1'b1;
3'b000, 3'b001, 3'b010, 3'b011, 3'b100 : fp_rnd_mode_o = frm_i; //legal rounding modes
default : illegal_insn_o = 1'b1;
endcase
end
default : illegal_insn_o = 1'b1;
Expand Down Expand Up @@ -1364,6 +1359,7 @@ module cv32e40p_decoder
NONCOMP : apu_lat_o = (FPU_OTHERS_LAT<2) ? FPU_OTHERS_LAT+1 : 2'h3;
// CONV uses the same latency for all formats
CONV : apu_lat_o = (FPU_OTHERS_LAT<2) ? FPU_OTHERS_LAT+1 : 2'h3;
default: ;
endcase

// Set FPnew OP and OPMOD as the APU op
Expand Down Expand Up @@ -1425,25 +1421,21 @@ module cv32e40p_decoder
unique case (instr_rdata_i[6:0])
// fmadd.fmt - FP Fused multiply-add
OPCODE_OP_FMADD : begin
fpu_op = cv32e40p_fpu_pkg::FMADD;
apu_op_o = 2'b00;
fpu_op = cv32e40p_fpu_pkg::FMADD;
end
// fmsub.fmt - FP Fused multiply-subtract
OPCODE_OP_FMSUB : begin
fpu_op = cv32e40p_fpu_pkg::FMADD;
fpu_op_mod = 1'b1;
apu_op_o = 2'b01;
fpu_op = cv32e40p_fpu_pkg::FMADD;
fpu_op_mod = 1'b1;
end
// fnmsub.fmt - FP Negated fused multiply-subtract
OPCODE_OP_FNMSUB : begin
fpu_op = cv32e40p_fpu_pkg::FNMSUB;
apu_op_o = 2'b10;
fpu_op = cv32e40p_fpu_pkg::FNMSUB;
end
// fnmadd.fmt - FP Negated fused multiply-add
OPCODE_OP_FNMADD : begin
fpu_op = cv32e40p_fpu_pkg::FNMSUB;
fpu_op_mod = 1'b1;
apu_op_o = 2'b11;
fpu_op = cv32e40p_fpu_pkg::FNMSUB;
fpu_op_mod = 1'b1;
end
default : ;
endcase
Expand All @@ -1459,19 +1451,19 @@ module cv32e40p_decoder

// check rounding mode
unique case (instr_rdata_i[14:12]) inside
[3'b000:3'b100]: ; //legal rounding modes
3'b000, 3'b001, 3'b010, 3'b011, 3'b100: ; //legal rounding modes
3'b101: begin // Alternative Half-Precsision encded as fmt=10 and rm=101
if (~C_XF16ALT || fpu_dst_fmt_o != cv32e40p_fpu_pkg::FP16ALT) illegal_insn_o = 1'b1;
// actual rounding mode from frm csr
unique case (frm_i) inside
[3'b000:3'b100] : fp_rnd_mode_o = frm_i; //legal rounding modes
3'b000, 3'b001, 3'b010, 3'b011, 3'b100 : fp_rnd_mode_o = frm_i; //legal rounding modes
default : illegal_insn_o = 1'b1;
endcase
end
3'b111: begin
// rounding mode from frm csr
unique case (frm_i) inside
[3'b000:3'b100] : fp_rnd_mode_o = frm_i; //legal rounding modes
3'b000, 3'b001, 3'b010, 3'b011, 3'b100 : fp_rnd_mode_o = frm_i; //legal rounding modes
default : illegal_insn_o = 1'b1;
endcase
end
Expand All @@ -1493,6 +1485,7 @@ module cv32e40p_decoder

// Set FPnew OP and OPMOD as the APU op
apu_op_o = {fpu_vec_op, fpu_op_mod, fpu_op};

// No FPU or (ZFINX == 0 && MSTATUS.FS == FS_OFF)
end else begin
illegal_insn_o = 1'b1;
Expand Down Expand Up @@ -2264,6 +2257,11 @@ module cv32e40p_decoder
instr_rdata_i[25] != 1'b0) begin
illegal_insn_o = 1'b1;
end
// Imm6 restrictions
if ((instr_rdata_i[14:12] == 3'b110 && instr_rdata_i[24:23] != 2'b0) ||
(instr_rdata_i[14:12] == 3'b111 && instr_rdata_i[24:22] != 3'b0)) begin
illegal_insn_o = 1'b1;
end
end
6'b01001_0: begin // cv.sra
alu_operator_o = ALU_SRA;
Expand All @@ -2275,6 +2273,11 @@ module cv32e40p_decoder
instr_rdata_i[25] != 1'b0) begin
illegal_insn_o = 1'b1;
end
// Imm6 restrictions
if ((instr_rdata_i[14:12] == 3'b110 && instr_rdata_i[24:23] != 2'b0) ||
(instr_rdata_i[14:12] == 3'b111 && instr_rdata_i[24:22] != 3'b0)) begin
illegal_insn_o = 1'b1;
end
end
6'b01010_0: begin // cv.sll
alu_operator_o = ALU_SLL;
Expand All @@ -2286,6 +2289,11 @@ module cv32e40p_decoder
instr_rdata_i[25] != 1'b0) begin
illegal_insn_o = 1'b1;
end
// Imm6 restrictions
if ((instr_rdata_i[14:12] == 3'b110 && instr_rdata_i[24:23] != 2'b0) ||
(instr_rdata_i[14:12] == 3'b111 && instr_rdata_i[24:22] != 3'b0)) begin
illegal_insn_o = 1'b1;
end
end
6'b01011_0: begin // cv.or
alu_operator_o = ALU_OR;
Expand Down Expand Up @@ -2422,6 +2430,11 @@ module cv32e40p_decoder
end
default: illegal_insn_o = 1'b1;
endcase
// Imm6 restrictions
if ((instr_rdata_i[12] == 1'b0 && instr_rdata_i[24:20] != 5'b0) ||
(instr_rdata_i[12] == 1'b1 && instr_rdata_i[24:21] != 4'b0)) begin
illegal_insn_o = 1'b1;
end
end
6'b11000_0: begin // cv.shuffle, cv.shuffleI0
alu_operator_o = ALU_SHUF;
Expand All @@ -2436,6 +2449,10 @@ module cv32e40p_decoder
instr_rdata_i[25] != 1'b0) begin
illegal_insn_o = 1'b1;
end
// Imm6 restriction
if (instr_rdata_i[14:12] == 3'b110 && instr_rdata_i[24:21] != 4'b0) begin
illegal_insn_o = 1'b1;
end
end
6'b11001_0,
6'b11010_0,
Expand Down

0 comments on commit cdd6955

Please sign in to comment.