From f1a1b77828e936e12761afa27fdefc8a1ef2bec8 Mon Sep 17 00:00:00 2001 From: Richard Yan Date: Tue, 10 Sep 2024 23:24:02 -0700 Subject: [PATCH] actually support large smem subbanks --- .../radiance/memory/AlignFilterNode.scala | 19 ++- .../scala/radiance/tile/RadianceCluster.scala | 127 +++++++++++++----- 2 files changed, 103 insertions(+), 43 deletions(-) diff --git a/src/main/scala/radiance/memory/AlignFilterNode.scala b/src/main/scala/radiance/memory/AlignFilterNode.scala index cd9a455..9d47fac 100644 --- a/src/main/scala/radiance/memory/AlignFilterNode.scala +++ b/src/main/scala/radiance/memory/AlignFilterNode.scala @@ -20,20 +20,23 @@ class AlignFilterNode(filters: Seq[AddressSet])(implicit p: Parameters) extends val master = seq.head.masters.head // TODO: to implement multiple filters, source Id mapping needs to be redone - assert(filters.length == 1, "multiple filters currently not supported") + // assert(filters.length == 1, "multiple filters currently not supported") + + val in_mapping = TLXbar.mapInputIds(Seq.fill(filters.length + 1)(seq.head)) + val unaligned_src_range = in_mapping.last seq.head.v1copy( - clients = filters.map { filter => + clients = filters.zipWithIndex.map { case (filter, i) => master.v2copy( name = s"${name}_filter_aligned", - sourceId = master.sourceId, + sourceId = in_mapping(i), visibility = Seq(filter), emits = seq.map(_.anyEmitClaims).reduce(_ mincover _) ) } ++ Seq( master.v2copy( name = s"${name}_filter_unaligned", - sourceId = master.sourceId.shift(master.sourceId.size), + sourceId = unaligned_src_range, visibility = Seq(AddressSet.everything), emits = seq.map(_.anyEmitClaims).reduce(_ mincover _) ), @@ -81,14 +84,18 @@ class AlignFilterNode(filters: Seq[AddressSet])(implicit p: Parameters) extends val a = node.out.init.map(_._1) val ua = node.out.last._1 + val in_mapping = TLXbar.mapInputIds(Seq.fill(filters.length + 1)(node.in.head._2.client)) + val unaligned_src = in_mapping.last + val a_aligned = filters.map(_.contains(c.a.bits.address)) - (a zip a_aligned).foreach { case (a, aligned) => + (a zip a_aligned).zipWithIndex.foreach { case ((a, aligned), idx) => a.a.bits := c.a.bits + a.a.bits.source := in_mapping(idx).start.U + c.a.bits.source a.a.valid := c.a.valid && aligned } ua.a.bits := c.a.bits - ua.a.bits.source := c.a.bits.source + (1.U << c.a.bits.source.getWidth) + ua.a.bits.source := unaligned_src.start.U + c.a.bits.source // + (1.U << c.a.bits.source.getWidth) ua.a.valid := c.a.valid && !a_aligned.reduce(_ || _) c.a.ready := MuxCase(ua.a.ready, (a zip a_aligned).map { case (a, aligned) => aligned -> a.a.ready }) diff --git a/src/main/scala/radiance/tile/RadianceCluster.scala b/src/main/scala/radiance/tile/RadianceCluster.scala index 8ec173f..1814265 100644 --- a/src/main/scala/radiance/tile/RadianceCluster.scala +++ b/src/main/scala/radiance/tile/RadianceCluster.scala @@ -223,52 +223,105 @@ class RadianceCluster ( val num_lsu_lanes = radianceTiles.head.numLsuLanes val num_lane_dupes = Math.max(1, smem_subbanks / num_lsu_lanes) - val filter_range = smem_subbanks / num_lane_dupes + val filter_range = Math.min(smem_subbanks, num_lsu_lanes) + println(s"num_lsu_lanes ${num_lsu_lanes} num_lane_dupes ${num_lane_dupes} filter_range ${filter_range}") - // (subbank, source, rw) - val filter_nodes: Seq[Seq[(TLNode, TLNode)]] = Seq.tabulate(num_lane_dupes) { did => - Seq.tabulate(filter_range) { wid => - val true_wid = did * filter_range + wid - val address = AddressSet(smem_base + wordSize * true_wid, (smem_size - 1) - (smem_subbanks - 1) * wordSize) + // (subbank, sources, aligned) = rw node + val (f_aligned, f_unaligned) = if (num_lsu_lanes >= smem_subbanks) { + val filter_nodes: Seq[Seq[(TLNode, TLNode)]] = Seq.tabulate(num_lane_dupes) { did => + Seq.tabulate(filter_range) { wid => + val true_wid = did * filter_range + wid + val address = AddressSet(smem_base + wordSize * true_wid, (smem_size - 1) - (smem_subbanks - 1) * wordSize) - radiance_smem_fanout.grouped(num_lsu_lanes).toList.zipWithIndex.flatMap { case (lanes, cid) => - lanes.zipWithIndex.flatMap { case (lane, lid) => - if ((lid % filter_range) == wid) { - println(f"c${cid}_l${lid} connected to d${did}w${wid}") - val filter_node = AlignFilterNode(Seq(address))(p, ValName(s"filter_l${lid}_w${true_wid}"), info) - DisableMonitors { implicit p => filter_node := lane } - // Seq((aligned splitter, unaligned splitter)) - Seq(( - connect_one(filter_node, () => - RWSplitterNode(address, s"aligned_splitter_c${cid}_l${lid}_w${true_wid}")), - connect_one(filter_node, () => - RWSplitterNode(AddressSet.everything, s"unaligned_splitter_c${cid}_l${lid}_w${true_wid}")) - )) - } else Seq() + radiance_smem_fanout.grouped(num_lsu_lanes).toList.zipWithIndex.flatMap { case (lanes, cid) => + lanes.zipWithIndex.flatMap { case (lane, lid) => + if ((lid % filter_range) == wid) { + println(f"c${cid}_l${lid} connected to d${did}w${wid}") + val filter_node = AlignFilterNode(Seq(address))(p, ValName(s"filter_l${lid}_w${true_wid}"), info) + DisableMonitors { implicit p => filter_node := lane } + // Seq((aligned splitter, unaligned splitter)) + Seq(( + connect_one(filter_node, () => + RWSplitterNode(address, s"aligned_splitter_c${cid}_l${lid}_w${true_wid}")), + connect_one(filter_node, () => + RWSplitterNode(AddressSet.everything, s"unaligned_splitter_c${cid}_l${lid}")) + )) + } else Seq() + } } } - } - }.flatten - val f_aligned = Seq.fill(2)(filter_nodes.map(_.map(_._1).map(connect_xbar_name(_, Some("rad_aligned"))))) + }.flatten - val f_unaligned = if (serialize_unaligned) { - Seq.fill(2) { - val serialized_node = TLEphemeralNode() - val serialized_in_xbar = LazyModule(new TLXbar()) - val serialized_out_xbar = LazyModule(new TLXbar()) - serialized_in_xbar.suggestName("unaligned_serialized_in_xbar") - serialized_out_xbar.suggestName("unaligned_serialized_out_xbar") - guard_monitors { implicit p => - filter_nodes.foreach(_.map(_._2).foreach(serialized_in_xbar.node := _)) - serialized_node := serialized_in_xbar.node - serialized_out_xbar.node := serialized_node + val f_aligned = Seq.fill(2)(filter_nodes.map(_.map(_._1).map(connect_xbar_name(_, Some("rad_aligned"))))) + val f_unaligned = if (serialize_unaligned) { + Seq.fill(2) { + val serialized_node = TLEphemeralNode() + val serialized_in_xbar = LazyModule(new TLXbar()) + val serialized_out_xbar = LazyModule(new TLXbar()) + serialized_in_xbar.suggestName("unaligned_serialized_in_xbar") + serialized_out_xbar.suggestName("unaligned_serialized_out_xbar") + guard_monitors { implicit p => + filter_nodes.foreach(_.map(_._2).foreach(serialized_in_xbar.node := _)) + serialized_node := serialized_in_xbar.node + serialized_out_xbar.node := serialized_node + } + Seq(serialized_out_xbar.node) } - Seq(serialized_out_xbar.node) + } else { + Seq.fill(2)(filter_nodes.flatMap(_.map(_._2).map(connect_xbar))) } - } else { - Seq.fill(2)(filter_nodes.flatMap(_.map(_._2).map(connect_xbar))) + (f_aligned, f_unaligned) + } else { // aligned: (subbanks, cores) = rw node + // (lanes, cores) = filter_node + val filter_nodes = Seq.tabulate(filter_range) { wid => + val addresses = Seq.tabulate(num_lane_dupes) { did => + AddressSet(smem_base + (did * filter_range + wid) * wordSize, + (smem_size - 1) - (smem_subbanks - 1) * wordSize) + } + radiance_smem_fanout.grouped(num_lsu_lanes).toSeq.zipWithIndex.map { case (lanes, cid) => + val lane = lanes(wid) + val filter_node = AlignFilterNode(addresses)(p, ValName(s"filter_c${cid}_w${wid}"), info) + guard_monitors { implicit p => + filter_node := lane + } + filter_node + } + } + val f_aligned_rw = Seq.tabulate(num_lane_dupes) { did => + filter_nodes.zipWithIndex.map { case (cores, lid) => + cores.zipWithIndex.map { case (fn, cid) => + val address = AddressSet(smem_base + (did * filter_range + lid) * wordSize, + (smem_size - 1) - (smem_subbanks - 1) * wordSize) + connect_one(fn, () => RWSplitterNode(address, s"aligned_split_c${cid}_l${lid}_d${did}")) + } + } + }.flatten + val f_unaligned_rw = filter_nodes.zipWithIndex.flatMap { case (cores, lid) => + cores.zipWithIndex.map { case (fn, cid) => + connect_one(fn, () => RWSplitterNode(AddressSet.everything, s"unaligned_split_c${cid}_l${lid}")) + } + } + val f_aligned = Seq.fill(2)(f_aligned_rw.map(_.map(connect_xbar_name(_, Some("rad_aligned"))))) + + val f_unaligned = if (serialize_unaligned) { + Seq.fill(2) { + val serialized_node = TLEphemeralNode() + val serialized_in_xbar = TLXbar(nameSuffix = Some("unaligned_ser_in")) + val serialized_out_xbar = TLXbar(nameSuffix = Some("unaligned_ser_out")) + guard_monitors { implicit p => + f_unaligned_rw.foreach(serialized_in_xbar := _) + serialized_node := serialized_in_xbar + serialized_out_xbar := serialized_node + } + Seq(serialized_out_xbar) + } + } else { + Seq.fill(2)(f_unaligned_rw.map(connect_xbar)) + } + (f_aligned, f_unaligned) } + val uniform_r_nodes: Seq[Seq[Seq[TLNexusNode]]] = spad_read_nodes.map { rb => (rb zip f_aligned.head).map { case (rw, fa) => rw ++ fa } }