xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRModule.scala (revision 523f2fa2aaf74fc75721a4481c008da507a5cb75)
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 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  reg.elements.foreach { case (str, field: CSREnumType) =>
30    val wfield = wdata.elements(str).asInstanceOf[CSREnumType]
31    field.rwType match {
32      case WARLType(wfn, _) =>
33        when(wen && wfield.isLegal)(field := wdata.elements(str))
34      case WLRLType(wfn, _) =>
35        when(wen && wfield.isLegal)(field := wdata.elements(str))
36      case RWType() =>
37        when(wen)(field := wdata.elements(str))
38      case ROType(_) =>
39      case RefROType(ref, rfn) =>
40      case RefRWType(ref) =>
41      case RefWARLType(ref, wfn, rfn) =>
42      case RefWLRLType(ref, wfn, rfn) =>
43      case _ =>
44    }
45  }
46
47  rdata :|= reg
48  regOut := reg
49
50  def wfnField(field: CSREnumType, str: String)(wAliasSeq: Seq[CSRAddrWriteBundle[_]]) = {
51    val wfield: CSREnumType = wdata.elements(str).asInstanceOf[CSREnumType]
52
53    when(wen && wfield.isLegal | wAliasSeq.map(x => x.wen && x.wdataFields.asInstanceOf[CSRBundle].elements(str).asInstanceOf[CSREnumType].isLegal).fold(false.B)(_ | _)) {
54      field := Mux1H(
55        wAliasSeq.map(wAlias => wAlias.wen -> wAlias.wdataFields.asInstanceOf[CSRBundle].elements(str)) :+
56        wen -> wdata.elements(str)
57      )
58    }
59  }
60
61  def wfn(reg: T)(wAliasSeq: Seq[CSRAddrWriteBundle[_]]) = {
62    reg.elements.foreach { case (str, field: CSREnumType) =>
63      if (!field.isRef) {
64        val fieldWAliasSeq = wAliasSeq.filter(_.wdataFields.asInstanceOf[CSRBundle].elements.contains(str))
65        wfnField(field, str)(fieldWAliasSeq)
66      }
67    }
68  }
69
70  def dumpFields: String = {
71    this.reg.getFields.map(_.dumpName).mkString("\n")
72  }
73
74  var addr = 0
75
76  def setAddr(addr_ : Int): this.type = {
77    this.addr = addr_
78    this
79  }
80}
81
82class CSRAddrWriteBundle[T <: CSRBundle](bundle: T) extends Bundle {
83  val wen = Bool()
84  val wdata = UInt(64.W)
85
86  def wdataFields: T = {
87    val wdataField = (Wire(bundle))
88    wdataField := wdata
89    wdataField
90  }
91}
92
93// Interrupt Controller
94class CSRIRCBundle extends Bundle {
95  val sip = Input(Bool())
96  val tip = Input(Bool())
97  val eip = Input(Bool())
98}
99