Skip to content

Commit 17da921

Browse files
committed
proper response handling for single address coalescer, add data and ready verification to mem perf tests
1 parent 989bad5 commit 17da921

5 files changed

Lines changed: 95 additions & 45 deletions

File tree

src/main/scala/radiance/cluster/RadianceCluster.scala

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,18 +136,14 @@ class RadianceCluster (
136136
clsbus.inwardNode := visibilityNode := l1cache.outNode
137137

138138
// connect barriers
139-
val numCoresInCluster = muonTiles.length
139+
val realMuons = muonTiles.filter(_.isInstanceOf[MuonTile]).map(_.asInstanceOf[MuonTile])
140+
if (realMuons.nonEmpty) {
141+
val barrierJunction = LazyModule(new BarrierJunction())
142+
val barrierSynchronizer = LazyModule(new Synchronizer())
140143

141-
val barrierJunction = LazyModule(new BarrierJunction())
142-
val barrierSynchronizer = LazyModule(new Synchronizer())
143-
144-
muonTiles.foreach(barrierJunction.node := _.asInstanceOf[MuonTile].barrierMaster)
145-
barrierSynchronizer.node := barrierJunction.node
146-
147-
// val barrierSlaveNode = BarrierSlaveNode(numCoresInCluster)
148-
// muonTiles.foreach { tile =>
149-
// barrierSlaveNode := tile.barrierMasterNode
150-
// }
144+
realMuons.foreach(barrierJunction.node := _.barrierMaster)
145+
barrierSynchronizer.node := barrierJunction.node
146+
}
151147

152148
// val l1InNodes = muonTiles.map(_.dcacheNode)
153149
val l1InNodes = muonTiles.flatMap(t => Seq(t.icacheNode, t.dcacheNode))

src/main/scala/radiance/cluster/RadianceSharedMemComponents.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ class RadianceSharedMemComponents(
8484

8585
(prealignBuffer, (xbar, xi, xo), policyNode)
8686
}
87-
// coalesce single addresses TODO: return leg is really hacky, disabled for now
88-
val prealignNodes = if (false) {
87+
// coalesce single addresses
88+
val prealignNodes = if (true) {
8989
val (coalescerAdapter, coalescerClient) = SingleAddrCoalescer(3)
9090
components.foreach(x => coalescerAdapter := x._1)
9191
Seq(coalescerAdapter, coalescerClient)

src/main/scala/radiance/memory/SingleAddrCoalescer.scala

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class SingleAddrCoalescer(val sourceBits: Int = 2)
3939
out.a.valid := in.a.valid && !coalescibleOut
4040
in.a.ready := Mux(coalescibleOut, coalOut.a.ready && coalSource.io.id.valid, out.a.ready)
4141

42-
in.d.valid := out.d.valid // || coalescedIn // TODO FIXME HACK, ASSUMES UNIFORM D READY
42+
in.d.valid := out.d.valid && !coalescedIn // TODO FIXME HACK, ASSUMES UNIFORM D READY
4343
out.d.ready := in.d.ready && !coalescedIn // coalesced response has priority
4444
}
4545

@@ -66,24 +66,44 @@ class SingleAddrCoalescer(val sourceBits: Int = 2)
6666
// coalesced D input
6767
val inD = node.in.map(_._1.d)
6868

69-
// TODO TODO TODO TODO TODO TODO TODO TODO TODO: MASSIVE HACK
70-
assert(!coalescedIn ||
71-
// coalesced response must fire at once back at all lanes (for now)
72-
inD.map(x => !x.valid || (x.ready === inD.head.ready)).andR)
69+
val currDFires = inD.map(_.fire)
70+
val pendingDResp = RegInit(VecInit.fill(numLanes)(false.B))
71+
val storedDResp = RegEnable(coalOut.d.bits, 0.U.asTypeOf(coalOut.d.bits), coalOut.d.fire)
72+
val peekMeta = coalSource.io.peek.get
73+
val storedDMeta = RegEnable(peekMeta, 0.U.asTypeOf(peekMeta), coalOut.d.fire)
74+
val partialMode = pendingDResp.asUInt.orR
7375

74-
coalescedIn := coalOut.d.valid
75-
val allDReady = inD.map(x => !x.valid || x.ready).andR
76-
coalOut.d.ready := allDReady
76+
// enter partial mode when cannot clear all D lanes in one cycle
77+
val currDFireOrInvalid = (currDFires zip peekMeta).map { case (df, pm) =>
78+
df || (!pm.valid)
79+
}
80+
when (coalOut.d.fire && !currDFireOrInvalid.andR) {
81+
assert(pendingDResp.asUInt === 0.U)
82+
// unfired and valid lanes
83+
pendingDResp := VecInit(currDFireOrInvalid.map(!_))
84+
}
85+
// when in partial mode, clear lanes that fire
86+
when (partialMode) {
87+
(pendingDResp zip currDFires).foreach { case (p, f) => p := p && !f }
88+
}
7789

78-
coalSource.io.reclaim.valid := coalOut.d.fire
79-
coalSource.io.reclaim.bits := coalOut.d.bits.source
80-
when (coalescedIn) { // override passthrough D
81-
(inD zip coalSource.io.peek.get).foreach { case (d, sv) =>
82-
d.valid := sv.valid
83-
d.bits := coalOut.d.bits
84-
d.bits.source := sv.bits
90+
coalescedIn := coalOut.d.valid || partialMode
91+
// we only drive uncoalesced D inputs when there's a coalesced response,
92+
// otherwise, passthrough nodes drive the inputs
93+
when (coalescedIn) {
94+
// when partial, in D is stored if that lane hasn't cleared yet; otherwise, it's out D
95+
val metas = Mux(partialMode, storedDMeta, peekMeta)
96+
(inD lazyZip pendingDResp lazyZip metas).foreach { case (in, pending, meta) =>
97+
in.valid := Mux(partialMode, pending, coalOut.d.valid) && meta.valid
98+
in.bits := Mux(partialMode, storedDResp, coalOut.d.bits)
99+
in.bits.source := meta.bits
85100
}
86101
}
102+
// take a new D resp when there's nothing pending
103+
coalOut.d.ready := pendingDResp.asUInt === 0.U
104+
105+
coalSource.io.reclaim.valid := coalOut.d.fire
106+
coalSource.io.reclaim.bits := coalOut.d.bits.source
87107
}
88108
}
89109

src/main/scala/radiance/unittest/TLTrafficGen.scala

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package radiance.unittest
33
import chisel3._
44
import chisel3.util._
55
import chisel3.experimental.BundleLiterals._
6+
import chisel3.util.random.LFSR
67
import freechips.rocketchip.diplomacy.IdRange
78
import freechips.rocketchip.tilelink._
89
import org.chipsalliance.cde.config.Parameters
@@ -65,6 +66,7 @@ class TLTrafficGen(val nodeName: String, val sourceBits: Int,
6566
}
6667

6768
class TLTrafficGenImp(outer: TLTrafficGen) extends LazyModuleImp(outer) {
69+
val verificationMode = true
6870

6971
// elaboration time
7072
// ================
@@ -90,7 +92,10 @@ class TLTrafficGenImp(outer: TLTrafficGen) extends LazyModuleImp(outer) {
9092
val allFinished = Output(Bool())
9193
})
9294

93-
val sourceGen = Module(new SourceGenerator(outer.sourceBits))
95+
val sourceGen = Module(new SourceGenerator(
96+
sourceWidth = outer.sourceBits,
97+
metadata = Option.when(verificationMode)(UInt(tlNode.params.dataBits.W))
98+
))
9499

95100
val (reqCounter, reqWrap) = Counter(tlNode.a.fire, outer.n)
96101
val (patternCounter, patternWrap) = Counter(reqWrap, outer.patterns.length)
@@ -123,7 +128,17 @@ class TLTrafficGenImp(outer: TLTrafficGen) extends LazyModuleImp(outer) {
123128
tlEdge.Get(sourceGen.io.id.bits, storedReq.address, storedReq.lgSize)._2,
124129
)
125130

126-
tlNode.d.ready := true.B
131+
if (verificationMode) {
132+
sourceGen.io.meta.get := tlNode.a.bits.address.asTypeOf(sourceGen.io.meta.get)
133+
val readyGen = LFSR(width = 16, seed = Some(outer.nodeName.hashCode >>> 16))
134+
tlNode.d.ready := readyGen(0)
135+
when (tlNode.d.fire && (tlNode.d.bits.opcode === TLMessages.AccessAckData)) {
136+
assert(tlNode.d.bits.data === sourceGen.io.peek.get)
137+
}
138+
} else {
139+
tlNode.d.ready := true.B
140+
}
141+
127142
sourceGen.io.reclaim.valid := tlNode.d.fire
128143
sourceGen.io.reclaim.bits := tlNode.d.bits.source
129144

src/main/scala/radiance/unittest/TrafficPatterns.scala

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -141,22 +141,41 @@ object TrafficPatterns {
141141
Seq(0, 1).map(new RandomAccess(0, 131072 >> lgSize, _))
142142
}
143143

144+
// def smemPatterns(clusterId: Int, size: Int = 128 << 10) = {
145+
// Seq(("w", (x: TrafficPattern) => x.putSmem _),
146+
// ("r", (x: TrafficPattern) => x.getSmem _))
147+
// .flatMap { case (suffix, func) =>
148+
149+
// Seq(
150+
// stridedPatterns,
151+
// randomPatterns,
152+
// tiledPatterns,
153+
// tiledPatterns.map(Transposed(_)),
154+
// swizzledPatterns,
155+
// swizzledPatterns.map(Transposed(_)),
156+
// )
157+
// .flatten
158+
// .map(Bounded(_, size))
159+
// .map(x => (s"${x.name}_$suffix", func(x)(clusterId)))
160+
// }
161+
// }
162+
144163
def smemPatterns(clusterId: Int, size: Int = 128 << 10) = {
145-
Seq(("r", (x: TrafficPattern) => x.getSmem _),
146-
("w", (x: TrafficPattern) => x.putSmem _))
147-
.flatMap { case (suffix, func) =>
148-
149-
Seq(
150-
stridedPatterns,
151-
randomPatterns,
152-
tiledPatterns,
153-
tiledPatterns.map(Transposed(_)),
154-
swizzledPatterns,
155-
swizzledPatterns.map(Transposed(_)),
164+
Seq(
165+
stridedPatterns,
166+
randomPatterns,
167+
tiledPatterns,
168+
tiledPatterns.map(Transposed(_)),
169+
swizzledPatterns,
170+
swizzledPatterns.map(Transposed(_)),
171+
)
172+
.flatten
173+
.map(Bounded(_, size))
174+
.flatMap(x =>
175+
Seq(("w", (x: TrafficPattern) => x.putSmem _),
176+
("r", (x: TrafficPattern) => x.getSmem _)).map { case (suffix, func) =>
177+
(s"${x.name}_$suffix", func(x)(clusterId))
178+
}
156179
)
157-
.flatten
158-
.map(Bounded(_, size))
159-
.map(x => (s"${x.name}_$suffix", func(x)(clusterId)))
160-
}
161180
}
162181
}

0 commit comments

Comments
 (0)