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