xref: /XiangShan/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala (revision 25dc4a827ee27e3ccbaf02e8e5134872cba28fcd)
1package xiangshan.backend.fu.wrapper
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import utility._
7import xiangshan._
8import xiangshan.backend.fu.NewCSR._
9import xiangshan.backend.fu.util._
10import xiangshan.backend.fu.{FuConfig, FuncUnit}
11import device._
12import system.HasSoCParameter
13
14class CSR(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg)
15{
16  val csrIn = io.csrio.get
17  val csrOut = io.csrio.get
18
19  val setFsDirty = csrIn.fpu.dirty_fs
20  val setFflags = csrIn.fpu.fflags
21  val setVsDirty = csrIn.vpu.dirty_vs
22  val setVxsat = csrIn.vpu.vxsat
23
24  val flushPipe = Wire(Bool())
25  val flush = io.flush.valid
26
27  val (valid, src1, src2, func) = (
28    io.in.valid,
29    io.in.bits.data.src(0),
30    io.in.bits.data.imm,
31    io.in.bits.ctrl.fuOpType
32  )
33
34  // split imm from IMM_Z
35  val addr = src2(11, 0)
36  val csri = src2(16, 12)
37
38  import CSRConst._
39
40  private val isEcall  = CSROpType.isSystemOp(func) && addr === privEcall
41  private val isEbreak = CSROpType.isSystemOp(func) && addr === privEbreak
42  private val isMret   = CSROpType.isSystemOp(func) && addr === privMret
43  private val isSret   = CSROpType.isSystemOp(func) && addr === privSret
44  private val isDret   = CSROpType.isSystemOp(func) && addr === privDret
45  private val isWfi    = CSROpType.isWfi(func)
46
47  val permitMod = Module(new CSRPermitModule)
48  val csrMod = Module(new NewCSR)
49
50  private val privState = csrMod.io.out.privState
51  // The real reg value in CSR, with no read mask
52  private val regOut = csrMod.io.out.regOut
53  // The read data with read mask
54  private val rdata = csrMod.io.out.rData
55  private val wdata = LookupTree(func, Seq(
56    CSROpType.wrt  -> src1,
57    CSROpType.set  -> (regOut | src1),
58    CSROpType.clr  -> (regOut & (~src1).asUInt),
59    CSROpType.wrti -> csri,
60    CSROpType.seti -> (regOut | csri),
61    CSROpType.clri -> (regOut & (~csri).asUInt),
62  ))
63
64  private val csrAccess = valid && CSROpType.isCsrAccess(func)
65  private val csrWen = valid && CSROpType.notReadOnly(func)
66
67  permitMod.io.in.wen       := csrWen
68  permitMod.io.in.addr      := addr
69  permitMod.io.in.privState := csrMod.io.out.privState
70
71  csrMod.io.in match {
72    case in =>
73      in.wen := csrWen && permitMod.io.out.legal
74      in.ren := csrAccess
75      in.addr := addr
76      in.wdata := wdata
77  }
78  csrMod.io.fromMem.excpVA  := csrIn.memExceptionVAddr
79  csrMod.io.fromMem.excpGPA := csrIn.memExceptionGPAddr
80
81  csrMod.io.fromRob.trap.valid := csrIn.exception.valid
82  csrMod.io.fromRob.trap.bits.pc := csrIn.exception.bits.pc
83  csrMod.io.fromRob.trap.bits.instr := csrIn.exception.bits.instr
84  // Todo: shrink the width of trap vector.
85  // We use 64bits trap vector in CSR, and 24 bits exceptionVec in exception bundle.
86  csrMod.io.fromRob.trap.bits.trapVec := csrIn.exception.bits.exceptionVec.asUInt
87  csrMod.io.fromRob.trap.bits.singleStep := csrIn.exception.bits.singleStep
88  csrMod.io.fromRob.trap.bits.crossPageIPFFix := csrIn.exception.bits.crossPageIPFFix
89  csrMod.io.fromRob.trap.bits.isInterrupt := csrIn.exception.bits.isInterrupt
90
91  csrMod.io.fromRob.commit.fflags := setFflags
92  csrMod.io.fromRob.commit.fsDirty := setFsDirty
93  csrMod.io.fromRob.commit.vxsat.valid := true.B // Todo:
94  csrMod.io.fromRob.commit.vxsat.bits := setVxsat // Todo:
95  csrMod.io.fromRob.commit.vsDirty := setVsDirty
96  csrMod.io.fromRob.commit.commitValid := false.B // Todo:
97  csrMod.io.fromRob.commit.commitInstRet := 0.U // Todo:
98
99  csrMod.io.mret := isMret
100  csrMod.io.sret := isSret
101  csrMod.io.dret := isDret
102  csrMod.io.wfi  := isWfi
103
104  csrMod.platformIRP.MEIP := csrIn.externalInterrupt.meip
105  csrMod.platformIRP.MTIP := csrIn.externalInterrupt.mtip
106  csrMod.platformIRP.MSIP := csrIn.externalInterrupt.msip
107  csrMod.platformIRP.SEIP := csrIn.externalInterrupt.seip
108  csrMod.platformIRP.VSEIP := false.B // Todo
109  csrMod.platformIRP.VSTIP := false.B // Todo
110  csrMod.platformIRP.debugIP := csrIn.externalInterrupt.debug
111
112  private val imsic = Module(new IMSIC)
113  imsic.i.hartId := io.csrin.get.hartId
114  imsic.i.setIpNumValidVec2 := io.csrin.get.setIpNumValidVec2
115  imsic.i.setIpNum.valid := true.B // Todo:
116  imsic.i.setIpNum.bits := io.csrin.get.setIpNum // Todo:
117  imsic.i.csr.addr.valid := csrMod.toAIA.addr.valid
118  imsic.i.csr.addr.bits.addr := csrMod.toAIA.addr.bits.addr
119  imsic.i.csr.addr.bits.prvm := csrMod.toAIA.addr.bits.prvm.asUInt
120  imsic.i.csr.addr.bits.v := csrMod.toAIA.addr.bits.v.asUInt
121  imsic.i.csr.vgein := csrMod.toAIA.vgein
122  imsic.i.csr.mClaim := csrMod.toAIA.mClaim
123  imsic.i.csr.sClaim := csrMod.toAIA.sClaim
124  imsic.i.csr.vsClaim := csrMod.toAIA.vsClaim
125  imsic.i.csr.wdata.valid := csrMod.toAIA.wdata.valid
126  imsic.i.csr.wdata.bits.data := csrMod.toAIA.wdata.bits.data
127
128  csrMod.fromAIA.rdata.valid := imsic.o.csr.rdata.valid
129  csrMod.fromAIA.rdata.bits.data := imsic.o.csr.rdata.bits.rdata
130  csrMod.fromAIA.rdata.bits.illegal := imsic.o.csr.rdata.bits.illegal
131  csrMod.fromAIA.mtopei.valid := imsic.o.mtopei.valid
132  csrMod.fromAIA.stopei.valid := imsic.o.stopei.valid
133  csrMod.fromAIA.vstopei.valid := imsic.o.vstopei.valid
134  csrMod.fromAIA.mtopei.bits := imsic.o.mtopei.bits
135  csrMod.fromAIA.stopei.bits := imsic.o.stopei.bits
136  csrMod.fromAIA.vstopei.bits := imsic.o.vstopei.bits
137
138  private val exceptionVec = WireInit(0.U.asTypeOf(ExceptionVec())) // Todo:
139  import ExceptionNO._
140  exceptionVec(EX_BP    ) := isEbreak
141  exceptionVec(EX_MCALL ) := isEcall && privState.isModeM
142  exceptionVec(EX_HSCALL) := isEcall && privState.isModeHS
143  exceptionVec(EX_VSCALL) := isEcall && privState.isModeVS
144  exceptionVec(EX_UCALL ) := isEcall && privState.isModeHUorVU
145  exceptionVec(EX_II    ) := csrMod.io.out.EX_II
146  //exceptionVec(EX_VI    ) := csrMod.io.out.EX_VI // Todo: check other EX_VI
147
148  val isXRet = valid && func === CSROpType.jmp && !isEcall && !isEbreak
149
150  // ctrl block will use theses later for flush
151  val isXRetFlag = RegInit(false.B)
152  isXRetFlag := Mux1H(
153    Seq(
154      DelayN(flush, 5),
155      isXRet,
156    ),
157    Seq(
158      false.B,
159      true.B,
160    )
161  )
162
163  flushPipe := csrMod.io.out.flushPipe || isXRet // || frontendTriggerUpdate // Todo: trigger
164
165  // tlb
166  val tlb = Wire(new TlbCsrBundle)
167  tlb.satp.apply(csrMod.io.tlb.satp)
168  // expose several csr bits for tlb
169  tlb.priv.mxr := csrMod.io.tlb.mxr
170  tlb.priv.sum := csrMod.io.tlb.sum
171  tlb.priv.imode := csrMod.io.tlb.imode
172  tlb.priv.dmode := csrMod.io.tlb.dmode
173
174  io.in.ready := true.B // Todo: Async read imsic may block CSR
175  io.out.valid := valid
176  io.out.bits.ctrl.exceptionVec.get := exceptionVec
177  io.out.bits.ctrl.flushPipe.get := flushPipe
178  io.out.bits.res.data := csrMod.io.out.rData
179  connect0LatencyCtrlSingal
180
181  csrOut.isPerfCnt  := csrMod.io.out.isPerfCnt && valid && func =/= CSROpType.jmp
182  csrOut.fpu.frm    := csrMod.io.out.frm
183  csrOut.vpu.vstart := csrMod.io.out.vstart
184  csrOut.vpu.vxsat  := csrMod.io.out.vxsat
185  csrOut.vpu.vxrm   := csrMod.io.out.vxrm
186  csrOut.vpu.vcsr   := csrMod.io.out.vcsr
187  csrOut.vpu.vl     := csrMod.io.out.vl
188  csrOut.vpu.vtype  := csrMod.io.out.vtype
189  csrOut.vpu.vlenb  := csrMod.io.out.vlenb
190  csrOut.vpu.vill   := csrMod.io.out.vtype.asTypeOf(new VtypeBundle).VILL.asUInt
191  csrOut.vpu.vma    := csrMod.io.out.vtype.asTypeOf(new VtypeBundle).VMA.asUInt
192  csrOut.vpu.vta    := csrMod.io.out.vtype.asTypeOf(new VtypeBundle).VTA.asUInt
193  csrOut.vpu.vsew   := csrMod.io.out.vtype.asTypeOf(new VtypeBundle).VSEW.asUInt
194  csrOut.vpu.vlmul  := csrMod.io.out.vtype.asTypeOf(new VtypeBundle).VLMUL.asUInt
195
196  csrOut.isXRet := isXRetFlag
197
198  csrOut.trapTarget := csrMod.io.out.targetPc
199  csrOut.interrupt := csrMod.io.out.interrupt
200  csrOut.wfi_event := csrMod.io.out.wfi_event
201
202  csrOut.tlb := tlb
203
204  csrOut.debugMode := csrMod.io.out.debugMode
205
206  csrOut.disableSfence := csrMod.io.out.disableSfence
207
208  csrOut.customCtrl match {
209    case custom =>
210      custom.l1I_pf_enable           := csrMod.io.customCtrl.spfctl.asTypeOf(new SpfctlBundle).L1I_PF_ENABLE.asBool
211      custom.l2_pf_enable            := csrMod.io.customCtrl.spfctl.asTypeOf(new SpfctlBundle).L2_PF_ENABLE.asBool
212      custom.l1D_pf_enable           := csrMod.io.customCtrl.spfctl.asTypeOf(new SpfctlBundle).L1D_PF_ENABLE.asBool
213      custom.l1D_pf_train_on_hit     := csrMod.io.customCtrl.spfctl.asTypeOf(new SpfctlBundle).L1D_PF_TRAIN_ON_HIT.asBool
214      custom.l1D_pf_enable_agt       := csrMod.io.customCtrl.spfctl.asTypeOf(new SpfctlBundle).L1D_PF_ENABLE_AGT.asBool
215      custom.l1D_pf_enable_pht       := csrMod.io.customCtrl.spfctl.asTypeOf(new SpfctlBundle).L1D_PF_ENABLE_PHT.asBool
216      custom.l1D_pf_active_threshold := csrMod.io.customCtrl.spfctl.asTypeOf(new SpfctlBundle).L1D_PF_ACTIVE_THRESHOLD.asBool
217      custom.l1D_pf_active_stride    := csrMod.io.customCtrl.spfctl.asTypeOf(new SpfctlBundle).L1D_PF_ACTIVE_STRIDE.asBool
218      custom.l1D_pf_enable_stride    := csrMod.io.customCtrl.spfctl.asTypeOf(new SpfctlBundle).L1D_PF_ENABLE_STRIDE.asBool
219      custom.l2_pf_store_only        := csrMod.io.customCtrl.spfctl.asTypeOf(new SpfctlBundle).L2_PF_STORE_ONLY.asBool
220      // ICache
221      custom.icache_parity_enable := csrMod.io.customCtrl.sfetchctl
222      // Labeled XiangShan
223      custom.dsid := csrMod.io.customCtrl.sdsid
224      // Load violation predictor
225      custom.lvpred_disable          := csrMod.io.customCtrl.slvpredctl.asTypeOf(new SlvpredctlBundle).LVPRED_DISABLE.asBool
226      custom.no_spec_load            := csrMod.io.customCtrl.slvpredctl.asTypeOf(new SlvpredctlBundle).NO_SPEC_LOAD.asBool
227      custom.storeset_wait_store     := csrMod.io.customCtrl.slvpredctl.asTypeOf(new SlvpredctlBundle).STORESET_WAIT_STORE.asBool
228      custom.storeset_no_fast_wakeup := csrMod.io.customCtrl.slvpredctl.asTypeOf(new SlvpredctlBundle).STORESET_NO_FAST_WAKEUP.asBool
229      custom.lvpred_timeout          := csrMod.io.customCtrl.slvpredctl.asTypeOf(new SlvpredctlBundle).LVPRED_TIMEOUT.asUInt
230      // Branch predictor
231      custom.bp_ctrl := csrMod.io.customCtrl.sbpctl.asUInt(6, 0)
232      // Memory Block
233      custom.sbuffer_threshold     := csrMod.io.customCtrl.smblockctl.asTypeOf(new SmblockctlBundle).SBUFFER_THRESHOLD.asUInt
234      custom.ldld_vio_check_enable := csrMod.io.customCtrl.smblockctl.asTypeOf(new SmblockctlBundle).LDLD_VIO_CHECK_ENABLE.asBool
235      custom.soft_prefetch_enable  := csrMod.io.customCtrl.smblockctl.asTypeOf(new SmblockctlBundle).SOFT_PREFETCH_ENABLE.asBool
236      custom.cache_error_enable    := csrMod.io.customCtrl.smblockctl.asTypeOf(new SmblockctlBundle).CACHE_ERROR_ENABLE.asBool
237      custom.uncache_write_outstanding_enable := csrMod.io.customCtrl.smblockctl.asTypeOf(new SmblockctlBundle).UNCACHE_WRITE_OUTSTANDING_ENABLE.asBool
238      // Rename
239      custom.fusion_enable := csrMod.io.customCtrl.srnctl.asTypeOf(new SrnctlBundle).FUSION_ENABLE.asBool
240      custom.wfi_enable    := csrMod.io.customCtrl.srnctl.asTypeOf(new SrnctlBundle).WFI_ENABLE.asBool
241      // Decode
242      custom.svinval_enable := csrMod.io.customCtrl.srnctl.asTypeOf(new SrnctlBundle).SVINVAL_ENABLE.asBool
243      // distribute csr write signal
244      // write to frontend and memory
245      custom.distribute_csr.w.valid // Todo:
246      custom.distribute_csr.w.bits.addr := addr
247      custom.distribute_csr.w.bits.data := wdata
248      // rename single step
249      custom.singlestep := DontCare
250      // trigger
251      custom.frontend_trigger := DontCare
252      custom.mem_trigger := DontCare
253  }
254}
255
256class CSRInput(implicit p: Parameters) extends XSBundle with HasSoCParameter{
257  val hartId = Input(UInt(8.W))
258  val setIpNumValidVec2 = Input(UInt(SetIpNumValidSize.W))
259  val setIpNum = Input(UInt(log2Up(NumIRSrc).W))
260}