Make VortexCoreParams; bring VortexTile into rocketchip.tile
Reduces duplicate declarations. Need to properly split it out of rocket-chip later.
This commit is contained in:
@@ -8,7 +8,6 @@ import chisel3.util._
|
||||
import chisel3.experimental._
|
||||
import org.chipsalliance.cde.config.Parameters
|
||||
import freechips.rocketchip.tile._
|
||||
import tile.VortexTile
|
||||
|
||||
class VortexBundleA(
|
||||
sourceWidth: Int,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// See LICENSE.SiFive for license details.
|
||||
// See LICENSE.Berkeley for license details.
|
||||
|
||||
package tile
|
||||
package freechips.rocketchip.tile
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
@@ -18,10 +18,8 @@ import freechips.rocketchip.regmapper.RegField
|
||||
import freechips.rocketchip.tile._
|
||||
import rocket.{Vortex, VortexBundleA, VortexBundleD}
|
||||
|
||||
case class RocketTileBoundaryBufferParams(force: Boolean = false)
|
||||
|
||||
case class VortexTileParams(
|
||||
core: RocketCoreParams = RocketCoreParams(),
|
||||
core: VortexCoreParams = VortexCoreParams(),
|
||||
useVxCache: Boolean = false,
|
||||
icache: Option[ICacheParams] = None /* Some(ICacheParams()) */,
|
||||
dcache: Option[DCacheParams] = None /* Some(DCacheParams()) */,
|
||||
@@ -44,6 +42,65 @@ case class VortexTileParams(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move to VortexCore
|
||||
// VortexTileParams extends from TileParams that require a `core: CoreParams`
|
||||
// field, so VortexCoreParams needs to also extend from that, requiring all
|
||||
// these fields to be initialized. TODO.
|
||||
case class VortexCoreParams(
|
||||
bootFreqHz: BigInt = 0,
|
||||
useVM: Boolean = true,
|
||||
useUser: Boolean = false,
|
||||
useSupervisor: Boolean = false,
|
||||
useHypervisor: Boolean = false,
|
||||
useDebug: Boolean = true,
|
||||
useAtomics: Boolean = true,
|
||||
useAtomicsOnlyForIO: Boolean = false,
|
||||
useCompressed: Boolean = true,
|
||||
useRVE: Boolean = false,
|
||||
useSCIE: Boolean = false,
|
||||
useBitManip: Boolean = false,
|
||||
useBitManipCrypto: Boolean = false,
|
||||
useCryptoNIST: Boolean = false,
|
||||
useCryptoSM: Boolean = false,
|
||||
useConditionalZero: Boolean = false,
|
||||
nLocalInterrupts: Int = 0,
|
||||
useNMI: Boolean = false,
|
||||
nBreakpoints: Int = 1,
|
||||
useBPWatch: Boolean = false,
|
||||
mcontextWidth: Int = 0,
|
||||
scontextWidth: Int = 0,
|
||||
nPMPs: Int = 8,
|
||||
nPerfCounters: Int = 0,
|
||||
haveBasicCounters: Boolean = true,
|
||||
haveCFlush: Boolean = false,
|
||||
misaWritable: Boolean = true,
|
||||
nL2TLBEntries: Int = 0,
|
||||
nL2TLBWays: Int = 1,
|
||||
nPTECacheEntries: Int = 8,
|
||||
mtvecInit: Option[BigInt] = Some(BigInt(0)),
|
||||
mtvecWritable: Boolean = true,
|
||||
fastLoadWord: Boolean = true,
|
||||
fastLoadByte: Boolean = false,
|
||||
branchPredictionModeCSR: Boolean = false,
|
||||
clockGate: Boolean = false,
|
||||
mvendorid: Int = 0, // 0 means non-commercial implementation
|
||||
mimpid: Int = 0x20181004, // release date in BCD
|
||||
mulDiv: Option[MulDivParams] = Some(MulDivParams()),
|
||||
fpu: Option[FPUParams] = Some(FPUParams()),
|
||||
debugROB: Boolean = false, // if enabled, uses a C++ debug ROB to generate trace-with-wdata
|
||||
haveCease: Boolean = true, // non-standard CEASE instruction
|
||||
haveSimTimeout: Boolean = true // add plusarg for simulation timeout
|
||||
) extends CoreParams {
|
||||
val haveFSDirty = false
|
||||
val pmpGranularity: Int = if (useHypervisor) 4096 else 4
|
||||
val fetchWidth: Int = if (useCompressed) 2 else 1
|
||||
val decodeWidth: Int = fetchWidth / (if (useCompressed) 2 else 1)
|
||||
val retireWidth: Int = 1
|
||||
val instBits: Int = if (useCompressed) 16 else 32
|
||||
val lrscCycles: Int = 80 // worst case is 14 mispredicted branches + slop
|
||||
val traceHasWdata: Boolean = false // ooo wb, so no wdata in trace
|
||||
}
|
||||
|
||||
class VortexTile private (
|
||||
val vortexParams: VortexTileParams,
|
||||
crossing: ClockCrossingType,
|
||||
@@ -64,6 +121,8 @@ class VortexTile private (
|
||||
val slaveNode = TLIdentityNode()
|
||||
val masterNode = visibilityNode
|
||||
|
||||
// Memory-mapped region for HTIF communication
|
||||
// We use fixed addresses instead of tohost/fromhost
|
||||
val regDevice = new SimpleDevice("vortex-reg", Seq(s"vortex-reg${tileParams.hartId}"))
|
||||
val regNode = TLRegisterNode(
|
||||
address = Seq(AddressSet(0x7c000000 + 0x1000 * tileParams.hartId, 0xfff)),
|
||||
@@ -248,6 +307,8 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) {
|
||||
core.io.clock := clock
|
||||
core.io.reset := reset
|
||||
|
||||
// begin @copypaste from RocketTile ------------------------------------------
|
||||
|
||||
// reset vector is connected in the Frontend to s2_pc
|
||||
core.io.reset_vector := DontCare
|
||||
|
||||
@@ -273,11 +334,13 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) {
|
||||
core.io.traceStall := outer.traceAuxSinkNode.bundle.stall
|
||||
// outer.bpwatchSourceNode.bundle <> core.io.bpwatch
|
||||
|
||||
// Copypasted from Rocket; not necessary for Vortex as hartId is set via Verilog parameter
|
||||
// not necessary for Vortex as hartId is set via Verilog parameter
|
||||
// core.io.hartid := outer.hartIdSinkNode.bundle
|
||||
// require(core.io.hartid.getWidth >= outer.hartIdSinkNode.bundle.getWidth,
|
||||
// s"core hartid wire (${core.io.hartid.getWidth}b) truncates external hartid wire (${outer.hartIdSinkNode.bundle.getWidth}b)")
|
||||
|
||||
// end @copypaste from RocketTile --------------------------------------------
|
||||
|
||||
// ---------------------------------------------
|
||||
// Translate Vortex memory interface to TileLink
|
||||
// ---------------------------------------------
|
||||
@@ -299,9 +362,6 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) {
|
||||
core.io.mem.get.d <> memTLAdapter.io.inResp
|
||||
outer.memNode.out(0)._1.a <> memTLAdapter.io.outReq
|
||||
memTLAdapter.io.outResp <> outer.memNode.out(0)._1.d
|
||||
|
||||
// core.io.mem.get.a <> outer.memNode.out.head._1.a
|
||||
// core.io.mem.get.d <> outer.memNode.out.head._1.d
|
||||
} else {
|
||||
val imemTLAdapter = Module(new VortexTLAdapter(
|
||||
outer.sourceWidth,
|
||||
@@ -317,7 +377,7 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) {
|
||||
imemTLAdapter.io.outResp <> outer.imemNodes(0).out(0)._1.d
|
||||
|
||||
// Since the individual per-lane TL requests might come back out-of-sync between
|
||||
// the lanes, but Vortex core expects the lane requests to be synced,
|
||||
// the lanes, but Vortex core expects the per-lane responses to be synced,
|
||||
// we need to selectively fire responses that have the same source, and
|
||||
// delay others. Below is the logic that implements this.
|
||||
|
||||
@@ -325,8 +385,9 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) {
|
||||
val arb = Module(
|
||||
new RRArbiter(core.io.dmem.get.head.d.bits.source.cloneType, outer.numLanes)
|
||||
)
|
||||
val dmemTLBundles = outer.dmemNodes.map(_.out.head._1)
|
||||
arb.io.out.ready := true.B
|
||||
|
||||
val dmemTLBundles = outer.dmemNodes.map(_.out.head._1)
|
||||
(arb.io.in zip dmemTLBundles).foreach { case (arbIn, tlBundle) =>
|
||||
arbIn.valid := tlBundle.d.valid
|
||||
arbIn.bits := tlBundle.d.bits.source
|
||||
@@ -364,10 +425,6 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) {
|
||||
tlAdapter.io.outResp.valid := tlBundle.d.valid && matchingSources(i)
|
||||
tlBundle.d.ready := tlAdapter.io.outResp.ready && matchingSources(i)
|
||||
}
|
||||
|
||||
// (core.io.dmem.get zip outer.dmemNodes).foreach { case (coreMem, tileNode) =>
|
||||
// tileNode.out.head._1.a <> coreMem.a
|
||||
// }
|
||||
}
|
||||
|
||||
// core.io.fpu := DontCare
|
||||
@@ -382,6 +439,61 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) {
|
||||
// dcacheArb.io.requestor <> dcachePorts.toSeq
|
||||
}
|
||||
|
||||
/** VortexCore wraps around the Vortex BlackBox module and exposes TileLink
|
||||
* nodes for the core-cache memory interface.
|
||||
*/
|
||||
class VortexCore(implicit p: Parameters) extends LazyModule {
|
||||
val numLanes = 4 // TODO: use Parameters for this
|
||||
val sourceWidth = 4 // TODO: use Parameters for this
|
||||
|
||||
// val imemNodes = Seq.tabulate(1) { i =>
|
||||
// TLClientNode(
|
||||
// Seq(
|
||||
// TLMasterPortParameters.v1(
|
||||
// clients = Seq(
|
||||
// TLMasterParameters.v1(
|
||||
// sourceId = IdRange(0, 1 << sourceWidth),
|
||||
// name = s"Vortex Core ${vortexParams.hartId} I-Mem $i",
|
||||
// requestFifo = true,
|
||||
// supportsProbe =
|
||||
// TransferSizes(1, lazyCoreParamsView.coreDataBytes),
|
||||
// supportsGet = TransferSizes(1, lazyCoreParamsView.coreDataBytes)
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
|
||||
// val dmemNodes = Seq.tabulate(numLanes) { i =>
|
||||
// TLClientNode(
|
||||
// Seq(
|
||||
// TLMasterPortParameters.v1(
|
||||
// clients = Seq(
|
||||
// TLMasterParameters.v1(
|
||||
// sourceId = IdRange(0, 1 << sourceWidth),
|
||||
// name = s"Vortex Core ${vortexParams.hartId} D-Mem Lane $i",
|
||||
// requestFifo = true,
|
||||
// supportsProbe =
|
||||
// TransferSizes(1, lazyCoreParamsView.coreDataBytes),
|
||||
// supportsGet = TransferSizes(1, lazyCoreParamsView.coreDataBytes),
|
||||
// supportsPutFull =
|
||||
// TransferSizes(1, lazyCoreParamsView.coreDataBytes),
|
||||
// supportsPutPartial =
|
||||
// TransferSizes(1, lazyCoreParamsView.coreDataBytes)
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
|
||||
lazy val module = new VortexCoreModuleImp(this)
|
||||
}
|
||||
|
||||
class VortexCoreModuleImp(outer: VortexCore) extends LazyModuleImp(outer) {
|
||||
}
|
||||
|
||||
// Some @copypaste from CoalescerSourceGen.
|
||||
class VortexTLAdapter(
|
||||
newSourceWidth: Int,
|
||||
@@ -434,9 +546,3 @@ class VortexTLAdapter(
|
||||
// translate upstream response back to its old sourceId
|
||||
io.inResp.bits.source := sourceGen.io.peek
|
||||
}
|
||||
|
||||
// FIXME: unsure this is necessary
|
||||
trait HasFpuOpt { this: RocketTileModuleImp =>
|
||||
val fpuOpt =
|
||||
outer.tileParams.core.fpu.map(params => Module(new FPU(params)(outer.p)))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user