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 permitMod.io.in.status.tvm := mstatus.regOut.TVM.asBool 344 permitMod.io.in.status.vtvm := hstatus.regOut.VTVM.asBool 345 346 miregiprios.foreach { mod => 347 mod.w.wen := (addr === mireg.addr.U) && (miselect.regOut.ALL.asUInt === mod.addr.U) 348 mod.w.wdata := wdata 349 } 350 351 siregiprios.foreach { mod => 352 mod.w.wen := (addr === sireg.addr.U) && (siselect.regOut.ALL.asUInt === mod.addr.U) 353 mod.w.wdata := wdata 354 } 355 356 mhartid.hartid := this.io.fromTop.hartId 357 358 cfgs.zipWithIndex.foreach { case (mod, i) => 359 mod.w.wen := wen && (addr === (0x3A0 + i / 8 * 2).U) 360 mod.w.wdata := pmpEntryMod.io.out.pmpCfgWData(8*((i%8)+1)-1,8*(i%8)) 361 } 362 363 pmpaddr.zipWithIndex.foreach{ case(mod, i) => 364 mod.w.wen := wen && (addr === (0x3B0 + i).U) 365 mod.w.wdata := pmpEntryMod.io.out.pmpAddrWData(i) 366 } 367 368 csrMods.foreach { mod => 369 mod match { 370 case m: HypervisorBundle => 371 m.hstatus := hstatus.regOut 372 m.hvip := hvip.regOut 373 m.hideleg := hideleg.regOut 374 m.hedeleg := hedeleg.regOut 375 m.hgeip := hgeip.regOut 376 m.hgeie := hgeie.regOut 377 m.hip := hip.regOut 378 m.hie := hie.regOut 379 case _ => 380 } 381 mod match { 382 case m: HasMachineInterruptBundle => 383 m.mvien := mvien.regOut 384 m.mvip := mvip.regOut 385 m.mip := mip.regOut 386 m.mie := mie.regOut 387 case _ => 388 } 389 mod match { 390 case m: HasMachineDelegBundle => 391 m.mideleg := mideleg.regOut 392 m.medeleg := medeleg.regOut 393 case _ => 394 } 395 mod match { 396 case m: HasMachineCounterControlBundle => 397 m.mcountinhibit := mcountinhibit.regOut 398 case _ => 399 } 400 mod match { 401 case m: HasExternalInterruptBundle => 402 m.platformIRP := this.platformIRP 403 case _ => 404 } 405 mod match { 406 case m: HasRobCommitBundle => 407 m.robCommit := io.fromRob.commit 408 m.robCommit.fsDirty := io.fromRob.commit.fsDirty || writeFpState 409 m.robCommit.vsDirty := io.fromRob.commit.vsDirty || writeVecState 410 case _ => 411 } 412 mod match { 413 case m: TrapEntryDEventSinkBundle => 414 m.trapToD := trapEntryDEvent.out 415 case _ => 416 } 417 mod match { 418 case m: TrapEntryMEventSinkBundle => 419 m.trapToM := trapEntryMEvent.out 420 case _ => 421 } 422 mod match { 423 case m: TrapEntryHSEventSinkBundle => 424 m.trapToHS := trapEntryHSEvent.out 425 case _ => 426 } 427 mod match { 428 case m: TrapEntryVSEventSinkBundle => 429 m.trapToVS := trapEntryVSEvent.out 430 case _ => 431 } 432 mod match { 433 case m: MretEventSinkBundle => 434 m.retFromM := mretEvent.out 435 case _ => 436 } 437 mod match { 438 case m: SretEventSinkBundle => 439 m.retFromS := sretEvent.out 440 case _ => 441 } 442 mod match { 443 case m: DretEventSinkBundle => 444 m.retFromD := dretEvent.out 445 case _ => 446 } 447 mod match { 448 case m: HasAIABundle => 449 m.aiaToCSR.rdata.valid := fromAIA.rdata.valid 450 m.aiaToCSR.rdata.bits.data := fromAIA.rdata.bits.data 451 m.aiaToCSR.rdata.bits.illegal := fromAIA.rdata.bits.illegal 452 m.aiaToCSR.mtopei.valid := fromAIA.mtopei.valid 453 m.aiaToCSR.stopei.valid := fromAIA.stopei.valid 454 m.aiaToCSR.vstopei.valid := fromAIA.vstopei.valid 455 m.aiaToCSR.mtopei.bits := fromAIA.mtopei.bits 456 m.aiaToCSR.stopei.bits := fromAIA.stopei.bits 457 m.aiaToCSR.vstopei.bits := fromAIA.vstopei.bits 458 case _ => 459 } 460 mod match { 461 case m: HasInterruptFilterSink => 462 m.topIR.mtopi := intrMod.io.out.mtopi 463 m.topIR.stopi := intrMod.io.out.stopi 464 m.topIR.vstopi := intrMod.io.out.vstopi 465 case _ => 466 } 467 mod match { 468 case m: HasISelectBundle => 469 m.privState := privState 470 m.miselect := miselect.regOut 471 m.siselect := siselect.regOut 472 m.mireg := mireg.regOut.asUInt 473 m.sireg := sireg.regOut.asUInt 474 case _ => 475 } 476 mod match { 477 case m: HasPMPAddrSink => 478 m.addrRData := pmpEntryMod.io.out.pmpAddrRData 479 case _ => 480 } 481 } 482 483 csrMods.foreach { mod => 484 println(s"${mod.modName}: ") 485 println(mod.dumpFields) 486 } 487 488 trapEntryMEvent .valid := hasTrap && entryPrivState.isModeM 489 trapEntryHSEvent.valid := hasTrap && entryPrivState.isModeHS 490 trapEntryVSEvent.valid := hasTrap && entryPrivState.isModeVS 491 492 493 Seq(trapEntryMEvent, trapEntryHSEvent, trapEntryVSEvent, trapEntryDEvent).foreach { eMod => 494 eMod.in match { 495 case in: TrapEntryEventInput => 496 in.causeNO := trapHandleMod.io.out.causeNO 497 in.trapPc := trapPC 498 in.isCrossPageIPF := trapIsCrossPageIPF 499 500 in.iMode.PRVM := PRVM 501 in.iMode.V := V 502 in.dMode.PRVM := Mux(mstatus.regOut.MPRV.asBool, mstatus.regOut.MPP, PRVM) 503 in.dMode.V := Mux(mstatus.regOut.MPRV.asBool, mstatus.regOut.MPV, V) 504 505 in.privState := privState 506 in.mstatus := mstatus.regOut 507 in.hstatus := hstatus.regOut 508 in.sstatus := mstatus.sstatus 509 in.vsstatus := vsstatus.regOut 510 in.pcFromXtvec := trapHandleMod.io.out.pcFromXtvec 511 512 in.satp := satp.regOut 513 in.vsatp := vsatp.regOut 514 in.hgatp := hgatp.regOut 515 516 in.memExceptionVAddr := io.fromMem.excpVA 517 in.memExceptionGPAddr := io.fromMem.excpGPA 518 } 519 } 520 521 mretEvent.valid := legalMret 522 mretEvent.in match { 523 case in => 524 in.mstatus := mstatus.regOut 525 in.mepc := mepc.regOut 526 } 527 528 sretEvent.valid := legalSret 529 sretEvent.in match { 530 case in => 531 in.privState := privState 532 in.sstatus := mstatus.sstatus 533 in.hstatus := hstatus.regOut 534 in.vsstatus := vsstatus.regOut 535 in.sepc := sepc.regOut 536 in.vsepc := vsepc.regOut 537 } 538 539 dretEvent.valid := isDret 540 dretEvent.in match { 541 case in => 542 in.dcsr := dcsr.regOut 543 in.dpc := dpc.regOut 544 in.mstatus := mstatus.regOut 545 } 546 547 PRVM := MuxCase( 548 PRVM, 549 events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map { 550 x => x.out match { 551 case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM) 552 } 553 } 554 ) 555 556 V := MuxCase( 557 V, 558 events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map { 559 x => x.out match { 560 case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V) 561 } 562 } 563 ) 564 565 debugMode := MuxCase( 566 debugMode, 567 Seq( 568 dretEvent.out.debugMode.valid -> dretEvent.out.debugMode.bits, 569 trapEntryDEvent.out.debugMode.valid -> trapEntryDEvent.out.debugMode.bits 570 ) 571 ) 572 573 debugIntrEnable := MuxCase( 574 debugIntrEnable, 575 Seq( 576 dretEvent.out.debugIntrEnable.valid -> dretEvent.out.debugIntrEnable.bits, 577 trapEntryDEvent.out.debugIntrEnable.valid -> trapEntryDEvent.out.debugIntrEnable.bits 578 ) 579 ) 580 581 // perf 582 val addrInPerfCnt = (addr >= CSRs.mcycle.U) && (addr <= CSRs.mhpmcounter31.U) || 583 (addr >= mcountinhibit.addr.U) && (addr <= mhpmevents.last.addr.U) || 584 (addr >= CSRs.cycle.U) && (addr <= CSRs.hpmcounter31.U) || 585 (addr === CSRs.mip.U) || 586 (addr === CSRs.hip.U) || 587 Cat(aiaCSRMap.keys.toSeq.sorted.map(_.U === addr)).orR || 588 (addr === CSRs.stimecmp.U) || 589 (addr === CSRs.mcounteren.U) || 590 (addr === CSRs.scounteren.U) || 591 (addr === CSRs.menvcfg.U) 592 // Todo: may be vsip and sip 593 594 // flush 595 val resetSatp = Cat(Seq(satp, vsatp, hgatp).map(_.addr.U === addr)).orR && wenLegal // write to satp will cause the pipeline be flushed 596 597 val wFcsrChangeRM = addr === fcsr.addr.U && wenLegal && wdata(7, 5) =/= fcsr.frm 598 val wFrmChangeRM = addr === CSRs.frm.U && wenLegal && wdata(2, 0) =/= fcsr.frm 599 val frmChange = wFcsrChangeRM || wFrmChangeRM 600 601 val wVcsrChangeRM = addr === CSRs.vcsr.U && wenLegal && wdata(2, 1) =/= vcsr.vxrm 602 val wVxrmChangeRM = addr === CSRs.vxrm.U && wenLegal && wdata(1, 0) =/= vcsr.vxrm 603 val vxrmChange = wVcsrChangeRM || wVxrmChangeRM 604 605 val triggerFrontendChange = Wire(Bool()) 606 val flushPipe = resetSatp || frmChange || vxrmChange || triggerFrontendChange 607 608 // fence 609 val tvm = mstatus.regOut.TVM.asBool 610 val vtvm = hstatus.regOut.VTVM.asBool 611 612 private val rdata = Mux1H(csrRwMap.map { case (id, (_, rBundle)) => 613 (raddr === id.U) -> rBundle.asUInt 614 }) 615 616 private val regOut = Mux1H(csrOutMap.map { case (id, regOut) => 617 (raddr === id.U) -> regOut 618 }) 619 620 private val needTargetUpdate = mretEvent.out.targetPc.valid || sretEvent.out.targetPc.valid || dretEvent.out.targetPc.valid || 621 trapEntryMEvent.out.targetPc.valid || trapEntryHSEvent.out.targetPc.valid || trapEntryVSEvent.out.targetPc.valid || trapEntryDEvent.out.targetPc.valid 622 623 private val noCSRIllegal = (ren || wen) && Cat(csrRwMap.keys.toSeq.sorted.map(csrAddr => !(addr === csrAddr.U))).andR 624 625 io.out.EX_II := permitMod.io.out.EX_II || noCSRIllegal 626 io.out.EX_VI := permitMod.io.out.EX_VI 627 io.out.flushPipe := flushPipe 628 629 io.out.rData := Mux(ren, rdata, 0.U) 630 io.out.regOut := regOut 631 io.out.targetPc := DataHoldBypass( 632 Mux(trapEntryDEvent.out.targetPc.valid, 633 trapEntryDEvent.out.targetPc.bits, 634 Mux1H(Seq( 635 mretEvent.out.targetPc.valid -> mretEvent.out.targetPc.bits, 636 sretEvent.out.targetPc.valid -> sretEvent.out.targetPc.bits, 637 dretEvent.out.targetPc.valid -> dretEvent.out.targetPc.bits, 638 trapEntryMEvent.out.targetPc.valid -> trapEntryMEvent.out.targetPc.bits, 639 trapEntryHSEvent.out.targetPc.valid -> trapEntryHSEvent.out.targetPc.bits, 640 trapEntryVSEvent.out.targetPc.valid -> trapEntryVSEvent.out.targetPc.bits) 641 ) 642 ), 643 needTargetUpdate) 644 645 io.out.privState := privState 646 647 io.out.fpState.frm := fcsr.frm 648 io.out.fpState.off := mstatus.regOut.FS === ContextStatus.Off 649 io.out.vecState.vstart := vstart.rdata.asUInt 650 io.out.vecState.vxsat := vcsr.vxsat 651 io.out.vecState.vxrm := vcsr.vxrm 652 io.out.vecState.vcsr := vcsr.rdata.asUInt 653 io.out.vecState.vl := vl.rdata.asUInt 654 io.out.vecState.vtype := vtype.rdata.asUInt // Todo: check correct 655 io.out.vecState.vlenb := vlenb.rdata.asUInt 656 io.out.vecState.off := mstatus.regOut.VS === ContextStatus.Off 657 io.out.isPerfCnt := addrInPerfCnt 658 io.out.interrupt := intrMod.io.out.interruptVec.valid 659 io.out.wfiEvent := debugIntr || (mie.rdata.asUInt & mip.rdata.asUInt).orR 660 io.out.debugMode := debugMode 661 io.out.singleStepFlag := !debugMode && dcsr.regOut.STEP 662 io.out.tvm := tvm 663 io.out.vtvm := vtvm 664 665 /** 666 * debug_begin 667 */ 668 // debug_intr 669 val hasIntr = hasTrap && trapIsInterrupt 670 val hasDebugIntr = hasIntr && intrVec(CSRConst.IRQ_DEBUG) 671 672 // debug_exception_ebreak 673 val hasExp = hasTrap && !trapIsInterrupt 674 val breakPoint = trapVec(ExceptionNO.breakPoint).asBool 675 val hasBreakPoint = hasExp && breakPoint 676 val ebreakEnterDebugMode = 677 (privState.isModeM && dcsr.regOut.EBREAKM.asBool) || 678 (privState.isModeHS && dcsr.regOut.EBREAKS.asBool) || 679 (privState.isModeHU && dcsr.regOut.EBREAKU.asBool) 680 val hasDebugEbreakException = hasBreakPoint && ebreakEnterDebugMode 681 682 // debug_exception_trigger 683 val triggerFrontendHitVec = triggerCf.frontendHit 684 val triggerMemHitVec = triggerCf.backendHit 685 val triggerHitVec = triggerFrontendHitVec.asUInt | triggerMemHitVec.asUInt // Todo: update mcontrol.hit 686 val triggerFrontendCanFireVec = triggerCf.frontendCanFire.asUInt 687 val triggerMemCanFireVec = triggerCf.backendCanFire.asUInt 688 val triggerCanFireVec = triggerFrontendCanFireVec | triggerMemCanFireVec 689 val tdata1WireVec = tdata1RegVec.map{ mod => { 690 val tdata1Wire = Wire(new Tdata1Bundle) 691 tdata1Wire := mod.rdata 692 tdata1Wire 693 }} 694 val tdata2WireVec = tdata2RegVec.map{ mod => { 695 val tdata2Wire = Wire(new Tdata2Bundle) 696 tdata2Wire := mod.rdata 697 tdata2Wire 698 }} 699 val mcontrolWireVec = tdata1WireVec.map{ mod => { 700 val mcontrolWire = Wire(new Mcontrol) 701 mcontrolWire := mod.DATA.asUInt 702 mcontrolWire 703 }} 704 705 // More than one triggers can hit at the same time, but only fire one 706 // We select the first hit trigger to fire 707 val triggerFireOH = PriorityEncoderOH(triggerCanFireVec) 708 val triggerFireAction = PriorityMux(triggerFireOH, tdata1WireVec.map(_.getTriggerAction)).asUInt 709 val hasTriggerFire = hasExp && triggerCf.canFire 710 val hasDebugTriggerException = hasTriggerFire && (triggerFireAction === TrigAction.DebugMode.asUInt) 711 712 // debug_exception_single 713 val hasSingleStep = hasExp && io.fromRob.trap.bits.singleStep 714 715 val hasDebugException = hasDebugEbreakException || hasDebugTriggerException || hasSingleStep 716 val hasDebugTrap = hasDebugException || hasDebugIntr 717 718 trapEntryDEvent.valid := hasDebugTrap && !debugMode 719 trapEntryDEvent.in.hasDebugIntr := hasDebugIntr 720 trapEntryDEvent.in.debugMode := debugMode 721 trapEntryDEvent.in.hasTrap := hasTrap 722 trapEntryDEvent.in.hasSingleStep := hasSingleStep 723 trapEntryDEvent.in.hasTriggerFire := hasTriggerFire 724 trapEntryDEvent.in.hasDebugEbreakException := hasDebugEbreakException 725 trapEntryDEvent.in.breakPoint := breakPoint 726 727 trapHandleMod.io.in.trapInfo.bits.singleStep := hasSingleStep 728 trapHandleMod.io.in.trapInfo.bits.triggerFire := hasTriggerFire 729 730 intrMod.io.in.debugMode := debugMode 731 intrMod.io.in.debugIntr := debugIntr 732 intrMod.io.in.dcsr := dcsr.rdata.asUInt 733 734 val tselect1H = UIntToOH(tselect.rdata.asUInt, TriggerNum).asBools 735 val chainVec = mcontrolWireVec.map(_.CHAIN.asBool) 736 val newTriggerChainVec = tselect1H.zip(chainVec).map{case(a, b) => a | b} 737 val newTriggerChainIsLegal = TriggerUtil.TriggerCheckChainLegal(newTriggerChainVec, TriggerChainMaxLength) 738 739 val tdata1Update = addr === tdata1.addr.U && wenLegal 740 val tdata2Update = addr === tdata2.addr.U && wenLegal 741 val triggerUpdate = tdata1Update || tdata2Update 742 743 tdata1RegVec.foreach { mod => 744 mod match { 745 case m: HasdebugModeBundle => 746 m.debugMode := debugMode 747 m.chainable := newTriggerChainIsLegal 748 case _ => 749 } 750 } 751 tdata1RegVec.zip(tdata2RegVec).zipWithIndex.map { case ((mod1, mod2), idx) => { 752 mod1.w.wen := tdata1Update && (tselect.rdata === idx.U) 753 mod1.w.wdata := wdata 754 mod2.w.wen := tdata2Update && (tselect.rdata === idx.U) 755 mod2.w.wdata := wdata 756 } 757 } 758 759 val tdata1Wdata = Wire(new Tdata1Bundle) 760 tdata1Wdata := wdata 761 val mcontrolWdata = Wire(new Mcontrol) 762 mcontrolWdata := tdata1Wdata.DATA.asUInt 763 val tdata1TypeWdata = tdata1Wdata.TYPE 764 765 val tdata1Selected = Wire(new Tdata1Bundle) 766 tdata1Selected := tdata1.rdata.asUInt 767 val mcontrolSelected = Wire(new Mcontrol) 768 mcontrolSelected := tdata1Selected.DATA.asUInt 769 val tdata2Selected = Wire(new Tdata2Bundle) 770 tdata2Selected := tdata2.rdata.asUInt 771 772 val frontendTriggerUpdate = 773 tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isFetchTrigger || 774 mcontrolSelected.isFetchTrigger && triggerUpdate 775 776 val memTriggerUpdate = 777 tdata1Update && tdata1TypeWdata.isLegal && mcontrolWdata.isMemAccTrigger || 778 mcontrolSelected.isMemAccTrigger && triggerUpdate 779 780 val triggerEnableVec = tdata1WireVec.zip(mcontrolWireVec).map { case(tdata1, mcontrol) => 781 tdata1.TYPE.isLegal && ( 782 mcontrol.M && privState.isModeM || 783 mcontrol.S && (privState.isModeHS) || 784 mcontrol.U && privState.isModeHU) 785 } 786 787 val fetchTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map { 788 case (tEnable, mod) => tEnable && mod.isFetchTrigger 789 } 790 val memAccTriggerEnableVec = triggerEnableVec.zip(mcontrolWireVec).map { 791 case (tEnable, mod) => tEnable && mod.isMemAccTrigger 792 } 793 794 triggerFrontendChange := frontendTriggerUpdate 795 796 io.out.frontendTrigger.tUpdate.valid := RegNext(RegNext(frontendTriggerUpdate)) 797 io.out.frontendTrigger.tUpdate.bits.addr := tselect.rdata.asUInt 798 io.out.frontendTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected) 799 io.out.frontendTrigger.tEnableVec := fetchTriggerEnableVec 800 io.out.memTrigger.tUpdate.valid := RegNext(RegNext(memTriggerUpdate)) 801 io.out.memTrigger.tUpdate.bits.addr := tselect.rdata.asUInt 802 io.out.memTrigger.tUpdate.bits.tdata.GenTdataDistribute(tdata1Selected, tdata2Selected) 803 io.out.memTrigger.tEnableVec := memAccTriggerEnableVec 804 /** 805 * debug_end 806 */ 807 808 /** 809 * [[io.out.custom]] connection 810 */ 811 io.out.custom.l1I_pf_enable := spfctl.regOut.L1I_PF_ENABLE.asBool 812 io.out.custom.l2_pf_enable := spfctl.regOut.L2_PF_ENABLE.asBool 813 io.out.custom.l1D_pf_enable := spfctl.regOut.L1D_PF_ENABLE.asBool 814 io.out.custom.l1D_pf_train_on_hit := spfctl.regOut.L1D_PF_TRAIN_ON_HIT.asBool 815 io.out.custom.l1D_pf_enable_agt := spfctl.regOut.L1D_PF_ENABLE_AGT.asBool 816 io.out.custom.l1D_pf_enable_pht := spfctl.regOut.L1D_PF_ENABLE_PHT.asBool 817 io.out.custom.l1D_pf_active_threshold := spfctl.regOut.L1D_PF_ACTIVE_THRESHOLD.asUInt 818 io.out.custom.l1D_pf_active_stride := spfctl.regOut.L1D_PF_ACTIVE_STRIDE.asUInt 819 io.out.custom.l1D_pf_enable_stride := spfctl.regOut.L1D_PF_ENABLE_STRIDE.asBool 820 io.out.custom.l2_pf_store_only := spfctl.regOut.L2_PF_STORE_ONLY.asBool 821 822 io.out.custom.icache_parity_enable := sfetchctl.regOut.ICACHE_PARITY_ENABLE.asBool 823 824 io.out.custom.lvpred_disable := slvpredctl.regOut.LVPRED_DISABLE.asBool 825 io.out.custom.no_spec_load := slvpredctl.regOut.NO_SPEC_LOAD.asBool 826 io.out.custom.storeset_wait_store := slvpredctl.regOut.STORESET_WAIT_STORE.asBool 827 io.out.custom.storeset_no_fast_wakeup := slvpredctl.regOut.STORESET_NO_FAST_WAKEUP.asBool 828 io.out.custom.lvpred_timeout := slvpredctl.regOut.LVPRED_TIMEOUT.asUInt 829 830 io.out.custom.bp_ctrl.ubtb_enable := sbpctl.regOut.UBTB_ENABLE .asBool 831 io.out.custom.bp_ctrl.btb_enable := sbpctl.regOut.BTB_ENABLE .asBool 832 io.out.custom.bp_ctrl.bim_enable := sbpctl.regOut.BIM_ENABLE .asBool 833 io.out.custom.bp_ctrl.tage_enable := sbpctl.regOut.TAGE_ENABLE .asBool 834 io.out.custom.bp_ctrl.sc_enable := sbpctl.regOut.SC_ENABLE .asBool 835 io.out.custom.bp_ctrl.ras_enable := sbpctl.regOut.RAS_ENABLE .asBool 836 io.out.custom.bp_ctrl.loop_enable := sbpctl.regOut.LOOP_ENABLE .asBool 837 838 io.out.custom.sbuffer_threshold := smblockctl.regOut.SBUFFER_THRESHOLD.asUInt 839 io.out.custom.ldld_vio_check_enable := smblockctl.regOut.LDLD_VIO_CHECK_ENABLE.asBool 840 io.out.custom.soft_prefetch_enable := smblockctl.regOut.SOFT_PREFETCH_ENABLE.asBool 841 io.out.custom.cache_error_enable := smblockctl.regOut.CACHE_ERROR_ENABLE.asBool 842 io.out.custom.uncache_write_outstanding_enable := smblockctl.regOut.UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool 843 844 io.out.custom.fusion_enable := srnctl.regOut.FUSION_ENABLE.asBool 845 io.out.custom.wfi_enable := srnctl.regOut.WFI_ENABLE.asBool 846 847 // Todo: record the last address to avoid xireg is different with xiselect 848 toAIA.addr.valid := wenLegal && Seq(miselect, siselect, vsiselect).map( 849 _.addr.U === addr 850 ).reduce(_ || _) 851 toAIA.addr.bits.addr := addr 852 toAIA.addr.bits.prvm := PRVM 853 toAIA.addr.bits.v := V 854 toAIA.vgein := hstatus.regOut.VGEIN.asUInt 855 toAIA.wdata.valid := wenLegal && Seq(mireg, sireg, vsireg).map( 856 _.addr.U === addr 857 ).reduce(_ || _) 858 toAIA.wdata.bits.data := wdata 859 toAIA.mClaim := wenLegal && mtopei.addr.U === addr 860 toAIA.sClaim := wenLegal && stopei.addr.U === addr 861 toAIA.vsClaim := wenLegal && vstopei.addr.U === addr 862 863 // tlb 864 io.tlb.satpASIDChanged := wenLegal && addr === CSRs. satp.U && satp .regOut.ASID =/= wdata.asTypeOf(new SatpBundle).ASID 865 io.tlb.vsatpASIDChanged := wenLegal && addr === CSRs.vsatp.U && vsatp.regOut.ASID =/= wdata.asTypeOf(new SatpBundle).ASID 866 io.tlb.hgatpVMIDChanged := wenLegal && addr === CSRs.hgatp.U && hgatp.regOut.VMID =/= wdata.asTypeOf(new HgatpBundle).VMID 867 io.tlb.satp := satp.rdata 868 io.tlb.vsatp := vsatp.rdata 869 io.tlb.hgatp := hgatp.rdata 870 io.tlb.mxr := mstatus.regOut.MXR.asBool 871 io.tlb.sum := mstatus.regOut.SUM.asBool 872 io.tlb.vmxr := vsstatus.regOut.MXR.asBool 873 io.tlb.vsum := vsstatus.regOut.SUM.asBool 874 io.tlb.spvp := hstatus.regOut.SPVP.asBool 875 876 io.tlb.imode := PRVM.asUInt 877 io.tlb.dmode := Mux((debugMode && dcsr.regOut.MPRVEN.asBool || !debugMode) && mstatus.regOut.MPRV.asBool, mstatus.regOut.MPP.asUInt, PRVM.asUInt) 878 879 // Always instantiate basic difftest modules. 880 if (env.AlwaysBasicDiff || env.EnableDifftest) { 881 val hartId = io.fromTop.hartId 882 val trapValid = io.fromRob.trap.valid 883 val trapNO = trapHandleMod.io.out.causeNO.ExceptionCode.asUInt 884 val interrupt = trapHandleMod.io.out.causeNO.Interrupt.asBool 885 val interruptNO = Mux(interrupt, trapNO, 0.U) 886 val exceptionNO = Mux(!interrupt, trapNO, 0.U) 887 val ivmHS = isModeHS && satp.regOut.MODE =/= SatpMode.Bare 888 val ivmVS = isModeVS && vsatp.regOut.MODE =/= SatpMode.Bare 889 // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57 890 val exceptionPC = Mux(ivmHS || ivmVS, SignExt(trapPC, XLEN), ZeroExt(trapPC, XLEN)) 891 892 val diffArchEvent = DifftestModule(new DiffArchEvent, delay = 3, dontCare = true) 893 diffArchEvent.coreid := hartId 894 diffArchEvent.valid := trapValid 895 diffArchEvent.interrupt := interruptNO 896 diffArchEvent.exception := exceptionNO 897 diffArchEvent.exceptionPC := exceptionPC 898 if (env.EnableDifftest) { 899 diffArchEvent.exceptionInst := io.fromRob.trap.bits.instr 900 } 901 902 val diffCSRState = DifftestModule(new DiffCSRState) 903 diffCSRState.coreid := hartId 904 diffCSRState.privilegeMode := privState.PRVM.asUInt 905 diffCSRState.mstatus := mstatus.rdata.asUInt 906 diffCSRState.sstatus := mstatus.sstatus.asUInt 907 diffCSRState.mepc := mepc.rdata.asUInt 908 diffCSRState.sepc := sepc.rdata.asUInt 909 diffCSRState.mtval := mtval.rdata.asUInt 910 diffCSRState.stval := stval.rdata.asUInt 911 diffCSRState.mtvec := mtvec.rdata.asUInt 912 diffCSRState.stvec := stvec.rdata.asUInt 913 diffCSRState.mcause := mcause.rdata.asUInt 914 diffCSRState.scause := scause.rdata.asUInt 915 diffCSRState.satp := satp.rdata.asUInt 916 diffCSRState.mip := mip.regOut.asUInt 917 diffCSRState.mie := mie.rdata.asUInt 918 diffCSRState.mscratch := mscratch.rdata.asUInt 919 diffCSRState.sscratch := sscratch.rdata.asUInt 920 diffCSRState.mideleg := mideleg.rdata.asUInt 921 diffCSRState.medeleg := medeleg.rdata.asUInt 922 923 val diffDebugMode = DifftestModule(new DiffDebugMode) 924 diffDebugMode.coreid := hartId 925 diffDebugMode.debugMode := debugMode 926 diffDebugMode.dcsr := dcsr.rdata.asUInt 927 diffDebugMode.dpc := dpc.rdata.asUInt 928 diffDebugMode.dscratch0 := dscratch0.rdata.asUInt 929 diffDebugMode.dscratch1 := dscratch1.rdata.asUInt 930 931 val diffVecCSRState = DifftestModule(new DiffVecCSRState) 932 diffVecCSRState.coreid := hartId 933 diffVecCSRState.vstart := vstart.rdata.asUInt 934 diffVecCSRState.vxsat := vcsr.vxsat.asUInt 935 diffVecCSRState.vxrm := vcsr.vxrm.asUInt 936 diffVecCSRState.vcsr := vcsr.rdata.asUInt 937 diffVecCSRState.vl := vl.rdata.asUInt 938 diffVecCSRState.vtype := vtype.rdata.asUInt 939 diffVecCSRState.vlenb := vlenb.rdata.asUInt 940 941 val diffHCSRState = DifftestModule(new DiffHCSRState) 942 diffHCSRState.coreid := hartId 943 diffHCSRState.virtMode := privState.V.asBool 944 diffHCSRState.mtval2 := mtval2.rdata.asUInt 945 diffHCSRState.mtinst := mtinst.rdata.asUInt 946 diffHCSRState.hstatus := hstatus.rdata.asUInt 947 diffHCSRState.hideleg := hideleg.rdata.asUInt 948 diffHCSRState.hedeleg := hedeleg.rdata.asUInt 949 diffHCSRState.hcounteren := hcounteren.rdata.asUInt 950 diffHCSRState.htval := htval.rdata.asUInt 951 diffHCSRState.htinst := htinst.rdata.asUInt 952 diffHCSRState.hgatp := hgatp.rdata.asUInt 953 diffHCSRState.vsstatus := vsstatus.rdata.asUInt 954 diffHCSRState.vstvec := vstvec.rdata.asUInt 955 diffHCSRState.vsepc := vsepc.rdata.asUInt 956 diffHCSRState.vscause := vscause.rdata.asUInt 957 diffHCSRState.vstval := vstval.rdata.asUInt 958 diffHCSRState.vsatp := vsatp.rdata.asUInt 959 diffHCSRState.vsscratch := vsscratch.rdata.asUInt 960 961 } 962} 963 964trait SupervisorMachineAliasConnect { self: NewCSR with MachineLevel with SupervisorLevel => 965 mip.fromMvip := mvip.toMip 966 mip.fromSip := sip.toMip 967 mie.fromSie := sie.toMie 968} 969 970object NewCSRMain extends App { 971 val (config, firrtlOpts, firtoolOpts) = ArgParser.parse( 972 args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog") 973 974 val defaultConfig = config.alterPartial({ 975 // Get XSCoreParams and pass it to the "small module" 976 case XSCoreParamsKey => config(XSTileKey).head 977 }) 978 979 Generator.execute( 980 firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend", 981 new NewCSR()(defaultConfig), 982 firtoolOpts 983 ) 984 985 println("done") 986}