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