xref: /XiangShan/src/main/scala/xiangshan/XSTile.scala (revision 3a6db8a39a25f02047d1fb2b257c89be0b2c36dc)
1package xiangshan
2
3import chisel3._
4import chipsalliance.rocketchip.config.{Config, Parameters}
5import chisel3.util.{Valid, ValidIO}
6import freechips.rocketchip.diplomacy.{BundleBridgeSink, LazyModule, LazyModuleImp, LazyModuleImpLike}
7import freechips.rocketchip.diplomaticobjectmodel.logicaltree.GenericLogicalTreeNode
8import freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortParameters, IntSinkPortSimple}
9import freechips.rocketchip.tile.{BusErrorUnit, BusErrorUnitParams, BusErrors}
10import freechips.rocketchip.tilelink.{BankBinder, TLBuffer, TLIdentityNode, TLNode, TLTempNode, TLXbar}
11import huancun.debug.TLLogger
12import huancun.{HCCacheParamsKey, HuanCun}
13import system.HasSoCParameter
14import top.BusPerfMonitor
15import utils.{ResetGen, TLClientsMerger, TLEdgeBuffer}
16
17class L1CacheErrorInfo(implicit val p: Parameters) extends Bundle with HasSoCParameter {
18  // L1CacheErrorInfo is also used to encode customized CACHE_ERROR CSR
19  val source = Output(new Bundle() {
20    val tag = Bool() // l1 tag array
21    val data = Bool() // l1 data array
22    val l2 = Bool()
23  })
24  val opType = Output(new Bundle() {
25    val fetch = Bool()
26    val load = Bool()
27    val store = Bool()
28    val probe = Bool()
29    val release = Bool()
30    val atom = Bool()
31  })
32
33  // report error and paddr to beu
34  // bus error unit will receive error info iff ecc_error.valid
35  val ecc_error = Valid(UInt(soc.PAddrBits.W))
36
37  // there is an valid error
38  // l1 cache error will always be report to CACHE_ERROR csr
39  val valid = Output(Bool())
40}
41
42class XSL1BusErrors()(implicit val p: Parameters) extends BusErrors {
43  val icache = new L1CacheErrorInfo
44  val dcache = new L1CacheErrorInfo
45
46  override def toErrorList: List[Option[(ValidIO[UInt], String, String)]] =
47    List(
48//      Some(icache.paddr, s"IBUS", s"Icache bus error"),
49      Some(icache.ecc_error, s"I_ECC", s"Icache ecc error"),
50//      Some(dcache.paddr, s"DBUS", s"Dcache bus error"),
51      Some(dcache.ecc_error, s"D_ECC", s"Dcache ecc error")
52    )
53}
54
55/**
56  *   XSTileMisc contains every module except Core and L2 Cache
57  */
58class XSTileMisc()(implicit p: Parameters) extends LazyModule
59  with HasXSParameter
60  with HasSoCParameter
61{
62  val l1_xbar = TLXbar()
63  val mmio_xbar = TLXbar()
64  val mmio_port = TLIdentityNode() // to L3
65  val memory_port = TLIdentityNode()
66  val beu = LazyModule(new BusErrorUnit(
67    new XSL1BusErrors(), BusErrorUnitParams(0x38010000), new GenericLogicalTreeNode
68  ))
69  val busPMU = BusPerfMonitor(enable = !debugOpts.FPGAPlatform)
70  val l1d_logger = TLLogger(s"L2_L1D_${coreParams.HartId}", !debugOpts.FPGAPlatform)
71  val l2_binder = coreParams.L2CacheParamsOpt.map(_ => BankBinder(coreParams.L2NBanks, 64))
72
73  val i_mmio_port = TLTempNode()
74  val d_mmio_port = TLTempNode()
75
76  busPMU := l1d_logger
77  l1_xbar :=* busPMU
78
79  l2_binder match {
80    case Some(binder) =>
81      memory_port := TLBuffer() := TLClientsMerger() := TLXbar() :=* binder
82    case None =>
83      memory_port := l1_xbar
84  }
85
86  mmio_xbar := TLBuffer.chainNode(2) := i_mmio_port
87  mmio_xbar := TLBuffer.chainNode(2) := d_mmio_port
88  beu.node := TLBuffer.chainNode(1) := mmio_xbar
89  mmio_port := TLBuffer() := mmio_xbar
90
91  lazy val module = new LazyModuleImp(this){
92    val beu_errors = IO(Input(chiselTypeOf(beu.module.io.errors)))
93    beu.module.io.errors <> beu_errors
94  }
95}
96
97class XSTile()(implicit p: Parameters) extends LazyModule
98  with HasXSParameter
99  with HasSoCParameter
100{
101  private val core = LazyModule(new XSCore())
102  private val misc = LazyModule(new XSTileMisc())
103  private val l2cache = coreParams.L2CacheParamsOpt.map(l2param =>
104    LazyModule(new HuanCun()(new Config((_, _, _) => {
105      case HCCacheParamsKey => l2param
106    })))
107  )
108
109  // public ports
110  val memory_port = misc.memory_port
111  val uncache = misc.mmio_port
112  val clint_int_sink = core.clint_int_sink
113  val plic_int_sink = core.plic_int_sink
114  val debug_int_sink = core.debug_int_sink
115  val beu_int_source = misc.beu.intNode
116  val core_reset_sink = BundleBridgeSink(Some(() => Bool()))
117
118  if (coreParams.dcacheParametersOpt.nonEmpty) {
119    misc.l1d_logger :=
120      TLBuffer.chainNode(1, Some("L1D_to_L2_buffer")) :=
121      core.memBlock.dcache.clientNode
122  }
123  misc.busPMU :=
124    TLLogger(s"L2_L1I_${coreParams.HartId}", !debugOpts.FPGAPlatform) :=
125    TLBuffer.chainNode(1, Some("L1I_to_L2_buffer")) :=
126    core.frontend.icache.clientNode
127
128  if (!coreParams.softPTW) {
129    misc.busPMU :=
130      TLLogger(s"L2_PTW_${coreParams.HartId}", !debugOpts.FPGAPlatform) :=
131      TLBuffer.chainNode(3, Some("PTW_to_L2_buffer")) :=
132      core.ptw.node
133  }
134  l2cache match {
135    case Some(l2) =>
136      misc.l2_binder.get :*= l2.node :*= TLBuffer() :*= misc.l1_xbar
137    case None =>
138  }
139
140  misc.i_mmio_port := core.frontend.instrUncache.clientNode
141  misc.d_mmio_port := core.memBlock.uncache.clientNode
142
143  lazy val module = new LazyModuleImp(this){
144    val io = IO(new Bundle {
145      val hartId = Input(UInt(64.W))
146    })
147
148    dontTouch(io.hartId)
149
150    val core_soft_rst = core_reset_sink.in.head._1
151
152    core.module.io.hartId := io.hartId
153    if(l2cache.isDefined){
154      core.module.io.perfEvents.zip(l2cache.get.module.io.perfEvents.flatten).foreach(x => x._1.value := x._2)
155    }
156    else {
157      core.module.io.perfEvents <> DontCare
158    }
159
160    misc.module.beu_errors <> core.module.io.beu_errors
161
162    // Modules are reset one by one
163    // io_reset ----
164    //             |
165    //             v
166    // reset ----> OR_SYNC --> {Misc, L2 Cache, Cores}
167    val l2cacheMod = if (l2cache.isDefined) Seq(l2cache.get.module) else Seq()
168    val resetChain = Seq(
169      Seq(misc.module, core.module) ++ l2cacheMod
170    )
171    ResetGen(resetChain, reset.asBool || core_soft_rst, !debugOpts.FPGAPlatform)
172  }
173}
174