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