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.rdataFields 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.stimecmp.U) 781 ) 782 783 // flush 784 val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegal // write to satp will cause the pipeline be flushed 785 786 val floatStatusOnOff = mstatus.w.wen && ( 787 mstatus.w.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off || 788 mstatus.w.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off 789 ) || mstatus.wAliasSstatus.wen && ( 790 mstatus.wAliasSstatus.wdataFields.FS === ContextStatus.Off && mstatus.regOut.FS =/= ContextStatus.Off || 791 mstatus.wAliasSstatus.wdataFields.FS =/= ContextStatus.Off && mstatus.regOut.FS === ContextStatus.Off 792 ) || vsstatus.w.wen && ( 793 vsstatus.w.wdataFields.FS === ContextStatus.Off && vsstatus.regOut.FS =/= ContextStatus.Off || 794 vsstatus.w.wdataFields.FS =/= ContextStatus.Off && vsstatus.regOut.FS === ContextStatus.Off 795 ) 796 797 val vectorStatusOnOff = mstatus.w.wen && ( 798 mstatus.w.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off || 799 mstatus.w.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off 800 ) || mstatus.wAliasSstatus.wen && ( 801 mstatus.wAliasSstatus.wdataFields.VS === ContextStatus.Off && mstatus.regOut.VS =/= ContextStatus.Off || 802 mstatus.wAliasSstatus.wdataFields.VS =/= ContextStatus.Off && mstatus.regOut.VS === ContextStatus.Off 803 ) || vsstatus.w.wen && ( 804 vsstatus.w.wdataFields.VS === ContextStatus.Off && vsstatus.regOut.VS =/= ContextStatus.Off || 805 vsstatus.w.wdataFields.VS =/= ContextStatus.Off && vsstatus.regOut.VS === ContextStatus.Off 806 ) 807 808 val triggerFrontendChange = Wire(Bool()) 809 810 val vstartChange = vstart.w.wen && ( 811 vstart.w.wdata === 0.U && vstart.regOut.vstart.asUInt =/= 0.U || 812 vstart.w.wdata =/= 0.U && vstart.regOut.vstart.asUInt === 0.U 813 ) 814 815 // flush pipe when write frm and data > 4 or write fcsr and data[7:5] > 4 or write frm/fcsr and frm is reserved 816 val frmIsReserved = fcsr.frm(2) && fcsr.frm(1, 0).orR 817 val frmWdataReserved = fcsr.wAliasFfm.wdata(2) && fcsr.wAliasFfm.wdata(1, 0).orR 818 val fcsrWdataReserved = fcsr.w.wdata(7) && fcsr.w.wdata(6, 5).orR 819 val frmChange = fcsr.wAliasFfm.wen && (!frmIsReserved && frmWdataReserved || frmIsReserved && !frmWdataReserved) || 820 fcsr.w.wen && (!frmIsReserved && fcsrWdataReserved || frmIsReserved && !fcsrWdataReserved) 821 822 val flushPipe = resetSatp || 823 triggerFrontendChange || floatStatusOnOff || vectorStatusOnOff || 824 vstartChange || frmChange 825 826 private val rdata = Mux1H(csrRwMap.map { case (id, (_, rdata)) => 827 if (vsMapS.contains(id)) { 828 ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> rdata 829 } else if (sMapVS.contains(id)) { 830 (!isModeVS && addr === id.U) -> rdata 831 } else { 832 (raddr === id.U) -> rdata 833 } 834 }) 835 836 private val regOut = Mux1H(csrOutMap.map { case (id, regOut) => 837 if (vsMapS.contains(id)) { 838 ((isModeVS && addr === vsMapS(id).U) || !isModeVS && addr === id.U) -> regOut 839 } else if (sMapVS.contains(id)) { 840 (!isModeVS && addr === id.U) -> regOut 841 } else { 842 (raddr === id.U) -> regOut 843 } 844 }) 845 846 private val needTargetUpdate = mnretEvent.out.targetPc.valid || mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid || 847 trapEntryMEvent.out.targetPc.valid || trapEntryMNEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid 848 849 private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR 850 851 private val s_idle :: s_waitIMSIC :: s_finish :: Nil = Enum(3) 852 853 /** the state machine of newCSR module */ 854 private val state = RegInit(s_idle) 855 /** the next state of newCSR */ 856 private val stateNext = WireInit(state) 857 state := stateNext 858 859 /** 860 * Asynchronous read operation of CSR. Check whether a read is asynchronous when read-enable is high. 861 * AIA registers are designed to be read asynchronously, so newCSR will wait for response. 862 **/ 863 private val asyncRead = ren && !(permitMod.io.out.EX_II || permitMod.io.out.EX_VI) && ( 864 mireg.addr.U === addr && miselect.inIMSICRange || 865 sireg.addr.U === addr && ((!V.asUInt.asBool && siselect.inIMSICRange) || (V.asUInt.asBool && vsiselect.inIMSICRange)) || 866 vsireg.addr.U === addr && vsiselect.inIMSICRange 867 ) 868 869 /** State machine of newCSR */ 870 switch(state) { 871 is(s_idle) { 872 when(valid && asyncRead) { 873 stateNext := s_waitIMSIC 874 }.elsewhen(valid && !io.out.ready) { 875 stateNext := s_finish 876 } 877 } 878 is(s_waitIMSIC) { 879 when(fromAIA.rdata.valid) { 880 when(io.out.ready) { 881 stateNext := s_idle 882 }.otherwise { 883 stateNext := s_finish 884 } 885 } 886 } 887 is(s_finish) { 888 when(io.out.ready) { 889 stateNext := s_idle 890 } 891 } 892 } 893 894 895 // Todo: check IMSIC EX_II and EX_VI 896 private val imsicIllegal = fromAIA.rdata.valid && fromAIA.rdata.bits.illegal 897 private val imsic_EX_II = imsicIllegal && !V.asUInt.asBool 898 private val imsic_EX_VI = imsicIllegal && V.asUInt.asBool 899 900 /** Set io.in.ready when state machine is ready to receive a new request synchronously */ 901 io.in.ready := (state === s_idle) 902 903 /** 904 * Valid signal of newCSR output. 905 * When in IDLE state, when input_valid is high, we set it. 906 * When in waitIMSIC state, and the next state is IDLE, we set it. 907 **/ 908 909 /** Data that have been read before,and should be stored because output not fired */ 910 io.out.valid := state === s_idle && valid && !asyncRead || 911 state === s_waitIMSIC && fromAIA.rdata.valid || 912 state === s_finish 913 io.out.bits.EX_II := DataHoldBypass(permitMod.io.out.EX_II || noCSRIllegal, false.B, io.in.fire) || 914 DataHoldBypass(imsic_EX_II, false.B, fromAIA.rdata.valid) 915 io.out.bits.EX_VI := DataHoldBypass(permitMod.io.out.EX_VI, false.B, io.in.fire) || 916 DataHoldBypass(imsic_EX_VI, false.B, fromAIA.rdata.valid) 917 io.out.bits.flushPipe := DataHoldBypass(flushPipe, false.B, io.in.fire) 918 919 /** Prepare read data for output */ 920 io.out.bits.rData := DataHoldBypass( 921 Mux1H(Seq( 922 io.in.fire -> rdata, 923 fromAIA.rdata.valid -> fromAIA.rdata.bits.data 924 )), 0.U(64.W), io.in.fire || fromAIA.rdata.valid) 925 io.out.bits.regOut := regOut 926 io.out.bits.targetPc := DataHoldBypass( 927 Mux(trapEntryDEvent.out.targetPc.valid, 928 trapEntryDEvent.out.targetPc.bits, 929 Mux1H(Seq( 930 mnretEvent.out.targetPc.valid -> mnretEvent.out.targetPc.bits, 931 mretEvent.out.targetPc.valid -> mretEvent.out.targetPc.bits, 932 sretEvent.out.targetPc.valid -> sretEvent.out.targetPc.bits, 933 dretEvent.out.targetPc.valid -> dretEvent.out.targetPc.bits, 934 trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits, 935 trapEntryMNEvent.out.targetPc.valid -> trapEntryMNEvent.out.targetPc.bits, 936 trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits, 937 trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits) 938 ) 939 ), 940 needTargetUpdate) 941 io.out.bits.targetPcUpdate := DataHoldBypass(needTargetUpdate, false.B, io.in.fire) 942 io.out.bits.isPerfCnt := DataHoldBypass(addrInPerfCnt, false.B, io.in.fire) 943 944 io.status.privState := privState 945 io.status.fpState.frm := fcsr.frm 946 io.status.fpState.off := mstatus.regOut.FS === ContextStatus.Off 947 io.status.vecState.vstart := vstart.rdata.asUInt 948 io.status.vecState.vxsat := vcsr.vxsat 949 io.status.vecState.vxrm := vcsr.vxrm 950 io.status.vecState.vcsr := vcsr.rdata.asUInt 951 io.status.vecState.vl := vl.rdata.asUInt 952 io.status.vecState.vtype := vtype.rdata.asUInt // Todo: check correct 953 io.status.vecState.vlenb := vlenb.rdata.asUInt 954 io.status.vecState.off := mstatus.regOut.VS === ContextStatus.Off 955 io.status.interrupt := intrMod.io.out.interruptVec.valid 956 io.status.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR 957 io.status.debugMode := debugMode 958 io.status.singleStepFlag := !debugMode && dcsr.regOut.STEP 959 960 /** 961 * debug_begin 962 */ 963 val tdata1Selected = Wire(new Tdata1Bundle) 964 tdata1Selected := tdata1.rdata 965 val dmodeInSelectedTrigger = tdata1Selected.DMODE.asBool 966 val triggerCanWrite = dmodeInSelectedTrigger && debugMode || !dmodeInSelectedTrigger 967 val tdata1Update = tdata1.w.wen && triggerCanWrite 968 val tdata2Update = tdata2.w.wen && triggerCanWrite 969 val tdata1Vec = tdata1RegVec.map{ mod => { 970 val tdata1Wire = Wire(new Tdata1Bundle) 971 tdata1Wire := mod.rdata 972 tdata1Wire 973 }} 974 975 val debugMod = Module(new Debug) 976 debugMod.io.in.trapInfo.valid := hasTrap 977 debugMod.io.in.trapInfo.bits.trapVec := trapVec.asUInt 978 debugMod.io.in.trapInfo.bits.intrVec := intrVec 979 debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt 980 debugMod.io.in.trapInfo.bits.trigger := trigger 981 debugMod.io.in.trapInfo.bits.singleStep := singleStep 982 debugMod.io.in.privState := privState 983 debugMod.io.in.debugMode := debugMode 984 debugMod.io.in.dcsr := dcsr.regOut 985 debugMod.io.in.tcontrol := tcontrol.regOut 986 debugMod.io.in.tselect := tselect.regOut 987 debugMod.io.in.tdata1Vec := tdata1Vec 988 debugMod.io.in.tdata1Selected := tdata1.rdata 989 debugMod.io.in.tdata2Selected := tdata2.rdata 990 debugMod.io.in.tdata1Update := tdata1Update 991 debugMod.io.in.tdata2Update := tdata2Update 992 debugMod.io.in.tdata1Wdata := wdata 993 994 entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode 995 996 trapEntryDEvent.valid := entryDebugMode 997 trapEntryDEvent.in.hasDebugIntr := debugMod.io.out.hasDebugIntr 998 trapEntryDEvent.in.debugMode := debugMode 999 trapEntryDEvent.in.hasTrap := hasTrap 1000 trapEntryDEvent.in.hasSingleStep := debugMod.io.out.hasSingleStep 1001 trapEntryDEvent.in.triggerEnterDebugMode := debugMod.io.out.triggerEnterDebugMode 1002 trapEntryDEvent.in.hasDebugEbreakException := debugMod.io.out.hasDebugEbreakException 1003 trapEntryDEvent.in.breakPoint := debugMod.io.out.breakPoint 1004 1005 trapHandleMod.io.in.trapInfo.bits.singleStep := debugMod.io.out.hasSingleStep 1006 1007 intrMod.io.in.debugMode := debugMode 1008 intrMod.io.in.debugIntr := debugIntr 1009 intrMod.io.in.dcsr := dcsr.regOut 1010 1011 tdata1RegVec.foreach { mod => 1012 mod match { 1013 case m: HasdebugModeBundle => 1014 m.debugMode := debugMode 1015 m.chainable := debugMod.io.out.newTriggerChainIsLegal 1016 case _ => 1017 } 1018 } 1019 tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => { 1020 mod1.w.wen := tdata1Update && (tselect.rdata === idx.U) 1021 mod1.w.wdata := wdata 1022 mod2.w.wen := tdata2Update && (tselect.rdata === idx.U) 1023 mod2.w.wdata := wdata 1024 }} 1025 1026 triggerFrontendChange := debugMod.io.out.triggerFrontendChange 1027 1028 io.status.frontendTrigger := debugMod.io.out.frontendTrigger 1029 io.status.memTrigger := debugMod.io.out.memTrigger 1030 /** 1031 * debug_end 1032 */ 1033 1034 /** 1035 * perf_begin 1036 * perf number: 29 (frontend 8, ctrlblock 8, memblock 8, huancun 5) 1037 */ 1038 // tmp: mhpmevents is wrapper of perfEvents, read/write/update mhpmevents -> read/write/update perfEvents 1039 val csrevents = perfEvents.slice(24, 29) 1040 1041 val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent)) 1042 for (i <- 0 until numPCntHc * coreParams.L2NBanks) { 1043 hcEvents(i) := io.perf.perfEventsHc(i) 1044 } 1045 1046 val hpmHc = HPerfMonitor(csrevents, hcEvents) 1047 1048 val privState1H = Cat(privState.isModeM, privState.isModeHS, privState.isModeHU, privState.isModeVS, privState.isModeVU) 1049 val countingEn = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool()))) 1050 for (i <-0 until perfCntNum) { 1051 countingEn(i) := ((~mhpmevents(i).rdata(62, 58)).asUInt & privState1H).orR 1052 } 1053 val allPerfEvents = io.perf.perfEventsFrontend ++ 1054 io.perf.perfEventsBackend ++ 1055 io.perf.perfEventsLsu ++ 1056 hpmHc.getPerf 1057 1058 val ofFromPerfCntVec = Wire(Vec(perfCntNum, Bool())) 1059 val lcofiReqVec = Wire(Vec(perfCntNum, Bool())) 1060 for(i <- 0 until perfCntNum) { 1061 mhpmcounters(i) match { 1062 case m: HasPerfCounterBundle => 1063 m.countingEn := countingEn(i) 1064 m.perf := allPerfEvents(i) 1065 ofFromPerfCntVec(i) := m.toMhpmeventOF 1066 case _ => 1067 } 1068 perfEvents(i) := Mux(mhpmevents(i).w.wen, wdata, (perfEvents(i).head(1).asBool || ofFromPerfCntVec(i)) ## perfEvents(i).tail(1)) 1069 lcofiReqVec(i) := ofFromPerfCntVec(i) && !mhpmevents(i).rdata.head(1) 1070 } 1071 1072 val lcofiReq = lcofiReqVec.asUInt.orR 1073 mip match { 1074 case m: HasLocalInterruptReqBundle => 1075 m.lcofiReq := lcofiReq 1076 case _ => 1077 } 1078 /** 1079 * perf_end 1080 */ 1081 1082 /** 1083 * [[io.status.custom]] connection 1084 */ 1085 io.status.custom.l1I_pf_enable := spfctl.regOut.L1I_PF_ENABLE.asBool 1086 io.status.custom.l2_pf_enable := spfctl.regOut.L2_PF_ENABLE.asBool 1087 io.status.custom.l1D_pf_enable := spfctl.regOut.L1D_PF_ENABLE.asBool 1088 io.status.custom.l1D_pf_train_on_hit := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool 1089 io.status.custom.l1D_pf_enable_agt := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool 1090 io.status.custom.l1D_pf_enable_pht := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool 1091 io.status.custom.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt 1092 io.status.custom.l1D_pf_active_stride := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt 1093 io.status.custom.l1D_pf_enable_stride := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool 1094 io.status.custom.l2_pf_store_only := spfctl.regOut.L2_PF_STORE_ONLY.asBool 1095 1096 io.status.custom.icache_parity_enable := sfetchctl.regOut.ICACHE_PARITY_ENABLE.asBool 1097 1098 io.status.custom.lvpred_disable := slvpredctl.regOut.LVPRED_DISABLE.asBool 1099 io.status.custom.no_spec_load := slvpredctl.regOut.NO_SPEC_LOAD.asBool 1100 io.status.custom.storeset_wait_store := slvpredctl.regOut.STORESET_WAIT_STORE.asBool 1101 io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool 1102 io.status.custom.lvpred_timeout := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt 1103 1104 io.status.custom.bp_ctrl.ubtb_enable := sbpctl.regOut.UBTB_ENABLE .asBool 1105 io.status.custom.bp_ctrl.btb_enable := sbpctl.regOut.BTB_ENABLE .asBool 1106 io.status.custom.bp_ctrl.bim_enable := sbpctl.regOut.BIM_ENABLE .asBool 1107 io.status.custom.bp_ctrl.tage_enable := sbpctl.regOut.TAGE_ENABLE .asBool 1108 io.status.custom.bp_ctrl.sc_enable := sbpctl.regOut.SC_ENABLE .asBool 1109 io.status.custom.bp_ctrl.ras_enable := sbpctl.regOut.RAS_ENABLE .asBool 1110 io.status.custom.bp_ctrl.loop_enable := sbpctl.regOut.LOOP_ENABLE .asBool 1111 1112 io.status.custom.sbuffer_threshold := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt 1113 io.status.custom.ldld_vio_check_enable := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool 1114 io.status.custom.soft_prefetch_enable := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool 1115 io.status.custom.cache_error_enable := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool 1116 io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool 1117 io.status.custom.hd_misalign_st_enable := smblockctl.regOut.HD_MISALIGN_ST_ENABLE.asBool 1118 io.status.custom.hd_misalign_ld_enable := smblockctl.regOut.HD_MISALIGN_LD_ENABLE.asBool 1119 1120 io.status.custom.fusion_enable := srnctl.regOut.FUSION_ENABLE.asBool 1121 io.status.custom.wfi_enable := srnctl.regOut.WFI_ENABLE.asBool 1122 1123 io.status.instrAddrTransType.bare := privState.isModeM || 1124 (!privState.isVirtual && satp.regOut.MODE === SatpMode.Bare) || 1125 (privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Bare) 1126 io.status.instrAddrTransType.sv39 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv39 || 1127 privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv39 1128 io.status.instrAddrTransType.sv48 := !privState.isModeM && !privState.isVirtual && satp.regOut.MODE === SatpMode.Sv48 || 1129 privState.isVirtual && vsatp.regOut.MODE === SatpMode.Sv48 1130 io.status.instrAddrTransType.sv39x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv39x4 1131 io.status.instrAddrTransType.sv48x4 := privState.isVirtual && vsatp.regOut.MODE === SatpMode.Bare && hgatp.regOut.MODE === HgatpMode.Sv48x4 1132 assert(PopCount(io.status.instrAddrTransType.asUInt) === 1.U, "Exactly one inst trans type should be asserted") 1133 1134 private val csrAccess = wen || ren 1135 1136 private val imsicAddrValid = 1137 csrAccess && addr === CSRs.mireg.U && miselect.inIMSICRange || 1138 csrAccess && addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange || 1139 csrAccess && (addr === CSRs.sireg.U && isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange 1140 1141 private val imsicAddr = Mux1H(Seq( 1142 (csrAccess && addr === CSRs.mireg.U) -> miselect.rdata, 1143 (csrAccess && addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata, 1144 (csrAccess && (addr === CSRs.sireg.U && isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata, 1145 )) 1146 1147 private val imsicAddrPrivState = Mux1H(Seq( 1148 (csrAccess && addr === CSRs.mireg.U) -> PrivState.ModeM, 1149 (csrAccess && addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS, 1150 (csrAccess && (addr === CSRs.sireg.U && isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS, 1151 )) 1152 1153 private val imsicWdataValid = 1154 mireg.w.wen && miselect.inIMSICRange || 1155 sireg.w.wen && siselect.inIMSICRange || 1156 vsireg.w.wen && vsiselect.inIMSICRange 1157 1158 toAIA.addr.valid := imsicAddrValid 1159 toAIA.addr.bits.addr := imsicAddr 1160 toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM 1161 toAIA.addr.bits.v := imsicAddrPrivState.V 1162 1163 toAIA.wdata.valid := imsicWdataValid 1164 toAIA.wdata.bits.op := io.in.bits.op 1165 toAIA.wdata.bits.data := io.in.bits.src 1166 toAIA.vgein := hstatus.regOut.VGEIN.asUInt 1167 toAIA.mClaim := mtopei.w.wen 1168 toAIA.sClaim := stopei.w.wen 1169 toAIA.vsClaim := vstopei.w.wen 1170 1171 // tlb 1172 io.tlb.satpASIDChanged := GatedValidRegNext(wenLegal && addr === CSRs. satp.U && satp .regOut.ASID =/= satp.w.wdataFields.ASID) 1173 io.tlb.vsatpASIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.vsatp.U && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID) 1174 io.tlb.hgatpVMIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.hgatp.U && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID) 1175 io.tlb.satp := satp.rdata 1176 io.tlb.vsatp := vsatp.rdata 1177 io.tlb.hgatp := hgatp.rdata 1178 io.tlb.mxr := mstatus.regOut.MXR.asBool 1179 io.tlb.sum := mstatus.regOut.SUM.asBool 1180 io.tlb.vmxr := vsstatus.regOut.MXR.asBool 1181 io.tlb.vsum := vsstatus.regOut.SUM.asBool 1182 io.tlb.spvp := hstatus.regOut.SPVP.asBool 1183 1184 io.tlb.imode := PRVM.asUInt 1185 // when NMIE is zero, force to behave as MPRV is zero 1186 io.tlb.dmode := Mux( 1187 (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE, 1188 mstatus.regOut.MPP.asUInt, 1189 PRVM.asUInt 1190 ) 1191 io.tlb.dvirt := Mux( 1192 (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mnstatus.regOut.NMIE && mstatus.regOut.MPP =/= PrivMode.M, 1193 mstatus.regOut.MPV.asUInt, 1194 V.asUInt 1195 ) 1196 io.tlb.mPBMTE := RegNext(menvcfg.regOut.PBMTE.asBool) 1197 io.tlb.hPBMTE := RegNext(henvcfg.regOut.PBMTE.asBool) 1198 1199 io.toDecode.illegalInst.sfenceVMA := isModeHS && mstatus.regOut.TVM || isModeHU 1200 io.toDecode.virtualInst.sfenceVMA := isModeVS && hstatus.regOut.VTVM || isModeVU 1201 io.toDecode.illegalInst.sfencePart := isModeHU 1202 io.toDecode.virtualInst.sfencePart := isModeVU 1203 io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU 1204 io.toDecode.illegalInst.hfenceVVMA := isModeHU 1205 io.toDecode.virtualInst.hfence := isModeVS || isModeVU 1206 io.toDecode.illegalInst.hlsv := isModeHU && !hstatus.regOut.HU 1207 io.toDecode.virtualInst.hlsv := isModeVS || isModeVU 1208 io.toDecode.illegalInst.fsIsOff := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off 1209 io.toDecode.illegalInst.vsIsOff := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off 1210 io.toDecode.illegalInst.wfi := isModeHU || !isModeM && mstatus.regOut.TW 1211 io.toDecode.virtualInst.wfi := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW 1212 io.toDecode.illegalInst.frm := frmIsReserved 1213 // Ref: The RISC-V Instruction Set Manual Volume I - 20.5. Control and Status Register State 1214 io.toDecode.illegalInst.cboZ := !isModeM && !menvcfg.regOut.CBZE || isModeHU && !senvcfg.regOut.CBZE 1215 io.toDecode.virtualInst.cboZ := menvcfg.regOut.CBZE && ( 1216 isModeVS && !henvcfg.regOut.CBZE || 1217 isModeVU && !(henvcfg.regOut.CBZE && senvcfg.regOut.CBZE) 1218 ) 1219 io.toDecode.illegalInst.cboCF := !isModeM && !menvcfg.regOut.CBCFE || isModeHU && !senvcfg.regOut.CBCFE 1220 io.toDecode.virtualInst.cboCF := menvcfg.regOut.CBCFE && ( 1221 isModeVS && !henvcfg.regOut.CBCFE || 1222 isModeVU && !(henvcfg.regOut.CBCFE && senvcfg.regOut.CBCFE) 1223 ) 1224 io.toDecode.illegalInst.cboI := 1225 !isModeM && menvcfg.regOut.CBIE === EnvCBIE.Off || 1226 isModeHU && senvcfg.regOut.CBIE === EnvCBIE.Off 1227 io.toDecode.virtualInst.cboI := menvcfg.regOut.CBIE =/= EnvCBIE.Off && ( 1228 isModeVS && henvcfg.regOut.CBIE === EnvCBIE.Off || 1229 isModeVU &&(henvcfg.regOut.CBIE === EnvCBIE.Off || senvcfg.regOut.CBIE === EnvCBIE.Off) 1230 ) 1231 io.toDecode.special.cboI2F := !io.toDecode.illegalInst.cboI && !io.toDecode.virtualInst.cboI && ( 1232 menvcfg.regOut.CBIE === EnvCBIE.Flush && !isModeM || 1233 senvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeHU || isModeVU) || 1234 henvcfg.regOut.CBIE === EnvCBIE.Flush && (isModeVS || isModeVU) 1235 ) 1236 1237 // Always instantiate basic difftest modules. 1238 if (env.AlwaysBasicDiff || env.EnableDifftest) { 1239 val hartId = io.fromTop.hartId 1240 val trapValid = io.fromRob.trap.valid 1241 val trapNO = Mux(virtualInterruptIsHvictlInject && hasTrap, hvictl.regOut.IID.asUInt, trapHandleMod.io.out.causeNO.ExceptionCode.asUInt) 1242 val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool 1243 val hasNMI = nmi && hasTrap 1244 val interruptNO = Mux(interrupt, trapNO, 0.U) 1245 val exceptionNO = Mux(!interrupt, trapNO, 0.U) 1246 val isSv39: Bool = 1247 (isModeHS || isModeHU) && satp.regOut.MODE === SatpMode.Sv39 || 1248 (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv39 1249 val isSv48: Bool = 1250 (isModeHS || isModeHU) && satp.regOut.MODE === SatpMode.Sv48 || 1251 (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv48 1252 val isBare = !isSv39 && !isSv48 1253 val sv39PC = SignExt(trapPC.take(39), XLEN) 1254 val sv48PC = SignExt(trapPC.take(48), XLEN) 1255 val barePC = ZeroExt(trapPC.take(PAddrBits), XLEN) 1256 // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57 1257 val exceptionPC = Mux1H(Seq( 1258 isSv39 -> sv39PC, 1259 isSv48 -> sv48PC, 1260 isBare -> barePC, 1261 )) 1262 1263 val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true) 1264 diffArchEvent.coreid := hartId 1265 diffArchEvent.valid := trapValid 1266 diffArchEvent.interrupt := interruptNO 1267 diffArchEvent.exception := exceptionNO 1268 diffArchEvent.exceptionPC := exceptionPC 1269 diffArchEvent.hasNMI := hasNMI 1270 diffArchEvent.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject && hasTrap 1271 if (env.EnableDifftest) { 1272 diffArchEvent.exceptionInst := io.fromRob.trap.bits.instr 1273 } 1274 1275 val diffCSRState = DifftestModule(new DiffCSRState) 1276 diffCSRState.coreid := hartId 1277 diffCSRState.privilegeMode := privState.PRVM.asUInt 1278 diffCSRState.mstatus := mstatus.rdata.asUInt 1279 diffCSRState.sstatus := mstatus.sstatus.asUInt 1280 diffCSRState.mepc := mepc.rdata.asUInt 1281 diffCSRState.sepc := sepc.rdata.asUInt 1282 diffCSRState.mtval := mtval.rdata.asUInt 1283 diffCSRState.stval := stval.rdata.asUInt 1284 diffCSRState.mtvec := mtvec.rdata.asUInt 1285 diffCSRState.stvec := stvec.rdata.asUInt 1286 diffCSRState.mcause := mcause.rdata.asUInt 1287 diffCSRState.scause := scause.rdata.asUInt 1288 diffCSRState.satp := satp.rdata.asUInt 1289 diffCSRState.mip := mip.regOut.asUInt 1290 diffCSRState.mie := mie.rdata.asUInt 1291 diffCSRState.mscratch := mscratch.rdata.asUInt 1292 diffCSRState.sscratch := sscratch.rdata.asUInt 1293 diffCSRState.mideleg := mideleg.rdata.asUInt 1294 diffCSRState.medeleg := medeleg.rdata.asUInt 1295 1296 val diffDebugMode = DifftestModule(new DiffDebugMode) 1297 diffDebugMode.coreid := hartId 1298 diffDebugMode.debugMode := debugMode 1299 diffDebugMode.dcsr := dcsr.rdata.asUInt 1300 diffDebugMode.dpc := dpc.rdata.asUInt 1301 diffDebugMode.dscratch0 := dscratch0.rdata.asUInt 1302 diffDebugMode.dscratch1 := dscratch1.rdata.asUInt 1303 1304 val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState) 1305 diffTriggerCSRState.coreid := hartId 1306 diffTriggerCSRState.tselect := tselect.rdata 1307 diffTriggerCSRState.tdata1 := tdata1.rdata 1308 diffTriggerCSRState.tinfo := tinfo.rdata 1309 diffTriggerCSRState.tcontrol := tcontrol.rdata 1310 1311 val diffVecCSRState = DifftestModule(new DiffVecCSRState) 1312 diffVecCSRState.coreid := hartId 1313 diffVecCSRState.vstart := vstart.rdata.asUInt 1314 diffVecCSRState.vxsat := vcsr.vxsat.asUInt 1315 diffVecCSRState.vxrm := vcsr.vxrm.asUInt 1316 diffVecCSRState.vcsr := vcsr.rdata.asUInt 1317 diffVecCSRState.vl := RegNext(io.fromRob.commit.vl) 1318 diffVecCSRState.vtype := vtype.rdata.asUInt 1319 diffVecCSRState.vlenb := vlenb.rdata.asUInt 1320 1321 val diffFpCSRState = DifftestModule(new DiffFpCSRState) 1322 diffFpCSRState.coreid := hartId 1323 diffFpCSRState.fcsr := fcsr.rdata.asUInt 1324 1325 val diffHCSRState = DifftestModule(new DiffHCSRState) 1326 diffHCSRState.coreid := hartId 1327 diffHCSRState.virtMode := privState.V.asBool 1328 diffHCSRState.mtval2 := mtval2.rdata.asUInt 1329 diffHCSRState.mtinst := mtinst.rdata.asUInt 1330 diffHCSRState.hstatus := hstatus.rdata.asUInt 1331 diffHCSRState.hideleg := hideleg.rdata.asUInt 1332 diffHCSRState.hedeleg := hedeleg.rdata.asUInt 1333 diffHCSRState.hcounteren := hcounteren.rdata.asUInt 1334 diffHCSRState.htval := htval.rdata.asUInt 1335 diffHCSRState.htinst := htinst.rdata.asUInt 1336 diffHCSRState.hgatp := hgatp.rdata.asUInt 1337 diffHCSRState.vsstatus := vsstatus.rdata.asUInt 1338 diffHCSRState.vstvec := vstvec.rdata.asUInt 1339 diffHCSRState.vsepc := vsepc.rdata.asUInt 1340 diffHCSRState.vscause := vscause.rdata.asUInt 1341 diffHCSRState.vstval := vstval.rdata.asUInt 1342 diffHCSRState.vsatp := vsatp.rdata.asUInt 1343 diffHCSRState.vsscratch := vsscratch.rdata.asUInt 1344 1345 } 1346} 1347 1348trait IpIeAliasConnect { 1349 self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel => 1350 1351 mip.fromMvip := mvip.toMip 1352 mip.fromSip := sip.toMip 1353 mip.fromVSip := vsip.toMip 1354 mvip.fromMip := mip.toMvip 1355 mvip.fromSip := sip.toMvip 1356 mvip.fromVSip := vsip.toMvip 1357 hvip.fromMip := mip.toHvip 1358 hvip.fromHip := hip.toHvip 1359 hvip.fromVSip := vsip.toHvip 1360 1361 mie.fromHie := hie.toMie 1362 mie.fromSie := sie.toMie 1363 mie.fromVSie := vsie.toMie 1364 sie.fromVSie := vsie.toSie 1365} 1366 1367object NewCSRMain extends App { 1368 val (config, firrtlOpts, firtoolOpts) = ArgParser.parse( 1369 args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog") 1370 1371 val defaultConfig = config.alterPartial({ 1372 // Get XSCoreParams and pass it to the "small module" 1373 case XSCoreParamsKey => config(XSTileKey).head 1374 }) 1375 1376 Generator.execute( 1377 firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend", 1378 new NewCSR()(defaultConfig), 1379 firtoolOpts 1380 ) 1381 1382 println("done") 1383}