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