diff --git a/CHANGELOG.md b/CHANGELOG.md index 542eb153d..bfd2eea05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Force cheshire's sim scripts re-generation - Fix u-boot to support RVV-linux - Fixed src emul check for vector integer extension operation + - Fix false illegal-instruction on a widening reduction (vwredsum/vwredsumu) with an unaligned vd ### Added diff --git a/hardware/src/ara_dispatcher.sv b/hardware/src/ara_dispatcher.sv index e5f9e06d5..355e5504d 100644 --- a/hardware/src/ara_dispatcher.sv +++ b/hardware/src/ara_dispatcher.sv @@ -931,18 +931,27 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( // Instructions with an integer LMUL have extra constraints on the registers they can // access. - unique case (ara_req.emul) - LMUL_2: if ((insn.varith_type.rs1 & 5'b00001) != 5'b00000 || - (insn.varith_type.rs2 & 5'b00001) != 5'b00000 || - (insn.varith_type.rd & 5'b00001) != 5'b00000) illegal_insn = 1'b1; - LMUL_4: if ((insn.varith_type.rs1 & 5'b00011) != 5'b00000 || - (insn.varith_type.rs2 & 5'b00011) != 5'b00000 || - (insn.varith_type.rd & 5'b00011) != 5'b00000) illegal_insn = 1'b1; - LMUL_8: if ((insn.varith_type.rs1 & 5'b00111) != 5'b00000 || - (insn.varith_type.rs2 & 5'b00111) != 5'b00000 || - (insn.varith_type.rd & 5'b00111) != 5'b00000) illegal_insn = 1'b1; - default:; - endcase + if (ara_req.op inside {VWREDSUMU, VWREDSUM}) begin + unique case (csr_vtype_q.vlmul) + LMUL_2: if ((insn.varith_type.rs2 & 5'b00001) != 5'b00000) illegal_insn = 1'b1; + LMUL_4: if ((insn.varith_type.rs2 & 5'b00011) != 5'b00000) illegal_insn = 1'b1; + LMUL_8: if ((insn.varith_type.rs2 & 5'b00111) != 5'b00000) illegal_insn = 1'b1; + default:; + endcase + end else begin + unique case (ara_req.emul) + LMUL_2: if ((insn.varith_type.rs1 & 5'b00001) != 5'b00000 || + (insn.varith_type.rs2 & 5'b00001) != 5'b00000 || + (insn.varith_type.rd & 5'b00001) != 5'b00000) illegal_insn = 1'b1; + LMUL_4: if ((insn.varith_type.rs1 & 5'b00011) != 5'b00000 || + (insn.varith_type.rs2 & 5'b00011) != 5'b00000 || + (insn.varith_type.rd & 5'b00011) != 5'b00000) illegal_insn = 1'b1; + LMUL_8: if ((insn.varith_type.rs1 & 5'b00111) != 5'b00000 || + (insn.varith_type.rs2 & 5'b00111) != 5'b00000 || + (insn.varith_type.rd & 5'b00111) != 5'b00000) illegal_insn = 1'b1; + default:; + endcase + end // Instruction is invalid if the vtype is invalid if (csr_vtype_q.vill) illegal_insn = 1'b1;