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