From c7651e26f4489fb9c0012e101e44126f377701d8 Mon Sep 17 00:00:00 2001 From: Hansung Kim Date: Mon, 6 Mar 2023 16:17:52 -0800 Subject: [PATCH] Organize Diplomacy node structure of CoalescingUnit IdentityNode with numThreads edges + master TL node with additional 1 edge for the new coalesced requests. --- src/main/scala/tilelink/Coalescing.scala | 115 ++++++++++++++--------- 1 file changed, 70 insertions(+), 45 deletions(-) diff --git a/src/main/scala/tilelink/Coalescing.scala b/src/main/scala/tilelink/Coalescing.scala index f18a9a0..4c876d3 100644 --- a/src/main/scala/tilelink/Coalescing.scala +++ b/src/main/scala/tilelink/Coalescing.scala @@ -6,42 +6,56 @@ import chisel3._ import chisel3.util._ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.devices.tilelink.TLTestRAM import freechips.rocketchip.unittest._ class CoalescingUnit(numThreads: Int = 1)(implicit p: Parameters) extends LazyModule { - val beatBytes = 8 - val seqParam = Seq( - TLSlaveParameters.v1( - address = Seq(AddressSet(0x0000, 0xffffff)), - // resources = device.reg, - regionType = RegionType.UNCACHED, - executable = true, - supportsArithmetic = TransferSizes(1, beatBytes), - supportsLogical = TransferSizes(1, beatBytes), - supportsGet = TransferSizes(1, beatBytes), - supportsPutFull = TransferSizes(1, beatBytes), - supportsPutPartial = TransferSizes(1, beatBytes), - supportsHint = TransferSizes(1, beatBytes), - fifoId = Some(0) + // val beatBytes = 8 + // val seqParam = Seq( + // TLSlaveParameters.v1( + // address = Seq(AddressSet(0x0000, 0xffffff)), + // // resources = device.reg, + // regionType = RegionType.UNCACHED, + // executable = true, + // supportsArithmetic = TransferSizes(1, beatBytes), + // supportsLogical = TransferSizes(1, beatBytes), + // supportsGet = TransferSizes(1, beatBytes), + // supportsPutFull = TransferSizes(1, beatBytes), + // supportsPutPartial = TransferSizes(1, beatBytes), + // supportsHint = TransferSizes(1, beatBytes), + // fifoId = Some(0) + // ) + // ) + + // Identity node that captures the incoming TL requests and passes them + // through the other end, dropping coalesced requests. This is what the + // upstream node will connect to. + val node = TLIdentityNode() + + // Master node that actually generates coalesced requests. + // This and the IdentityNode will be the two outward-facing nodes that the + // downstream, either L1 or the system bus, will connect to. + val clientParam = Seq( + TLMasterParameters.v1( + name = "CoalescerNode", + sourceId = IdRange(0, 1), + visibility = Seq(AddressSet(0x0000, 0xffffff)) ) ) - val entryNodes = Seq.tabulate(numThreads) { _ => - TLManagerNode(Seq(TLSlavePortParameters.v1(seqParam, beatBytes))) - } - - val node = TLIdentityNode() - entryNodes.foreach { n => n := node } + val coalescerNode = TLClientNode( + Seq(TLMasterPortParameters.v1(clientParam)) + ) lazy val module = new Impl class Impl extends LazyModuleImp(this) { - // Example 1: accessing the entire A channel data for Thread 0 - val (tlIn0, edge0) = entryNodes(0).in(0) - dontTouch(tlIn0.a) + // // Example 1: accessing the entire A channel data for Thread 0 + // val (tlIn0, edge0) = threadNodes(0).in(0) + // dontTouch(tlIn0.a) - // Example 2: accssing the entire A channel data for Thread 1 - val (tlIn1, edge1) = entryNodes(1).in(0) - dontTouch(tlIn1.a) + // // Example 2: accssing the entire A channel data for Thread 1 + // val (tlIn1, edge1) = threadNodes(1).in(0) + // dontTouch(tlIn1.a) } } @@ -49,13 +63,14 @@ class MemTraceDriver(numThreads: Int = 1)(implicit p: Parameters) extends LazyModule { // Create N client nodes together val threadNodes = Seq.tabulate(numThreads) { i => - val clients = Seq( + val clientParam = Seq( TLMasterParameters.v1( name = "MemTraceDriver" + i.toString, - sourceId = IdRange(0, 4) + sourceId = IdRange(0, numThreads), + visibility = Seq(AddressSet(0x0000, 0xffffff)) ) ) - TLClientNode(Seq(TLMasterPortParameters.v1(clients))) + TLClientNode(Seq(TLMasterPortParameters.v1(clientParam))) } // Combine N outgoing client node into 1 idenity node for diplomatic @@ -68,15 +83,8 @@ class MemTraceDriver(numThreads: Int = 1)(implicit p: Parameters) lazy val module = new MemTraceDriverImp(this, numThreads) } -class TraceReq extends Bundle { - val valid = Bool() - val address = UInt(64.W) -} - -class MemTraceDriverImp( - outer: MemTraceDriver, - numThreads: Int -) extends LazyModuleImp(outer) +class MemTraceDriverImp(outer: MemTraceDriver, numThreads: Int) + extends LazyModuleImp(outer) with UnitTestModule { val sim = Module( new SimMemTrace(filename = "vecadd.core1.thread4.trace", numThreads) @@ -85,7 +93,7 @@ class MemTraceDriverImp( sim.io.reset := reset.asBool sim.io.trace_read.ready := true.B - // Split output of SimMemTrace, which is flattened across all lanes, + // Split output of SimMemTrace, which is flattened across all threads, // back to each thread's. val threadReqs = Wire(Vec(numThreads, new TraceReq)) threadReqs.zipWithIndex.foreach { case (req, i) => @@ -93,7 +101,7 @@ class MemTraceDriverImp( req.address := (sim.io.trace_read.address >> (64 * i)) } - // Connect each sim module to its respective TL connection + // Connect each thread to its respective TL node. (outer.threadNodes zip threadReqs).foreach { case (node, req) => val (tlOut, edge) = node.out(0) tlOut.a.valid := req.valid @@ -116,6 +124,11 @@ class MemTraceDriverImp( io.finished := sim.io.trace_read.finished } +class TraceReq extends Bundle { + val valid = Bool() + val address = UInt(64.W) +} + class SimMemTrace(val filename: String, numThreads: Int) extends BlackBox( Map("FILENAME" -> filename, "NUM_THREADS" -> numThreads) @@ -130,6 +143,7 @@ class SimMemTrace(val filename: String, numThreads: Int) val valid = Output(UInt(numThreads.W)) // Chisel can't interface with Verilog 2D port, so flatten all lanes into // single wide 1D array. + // TODO: assumes 64-bit address. val address = Output(UInt((64 * numThreads).W)) val finished = Output(Bool()) } @@ -142,11 +156,23 @@ class SimMemTrace(val filename: String, numThreads: Int) class CoalConnectTrace(implicit p: Parameters) extends LazyModule { // TODO: use parameters for numThreads - val coal = LazyModule(new CoalescingUnit(numThreads = 4)) - val driver = LazyModule(new MemTraceDriver(numThreads = 4)) + val numThreads = 4 + val coal = LazyModule(new CoalescingUnit(numThreads)) + val driver = LazyModule(new MemTraceDriver(numThreads)) coal.node :=* driver.node + // Use TLTestRAM as bogus downstream TL manager nodes + // TODO: swap this out with a memtrace logger + val rams = Seq.tabulate(numThreads + 1) { _ => + LazyModule( + new TLTestRAM(address = AddressSet(0x0000, 0xffffff), beatBytes = 8) + ) + } + // Connect all (N+1) outputs of coal to separate TestRAM modules + (0 until numThreads).foreach { i => rams(i).node := coal.node } + rams(numThreads).node := coal.coalescerNode + lazy val module = new Impl class Impl extends LazyModuleImp(this) with UnitTestModule { driver.module.io.start := io.start @@ -154,9 +180,8 @@ class CoalConnectTrace(implicit p: Parameters) extends LazyModule { } } -class CoalescingUnitTest(timeout: Int = 500000)(implicit - p: Parameters -) extends UnitTest(timeout) { +class CoalescingUnitTest(timeout: Int = 500000)(implicit p: Parameters) + extends UnitTest(timeout) { val dut = Module(LazyModule(new CoalConnectTrace).module) dut.io.start := io.start io.finished := dut.io.finished