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