xref: /XiangShan/src/main/scala/device/AXI4SlaveModule.scala (revision 8b33cd30e0034914b58520e0dc3c0c4b1aad6a03)
1c6d43980SLemover/***************************************************************************************
2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory
4c6d43980SLemover*
5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2.
6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2.
7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at:
8c6d43980SLemover*          http://license.coscl.org.cn/MulanPSL2
9c6d43980SLemover*
10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13c6d43980SLemover*
14c6d43980SLemover* See the Mulan PSL v2 for more details.
15c6d43980SLemover***************************************************************************************/
16c6d43980SLemover
171db30e61Slinjiaweipackage device
181db30e61Slinjiawei
191db30e61Slinjiaweiimport chisel3._
201db30e61Slinjiaweiimport chisel3.util._
211db30e61Slinjiaweiimport utils._
223c02ee8fSwakafaimport utility._
231db30e61Slinjiaweiimport freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp, RegionType, TransferSizes}
248891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters
251db30e61Slinjiaweiimport freechips.rocketchip.amba.axi4.{AXI4Parameters, AXI4SlaveNode, AXI4SlaveParameters, AXI4SlavePortParameters}
261db30e61Slinjiawei
271db30e61Slinjiaweiabstract class AXI4SlaveModule[T <: Data]
281db30e61Slinjiawei(
29a2e9bde6SAllen  address: Seq[AddressSet],
301db30e61Slinjiawei  executable: Boolean = true,
311db30e61Slinjiawei  beatBytes: Int = 8,
321db30e61Slinjiawei  burstLen: Int = 1,
331db30e61Slinjiawei  val _extra: T = null
341db30e61Slinjiawei)(implicit p: Parameters) extends LazyModule {
351db30e61Slinjiawei
361db30e61Slinjiawei  val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
371db30e61Slinjiawei    Seq(AXI4SlaveParameters(
38a2e9bde6SAllen      address,
391db30e61Slinjiawei      regionType = RegionType.UNCACHED,
401db30e61Slinjiawei      executable = executable,
411db30e61Slinjiawei      supportsWrite = TransferSizes(1, beatBytes * burstLen),
421db30e61Slinjiawei      supportsRead = TransferSizes(1, beatBytes * burstLen),
431db30e61Slinjiawei      interleavedId = Some(0)
441db30e61Slinjiawei    )),
451db30e61Slinjiawei    beatBytes = beatBytes
461db30e61Slinjiawei  )))
471db30e61Slinjiawei
481db30e61Slinjiawei  lazy val module = new AXI4SlaveModuleImp[T](this)
491db30e61Slinjiawei
501db30e61Slinjiawei}
511db30e61Slinjiawei
521db30e61Slinjiaweiclass AXI4SlaveModuleImp[T<:Data](outer: AXI4SlaveModule[T])
535c5bd416Sljw  extends LazyModuleImp(outer)
541db30e61Slinjiawei{
551db30e61Slinjiawei  val io = IO(new Bundle {
56956d83c0Slinjiawei    val extra = if(outer._extra == null) None else Some(outer._extra.cloneType)
571db30e61Slinjiawei  })
581db30e61Slinjiawei
591db30e61Slinjiawei  val (in, edge) = outer.node.in.head
6055fc3133SAllen  // do not let MMIO AXI signals optimized out
6155fc3133SAllen  chisel3.dontTouch(in)
6255fc3133SAllen
631db30e61Slinjiawei
64e2801f97Slinjiawei//  val timer = GTimer()
65*8b33cd30Sklin02  XSDebug(in.ar.fire,
66*8b33cd30Sklin02    p"[ar] addr: ${Hexadecimal(in.ar.bits.addr)} " +
671db30e61Slinjiawei    p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " +
681db30e61Slinjiawei    p"id: ${in.ar.bits.id}\n"
691db30e61Slinjiawei  )
70*8b33cd30Sklin02  XSDebug(in.aw.fire,
71*8b33cd30Sklin02    p"[aw] addr: ${Hexadecimal(in.aw.bits.addr)} " +
721db30e61Slinjiawei    p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " +
731db30e61Slinjiawei    p"id: ${in.aw.bits.id}\n"
741db30e61Slinjiawei  )
75*8b33cd30Sklin02  XSDebug(in.w.fire,
76*8b33cd30Sklin02    p"[w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last} data:${Hexadecimal(in.w.bits.data)}\n"
77*8b33cd30Sklin02  )
78*8b33cd30Sklin02  XSDebug(in.b.fire,
79*8b33cd30Sklin02    p"[b] id: ${in.b.bits.id}\n"
80*8b33cd30Sklin02  )
81*8b33cd30Sklin02  XSDebug(in.r.fire,
82*8b33cd30Sklin02    p"[r] id: ${in.r.bits.id} data: ${Hexadecimal(in.r.bits.data)}\n"
83*8b33cd30Sklin02  )
841db30e61Slinjiawei
85935edac4STang Haojin  when(in.aw.fire){
86efc6a777Slinjiawei    assert(in.aw.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!")
87efc6a777Slinjiawei  }
88935edac4STang Haojin  when(in.ar.fire){
89efc6a777Slinjiawei    assert(in.ar.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!")
90efc6a777Slinjiawei  }
91075891a7Slinjiawei
922195ebbdSYinan Xu  val s_idle :: s_rdata :: s_wdata :: s_wresp :: Nil = Enum(4)
93075891a7Slinjiawei
942195ebbdSYinan Xu  val state = RegInit(s_idle)
95075891a7Slinjiawei
96075891a7Slinjiawei  switch(state){
97075891a7Slinjiawei    is(s_idle){
98935edac4STang Haojin      when(in.ar.fire){
99075891a7Slinjiawei        state := s_rdata
100075891a7Slinjiawei      }
101935edac4STang Haojin      when(in.aw.fire){
102075891a7Slinjiawei        state := s_wdata
103075891a7Slinjiawei      }
104075891a7Slinjiawei    }
105075891a7Slinjiawei    is(s_rdata){
106935edac4STang Haojin      when(in.r.fire && in.r.bits.last){
107075891a7Slinjiawei        state := s_idle
108075891a7Slinjiawei      }
109075891a7Slinjiawei    }
110075891a7Slinjiawei    is(s_wdata){
111935edac4STang Haojin      when(in.w.fire && in.w.bits.last){
112075891a7Slinjiawei        state := s_wresp
113075891a7Slinjiawei      }
114075891a7Slinjiawei    }
115075891a7Slinjiawei    is(s_wresp){
116935edac4STang Haojin      when(in.b.fire){
117075891a7Slinjiawei        state := s_idle
118075891a7Slinjiawei      }
119075891a7Slinjiawei    }
120075891a7Slinjiawei  }
121075891a7Slinjiawei
122075891a7Slinjiawei
1231db30e61Slinjiawei  val fullMask = MaskExpand(in.w.bits.strb)
1241db30e61Slinjiawei
125935edac4STang Haojin  def genWdata(originData: UInt) = (originData & (~fullMask).asUInt) | (in.w.bits.data & fullMask)
1261db30e61Slinjiawei
1271db30e61Slinjiawei  val raddr = Wire(UInt())
1281db30e61Slinjiawei  val (readBeatCnt, rLast) = {
1291db30e61Slinjiawei    val c = Counter(256)
130935edac4STang Haojin    val len = HoldUnless(in.ar.bits.len, in.ar.fire)
131935edac4STang Haojin    raddr := HoldUnless(in.ar.bits.addr, in.ar.fire)
1321db30e61Slinjiawei    in.r.bits.last := (c.value === len)
133efc6a777Slinjiawei
134935edac4STang Haojin    when(in.r.fire) {
1351db30e61Slinjiawei      c.inc()
1361db30e61Slinjiawei      when(in.r.bits.last) {
1371db30e61Slinjiawei        c.value := 0.U
1381db30e61Slinjiawei      }
1391db30e61Slinjiawei    }
140935edac4STang Haojin    when(in.ar.fire) {
141efc6a777Slinjiawei      assert(
142efc6a777Slinjiawei        in.ar.bits.len === 0.U ||
143efc6a777Slinjiawei          in.ar.bits.len === 1.U ||
144efc6a777Slinjiawei          in.ar.bits.len === 3.U ||
145efc6a777Slinjiawei          in.ar.bits.len === 7.U ||
146efc6a777Slinjiawei          in.ar.bits.len === 15.U
147efc6a777Slinjiawei      )
1481db30e61Slinjiawei    }
149efc6a777Slinjiawei    (c.value, in.r.bits.last)
1501db30e61Slinjiawei  }
1511db30e61Slinjiawei
152075891a7Slinjiawei  in.ar.ready := state === s_idle
1531db30e61Slinjiawei  in.r.bits.resp := AXI4Parameters.RESP_OKAY
154075891a7Slinjiawei  in.r.valid := state === s_rdata
1551db30e61Slinjiawei
1561db30e61Slinjiawei
1571db30e61Slinjiawei  val waddr = Wire(UInt())
1581db30e61Slinjiawei  val (writeBeatCnt, wLast) = {
1591db30e61Slinjiawei    val c = Counter(256)
160935edac4STang Haojin    waddr := HoldUnless(in.aw.bits.addr, in.aw.fire)
161935edac4STang Haojin    when(in.w.fire) {
1621db30e61Slinjiawei      c.inc()
1631db30e61Slinjiawei      when(in.w.bits.last) {
1641db30e61Slinjiawei        c.value := 0.U
1651db30e61Slinjiawei      }
1661db30e61Slinjiawei    }
1671db30e61Slinjiawei    (c.value, in.w.bits.last)
1681db30e61Slinjiawei  }
1691db30e61Slinjiawei
1706c6d537cSAllen  in.aw.ready := state === s_idle && !in.ar.valid
171075891a7Slinjiawei  in.w.ready := state === s_wdata
172075891a7Slinjiawei
1731db30e61Slinjiawei  in.b.bits.resp := AXI4Parameters.RESP_OKAY
174075891a7Slinjiawei  in.b.valid := state===s_wresp
1751db30e61Slinjiawei
176935edac4STang Haojin  in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire)
177935edac4STang Haojin  in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire)
178935edac4STang Haojin  in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire)
179935edac4STang Haojin  in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire)
1801db30e61Slinjiawei}
181