1package xiangshan 2 3import chisel3._ 4import chipsalliance.rocketchip.config.{Config, Parameters} 5import chisel3.util.{Valid, ValidIO} 6import freechips.rocketchip.diplomacy.{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 16 17class L1CacheErrorInfo(implicit val p: Parameters) extends Bundle with HasSoCParameter { 18 val paddr = Valid(UInt(soc.PAddrBits.W)) 19 // for now, we only detect ecc 20 val ecc_error = Valid(Bool()) 21} 22 23class XSL1BusErrors()(implicit val p: Parameters) extends BusErrors { 24 val icache = new L1CacheErrorInfo 25 val dcache = new L1CacheErrorInfo 26 27 override def toErrorList: List[Option[(ValidIO[UInt], String, String)]] = 28 List( 29 Some(icache.paddr, s"IBUS", s"Icache bus error"), 30 Some(icache.ecc_error, s"I_ECC", s"Icache ecc error"), 31 Some(dcache.paddr, s"DBUS", s"Dcache bus error"), 32 Some(dcache.ecc_error, s"D_ECC", s"Dcache ecc error") 33 ) 34} 35 36/** 37 * XSTileMisc contains every module except Core and L2 Cache 38 */ 39class XSTileMisc()(implicit p: Parameters) extends LazyModule 40 with HasXSParameter 41 with HasSoCParameter 42{ 43 val l1_xbar = TLXbar() 44 val mmio_xbar = TLXbar() 45 val memory_port = TLIdentityNode() 46 val beu = LazyModule(new BusErrorUnit( 47 new XSL1BusErrors(), BusErrorUnitParams(0x38010000), new GenericLogicalTreeNode 48 )) 49 val busPMU = BusPerfMonitor(enable = !debugOpts.FPGAPlatform) 50 val l1d_logger = TLLogger(s"L2_L1D_$hardId", !debugOpts.FPGAPlatform) 51 val l2_binder = coreParams.L2CacheParamsOpt.map(_ => BankBinder(coreParams.L2NBanks, 64)) 52 53 val i_mmio_port = TLTempNode() 54 val d_mmio_port = TLTempNode() 55 56 busPMU := l1d_logger 57 l1_xbar :=* busPMU 58 59 def bufferN[T <: TLNode](n: Int, sink: T, source: T) = { 60 val buffers = (0 until n).map(_ => TLBuffer()) 61 val nodes = sink +: buffers :+ source 62 nodes.reduce((x, y) => x :=* y) 63 } 64 65 l2_binder match { 66 case Some(binder) => 67 bufferN(5, memory_port, binder) 68 case None => 69 memory_port := l1_xbar 70 } 71 72 mmio_xbar := TLBuffer() := i_mmio_port 73 mmio_xbar := TLBuffer() := d_mmio_port 74 beu.node := TLBuffer() := mmio_xbar 75 76 lazy val module = new LazyModuleImp(this){ 77 val beu_errors = IO(Input(chiselTypeOf(beu.module.io.errors))) 78 beu.module.io.errors <> beu_errors 79 } 80} 81 82class XSTile()(implicit p: Parameters) extends LazyModule 83 with HasXSParameter 84 with HasSoCParameter 85{ 86 private val core = LazyModule(new XSCore()) 87 private val misc = LazyModule(new XSTileMisc()) 88 private val l2cache = coreParams.L2CacheParamsOpt.map(l2param => 89 LazyModule(new HuanCun()(new Config((_, _, _) => { 90 case HCCacheParamsKey => l2param 91 }))) 92 ) 93 94 // public ports 95 val memory_port = misc.memory_port 96 val uncache = misc.mmio_xbar 97 val clint_int_sink = core.clint_int_sink 98 val plic_int_sink = core.plic_int_sink 99 val debug_int_sink = core.debug_int_sink 100 val beu_int_source = misc.beu.intNode 101 102 if (coreParams.dcacheParametersOpt.nonEmpty) { 103 misc.l1d_logger := core.memBlock.dcache.clientNode 104 } 105 misc.busPMU := 106 TLLogger(s"L2_L1I_$hardId", !debugOpts.FPGAPlatform) := 107 TLBuffer() := 108 core.frontend.icache.clientNode 109 110 if (!coreParams.softPTW) { 111 misc.busPMU := 112 TLLogger(s"L2_PTW_$hardId", !debugOpts.FPGAPlatform) := 113 TLBuffer() := 114 core.ptw.node 115 } 116 l2cache match { 117 case Some(l2) => 118 misc.l2_binder.get :*= l2.node :*= TLBuffer() :*= misc.l1_xbar 119 case None => 120 } 121 122 misc.i_mmio_port := core.frontend.instrUncache.clientNode 123 misc.d_mmio_port := core.memBlock.uncache.clientNode 124 125 lazy val module = new LazyModuleImp(this){ 126 val io = IO(new Bundle { 127 val hartId = Input(UInt(64.W)) 128 val reset = Input(Bool()) 129 }) 130 131 core.module.io.hartId := io.hartId 132 if(l2cache.isDefined){ 133 core.module.io.perfEvents <> l2cache.get.module.io.perfEvents.flatten 134 } 135 else { 136 core.module.io.perfEvents <> DontCare 137 } 138 139 misc.module.beu_errors <> core.module.io.beu_errors 140 141 // Modules are reset one by one 142 // io_reset ---- 143 // | 144 // v 145 // reset ----> OR_SYNC --> {Misc, L2 Cache, Cores} 146 val l2cacheMod = if (l2cache.isDefined) Seq(l2cache.get.module) else Seq() 147 val resetChain = Seq( 148 Seq(misc.module, core.module) ++ l2cacheMod 149 ) 150 ResetGen(resetChain, reset.asBool || io.reset, !debugOpts.FPGAPlatform) 151 } 152} 153