Skip to content

Commit 733f0d9

Browse files
Fix commit (#199)
* refactor: flush with reg next * refactor: flush with reg next * block 1 more clock when interrupt * fix: connect error * refactor sth * fix: error when channel num = 1 in distribute queue * refactor: distribute queue for rob * fix rob id bug --------- Co-authored-by: Chrisqcwx <3075401625@qq.com>
1 parent 5ef5195 commit 733f0d9

File tree

9 files changed

+180
-110
lines changed

9 files changed

+180
-110
lines changed

src/src/CoreCpuTop.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ class CoreCpuTop extends Module {
280280
case (dst, src) =>
281281
dst <> src
282282
}
283+
commitStage.io.hasInterrupt := csr.io.hasInterrupt
283284

284285
// Register file (GPR file)
285286
regFile.io.writePorts <> cu.io.gprWritePassThroughPorts.out

src/src/control/Cu.scala

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -220,19 +220,25 @@ class Cu(
220220

221221
io.csrMessage.ertnFlush := isExceptionReturn // TODO: Make ERTN jump gracefully like branch instruction
222222
io.frontendFlush :=
223-
isException || io.branchExe.en || isTlbMaintenance || io.csrFlushRequest || cacopFlush || idleFlush || isExceptionReturn
223+
RegNext(
224+
isException || io.branchExe.en || isTlbMaintenance || io.csrFlushRequest || cacopFlush || idleFlush || isExceptionReturn,
225+
false.B
226+
)
224227
io.backendFlush := RegNext(
225228
isException || io.branchCommit || isTlbMaintenance || io.csrFlushRequest || cacopFlush || idleFlush || isExceptionReturn,
226229
false.B
227230
)
228-
io.idleFlush := idleFlush
231+
io.idleFlush := RegNext(idleFlush)
229232

230233
// Select new pc
231-
io.newPc := PcSetNdPort.default
232-
io.newPc.en :=
234+
val newPc = RegInit(PcSetNdPort.default)
235+
io.newPc := newPc
236+
237+
newPc := PcSetNdPort.default
238+
newPc.en :=
233239
isTlbMaintenance || io.csrFlushRequest || isException || io.branchExe.en || cacopFlush || idleFlush || isExceptionReturn
234-
io.newPc.isTlb := isTlbMaintenance
235-
io.newPc.pcAddr := Mux(
240+
newPc.isTlb := isTlbMaintenance
241+
newPc.pcAddr := Mux(
236242
isException,
237243
Mux(
238244
majorInstInfo.exceptionRecord === Csr.ExceptionIndex.tlbr,
@@ -250,11 +256,6 @@ class Cu(
250256
)
251257
)
252258

253-
val is_softwareInt = io.instInfoPorts(0).isValid &&
254-
io.instInfoPorts(0).csrWritePort.en &&
255-
(io.instInfoPorts(0).csrWritePort.addr === Csr.Index.estat) &&
256-
io.instInfoPorts(0).csrWritePort.data(1, 0).orR
257-
258259
io.difftest match {
259260
case Some(dt) =>
260261
dt.cmt_ertn := RegNext(isExceptionReturn)

src/src/pipeline/commit/CommitStage.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,16 @@ class CommitStage(
4040
// `CommitStage` -> `Cu` NO delay
4141
val isExceptionValid = Output(Bool())
4242

43+
val hasInterrupt = Input(Bool())
44+
4345
val difftest =
4446
if (isDiffTest)
4547
Some(Output(new Bundle {
4648
val valid = Bool()
4749
val pc = UInt(Width.Reg.data)
4850
val instr = UInt(Width.Reg.data)
49-
val is_TLBFILL = Bool() // TODO
50-
val TLBFILL_index = UInt(Width.Reg.addr) // TODO
51+
val is_TLBFILL = Bool()
52+
val TLBFILL_index = UInt(Width.Reg.addr)
5153
val wen = Bool()
5254
val wdest = UInt(Width.Reg.addr)
5355
val wdata = UInt(Width.Reg.data)
@@ -73,7 +75,7 @@ class CommitStage(
7375
else None
7476
})
7577

76-
io.ins.foreach(_.ready := true.B)
78+
io.ins.foreach(_.ready := !io.hasInterrupt)
7779

7880
val inBits = WireDefault(VecInit(io.ins.map(_.bits)))
7981

src/src/pipeline/common/DistributedQueue.scala

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@ class DistributedQueue[ElemT <: Data](
2020
val isFlush = Input(Bool())
2121
val enqueuePorts = Vec(enqMaxNum, Flipped(Decoupled(elemNdFactory)))
2222
val dequeuePorts = Vec(deqMaxNum, Decoupled(elemNdFactory))
23-
24-
// deq_ptr -> enq_ptr
25-
val enqIncResults = Output(Vec(enqMaxNum + 1, UInt(log2Ceil(channelNum).W)))
26-
val deqIncResults = Output(Vec(deqMaxNum + 1, UInt(log2Ceil(channelNum).W)))
27-
val enq_ptr = Output(UInt(log2Ceil(channelNum).W))
28-
val deq_ptr = Output(UInt(log2Ceil(channelNum).W))
2923
})
3024

3125
// Fallback
@@ -53,22 +47,14 @@ class DistributedQueue[ElemT <: Data](
5347

5448
storeOuts.foreach(_.ready := false.B)
5549
if (channelNum == 1) {
56-
storeOuts(0) <> storeIns(0)
50+
// storeOuts(0) <> storeIns(0)
51+
io.enqueuePorts(0) <> storeIns(0)
52+
io.dequeuePorts(0) <> storeOuts(0)
5753
} else {
5854
val enq_ptr = Module(new MultiCounter(channelNum, enqMaxNum))
5955
val deq_ptr = Module(new MultiCounter(channelNum, deqMaxNum))
6056
enq_ptr.io.flush := io.isFlush
6157
deq_ptr.io.flush := io.isFlush
62-
io.enq_ptr := enq_ptr.io.value
63-
io.deq_ptr := deq_ptr.io.value
64-
io.enqIncResults.zip(enq_ptr.io.incResults).foreach {
65-
case (dst, src) =>
66-
dst := src
67-
}
68-
io.deqIncResults.zip(deq_ptr.io.incResults).foreach {
69-
case (dst, src) =>
70-
dst := src
71-
}
7258

7359
enq_ptr.io.inc := io.enqueuePorts.zipWithIndex.map {
7460
case (enqPort, idx) =>
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package pipeline.common
2+
3+
import chisel3._
4+
import chisel3.util._
5+
import utils.MultiCounter
6+
import spec.Param
7+
8+
class DistributedQueuePlus[ElemT <: Data](
9+
enqMaxNum: Int,
10+
deqMaxNum: Int,
11+
channelNum: Int,
12+
channelLength: Int,
13+
elemNdFactory: => ElemT,
14+
blankElem: => ElemT,
15+
useSyncReadMem: Boolean = true)
16+
extends Module {
17+
18+
require(channelNum >= enqMaxNum)
19+
require(channelNum >= deqMaxNum)
20+
require(log2Ceil(channelNum) == log2Floor(channelNum))
21+
val channelNumWidth = log2Ceil(channelNum)
22+
23+
val io = IO(new Bundle {
24+
val isFlush = Input(Bool())
25+
val enqueuePorts = Vec(enqMaxNum, Flipped(Decoupled(elemNdFactory)))
26+
val dequeuePorts = Vec(deqMaxNum, Decoupled(elemNdFactory))
27+
28+
// deq_ptr -> enq_ptr
29+
val enqIncResults = Output(Vec(enqMaxNum + 1, UInt(log2Ceil(channelLength * channelNum).W)))
30+
val deqIncResults = Output(Vec(deqMaxNum + 1, UInt(log2Ceil(channelLength * channelNum).W)))
31+
// val deqIncResults = Output(Vec(deqMaxNum + 1, UInt(log2Ceil(channelLength * channelNum).W)))
32+
// val enq_ptr = Output(UInt(log2Ceil(channelLength * channelNum).W))
33+
// val deq_ptr = Output(UInt(log2Ceil(channelLength * channelNum).W))
34+
35+
val elems = Output(Vec(channelLength * channelNum, elemNdFactory))
36+
val setPorts = Input(Vec(channelLength * channelNum, Valid(elemNdFactory)))
37+
})
38+
39+
// Fallback
40+
io.dequeuePorts.foreach(_ <> DontCare)
41+
io.enqueuePorts.foreach(_.ready := false.B)
42+
io.dequeuePorts.foreach(_.valid := false.B)
43+
44+
// val storeIns = Wire(Vec(channelNum, (DecoupledIO(elemNdFactory))))
45+
46+
val queues = Seq.fill(channelNum)(
47+
Module(
48+
new MultiQueue(
49+
channelLength,
50+
1,
51+
1,
52+
elemNdFactory,
53+
blankElem,
54+
writeFirst = false
55+
)
56+
)
57+
)
58+
queues.foreach(_.io.isFlush := io.isFlush)
59+
60+
val storeIns = VecInit(queues.map(_.io.enqueuePorts(0)))
61+
val storeOuts = VecInit(queues.map(_.io.dequeuePorts(0)))
62+
63+
for (i <- 0 until channelLength) {
64+
for (j <- 0 until channelNum) {
65+
val idx = i * channelLength + j
66+
io.elems(idx) := queues(j).io.elems(i)
67+
queues(j).io.setPorts(i) := io.setPorts(idx)
68+
}
69+
}
70+
71+
storeIns.foreach { in =>
72+
in.valid := false.B
73+
in.bits := DontCare
74+
}
75+
76+
storeOuts.foreach(_.ready := false.B)
77+
if (channelNum == 1) {
78+
io.enqueuePorts(0) <> storeIns(0)
79+
io.dequeuePorts(0) <> storeOuts(0)
80+
} else {
81+
val enq_ptr = Module(new MultiCounter(channelLength * channelNum, enqMaxNum))
82+
val deq_ptr = Module(new MultiCounter(channelLength * channelNum, deqMaxNum))
83+
84+
enq_ptr.io.flush := io.isFlush
85+
deq_ptr.io.flush := io.isFlush
86+
// io.enq_ptr := enq_ptr.io.value
87+
// io.deq_ptr := deq_ptr.io.value
88+
// io.enqIncResults.zip(enq_ptr.io.incResults).foreach {
89+
// case (dst, src) =>
90+
// dst := src
91+
// }
92+
// io.deqIncResults.zip(deq_ptr.io.incResults).foreach {
93+
// case (dst, src) =>
94+
// dst := src
95+
// }
96+
io.enqIncResults.zipWithIndex.foreach {
97+
case (dst, idx) =>
98+
dst := enq_ptr.io.incResults(idx)
99+
}
100+
io.deqIncResults.zipWithIndex.foreach {
101+
case (dst, idx) =>
102+
dst := deq_ptr.io.incResults(idx)
103+
}
104+
105+
enq_ptr.io.inc := io.enqueuePorts.zipWithIndex.map {
106+
case (enqPort, idx) =>
107+
// connect
108+
enqPort <> storeIns(enq_ptr.io.incResults(idx)(channelNumWidth - 1, 0))
109+
// return
110+
enqPort.valid && storeIns(enq_ptr.io.incResults(idx)(channelNumWidth - 1, 0)).ready
111+
}.map(_.asUInt).reduce(_ +& _)
112+
113+
deq_ptr.io.inc := io.dequeuePorts.zipWithIndex.map {
114+
case (deqPort, idx) =>
115+
// connect
116+
deqPort <> storeOuts(deq_ptr.io.incResults(idx)(channelNumWidth - 1, 0))
117+
// return
118+
deqPort.valid && storeOuts(deq_ptr.io.incResults(idx)(channelNumWidth - 1, 0)).ready
119+
}.map(_.asUInt).reduce(_ +& _)
120+
}
121+
}

src/src/pipeline/dispatch/RenameStage.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,13 @@ class RenameStage(
246246
}
247247

248248
when(peer.branchFlush) {
249-
peer.requests.foreach(_.en := false.B)
249+
// peer.requests.foreach(_.en := false.B)
250250
io.ins.foreach(_.ready := false.B)
251251
fetchEnableFlag := false.B
252252
}
253253

254254
when(io.isFlush) {
255-
peer.requests.foreach(_.en := false.B)
255+
// peer.requests.foreach(_.en := false.B)
256256
io.ins.foreach(_.ready := false.B)
257257
fetchEnableFlag := true.B
258258
}

src/src/pipeline/rob/Rob.scala

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import pipeline.common.MultiQueue
99
import pipeline.rob.bundles._
1010
import pipeline.rob.enums.{RegDataLocateSel, RobDistributeSel, RobInstState => State}
1111
import spec._
12+
import pipeline.common.DistributedQueuePlus
1213

1314
// assert: commits cannot ready 1 but not 0
1415
class Rob(
@@ -57,15 +58,28 @@ class Rob(
5758

5859
val matchTable = RegInit(VecInit(Seq.fill(spec.Count.reg)(RobMatchBundle.default)))
5960

61+
// val queue = Module(
62+
// new MultiQueue(
63+
// robLength,
64+
// issueNum,
65+
// commitNum,
66+
// new RobInstStoreBundle,
67+
// RobInstStoreBundle.default
68+
// )
69+
// )
70+
6071
val queue = Module(
61-
new MultiQueue(
62-
robLength,
72+
new DistributedQueuePlus(
6373
issueNum,
6474
commitNum,
75+
Param.Width.Rob._channelNum,
76+
Param.Width.Rob._channelLength,
6577
new RobInstStoreBundle,
66-
RobInstStoreBundle.default
78+
RobInstStoreBundle.default,
79+
useSyncReadMem = false
6780
)
6881
)
82+
6983
queue.io.enqueuePorts.foreach { port =>
7084
port.valid := false.B
7185
port.bits := DontCare
@@ -77,7 +91,7 @@ class Rob(
7791
}
7892
queue.io.dequeuePorts.foreach(_.ready := false.B)
7993
queue.io.isFlush := io.isFlush
80-
io.emptyNum := queue.io.emptyNum
94+
io.emptyNum := VecInit(queue.io.enqueuePorts.map(_.ready.asUInt)).reduceTree(_ +& _)
8195
io.instWbBroadCasts.zip(io.finishInsts).foreach {
8296
case (dst, src) =>
8397
dst.en := src.valid // && io.robInstValids(src.bits.instInfo.robId)
@@ -91,9 +105,9 @@ class Rob(
91105
io.finishInsts.foreach { finishInst =>
92106
finishInst.ready := true.B
93107
when(finishInst.valid && finishInst.bits.instInfo.isValid) {
94-
queue.io.elemValids.lazyZip(queue.io.elems).lazyZip(queue.io.setPorts).zipWithIndex.foreach {
95-
case ((elemValid, elem, set), idx) =>
96-
when(elemValid && elem.state === State.busy && idx.U === finishInst.bits.instInfo.robId) {
108+
queue.io.elems.lazyZip(queue.io.setPorts).zipWithIndex.foreach {
109+
case ((elem, set), idx) =>
110+
when(elem.state === State.busy && idx.U === finishInst.bits.instInfo.robId) {
97111
set.valid := true.B
98112
set.bits.isValid := elem.isValid
99113
set.bits.state := State.ready
@@ -138,8 +152,9 @@ class Rob(
138152
!deqPort.bits.wbPort.instInfo.forbidParallelCommit &&
139153
queue.io.dequeuePorts(idx - 1).valid &&
140154
queue.io.dequeuePorts(idx - 1).ready && // promise commit in order
141-
!hasInterruptReg &&
142-
!io.hasInterrupt
155+
!hasInterruptReg
156+
// &&
157+
// !io.hasInterrupt
143158
}
144159

145160
commit.valid := deqPort.ready
@@ -159,12 +174,12 @@ class Rob(
159174
}
160175

161176
when(io.hasInterrupt) {
162-
when(io.commits(0).valid && io.commits(0).ready) {
163-
io.commits(0).bits.instInfo.exceptionRecord := Csr.ExceptionIndex.int
164-
io.commits(0).bits.instInfo.exceptionPos := ExceptionPos.backend
165-
}.otherwise {
166-
hasInterruptReg := true.B
167-
}
177+
// when(io.commits(0).valid && io.commits(0).ready) {
178+
// io.commits(0).bits.instInfo.exceptionRecord := Csr.ExceptionIndex.int
179+
// io.commits(0).bits.instInfo.exceptionPos := ExceptionPos.backend
180+
// }.otherwise {
181+
hasInterruptReg := true.B
182+
// }
168183
}.elsewhen(hasInterruptReg && io.commits(0).valid && io.commits(0).ready) {
169184
hasInterruptReg := false.B
170185
io.commits(0).bits.instInfo.exceptionRecord := Csr.ExceptionIndex.int
@@ -241,8 +256,8 @@ class Rob(
241256
*/
242257

243258
when(io.isFlush) {
244-
queue.io.enqueuePorts.foreach(_.valid := false.B)
245-
io.commits.foreach(_.valid := false.B)
259+
// queue.io.enqueuePorts.foreach(_.valid := false.B)
260+
// io.commits.foreach(_.valid := false.B)
246261
matchTable.foreach(_.locate := RegDataLocateSel.regfile)
247262
}
248263
}

src/src/spec/Param.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ object Param {
3636
val exeOp = log2Ceil(ExeInst.Op.count + 1).W
3737

3838
object Rob {
39-
val _length = 16
40-
val id = log2Ceil(_length).W
39+
val _length = 16
40+
val _channelNum = 4
41+
val _channelLength = _length / _channelNum
42+
val id = log2Ceil(_length).W
4143
}
4244

4345
object Axi {

0 commit comments

Comments
 (0)