1package xiangshan.backend.fu 2 3import chisel3._ 4import chisel3.ExcitingUtils.{ConnectionType, Debug} 5import chisel3.util._ 6import utils._ 7import xiangshan._ 8import xiangshan.backend._ 9import xiangshan.frontend.BPUCtrl 10import xiangshan.backend.fu.util._ 11 12trait HasExceptionNO { 13 def instrAddrMisaligned = 0 14 def instrAccessFault = 1 15 def illegalInstr = 2 16 def breakPoint = 3 17 def loadAddrMisaligned = 4 18 def loadAccessFault = 5 19 def storeAddrMisaligned = 6 20 def storeAccessFault = 7 21 def ecallU = 8 22 def ecallS = 9 23 def ecallM = 11 24 def instrPageFault = 12 25 def loadPageFault = 13 26 def storePageFault = 15 27 28 val ExcPriority = Seq( 29 breakPoint, // TODO: different BP has different priority 30 instrPageFault, 31 instrAccessFault, 32 illegalInstr, 33 instrAddrMisaligned, 34 ecallM, ecallS, ecallU, 35 storePageFault, 36 loadPageFault, 37 storeAccessFault, 38 loadAccessFault, 39 storeAddrMisaligned, 40 loadAddrMisaligned 41 ) 42 val frontendSet = List( 43 // instrAddrMisaligned, 44 instrAccessFault, 45 illegalInstr, 46 instrPageFault 47 ) 48 val csrSet = List( 49 illegalInstr, 50 breakPoint, 51 ecallU, 52 ecallS, 53 ecallM 54 ) 55 val loadUnitSet = List( 56 loadAddrMisaligned, 57 loadAccessFault, 58 loadPageFault 59 ) 60 val storeUnitSet = List( 61 storeAddrMisaligned, 62 storeAccessFault, 63 storePageFault 64 ) 65 val atomicsUnitSet = (loadUnitSet ++ storeUnitSet).distinct 66 val allPossibleSet = (frontendSet ++ csrSet ++ loadUnitSet ++ storeUnitSet).distinct 67 val csrWbCount = (0 until 16).map(i => if (csrSet.contains(i)) 1 else 0) 68 val loadWbCount = (0 until 16).map(i => if (loadUnitSet.contains(i)) 1 else 0) 69 val storeWbCount = (0 until 16).map(i => if (storeUnitSet.contains(i)) 1 else 0) 70 val atomicsWbCount = (0 until 16).map(i => if (atomicsUnitSet.contains(i)) 1 else 0) 71 val writebackCount = (0 until 16).map(i => csrWbCount(i) + atomicsWbCount(i) + loadWbCount(i) + 2 * storeWbCount(i)) 72 def partialSelect(vec: Vec[Bool], select: Seq[Int], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = { 73 if (dontCareBits) { 74 val new_vec = Wire(ExceptionVec()) 75 new_vec := DontCare 76 select.map(i => new_vec(i) := vec(i)) 77 return new_vec 78 } 79 else if (falseBits) { 80 val new_vec = Wire(ExceptionVec()) 81 new_vec.map(_ := false.B) 82 select.map(i => new_vec(i) := vec(i)) 83 return new_vec 84 } 85 else { 86 val new_vec = Wire(Vec(select.length, Bool())) 87 select.zipWithIndex.map{ case(s, i) => new_vec(i) := vec(s) } 88 return new_vec 89 } 90 } 91 def selectFrontend(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 92 partialSelect(vec, frontendSet, dontCareBits, falseBits) 93 def selectCSR(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 94 partialSelect(vec, csrSet, dontCareBits, falseBits) 95 def selectLoad(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 96 partialSelect(vec, loadUnitSet, dontCareBits, falseBits) 97 def selectStore(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 98 partialSelect(vec, storeUnitSet, dontCareBits, falseBits) 99 def selectAtomics(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 100 partialSelect(vec, atomicsUnitSet, dontCareBits, falseBits) 101 def selectAll(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = 102 partialSelect(vec, allPossibleSet, dontCareBits, falseBits) 103} 104 105class FpuCsrIO extends XSBundle { 106 val fflags = Output(Valid(UInt(5.W))) 107 val isIllegal = Output(Bool()) 108 val dirty_fs = Output(Bool()) 109 val frm = Input(UInt(3.W)) 110} 111 112 113class PerfCounterIO extends XSBundle { 114 val retiredInstr = UInt(3.W) 115 val frontendInfo = new Bundle { 116 val ibufFull = Bool() 117 } 118 val ctrlInfo = new Bundle { 119 val roqFull = Bool() 120 val intdqFull = Bool() 121 val fpdqFull = Bool() 122 val lsdqFull = Bool() 123 } 124 val memInfo = new Bundle { 125 val sqFull = Bool() 126 val lqFull = Bool() 127 val dcacheMSHRFull = Bool() 128 } 129 val bpuInfo = new Bundle { 130 val bpRight = UInt(XLEN.W) 131 val bpWrong = UInt(XLEN.W) 132 } 133 val cacheInfo = new Bundle { 134 val l2MSHRFull = Bool() 135 val l3MSHRFull = Bool() 136 val l2nAcquire = UInt(XLEN.W) 137 val l2nAcquireMiss = UInt(XLEN.W) 138 val l3nAcquire = UInt(XLEN.W) 139 val l3nAcquireMiss = UInt(XLEN.W) 140 } 141} 142 143class CSRFileIO extends XSBundle { 144 val hartId = Input(UInt(64.W)) 145 // output (for func === CSROpType.jmp) 146 val perf = Input(new PerfCounterIO) 147 val isPerfCnt = Output(Bool()) 148 // to FPU 149 val fpu = Flipped(new FpuCsrIO) 150 // from rob 151 val exception = Flipped(ValidIO(new ExceptionInfo)) 152 // to ROB 153 val isXRet = Output(Bool()) 154 val trapTarget = Output(UInt(VAddrBits.W)) 155 val interrupt = Output(Bool()) 156 // from LSQ 157 val memExceptionVAddr = Input(UInt(VAddrBits.W)) 158 // from outside cpu,externalInterrupt 159 val externalInterrupt = new ExternalInterruptIO 160 // TLB 161 val tlb = Output(new TlbCsrBundle) 162 // Custom microarchiture ctrl signal 163 val customCtrl = Output(new CustomCSRCtrlIO) 164} 165 166class CSR extends FunctionUnit with HasCSRConst 167{ 168 val csrio = IO(new CSRFileIO) 169 val difftestIO = IO(new Bundle() { 170 val intrNO = Output(UInt(64.W)) 171 val cause = Output(UInt(64.W)) 172 val priviledgeMode = Output(UInt(2.W)) 173 val mstatus = Output(UInt(64.W)) 174 val sstatus = Output(UInt(64.W)) 175 val mepc = Output(UInt(64.W)) 176 val sepc = Output(UInt(64.W)) 177 val mtval = Output(UInt(64.W)) 178 val stval = Output(UInt(64.W)) 179 val mtvec = Output(UInt(64.W)) 180 val stvec = Output(UInt(64.W)) 181 val mcause = Output(UInt(64.W)) 182 val scause = Output(UInt(64.W)) 183 val satp = Output(UInt(64.W)) 184 val mip = Output(UInt(64.W)) 185 val mie = Output(UInt(64.W)) 186 val mscratch = Output(UInt(64.W)) 187 val sscratch = Output(UInt(64.W)) 188 val mideleg = Output(UInt(64.W)) 189 val medeleg = Output(UInt(64.W)) 190 }) 191 difftestIO <> DontCare 192 193 val cfIn = io.in.bits.uop.cf 194 val cfOut = Wire(new CtrlFlow) 195 cfOut := cfIn 196 val flushPipe = Wire(Bool()) 197 198 val (valid, src1, src2, func) = ( 199 io.in.valid, 200 io.in.bits.src(0), 201 io.in.bits.uop.ctrl.imm, 202 io.in.bits.uop.ctrl.fuOpType 203 ) 204 205 // CSR define 206 207 class Priv extends Bundle { 208 val m = Output(Bool()) 209 val h = Output(Bool()) 210 val s = Output(Bool()) 211 val u = Output(Bool()) 212 } 213 214 val csrNotImplemented = RegInit(UInt(XLEN.W), 0.U) 215 216 class MstatusStruct extends Bundle { 217 val sd = Output(UInt(1.W)) 218 219 val pad1 = if (XLEN == 64) Output(UInt(27.W)) else null 220 val sxl = if (XLEN == 64) Output(UInt(2.W)) else null 221 val uxl = if (XLEN == 64) Output(UInt(2.W)) else null 222 val pad0 = if (XLEN == 64) Output(UInt(9.W)) else Output(UInt(8.W)) 223 224 val tsr = Output(UInt(1.W)) 225 val tw = Output(UInt(1.W)) 226 val tvm = Output(UInt(1.W)) 227 val mxr = Output(UInt(1.W)) 228 val sum = Output(UInt(1.W)) 229 val mprv = Output(UInt(1.W)) 230 val xs = Output(UInt(2.W)) 231 val fs = Output(UInt(2.W)) 232 val mpp = Output(UInt(2.W)) 233 val hpp = Output(UInt(2.W)) 234 val spp = Output(UInt(1.W)) 235 val pie = new Priv 236 val ie = new Priv 237 assert(this.getWidth == XLEN) 238 } 239 240 class SatpStruct extends Bundle { 241 val mode = UInt(4.W) 242 val asid = UInt(16.W) 243 val ppn = UInt(44.W) 244 } 245 246 class Interrupt extends Bundle { 247 val e = new Priv 248 val t = new Priv 249 val s = new Priv 250 } 251 252 // Machine-Level CSRs 253 254 val mtvec = RegInit(UInt(XLEN.W), 0.U) 255 val mcounteren = RegInit(UInt(XLEN.W), 0.U) 256 val mcause = RegInit(UInt(XLEN.W), 0.U) 257 val mtval = RegInit(UInt(XLEN.W), 0.U) 258 val mepc = Reg(UInt(XLEN.W)) 259 260 val mie = RegInit(0.U(XLEN.W)) 261 val mipWire = WireInit(0.U.asTypeOf(new Interrupt)) 262 val mipReg = RegInit(0.U.asTypeOf(new Interrupt).asUInt) 263 val mipFixMask = GenMask(9) | GenMask(5) | GenMask(1) 264 val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt) 265 266 def getMisaMxl(mxl: Int): UInt = {mxl.U << (XLEN-2)}.asUInt() 267 def getMisaExt(ext: Char): UInt = {1.U << (ext.toInt - 'a'.toInt)}.asUInt() 268 var extList = List('a', 's', 'i', 'u') 269 if (HasMExtension) { extList = extList :+ 'm' } 270 if (HasCExtension) { extList = extList :+ 'c' } 271 if (HasFPU) { extList = extList ++ List('f', 'd') } 272 val misaInitVal = getMisaMxl(2) | extList.foldLeft(0.U)((sum, i) => sum | getMisaExt(i)) //"h8000000000141105".U 273 val misa = RegInit(UInt(XLEN.W), misaInitVal) 274 275 // MXL = 2 | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101 276 // (XLEN-1, XLEN-2) | |(25, 0) ZY XWVU TSRQ PONM LKJI HGFE DCBA 277 278 val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation 279 val marchid = RegInit(UInt(XLEN.W), 0.U) // return 0 to indicate the field is not implemented 280 val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation 281 val mhartid = RegInit(UInt(XLEN.W), csrio.hartId) // the hardware thread running the code 282 val mstatus = RegInit(UInt(XLEN.W), 0.U) 283 284 // mstatus Value Table 285 // | sd | 286 // | pad1 | 287 // | sxl | hardlinked to 10, use 00 to pass xv6 test 288 // | uxl | hardlinked to 00 289 // | pad0 | 290 // | tsr | 291 // | tw | 292 // | tvm | 293 // | mxr | 294 // | sum | 295 // | mprv | 296 // | xs | 00 | 297 // | fs | 00 | 298 // | mpp | 00 | 299 // | hpp | 00 | 300 // | spp | 0 | 301 // | pie | 0000 | pie.h is used as UBE 302 // | ie | 0000 | uie hardlinked to 0, as N ext is not implemented 303 304 val mstatusStruct = mstatus.asTypeOf(new MstatusStruct) 305 def mstatusUpdateSideEffect(mstatus: UInt): UInt = { 306 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 307 val mstatusNew = Cat(mstatusOld.xs === "b11".U || mstatusOld.fs === "b11".U, mstatus(XLEN-2, 0)) 308 mstatusNew 309 } 310 311 val mstatusMask = (~ZeroExt(( 312 GenMask(XLEN-2, 38) | GenMask(31, 23) | GenMask(10, 9) | GenMask(2) | 313 GenMask(37) | // MBE 314 GenMask(36) | // SBE 315 GenMask(6) // UBE 316 ), 64)).asUInt() 317 318 val medeleg = RegInit(UInt(XLEN.W), 0.U) 319 val mideleg = RegInit(UInt(XLEN.W), 0.U) 320 val mscratch = RegInit(UInt(XLEN.W), 0.U) 321 322 val pmpcfg0 = RegInit(UInt(XLEN.W), 0.U) 323 val pmpcfg1 = RegInit(UInt(XLEN.W), 0.U) 324 val pmpcfg2 = RegInit(UInt(XLEN.W), 0.U) 325 val pmpcfg3 = RegInit(UInt(XLEN.W), 0.U) 326 val pmpaddr0 = RegInit(UInt(XLEN.W), 0.U) 327 val pmpaddr1 = RegInit(UInt(XLEN.W), 0.U) 328 val pmpaddr2 = RegInit(UInt(XLEN.W), 0.U) 329 val pmpaddr3 = RegInit(UInt(XLEN.W), 0.U) 330 331 // Superviser-Level CSRs 332 333 // val sstatus = RegInit(UInt(XLEN.W), "h00000000".U) 334 val sstatusWmask = "hc6122".U 335 // Sstatus Write Mask 336 // ------------------------------------------------------- 337 // 19 9 5 2 338 // 0 1100 0000 0001 0010 0010 339 // 0 c 0 1 2 2 340 // ------------------------------------------------------- 341 val sstatusRmask = sstatusWmask | "h8000000300018000".U 342 // Sstatus Read Mask = (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32)) 343 val stvec = RegInit(UInt(XLEN.W), 0.U) 344 // val sie = RegInit(0.U(XLEN.W)) 345 val sieMask = "h222".U & mideleg 346 val sipMask = "h222".U & mideleg 347 val satp = if(EnbaleTlbDebug) RegInit(UInt(XLEN.W), "h8000000000087fbe".U) else RegInit(0.U(XLEN.W)) 348 // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug 349 val satpMask = "h80000fffffffffff".U // disable asid, mode can only be 8 / 0 350 val sepc = RegInit(UInt(XLEN.W), 0.U) 351 val scause = RegInit(UInt(XLEN.W), 0.U) 352 val stval = Reg(UInt(XLEN.W)) 353 val sscratch = RegInit(UInt(XLEN.W), 0.U) 354 val scounteren = RegInit(UInt(XLEN.W), 0.U) 355 356 // sbpctl 357 // Bits 0-7: {LOOP, RAS, SC, TAGE, BIM, BTB, uBTB} 358 val sbpctl = RegInit(UInt(XLEN.W), "h7f".U) 359 csrio.customCtrl.bp_ctrl.ubtb_enable := sbpctl(0) 360 csrio.customCtrl.bp_ctrl.btb_enable := sbpctl(1) 361 csrio.customCtrl.bp_ctrl.bim_enable := sbpctl(2) 362 csrio.customCtrl.bp_ctrl.tage_enable := sbpctl(3) 363 csrio.customCtrl.bp_ctrl.sc_enable := sbpctl(4) 364 csrio.customCtrl.bp_ctrl.ras_enable := sbpctl(5) 365 csrio.customCtrl.bp_ctrl.loop_enable := sbpctl(6) 366 367 // spfctl Bit 0: L1plusCache Prefetcher Enable 368 // spfctl Bit 1: L2Cache Prefetcher Enable 369 val spfctl = RegInit(UInt(XLEN.W), "h3".U) 370 csrio.customCtrl.l1plus_pf_enable := spfctl(0) 371 csrio.customCtrl.l2_pf_enable := spfctl(1) 372 373 // sdsid: Differentiated Services ID 374 val sdsid = RegInit(UInt(XLEN.W), 0.U) 375 csrio.customCtrl.dsid := sdsid 376 377 // slvpredctl: load violation predict settings 378 val slvpredctl = RegInit(UInt(XLEN.W), "h70".U) // default reset period: 2^17 379 csrio.customCtrl.lvpred_disable := slvpredctl(0) 380 csrio.customCtrl.no_spec_load := slvpredctl(1) 381 csrio.customCtrl.waittable_timeout := slvpredctl(8, 4) 382 383 // smblockctl: memory block configurations 384 // bits 0-3: store buffer flush threshold (default: 8 entries) 385 val smblockctl = RegInit(UInt(XLEN.W), "h7".U) 386 csrio.customCtrl.sbuffer_threshold := smblockctl(3, 0) 387 388 val srnctl = RegInit(UInt(XLEN.W), "h1".U) 389 csrio.customCtrl.move_elim_enable := srnctl(0) 390 391 val tlbBundle = Wire(new TlbCsrBundle) 392 tlbBundle.satp := satp.asTypeOf(new SatpStruct) 393 csrio.tlb := tlbBundle 394 395 // User-Level CSRs 396 val uepc = Reg(UInt(XLEN.W)) 397 398 // fcsr 399 class FcsrStruct extends Bundle { 400 val reserved = UInt((XLEN-3-5).W) 401 val frm = UInt(3.W) 402 val fflags = UInt(5.W) 403 assert(this.getWidth == XLEN) 404 } 405 val fcsr = RegInit(0.U(XLEN.W)) 406 // set mstatus->sd and mstatus->fs when true 407 val csrw_dirty_fp_state = WireInit(false.B) 408 409 def frm_wfn(wdata: UInt): UInt = { 410 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 411 csrw_dirty_fp_state := true.B 412 fcsrOld.frm := wdata(2,0) 413 fcsrOld.asUInt() 414 } 415 def frm_rfn(rdata: UInt): UInt = rdata(7,5) 416 417 def fflags_wfn(update: Boolean)(wdata: UInt): UInt = { 418 val fcsrOld = fcsr.asTypeOf(new FcsrStruct) 419 val fcsrNew = WireInit(fcsrOld) 420 csrw_dirty_fp_state := true.B 421 if (update) { 422 fcsrNew.fflags := wdata(4,0) | fcsrOld.fflags 423 } else { 424 fcsrNew.fflags := wdata(4,0) 425 } 426 fcsrNew.asUInt() 427 } 428 def fflags_rfn(rdata:UInt): UInt = rdata(4,0) 429 430 def fcsr_wfn(wdata: UInt): UInt = { 431 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 432 csrw_dirty_fp_state := true.B 433 Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags) 434 } 435 436 val fcsrMapping = Map( 437 MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn(update = false), rfn = fflags_rfn), 438 MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn), 439 MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn) 440 ) 441 442 // Atom LR/SC Control Bits 443 // val setLr = WireInit(Bool(), false.B) 444 // val setLrVal = WireInit(Bool(), false.B) 445 // val setLrAddr = WireInit(UInt(AddrBits.W), DontCare) //TODO : need check 446 // val lr = RegInit(Bool(), false.B) 447 // val lrAddr = RegInit(UInt(AddrBits.W), 0.U) 448 // 449 // when (setLr) { 450 // lr := setLrVal 451 // lrAddr := setLrAddr 452 // } 453 454 // Hart Priviledge Mode 455 val priviledgeMode = RegInit(UInt(2.W), ModeM) 456 457 // Emu perfcnt 458 val hasEmuPerfCnt = !env.FPGAPlatform 459 val nrEmuPerfCnts = if (hasEmuPerfCnt) 0x80 else 0x3 460 461 val emuPerfCnts = List.fill(nrEmuPerfCnts)(RegInit(0.U(XLEN.W))) 462 val emuPerfCntCond = List.fill(nrEmuPerfCnts)(WireInit(false.B)) 463 (emuPerfCnts zip emuPerfCntCond).map { case (c, e) => when (e) { c := c + 1.U } } 464 465 val emuPerfCntsLoMapping = (0 until nrEmuPerfCnts).map(i => MaskedRegMap(0x1000 + i, emuPerfCnts(i))) 466 val emuPerfCntsHiMapping = (0 until nrEmuPerfCnts).map(i => MaskedRegMap(0x1080 + i, emuPerfCnts(i)(63, 32))) 467 println(s"CSR: hasEmuPerfCnt:${hasEmuPerfCnt}") 468 469 // Perf Counter 470 val nrPerfCnts = 29 // 3...31 471 val perfCnts = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 472 val perfEvents = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 473 val mcountinhibit = RegInit(0.U(XLEN.W)) 474 val mcycle = RegInit(0.U(XLEN.W)) 475 mcycle := mcycle + 1.U 476 val minstret = RegInit(0.U(XLEN.W)) 477 minstret := minstret + RegNext(csrio.perf.retiredInstr) 478 val ibufFull = RegInit(0.U(XLEN.W)) 479 ibufFull := ibufFull + RegNext(csrio.perf.frontendInfo.ibufFull) 480 val roqFull = RegInit(0.U(XLEN.W)) 481 roqFull := roqFull + RegNext(csrio.perf.ctrlInfo.roqFull) 482 val intdqFull = RegInit(0.U(XLEN.W)) 483 intdqFull := intdqFull + RegNext(csrio.perf.ctrlInfo.intdqFull) 484 val fpdqFull = RegInit(0.U(XLEN.W)) 485 fpdqFull := fpdqFull + RegNext(csrio.perf.ctrlInfo.fpdqFull) 486 val lsdqFull = RegInit(0.U(XLEN.W)) 487 lsdqFull := lsdqFull + RegNext(csrio.perf.ctrlInfo.lsdqFull) 488 val sqFull = RegInit(0.U(XLEN.W)) 489 sqFull := sqFull + RegNext(csrio.perf.memInfo.sqFull) 490 val lqFull = RegInit(0.U(XLEN.W)) 491 lqFull := lqFull + RegNext(csrio.perf.memInfo.lqFull) 492 val dcacheMSHRFull = RegInit(0.U(XLEN.W)) 493 dcacheMSHRFull := dcacheMSHRFull + RegNext(csrio.perf.memInfo.dcacheMSHRFull) 494 val bpRight = RegInit(0.U(XLEN.W)) 495 bpRight := bpRight + RegNext(csrio.perf.bpuInfo.bpRight) 496 val bpWrong = RegInit(0.U(XLEN.W)) 497 bpWrong := bpWrong + RegNext(csrio.perf.bpuInfo.bpWrong) 498 499 // CSR reg map 500 val basicPrivMapping = Map( 501 502 //--- User Trap Setup --- 503 // MaskedRegMap(Ustatus, ustatus), 504 // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable), 505 // MaskedRegMap(Utvec, utvec), 506 507 //--- User Trap Handling --- 508 // MaskedRegMap(Uscratch, uscratch), 509 // MaskedRegMap(Uepc, uepc), 510 // MaskedRegMap(Ucause, ucause), 511 // MaskedRegMap(Utval, utval), 512 // MaskedRegMap(Uip, uip), 513 514 //--- User Counter/Timers --- 515 // MaskedRegMap(Cycle, cycle), 516 // MaskedRegMap(Time, time), 517 // MaskedRegMap(Instret, instret), 518 519 //--- Supervisor Trap Setup --- 520 MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask), 521 // MaskedRegMap(Sedeleg, Sedeleg), 522 // MaskedRegMap(Sideleg, Sideleg), 523 MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask), 524 MaskedRegMap(Stvec, stvec), 525 MaskedRegMap(Scounteren, scounteren), 526 527 //--- Supervisor Trap Handling --- 528 MaskedRegMap(Sscratch, sscratch), 529 MaskedRegMap(Sepc, sepc), 530 MaskedRegMap(Scause, scause), 531 MaskedRegMap(Stval, stval), 532 MaskedRegMap(Sip, mip.asUInt, sipMask, MaskedRegMap.Unwritable, sipMask), 533 534 //--- Supervisor Protection and Translation --- 535 MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 536 537 //--- Supervisor Custom Read/Write Registers 538 MaskedRegMap(Sbpctl, sbpctl), 539 MaskedRegMap(Spfctl, spfctl), 540 MaskedRegMap(Sdsid, sdsid), 541 MaskedRegMap(Slvpredctl, slvpredctl), 542 MaskedRegMap(Smblockctl, smblockctl), 543 MaskedRegMap(Srnctl, srnctl), 544 545 //--- Machine Information Registers --- 546 MaskedRegMap(Mvendorid, mvendorid, 0.U, MaskedRegMap.Unwritable), 547 MaskedRegMap(Marchid, marchid, 0.U, MaskedRegMap.Unwritable), 548 MaskedRegMap(Mimpid, mimpid, 0.U, MaskedRegMap.Unwritable), 549 MaskedRegMap(Mhartid, mhartid, 0.U, MaskedRegMap.Unwritable), 550 551 //--- Machine Trap Setup --- 552 MaskedRegMap(Mstatus, mstatus, mstatusMask, mstatusUpdateSideEffect, mstatusMask), 553 MaskedRegMap(Misa, misa), // now MXL, EXT is not changeable 554 MaskedRegMap(Medeleg, medeleg, "hf3ff".U), 555 MaskedRegMap(Mideleg, mideleg, "h222".U), 556 MaskedRegMap(Mie, mie), 557 MaskedRegMap(Mtvec, mtvec), 558 MaskedRegMap(Mcounteren, mcounteren), 559 560 //--- Machine Trap Handling --- 561 MaskedRegMap(Mscratch, mscratch), 562 MaskedRegMap(Mepc, mepc), 563 MaskedRegMap(Mcause, mcause), 564 MaskedRegMap(Mtval, mtval), 565 MaskedRegMap(Mip, mip.asUInt, 0.U, MaskedRegMap.Unwritable), 566 ) 567 568 // PMP is unimplemented yet 569 val pmpMapping = Map( 570 MaskedRegMap(Pmpcfg0, pmpcfg0), 571 MaskedRegMap(Pmpcfg1, pmpcfg1), 572 MaskedRegMap(Pmpcfg2, pmpcfg2), 573 MaskedRegMap(Pmpcfg3, pmpcfg3), 574 MaskedRegMap(PmpaddrBase + 0, pmpaddr0), 575 MaskedRegMap(PmpaddrBase + 1, pmpaddr1), 576 MaskedRegMap(PmpaddrBase + 2, pmpaddr2), 577 MaskedRegMap(PmpaddrBase + 3, pmpaddr3) 578 ) 579 580 var perfCntMapping = Map( 581 MaskedRegMap(Mcountinhibit, mcountinhibit), 582 MaskedRegMap(Mcycle, mcycle), 583 MaskedRegMap(Minstret, minstret), 584 MaskedRegMap(Mhpmevent3, ibufFull), 585 MaskedRegMap(Mhpmevent4, roqFull), 586 MaskedRegMap(Mhpmevent5, intdqFull), 587 MaskedRegMap(Mhpmevent6, fpdqFull), 588 MaskedRegMap(Mhpmevent7, lsdqFull), 589 MaskedRegMap(Mhpmevent8, sqFull), 590 MaskedRegMap(Mhpmevent9, lqFull), 591 MaskedRegMap(Mhpmevent10, dcacheMSHRFull), 592 MaskedRegMap(Mhpmevent11, bpRight), 593 MaskedRegMap(Mhpmevent12, bpWrong), 594 ) 595 val MhpmcounterStart = Mhpmcounter3 596 val MhpmeventStart = Mhpmevent3 597 for (i <- 0 until nrPerfCnts) { 598 perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i)) 599 perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i)) 600 } 601 602 val mapping = basicPrivMapping ++ 603 perfCntMapping ++ 604 pmpMapping ++ 605 emuPerfCntsLoMapping ++ 606 (if (XLEN == 32) emuPerfCntsHiMapping else Nil) ++ 607 (if (HasFPU) fcsrMapping else Nil) 608 609 val addr = src2(11, 0) 610 val csri = ZeroExt(src2(16, 12), XLEN) 611 val rdata = Wire(UInt(XLEN.W)) 612 val wdata = LookupTree(func, List( 613 CSROpType.wrt -> src1, 614 CSROpType.set -> (rdata | src1), 615 CSROpType.clr -> (rdata & (~src1).asUInt()), 616 CSROpType.wrti -> csri, 617 CSROpType.seti -> (rdata | csri), 618 CSROpType.clri -> (rdata & (~csri).asUInt()) 619 )) 620 621 val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U) 622 csrio.isPerfCnt := addrInPerfCnt 623 624 // satp wen check 625 val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 626 627 // general CSR wen check 628 val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode) 629 val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode) 630 val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren) 631 val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) 632 // Writeable check is ingored. 633 // Currently, write to illegal csr addr will be ignored 634 MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata) 635 io.out.bits.data := rdata 636 io.out.bits.uop := io.in.bits.uop 637 io.out.bits.uop.cf := cfOut 638 io.out.bits.uop.ctrl.flushPipe := flushPipe 639 640 // Fix Mip/Sip write 641 val fixMapping = Map( 642 MaskedRegMap(Mip, mipReg.asUInt, mipFixMask), 643 MaskedRegMap(Sip, mipReg.asUInt, sipMask, MaskedRegMap.NoSideEffect, sipMask) 644 ) 645 val rdataDummy = Wire(UInt(XLEN.W)) 646 MaskedRegMap.generate(fixMapping, addr, rdataDummy, wen, wdata) 647 648 when (csrio.fpu.fflags.valid) { 649 fcsr := fflags_wfn(update = true)(csrio.fpu.fflags.bits) 650 } 651 // set fs and sd in mstatus 652 when (csrw_dirty_fp_state || csrio.fpu.dirty_fs) { 653 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 654 mstatusNew.fs := "b11".U 655 mstatusNew.sd := true.B 656 mstatus := mstatusNew.asUInt() 657 } 658 csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm 659 660 // CSR inst decode 661 val isEbreak = addr === privEbreak && func === CSROpType.jmp 662 val isEcall = addr === privEcall && func === CSROpType.jmp 663 val isMret = addr === privMret && func === CSROpType.jmp 664 val isSret = addr === privSret && func === CSROpType.jmp 665 val isUret = addr === privUret && func === CSROpType.jmp 666 667 XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func) 668 XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode) 669 670 // Illegal priviledged operation list 671 val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool 672 673 // Illegal priviledged instruction check 674 val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr) 675 val isIllegalAccess = !permitted 676 val isIllegalPrivOp = illegalSModeSret 677 678 // def MMUPermissionCheck(ptev: Bool, pteu: Bool): Bool = ptev && !(priviledgeMode === ModeU && !pteu) && !(priviledgeMode === ModeS && pteu && mstatusStruct.sum.asBool) 679 // def MMUPermissionCheckLoad(ptev: Bool, pteu: Bool): Bool = ptev && !(priviledgeMode === ModeU && !pteu) && !(priviledgeMode === ModeS && pteu && mstatusStruct.sum.asBool) && (pter || (mstatusStruct.mxr && ptex)) 680 // imem 681 // val imemPtev = true.B 682 // val imemPteu = true.B 683 // val imemPtex = true.B 684 // val imemReq = true.B 685 // val imemPermissionCheckPassed = MMUPermissionCheck(imemPtev, imemPteu) 686 // val hasInstrPageFault = imemReq && !(imemPermissionCheckPassed && imemPtex) 687 // assert(!hasInstrPageFault) 688 689 // dmem 690 // val dmemPtev = true.B 691 // val dmemPteu = true.B 692 // val dmemReq = true.B 693 // val dmemPermissionCheckPassed = MMUPermissionCheck(dmemPtev, dmemPteu) 694 // val dmemIsStore = true.B 695 696 // val hasLoadPageFault = dmemReq && !dmemIsStore && !(dmemPermissionCheckPassed) 697 // val hasStorePageFault = dmemReq && dmemIsStore && !(dmemPermissionCheckPassed) 698 // assert(!hasLoadPageFault) 699 // assert(!hasStorePageFault) 700 701 //TODO: Havn't test if io.dmemMMU.priviledgeMode is correct yet 702 tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 703 tlbBundle.priv.sum := mstatusStruct.sum.asBool 704 tlbBundle.priv.imode := priviledgeMode 705 tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode) 706 707 // Branch control 708 val retTarget = Wire(UInt(VAddrBits.W)) 709 val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed 710 flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall) 711 712 retTarget := DontCare 713 // val illegalEret = TODO 714 715 when (valid && isMret) { 716 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 717 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 718 mstatusNew.ie.m := mstatusOld.pie.m 719 priviledgeMode := mstatusOld.mpp 720 mstatusNew.pie.m := true.B 721 mstatusNew.mpp := ModeU 722 mstatusNew.mprv := 0.U 723 mstatus := mstatusNew.asUInt 724 // lr := false.B 725 retTarget := mepc(VAddrBits-1, 0) 726 } 727 728 when (valid && isSret && !illegalSModeSret) { 729 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 730 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 731 mstatusNew.ie.s := mstatusOld.pie.s 732 priviledgeMode := Cat(0.U(1.W), mstatusOld.spp) 733 mstatusNew.pie.s := true.B 734 mstatusNew.spp := ModeU 735 mstatus := mstatusNew.asUInt 736 mstatusNew.mprv := 0.U 737 // lr := false.B 738 retTarget := sepc(VAddrBits-1, 0) 739 } 740 741 when (valid && isUret) { 742 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 743 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 744 // mstatusNew.mpp.m := ModeU //TODO: add mode U 745 mstatusNew.ie.u := mstatusOld.pie.u 746 priviledgeMode := ModeU 747 mstatusNew.pie.u := true.B 748 mstatus := mstatusNew.asUInt 749 retTarget := uepc(VAddrBits-1, 0) 750 } 751 752 io.in.ready := true.B 753 io.out.valid := valid 754 755 val csrExceptionVec = WireInit(cfIn.exceptionVec) 756 csrExceptionVec(breakPoint) := io.in.valid && isEbreak 757 csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall 758 csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall 759 csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall 760 // Trigger an illegal instr exception when: 761 // * unimplemented csr is being read/written 762 // * csr access is illegal 763 csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen 764 cfOut.exceptionVec := csrExceptionVec 765 766 /** 767 * Exception and Intr 768 */ 769 val ideleg = (mideleg & mip.asUInt) 770 def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS), 771 ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM)) 772 773 // send interrupt information to ROQ 774 val intrVecEnable = Wire(Vec(12, Bool())) 775 intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)} 776 val intrVec = mie(11,0) & mip.asUInt & intrVecEnable.asUInt 777 val intrBitSet = intrVec.orR() 778 csrio.interrupt := intrBitSet 779 mipWire.t.m := csrio.externalInterrupt.mtip 780 mipWire.s.m := csrio.externalInterrupt.msip 781 mipWire.e.m := csrio.externalInterrupt.meip 782 783 // interrupts 784 val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 785 val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt 786 XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.uop.cf.pc, intrNO) 787 788 // exceptions 789 val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt 790 val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException 791 val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException 792 val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException 793 val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException 794 val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException 795 val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException 796 val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException 797 val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException 798 799 val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec 800 val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) 801 val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO) 802 803 val raiseExceptionIntr = csrio.exception.valid 804 XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", 805 csrio.exception.bits.uop.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt 806 ) 807 XSDebug(raiseExceptionIntr, 808 "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", 809 csrio.exception.bits.uop.cf.pc, 810 mstatus, 811 mideleg, 812 medeleg, 813 priviledgeMode 814 ) 815 816 // mtval write logic 817 val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN) 818 when (hasInstrPageFault || hasLoadPageFault || hasStorePageFault) { 819 val tval = Mux( 820 hasInstrPageFault, 821 Mux( 822 csrio.exception.bits.uop.cf.crossPageIPFFix, 823 SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN), 824 SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 825 ), 826 memExceptionAddr 827 ) 828 when (priviledgeMode === ModeM) { 829 mtval := tval 830 }.otherwise { 831 stval := tval 832 } 833 } 834 835 when (hasLoadAddrMisaligned || hasStoreAddrMisaligned) { 836 mtval := memExceptionAddr 837 } 838 839 val deleg = Mux(raiseIntr, mideleg , medeleg) 840 // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM); 841 val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM) 842 val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check 843 val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall 844 845 // ctrl block will use theses later for flush 846 val isXRetFlag = RegInit(false.B) 847 val retTargetReg = Reg(retTarget.cloneType) 848 when (io.flushIn) { 849 isXRetFlag := false.B 850 }.elsewhen (isXRet) { 851 isXRetFlag := true.B 852 retTargetReg := retTarget 853 } 854 csrio.isXRet := isXRetFlag 855 csrio.trapTarget := Mux(isXRetFlag, 856 retTargetReg, 857 Mux(delegS, stvec, mtvec)(VAddrBits-1, 0) 858 ) 859 860 when (raiseExceptionIntr) { 861 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 862 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 863 864 when (delegS) { 865 scause := causeNO 866 sepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 867 mstatusNew.spp := priviledgeMode 868 mstatusNew.pie.s := mstatusOld.ie.s 869 mstatusNew.ie.s := false.B 870 priviledgeMode := ModeS 871 when (tvalWen) { stval := 0.U } 872 }.otherwise { 873 mcause := causeNO 874 mepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 875 mstatusNew.mpp := priviledgeMode 876 mstatusNew.pie.m := mstatusOld.ie.m 877 mstatusNew.ie.m := false.B 878 priviledgeMode := ModeM 879 when (tvalWen) { mtval := 0.U } 880 } 881 882 mstatus := mstatusNew.asUInt 883 } 884 885 XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc) 886 887 def readWithScala(addr: Int): UInt = mapping(addr)._1 888 889 val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U) 890 891 if (!env.FPGAPlatform) { 892 difftestIO.intrNO := RegNext(difftestIntrNO) 893 difftestIO.cause := RegNext(Mux(csrio.exception.valid, causeNO, 0.U)) 894 difftestIO.priviledgeMode := priviledgeMode 895 difftestIO.mstatus := mstatus 896 difftestIO.sstatus := mstatus & sstatusRmask 897 difftestIO.mepc := mepc 898 difftestIO.sepc := sepc 899 difftestIO.mtval:= mtval 900 difftestIO.stval:= stval 901 difftestIO.mtvec := mtvec 902 difftestIO.stvec := stvec 903 difftestIO.mcause := mcause 904 difftestIO.scause := scause 905 difftestIO.satp := satp 906 difftestIO.mip := mipReg 907 difftestIO.mie := mie 908 difftestIO.mscratch := mscratch 909 difftestIO.sscratch := sscratch 910 difftestIO.mideleg := mideleg 911 difftestIO.medeleg := medeleg 912 } 913} 914