1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import freechips.rocketchip.rocket.CSRs 6import difftest._ 7import org.chipsalliance.cde.config.Parameters 8import top.{ArgParser, Generator} 9import utility.{DataHoldBypass, SignExt, ZeroExt} 10import utils.OptionWrapper 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.vector.Bundles.{Vl, Vstart, Vxrm, Vxsat} 17import xiangshan.{FrontendTdataDistributeIO, HasXSParameter, MemTdataDistributeIO, XSCoreParamsKey, XSTileKey} 18import xiangshan._ 19import xiangshan.backend.fu.util.CSRConst 20 21import scala.collection.immutable.SeqMap 22 23object CSRConfig { 24 final val GEILEN = 63 25 26 final val ASIDLEN = 16 // the length of ASID of XS implementation 27 28 final val ASIDMAX = 16 // the max value of ASIDLEN defined by spec 29 30 final val HIIDWidth = 12 // support Hvictl[27:16](IID) 31 32 final val VMIDLEN = 14 // the length of VMID of XS implementation 33 34 final val VMIDMAX = 14 // the max value of VMIDLEN defined by spec 35 36 // the width of VGEIN 37 final val VGEINWidth = 6 38 39 final val VaddrMaxWidth = 41 // only Sv39 and Sv39x4 40 41 final val XLEN = 64 // Todo: use XSParams 42 43 final val VLEN = 128 44 45 // Since we need macro to compute the width of CSR field, the input of macro should be the value that can be computed 46 // at compile time. The log2Up function cannot be used as meta-programming function, so we use litral value here 47 // log2Up(128 + 1), hold 0~128 48 final val VlWidth = 8 49 50 final val PAddrWidth = 36 51 52 final val AddrWidthInPage = 12 53 54 final val PMPAddrWidth = 36 55 56 final val PMPOffBits = 2 57 58 final val PMPAddrBits = PMPAddrWidth - PMPOffBits 59 60 // trigger 61 final val triggerNum = 4 // Todo: use XSParams 62 final val tselectWidth = 2 // log2Up(triggerNum) 63} 64 65class NewCSR(implicit val p: Parameters) extends Module 66 with HasXSParameter 67 with MachineLevel 68 with SupervisorLevel 69 with HypervisorLevel 70 with VirtualSupervisorLevel 71 with Unprivileged 72 with CSRAIA 73 with HasExternalInterruptBundle 74 with SupervisorMachineAliasConnect 75 with CSREvents 76 with DebugLevel 77 with CSRCustom 78 with CSRPMP 79{ 80 81 import CSRConfig._ 82 83 val io = IO(new Bundle { 84 val fromTop = Input(new Bundle { 85 val hartId = UInt(hartIdLen.W) 86 }) 87 val in = Input(new Bundle { 88 val wen = Bool() 89 val ren = Bool() 90 val addr = UInt(12.W) 91 val wdata = UInt(64.W) 92 }) 93 val fromMem = Input(new Bundle { 94 val excpVA = UInt(VaddrMaxWidth.W) 95 val excpGPA = UInt(VaddrMaxWidth.W) // Todo: use guest physical address width 96 }) 97 val fromRob = Input(new Bundle { 98 val trap = ValidIO(new Bundle { 99 val pc = UInt(VaddrMaxWidth.W) 100 val instr = UInt(32.W) 101 val trapVec = UInt(64.W) 102 val singleStep = Bool() 103 val triggerCf = new TriggerCf 104 val crossPageIPFFix = Bool() 105 val isInterrupt = Bool() 106 }) 107 val commit = Input(new RobCommitCSR) 108 }) 109 val mret = Input(Bool()) 110 val sret = Input(Bool()) 111 val dret = Input(Bool()) 112 val wfi = Input(Bool()) 113 val ebreak = Input(Bool()) 114 115 val out = Output(new Bundle { 116 val EX_II = Bool() 117 val EX_VI = Bool() 118 val flushPipe = Bool() 119 val rData = UInt(64.W) 120 val targetPc = UInt(VaddrMaxWidth.W) 121 val regOut = UInt(64.W) 122 val privState = new PrivState 123 val interrupt = Bool() 124 val wfiEvent = Bool() 125 val tvm = Bool() 126 val vtvm = Bool() 127 // fp 128 val fpState = new Bundle { 129 val off = Bool() 130 val frm = Frm() 131 } 132 // vec 133 val vecState = new Bundle { 134 val vstart = Vstart() 135 val vxsat = Vxsat() 136 val vxrm = Vxrm() 137 val vcsr = UInt(XLEN.W) 138 val vl = Vl() 139 val vtype = UInt(XLEN.W) 140 val vlenb = UInt(XLEN.W) 141 val off = Bool() 142 } 143 // perf 144 val isPerfCnt = Bool() 145 // debug 146 val debugMode = Bool() 147 val singleStepFlag = Bool() 148 // trigger 149 val frontendTrigger = new FrontendTdataDistributeIO() 150 val memTrigger = new MemTdataDistributeIO() 151 // custom 152 val custom = new CSRCustomState 153 }) 154 // tlb 155 val tlb = Output(new Bundle { 156 val satpASIDChanged = Bool() 157 val vsatpASIDChanged = Bool() 158 val hgatpVMIDChanged = Bool() 159 val satp = new SatpBundle 160 val vsatp = new SatpBundle 161 val hgatp = new HgatpBundle 162 val mxr = Bool() 163 val sum = Bool() 164 val vmxr = Bool() 165 val vsum = Bool() 166 val spvp = Bool() 167 val imode = UInt(2.W) 168 val dmode = UInt(2.W) 169 }) 170 }) 171 172 val toAIA = IO(Output(new CSRToAIABundle)) 173 val fromAIA = IO(Flipped(Output(new AIAToCSRBundle))) 174 175 dontTouch(toAIA) 176 dontTouch(fromAIA) 177 178 val wen = io.in.wen 179 val addr = io.in.addr 180 val wdata = io.in.wdata 181 182 val ren = io.in.ren 183 val raddr = io.in.addr 184 185 val hasTrap = io.fromRob.trap.valid 186 val trapVec = io.fromRob.trap.bits.trapVec 187 val trapPC = io.fromRob.trap.bits.pc 188 val trapIsInterrupt = io.fromRob.trap.bits.isInterrupt 189 val trapIsCrossPageIPF = io.fromRob.trap.bits.crossPageIPFFix 190 val triggerCf = io.fromRob.trap.bits.triggerCf 191 192 // debug_intrrupt 193 val debugIntrEnable = RegInit(true.B) // debug interrupt will be handle only when debugIntrEnable 194 val debugIntr = platformIRP.debugIP && debugIntrEnable 195 196 // CSR Privilege State 197 val PRVM = RegInit(PrivMode(0), PrivMode.M) 198 val V = RegInit(VirtMode(0), VirtMode.Off) 199 val debugMode = RegInit(false.B) 200 201 private val privState = Wire(new PrivState) 202 privState.PRVM := PRVM 203 privState.V := V 204 205 private val isModeM = privState.isModeM 206 private val (isModeHS, isModeHU) = (privState.isModeHS, privState.isModeHU) 207 private val (isModeVS, isModeVU) = (privState.isModeVS, privState.isModeVU) 208 209 val permitMod = Module(new CSRPermitModule) 210 211 private val wenLegal = permitMod.io.out.hasLegalWen 212 213 val legalSret = permitMod.io.out.hasLegalSret 214 val legalMret = permitMod.io.out.hasLegalMret 215 val isDret = io.dret // Todo: check permission 216 val isWfi = permitMod.io.out.hasLegalWfi 217 218 var csrRwMap: SeqMap[Int, (CSRAddrWriteBundle[_], Data)] = 219 machineLevelCSRMap ++ 220 supervisorLevelCSRMap ++ 221 hypervisorCSRMap ++ 222 virtualSupervisorCSRMap ++ 223 unprivilegedCSRMap ++ 224 debugCSRMap ++ 225 aiaCSRMap ++ 226 customCSRMap ++ 227 pmpCSRMap 228 229 val csrMods: Seq[CSRModule[_]] = 230 machineLevelCSRMods ++ 231 supervisorLevelCSRMods ++ 232 hypervisorCSRMods ++ 233 virtualSupervisorCSRMods ++ 234 unprivilegedCSRMods ++ 235 debugCSRMods ++ 236 aiaCSRMods ++ 237 customCSRMods ++ 238 pmpCSRMods 239 240 var csrOutMap: SeqMap[Int, UInt] = 241 machineLevelCSROutMap ++ 242 supervisorLevelCSROutMap ++ 243 hypervisorCSROutMap ++ 244 virtualSupervisorCSROutMap ++ 245 unprivilegedCSROutMap ++ 246 debugCSROutMap ++ 247 aiaCSROutMap ++ 248 customCSROutMap ++ 249 pmpCSROutMap 250 251 // interrupt 252 val intrMod = Module(new InterruptFilter) 253 intrMod.io.in.privState := privState 254 intrMod.io.in.mstatusMIE := mstatus.regOut.MIE.asBool 255 intrMod.io.in.sstatusSIE := mstatus.regOut.SIE.asBool 256 intrMod.io.in.vsstatusSIE := vsstatus.regOut.SIE.asBool 257 intrMod.io.in.mip := mip.rdata.asUInt 258 intrMod.io.in.mie := mie.rdata.asUInt 259 intrMod.io.in.mideleg := mideleg.rdata.asUInt 260 intrMod.io.in.sip := sip.rdata.asUInt 261 intrMod.io.in.sie := sie.rdata.asUInt 262 intrMod.io.in.hip := hip.rdata.asUInt 263 intrMod.io.in.hie := hie.rdata.asUInt 264 intrMod.io.in.hideleg := hideleg.rdata.asUInt 265 intrMod.io.in.vsip := vsip.rdata.asUInt 266 intrMod.io.in.vsie := vsie.rdata.asUInt 267 intrMod.io.in.hvictl := hvictl.rdata.asUInt 268 intrMod.io.in.hstatus := hstatus.rdata.asUInt 269 intrMod.io.in.mtopei := mtopei.rdata.asUInt 270 intrMod.io.in.stopei := stopei.rdata.asUInt 271 intrMod.io.in.vstopei := vstopei.rdata.asUInt 272 intrMod.io.in.hviprio1 := hviprio1.rdata.asUInt 273 intrMod.io.in.hviprio2 := hviprio2.rdata.asUInt 274 intrMod.io.in.miprios := Cat(miregiprios.map(_.rdata).reverse) 275 intrMod.io.in.hsiprios := Cat(siregiprios.map(_.rdata).reverse) 276 // val disableInterrupt = debugMode || (dcsr.rdata.STEP.asBool && !dcsr.rdata.STEPIE.asBool) 277 // val intrVec = Cat(debugIntr && !debugMode, mie.rdata.asUInt(11, 0) & mip.rdata.asUInt & intrVecEnable.asUInt) // Todo: asUInt(11,0) is ok? 278 279 val intrVec = RegEnable(intrMod.io.out.interruptVec.bits, 0.U, intrMod.io.out.interruptVec.valid) 280 281 val trapHandleMod = Module(new TrapHandleModule) 282 283 trapHandleMod.io.in.trapInfo.valid := hasTrap 284 trapHandleMod.io.in.trapInfo.bits.trapVec := trapVec.asUInt 285 trapHandleMod.io.in.trapInfo.bits.intrVec := intrVec 286 trapHandleMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt 287 trapHandleMod.io.in.privState := privState 288 trapHandleMod.io.in.mideleg := mideleg.regOut 289 trapHandleMod.io.in.medeleg := medeleg.regOut 290 trapHandleMod.io.in.hideleg := hideleg.regOut 291 trapHandleMod.io.in.hedeleg := hedeleg.regOut 292 trapHandleMod.io.in.mtvec := mtvec.regOut 293 trapHandleMod.io.in.stvec := stvec.regOut 294 trapHandleMod.io.in.vstvec := vstvec.regOut 295 296 val entryPrivState = trapHandleMod.io.out.entryPrivState 297 298 // PMP 299 val pmpEntryMod = Module(new PMPEntryHandleModule) 300 pmpEntryMod.io.in.pmpCfg := cfgs.map(_.regOut.asInstanceOf[PMPCfgBundle]) 301 pmpEntryMod.io.in.pmpAddr := pmpaddr.map(_.regOut.asInstanceOf[PMPAddrBundle]) 302 pmpEntryMod.io.in.ren := ren 303 pmpEntryMod.io.in.wen := wen 304 pmpEntryMod.io.in.addr := addr 305 pmpEntryMod.io.in.wdata := wdata 306 307 for ((id, (wBundle, _)) <- csrRwMap) { 308 if (vsMapS.contains(id)) { 309 // VS access CSR by S: privState.isModeVS && addrMappedToVS === sMapVS(id).U 310 wBundle.wen := wenLegal && ((isModeVS && addr === vsMapS(id).U) || (!isModeVS && addr === id.U)) 311 wBundle.wdata := wdata 312 } else if (sMapVS.contains(id)) { 313 wBundle.wen := wenLegal && !isModeVS && addr === id.U 314 wBundle.wdata := wdata 315 } else { 316 wBundle.wen := wenLegal && addr === id.U 317 wBundle.wdata := wdata 318 } 319 } 320 321 // Todo: support set dirty only when fcsr has changed 322 private val writeFpState = wenLegal && Seq(CSRs.fflags, CSRs.frm, CSRs.fcsr).map(_.U === addr).reduce(_ || _) 323 private val writeVecState = wenLegal && Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr).map(_.U === addr).reduce(_ || _) 324 325 permitMod.io.in.csrAccess.ren := ren 326 permitMod.io.in.csrAccess.wen := wen 327 permitMod.io.in.csrAccess.addr := addr 328 329 330 permitMod.io.in.privState := privState 331 permitMod.io.in.debugMode := debugMode 332 333 permitMod.io.in.mret := io.mret 334 permitMod.io.in.sret := io.sret 335 permitMod.io.in.wfi := io.wfi 336 337 permitMod.io.in.status.tsr := mstatus.regOut.TSR.asBool 338 permitMod.io.in.status.vtsr := hstatus.regOut.VTSR.asBool 339 340 permitMod.io.in.status.tw := mstatus.regOut.TW.asBool 341 permitMod.io.in.status.vtw := hstatus.regOut.VTW.asBool 342 343 miregiprios.foreach { mod => 344 mod.w.wen := (addr === mireg.addr.U) && (miselect.regOut.ALL.asUInt === mod.addr.U) 345 mod.w.wdata := wdata 346 } 347 348 siregiprios.foreach { mod => 349 mod.w.wen := (addr === sireg.addr.U) && (siselect.regOut.ALL.asUInt === mod.addr.U) 350 mod.w.wdata := wdata 351 } 352 353 mhartid.hartid := this.io.fromTop.hartId 354 355 cfgs.zipWithIndex.foreach { case (mod, i) => 356 mod.w.wen := wen && (addr === (0x3A0 + i / 8 * 2).U) 357 mod.w.wdata := pmpEntryMod.io.out.pmpCfgWData(8*((i%8)+1)-1,8*(i%8)) 358 } 359 360 pmpaddr.zipWithIndex.foreach{ case(mod, i) => 361 mod.w.wen := wen && (addr === (0x3B0 + i).U) 362 mod.w.wdata := pmpEntryMod.io.out.pmpAddrWData(i) 363 } 364 365 csrMods.foreach { mod => 366 mod match { 367 case m: HypervisorBundle => 368 m.hstatus := hstatus.regOut 369 m.hvip := hvip.regOut 370 m.hideleg := hideleg.regOut 371 m.hedeleg := hedeleg.regOut 372 m.hgeip := hgeip.regOut 373 m.hgeie := hgeie.regOut 374 m.hip := hip.regOut 375 m.hie := hie.regOut 376 case _ => 377 } 378 mod match { 379 case m: HasMachineInterruptBundle => 380 m.mvien := mvien.regOut 381 m.mvip := mvip.regOut 382 m.mip := mip.regOut 383 m.mie := mie.regOut 384 case _ => 385 } 386 mod match { 387 case m: HasMachineDelegBundle => 388 m.mideleg := mideleg.regOut 389 m.medeleg := medeleg.regOut 390 case _ => 391 } 392 mod match { 393 case m: HasMachineCounterControlBundle => 394 m.mcountinhibit := mcountinhibit.regOut 395 case _ => 396 } 397 mod match { 398 case m: HasExternalInterruptBundle => 399 m.platformIRP := this.platformIRP 400 case _ => 401 } 402 mod match { 403 case m: HasRobCommitBundle => 404 m.robCommit := io.fromRob.commit 405 m.robCommit.fsDirty := io.fromRob.commit.fsDirty || writeFpState 406 m.robCommit.vsDirty := io.fromRob.commit.vsDirty || writeVecState 407 case _ => 408 } 409 mod match { 410 case m: TrapEntryDEventSinkBundle => 411 m.trapToD := trapEntryDEvent.out 412 case _ => 413 } 414 mod match { 415 case m: TrapEntryMEventSinkBundle => 416 m.trapToM := trapEntryMEvent.out 417 case _ => 418 } 419 mod match { 420 case m: TrapEntryHSEventSinkBundle => 421 m.trapToHS := trapEntryHSEvent.out 422 case _ => 423 } 424 mod match { 425 case m: TrapEntryVSEventSinkBundle => 426 m.trapToVS := trapEntryVSEvent.out 427 case _ => 428 } 429 mod match { 430 case m: MretEventSinkBundle => 431 m.retFromM := mretEvent.out 432 case _ => 433 } 434 mod match { 435 case m: SretEventSinkBundle => 436 m.retFromS := sretEvent.out 437 case _ => 438 } 439 mod match { 440 case m: DretEventSinkBundle => 441 m.retFromD := dretEvent.out 442 case _ => 443 } 444 mod match { 445 case m: HasAIABundle => 446 m.aiaToCSR.rdata.valid := fromAIA.rdata.valid 447 m.aiaToCSR.rdata.bits.data := fromAIA.rdata.bits.data 448 m.aiaToCSR.rdata.bits.illegal := fromAIA.rdata.bits.illegal 449 m.aiaToCSR.mtopei.valid := fromAIA.mtopei.valid 450 m.aiaToCSR.stopei.valid := fromAIA.stopei.valid 451 m.aiaToCSR.vstopei.valid := fromAIA.vstopei.valid 452 m.aiaToCSR.mtopei.bits := fromAIA.mtopei.bits 453 m.aiaToCSR.stopei.bits := fromAIA.stopei.bits 454 m.aiaToCSR.vstopei.bits := fromAIA.vstopei.bits 455 case _ => 456 } 457 mod match { 458 case m: HasInterruptFilterSink => 459 m.topIR.mtopi := intrMod.io.out.mtopi 460 m.topIR.stopi := intrMod.io.out.stopi 461 m.topIR.vstopi := intrMod.io.out.vstopi 462 case _ => 463 } 464 mod match { 465 case m: HasISelectBundle => 466 m.privState := privState 467 m.miselect := miselect.regOut 468 m.siselect := siselect.regOut 469 m.mireg := mireg.regOut.asUInt 470 m.sireg := sireg.regOut.asUInt 471 case _ => 472 } 473 mod match { 474 case m: HasPMPAddrSink => 475 m.addrRData := pmpEntryMod.io.out.pmpAddrRData 476 case _ => 477 } 478 } 479 480 csrMods.foreach { mod => 481 println(s"${mod.modName}: ") 482 println(mod.dumpFields) 483 } 484 485 trapEntryMEvent .valid := hasTrap && entryPrivState.isModeM 486 trapEntryHSEvent.valid := hasTrap && entryPrivState.isModeHS 487 trapEntryVSEvent.valid := hasTrap && entryPrivState.isModeVS 488 489 490 Seq(trapEntryMEvent, trapEntryHSEvent, trapEntryVSEvent, trapEntryDEvent).foreach { eMod => 491 eMod.in match { 492 case in: TrapEntryEventInput => 493 in.causeNO := trapHandleMod.io.out.causeNO 494 in.trapPc := trapPC 495 in.isCrossPageIPF := trapIsCrossPageIPF 496 497 in.iMode.PRVM := PRVM 498 in.iMode.V := V 499 in.dMode.PRVM := Mux(mstatus.regOut.MPRV.asBool, mstatus.regOut.MPP, PRVM) 500 in.dMode.V := Mux(mstatus.regOut.MPRV.asBool, mstatus.regOut.MPV, V) 501 502 in.privState := privState 503 in.mstatus := mstatus.regOut 504 in.hstatus := hstatus.regOut 505 in.sstatus := mstatus.sstatus 506 in.vsstatus := vsstatus.regOut 507 in.pcFromXtvec := trapHandleMod.io.out.pcFromXtvec 508 509 in.satp := satp.regOut 510 in.vsatp := vsatp.regOut 511 in.hgatp := hgatp.regOut 512 513 in.memExceptionVAddr := io.fromMem.excpVA 514 in.memExceptionGPAddr := io.fromMem.excpGPA 515 } 516 } 517 518 mretEvent.valid := legalMret 519 mretEvent.in match { 520 case in => 521 in.mstatus := mstatus.regOut 522 in.mepc := mepc.regOut 523 } 524 525 sretEvent.valid := legalSret 526 sretEvent.in match { 527 case in => 528 in.privState := privState 529 in.sstatus := mstatus.sstatus 530 in.hstatus := hstatus.regOut 531 in.vsstatus := vsstatus.regOut 532 in.sepc := sepc.regOut 533 in.vsepc := vsepc.regOut 534 } 535 536 dretEvent.valid := isDret 537 dretEvent.in match { 538 case in => 539 in.dcsr := dcsr.regOut 540 in.dpc := dpc.regOut 541 in.mstatus := mstatus.regOut 542 } 543 544 PRVM := MuxCase( 545 PRVM, 546 events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map { 547 x => x.out match { 548 case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM) 549 } 550 } 551 ) 552 553 V := MuxCase( 554 V, 555 events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map { 556 x => x.out match { 557 case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V) 558 } 559 } 560 ) 561 562 debugMode := MuxCase( 563 debugMode, 564 Seq( 565 dretEvent.out.debugMode.valid -> dretEvent.out.debugMode.bits, 566 trapEntryDEvent.out.debugMode.valid -> trapEntryDEvent.out.debugMode.bits 567 ) 568 ) 569 570 debugIntrEnable := MuxCase( 571 debugIntrEnable, 572 Seq( 573 dretEvent.out.debugIntrEnable.valid -> dretEvent.out.debugIntrEnable.bits, 574 trapEntryDEvent.out.debugIntrEnable.valid -> trapEntryDEvent.out.debugIntrEnable.bits 575 ) 576 ) 577 578 // perf 579 val addrInPerfCnt = (addr >= CSRs.mcycle.U) && (addr <= CSRs.mhpmcounter31.U) || 580 (addr >= mcountinhibit.addr.U) && (addr <= mhpmevents.last.addr.U) || 581 (addr >= CSRs.cycle.U) && (addr <= CSRs.hpmcounter31.U) || 582 (addr === CSRs.mip.U) || 583 (addr === CSRs.hip.U) || 584 Cat(aiaCSRMap.keys.toSeq.sorted.map(_.U === addr)).orR || 585 (addr === CSRs.stimecmp.U) || 586 (addr === CSRs.mcounteren.U) || 587 (addr === CSRs.scounteren.U) || 588 (addr === CSRs.menvcfg.U) 589 // Todo: may be vsip and sip 590 591 // flush 592 val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegal // write to satp will cause the pipeline be flushed 593 594 val wFcsrChangeRM = addr === fcsr.addr.U && wenLegal && wdata(7, 5) =/= fcsr.frm 595 val wFrmChangeRM = addr === CSRs.frm.U && wenLegal && wdata(2, 0) =/= fcsr.frm 596 val frmChange = wFcsrChangeRM || wFrmChangeRM 597 598 val wVcsrChangeRM = addr === CSRs.vcsr.U && wenLegal && wdata(2, 1) =/= vcsr.vxrm 599 val wVxrmChangeRM = addr === CSRs.vxrm.U && wenLegal && wdata(1, 0) =/= vcsr.vxrm 600 val vxrmChange = wVcsrChangeRM || wVxrmChangeRM 601 602 val triggerFrontendChange = Wire(Bool()) 603 val flushPipe = resetSatp || frmChange || vxrmChange || triggerFrontendChange 604 605 // fence 606 val tvm = mstatus.regOut.TVM.asBool 607 val vtvm = hstatus.regOut.VTVM.asBool 608 609 private val rdata = Mux1H(csrRwMap.map { case (id, (_, rBundle)) => 610 (raddr === id.U) -> rBundle.asUInt 611 }) 612 613 private val regOut = Mux1H(csrOutMap.map { case (id, regOut) => 614 (raddr === id.U) -> regOut 615 }) 616 617 private val needTargetUpdate = mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid || 618 trapEntryMEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid 619 620 private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR 621 622 io.out.EX_II := permitMod.io.out.EX_II || noCSRIllegal 623 io.out.EX_VI := permitMod.io.out.EX_VI 624 io.out.flushPipe := flushPipe 625 626 io.out.rData := Mux(ren, rdata, 0.U) 627 io.out.regOut := regOut 628 io.out.targetPc := DataHoldBypass( 629 Mux(trapEntryDEvent.out.targetPc.valid, 630 trapEntryDEvent.out.targetPc.bits, 631 Mux1H(Seq( 632 mretEvent.out.targetPc.valid -> mretEvent.out.targetPc.bits, 633 sretEvent.out.targetPc.valid -> sretEvent.out.targetPc.bits, 634 dretEvent.out.targetPc.valid -> dretEvent.out.targetPc.bits, 635 trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits, 636 trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits, 637 trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits) 638 ) 639 ), 640 needTargetUpdate) 641 642 io.out.privState := privState 643 644 io.out.fpState.frm := fcsr.frm 645 io.out.fpState.off := mstatus.regOut.FS === ContextStatus.Off 646 io.out.vecState.vstart := vstart.rdata.asUInt 647 io.out.vecState.vxsat := vcsr.vxsat 648 io.out.vecState.vxrm := vcsr.vxrm 649 io.out.vecState.vcsr := vcsr.rdata.asUInt 650 io.out.vecState.vl := vl.rdata.asUInt 651 io.out.vecState.vtype := vtype.rdata.asUInt // Todo: check correct 652 io.out.vecState.vlenb := vlenb.rdata.asUInt 653 io.out.vecState.off := mstatus.regOut.VS === ContextStatus.Off 654 io.out.isPerfCnt := addrInPerfCnt 655 io.out.interrupt := intrMod.io.out.interruptVec.valid 656 io.out.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR 657 io.out.debugMode := debugMode 658 io.out.singleStepFlag := !debugMode && dcsr.regOut.STEP 659 io.out.tvm := tvm 660 io.out.vtvm := vtvm 661 662 /** 663 * debug_begin 664 */ 665 // debug_intr 666 val hasIntr = hasTrap && trapIsInterrupt 667 val hasDebugIntr = hasIntr && intrVec(CSRConst.IRQ_DEBUG) 668 669 // debug_exception_ebreak 670 val hasExp = hasTrap && !trapIsInterrupt 671 val breakPoint = trapVec(ExceptionNO.breakPoint).asBool 672 val hasBreakPoint = hasExp && breakPoint 673 val ebreakEnterDebugMode = 674 (privState.isModeM && dcsr.regOut.EBREAKM.asBool) || 675 (privState.isModeHS && dcsr.regOut.EBREAKS.asBool) || 676 (privState.isModeHU && dcsr.regOut.EBREAKU.asBool) 677 val hasDebugEbreakException = hasBreakPoint && ebreakEnterDebugMode 678 679 // debug_exception_trigger 680 val triggerFrontendHitVec = triggerCf.frontendHit 681 val triggerMemHitVec = triggerCf.backendHit 682 val triggerHitVec = triggerFrontendHitVec.asUInt | triggerMemHitVec.asUInt // Todo: update mcontrol.hit 683 val triggerFrontendCanFireVec = triggerCf.frontendCanFire.asUInt 684 val triggerMemCanFireVec = triggerCf.backendCanFire.asUInt 685 val triggerCanFireVec = triggerFrontendCanFireVec | triggerMemCanFireVec 686 val tdata1WireVec = tdata1RegVec.map{ mod => { 687 val tdata1Wire = Wire(new Tdata1Bundle) 688 tdata1Wire := mod.rdata 689 tdata1Wire 690 }} 691 val tdata2WireVec = tdata2RegVec.map{ mod => { 692 val tdata2Wire = Wire(new Tdata2Bundle) 693 tdata2Wire := mod.rdata 694 tdata2Wire 695 }} 696 val mcontrolWireVec = tdata1WireVec.map{ mod => { 697 val mcontrolWire = Wire(new Mcontrol) 698 mcontrolWire := mod.DATA.asUInt 699 mcontrolWire 700 }} 701 702 // More than one triggers can hit at the same time, but only fire one 703 // We select the first hit trigger to fire 704 val triggerFireOH = PriorityEncoderOH(triggerCanFireVec) 705 val triggerFireAction = PriorityMux(triggerFireOH, tdata1WireVec.map(_.getTriggerAction)).asUInt 706 val hasTriggerFire = hasExp && triggerCf.canFire 707 val hasDebugTriggerException = hasTriggerFire && (triggerFireAction === TrigAction.DebugMode.asUInt) 708 709 // debug_exception_single 710 val hasSingleStep = hasExp && io.fromRob.trap.bits.singleStep 711 712 val hasDebugException = hasDebugEbreakException || hasDebugTriggerException || hasSingleStep 713 val hasDebugTrap = hasDebugException || hasDebugIntr 714 715 trapEntryDEvent.valid := hasDebugTrap && !debugMode 716 trapEntryDEvent.in.hasDebugIntr := hasDebugIntr 717 trapEntryDEvent.in.debugMode := debugMode 718 trapEntryDEvent.in.hasTrap := hasTrap 719 trapEntryDEvent.in.hasSingleStep := hasSingleStep 720 trapEntryDEvent.in.hasTriggerFire := hasTriggerFire 721 trapEntryDEvent.in.hasDebugEbreakException := hasDebugEbreakException 722 trapEntryDEvent.in.breakPoint := breakPoint 723 724 trapHandleMod.io.in.trapInfo.bits.singleStep := hasSingleStep 725 trapHandleMod.io.in.trapInfo.bits.triggerFire := hasTriggerFire 726 727 intrMod.io.in.debugMode := debugMode 728 intrMod.io.in.debugIntr := debugIntr 729 intrMod.io.in.dcsr := dcsr.rdata.asUInt 730 731 val tselect1H = UIntToOH(tselect.rdata.asUInt, TriggerNum).asBools 732 val chainVec = mcontrolWireVec.map(_.CHAIN.asBool) 733 val newTriggerChainVec = tselect1H.zip(chainVec).map{case(a, b) => a | b} 734 val newTriggerChainIsLegal = TriggerUtil.TriggerCheckChainLegal(newTriggerChainVec, TriggerChainMaxLength) 735 736 val tdata1Update = addr === tdata1.addr.U && wenLegal 737 val tdata2Update = addr === tdata2.addr.U && wenLegal 738 val triggerUpdate = tdata1Update || tdata2Update 739 740 tdata1RegVec.foreach { mod => 741 mod match { 742 case m: HasdebugModeBundle => 743 m.debugMode := debugMode 744 m.chainable := newTriggerChainIsLegal 745 case _ => 746 } 747 } 748 tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => { 749 mod1.w.wen := tdata1Update && (tselect.rdata === idx.U) 750 mod1.w.wdata := wdata 751 mod2.w.wen := tdata2Update && (tselect.rdata === idx.U) 752 mod2.w.wdata := wdata 753 } 754 } 755 756 val tdata1Wdata = Wire(new Tdata1Bundle) 757 tdata1Wdata := wdata 758 val mcontrolWdata = Wire(new Mcontrol) 759 mcontrolWdata := tdata1Wdata.DATA.asUInt 760 val tdata1TypeWdata = tdata1Wdata.TYPE 761 762 val tdata1Selected = Wire(new Tdata1Bundle) 763 tdata1Selected := tdata1.rdata.asUInt 764 val mcontrolSelected = Wire(new Mcontrol) 765 mcontrolSelected := tdata1Selected.DATA.asUInt 766 val tdata2Selected = Wire(new Tdata2Bundle) 767 tdata2Selected := tdata2.rdata.asUInt 768 769 val frontendTriggerUpdate = 770 tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isFetchTrigger || 771 mcontrolSelected.isFetchTrigger && triggerUpdate 772 773 val memTriggerUpdate = 774 tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isMemAccTrigger || 775 mcontrolSelected.isMemAccTrigger && triggerUpdate 776 777 val triggerEnableVec = tdata1WireVec.zip(mcontrolWireVec).map { case(tdata1, mcontrol) => 778 tdata1.TYPE.isLegal && ( 779 mcontrol.M && privState.isModeM || 780 mcontrol.S && (privState.isModeHS) || 781 mcontrol.U && privState.isModeHU) 782 } 783 784 val fetchTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map { 785 case (tEnable, mod) => tEnable && mod.isFetchTrigger 786 } 787 val memAccTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map { 788 case (tEnable, mod) => tEnable && mod.isMemAccTrigger 789 } 790 791 triggerFrontendChange := frontendTriggerUpdate 792 793 io.out.frontendTrigger.tUpdate.valid := RegNext(RegNext(frontendTriggerUpdate)) 794 io.out.frontendTrigger.tUpdate.bits.addr := tselect.rdata.asUInt 795 io.out.frontendTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected) 796 io.out.frontendTrigger.tEnableVec := fetchTriggerEnableVec 797 io.out.memTrigger.tUpdate.valid := RegNext(RegNext(memTriggerUpdate)) 798 io.out.memTrigger.tUpdate.bits.addr := tselect.rdata.asUInt 799 io.out.memTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected) 800 io.out.memTrigger.tEnableVec := memAccTriggerEnableVec 801 /** 802 * debug_end 803 */ 804 805 /** 806 * [[io.out.custom]] connection 807 */ 808 io.out.custom.l1I_pf_enable := spfctl.regOut.L1I_PF_ENABLE.asBool 809 io.out.custom.l2_pf_enable := spfctl.regOut.L2_PF_ENABLE.asBool 810 io.out.custom.l1D_pf_enable := spfctl.regOut.L1D_PF_ENABLE.asBool 811 io.out.custom.l1D_pf_train_on_hit := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool 812 io.out.custom.l1D_pf_enable_agt := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool 813 io.out.custom.l1D_pf_enable_pht := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool 814 io.out.custom.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt 815 io.out.custom.l1D_pf_active_stride := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt 816 io.out.custom.l1D_pf_enable_stride := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool 817 io.out.custom.l2_pf_store_only := spfctl.regOut.L2_PF_STORE_ONLY.asBool 818 819 io.out.custom.icache_parity_enable := sfetchctl.regOut.ICACHE_PARITY_ENABLE.asBool 820 821 io.out.custom.lvpred_disable := slvpredctl.regOut.LVPRED_DISABLE.asBool 822 io.out.custom.no_spec_load := slvpredctl.regOut.NO_SPEC_LOAD.asBool 823 io.out.custom.storeset_wait_store := slvpredctl.regOut.STORESET_WAIT_STORE.asBool 824 io.out.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool 825 io.out.custom.lvpred_timeout := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt 826 827 io.out.custom.bp_ctrl.ubtb_enable := sbpctl.regOut.UBTB_ENABLE .asBool 828 io.out.custom.bp_ctrl.btb_enable := sbpctl.regOut.BTB_ENABLE .asBool 829 io.out.custom.bp_ctrl.bim_enable := sbpctl.regOut.BIM_ENABLE .asBool 830 io.out.custom.bp_ctrl.tage_enable := sbpctl.regOut.TAGE_ENABLE .asBool 831 io.out.custom.bp_ctrl.sc_enable := sbpctl.regOut.SC_ENABLE .asBool 832 io.out.custom.bp_ctrl.ras_enable := sbpctl.regOut.RAS_ENABLE .asBool 833 io.out.custom.bp_ctrl.loop_enable := sbpctl.regOut.LOOP_ENABLE .asBool 834 835 io.out.custom.sbuffer_threshold := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt 836 io.out.custom.ldld_vio_check_enable := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool 837 io.out.custom.soft_prefetch_enable := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool 838 io.out.custom.cache_error_enable := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool 839 io.out.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool 840 841 io.out.custom.fusion_enable := srnctl.regOut.FUSION_ENABLE.asBool 842 io.out.custom.wfi_enable := srnctl.regOut.WFI_ENABLE.asBool 843 io.out.custom.svinval_enable := srnctl.regOut.SVINVAL_ENABLE.asBool 844 845 // Todo: record the last address to avoid xireg is different with xiselect 846 toAIA.addr.valid := wenLegal && Seq(miselect, siselect, vsiselect).map( 847 _.addr.U === addr 848 ).reduce(_ || _) 849 toAIA.addr.bits.addr := addr 850 toAIA.addr.bits.prvm := PRVM 851 toAIA.addr.bits.v := V 852 toAIA.vgein := hstatus.regOut.VGEIN.asUInt 853 toAIA.wdata.valid := wenLegal && Seq(mireg, sireg, vsireg).map( 854 _.addr.U === addr 855 ).reduce(_ || _) 856 toAIA.wdata.bits.data := wdata 857 toAIA.mClaim := wenLegal && mtopei.addr.U === addr 858 toAIA.sClaim := wenLegal && stopei.addr.U === addr 859 toAIA.vsClaim := wenLegal && vstopei.addr.U === addr 860 861 // tlb 862 io.tlb.satpASIDChanged := wenLegal && addr === CSRs. satp.U && satp .regOut.ASID =/= wdata.asTypeOf(new SatpBundle).ASID 863 io.tlb.vsatpASIDChanged := wenLegal && addr === CSRs.vsatp.U && vsatp.regOut.ASID =/= wdata.asTypeOf(new SatpBundle).ASID 864 io.tlb.hgatpVMIDChanged := wenLegal && addr === CSRs.hgatp.U && hgatp.regOut.VMID =/= wdata.asTypeOf(new HgatpBundle).VMID 865 io.tlb.satp := satp.rdata 866 io.tlb.vsatp := vsatp.rdata 867 io.tlb.hgatp := hgatp.rdata 868 io.tlb.mxr := mstatus.regOut.MXR.asBool 869 io.tlb.sum := mstatus.regOut.SUM.asBool 870 io.tlb.vmxr := vsstatus.regOut.MXR.asBool 871 io.tlb.vsum := vsstatus.regOut.SUM.asBool 872 io.tlb.spvp := hstatus.regOut.SPVP.asBool 873 874 io.tlb.imode := PRVM.asUInt 875 io.tlb.dmode := Mux((debugMode && dcsr.regOut.MPRVEN.asBool || !debugMode) && mstatus.regOut.MPRV.asBool, mstatus.regOut.MPP.asUInt, PRVM.asUInt) 876 877 // Always instantiate basic difftest modules. 878 if (env.AlwaysBasicDiff || env.EnableDifftest) { 879 val hartId = io.fromTop.hartId 880 val trapValid = io.fromRob.trap.valid 881 val trapNO = trapHandleMod.io.out.causeNO.ExceptionCode.asUInt 882 val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool 883 val interruptNO = Mux(interrupt, trapNO, 0.U) 884 val exceptionNO = Mux(!interrupt, trapNO, 0.U) 885 val ivmHS = isModeHS && satp.regOut.MODE =/= SatpMode.Bare 886 val ivmVS = isModeVS && vsatp.regOut.MODE =/= SatpMode.Bare 887 // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57 888 val exceptionPC = Mux(ivmHS || ivmVS, SignExt(trapPC, XLEN), ZeroExt(trapPC, XLEN)) 889 890 val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true) 891 diffArchEvent.coreid := hartId 892 diffArchEvent.valid := trapValid 893 diffArchEvent.interrupt := interruptNO 894 diffArchEvent.exception := exceptionNO 895 diffArchEvent.exceptionPC := exceptionPC 896 if (env.EnableDifftest) { 897 diffArchEvent.exceptionInst := io.fromRob.trap.bits.instr 898 } 899 900 val diffCSRState = DifftestModule(new DiffCSRState) 901 diffCSRState.coreid := hartId 902 diffCSRState.privilegeMode := privState.PRVM.asUInt 903 diffCSRState.mstatus := mstatus.rdata.asUInt 904 diffCSRState.sstatus := mstatus.sstatus.asUInt 905 diffCSRState.mepc := mepc.rdata.asUInt 906 diffCSRState.sepc := sepc.rdata.asUInt 907 diffCSRState.mtval := mtval.rdata.asUInt 908 diffCSRState.stval := stval.rdata.asUInt 909 diffCSRState.mtvec := mtvec.rdata.asUInt 910 diffCSRState.stvec := stvec.rdata.asUInt 911 diffCSRState.mcause := mcause.rdata.asUInt 912 diffCSRState.scause := scause.rdata.asUInt 913 diffCSRState.satp := satp.rdata.asUInt 914 diffCSRState.mip := mip.regOut.asUInt 915 diffCSRState.mie := mie.rdata.asUInt 916 diffCSRState.mscratch := mscratch.rdata.asUInt 917 diffCSRState.sscratch := sscratch.rdata.asUInt 918 diffCSRState.mideleg := mideleg.rdata.asUInt 919 diffCSRState.medeleg := medeleg.rdata.asUInt 920 921 val diffDebugMode = DifftestModule(new DiffDebugMode) 922 diffDebugMode.coreid := hartId 923 diffDebugMode.debugMode := debugMode 924 diffDebugMode.dcsr := dcsr.rdata.asUInt 925 diffDebugMode.dpc := dpc.rdata.asUInt 926 diffDebugMode.dscratch0 := dscratch0.rdata.asUInt 927 diffDebugMode.dscratch1 := dscratch1.rdata.asUInt 928 929 val diffVecCSRState = DifftestModule(new DiffVecCSRState) 930 diffVecCSRState.coreid := hartId 931 diffVecCSRState.vstart := vstart.rdata.asUInt 932 diffVecCSRState.vxsat := vcsr.vxsat.asUInt 933 diffVecCSRState.vxrm := vcsr.vxrm.asUInt 934 diffVecCSRState.vcsr := vcsr.rdata.asUInt 935 diffVecCSRState.vl := vl.rdata.asUInt 936 diffVecCSRState.vtype := vtype.rdata.asUInt 937 diffVecCSRState.vlenb := vlenb.rdata.asUInt 938 939 val diffHCSRState = DifftestModule(new DiffHCSRState) 940 diffHCSRState.coreid := hartId 941 diffHCSRState.virtMode := privState.V.asBool 942 diffHCSRState.mtval2 := mtval2.rdata.asUInt 943 diffHCSRState.mtinst := mtinst.rdata.asUInt 944 diffHCSRState.hstatus := hstatus.rdata.asUInt 945 diffHCSRState.hideleg := hideleg.rdata.asUInt 946 diffHCSRState.hedeleg := hedeleg.rdata.asUInt 947 diffHCSRState.hcounteren := hcounteren.rdata.asUInt 948 diffHCSRState.htval := htval.rdata.asUInt 949 diffHCSRState.htinst := htinst.rdata.asUInt 950 diffHCSRState.hgatp := hgatp.rdata.asUInt 951 diffHCSRState.vsstatus := vsstatus.rdata.asUInt 952 diffHCSRState.vstvec := vstvec.rdata.asUInt 953 diffHCSRState.vsepc := vsepc.rdata.asUInt 954 diffHCSRState.vscause := vscause.rdata.asUInt 955 diffHCSRState.vstval := vstval.rdata.asUInt 956 diffHCSRState.vsatp := vsatp.rdata.asUInt 957 diffHCSRState.vsscratch := vsscratch.rdata.asUInt 958 959 } 960} 961 962trait SupervisorMachineAliasConnect { self: NewCSR with MachineLevel with SupervisorLevel => 963 mip.fromMvip := mvip.toMip 964 mip.fromSip := sip.toMip 965 mie.fromSie := sie.toMie 966} 967 968object NewCSRMain extends App { 969 val (config, firrtlOpts, firtoolOpts) = ArgParser.parse( 970 args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog") 971 972 val defaultConfig = config.alterPartial({ 973 // Get XSCoreParams and pass it to the "small module" 974 case XSCoreParamsKey => config(XSTileKey).head 975 }) 976 977 Generator.execute( 978 firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend", 979 new NewCSR()(defaultConfig), 980 firtoolOpts 981 ) 982 983 println("done") 984}