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