From fb97bd3c2b7d1ac7f605703d40bc0865d1f4bbb6 Mon Sep 17 00:00:00 2001 From: Hansung Kim Date: Tue, 17 Oct 2023 12:18:58 -0700 Subject: [PATCH] Decouple Vortex imem bundle from TL --- src/main/resources/vsrc/vortex | 2 +- src/main/scala/rocket/VortexCore.scala | 6 ++-- src/main/scala/tile/VortexTile.scala | 42 ++++++++++++++++---------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/main/resources/vsrc/vortex b/src/main/resources/vsrc/vortex index 3adf178..696621b 160000 --- a/src/main/resources/vsrc/vortex +++ b/src/main/resources/vsrc/vortex @@ -1 +1 @@ -Subproject commit 3adf178478c28fa9629da31afe3c6b8b55c58772 +Subproject commit 696621b2dc4b14e5de382c144b8ee29f437ea1b5 diff --git a/src/main/scala/rocket/VortexCore.scala b/src/main/scala/rocket/VortexCore.scala index 8bb0b62..0c2f066 100644 --- a/src/main/scala/rocket/VortexCore.scala +++ b/src/main/scala/rocket/VortexCore.scala @@ -34,9 +34,9 @@ class VortexBundle(tile: VortexTile)(implicit p: Parameters) extends CoreBundle val interrupts = Input(new CoreInterrupts()) // 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 { // TODO: magic number - val a = tile.imemNodes.head.out.head._1.a.cloneType - val d = Flipped(tile.imemNodes.head.out.head._1.d.cloneType) + val imem = if (!tile.vortexParams.useVxCache) Some(Vec(1, new Bundle { + val a = Decoupled(new VortexBundleA()) + val d = Flipped(Decoupled(new VortexBundleD())) })) else None val dmem = if (!tile.vortexParams.useVxCache) Some(Vec(tile.numLanes, new Bundle { val a = Decoupled(new VortexBundleA()) diff --git a/src/main/scala/tile/VortexTile.scala b/src/main/scala/tile/VortexTile.scala index 23cd4ca..5b9cfa4 100644 --- a/src/main/scala/tile/VortexTile.scala +++ b/src/main/scala/tile/VortexTile.scala @@ -290,10 +290,18 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) { core.io.mem.get.a <> outer.memNode.out.head._1.a core.io.mem.get.d <> outer.memNode.out.head._1.d } else { - (core.io.imem.get zip outer.imemNodes).foreach { case (coreMem, tileNode) => - coreMem.d <> tileNode.out.head._1.d - tileNode.out.head._1.a <> coreMem.a - } + val imemTLAdapter = Module(new VortexTLAdapter( + outer.sourceWidth, + new VortexBundleA(), + new VortexBundleD(), + chiselTypeOf(outer.imemNodes.head.out.head._1.a.bits), + chiselTypeOf(outer.imemNodes.head.out.head._1.d.bits), + )) + // TODO: make imemNodes not a vector + imemTLAdapter.io.inReq <> core.io.imem.get(0).a + core.io.imem.get(0).d <> imemTLAdapter.io.inResp + outer.imemNodes(0).out(0)._1.a <> imemTLAdapter.io.outReq + 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, @@ -315,8 +323,10 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) { .map(b => (b.d.bits.source === arb.io.out.bits) && arb.io.out.valid) .asUInt - // connection: VortexBundle <--> sourceGen <--> dmemNodes - val sourceGens = Seq.tabulate(outer.numLanes) { _ => + // connection: VortexBundle <--> VortexTLAdapter <--> dmemNodes + // @perf: this would duplicate SourceGenerator table for every lane and eat + // up some area + val tlAdapters = Seq.tabulate(outer.numLanes) { _ => Module(new VortexTLAdapter( outer.sourceWidth, new VortexBundleA(), @@ -325,21 +335,21 @@ class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) { chiselTypeOf(dmemTLBundles.head.d.bits), )) } - (core.io.dmem.get zip sourceGens) foreach { case (coreMem, sourceGen) => - sourceGen.io.inReq <> coreMem.a - coreMem.d <> sourceGen.io.inResp + (core.io.dmem.get zip tlAdapters) foreach { case (coreMem, tlAdapter) => + tlAdapter.io.inReq <> coreMem.a + coreMem.d <> tlAdapter.io.inResp } - (sourceGens zip dmemTLBundles) foreach { case (sourceGen, tlBundle) => - tlBundle.a <> sourceGen.io.outReq + (tlAdapters zip dmemTLBundles) foreach { case (tlAdapter, tlBundle) => + tlBundle.a <> tlAdapter.io.outReq } // using the chosen source id, // - 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 - (sourceGens zip dmemTLBundles).zipWithIndex.foreach { - case ((sourceGen, tlBundle), i) => - sourceGen.io.outResp.bits := tlBundle.d.bits - sourceGen.io.outResp.valid := tlBundle.d.valid && matchingSources(i) - tlBundle.d.ready := sourceGen.io.outResp.ready && matchingSources(i) + (tlAdapters zip dmemTLBundles).zipWithIndex.foreach { + case ((tlAdapter, tlBundle), i) => + tlAdapter.io.outResp.bits := tlBundle.d.bits + 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) =>