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