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