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 val csrevents = perfEvents.slice(24, 29) 929 930 val hcEvents = Wire(Vec(numPCntHc * coreParams.L2NBanks, new PerfEvent)) 931 for (i <- 0 until numPCntHc * coreParams.L2NBanks) { 932 hcEvents(i) := io.perf.perfEventsHc(i) 933 } 934 935 val allHcPerfEvents = hcEvents.map(x => (s"Hc", x.value)) 936 if (printEventCoding) { 937 for (((name, inc), i) <- allHcPerfEvents.zipWithIndex) { 938 println("HuanCun perfEvents Set", name, inc, i) 939 } 940 } 941 942 val hpmHc = HPerfMonitor(csrevents, hcEvents) 943 944 val privState1H = Cat(privState.isModeM, privState.isModeHS, privState.isModeHU, privState.isModeVS, privState.isModeVU) 945 val countingEn = RegInit(0.U.asTypeOf(Vec(perfCntNum, Bool()))) 946 for (i <-0 until perfCntNum) { 947 countingEn(i) := ((~mhpmevents(i).rdata(62, 58)).asUInt & privState1H).orR 948 } 949 val allPerfEvents = io.perf.perfEventsFrontend ++ 950 io.perf.perfEventsBackend ++ 951 io.perf.perfEventsLsu ++ 952 hpmHc.getPerf 953 954 val ofFromPerfCntVec = Wire(Vec(perfCntNum, Bool())) 955 val lcofiReqVec = Wire(Vec(perfCntNum, Bool())) 956 for(i <- 0 until perfCntNum) { 957 mhpmcounters(i) match { 958 case m: HasPerfCounterBundle => 959 m.countingEn := countingEn(i) 960 m.perf := allPerfEvents(i) 961 ofFromPerfCntVec(i) := m.toMhpmeventOF 962 case _ => 963 } 964 perfEvents(i) := Mux(mhpmevents(i).w.wen, wdata, (perfEvents(i).head(1).asBool || ofFromPerfCntVec(i)) ## perfEvents(i).tail(1)) 965 lcofiReqVec(i) := ofFromPerfCntVec(i) && !mhpmevents(i).rdata.head(1) 966 } 967 968 val lcofiReq = lcofiReqVec.asUInt.orR 969 mip match { 970 case m: HasLocalInterruptReqBundle => 971 m.lcofiReq := lcofiReq 972 case _ => 973 } 974 /** 975 * perf_end 976 */ 977 978 /** 979 * [[io.status.custom]] connection 980 */ 981 io.status.custom.l1I_pf_enable := spfctl.regOut.L1I_PF_ENABLE.asBool 982 io.status.custom.l2_pf_enable := spfctl.regOut.L2_PF_ENABLE.asBool 983 io.status.custom.l1D_pf_enable := spfctl.regOut.L1D_PF_ENABLE.asBool 984 io.status.custom.l1D_pf_train_on_hit := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool 985 io.status.custom.l1D_pf_enable_agt := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool 986 io.status.custom.l1D_pf_enable_pht := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool 987 io.status.custom.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt 988 io.status.custom.l1D_pf_active_stride := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt 989 io.status.custom.l1D_pf_enable_stride := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool 990 io.status.custom.l2_pf_store_only := spfctl.regOut.L2_PF_STORE_ONLY.asBool 991 992 io.status.custom.icache_parity_enable := sfetchctl.regOut.ICACHE_PARITY_ENABLE.asBool 993 994 io.status.custom.lvpred_disable := slvpredctl.regOut.LVPRED_DISABLE.asBool 995 io.status.custom.no_spec_load := slvpredctl.regOut.NO_SPEC_LOAD.asBool 996 io.status.custom.storeset_wait_store := slvpredctl.regOut.STORESET_WAIT_STORE.asBool 997 io.status.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool 998 io.status.custom.lvpred_timeout := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt 999 1000 io.status.custom.bp_ctrl.ubtb_enable := sbpctl.regOut.UBTB_ENABLE .asBool 1001 io.status.custom.bp_ctrl.btb_enable := sbpctl.regOut.BTB_ENABLE .asBool 1002 io.status.custom.bp_ctrl.bim_enable := sbpctl.regOut.BIM_ENABLE .asBool 1003 io.status.custom.bp_ctrl.tage_enable := sbpctl.regOut.TAGE_ENABLE .asBool 1004 io.status.custom.bp_ctrl.sc_enable := sbpctl.regOut.SC_ENABLE .asBool 1005 io.status.custom.bp_ctrl.ras_enable := sbpctl.regOut.RAS_ENABLE .asBool 1006 io.status.custom.bp_ctrl.loop_enable := sbpctl.regOut.LOOP_ENABLE .asBool 1007 1008 io.status.custom.sbuffer_threshold := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt 1009 io.status.custom.ldld_vio_check_enable := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool 1010 io.status.custom.soft_prefetch_enable := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool 1011 io.status.custom.cache_error_enable := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool 1012 io.status.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool 1013 io.status.custom.hd_misalign_st_enable := smblockctl.regOut.HD_MISALIGN_ST_ENABLE.asBool 1014 io.status.custom.hd_misalign_ld_enable := smblockctl.regOut.HD_MISALIGN_LD_ENABLE.asBool 1015 1016 io.status.custom.fusion_enable := srnctl.regOut.FUSION_ENABLE.asBool 1017 io.status.custom.wfi_enable := srnctl.regOut.WFI_ENABLE.asBool 1018 1019 private val csrAccess = wen || ren 1020 1021 private val imsicAddrValid = 1022 csrAccess && addr === CSRs.mireg.U && miselect.inIMSICRange || 1023 csrAccess && addr === CSRs.sireg.U && !isModeVS && siselect.inIMSICRange || 1024 csrAccess && (addr === CSRs.sireg.U && isModeVS || addr === CSRs.vsireg.U) && vsiselect.inIMSICRange 1025 1026 private val imsicAddr = Mux1H(Seq( 1027 (csrAccess && addr === CSRs.mireg.U) -> miselect.rdata, 1028 (csrAccess && addr === CSRs.sireg.U && !isModeVS) -> siselect.rdata, 1029 (csrAccess && (addr === CSRs.sireg.U && isModeVS || addr === CSRs.vsireg.U)) -> vsiselect.rdata, 1030 )) 1031 1032 private val imsicAddrPrivState = Mux1H(Seq( 1033 (csrAccess && addr === CSRs.mireg.U) -> PrivState.ModeM, 1034 (csrAccess && addr === CSRs.sireg.U && !isModeVS) -> PrivState.ModeHS, 1035 (csrAccess && (addr === CSRs.sireg.U && isModeVS || addr === CSRs.vsireg.U)) -> PrivState.ModeVS, 1036 )) 1037 1038 private val imsicWdataValid = 1039 mireg.w.wen && miselect.inIMSICRange || 1040 sireg.w.wen && siselect.inIMSICRange || 1041 vsireg.w.wen && vsiselect.inIMSICRange 1042 1043 toAIA.addr.valid := imsicAddrValid 1044 toAIA.addr.bits.addr := imsicAddr 1045 toAIA.addr.bits.prvm := imsicAddrPrivState.PRVM 1046 toAIA.addr.bits.v := imsicAddrPrivState.V 1047 1048 toAIA.wdata.valid := imsicWdataValid 1049 toAIA.wdata.bits.op := io.in.bits.op 1050 toAIA.wdata.bits.data := io.in.bits.src 1051 toAIA.vgein := hstatus.regOut.VGEIN.asUInt 1052 toAIA.mClaim := mtopei.w.wen 1053 toAIA.sClaim := stopei.w.wen 1054 toAIA.vsClaim := vstopei.w.wen 1055 1056 // tlb 1057 io.tlb.satpASIDChanged := GatedValidRegNext(wenLegal && addr === CSRs. satp.U && satp .regOut.ASID =/= satp.w.wdataFields.ASID) 1058 io.tlb.vsatpASIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.vsatp.U && vsatp.regOut.ASID =/= vsatp.w.wdataFields.ASID) 1059 io.tlb.hgatpVMIDChanged := GatedValidRegNext(wenLegal && addr === CSRs.hgatp.U && hgatp.regOut.VMID =/= hgatp.w.wdataFields.VMID) 1060 io.tlb.satp := satp.rdata 1061 io.tlb.vsatp := vsatp.rdata 1062 io.tlb.hgatp := hgatp.rdata 1063 io.tlb.mxr := mstatus.regOut.MXR.asBool 1064 io.tlb.sum := mstatus.regOut.SUM.asBool 1065 io.tlb.vmxr := vsstatus.regOut.MXR.asBool 1066 io.tlb.vsum := vsstatus.regOut.SUM.asBool 1067 io.tlb.spvp := hstatus.regOut.SPVP.asBool 1068 1069 io.tlb.imode := PRVM.asUInt 1070 io.tlb.dmode := Mux( 1071 (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV, 1072 mstatus.regOut.MPP.asUInt, 1073 PRVM.asUInt 1074 ) 1075 io.tlb.dvirt := Mux( 1076 (debugMode && dcsr.regOut.MPRVEN || !debugMode) && mstatus.regOut.MPRV && mstatus.regOut.MPP =/= PrivMode.M, 1077 mstatus.regOut.MPV.asUInt, 1078 V.asUInt 1079 ) 1080 1081 io.toDecode.illegalInst.sfenceVMA := isModeHS && mstatus.regOut.TVM || isModeHU 1082 io.toDecode.virtualInst.sfenceVMA := isModeVS && hstatus.regOut.VTVM || isModeVU 1083 io.toDecode.illegalInst.sfencePart := isModeHU 1084 io.toDecode.virtualInst.sfencePart := isModeVU 1085 io.toDecode.illegalInst.hfenceGVMA := isModeHS && mstatus.regOut.TVM || isModeHU 1086 io.toDecode.illegalInst.hfenceVVMA := isModeHU 1087 io.toDecode.virtualInst.hfence := isModeVS || isModeVU 1088 io.toDecode.illegalInst.hlsv := isModeHU && !hstatus.regOut.HU 1089 io.toDecode.virtualInst.hlsv := isModeVS || isModeVU 1090 io.toDecode.illegalInst.fsIsOff := mstatus.regOut.FS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.FS === ContextStatus.Off 1091 io.toDecode.illegalInst.vsIsOff := mstatus.regOut.VS === ContextStatus.Off || (isModeVS || isModeVU) && vsstatus.regOut.VS === ContextStatus.Off 1092 io.toDecode.illegalInst.wfi := isModeHU || !isModeM && mstatus.regOut.TW 1093 io.toDecode.virtualInst.wfi := isModeVS && !mstatus.regOut.TW && hstatus.regOut.VTW || isModeVU && !mstatus.regOut.TW 1094 io.toDecode.illegalInst.frm := frmIsReserved 1095 1096 // Always instantiate basic difftest modules. 1097 if (env.AlwaysBasicDiff || env.EnableDifftest) { 1098 val hartId = io.fromTop.hartId 1099 val trapValid = io.fromRob.trap.valid 1100 val trapNO = trapHandleMod.io.out.causeNO.ExceptionCode.asUInt 1101 val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool 1102 val interruptNO = Mux(interrupt, trapNO, 0.U) 1103 val exceptionNO = Mux(!interrupt, trapNO, 0.U) 1104 val isSv39: Bool = 1105 (isModeHS || isModeHU) && satp.regOut.MODE === SatpMode.Sv39 || 1106 (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv39 1107 val isSv48: Bool = 1108 (isModeHS || isModeHU) && satp.regOut.MODE === SatpMode.Sv48 || 1109 (isModeVS || isModeVU) && vsatp.regOut.MODE === SatpMode.Sv48 1110 val isBare = !isSv39 && !isSv48 1111 val sv39PC = SignExt(trapPC.take(39), XLEN) 1112 val sv48PC = SignExt(trapPC.take(48), XLEN) 1113 val barePC = ZeroExt(trapPC.take(PAddrBits), XLEN) 1114 // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57 1115 val exceptionPC = Mux1H(Seq( 1116 isSv39 -> sv39PC, 1117 isSv48 -> sv48PC, 1118 isBare -> barePC, 1119 )) 1120 1121 val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true) 1122 diffArchEvent.coreid := hartId 1123 diffArchEvent.valid := trapValid 1124 diffArchEvent.interrupt := interruptNO 1125 diffArchEvent.exception := exceptionNO 1126 diffArchEvent.exceptionPC := exceptionPC 1127 if (env.EnableDifftest) { 1128 diffArchEvent.exceptionInst := io.fromRob.trap.bits.instr 1129 } 1130 1131 val diffCSRState = DifftestModule(new DiffCSRState) 1132 diffCSRState.coreid := hartId 1133 diffCSRState.privilegeMode := privState.PRVM.asUInt 1134 diffCSRState.mstatus := mstatus.rdata.asUInt 1135 diffCSRState.sstatus := mstatus.sstatus.asUInt 1136 diffCSRState.mepc := mepc.rdata.asUInt 1137 diffCSRState.sepc := sepc.rdata.asUInt 1138 diffCSRState.mtval := mtval.rdata.asUInt 1139 diffCSRState.stval := stval.rdata.asUInt 1140 diffCSRState.mtvec := mtvec.rdata.asUInt 1141 diffCSRState.stvec := stvec.rdata.asUInt 1142 diffCSRState.mcause := mcause.rdata.asUInt 1143 diffCSRState.scause := scause.rdata.asUInt 1144 diffCSRState.satp := satp.rdata.asUInt 1145 diffCSRState.mip := mip.regOut.asUInt 1146 diffCSRState.mie := mie.rdata.asUInt 1147 diffCSRState.mscratch := mscratch.rdata.asUInt 1148 diffCSRState.sscratch := sscratch.rdata.asUInt 1149 diffCSRState.mideleg := mideleg.rdata.asUInt 1150 diffCSRState.medeleg := medeleg.rdata.asUInt 1151 1152 val diffDebugMode = DifftestModule(new DiffDebugMode) 1153 diffDebugMode.coreid := hartId 1154 diffDebugMode.debugMode := debugMode 1155 diffDebugMode.dcsr := dcsr.rdata.asUInt 1156 diffDebugMode.dpc := dpc.rdata.asUInt 1157 diffDebugMode.dscratch0 := dscratch0.rdata.asUInt 1158 diffDebugMode.dscratch1 := dscratch1.rdata.asUInt 1159 1160 val diffTriggerCSRState = DifftestModule(new DiffTriggerCSRState) 1161 diffTriggerCSRState.coreid := hartId 1162 diffTriggerCSRState.tselect := tselect.rdata 1163 diffTriggerCSRState.tdata1 := tdata1.rdata 1164 diffTriggerCSRState.tinfo := tinfo.rdata 1165 diffTriggerCSRState.tcontrol := tcontrol.rdata 1166 1167 val diffVecCSRState = DifftestModule(new DiffVecCSRState) 1168 diffVecCSRState.coreid := hartId 1169 diffVecCSRState.vstart := vstart.rdata.asUInt 1170 diffVecCSRState.vxsat := vcsr.vxsat.asUInt 1171 diffVecCSRState.vxrm := vcsr.vxrm.asUInt 1172 diffVecCSRState.vcsr := vcsr.rdata.asUInt 1173 diffVecCSRState.vl := RegNext(io.fromRob.commit.vl) 1174 diffVecCSRState.vtype := vtype.rdata.asUInt 1175 diffVecCSRState.vlenb := vlenb.rdata.asUInt 1176 1177 val diffFpCSRState = DifftestModule(new DiffFpCSRState) 1178 diffFpCSRState.coreid := hartId 1179 diffFpCSRState.fcsr := fcsr.rdata.asUInt 1180 1181 val diffHCSRState = DifftestModule(new DiffHCSRState) 1182 diffHCSRState.coreid := hartId 1183 diffHCSRState.virtMode := privState.V.asBool 1184 diffHCSRState.mtval2 := mtval2.rdata.asUInt 1185 diffHCSRState.mtinst := mtinst.rdata.asUInt 1186 diffHCSRState.hstatus := hstatus.rdata.asUInt 1187 diffHCSRState.hideleg := hideleg.rdata.asUInt 1188 diffHCSRState.hedeleg := hedeleg.rdata.asUInt 1189 diffHCSRState.hcounteren := hcounteren.rdata.asUInt 1190 diffHCSRState.htval := htval.rdata.asUInt 1191 diffHCSRState.htinst := htinst.rdata.asUInt 1192 diffHCSRState.hgatp := hgatp.rdata.asUInt 1193 diffHCSRState.vsstatus := vsstatus.rdata.asUInt 1194 diffHCSRState.vstvec := vstvec.rdata.asUInt 1195 diffHCSRState.vsepc := vsepc.rdata.asUInt 1196 diffHCSRState.vscause := vscause.rdata.asUInt 1197 diffHCSRState.vstval := vstval.rdata.asUInt 1198 diffHCSRState.vsatp := vsatp.rdata.asUInt 1199 diffHCSRState.vsscratch := vsscratch.rdata.asUInt 1200 1201 } 1202} 1203 1204trait IpIeAliasConnect { 1205 self: NewCSR with MachineLevel with SupervisorLevel with VirtualSupervisorLevel with HypervisorLevel => 1206 1207 mip.fromMvip := mvip.toMip 1208 mip.fromSip := sip.toMip 1209 mip.fromVSip := vsip.toMip 1210 mvip.fromMip := mip.toMvip 1211 mvip.fromSip := sip.toMvip 1212 mvip.fromVSip := vsip.toMvip 1213 hvip.fromMip := mip.toHvip 1214 hvip.fromHip := hip.toHvip 1215 hvip.fromVSip := vsip.toHvip 1216 1217 mie.fromHie := hie.toMie 1218 mie.fromSie := sie.toMie 1219 mie.fromVSie := vsie.toMie 1220 sie.fromVSie := vsie.toSie 1221} 1222 1223object NewCSRMain extends App { 1224 val (config, firrtlOpts, firtoolOpts) = ArgParser.parse( 1225 args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog") 1226 1227 val defaultConfig = config.alterPartial({ 1228 // Get XSCoreParams and pass it to the "small module" 1229 case XSCoreParamsKey => config(XSTileKey).head 1230 }) 1231 1232 Generator.execute( 1233 firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend", 1234 new NewCSR()(defaultConfig), 1235 firtoolOpts 1236 ) 1237 1238 println("done") 1239}