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