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