From 96580e38abc2b438639fb29ab262a0afc086b0c8 Mon Sep 17 00:00:00 2001 From: nananapo Date: Mon, 10 Jul 2023 14:54:57 +0900 Subject: [PATCH 1/5] Create divEnabled parameter in MulDivParams Signed-off-by: kanataso --- src/main/scala/rocket/Multiplier.scala | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/scala/rocket/Multiplier.scala b/src/main/scala/rocket/Multiplier.scala index fd571024d63..12bbd1bdbe2 100644 --- a/src/main/scala/rocket/Multiplier.scala +++ b/src/main/scala/rocket/Multiplier.scala @@ -29,6 +29,7 @@ class MultiplierIO(val dataBits: Int, val tagBits: Int, aluFn: ALUFN = new ALUFN case class MulDivParams( mulUnroll: Int = 1, divUnroll: Int = 1, + divEnabled: Boolean = true, mulEarlyOut: Boolean = false, divEarlyOut: Boolean = false, divEarlyOutGranularity: Int = 1 @@ -49,7 +50,7 @@ class MulDiv(cfg: MulDivParams, width: Int, nXpr: Int = 32, aluFn: ALUFN = new A val req = Reg(chiselTypeOf(io.req.bits)) val count = Reg(UInt(log2Ceil( - ((cfg.divUnroll != 0).option(w/cfg.divUnroll + 1).toSeq ++ + ((cfg.divEnabled && cfg.divUnroll != 0).option(w/cfg.divUnroll + 1).toSeq ++ (cfg.mulUnroll != 0).option(mulw/cfg.mulUnroll)).reduce(_ max _)).W)) val neg_out = Reg(Bool()) val isHi = Reg(Bool()) @@ -69,7 +70,7 @@ class MulDiv(cfg: MulDivParams, width: Int, nXpr: Int = 32, aluFn: ALUFN = new A aluFn.FN_REMU -> List(N, Y, N, N)) val cmdMul :: cmdHi :: lhsSigned :: rhsSigned :: Nil = DecodeLogic(io.req.bits.fn, List(X, X, X, X), - (if (cfg.divUnroll != 0) divDecode else Nil) ++ (if (cfg.mulUnroll != 0) mulDecode else Nil)).map(_.asBool) + (if (cfg.divEnabled && cfg.divUnroll != 0) divDecode else Nil) ++ (if (cfg.mulUnroll != 0) mulDecode else Nil)).map(_.asBool) require(w == 32 || w == 64) def halfWidth(req: MultiplierReq) = (w > 32).B && req.dw === DW_32 @@ -86,7 +87,7 @@ class MulDiv(cfg: MulDivParams, width: Int, nXpr: Int = 32, aluFn: ALUFN = new A val result = Mux(resHi, remainder(2*w, w+1), remainder(w-1, 0)) val negated_remainder = -result - if (cfg.divUnroll != 0) when (state === s_neg_inputs) { + if (cfg.divEnabled && cfg.divUnroll != 0) when (state === s_neg_inputs) { when (remainder(w-1)) { remainder := negated_remainder } @@ -95,7 +96,7 @@ class MulDiv(cfg: MulDivParams, width: Int, nXpr: Int = 32, aluFn: ALUFN = new A } state := s_div } - if (cfg.divUnroll != 0) when (state === s_neg_output) { + if (cfg.divEnabled && cfg.divUnroll != 0) when (state === s_neg_output) { remainder := negated_remainder state := s_done_div resHi := false.B @@ -123,7 +124,7 @@ class MulDiv(cfg: MulDivParams, width: Int, nXpr: Int = 32, aluFn: ALUFN = new A resHi := isHi } } - if (cfg.divUnroll != 0) when (state === s_div) { + if (cfg.divEnabled && cfg.divUnroll != 0) when (state === s_div) { val unrolls = ((0 until cfg.divUnroll) scanLeft remainder) { case (rem, i) => // the special case for iteration 0 is to save HW, not for correctness val difference = if (i == 0) subtractor else rem(2*w,w) - divisor(w-1,0) From e3e587decdc4a139820fafa10d4ee48c68c429d5 Mon Sep 17 00:00:00 2001 From: nananapo Date: Mon, 10 Jul 2023 14:58:01 +0900 Subject: [PATCH 2/5] Split MDecode into MMulDecode and MDivDecode Signed-off-by: kanataso --- src/main/scala/rocket/IDecode.scala | 17 +++++++++++++---- src/main/scala/rocket/RocketCore.scala | 3 ++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/main/scala/rocket/IDecode.scala b/src/main/scala/rocket/IDecode.scala index d75be986481..3b1bfa4e6d4 100644 --- a/src/main/scala/rocket/IDecode.scala +++ b/src/main/scala/rocket/IDecode.scala @@ -244,29 +244,38 @@ class Hypervisor64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) ext HLV_WU-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N)) } -class MDecode(pipelinedMul: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants +class MMulDecode(pipelinedMul: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val M = if (pipelinedMul) Y else N val D = if (pipelinedMul) N else Y + val table: Array[(BitPat, List[BitPat])] = Array( MUL-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MUL, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), MULH-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULH, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), MULHU-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULHU, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), - MULHSU-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULHSU,N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), + MULHSU-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULHSU,N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N)) +} +class MDivDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants +{ + val table: Array[(BitPat, List[BitPat])] = Array( DIV-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_DIV, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), DIVU-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_DIVU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), REM-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_REM, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), REMU-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_REMU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N)) } -class M64Decode(pipelinedMul: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants +class MMul64Decode(pipelinedMul: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val M = if (pipelinedMul) Y else N val D = if (pipelinedMul) N else Y val table: Array[(BitPat, List[BitPat])] = Array( - MULW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_MUL, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), + MULW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_MUL, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N)) +} +class MDiv64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants +{ + val table: Array[(BitPat, List[BitPat])] = Array( DIVW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_DIV, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), DIVUW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_DIVU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), REMW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_REM, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index f07fdb75baa..a7e0374521c 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -185,7 +185,8 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val pipelinedMul = usingMulDiv && mulDivParams.mulUnroll == xLen val decode_table = { require(!usingRoCC || !rocketParams.useSCIE) - (if (usingMulDiv) new MDecode(pipelinedMul, aluFn) +: (xLen > 32).option(new M64Decode(pipelinedMul, aluFn)).toSeq else Nil) ++: + (if (usingMulDiv) new MMulDecode(pipelinedMul, aluFn) +: (xLen > 32).option(new MMul64Decode(pipelinedMul, aluFn)).toSeq else Nil) ++: + (if (usingMulDiv && mulDivParams.divEnabled) new MDivDecode(aluFn) +: (xLen > 32).option(new MDiv64Decode(aluFn)).toSeq else Nil) ++: (if (usingAtomics) new ADecode(aluFn) +: (xLen > 32).option(new A64Decode(aluFn)).toSeq else Nil) ++: (if (fLen >= 32) new FDecode(aluFn) +: (xLen > 32).option(new F64Decode(aluFn)).toSeq else Nil) ++: (if (fLen >= 64) new DDecode(aluFn) +: (xLen > 32).option(new D64Decode(aluFn)).toSeq else Nil) ++: From cb57d2da63366ad94db6bbe6ce19ea7ce7bc00ff Mon Sep 17 00:00:00 2001 From: nananapo Date: Mon, 10 Jul 2023 14:59:08 +0900 Subject: [PATCH 3/5] Add ISA extension when Zmmul Signed-off-by: kanataso --- src/main/scala/rocket/CSR.scala | 2 +- src/main/scala/tile/BaseTile.scala | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 89aae1b89e2..44645f81fab 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -613,7 +613,7 @@ class CSRFile( io.pmp := reg_pmp.map(PMP(_)) val isaMaskString = - (if (usingMulDiv) "M" else "") + + (if (usingMulDiv && coreParams.mulDiv.get.divEnabled) "M" else "") + (if (usingAtomics) "A" else "") + (if (fLen >= 32) "F" else "") + (if (fLen >= 64) "D" else "") + diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index 1265cb622bb..367b280ad59 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -98,7 +98,7 @@ trait HasNonDiplomaticTileParameters { // TODO merge with isaString in CSR.scala def isaDTS: String = { val ie = if (tileParams.core.useRVE) "e" else "i" - val m = if (tileParams.core.mulDiv.nonEmpty) "m" else "" + val m = if (tileParams.core.mulDiv.nonEmpty && tileParams.core.mulDiv.get.divEnabled) "m" else "" val a = if (tileParams.core.useAtomics) "a" else "" val f = if (tileParams.core.fpu.nonEmpty) "f" else "" val d = if (tileParams.core.fpu.nonEmpty && tileParams.core.fpu.get.fLen > 32) "d" else "" @@ -112,6 +112,7 @@ trait HasNonDiplomaticTileParameters { //Some(Seq("zicntr")) ++ Option.when(tileParams.core.useConditionalZero)(Seq("zicond")) ++ Some(Seq("zicsr", "zifencei", "zihpm")) ++ + Option.when(tileParams.core.mulDiv.nonEmpty)(Seq("zmmul")) ++ Option.when(tileParams.core.fpu.nonEmpty && tileParams.core.fpu.get.fLen >= 16 && tileParams.core.fpu.get.minFLen <= 16)(Seq("zfh")) ++ Option.when(tileParams.core.useBitManip)(Seq("zba", "zbb", "zbc")) ++ Option.when(tileParams.core.hasBitManipCrypto)(Seq("zbkb", "zbkc", "zbkx")) ++ From a5b829a3675e7b20a4102f8f4470a18b2d89fe9c Mon Sep 17 00:00:00 2001 From: nananapo Date: Mon, 10 Jul 2023 15:34:37 +0900 Subject: [PATCH 4/5] Add WithoutDiv Config Signed-off-by: kanataso --- src/main/scala/subsystem/Configs.scala | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/scala/subsystem/Configs.scala b/src/main/scala/subsystem/Configs.scala index 860f962a39b..6cf625e0af7 100644 --- a/src/main/scala/subsystem/Configs.scala +++ b/src/main/scala/subsystem/Configs.scala @@ -382,6 +382,15 @@ class WithoutMulDiv extends Config((site, here, up) => { } }) +class WithoutDiv extends Config((site, here, up) => { + case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( + core = tp.tileParams.core.copy( + mulDiv = tp.tileParams.core.mulDiv.map(_.copy(divEnabled = false))))) + case t => t + } +}) + class WithoutFPU extends Config((site, here, up) => { case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( From 7774cd099252a644972a1e5b51b3948303c05b6a Mon Sep 17 00:00:00 2001 From: kanataso Date: Mon, 17 Jul 2023 15:17:53 +0900 Subject: [PATCH 5/5] Change the condition of mul/div illegal instruction trap Signed-off-by: kanataso --- src/main/scala/rocket/RocketCore.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index a7e0374521c..b8486c581a7 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -328,7 +328,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) } val id_illegal_rnum = if (usingCryptoNIST) (id_ctrl.zkn && aluFn.isKs1(id_ctrl.alu_fn) && id_inst(0)(23,20) > 0xA.U(4.W)) else false.B val id_illegal_insn = !id_ctrl.legal || - (id_ctrl.mul || id_ctrl.div) && !csr.io.status.isa('m'-'a') || + id_ctrl.div && !csr.io.status.isa('m'-'a') || id_ctrl.amo && !csr.io.status.isa('a'-'a') || id_ctrl.fp && (csr.io.decode(0).fp_illegal || io.fpu.illegal_rm) || id_ctrl.dp && !csr.io.status.isa('d'-'a') ||