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