xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/Unprivileged.scala (revision b03c55a5df5dc8793cb44b42dd60141566e57e78)
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)
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    // write connection
34    this.wfn(reg)(Seq(wAliasFflags, wAliasFfm))
35
36    when (robCommit.fflags.valid) {
37      reg.NX := robCommit.fflags.bits(0) || reg.NX
38      reg.UF := robCommit.fflags.bits(1) || reg.UF
39      reg.OF := robCommit.fflags.bits(2) || reg.OF
40      reg.DZ := robCommit.fflags.bits(3) || reg.DZ
41      reg.NV := robCommit.fflags.bits(4) || reg.NV
42    }
43
44    // read connection
45    fflags := reg.asUInt(4, 0)
46    frm := reg.FRM.asUInt
47
48    fflagsRdata := fflags.asUInt
49    frmRdata := frm.asUInt
50  }).setAddr(CSRs.fcsr)
51
52  // vec
53  val vstart = Module(new CSRModule("Vstart", new CSRBundle {
54    val vstart = RW(VlWidth - 2, 0) // hold [0, 128)
55  }) with HasRobCommitBundle {
56    // Todo make The use of vstart values greater than the largest element index for the current SEW setting is reserved.
57    // Not trap
58    when (wen) {
59      reg.vstart := this.w.wdata(VlWidth - 2, 0)
60    }.elsewhen (robCommit.vsDirty && !robCommit.vstart.valid) {
61      reg.vstart := 0.U
62    }.elsewhen (robCommit.vstart.valid) {
63      reg.vstart := robCommit.vstart.bits
64    }.otherwise {
65      reg := reg
66    }
67  })
68    .setAddr(CSRs.vstart)
69
70  val vcsr = Module(new CSRModule("Vcsr", new CSRBundle {
71    val VXSAT = RW(   0)
72    val VXRM  = RW(2, 1)
73  }) with HasRobCommitBundle {
74    val wAliasVxsat = IO(Input(new CSRAddrWriteBundle(new CSRBundle {
75      val VXSAT = RW(0)
76    })))
77    val wAlisaVxrm = IO(Input(new CSRAddrWriteBundle(new CSRBundle {
78      val VXRM = RW(1, 0)
79    })))
80    val vxsat = IO(Output(Vxsat()))
81    val vxrm  = IO(Output(Vxrm()))
82
83    // write connection
84    this.wfn(reg)(Seq(wAliasVxsat, wAlisaVxrm))
85
86    when(robCommit.vxsat.valid) {
87      reg.VXSAT := reg.VXSAT.asBool || robCommit.vxsat.bits.asBool
88    }
89
90    // read connection
91    vxsat := reg.VXSAT.asUInt
92    vxrm  := reg.VXRM.asUInt
93  }).setAddr(CSRs.vcsr)
94
95  val vl = Module(new CSRModule("Vl", new CSRBundle {
96    val VL = RO(VlWidth - 1, 0)
97  }))
98    .setAddr(CSRs.vl)
99
100  val vtype = Module(new CSRModule("Vtype", new CSRVTypeBundle) with HasRobCommitBundle {
101    when(robCommit.vtype.valid) {
102      reg := robCommit.vtype.bits
103    }
104  })
105    .setAddr(CSRs.vtype)
106
107  val vlenb = Module(new CSRModule("Vlenb", new CSRBundle {
108    val VLENB = VlenbField(63, 0).withReset(VlenbField.init)
109  }))
110    .setAddr(CSRs.vlenb)
111
112  val cycle = Module(new CSRModule("cycle", new CSRBundle {
113    val cycle = RO(63, 0)
114  }) with HasMHPMSink {
115    regOut.cycle := mHPM.cycle
116  })
117    .setAddr(CSRs.cycle)
118
119  val time = Module(new CSRModule("time", new CSRBundle {
120    val time = RO(63, 0)
121  }) with HasMHPMSink {
122    val updated = IO(Output(Bool()))
123    val stime  = IO(Output(UInt(64.W)))
124    val vstime = IO(Output(UInt(64.W)))
125
126    val stimeTmp  = mHPM.time.bits
127    val vstimeTmp = mHPM.time.bits + htimedelta
128
129    when (mHPM.time.valid) {
130      reg.time := Mux(v, vstimeTmp, stimeTmp)
131    }
132
133    updated := GatedValidRegNext(mHPM.time.valid)
134    stime  := stimeTmp
135    vstime := vstimeTmp
136  })
137    .setAddr(CSRs.time)
138
139  val instret = Module(new CSRModule("instret", new CSRBundle {
140    val instret = RO(63, 0)
141  }) with HasMHPMSink {
142    regOut.instret := mHPM.instret
143  })
144    .setAddr(CSRs.instret)
145
146  val hpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num =>
147    Module(new CSRModule(s"Hpmcounter$num", new CSRBundle {
148      val hpmcounter = RO(63, 0).withReset(0.U)
149    }) with HasMHPMSink {
150      regOut.hpmcounter := mHPM.hpmcounters(num - 3)
151    }).setAddr(CSRs.cycle + num)
152  )
153
154  val unprivilegedCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap(
155    CSRs.fflags -> (fcsr.wAliasFflags -> fcsr.fflagsRdata),
156    CSRs.frm    -> (fcsr.wAliasFfm    -> fcsr.frmRdata),
157    CSRs.fcsr   -> (fcsr.w            -> fcsr.rdata),
158    CSRs.vstart -> (vstart.w          -> vstart.rdata),
159    CSRs.vxsat  -> (vcsr.wAliasVxsat  -> vcsr.vxsat),
160    CSRs.vxrm   -> (vcsr.wAlisaVxrm   -> vcsr.vxrm),
161    CSRs.vcsr   -> (vcsr.w            -> vcsr.rdata),
162    CSRs.vl     -> (vl.w              -> vl.rdata),
163    CSRs.vtype  -> (vtype.w           -> vtype.rdata),
164    CSRs.vlenb  -> (vlenb.w           -> vlenb.rdata),
165    CSRs.cycle  -> (cycle.w           -> cycle.rdata),
166    CSRs.time   -> (time.w            -> time.rdata),
167    CSRs.instret -> (instret.w        -> instret.rdata),
168  ) ++ hpmcounters.map(counter => (counter.addr -> (counter.w -> counter.rdata)))
169
170  val unprivilegedCSRMods: Seq[CSRModule[_]] = Seq(
171    fcsr,
172    vcsr,
173    vstart,
174    vl,
175    vtype,
176    vlenb,
177    cycle,
178    time,
179    instret,
180  ) ++ hpmcounters
181
182  val unprivilegedCSROutMap: SeqMap[Int, UInt] = SeqMap(
183    CSRs.fflags  -> fcsr.fflags.asUInt,
184    CSRs.frm     -> fcsr.frm.asUInt,
185    CSRs.fcsr    -> fcsr.rdata.asUInt,
186    CSRs.vstart  -> vstart.rdata.asUInt,
187    CSRs.vxsat   -> vcsr.vxsat.asUInt,
188    CSRs.vxrm    -> vcsr.vxrm.asUInt,
189    CSRs.vcsr    -> vcsr.rdata.asUInt,
190    CSRs.vl      -> vl.rdata.asUInt,
191    CSRs.vtype   -> vtype.rdata.asUInt,
192    CSRs.vlenb   -> vlenb.rdata.asUInt,
193    CSRs.cycle   -> cycle.rdata,
194    CSRs.time    -> time.rdata,
195    CSRs.instret -> instret.rdata,
196  ) ++ hpmcounters.map(counter => (counter.addr -> counter.rdata))
197}
198
199class CSRVTypeBundle extends CSRBundle {
200  val VILL  = RO(  63)
201  val VMA   = RO(   7)
202  val VTA   = RO(   6)
203  val VSEW  = RO(5, 3)
204  val VLMUL = RO(2, 0)
205}
206
207class CSRFrmBundle extends CSRBundle {
208  val FRM = WARL(2, 0, wNoFilter)
209}
210
211class CSRFFlagsBundle extends CSRBundle {
212  val NX = WARL(0, wNoFilter)
213  val UF = WARL(1, wNoFilter)
214  val OF = WARL(2, wNoFilter)
215  val DZ = WARL(3, wNoFilter)
216  val NV = WARL(4, wNoFilter)
217}
218
219object VlenbField extends CSREnum with ROApply {
220  val init = Value((VLEN / 8).U)
221}
222
223trait HasMHPMSink { self: CSRModule[_] =>
224  val mHPM = IO(Input(new Bundle {
225    val cycle   = UInt(64.W)
226    // ValidIO is used to update time reg
227    val time    = ValidIO(UInt(64.W))
228    val instret = UInt(64.W)
229    val hpmcounters = Vec(perfCntNum, UInt(XLEN.W))
230  }))
231  val v = IO(Input(Bool()))
232  val htimedelta = IO(Input(UInt(64.W)))
233}
234