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