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