Skip to content

Commit 6be0177

Browse files
committed
make dirty lines also update metadata, fix tlc to tlul logic
1 parent 33b0631 commit 6be0177

3 files changed

Lines changed: 60 additions & 61 deletions

File tree

src/main/scala/radiance/memory/MuonDCache.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class CacheFlushUnit(implicit edge: TLEdgeOut, p: Parameters) extends L1HellaCac
8383
val wrap = flushCounter.inc()
8484
when (wrap) {
8585
flushing := false.B
86+
printf("CACHE FLUSH COMPLETE!\n")
8687
}
8788
}
8889

@@ -114,22 +115,25 @@ class CacheFlushUnit(implicit edge: TLEdgeOut, p: Parameters) extends L1HellaCac
114115
val (isDirty, respType, nextCoh) = meta.coh.onCacheControl(M_FLUSH)
115116
// invalid line gets automatically skipped
116117

117-
// clean line: invalidate in tag array only
118-
io.meta_write.valid := metaValid && meta.coh.isValid() && !isDirty
118+
// valid line: invalidate in tag array
119+
// need double fire for dirty lines
120+
io.meta_write.valid := metaValid && meta.coh.isValid() && (!isDirty || io.wb_req.ready)
119121
io.meta_write.bits.way_en := metaReq.way_en
120122
io.meta_write.bits.idx := metaReq.idx
121123
io.meta_write.bits.tag := meta.tag
122124
io.meta_write.bits.data.tag := meta.tag
123125
io.meta_write.bits.data.coh := nextCoh
124126

125127
// dirty line: send a writeback request with voluntary release
126-
io.wb_req.valid := metaValid && meta.coh.isValid() && isDirty
128+
io.wb_req.valid := metaValid && meta.coh.isValid() && isDirty && io.meta_write.ready
127129
io.wb_req.bits.idx := metaReq.idx
128130
io.wb_req.bits.tag := meta.tag
129131
io.wb_req.bits.source := 0.U // TODO: does this work??
130132
io.wb_req.bits.param := respType
131133
io.wb_req.bits.way_en := metaReq.way_en
132134
io.wb_req.bits.voluntary := true.B
135+
136+
assert(!io.wb_req.fire || io.meta_write.fire)
133137
}
134138

135139
class MuonNonBlockingDCache(staticIdForMetadataUseOnly: Int,

src/main/scala/radiance/memory/TLNBDCache.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ class TLNBDCacheModule(outer: TLNBDCache)(implicit p: Parameters) extends LazyMo
226226
when (valid) {
227227
fio.start := true.B
228228
}
229-
!fio.busy
229+
true.B
230+
// !fio.busy
230231
})),
231232
)
232233
}

src/main/scala/radiance/memory/TLULNBDCache.scala

Lines changed: 51 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,57 @@ class TLCToTLULNode(beatBytes: Int)(implicit p: Parameters) extends LazyModule {
3535
}
3636
)
3737
lazy val module = new LazyModuleImp(this) {
38-
(node.in.map(_._1) zip node.out.map(_._1)).foreach { case (i, o) =>
38+
(node.in.map(_._1) zip node.out).foreach { case (tlIn, (tlOut, oe)) =>
3939
// out (ul) has no E bundle, but in (c) does
40-
o.a <> i.a
41-
i.b <> o.b
42-
o.c <> i.c
43-
i.d <> o.d
4440

45-
i.e.ready := true.B
41+
tlOut.a.valid := tlIn.a.valid || tlIn.c.valid
42+
tlIn.a.ready := tlOut.a.ready && (!tlIn.c.valid) // C channel has priority over A
43+
tlOut.a.bits := tlIn.a.bits
44+
when (tlIn.c.valid) {
45+
tlOut.a.bits := oe.Put(tlIn.c.bits.source, tlIn.c.bits.address, tlIn.c.bits.size, tlIn.c.bits.data)._2
46+
tlOut.a.bits.source := tlIn.c.bits.source
47+
// tlOut.a.bits.data := tlIn.c.bits.data
48+
// tlOut.a.bits.size := tlIn.c.bits.size
49+
}
50+
// C channel ReleaseData translates to PutFull, A channel AcquireBlock translates to Get
51+
tlOut.a.bits.opcode := Mux(tlIn.c.valid, TLMessages.PutFullData, TLMessages.Get)
52+
// squash A channel param to 0 (normally represents permission change, we don't want this)
53+
tlOut.a.bits.param := 0.U
54+
55+
assert(!tlIn.a.valid || (tlIn.a.bits.opcode === TLMessages.AcquireBlock))
56+
assert(!tlIn.c.valid || (tlIn.c.bits.opcode === TLMessages.ReleaseData))
57+
58+
assert(!tlOut.b.valid, "no probes allowed")
59+
60+
tlOut.c.valid := false.B
61+
tlOut.c.bits := DontCare
62+
tlIn.c.ready := tlOut.a.ready // priority over A
63+
64+
tlIn.d.valid := tlOut.d.valid
65+
tlIn.d.bits := tlOut.d.bits
66+
tlIn.d.bits.opcode := Mux(tlOut.d.bits.opcode === TLMessages.AccessAckData,
67+
TLMessages.GrantData, // response for A channel AcquireBlock
68+
TLMessages.ReleaseAck // response for C channel ReleaseData
69+
)
70+
tlIn.d.bits.sink := Counter(
71+
tlIn.d.fire && tlIn.d.bits.opcode === TLMessages.GrantData,
72+
1 << tlIn.params.sinkBits)._1
73+
tlOut.d.ready := tlIn.d.ready
74+
75+
tlOut.e.valid := false.B
76+
tlOut.e.bits := DontCare
77+
tlIn.e.ready := true.B // silently sink GrantAck's
78+
79+
dontTouch(tlIn.a)
80+
dontTouch(tlIn.b)
81+
dontTouch(tlIn.c)
82+
dontTouch(tlIn.d)
83+
dontTouch(tlIn.e)
84+
dontTouch(tlOut.a)
85+
dontTouch(tlOut.b)
86+
dontTouch(tlOut.c)
87+
dontTouch(tlOut.d)
88+
dontTouch(tlOut.e)
4689
}
4790
}
4891
}
@@ -69,56 +112,7 @@ class TLULNBDCacheModule(outer: TLULNBDCache) extends LazyModuleImp(outer)
69112

70113
require(outer.outNode.in.length == 1, s"tlcOutNode has ${outer.outNode.in.length} inputs")
71114

72-
val (tlIn, _) = outer.outNode.in.head
73-
val (tlOut, oe) = outer.outNode.out.head
74-
75-
tlOut.a.valid := tlIn.a.valid || tlIn.c.valid
76-
tlIn.a.ready := tlOut.a.ready && (!tlIn.c.valid) // C channel has priority over A
77-
tlOut.a.bits := tlIn.a.bits
78-
when (tlIn.c.valid) {
79-
tlOut.a.bits := oe.Put(tlIn.c.bits.source, tlIn.c.bits.address, tlIn.c.bits.size, tlIn.c.bits.data)._2
80-
tlOut.a.bits.source := tlIn.c.bits.source
81-
// tlOut.a.bits.data := tlIn.c.bits.data
82-
// tlOut.a.bits.size := tlIn.c.bits.size
83-
}
84-
// C channel ReleaseData translates to PutFull, A channel AcquireBlock translates to Get
85-
tlOut.a.bits.opcode := Mux(tlIn.c.valid, TLMessages.PutFullData, TLMessages.Get)
86-
// squash A channel param to 0 (normally represents permission change, we don't want this)
87-
tlOut.a.bits.param := 0.U
88-
89-
assert(!tlIn.a.valid || (tlIn.a.bits.opcode === TLMessages.AcquireBlock))
90-
assert(!tlIn.c.valid || (tlIn.c.bits.opcode === TLMessages.ReleaseData))
91-
92-
assert(!tlOut.b.valid, "no probes allowed")
93-
94-
tlOut.c.valid := false.B
95-
tlOut.c.bits := DontCare
96-
tlIn.c.ready := tlOut.a.ready // priority over A
97-
98-
tlIn.d.valid := tlOut.d.valid
99-
tlIn.d.bits := tlOut.d.bits
100-
tlIn.d.bits.opcode := Mux(tlOut.d.bits.opcode === TLMessages.AccessAckData,
101-
TLMessages.GrantData, // response for A channel AcquireBlock
102-
TLMessages.ReleaseAck // response for C channel ReleaseData
103-
)
104-
tlIn.d.bits.sink := Counter(
105-
tlIn.d.fire && tlIn.d.bits.opcode === TLMessages.GrantData,
106-
1 << tlIn.params.sinkBits)._1
107-
tlOut.d.ready := tlIn.d.ready
108-
109-
tlOut.e.valid := false.B
110-
tlOut.e.bits := DontCare
111-
tlIn.e.ready := true.B // silently sink GrantAck's
112-
113-
dontTouch(tlIn.a)
114-
dontTouch(tlIn.b)
115-
dontTouch(tlIn.c)
116-
dontTouch(tlIn.d)
117-
dontTouch(tlIn.e)
118-
dontTouch(tlOut.a)
119-
dontTouch(tlOut.b)
120-
dontTouch(tlOut.c)
121-
dontTouch(tlOut.d)
122-
dontTouch(tlOut.e)
115+
// val (tlIn, _) = outer.outNode.in.head
116+
// val (tlOut, oe) = outer.outNode.out.head
123117
}
124118

0 commit comments

Comments
 (0)