1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import difftest._ 6import freechips.rocketchip.rocket.CSRs 7import org.chipsalliance.cde.config.Parameters 8import top.{ArgParser, Generator} 9import utility._ 10import utils.OptionWrapper 11import xiangshan.backend.fu.NewCSR.CSRBundles.{CSRCustomState, PrivState, RobCommitCSR} 12import xiangshan.backend.fu.NewCSR.CSRDefines._ 13import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._ 14import xiangshan.backend.fu.NewCSR.CSREvents.{CSREvents, DretEventSinkBundle, EventUpdatePrivStateOutput, MNretEventSinkBundle, MretEventSinkBundle, SretEventSinkBundle, TargetPCBundle, TrapEntryDEventSinkBundle, TrapEntryEventInput, TrapEntryHSEventSinkBundle, TrapEntryMEventSinkBundle, TrapEntryMNEventSinkBundle, TrapEntryVSEventSinkBundle} 15import xiangshan.backend.fu.fpu.Bundles.Frm 16import xiangshan.backend.fu.vector.Bundles.{Vl, Vstart, Vxrm, Vxsat} 17import xiangshan.backend.fu.wrapper.CSRToDecode 18import xiangshan.backend.rob.RobPtr 19import xiangshan._ 20import xiangshan.backend.fu.PerfCounterIO 21import xiangshan.ExceptionNO._ 22import xiangshan.backend.trace._ 23 24import scala.collection.immutable.SeqMap 25 26object CSRConfig { 27 final val GEILEN = 5 // m,s,5vs 28 29 final val ASIDLEN = 16 // the length of ASID of XS implementation 30 31 final val ASIDMAX = 16 // the max value of ASIDLEN defined by spec 32 33 final val HIIDWidth = 12 // support Hvictl[27:16](IID) 34 35 final val VMIDLEN = 14 // the length of VMID of XS implementation 36 37 final val VMIDMAX = 14 // the max value of VMIDLEN defined by spec 38 39 // the width of VGEIN 40 final val VGEINWidth = 6 41 42 final val VaddrMaxWidth = 48 + 2 // support Sv39/Sv48/Sv39x4/Sv48x4 43 44 final val InstWidth = 32 45 46 final val XLEN = 64 // Todo: use XSParams 47 48 final val VLEN = 128 49 50 // Since we need macro to compute the width of CSR field, the input of macro should be the value that can be computed 51 // at compile time. The log2Up function cannot be used as meta-programming function, so we use litral value here 52 // log2Up(128 + 1), hold 0~128 53 final val VlWidth = 8 54 55 final val PAddrWidth = 48 56 57 final val AddrWidthInPage = 12 58 59 final val PMPAddrWidth = 48 60 61 final val PMPOffBits = 2 62 63 final val PMPAddrBits = PMPAddrWidth - PMPOffBits 64 65 // perf 66 final val perfCntNum = 29 // in Spec 67 68 final val EXT_SSTC = true 69 70 final val EXT_DBLTRP = true 71 72 final val PPNLength = 44 73 // TODO: as current test not support clean mdt , we set mstatus->mdt = 0 to allow exception in m-mode 74 final val mdtInit = 0 75 76} 77 78class NewCSRInput(implicit p: Parameters) extends Bundle { 79 val wen = Bool() 80 val ren = Bool() 81 val op = UInt(2.W) 82 val addr = UInt(12.W) 83 val src = UInt(64.W) 84 val wdata = UInt(64.W) 85 val mnret = Input(Bool()) 86 val mret = Input(Bool()) 87 val sret = Input(Bool()) 88 val dret = Input(Bool()) 89 val redirectFlush = Input(Bool()) 90} 91 92class NewCSROutput(implicit p: Parameters) extends Bundle { 93 val EX_II = Bool() 94 val EX_VI = Bool() 95 val flushPipe = Bool() 96 val rData = UInt(64.W) 97 val targetPcUpdate = Bool() 98 val targetPc = new TargetPCBundle 99 val regOut = UInt(64.W) 100 // perf 101 val isPerfCnt = Bool() 102} 103 104class NewCSR(implicit val p: Parameters) extends Module 105 with HasXSParameter 106 with MachineLevel 107 with SupervisorLevel 108 with HypervisorLevel 109 with VirtualSupervisorLevel 110 with Unprivileged 111 with CSRAIA 112 with HasExternalInterruptBundle 113 with HasNonMaskableIRPBundle 114 with CSREvents 115 with DebugLevel 116 with CSRCustom 117 with CSRPMP 118 with HasCriticalErrors 119 with IpIeAliasConnect 120{ 121 122 import CSRConfig._ 123 124 val io = IO(new Bundle { 125 val fromTop = Input(new Bundle { 126 val hartId = UInt(hartIdLen.W) 127 val clintTime = Input(ValidIO(UInt(64.W))) 128 val l2FlushDone = Input(Bool()) 129 val criticalErrorState = Input(Bool()) 130 }) 131 val in = Flipped(DecoupledIO(new NewCSRInput)) 132 val trapInst = Input(ValidIO(UInt(InstWidth.W))) 133 val fromMem = Input(new Bundle { 134 val excpVA = UInt(XLEN.W) 135 val excpGPA = UInt(XLEN.W) 136 val excpIsForVSnonLeafPTE = Bool() 137 }) 138 val fromRob = Input(new Bundle { 139 val trap = ValidIO(new Bundle { 140 val pc = UInt(VaddrMaxWidth.W) 141 val pcGPA = UInt(PAddrBitsMax.W) 142 val instr = UInt(InstWidth.W) 143 val trapVec = UInt(64.W) 144 val isFetchBkpt = Bool() 145 val singleStep = Bool() 146 val trigger = TriggerAction() 147 val crossPageIPFFix = Bool() 148 val isInterrupt = Bool() 149 val isHls = Bool() 150 val isFetchMalAddr = Bool() 151 val isForVSnonLeafPTE = Bool() 152 }) 153 val commit = Input(new RobCommitCSR) 154 val robDeqPtr = Input(new RobPtr) 155 }) 156 157 val fromVecExcpMod = Input(new Bundle { 158 val busy = Bool() 159 }) 160 161 val perf = Input(new PerfCounterIO) 162 163 /** Output should be a DecoupledIO, since now CSR writing to integer register file might be blocked (by arbiter) */ 164 val out = DecoupledIO(new NewCSROutput) 165 val status = Output(new Bundle { 166 val privState = new PrivState 167 val interrupt = Bool() 168 val wfiEvent = Bool() 169 // fp 170 val fpState = new Bundle { 171 val off = Bool() 172 val frm = Frm() 173 } 174 // vec 175 val vecState = new Bundle { 176 val vstart = Vstart() 177 val vxsat = Vxsat() 178 val vxrm = Vxrm() 179 val vcsr = UInt(XLEN.W) 180 val vl = Vl() 181 val vtype = UInt(XLEN.W) 182 val vlenb = UInt(XLEN.W) 183 val off = Bool() 184 } 185 // debug 186 val debugMode = Bool() 187 val singleStepFlag = Bool() 188 // trigger 189 val frontendTrigger = new FrontendTdataDistributeIO() 190 val memTrigger = new MemTdataDistributeIO() 191 // Instruction fetch address translation type 192 val instrAddrTransType = new AddrTransType 193 // trace 194 val traceCSR = Output(new TraceCSR) 195 // custom 196 val custom = new CSRCustomState 197 val criticalErrorState = Bool() 198 }) 199 // tlb 200 val tlb = Output(new Bundle { 201 val satpASIDChanged = Bool() 202 val vsatpASIDChanged = Bool() 203 val hgatpVMIDChanged = Bool() 204 val satp = new SatpBundle 205 val vsatp = new SatpBundle 206 val hgatp = new HgatpBundle 207 val mxr = Bool() 208 val sum = Bool() 209 val vmxr = Bool() 210 val vsum = Bool() 211 val spvp = Bool() 212 val imode = UInt(2.W) 213 val dmode = UInt(2.W) 214 val dvirt = Bool() 215 val mPBMTE = Bool() 216 val hPBMTE = Bool() 217 val pmm = new Bundle { 218 val mseccfg = UInt(2.W) 219 val menvcfg = UInt(2.W) 220 val henvcfg = UInt(2.W) 221 val hstatus = UInt(2.W) 222 val senvcfg = UInt(2.W) 223 } 224 }) 225 226 val toDecode = new CSRToDecode 227 228 val fetchMalTval = Input(UInt(XLEN.W)) 229 230 val distributedWenLegal = Output(Bool()) 231 }) 232 233 val toAIA = IO(Output(new CSRToAIABundle)) 234 val fromAIA = IO(Flipped(Output(new AIAToCSRBundle))) 235 236 dontTouch(toAIA) 237 dontTouch(fromAIA) 238 dontTouch(io.fromTop.clintTime) 239 240 /* Alias of input valid/ready */ 241 val valid = io.in.valid 242 243 /* Alias of input signals */ 244 val wen = io.in.bits.wen && valid 245 val addr = io.in.bits.addr 246 val wdata = io.in.bits.wdata 247 248 val ren = io.in.bits.ren && valid 249 val raddr = io.in.bits.addr 250 251 // flush 252 val redirectFlush = io.in.bits.redirectFlush 253 254 val hasTrap = io.fromRob.trap.valid 255 val trapVec = io.fromRob.trap.bits.trapVec 256 val trapPC = io.fromRob.trap.bits.pc 257 val trapPCGPA = io.fromRob.trap.bits.pcGPA 258 val trapIsInterrupt = io.fromRob.trap.bits.isInterrupt 259 val trapIsCrossPageIPF = io.fromRob.trap.bits.crossPageIPFFix 260 val trigger = io.fromRob.trap.bits.trigger 261 val singleStep = io.fromRob.trap.bits.singleStep 262 val trapIsHls = io.fromRob.trap.bits.isHls 263 val trapIsFetchMalAddr = io.fromRob.trap.bits.isFetchMalAddr 264 val trapIsFetchBkpt = io.fromRob.trap.bits.isFetchBkpt 265 val trapIsForVSnonLeafPTE = io.fromRob.trap.bits.isForVSnonLeafPTE 266 267 // debug_intrrupt 268 val debugIntrEnable = RegInit(true.B) // debug interrupt will be handle only when debugIntrEnable 269 val debugIntr = platformIRP.debugIP && debugIntrEnable 270 271 // CSR Privilege State 272 val PRVM = RegInit(PrivMode(1, 0), PrivMode.M) 273 val V = RegInit(VirtMode(0), VirtMode.Off) 274 val debugMode = RegInit(false.B) 275 private val nextV = WireInit(VirtMode(0), VirtMode.Off) 276 V := nextV 277 // dcsr stopcount 278 val debugModeStopCountNext = debugMode && dcsr.regOut.STOPCOUNT 279 val debugModeStopTimeNext = debugMode && dcsr.regOut.STOPTIME 280 val debugModeStopCount = RegNext(debugModeStopCountNext) 281 val unprivCountUpdate = !debugModeStopCount && debugModeStopCountNext 282 283 val criticalErrorStateInCSR = Wire(Bool()) 284 val criticalErrorState = RegEnable(true.B, false.B, io.fromTop.criticalErrorState || criticalErrorStateInCSR) 285 286 private val privState = Wire(new PrivState) 287 privState.PRVM := PRVM 288 privState.V := V 289 290 private val isModeM = privState.isModeM 291 private val (isModeHS, isModeHU) = (privState.isModeHS, privState.isModeHU) 292 private val (isModeVS, isModeVU) = (privState.isModeVS, privState.isModeVU) 293 294 val permitMod = Module(new CSRPermitModule) 295 val sstcIRGen = Module(new SstcInterruptGen) 296 val commidIdMod = Module(new CommitIDModule(40)) 297 298 val gitCommitSHA = WireInit(commidIdMod.io.commitID) 299 val gitDirty = WireInit(commidIdMod.io.dirty) 300 dontTouch(gitCommitSHA) 301 dontTouch(gitDirty) 302 303 private val wenLegal = permitMod.io.out.hasLegalWen 304 305 val legalSret = permitMod.io.out.hasLegalSret 306 val legalMret = permitMod.io.out.hasLegalMret 307 val legalMNret = permitMod.io.out.hasLegalMNret 308 val legalDret = permitMod.io.out.hasLegalDret 309 310 private val wenLegalReg = GatedValidRegNext(wenLegal) 311 312 var csrRwMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = 313 machineLevelCSRMap ++ 314 supervisorLevelCSRMap ++ 315 hypervisorCSRMap ++ 316 virtualSupervisorCSRMap ++ 317 unprivilegedCSRMap ++ 318 debugCSRMap ++ 319 aiaCSRMap ++ 320 customCSRMap ++ 321 pmpCSRMap 322 323 val csrMods: Seq[CSRModule[_]] = 324 machineLevelCSRMods ++ 325 supervisorLevelCSRMods ++ 326 hypervisorCSRMods ++ 327 virtualSupervisorCSRMods ++ 328 unprivilegedCSRMods ++ 329 debugCSRMods ++ 330 aiaCSRMods ++ 331 customCSRMods ++ 332 pmpCSRMods 333 334 var csrOutMap: SeqMap[Int, UInt] = 335 machineLevelCSROutMap ++ 336 supervisorLevelCSROutMap ++ 337 hypervisorCSROutMap ++ 338 virtualSupervisorCSROutMap ++ 339 unprivilegedCSROutMap ++ 340 debugCSROutMap ++ 341 aiaCSROutMap ++ 342 customCSROutMap ++ 343 pmpCSROutMap 344 345 // interrupt 346 val nmip = RegInit(new NonMaskableIRPendingBundle, (new NonMaskableIRPendingBundle).init) 347 when(nonMaskableIRP.NMI_43) { 348 nmip.NMI_43 := true.B 349 } 350 when(nonMaskableIRP.NMI_31) { 351 nmip.NMI_31 := true.B 352 } 353 354 val intrMod = Module(new InterruptFilter) 355 intrMod.io.in.privState := privState 356 intrMod.io.in.mstatusMIE := mstatus.regOut.MIE.asBool 357 intrMod.io.in.sstatusSIE := mstatus.regOut.SIE.asBool 358 intrMod.io.in.vsstatusSIE := vsstatus.regOut.SIE.asBool 359 intrMod.io.in.mip := mip.rdataFields 360 intrMod.io.in.mie := mie.regOut 361 intrMod.io.in.mideleg := mideleg.regOut 362 intrMod.io.in.sip := sip.regOut 363 intrMod.io.in.sie := sie.regOut 364 intrMod.io.in.hip := hip.regOut 365 intrMod.io.in.hie := hie.regOut 366 intrMod.io.in.hideleg := hideleg.regOut 367 intrMod.io.in.vsip := vsip.regOut 368 intrMod.io.in.vsie := vsie.regOut 369 intrMod.io.in.hvictl := hvictl.regOut 370 intrMod.io.in.hstatus := hstatus.regOut 371 intrMod.io.in.mtopei := mtopei.regOut 372 intrMod.io.in.stopei := stopei.regOut 373 intrMod.io.in.vstopei := vstopei.regOut 374 intrMod.io.in.hviprio1 := hviprio1.regOut 375 intrMod.io.in.hviprio2 := hviprio2.regOut 376 intrMod.io.in.miprios := Cat(miregiprios.map(_.rdata).reverse) 377 intrMod.io.in.hsiprios := Cat(siregiprios.map(_.rdata).reverse) 378 intrMod.io.in.mnstatusNMIE := mnstatus.regOut.NMIE.asBool 379 intrMod.io.in.nmi := nmip.asUInt.orR 380 intrMod.io.in.nmiVec := nmip.asUInt 381 intrMod.io.in.debugMode := debugMode 382 intrMod.io.in.debugIntr := debugIntr 383 intrMod.io.in.dcsr := dcsr.regOut 384 intrMod.io.in.platform.meip := platformIRP.MEIP 385 intrMod.io.in.platform.seip := platformIRP.SEIP 386 intrMod.io.in.fromAIA.meip := fromAIA.meip 387 intrMod.io.in.fromAIA.seip := fromAIA.seip 388 389 when(intrMod.io.out.nmi && intrMod.io.out.interruptVec.valid) { 390 nmip.NMI_31 := nmip.NMI_31 & !UIntToOH(intrMod.io.out.interruptVec.bits, 64)(NonMaskableIRNO.NMI_31) 391 nmip.NMI_43 := nmip.NMI_43 & !UIntToOH(intrMod.io.out.interruptVec.bits, 64)(NonMaskableIRNO.NMI_43) 392 } 393 val intrVec = RegEnable(intrMod.io.out.interruptVec.bits, 0.U, intrMod.io.out.interruptVec.valid) 394 val debug = RegEnable(intrMod.io.out.debug, false.B, intrMod.io.out.interruptVec.valid) 395 val nmi = RegEnable(intrMod.io.out.nmi, false.B, intrMod.io.out.interruptVec.valid) 396 val virtualInterruptIsHvictlInject = RegEnable(intrMod.io.out.virtualInterruptIsHvictlInject, false.B, intrMod.io.out.interruptVec.valid) 397 val irToHS = RegEnable(intrMod.io.out.irToHS, false.B, intrMod.io.out.interruptVec.valid) 398 val irToVS = RegEnable(intrMod.io.out.irToVS, false.B, intrMod.io.out.interruptVec.valid) 399 400 val trapHandleMod = Module(new TrapHandleModule) 401 402 trapHandleMod.io.in.trapInfo.valid := hasTrap 403 trapHandleMod.io.in.trapInfo.bits.trapVec := trapVec.asUInt 404 trapHandleMod.io.in.trapInfo.bits.nmi := nmi 405 trapHandleMod.io.in.trapInfo.bits.intrVec := intrVec 406 trapHandleMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt 407 trapHandleMod.io.in.trapInfo.bits.irToHS := irToHS 408 trapHandleMod.io.in.trapInfo.bits.irToVS := irToVS 409 trapHandleMod.io.in.privState := privState 410 trapHandleMod.io.in.mstatus := mstatus.regOut 411 trapHandleMod.io.in.vsstatus := vsstatus.regOut 412 trapHandleMod.io.in.mnstatus := mnstatus.regOut 413 trapHandleMod.io.in.mideleg := mideleg.regOut 414 trapHandleMod.io.in.medeleg := medeleg.regOut 415 trapHandleMod.io.in.hideleg := hideleg.regOut 416 trapHandleMod.io.in.hedeleg := hedeleg.regOut 417 trapHandleMod.io.in.mvien := mvien.regOut 418 trapHandleMod.io.in.hvien := hvien.regOut 419 trapHandleMod.io.in.mtvec := mtvec.regOut 420 trapHandleMod.io.in.stvec := stvec.regOut 421 trapHandleMod.io.in.vstvec := vstvec.regOut 422 trapHandleMod.io.in.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject 423 trapHandleMod.io.in.trapInfo.bits.singleStep := hasTrap && !trapIsInterrupt && singleStep 424 425 val entryPrivState = trapHandleMod.io.out.entryPrivState 426 val entryDebugMode = WireInit(false.B) 427 val dbltrpToMN = trapHandleMod.io.out.dbltrpToMN 428 val hasDTExcp = trapHandleMod.io.out.hasDTExcp 429 430 // PMP 431 val pmpEntryMod = Module(new PMPEntryHandleModule) 432 pmpEntryMod.io.in.pmpCfg := cfgs.map(_.regOut.asInstanceOf[PMPCfgBundle]) 433 pmpEntryMod.io.in.pmpAddr := pmpaddr.map(_.regOut.asInstanceOf[PMPAddrBundle]) 434 pmpEntryMod.io.in.ren := ren 435 pmpEntryMod.io.in.wen := wenLegalReg 436 pmpEntryMod.io.in.addr := addr 437 pmpEntryMod.io.in.wdata := wdata 438 439 // Todo: all wen and wdata of CSRModule assigned in this for loop 440 for ((id, (wBundle, _)) <- csrRwMap) { 441 if (vsMapS.contains(id)) { 442 // VS access CSR by S: privState.isModeVS && addrMappedToVS === sMapVS(id).U 443 wBundle.wen := wenLegalReg && ((isModeVS && addr === vsMapS(id).U) || (!isModeVS && addr === id.U)) 444 wBundle.wdata := wdata 445 } else if (sMapVS.contains(id)) { 446 wBundle.wen := wenLegalReg && !isModeVS && addr === id.U 447 wBundle.wdata := wdata 448 } else { 449 wBundle.wen := wenLegalReg && addr === id.U 450 wBundle.wdata := wdata 451 } 452 } 453 454 private val writeFpLegal = permitMod.io.out.hasLegalWriteFcsr 455 private val writeVecLegal = permitMod.io.out.hasLegalWriteVcsr 456 457 permitMod.io.in.csrAccess.ren := ren && valid 458 permitMod.io.in.csrAccess.wen := wen 459 permitMod.io.in.csrAccess.addr := addr 460 461 permitMod.io.in.privState := privState 462 permitMod.io.in.debugMode := debugMode 463 464 permitMod.io.in.xRet.mnret := io.in.bits.mnret && valid 465 permitMod.io.in.xRet.mret := io.in.bits.mret && valid 466 permitMod.io.in.xRet.sret := io.in.bits.sret && valid 467 permitMod.io.in.xRet.dret := io.in.bits.dret && valid 468 469 permitMod.io.in.status.tsr := mstatus.regOut.TSR.asBool 470 permitMod.io.in.status.vtsr := hstatus.regOut.VTSR.asBool 471 472 permitMod.io.in.status.tvm := mstatus.regOut.TVM.asBool 473 permitMod.io.in.status.vtvm := hstatus.regOut.VTVM.asBool 474 475 permitMod.io.in.status.vgein := hstatus.regOut.VGEIN.asUInt 476 477 permitMod.io.in.xcounteren.mcounteren := mcounteren.rdata 478 permitMod.io.in.xcounteren.hcounteren := hcounteren.rdata 479 permitMod.io.in.xcounteren.scounteren := scounteren.rdata 480 481 permitMod.io.in.xstateen.mstateen0 := mstateen0.rdata 482 permitMod.io.in.xstateen.hstateen0 := hstateen0.rdata 483 permitMod.io.in.xstateen.sstateen0 := sstateen0.rdata 484 485 permitMod.io.in.xenvcfg.menvcfg := menvcfg.rdata 486 permitMod.io.in.xenvcfg.henvcfg := henvcfg.rdata 487 488 permitMod.io.in.status.mstatusFSOff := mstatus.regOut.FS === ContextStatus.Off 489 permitMod.io.in.status.mstatusVSOff := mstatus.regOut.VS === ContextStatus.Off 490 permitMod.io.in.status.vsstatusFSOff := vsstatus.regOut.FS === ContextStatus.Off 491 permitMod.io.in.status.vsstatusVSOff := vsstatus.regOut.VS === ContextStatus.Off 492 493 permitMod.io.in.aia.miselectIsIllegal := miselect.isIllegal 494 permitMod.io.in.aia.siselectIsIllegal := siselect.isIllegal 495 permitMod.io.in.aia.vsiselectIsIllegal := vsiselect.isIllegal 496 permitMod.io.in.aia.siselect := siselect.rdata 497 permitMod.io.in.aia.vsiselect := vsiselect.rdata 498 permitMod.io.in.aia.mvienSEIE := mvien.regOut.SEIE.asBool 499 permitMod.io.in.aia.hvictlVTI := hvictl.regOut.VTI.asBool 500 501 sstcIRGen.i.stime.valid := time.updated 502 sstcIRGen.i.stime.bits := time.stime 503 sstcIRGen.i.vstime.valid := time.updated 504 sstcIRGen.i.vstime.bits := time.vstime 505 sstcIRGen.i.stimecmp.wen := GatedValidRegNext(stimecmp.w.wen) 506 sstcIRGen.i.stimecmp.rdata := stimecmp.rdata 507 sstcIRGen.i.vstimecmp.wen := GatedValidRegNext(vstimecmp.w.wen) 508 sstcIRGen.i.vstimecmp.rdata := vstimecmp.rdata 509 sstcIRGen.i.menvcfg.wen := GatedValidRegNext(menvcfg.w.wen) 510 sstcIRGen.i.menvcfg.STCE := menvcfg.regOut.STCE.asBool 511 sstcIRGen.i.henvcfg.wen := GatedValidRegNext(henvcfg.w.wen) 512 sstcIRGen.i.henvcfg.STCE := henvcfg.regOut.STCE.asBool 513 sstcIRGen.i.htimedeltaWen := GatedValidRegNext(htimedelta.w.wen) 514 515 miregiprios.foreach { mod => 516 mod.w.wen := mireg.w.wen && (miselect.regOut.ALL.asUInt === mod.addr.U) 517 mod.w.wdata := wdata 518 } 519 520 siregiprios.foreach { mod => 521 mod.w.wen := sireg.w.wen && (siselect.regOut.ALL.asUInt === mod.addr.U) 522 mod.w.wdata := wdata 523 } 524 525 iregiprios.foreach { mod => 526 mod match { 527 case m: HasIeBundle => 528 m.mie := mie.regOut 529 m.sie := sie.regOut 530 case _ => 531 } 532 } 533 534 mhartid.hartid := this.io.fromTop.hartId 535 536 cfgs.zipWithIndex.foreach { case (mod, i) => 537 mod.w.wen := wenLegalReg && (addr === (0x3A0 + i / 8 * 2).U) 538 mod.w.wdata := pmpEntryMod.io.out.pmpCfgWData(8*((i%8)+1)-1,8*(i%8)) 539 } 540 541 pmpaddr.zipWithIndex.foreach{ case(mod, i) => 542 mod.w.wen := wenLegalReg && (addr === (0x3B0 + i).U) 543 mod.w.wdata := pmpEntryMod.io.out.pmpAddrWData(i) 544 } 545 546 csrMods.foreach { mod => 547 mod match { 548 case m: HypervisorBundle => 549 m.hstatus := hstatus.regOut 550 case _ => 551 } 552 mod match { 553 case m: VirtualSupervisorBundle => 554 m.v := V.asUInt.asBool 555 m.hgatp := hgatp.regOut 556 case _ => 557 } 558 mod match { 559 case m: HasMachineDelegBundle => 560 m.mideleg := mideleg.regOut 561 m.medeleg := medeleg.regOut 562 case _ => 563 } 564 mod match { 565 case m: HasMachineCounterControlBundle => 566 m.mcountinhibit := mcountinhibit.regOut 567 case _ => 568 } 569 mod match { 570 case m: HasExternalInterruptBundle => 571 m.platformIRP := this.platformIRP 572 m.platformIRP.STIP := sstcIRGen.o.STIP 573 m.platformIRP.VSTIP := sstcIRGen.o.VSTIP 574 case _ => 575 } 576 mod match { 577 case m: HasRobCommitBundle => 578 // Todo: move RegNext from ROB to CSR 579 m.robCommit.instNum := io.fromRob.commit.instNum 580 m.robCommit.fflags := RegNextWithEnable(io.fromRob.commit.fflags) 581 m.robCommit.fsDirty := GatedValidRegNext(io.fromRob.commit.fsDirty) 582 m.robCommit.vsDirty := GatedValidRegNext(io.fromRob.commit.vsDirty) 583 m.robCommit.vxsat := RegNextWithEnable(io.fromRob.commit.vxsat) 584 m.robCommit.vtype := RegNextWithEnable(io.fromRob.commit.vtype) 585 m.robCommit.vl := RegNext (io.fromRob.commit.vl) 586 m.robCommit.vstart := RegNextWithEnable(io.fromRob.commit.vstart) 587 m.writeFCSR := writeFpLegal 588 m.writeVCSR := writeVecLegal 589 m.isVirtMode := V.asUInt.asBool 590 case _ => 591 } 592 mod match { 593 case m: TrapEntryDEventSinkBundle => 594 m.trapToD := trapEntryDEvent.out 595 case _ => 596 } 597 mod match { 598 case m: TrapEntryMEventSinkBundle => 599 m.trapToM := trapEntryMEvent.out 600 case _ => 601 } 602 mod match { 603 case m: TrapEntryMNEventSinkBundle => 604 m.trapToMN := trapEntryMNEvent.out 605 case _ => 606 } 607 mod match { 608 case m: TrapEntryHSEventSinkBundle => 609 m.trapToHS := trapEntryHSEvent.out 610 case _ => 611 } 612 mod match { 613 case m: TrapEntryVSEventSinkBundle => 614 m.trapToVS := trapEntryVSEvent.out 615 case _ => 616 } 617 mod match { 618 case m: MretEventSinkBundle => 619 m.retFromM := mretEvent.out 620 case _ => 621 } 622 mod match { 623 case m: MNretEventSinkBundle => 624 m.retFromMN := mnretEvent.out 625 case _ => 626 } 627 mod match { 628 case m: SretEventSinkBundle => 629 m.retFromS := sretEvent.out 630 case _ => 631 } 632 mod match { 633 case m: DretEventSinkBundle => 634 m.retFromD := dretEvent.out 635 case _ => 636 } 637 mod match { 638 case m: HasAIABundle => 639 m.aiaToCSR.rdata.valid := fromAIA.rdata.valid 640 m.aiaToCSR.rdata.bits.data := fromAIA.rdata.bits.data 641 m.aiaToCSR.rdata.bits.illegal := fromAIA.rdata.bits.illegal 642 m.aiaToCSR.meip := fromAIA.meip 643 m.aiaToCSR.seip := fromAIA.seip 644 m.aiaToCSR.vseip := fromAIA.vseip 645 m.aiaToCSR.mtopei := fromAIA.mtopei 646 m.aiaToCSR.stopei := fromAIA.stopei 647 m.aiaToCSR.vstopei := fromAIA.vstopei 648 case _ => 649 } 650 mod match { 651 case m: HasInterruptFilterSink => 652 m.topIR.mtopi := intrMod.io.out.mtopi 653 m.topIR.stopi := intrMod.io.out.stopi 654 m.topIR.vstopi := intrMod.io.out.vstopi 655 case _ => 656 } 657 mod match { 658 case m: HasPMPAddrSink => 659 m.addrRData := pmpEntryMod.io.out.pmpAddrRData 660 case _ => 661 } 662 mod match { 663 case m: HasMHPMSink => 664 // cycle from mcycle 665 m.mHPM.cycle := mcycle.rdata 666 // time from clint 667 m.mHPM.time := io.fromTop.clintTime 668 // instret from minstret 669 m.mHPM.instret := minstret.rdata 670 // VS-Mode or VU-Mode 671 m.v := privState.isVirtual 672 m.nextV := nextV.isOneOf(VirtMode.On) 673 m.htimedelta := htimedelta.rdata 674 m.mHPM.hpmcounters.zip(mhpmcounters).map{ 675 case(counter, mcounter) => counter := mcounter.rdata 676 } 677 case _ => 678 } 679 mod match { 680 case m: HasMachineEnvBundle => 681 m.menvcfg := menvcfg.regOut 682 case _ => 683 } 684 mod match { 685 case m: HasHypervisorEnvBundle => 686 m.menvcfg := menvcfg.regOut 687 case _ => 688 } 689 mod match { 690 case m: HasVirtualSupervisorEnvBundle => 691 m.henvcfg := henvcfg.regOut 692 m.menvcfg := menvcfg.regOut 693 case _ => 694 } 695 mod match { 696 case m: HasIpIeBundle => 697 m.mideleg := mideleg.regOut 698 m.mip := mip.rdata 699 m.mie := mie.regOut 700 m.mvip := mvip.regOut 701 m.mvien := mvien.regOut 702 m.hideleg := hideleg.regOut 703 m.hip := hip.regOut 704 m.hie := hie.regOut 705 m.hvien := hvien.regOut 706 m.hvip := hvip.regOut 707 m.sip := sip.regOut 708 m.sie := sie.regOut 709 m.vsip := vsip.regOut 710 m.vsie := vsie.regOut 711 m.hgeip := hgeip.regOut 712 m.hgeie := hgeie.regOut 713 m.hstatusVGEIN := hstatus.regOut.VGEIN 714 case _ => 715 } 716 mod match { 717 case m: HasMhpmeventOfBundle => 718 m.ofVec := VecInit(mhpmevents.map{ event => 719 val mhpmevent = Wire(new MhpmeventBundle) 720 mhpmevent := event.rdata 721 mhpmevent.OF.asBool 722 }).asUInt 723 m.privState := privState 724 m.mcounteren := mcounteren.rdata 725 m.hcounteren := hcounteren.rdata 726 case _ => 727 } 728 mod match { 729 case m: HasStateen0Bundle => 730 m.fromMstateen0 := mstateen0.regOut 731 m.fromHstateen0 := hstateen0.regOut 732 m.privState := privState 733 case _ => 734 } 735 mod match { 736 case m: HasDebugStopBundle => 737 m.debugModeStopCount := debugModeStopCount 738 m.debugModeStopTime := debugModeStopTimeNext 739 m.unprivCountUpdate := unprivCountUpdate 740 case _ => 741 } 742 mod match { 743 case m: HasNmipBundle => 744 m.nmip := nmip.asUInt.orR 745 case _ => 746 } 747 mod match { 748 case m: HasMachineFlushL2Bundle => 749 m.l2FlushDone := io.fromTop.l2FlushDone 750 case _ => 751 } 752 } 753 754 csrMods.foreach { mod => 755 println(s"${mod.modName}: ") 756 println(mod.dumpFields) 757 } 758 759 trapEntryMNEvent.valid := ((hasTrap && nmi) || dbltrpToMN) && !entryDebugMode && !debugMode && mnstatus.regOut.NMIE 760 trapEntryMEvent .valid := hasTrap && entryPrivState.isModeM && !dbltrpToMN && !entryDebugMode && !debugMode && !nmi && mnstatus.regOut.NMIE 761 trapEntryHSEvent.valid := hasTrap && entryPrivState.isModeHS && !entryDebugMode && !debugMode && mnstatus.regOut.NMIE 762 trapEntryVSEvent.valid := hasTrap && entryPrivState.isModeVS && !entryDebugMode && !debugMode && mnstatus.regOut.NMIE 763 764 Seq(trapEntryMEvent, trapEntryMNEvent, trapEntryHSEvent, trapEntryVSEvent, trapEntryDEvent).foreach { eMod => 765 eMod.in match { 766 case in: TrapEntryEventInput => 767 in.causeNO := trapHandleMod.io.out.causeNO 768 in.trapPc := trapPC 769 in.trapPcGPA := trapPCGPA // only used by trapEntryMEvent & trapEntryHSEvent 770 in.trapInst := io.trapInst 771 in.fetchMalTval := io.fetchMalTval 772 in.isCrossPageIPF := trapIsCrossPageIPF 773 in.isHls := trapIsHls 774 in.isFetchMalAddr := trapIsFetchMalAddr 775 in.isFetchBkpt := trapIsFetchBkpt 776 in.trapIsForVSnonLeafPTE := trapIsForVSnonLeafPTE 777 in.hasDTExcp := hasDTExcp 778 779 in.iMode.PRVM := PRVM 780 in.iMode.V := V 781 // when NMIE is zero, force to behave as MPRV is zero 782 in.dMode.PRVM := Mux(mstatus.regOut.MPRV.asBool && mnstatus.regOut.NMIE.asBool, mstatus.regOut.MPP, PRVM) 783 in.dMode.V := V.asUInt.asBool || mstatus.regOut.MPRV && mnstatus.regOut.NMIE.asBool && (mstatus.regOut.MPP =/= PrivMode.M) && mstatus.regOut.MPV 784 785 in.privState := privState 786 in.mstatus := mstatus.regOut 787 in.hstatus := hstatus.regOut 788 in.sstatus := mstatus.sstatus 789 in.vsstatus := vsstatus.regOut 790 in.pcFromXtvec := trapHandleMod.io.out.pcFromXtvec 791 792 in.menvcfg := menvcfg.regOut 793 in.henvcfg := henvcfg.regOut 794 795 in.satp := satp.regOut 796 in.vsatp := vsatp.regOut 797 in.hgatp := hgatp.regOut 798 799 in.memExceptionVAddr := io.fromMem.excpVA 800 in.memExceptionGPAddr := io.fromMem.excpGPA 801 in.memExceptionIsForVSnonLeafPTE := io.fromMem.excpIsForVSnonLeafPTE 802 803 in.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject 804 in.hvictlIID := hvictl.regOut.IID.asUInt 805 } 806 } 807 808 mnretEvent.valid := legalMNret 809 mnretEvent.in match { 810 case in => 811 in.mstatus := mstatus.regOut 812 in.vsstatus := vsstatus.regOut 813 in.mnepc := mnepc.regOut 814 in.mnstatus:= mnstatus.regOut 815 in.satp := satp.regOut 816 in.vsatp := vsatp.regOut 817 in.hgatp := hgatp.regOut 818 } 819 820 mretEvent.valid := legalMret 821 mretEvent.in match { 822 case in => 823 in.mstatus := mstatus.regOut 824 in.vsstatus := vsstatus.regOut 825 in.mepc := mepc.regOut 826 in.satp := satp.regOut 827 in.vsatp := vsatp.regOut 828 in.hgatp := hgatp.regOut 829 } 830 831 sretEvent.valid := legalSret 832 sretEvent.in match { 833 case in => 834 in.privState := privState 835 in.mstatus := mstatus.regOut 836 in.hstatus := hstatus.regOut 837 in.vsstatus := vsstatus.regOut 838 in.sepc := sepc.regOut 839 in.vsepc := vsepc.regOut 840 in.satp := satp.regOut 841 in.vsatp := vsatp.regOut 842 in.hgatp := hgatp.regOut 843 } 844 845 dretEvent.valid := legalDret 846 dretEvent.in match { 847 case in => 848 in.dcsr := dcsr.regOut 849 in.dpc := dpc.regOut 850 in.mstatus := mstatus.regOut 851 in.vsstatus := vsstatus.regOut 852 in.satp := satp.regOut 853 in.vsatp := vsatp.regOut 854 in.hgatp := hgatp.regOut 855 } 856 857 PRVM := MuxCase( 858 PRVM, 859 events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map { 860 x => x.out match { 861 case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM) 862 } 863 } 864 ) 865 866 nextV := MuxCase( 867 V, 868 events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map { 869 x => x.out match { 870 case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V) 871 } 872 } 873 ) 874 875 debugMode := MuxCase( 876 debugMode, 877 Seq( 878 dretEvent.out.debugMode.valid -> dretEvent.out.debugMode.bits, 879 trapEntryDEvent.out.debugMode.valid -> trapEntryDEvent.out.debugMode.bits 880 ) 881 ) 882 883 debugIntrEnable := MuxCase( 884 debugIntrEnable, 885 Seq( 886 dretEvent.out.debugIntrEnable.valid -> dretEvent.out.debugIntrEnable.bits, 887 trapEntryDEvent.out.debugIntrEnable.valid -> trapEntryDEvent.out.debugIntrEnable.bits 888 ) 889 ) 890 891 // perf 892 val addrInPerfCnt = (wenLegal || ren) && ( 893 (addr >= CSRs.mcycle.U) && (addr <= CSRs.mhpmcounter31.U) || 894 (addr >= CSRs.cycle.U) && (addr <= CSRs.hpmcounter31.U) 895 ) 896 897 // flush 898 val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegalReg // write to satp will cause the pipeline be flushed 899 900 val floatStatusOnOff = mstatus.w.wen && ( 901 mstatus.w.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off || 902 mstatus.w.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off 903 ) || mstatus.wAliasSstatus.wen && ( 904 mstatus.wAliasSstatus.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off || 905 mstatus.wAliasSstatus.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off 906 ) || vsstatus.w.wen && ( 907 vsstatus.w.wdataFields.FS === ContextStatus.Off && vsstatus.regOut.FS =/= ContextStatus.Off || 908 vsstatus.w.wdataFields.FS =/= ContextStatus.Off && vsstatus.regOut.FS === ContextStatus.Off 909 ) 910 911 val vectorStatusOnOff = mstatus.w.wen && ( 912 mstatus.w.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off || 913 mstatus.w.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off 914 ) || mstatus.wAliasSstatus.wen && ( 915 mstatus.wAliasSstatus.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off || 916 mstatus.wAliasSstatus.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off 917 ) || vsstatus.w.wen && ( 918 vsstatus.w.wdataFields.VS === ContextStatus.Off && vsstatus.regOut.VS =/= ContextStatus.Off || 919 vsstatus.w.wdataFields.VS =/= ContextStatus.Off && vsstatus.regOut.VS === ContextStatus.Off 920 ) 921 922 val triggerFrontendChange = Wire(Bool()) 923 924 val vstartChange = vstart.w.wen && ( 925 vstart.w.wdata === 0.U && vstart.regOut.vstart.asUInt =/= 0.U || 926 vstart.w.wdata =/= 0.U && vstart.regOut.vstart.asUInt === 0.U 927 ) 928 929 // flush pipe when write frm and data > 4 or write fcsr and data[7:5] > 4 or write frm/fcsr and frm is reserved 930 val frmIsReserved = fcsr.frm(2) && fcsr.frm(1, 0).orR 931 val frmWdataReserved = fcsr.wAliasFfm.wdata(2) && fcsr.wAliasFfm.wdata(1, 0).orR 932 val fcsrWdataReserved = fcsr.w.wdata(7) && fcsr.w.wdata(6, 5).orR 933 val frmChange = fcsr.wAliasFfm.wen && (!frmIsReserved && frmWdataReserved || frmIsReserved && !frmWdataReserved) || 934 fcsr.w.wen && (!frmIsReserved && fcsrWdataReserved || frmIsReserved && !fcsrWdataReserved) 935 936 val flushPipe = resetSatp || 937 triggerFrontendChange || floatStatusOnOff || vectorStatusOnOff || 938 vstartChange || frmChange 939 940 /** 941 * Look up id in vsMapS and sMapVS. 942 * If id is in vsMapS, use vsMapS(id) when under VS mode, 943 * id under other modes 944 * Else If id is in sMapVS, use 0 when under VS mode, 945 * id under modes except VS 946 * Else, use id as read address 947 * Use read address to look up rdata in csrRwMap 948 */ 949 private val rdata = Mux1H(csrRwMap.map { case (id, (_, rdata)) => 950 if (vsMapS.contains(id)) { 951 ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> rdata 952 } else if (sMapVS.contains(id)) { 953 (!isModeVS && addr === id.U) -> rdata 954 } else { 955 (raddr === id.U) -> rdata 956 } 957 }) 958 959 private val regOut = Mux1H(csrOutMap.map { case (id, regOut) => 960 if (vsMapS.contains(id)) { 961 ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> regOut 962 } else if (sMapVS.contains(id)) { 963 (!isModeVS && addr === id.U) -> regOut 964 } else { 965 (raddr === id.U) -> regOut 966 } 967 }) 968 969 private val needTargetUpdate = mnretEvent.out.targetPc.valid || mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid || 970 trapEntryMEvent.out.targetPc.valid || trapEntryMNEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid 971 972 private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR 973 974 private val noCSRIllegalReg = RegEnable(noCSRIllegal, ren || wen) 975 976 private val s_idle :: s_waitIMSIC :: s_finish :: Nil = Enum(3) 977 978 /** the state machine of newCSR module */ 979 private val state = RegInit(s_idle) 980 /** the next state of newCSR */ 981 private val stateNext = WireInit(state) 982 state := stateNext 983 984 /** 985 * Asynchronous access operation of CSR. Check whether an access is asynchronous when read/write-enable is high. 986 * AIA registers are designed to be access asynchronously, so newCSR will wait for response. 987 **/ 988 private val asyncAccess = (wen || ren) && !(permitMod.io.out.EX_II || permitMod.io.out.EX_VI) && ( 989 mireg.addr.U === addr && miselect.inIMSICRange || 990 sireg.addr.U === addr && ((!V.asUInt.asBool && siselect.inIMSICRange) || (V.asUInt.asBool && vsiselect.inIMSICRange)) || 991 vsireg.addr.U === addr && vsiselect.inIMSICRange 992 ) 993 994 /** State machine of newCSR */ 995 switch(state) { 996 is(s_idle) { 997 when(valid && redirectFlush) { 998 stateNext := s_idle 999 }.elsewhen(valid && asyncAccess) { 1000 stateNext := s_waitIMSIC 1001 }.elsewhen(valid) { 1002 stateNext := s_finish 1003 } 1004 } 1005 is(s_waitIMSIC) { 1006 when(redirectFlush) { 1007 stateNext := s_idle 1008 }.elsewhen(fromAIA.rdata.valid) { 1009 when(io.out.ready) { 1010 stateNext := s_idle 1011 }.otherwise { 1012 stateNext := s_finish 1013 } 1014 } 1015 } 1016 is(s_finish) { 1017 when(redirectFlush || io.out.ready) { 1018 stateNext := s_idle 1019 } 1020 } 1021 } 1022 1023 1024 // Todo: check IMSIC EX_II and EX_VI 1025 private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal 1026 private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool 1027 private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool 1028 1029 /** Set io.in.ready when state machine is ready to receive a new request synchronously */ 1030 io.in.ready := (state === s_idle) 1031 1032 /** 1033 * Valid signal of newCSR output. 1034 * When in IDLE state, when input_valid is high, we set it. 1035 * When in waitIMSIC state, and the next state is IDLE, we set it. 1036 **/ 1037 1038 /** Data that have been read before,and should be stored because output not fired */ 1039 val normalCSRValid = state === s_idle && valid && !asyncAccess 1040 val waitIMSICValid = state === s_waitIMSIC && fromAIA.rdata.valid 1041 1042 io.out.valid := (waitIMSICValid || state === s_finish) && !redirectFlush 1043 io.out.bits.EX_II := DataHoldBypass(Mux1H(Seq( 1044 normalCSRValid -> (permitMod.io.out.EX_II || noCSRIllegal), 1045 waitIMSICValid -> imsic_EX_II, 1046 )), false.B, normalCSRValid || waitIMSICValid) 1047 io.out.bits.EX_VI := DataHoldBypass(Mux1H(Seq( 1048 normalCSRValid -> permitMod.io.out.EX_VI, 1049 waitIMSICValid -> imsic_EX_VI, 1050 )), false.B, normalCSRValid || waitIMSICValid) 1051 io.out.bits.flushPipe := flushPipe 1052 1053 /** Prepare read data for output */ 1054 io.out.bits.rData := DataHoldBypass( 1055 Mux1H(Seq( 1056 io.in.fire -> rdata, 1057 fromAIA.rdata.valid -> fromAIA.rdata.bits.data 1058 )), 0.U(64.W), io.in.fire || fromAIA.rdata.valid) 1059 io.out.bits.regOut := regOut 1060 io.out.bits.targetPc := DataHoldBypass( 1061 Mux(trapEntryDEvent.out.targetPc.valid, 1062 trapEntryDEvent.out.targetPc.bits, 1063 Mux1H(Seq( 1064 mnretEvent.out.targetPc.valid -> mnretEvent.out.targetPc.bits, 1065 mretEvent.out.targetPc.valid -> mretEvent.out.targetPc.bits, 1066 sretEvent.out.targetPc.valid -> sretEvent.out.targetPc.bits, 1067 dretEvent.out.targetPc.valid -> dretEvent.out.targetPc.bits, 1068 trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits, 1069 trapEntryMNEvent.out.targetPc.valid -> trapEntryMNEvent.out.targetPc.bits, 1070 trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits, 1071 trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits) 1072 ) 1073 ), 1074 needTargetUpdate) 1075 io.out.bits.targetPcUpdate := needTargetUpdate 1076 io.out.bits.isPerfCnt := DataHoldBypass(addrInPerfCnt, false.B, io.in.fire) 1077 1078 io.status.privState := privState 1079 io.status.fpState.frm := fcsr.frm 1080 io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off 1081 io.status.vecState.vstart := vstart.rdata.asUInt 1082 io.status.vecState.vxsat := vcsr.vxsat 1083 io.status.vecState.vxrm := vcsr.vxrm 1084 io.status.vecState.vcsr := vcsr.rdata.asUInt 1085 io.status.vecState.vl := vl.rdata.asUInt 1086 io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct 1087 io.status.vecState.vlenb := vlenb.rdata.asUInt 1088 io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off 1089 io.status.interrupt := intrMod.io.out.interruptVec.valid 1090 io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR 1091 io.status.debugMode := debugMode 1092 io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP 1093 1094 /** 1095 * debug_begin 1096 */ 1097 val tdata1Selected = Wire(new Tdata1Bundle) 1098 tdata1Selected := tdata1.rdata 1099 val dmodeInSelectedTrigger = tdata1Selected.DMODE.asBool 1100 val triggerCanWrite = dmodeInSelectedTrigger && debugMode || !dmodeInSelectedTrigger 1101 val tdata1Update = tdata1.w.wen && triggerCanWrite 1102 val tdata2Update = tdata2.w.wen && triggerCanWrite 1103 val tdata1Vec = tdata1RegVec.map{ mod => { 1104 val tdata1Wire = Wire(new Tdata1Bundle) 1105 tdata1Wire := mod.rdata 1106 tdata1Wire 1107 }} 1108 1109 val triggerCanRaiseBpExp = !(privState.isModeM && !mstatus.regOut.MIE || 1110 medeleg.regOut.EX_BP && privState.isModeHS && !mstatus.sstatus.SIE || 1111 medeleg.regOut.EX_BP && hedeleg.regOut.EX_BP && privState.isModeVS && !vsstatus.regOut.SIE) 1112 1113 val debugMod = Module(new Debug) 1114 debugMod.io.in.trapInfo.valid := hasTrap 1115 debugMod.io.in.trapInfo.bits.trapVec := trapVec.asUInt 1116 debugMod.io.in.trapInfo.bits.isDebugIntr := debug 1117 debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt 1118 debugMod.io.in.trapInfo.bits.trigger := trigger 1119 debugMod.io.in.trapInfo.bits.singleStep := singleStep 1120 debugMod.io.in.trapInfo.bits.criticalErrorState := criticalErrorState 1121 debugMod.io.in.privState := privState 1122 debugMod.io.in.debugMode := debugMode 1123 debugMod.io.in.dcsr := dcsr.regOut 1124 debugMod.io.in.tselect := tselect.regOut 1125 debugMod.io.in.tdata1Vec := tdata1Vec 1126 debugMod.io.in.tdata1Selected := tdata1.rdata 1127 debugMod.io.in.tdata2Selected := tdata2.rdata 1128 debugMod.io.in.tdata1Update := tdata1Update 1129 debugMod.io.in.tdata2Update := tdata2Update 1130 debugMod.io.in.tdata1Wdata := wdata 1131 debugMod.io.in.triggerCanRaiseBpExp := triggerCanRaiseBpExp 1132 1133 entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode 1134 1135 trapEntryDEvent.valid := entryDebugMode 1136 trapEntryDEvent.in.hasDebugIntr := debugMod.io.out.hasDebugIntr 1137 trapEntryDEvent.in.debugMode := debugMode 1138 trapEntryDEvent.in.hasTrap := hasTrap 1139 trapEntryDEvent.in.hasSingleStep := debugMod.io.out.hasSingleStep 1140 trapEntryDEvent.in.triggerEnterDebugMode := debugMod.io.out.triggerEnterDebugMode 1141 trapEntryDEvent.in.hasDebugEbreakException := debugMod.io.out.hasDebugEbreakException 1142 trapEntryDEvent.in.breakPoint := debugMod.io.out.breakPoint 1143 trapEntryDEvent.in.criticalErrorStateEnterDebug := debugMod.io.out.criticalErrorStateEnterDebug 1144 1145 for(idx <- 0 until TriggerNum) { 1146 val tdata1Pre = Wire(new Tdata1Bundle) 1147 val mcontrol6Pre = Wire(new Mcontrol6) 1148 tdata1Pre := (if (idx > 0) tdata1RegVec(idx - 1) else tdata1RegVec(idx)).rdata.asUInt 1149 mcontrol6Pre := tdata1Pre.DATA.asUInt 1150 val canWriteDmode = WireInit(false.B) 1151 canWriteDmode := (if(idx > 0) (Mux(mcontrol6Pre.CHAIN.asBool, tdata1Pre.DMODE.asBool && tdata1Pre.TYPE.isLegal, true.B)) && debugMode else debugMode).asBool 1152 tdata1RegVec(idx) match { 1153 case m: HasTriggerBundle => 1154 m.canWriteDmode := canWriteDmode 1155 m.chainable := debugMod.io.out.newTriggerChainIsLegal 1156 case _ => 1157 } 1158 } 1159 1160 tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => { 1161 mod1.w.wen := tdata1Update && (tselect.rdata === idx.U) 1162 mod1.w.wdata := wdata 1163 mod2.w.wen := tdata2Update && (tselect.rdata === idx.U) 1164 mod2.w.wdata := wdata 1165 }} 1166 1167 triggerFrontendChange := debugMod.io.out.triggerFrontendChange 1168 1169 io.status.frontendTrigger := debugMod.io.out.frontendTrigger 1170 io.status.memTrigger := debugMod.io.out.memTrigger 1171 /** 1172 * debug_end 1173 */ 1174 1175 // trace 1176 val privForTrace = Mux(debugMode, 1177 Priv.D, 1178 Mux1H( 1179 Seq(privState.isModeM, privState.isModeHS, privState.isModeVS, privState.isModeHU, privState.isModeVU), 1180 Seq(Priv.M, Priv.HS, Priv.VS, Priv.HU, Priv.VU) 1181 ) 1182 ) 1183 val xret = legalDret || legalMNret || legalMret || legalSret 1184 val currentPriv = privForTrace 1185 val lastPriv = RegEnable(privForTrace, Priv.M, (xret || io.fromRob.trap.valid)) 1186 1187 io.status.traceCSR.lastPriv := lastPriv 1188 io.status.traceCSR.currentPriv := privForTrace 1189 io.status.traceCSR.cause := Mux1H( 1190 Seq(privState.isModeM, privState.isModeHS, privState.isModeVS), 1191 Seq(mcause.rdata, scause.rdata, vscause.rdata) 1192 ) 1193 io.status.traceCSR.tval := Mux1H( 1194 Seq(privState.isModeM, privState.isModeHS, privState.isModeVS), 1195 Seq(mtval.rdata, stval.rdata, vstval.rdata) 1196 ) 1197 1198 /** 1199 * perf_begin 1200 * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5) 1201 */ 1202 val csrevents = mhpmevents.slice(24, 29).map(_.rdata) 1203 1204 val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent)) 1205 for (i <- 0 until numPCntHc * coreParams.L2NBanks) { 1206 hcEvents(i) := io.perf.perfEventsHc(i) 1207 } 1208 1209 val hpmHc = HPerfMonitor(csrevents, hcEvents) 1210 val allPerfEvents = io.perf.perfEventsFrontend ++ 1211 io.perf.perfEventsBackend ++ 1212 io.perf.perfEventsLsu ++ 1213 hpmHc.getPerf 1214 1215 val countingEn = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool()))) 1216 val ofFromPerfCntVec = Wire(Vec(perfCntNum, Bool())) 1217 val lcofiReqVec = Wire(Vec(perfCntNum, Bool())) 1218 1219 for(i <- 0 until perfCntNum) { 1220 mhpmcounters(i) match { 1221 case m: HasPerfCounterBundle => 1222 m.countingEn := countingEn(i) 1223 m.perf := allPerfEvents(i) 1224 ofFromPerfCntVec(i) := m.toMhpmeventOF 1225 case _ => 1226 } 1227 1228 mhpmevents(i) match { 1229 case m: HasOfFromPerfCntBundle => 1230 m.ofFromPerfCnt := ofFromPerfCntVec(i) 1231 case _ => 1232 } 1233 1234 val mhpmevent = Wire(new MhpmeventBundle) 1235 mhpmevent := mhpmevents(i).rdata 1236 lcofiReqVec(i) := ofFromPerfCntVec(i) && !mhpmevent.OF.asBool 1237 1238 countingEn(i) := (privState.isModeM && !mhpmevent.MINH) || 1239 (privState.isModeHS && !mhpmevent.SINH) || 1240 (privState.isModeHU && !mhpmevent.UINH) || 1241 (privState.isModeVS && !mhpmevent.VSINH) || 1242 (privState.isModeVU && !mhpmevent.VUINH) 1243 } 1244 1245 val lcofiReq = lcofiReqVec.asUInt.orR 1246 mip match { 1247 case m: HasLocalInterruptReqBundle => 1248 m.lcofiReq := lcofiReq 1249 case _ => 1250 } 1251 /** 1252 * perf_end 1253 */ 1254 1255 /** 1256 * [[io.status.custom]] connection 1257 */ 1258 io.status.custom.pf_ctrl.l1I_pf_enable := spfctl.regOut.L1I_PF_ENABLE.asBool 1259 io.status.custom.pf_ctrl.l2_pf_enable := spfctl.regOut.L2_PF_ENABLE.asBool 1260 io.status.custom.pf_ctrl.l1D_pf_enable := spfctl.regOut.L1D_PF_ENABLE.asBool 1261 io.status.custom.pf_ctrl.l1D_pf_train_on_hit := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool 1262 io.status.custom.pf_ctrl.l1D_pf_enable_agt := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool 1263 io.status.custom.pf_ctrl.l1D_pf_enable_pht := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool 1264 io.status.custom.pf_ctrl.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt 1265 io.status.custom.pf_ctrl.l1D_pf_active_stride := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt 1266 io.status.custom.pf_ctrl.l1D_pf_enable_stride := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool 1267 io.status.custom.pf_ctrl.l2_pf_store_only := spfctl.regOut.L2_PF_STORE_ONLY.asBool 1268 io.status.custom.pf_ctrl.l2_pf_recv_enable := spfctl.regOut.L2_PF_RECV_ENABLE.asBool 1269 io.status.custom.pf_ctrl.l2_pf_pbop_enable := spfctl.regOut.L2_PF_PBOP_ENABLE.asBool 1270 io.status.custom.pf_ctrl.l2_pf_vbop_enable := spfctl.regOut.L2_PF_VBOP_ENABLE.asBool 1271 io.status.custom.pf_ctrl.l2_pf_tp_enable := spfctl.regOut.L2_PF_TP_ENABLE.asBool 1272 1273 io.status.custom.lvpred_disable := slvpredctl.regOut.LVPRED_DISABLE.asBool 1274 io.status.custom.no_spec_load := slvpredctl.regOut.NO_SPEC_LOAD.asBool 1275 io.status.custom.storeset_wait_store := slvpredctl.regOut.STORESET_WAIT_STORE.asBool 1276 io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool 1277 io.status.custom.lvpred_timeout := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt 1278 1279 io.status.custom.bp_ctrl.ubtb_enable := sbpctl.regOut.UBTB_ENABLE .asBool 1280 io.status.custom.bp_ctrl.btb_enable := sbpctl.regOut.BTB_ENABLE .asBool 1281 io.status.custom.bp_ctrl.bim_enable := sbpctl.regOut.BIM_ENABLE .asBool 1282 io.status.custom.bp_ctrl.tage_enable := sbpctl.regOut.TAGE_ENABLE .asBool 1283 io.status.custom.bp_ctrl.sc_enable := sbpctl.regOut.SC_ENABLE .asBool 1284 io.status.custom.bp_ctrl.ras_enable := sbpctl.regOut.RAS_ENABLE .asBool 1285 io.status.custom.bp_ctrl.loop_enable := sbpctl.regOut.LOOP_ENABLE .asBool 1286 1287 io.status.custom.sbuffer_threshold := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt 1288 io.status.custom.ldld_vio_check_enable := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool 1289 io.status.custom.soft_prefetch_enable := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool 1290 io.status.custom.cache_error_enable := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool 1291 io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool 1292 io.status.custom.hd_misalign_st_enable := smblockctl.regOut.HD_MISALIGN_ST_ENABLE.asBool 1293 io.status.custom.hd_misalign_ld_enable := smblockctl.regOut.HD_MISALIGN_LD_ENABLE.asBool 1294 1295 io.status.custom.fusion_enable := srnctl.regOut.FUSION_ENABLE.asBool 1296 io.status.custom.wfi_enable := srnctl.regOut.WFI_ENABLE.asBool && (!io.status.singleStepFlag) && !debugMode 1297 1298 io.status.custom.power_down_enable := mcorepwr.regOut.POWER_DOWN_ENABLE.asBool 1299 1300 io.status.custom.flush_l2_enable := mflushpwr.regOut.FLUSH_L2_ENABLE.asBool 1301 1302 io.status.instrAddrTransType.bare := privState.isModeM || 1303 (!privState.isVirtual && satp.regOut.MODE === SatpMode.Bare) || 1304 (privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Bare) 1305 io.status.instrAddrTransType.sv39 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv39 || 1306 privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv39 1307 io.status.instrAddrTransType.sv48 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv48 || 1308 privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv48 1309 io.status.instrAddrTransType.sv39x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv39x4 1310 io.status.instrAddrTransType.sv48x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv48x4 1311 assert(PopCount(io.status.instrAddrTransType.asUInt) === 1.U, "Exactly one inst trans type should be asserted") 1312 1313 private val csrAccess = wenLegalReg || RegNext(ren) 1314 1315 private val imsicAddrValid = 1316 csrAccess && addr === CSRs.mireg.U && miselect.inIMSICRange || 1317 csrAccess && addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange || 1318 csrAccess && (addr === CSRs.sireg.U && isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange 1319 1320 private val imsicAddr = Mux1H(Seq( 1321 (csrAccess && addr === CSRs.mireg.U) -> miselect.rdata, 1322 (csrAccess && addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata, 1323 (csrAccess && (addr === CSRs.sireg.U && isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata, 1324 )) 1325 1326 private val imsicAddrPrivState = Mux1H(Seq( 1327 (csrAccess && addr === CSRs.mireg.U) -> PrivState.ModeM, 1328 (csrAccess && addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS, 1329 (csrAccess && (addr === CSRs.sireg.U && isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS, 1330 )) 1331 1332 private val imsicWdataValid = 1333 mireg.w.wen && miselect.inIMSICRange || 1334 sireg.w.wen && siselect.inIMSICRange || 1335 vsireg.w.wen && vsiselect.inIMSICRange 1336 1337 toAIA.addr.valid := imsicAddrValid 1338 toAIA.addr.bits.addr := imsicAddr 1339 toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM 1340 toAIA.addr.bits.v := imsicAddrPrivState.V 1341 1342 toAIA.wdata.valid := imsicWdataValid 1343 toAIA.wdata.bits.op := RegNext(io.in.bits.op) 1344 toAIA.wdata.bits.data := RegNext(io.in.bits.src) 1345 toAIA.vgein := hstatus.regOut.VGEIN.asUInt 1346 toAIA.mClaim := mtopei.w.wen 1347 toAIA.sClaim := stopei.w.wen 1348 toAIA.vsClaim := vstopei.w.wen 1349 1350 // tlb 1351 io.tlb.satpASIDChanged := GatedValidRegNext(satp.w.wen && satp .regOut.ASID =/= satp.w.wdataFields.ASID) 1352 io.tlb.vsatpASIDChanged := GatedValidRegNext(vsatp.w.wen && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID) 1353 io.tlb.hgatpVMIDChanged := GatedValidRegNext(hgatp.w.wen && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID) 1354 io.tlb.satp := satp.rdata 1355 io.tlb.vsatp := vsatp.rdata 1356 io.tlb.hgatp := hgatp.rdata 1357 io.tlb.mxr := mstatus.regOut.MXR.asBool 1358 io.tlb.sum := mstatus.regOut.SUM.asBool 1359 io.tlb.vmxr := vsstatus.regOut.MXR.asBool 1360 io.tlb.vsum := vsstatus.regOut.SUM.asBool 1361 io.tlb.spvp := hstatus.regOut.SPVP.asBool 1362 1363 io.tlb.imode := PRVM.asUInt 1364 // when NMIE is zero, force to behave as MPRV is zero 1365 io.tlb.dmode := Mux( 1366 (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE, 1367 mstatus.regOut.MPP.asUInt, 1368 PRVM.asUInt 1369 ) 1370 io.tlb.dvirt := Mux( 1371 (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE && mstatus.regOut.MPP =/= PrivMode.M, 1372 mstatus.regOut.MPV.asUInt, 1373 V.asUInt 1374 ) 1375 io.tlb.mPBMTE := RegNext(menvcfg.regOut.PBMTE.asBool) 1376 io.tlb.hPBMTE := RegNext(henvcfg.regOut.PBMTE.asBool) 1377 io.tlb.pmm.mseccfg := RegNext(mseccfg.regOut.PMM.asUInt) 1378 io.tlb.pmm.menvcfg := RegNext(menvcfg.regOut.PMM.asUInt) 1379 io.tlb.pmm.henvcfg := RegNext(henvcfg.regOut.PMM.asUInt) 1380 io.tlb.pmm.hstatus := RegNext(hstatus.regOut.HUPMM.asUInt) 1381 io.tlb.pmm.senvcfg := RegNext(senvcfg.regOut.PMM.asUInt) 1382 1383 io.toDecode.illegalInst.sfenceVMA := isModeHS && mstatus.regOut.TVM || isModeHU 1384 io.toDecode.virtualInst.sfenceVMA := isModeVS && hstatus.regOut.VTVM || isModeVU 1385 io.toDecode.illegalInst.sfencePart := isModeHU 1386 io.toDecode.virtualInst.sfencePart := isModeVU 1387 io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU 1388 io.toDecode.illegalInst.hfenceVVMA := isModeHU 1389 io.toDecode.virtualInst.hfence := isModeVS || isModeVU 1390 io.toDecode.illegalInst.hlsv := isModeHU && !hstatus.regOut.HU 1391 io.toDecode.virtualInst.hlsv := isModeVS || isModeVU 1392 io.toDecode.illegalInst.fsIsOff := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off 1393 io.toDecode.illegalInst.vsIsOff := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off 1394 io.toDecode.illegalInst.wfi := isModeHU || !isModeM && mstatus.regOut.TW 1395 io.toDecode.virtualInst.wfi := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW 1396 io.toDecode.illegalInst.wrs_nto := !isModeM && mstatus.regOut.TW 1397 io.toDecode.virtualInst.wrs_nto := privState.V && !mstatus.regOut.TW && hstatus.regOut.VTW 1398 io.toDecode.illegalInst.frm := frmIsReserved 1399 // Ref: The RISC-V Instruction Set Manual Volume I - 20.5. Control and Status Register State 1400 io.toDecode.illegalInst.cboZ := !isModeM && !menvcfg.regOut.CBZE || isModeHU && !senvcfg.regOut.CBZE 1401 io.toDecode.virtualInst.cboZ := menvcfg.regOut.CBZE && ( 1402 isModeVS && !henvcfg.regOut.CBZE || 1403 isModeVU && !(henvcfg.regOut.CBZE && senvcfg.regOut.CBZE) 1404 ) 1405 io.toDecode.illegalInst.cboCF := !isModeM && !menvcfg.regOut.CBCFE || isModeHU && !senvcfg.regOut.CBCFE 1406 io.toDecode.virtualInst.cboCF := menvcfg.regOut.CBCFE && ( 1407 isModeVS && !henvcfg.regOut.CBCFE || 1408 isModeVU && !(henvcfg.regOut.CBCFE && senvcfg.regOut.CBCFE) 1409 ) 1410 io.toDecode.illegalInst.cboI := 1411 !isModeM && menvcfg.regOut.CBIE === EnvCBIE.Off || 1412 isModeHU && senvcfg.regOut.CBIE === EnvCBIE.Off 1413 io.toDecode.virtualInst.cboI := menvcfg.regOut.CBIE =/= EnvCBIE.Off && ( 1414 isModeVS && henvcfg.regOut.CBIE === EnvCBIE.Off || 1415 isModeVU &&(henvcfg.regOut.CBIE === EnvCBIE.Off || senvcfg.regOut.CBIE === EnvCBIE.Off) 1416 ) 1417 io.toDecode.special.cboI2F := !io.toDecode.illegalInst.cboI && !io.toDecode.virtualInst.cboI && ( 1418 menvcfg.regOut.CBIE === EnvCBIE.Flush && !isModeM || 1419 senvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeHU || isModeVU) || 1420 henvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeVS || isModeVU) 1421 ) 1422 1423 io.distributedWenLegal := wenLegalReg && !noCSRIllegalReg 1424 io.status.criticalErrorState := criticalErrorState && !dcsr.regOut.CETRIG.asBool 1425 1426 val criticalErrors = Seq( 1427 ("csr_dbltrp_inMN", !mnstatus.regOut.NMIE && hasTrap && !entryDebugMode), 1428 ) 1429 criticalErrorStateInCSR := criticalErrors.map(criticalError => criticalError._2).reduce(_ || _).asBool 1430 generateCriticalErrors() 1431 1432 // Always instantiate basic difftest modules. 1433 if (env.AlwaysBasicDiff || env.EnableDifftest) { 1434 // Delay trap passed to difftest until VecExcpMod is not busy 1435 val pendingTrap = RegInit(false.B) 1436 when (hasTrap) { 1437 pendingTrap := true.B 1438 }.elsewhen (!io.fromVecExcpMod.busy) { 1439 pendingTrap := false.B 1440 } 1441 1442 val hartId = io.fromTop.hartId 1443 val trapValid = pendingTrap && !io.fromVecExcpMod.busy 1444 val trapNO = Mux(virtualInterruptIsHvictlInject && hasTrap, hvictl.regOut.IID.asUInt, trapHandleMod.io.out.causeNO.ExceptionCode.asUInt) 1445 val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool 1446 val hasNMI = nmi && hasTrap 1447 val interruptNO = Mux(interrupt, trapNO, 0.U) 1448 val exceptionNO = Mux(!interrupt, trapNO, 0.U) 1449 val isSv39: Bool = 1450 (isModeHS || isModeHU) && satp.regOut.MODE === SatpMode.Sv39 || 1451 (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv39 1452 val isSv48: Bool = 1453 (isModeHS || isModeHU) && satp.regOut.MODE === SatpMode.Sv48 || 1454 (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv48 1455 val isBare = !isSv39 && !isSv48 1456 val sv39PC = SignExt(trapPC.take(39), XLEN) 1457 val sv48PC = SignExt(trapPC.take(48), XLEN) 1458 val barePC = ZeroExt(trapPC.take(PAddrBits), XLEN) 1459 // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57 1460 val exceptionPC = Mux1H(Seq( 1461 isSv39 -> sv39PC, 1462 isSv48 -> sv48PC, 1463 isBare -> barePC, 1464 )) 1465 1466 val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true) 1467 diffArchEvent.coreid := hartId 1468 diffArchEvent.valid := trapValid 1469 diffArchEvent.interrupt := RegEnable(interruptNO, hasTrap) 1470 diffArchEvent.exception := RegEnable(exceptionNO, hasTrap) 1471 diffArchEvent.exceptionPC := RegEnable(exceptionPC, hasTrap) 1472 diffArchEvent.hasNMI := RegEnable(hasNMI, hasTrap) 1473 diffArchEvent.virtualInterruptIsHvictlInject := RegNext(virtualInterruptIsHvictlInject && hasTrap) 1474 if (env.EnableDifftest) { 1475 diffArchEvent.exceptionInst := RegEnable(io.fromRob.trap.bits.instr, hasTrap) 1476 } 1477 1478 val diffCriticalErrorEvent = DifftestModule(new DiffCriticalErrorEvent, delay = 4, dontCare = true) 1479 diffCriticalErrorEvent.valid := io.status.criticalErrorState && trapValid 1480 diffCriticalErrorEvent.coreid := hartId 1481 diffCriticalErrorEvent.criticalError := io.status.criticalErrorState 1482 1483 val diffCSRState = DifftestModule(new DiffCSRState) 1484 diffCSRState.coreid := hartId 1485 diffCSRState.privilegeMode := privState.PRVM.asUInt 1486 diffCSRState.mstatus := mstatus.rdata.asUInt 1487 diffCSRState.sstatus := mstatus.sstatus.asUInt 1488 diffCSRState.mepc := mepc.rdata.asUInt 1489 diffCSRState.sepc := sepc.rdata.asUInt 1490 diffCSRState.mtval := mtval.rdata.asUInt 1491 diffCSRState.stval := stval.rdata.asUInt 1492 diffCSRState.mtvec := mtvec.rdata.asUInt 1493 diffCSRState.stvec := stvec.rdata.asUInt 1494 diffCSRState.mcause := mcause.rdata.asUInt 1495 diffCSRState.scause := scause.rdata.asUInt 1496 diffCSRState.satp := satp.rdata.asUInt 1497 diffCSRState.mip := mip.rdata.asUInt 1498 diffCSRState.mie := mie.rdata.asUInt 1499 diffCSRState.mscratch := mscratch.rdata.asUInt 1500 diffCSRState.sscratch := sscratch.rdata.asUInt 1501 diffCSRState.mideleg := mideleg.rdata.asUInt 1502 diffCSRState.medeleg := medeleg.rdata.asUInt 1503 1504 val diffDebugMode = DifftestModule(new DiffDebugMode) 1505 diffDebugMode.coreid := hartId 1506 diffDebugMode.debugMode := debugMode 1507 diffDebugMode.dcsr := dcsr.rdata.asUInt 1508 diffDebugMode.dpc := dpc.rdata.asUInt 1509 diffDebugMode.dscratch0 := dscratch0.rdata.asUInt 1510 diffDebugMode.dscratch1 := dscratch1.rdata.asUInt 1511 1512 val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState) 1513 diffTriggerCSRState.coreid := hartId 1514 diffTriggerCSRState.tselect := tselect.rdata 1515 diffTriggerCSRState.tdata1 := tdata1.rdata 1516 diffTriggerCSRState.tinfo := tinfo.rdata 1517 1518 val diffVecCSRState = DifftestModule(new DiffVecCSRState) 1519 diffVecCSRState.coreid := hartId 1520 diffVecCSRState.vstart := vstart.rdata.asUInt 1521 diffVecCSRState.vxsat := vcsr.vxsat.asUInt 1522 diffVecCSRState.vxrm := vcsr.vxrm.asUInt 1523 diffVecCSRState.vcsr := vcsr.rdata.asUInt 1524 diffVecCSRState.vl := RegNext(io.fromRob.commit.vl) 1525 diffVecCSRState.vtype := vtype.rdata.asUInt 1526 diffVecCSRState.vlenb := vlenb.rdata.asUInt 1527 1528 val diffFpCSRState = DifftestModule(new DiffFpCSRState) 1529 diffFpCSRState.coreid := hartId 1530 diffFpCSRState.fcsr := fcsr.rdata.asUInt 1531 1532 val diffHCSRState = DifftestModule(new DiffHCSRState) 1533 diffHCSRState.coreid := hartId 1534 diffHCSRState.virtMode := privState.V.asBool 1535 diffHCSRState.mtval2 := mtval2.rdata.asUInt 1536 diffHCSRState.mtinst := mtinst.rdata.asUInt 1537 diffHCSRState.hstatus := hstatus.rdata.asUInt 1538 diffHCSRState.hideleg := hideleg.rdata.asUInt 1539 diffHCSRState.hedeleg := hedeleg.rdata.asUInt 1540 diffHCSRState.hcounteren := hcounteren.rdata.asUInt 1541 diffHCSRState.htval := htval.rdata.asUInt 1542 diffHCSRState.htinst := htinst.rdata.asUInt 1543 diffHCSRState.hgatp := hgatp.rdata.asUInt 1544 diffHCSRState.vsstatus := vsstatus.rdata.asUInt 1545 diffHCSRState.vstvec := vstvec.rdata.asUInt 1546 diffHCSRState.vsepc := vsepc.rdata.asUInt 1547 diffHCSRState.vscause := vscause.rdata.asUInt 1548 diffHCSRState.vstval := vstval.rdata.asUInt 1549 diffHCSRState.vsatp := vsatp.rdata.asUInt 1550 diffHCSRState.vsscratch := vsscratch.rdata.asUInt 1551 1552 val platformIRPMeipChange = !platformIRP.MEIP && RegNext(platformIRP.MEIP) || platformIRP.MEIP && !RegNext(platformIRP.MEIP) 1553 val platformIRPMtipChange = !platformIRP.MTIP && RegNext(platformIRP.MTIP) || platformIRP.MTIP && !RegNext(platformIRP.MTIP) 1554 val platformIRPMsipChange = !platformIRP.MSIP && RegNext(platformIRP.MSIP) || platformIRP.MSIP && !RegNext(platformIRP.MSIP) 1555 val platformIRPSeipChange = !platformIRP.SEIP && RegNext(platformIRP.SEIP) || platformIRP.SEIP && !RegNext(platformIRP.SEIP) 1556 val platformIRPStipChange = !sstcIRGen.o.STIP && RegNext(sstcIRGen.o.STIP) || sstcIRGen.o.STIP && !RegNext(sstcIRGen.o.STIP) 1557 val platformIRPVseipChange = !platformIRP.VSEIP && RegNext(platformIRP.VSEIP) || 1558 platformIRP.VSEIP && !RegNext(platformIRP.VSEIP) || 1559 !hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) && RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)) || 1560 hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) && !RegNext(hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt)) 1561 val platformIRPVstipChange = !sstcIRGen.o.VSTIP && RegNext(sstcIRGen.o.VSTIP) || sstcIRGen.o.VSTIP && !RegNext(sstcIRGen.o.VSTIP) 1562 val fromAIAMeipChange = !fromAIA.meip && RegNext(fromAIA.meip) || fromAIA.meip && !RegNext(fromAIA.meip) 1563 val fromAIASeipChange = !fromAIA.seip && RegNext(fromAIA.seip) || fromAIA.seip && !RegNext(fromAIA.seip) 1564 val lcofiReqChange = !lcofiReq && RegNext(lcofiReq) || lcofiReq && !RegNext(lcofiReq) 1565 1566 val diffNonRegInterruptPendingEvent = DifftestModule(new DiffNonRegInterruptPendingEvent) 1567 diffNonRegInterruptPendingEvent.coreid := hartId 1568 diffNonRegInterruptPendingEvent.valid := platformIRPMeipChange || platformIRPMtipChange || platformIRPMsipChange || 1569 platformIRPSeipChange || platformIRPStipChange || 1570 platformIRPVseipChange || platformIRPVstipChange || 1571 fromAIAMeipChange || fromAIASeipChange || 1572 lcofiReqChange 1573 diffNonRegInterruptPendingEvent.platformIRPMeip := platformIRP.MEIP 1574 diffNonRegInterruptPendingEvent.platformIRPMtip := platformIRP.MTIP 1575 diffNonRegInterruptPendingEvent.platformIRPMsip := platformIRP.MSIP 1576 diffNonRegInterruptPendingEvent.platformIRPSeip := platformIRP.SEIP 1577 diffNonRegInterruptPendingEvent.platformIRPStip := sstcIRGen.o.STIP 1578 diffNonRegInterruptPendingEvent.platformIRPVseip := platformIRP.VSEIP || hgeip.rdata.asUInt(hstatus.regOut.VGEIN.asUInt) 1579 diffNonRegInterruptPendingEvent.platformIRPVstip := sstcIRGen.o.VSTIP 1580 diffNonRegInterruptPendingEvent.fromAIAMeip := fromAIA.meip 1581 diffNonRegInterruptPendingEvent.fromAIASeip := fromAIA.seip 1582 diffNonRegInterruptPendingEvent.localCounterOverflowInterruptReq := mip.regOut.LCOFIP.asBool 1583 1584 val diffMhpmeventOverflowEvent = DifftestModule(new DiffMhpmeventOverflowEvent) 1585 diffMhpmeventOverflowEvent.coreid := hartId 1586 diffMhpmeventOverflowEvent.valid := Cat(mhpmevents.zipWithIndex.map{ case (event, i) => 1587 !ofFromPerfCntVec(i) && RegNext(ofFromPerfCntVec(i)) || ofFromPerfCntVec(i) && !RegNext(ofFromPerfCntVec(i)) 1588 }).orR 1589 diffMhpmeventOverflowEvent.mhpmeventOverflow := VecInit(mhpmevents.map(_.regOut.asInstanceOf[MhpmeventBundle].OF.asBool)).asUInt 1590 1591 val diffSyncAIAEvent = DifftestModule(new DiffSyncAIAEvent) 1592 diffSyncAIAEvent.coreid := hartId 1593 diffSyncAIAEvent.valid := fromAIA.rdata.valid 1594 diffSyncAIAEvent.mtopei := mtopei.rdata 1595 diffSyncAIAEvent.stopei := stopei.rdata 1596 diffSyncAIAEvent.vstopei := vstopei.rdata 1597 diffSyncAIAEvent.hgeip := hgeip.rdata 1598 1599 val diffCustomMflushpwr = DifftestModule(new DiffSyncCustomMflushpwrEvent) 1600 diffCustomMflushpwr.coreid := hartId 1601 diffCustomMflushpwr.valid := RegNext(io.fromTop.l2FlushDone) =/= io.fromTop.l2FlushDone 1602 diffCustomMflushpwr.l2FlushDone := io.fromTop.l2FlushDone 1603 } 1604} 1605 1606trait IpIeAliasConnect { 1607 self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel => 1608 1609 mip.fromMvip := mvip.toMip 1610 mip.fromSip := sip.toMip 1611 mip.fromVSip := vsip.toMip 1612 mvip.fromMip := mip.toMvip 1613 mvip.fromSip := sip.toMvip 1614 mvip.fromVSip := vsip.toMvip 1615 hvip.fromMip := mip.toHvip 1616 hvip.fromHip := hip.toHvip 1617 hvip.fromVSip := vsip.toHvip 1618 1619 mie.fromHie := hie.toMie 1620 mie.fromSie := sie.toMie 1621 mie.fromVSie := vsie.toMie 1622 sie.fromVSie := vsie.toSie 1623} 1624 1625object NewCSRMain extends App { 1626 val (config, firrtlOpts, firtoolOpts) = ArgParser.parse( 1627 args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog") 1628 1629 val defaultConfig = config.alterPartial({ 1630 // Get XSCoreParams and pass it to the "small module" 1631 case XSCoreParamsKey => config(XSTileKey).head 1632 }) 1633 1634 Generator.execute( 1635 firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend", 1636 new NewCSR()(defaultConfig), 1637 firtoolOpts 1638 ) 1639 1640 println("done") 1641}