xref: /XiangShan/src/main/scala/device/AXI4SlaveModule.scala (revision 956d83c0f98bae64d3d4939708d2b7809038e7f4)
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}
91db30e61Slinjiawei
101db30e61Slinjiaweiabstract class AXI4SlaveModule[T <: Data]
111db30e61Slinjiawei(
121db30e61Slinjiawei  address: AddressSet,
131db30e61Slinjiawei  executable: Boolean = true,
141db30e61Slinjiawei  beatBytes: Int = 8,
151db30e61Slinjiawei  burstLen: Int = 1,
161db30e61Slinjiawei  val _extra: T = null
171db30e61Slinjiawei)(implicit p: Parameters) extends LazyModule {
181db30e61Slinjiawei
191db30e61Slinjiawei  val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
201db30e61Slinjiawei    Seq(AXI4SlaveParameters(
211db30e61Slinjiawei      Seq(address),
221db30e61Slinjiawei      regionType = RegionType.UNCACHED,
231db30e61Slinjiawei      executable = executable,
241db30e61Slinjiawei      supportsWrite = TransferSizes(1, beatBytes * burstLen),
251db30e61Slinjiawei      supportsRead = TransferSizes(1, beatBytes * burstLen),
261db30e61Slinjiawei      interleavedId = Some(0)
271db30e61Slinjiawei    )),
281db30e61Slinjiawei    beatBytes = beatBytes
291db30e61Slinjiawei  )))
301db30e61Slinjiawei
311db30e61Slinjiawei  lazy val module = new AXI4SlaveModuleImp[T](this)
321db30e61Slinjiawei
331db30e61Slinjiawei}
341db30e61Slinjiawei
351db30e61Slinjiaweiclass AXI4SlaveModuleImp[T<:Data](outer: AXI4SlaveModule[T])
361db30e61Slinjiawei  extends LazyModuleImp(outer)
371db30e61Slinjiawei{
381db30e61Slinjiawei  val io = IO(new Bundle {
39*956d83c0Slinjiawei    val extra = if(outer._extra == null) None else Some(outer._extra.cloneType)
401db30e61Slinjiawei  })
411db30e61Slinjiawei
421db30e61Slinjiawei  val (in, edge) = outer.node.in.head
431db30e61Slinjiawei
441db30e61Slinjiawei  val timer = GTimer()
451db30e61Slinjiawei  when(in.ar.fire()){
461db30e61Slinjiawei    printf(p"[$timer][ar] addr: ${Hexadecimal(in.ar.bits.addr)} " +
471db30e61Slinjiawei      p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " +
481db30e61Slinjiawei      p"id: ${in.ar.bits.id}\n"
491db30e61Slinjiawei    )
501db30e61Slinjiawei  }
511db30e61Slinjiawei  when(in.aw.fire()){
521db30e61Slinjiawei    printf(p"[$timer][aw] addr: ${Hexadecimal(in.aw.bits.addr)} " +
531db30e61Slinjiawei      p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " +
541db30e61Slinjiawei      p"id: ${in.aw.bits.id}\n"
551db30e61Slinjiawei    )
561db30e61Slinjiawei  }
571db30e61Slinjiawei  when(in.w.fire()){
581db30e61Slinjiawei    printf(p"[$timer][w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last}\n")
591db30e61Slinjiawei  }
601db30e61Slinjiawei  when(in.b.fire()){
611db30e61Slinjiawei    printf(p"[$timer][b] id: ${in.b.bits.id}\n")
621db30e61Slinjiawei  }
631db30e61Slinjiawei  when(in.r.fire()){
641db30e61Slinjiawei    printf(p"[$timer][r] id: ${in.r.bits.id}\n")
651db30e61Slinjiawei  }
661db30e61Slinjiawei
671db30e61Slinjiawei  val fullMask = MaskExpand(in.w.bits.strb)
681db30e61Slinjiawei
691db30e61Slinjiawei  def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask)
701db30e61Slinjiawei
711db30e61Slinjiawei  val raddr = Wire(UInt())
721db30e61Slinjiawei  val ren = Wire(Bool())
731db30e61Slinjiawei  val (readBeatCnt, rLast) = {
741db30e61Slinjiawei    val c = Counter(256)
751db30e61Slinjiawei    val beatCnt = Counter(256)
761db30e61Slinjiawei    val len = HoldUnless(in.ar.bits.len, in.ar.fire())
771db30e61Slinjiawei    val burst = HoldUnless(in.ar.bits.burst, in.ar.fire())
781db30e61Slinjiawei    val wrapAddr = in.ar.bits.addr & (~(in.ar.bits.len << in.ar.bits.size)).asUInt()
791db30e61Slinjiawei    raddr := HoldUnless(wrapAddr, in.ar.fire())
801db30e61Slinjiawei    in.r.bits.last := (c.value === len)
811db30e61Slinjiawei    when(ren) {
821db30e61Slinjiawei      beatCnt.inc()
831db30e61Slinjiawei      when(burst === AXI4Parameters.BURST_WRAP && beatCnt.value === len) {
841db30e61Slinjiawei        beatCnt.value := 0.U
851db30e61Slinjiawei      }
861db30e61Slinjiawei    }
871db30e61Slinjiawei    when(in.r.fire()) {
881db30e61Slinjiawei      c.inc()
891db30e61Slinjiawei      when(in.r.bits.last) {
901db30e61Slinjiawei        c.value := 0.U
911db30e61Slinjiawei      }
921db30e61Slinjiawei    }
931db30e61Slinjiawei    when(in.ar.fire()) {
941db30e61Slinjiawei      beatCnt.value := (in.ar.bits.addr >> in.ar.bits.size).asUInt() & in.ar.bits.len
951db30e61Slinjiawei      when(in.ar.bits.len =/= 0.U && in.ar.bits.burst === AXI4Parameters.BURST_WRAP) {
961db30e61Slinjiawei        assert(in.ar.bits.len === 1.U || in.ar.bits.len === 3.U ||
971db30e61Slinjiawei          in.ar.bits.len === 7.U || in.ar.bits.len === 15.U)
981db30e61Slinjiawei      }
991db30e61Slinjiawei    }
1001db30e61Slinjiawei    (beatCnt.value, in.r.bits.last)
1011db30e61Slinjiawei  }
1021db30e61Slinjiawei
1031db30e61Slinjiawei  val r_busy = BoolStopWatch(in.ar.fire(), in.r.fire() && rLast, startHighPriority = true)
1041db30e61Slinjiawei  in.ar.ready := in.r.ready || !r_busy
1051db30e61Slinjiawei  in.r.bits.resp := AXI4Parameters.RESP_OKAY
1061db30e61Slinjiawei  ren := RegNext(in.ar.fire()) || (in.r.fire() && !rLast)
1071db30e61Slinjiawei  in.r.valid := BoolStopWatch(ren && (in.ar.fire() || r_busy), in.r.fire(), startHighPriority = true)
1081db30e61Slinjiawei
1091db30e61Slinjiawei
1101db30e61Slinjiawei  val waddr = Wire(UInt())
1111db30e61Slinjiawei  val (writeBeatCnt, wLast) = {
1121db30e61Slinjiawei    val c = Counter(256)
1131db30e61Slinjiawei    waddr := HoldUnless(in.aw.bits.addr, in.aw.fire())
1141db30e61Slinjiawei    when(in.w.fire()) {
1151db30e61Slinjiawei      c.inc()
1161db30e61Slinjiawei      when(in.w.bits.last) {
1171db30e61Slinjiawei        c.value := 0.U
1181db30e61Slinjiawei      }
1191db30e61Slinjiawei    }
1201db30e61Slinjiawei    (c.value, in.w.bits.last)
1211db30e61Slinjiawei  }
1221db30e61Slinjiawei
1231db30e61Slinjiawei  val w_busy = BoolStopWatch(in.aw.fire(), in.b.fire(), startHighPriority = true)
1241db30e61Slinjiawei  in.aw.ready := !w_busy
1251db30e61Slinjiawei  in.w.ready := in.aw.valid || (w_busy)
1261db30e61Slinjiawei  in.b.bits.resp := AXI4Parameters.RESP_OKAY
1271db30e61Slinjiawei  in.b.valid := BoolStopWatch(in.w.fire() && wLast, in.b.fire(), startHighPriority = true)
1281db30e61Slinjiawei
1291db30e61Slinjiawei  in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire())
1301db30e61Slinjiawei  in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire())
1311db30e61Slinjiawei  in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire())
1321db30e61Slinjiawei  in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire())
1331db30e61Slinjiawei}
134