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