diff --git a/context-dependent-environments b/context-dependent-environments index dc0537b4..ae2ca70b 160000 --- a/context-dependent-environments +++ b/context-dependent-environments @@ -1 +1 @@ -Subproject commit dc0537b4a3c486d10cad6d0cf33547aef8bfbbbb +Subproject commit ae2ca70b4c50ad34751c9aa732ac404e61508f5e diff --git a/coreplex/src/main/scala/Configs.scala b/coreplex/src/main/scala/Configs.scala index 67a9e5c7..32c32134 100644 --- a/coreplex/src/main/scala/Configs.scala +++ b/coreplex/src/main/scala/Configs.scala @@ -79,6 +79,18 @@ class BaseCoreplexConfig extends Config ( case NUncachedTileLinkPorts => 1 //Tile Constants case BuildTiles => { + val env = if(site(UseVM)) List("p","v") else List("p") + site(FPUKey) foreach { case cfg => + TestGeneration.addSuite(rv32udBenchmarks) + TestGeneration.addSuites(env.map(rv64ufNoDiv)) + TestGeneration.addSuites(env.map(rv64udNoDiv)) + if (cfg.divSqrt) { + TestGeneration.addSuites(env.map(rv64uf)) + TestGeneration.addSuites(env.map(rv64ud)) + } + } + if (site(UseAtomics)) TestGeneration.addSuites(env.map(if (site(XLen) == 64) rv64ua else rv32ua)) + if (site(UseCompressed)) TestGeneration.addSuites(env.map(if (site(XLen) == 64) rv64uc else rv32uc)) val (rvi, rvu) = if (site(XLen) == 64) ((if (site(UseVM)) rv64i else rv64pi), rv64u) else ((if (site(UseVM)) rv32i else rv32pi), rv32u) @@ -105,36 +117,13 @@ class BaseCoreplexConfig extends Config ( case NBreakpoints => 1 case FastLoadWord => true case FastLoadByte => false - case MulUnroll => 8 - case DivEarlyOut => true case XLen => 64 - case UseFPU => { - val env = if(site(UseVM)) List("p","v") else List("p") - TestGeneration.addSuite(rv32udBenchmarks) - if(site(FDivSqrt)) { - TestGeneration.addSuites(env.map(rv64uf)) - TestGeneration.addSuites(env.map(rv64ud)) - } else { - TestGeneration.addSuites(env.map(rv64ufNoDiv)) - TestGeneration.addSuites(env.map(rv64udNoDiv)) - } - true - } - case UseAtomics => { - val env = if(site(UseVM)) List("p","v") else List("p") - TestGeneration.addSuites(env.map(if (site(XLen) == 64) rv64ua else rv32ua)) - true - } - case UseCompressed => { - val env = if(site(UseVM)) List("p","v") else List("p") - TestGeneration.addSuites(env.map(if (site(XLen) == 64) rv64uc else rv32uc)) - true - } + case FPUKey => Some(FPUConfig()) + case MulDivKey => Some(MulDivConfig()) + case UseAtomics => true + case UseCompressed => true case PLICKey => PLICConfig(site(NTiles), site(UseVM), site(NExtInterrupts), 0) case DMKey => new DefaultDebugModuleConfig(site(NTiles), site(XLen)) - case FDivSqrt => true - case SFMALatency => 2 - case DFMALatency => 3 case NCustomMRWCSRs => 0 case ResetVector => BigInt(0x1000) case MtvecInit => BigInt(0x1010) @@ -336,7 +325,7 @@ class WithRV32 extends Config( case UseVM => false case UseUser => false case UseAtomics => false - case UseFPU => false + case FPUKey => None case RegressionTestNames => LinkedHashSet( "rv32mi-p-ma_addr", "rv32mi-p-csr", @@ -357,9 +346,7 @@ class WithBlockingL1 extends Config ( class WithSmallCores extends Config ( topDefinitions = { (pname,site,here) => pname match { - case UseFPU => false - case MulUnroll => 1 - case DivEarlyOut => false + case FPUKey => None case NTLBEntries => 4 case BtbKey => BtbParameters(nEntries = 0) case StoreDataQueueDepth => 2 diff --git a/coreplex/src/main/scala/TestConfigs.scala b/coreplex/src/main/scala/TestConfigs.scala index 24ce9c8a..4ae403bf 100644 --- a/coreplex/src/main/scala/TestConfigs.scala +++ b/coreplex/src/main/scala/TestConfigs.scala @@ -29,7 +29,7 @@ class WithComparator extends Config( operations = 1000, atomics = site(UseAtomics), prefetches = site("COMPARATOR_PREFETCHES")) - case UseFPU => false + case FPUConfig => None case UseAtomics => false case "COMPARATOR_PREFETCHES" => false case _ => throw new CDEMatchError @@ -193,7 +193,7 @@ class WithDirectComparator extends Config( operations = 1000, atomics = site(UseAtomics), prefetches = site("COMPARATOR_PREFETCHES")) - case UseFPU => false + case FPUConfig => None case UseAtomics => false case "COMPARATOR_PREFETCHES" => false case _ => throw new CDEMatchError diff --git a/firrtl b/firrtl index 5db4abeb..197760a9 160000 --- a/firrtl +++ b/firrtl @@ -1 +1 @@ -Subproject commit 5db4abebb7ceb5939a9efca158d78e3dc0e32c44 +Subproject commit 197760a962633d0e6140bcff16b96cc3d6b4e776 diff --git a/rocket/src/main/scala/fpu.scala b/rocket/src/main/scala/fpu.scala index a3ebcc39..c2b771ca 100644 --- a/rocket/src/main/scala/fpu.scala +++ b/rocket/src/main/scala/fpu.scala @@ -10,8 +10,11 @@ import uncore.constants.MemoryOpConstants._ import uncore.util._ import cde.{Parameters, Field} -case object SFMALatency extends Field[Int] -case object DFMALatency extends Field[Int] +case class FPUConfig( + divSqrt: Boolean = true, + sfmaLatency: Int = 2, + dfmaLatency: Int = 3 +) object FPConstants { @@ -414,7 +417,7 @@ class FPUFMAPipe(val latency: Int, expWidth: Int, sigWidth: Int) extends Module io.out := Pipe(valid, res, latency-1) } -class FPU(implicit p: Parameters) extends CoreModule()(p) { +class FPU(cfg: FPUConfig)(implicit p: Parameters) extends CoreModule()(p) { require(xLen == 64, "RV32 Rocket FP support missing") val io = new FPUIO @@ -489,11 +492,11 @@ class FPU(implicit p: Parameters) extends CoreModule()(p) { req.in3 := Mux(ex_reg_valid, ex_rs3, cp_rs3) req.typ := Mux(ex_reg_valid, ex_reg_inst(21,20), io.cp_req.bits.typ) - val sfma = Module(new FPUFMAPipe(p(SFMALatency), 8, 24)) + val sfma = Module(new FPUFMAPipe(cfg.sfmaLatency, 8, 24)) sfma.io.in.valid := req_valid && ex_ctrl.fma && ex_ctrl.single sfma.io.in.bits := req - val dfma = Module(new FPUFMAPipe(p(DFMALatency), 11, 53)) + val dfma = Module(new FPUFMAPipe(cfg.dfmaLatency, 11, 53)) dfma.io.in.valid := req_valid && ex_ctrl.fma && !ex_ctrl.single dfma.io.in.bits := req @@ -610,7 +613,7 @@ class FPU(implicit p: Parameters) extends CoreModule()(p) { divSqrt_wdata := 0 divSqrt_flags := 0 - if (p(FDivSqrt)) { + if (cfg.divSqrt) { val divSqrt_single = Reg(Bool()) val divSqrt_rm = Reg(Bits()) val divSqrt_flags_double = Reg(Bits()) @@ -645,5 +648,7 @@ class FPU(implicit p: Parameters) extends CoreModule()(p) { divSqrt_toSingle.io.roundingMode := divSqrt_rm divSqrt_wdata := Mux(divSqrt_single, divSqrt_toSingle.io.out, divSqrt_wdata_double) divSqrt_flags := divSqrt_flags_double | Mux(divSqrt_single, divSqrt_toSingle.io.exceptionFlags, Bits(0)) + } else { + when (ex_ctrl.div || ex_ctrl.sqrt) { io.illegal_rm := true } } } diff --git a/rocket/src/main/scala/idecode.scala b/rocket/src/main/scala/idecode.scala index 14ac3553..12fc4b94 100644 --- a/rocket/src/main/scala/idecode.scala +++ b/rocket/src/main/scala/idecode.scala @@ -277,12 +277,7 @@ class F64Decode(implicit val p: Parameters) extends DecodeConstants FCVT_S_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), FCVT_D_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), FCVT_S_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), - FCVT_D_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N)) -} - -class FDivSqrtDecode(implicit val p: Parameters) extends DecodeConstants -{ - val table: Array[(BitPat, List[BitPat])] = Array( + FCVT_D_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,Y,N,N,CSR.N,N,N,N), FDIV_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), FDIV_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), FSQRT_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N), diff --git a/rocket/src/main/scala/multiplier.scala b/rocket/src/main/scala/multiplier.scala index e3d1c4ac..119ee3f9 100644 --- a/rocket/src/main/scala/multiplier.scala +++ b/rocket/src/main/scala/multiplier.scala @@ -27,14 +27,16 @@ class MultiplierIO(dataBits: Int, tagBits: Int) extends Bundle { val resp = Decoupled(new MultiplierResp(dataBits, tagBits)) } -class MulDiv( - width: Int, - nXpr: Int = 32, - unroll: Int = 1, - earlyOut: Boolean = false) extends Module { +case class MulDivConfig( + mulUnroll: Int = 1, + mulEarlyOut: Boolean = false, + divEarlyOut: Boolean = false +) + +class MulDiv(cfg: MulDivConfig, width: Int, nXpr: Int = 32) extends Module { val io = new MultiplierIO(width, log2Up(nXpr)) val w = io.req.bits.in1.getWidth - val mulw = (w+unroll-1)/unroll*unroll + val mulw = (w + cfg.mulUnroll - 1) / cfg.mulUnroll * cfg.mulUnroll val s_ready :: s_neg_inputs :: s_busy :: s_move_rem :: s_neg_output :: s_done :: Nil = Enum(UInt(), 6) val state = Reg(init=s_ready) @@ -96,18 +98,18 @@ class MulDiv( val mplier = mulReg(mulw-1,0) val accum = mulReg(2*mulw,mulw).asSInt val mpcand = divisor.asSInt - val prod = mplier(unroll-1,0) * mpcand + accum - val nextMulReg = Cat(prod, mplier(mulw-1,unroll)) + val prod = mplier(cfg.mulUnroll-1, 0) * mpcand + accum + val nextMulReg = Cat(prod, mplier(mulw-1, cfg.mulUnroll)) - val eOutMask = (SInt(BigInt(-1) << mulw) >> (count * unroll)(log2Up(mulw)-1,0))(mulw-1,0) - val eOut = Bool(earlyOut) && count =/= mulw/unroll-1 && count =/= 0 && + val eOutMask = (SInt(BigInt(-1) << mulw) >> (count * cfg.mulUnroll)(log2Up(mulw)-1,0))(mulw-1,0) + val eOut = Bool(cfg.mulEarlyOut) && count =/= mulw/cfg.mulUnroll-1 && count =/= 0 && !isHi && (mplier & ~eOutMask) === UInt(0) - val eOutRes = (mulReg >> (mulw - count * unroll)(log2Up(mulw)-1,0)) + val eOutRes = (mulReg >> (mulw - count * cfg.mulUnroll)(log2Up(mulw)-1,0)) val nextMulReg1 = Cat(nextMulReg(2*mulw,mulw), Mux(eOut, eOutRes, nextMulReg)(mulw-1,0)) remainder := Cat(nextMulReg1 >> w, Bool(false), nextMulReg1(w-1,0)) count := count + 1 - when (eOut || count === mulw/unroll-1) { + when (eOut || count === mulw/cfg.mulUnroll-1) { state := Mux(isHi, s_move_rem, s_done) } } @@ -124,7 +126,7 @@ class MulDiv( val eOutPos = UInt(w-1) + divisorMSB - dividendMSB val eOutZero = divisorMSB > dividendMSB val eOut = count === 0 && less /* not divby0 */ && (eOutPos > 0 || eOutZero) - when (Bool(earlyOut) && eOut) { + when (Bool(cfg.divEarlyOut) && eOut) { val shift = Mux(eOutZero, UInt(w-1), eOutPos(log2Up(w)-1,0)) remainder := remainder(w-1,0) << shift count := shift diff --git a/rocket/src/main/scala/rocket.scala b/rocket/src/main/scala/rocket.scala index 021f6cfa..bf59ad14 100644 --- a/rocket/src/main/scala/rocket.scala +++ b/rocket/src/main/scala/rocket.scala @@ -10,11 +10,11 @@ import uncore.constants._ import Util._ import cde.{Parameters, Field} -case object UseFPU extends Field[Boolean] -case object FDivSqrt extends Field[Boolean] case object XLen extends Field[Int] case object FetchWidth extends Field[Int] case object RetireWidth extends Field[Int] +case object FPUKey extends Field[Option[FPUConfig]] +case object MulDivKey extends Field[Option[MulDivConfig]] case object UseVM extends Field[Boolean] case object UseUser extends Field[Boolean] case object UseDebug extends Field[Boolean] @@ -22,8 +22,6 @@ case object UseAtomics extends Field[Boolean] case object UseCompressed extends Field[Boolean] case object FastLoadWord extends Field[Boolean] case object FastLoadByte extends Field[Boolean] -case object MulUnroll extends Field[Int] -case object DivEarlyOut extends Field[Boolean] case object CoreInstBits extends Field[Int] case object NCustomMRWCSRs extends Field[Int] case object MtvecWritable extends Field[Boolean] @@ -38,13 +36,11 @@ trait HasCoreParameters extends HasAddrMapParameters { val usingVM = p(UseVM) val usingUser = p(UseUser) || usingVM val usingDebug = p(UseDebug) - val usingFPU = p(UseFPU) + val usingMulDiv = p(MulDivKey).nonEmpty + val usingFPU = p(FPUKey).nonEmpty val usingAtomics = p(UseAtomics) val usingCompressed = p(UseCompressed) - val usingFDivSqrt = p(FDivSqrt) val usingRoCC = !p(BuildRoCC).isEmpty - val mulUnroll = p(MulUnroll) - val divEarlyOut = p(DivEarlyOut) val fastLoadWord = p(FastLoadWord) val fastLoadByte = p(FastLoadByte) @@ -144,10 +140,9 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) { } val decode_table = { - (if (true) new MDecode +: (if (xLen > 32) Seq(new M64Decode) else Nil) else Nil) ++: + (if (usingMulDiv) new MDecode +: (if (xLen > 32) Seq(new M64Decode) else Nil) else Nil) ++: (if (usingAtomics) new ADecode +: (if (xLen > 32) Seq(new A64Decode) else Nil) else Nil) ++: (if (usingFPU) new FDecode +: (if (xLen > 32) Seq(new F64Decode) else Nil) else Nil) ++: - (if (usingFPU && usingFDivSqrt) Some(new FDivSqrtDecode) else None) ++: (if (usingRoCC) Some(new RoCCDecode) else None) ++: (if (xLen > 32) Some(new I64Decode) else None) ++: (if (usingVM) Some(new SDecode) else None) ++: @@ -302,10 +297,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) { alu.io.in1 := ex_op1.asUInt // multiplier and divider - val div = Module(new MulDiv(width = xLen, - unroll = mulUnroll, - earlyOut = divEarlyOut)) - + val div = Module(new MulDiv(p(MulDivKey).getOrElse(MulDivConfig()), width = xLen)) div.io.req.valid := ex_reg_valid && ex_ctrl.div div.io.req.bits.dw := ex_ctrl.alu_dw div.io.req.bits.fn := ex_ctrl.alu_fn diff --git a/rocket/src/main/scala/tile.scala b/rocket/src/main/scala/tile.scala index 322a36c0..3605630d 100644 --- a/rocket/src/main/scala/tile.scala +++ b/rocket/src/main/scala/tile.scala @@ -56,7 +56,7 @@ class RocketTile(clockSignal: Clock = null, resetSignal: Bool = null) core.io.prci <> io.prci icache.io.cpu <> core.io.imem - val fpuOpt = if (p(UseFPU)) Some(Module(new FPU)) else None + val fpuOpt = p(FPUKey).map(cfg => Module(new FPU(cfg))) fpuOpt.foreach(fpu => core.io.fpu <> fpu.io) if (usingRocc) { @@ -127,7 +127,7 @@ class RocketTile(clockSignal: Clock = null, resetSignal: Bool = null) dcArb.io.requestor <> dcPorts dcache.cpu <> dcArb.io.mem - if (!usingRocc || nFPUPorts == 0) { + if (nFPUPorts == 0) { fpuOpt.foreach { fpu => fpu.io.cp_req.valid := Bool(false) fpu.io.cp_resp.ready := Bool(false) diff --git a/src/main/scala/Configs.scala b/src/main/scala/Configs.scala index ac7b621f..9b425b1a 100644 --- a/src/main/scala/Configs.scala +++ b/src/main/scala/Configs.scala @@ -69,7 +69,7 @@ class BasePlatformConfig extends Config ( res append "};\n" res append "core {\n" for (i <- 0 until site(NTiles)) { - val isa = s"rv${site(XLen)}im${if (site(UseAtomics)) "a" else ""}${if (site(UseFPU)) "fd" else ""}" + val isa = s"rv${site(XLen)}im${if (site(UseAtomics)) "a" else ""}${if (site(FPUKey).nonEmpty) "fd" else ""}" res append s" $i {\n" res append " 0 {\n" res append s" isa $isa;\n" diff --git a/src/main/scala/TestConfigs.scala b/src/main/scala/TestConfigs.scala index 06b3b18b..dfc3c061 100644 --- a/src/main/scala/TestConfigs.scala +++ b/src/main/scala/TestConfigs.scala @@ -30,7 +30,7 @@ class WithUnitTest extends Config( case UnitTests => (testParams: Parameters) => JunctionsUnitTests(testParams) ++ UncoreUnitTests(testParams) case NMemoryChannels => Dump("N_MEM_CHANNELS", 0) - case UseFPU => false + case FPUKey => None case UseAtomics => false case UseCompressed => false case RegressionTestNames => LinkedHashSet("rv64ui-p-simple") @@ -78,7 +78,7 @@ class WithGroundTest extends Config( } } } - case UseFPU => false + case FPUKey => None case UseAtomics => false case UseCompressed => false case RegressionTestNames => LinkedHashSet("rv64ui-p-simple") @@ -199,6 +199,7 @@ class WithBusMasterTest extends Config( } Seq(new BusMasterDevice) } + case _ => throw new CDEMatchError }) class BusMasterTestConfig extends Config(new WithBusMasterTest ++ new GroundTestConfig)