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 val tdata1Selected = Wire(new Tdata1Bundle) 853 tdata1Selected := tdata1.rdata 854 val dmodeInSelectedTrigger = tdata1Selected.DMODE.asBool 855 val triggerCanWrite = dmodeInSelectedTrigger && debugMode || !dmodeInSelectedTrigger 856 val tdata1Update = tdata1.w.wen && triggerCanWrite 857 val tdata2Update = tdata2.w.wen && triggerCanWrite 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}