1*72dab974Scz4e/*************************************************************************************** 2*72dab974Scz4e* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3*72dab974Scz4e* Copyright (c) 2020-2021 Peng Cheng Laboratory 4*72dab974Scz4e* 5*72dab974Scz4e* XiangShan is licensed under Mulan PSL v2. 6*72dab974Scz4e* You can use this software according to the terms and conditions of the Mulan PSL v2. 7*72dab974Scz4e* You may obtain a copy of Mulan PSL v2 at: 8*72dab974Scz4e* http://license.coscl.org.cn/MulanPSL2 9*72dab974Scz4e* 10*72dab974Scz4e* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11*72dab974Scz4e* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12*72dab974Scz4e* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13*72dab974Scz4e* 14*72dab974Scz4e* See the Mulan PSL v2 for more details. 15*72dab974Scz4e***************************************************************************************/ 16*72dab974Scz4e 17*72dab974Scz4epackage xiangshan.cache 18*72dab974Scz4e 19*72dab974Scz4eimport org.chipsalliance.cde.config.Parameters 20*72dab974Scz4eimport chisel3._ 21*72dab974Scz4eimport chisel3.util._ 22*72dab974Scz4eimport freechips.rocketchip.subsystem._ 23*72dab974Scz4eimport freechips.rocketchip.diplomacy._ 24*72dab974Scz4eimport freechips.rocketchip.regmapper._ 25*72dab974Scz4eimport freechips.rocketchip.tilelink._ 26*72dab974Scz4eimport freechips.rocketchip.interrupts._ 27*72dab974Scz4eimport freechips.rocketchip.util._ 28*72dab974Scz4eimport chisel3.experimental.SourceInfo 29*72dab974Scz4eimport xiangshan._ 30*72dab974Scz4e 31*72dab974Scz4ecase class L1CacheCtrlParams ( 32*72dab974Scz4e address: AddressSet, 33*72dab974Scz4e beatBytes: Int = 8, 34*72dab974Scz4e) { 35*72dab974Scz4e def maxBanks = 1 36*72dab974Scz4e def bankBytes = 128 37*72dab974Scz4e 38*72dab974Scz4e def regWidth = 64 39*72dab974Scz4e def regBytes = regWidth / 8 40*72dab974Scz4e 41*72dab974Scz4e def ctrlOffset = 0x0 42*72dab974Scz4e def delayOffset = ctrlOffset + regBytes 43*72dab974Scz4e def maskOffset = delayOffset + regBytes 44*72dab974Scz4e 45*72dab974Scz4e def nSignalComps = 2 46*72dab974Scz4e} 47*72dab974Scz4e 48*72dab974Scz4eclass CtrlUnitCtrlBundle(implicit p: Parameters) extends XSBundle with HasDCacheParameters { 49*72dab974Scz4e val zero0 = UInt((60-DCacheBanks).W) // padding bits 50*72dab974Scz4e val bank = UInt(DCacheBanks.W) // bank enable 51*72dab974Scz4e val comp = UInt(1.W) // components: 1'b0 tag, 1'b1 data 52*72dab974Scz4e val ede = Bool() // error delay enable 53*72dab974Scz4e val persist = Bool() // persist inject 54*72dab974Scz4e val ese = Bool() // error signaling enable 55*72dab974Scz4e} 56*72dab974Scz4e 57*72dab974Scz4eclass CtrlUnitSignalingBundle(implicit p: Parameters) extends XSBundle with HasDCacheParameters { 58*72dab974Scz4e val valid = Bool() 59*72dab974Scz4e val mask = UInt(DCacheSRAMRowBits.W) 60*72dab974Scz4e} 61*72dab974Scz4e 62*72dab974Scz4eclass CtrlUnit(params: L1CacheCtrlParams)(implicit p: Parameters) extends LazyModule 63*72dab974Scz4e with HasDCacheParameters 64*72dab974Scz4e{ 65*72dab974Scz4e val device: SimpleDevice = new SimpleDevice("L1DCacheCtrl", Seq("xiangshan,l1dcache_ctrl")) 66*72dab974Scz4e 67*72dab974Scz4e val node: TLRegisterNode = TLRegisterNode( 68*72dab974Scz4e address = Seq(params.address), 69*72dab974Scz4e device = device, 70*72dab974Scz4e beatBytes = params.beatBytes, 71*72dab974Scz4e concurrency = 1, 72*72dab974Scz4e ) 73*72dab974Scz4e 74*72dab974Scz4e lazy val module = new CtrlUnitImp 75*72dab974Scz4e 76*72dab974Scz4e class CtrlUnitImp extends LazyModuleImp(this) { 77*72dab974Scz4e val io_pseudoError = IO(Vec(params.nSignalComps, DecoupledIO(Vec(DCacheBanks, new CtrlUnitSignalingBundle)))) 78*72dab974Scz4e 79*72dab974Scz4e require(params.maxBanks > 0, "At least one bank!") 80*72dab974Scz4e require(params.maxBanks == 1, "Is it necessary to have more than 1 bank?") 81*72dab974Scz4e require(params.regWidth == DCacheSRAMRowBits, "regWidth must be equal to DCacheSRAMRowBits!") 82*72dab974Scz4e val ctrlRegs = RegInit(VecInit(Seq.fill(1)(0.U(params.regWidth.W)))) 83*72dab974Scz4e val delayRegs = RegInit(VecInit(Seq.fill(1)(0.U(params.regWidth.W)))) 84*72dab974Scz4e val maskRegs = RegInit(VecInit(Seq.fill(DCacheBanks)(0.U(DCacheSRAMRowBits.W)))) 85*72dab974Scz4e val counterRegs = RegInit(VecInit(Seq.fill(1)(0.U(params.regWidth.W)))) 86*72dab974Scz4e 87*72dab974Scz4e io_pseudoError.zipWithIndex.foreach { 88*72dab974Scz4e case (inj, i) => 89*72dab974Scz4e val ctrlReg = ctrlRegs.head 90*72dab974Scz4e val ctrlRegBundle = ctrlRegs.head.asTypeOf(new CtrlUnitCtrlBundle) 91*72dab974Scz4e val delayReg = delayRegs.head 92*72dab974Scz4e val counterReg = counterRegs.head 93*72dab974Scz4e 94*72dab974Scz4e require(log2Up(io_pseudoError.length) == ctrlRegBundle.comp.getWidth, "io_pseudoError must equal number of components!") 95*72dab974Scz4e inj.valid := ctrlRegBundle.ese && (ctrlRegBundle.comp === i.U) && (!ctrlRegBundle.ede || counterReg === 0.U) 96*72dab974Scz4e inj.bits.zip(ctrlRegBundle.bank.asBools).zip(maskRegs).map { 97*72dab974Scz4e case ((bankOut, bankEnable), mask) => 98*72dab974Scz4e bankOut.valid := bankEnable 99*72dab974Scz4e bankOut.mask := mask 100*72dab974Scz4e } 101*72dab974Scz4e 102*72dab974Scz4e when (inj.fire) { 103*72dab974Scz4e val newCtrlReg = WireInit(0.U.asTypeOf(ctrlRegBundle)) 104*72dab974Scz4e newCtrlReg := ctrlRegBundle 105*72dab974Scz4e newCtrlReg.ese := Mux(ctrlRegBundle.persist, ctrlRegBundle.ese, false.B) 106*72dab974Scz4e 107*72dab974Scz4e when (newCtrlReg.ese && newCtrlReg.ede) { 108*72dab974Scz4e counterReg := Mux(newCtrlReg.persist, delayReg, 0.U) 109*72dab974Scz4e } 110*72dab974Scz4e ctrlReg := newCtrlReg.asUInt 111*72dab974Scz4e } 112*72dab974Scz4e } 113*72dab974Scz4e 114*72dab974Scz4e ctrlRegs.map(_.asTypeOf(new CtrlUnitCtrlBundle)).zip(counterRegs).zipWithIndex.foreach { 115*72dab974Scz4e case ((ctl, cnt), i) => 116*72dab974Scz4e when (ctl.ese && ctl.ede && cnt =/= 0.U) { 117*72dab974Scz4e cnt := cnt - 1.U 118*72dab974Scz4e } 119*72dab974Scz4e } 120*72dab974Scz4e 121*72dab974Scz4e def ctrlRegDesc(i: Int) = 122*72dab974Scz4e RegFieldDesc( 123*72dab974Scz4e name = s"control_$i", 124*72dab974Scz4e desc = s"Acting control of controller $i", 125*72dab974Scz4e group = Some(s"controll_${i}"), 126*72dab974Scz4e groupDesc = Some(s"Acting control of controller ${i}"), 127*72dab974Scz4e reset = Some(0) 128*72dab974Scz4e ) 129*72dab974Scz4e 130*72dab974Scz4e def delayRegDesc(i: Int) = 131*72dab974Scz4e RegFieldDesc( 132*72dab974Scz4e name = s"delay_$i", 133*72dab974Scz4e desc = s"pseudo error delay $i", 134*72dab974Scz4e group = Some(s"delay_${i}"), 135*72dab974Scz4e groupDesc = Some(s"pseudo error delay ${i}"), 136*72dab974Scz4e reset = Some(0) 137*72dab974Scz4e ) 138*72dab974Scz4e 139*72dab974Scz4e def maskRegDesc(i: Int) = 140*72dab974Scz4e RegFieldDesc( 141*72dab974Scz4e name = s"mask_$i", 142*72dab974Scz4e desc = s"pseudo error toggle mask$i", 143*72dab974Scz4e group = Some(s"mask_${i}"), 144*72dab974Scz4e groupDesc = Some(s"pseudo error toggle mask ${i}"), 145*72dab974Scz4e reset = Some(0) 146*72dab974Scz4e ) 147*72dab974Scz4e 148*72dab974Scz4e def ctrlRegField(x: UInt, i: Int) = { 149*72dab974Scz4e RegField(params.regWidth, x, ctrlRegDesc(i)) 150*72dab974Scz4e } 151*72dab974Scz4e 152*72dab974Scz4e def delayRegField(x: UInt, i: Int) = { 153*72dab974Scz4e RegField(params.regWidth, 154*72dab974Scz4e RegReadFn { valid => 155*72dab974Scz4e (true.B, x) 156*72dab974Scz4e }, 157*72dab974Scz4e RegWriteFn { (valid, data) => 158*72dab974Scz4e when(valid) { x := data; counterRegs(i) := data } 159*72dab974Scz4e true.B 160*72dab974Scz4e }, 161*72dab974Scz4e delayRegDesc(i) 162*72dab974Scz4e ) 163*72dab974Scz4e } 164*72dab974Scz4e 165*72dab974Scz4e def maskRegField(x: UInt, i: Int) = { 166*72dab974Scz4e RegField(params.regWidth, x, maskRegDesc(i)) 167*72dab974Scz4e } 168*72dab974Scz4e 169*72dab974Scz4e val ctrlRegFields = ctrlRegs.zipWithIndex.map { 170*72dab974Scz4e case (reg, i) => 171*72dab974Scz4e params.ctrlOffset -> Seq(ctrlRegField(reg, i)) 172*72dab974Scz4e } 173*72dab974Scz4e val delayRegFields = delayRegs.zipWithIndex.map { 174*72dab974Scz4e case (reg, i) => 175*72dab974Scz4e params.delayOffset -> Seq(delayRegField(reg, i)) 176*72dab974Scz4e } 177*72dab974Scz4e val maskRegFields = maskRegs.zipWithIndex.map { 178*72dab974Scz4e case (reg, i) => 179*72dab974Scz4e (params.maskOffset + 8 * i) -> Seq(maskRegField(reg, i)) 180*72dab974Scz4e } 181*72dab974Scz4e 182*72dab974Scz4e node.regmap((ctrlRegFields ++ delayRegFields ++ maskRegFields):_*) 183*72dab974Scz4e } 184*72dab974Scz4e}