Decouple Vortex dmem bundle from TL

Previously VortexBundle was being instantiated using the parameters of
the TileLink bundle from VortexTile.  This results in tight coupling
between Vortex interface parameters and downstream TileLink parameters.
This change adds a standalone Bundle used by the VortexCore wrapper
and is independently instantiated from the TL params, i.e. different
source widths.  Ideally we want to move away from using TL-like
structures for VortexBundle and handling adapter logic completely
outside the core blackbox.
This commit is contained in:
Hansung Kim
2023-10-16 17:42:17 -07:00
parent db8625fb20
commit eb9772b750
2 changed files with 60 additions and 21 deletions

View File

@@ -8,7 +8,7 @@ import chisel3.util._
import chisel3.experimental._ import chisel3.experimental._
import org.chipsalliance.cde.config.Parameters import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.tile._ import freechips.rocketchip.tile._
import tile.VortexTile import tile.{VortexTile, VortexBundleA, VortexBundleD}
class VortexBundle(tile: VortexTile)(implicit p: Parameters) extends CoreBundle { class VortexBundle(tile: VortexTile)(implicit p: Parameters) extends CoreBundle {
val clock = Input(Clock()) val clock = Input(Clock())
@@ -22,9 +22,9 @@ class VortexBundle(tile: VortexTile)(implicit p: Parameters) extends CoreBundle
val a = tile.imemNodes.head.out.head._1.a.cloneType val a = tile.imemNodes.head.out.head._1.a.cloneType
val d = Flipped(tile.imemNodes.head.out.head._1.d.cloneType) val d = Flipped(tile.imemNodes.head.out.head._1.d.cloneType)
})) else None })) else None
val dmem = if (!tile.vortexParams.useVxCache) Some(Vec(4, new Bundle { val dmem = if (!tile.vortexParams.useVxCache) Some(Vec(tile.numLanes, new Bundle {
val a = tile.dmemNodes.head.out.head._1.a.cloneType val a = Decoupled(new VortexBundleA())
val d = Flipped(tile.dmemNodes.head.out.head._1.d.cloneType) val d = Flipped(Decoupled(new VortexBundleD()))
})) else None })) else None
val mem = if (tile.vortexParams.useVxCache) Some(new Bundle { val mem = if (tile.vortexParams.useVxCache) Some(new Bundle {
val a = tile.memNode.out.head._1.a.cloneType val a = tile.memNode.out.head._1.a.cloneType

View File

@@ -44,6 +44,22 @@ case class VortexTileParams(
} }
} }
class VortexBundleA extends Bundle {
val opcode = UInt(3.W) // FIXME: hardcoded
val size = UInt(4.W) // FIXME: hardcoded
val source = UInt(10.W) // FIXME: hardcoded
val address = UInt(32.W) // FIXME: hardcoded
val mask = UInt(4.W) // FIXME: hardcoded
val data = UInt(32.W) // FIXME: hardcoded
}
class VortexBundleD extends Bundle {
val opcode = UInt(3.W) // FIXME: hardcoded
val size = UInt(4.W) // FIXME: hardcoded
val source = UInt(10.W) // FIXME: hardcoded
val data = UInt(32.W) // FIXME: hardcoded
}
class VortexTile private ( class VortexTile private (
val vortexParams: VortexTileParams, val vortexParams: VortexTileParams,
crossing: ClockCrossingType, crossing: ClockCrossingType,
@@ -91,6 +107,7 @@ class VortexTile private (
minLatency = 1)))*/ minLatency = 1)))*/
val numLanes = 4 // FIXME: hardcoded val numLanes = 4 // FIXME: hardcoded
val sourceWidth = 1 // TODO: use Parameters for this
val imemNodes = Seq.tabulate(1) { i => val imemNodes = Seq.tabulate(1) { i =>
TLClientNode( TLClientNode(
@@ -98,7 +115,7 @@ class VortexTile private (
TLMasterPortParameters.v1( TLMasterPortParameters.v1(
clients = Seq( clients = Seq(
TLMasterParameters.v1( TLMasterParameters.v1(
sourceId = IdRange(0, 1 << 10), // TODO magic number sourceId = IdRange(0, 1 << 10), // TODO: magic numbers
name = s"Vortex Core ${vortexParams.hartId} I-Mem $i", name = s"Vortex Core ${vortexParams.hartId} I-Mem $i",
requestFifo = true, requestFifo = true,
supportsProbe = supportsProbe =
@@ -117,7 +134,7 @@ class VortexTile private (
TLMasterPortParameters.v1( TLMasterPortParameters.v1(
clients = Seq( clients = Seq(
TLMasterParameters.v1( TLMasterParameters.v1(
sourceId = IdRange(0, 1 << 10), // TODO magic number sourceId = IdRange(0, 1 << sourceWidth),
name = s"Vortex Core ${vortexParams.hartId} D-Mem Lane $i", name = s"Vortex Core ${vortexParams.hartId} D-Mem Lane $i",
requestFifo = true, requestFifo = true,
supportsProbe = supportsProbe =
@@ -316,10 +333,12 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) {
// connection: VortexBundle <--> sourceGen <--> dmemNodes // connection: VortexBundle <--> sourceGen <--> dmemNodes
val sourceGens = Seq.tabulate(outer.numLanes) { _ => val sourceGens = Seq.tabulate(outer.numLanes) { _ =>
Module(new VortexSourceGen( Module(new VortexTLAdapter(
2, // FIXME: hardcoded outer.sourceWidth,
dmemTLBundles.head.a.bits, new VortexBundleA(),
dmemTLBundles.head.d.bits, new VortexBundleD(),
chiselTypeOf(dmemTLBundles.head.a.bits),
chiselTypeOf(dmemTLBundles.head.d.bits),
)) ))
} }
(core.io.dmem.get zip sourceGens) foreach { case (coreMem, sourceGen) => (core.io.dmem.get zip sourceGens) foreach { case (coreMem, sourceGen) =>
@@ -360,21 +379,24 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) {
// sourceWidth; this needs to be more flexible. // sourceWidth; this needs to be more flexible.
// //
// Some @copypaste from CoalescerSourceGen. // Some @copypaste from CoalescerSourceGen.
class VortexSourceGen( class VortexTLAdapter(
newSourceWidth: Int, newSourceWidth: Int,
reqT: TLBundleA, inReqT: VortexBundleA,
respT: TLBundleD inRespT: VortexBundleD,
outReqT: TLBundleA,
outRespT: TLBundleD
) extends Module { ) extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
// in/out means upstream/downstream // in/out means upstream/downstream
val inReq = Flipped(Decoupled(reqT.cloneType)) // TODO: change inReq/inResp to VortexBundle
val outReq = Decoupled(reqT.cloneType) val inReq = Flipped(Decoupled(inReqT))
val inResp = Decoupled(respT.cloneType) val outReq = Decoupled(outReqT)
val outResp = Flipped(Decoupled(respT.cloneType)) val inResp = Decoupled(inRespT)
val outResp = Flipped(Decoupled(outRespT))
}) })
val sourceGen = Module(new SourceGenerator( val sourceGen = Module(new SourceGenerator(
newSourceWidth, newSourceWidth,
Some(chiselTypeOf(reqT.source)), Some(inReqT.source),
ignoreInUse = false ignoreInUse = false
)) ))
sourceGen.io.gen := io.outReq.fire // use up a source ID only when request is created sourceGen.io.gen := io.outReq.fire // use up a source ID only when request is created
@@ -382,15 +404,32 @@ class VortexSourceGen(
sourceGen.io.reclaim.bits := io.outResp.bits.source sourceGen.io.reclaim.bits := io.outResp.bits.source
sourceGen.io.meta := io.inReq.bits.source sourceGen.io.meta := io.inReq.bits.source
// passthrough logic // io passthrough logic
io.outReq <> io.inReq // TLBundleA <> VortexBundleA
io.outReq.valid := io.inReq.valid
io.outReq.bits.opcode := io.inReq.bits.opcode
io.outReq.bits.param := 0.U
io.outReq.bits.size := io.inReq.bits.size
io.outReq.bits.source := io.inReq.bits.source
io.outReq.bits.address := io.inReq.bits.address
io.outReq.bits.mask := io.inReq.bits.mask
io.outReq.bits.data := io.inReq.bits.data
io.outReq.bits.corrupt := 0.U
io.inReq.ready := io.outReq.ready
// VortexBundleD <> TLBundleD
io.inResp.valid := io.outResp.valid
io.inResp.bits.opcode := io.outResp.bits.opcode
io.inResp.bits.size := io.outResp.bits.size
io.inResp.bits.source := io.outResp.bits.source
io.inResp.bits.data := io.outResp.bits.data
io.outResp.ready := io.inResp.ready
// "man-in-the-middle" // "man-in-the-middle"
io.inReq.ready := io.outReq.ready && sourceGen.io.id.valid io.inReq.ready := io.outReq.ready && sourceGen.io.id.valid
io.outReq.valid := io.inReq.valid && sourceGen.io.id.valid io.outReq.valid := io.inReq.valid && sourceGen.io.id.valid
// FIXME: Fill is a hack; just change downstream to the right sourceWidth // FIXME: Fill is a hack; just change downstream to the right sourceWidth
// io.outReq.bits.source := Fill(newSourceWidth, sourceGen.io.id.bits) // io.outReq.bits.source := Fill(newSourceWidth, sourceGen.io.id.bits)
io.outReq.bits.source := sourceGen.io.id.bits io.outReq.bits.source := sourceGen.io.id.bits
io.inResp <> io.outResp
// translate upstream response back to its old sourceId // translate upstream response back to its old sourceId
io.inResp.bits.source := sourceGen.io.peek io.inResp.bits.source := sourceGen.io.peek
} }