1package xiangshan.backend.fu 2 3import chisel3._ 4import chisel3.ExcitingUtils.ConnectionType 5import chisel3.util._ 6import chisel3.util.experimental.BoringUtils 7import fpu.Fflags 8import noop.MMUIO 9import utils._ 10import xiangshan._ 11import xiangshan.backend._ 12import xiangshan.backend.fu.FunctionUnit._ 13import utils.XSDebug 14 15trait HasCSRConst { 16 // User Trap Setup 17 val Ustatus = 0x000 18 val Uie = 0x004 19 val Utvec = 0x005 20 21 // User Trap Handling 22 val Uscratch = 0x040 23 val Uepc = 0x041 24 val Ucause = 0x042 25 val Utval = 0x043 26 val Uip = 0x044 27 28 // User Floating-Point CSRs (not implemented) 29 val Fflags = 0x001 30 val Frm = 0x002 31 val Fcsr = 0x003 32 33 // User Counter/Timers 34 val Cycle = 0xC00 35 val Time = 0xC01 36 val Instret = 0xC02 37 38 // Supervisor Trap Setup 39 val Sstatus = 0x100 40 val Sedeleg = 0x102 41 val Sideleg = 0x103 42 val Sie = 0x104 43 val Stvec = 0x105 44 val Scounteren = 0x106 45 46 // Supervisor Trap Handling 47 val Sscratch = 0x140 48 val Sepc = 0x141 49 val Scause = 0x142 50 val Stval = 0x143 51 val Sip = 0x144 52 53 // Supervisor Protection and Translation 54 val Satp = 0x180 55 56 // Machine Information Registers 57 val Mvendorid = 0xF11 58 val Marchid = 0xF12 59 val Mimpid = 0xF13 60 val Mhartid = 0xF14 61 62 // Machine Trap Setup 63 val Mstatus = 0x300 64 val Misa = 0x301 65 val Medeleg = 0x302 66 val Mideleg = 0x303 67 val Mie = 0x304 68 val Mtvec = 0x305 69 val Mcounteren = 0x306 70 71 // Machine Trap Handling 72 val Mscratch = 0x340 73 val Mepc = 0x341 74 val Mcause = 0x342 75 val Mtval = 0x343 76 val Mip = 0x344 77 78 // Machine Memory Protection 79 // TBD 80 val Pmpcfg0 = 0x3A0 81 val Pmpcfg1 = 0x3A1 82 val Pmpcfg2 = 0x3A2 83 val Pmpcfg3 = 0x3A3 84 val PmpaddrBase = 0x3B0 85 86 // Machine Counter/Timers 87 // Currently, we uses perfcnt csr set instead of standard Machine Counter/Timers 88 // 0xB80 - 0x89F are also used as perfcnt csr 89 90 // Machine Counter Setup (not implemented) 91 // Debug/Trace Registers (shared with Debug Mode) (not implemented) 92 // Debug Mode Registers (not implemented) 93 94 def privEcall = 0x000.U 95 def privEbreak = 0x001.U 96 def privMret = 0x302.U 97 def privSret = 0x102.U 98 def privUret = 0x002.U 99 100 def ModeM = 0x3.U 101 def ModeH = 0x2.U 102 def ModeS = 0x1.U 103 def ModeU = 0x0.U 104 105 def IRQ_UEIP = 0 106 def IRQ_SEIP = 1 107 def IRQ_MEIP = 3 108 109 def IRQ_UTIP = 4 110 def IRQ_STIP = 5 111 def IRQ_MTIP = 7 112 113 def IRQ_USIP = 8 114 def IRQ_SSIP = 9 115 def IRQ_MSIP = 11 116 117 val IntPriority = Seq( 118 IRQ_MEIP, IRQ_MSIP, IRQ_MTIP, 119 IRQ_SEIP, IRQ_SSIP, IRQ_STIP, 120 IRQ_UEIP, IRQ_USIP, IRQ_UTIP 121 ) 122 123 def csrAccessPermissionCheck(addr: UInt, wen: Bool, mode: UInt): Bool = { 124 val readOnly = addr(11,10) === "b11".U 125 val lowestAccessPrivilegeLevel = addr(9,8) 126 mode >= lowestAccessPrivilegeLevel && !(wen && readOnly) 127 } 128} 129 130trait HasExceptionNO { 131 def instrAddrMisaligned = 0 132 def instrAccessFault = 1 133 def illegalInstr = 2 134 def breakPoint = 3 135 def loadAddrMisaligned = 4 136 def loadAccessFault = 5 137 def storeAddrMisaligned = 6 138 def storeAccessFault = 7 139 def ecallU = 8 140 def ecallS = 9 141 def ecallM = 11 142 def instrPageFault = 12 143 def loadPageFault = 13 144 def storePageFault = 15 145 146 val ExcPriority = Seq( 147 breakPoint, // TODO: different BP has different priority 148 instrPageFault, 149 instrAccessFault, 150 illegalInstr, 151 instrAddrMisaligned, 152 ecallM, ecallS, ecallU, 153 storePageFault, 154 loadPageFault, 155 storeAccessFault, 156 loadAccessFault, 157 storeAddrMisaligned, 158 loadAddrMisaligned 159 ) 160} 161 162class FpuCsrIO extends XSBundle { 163 val fflags = Output(new Fflags) 164 val isIllegal = Output(Bool()) 165 val dirty_fs = Output(Bool()) 166 val frm = Input(UInt(3.W)) 167} 168 169class CSRIO extends FunctionUnitIO { 170 val cfIn = Input(new CtrlFlow) 171 val redirect = Output(new Redirect) 172 val redirectValid = Output(Bool()) 173 val fpu_csr = Flipped(new FpuCsrIO) 174 val cfOut = Output(new CtrlFlow) 175 // from rob 176 val exception = Flipped(ValidIO(new MicroOp)) 177 // for exception check 178 val instrValid = Input(Bool()) 179 // for differential testing 180// val intrNO = Output(UInt(XLEN.W)) 181 val wenFix = Output(Bool()) 182} 183 184class CSR extends FunctionUnit(csrCfg) with HasCSRConst{ 185 val io = IO(new CSRIO) 186 187 io.cfOut := io.cfIn 188 189 val (valid, src1, src2, func) = (io.in.valid, io.in.bits.src1, io.in.bits.src2, io.in.bits.func) 190 def access(valid: Bool, src1: UInt, src2: UInt, func: UInt): UInt = { 191 this.valid := valid 192 this.src1 := src1 193 this.src2 := src2 194 this.func := func 195 io.out.bits 196 } 197 198 // CSR define 199 200 class Priv extends Bundle { 201 val m = Output(Bool()) 202 val h = Output(Bool()) 203 val s = Output(Bool()) 204 val u = Output(Bool()) 205 } 206 207 val csrNotImplemented = RegInit(UInt(XLEN.W), 0.U) 208 209 class MstatusStruct extends Bundle { 210 val sd = Output(UInt(1.W)) 211 212 val pad1 = if (XLEN == 64) Output(UInt(27.W)) else null 213 val sxl = if (XLEN == 64) Output(UInt(2.W)) else null 214 val uxl = if (XLEN == 64) Output(UInt(2.W)) else null 215 val pad0 = if (XLEN == 64) Output(UInt(9.W)) else Output(UInt(8.W)) 216 217 val tsr = Output(UInt(1.W)) 218 val tw = Output(UInt(1.W)) 219 val tvm = Output(UInt(1.W)) 220 val mxr = Output(UInt(1.W)) 221 val sum = Output(UInt(1.W)) 222 val mprv = Output(UInt(1.W)) 223 val xs = Output(UInt(2.W)) 224 val fs = Output(UInt(2.W)) 225 val mpp = Output(UInt(2.W)) 226 val hpp = Output(UInt(2.W)) 227 val spp = Output(UInt(1.W)) 228 val pie = new Priv 229 val ie = new Priv 230 assert(this.getWidth == XLEN) 231 } 232 233 class SatpStruct extends Bundle { 234 val mode = UInt(4.W) 235 val asid = UInt(16.W) 236 val ppn = UInt(44.W) 237 } 238 239 class Interrupt extends Bundle { 240 val e = new Priv 241 val t = new Priv 242 val s = new Priv 243 } 244 245 // Machine-Level CSRs 246 247 val mtvec = RegInit(UInt(XLEN.W), 0.U) 248 val mcounteren = RegInit(UInt(XLEN.W), 0.U) 249 val mcause = RegInit(UInt(XLEN.W), 0.U) 250 val mtval = RegInit(UInt(XLEN.W), 0.U) 251 val mepc = Reg(UInt(XLEN.W)) 252 253 val mie = RegInit(0.U(XLEN.W)) 254 val mipWire = WireInit(0.U.asTypeOf(new Interrupt)) 255 val mipReg = RegInit(0.U.asTypeOf(new Interrupt).asUInt) 256 val mipFixMask = GenMask(9) | GenMask(5) | GenMask(1) 257 val mip = (mipWire.asUInt | mipReg).asTypeOf(new Interrupt) 258 259 def getMisaMxl(mxl: Int): UInt = {mxl.U << (XLEN-2)} 260 def getMisaExt(ext: Char): UInt = {1.U << (ext.toInt - 'a'.toInt)} 261 var extList = List('a', 's', 'i', 'u') 262 if(HasMExtension){ extList = extList :+ 'm'} 263 if(HasCExtension){ extList = extList :+ 'c'} 264 if(HasFPU){ extList = extList ++ List('f', 'd')} 265 val misaInitVal = getMisaMxl(2) | extList.foldLeft(0.U)((sum, i) => sum | getMisaExt(i)) //"h8000000000141105".U 266 val misa = RegInit(UInt(XLEN.W), misaInitVal) 267 // MXL = 2 | 0 | EXT = b 00 0000 0100 0001 0001 0000 0101 268 // (XLEN-1, XLEN-2) | |(25, 0) ZY XWVU TSRQ PONM LKJI HGFE DCBA 269 270 val mvendorid = RegInit(UInt(XLEN.W), 0.U) // this is a non-commercial implementation 271 val marchid = RegInit(UInt(XLEN.W), 0.U) // return 0 to indicate the field is not implemented 272 val mimpid = RegInit(UInt(XLEN.W), 0.U) // provides a unique encoding of the version of the processor implementation 273 val mhartid = RegInit(UInt(XLEN.W), 0.U) // the hardware thread running the code 274 val mstatus = RegInit(UInt(XLEN.W), "h00001800".U) 275 // val mstatus = RegInit(UInt(XLEN.W), "h8000c0100".U) 276 // mstatus Value Table 277 // | sd | 278 // | pad1 | 279 // | sxl | hardlinked to 10, use 00 to pass xv6 test 280 // | uxl | hardlinked to 00 281 // | pad0 | 282 // | tsr | 283 // | tw | 284 // | tvm | 285 // | mxr | 286 // | sum | 287 // | mprv | 288 // | xs | 00 | 289 // | fs | 00 | 290 // | mpp | 00 | 291 // | hpp | 00 | 292 // | spp | 0 | 293 // | pie | 0000 | pie.h is used as UBE 294 // | ie | 0000 | uie hardlinked to 0, as N ext is not implemented 295 val mstatusStruct = mstatus.asTypeOf(new MstatusStruct) 296 def mstatusUpdateSideEffect(mstatus: UInt): UInt = { 297 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 298 val mstatusNew = Cat(mstatusOld.xs === "b11".U || mstatusOld.fs === "b11".U, mstatus(XLEN-2, 0)) 299 mstatusNew 300 } 301 302 val mstatusMask = ~ZeroExt(( 303 GenMask(XLEN-2, 38) | GenMask(31, 23) | GenMask(10, 9) | GenMask(2) | 304 GenMask(37) | // MBE 305 GenMask(36) | // SBE 306 GenMask(6) // UBE 307 ), 64) 308 309 val medeleg = RegInit(UInt(XLEN.W), 0.U) 310 val mideleg = RegInit(UInt(XLEN.W), 0.U) 311 val mscratch = RegInit(UInt(XLEN.W), 0.U) 312 313 val pmpcfg0 = RegInit(UInt(XLEN.W), 0.U) 314 val pmpcfg1 = RegInit(UInt(XLEN.W), 0.U) 315 val pmpcfg2 = RegInit(UInt(XLEN.W), 0.U) 316 val pmpcfg3 = RegInit(UInt(XLEN.W), 0.U) 317 val pmpaddr0 = RegInit(UInt(XLEN.W), 0.U) 318 val pmpaddr1 = RegInit(UInt(XLEN.W), 0.U) 319 val pmpaddr2 = RegInit(UInt(XLEN.W), 0.U) 320 val pmpaddr3 = RegInit(UInt(XLEN.W), 0.U) 321 322 // Superviser-Level CSRs 323 324 // val sstatus = RegInit(UInt(XLEN.W), "h00000000".U) 325 val sstatusWmask = "hc6122".U 326 // Sstatus Write Mask 327 // ------------------------------------------------------- 328 // 19 9 5 2 329 // 0 1100 0000 0001 0010 0010 330 // 0 c 0 1 2 2 331 // ------------------------------------------------------- 332 val sstatusRmask = sstatusWmask | "h8000000300018000".U 333 // Sstatus Read Mask = (SSTATUS_WMASK | (0xf << 13) | (1ull << 63) | (3ull << 32)) 334 val stvec = RegInit(UInt(XLEN.W), 0.U) 335 // val sie = RegInit(0.U(XLEN.W)) 336 val sieMask = "h222".U & mideleg 337 val sipMask = "h222".U & mideleg 338 val satp = RegInit(0.U(XLEN.W)) 339 // val satp = RegInit(UInt(XLEN.W), "h8000000000087fbe".U) // only use for tlb naive debug 340 val satpMask = "h80000fffffffffff".U // disable asid, mode can only be 8 / 0 341 // val satp = RegInit(UInt(XLEN.W), 0.U) 342 val sepc = RegInit(UInt(XLEN.W), 0.U) 343 val scause = RegInit(UInt(XLEN.W), 0.U) 344 val stval = Reg(UInt(XLEN.W)) 345 val sscratch = RegInit(UInt(XLEN.W), 0.U) 346 val scounteren = RegInit(UInt(XLEN.W), 0.U) 347 348 val tlbBundle = Wire(new TlbCsrBundle) 349 // val sfence = Wire(new SfenceBundle) 350 tlbBundle.satp := satp.asTypeOf(new SatpStruct) 351 // sfence := 0.U.asTypeOf(new SfenceBundle) 352 BoringUtils.addSource(tlbBundle, "TLBCSRIO") 353 // BoringUtils.addSource(sfence, "SfenceBundle") // FIXME: move to MOU 354 355 // User-Level CSRs 356 val uepc = Reg(UInt(XLEN.W)) 357 358 // fcsr 359 class FcsrStruct extends Bundle{ 360 val reserved = UInt((XLEN-3-5).W) 361 val frm = UInt(3.W) 362 val fflags = UInt(5.W) 363 assert(this.getWidth == XLEN) 364 } 365 val fcsr = RegInit(0.U(XLEN.W)) 366 // set mstatus->sd and mstatus->fs when true 367 val csrw_dirty_fp_state = WireInit(false.B) 368 369 def frm_wfn(wdata: UInt): UInt = { 370 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 371 csrw_dirty_fp_state := true.B 372 fcsrOld.frm := wdata(2,0) 373 fcsrOld.asUInt() 374 } 375 def frm_rfn(rdata: UInt): UInt = rdata(7,5) 376 377 def fflags_wfn(wdata: UInt): UInt = { 378 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 379 csrw_dirty_fp_state := true.B 380 fcsrOld.fflags := wdata(4,0) 381 fcsrOld.asUInt() 382 } 383 def fflags_rfn(rdata:UInt): UInt = rdata(4,0) 384 385 def fcsr_wfn(wdata: UInt): UInt = { 386 val fcsrOld = WireInit(fcsr.asTypeOf(new FcsrStruct)) 387 csrw_dirty_fp_state := true.B 388 Cat(fcsrOld.reserved, wdata.asTypeOf(fcsrOld).frm, wdata.asTypeOf(fcsrOld).fflags) 389 } 390 391 val fcsrMapping = Map( 392 MaskedRegMap(Fflags, fcsr, wfn = fflags_wfn, rfn = fflags_rfn), 393 MaskedRegMap(Frm, fcsr, wfn = frm_wfn, rfn = frm_rfn), 394 MaskedRegMap(Fcsr, fcsr, wfn = fcsr_wfn) 395 ) 396 397 // Atom LR/SC Control Bits 398// val setLr = WireInit(Bool(), false.B) 399// val setLrVal = WireInit(Bool(), false.B) 400// val setLrAddr = WireInit(UInt(AddrBits.W), DontCare) //TODO : need check 401// val lr = RegInit(Bool(), false.B) 402// val lrAddr = RegInit(UInt(AddrBits.W), 0.U) 403// BoringUtils.addSink(setLr, "set_lr") 404// BoringUtils.addSink(setLrVal, "set_lr_val") 405// BoringUtils.addSink(setLrAddr, "set_lr_addr") 406// BoringUtils.addSource(lr, "lr") 407// BoringUtils.addSource(lrAddr, "lr_addr") 408// 409// when(setLr){ 410// lr := setLrVal 411// lrAddr := setLrAddr 412// } 413 414 // Hart Priviledge Mode 415 val priviledgeMode = RegInit(UInt(2.W), ModeM) 416 417 // perfcnt 418 val hasPerfCnt = !env.FPGAPlatform 419 val nrPerfCnts = if (hasPerfCnt) 0x80 else 0x3 420 val perfCnts = List.fill(nrPerfCnts)(RegInit(0.U(XLEN.W))) 421 val perfCntsLoMapping = (0 until nrPerfCnts).map(i => MaskedRegMap(0xb00 + i, perfCnts(i))) 422 val perfCntsHiMapping = (0 until nrPerfCnts).map(i => MaskedRegMap(0xb80 + i, perfCnts(i)(63, 32))) 423 424 // CSR reg map 425 val mapping = Map( 426 427 // User Trap Setup 428 // MaskedRegMap(Ustatus, ustatus), 429 // MaskedRegMap(Uie, uie, 0.U, MaskedRegMap.Unwritable), 430 // MaskedRegMap(Utvec, utvec), 431 432 // User Trap Handling 433 // MaskedRegMap(Uscratch, uscratch), 434 // MaskedRegMap(Uepc, uepc), 435 // MaskedRegMap(Ucause, ucause), 436 // MaskedRegMap(Utval, utval), 437 // MaskedRegMap(Uip, uip), 438 439 // User Counter/Timers 440 // MaskedRegMap(Cycle, cycle), 441 // MaskedRegMap(Time, time), 442 // MaskedRegMap(Instret, instret), 443 444 // Supervisor Trap Setup 445 MaskedRegMap(Sstatus, mstatus, sstatusWmask, mstatusUpdateSideEffect, sstatusRmask), 446 447 // MaskedRegMap(Sedeleg, Sedeleg), 448 // MaskedRegMap(Sideleg, Sideleg), 449 MaskedRegMap(Sie, mie, sieMask, MaskedRegMap.NoSideEffect, sieMask), 450 MaskedRegMap(Stvec, stvec), 451 MaskedRegMap(Scounteren, scounteren), 452 453 // Supervisor Trap Handling 454 MaskedRegMap(Sscratch, sscratch), 455 MaskedRegMap(Sepc, sepc), 456 MaskedRegMap(Scause, scause), 457 MaskedRegMap(Stval, stval), 458 MaskedRegMap(Sip, mip.asUInt, sipMask, MaskedRegMap.Unwritable, sipMask), 459 460 // Supervisor Protection and Translation 461 MaskedRegMap(Satp, satp, satpMask, MaskedRegMap.NoSideEffect, satpMask), 462 463 // Machine Information Registers 464 MaskedRegMap(Mvendorid, mvendorid, 0.U, MaskedRegMap.Unwritable), 465 MaskedRegMap(Marchid, marchid, 0.U, MaskedRegMap.Unwritable), 466 MaskedRegMap(Mimpid, mimpid, 0.U, MaskedRegMap.Unwritable), 467 MaskedRegMap(Mhartid, mhartid, 0.U, MaskedRegMap.Unwritable), 468 469 // Machine Trap Setup 470 // MaskedRegMap(Mstatus, mstatus, "hffffffffffffffee".U, (x=>{printf("mstatus write: %x time: %d\n", x, GTimer()); x})), 471 MaskedRegMap(Mstatus, mstatus, mstatusMask, mstatusUpdateSideEffect, mstatusMask), 472 MaskedRegMap(Misa, misa), // now MXL, EXT is not changeable 473 MaskedRegMap(Medeleg, medeleg, "hf3ff".U), 474 MaskedRegMap(Mideleg, mideleg, "h222".U), 475 MaskedRegMap(Mie, mie), 476 MaskedRegMap(Mtvec, mtvec), 477 MaskedRegMap(Mcounteren, mcounteren), 478 479 // Machine Trap Handling 480 MaskedRegMap(Mscratch, mscratch), 481 MaskedRegMap(Mepc, mepc), 482 MaskedRegMap(Mcause, mcause), 483 MaskedRegMap(Mtval, mtval), 484 MaskedRegMap(Mip, mip.asUInt, 0.U, MaskedRegMap.Unwritable), 485 486 // Machine Memory Protection 487 MaskedRegMap(Pmpcfg0, pmpcfg0), 488 MaskedRegMap(Pmpcfg1, pmpcfg1), 489 MaskedRegMap(Pmpcfg2, pmpcfg2), 490 MaskedRegMap(Pmpcfg3, pmpcfg3), 491 MaskedRegMap(PmpaddrBase + 0, pmpaddr0), 492 MaskedRegMap(PmpaddrBase + 1, pmpaddr1), 493 MaskedRegMap(PmpaddrBase + 2, pmpaddr2), 494 MaskedRegMap(PmpaddrBase + 3, pmpaddr3) 495 496 ) ++ 497 perfCntsLoMapping ++ (if (XLEN == 32) perfCntsHiMapping else Nil) ++ 498 (if(HasFPU) fcsrMapping else Nil) 499 500 val addr = src2(11, 0) 501 val rdata = Wire(UInt(XLEN.W)) 502 val csri = ZeroExt(io.cfIn.instr(19,15), XLEN) //unsigned imm for csri. [TODO] 503 val wdata = LookupTree(func, List( 504 CSROpType.wrt -> src1, 505 CSROpType.set -> (rdata | src1), 506 CSROpType.clr -> (rdata & (~src1).asUInt()), 507 CSROpType.wrti -> csri,//TODO: csri --> src2 508 CSROpType.seti -> (rdata | csri), 509 CSROpType.clri -> (rdata & (~csri).asUInt()) 510 )) 511 512 // satp wen check 513 val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 514 515 // general CSR wen check 516 val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode) 517 val permitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode) 518 // Writeable check is ingored. 519 // Currently, write to illegal csr addr will be ignored 520 MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata) 521 io.out.bits := rdata 522 523 // Fix Mip/Sip write 524 val fixMapping = Map( 525 MaskedRegMap(Mip, mipReg.asUInt, mipFixMask), 526 MaskedRegMap(Sip, mipReg.asUInt, sipMask, MaskedRegMap.NoSideEffect, sipMask) 527 ) 528 val rdataDummy = Wire(UInt(XLEN.W)) 529 MaskedRegMap.generate(fixMapping, addr, rdataDummy, wen, wdata) 530 531 when(io.fpu_csr.fflags.asUInt() =/= 0.U){ 532 fcsr := fflags_wfn(io.fpu_csr.fflags.asUInt()) 533 } 534 // set fs and sd in mstatus 535 when(csrw_dirty_fp_state || io.fpu_csr.dirty_fs){ 536 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 537 mstatusNew.fs := "b11".U 538 mstatusNew.sd := true.B 539 mstatus := mstatusNew.asUInt() 540 } 541 io.fpu_csr.frm := fcsr.asTypeOf(new FcsrStruct).frm 542 543 // CSR inst decode 544 val isEbreak = addr === privEbreak && func === CSROpType.jmp 545 val isEcall = addr === privEcall && func === CSROpType.jmp 546 val isMret = addr === privMret && func === CSROpType.jmp 547 val isSret = addr === privSret && func === CSROpType.jmp 548 val isUret = addr === privUret && func === CSROpType.jmp 549 550 XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", io.cfIn.pc, addr, rdata, wdata, func) 551 XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", io.cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode) 552 553 // Illegal priviledged operation list 554 val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool 555 556 // Illegal priviledged instruction check 557 val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr) 558 val isIllegalAccess = !permitted 559 val isIllegalPrivOp = illegalSModeSret 560 561 // def MMUPermissionCheck(ptev: Bool, pteu: Bool): Bool = ptev && !(priviledgeMode === ModeU && !pteu) && !(priviledgeMode === ModeS && pteu && mstatusStruct.sum.asBool) 562 // def MMUPermissionCheckLoad(ptev: Bool, pteu: Bool): Bool = ptev && !(priviledgeMode === ModeU && !pteu) && !(priviledgeMode === ModeS && pteu && mstatusStruct.sum.asBool) && (pter || (mstatusStruct.mxr && ptex)) 563 // imem 564 // val imemPtev = true.B 565 // val imemPteu = true.B 566 // val imemPtex = true.B 567 // val imemReq = true.B 568 // val imemPermissionCheckPassed = MMUPermissionCheck(imemPtev, imemPteu) 569 // val hasInstrPageFault = imemReq && !(imemPermissionCheckPassed && imemPtex) 570 // assert(!hasInstrPageFault) 571 572 // dmem 573 // val dmemPtev = true.B 574 // val dmemPteu = true.B 575 // val dmemReq = true.B 576 // val dmemPermissionCheckPassed = MMUPermissionCheck(dmemPtev, dmemPteu) 577 // val dmemIsStore = true.B 578 579 // val hasLoadPageFault = dmemReq && !dmemIsStore && !(dmemPermissionCheckPassed) 580 // val hasStorePageFault = dmemReq && dmemIsStore && !(dmemPermissionCheckPassed) 581 // assert(!hasLoadPageFault) 582 // assert(!hasStorePageFault) 583 584 //TODO: Havn't test if io.dmemMMU.priviledgeMode is correct yet 585 tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 586 tlbBundle.priv.sum := mstatusStruct.sum.asBool 587 tlbBundle.priv.imode := priviledgeMode 588 tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode) 589 590 val hasInstrPageFault = io.exception.bits.cf.exceptionVec(instrPageFault) && io.exception.valid 591 val hasLoadPageFault = io.exception.bits.cf.exceptionVec(loadPageFault) && io.exception.valid 592 val hasStorePageFault = io.exception.bits.cf.exceptionVec(storePageFault) && io.exception.valid 593 val hasStoreAddrMisaligned = io.exception.bits.cf.exceptionVec(storeAddrMisaligned) && io.exception.valid 594 val hasLoadAddrMisaligned = io.exception.bits.cf.exceptionVec(loadAddrMisaligned) && io.exception.valid 595 596 // mtval write logic 597 val memExceptionAddr = WireInit(0.U(VAddrBits.W)) 598 ExcitingUtils.addSource(io.exception.bits.lsroqIdx, "EXECPTION_LSROQIDX") 599 ExcitingUtils.addSink(memExceptionAddr, "EXECPTION_VADDR") 600 when(hasInstrPageFault || hasLoadPageFault || hasStorePageFault){ 601 val tval = Mux( 602 hasInstrPageFault, 603 Mux( 604 io.exception.bits.cf.crossPageIPFFix, 605 SignExt(io.exception.bits.cf.pc + 2.U, XLEN), 606 SignExt(io.exception.bits.cf.pc, XLEN) 607 ), 608 SignExt(memExceptionAddr, XLEN) 609 ) 610 when(priviledgeMode === ModeM){ 611 mtval := tval 612 }.otherwise{ 613 stval := tval 614 } 615 } 616 617 when(hasLoadAddrMisaligned || hasStoreAddrMisaligned) 618 { 619 mtval := SignExt(memExceptionAddr, XLEN) 620 } 621 622 // Exception and Intr 623 624 // interrupts 625 626 val ideleg = (mideleg & mip.asUInt) 627 def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS), 628 ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM)) 629 630 val intrVecEnable = Wire(Vec(12, Bool())) 631 intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)} 632 val intrVec = mie(11,0) & mip.asUInt & intrVecEnable.asUInt 633 val intrBitSet = intrVec.orR() 634 ExcitingUtils.addSource(intrBitSet, "intrBitSetIDU") 635 val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 636 val raiseIntr = intrBitSet && io.exception.valid 637 XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", io.exception.bits.cf.pc, intrNO) 638 639 val mtip = WireInit(false.B) 640 val meip = WireInit(false.B) 641 ExcitingUtils.addSink(mtip, "mtip") 642 ExcitingUtils.addSink(meip, "meip") 643 mipWire.t.m := mtip 644 mipWire.e.m := meip 645 646 // exceptions 647 val csrExceptionVec = Wire(Vec(16, Bool())) 648 csrExceptionVec.map(_ := false.B) 649 csrExceptionVec(breakPoint) := io.in.valid && isEbreak 650 csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall 651 csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall 652 csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall 653 // Trigger an illegal instr exception when: 654 // * unimplemented csr is being read/written 655 // * csr access is illegal 656 csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen 657 csrExceptionVec(loadPageFault) := hasLoadPageFault 658 csrExceptionVec(storePageFault) := hasStorePageFault 659 val iduExceptionVec = io.cfIn.exceptionVec 660 val exceptionVec = csrExceptionVec.asUInt() | iduExceptionVec.asUInt() 661 io.cfOut.exceptionVec.zipWithIndex.map{case (e, i) => e := exceptionVec(i) } 662 io.wenFix := DontCare 663 664 val raiseExceptionVec = io.exception.bits.cf.exceptionVec.asUInt() 665 val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) 666 val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO) 667 val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U) 668 ExcitingUtils.addSource(difftestIntrNO, "difftestIntrNOfromCSR") 669 670 val raiseExceptionIntr = io.exception.valid 671 val retTarget = Wire(UInt(VAddrBits.W)) 672 val trapTarget = Wire(UInt(VAddrBits.W)) 673 ExcitingUtils.addSource(trapTarget, "trapTarget") 674 val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed 675 io.redirect := DontCare 676 io.redirectValid := (valid && func === CSROpType.jmp && !isEcall) || resetSatp 677 //TODO: use pred pc instead pc+4 678 io.redirect.target := Mux(resetSatp, io.cfIn.pc+4.U, retTarget) 679 680 XSDebug(io.redirectValid, "redirect to %x, pc=%x\n", io.redirect.target, io.cfIn.pc) 681 682 XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n",io.exception.bits.cf.pc, intrNO, io.exception.bits.cf.intrVec.asUInt, exceptionNO, raiseExceptionVec.asUInt) 683 XSDebug(raiseExceptionIntr, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", io.exception.bits.cf.pc, mstatus, mideleg, medeleg, priviledgeMode) 684 685 // Branch control 686 687 val deleg = Mux(raiseIntr, mideleg , medeleg) 688 // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM); 689 val delegS = (deleg(causeNO(3,0))) && (priviledgeMode < ModeM) 690 val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check 691 692 trapTarget := Mux(delegS, stvec, mtvec)(VAddrBits-1, 0) 693 retTarget := DontCare 694 // val illegalEret = TODO 695 696 when (valid && isMret) { 697 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 698 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 699 mstatusNew.ie.m := mstatusOld.pie.m 700 priviledgeMode := mstatusOld.mpp 701 mstatusNew.pie.m := true.B 702 mstatusNew.mpp := ModeU 703 mstatusNew.mprv := 0.U 704 mstatus := mstatusNew.asUInt 705// lr := false.B 706 retTarget := mepc(VAddrBits-1, 0) 707 } 708 709 when (valid && isSret && !illegalSModeSret) { 710 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 711 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 712 mstatusNew.ie.s := mstatusOld.pie.s 713 priviledgeMode := Cat(0.U(1.W), mstatusOld.spp) 714 mstatusNew.pie.s := true.B 715 mstatusNew.spp := ModeU 716 mstatus := mstatusNew.asUInt 717 mstatusNew.mprv := 0.U 718 // lr := false.B 719 retTarget := sepc(VAddrBits-1, 0) 720 } 721 722 when (valid && isUret) { 723 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 724 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 725 // mstatusNew.mpp.m := ModeU //TODO: add mode U 726 mstatusNew.ie.u := mstatusOld.pie.u 727 priviledgeMode := ModeU 728 mstatusNew.pie.u := true.B 729 mstatus := mstatusNew.asUInt 730 retTarget := uepc(VAddrBits-1, 0) 731 } 732 733 when (raiseExceptionIntr) { 734 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 735 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 736 737 when (delegS) { 738 scause := causeNO 739 sepc := SignExt(io.exception.bits.cf.pc, XLEN) 740 mstatusNew.spp := priviledgeMode 741 mstatusNew.pie.s := mstatusOld.ie.s 742 mstatusNew.ie.s := false.B 743 priviledgeMode := ModeS 744 when(tvalWen){stval := 0.U} 745 // trapTarget := stvec(VAddrBits-1. 0) 746 }.otherwise { 747 mcause := causeNO 748 mepc := SignExt(io.exception.bits.cf.pc, XLEN) 749 mstatusNew.mpp := priviledgeMode 750 mstatusNew.pie.m := mstatusOld.ie.m 751 mstatusNew.ie.m := false.B 752 priviledgeMode := ModeM 753 when(tvalWen){mtval := 0.U} 754 // trapTarget := mtvec(VAddrBits-1. 0) 755 } 756 757 mstatus := mstatusNew.asUInt 758 } 759 760 io.in.ready := true.B 761 io.out.valid := valid 762 763 764 XSDebug(io.redirectValid, "Rediret %x raiseExcepIntr:%d isSret:%d retTarget:%x sepc:%x delegs:%d deleg:%x cfInpc:%x valid:%d instrValid:%x \n", 765 io.redirect.target, raiseExceptionIntr, isSret, retTarget, sepc, delegS, deleg, io.cfIn.pc, valid, io.instrValid) 766 XSDebug(raiseExceptionIntr && delegS, "Red(%d, %x) raiseExcepIntr:%d isSret:%d retTarget:%x sepc:%x delegs:%d deleg:%x cfInpc:%x valid:%d instrValid:%x \n", 767 io.redirectValid, io.redirect.target, raiseExceptionIntr, isSret, retTarget, sepc, delegS, deleg, io.cfIn.pc, valid, io.instrValid) 768 XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", io.cfIn.pc) 769 770 771 // perfcnt 772 773 val perfCntList = Map( 774// "Mcycle" -> (0xb00, "perfCntCondMcycle" ), 775// "Minstret" -> (0xb02, "perfCntCondMinstret" ), 776 "MbpInstr" -> (0xb03, "perfCntCondMbpInstr" ), 777 "MbpRight" -> (0xb04, "perfCntCondMbpRight" ), 778 "MbpWrong" -> (0xb05, "perfCntCondMbpWrong" ), 779 "MbpBRight" -> (0xb06, "perfCntCondMbpBRight" ), 780 "MbpBWrong" -> (0xb07, "perfCntCondMbpBWrong" ), 781 "MbpJRight" -> (0xb08, "perfCntCondMbpJRight" ), 782 "MbpJWrong" -> (0xb09, "perfCntCondMbpJWrong" ), 783 "MbpIRight" -> (0xb0a, "perfCntCondMbpIRight" ), 784 "MbpIWrong" -> (0xb0b, "perfCntCondMbpIWrong" ), 785 "MbpRRight" -> (0xb0c, "perfCntCondMbpRRight" ), 786 "MbpRWrong" -> (0xb0d, "perfCntCondMbpRWrong" ), 787 "DpqReplay" -> (0xb0e, "perfCntCondDpqReplay" ), 788 "RoqWalk" -> (0xb0f, "perfCntCondRoqWalk" ), 789 "RoqWaitInt" -> (0xb10, "perfCntCondRoqWaitInt" ), 790 "RoqWaitFp" -> (0xb11, "perfCntCondRoqWaitFp" ), 791 "RoqWaitLoad" -> (0xb12, "perfCntCondRoqWaitLoad" ), 792 "RoqWaitStore"-> (0xb13, "perfCntCondRoqWaitStore"), 793 "Dp1Empty" -> (0xb14, "perfCntCondDp1Empty" ), 794 "DTlbReqCnt0" -> (0xb15, "perfCntDtlbReqCnt0" ), 795 "DTlbReqCnt1" -> (0xb16, "perfCntDtlbReqCnt1" ), 796 "DTlbReqCnt2" -> (0xb17, "perfCntDtlbReqCnt2" ), 797 "DTlbReqCnt3" -> (0xb18, "perfCntDtlbReqCnt3" ), 798 "DTlbMissCnt0"-> (0xb19, "perfCntDtlbMissCnt0" ), 799 "DTlbMissCnt1"-> (0xb20, "perfCntDtlbMissCnt1" ), 800 "DTlbMissCnt2"-> (0xb21, "perfCntDtlbMissCnt2" ), 801 "DTlbMissCnt3"-> (0xb22, "perfCntDtlbMissCnt3" ), 802 "ITlbReqCnt0" -> (0xb23, "perfCntItlbReqCnt0" ), 803 "ITlbMissCnt0"-> (0xb24, "perfCntItlbMissCnt0" ), 804 "PtwReqCnt" -> (0xb25, "perfCntPtwReqCnt" ), 805 "PtwCycleCnt" -> (0xb26, "perfCntPtwCycleCnt" ), 806 "PtwL2TlbHit" -> (0xb27, "perfCntPtwL2TlbHit" ) 807// "Custom1" -> (0xb1b, "Custom1" ), 808// "Custom2" -> (0xb1c, "Custom2" ), 809// "Custom3" -> (0xb1d, "Custom3" ), 810// "Custom4" -> (0xb1e, "Custom4" ), 811// "Custom5" -> (0xb1f, "Custom5" ), 812// "Custom6" -> (0xb20, "Custom6" ), 813// "Custom7" -> (0xb21, "Custom7" ), 814// "Custom8" -> (0xb22, "Custom8" ), 815// "Ml2cacheHit" -> (0xb23, "perfCntCondMl2cacheHit") 816 ) 817 val perfCntCond = List.fill(0x80)(WireInit(false.B)) 818 (perfCnts zip perfCntCond).map { case (c, e) => when (e) { c := c + 1.U } } 819 820// ExcitingUtils.addSource(WireInit(true.B), "perfCntCondMcycle", ConnectionType.Perf) 821 perfCntList.foreach { 822 case (_, (address, boringId)) => 823 if(hasPerfCnt){ 824 ExcitingUtils.addSink(perfCntCond(address & 0x7f), boringId, ConnectionType.Perf) 825 } 826// if (!hasPerfCnt) { 827// // do not enable perfcnts except for Mcycle and Minstret 828// if (address != perfCntList("Mcycle")._1 && address != perfCntList("Minstret")._1) { 829// perfCntCond(address & 0x7f) := false.B 830// } 831// } 832 } 833 834 val xstrap = WireInit(false.B) 835 if(!env.FPGAPlatform && EnableBPU){ 836 ExcitingUtils.addSink(xstrap, "XSTRAP", ConnectionType.Debug) 837 } 838 def readWithScala(addr: Int): UInt = mapping(addr)._1 839 840 if (!env.FPGAPlatform) { 841 842 // display all perfcnt when nooptrap is executed 843 when (xstrap) { 844 printf("======== PerfCnt =========\n") 845 perfCntList.toSeq.sortBy(_._2._1).foreach { case (str, (address, boringId)) => 846 printf("%d <- " + str + "\n", readWithScala(address)) 847 } 848 } 849 850 // for differential testing 851// BoringUtils.addSource(RegNext(priviledgeMode), "difftestMode") 852// BoringUtils.addSource(RegNext(mstatus), "difftestMstatus") 853// BoringUtils.addSource(RegNext(mstatus & sstatusRmask), "difftestSstatus") 854// BoringUtils.addSource(RegNext(mepc), "difftestMepc") 855// BoringUtils.addSource(RegNext(sepc), "difftestSepc") 856// BoringUtils.addSource(RegNext(mcause), "difftestMcause") 857// BoringUtils.addSource(RegNext(scause), "difftestScause") 858 BoringUtils.addSource(priviledgeMode, "difftestMode") 859 BoringUtils.addSource(mstatus, "difftestMstatus") 860 BoringUtils.addSource(mstatus & sstatusRmask, "difftestSstatus") 861 BoringUtils.addSource(mepc, "difftestMepc") 862 BoringUtils.addSource(sepc, "difftestSepc") 863 BoringUtils.addSource(mcause, "difftestMcause") 864 BoringUtils.addSource(scause, "difftestScause") 865 } else { 866// BoringUtils.addSource(readWithScala(perfCntList("Minstret")._1), "ilaInstrCnt") 867 } 868} 869