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