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 // TODO: mechanism should be implemented later 596 // val MhpmcounterStart = Mhpmcounter3 597 // val MhpmeventStart = Mhpmevent3 598 // for (i <- 0 until nrPerfCnts) { 599 // perfCntMapping += MaskedRegMap(MhpmcounterStart + i, perfCnts(i)) 600 // perfCntMapping += MaskedRegMap(MhpmeventStart + i, perfEvents(i)) 601 // } 602 603 val mapping = basicPrivMapping ++ 604 perfCntMapping ++ 605 pmpMapping ++ 606 emuPerfCntsLoMapping ++ 607 (if (XLEN == 32) emuPerfCntsHiMapping else Nil) ++ 608 (if (HasFPU) fcsrMapping else Nil) 609 610 val addr = src2(11, 0) 611 val csri = ZeroExt(src2(16, 12), XLEN) 612 val rdata = Wire(UInt(XLEN.W)) 613 val wdata = LookupTree(func, List( 614 CSROpType.wrt -> src1, 615 CSROpType.set -> (rdata | src1), 616 CSROpType.clr -> (rdata & (~src1).asUInt()), 617 CSROpType.wrti -> csri, 618 CSROpType.seti -> (rdata | csri), 619 CSROpType.clri -> (rdata & (~csri).asUInt()) 620 )) 621 622 val addrInPerfCnt = (addr >= Mcycle.U) && (addr <= Mhpmcounter31.U) 623 csrio.isPerfCnt := addrInPerfCnt 624 625 // satp wen check 626 val satpLegalMode = (wdata.asTypeOf(new SatpStruct).mode===0.U) || (wdata.asTypeOf(new SatpStruct).mode===8.U) 627 628 // general CSR wen check 629 val wen = valid && func =/= CSROpType.jmp && (addr=/=Satp.U || satpLegalMode) 630 val modePermitted = csrAccessPermissionCheck(addr, false.B, priviledgeMode) 631 val perfcntPermitted = perfcntPermissionCheck(addr, priviledgeMode, mcounteren, scounteren) 632 val permitted = Mux(addrInPerfCnt, perfcntPermitted, modePermitted) 633 // Writeable check is ingored. 634 // Currently, write to illegal csr addr will be ignored 635 MaskedRegMap.generate(mapping, addr, rdata, wen && permitted, wdata) 636 io.out.bits.data := rdata 637 io.out.bits.uop := io.in.bits.uop 638 io.out.bits.uop.cf := cfOut 639 io.out.bits.uop.ctrl.flushPipe := flushPipe 640 641 // Fix Mip/Sip write 642 val fixMapping = Map( 643 MaskedRegMap(Mip, mipReg.asUInt, mipFixMask), 644 MaskedRegMap(Sip, mipReg.asUInt, sipMask, MaskedRegMap.NoSideEffect, sipMask) 645 ) 646 val rdataDummy = Wire(UInt(XLEN.W)) 647 MaskedRegMap.generate(fixMapping, addr, rdataDummy, wen, wdata) 648 649 when (csrio.fpu.fflags.valid) { 650 fcsr := fflags_wfn(update = true)(csrio.fpu.fflags.bits) 651 } 652 // set fs and sd in mstatus 653 when (csrw_dirty_fp_state || csrio.fpu.dirty_fs) { 654 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 655 mstatusNew.fs := "b11".U 656 mstatusNew.sd := true.B 657 mstatus := mstatusNew.asUInt() 658 } 659 csrio.fpu.frm := fcsr.asTypeOf(new FcsrStruct).frm 660 661 // CSR inst decode 662 val isEbreak = addr === privEbreak && func === CSROpType.jmp 663 val isEcall = addr === privEcall && func === CSROpType.jmp 664 val isMret = addr === privMret && func === CSROpType.jmp 665 val isSret = addr === privSret && func === CSROpType.jmp 666 val isUret = addr === privUret && func === CSROpType.jmp 667 668 XSDebug(wen, "csr write: pc %x addr %x rdata %x wdata %x func %x\n", cfIn.pc, addr, rdata, wdata, func) 669 XSDebug(wen, "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", cfIn.pc, mstatus, mideleg , medeleg, priviledgeMode) 670 671 // Illegal priviledged operation list 672 val illegalSModeSret = valid && isSret && priviledgeMode === ModeS && mstatusStruct.tsr.asBool 673 674 // Illegal priviledged instruction check 675 val isIllegalAddr = MaskedRegMap.isIllegalAddr(mapping, addr) 676 val isIllegalAccess = !permitted 677 val isIllegalPrivOp = illegalSModeSret 678 679 // def MMUPermissionCheck(ptev: Bool, pteu: Bool): Bool = ptev && !(priviledgeMode === ModeU && !pteu) && !(priviledgeMode === ModeS && pteu && mstatusStruct.sum.asBool) 680 // def MMUPermissionCheckLoad(ptev: Bool, pteu: Bool): Bool = ptev && !(priviledgeMode === ModeU && !pteu) && !(priviledgeMode === ModeS && pteu && mstatusStruct.sum.asBool) && (pter || (mstatusStruct.mxr && ptex)) 681 // imem 682 // val imemPtev = true.B 683 // val imemPteu = true.B 684 // val imemPtex = true.B 685 // val imemReq = true.B 686 // val imemPermissionCheckPassed = MMUPermissionCheck(imemPtev, imemPteu) 687 // val hasInstrPageFault = imemReq && !(imemPermissionCheckPassed && imemPtex) 688 // assert(!hasInstrPageFault) 689 690 // dmem 691 // val dmemPtev = true.B 692 // val dmemPteu = true.B 693 // val dmemReq = true.B 694 // val dmemPermissionCheckPassed = MMUPermissionCheck(dmemPtev, dmemPteu) 695 // val dmemIsStore = true.B 696 697 // val hasLoadPageFault = dmemReq && !dmemIsStore && !(dmemPermissionCheckPassed) 698 // val hasStorePageFault = dmemReq && dmemIsStore && !(dmemPermissionCheckPassed) 699 // assert(!hasLoadPageFault) 700 // assert(!hasStorePageFault) 701 702 //TODO: Havn't test if io.dmemMMU.priviledgeMode is correct yet 703 tlbBundle.priv.mxr := mstatusStruct.mxr.asBool 704 tlbBundle.priv.sum := mstatusStruct.sum.asBool 705 tlbBundle.priv.imode := priviledgeMode 706 tlbBundle.priv.dmode := Mux(mstatusStruct.mprv.asBool, mstatusStruct.mpp, priviledgeMode) 707 708 // Branch control 709 val retTarget = Wire(UInt(VAddrBits.W)) 710 val resetSatp = addr === Satp.U && wen // write to satp will cause the pipeline be flushed 711 flushPipe := resetSatp || (valid && func === CSROpType.jmp && !isEcall) 712 713 retTarget := DontCare 714 // val illegalEret = TODO 715 716 when (valid && isMret) { 717 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 718 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 719 mstatusNew.ie.m := mstatusOld.pie.m 720 priviledgeMode := mstatusOld.mpp 721 mstatusNew.pie.m := true.B 722 mstatusNew.mpp := ModeU 723 mstatusNew.mprv := 0.U 724 mstatus := mstatusNew.asUInt 725 // lr := false.B 726 retTarget := mepc(VAddrBits-1, 0) 727 } 728 729 when (valid && isSret && !illegalSModeSret) { 730 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 731 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 732 mstatusNew.ie.s := mstatusOld.pie.s 733 priviledgeMode := Cat(0.U(1.W), mstatusOld.spp) 734 mstatusNew.pie.s := true.B 735 mstatusNew.spp := ModeU 736 mstatus := mstatusNew.asUInt 737 mstatusNew.mprv := 0.U 738 // lr := false.B 739 retTarget := sepc(VAddrBits-1, 0) 740 } 741 742 when (valid && isUret) { 743 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 744 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 745 // mstatusNew.mpp.m := ModeU //TODO: add mode U 746 mstatusNew.ie.u := mstatusOld.pie.u 747 priviledgeMode := ModeU 748 mstatusNew.pie.u := true.B 749 mstatus := mstatusNew.asUInt 750 retTarget := uepc(VAddrBits-1, 0) 751 } 752 753 io.in.ready := true.B 754 io.out.valid := valid 755 756 val csrExceptionVec = WireInit(cfIn.exceptionVec) 757 csrExceptionVec(breakPoint) := io.in.valid && isEbreak 758 csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall 759 csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall 760 csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall 761 // Trigger an illegal instr exception when: 762 // * unimplemented csr is being read/written 763 // * csr access is illegal 764 csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen 765 cfOut.exceptionVec := csrExceptionVec 766 767 /** 768 * Exception and Intr 769 */ 770 val ideleg = (mideleg & mip.asUInt) 771 def priviledgedEnableDetect(x: Bool): Bool = Mux(x, ((priviledgeMode === ModeS) && mstatusStruct.ie.s) || (priviledgeMode < ModeS), 772 ((priviledgeMode === ModeM) && mstatusStruct.ie.m) || (priviledgeMode < ModeM)) 773 774 // send interrupt information to ROQ 775 val intrVecEnable = Wire(Vec(12, Bool())) 776 intrVecEnable.zip(ideleg.asBools).map{case(x,y) => x := priviledgedEnableDetect(y)} 777 val intrVec = mie(11,0) & mip.asUInt & intrVecEnable.asUInt 778 val intrBitSet = intrVec.orR() 779 csrio.interrupt := intrBitSet 780 mipWire.t.m := csrio.externalInterrupt.mtip 781 mipWire.s.m := csrio.externalInterrupt.msip 782 mipWire.e.m := csrio.externalInterrupt.meip 783 784 // interrupts 785 val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum)) 786 val raiseIntr = csrio.exception.valid && csrio.exception.bits.isInterrupt 787 XSDebug(raiseIntr, "interrupt: pc=0x%x, %d\n", csrio.exception.bits.uop.cf.pc, intrNO) 788 789 // exceptions 790 val raiseException = csrio.exception.valid && !csrio.exception.bits.isInterrupt 791 val hasInstrPageFault = csrio.exception.bits.uop.cf.exceptionVec(instrPageFault) && raiseException 792 val hasLoadPageFault = csrio.exception.bits.uop.cf.exceptionVec(loadPageFault) && raiseException 793 val hasStorePageFault = csrio.exception.bits.uop.cf.exceptionVec(storePageFault) && raiseException 794 val hasStoreAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(storeAddrMisaligned) && raiseException 795 val hasLoadAddrMisaligned = csrio.exception.bits.uop.cf.exceptionVec(loadAddrMisaligned) && raiseException 796 val hasInstrAccessFault = csrio.exception.bits.uop.cf.exceptionVec(instrAccessFault) && raiseException 797 val hasLoadAccessFault = csrio.exception.bits.uop.cf.exceptionVec(loadAccessFault) && raiseException 798 val hasStoreAccessFault = csrio.exception.bits.uop.cf.exceptionVec(storeAccessFault) && raiseException 799 800 val raiseExceptionVec = csrio.exception.bits.uop.cf.exceptionVec 801 val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) 802 val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO) 803 804 val raiseExceptionIntr = csrio.exception.valid 805 XSDebug(raiseExceptionIntr, "int/exc: pc %x int (%d):%x exc: (%d):%x\n", 806 csrio.exception.bits.uop.cf.pc, intrNO, intrVec, exceptionNO, raiseExceptionVec.asUInt 807 ) 808 XSDebug(raiseExceptionIntr, 809 "pc %x mstatus %x mideleg %x medeleg %x mode %x\n", 810 csrio.exception.bits.uop.cf.pc, 811 mstatus, 812 mideleg, 813 medeleg, 814 priviledgeMode 815 ) 816 817 // mtval write logic 818 val memExceptionAddr = SignExt(csrio.memExceptionVAddr, XLEN) 819 when (hasInstrPageFault || hasLoadPageFault || hasStorePageFault) { 820 val tval = Mux( 821 hasInstrPageFault, 822 Mux( 823 csrio.exception.bits.uop.cf.crossPageIPFFix, 824 SignExt(csrio.exception.bits.uop.cf.pc + 2.U, XLEN), 825 SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 826 ), 827 memExceptionAddr 828 ) 829 when (priviledgeMode === ModeM) { 830 mtval := tval 831 }.otherwise { 832 stval := tval 833 } 834 } 835 836 when (hasLoadAddrMisaligned || hasStoreAddrMisaligned) { 837 mtval := memExceptionAddr 838 } 839 840 val deleg = Mux(raiseIntr, mideleg , medeleg) 841 // val delegS = ((deleg & (1 << (causeNO & 0xf))) != 0) && (priviledgeMode < ModeM); 842 val delegS = deleg(causeNO(3,0)) && (priviledgeMode < ModeM) 843 val tvalWen = !(hasInstrPageFault || hasLoadPageFault || hasStorePageFault || hasLoadAddrMisaligned || hasStoreAddrMisaligned) || raiseIntr // TODO: need check 844 val isXRet = io.in.valid && func === CSROpType.jmp && !isEcall 845 846 // ctrl block will use theses later for flush 847 val isXRetFlag = RegInit(false.B) 848 val retTargetReg = Reg(retTarget.cloneType) 849 when (io.flushIn) { 850 isXRetFlag := false.B 851 }.elsewhen (isXRet) { 852 isXRetFlag := true.B 853 retTargetReg := retTarget 854 } 855 csrio.isXRet := isXRetFlag 856 csrio.trapTarget := Mux(isXRetFlag, 857 retTargetReg, 858 Mux(delegS, stvec, mtvec)(VAddrBits-1, 0) 859 ) 860 861 when (raiseExceptionIntr) { 862 val mstatusOld = WireInit(mstatus.asTypeOf(new MstatusStruct)) 863 val mstatusNew = WireInit(mstatus.asTypeOf(new MstatusStruct)) 864 865 when (delegS) { 866 scause := causeNO 867 sepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 868 mstatusNew.spp := priviledgeMode 869 mstatusNew.pie.s := mstatusOld.ie.s 870 mstatusNew.ie.s := false.B 871 priviledgeMode := ModeS 872 when (tvalWen) { stval := 0.U } 873 }.otherwise { 874 mcause := causeNO 875 mepc := SignExt(csrio.exception.bits.uop.cf.pc, XLEN) 876 mstatusNew.mpp := priviledgeMode 877 mstatusNew.pie.m := mstatusOld.ie.m 878 mstatusNew.ie.m := false.B 879 priviledgeMode := ModeM 880 when (tvalWen) { mtval := 0.U } 881 } 882 883 mstatus := mstatusNew.asUInt 884 } 885 886 XSDebug(raiseExceptionIntr && delegS, "sepc is writen!!! pc:%x\n", cfIn.pc) 887 888 def readWithScala(addr: Int): UInt = mapping(addr)._1 889 890 val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U) 891 892 if (!env.FPGAPlatform) { 893 difftestIO.intrNO := RegNext(difftestIntrNO) 894 difftestIO.cause := RegNext(Mux(csrio.exception.valid, causeNO, 0.U)) 895 difftestIO.priviledgeMode := priviledgeMode 896 difftestIO.mstatus := mstatus 897 difftestIO.sstatus := mstatus & sstatusRmask 898 difftestIO.mepc := mepc 899 difftestIO.sepc := sepc 900 difftestIO.mtval:= mtval 901 difftestIO.stval:= stval 902 difftestIO.mtvec := mtvec 903 difftestIO.stvec := stvec 904 difftestIO.mcause := mcause 905 difftestIO.scause := scause 906 difftestIO.satp := satp 907 difftestIO.mip := mipReg 908 difftestIO.mie := mie 909 difftestIO.mscratch := mscratch 910 difftestIO.sscratch := sscratch 911 difftestIO.mideleg := mideleg 912 difftestIO.medeleg := medeleg 913 } 914} 915