xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRModule.scala (revision b03c55a5df5dc8793cb44b42dd60141566e57e78)
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  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  protected val rdataFields = Wire(bundle)
48  rdataFields :|= regOut
49
50  rdata := rdataFields.asUInt
51  regOut := reg
52
53  def wfnField(field: CSREnumType, str: String)(wAliasSeq: Seq[CSRAddrWriteBundle[_]]) = {
54    val wfield: CSREnumType = wdata.elements(str).asInstanceOf[CSREnumType]
55
56    when(wen && wfield.isLegal | wAliasSeq.map(x => x.wen && x.wdataFields.asInstanceOf[CSRBundle].elements(str).asInstanceOf[CSREnumType].isLegal).fold(false.B)(_ | _)) {
57      field := Mux1H(
58        wAliasSeq.map(wAlias => wAlias.wen -> wAlias.wdataFields.asInstanceOf[CSRBundle].elements(str)) :+
59        wen -> wdata.elements(str)
60      )
61    }
62  }
63
64  def wfn(reg: T)(wAliasSeq: Seq[CSRAddrWriteBundle[_]]) = {
65    reg.elements.foreach { case (str, field: CSREnumType) =>
66      if (!field.isRef) {
67        val fieldWAliasSeq = wAliasSeq.filter(_.wdataFields.asInstanceOf[CSRBundle].elements.contains(str))
68        wfnField(field, str)(fieldWAliasSeq)
69      }
70    }
71  }
72
73  def dumpFields: String = {
74    this.reg.getFields.map(_.dumpName).mkString("\n")
75  }
76
77  var addr = 0
78
79  def setAddr(addr_ : Int): this.type = {
80    this.addr = addr_
81    this
82  }
83}
84
85class CSRAddrWriteBundle[T <: CSRBundle](bundle: T) extends Bundle {
86  val wen = Bool()
87  val wdata = UInt(64.W)
88
89  def wdataFields: T = {
90    val wdataField = (Wire(bundle))
91    wdataField := wdata
92    wdataField
93  }
94}
95
96// Interrupt Controller
97class CSRIRCBundle extends Bundle {
98  val sip = Input(Bool())
99  val tip = Input(Bool())
100  val eip = Input(Bool())
101}
102