xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/Unprivileged.scala (revision ceaa4109647299dad8c9914e5295c15e7eb5c9c3)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import freechips.rocketchip.rocket.CSRs
6import utility.GatedValidRegNext
7import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, CSRWARLField => WARL}
8import xiangshan.backend.fu.NewCSR.CSRFunc._
9import xiangshan.backend.fu.vector.Bundles._
10import xiangshan.backend.fu.NewCSR.CSRConfig._
11import xiangshan.backend.fu.fpu.Bundles.{Fflags, Frm}
12import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._
13
14import scala.collection.immutable.SeqMap
15
16trait Unprivileged { self: NewCSR with MachineLevel with SupervisorLevel =>
17
18  val fcsr = Module(new CSRModule("Fcsr", new CSRBundle {
19    val NX = WARL(0, wNoFilter)
20    val UF = WARL(1, wNoFilter)
21    val OF = WARL(2, wNoFilter)
22    val DZ = WARL(3, wNoFilter)
23    val NV = WARL(4, wNoFilter)
24    val FRM = WARL(7, 5, wNoFilter).withReset(0.U)
25  }) with HasRobCommitBundle {
26    val wAliasFflags = IO(Input(new CSRAddrWriteBundle(new CSRFFlagsBundle)))
27    val wAliasFfm = IO(Input(new CSRAddrWriteBundle(new CSRFrmBundle)))
28    val fflags = IO(Output(Fflags()))
29    val frm = IO(Output(Frm()))
30    val fflagsRdata = IO(Output(Fflags()))
31    val frmRdata = IO(Output(Frm()))
32
33    for (wAlias <- Seq(wAliasFflags, wAliasFfm)) {
34      for ((name, field) <- wAlias.wdataFields.elements) {
35        reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate(
36          wAlias.wen && field.asInstanceOf[CSREnumType].isLegal,
37          field.asInstanceOf[CSREnumType]
38        )
39      }
40    }
41
42    // write connection
43    reconnectReg()
44
45    when (robCommit.fflags.valid) {
46      reg.NX := robCommit.fflags.bits(0) || reg.NX
47      reg.UF := robCommit.fflags.bits(1) || reg.UF
48      reg.OF := robCommit.fflags.bits(2) || reg.OF
49      reg.DZ := robCommit.fflags.bits(3) || reg.DZ
50      reg.NV := robCommit.fflags.bits(4) || reg.NV
51    }
52
53    // read connection
54    fflags := reg.asUInt(4, 0)
55    frm := reg.FRM.asUInt
56
57    fflagsRdata := fflags.asUInt
58    frmRdata := frm.asUInt
59  }).setAddr(CSRs.fcsr)
60
61  // vec
62  val vstart = Module(new CSRModule("Vstart", new CSRBundle {
63    // vstart is not a WARL CSR.
64    // Since we need to judge whether flush pipe by vstart being not 0 in DecodeStage, vstart must be initialized to some value at reset.
65    val vstart = RW(VlWidth - 2, 0).withReset(0.U) // hold [0, 128)
66  }) with HasRobCommitBundle {
67    // Todo make The use of vstart values greater than the largest element index for the current SEW setting is reserved.
68    // Not trap
69    when (wen) {
70      reg.vstart := this.w.wdata(VlWidth - 2, 0)
71    }.elsewhen (robCommit.vsDirty && !robCommit.vstart.valid) {
72      reg.vstart := 0.U
73    }.elsewhen (robCommit.vstart.valid) {
74      reg.vstart := robCommit.vstart.bits
75    }.otherwise {
76      reg := reg
77    }
78  })
79    .setAddr(CSRs.vstart)
80
81  val vcsr = Module(new CSRModule("Vcsr", new CSRBundle {
82    val VXSAT = RW(   0)
83    val VXRM  = RW(2, 1)
84  }) with HasRobCommitBundle {
85    val wAliasVxsat = IO(Input(new CSRAddrWriteBundle(new CSRBundle {
86      val VXSAT = RW(0)
87    })))
88    val wAliasVxrm = IO(Input(new CSRAddrWriteBundle(new CSRBundle {
89      val VXRM = RW(1, 0)
90    })))
91    val vxsat = IO(Output(Vxsat()))
92    val vxrm  = IO(Output(Vxrm()))
93
94    for (wAlias <- Seq(wAliasVxsat, wAliasVxrm)) {
95      for ((name, field) <- wAlias.wdataFields.elements) {
96        reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate(
97          wAlias.wen && field.asInstanceOf[CSREnumType].isLegal,
98          field.asInstanceOf[CSREnumType]
99        )
100      }
101    }
102
103    // write connection
104    reconnectReg()
105
106    when(robCommit.vxsat.valid) {
107      reg.VXSAT := reg.VXSAT.asBool || robCommit.vxsat.bits.asBool
108    }
109
110    // read connection
111    vxsat := reg.VXSAT.asUInt
112    vxrm  := reg.VXRM.asUInt
113  }).setAddr(CSRs.vcsr)
114
115  val vl = Module(new CSRModule("Vl", new CSRBundle {
116    val VL = RO(VlWidth - 1, 0).withReset(0.U)
117  }))
118    .setAddr(CSRs.vl)
119
120  val vtype = Module(new CSRModule("Vtype", new CSRVTypeBundle) with HasRobCommitBundle {
121    when(robCommit.vtype.valid) {
122      reg := robCommit.vtype.bits
123    }
124  })
125    .setAddr(CSRs.vtype)
126
127  val vlenb = Module(new CSRModule("Vlenb", new CSRBundle {
128    val VLENB = VlenbField(63, 0).withReset(VlenbField.init)
129  }))
130    .setAddr(CSRs.vlenb)
131
132  val cycle = Module(new CSRModule("cycle", new CSRBundle {
133    val cycle = RO(63, 0)
134  }) with HasMHPMSink with HasDebugStopBundle {
135    when(unprivCountUpdate) {
136      reg := mHPM.cycle
137    }.otherwise{
138      reg := reg
139    }
140    regOut := Mux(debugModeStopCount, reg.asUInt, mHPM.cycle)
141  })
142    .setAddr(CSRs.cycle)
143
144  val time = Module(new CSRModule("time", new CSRBundle {
145    val time = RO(63, 0)
146  }) with HasMHPMSink with HasDebugStopBundle {
147    val updated = IO(Output(Bool()))
148    val stime  = IO(Output(UInt(64.W)))
149    val vstime = IO(Output(UInt(64.W)))
150
151    val stimeTmp  = mHPM.time.bits
152    val vstimeTmp = mHPM.time.bits + htimedelta
153
154    // Update when rtc clock tick and not dcsr.STOPTIME
155    // or virtual mode changed
156    // Note: we delay a cycle and use `v` for better timing
157    val virtModeChanged = RegNext(nextV =/= v, false.B)
158    when(mHPM.time.valid && !debugModeStopTime || virtModeChanged) {
159      reg.time := Mux(v, vstimeTmp, stimeTmp)
160    }.otherwise {
161      reg := reg
162    }
163
164    updated := GatedValidRegNext(mHPM.time.valid && !debugModeStopTime)
165    stime  := stimeTmp
166    vstime := vstimeTmp
167  })
168    .setAddr(CSRs.time)
169
170  val instret = Module(new CSRModule("instret", new CSRBundle {
171    val instret = RO(63, 0)
172  }) with HasMHPMSink with HasDebugStopBundle {
173    when(unprivCountUpdate) {
174      reg := mHPM.instret
175    }.otherwise{
176      reg := reg
177    }
178    regOut := Mux(debugModeStopCount, reg.asUInt, mHPM.instret)
179  })
180    .setAddr(CSRs.instret)
181
182  val hpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num =>
183    Module(new CSRModule(s"Hpmcounter$num", new CSRBundle {
184      val hpmcounter = RO(63, 0).withReset(0.U)
185    }) with HasMHPMSink with HasDebugStopBundle {
186      when(unprivCountUpdate) {
187        reg := mHPM.hpmcounters(num - 3)
188      }.otherwise{
189        reg := reg
190      }
191      regOut := Mux(debugModeStopCount, reg.asUInt, mHPM.hpmcounters(num - 3))
192    }).setAddr(CSRs.cycle + num)
193  )
194
195  val unprivilegedCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap(
196    CSRs.fflags -> (fcsr.wAliasFflags -> fcsr.fflagsRdata),
197    CSRs.frm    -> (fcsr.wAliasFfm    -> fcsr.frmRdata),
198    CSRs.fcsr   -> (fcsr.w            -> fcsr.rdata),
199    CSRs.vstart -> (vstart.w          -> vstart.rdata),
200    CSRs.vxsat  -> (vcsr.wAliasVxsat  -> vcsr.vxsat),
201    CSRs.vxrm   -> (vcsr.wAliasVxrm   -> vcsr.vxrm),
202    CSRs.vcsr   -> (vcsr.w            -> vcsr.rdata),
203    CSRs.vl     -> (vl.w              -> vl.rdata),
204    CSRs.vtype  -> (vtype.w           -> vtype.rdata),
205    CSRs.vlenb  -> (vlenb.w           -> vlenb.rdata),
206    CSRs.cycle  -> (cycle.w           -> cycle.rdata),
207    CSRs.time   -> (time.w            -> time.rdata),
208    CSRs.instret -> (instret.w        -> instret.rdata),
209  ) ++ hpmcounters.map(counter => (counter.addr -> (counter.w -> counter.rdata)))
210
211  val unprivilegedCSRMods: Seq[CSRModule[_]] = Seq(
212    fcsr,
213    vcsr,
214    vstart,
215    vl,
216    vtype,
217    vlenb,
218    cycle,
219    time,
220    instret,
221  ) ++ hpmcounters
222
223  val unprivilegedCSROutMap: SeqMap[Int, UInt] = SeqMap(
224    CSRs.fflags  -> fcsr.fflags.asUInt,
225    CSRs.frm     -> fcsr.frm.asUInt,
226    CSRs.fcsr    -> fcsr.rdata.asUInt,
227    CSRs.vstart  -> vstart.rdata.asUInt,
228    CSRs.vxsat   -> vcsr.vxsat.asUInt,
229    CSRs.vxrm    -> vcsr.vxrm.asUInt,
230    CSRs.vcsr    -> vcsr.rdata.asUInt,
231    CSRs.vl      -> vl.rdata.asUInt,
232    CSRs.vtype   -> vtype.rdata.asUInt,
233    CSRs.vlenb   -> vlenb.rdata.asUInt,
234    CSRs.cycle   -> cycle.rdata,
235    CSRs.time    -> time.rdata,
236    CSRs.instret -> instret.rdata,
237  ) ++ hpmcounters.map(counter => (counter.addr -> counter.rdata))
238}
239
240class CSRVTypeBundle extends CSRBundle {
241  // vtype's vill is initialized to 1, when executing vector instructions
242  // which depend on vtype, will raise illegal instruction exception
243  val VILL  = RO(  63).withReset(1.U)
244  val VMA   = RO(   7).withReset(0.U)
245  val VTA   = RO(   6).withReset(0.U)
246  val VSEW  = RO(5, 3).withReset(0.U)
247  val VLMUL = RO(2, 0).withReset(0.U)
248}
249
250class CSRFrmBundle extends CSRBundle {
251  val FRM = WARL(2, 0, wNoFilter)
252}
253
254class CSRFFlagsBundle extends CSRBundle {
255  val NX = WARL(0, wNoFilter)
256  val UF = WARL(1, wNoFilter)
257  val OF = WARL(2, wNoFilter)
258  val DZ = WARL(3, wNoFilter)
259  val NV = WARL(4, wNoFilter)
260}
261
262object VlenbField extends CSREnum with ROApply {
263  val init = Value((VLEN / 8).U)
264}
265
266trait HasMHPMSink { self: CSRModule[_] =>
267  val mHPM = IO(Input(new Bundle {
268    val cycle   = UInt(64.W)
269    // ValidIO is used to update time reg
270    val time    = ValidIO(UInt(64.W))
271    val instret = UInt(64.W)
272    val hpmcounters = Vec(perfCntNum, UInt(XLEN.W))
273  }))
274  val v = IO(Input(Bool()))
275  val nextV = IO(Input(Bool()))
276  val htimedelta = IO(Input(UInt(64.W)))
277}
278
279trait HasDebugStopBundle { self: CSRModule[_] =>
280  val debugModeStopCount = IO(Input(Bool()))
281  val debugModeStopTime  = IO(Input(Bool()))
282  val unprivCountUpdate  = IO(Input(Bool()))
283}