xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/Unprivileged.scala (revision ceaa4109647299dad8c9914e5295c15e7eb5c9c3)
1039cdc35SXuan Hupackage xiangshan.backend.fu.NewCSR
2039cdc35SXuan Hu
3039cdc35SXuan Huimport chisel3._
4e628dd84SXuan Huimport chisel3.util._
5e628dd84SXuan Huimport freechips.rocketchip.rocket.CSRs
60b4c00ffSXuan Huimport utility.GatedValidRegNext
701cdded8SXuan Huimport xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, CSRWARLField => WARL}
8039cdc35SXuan Huimport xiangshan.backend.fu.NewCSR.CSRFunc._
9007f6122SXuan Huimport xiangshan.backend.fu.vector.Bundles._
1001cdded8SXuan Huimport xiangshan.backend.fu.NewCSR.CSRConfig._
1101cdded8SXuan Huimport xiangshan.backend.fu.fpu.Bundles.{Fflags, Frm}
1201cdded8SXuan Huimport xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._
13039cdc35SXuan Hu
14039cdc35SXuan Huimport scala.collection.immutable.SeqMap
15039cdc35SXuan Hu
16039cdc35SXuan Hutrait Unprivileged { self: NewCSR with MachineLevel with SupervisorLevel =>
17039cdc35SXuan Hu
18039cdc35SXuan Hu  val fcsr = Module(new CSRModule("Fcsr", new CSRBundle {
19007f6122SXuan Hu    val NX = WARL(0, wNoFilter)
20007f6122SXuan Hu    val UF = WARL(1, wNoFilter)
21007f6122SXuan Hu    val OF = WARL(2, wNoFilter)
22007f6122SXuan Hu    val DZ = WARL(3, wNoFilter)
23007f6122SXuan Hu    val NV = WARL(4, wNoFilter)
24689f6b88SsinceforYy    val FRM = WARL(7, 5, wNoFilter).withReset(0.U)
2501cdded8SXuan Hu  }) with HasRobCommitBundle {
2601cdded8SXuan Hu    val wAliasFflags = IO(Input(new CSRAddrWriteBundle(new CSRFFlagsBundle)))
2701cdded8SXuan Hu    val wAliasFfm = IO(Input(new CSRAddrWriteBundle(new CSRFrmBundle)))
2801cdded8SXuan Hu    val fflags = IO(Output(Fflags()))
2901cdded8SXuan Hu    val frm = IO(Output(Frm()))
3094895e77SXuan Hu    val fflagsRdata = IO(Output(Fflags()))
3194895e77SXuan Hu    val frmRdata = IO(Output(Frm()))
32039cdc35SXuan Hu
33cb36ac0fSXuan Hu    for (wAlias <- Seq(wAliasFflags, wAliasFfm)) {
34cb36ac0fSXuan Hu      for ((name, field) <- wAlias.wdataFields.elements) {
35cb36ac0fSXuan Hu        reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate(
36cb36ac0fSXuan Hu          wAlias.wen && field.asInstanceOf[CSREnumType].isLegal,
37cb36ac0fSXuan Hu          field.asInstanceOf[CSREnumType]
38cb36ac0fSXuan Hu        )
39cb36ac0fSXuan Hu      }
40cb36ac0fSXuan Hu    }
41cb36ac0fSXuan Hu
42039cdc35SXuan Hu    // write connection
43cb36ac0fSXuan Hu    reconnectReg()
44039cdc35SXuan Hu
4501cdded8SXuan Hu    when (robCommit.fflags.valid) {
4601cdded8SXuan Hu      reg.NX := robCommit.fflags.bits(0) || reg.NX
4701cdded8SXuan Hu      reg.UF := robCommit.fflags.bits(1) || reg.UF
4801cdded8SXuan Hu      reg.OF := robCommit.fflags.bits(2) || reg.OF
4901cdded8SXuan Hu      reg.DZ := robCommit.fflags.bits(3) || reg.DZ
5001cdded8SXuan Hu      reg.NV := robCommit.fflags.bits(4) || reg.NV
5101cdded8SXuan Hu    }
5201cdded8SXuan Hu
53039cdc35SXuan Hu    // read connection
54039cdc35SXuan Hu    fflags := reg.asUInt(4, 0)
55039cdc35SXuan Hu    frm := reg.FRM.asUInt
5694895e77SXuan Hu
5794895e77SXuan Hu    fflagsRdata := fflags.asUInt
5894895e77SXuan Hu    frmRdata := frm.asUInt
592c054816SsinceforYy  }).setAddr(CSRs.fcsr)
60007f6122SXuan Hu
61007f6122SXuan Hu  // vec
6201cdded8SXuan Hu  val vstart = Module(new CSRModule("Vstart", new CSRBundle {
63dcaa6f06SXuan Hu    // vstart is not a WARL CSR.
64dcaa6f06SXuan Hu    // Since we need to judge whether flush pipe by vstart being not 0 in DecodeStage, vstart must be initialized to some value at reset.
65dcaa6f06SXuan Hu    val vstart = RW(VlWidth - 2, 0).withReset(0.U) // hold [0, 128)
6601cdded8SXuan Hu  }) with HasRobCommitBundle {
6701cdded8SXuan Hu    // Todo make The use of vstart values greater than the largest element index for the current SEW setting is reserved.
6801cdded8SXuan Hu    // Not trap
691dfefe3cSZhaoyang You    when (wen) {
7001cdded8SXuan Hu      reg.vstart := this.w.wdata(VlWidth - 2, 0)
71c715e8feSXuan Hu    }.elsewhen (robCommit.vsDirty && !robCommit.vstart.valid) {
72c715e8feSXuan Hu      reg.vstart := 0.U
7301cdded8SXuan Hu    }.elsewhen (robCommit.vstart.valid) {
7401cdded8SXuan Hu      reg.vstart := robCommit.vstart.bits
75c715e8feSXuan Hu    }.otherwise {
76c715e8feSXuan Hu      reg := reg
7701cdded8SXuan Hu    }
7801cdded8SXuan Hu  })
792c054816SsinceforYy    .setAddr(CSRs.vstart)
80007f6122SXuan Hu
81007f6122SXuan Hu  val vcsr = Module(new CSRModule("Vcsr", new CSRBundle {
8201cdded8SXuan Hu    val VXSAT = RW(   0)
8301cdded8SXuan Hu    val VXRM  = RW(2, 1)
8401cdded8SXuan Hu  }) with HasRobCommitBundle {
85007f6122SXuan Hu    val wAliasVxsat = IO(Input(new CSRAddrWriteBundle(new CSRBundle {
8601cdded8SXuan Hu      val VXSAT = RW(0)
87007f6122SXuan Hu    })))
88*ceaa4109Sjunxiong-ji    val wAliasVxrm = IO(Input(new CSRAddrWriteBundle(new CSRBundle {
8901cdded8SXuan Hu      val VXRM = RW(1, 0)
90007f6122SXuan Hu    })))
91007f6122SXuan Hu    val vxsat = IO(Output(Vxsat()))
92007f6122SXuan Hu    val vxrm  = IO(Output(Vxrm()))
93007f6122SXuan Hu
94*ceaa4109Sjunxiong-ji    for (wAlias <- Seq(wAliasVxsat, wAliasVxrm)) {
95cb36ac0fSXuan Hu      for ((name, field) <- wAlias.wdataFields.elements) {
96cb36ac0fSXuan Hu        reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate(
97cb36ac0fSXuan Hu          wAlias.wen && field.asInstanceOf[CSREnumType].isLegal,
98cb36ac0fSXuan Hu          field.asInstanceOf[CSREnumType]
99cb36ac0fSXuan Hu        )
100cb36ac0fSXuan Hu      }
101cb36ac0fSXuan Hu    }
102cb36ac0fSXuan Hu
103007f6122SXuan Hu    // write connection
104cb36ac0fSXuan Hu    reconnectReg()
105007f6122SXuan Hu
10601cdded8SXuan Hu    when(robCommit.vxsat.valid) {
10701cdded8SXuan Hu      reg.VXSAT := reg.VXSAT.asBool || robCommit.vxsat.bits.asBool
10801cdded8SXuan Hu    }
10901cdded8SXuan Hu
110007f6122SXuan Hu    // read connection
111007f6122SXuan Hu    vxsat := reg.VXSAT.asUInt
112007f6122SXuan Hu    vxrm  := reg.VXRM.asUInt
1132c054816SsinceforYy  }).setAddr(CSRs.vcsr)
114007f6122SXuan Hu
11501cdded8SXuan Hu  val vl = Module(new CSRModule("Vl", new CSRBundle {
1165ae0e5deSZiyue Zhang    val VL = RO(VlWidth - 1, 0).withReset(0.U)
117d23963a8SXuan Hu  }))
1182c054816SsinceforYy    .setAddr(CSRs.vl)
119007f6122SXuan Hu
12001cdded8SXuan Hu  val vtype = Module(new CSRModule("Vtype", new CSRVTypeBundle) with HasRobCommitBundle {
12101cdded8SXuan Hu    when(robCommit.vtype.valid) {
12201cdded8SXuan Hu      reg := robCommit.vtype.bits
12301cdded8SXuan Hu    }
12401cdded8SXuan Hu  })
1252c054816SsinceforYy    .setAddr(CSRs.vtype)
126007f6122SXuan Hu
12701cdded8SXuan Hu  val vlenb = Module(new CSRModule("Vlenb", new CSRBundle {
12801cdded8SXuan Hu    val VLENB = VlenbField(63, 0).withReset(VlenbField.init)
12901cdded8SXuan Hu  }))
1302c054816SsinceforYy    .setAddr(CSRs.vlenb)
131039cdc35SXuan Hu
13265ddf865SXuan Hu  val cycle = Module(new CSRModule("cycle", new CSRBundle {
13365ddf865SXuan Hu    val cycle = RO(63, 0)
1341e49aeedSchengguanghui  }) with HasMHPMSink with HasDebugStopBundle {
1351e49aeedSchengguanghui    when(unprivCountUpdate) {
1361e49aeedSchengguanghui      reg := mHPM.cycle
1371e49aeedSchengguanghui    }.otherwise{
1381e49aeedSchengguanghui      reg := reg
1391e49aeedSchengguanghui    }
1401e49aeedSchengguanghui    regOut := Mux(debugModeStopCount, reg.asUInt, mHPM.cycle)
14165ddf865SXuan Hu  })
14265ddf865SXuan Hu    .setAddr(CSRs.cycle)
14365ddf865SXuan Hu
144e628dd84SXuan Hu  val time = Module(new CSRModule("time", new CSRBundle {
145e628dd84SXuan Hu    val time = RO(63, 0)
1461e49aeedSchengguanghui  }) with HasMHPMSink with HasDebugStopBundle {
1470b4c00ffSXuan Hu    val updated = IO(Output(Bool()))
148244b1012SsinceforYy    val stime  = IO(Output(UInt(64.W)))
149244b1012SsinceforYy    val vstime = IO(Output(UInt(64.W)))
150244b1012SsinceforYy
151244b1012SsinceforYy    val stimeTmp  = mHPM.time.bits
152244b1012SsinceforYy    val vstimeTmp = mHPM.time.bits + htimedelta
1530b4c00ffSXuan Hu
1542e25304fSXu, Zefan    // Update when rtc clock tick and not dcsr.STOPTIME
1552e25304fSXu, Zefan    // or virtual mode changed
156d94fbfffSTang Haojin    // Note: we delay a cycle and use `v` for better timing
157d94fbfffSTang Haojin    val virtModeChanged = RegNext(nextV =/= v, false.B)
158d94fbfffSTang Haojin    when(mHPM.time.valid && !debugModeStopTime || virtModeChanged) {
159244b1012SsinceforYy      reg.time := Mux(v, vstimeTmp, stimeTmp)
1601e49aeedSchengguanghui    }.otherwise {
1611e49aeedSchengguanghui      reg := reg
162e628dd84SXuan Hu    }
1630b4c00ffSXuan Hu
1641e49aeedSchengguanghui    updated := GatedValidRegNext(mHPM.time.valid && !debugModeStopTime)
165244b1012SsinceforYy    stime  := stimeTmp
166244b1012SsinceforYy    vstime := vstimeTmp
167e628dd84SXuan Hu  })
168e628dd84SXuan Hu    .setAddr(CSRs.time)
169e628dd84SXuan Hu
17065ddf865SXuan Hu  val instret = Module(new CSRModule("instret", new CSRBundle {
17165ddf865SXuan Hu    val instret = RO(63, 0)
1721e49aeedSchengguanghui  }) with HasMHPMSink with HasDebugStopBundle {
1731e49aeedSchengguanghui    when(unprivCountUpdate) {
1741e49aeedSchengguanghui      reg := mHPM.instret
1751e49aeedSchengguanghui    }.otherwise{
1761e49aeedSchengguanghui      reg := reg
1771e49aeedSchengguanghui    }
1781e49aeedSchengguanghui    regOut := Mux(debugModeStopCount, reg.asUInt, mHPM.instret)
17965ddf865SXuan Hu  })
18065ddf865SXuan Hu    .setAddr(CSRs.instret)
18165ddf865SXuan Hu
182b51a1abdSchengguanghui  val hpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num =>
183b51a1abdSchengguanghui    Module(new CSRModule(s"Hpmcounter$num", new CSRBundle {
184499d09b3SsinceforYy      val hpmcounter = RO(63, 0).withReset(0.U)
1851e49aeedSchengguanghui    }) with HasMHPMSink with HasDebugStopBundle {
1861e49aeedSchengguanghui      when(unprivCountUpdate) {
1871e49aeedSchengguanghui        reg := mHPM.hpmcounters(num - 3)
1881e49aeedSchengguanghui      }.otherwise{
1891e49aeedSchengguanghui        reg := reg
1901e49aeedSchengguanghui      }
1911e49aeedSchengguanghui      regOut := Mux(debugModeStopCount, reg.asUInt, mHPM.hpmcounters(num - 3))
192b51a1abdSchengguanghui    }).setAddr(CSRs.cycle + num)
193b51a1abdSchengguanghui  )
194b51a1abdSchengguanghui
19594895e77SXuan Hu  val unprivilegedCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap(
19694895e77SXuan Hu    CSRs.fflags -> (fcsr.wAliasFflags -> fcsr.fflagsRdata),
19794895e77SXuan Hu    CSRs.frm    -> (fcsr.wAliasFfm    -> fcsr.frmRdata),
1982c054816SsinceforYy    CSRs.fcsr   -> (fcsr.w            -> fcsr.rdata),
1992c054816SsinceforYy    CSRs.vstart -> (vstart.w          -> vstart.rdata),
2002c054816SsinceforYy    CSRs.vxsat  -> (vcsr.wAliasVxsat  -> vcsr.vxsat),
201*ceaa4109Sjunxiong-ji    CSRs.vxrm   -> (vcsr.wAliasVxrm   -> vcsr.vxrm),
2022c054816SsinceforYy    CSRs.vcsr   -> (vcsr.w            -> vcsr.rdata),
2032c054816SsinceforYy    CSRs.vl     -> (vl.w              -> vl.rdata),
2042c054816SsinceforYy    CSRs.vtype  -> (vtype.w           -> vtype.rdata),
2052c054816SsinceforYy    CSRs.vlenb  -> (vlenb.w           -> vlenb.rdata),
20665ddf865SXuan Hu    CSRs.cycle  -> (cycle.w           -> cycle.rdata),
207e628dd84SXuan Hu    CSRs.time   -> (time.w            -> time.rdata),
20865ddf865SXuan Hu    CSRs.instret -> (instret.w        -> instret.rdata),
209b51a1abdSchengguanghui  ) ++ hpmcounters.map(counter => (counter.addr -> (counter.w -> counter.rdata)))
210039cdc35SXuan Hu
211039cdc35SXuan Hu  val unprivilegedCSRMods: Seq[CSRModule[_]] = Seq(
212039cdc35SXuan Hu    fcsr,
213007f6122SXuan Hu    vcsr,
214007f6122SXuan Hu    vstart,
215007f6122SXuan Hu    vl,
216007f6122SXuan Hu    vtype,
217007f6122SXuan Hu    vlenb,
21865ddf865SXuan Hu    cycle,
219e628dd84SXuan Hu    time,
22065ddf865SXuan Hu    instret,
221b51a1abdSchengguanghui  ) ++ hpmcounters
222e877d8bfSXuan Hu
223e877d8bfSXuan Hu  val unprivilegedCSROutMap: SeqMap[Int, UInt] = SeqMap(
22479aaf6c2SsinceforYy    CSRs.fflags  -> fcsr.fflags.asUInt,
22579aaf6c2SsinceforYy    CSRs.frm     -> fcsr.frm.asUInt,
22679aaf6c2SsinceforYy    CSRs.fcsr    -> fcsr.rdata.asUInt,
22779aaf6c2SsinceforYy    CSRs.vstart  -> vstart.rdata.asUInt,
22879aaf6c2SsinceforYy    CSRs.vxsat   -> vcsr.vxsat.asUInt,
22979aaf6c2SsinceforYy    CSRs.vxrm    -> vcsr.vxrm.asUInt,
23079aaf6c2SsinceforYy    CSRs.vcsr    -> vcsr.rdata.asUInt,
23179aaf6c2SsinceforYy    CSRs.vl      -> vl.rdata.asUInt,
23279aaf6c2SsinceforYy    CSRs.vtype   -> vtype.rdata.asUInt,
23379aaf6c2SsinceforYy    CSRs.vlenb   -> vlenb.rdata.asUInt,
23465ddf865SXuan Hu    CSRs.cycle   -> cycle.rdata,
235e628dd84SXuan Hu    CSRs.time    -> time.rdata,
23665ddf865SXuan Hu    CSRs.instret -> instret.rdata,
237b51a1abdSchengguanghui  ) ++ hpmcounters.map(counter => (counter.addr -> counter.rdata))
238039cdc35SXuan Hu}
239007f6122SXuan Hu
24001cdded8SXuan Huclass CSRVTypeBundle extends CSRBundle {
2415ae0e5deSZiyue Zhang  // vtype's vill is initialized to 1, when executing vector instructions
2425ae0e5deSZiyue Zhang  // which depend on vtype, will raise illegal instruction exception
2435ae0e5deSZiyue Zhang  val VILL  = RO(  63).withReset(1.U)
2445ae0e5deSZiyue Zhang  val VMA   = RO(   7).withReset(0.U)
2455ae0e5deSZiyue Zhang  val VTA   = RO(   6).withReset(0.U)
2465ae0e5deSZiyue Zhang  val VSEW  = RO(5, 3).withReset(0.U)
2475ae0e5deSZiyue Zhang  val VLMUL = RO(2, 0).withReset(0.U)
248007f6122SXuan Hu}
24901cdded8SXuan Hu
25001cdded8SXuan Huclass CSRFrmBundle extends CSRBundle {
25101cdded8SXuan Hu  val FRM = WARL(2, 0, wNoFilter)
25201cdded8SXuan Hu}
25301cdded8SXuan Hu
25401cdded8SXuan Huclass CSRFFlagsBundle extends CSRBundle {
25501cdded8SXuan Hu  val NX = WARL(0, wNoFilter)
25601cdded8SXuan Hu  val UF = WARL(1, wNoFilter)
25701cdded8SXuan Hu  val OF = WARL(2, wNoFilter)
25801cdded8SXuan Hu  val DZ = WARL(3, wNoFilter)
25901cdded8SXuan Hu  val NV = WARL(4, wNoFilter)
26001cdded8SXuan Hu}
26101cdded8SXuan Hu
26201cdded8SXuan Huobject VlenbField extends CSREnum with ROApply {
26301cdded8SXuan Hu  val init = Value((VLEN / 8).U)
26401cdded8SXuan Hu}
265e628dd84SXuan Hu
26665ddf865SXuan Hutrait HasMHPMSink { self: CSRModule[_] =>
26765ddf865SXuan Hu  val mHPM = IO(Input(new Bundle {
26865ddf865SXuan Hu    val cycle   = UInt(64.W)
26965ddf865SXuan Hu    // ValidIO is used to update time reg
270e628dd84SXuan Hu    val time    = ValidIO(UInt(64.W))
27165ddf865SXuan Hu    val instret = UInt(64.W)
272b51a1abdSchengguanghui    val hpmcounters = Vec(perfCntNum, UInt(XLEN.W))
273e628dd84SXuan Hu  }))
274244b1012SsinceforYy  val v = IO(Input(Bool()))
2752e25304fSXu, Zefan  val nextV = IO(Input(Bool()))
276244b1012SsinceforYy  val htimedelta = IO(Input(UInt(64.W)))
277e628dd84SXuan Hu}
2781e49aeedSchengguanghui
2791e49aeedSchengguanghuitrait HasDebugStopBundle { self: CSRModule[_] =>
2801e49aeedSchengguanghui  val debugModeStopCount = IO(Input(Bool()))
2811e49aeedSchengguanghui  val debugModeStopTime  = IO(Input(Bool()))
2821e49aeedSchengguanghui  val unprivCountUpdate  = IO(Input(Bool()))
2831e49aeedSchengguanghui}