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