xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRModule.scala (revision e2216eca0e0ca4615994eafcd15445083e968a7f)
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, the same as the value of CSRR
20  val rdata = IO(Output(UInt(bundle.len.W)))
21  // read data without mask
22  val regOut = IO(Output(bundle))
23
24  protected 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  bundle.elements.foreach { case (str, field: CSREnumType) =>
30    val wfield = wdata.elements(str).asInstanceOf[CSREnumType]
31    field.rwType match {
32      case WARLType(wfn, _) =>
33        field.addOtherUpdate(wen && wfield.isLegal, wdata.elements(str).asInstanceOf[CSREnumType])
34      case WLRLType(wfn, _) =>
35        field.addOtherUpdate(wen && wfield.isLegal, wdata.elements(str).asInstanceOf[CSREnumType])
36      case RWType() =>
37        field.addOtherUpdate(wen, wdata.elements(str).asInstanceOf[CSREnumType])
38      case ROType(_) =>
39      case _ =>
40    }
41  }
42
43  reconnectReg()
44
45  val rdataFields = IO(Output(bundle))
46  rdataFields :|= regOut
47
48  rdata := rdataFields.asUInt
49  regOut := reg
50
51  private def wfnField(field: CSREnumType, str: String): Unit = {
52    val wfield: CSREnumType = wdata.elements(str).asInstanceOf[CSREnumType]
53
54    when (wen && wfield.isLegal || field.otherUpdateSeq.map(_._1).fold(false.B)(_ || _)) {
55      field := Mux1H(
56        field.otherUpdateSeq.map { case (valid, data) =>
57          valid -> data
58        } :+ (wen -> wdata.elements(str)),
59      )
60    }.otherwise {
61      field := field
62    }
63  }
64
65  private def wfn(reg: CSRBundle): Unit = {
66    reg.elements.foreach { case (str, field: CSREnumType) =>
67      if (!field.isRef) {
68        wfnField(field, str)
69      }
70    }
71  }
72
73  protected def reconnectReg(): Unit = {
74    this.wfn(this.reg)
75  }
76
77  def dumpFields: String = {
78    this.reg.getFields.map(_.dumpName).mkString("\n")
79  }
80
81  var addr = 0
82
83  def setAddr(addr_ : Int): this.type = {
84    this.addr = addr_
85    this
86  }
87}
88
89class CSRAddrWriteBundle[T <: CSRBundle](bundle: T) extends Bundle {
90  val wen = Bool()
91  val wdata = UInt(64.W)
92
93  def wdataFields: T = {
94    val wdataField = (Wire(bundle))
95    wdataField := wdata
96    wdataField
97  }
98}
99
100// Interrupt Controller
101class CSRIRCBundle extends Bundle {
102  val sip = Input(Bool())
103  val tip = Input(Bool())
104  val eip = Input(Bool())
105}
106