Use VortexTLAdapter for useVxCache = true as well

This commit is contained in:
Hansung Kim
2023-10-18 20:04:31 -07:00
parent 0d92eb65d4
commit ff302c1ba5
2 changed files with 55 additions and 25 deletions

View File

@@ -10,20 +10,28 @@ import org.chipsalliance.cde.config.Parameters
import freechips.rocketchip.tile._ import freechips.rocketchip.tile._
import tile.VortexTile import tile.VortexTile
class VortexBundleA extends Bundle { class VortexBundleA(
sourceWidth: Int,
dataWidth: Int
) extends Bundle {
assert(dataWidth % 8 == 0)
val opcode = UInt(3.W) // FIXME: hardcoded val opcode = UInt(3.W) // FIXME: hardcoded
val size = UInt(4.W) // FIXME: hardcoded val size = UInt(4.W) // FIXME: hardcoded
val source = UInt(10.W) // FIXME: hardcoded val source = UInt(sourceWidth.W) // FIXME: hardcoded
val address = UInt(32.W) // FIXME: hardcoded val address = UInt(32.W) // FIXME: hardcoded
val mask = UInt(4.W) // FIXME: hardcoded val mask = UInt((dataWidth / 8).W) // FIXME: hardcoded
val data = UInt(32.W) // FIXME: hardcoded val data = UInt(dataWidth.W) // FIXME: hardcoded
} }
class VortexBundleD extends Bundle { class VortexBundleD(
sourceWidth: Int,
dataWidth: Int
) extends Bundle {
assert(dataWidth % 8 == 0)
val opcode = UInt(3.W) // FIXME: hardcoded val opcode = UInt(3.W) // FIXME: hardcoded
val size = UInt(4.W) // FIXME: hardcoded val size = UInt(4.W) // FIXME: hardcoded
val source = UInt(10.W) // FIXME: hardcoded val source = UInt(sourceWidth.W) // FIXME: hardcoded
val data = UInt(32.W) // FIXME: hardcoded val data = UInt(dataWidth.W) // FIXME: hardcoded
} }
class VortexBundle(tile: VortexTile)(implicit p: Parameters) extends CoreBundle { class VortexBundle(tile: VortexTile)(implicit p: Parameters) extends CoreBundle {
@@ -35,16 +43,18 @@ class VortexBundle(tile: VortexTile)(implicit p: Parameters) extends CoreBundle
// conditionally instantiate ports depending on whether we want to use VX_cache or not // conditionally instantiate ports depending on whether we want to use VX_cache or not
val imem = if (!tile.vortexParams.useVxCache) Some(Vec(1, new Bundle { val imem = if (!tile.vortexParams.useVxCache) Some(Vec(1, new Bundle {
val a = Decoupled(new VortexBundleA()) val a = Decoupled(new VortexBundleA(sourceWidth = 10, dataWidth = 32))
val d = Flipped(Decoupled(new VortexBundleD())) val d = Flipped(Decoupled(new VortexBundleD(sourceWidth = 10, dataWidth = 32)))
})) else None })) else None
val dmem = if (!tile.vortexParams.useVxCache) Some(Vec(tile.numLanes, new Bundle { val dmem = if (!tile.vortexParams.useVxCache) Some(Vec(tile.numLanes, new Bundle {
val a = Decoupled(new VortexBundleA()) val a = Decoupled(new VortexBundleA(sourceWidth = 10, dataWidth = 32))
val d = Flipped(Decoupled(new VortexBundleD())) val d = Flipped(Decoupled(new VortexBundleD(sourceWidth = 10, dataWidth = 32)))
})) 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 = Decoupled(new VortexBundleA(sourceWidth = 15, dataWidth = 128))
val d = Flipped(tile.memNode.out.head._1.d.cloneType) val d = Flipped(Decoupled(new VortexBundleD(sourceWidth = 15, dataWidth = 128)))
// val a = tile.memNode.out.head._1.a.cloneType
// val d = Flipped(tile.memNode.out.head._1.d.cloneType)
}) else None }) else None
// val fpu = Flipped(new FPUCoreIO()) // val fpu = Flipped(new FPUCoreIO())

View File

@@ -135,15 +135,16 @@ class VortexTile private (
) )
} }
println(s"============= lazyCoreParamsView.coreDataBytes=${lazyCoreParamsView.coreDataBytes}")
val memNode = TLClientNode( val memNode = TLClientNode(
Seq( Seq(
TLMasterPortParameters.v1( TLMasterPortParameters.v1(
clients = Seq( clients = Seq(
TLMasterParameters.v1( TLMasterParameters.v1(
sourceId = IdRange(0, 1 << 15), // TODO magic numbers sourceId = IdRange(0, 1 << sourceWidth),
name = s"Vortex Core ${vortexParams.hartId} Mem Interface", name = s"Vortex Core ${vortexParams.hartId} Mem Interface",
requestFifo = true, requestFifo = true,
supportsProbe = TransferSizes(16, 16), supportsProbe = TransferSizes(16, 16), // FIXME: hardcoded
supportsGet = TransferSizes(16, 16), supportsGet = TransferSizes(16, 16),
supportsPutFull = TransferSizes(16, 16), supportsPutFull = TransferSizes(16, 16),
supportsPutPartial = TransferSizes(16, 16) supportsPutPartial = TransferSizes(16, 16)
@@ -284,16 +285,35 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) {
// require(core.io.hartid.getWidth >= outer.hartIdSinkNode.bundle.getWidth, // 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)") // s"core hartid wire (${core.io.hartid.getWidth}b) truncates external hartid wire (${outer.hartIdSinkNode.bundle.getWidth}b)")
// ---------------------------------------------
// Translate Vortex memory interface to TileLink
// ---------------------------------------------
if (outer.vortexParams.useVxCache) { if (outer.vortexParams.useVxCache) {
println(s"width of a channel data ${core.io.mem.get.a.bits.data.getWidth}") println(s"width of a channel data ${core.io.mem.get.a.bits.data.getWidth}")
println(s"width of d channel data ${core.io.mem.get.d.bits.data.getWidth}") println(s"width of d channel data ${core.io.mem.get.d.bits.data.getWidth}")
core.io.mem.get.a <> outer.memNode.out.head._1.a
core.io.mem.get.d <> outer.memNode.out.head._1.d val memTLAdapter = Module(new VortexTLAdapter(
outer.sourceWidth,
chiselTypeOf(core.io.mem.get.a.bits),
chiselTypeOf(core.io.mem.get.d.bits),
chiselTypeOf(outer.memNode.out.head._1.a.bits),
chiselTypeOf(outer.memNode.out.head._1.d.bits),
))
// connection: VortexBundle <--> VortexTLAdapter <--> TL memNode
memTLAdapter.io.inReq <> core.io.mem.get.a
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 { } else {
val imemTLAdapter = Module(new VortexTLAdapter( val imemTLAdapter = Module(new VortexTLAdapter(
outer.sourceWidth, outer.sourceWidth,
new VortexBundleA(), chiselTypeOf(core.io.imem.get(0).a.bits),
new VortexBundleD(), chiselTypeOf(core.io.imem.get(0).d.bits),
chiselTypeOf(outer.imemNodes.head.out.head._1.a.bits), chiselTypeOf(outer.imemNodes.head.out.head._1.a.bits),
chiselTypeOf(outer.imemNodes.head.out.head._1.d.bits), chiselTypeOf(outer.imemNodes.head.out.head._1.d.bits),
)) ))
@@ -326,26 +346,26 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) {
// connection: VortexBundle <--> VortexTLAdapter <--> dmemNodes // connection: VortexBundle <--> VortexTLAdapter <--> dmemNodes
// @perf: this would duplicate SourceGenerator table for every lane and eat // @perf: this would duplicate SourceGenerator table for every lane and eat
// up some area // up some area
val tlAdapters = Seq.tabulate(outer.numLanes) { _ => val dmemTLAdapters = Seq.tabulate(outer.numLanes) { _ =>
Module(new VortexTLAdapter( Module(new VortexTLAdapter(
outer.sourceWidth, outer.sourceWidth,
new VortexBundleA(), chiselTypeOf(core.io.dmem.get(0).a.bits),
new VortexBundleD(), chiselTypeOf(core.io.dmem.get(0).d.bits),
chiselTypeOf(dmemTLBundles.head.a.bits), chiselTypeOf(dmemTLBundles.head.a.bits),
chiselTypeOf(dmemTLBundles.head.d.bits), chiselTypeOf(dmemTLBundles.head.d.bits),
)) ))
} }
(core.io.dmem.get zip tlAdapters) foreach { case (coreMem, tlAdapter) => (core.io.dmem.get zip dmemTLAdapters) foreach { case (coreMem, tlAdapter) =>
tlAdapter.io.inReq <> coreMem.a tlAdapter.io.inReq <> coreMem.a
coreMem.d <> tlAdapter.io.inResp coreMem.d <> tlAdapter.io.inResp
} }
(tlAdapters zip dmemTLBundles) foreach { case (tlAdapter, tlBundle) => (dmemTLAdapters zip dmemTLBundles) foreach { case (tlAdapter, tlBundle) =>
tlBundle.a <> tlAdapter.io.outReq tlBundle.a <> tlAdapter.io.outReq
} }
// using the chosen source id, // using the chosen source id,
// - lie to core that response is not valid if source doesn't match picked // - lie to core that response is not valid if source doesn't match picked
// - lie to downstream that core is not ready if source doesn't match picked // - lie to downstream that core is not ready if source doesn't match picked
(tlAdapters zip dmemTLBundles).zipWithIndex.foreach { (dmemTLAdapters zip dmemTLBundles).zipWithIndex.foreach {
case ((tlAdapter, tlBundle), i) => case ((tlAdapter, tlBundle), i) =>
tlAdapter.io.outResp.bits := tlBundle.d.bits tlAdapter.io.outResp.bits := tlBundle.d.bits
tlAdapter.io.outResp.valid := tlBundle.d.valid && matchingSources(i) tlAdapter.io.outResp.valid := tlBundle.d.valid && matchingSources(i)