xref: /XiangShan/src/main/scala/xiangshan/backend/trace/Trace.scala (revision 38d0d7c5a34a23dfdb58a3cb2737c3cfddb3ec9d)
1package xiangshan.backend.trace
2
3import chisel3._
4import chisel3.util.{RegEnable, ValidIO, log2Up}
5import org.chipsalliance.cde.config.Parameters
6import xiangshan.HasXSParameter
7
8class TraceParams(
9  val TraceGroupNum  : Int,
10  val IaddrWidth     : Int,
11  val PrivWidth      : Int,
12  val ItypeWidth     : Int,
13  val IlastsizeWidth : Int,
14)
15
16class TraceIO(implicit val p: Parameters) extends Bundle with HasXSParameter {
17  val in = new Bundle {
18    val fromEncoder    = Input(new FromEncoder)
19    val fromRob        = Flipped(new TraceBundle(hasIaddr = false, CommitWidth, IretireWidthInPipe))
20    val fromPcMem      = Input(Vec(TraceGroupNum, UInt(IaddrWidth.W)))
21  }
22  val out = new Bundle {
23    val toPcMem        = new TraceBundle(hasIaddr = false, TraceGroupNum, IretireWidthCompressed)
24    val toEncoder      = new TraceBundle(hasIaddr = true,  TraceGroupNum, IretireWidthCompressed)
25    val blockRobCommit = Output(Bool())
26  }
27}
28
29class Trace(implicit val p: Parameters) extends Module with HasXSParameter {
30  val io = IO(new TraceIO)
31  val (fromEncoder, fromRob, fromPcMem, toPcMem, toEncoder) = (io.in.fromEncoder, io.in.fromRob, io.in.fromPcMem, io.out.toPcMem, io.out.toEncoder)
32
33  /**
34   * stage 0: CommitInfo from rob
35   */
36  val blockCommit = Wire(Bool())
37  io.out.blockRobCommit := blockCommit
38
39  /**
40   * stage 1: regNext(robCommitInfo)
41   */
42  val s1_in = fromRob
43  val s1_out = WireInit(0.U.asTypeOf(s1_in))
44  for(i <- 0 until CommitWidth) {
45    s1_out.blocks(i).valid := RegEnable(s1_in.blocks(i).valid, false.B, !blockCommit)
46    s1_out.blocks(i).bits := RegEnable(s1_in.blocks(i).bits, 0.U.asTypeOf(s1_in.blocks(i).bits), s1_in.blocks(i).valid)
47  }
48
49  /**
50   * stage 2: compress, s2_out(deq from traceBuffer) -> pcMem
51   */
52  val s2_in = s1_out
53  val traceBuffer = Module(new TraceBuffer)
54  traceBuffer.io.in.fromEncoder := fromEncoder
55  traceBuffer.io.in.fromRob := s2_in
56  val s2_out_groups = traceBuffer.io.out.groups
57  blockCommit := traceBuffer.io.out.blockCommit
58
59  /**
60   * stage 3: groups with iaddr from pcMem(ftqidx & ftqOffset -> iaddr) -> encoder
61   */
62  val s3_in_groups = s2_out_groups
63  val s3_out_groups = RegNext(s3_in_groups)
64  toPcMem := s3_in_groups
65
66  for(i <- 0 until TraceGroupNum) {
67    toEncoder.blocks(i).valid := s3_out_groups.blocks(i).valid
68    toEncoder.blocks(i).bits.iaddr.foreach(_ := Mux(s3_out_groups.blocks(i).valid, fromPcMem(i), 0.U))
69    toEncoder.blocks(i).bits.tracePipe := s3_out_groups.blocks(i).bits.tracePipe
70  }
71  if(backendParams.debugEn) {
72    dontTouch(io.out.toEncoder)
73  }
74}
75