1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import freechips.rocketchip.rocket.CSRs 6import CSRConfig._ 7import xiangshan.backend.fu.NewCSR.CSRBundles.PrivState 8import xiangshan.backend.fu.NewCSR.CSRConfig._ 9import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, _} 10 11import scala.collection.immutable.SeqMap 12 13trait CSRAIA { self: NewCSR with HypervisorLevel => 14 val miselect = Module(new CSRModule("Miselect", new MISelectBundle) with HasISelectBundle { 15 private val value = reg.ALL.asUInt 16 inIMSICRange := value >= 0x70.U && value < 0x100.U && value(0) =/= 1.U 17 isIllegal := 18 value < 0x30.U || 19 value >= 0x40.U && value < 0x70.U || 20 value >= 0x100.U || 21 value(0) === 1.U 22 }) 23 .setAddr(CSRs.miselect) 24 25 val mireg = Module(new CSRModule("Mireg") with HasIregSink { 26 rdata := iregRead.mireg 27 }) 28 .setAddr(CSRs.mireg) 29 30 val mtopei = Module(new CSRModule("Mtopei", new CSRBundle { 31 val id = RO(26, 16) 32 val prio = RO(10, 0) 33 }) with HasAIABundle { 34 when (aiaToCSR.mtopei.valid) { 35 reg.id := aiaToCSR.mtopei.bits.IID 36 reg.prio := aiaToCSR.mtopei.bits.IPRIO 37 }.otherwise{ 38 reg := reg 39 } 40 }) 41 .setAddr(CSRs.mtopei) 42 43 val mtopi = Module(new CSRModule("Mtopi", new TopIBundle) with HasInterruptFilterSink { 44 regOut.IID := topIR.mtopi.IID 45 regOut.IPRIO := topIR.mtopi.IPRIO 46 }) 47 .setAddr(CSRs.mtopi) 48 49 val siselect = Module(new CSRModule("Siselect", new SISelectBundle) with HasISelectBundle { 50 private val value = reg.ALL.asUInt 51 inIMSICRange := value >= 0x70.U && value < 0x100.U && value(0) =/= 1.U 52 isIllegal := 53 value < 0x30.U || 54 value >= 0x40.U && value < 0x70.U || 55 value >= 0x100.U || 56 value(0) === 1.U 57 }) 58 .setAddr(CSRs.siselect) 59 60 val sireg = Module(new CSRModule("Sireg") with HasIregSink { 61 rdata := iregRead.sireg 62 }) 63 .setAddr(CSRs.sireg) 64 65 val stopei = Module(new CSRModule("Stopei", new CSRBundle { 66 val id = RW(26, 16) 67 val prio = RW(10, 0) 68 }) with HasAIABundle { 69 when(aiaToCSR.stopei.valid) { 70 reg.id := aiaToCSR.stopei.bits.IID 71 reg.prio := aiaToCSR.stopei.bits.IPRIO 72 }.otherwise { 73 reg := reg 74 } 75 }) 76 .setAddr(CSRs.stopei) 77 78 val stopi = Module(new CSRModule("Stopi", new TopIBundle) with HasInterruptFilterSink { 79 regOut.IID := topIR.stopi.IID 80 regOut.IPRIO := topIR.stopi.IPRIO 81 }) 82 .setAddr(CSRs.stopi) 83 84 val vsiselect = Module(new CSRModule("VSiselect", new VSISelectBundle) with HasISelectBundle { 85 private val value = reg.ALL.asUInt 86 inIMSICRange := value >= 0x70.U && value < 0x100.U && value(0) =/= 1.U 87 isIllegal := 88 value < 0x70.U || 89 value >= 0x100.U || 90 value(0) === 1.U 91 }) 92 .setAddr(CSRs.vsiselect) 93 94 val vsireg = Module(new CSRModule("VSireg") with HasIregSink { 95 rdata := iregRead.sireg 96 }) 97 .setAddr(CSRs.vsireg) 98 99 val vstopei = Module(new CSRModule("VStopei", new CSRBundle { 100 val id = RW(26, 16) 101 val prio = RW(10, 0) 102 }) with HasAIABundle { 103 when(aiaToCSR.vstopei.valid) { 104 reg.id := aiaToCSR.vstopei.bits.IID 105 reg.prio := aiaToCSR.vstopei.bits.IPRIO 106 }.otherwise { 107 reg := reg 108 } 109 }) 110 .setAddr(CSRs.vstopei) 111 112 val vstopi = Module(new CSRModule("VStopi", new TopIBundle) with HasInterruptFilterSink { 113 regOut.IID := topIR.vstopi.IID 114 regOut.IPRIO := topIR.vstopi.IPRIO 115 }) 116 .setAddr(CSRs.vstopi) 117 118 val miregiprios: Seq[CSRModule[_]] = Range(0, 0xF, 2).map(num => 119 Module(new CSRModule(s"Iprio$num")) 120 .setAddr(0x30 + num) 121 ) 122 123 val siregiprios: Seq[CSRModule[_]] = Range(0, 0xF, 2).map(num => 124 Module(new CSRModule(s"Iprio$num")) 125 .setAddr(0x30 + num) 126 ) 127 128 val aiaCSRMods = Seq( 129 miselect, 130 mireg, 131 mtopei, 132 mtopi, 133 siselect, 134 sireg, 135 stopei, 136 stopi, 137 vsiselect, 138 vsireg, 139 vstopi, 140 vstopei, 141 ) 142 143 val aiaSkipCSRs = Seq( 144 mtopei, 145 mtopi, 146 stopei, 147 stopi, 148 vstopi, 149 vstopei, 150 ) 151 152 val aiaCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 153 aiaCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator 154 ) 155 156 val aiaCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 157 aiaCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 158 ) 159 160 private val miregRData: UInt = Mux1H( 161 miregiprios.map(prio => (miselect.rdata.asUInt === prio.addr.U) -> prio.rdata) 162 ) 163 164 private val siregRData: UInt = Mux1H( 165 siregiprios.map(prio => (siselect.rdata.asUInt === prio.addr.U) -> prio.rdata) 166 ) 167 168 aiaCSRMods.foreach { mod => 169 mod match { 170 case m: HasIregSink => 171 m.iregRead.mireg := miregRData 172 m.iregRead.sireg := siregRData 173 m.iregRead.vsireg := 0.U // Todo: IMSIC 174 case _ => 175 } 176 } 177} 178 179class ISelectField(final val maxValue: Int, reserved: Seq[Range]) extends CSREnum with WARLApply { 180 override def isLegal(enum: CSREnumType): Bool = { 181 !reserved.map(range => enum.asUInt >= range.start.U && enum.asUInt <= range.end.U).reduce(_ || _) 182 } 183} 184 185object VSISelectField extends ISelectField( 186 0x1FF, 187 reserved = Seq( 188 Range.inclusive(0x000, 0x02F), 189 Range.inclusive(0x040, 0x06F), 190 Range.inclusive(0x100, 0x1FF), 191 ), 192) 193 194object MISelectField extends ISelectField( 195 maxValue = 0xFF, 196 reserved = Seq( 197 Range.inclusive(0x00, 0x2F), 198 Range.inclusive(0x40, 0x6F), 199 ), 200) 201 202object SISelectField extends ISelectField( 203 maxValue = 0xFF, 204 reserved = Seq( 205 Range.inclusive(0x00, 0x2F), 206 Range.inclusive(0x40, 0x6F), 207 ), 208) 209 210class VSISelectBundle extends CSRBundle { 211 val ALL = VSISelectField(log2Up(0x1FF), 0, null) 212} 213 214class MISelectBundle extends CSRBundle { 215 val ALL = MISelectField(log2Up(0xFF), 0, null) 216} 217 218class SISelectBundle extends CSRBundle { 219 val ALL = SISelectField(log2Up(0xFF), 0, null) 220} 221 222class TopIBundle extends CSRBundle { 223 val IID = RO(27, 16) 224 val IPRIO = RO(7, 0) 225} 226 227class TopEIBundle extends CSRBundle { 228 val IID = RW(26, 16) 229 val IPRIO = RW(10, 0) 230} 231 232class IprioBundle extends CSRBundle { 233 val ALL = RW(63, 0).withReset(0.U) 234} 235 236class CSRToAIABundle extends Bundle { 237 private final val AddrWidth = 12 238 239 val addr = ValidIO(new Bundle { 240 val addr = UInt(AddrWidth.W) 241 val v = VirtMode() 242 val prvm = PrivMode() 243 }) 244 245 val vgein = UInt(VGEINWidth.W) 246 247 val wdata = ValidIO(new Bundle { 248 val op = UInt(2.W) 249 val data = UInt(XLEN.W) 250 }) 251 252 val mClaim = Bool() 253 val sClaim = Bool() 254 val vsClaim = Bool() 255} 256 257class AIAToCSRBundle extends Bundle { 258 val rdata = ValidIO(new Bundle { 259 val data = UInt(XLEN.W) 260 val illegal = Bool() 261 }) 262 val mtopei = ValidIO(new TopEIBundle) 263 val stopei = ValidIO(new TopEIBundle) 264 val vstopei = ValidIO(new TopEIBundle) 265} 266 267trait HasAIABundle { self: CSRModule[_] => 268 val aiaToCSR = IO(Input(new AIAToCSRBundle)) 269} 270 271trait HasInterruptFilterSink { self: CSRModule[_] => 272 val topIR = IO(new Bundle { 273 val mtopi = Input(new TopIBundle) 274 val stopi = Input(new TopIBundle) 275 val vstopi = Input(new TopIBundle) 276 }) 277} 278 279trait HasISelectBundle { self: CSRModule[_] => 280 val inIMSICRange = IO(Output(Bool())) 281 val isIllegal = IO(Output(Bool())) 282} 283 284trait HasIregSink { self: CSRModule[_] => 285 val iregRead = IO(Input(new Bundle { 286 val mireg = UInt(XLEN.W) // Todo: check if use ireg bundle, and shrink the width 287 val sireg = UInt(XLEN.W) 288 val vsireg = UInt(XLEN.W) 289 })) 290} 291