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