xref: /XiangShan/src/main/scala/device/AXI4SlaveModule.scala (revision efc6a777574eec1b301402a95a0cfe7aee94b526)
11db30e61Slinjiaweipackage device
21db30e61Slinjiawei
31db30e61Slinjiaweiimport chisel3._
41db30e61Slinjiaweiimport chisel3.util._
51db30e61Slinjiaweiimport utils._
61db30e61Slinjiaweiimport freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp, RegionType, TransferSizes}
71db30e61Slinjiaweiimport chipsalliance.rocketchip.config.Parameters
81db30e61Slinjiaweiimport freechips.rocketchip.amba.axi4.{AXI4Parameters, AXI4SlaveNode, AXI4SlaveParameters, AXI4SlavePortParameters}
9e2801f97Slinjiaweiimport xiangshan.HasXSLog
101db30e61Slinjiawei
111db30e61Slinjiaweiabstract class AXI4SlaveModule[T <: Data]
121db30e61Slinjiawei(
131db30e61Slinjiawei  address: AddressSet,
141db30e61Slinjiawei  executable: Boolean = true,
151db30e61Slinjiawei  beatBytes: Int = 8,
161db30e61Slinjiawei  burstLen: Int = 1,
171db30e61Slinjiawei  val _extra: T = null
181db30e61Slinjiawei)(implicit p: Parameters) extends LazyModule {
191db30e61Slinjiawei
201db30e61Slinjiawei  val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
211db30e61Slinjiawei    Seq(AXI4SlaveParameters(
221db30e61Slinjiawei      Seq(address),
231db30e61Slinjiawei      regionType = RegionType.UNCACHED,
241db30e61Slinjiawei      executable = executable,
251db30e61Slinjiawei      supportsWrite = TransferSizes(1, beatBytes * burstLen),
261db30e61Slinjiawei      supportsRead = TransferSizes(1, beatBytes * burstLen),
271db30e61Slinjiawei      interleavedId = Some(0)
281db30e61Slinjiawei    )),
291db30e61Slinjiawei    beatBytes = beatBytes
301db30e61Slinjiawei  )))
311db30e61Slinjiawei
321db30e61Slinjiawei  lazy val module = new AXI4SlaveModuleImp[T](this)
331db30e61Slinjiawei
341db30e61Slinjiawei}
351db30e61Slinjiawei
361db30e61Slinjiaweiclass AXI4SlaveModuleImp[T<:Data](outer: AXI4SlaveModule[T])
37e2801f97Slinjiawei  extends LazyModuleImp(outer) with HasXSLog
381db30e61Slinjiawei{
391db30e61Slinjiawei  val io = IO(new Bundle {
40956d83c0Slinjiawei    val extra = if(outer._extra == null) None else Some(outer._extra.cloneType)
411db30e61Slinjiawei  })
421db30e61Slinjiawei
431db30e61Slinjiawei  val (in, edge) = outer.node.in.head
441db30e61Slinjiawei
45e2801f97Slinjiawei//  val timer = GTimer()
461db30e61Slinjiawei  when(in.ar.fire()){
47e2801f97Slinjiawei    XSDebug(p"[ar] addr: ${Hexadecimal(in.ar.bits.addr)} " +
481db30e61Slinjiawei      p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " +
491db30e61Slinjiawei      p"id: ${in.ar.bits.id}\n"
501db30e61Slinjiawei    )
511db30e61Slinjiawei  }
521db30e61Slinjiawei  when(in.aw.fire()){
53e2801f97Slinjiawei    XSDebug(p"[aw] addr: ${Hexadecimal(in.aw.bits.addr)} " +
541db30e61Slinjiawei      p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " +
551db30e61Slinjiawei      p"id: ${in.aw.bits.id}\n"
561db30e61Slinjiawei    )
571db30e61Slinjiawei  }
581db30e61Slinjiawei  when(in.w.fire()){
5924b11ca3Slinjiawei    XSDebug(p"[w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last} data:${Hexadecimal(in.w.bits.data)}\n")
601db30e61Slinjiawei  }
611db30e61Slinjiawei  when(in.b.fire()){
62e2801f97Slinjiawei    XSDebug(p"[b] id: ${in.b.bits.id}\n")
631db30e61Slinjiawei  }
641db30e61Slinjiawei  when(in.r.fire()){
6524b11ca3Slinjiawei    XSDebug(p"[r] id: ${in.r.bits.id} data: ${Hexadecimal(in.r.bits.data)}\n")
661db30e61Slinjiawei  }
671db30e61Slinjiawei
68*efc6a777Slinjiawei  when(in.aw.fire()){
69*efc6a777Slinjiawei    assert(in.aw.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!")
70*efc6a777Slinjiawei  }
71*efc6a777Slinjiawei  when(in.ar.fire()){
72*efc6a777Slinjiawei    assert(in.ar.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!")
73*efc6a777Slinjiawei  }
74075891a7Slinjiawei
7524b11ca3Slinjiawei  private val s_idle :: s_rdata :: s_wdata :: s_wresp :: Nil = Enum(4)
76075891a7Slinjiawei
7724b11ca3Slinjiawei  private val state = RegInit(s_idle)
78075891a7Slinjiawei
79075891a7Slinjiawei  switch(state){
80075891a7Slinjiawei    is(s_idle){
81075891a7Slinjiawei      when(in.ar.fire()){
82075891a7Slinjiawei        state := s_rdata
83075891a7Slinjiawei      }
84075891a7Slinjiawei      when(in.aw.fire()){
85075891a7Slinjiawei        state := s_wdata
86075891a7Slinjiawei      }
87075891a7Slinjiawei    }
88075891a7Slinjiawei    is(s_rdata){
89075891a7Slinjiawei      when(in.r.fire() && in.r.bits.last){
90075891a7Slinjiawei        state := s_idle
91075891a7Slinjiawei      }
92075891a7Slinjiawei    }
93075891a7Slinjiawei    is(s_wdata){
94075891a7Slinjiawei      when(in.w.fire() && in.w.bits.last){
95075891a7Slinjiawei        state := s_wresp
96075891a7Slinjiawei      }
97075891a7Slinjiawei    }
98075891a7Slinjiawei    is(s_wresp){
99075891a7Slinjiawei      when(in.b.fire()){
100075891a7Slinjiawei        state := s_idle
101075891a7Slinjiawei      }
102075891a7Slinjiawei    }
103075891a7Slinjiawei  }
104075891a7Slinjiawei
105075891a7Slinjiawei
1061db30e61Slinjiawei  val fullMask = MaskExpand(in.w.bits.strb)
1071db30e61Slinjiawei
1081db30e61Slinjiawei  def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask)
1091db30e61Slinjiawei
1101db30e61Slinjiawei  val raddr = Wire(UInt())
1111db30e61Slinjiawei  val (readBeatCnt, rLast) = {
1121db30e61Slinjiawei    val c = Counter(256)
1131db30e61Slinjiawei    val len = HoldUnless(in.ar.bits.len, in.ar.fire())
114*efc6a777Slinjiawei    raddr := HoldUnless(in.ar.bits.addr, in.ar.fire())
1151db30e61Slinjiawei    in.r.bits.last := (c.value === len)
116*efc6a777Slinjiawei
1171db30e61Slinjiawei    when(in.r.fire()) {
1181db30e61Slinjiawei      c.inc()
1191db30e61Slinjiawei      when(in.r.bits.last) {
1201db30e61Slinjiawei        c.value := 0.U
1211db30e61Slinjiawei      }
1221db30e61Slinjiawei    }
1231db30e61Slinjiawei    when(in.ar.fire()) {
124*efc6a777Slinjiawei      assert(
125*efc6a777Slinjiawei        in.ar.bits.len === 0.U ||
126*efc6a777Slinjiawei          in.ar.bits.len === 1.U ||
127*efc6a777Slinjiawei          in.ar.bits.len === 3.U ||
128*efc6a777Slinjiawei          in.ar.bits.len === 7.U ||
129*efc6a777Slinjiawei          in.ar.bits.len === 15.U
130*efc6a777Slinjiawei      )
1311db30e61Slinjiawei    }
132*efc6a777Slinjiawei    (c.value, in.r.bits.last)
1331db30e61Slinjiawei  }
1341db30e61Slinjiawei
135075891a7Slinjiawei  in.ar.ready := state === s_idle
1361db30e61Slinjiawei  in.r.bits.resp := AXI4Parameters.RESP_OKAY
137075891a7Slinjiawei  in.r.valid := state === s_rdata
1381db30e61Slinjiawei
1391db30e61Slinjiawei
1401db30e61Slinjiawei  val waddr = Wire(UInt())
1411db30e61Slinjiawei  val (writeBeatCnt, wLast) = {
1421db30e61Slinjiawei    val c = Counter(256)
1431db30e61Slinjiawei    waddr := HoldUnless(in.aw.bits.addr, in.aw.fire())
1441db30e61Slinjiawei    when(in.w.fire()) {
1451db30e61Slinjiawei      c.inc()
1461db30e61Slinjiawei      when(in.w.bits.last) {
1471db30e61Slinjiawei        c.value := 0.U
1481db30e61Slinjiawei      }
1491db30e61Slinjiawei    }
1501db30e61Slinjiawei    (c.value, in.w.bits.last)
1511db30e61Slinjiawei  }
1521db30e61Slinjiawei
153075891a7Slinjiawei  in.aw.ready := state === s_idle
154075891a7Slinjiawei  in.w.ready := state === s_wdata
155075891a7Slinjiawei
1561db30e61Slinjiawei  in.b.bits.resp := AXI4Parameters.RESP_OKAY
157075891a7Slinjiawei  in.b.valid := state===s_wresp
1581db30e61Slinjiawei
1591db30e61Slinjiawei  in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire())
1601db30e61Slinjiawei  in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire())
1611db30e61Slinjiawei  in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire())
1621db30e61Slinjiawei  in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire())
1631db30e61Slinjiawei}
164