xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRModule.scala (revision 039cdc35f5f3b68b6295ec5ace90f22a77322e02)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util.Mux1H
5import xiangshan.backend.fu.NewCSR.CSRDefines._
6import xiangshan.backend.fu.NewCSR.CSRBundles._
7import chisel3.experimental.BundleLiterals.AddBundleLiteralConstructor
8
9class CSRModule[T <: CSRBundle](
10  val modName: String,
11  val bundle: T = new OneFieldBundle,
12) extends Module {
13
14  override def desiredName: String = modName + "Module"
15
16  val commonIn = IO(Input(new CSRCommonIn))
17  val w = IO(Input(new CSRAddrWriteBundle(bundle)))
18
19  // read data with mask
20  val rdata = IO(Output(bundle))
21  // read data without mask
22  val regOut = IO(Output(bundle))
23
24  val reg = (if (bundle.needReset) RegInit(bundle, bundle.init) else Reg(bundle))
25
26  protected val wen = w.wen
27  protected val wdata = w.wdataFields
28
29  protected val status = commonIn.status
30  protected val v = commonIn.v
31  protected val prvm = commonIn.prvm
32
33  reg.elements.foreach { case (str, field: CSREnumType) =>
34    val wfield = wdata.elements(str).asInstanceOf[CSREnumType]
35    field.rwType match {
36      case WARLType(wfn, _) =>
37        when(wen && wfield.isLegal)(field := wdata.elements(str))
38      case WLRLType(wfn, _) =>
39        when(wen && wfield.isLegal)(field := wdata.elements(str))
40      case RWType() =>
41        when(wen)(field := wdata.elements(str))
42      case ROType(_) =>
43      case RefROType(ref, rfn) =>
44      case RefRWType(ref) =>
45      case RefWARLType(ref, wfn, rfn) =>
46      case RefWLRLType(ref, wfn, rfn) =>
47      case _ =>
48    }
49  }
50
51  rdata :|= reg
52  regOut := reg
53
54  def wfnField(field: CSREnumType, str: String)(wAliasSeq: Seq[CSRAddrWriteBundle[_]]) = {
55    val wfield: CSREnumType = wdata.elements(str).asInstanceOf[CSREnumType]
56
57    when(wen && wfield.isLegal | wAliasSeq.map(x => x.wen && x.wdataFields.asInstanceOf[CSRBundle].elements(str).asInstanceOf[CSREnumType].isLegal).fold(false.B)(_ | _)) {
58      field := Mux1H(
59        wAliasSeq.map(wAlias => wAlias.wen -> wAlias.wdataFields.asInstanceOf[CSRBundle].elements(str)) :+
60        wen -> wdata.elements(str)
61      )
62    }
63  }
64
65  def wfn(reg: T)(wAliasSeq: Seq[CSRAddrWriteBundle[_]]) = {
66    reg.elements.foreach { case (str, field: CSREnumType) =>
67      if (!field.isRef) {
68        val fieldWAliasSeq = wAliasSeq.filter(_.wdataFields.asInstanceOf[CSRBundle].elements.contains(str))
69        wfnField(field, str)(fieldWAliasSeq)
70      }
71    }
72  }
73
74  def dumpFields: String = {
75    this.reg.getFields.map(_.dumpName).mkString("\n")
76  }
77
78  var addr = 0
79
80  def setAddr(addr_ : Int): this.type = {
81    this.addr = addr_
82    this
83  }
84}
85
86class CSRAddrWriteBundle[T <: CSRBundle](bundle: T) extends Bundle {
87  val wen = Bool()
88  val wdata = UInt(64.W)
89
90  def wdataFields: T = {
91    val wdataField = (Wire(bundle))
92    wdataField := wdata
93    wdataField
94  }
95}
96
97class CSRCommonIn extends Bundle {
98  val status = new MstatusBundle
99  val prvm = PrivMode()
100  val v = VirtMode()
101  val hstatus = new HstatusBundle
102}
103
104// Interrupt Controller
105class CSRIRCBundle extends Bundle {
106  val sip = Input(Bool())
107  val tip = Input(Bool())
108  val eip = Input(Bool())
109}
110