Skip to content

Commit 784bbdd

Browse files
committed
scoreboard: Simplify overflow/underflow arithmetic
1 parent fc51b11 commit 784bbdd

2 files changed

Lines changed: 25 additions & 28 deletions

File tree

src/main/scala/radiance/muon/Scoreboard.scala

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -190,29 +190,26 @@ class Scoreboard(implicit p: Parameters) extends CoreModule()(p) {
190190
// if currCount + u.incr overflows but u.decr cancels it out, treat
191191
// it as a success.
192192
when (u.incr =/= u.decr) {
193-
val delta = u.incr.pad(u.incr.getWidth + 1).asSInt -& u.decr.pad(u.decr.getWidth + 1).asSInt
194-
val currCountWide = currCount.pad(currCount.getWidth + 1)
195-
val newCountWide = currCountWide.asSInt + delta
196-
val maxCountWide = maxCount.pad(newCountWide.getWidth).asSInt
197-
printf(cf"applyUpdates: [${debug}] ${countName} pReg:${u.pReg}, newCount: ${newCountWide}, currCount: ${currCountWide}, incr:${u.incr}(${u.incr.getWidth}W), decr:${u.decr}(${u.decr.getWidth}W), delta:${delta}(${delta.getWidth}W)\n")
198-
when (newCountWide > maxCountWide) {
199-
success := false.B
200-
// ignore incr and just reflect decr
201-
dirtied := (u.decr =/= 0.U)
202-
assert(currCountWide >= u.decr,
203-
cf"scoreboard: ${countName} underflow at pReg=${u.pReg} " +
204-
cf"(currCount=${currCountWide}, incr=${u.incr}, decr=${u.decr}) ")
205-
newCount := currCountWide - u.decr
206-
}.otherwise {
207-
dirtied := true.B
208-
// underflow should never be possible since the number of retired
209-
// regs should strictly be smaller than the pending regs, i.e. no
210-
// over-commit beyond what's issued
211-
assert(newCountWide >= 0.S,
212-
cf"scoreboard: ${countName} underflow at pReg:${u.pReg} " +
213-
cf"(newCount:${newCountWide}, oldCount:${currCountWide} (width ${currCountWide.getWidth}), maxCount:${maxCountWide}, incr:${u.incr}, decr:${u.decr})")
214-
newCount := newCountWide.asUInt
193+
// stay positive (literally)
194+
val posDelta = (u.incr > u.decr)
195+
val overflow = posDelta && ((u.incr - u.decr) > (maxCount - currCount))
196+
val underflow = !posDelta && (u.decr - u.incr) > currCount
197+
198+
success := !overflow && !underflow
199+
dirtied := success
200+
when (success) {
201+
newCount := currCount + u.incr - u.decr
215202
}
203+
204+
printf(cf"applyUpdates: [${debug}] ${countName} pReg:${u.pReg}, newCount:${newCount}, currCount:${currCount}, incr:${u.incr}(${u.incr.getWidth}W), decr:${u.decr}(${u.decr.getWidth}W), success:${success}\n")
205+
206+
// underflow should never be possible since the number of retired
207+
// regs should strictly be smaller than the pending regs, i.e. no
208+
// over-commit beyond what's issued
209+
//
210+
// assert(!underflow,
211+
// cf"scoreboard: ${countName} underflow at pReg=${u.pReg} " +
212+
// cf"(currCount=${currCount}, incr=${u.incr}, decr=${u.decr})")
216213
}.elsewhen (u.incr === u.decr && u.incr =/= 0.U) {
217214
printf(cf"applyUpdates: [${debug}] ${countName} incr/decr cancel; pReg:${u.pReg}, newCount: ${newCount}, currCount: ${currCount}(${currCount.getWidth}W), incr:${u.incr}(${u.incr.getWidth}W), decr:${u.decr}(${u.decr.getWidth}W)\n")
218215
}
@@ -230,7 +227,7 @@ class Scoreboard(implicit p: Parameters) extends CoreModule()(p) {
230227
val uniqWBWriteUpdates = consolidateUpdates(Seq(io.updateWB.write))
231228
val (collReadRecs, collSuccess) = applyUpdates(Seq(), uniqCollReadUpdates, isWrite = false, debug = "coll")
232229
val (wbWriteRecs, wbSuccess) = applyUpdates(Seq(), uniqWBWriteUpdates, isWrite = true, debug = "wb")
233-
assert(collSuccess && wbSuccess, "scoreboard: collector / WB update must always succeed!")
230+
// assert(collSuccess && wbSuccess, "scoreboard: collector / WB update must always succeed!")
234231

235232
// RS admission updates
236233
val uniqRSReadUpdates = consolidateUpdates(io.updateRS.reads)
@@ -241,8 +238,8 @@ class Scoreboard(implicit p: Parameters) extends CoreModule()(p) {
241238
dontTouch(rsSuccess)
242239

243240
io.updateRS.success := io.updateRS.enable && rsSuccess
244-
io.updateWB.success := collSuccess
245-
io.updateColl.success := wbSuccess
241+
io.updateWB.success := wbSuccess
242+
io.updateColl.success := collSuccess
246243

247244
when (io.updateRS.enable || io.updateWB.enable || io.updateColl.enable) {
248245
when (io.updateRS.enable) {

src/test/scala/radiance/ScoreboardTest.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class ScoreboardTest extends AnyFlatSpec {
112112
}
113113
}
114114

115-
it should "not increment if both incr and decr at the same time" in {
115+
it should "not increment if incr and decr cancels each other" in {
116116
val p = testParams()
117117
simulate(new Scoreboard()(p)) { c =>
118118
reset(c)
@@ -154,7 +154,7 @@ class ScoreboardTest extends AnyFlatSpec {
154154
}
155155
}
156156

157-
it should "fail if pendingReads counter has saturated" in {
157+
it should "fail if pendingReads counter has overflown" in {
158158
val p = testParams()
159159
val m = p(MuonKey)
160160
simulate(new Scoreboard()(p)) { c =>
@@ -179,7 +179,7 @@ class ScoreboardTest extends AnyFlatSpec {
179179
}
180180
}
181181

182-
it should "fail if pendingWrites counter has saturated" in {
182+
it should "fail if pendingWrites counter has overflown" in {
183183
val p = testParams()
184184
simulate(new Scoreboard()(p)) { c =>
185185
reset(c)

0 commit comments

Comments
 (0)