diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index ab6d6fa7..b5840a41 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -165,8 +165,8 @@ class WithRV32 extends Config((site, here, up) => { case XLen => 32 case RocketTilesKey => up(RocketTilesKey, site) map { r => r.copy(core = r.core.copy( - mulDiv = Some(MulDivParams(mulUnroll = 8)), - fpu = r.core.fpu.map(_.copy(divSqrt = false)))) + fpu = r.core.fpu.map(_.copy(fLen = 32)), + mulDiv = Some(MulDivParams(mulUnroll = 8)))) } }) diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index e34ed3be..a44c930e 100644 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -7,7 +7,6 @@ import freechips.rocketchip.config._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.regmapper._ import freechips.rocketchip.rocket.Instructions -import freechips.rocketchip.tile.XLen import freechips.rocketchip.tilelink._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.util._ @@ -424,7 +423,7 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La } } -class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: Parameters) extends LazyModule +class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: Int)(implicit p: Parameters) extends LazyModule { val dmiNode = TLRegisterNode( @@ -438,7 +437,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: val tlNode = TLRegisterNode( address=Seq(AddressSet(0, 0xFFF)), // This is required for correct functionality, it's not configurable. device=device, - beatBytes=p(XLen)/8, + beatBytes=beatBytes, executable=true ) @@ -1029,9 +1028,9 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: // Handles the synchronization of dmactive, which is used as a synchronous reset // inside the Inner block. // Also is the Sink side of hartsel & resumereq fields of DMCONTROL. -class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int)(implicit p: Parameters) extends LazyModule{ +class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int, beatBytes: Int)(implicit p: Parameters) extends LazyModule{ - val dmInner = LazyModule(new TLDebugModuleInner(device, getNComponents)) + val dmInner = LazyModule(new TLDebugModuleInner(device, getNComponents, beatBytes)) val dmiXing = LazyModule(new TLAsyncCrossingSink(depth=1)) val dmiNode = dmiXing.node val tlNode = dmInner.tlNode @@ -1060,14 +1059,14 @@ class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int)(implici * because the Clock must run when tlClock isn't running or tlReset is asserted. */ -class TLDebugModule(implicit p: Parameters) extends LazyModule { +class TLDebugModule(beatBytes: Int)(implicit p: Parameters) extends LazyModule { val device = new SimpleDevice("debug-controller", Seq("sifive,debug-013","riscv,debug-013")){ override val alwaysExtended = true } val dmOuter = LazyModule(new TLDebugModuleOuterAsync(device)(p)) - val dmInner = LazyModule(new TLDebugModuleInnerAsync(device, () => {dmOuter.dmOuter.intnode.edges.out.size})(p)) + val dmInner = LazyModule(new TLDebugModuleInnerAsync(device, () => {dmOuter.dmOuter.intnode.edges.out.size}, beatBytes)(p)) val node = dmInner.tlNode val intnode = dmOuter.intnode diff --git a/src/main/scala/devices/debug/Periphery.scala b/src/main/scala/devices/debug/Periphery.scala index 3cec79e2..2496b15d 100644 --- a/src/main/scala/devices/debug/Periphery.scala +++ b/src/main/scala/devices/debug/Periphery.scala @@ -29,7 +29,7 @@ class DebugIO(implicit val p: Parameters) extends ParameterizedBundle()(p) with trait HasPeripheryDebug extends HasPeripheryBus { val module: HasPeripheryDebugModuleImp - val debug = LazyModule(new TLDebugModule()) + val debug = LazyModule(new TLDebugModule(pbus.beatBytes)) debug.node := pbus.toVariableWidthSlaves } diff --git a/src/main/scala/devices/tilelink/Clint.scala b/src/main/scala/devices/tilelink/Clint.scala index f4281417..75f16ab7 100644 --- a/src/main/scala/devices/tilelink/Clint.scala +++ b/src/main/scala/devices/tilelink/Clint.scala @@ -7,7 +7,6 @@ import freechips.rocketchip.config.{Field, Parameters} import freechips.rocketchip.coreplex.HasPeripheryBus import freechips.rocketchip.diplomacy._ import freechips.rocketchip.regmapper._ -import freechips.rocketchip.tile.XLen import freechips.rocketchip.tilelink._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.util._ @@ -33,7 +32,7 @@ case class ClintParams(baseAddress: BigInt = 0x02000000, intStages: Int = 0) case object ClintKey extends Field(ClintParams()) -class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) extends LazyModule +class CoreplexLocalInterrupter(params: ClintParams, beatBytes: Int)(implicit p: Parameters) extends LazyModule { import ClintConsts._ @@ -45,7 +44,7 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte val node = TLRegisterNode( address = Seq(params.address), device = device, - beatBytes = p(XLen)/8) + beatBytes = beatBytes) val intnode = IntNexusNode( sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(ints, Seq(Resource(device, "int"))))) }, @@ -93,6 +92,6 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte /** Trait that will connect a Clint to a coreplex */ trait HasPeripheryClint extends HasPeripheryBus { - val clint = LazyModule(new CoreplexLocalInterrupter(p(ClintKey))) + val clint = LazyModule(new CoreplexLocalInterrupter(p(ClintKey), pbus.beatBytes)) clint.node := pbus.toVariableWidthSlaves } diff --git a/src/main/scala/devices/tilelink/Plic.scala b/src/main/scala/devices/tilelink/Plic.scala index 9de673d3..c0a0b75b 100644 --- a/src/main/scala/devices/tilelink/Plic.scala +++ b/src/main/scala/devices/tilelink/Plic.scala @@ -8,7 +8,6 @@ import freechips.rocketchip.config.{Field, Parameters} import freechips.rocketchip.coreplex.{HasInterruptBus, HasPeripheryBus} import freechips.rocketchip.diplomacy._ import freechips.rocketchip.regmapper._ -import freechips.rocketchip.tile.XLen import freechips.rocketchip.tilelink._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.util._ @@ -64,7 +63,7 @@ case class PLICParams(baseAddress: BigInt = 0xC000000, maxPriorities: Int = 7, i case object PLICKey extends Field(PLICParams()) /** Platform-Level Interrupt Controller */ -class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule +class TLPLIC(params: PLICParams, beatBytes: Int)(implicit p: Parameters) extends LazyModule { // plic0 => max devices 1023 val device = new SimpleDevice("interrupt-controller", Seq("riscv,plic0")) { @@ -83,7 +82,7 @@ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule val node = TLRegisterNode( address = Seq(params.address), device = device, - beatBytes = p(XLen)/8, + beatBytes = beatBytes, undefZero = true, concurrency = 1) // limiting concurrency handles RAW hazards on claim registers @@ -271,7 +270,7 @@ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule /** Trait that will connect a PLIC to a coreplex */ trait HasPeripheryPLIC extends HasInterruptBus with HasPeripheryBus { - val plic = LazyModule(new TLPLIC(p(PLICKey))) + val plic = LazyModule(new TLPLIC(p(PLICKey), pbus.beatBytes)) plic.node := pbus.toVariableWidthSlaves plic.intnode := ibus.toPLIC } diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 79b56e17..0bf870df 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -333,8 +333,8 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param val isaMaskString = (if (usingMulDiv) "M" else "") + (if (usingAtomics) "A" else "") + - (if (usingFPU) "F" else "") + - (if (usingFPU && xLen > 32) "D" else "") + + (if (fLen >= 32) "F" else "") + + (if (fLen >= 64) "D" else "") + (if (usingCompressed) "C" else "") + (if (usingRoCC) "X" else "") val isaString = "I" + isaMaskString + diff --git a/src/main/scala/rocket/DCache.scala b/src/main/scala/rocket/DCache.scala index 9eea5875..83d1df9c 100644 --- a/src/main/scala/rocket/DCache.scala +++ b/src/main/scala/rocket/DCache.scala @@ -687,7 +687,8 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) { // AMOs if (usingRMW) { - val amoalu = Module(new AMOALU(xLen)) + // when xLen < coreDataBits (e.g. RV32D), this AMOALU is wider than necessary + val amoalu = Module(new AMOALU(coreDataBits)) amoalu.io.mask := pstore1_mask amoalu.io.cmd := (if (usingAtomicsInCache) pstore1_cmd else M_XWR) amoalu.io.lhs := s2_data_word diff --git a/src/main/scala/rocket/HellaCache.scala b/src/main/scala/rocket/HellaCache.scala index 491f74dc..030c2ce5 100644 --- a/src/main/scala/rocket/HellaCache.scala +++ b/src/main/scala/rocket/HellaCache.scala @@ -46,8 +46,8 @@ trait HasL1HellaCacheParameters extends HasL1CacheParameters with HasCoreParamet val cacheParams = tileParams.dcache.get val cfg = cacheParams - def wordBits = xLen // really, xLen max - def wordBytes = wordBits/8 + def wordBits = coreDataBits + def wordBytes = coreDataBytes def wordOffBits = log2Up(wordBytes) def beatBytes = cacheBlockBytes / cacheDataBeats def beatWords = beatBytes / wordBytes diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index 660abe7d..0f3101c0 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -108,8 +108,8 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) val decode_table = { (if (usingMulDiv) new MDecode +: (xLen > 32).option(new M64Decode).toSeq else Nil) ++: (if (usingAtomics) new ADecode +: (xLen > 32).option(new A64Decode).toSeq else Nil) ++: - (if (usingFPU) new FDecode +: (xLen > 32).option(new F64Decode).toSeq else Nil) ++: - (if (usingFPU && xLen > 32) Seq(new DDecode, new D64Decode) else Nil) ++: + (if (fLen >= 32) new FDecode +: (xLen > 32).option(new F64Decode).toSeq else Nil) ++: + (if (fLen >= 64) new DDecode +: (xLen > 32).option(new D64Decode).toSeq else Nil) ++: (usingRoCC.option(new RoCCDecode)) ++: ((xLen > 32).option(new I64Decode)) ++: (usingVM.option(new SDecode)) ++: @@ -250,8 +250,8 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) coverExceptions(id_xcpt, id_cause, "DECODE", idCoverCauses) val dcache_bypass_data = - if (fastLoadByte) io.dmem.resp.bits.data - else if (fastLoadWord) io.dmem.resp.bits.data_word_bypass + if (fastLoadByte) io.dmem.resp.bits.data(xLen-1, 0) + else if (fastLoadWord) io.dmem.resp.bits.data_word_bypass(xLen-1, 0) else wb_reg_wdata // detect bypass opportunities @@ -527,7 +527,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) val wb_wen = wb_valid && wb_ctrl.wxd val rf_wen = wb_wen || ll_wen val rf_waddr = Mux(ll_wen, ll_waddr, wb_waddr) - val rf_wdata = Mux(dmem_resp_valid && dmem_resp_xpu, io.dmem.resp.bits.data, + val rf_wdata = Mux(dmem_resp_valid && dmem_resp_xpu, io.dmem.resp.bits.data(xLen-1, 0), Mux(ll_wen, ll_wdata, Mux(wb_ctrl.csr =/= CSR.N, csr.io.rw.rdata, wb_reg_wdata))) @@ -676,7 +676,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) io.dmem.req.bits.phys := Bool(false) io.dmem.req.bits.addr := encodeVirtualAddress(ex_rs(0), alu.io.adder_out) io.dmem.invalidate_lr := wb_xcpt - io.dmem.s1_data.data := Mux(mem_ctrl.fp, io.fpu.store_data, mem_reg_rs2) + io.dmem.s1_data.data := (if (fLen == 0) mem_reg_rs2 else Mux(mem_ctrl.fp, Fill((xLen max fLen) / fLen, io.fpu.store_data), mem_reg_rs2)) io.dmem.s1_kill := killm_common || mem_breakpoint io.rocc.cmd.valid := wb_reg_valid && wb_ctrl.rocc && !replay_wb_common diff --git a/src/main/scala/system/Generator.scala b/src/main/scala/system/Generator.scala index 5232bb30..db5f69b6 100644 --- a/src/main/scala/system/Generator.scala +++ b/src/main/scala/system/Generator.scala @@ -57,15 +57,14 @@ object Generator extends GeneratorApp { val env = if (vm) List("p","v") else List("p") coreParams.fpu foreach { case cfg => if (xlen == 32) { - TestGeneration.addSuites(env.map(rv32ufNoDiv)) + TestGeneration.addSuites(env.map(rv32uf)) + if (cfg.fLen >= 64) + TestGeneration.addSuites(env.map(rv32ud)) } else { 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(rv64uf)) + if (cfg.fLen >= 64) TestGeneration.addSuites(env.map(rv64ud)) - } } } if (coreParams.useAtomics) { diff --git a/src/main/scala/system/RocketTestSuite.scala b/src/main/scala/system/RocketTestSuite.scala index 4a29356c..71b0acbd 100644 --- a/src/main/scala/system/RocketTestSuite.scala +++ b/src/main/scala/system/RocketTestSuite.scala @@ -143,13 +143,12 @@ object DefaultTestSuites { val rv64ufNames = LinkedHashSet("ldst", "move", "fcmp", "fcvt", "fcvt_w", "fclass", "fadd", "fdiv", "fmin", "fmadd") val rv64uf = new AssemblyTestSuite("rv64uf", rv64ufNames)(_) - val rv64ufNoDiv = new AssemblyTestSuite("rv64uf", rv64ufNames - "fdiv")(_) - val rv32ufNoDiv = new AssemblyTestSuite("rv32uf", rv64ufNames - "fdiv")(_) + val rv32uf = new AssemblyTestSuite("rv32uf", rv64ufNames)(_) + val rv32ud = new AssemblyTestSuite("rv32ud", rv64ufNames - "move")(_) val rv64udNames = rv64ufNames + "structural" val rv64ud = new AssemblyTestSuite("rv64ud", rv64udNames)(_) - val rv64udNoDiv = new AssemblyTestSuite("rv64ud", rv64udNames - "fdiv")(_) val rv64siNames = rv32siNames val rv64si = new AssemblyTestSuite("rv64si", rv64siNames)(_) diff --git a/src/main/scala/tile/Core.scala b/src/main/scala/tile/Core.scala index 12d2a83f..888916a5 100644 --- a/src/main/scala/tile/Core.scala +++ b/src/main/scala/tile/Core.scala @@ -44,7 +44,7 @@ trait CoreParams { trait HasCoreParameters extends HasTileParameters { val coreParams: CoreParams = tileParams.core - val fLen = xLen // TODO relax this + val fLen = coreParams.fpu.map(_.fLen).getOrElse(0) val usingMulDiv = coreParams.mulDiv.nonEmpty val usingFPU = coreParams.fpu.nonEmpty diff --git a/src/main/scala/tile/FPU.scala b/src/main/scala/tile/FPU.scala index 17bd316b..3584c9ac 100644 --- a/src/main/scala/tile/FPU.scala +++ b/src/main/scala/tile/FPU.scala @@ -14,6 +14,7 @@ import freechips.rocketchip.util.property._ import chisel3.internal.sourceinfo.SourceInfo case class FPUParams( + fLen: Int = 64, divSqrt: Boolean = true, sfmaLatency: Int = 3, dfmaLatency: Int = 4 @@ -168,6 +169,12 @@ class FPResult(implicit p: Parameters) extends CoreBundle()(p) { val exc = Bits(width = FPConstants.FLAGS_SZ) } +class IntToFPInput(implicit p: Parameters) extends CoreBundle()(p) with HasFPUCtrlSigs { + val rm = Bits(width = FPConstants.RM_SZ) + val typ = Bits(width = 2) + val in1 = Bits(width = xLen) +} + class FPInput(implicit p: Parameters) extends CoreBundle()(p) with HasFPUCtrlSigs { val rm = Bits(width = FPConstants.RM_SZ) val fmaCmd = Bits(width = 2) @@ -233,6 +240,7 @@ object FType { } trait HasFPUParameters { + require(fLen == 32 || fLen == 64) val fLen: Int def xLen: Int val minXLen = 32 @@ -390,7 +398,7 @@ class FPToInt(implicit p: Parameters) extends FPUModule()(p) { val store = ieee(in.in1) val toint = Wire(init = store) val intType = Wire(init = tag) - io.out.bits.store := ((0 until nIntTypes).map(i => Fill(1 << (nIntTypes - i - 1), store((minXLen << i) - 1, 0))): Seq[UInt])(tag) + io.out.bits.store := (floatTypes.map(t => Fill(maxType.ieeeWidth / t.ieeeWidth, store(t.ieeeWidth - 1, 0))): Seq[UInt])(tag) io.out.bits.toint := ((0 until nIntTypes).map(i => toint((minXLen << i) - 1, 0).sextTo(xLen)): Seq[UInt])(intType) io.out.bits.exc := Bits(0) @@ -441,7 +449,7 @@ class FPToInt(implicit p: Parameters) extends FPUModule()(p) { class IntToFP(val latency: Int)(implicit p: Parameters) extends FPUModule()(p) { val io = new Bundle { - val in = Valid(new FPInput).flip + val in = Valid(new IntToFPInput).flip val out = Valid(new FPResult) }