Rob.scala (ef8fa011e9c69f5312d71d3d10bc9f67a1d54834) Rob.scala (839e5512b11a14daed2f8e8e654ac047f4cc50ae)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8* http://license.coscl.org.cn/MulanPSL2

--- 7 unchanged lines hidden (view full) ---

16
17package xiangshan.backend.rob
18
19import chipsalliance.rocketchip.config.Parameters
20import chisel3._
21import chisel3.util._
22import difftest._
23import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8* http://license.coscl.org.cn/MulanPSL2

--- 7 unchanged lines hidden (view full) ---

16
17package xiangshan.backend.rob
18
19import chipsalliance.rocketchip.config.Parameters
20import chisel3._
21import chisel3.util._
22import difftest._
23import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
24import utility._
25import utils._
24import utils._
25import utility._
26import xiangshan._
26import xiangshan._
27import xiangshan.backend.BackendParams
28import xiangshan.backend.Bundles.{DynInst, ExceptionInfo, ExuOutput}
29import xiangshan.backend.fu.FuType
27import xiangshan.backend.SnapshotGenerator
28import xiangshan.backend.exu.ExuConfig
30import xiangshan.frontend.FtqPtr
29import xiangshan.frontend.FtqPtr
31import xiangshan.mem.{LqPtr, LsqEnqIO, SqPtr}
32import xiangshan.backend.Bundles.{DynInst, ExceptionInfo, ExuOutput}
33import xiangshan.backend.ctrlblock.{DebugLSIO, DebugLsInfo, LsTopdownInfo}
34import xiangshan.backend.rename.SnapshotGenerator
30import xiangshan.mem.{LsqEnqIO, LqPtr}
35
31
36class RobPtr(entries: Int) extends CircularQueuePtr[RobPtr](
37 entries
38) with HasCircularQueuePtrHelper {
32class DebugMdpInfo(implicit p: Parameters) extends XSBundle{
33 val ssid = UInt(SSIDWidth.W)
34 val waitAllStore = Bool()
35}
39
36
40 def this()(implicit p: Parameters) = this(p(XSCoreParamsKey).RobSize)
37class DebugLsInfo(implicit p: Parameters) extends XSBundle {
38 val s1 = new Bundle {
39 val isTlbFirstMiss = Bool() // in s1
40 val isBankConflict = Bool() // in s1
41 val isLoadToLoadForward = Bool()
42 val isReplayFast = Bool()
43 }
44 val s2 = new Bundle{
45 val isDcacheFirstMiss = Bool() // in s2 (predicted result is in s1 when using WPU, real result is in s2)
46 val isForwardFail = Bool() // in s2
47 val isReplaySlow = Bool()
48 val isLoadReplayTLBMiss = Bool()
49 val isLoadReplayCacheMiss = Bool()
50 }
51 val replayCnt = UInt(XLEN.W)
41
52
53 def s1SignalEnable(ena: DebugLsInfo) = {
54 when(ena.s1.isTlbFirstMiss) { s1.isTlbFirstMiss := true.B }
55 when(ena.s1.isBankConflict) { s1.isBankConflict := true.B }
56 when(ena.s1.isLoadToLoadForward) { s1.isLoadToLoadForward := true.B }
57 when(ena.s1.isReplayFast) {
58 s1.isReplayFast := true.B
59 replayCnt := replayCnt + 1.U
60 }
61 }
62
63 def s2SignalEnable(ena: DebugLsInfo) = {
64 when(ena.s2.isDcacheFirstMiss) { s2.isDcacheFirstMiss := true.B }
65 when(ena.s2.isForwardFail) { s2.isForwardFail := true.B }
66 when(ena.s2.isLoadReplayTLBMiss) { s2.isLoadReplayTLBMiss := true.B }
67 when(ena.s2.isLoadReplayCacheMiss) { s2.isLoadReplayCacheMiss := true.B }
68 when(ena.s2.isReplaySlow) {
69 s2.isReplaySlow := true.B
70 replayCnt := replayCnt + 1.U
71 }
72 }
73
74}
75object DebugLsInfo {
76 def init(implicit p: Parameters): DebugLsInfo = {
77 val lsInfo = Wire(new DebugLsInfo)
78 lsInfo.s1.isTlbFirstMiss := false.B
79 lsInfo.s1.isBankConflict := false.B
80 lsInfo.s1.isLoadToLoadForward := false.B
81 lsInfo.s1.isReplayFast := false.B
82 lsInfo.s2.isDcacheFirstMiss := false.B
83 lsInfo.s2.isForwardFail := false.B
84 lsInfo.s2.isReplaySlow := false.B
85 lsInfo.s2.isLoadReplayTLBMiss := false.B
86 lsInfo.s2.isLoadReplayCacheMiss := false.B
87 lsInfo.replayCnt := 0.U
88 lsInfo
89 }
90
91}
92class DebugLsInfoBundle(implicit p: Parameters) extends DebugLsInfo {
93 // unified processing at the end stage of load/store ==> s2 ==> bug that will write error robIdx data
94 val s1_robIdx = UInt(log2Ceil(RobSize).W)
95 val s2_robIdx = UInt(log2Ceil(RobSize).W)
96}
97class DebugLSIO(implicit p: Parameters) extends XSBundle {
98 val debugLsInfo = Vec(exuParameters.LduCnt + exuParameters.StuCnt, Output(new DebugLsInfoBundle))
99}
100
101class LsTopdownInfo(implicit p: Parameters) extends XSBundle {
102 val s1 = new Bundle {
103 val robIdx = UInt(log2Ceil(RobSize).W)
104 val vaddr_valid = Bool()
105 val vaddr_bits = UInt(VAddrBits.W)
106 }
107 val s2 = new Bundle {
108 val robIdx = UInt(log2Ceil(RobSize).W)
109 val paddr_valid = Bool()
110 val paddr_bits = UInt(PAddrBits.W)
111 }
112
113 def s1SignalEnable(ena: LsTopdownInfo) = {
114 when(ena.s1.vaddr_valid) {
115 s1.vaddr_valid := true.B
116 s1.vaddr_bits := ena.s1.vaddr_bits
117 }
118 }
119
120 def s2SignalEnable(ena: LsTopdownInfo) = {
121 when(ena.s2.paddr_valid) {
122 s2.paddr_valid := true.B
123 s2.paddr_bits := ena.s2.paddr_bits
124 }
125 }
126}
127
128object LsTopdownInfo {
129 def init(implicit p: Parameters): LsTopdownInfo = 0.U.asTypeOf(new LsTopdownInfo)
130}
131
132class RobPtr(implicit p: Parameters) extends CircularQueuePtr[RobPtr](
133 p => p(XSCoreParamsKey).RobSize
134) with HasCircularQueuePtrHelper {
135
42 def needFlush(redirect: Valid[Redirect]): Bool = {
43 val flushItself = redirect.bits.flushItself() && this === redirect.bits.robIdx
44 redirect.valid && (flushItself || isAfter(this, redirect.bits.robIdx))
45 }
46
47 def needFlush(redirect: Seq[Valid[Redirect]]): Bool = VecInit(redirect.map(needFlush)).asUInt.orR
48}
49

--- 8 unchanged lines hidden (view full) ---

58
59class RobCSRIO(implicit p: Parameters) extends XSBundle {
60 val intrBitSet = Input(Bool())
61 val trapTarget = Input(UInt(VAddrBits.W))
62 val isXRet = Input(Bool())
63 val wfiEvent = Input(Bool())
64
65 val fflags = Output(Valid(UInt(5.W)))
136 def needFlush(redirect: Valid[Redirect]): Bool = {
137 val flushItself = redirect.bits.flushItself() && this === redirect.bits.robIdx
138 redirect.valid && (flushItself || isAfter(this, redirect.bits.robIdx))
139 }
140
141 def needFlush(redirect: Seq[Valid[Redirect]]): Bool = VecInit(redirect.map(needFlush)).asUInt.orR
142}
143

--- 8 unchanged lines hidden (view full) ---

152
153class RobCSRIO(implicit p: Parameters) extends XSBundle {
154 val intrBitSet = Input(Bool())
155 val trapTarget = Input(UInt(VAddrBits.W))
156 val isXRet = Input(Bool())
157 val wfiEvent = Input(Bool())
158
159 val fflags = Output(Valid(UInt(5.W)))
66 val vxsat = Output(Valid(Bool()))
67 val dirty_fs = Output(Bool())
68 val perfinfo = new Bundle {
69 val retiredInstr = Output(UInt(3.W))
70 }
160 val dirty_fs = Output(Bool())
161 val perfinfo = new Bundle {
162 val retiredInstr = Output(UInt(3.W))
163 }
71
72 val vcsrFlag = Output(Bool())
73}
74
75class RobLsqIO(implicit p: Parameters) extends XSBundle {
76 val lcommit = Output(UInt(log2Up(CommitWidth + 1).W))
77 val scommit = Output(UInt(log2Up(CommitWidth + 1).W))
78 val pendingld = Output(Bool())
79 val pendingst = Output(Bool())
80 val commit = Output(Bool())
81 val pendingPtr = Output(new RobPtr)
82
83 val mmio = Input(Vec(LoadPipelineWidth, Bool()))
164}
165
166class RobLsqIO(implicit p: Parameters) extends XSBundle {
167 val lcommit = Output(UInt(log2Up(CommitWidth + 1).W))
168 val scommit = Output(UInt(log2Up(CommitWidth + 1).W))
169 val pendingld = Output(Bool())
170 val pendingst = Output(Bool())
171 val commit = Output(Bool())
172 val pendingPtr = Output(new RobPtr)
173
174 val mmio = Input(Vec(LoadPipelineWidth, Bool()))
84 val uop = Input(Vec(LoadPipelineWidth, new DynInst))
175 val uop = Input(Vec(LoadPipelineWidth, new MicroOp))
85}
86
87class RobEnqIO(implicit p: Parameters) extends XSBundle {
88 val canAccept = Output(Bool())
89 val isEmpty = Output(Bool())
90 // valid vector, for robIdx gen and walk
91 val needAlloc = Vec(RenameWidth, Input(Bool()))
176}
177
178class RobEnqIO(implicit p: Parameters) extends XSBundle {
179 val canAccept = Output(Bool())
180 val isEmpty = Output(Bool())
181 // valid vector, for robIdx gen and walk
182 val needAlloc = Vec(RenameWidth, Input(Bool()))
92 val req = Vec(RenameWidth, Flipped(ValidIO(new DynInst)))
183 val req = Vec(RenameWidth, Flipped(ValidIO(new MicroOp)))
93 val resp = Vec(RenameWidth, Output(new RobPtr))
94}
95
184 val resp = Vec(RenameWidth, Output(new RobPtr))
185}
186
96class RobDispatchData(implicit p: Parameters) extends RobCommitInfo {}
97
98class RobDeqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper {
99 val io = IO(new Bundle {
100 // for commits/flush
101 val state = Input(UInt(2.W))
102 val deq_v = Vec(CommitWidth, Input(Bool()))
103 val deq_w = Vec(CommitWidth, Input(Bool()))
104 val exception_state = Flipped(ValidIO(new RobExceptionInfo))
105 // for flush: when exception occurs, reset deqPtrs to range(0, CommitWidth)

--- 67 unchanged lines hidden (view full) ---

173
174}
175
176class RobExceptionInfo(implicit p: Parameters) extends XSBundle {
177 // val valid = Bool()
178 val robIdx = new RobPtr
179 val exceptionVec = ExceptionVec()
180 val flushPipe = Bool()
187class RobDeqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper {
188 val io = IO(new Bundle {
189 // for commits/flush
190 val state = Input(UInt(2.W))
191 val deq_v = Vec(CommitWidth, Input(Bool()))
192 val deq_w = Vec(CommitWidth, Input(Bool()))
193 val exception_state = Flipped(ValidIO(new RobExceptionInfo))
194 // for flush: when exception occurs, reset deqPtrs to range(0, CommitWidth)

--- 67 unchanged lines hidden (view full) ---

262
263}
264
265class RobExceptionInfo(implicit p: Parameters) extends XSBundle {
266 // val valid = Bool()
267 val robIdx = new RobPtr
268 val exceptionVec = ExceptionVec()
269 val flushPipe = Bool()
181 val isVset = Bool()
182 val replayInst = Bool() // redirect to that inst itself
183 val singleStep = Bool() // TODO add frontend hit beneath
184 val crossPageIPFFix = Bool()
185 val trigger = new TriggerCf
186
187// def trigger_before = !trigger.getTimingBackend && trigger.getHitBackend
188// def trigger_after = trigger.getTimingBackend && trigger.getHitBackend
189 def has_exception = exceptionVec.asUInt.orR || flushPipe || singleStep || replayInst || trigger.hit
190 def not_commit = exceptionVec.asUInt.orR || singleStep || replayInst || trigger.hit
191 // only exceptions are allowed to writeback when enqueue
192 def can_writeback = exceptionVec.asUInt.orR || singleStep || trigger.hit
193}
194
270 val replayInst = Bool() // redirect to that inst itself
271 val singleStep = Bool() // TODO add frontend hit beneath
272 val crossPageIPFFix = Bool()
273 val trigger = new TriggerCf
274
275// def trigger_before = !trigger.getTimingBackend && trigger.getHitBackend
276// def trigger_after = trigger.getTimingBackend && trigger.getHitBackend
277 def has_exception = exceptionVec.asUInt.orR || flushPipe || singleStep || replayInst || trigger.hit
278 def not_commit = exceptionVec.asUInt.orR || singleStep || replayInst || trigger.hit
279 // only exceptions are allowed to writeback when enqueue
280 def can_writeback = exceptionVec.asUInt.orR || singleStep || trigger.hit
281}
282
195class ExceptionGen(params: BackendParams)(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper {
283class ExceptionGen(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper {
196 val io = IO(new Bundle {
197 val redirect = Input(Valid(new Redirect))
198 val flush = Input(Bool())
199 val enq = Vec(RenameWidth, Flipped(ValidIO(new RobExceptionInfo)))
284 val io = IO(new Bundle {
285 val redirect = Input(Valid(new Redirect))
286 val flush = Input(Bool())
287 val enq = Vec(RenameWidth, Flipped(ValidIO(new RobExceptionInfo)))
200 // csr + load + store
201 val wb = Vec(params.numException, Flipped(ValidIO(new RobExceptionInfo)))
288 val wb = Vec(1 + LoadPipelineWidth + StorePipelineWidth, Flipped(ValidIO(new RobExceptionInfo)))
202 val out = ValidIO(new RobExceptionInfo)
203 val state = ValidIO(new RobExceptionInfo)
204 })
205
206 def getOldest(valid: Seq[Bool], bits: Seq[RobExceptionInfo]): (Seq[Bool], Seq[RobExceptionInfo]) = {
207 assert(valid.length == bits.length)
208 assert(isPow2(valid.length))
209 if (valid.length == 1) {

--- 79 unchanged lines hidden (view full) ---

289
290class RobFlushInfo(implicit p: Parameters) extends XSBundle {
291 val ftqIdx = new FtqPtr
292 val robIdx = new RobPtr
293 val ftqOffset = UInt(log2Up(PredictWidth).W)
294 val replayInst = Bool()
295}
296
289 val out = ValidIO(new RobExceptionInfo)
290 val state = ValidIO(new RobExceptionInfo)
291 })
292
293 def getOldest(valid: Seq[Bool], bits: Seq[RobExceptionInfo]): (Seq[Bool], Seq[RobExceptionInfo]) = {
294 assert(valid.length == bits.length)
295 assert(isPow2(valid.length))
296 if (valid.length == 1) {

--- 79 unchanged lines hidden (view full) ---

376
377class RobFlushInfo(implicit p: Parameters) extends XSBundle {
378 val ftqIdx = new FtqPtr
379 val robIdx = new RobPtr
380 val ftqOffset = UInt(log2Up(PredictWidth).W)
381 val replayInst = Bool()
382}
383
297class Rob(params: BackendParams)(implicit p: Parameters) extends LazyModule with HasXSParameter {
384class Rob(implicit p: Parameters) extends LazyModule with HasWritebackSink with HasXSParameter {
298
385
299 lazy val module = new RobImp(this)(p, params)
386 lazy val module = new RobImp(this)
387
388 override def generateWritebackIO(
389 thisMod: Option[HasWritebackSource] = None,
390 thisModImp: Option[HasWritebackSourceImp] = None
391 ): Unit = {
392 val sources = writebackSinksImp(thisMod, thisModImp)
393 module.io.writeback.zip(sources).foreach(x => x._1 := x._2)
394 }
300}
301
395}
396
302class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendParams) extends LazyModuleImp(wrapper)
397class RobImp(outer: Rob)(implicit p: Parameters) extends LazyModuleImp(outer)
303 with HasXSParameter with HasCircularQueuePtrHelper with HasPerfEvents {
398 with HasXSParameter with HasCircularQueuePtrHelper with HasPerfEvents {
399 val wbExuConfigs = outer.writebackSinksParams.map(_.exuConfigs)
400 val numWbPorts = wbExuConfigs.map(_.length)
304
401
305 private val LduCnt = params.LduCnt
306 private val StaCnt = params.StaCnt
307
308 val io = IO(new Bundle() {
309 val hartId = Input(UInt(8.W))
310 val redirect = Input(Valid(new Redirect))
311 val enq = new RobEnqIO
312 val flushOut = ValidIO(new Redirect)
313 val exception = ValidIO(new ExceptionInfo)
314 // exu + brq
402 val io = IO(new Bundle() {
403 val hartId = Input(UInt(8.W))
404 val redirect = Input(Valid(new Redirect))
405 val enq = new RobEnqIO
406 val flushOut = ValidIO(new Redirect)
407 val exception = ValidIO(new ExceptionInfo)
408 // exu + brq
315 val writeback: MixedVec[ValidIO[ExuOutput]] = Flipped(params.genWrite2CtrlBundles)
409 val writeback = MixedVec(numWbPorts.map(num => Vec(num, Flipped(ValidIO(new ExuOutput)))))
316 val commits = Output(new RobCommitIO)
410 val commits = Output(new RobCommitIO)
317 val rabCommits = Output(new RobCommitIO)
318 val diffCommits = Output(new DiffCommitIO)
319 val isVsetFlushPipe = Output(Bool())
320 val vconfigPdest = Output(UInt(PhyRegIdxWidth.W))
321 val lsq = new RobLsqIO
322 val robDeqPtr = Output(new RobPtr)
323 val csr = new RobCSRIO
324 val snpt = Input(new SnapshotPort)
325 val robFull = Output(Bool())
326 val headNotReady = Output(Bool())
327 val cpu_halt = Output(Bool())
328 val wfi_enable = Input(Bool())
329 val debug_ls = Flipped(new DebugLSIO)
411 val lsq = new RobLsqIO
412 val robDeqPtr = Output(new RobPtr)
413 val csr = new RobCSRIO
414 val snpt = Input(new SnapshotPort)
415 val robFull = Output(Bool())
416 val headNotReady = Output(Bool())
417 val cpu_halt = Output(Bool())
418 val wfi_enable = Input(Bool())
419 val debug_ls = Flipped(new DebugLSIO)
330 val debugRobHead = Output(new DynInst)
420 val debugRobHead = Output(new MicroOp)
331 val debugEnqLsq = Input(new LsqEnqIO)
332 val debugHeadLsIssue = Input(Bool())
421 val debugEnqLsq = Input(new LsqEnqIO)
422 val debugHeadLsIssue = Input(Bool())
333 val lsTopdownInfo = Vec(LduCnt, Input(new LsTopdownInfo))
423 val lsTopdownInfo = Vec(exuParameters.LduCnt, Input(new LsTopdownInfo))
334 })
335
424 })
425
336 val exuWBs: Seq[ValidIO[ExuOutput]] = io.writeback.filter(!_.bits.params.hasStdFu)
337 val stdWBs: Seq[ValidIO[ExuOutput]] = io.writeback.filter(_.bits.params.hasStdFu)
338 val fflagsWBs = io.writeback.filter(x => x.bits.fflags.nonEmpty)
339 val exceptionWBs = io.writeback.filter(x => x.bits.exceptionVec.nonEmpty)
340 val redirectWBs = io.writeback.filter(x => x.bits.redirect.nonEmpty)
426 def selectWb(index: Int, func: Seq[ExuConfig] => Boolean): Seq[(Seq[ExuConfig], ValidIO[ExuOutput])] = {
427 wbExuConfigs(index).zip(io.writeback(index)).filter(x => func(x._1))
428 }
429 val exeWbSel = outer.selWritebackSinks(_.exuConfigs.length)
430 val fflagsWbSel = outer.selWritebackSinks(_.exuConfigs.count(_.exists(_.writeFflags)))
431 val fflagsPorts = selectWb(fflagsWbSel, _.exists(_.writeFflags))
432 val exceptionWbSel = outer.selWritebackSinks(_.exuConfigs.count(_.exists(_.needExceptionGen)))
433 val exceptionPorts = selectWb(fflagsWbSel, _.exists(_.needExceptionGen))
434 val exuWbPorts = selectWb(exeWbSel, _.forall(_ != StdExeUnitCfg))
435 val stdWbPorts = selectWb(exeWbSel, _.contains(StdExeUnitCfg))
436 println(s"Rob: size $RobSize, numWbPorts: $numWbPorts, commitwidth: $CommitWidth")
437 println(s"exuPorts: ${exuWbPorts.map(_._1.map(_.name))}")
438 println(s"stdPorts: ${stdWbPorts.map(_._1.map(_.name))}")
439 println(s"fflags: ${fflagsPorts.map(_._1.map(_.name))}")
341
440
342 val exuWbPorts = io.writeback.filter(!_.bits.params.hasStdFu)
343 val stdWbPorts = io.writeback.filter(_.bits.params.hasStdFu)
344 val fflagsPorts = io.writeback.filter(x => x.bits.fflags.nonEmpty)
345 val vxsatPorts = io.writeback.filter(x => x.bits.vxsat.nonEmpty)
346 val exceptionPorts = io.writeback.filter(x => x.bits.exceptionVec.nonEmpty)
347 val numExuWbPorts = exuWBs.length
348 val numStdWbPorts = stdWBs.length
349
441
442 val exuWriteback = exuWbPorts.map(_._2)
443 val stdWriteback = stdWbPorts.map(_._2)
350
444
351 println(s"Rob: size $RobSize, numExuWbPorts: $numExuWbPorts, numStdWbPorts: $numStdWbPorts, commitwidth: $CommitWidth")
352// println(s"exuPorts: ${exuWbPorts.map(_._1.map(_.name))}")
353// println(s"stdPorts: ${stdWbPorts.map(_._1.map(_.name))}")
354// println(s"fflags: ${fflagsPorts.map(_._1.map(_.name))}")
355
356
357 // instvalid field
358 val valid = RegInit(VecInit(Seq.fill(RobSize)(false.B)))
359 // writeback status
445 // instvalid field
446 val valid = RegInit(VecInit(Seq.fill(RobSize)(false.B)))
447 // writeback status
360
361 val stdWritebacked = Reg(Vec(RobSize, Bool()))
362 val uopNumVec = RegInit(VecInit(Seq.fill(RobSize)(0.U(log2Up(MaxUopSize + 1).W))))
363 val realDestSize = RegInit(VecInit(Seq.fill(RobSize)(0.U(log2Up(MaxUopSize + 1).W))))
364 val fflagsDataModule = RegInit(VecInit(Seq.fill(RobSize)(0.U(5.W))))
365 val vxsatDataModule = RegInit(VecInit(Seq.fill(RobSize)(false.B)))
366
367 def isWritebacked(ptr: UInt): Bool = {
368 !uopNumVec(ptr).orR && stdWritebacked(ptr)
369 }
370
448 val writebacked = Mem(RobSize, Bool())
449 val store_data_writebacked = Mem(RobSize, Bool())
371 val mmio = RegInit(VecInit(Seq.fill(RobSize)(false.B)))
450 val mmio = RegInit(VecInit(Seq.fill(RobSize)(false.B)))
372
373 // data for redirect, exception, etc.
374 val flagBkup = Mem(RobSize, Bool())
375 // some instructions are not allowed to trigger interrupts
376 // They have side effects on the states of the processor before they write back
377 val interrupt_safe = Mem(RobSize, Bool())
378
379 // data for debug
380 // Warn: debug_* prefix should not exist in generated verilog.
451 // data for redirect, exception, etc.
452 val flagBkup = Mem(RobSize, Bool())
453 // some instructions are not allowed to trigger interrupts
454 // They have side effects on the states of the processor before they write back
455 val interrupt_safe = Mem(RobSize, Bool())
456
457 // data for debug
458 // Warn: debug_* prefix should not exist in generated verilog.
381 val debug_microOp = Mem(RobSize, new DynInst)
459 val debug_microOp = Mem(RobSize, new MicroOp)
382 val debug_exuData = Reg(Vec(RobSize, UInt(XLEN.W)))//for debug
383 val debug_exuDebug = Reg(Vec(RobSize, new DebugBundle))//for debug
384 val debug_lsInfo = RegInit(VecInit(Seq.fill(RobSize)(DebugLsInfo.init)))
385 val debug_lsTopdownInfo = RegInit(VecInit(Seq.fill(RobSize)(LsTopdownInfo.init)))
386 val debug_lqIdxValid = RegInit(VecInit.fill(RobSize)(false.B))
387 val debug_lsIssued = RegInit(VecInit.fill(RobSize)(false.B))
388
389 // pointers

--- 9 unchanged lines hidden (view full) ---

399 val deqPtr = deqPtrVec(0)
400 val walkPtr = walkPtrVec(0)
401
402 val isEmpty = enqPtr === deqPtr
403 val isReplaying = io.redirect.valid && RedirectLevel.flushItself(io.redirect.bits.level)
404
405 val snptEnq = io.enq.canAccept && io.enq.req.head.valid && io.enq.req.head.bits.snapshot
406 val snapshots = SnapshotGenerator(enqPtrVec, snptEnq, io.snpt.snptDeq, io.redirect.valid)
460 val debug_exuData = Reg(Vec(RobSize, UInt(XLEN.W)))//for debug
461 val debug_exuDebug = Reg(Vec(RobSize, new DebugBundle))//for debug
462 val debug_lsInfo = RegInit(VecInit(Seq.fill(RobSize)(DebugLsInfo.init)))
463 val debug_lsTopdownInfo = RegInit(VecInit(Seq.fill(RobSize)(LsTopdownInfo.init)))
464 val debug_lqIdxValid = RegInit(VecInit.fill(RobSize)(false.B))
465 val debug_lsIssued = RegInit(VecInit.fill(RobSize)(false.B))
466
467 // pointers

--- 9 unchanged lines hidden (view full) ---

477 val deqPtr = deqPtrVec(0)
478 val walkPtr = walkPtrVec(0)
479
480 val isEmpty = enqPtr === deqPtr
481 val isReplaying = io.redirect.valid && RedirectLevel.flushItself(io.redirect.bits.level)
482
483 val snptEnq = io.enq.canAccept && io.enq.req.head.valid && io.enq.req.head.bits.snapshot
484 val snapshots = SnapshotGenerator(enqPtrVec, snptEnq, io.snpt.snptDeq, io.redirect.valid)
485
407 val debug_lsIssue = WireDefault(debug_lsIssued)
408 debug_lsIssue(deqPtr.value) := io.debugHeadLsIssue
409
410 /**
411 * states of Rob
412 */
413 val s_idle :: s_walk :: Nil = Enum(2)
414 val state = RegInit(s_idle)

--- 4 unchanged lines hidden (view full) ---

419 * CommitDataModule: data from dispatch
420 * (1) read: commits/walk/exception
421 * (2) write: enqueue
422 *
423 * WritebackData: data from writeback
424 * (1) read: commits/walk/exception
425 * (2) write: write back from exe units
426 */
486 val debug_lsIssue = WireDefault(debug_lsIssued)
487 debug_lsIssue(deqPtr.value) := io.debugHeadLsIssue
488
489 /**
490 * states of Rob
491 */
492 val s_idle :: s_walk :: Nil = Enum(2)
493 val state = RegInit(s_idle)

--- 4 unchanged lines hidden (view full) ---

498 * CommitDataModule: data from dispatch
499 * (1) read: commits/walk/exception
500 * (2) write: enqueue
501 *
502 * WritebackData: data from writeback
503 * (1) read: commits/walk/exception
504 * (2) write: write back from exe units
505 */
427 val dispatchData = Module(new SyncDataModuleTemplate(new RobDispatchData, RobSize, CommitWidth, RenameWidth))
506 val dispatchData = Module(new SyncDataModuleTemplate(new RobCommitInfo, RobSize, CommitWidth, RenameWidth))
428 val dispatchDataRead = dispatchData.io.rdata
429
507 val dispatchDataRead = dispatchData.io.rdata
508
430 val exceptionGen = Module(new ExceptionGen(params))
509 val exceptionGen = Module(new ExceptionGen)
431 val exceptionDataRead = exceptionGen.io.state
432 val fflagsDataRead = Wire(Vec(CommitWidth, UInt(5.W)))
510 val exceptionDataRead = exceptionGen.io.state
511 val fflagsDataRead = Wire(Vec(CommitWidth, UInt(5.W)))
433 val vxsatDataRead = Wire(Vec(CommitWidth, Bool()))
434
435 io.robDeqPtr := deqPtr
436 io.debugRobHead := debug_microOp(deqPtr.value)
437
512
513 io.robDeqPtr := deqPtr
514 io.debugRobHead := debug_microOp(deqPtr.value)
515
438 val rab = Module(new RenameBuffer(RabSize))
439
440 rab.io.redirect.valid := io.redirect.valid
441
442 rab.io.req.zip(io.enq.req).map { case (dest, src) =>
443 dest.bits := src.bits
444 dest.valid := src.valid && io.enq.canAccept
445 }
446
447 val commitDestSizeSeq = (0 until CommitWidth).map(i => realDestSize(deqPtrVec(i).value))
448 val walkDestSizeSeq = (0 until CommitWidth).map(i => realDestSize(walkPtrVec(i).value))
449
450 val commitSizeSum = io.commits.commitValid.zip(commitDestSizeSeq).map { case (commitValid, destSize) =>
451 Mux(io.commits.isCommit && commitValid, destSize, 0.U)
452 }.reduce(_ +& _)
453 val walkSizeSum = io.commits.walkValid.zip(walkDestSizeSeq).map { case (walkValid, destSize) =>
454 Mux(io.commits.isWalk && walkValid, destSize, 0.U)
455 }.reduce(_ +& _)
456
457 rab.io.commitSize := commitSizeSum
458 rab.io.walkSize := walkSizeSum
459 rab.io.snpt.snptEnq := false.B
460 rab.io.snpt.snptDeq := io.snpt.snptDeq
461 rab.io.snpt.snptSelect := io.snpt.snptSelect
462 rab.io.snpt.useSnpt := io.snpt.useSnpt
463
464 io.rabCommits := rab.io.commits
465 io.diffCommits := rab.io.diffCommits
466
467 /**
468 * Enqueue (from dispatch)
469 */
470 // special cases
471 val hasBlockBackward = RegInit(false.B)
516 /**
517 * Enqueue (from dispatch)
518 */
519 // special cases
520 val hasBlockBackward = RegInit(false.B)
472 val hasWaitForward = RegInit(false.B)
521 val hasNoSpecExec = RegInit(false.B)
473 val doingSvinval = RegInit(false.B)
474 // When blockBackward instruction leaves Rob (commit or walk), hasBlockBackward should be set to false.B
475 // To reduce registers usage, for hasBlockBackward cases, we allow enqueue after ROB is empty.
476 when (isEmpty) { hasBlockBackward:= false.B }
477 // When any instruction commits, hasNoSpecExec should be set to false.B
522 val doingSvinval = RegInit(false.B)
523 // When blockBackward instruction leaves Rob (commit or walk), hasBlockBackward should be set to false.B
524 // To reduce registers usage, for hasBlockBackward cases, we allow enqueue after ROB is empty.
525 when (isEmpty) { hasBlockBackward:= false.B }
526 // When any instruction commits, hasNoSpecExec should be set to false.B
478 when (io.commits.hasWalkInstr || io.commits.hasCommitInstr) { hasWaitForward:= false.B }
527 when (io.commits.hasWalkInstr || io.commits.hasCommitInstr) { hasNoSpecExec:= false.B }
479
480 // The wait-for-interrupt (WFI) instruction waits in the ROB until an interrupt might need servicing.
481 // io.csr.wfiEvent will be asserted if the WFI can resume execution, and we change the state to s_wfi_idle.
482 // It does not affect how interrupts are serviced. Note that WFI is noSpecExec and it does not trigger interrupts.
483 val hasWFI = RegInit(false.B)
484 io.cpu_halt := hasWFI
485 // WFI Timeout: 2^20 = 1M cycles
486 val wfi_cycles = RegInit(0.U(20.W))
487 when (hasWFI) {
488 wfi_cycles := wfi_cycles + 1.U
489 }.elsewhen (!hasWFI && RegNext(hasWFI)) {
490 wfi_cycles := 0.U
491 }
492 val wfi_timeout = wfi_cycles.andR
493 when (RegNext(RegNext(io.csr.wfiEvent)) || io.flushOut.valid || wfi_timeout) {
494 hasWFI := false.B
495 }
496
528
529 // The wait-for-interrupt (WFI) instruction waits in the ROB until an interrupt might need servicing.
530 // io.csr.wfiEvent will be asserted if the WFI can resume execution, and we change the state to s_wfi_idle.
531 // It does not affect how interrupts are serviced. Note that WFI is noSpecExec and it does not trigger interrupts.
532 val hasWFI = RegInit(false.B)
533 io.cpu_halt := hasWFI
534 // WFI Timeout: 2^20 = 1M cycles
535 val wfi_cycles = RegInit(0.U(20.W))
536 when (hasWFI) {
537 wfi_cycles := wfi_cycles + 1.U
538 }.elsewhen (!hasWFI && RegNext(hasWFI)) {
539 wfi_cycles := 0.U
540 }
541 val wfi_timeout = wfi_cycles.andR
542 when (RegNext(RegNext(io.csr.wfiEvent)) || io.flushOut.valid || wfi_timeout) {
543 hasWFI := false.B
544 }
545
497 val allocatePtrVec = VecInit((0 until RenameWidth).map(i => enqPtrVec(PopCount(io.enq.req.take(i).map(req => req.valid && req.bits.firstUop)))))
498 io.enq.canAccept := allowEnqueue && !hasBlockBackward && rab.io.canEnq
546 val allocatePtrVec = VecInit((0 until RenameWidth).map(i => enqPtrVec(PopCount(io.enq.needAlloc.take(i)))))
547 io.enq.canAccept := allowEnqueue && !hasBlockBackward
499 io.enq.resp := allocatePtrVec
548 io.enq.resp := allocatePtrVec
500 val canEnqueue = VecInit(io.enq.req.map(req => req.valid && req.bits.firstUop && io.enq.canAccept))
549 val canEnqueue = VecInit(io.enq.req.map(_.valid && io.enq.canAccept))
501 val timer = GTimer()
502 for (i <- 0 until RenameWidth) {
503 // we don't check whether io.redirect is valid here since redirect has higher priority
504 when (canEnqueue(i)) {
505 val enqUop = io.enq.req(i).bits
506 val enqIndex = allocatePtrVec(i).value
507 // store uop in data module and debug_microOp Vec
508 debug_microOp(enqIndex) := enqUop
509 debug_microOp(enqIndex).debugInfo.dispatchTime := timer
510 debug_microOp(enqIndex).debugInfo.enqRsTime := timer
511 debug_microOp(enqIndex).debugInfo.selectTime := timer
512 debug_microOp(enqIndex).debugInfo.issueTime := timer
513 debug_microOp(enqIndex).debugInfo.writebackTime := timer
514 debug_microOp(enqIndex).debugInfo.tlbFirstReqTime := timer
515 debug_microOp(enqIndex).debugInfo.tlbRespTime := timer
516 debug_lsInfo(enqIndex) := DebugLsInfo.init
517 debug_lsTopdownInfo(enqIndex) := LsTopdownInfo.init
518 debug_lqIdxValid(enqIndex) := false.B
519 debug_lsIssued(enqIndex) := false.B
550 val timer = GTimer()
551 for (i <- 0 until RenameWidth) {
552 // we don't check whether io.redirect is valid here since redirect has higher priority
553 when (canEnqueue(i)) {
554 val enqUop = io.enq.req(i).bits
555 val enqIndex = allocatePtrVec(i).value
556 // store uop in data module and debug_microOp Vec
557 debug_microOp(enqIndex) := enqUop
558 debug_microOp(enqIndex).debugInfo.dispatchTime := timer
559 debug_microOp(enqIndex).debugInfo.enqRsTime := timer
560 debug_microOp(enqIndex).debugInfo.selectTime := timer
561 debug_microOp(enqIndex).debugInfo.issueTime := timer
562 debug_microOp(enqIndex).debugInfo.writebackTime := timer
563 debug_microOp(enqIndex).debugInfo.tlbFirstReqTime := timer
564 debug_microOp(enqIndex).debugInfo.tlbRespTime := timer
565 debug_lsInfo(enqIndex) := DebugLsInfo.init
566 debug_lsTopdownInfo(enqIndex) := LsTopdownInfo.init
567 debug_lqIdxValid(enqIndex) := false.B
568 debug_lsIssued(enqIndex) := false.B
520
521 when (enqUop.blockBackward) {
569 when (enqUop.ctrl.blockBackward) {
522 hasBlockBackward := true.B
523 }
570 hasBlockBackward := true.B
571 }
524 when (enqUop.waitForward) {
525 hasWaitForward := true.B
572 when (enqUop.ctrl.noSpecExec) {
573 hasNoSpecExec := true.B
526 }
574 }
527 val enqHasTriggerHit = false.B // io.enq.req(i).bits.cf.trigger.getHitFrontend
528 val enqHasException = ExceptionNO.selectFrontend(enqUop.exceptionVec).asUInt.orR
575 val enqHasTriggerHit = io.enq.req(i).bits.cf.trigger.getHitFrontend
576 val enqHasException = ExceptionNO.selectFrontend(enqUop.cf.exceptionVec).asUInt.orR
529 // the begin instruction of Svinval enqs so mark doingSvinval as true to indicate this process
577 // the begin instruction of Svinval enqs so mark doingSvinval as true to indicate this process
530 when(!enqHasTriggerHit && !enqHasException && enqUop.isSvinvalBegin(enqUop.flushPipe))
578 when(!enqHasTriggerHit && !enqHasException && FuType.isSvinvalBegin(enqUop.ctrl.fuType, enqUop.ctrl.fuOpType, enqUop.ctrl.flushPipe))
531 {
532 doingSvinval := true.B
533 }
534 // the end instruction of Svinval enqs so clear doingSvinval
579 {
580 doingSvinval := true.B
581 }
582 // the end instruction of Svinval enqs so clear doingSvinval
535 when(!enqHasTriggerHit && !enqHasException && enqUop.isSvinvalEnd(enqUop.flushPipe))
583 when(!enqHasTriggerHit && !enqHasException && FuType.isSvinvalEnd(enqUop.ctrl.fuType, enqUop.ctrl.fuOpType, enqUop.ctrl.flushPipe))
536 {
537 doingSvinval := false.B
538 }
539 // when we are in the process of Svinval software code area , only Svinval.vma and end instruction of Svinval can appear
584 {
585 doingSvinval := false.B
586 }
587 // when we are in the process of Svinval software code area , only Svinval.vma and end instruction of Svinval can appear
540 assert(!doingSvinval || (enqUop.isSvinval(enqUop.flushPipe) || enqUop.isSvinvalEnd(enqUop.flushPipe)))
541 when (enqUop.isWFI && !enqHasException && !enqHasTriggerHit) {
588 assert(!doingSvinval || (FuType.isSvinval(enqUop.ctrl.fuType, enqUop.ctrl.fuOpType, enqUop.ctrl.flushPipe) ||
589 FuType.isSvinvalEnd(enqUop.ctrl.fuType, enqUop.ctrl.fuOpType, enqUop.ctrl.flushPipe)))
590 when (enqUop.ctrl.isWFI && !enqHasException && !enqHasTriggerHit) {
542 hasWFI := true.B
543 }
544
545 mmio(enqIndex) := false.B
546 }
547 }
591 hasWFI := true.B
592 }
593
594 mmio(enqIndex) := false.B
595 }
596 }
548 val dispatchNum = Mux(io.enq.canAccept, PopCount(io.enq.req.map(req => req.valid && req.bits.firstUop)), 0.U)
597 val dispatchNum = Mux(io.enq.canAccept, PopCount(io.enq.req.map(_.valid)), 0.U)
549 io.enq.isEmpty := RegNext(isEmpty && !VecInit(io.enq.req.map(_.valid)).asUInt.orR)
550
551 when (!io.wfi_enable) {
552 hasWFI := false.B
553 }
598 io.enq.isEmpty := RegNext(isEmpty && !VecInit(io.enq.req.map(_.valid)).asUInt.orR)
599
600 when (!io.wfi_enable) {
601 hasWFI := false.B
602 }
554 // sel vsetvl's flush position
555 val vs_idle :: vs_waitVinstr :: vs_waitFlush :: Nil = Enum(3)
556 val vsetvlState = RegInit(vs_idle)
557
603
558 val firstVInstrFtqPtr = RegInit(0.U.asTypeOf(new FtqPtr))
559 val firstVInstrFtqOffset = RegInit(0.U.asTypeOf(UInt(log2Up(PredictWidth).W)))
560 val firstVInstrRobIdx = RegInit(0.U.asTypeOf(new RobPtr))
561
562 val enq0 = io.enq.req(0)
563 val enq0IsVset = enq0.bits.isVset && enq0.bits.lastUop && canEnqueue(0)
564 val enq0IsVsetFlush = enq0IsVset && enq0.bits.flushPipe
565 val enqIsVInstrVec = io.enq.req.zip(canEnqueue).map{case (req, fire) => FuType.isVpu(req.bits.fuType) && fire}
566 // for vs_idle
567 val firstVInstrIdle = PriorityMux(enqIsVInstrVec.zip(io.enq.req).drop(1) :+ (true.B, 0.U.asTypeOf(io.enq.req(0).cloneType)))
568 // for vs_waitVinstr
569 val enqIsVInstrOrVset = (enqIsVInstrVec(0) || enq0IsVset) +: enqIsVInstrVec.drop(1)
570 val firstVInstrWait = PriorityMux(enqIsVInstrOrVset, io.enq.req)
571 when(vsetvlState === vs_idle){
572 firstVInstrFtqPtr := firstVInstrIdle.bits.ftqPtr
573 firstVInstrFtqOffset := firstVInstrIdle.bits.ftqOffset
574 firstVInstrRobIdx := firstVInstrIdle.bits.robIdx
575 }.elsewhen(vsetvlState === vs_waitVinstr){
576 when(Cat(enqIsVInstrOrVset).orR){
577 firstVInstrFtqPtr := firstVInstrWait.bits.ftqPtr
578 firstVInstrFtqOffset := firstVInstrWait.bits.ftqOffset
579 firstVInstrRobIdx := firstVInstrWait.bits.robIdx
580 }
581 }
582
583 val hasVInstrAfterI = Cat(enqIsVInstrVec(0)).orR
584 when(vsetvlState === vs_idle && !io.redirect.valid){
585 when(enq0IsVsetFlush){
586 vsetvlState := Mux(hasVInstrAfterI, vs_waitFlush, vs_waitVinstr)
587 }
588 }.elsewhen(vsetvlState === vs_waitVinstr){
589 when(io.redirect.valid){
590 vsetvlState := vs_idle
591 }.elsewhen(Cat(enqIsVInstrOrVset).orR){
592 vsetvlState := vs_waitFlush
593 }
594 }.elsewhen(vsetvlState === vs_waitFlush){
595 when(io.redirect.valid){
596 vsetvlState := vs_idle
597 }
598 }
599
600 // lqEnq
601 io.debugEnqLsq.needAlloc.map(_(0)).zip(io.debugEnqLsq.req).foreach { case (alloc, req) =>
602 when(io.debugEnqLsq.canAccept && alloc && req.valid) {
603 debug_microOp(req.bits.robIdx.value).lqIdx := req.bits.lqIdx
604 debug_lqIdxValid(req.bits.robIdx.value) := true.B
605 }
606 }
607
608 // lsIssue
609 when(io.debugHeadLsIssue) {
610 debug_lsIssued(deqPtr.value) := true.B
611 }
612
613 /**
614 * Writeback (from execution units)
615 */
604 // lqEnq
605 io.debugEnqLsq.needAlloc.map(_(0)).zip(io.debugEnqLsq.req).foreach { case (alloc, req) =>
606 when(io.debugEnqLsq.canAccept && alloc && req.valid) {
607 debug_microOp(req.bits.robIdx.value).lqIdx := req.bits.lqIdx
608 debug_lqIdxValid(req.bits.robIdx.value) := true.B
609 }
610 }
611
612 // lsIssue
613 when(io.debugHeadLsIssue) {
614 debug_lsIssued(deqPtr.value) := true.B
615 }
616
617 /**
618 * Writeback (from execution units)
619 */
616 for (wb <- exuWBs) {
620 for (wb <- exuWriteback) {
617 when (wb.valid) {
621 when (wb.valid) {
618 val wbIdx = wb.bits.robIdx.value
622 val wbIdx = wb.bits.uop.robIdx.value
619 debug_exuData(wbIdx) := wb.bits.data
620 debug_exuDebug(wbIdx) := wb.bits.debug
623 debug_exuData(wbIdx) := wb.bits.data
624 debug_exuDebug(wbIdx) := wb.bits.debug
621 debug_microOp(wbIdx).debugInfo.enqRsTime := wb.bits.debugInfo.enqRsTime
622 debug_microOp(wbIdx).debugInfo.selectTime := wb.bits.debugInfo.selectTime
623 debug_microOp(wbIdx).debugInfo.issueTime := wb.bits.debugInfo.issueTime
624 debug_microOp(wbIdx).debugInfo.writebackTime := wb.bits.debugInfo.writebackTime
625 debug_microOp(wbIdx).debugInfo.enqRsTime := wb.bits.uop.debugInfo.enqRsTime
626 debug_microOp(wbIdx).debugInfo.selectTime := wb.bits.uop.debugInfo.selectTime
627 debug_microOp(wbIdx).debugInfo.issueTime := wb.bits.uop.debugInfo.issueTime
628 debug_microOp(wbIdx).debugInfo.writebackTime := wb.bits.uop.debugInfo.writebackTime
629 debug_microOp(wbIdx).debugInfo.tlbFirstReqTime := wb.bits.uop.debugInfo.tlbFirstReqTime
630 debug_microOp(wbIdx).debugInfo.tlbRespTime := wb.bits.uop.debugInfo.tlbRespTime
625
626 // debug for lqidx and sqidx
631
632 // debug for lqidx and sqidx
627 debug_microOp(wbIdx).lqIdx := wb.bits.lqIdx.getOrElse(0.U.asTypeOf(new LqPtr))
628 debug_microOp(wbIdx).sqIdx := wb.bits.sqIdx.getOrElse(0.U.asTypeOf(new SqPtr))
633 debug_microOp(wbIdx).lqIdx := wb.bits.uop.lqIdx
634 debug_microOp(wbIdx).sqIdx := wb.bits.uop.sqIdx
629
630 val debug_Uop = debug_microOp(wbIdx)
631 XSInfo(true.B,
635
636 val debug_Uop = debug_microOp(wbIdx)
637 XSInfo(true.B,
632 p"writebacked pc 0x${Hexadecimal(debug_Uop.pc)} wen ${debug_Uop.rfWen} " +
633 p"data 0x${Hexadecimal(wb.bits.data)} ldst ${debug_Uop.ldest} pdst ${debug_Uop.pdest} " +
634 p"skip ${wb.bits.debug.isMMIO} robIdx: ${wb.bits.robIdx}\n"
638 p"writebacked pc 0x${Hexadecimal(debug_Uop.cf.pc)} wen ${debug_Uop.ctrl.rfWen} " +
639 p"data 0x${Hexadecimal(wb.bits.data)} ldst ${debug_Uop.ctrl.ldest} pdst ${debug_Uop.pdest} " +
640 p"skip ${wb.bits.debug.isMMIO} robIdx: ${wb.bits.uop.robIdx}\n"
635 )
636 }
637 }
641 )
642 }
643 }
638
639 val writebackNum = PopCount(exuWBs.map(_.valid))
644 val writebackNum = PopCount(exuWriteback.map(_.valid))
640 XSInfo(writebackNum =/= 0.U, "writebacked %d insts\n", writebackNum)
641
642 for (i <- 0 until LoadPipelineWidth) {
643 when (RegNext(io.lsq.mmio(i))) {
644 mmio(RegNext(io.lsq.uop(i).robIdx).value) := true.B
645 }
646 }
647
648 /**
649 * RedirectOut: Interrupt and Exceptions
650 */
651 val deqDispatchData = dispatchDataRead(0)
652 val debug_deqUop = debug_microOp(deqPtr.value)
653
654 val intrBitSetReg = RegNext(io.csr.intrBitSet)
645 XSInfo(writebackNum =/= 0.U, "writebacked %d insts\n", writebackNum)
646
647 for (i <- 0 until LoadPipelineWidth) {
648 when (RegNext(io.lsq.mmio(i))) {
649 mmio(RegNext(io.lsq.uop(i).robIdx).value) := true.B
650 }
651 }
652
653 /**
654 * RedirectOut: Interrupt and Exceptions
655 */
656 val deqDispatchData = dispatchDataRead(0)
657 val debug_deqUop = debug_microOp(deqPtr.value)
658
659 val intrBitSetReg = RegNext(io.csr.intrBitSet)
655 val intrEnable = intrBitSetReg && !hasWaitForward && interrupt_safe(deqPtr.value)
660 val intrEnable = intrBitSetReg && !hasNoSpecExec && interrupt_safe(deqPtr.value)
656 val deqHasExceptionOrFlush = exceptionDataRead.valid && exceptionDataRead.bits.robIdx === deqPtr
657 val deqHasException = deqHasExceptionOrFlush && (exceptionDataRead.bits.exceptionVec.asUInt.orR ||
658 exceptionDataRead.bits.singleStep || exceptionDataRead.bits.trigger.hit)
659 val deqHasFlushPipe = deqHasExceptionOrFlush && exceptionDataRead.bits.flushPipe
660 val deqHasReplayInst = deqHasExceptionOrFlush && exceptionDataRead.bits.replayInst
661 val deqHasExceptionOrFlush = exceptionDataRead.valid && exceptionDataRead.bits.robIdx === deqPtr
662 val deqHasException = deqHasExceptionOrFlush && (exceptionDataRead.bits.exceptionVec.asUInt.orR ||
663 exceptionDataRead.bits.singleStep || exceptionDataRead.bits.trigger.hit)
664 val deqHasFlushPipe = deqHasExceptionOrFlush && exceptionDataRead.bits.flushPipe
665 val deqHasReplayInst = deqHasExceptionOrFlush && exceptionDataRead.bits.replayInst
661 val exceptionEnable = isWritebacked(deqPtr.value) && deqHasException
666 val exceptionEnable = writebacked(deqPtr.value) && deqHasException
662
663 XSDebug(deqHasException && exceptionDataRead.bits.singleStep, "Debug Mode: Deq has singlestep exception\n")
664 XSDebug(deqHasException && exceptionDataRead.bits.trigger.getHitFrontend, "Debug Mode: Deq has frontend trigger exception\n")
665 XSDebug(deqHasException && exceptionDataRead.bits.trigger.getHitBackend, "Debug Mode: Deq has backend trigger exception\n")
666
667
668 XSDebug(deqHasException && exceptionDataRead.bits.singleStep, "Debug Mode: Deq has singlestep exception\n")
669 XSDebug(deqHasException && exceptionDataRead.bits.trigger.getHitFrontend, "Debug Mode: Deq has frontend trigger exception\n")
670 XSDebug(deqHasException && exceptionDataRead.bits.trigger.getHitBackend, "Debug Mode: Deq has backend trigger exception\n")
671
667 val isFlushPipe = isWritebacked(deqPtr.value) && (deqHasFlushPipe || deqHasReplayInst)
672 val isFlushPipe = writebacked(deqPtr.value) && (deqHasFlushPipe || deqHasReplayInst)
668
673
669 val isVsetFlushPipe = isWritebacked(deqPtr.value) && deqHasFlushPipe && exceptionDataRead.bits.isVset
670// val needModifyFtqIdxOffset = isVsetFlushPipe && (vsetvlState === vs_waitFlush)
671 val needModifyFtqIdxOffset = false.B
672 io.isVsetFlushPipe := isVsetFlushPipe
673 io.vconfigPdest := rab.io.vconfigPdest
674 // io.flushOut will trigger redirect at the next cycle.
675 // Block any redirect or commit at the next cycle.
676 val lastCycleFlush = RegNext(io.flushOut.valid)
677
678 io.flushOut.valid := (state === s_idle) && valid(deqPtr.value) && (intrEnable || exceptionEnable || isFlushPipe) && !lastCycleFlush
679 io.flushOut.bits := DontCare
680 io.flushOut.bits.isRVC := deqDispatchData.isRVC
674 // io.flushOut will trigger redirect at the next cycle.
675 // Block any redirect or commit at the next cycle.
676 val lastCycleFlush = RegNext(io.flushOut.valid)
677
678 io.flushOut.valid := (state === s_idle) && valid(deqPtr.value) && (intrEnable || exceptionEnable || isFlushPipe) && !lastCycleFlush
679 io.flushOut.bits := DontCare
680 io.flushOut.bits.isRVC := deqDispatchData.isRVC
681 io.flushOut.bits.robIdx := Mux(needModifyFtqIdxOffset, firstVInstrRobIdx, deqPtr)
682 io.flushOut.bits.ftqIdx := Mux(needModifyFtqIdxOffset, firstVInstrFtqPtr, deqDispatchData.ftqIdx)
683 io.flushOut.bits.ftqOffset := Mux(needModifyFtqIdxOffset, firstVInstrFtqOffset, deqDispatchData.ftqOffset)
684 io.flushOut.bits.level := Mux(deqHasReplayInst || intrEnable || exceptionEnable || needModifyFtqIdxOffset, RedirectLevel.flush, RedirectLevel.flushAfter) // TODO use this to implement "exception next"
681 io.flushOut.bits.robIdx := deqPtr
682 io.flushOut.bits.ftqIdx := deqDispatchData.ftqIdx
683 io.flushOut.bits.ftqOffset := deqDispatchData.ftqOffset
684 io.flushOut.bits.level := Mux(deqHasReplayInst || intrEnable || exceptionEnable, RedirectLevel.flush, RedirectLevel.flushAfter) // TODO use this to implement "exception next"
685 io.flushOut.bits.interrupt := true.B
686 XSPerfAccumulate("interrupt_num", io.flushOut.valid && intrEnable)
687 XSPerfAccumulate("exception_num", io.flushOut.valid && exceptionEnable)
688 XSPerfAccumulate("flush_pipe_num", io.flushOut.valid && isFlushPipe)
689 XSPerfAccumulate("replay_inst_num", io.flushOut.valid && isFlushPipe && deqHasReplayInst)
690
691 val exceptionHappen = (state === s_idle) && valid(deqPtr.value) && (intrEnable || exceptionEnable) && !lastCycleFlush
685 io.flushOut.bits.interrupt := true.B
686 XSPerfAccumulate("interrupt_num", io.flushOut.valid && intrEnable)
687 XSPerfAccumulate("exception_num", io.flushOut.valid && exceptionEnable)
688 XSPerfAccumulate("flush_pipe_num", io.flushOut.valid && isFlushPipe)
689 XSPerfAccumulate("replay_inst_num", io.flushOut.valid && isFlushPipe && deqHasReplayInst)
690
691 val exceptionHappen = (state === s_idle) && valid(deqPtr.value) && (intrEnable || exceptionEnable) && !lastCycleFlush
692 io.exception.valid := RegNext(exceptionHappen)
693 io.exception.bits.pc := RegEnable(debug_deqUop.pc, exceptionHappen)
694 io.exception.bits.instr := RegEnable(debug_deqUop.instr, exceptionHappen)
695 io.exception.bits.commitType := RegEnable(deqDispatchData.commitType, exceptionHappen)
696 io.exception.bits.exceptionVec := RegEnable(exceptionDataRead.bits.exceptionVec, exceptionHappen)
697 io.exception.bits.singleStep := RegEnable(exceptionDataRead.bits.singleStep, exceptionHappen)
698 io.exception.bits.crossPageIPFFix := RegEnable(exceptionDataRead.bits.crossPageIPFFix, exceptionHappen)
699 io.exception.bits.isInterrupt := RegEnable(intrEnable, exceptionHappen)
700// io.exception.bits.trigger := RegEnable(exceptionDataRead.bits.trigger, exceptionHappen)
692 io.exception.valid := RegNext(exceptionHappen)
693 io.exception.bits.uop := RegEnable(debug_deqUop, exceptionHappen)
694 io.exception.bits.uop.ctrl.commitType := RegEnable(deqDispatchData.commitType, exceptionHappen)
695 io.exception.bits.uop.cf.exceptionVec := RegEnable(exceptionDataRead.bits.exceptionVec, exceptionHappen)
696 io.exception.bits.uop.ctrl.singleStep := RegEnable(exceptionDataRead.bits.singleStep, exceptionHappen)
697 io.exception.bits.uop.cf.crossPageIPFFix := RegEnable(exceptionDataRead.bits.crossPageIPFFix, exceptionHappen)
698 io.exception.bits.isInterrupt := RegEnable(intrEnable, exceptionHappen)
699 io.exception.bits.uop.cf.trigger := RegEnable(exceptionDataRead.bits.trigger, exceptionHappen)
701
702 XSDebug(io.flushOut.valid,
700
701 XSDebug(io.flushOut.valid,
703 p"generate redirect: pc 0x${Hexadecimal(io.exception.bits.pc)} intr $intrEnable " +
702 p"generate redirect: pc 0x${Hexadecimal(io.exception.bits.uop.cf.pc)} intr $intrEnable " +
704 p"excp $exceptionEnable flushPipe $isFlushPipe " +
705 p"Trap_target 0x${Hexadecimal(io.csr.trapTarget)} exceptionVec ${Binary(exceptionDataRead.bits.exceptionVec.asUInt)}\n")
706
707
708 /**
709 * Commits (and walk)
710 * They share the same width.
711 */
712 val shouldWalkVec = VecInit(walkPtrVec.map(_ <= lastWalkPtr))
713 val walkFinished = VecInit(walkPtrVec.map(_ >= lastWalkPtr)).asUInt.orR
703 p"excp $exceptionEnable flushPipe $isFlushPipe " +
704 p"Trap_target 0x${Hexadecimal(io.csr.trapTarget)} exceptionVec ${Binary(exceptionDataRead.bits.exceptionVec.asUInt)}\n")
705
706
707 /**
708 * Commits (and walk)
709 * They share the same width.
710 */
711 val shouldWalkVec = VecInit(walkPtrVec.map(_ <= lastWalkPtr))
712 val walkFinished = VecInit(walkPtrVec.map(_ >= lastWalkPtr)).asUInt.orR
714 rab.io.robWalkEnd := state === s_walk && walkFinished
715
716 require(RenameWidth <= CommitWidth)
717
718 // wiring to csr
719 val (wflags, fpWen) = (0 until CommitWidth).map(i => {
720 val v = io.commits.commitValid(i)
721 val info = io.commits.info(i)
722 (v & info.wflags, v & info.fpWen)
723 }).unzip
724 val fflags = Wire(Valid(UInt(5.W)))
725 fflags.valid := io.commits.isCommit && VecInit(wflags).asUInt.orR
726 fflags.bits := wflags.zip(fflagsDataRead).map({
727 case (w, f) => Mux(w, f, 0.U)
728 }).reduce(_|_)
729 val dirty_fs = io.commits.isCommit && VecInit(fpWen).asUInt.orR
730
713
714 require(RenameWidth <= CommitWidth)
715
716 // wiring to csr
717 val (wflags, fpWen) = (0 until CommitWidth).map(i => {
718 val v = io.commits.commitValid(i)
719 val info = io.commits.info(i)
720 (v & info.wflags, v & info.fpWen)
721 }).unzip
722 val fflags = Wire(Valid(UInt(5.W)))
723 fflags.valid := io.commits.isCommit && VecInit(wflags).asUInt.orR
724 fflags.bits := wflags.zip(fflagsDataRead).map({
725 case (w, f) => Mux(w, f, 0.U)
726 }).reduce(_|_)
727 val dirty_fs = io.commits.isCommit && VecInit(fpWen).asUInt.orR
728
731 val vxsat = Wire(Valid(Bool()))
732 vxsat.valid := io.commits.isCommit && vxsat.bits
733 vxsat.bits := io.commits.commitValid.zip(vxsatDataRead).map {
734 case (valid, vxsat) => valid & vxsat
735 }.reduce(_ | _)
736
737 // when mispredict branches writeback, stop commit in the next 2 cycles
738 // TODO: don't check all exu write back
729 // when mispredict branches writeback, stop commit in the next 2 cycles
730 // TODO: don't check all exu write back
739 val misPredWb = Cat(VecInit(redirectWBs.map(wb =>
740 wb.bits.redirect.get.bits.cfiUpdate.isMisPred && wb.bits.redirect.get.valid && wb.valid
731 val misPredWb = Cat(VecInit(exuWriteback.map(wb =>
732 wb.bits.redirect.cfiUpdate.isMisPred && wb.bits.redirectValid
741 ))).orR
742 val misPredBlockCounter = Reg(UInt(3.W))
743 misPredBlockCounter := Mux(misPredWb,
744 "b111".U,
745 misPredBlockCounter >> 1.U
746 )
747 val misPredBlock = misPredBlockCounter(0)
733 ))).orR
734 val misPredBlockCounter = Reg(UInt(3.W))
735 misPredBlockCounter := Mux(misPredWb,
736 "b111".U,
737 misPredBlockCounter >> 1.U
738 )
739 val misPredBlock = misPredBlockCounter(0)
748 val blockCommit = misPredBlock || isReplaying || lastCycleFlush || hasWFI
740 val blockCommit = misPredBlock || isReplaying || lastCycleFlush || hasWFI || io.redirect.valid
749
750 io.commits.isWalk := state === s_walk
751 io.commits.isCommit := state === s_idle && !blockCommit
752 val walk_v = VecInit(walkPtrVec.map(ptr => valid(ptr.value)))
753 val commit_v = VecInit(deqPtrVec.map(ptr => valid(ptr.value)))
754 // store will be commited iff both sta & std have been writebacked
741
742 io.commits.isWalk := state === s_walk
743 io.commits.isCommit := state === s_idle && !blockCommit
744 val walk_v = VecInit(walkPtrVec.map(ptr => valid(ptr.value)))
745 val commit_v = VecInit(deqPtrVec.map(ptr => valid(ptr.value)))
746 // store will be commited iff both sta & std have been writebacked
755 val commit_w = VecInit(deqPtrVec.map(ptr => isWritebacked(ptr.value)))
747 val commit_w = VecInit(deqPtrVec.map(ptr => writebacked(ptr.value) && store_data_writebacked(ptr.value)))
756 val commit_exception = exceptionDataRead.valid && !isAfter(exceptionDataRead.bits.robIdx, deqPtrVec.last)
757 val commit_block = VecInit((0 until CommitWidth).map(i => !commit_w(i)))
758 val allowOnlyOneCommit = commit_exception || intrBitSetReg
759 // for instructions that may block others, we don't allow them to commit
760 for (i <- 0 until CommitWidth) {
761 // defaults: state === s_idle and instructions commit
762 // when intrBitSetReg, allow only one instruction to commit at each clock cycle
763 val isBlocked = if (i != 0) Cat(commit_block.take(i)).orR || allowOnlyOneCommit else intrEnable || deqHasException || deqHasReplayInst
764 io.commits.commitValid(i) := commit_v(i) && commit_w(i) && !isBlocked
765 io.commits.info(i) := dispatchDataRead(i)
766 io.commits.robIdx(i) := deqPtrVec(i)
767
768 when (state === s_walk) {
769 io.commits.walkValid(i) := shouldWalkVec(i)
770 when (io.commits.isWalk && state === s_walk && shouldWalkVec(i)) {
748 val commit_exception = exceptionDataRead.valid && !isAfter(exceptionDataRead.bits.robIdx, deqPtrVec.last)
749 val commit_block = VecInit((0 until CommitWidth).map(i => !commit_w(i)))
750 val allowOnlyOneCommit = commit_exception || intrBitSetReg
751 // for instructions that may block others, we don't allow them to commit
752 for (i <- 0 until CommitWidth) {
753 // defaults: state === s_idle and instructions commit
754 // when intrBitSetReg, allow only one instruction to commit at each clock cycle
755 val isBlocked = if (i != 0) Cat(commit_block.take(i)).orR || allowOnlyOneCommit else intrEnable || deqHasException || deqHasReplayInst
756 io.commits.commitValid(i) := commit_v(i) && commit_w(i) && !isBlocked
757 io.commits.info(i) := dispatchDataRead(i)
758 io.commits.robIdx(i) := deqPtrVec(i)
759
760 when (state === s_walk) {
761 io.commits.walkValid(i) := shouldWalkVec(i)
762 when (io.commits.isWalk && state === s_walk && shouldWalkVec(i)) {
771 XSError(!walk_v(i), s"The walking entry($i) should be valid\n")
763 XSError(!walk_v(i), s"why not $i???\n")
772 }
773 }
774
775 XSInfo(io.commits.isCommit && io.commits.commitValid(i),
764 }
765 }
766
767 XSInfo(io.commits.isCommit && io.commits.commitValid(i),
776 "retired pc %x wen %d ldest %d pdest %x data %x fflags: %b vxsat: %b\n",
777 debug_microOp(deqPtrVec(i).value).pc,
768 "retired pc %x wen %d ldest %d pdest %x data %x fflags: %b\n",
769 debug_microOp(deqPtrVec(i).value).cf.pc,
778 io.commits.info(i).rfWen,
779 io.commits.info(i).ldest,
780 io.commits.info(i).pdest,
781 debug_exuData(deqPtrVec(i).value),
770 io.commits.info(i).rfWen,
771 io.commits.info(i).ldest,
772 io.commits.info(i).pdest,
773 debug_exuData(deqPtrVec(i).value),
782 fflagsDataRead(i),
783 vxsatDataRead(i)
774 fflagsDataRead(i)
784 )
785 XSInfo(state === s_walk && io.commits.walkValid(i), "walked pc %x wen %d ldst %d data %x\n",
775 )
776 XSInfo(state === s_walk && io.commits.walkValid(i), "walked pc %x wen %d ldst %d data %x\n",
786 debug_microOp(walkPtrVec(i).value).pc,
777 debug_microOp(walkPtrVec(i).value).cf.pc,
787 io.commits.info(i).rfWen,
788 io.commits.info(i).ldest,
789 debug_exuData(walkPtrVec(i).value)
790 )
791 }
792 if (env.EnableDifftest) {
793 io.commits.info.map(info => dontTouch(info.pc))
794 }
795
778 io.commits.info(i).rfWen,
779 io.commits.info(i).ldest,
780 debug_exuData(walkPtrVec(i).value)
781 )
782 }
783 if (env.EnableDifftest) {
784 io.commits.info.map(info => dontTouch(info.pc))
785 }
786
796 // sync fflags/dirty_fs/vxsat to csr
787 // sync fflags/dirty_fs to csr
797 io.csr.fflags := RegNext(fflags)
798 io.csr.dirty_fs := RegNext(dirty_fs)
788 io.csr.fflags := RegNext(fflags)
789 io.csr.dirty_fs := RegNext(dirty_fs)
799 io.csr.vxsat := RegNext(vxsat)
800
790
801 // sync v csr to csr
802 // for difftest
803 if(env.AlwaysBasicDiff || env.EnableDifftest) {
804 val isDiffWriteVconfigVec = io.diffCommits.commitValid.zip(io.diffCommits.info).map { case (valid, info) => valid && info.ldest === VCONFIG_IDX.U && info.vecWen }.reverse
805 io.csr.vcsrFlag := RegNext(io.diffCommits.isCommit && Cat(isDiffWriteVconfigVec).orR)
806 }
807 else{
808 io.csr.vcsrFlag := false.B
809 }
810
811 // commit load/store to lsq
812 val ldCommitVec = VecInit((0 until CommitWidth).map(i => io.commits.commitValid(i) && io.commits.info(i).commitType === CommitType.LOAD))
813 val stCommitVec = VecInit((0 until CommitWidth).map(i => io.commits.commitValid(i) && io.commits.info(i).commitType === CommitType.STORE))
814 io.lsq.lcommit := RegNext(Mux(io.commits.isCommit, PopCount(ldCommitVec), 0.U))
815 io.lsq.scommit := RegNext(Mux(io.commits.isCommit, PopCount(stCommitVec), 0.U))
816 // indicate a pending load or store
817 io.lsq.pendingld := RegNext(io.commits.isCommit && io.commits.info(0).commitType === CommitType.LOAD && valid(deqPtr.value) && mmio(deqPtr.value))
818 io.lsq.pendingst := RegNext(io.commits.isCommit && io.commits.info(0).commitType === CommitType.STORE && valid(deqPtr.value))
819 io.lsq.commit := RegNext(io.commits.isCommit && io.commits.commitValid(0))
820 io.lsq.pendingPtr := RegNext(deqPtr)
821
822 /**
823 * state changes
824 * (1) redirect: switch to s_walk
825 * (2) walk: when walking comes to the end, switch to s_idle
826 */
791 // commit load/store to lsq
792 val ldCommitVec = VecInit((0 until CommitWidth).map(i => io.commits.commitValid(i) && io.commits.info(i).commitType === CommitType.LOAD))
793 val stCommitVec = VecInit((0 until CommitWidth).map(i => io.commits.commitValid(i) && io.commits.info(i).commitType === CommitType.STORE))
794 io.lsq.lcommit := RegNext(Mux(io.commits.isCommit, PopCount(ldCommitVec), 0.U))
795 io.lsq.scommit := RegNext(Mux(io.commits.isCommit, PopCount(stCommitVec), 0.U))
796 // indicate a pending load or store
797 io.lsq.pendingld := RegNext(io.commits.isCommit && io.commits.info(0).commitType === CommitType.LOAD && valid(deqPtr.value) && mmio(deqPtr.value))
798 io.lsq.pendingst := RegNext(io.commits.isCommit && io.commits.info(0).commitType === CommitType.STORE && valid(deqPtr.value))
799 io.lsq.commit := RegNext(io.commits.isCommit && io.commits.commitValid(0))
800 io.lsq.pendingPtr := RegNext(deqPtr)
801
802 /**
803 * state changes
804 * (1) redirect: switch to s_walk
805 * (2) walk: when walking comes to the end, switch to s_idle
806 */
827 val state_next = Mux(io.redirect.valid, s_walk, Mux(state === s_walk && walkFinished && rab.io.rabWalkEnd, s_idle, state))
807 val state_next = Mux(io.redirect.valid, s_walk, Mux(state === s_walk && walkFinished, s_idle, state))
828 XSPerfAccumulate("s_idle_to_idle", state === s_idle && state_next === s_idle)
829 XSPerfAccumulate("s_idle_to_walk", state === s_idle && state_next === s_walk)
830 XSPerfAccumulate("s_walk_to_idle", state === s_walk && state_next === s_idle)
831 XSPerfAccumulate("s_walk_to_walk", state === s_walk && state_next === s_walk)
832 state := state_next
833
834 /**
835 * pointers and counters
836 */
837 val deqPtrGenModule = Module(new RobDeqPtrWrapper)
838 deqPtrGenModule.io.state := state
839 deqPtrGenModule.io.deq_v := commit_v
840 deqPtrGenModule.io.deq_w := commit_w
841 deqPtrGenModule.io.exception_state := exceptionDataRead
842 deqPtrGenModule.io.intrBitSetReg := intrBitSetReg
808 XSPerfAccumulate("s_idle_to_idle", state === s_idle && state_next === s_idle)
809 XSPerfAccumulate("s_idle_to_walk", state === s_idle && state_next === s_walk)
810 XSPerfAccumulate("s_walk_to_idle", state === s_walk && state_next === s_idle)
811 XSPerfAccumulate("s_walk_to_walk", state === s_walk && state_next === s_walk)
812 state := state_next
813
814 /**
815 * pointers and counters
816 */
817 val deqPtrGenModule = Module(new RobDeqPtrWrapper)
818 deqPtrGenModule.io.state := state
819 deqPtrGenModule.io.deq_v := commit_v
820 deqPtrGenModule.io.deq_w := commit_w
821 deqPtrGenModule.io.exception_state := exceptionDataRead
822 deqPtrGenModule.io.intrBitSetReg := intrBitSetReg
843 deqPtrGenModule.io.hasNoSpecExec := hasWaitForward
823 deqPtrGenModule.io.hasNoSpecExec := hasNoSpecExec
844 deqPtrGenModule.io.interrupt_safe := interrupt_safe(deqPtr.value)
845 deqPtrGenModule.io.blockCommit := blockCommit
846 deqPtrVec := deqPtrGenModule.io.out
847 val deqPtrVec_next = deqPtrGenModule.io.next_out
848
849 val enqPtrGenModule = Module(new RobEnqPtrWrapper)
850 enqPtrGenModule.io.redirect := io.redirect
824 deqPtrGenModule.io.interrupt_safe := interrupt_safe(deqPtr.value)
825 deqPtrGenModule.io.blockCommit := blockCommit
826 deqPtrVec := deqPtrGenModule.io.out
827 val deqPtrVec_next = deqPtrGenModule.io.next_out
828
829 val enqPtrGenModule = Module(new RobEnqPtrWrapper)
830 enqPtrGenModule.io.redirect := io.redirect
851 enqPtrGenModule.io.allowEnqueue := allowEnqueue && rab.io.canEnq
831 enqPtrGenModule.io.allowEnqueue := allowEnqueue
852 enqPtrGenModule.io.hasBlockBackward := hasBlockBackward
832 enqPtrGenModule.io.hasBlockBackward := hasBlockBackward
853 enqPtrGenModule.io.enq := VecInit(io.enq.req.map(req => req.valid && req.bits.firstUop))
833 enqPtrGenModule.io.enq := VecInit(io.enq.req.map(_.valid))
854 enqPtrVec := enqPtrGenModule.io.out
855
856 // next walkPtrVec:
857 // (1) redirect occurs: update according to state
858 // (2) walk: move forwards
859 val walkPtrVec_next = Mux(io.redirect.valid,
860 Mux(io.snpt.useSnpt, snapshots(io.snpt.snptSelect), deqPtrVec_next),
861 Mux(state === s_walk, VecInit(walkPtrVec.map(_ + CommitWidth.U)), walkPtrVec)

--- 56 unchanged lines hidden (view full) ---

918 for (i <- 0 until CommitWidth) {
919 val commitValid = io.commits.isCommit && io.commits.commitValid(i)
920 when (commitValid) {
921 valid(commitReadAddr(i)) := false.B
922 }
923 }
924
925 // debug_inst update
834 enqPtrVec := enqPtrGenModule.io.out
835
836 // next walkPtrVec:
837 // (1) redirect occurs: update according to state
838 // (2) walk: move forwards
839 val walkPtrVec_next = Mux(io.redirect.valid,
840 Mux(io.snpt.useSnpt, snapshots(io.snpt.snptSelect), deqPtrVec_next),
841 Mux(state === s_walk, VecInit(walkPtrVec.map(_ + CommitWidth.U)), walkPtrVec)

--- 56 unchanged lines hidden (view full) ---

898 for (i <- 0 until CommitWidth) {
899 val commitValid = io.commits.isCommit && io.commits.commitValid(i)
900 when (commitValid) {
901 valid(commitReadAddr(i)) := false.B
902 }
903 }
904
905 // debug_inst update
926 for(i <- 0 until (LduCnt + StaCnt)) {
906 for(i <- 0 until (exuParameters.LduCnt + exuParameters.StuCnt)) {
927 debug_lsInfo(io.debug_ls.debugLsInfo(i).s1_robIdx).s1SignalEnable(io.debug_ls.debugLsInfo(i))
928 debug_lsInfo(io.debug_ls.debugLsInfo(i).s2_robIdx).s2SignalEnable(io.debug_ls.debugLsInfo(i))
929 }
907 debug_lsInfo(io.debug_ls.debugLsInfo(i).s1_robIdx).s1SignalEnable(io.debug_ls.debugLsInfo(i))
908 debug_lsInfo(io.debug_ls.debugLsInfo(i).s2_robIdx).s2SignalEnable(io.debug_ls.debugLsInfo(i))
909 }
930 for (i <- 0 until LduCnt) {
910 for (i <- 0 until exuParameters.LduCnt) {
931 debug_lsTopdownInfo(io.lsTopdownInfo(i).s1.robIdx).s1SignalEnable(io.lsTopdownInfo(i))
932 debug_lsTopdownInfo(io.lsTopdownInfo(i).s2.robIdx).s2SignalEnable(io.lsTopdownInfo(i))
933 }
934
911 debug_lsTopdownInfo(io.lsTopdownInfo(i).s1.robIdx).s1SignalEnable(io.lsTopdownInfo(i))
912 debug_lsTopdownInfo(io.lsTopdownInfo(i).s2.robIdx).s2SignalEnable(io.lsTopdownInfo(i))
913 }
914
935 // writeback logic set numWbPorts writebacked to true
936 val blockWbSeq = Wire(Vec(exuWBs.length, Bool()))
937 blockWbSeq.map(_ := false.B)
938 for ((wb, blockWb) <- exuWBs.zip(blockWbSeq)) {
939 when(wb.valid) {
940 val wbHasException = wb.bits.exceptionVec.getOrElse(0.U).asUInt.orR
941 val wbHasTriggerHit = false.B //Todo: wb.bits.trigger.getHitBackend
942 val wbHasFlushPipe = wb.bits.flushPipe.getOrElse(false.B)
943 val wbHasReplayInst = wb.bits.replay.getOrElse(false.B) //Todo: && wb.bits.replayInst
944 blockWb := wbHasException || wbHasFlushPipe || wbHasReplayInst || wbHasTriggerHit
915 // status field: writebacked
916 // enqueue logic set 6 writebacked to false
917 for (i <- 0 until RenameWidth) {
918 when (canEnqueue(i)) {
919 val enqHasException = ExceptionNO.selectFrontend(io.enq.req(i).bits.cf.exceptionVec).asUInt.orR
920 val enqHasTriggerHit = io.enq.req(i).bits.cf.trigger.getHitFrontend
921 val enqIsWritebacked = io.enq.req(i).bits.eliminatedMove
922 writebacked(allocatePtrVec(i).value) := enqIsWritebacked && !enqHasException && !enqHasTriggerHit
923 val isStu = io.enq.req(i).bits.ctrl.fuType === FuType.stu
924 store_data_writebacked(allocatePtrVec(i).value) := !isStu
945 }
946 }
925 }
926 }
947
948 // if the first uop of an instruction is valid , write writebackedCounter
949 val uopEnqValidSeq = io.enq.req.map(req => io.enq.canAccept && req.valid)
950 val instEnqValidSeq = io.enq.req.map (req => io.enq.canAccept && req.valid && req.bits.firstUop)
951 val enqNeedWriteRFSeq = io.enq.req.map(_.bits.needWriteRf)
952 val enqRobIdxSeq = io.enq.req.map(req => req.bits.robIdx.value)
953 val enqUopNumVec = VecInit(io.enq.req.map(req => req.bits.numUops))
954 val enqEliminatedMoveVec = VecInit(io.enq.req.map(req => req.bits.eliminatedMove))
955
956 private val enqWriteStdVec: Vec[Bool] = VecInit(io.enq.req.map {
957 req => FuType.isAMO(req.bits.fuType) || FuType.isStore(req.bits.fuType)
958 })
959 val enqWbSizeSeq = io.enq.req.map { req =>
960 val enqHasException = ExceptionNO.selectFrontend(req.bits.exceptionVec).asUInt.orR
961 val enqHasTriggerHit = req.bits.trigger.getHitFrontend
962 Mux(req.bits.eliminatedMove, Mux(enqHasException || enqHasTriggerHit, 1.U, 0.U),
963 Mux(FuType.isAMO(req.bits.fuType) || FuType.isStore(req.bits.fuType), 2.U, 1.U))
927 when (exceptionGen.io.out.valid) {
928 val wbIdx = exceptionGen.io.out.bits.robIdx.value
929 writebacked(wbIdx) := true.B
930 store_data_writebacked(wbIdx) := true.B
964 }
931 }
965 val enqWbSizeSumSeq = enqRobIdxSeq.zipWithIndex.map { case (robIdx, idx) =>
966 val addend = enqRobIdxSeq.zip(enqWbSizeSeq).take(idx + 1).map { case (uopRobIdx, uopWbSize) => Mux(robIdx === uopRobIdx, uopWbSize, 0.U) }
967 addend.reduce(_ +& _)
932 // writeback logic set numWbPorts writebacked to true
933 for ((wb, cfgs) <- exuWriteback.zip(wbExuConfigs(exeWbSel))) {
934 when (wb.valid) {
935 val wbIdx = wb.bits.uop.robIdx.value
936 val wbHasException = ExceptionNO.selectByExu(wb.bits.uop.cf.exceptionVec, cfgs).asUInt.orR
937 val wbHasTriggerHit = wb.bits.uop.cf.trigger.getHitBackend
938 val wbHasFlushPipe = cfgs.exists(_.flushPipe).B && wb.bits.uop.ctrl.flushPipe
939 val wbHasReplayInst = cfgs.exists(_.replayInst).B && wb.bits.uop.ctrl.replayInst
940 val block_wb = wbHasException || wbHasFlushPipe || wbHasReplayInst || wbHasTriggerHit
941 writebacked(wbIdx) := !block_wb
942 }
968 }
943 }
969 val fflags_wb = fflagsPorts
970 val vxsat_wb = vxsatPorts
971 for(i <- 0 until RobSize){
972
973 val robIdxMatchSeq = io.enq.req.map(_.bits.robIdx.value === i.U)
974 val uopCanEnqSeq = uopEnqValidSeq.zip(robIdxMatchSeq).map{ case(valid, isMatch) => valid && isMatch }
975 val instCanEnqSeq = instEnqValidSeq.zip(robIdxMatchSeq).map{ case(valid, isMatch) => valid && isMatch }
976 val instCanEnqFlag = Cat(instCanEnqSeq).orR
977
978 realDestSize(i) := Mux(!valid(i) && instCanEnqFlag || valid(i), realDestSize(i) + PopCount(enqNeedWriteRFSeq.zip(uopCanEnqSeq).map{ case(writeFlag, valid) => writeFlag && valid }), 0.U)
979
980 val enqUopNum = PriorityMux(instCanEnqSeq, enqUopNumVec)
981 val enqEliminatedMove = PriorityMux(instCanEnqSeq, enqEliminatedMoveVec)
982 val enqWriteStd = PriorityMux(instCanEnqSeq, enqWriteStdVec)
983
984 val canWbSeq = exuWBs.map(writeback => writeback.valid && writeback.bits.robIdx.value === i.U)
985 val canWbNoBlockSeq = canWbSeq.zip(blockWbSeq).map{ case(canWb, blockWb) => canWb && !blockWb }
986 val canStdWbSeq = VecInit(stdWBs.map(writeback => writeback.valid && writeback.bits.robIdx.value === i.U))
987 val wbCnt = PopCount(canWbNoBlockSeq)
988 when (exceptionGen.io.out.valid && exceptionGen.io.out.bits.robIdx.value === i.U) {
989 // exception flush
990 uopNumVec(i) := 0.U
991 stdWritebacked(i) := true.B
992 }.elsewhen(!valid(i) && instCanEnqFlag) {
993 // enq set num of uops
994 uopNumVec(i) := Mux(enqEliminatedMove, 0.U, enqUopNum)
995 stdWritebacked(i) := Mux(enqWriteStd, false.B, true.B)
996 }.elsewhen(valid(i)) {
997 // update by writing back
998 uopNumVec(i) := uopNumVec(i) - wbCnt
999 when (canStdWbSeq.asUInt.orR) {
1000 stdWritebacked(i) := true.B
1001 }
1002 }.otherwise {
1003 uopNumVec(i) := 0.U
944 // store data writeback logic mark store as data_writebacked
945 for (wb <- stdWriteback) {
946 when(RegNext(wb.valid)) {
947 store_data_writebacked(RegNext(wb.bits.uop.robIdx.value)) := true.B
1004 }
948 }
1005
1006 val fflagsCanWbSeq = fflags_wb.map(writeback => writeback.valid && writeback.bits.robIdx.value === i.U)
1007 val fflagsRes = fflagsCanWbSeq.zip(fflags_wb).map { case (canWb, wb) => Mux(canWb, wb.bits.fflags.get, 0.U) }.fold(false.B)(_ | _)
1008 fflagsDataModule(i) := Mux(!valid(i) && instCanEnqFlag, 0.U, fflagsDataModule(i) | fflagsRes)
1009
1010 val vxsatCanWbSeq = vxsat_wb.map(writeback => writeback.valid && writeback.bits.robIdx.value === i.U)
1011 val vxsatRes = vxsatCanWbSeq.zip(vxsat_wb).map { case (canWb, wb) => Mux(canWb, wb.bits.vxsat.get, 0.U) }.fold(false.B)(_ | _)
1012 vxsatDataModule(i) := Mux(!valid(i) && instCanEnqFlag, 0.U, vxsatDataModule(i) | vxsatRes)
1013 }
1014
1015 // flagBkup
1016 // enqueue logic set 6 flagBkup at most
1017 for (i <- 0 until RenameWidth) {
1018 when (canEnqueue(i)) {
1019 flagBkup(allocatePtrVec(i).value) := allocatePtrVec(i).flag
1020 }

--- 5 unchanged lines hidden (view full) ---

1026 // Note that instructions won't change the system's states in this cycle.
1027 when (RegNext(canEnqueue(i))) {
1028 // For now, we allow non-load-store instructions to trigger interrupts
1029 // For MMIO instructions, they should not trigger interrupts since they may
1030 // be sent to lower level before it writes back.
1031 // However, we cannot determine whether a load/store instruction is MMIO.
1032 // Thus, we don't allow load/store instructions to trigger an interrupt.
1033 // TODO: support non-MMIO load-store instructions to trigger interrupts
949 }
950
951 // flagBkup
952 // enqueue logic set 6 flagBkup at most
953 for (i <- 0 until RenameWidth) {
954 when (canEnqueue(i)) {
955 flagBkup(allocatePtrVec(i).value) := allocatePtrVec(i).flag
956 }

--- 5 unchanged lines hidden (view full) ---

962 // Note that instructions won't change the system's states in this cycle.
963 when (RegNext(canEnqueue(i))) {
964 // For now, we allow non-load-store instructions to trigger interrupts
965 // For MMIO instructions, they should not trigger interrupts since they may
966 // be sent to lower level before it writes back.
967 // However, we cannot determine whether a load/store instruction is MMIO.
968 // Thus, we don't allow load/store instructions to trigger an interrupt.
969 // TODO: support non-MMIO load-store instructions to trigger interrupts
1034 val allow_interrupts = !CommitType.isLoadStore(io.enq.req(i).bits.commitType)
970 val allow_interrupts = !CommitType.isLoadStore(io.enq.req(i).bits.ctrl.commitType)
1035 interrupt_safe(RegNext(allocatePtrVec(i).value)) := RegNext(allow_interrupts)
1036 }
1037 }
1038
1039 /**
1040 * read and write of data modules
1041 */
1042 val commitReadAddr_next = Mux(state_next === s_idle,
1043 VecInit(deqPtrVec_next.map(_.value)),
1044 VecInit(walkPtrVec_next.map(_.value))
1045 )
971 interrupt_safe(RegNext(allocatePtrVec(i).value)) := RegNext(allow_interrupts)
972 }
973 }
974
975 /**
976 * read and write of data modules
977 */
978 val commitReadAddr_next = Mux(state_next === s_idle,
979 VecInit(deqPtrVec_next.map(_.value)),
980 VecInit(walkPtrVec_next.map(_.value))
981 )
982 // NOTE: dispatch info will record the uop of inst
1046 dispatchData.io.wen := canEnqueue
1047 dispatchData.io.waddr := allocatePtrVec.map(_.value)
983 dispatchData.io.wen := canEnqueue
984 dispatchData.io.waddr := allocatePtrVec.map(_.value)
1048 dispatchData.io.wdata.zip(io.enq.req.map(_.bits)).zipWithIndex.foreach{ case ((wdata, req), portIdx) =>
1049 wdata.ldest := req.ldest
1050 wdata.rfWen := req.rfWen
1051 wdata.fpWen := req.fpWen
1052 wdata.vecWen := req.vecWen
1053 wdata.wflags := req.fpu.wflags
1054 wdata.commitType := req.commitType
985 dispatchData.io.wdata.zip(io.enq.req.map(_.bits)).foreach{ case (wdata, req) =>
986 wdata.ldest := req.ctrl.ldest
987 wdata.rfWen := req.ctrl.rfWen
988 wdata.fpWen := req.ctrl.fpWen
989 wdata.wflags := req.ctrl.fpu.wflags
990 wdata.commitType := req.ctrl.commitType
1055 wdata.pdest := req.pdest
991 wdata.pdest := req.pdest
1056 wdata.ftqIdx := req.ftqPtr
1057 wdata.ftqOffset := req.ftqOffset
992 wdata.ftqIdx := req.cf.ftqPtr
993 wdata.ftqOffset := req.cf.ftqOffset
1058 wdata.isMove := req.eliminatedMove
994 wdata.isMove := req.eliminatedMove
1059 wdata.isRVC := req.preDecodeInfo.isRVC
1060 wdata.pc := req.pc
1061 wdata.vtype := req.vpu.vtype
1062 wdata.isVset := req.isVset
995 wdata.isRVC := req.cf.pd.isRVC
996 wdata.pc := req.cf.pc
1063 }
1064 dispatchData.io.raddr := commitReadAddr_next
1065
1066 exceptionGen.io.redirect <> io.redirect
1067 exceptionGen.io.flush := io.flushOut.valid
997 }
998 dispatchData.io.raddr := commitReadAddr_next
999
1000 exceptionGen.io.redirect <> io.redirect
1001 exceptionGen.io.flush := io.flushOut.valid
1068
1069 val canEnqueueEG = VecInit(io.enq.req.map(req => req.valid && io.enq.canAccept))
1070 for (i <- 0 until RenameWidth) {
1002 for (i <- 0 until RenameWidth) {
1071 exceptionGen.io.enq(i).valid := canEnqueueEG(i)
1003 exceptionGen.io.enq(i).valid := canEnqueue(i)
1072 exceptionGen.io.enq(i).bits.robIdx := io.enq.req(i).bits.robIdx
1004 exceptionGen.io.enq(i).bits.robIdx := io.enq.req(i).bits.robIdx
1073 exceptionGen.io.enq(i).bits.exceptionVec := ExceptionNO.selectFrontend(io.enq.req(i).bits.exceptionVec)
1074 exceptionGen.io.enq(i).bits.flushPipe := io.enq.req(i).bits.flushPipe
1075 exceptionGen.io.enq(i).bits.isVset := io.enq.req(i).bits.isVset
1005 exceptionGen.io.enq(i).bits.exceptionVec := ExceptionNO.selectFrontend(io.enq.req(i).bits.cf.exceptionVec)
1006 exceptionGen.io.enq(i).bits.flushPipe := io.enq.req(i).bits.ctrl.flushPipe
1076 exceptionGen.io.enq(i).bits.replayInst := false.B
1007 exceptionGen.io.enq(i).bits.replayInst := false.B
1077 XSError(canEnqueue(i) && io.enq.req(i).bits.replayInst, "enq should not set replayInst")
1078 exceptionGen.io.enq(i).bits.singleStep := io.enq.req(i).bits.singleStep
1079 exceptionGen.io.enq(i).bits.crossPageIPFFix := io.enq.req(i).bits.crossPageIPFFix
1008 XSError(canEnqueue(i) && io.enq.req(i).bits.ctrl.replayInst, "enq should not set replayInst")
1009 exceptionGen.io.enq(i).bits.singleStep := io.enq.req(i).bits.ctrl.singleStep
1010 exceptionGen.io.enq(i).bits.crossPageIPFFix := io.enq.req(i).bits.cf.crossPageIPFFix
1080 exceptionGen.io.enq(i).bits.trigger.clear()
1011 exceptionGen.io.enq(i).bits.trigger.clear()
1081 exceptionGen.io.enq(i).bits.trigger.frontendHit := io.enq.req(i).bits.trigger.frontendHit
1012 exceptionGen.io.enq(i).bits.trigger.frontendHit := io.enq.req(i).bits.cf.trigger.frontendHit
1082 }
1083
1084 println(s"ExceptionGen:")
1013 }
1014
1015 println(s"ExceptionGen:")
1085 println(s"num of exceptions: ${params.numException}")
1086 require(exceptionWBs.length == exceptionGen.io.wb.length,
1087 f"exceptionWBs.length: ${exceptionWBs.length}, " +
1088 f"exceptionGen.io.wb.length: ${exceptionGen.io.wb.length}")
1089 for (((wb, exc_wb), i) <- exceptionWBs.zip(exceptionGen.io.wb).zipWithIndex) {
1016 val exceptionCases = exceptionPorts.map(_._1.flatMap(_.exceptionOut).distinct.sorted)
1017 require(exceptionCases.length == exceptionGen.io.wb.length)
1018 for ((((configs, wb), exc_wb), i) <- exceptionPorts.zip(exceptionGen.io.wb).zipWithIndex) {
1090 exc_wb.valid := wb.valid
1019 exc_wb.valid := wb.valid
1091 exc_wb.bits.robIdx := wb.bits.robIdx
1092 exc_wb.bits.exceptionVec := wb.bits.exceptionVec.get
1093 exc_wb.bits.flushPipe := wb.bits.flushPipe.getOrElse(false.B)
1094 exc_wb.bits.isVset := false.B
1095 exc_wb.bits.replayInst := wb.bits.replay.getOrElse(false.B)
1020 exc_wb.bits.robIdx := wb.bits.uop.robIdx
1021 exc_wb.bits.exceptionVec := ExceptionNO.selectByExu(wb.bits.uop.cf.exceptionVec, configs)
1022 exc_wb.bits.flushPipe := configs.exists(_.flushPipe).B && wb.bits.uop.ctrl.flushPipe
1023 exc_wb.bits.replayInst := configs.exists(_.replayInst).B && wb.bits.uop.ctrl.replayInst
1096 exc_wb.bits.singleStep := false.B
1097 exc_wb.bits.crossPageIPFFix := false.B
1024 exc_wb.bits.singleStep := false.B
1025 exc_wb.bits.crossPageIPFFix := false.B
1098 exc_wb.bits.trigger := 0.U.asTypeOf(exc_wb.bits.trigger) // Todo
1099// println(s" [$i] ${configs.map(_.name)}: exception ${exceptionCases(i)}, " +
1100// s"flushPipe ${configs.exists(_.flushPipe)}, " +
1101// s"replayInst ${configs.exists(_.replayInst)}")
1026 // TODO: make trigger configurable
1027 exc_wb.bits.trigger.clear()
1028 exc_wb.bits.trigger.backendHit := wb.bits.uop.cf.trigger.backendHit
1029 println(s" [$i] ${configs.map(_.name)}: exception ${exceptionCases(i)}, " +
1030 s"flushPipe ${configs.exists(_.flushPipe)}, " +
1031 s"replayInst ${configs.exists(_.replayInst)}")
1102 }
1103
1032 }
1033
1104 fflagsDataRead := (0 until CommitWidth).map(i => fflagsDataModule(deqPtrVec(i).value))
1105 vxsatDataRead := (0 until CommitWidth).map(i => vxsatDataModule(deqPtrVec(i).value))
1034 val fflags_wb = fflagsPorts.map(_._2)
1035 val fflagsDataModule = Module(new SyncDataModuleTemplate(
1036 UInt(5.W), RobSize, CommitWidth, fflags_wb.size)
1037 )
1038 for(i <- fflags_wb.indices){
1039 fflagsDataModule.io.wen (i) := fflags_wb(i).valid
1040 fflagsDataModule.io.waddr(i) := fflags_wb(i).bits.uop.robIdx.value
1041 fflagsDataModule.io.wdata(i) := fflags_wb(i).bits.fflags
1042 }
1043 fflagsDataModule.io.raddr := VecInit(deqPtrVec_next.map(_.value))
1044 fflagsDataRead := fflagsDataModule.io.rdata
1106
1107 val instrCntReg = RegInit(0.U(64.W))
1108 val fuseCommitCnt = PopCount(io.commits.commitValid.zip(io.commits.info).map{ case (v, i) => RegNext(v && CommitType.isFused(i.commitType)) })
1109 val trueCommitCnt = RegNext(commitCnt) +& fuseCommitCnt
1110 val retireCounter = Mux(RegNext(io.commits.isCommit), trueCommitCnt, 0.U)
1111 val instrCnt = instrCntReg + retireCounter
1112 instrCntReg := instrCnt
1113 io.csr.perfinfo.retiredInstr := retireCounter
1114 io.robFull := !allowEnqueue
1115 io.headNotReady := commit_v.head && !commit_w.head
1116
1117 /**
1118 * debug info
1119 */
1120 XSDebug(p"enqPtr ${enqPtr} deqPtr ${deqPtr}\n")
1121 XSDebug("")
1045
1046 val instrCntReg = RegInit(0.U(64.W))
1047 val fuseCommitCnt = PopCount(io.commits.commitValid.zip(io.commits.info).map{ case (v, i) => RegNext(v && CommitType.isFused(i.commitType)) })
1048 val trueCommitCnt = RegNext(commitCnt) +& fuseCommitCnt
1049 val retireCounter = Mux(RegNext(io.commits.isCommit), trueCommitCnt, 0.U)
1050 val instrCnt = instrCntReg + retireCounter
1051 instrCntReg := instrCnt
1052 io.csr.perfinfo.retiredInstr := retireCounter
1053 io.robFull := !allowEnqueue
1054 io.headNotReady := commit_v.head && !commit_w.head
1055
1056 /**
1057 * debug info
1058 */
1059 XSDebug(p"enqPtr ${enqPtr} deqPtr ${deqPtr}\n")
1060 XSDebug("")
1122 XSError(isBefore(enqPtr, deqPtr) && !isFull(enqPtr, deqPtr), "\ndeqPtr is older than enqPtr!\n")
1123 for(i <- 0 until RobSize){
1124 XSDebug(false, !valid(i), "-")
1061 for(i <- 0 until RobSize){
1062 XSDebug(false, !valid(i), "-")
1125 XSDebug(false, valid(i) && isWritebacked(i.U), "w")
1126 XSDebug(false, valid(i) && !isWritebacked(i.U), "v")
1063 XSDebug(false, valid(i) && writebacked(i), "w")
1064 XSDebug(false, valid(i) && !writebacked(i), "v")
1127 }
1128 XSDebug(false, true.B, "\n")
1129
1130 for(i <- 0 until RobSize) {
1131 if(i % 4 == 0) XSDebug("")
1065 }
1066 XSDebug(false, true.B, "\n")
1067
1068 for(i <- 0 until RobSize) {
1069 if(i % 4 == 0) XSDebug("")
1132 XSDebug(false, true.B, "%x ", debug_microOp(i).pc)
1070 XSDebug(false, true.B, "%x ", debug_microOp(i).cf.pc)
1133 XSDebug(false, !valid(i), "- ")
1071 XSDebug(false, !valid(i), "- ")
1134 XSDebug(false, valid(i) && isWritebacked(i.U), "w ")
1135 XSDebug(false, valid(i) && !isWritebacked(i.U), "v ")
1072 XSDebug(false, valid(i) && writebacked(i), "w ")
1073 XSDebug(false, valid(i) && !writebacked(i), "v ")
1136 if(i % 4 == 3) XSDebug(false, true.B, "\n")
1137 }
1138
1139 def ifCommit(counter: UInt): UInt = Mux(io.commits.isCommit, counter, 0.U)
1140 def ifCommitReg(counter: UInt): UInt = Mux(RegNext(io.commits.isCommit), counter, 0.U)
1141
1074 if(i % 4 == 3) XSDebug(false, true.B, "\n")
1075 }
1076
1077 def ifCommit(counter: UInt): UInt = Mux(io.commits.isCommit, counter, 0.U)
1078 def ifCommitReg(counter: UInt): UInt = Mux(RegNext(io.commits.isCommit), counter, 0.U)
1079
1080 val commitDebugExu = deqPtrVec.map(_.value).map(debug_exuDebug(_))
1142 val commitDebugUop = deqPtrVec.map(_.value).map(debug_microOp(_))
1081 val commitDebugUop = deqPtrVec.map(_.value).map(debug_microOp(_))
1082 val commitDebugLsInfo = deqPtrVec.map(_.value).map(debug_lsInfo(_))
1083 ExcitingUtils.addSource(ifCommitReg(trueCommitCnt), "ROBTrueCommit_hart" + p(XSCoreParamsKey).HartId.toString, ExcitingUtils.Perf)
1143 XSPerfAccumulate("clock_cycle", 1.U)
1144 QueuePerf(RobSize, PopCount((0 until RobSize).map(valid(_))), !allowEnqueue)
1145 XSPerfAccumulate("commitUop", ifCommit(commitCnt))
1146 XSPerfAccumulate("commitInstr", ifCommitReg(trueCommitCnt))
1084 XSPerfAccumulate("clock_cycle", 1.U)
1085 QueuePerf(RobSize, PopCount((0 until RobSize).map(valid(_))), !allowEnqueue)
1086 XSPerfAccumulate("commitUop", ifCommit(commitCnt))
1087 XSPerfAccumulate("commitInstr", ifCommitReg(trueCommitCnt))
1147 val commitIsMove = commitDebugUop.map(_.isMove)
1088 XSPerfRolling("ipc", ifCommitReg(trueCommitCnt), 1000, clock, reset)
1089 XSPerfRolling("cpi", perfCnt = 1.U/*Cycle*/, eventTrigger = ifCommitReg(trueCommitCnt), granularity = 1000, clock, reset)
1090 val commitIsMove = commitDebugUop.map(_.ctrl.isMove)
1148 XSPerfAccumulate("commitInstrMove", ifCommit(PopCount(io.commits.commitValid.zip(commitIsMove).map{ case (v, m) => v && m })))
1149 val commitMoveElim = commitDebugUop.map(_.debugInfo.eliminatedMove)
1150 XSPerfAccumulate("commitInstrMoveElim", ifCommit(PopCount(io.commits.commitValid zip commitMoveElim map { case (v, e) => v && e })))
1151 XSPerfAccumulate("commitInstrFused", ifCommitReg(fuseCommitCnt))
1152 val commitIsLoad = io.commits.info.map(_.commitType).map(_ === CommitType.LOAD)
1153 val commitLoadValid = io.commits.commitValid.zip(commitIsLoad).map{ case (v, t) => v && t }
1154 XSPerfAccumulate("commitInstrLoad", ifCommit(PopCount(commitLoadValid)))
1155 val commitIsBranch = io.commits.info.map(_.commitType).map(_ === CommitType.BRANCH)
1156 val commitBranchValid = io.commits.commitValid.zip(commitIsBranch).map{ case (v, t) => v && t }
1157 XSPerfAccumulate("commitInstrBranch", ifCommit(PopCount(commitBranchValid)))
1091 XSPerfAccumulate("commitInstrMove", ifCommit(PopCount(io.commits.commitValid.zip(commitIsMove).map{ case (v, m) => v && m })))
1092 val commitMoveElim = commitDebugUop.map(_.debugInfo.eliminatedMove)
1093 XSPerfAccumulate("commitInstrMoveElim", ifCommit(PopCount(io.commits.commitValid zip commitMoveElim map { case (v, e) => v && e })))
1094 XSPerfAccumulate("commitInstrFused", ifCommitReg(fuseCommitCnt))
1095 val commitIsLoad = io.commits.info.map(_.commitType).map(_ === CommitType.LOAD)
1096 val commitLoadValid = io.commits.commitValid.zip(commitIsLoad).map{ case (v, t) => v && t }
1097 XSPerfAccumulate("commitInstrLoad", ifCommit(PopCount(commitLoadValid)))
1098 val commitIsBranch = io.commits.info.map(_.commitType).map(_ === CommitType.BRANCH)
1099 val commitBranchValid = io.commits.commitValid.zip(commitIsBranch).map{ case (v, t) => v && t }
1100 XSPerfAccumulate("commitInstrBranch", ifCommit(PopCount(commitBranchValid)))
1158 val commitLoadWaitBit = commitDebugUop.map(_.loadWaitBit)
1101 val commitLoadWaitBit = commitDebugUop.map(_.cf.loadWaitBit)
1159 XSPerfAccumulate("commitInstrLoadWait", ifCommit(PopCount(commitLoadValid.zip(commitLoadWaitBit).map{ case (v, w) => v && w })))
1160 val commitIsStore = io.commits.info.map(_.commitType).map(_ === CommitType.STORE)
1161 XSPerfAccumulate("commitInstrStore", ifCommit(PopCount(io.commits.commitValid.zip(commitIsStore).map{ case (v, t) => v && t })))
1102 XSPerfAccumulate("commitInstrLoadWait", ifCommit(PopCount(commitLoadValid.zip(commitLoadWaitBit).map{ case (v, w) => v && w })))
1103 val commitIsStore = io.commits.info.map(_.commitType).map(_ === CommitType.STORE)
1104 XSPerfAccumulate("commitInstrStore", ifCommit(PopCount(io.commits.commitValid.zip(commitIsStore).map{ case (v, t) => v && t })))
1162 XSPerfAccumulate("writeback", PopCount((0 until RobSize).map(i => valid(i) && isWritebacked(i.U))))
1105 XSPerfAccumulate("writeback", PopCount((0 until RobSize).map(i => valid(i) && writebacked(i))))
1163 // XSPerfAccumulate("enqInstr", PopCount(io.dp1Req.map(_.fire)))
1164 // XSPerfAccumulate("d2rVnR", PopCount(io.dp1Req.map(p => p.valid && !p.ready)))
1165 XSPerfAccumulate("walkInstr", Mux(io.commits.isWalk, PopCount(io.commits.walkValid), 0.U))
1166 XSPerfAccumulate("walkCycle", state === s_walk)
1106 // XSPerfAccumulate("enqInstr", PopCount(io.dp1Req.map(_.fire)))
1107 // XSPerfAccumulate("d2rVnR", PopCount(io.dp1Req.map(p => p.valid && !p.ready)))
1108 XSPerfAccumulate("walkInstr", Mux(io.commits.isWalk, PopCount(io.commits.walkValid), 0.U))
1109 XSPerfAccumulate("walkCycle", state === s_walk)
1167 val deqNotWritebacked = valid(deqPtr.value) && !isWritebacked(deqPtr.value)
1110 val deqNotWritebacked = valid(deqPtr.value) && !writebacked(deqPtr.value)
1168 val deqUopCommitType = io.commits.info(0).commitType
1169 XSPerfAccumulate("waitNormalCycle", deqNotWritebacked && deqUopCommitType === CommitType.NORMAL)
1170 XSPerfAccumulate("waitBranchCycle", deqNotWritebacked && deqUopCommitType === CommitType.BRANCH)
1171 XSPerfAccumulate("waitLoadCycle", deqNotWritebacked && deqUopCommitType === CommitType.LOAD)
1172 XSPerfAccumulate("waitStoreCycle", deqNotWritebacked && deqUopCommitType === CommitType.STORE)
1173 XSPerfAccumulate("robHeadPC", io.commits.info(0).pc)
1174 val dispatchLatency = commitDebugUop.map(uop => uop.debugInfo.dispatchTime - uop.debugInfo.renameTime)
1175 val enqRsLatency = commitDebugUop.map(uop => uop.debugInfo.enqRsTime - uop.debugInfo.dispatchTime)
1176 val selectLatency = commitDebugUop.map(uop => uop.debugInfo.selectTime - uop.debugInfo.enqRsTime)
1177 val issueLatency = commitDebugUop.map(uop => uop.debugInfo.issueTime - uop.debugInfo.selectTime)
1178 val executeLatency = commitDebugUop.map(uop => uop.debugInfo.writebackTime - uop.debugInfo.issueTime)
1179 val rsFuLatency = commitDebugUop.map(uop => uop.debugInfo.writebackTime - uop.debugInfo.enqRsTime)
1180 val commitLatency = commitDebugUop.map(uop => timer - uop.debugInfo.writebackTime)
1111 val deqUopCommitType = io.commits.info(0).commitType
1112 XSPerfAccumulate("waitNormalCycle", deqNotWritebacked && deqUopCommitType === CommitType.NORMAL)
1113 XSPerfAccumulate("waitBranchCycle", deqNotWritebacked && deqUopCommitType === CommitType.BRANCH)
1114 XSPerfAccumulate("waitLoadCycle", deqNotWritebacked && deqUopCommitType === CommitType.LOAD)
1115 XSPerfAccumulate("waitStoreCycle", deqNotWritebacked && deqUopCommitType === CommitType.STORE)
1116 XSPerfAccumulate("robHeadPC", io.commits.info(0).pc)
1117 val dispatchLatency = commitDebugUop.map(uop => uop.debugInfo.dispatchTime - uop.debugInfo.renameTime)
1118 val enqRsLatency = commitDebugUop.map(uop => uop.debugInfo.enqRsTime - uop.debugInfo.dispatchTime)
1119 val selectLatency = commitDebugUop.map(uop => uop.debugInfo.selectTime - uop.debugInfo.enqRsTime)
1120 val issueLatency = commitDebugUop.map(uop => uop.debugInfo.issueTime - uop.debugInfo.selectTime)
1121 val executeLatency = commitDebugUop.map(uop => uop.debugInfo.writebackTime - uop.debugInfo.issueTime)
1122 val rsFuLatency = commitDebugUop.map(uop => uop.debugInfo.writebackTime - uop.debugInfo.enqRsTime)
1123 val commitLatency = commitDebugUop.map(uop => timer - uop.debugInfo.writebackTime)
1124 val accessLatency = commitDebugUop.map(uop => uop.debugInfo.writebackTime - uop.debugInfo.issueTime)
1125 val tlbLatency = commitDebugUop.map(uop => uop.debugInfo.tlbRespTime - uop.debugInfo.tlbFirstReqTime)
1181 def latencySum(cond: Seq[Bool], latency: Seq[UInt]): UInt = {
1182 cond.zip(latency).map(x => Mux(x._1, x._2, 0.U)).reduce(_ +& _)
1183 }
1184 for (fuType <- FuType.functionNameMap.keys) {
1185 val fuName = FuType.functionNameMap(fuType)
1126 def latencySum(cond: Seq[Bool], latency: Seq[UInt]): UInt = {
1127 cond.zip(latency).map(x => Mux(x._1, x._2, 0.U)).reduce(_ +& _)
1128 }
1129 for (fuType <- FuType.functionNameMap.keys) {
1130 val fuName = FuType.functionNameMap(fuType)
1186 val commitIsFuType = io.commits.commitValid.zip(commitDebugUop).map(x => x._1 && x._2.fuType === fuType.U )
1131 val commitIsFuType = io.commits.commitValid.zip(commitDebugUop).map(x => x._1 && x._2.ctrl.fuType === fuType.U )
1132 XSPerfRolling(s"ipc_futype_${fuName}", ifCommit(PopCount(commitIsFuType)), 1000, clock, reset)
1187 XSPerfAccumulate(s"${fuName}_instr_cnt", ifCommit(PopCount(commitIsFuType)))
1188 XSPerfAccumulate(s"${fuName}_latency_dispatch", ifCommit(latencySum(commitIsFuType, dispatchLatency)))
1189 XSPerfAccumulate(s"${fuName}_latency_enq_rs", ifCommit(latencySum(commitIsFuType, enqRsLatency)))
1190 XSPerfAccumulate(s"${fuName}_latency_select", ifCommit(latencySum(commitIsFuType, selectLatency)))
1191 XSPerfAccumulate(s"${fuName}_latency_issue", ifCommit(latencySum(commitIsFuType, issueLatency)))
1192 XSPerfAccumulate(s"${fuName}_latency_execute", ifCommit(latencySum(commitIsFuType, executeLatency)))
1193 XSPerfAccumulate(s"${fuName}_latency_enq_rs_execute", ifCommit(latencySum(commitIsFuType, rsFuLatency)))
1194 XSPerfAccumulate(s"${fuName}_latency_commit", ifCommit(latencySum(commitIsFuType, commitLatency)))
1133 XSPerfAccumulate(s"${fuName}_instr_cnt", ifCommit(PopCount(commitIsFuType)))
1134 XSPerfAccumulate(s"${fuName}_latency_dispatch", ifCommit(latencySum(commitIsFuType, dispatchLatency)))
1135 XSPerfAccumulate(s"${fuName}_latency_enq_rs", ifCommit(latencySum(commitIsFuType, enqRsLatency)))
1136 XSPerfAccumulate(s"${fuName}_latency_select", ifCommit(latencySum(commitIsFuType, selectLatency)))
1137 XSPerfAccumulate(s"${fuName}_latency_issue", ifCommit(latencySum(commitIsFuType, issueLatency)))
1138 XSPerfAccumulate(s"${fuName}_latency_execute", ifCommit(latencySum(commitIsFuType, executeLatency)))
1139 XSPerfAccumulate(s"${fuName}_latency_enq_rs_execute", ifCommit(latencySum(commitIsFuType, rsFuLatency)))
1140 XSPerfAccumulate(s"${fuName}_latency_commit", ifCommit(latencySum(commitIsFuType, commitLatency)))
1195 if (fuType == FuType.fmac) {
1196 val commitIsFma = commitIsFuType.zip(commitDebugUop).map(x => x._1 && x._2.fpu.ren3 )
1141 if (fuType == FuType.fmac.litValue) {
1142 val commitIsFma = commitIsFuType.zip(commitDebugUop).map(x => x._1 && x._2.ctrl.fpu.ren3 )
1197 XSPerfAccumulate(s"${fuName}_instr_cnt_fma", ifCommit(PopCount(commitIsFma)))
1198 XSPerfAccumulate(s"${fuName}_latency_enq_rs_execute_fma", ifCommit(latencySum(commitIsFma, rsFuLatency)))
1199 XSPerfAccumulate(s"${fuName}_latency_execute_fma", ifCommit(latencySum(commitIsFma, executeLatency)))
1200 }
1201 }
1202
1203 val sourceVaddr = Wire(Valid(UInt(VAddrBits.W)))
1204 sourceVaddr.valid := debug_lsTopdownInfo(deqPtr.value).s1.vaddr_valid

--- 6 unchanged lines hidden (view full) ---

1211 sourceLqIdx.bits := debug_microOp(deqPtr.value).lqIdx
1212 val sourceHeadLsIssue = WireDefault(debug_lsIssue(deqPtr.value))
1213 ExcitingUtils.addSource(sourceVaddr, s"rob_head_vaddr_${coreParams.HartId}", ExcitingUtils.Perf, true)
1214 ExcitingUtils.addSource(sourcePaddr, s"rob_head_paddr_${coreParams.HartId}", ExcitingUtils.Perf, true)
1215 ExcitingUtils.addSource(sourceLqIdx, s"rob_head_lqIdx_${coreParams.HartId}", ExcitingUtils.Perf, true)
1216 ExcitingUtils.addSource(sourceHeadLsIssue, s"rob_head_ls_issue_${coreParams.HartId}", ExcitingUtils.Perf, true)
1217 // dummy sink
1218 ExcitingUtils.addSink(WireDefault(sourceLqIdx), s"rob_head_lqIdx_${coreParams.HartId}", ExcitingUtils.Perf)
1143 XSPerfAccumulate(s"${fuName}_instr_cnt_fma", ifCommit(PopCount(commitIsFma)))
1144 XSPerfAccumulate(s"${fuName}_latency_enq_rs_execute_fma", ifCommit(latencySum(commitIsFma, rsFuLatency)))
1145 XSPerfAccumulate(s"${fuName}_latency_execute_fma", ifCommit(latencySum(commitIsFma, executeLatency)))
1146 }
1147 }
1148
1149 val sourceVaddr = Wire(Valid(UInt(VAddrBits.W)))
1150 sourceVaddr.valid := debug_lsTopdownInfo(deqPtr.value).s1.vaddr_valid

--- 6 unchanged lines hidden (view full) ---

1157 sourceLqIdx.bits := debug_microOp(deqPtr.value).lqIdx
1158 val sourceHeadLsIssue = WireDefault(debug_lsIssue(deqPtr.value))
1159 ExcitingUtils.addSource(sourceVaddr, s"rob_head_vaddr_${coreParams.HartId}", ExcitingUtils.Perf, true)
1160 ExcitingUtils.addSource(sourcePaddr, s"rob_head_paddr_${coreParams.HartId}", ExcitingUtils.Perf, true)
1161 ExcitingUtils.addSource(sourceLqIdx, s"rob_head_lqIdx_${coreParams.HartId}", ExcitingUtils.Perf, true)
1162 ExcitingUtils.addSource(sourceHeadLsIssue, s"rob_head_ls_issue_${coreParams.HartId}", ExcitingUtils.Perf, true)
1163 // dummy sink
1164 ExcitingUtils.addSink(WireDefault(sourceLqIdx), s"rob_head_lqIdx_${coreParams.HartId}", ExcitingUtils.Perf)
1219 ExcitingUtils.addSink(WireDefault(sourcePaddr), name=s"rob_head_paddr_${coreParams.HartId}", ExcitingUtils.Perf)
1220 ExcitingUtils.addSink(WireDefault(sourceVaddr), name=s"rob_head_vaddr_${coreParams.HartId}", ExcitingUtils.Perf)
1221 ExcitingUtils.addSink(WireDefault(sourceHeadLsIssue), name=s"rob_head_ls_issue_${coreParams.HartId}", ExcitingUtils.Perf)
1222
1223 /**
1224 * DataBase info:
1225 * log trigger is at writeback valid
1226 * */
1165
1166 /**
1167 * DataBase info:
1168 * log trigger is at writeback valid
1169 * */
1170 if(!env.FPGAPlatform){
1171 val isWriteInstInfoTable = WireInit(Constantin.createRecord("isWriteInstInfoTable" + p(XSCoreParamsKey).HartId.toString))
1172 val instTableName = "InstTable" + p(XSCoreParamsKey).HartId.toString
1173 val instSiteName = "Rob" + p(XSCoreParamsKey).HartId.toString
1174 val debug_instTable = ChiselDB.createTable(instTableName, new InstInfoEntry)
1175 // FIXME lyq: only get inst (alu, bj, ls) in exuWriteback
1176 for (wb <- exuWriteback) {
1177 when(wb.valid) {
1178 val debug_instData = Wire(new InstInfoEntry)
1179 val idx = wb.bits.uop.robIdx.value
1180 debug_instData.globalID := wb.bits.uop.ctrl.debug_globalID
1181 debug_instData.robIdx := idx
1182 debug_instData.instType := wb.bits.uop.ctrl.fuType
1183 debug_instData.ivaddr := wb.bits.uop.cf.pc
1184 debug_instData.dvaddr := wb.bits.debug.vaddr
1185 debug_instData.dpaddr := wb.bits.debug.paddr
1186 debug_instData.tlbLatency := wb.bits.uop.debugInfo.tlbRespTime - wb.bits.uop.debugInfo.tlbFirstReqTime
1187 debug_instData.accessLatency := wb.bits.uop.debugInfo.writebackTime - wb.bits.uop.debugInfo.issueTime
1188 debug_instData.executeLatency := wb.bits.uop.debugInfo.writebackTime - wb.bits.uop.debugInfo.issueTime
1189 debug_instData.issueLatency := wb.bits.uop.debugInfo.issueTime - wb.bits.uop.debugInfo.selectTime
1190 debug_instData.exceptType := Cat(wb.bits.uop.cf.exceptionVec)
1191 debug_instData.lsInfo := debug_lsInfo(idx)
1192 debug_instData.mdpInfo.ssid := wb.bits.uop.cf.ssid
1193 debug_instData.mdpInfo.waitAllStore := wb.bits.uop.cf.loadWaitStrict && wb.bits.uop.cf.loadWaitBit
1194 debug_instData.issueTime := wb.bits.uop.debugInfo.issueTime
1195 debug_instData.writebackTime := wb.bits.uop.debugInfo.writebackTime
1196 debug_instTable.log(
1197 data = debug_instData,
1198 en = wb.valid,
1199 site = instSiteName,
1200 clock = clock,
1201 reset = reset
1202 )
1203 }
1204 }
1205 }
1227
1206
1228 /**
1229 * @todo add InstInfoEntry back
1230 * @author Maxpicca-Li
1231 */
1232
1233 //difftest signals
1234 val firstValidCommit = (deqPtr + PriorityMux(io.commits.commitValid, VecInit(List.tabulate(CommitWidth)(_.U(log2Up(CommitWidth).W))))).value
1235
1236 val wdata = Wire(Vec(CommitWidth, UInt(XLEN.W)))
1237 val wpc = Wire(Vec(CommitWidth, UInt(XLEN.W)))
1238
1239 for(i <- 0 until CommitWidth) {
1240 val idx = deqPtrVec(i).value
1241 wdata(i) := debug_exuData(idx)
1207
1208 //difftest signals
1209 val firstValidCommit = (deqPtr + PriorityMux(io.commits.commitValid, VecInit(List.tabulate(CommitWidth)(_.U(log2Up(CommitWidth).W))))).value
1210
1211 val wdata = Wire(Vec(CommitWidth, UInt(XLEN.W)))
1212 val wpc = Wire(Vec(CommitWidth, UInt(XLEN.W)))
1213
1214 for(i <- 0 until CommitWidth) {
1215 val idx = deqPtrVec(i).value
1216 wdata(i) := debug_exuData(idx)
1242 wpc(i) := SignExt(commitDebugUop(i).pc, XLEN)
1217 wpc(i) := SignExt(commitDebugUop(i).cf.pc, XLEN)
1243 }
1244
1245 if (env.EnableDifftest) {
1246 for (i <- 0 until CommitWidth) {
1247 val difftest = Module(new DifftestInstrCommit)
1248 // assgin default value
1249 difftest.io := DontCare
1250
1251 difftest.io.clock := clock
1252 difftest.io.coreid := io.hartId
1253 difftest.io.index := i.U
1254
1255 val ptr = deqPtrVec(i).value
1256 val uop = commitDebugUop(i)
1257 val exuOut = debug_exuDebug(ptr)
1258 val exuData = debug_exuData(ptr)
1259 difftest.io.valid := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.isCommit)))
1218 }
1219
1220 if (env.EnableDifftest) {
1221 for (i <- 0 until CommitWidth) {
1222 val difftest = Module(new DifftestInstrCommit)
1223 // assgin default value
1224 difftest.io := DontCare
1225
1226 difftest.io.clock := clock
1227 difftest.io.coreid := io.hartId
1228 difftest.io.index := i.U
1229
1230 val ptr = deqPtrVec(i).value
1231 val uop = commitDebugUop(i)
1232 val exuOut = debug_exuDebug(ptr)
1233 val exuData = debug_exuData(ptr)
1234 difftest.io.valid := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.isCommit)))
1260 difftest.io.pc := RegNext(RegNext(RegNext(SignExt(uop.pc, XLEN))))
1261 difftest.io.instr := RegNext(RegNext(RegNext(uop.instr)))
1235 difftest.io.pc := RegNext(RegNext(RegNext(SignExt(uop.cf.pc, XLEN))))
1236 difftest.io.instr := RegNext(RegNext(RegNext(uop.cf.instr)))
1262 difftest.io.robIdx := RegNext(RegNext(RegNext(ZeroExt(ptr, 10))))
1263 difftest.io.lqIdx := RegNext(RegNext(RegNext(ZeroExt(uop.lqIdx.value, 7))))
1264 difftest.io.sqIdx := RegNext(RegNext(RegNext(ZeroExt(uop.sqIdx.value, 7))))
1265 difftest.io.isLoad := RegNext(RegNext(RegNext(io.commits.info(i).commitType === CommitType.LOAD)))
1266 difftest.io.isStore := RegNext(RegNext(RegNext(io.commits.info(i).commitType === CommitType.STORE)))
1267 difftest.io.special := RegNext(RegNext(RegNext(CommitType.isFused(io.commits.info(i).commitType))))
1268 // when committing an eliminated move instruction,
1269 // we must make sure that skip is properly set to false (output from EXU is random value)
1270 difftest.io.skip := RegNext(RegNext(RegNext(Mux(uop.eliminatedMove, false.B, exuOut.isMMIO || exuOut.isPerfCnt))))
1237 difftest.io.robIdx := RegNext(RegNext(RegNext(ZeroExt(ptr, 10))))
1238 difftest.io.lqIdx := RegNext(RegNext(RegNext(ZeroExt(uop.lqIdx.value, 7))))
1239 difftest.io.sqIdx := RegNext(RegNext(RegNext(ZeroExt(uop.sqIdx.value, 7))))
1240 difftest.io.isLoad := RegNext(RegNext(RegNext(io.commits.info(i).commitType === CommitType.LOAD)))
1241 difftest.io.isStore := RegNext(RegNext(RegNext(io.commits.info(i).commitType === CommitType.STORE)))
1242 difftest.io.special := RegNext(RegNext(RegNext(CommitType.isFused(io.commits.info(i).commitType))))
1243 // when committing an eliminated move instruction,
1244 // we must make sure that skip is properly set to false (output from EXU is random value)
1245 difftest.io.skip := RegNext(RegNext(RegNext(Mux(uop.eliminatedMove, false.B, exuOut.isMMIO || exuOut.isPerfCnt))))
1271 difftest.io.isRVC := RegNext(RegNext(RegNext(uop.preDecodeInfo.isRVC)))
1246 difftest.io.isRVC := RegNext(RegNext(RegNext(uop.cf.pd.isRVC)))
1272 difftest.io.rfwen := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.info(i).rfWen && io.commits.info(i).ldest =/= 0.U)))
1273 difftest.io.fpwen := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.info(i).fpWen)))
1274 difftest.io.wpdest := RegNext(RegNext(RegNext(io.commits.info(i).pdest)))
1275 difftest.io.wdest := RegNext(RegNext(RegNext(io.commits.info(i).ldest)))
1247 difftest.io.rfwen := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.info(i).rfWen && io.commits.info(i).ldest =/= 0.U)))
1248 difftest.io.fpwen := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.info(i).fpWen)))
1249 difftest.io.wpdest := RegNext(RegNext(RegNext(io.commits.info(i).pdest)))
1250 difftest.io.wdest := RegNext(RegNext(RegNext(io.commits.info(i).ldest)))
1251
1276 // // runahead commit hint
1277 // val runahead_commit = Module(new DifftestRunaheadCommitEvent)
1278 // runahead_commit.io.clock := clock
1279 // runahead_commit.io.coreid := io.hartId
1280 // runahead_commit.io.index := i.U
1281 // runahead_commit.io.valid := difftest.io.valid &&
1282 // (commitBranchValid(i) || commitIsStore(i))
1283 // // TODO: is branch or store
1284 // runahead_commit.io.pc := difftest.io.pc
1285 }
1286 }
1287 else if (env.AlwaysBasicDiff) {
1288 // These are the structures used by difftest only and should be optimized after synthesis.
1289 val dt_eliminatedMove = Mem(RobSize, Bool())
1290 val dt_isRVC = Mem(RobSize, Bool())
1291 val dt_exuDebug = Reg(Vec(RobSize, new DebugBundle))
1292 for (i <- 0 until RenameWidth) {
1293 when (canEnqueue(i)) {
1294 dt_eliminatedMove(allocatePtrVec(i).value) := io.enq.req(i).bits.eliminatedMove
1252 // // runahead commit hint
1253 // val runahead_commit = Module(new DifftestRunaheadCommitEvent)
1254 // runahead_commit.io.clock := clock
1255 // runahead_commit.io.coreid := io.hartId
1256 // runahead_commit.io.index := i.U
1257 // runahead_commit.io.valid := difftest.io.valid &&
1258 // (commitBranchValid(i) || commitIsStore(i))
1259 // // TODO: is branch or store
1260 // runahead_commit.io.pc := difftest.io.pc
1261 }
1262 }
1263 else if (env.AlwaysBasicDiff) {
1264 // These are the structures used by difftest only and should be optimized after synthesis.
1265 val dt_eliminatedMove = Mem(RobSize, Bool())
1266 val dt_isRVC = Mem(RobSize, Bool())
1267 val dt_exuDebug = Reg(Vec(RobSize, new DebugBundle))
1268 for (i <- 0 until RenameWidth) {
1269 when (canEnqueue(i)) {
1270 dt_eliminatedMove(allocatePtrVec(i).value) := io.enq.req(i).bits.eliminatedMove
1295 dt_isRVC(allocatePtrVec(i).value) := io.enq.req(i).bits.preDecodeInfo.isRVC
1271 dt_isRVC(allocatePtrVec(i).value) := io.enq.req(i).bits.cf.pd.isRVC
1296 }
1297 }
1272 }
1273 }
1298 for (wb <- exuWBs) {
1274 for (wb <- exuWriteback) {
1299 when (wb.valid) {
1275 when (wb.valid) {
1300 val wbIdx = wb.bits.robIdx.value
1276 val wbIdx = wb.bits.uop.robIdx.value
1301 dt_exuDebug(wbIdx) := wb.bits.debug
1302 }
1303 }
1304 // Always instantiate basic difftest modules.
1305 for (i <- 0 until CommitWidth) {
1306 val commitInfo = io.commits.info(i)
1307 val ptr = deqPtrVec(i).value
1308 val exuOut = dt_exuDebug(ptr)

--- 22 unchanged lines hidden (view full) ---

1331 difftest.io.coreid := io.hartId
1332 difftest.io.index := i.U
1333
1334 val ptr = deqPtrVec(i).value
1335 val uop = commitDebugUop(i)
1336 val exuOut = debug_exuDebug(ptr)
1337 difftest.io.valid := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.isCommit)))
1338 difftest.io.paddr := RegNext(RegNext(RegNext(exuOut.paddr)))
1277 dt_exuDebug(wbIdx) := wb.bits.debug
1278 }
1279 }
1280 // Always instantiate basic difftest modules.
1281 for (i <- 0 until CommitWidth) {
1282 val commitInfo = io.commits.info(i)
1283 val ptr = deqPtrVec(i).value
1284 val exuOut = dt_exuDebug(ptr)

--- 22 unchanged lines hidden (view full) ---

1307 difftest.io.coreid := io.hartId
1308 difftest.io.index := i.U
1309
1310 val ptr = deqPtrVec(i).value
1311 val uop = commitDebugUop(i)
1312 val exuOut = debug_exuDebug(ptr)
1313 difftest.io.valid := RegNext(RegNext(RegNext(io.commits.commitValid(i) && io.commits.isCommit)))
1314 difftest.io.paddr := RegNext(RegNext(RegNext(exuOut.paddr)))
1339 difftest.io.opType := RegNext(RegNext(RegNext(uop.fuOpType)))
1340 difftest.io.fuType := RegNext(RegNext(RegNext(uop.fuType)))
1315 difftest.io.opType := RegNext(RegNext(RegNext(uop.ctrl.fuOpType)))
1316 difftest.io.fuType := RegNext(RegNext(RegNext(uop.ctrl.fuType)))
1341 }
1342 }
1343
1344 // Always instantiate basic difftest modules.
1345 if (env.EnableDifftest) {
1346 val dt_isXSTrap = Mem(RobSize, Bool())
1347 for (i <- 0 until RenameWidth) {
1348 when (canEnqueue(i)) {
1317 }
1318 }
1319
1320 // Always instantiate basic difftest modules.
1321 if (env.EnableDifftest) {
1322 val dt_isXSTrap = Mem(RobSize, Bool())
1323 for (i <- 0 until RenameWidth) {
1324 when (canEnqueue(i)) {
1349 dt_isXSTrap(allocatePtrVec(i).value) := io.enq.req(i).bits.isXSTrap
1325 dt_isXSTrap(allocatePtrVec(i).value) := io.enq.req(i).bits.ctrl.isXSTrap
1350 }
1351 }
1352 val trapVec = io.commits.commitValid.zip(deqPtrVec).map{ case (v, d) => io.commits.isCommit && v && dt_isXSTrap(d.value) }
1353 val hitTrap = trapVec.reduce(_||_)
1354 val trapCode = PriorityMux(wdata.zip(trapVec).map(x => x._2 -> x._1))
1355 val trapPC = SignExt(PriorityMux(wpc.zip(trapVec).map(x => x._2 ->x._1)), XLEN)
1356 val difftest = Module(new DifftestTrapEvent)
1357 difftest.io.clock := clock

--- 4 unchanged lines hidden (view full) ---

1362 difftest.io.cycleCnt := timer
1363 difftest.io.instrCnt := instrCnt
1364 difftest.io.hasWFI := hasWFI
1365 }
1366 else if (env.AlwaysBasicDiff) {
1367 val dt_isXSTrap = Mem(RobSize, Bool())
1368 for (i <- 0 until RenameWidth) {
1369 when (canEnqueue(i)) {
1326 }
1327 }
1328 val trapVec = io.commits.commitValid.zip(deqPtrVec).map{ case (v, d) => io.commits.isCommit && v && dt_isXSTrap(d.value) }
1329 val hitTrap = trapVec.reduce(_||_)
1330 val trapCode = PriorityMux(wdata.zip(trapVec).map(x => x._2 -> x._1))
1331 val trapPC = SignExt(PriorityMux(wpc.zip(trapVec).map(x => x._2 ->x._1)), XLEN)
1332 val difftest = Module(new DifftestTrapEvent)
1333 difftest.io.clock := clock

--- 4 unchanged lines hidden (view full) ---

1338 difftest.io.cycleCnt := timer
1339 difftest.io.instrCnt := instrCnt
1340 difftest.io.hasWFI := hasWFI
1341 }
1342 else if (env.AlwaysBasicDiff) {
1343 val dt_isXSTrap = Mem(RobSize, Bool())
1344 for (i <- 0 until RenameWidth) {
1345 when (canEnqueue(i)) {
1370 dt_isXSTrap(allocatePtrVec(i).value) := io.enq.req(i).bits.isXSTrap
1346 dt_isXSTrap(allocatePtrVec(i).value) := io.enq.req(i).bits.ctrl.isXSTrap
1371 }
1372 }
1373 val trapVec = io.commits.commitValid.zip(deqPtrVec).map{ case (v, d) => io.commits.isCommit && v && dt_isXSTrap(d.value) }
1374 val hitTrap = trapVec.reduce(_||_)
1375 val difftest = Module(new DifftestBasicTrapEvent)
1376 difftest.io.clock := clock
1377 difftest.io.coreid := io.hartId
1378 difftest.io.valid := hitTrap

--- 33 unchanged lines hidden ---
1347 }
1348 }
1349 val trapVec = io.commits.commitValid.zip(deqPtrVec).map{ case (v, d) => io.commits.isCommit && v && dt_isXSTrap(d.value) }
1350 val hitTrap = trapVec.reduce(_||_)
1351 val difftest = Module(new DifftestBasicTrapEvent)
1352 difftest.io.clock := clock
1353 difftest.io.coreid := io.hartId
1354 difftest.io.valid := hitTrap

--- 33 unchanged lines hidden ---