diff --git a/rtl/cv32e40p_decoder.sv b/rtl/cv32e40p_decoder.sv index 7d7fb676b..c1608eb4a 100644 --- a/rtl/cv32e40p_decoder.sv +++ b/rtl/cv32e40p_decoder.sv @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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; @@ -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 @@ -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 @@ -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 @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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,