xref: /XiangShan/src/main/scala/device/AXI4SlaveModule.scala (revision 1db30e6124dd6ed0d104be42e3e29c5b4e1cf8e5)
1*1db30e61Slinjiaweipackage device
2*1db30e61Slinjiawei
3*1db30e61Slinjiaweiimport chisel3._
4*1db30e61Slinjiaweiimport chisel3.util._
5*1db30e61Slinjiaweiimport utils._
6*1db30e61Slinjiaweiimport freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp, RegionType, TransferSizes}
7*1db30e61Slinjiaweiimport chipsalliance.rocketchip.config.Parameters
8*1db30e61Slinjiaweiimport freechips.rocketchip.amba.axi4.{AXI4Parameters, AXI4SlaveNode, AXI4SlaveParameters, AXI4SlavePortParameters}
9*1db30e61Slinjiawei
10*1db30e61Slinjiaweiabstract class AXI4SlaveModule[T <: Data]
11*1db30e61Slinjiawei(
12*1db30e61Slinjiawei  address: AddressSet,
13*1db30e61Slinjiawei  executable: Boolean = true,
14*1db30e61Slinjiawei  beatBytes: Int = 8,
15*1db30e61Slinjiawei  burstLen: Int = 1,
16*1db30e61Slinjiawei  val _extra: T = null
17*1db30e61Slinjiawei)(implicit p: Parameters) extends LazyModule {
18*1db30e61Slinjiawei
19*1db30e61Slinjiawei  val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
20*1db30e61Slinjiawei    Seq(AXI4SlaveParameters(
21*1db30e61Slinjiawei      Seq(address),
22*1db30e61Slinjiawei      regionType = RegionType.UNCACHED,
23*1db30e61Slinjiawei      executable = executable,
24*1db30e61Slinjiawei      supportsWrite = TransferSizes(1, beatBytes * burstLen),
25*1db30e61Slinjiawei      supportsRead = TransferSizes(1, beatBytes * burstLen),
26*1db30e61Slinjiawei      interleavedId = Some(0)
27*1db30e61Slinjiawei    )),
28*1db30e61Slinjiawei    beatBytes = beatBytes
29*1db30e61Slinjiawei  )))
30*1db30e61Slinjiawei
31*1db30e61Slinjiawei  lazy val module = new AXI4SlaveModuleImp[T](this)
32*1db30e61Slinjiawei
33*1db30e61Slinjiawei}
34*1db30e61Slinjiawei
35*1db30e61Slinjiaweiclass AXI4SlaveModuleImp[T<:Data](outer: AXI4SlaveModule[T])
36*1db30e61Slinjiawei  extends LazyModuleImp(outer)
37*1db30e61Slinjiawei{
38*1db30e61Slinjiawei  val io = IO(new Bundle {
39*1db30e61Slinjiawei    val extra = Option(outer._extra)
40*1db30e61Slinjiawei  })
41*1db30e61Slinjiawei
42*1db30e61Slinjiawei  val (in, edge) = outer.node.in.head
43*1db30e61Slinjiawei
44*1db30e61Slinjiawei  val timer = GTimer()
45*1db30e61Slinjiawei  when(in.ar.fire()){
46*1db30e61Slinjiawei    printf(p"[$timer][ar] addr: ${Hexadecimal(in.ar.bits.addr)} " +
47*1db30e61Slinjiawei      p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " +
48*1db30e61Slinjiawei      p"id: ${in.ar.bits.id}\n"
49*1db30e61Slinjiawei    )
50*1db30e61Slinjiawei  }
51*1db30e61Slinjiawei  when(in.aw.fire()){
52*1db30e61Slinjiawei    printf(p"[$timer][aw] addr: ${Hexadecimal(in.aw.bits.addr)} " +
53*1db30e61Slinjiawei      p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " +
54*1db30e61Slinjiawei      p"id: ${in.aw.bits.id}\n"
55*1db30e61Slinjiawei    )
56*1db30e61Slinjiawei  }
57*1db30e61Slinjiawei  when(in.w.fire()){
58*1db30e61Slinjiawei    printf(p"[$timer][w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last}\n")
59*1db30e61Slinjiawei  }
60*1db30e61Slinjiawei  when(in.b.fire()){
61*1db30e61Slinjiawei    printf(p"[$timer][b] id: ${in.b.bits.id}\n")
62*1db30e61Slinjiawei  }
63*1db30e61Slinjiawei  when(in.r.fire()){
64*1db30e61Slinjiawei    printf(p"[$timer][r] id: ${in.r.bits.id}\n")
65*1db30e61Slinjiawei  }
66*1db30e61Slinjiawei
67*1db30e61Slinjiawei  val fullMask = MaskExpand(in.w.bits.strb)
68*1db30e61Slinjiawei
69*1db30e61Slinjiawei  def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask)
70*1db30e61Slinjiawei
71*1db30e61Slinjiawei  val raddr = Wire(UInt())
72*1db30e61Slinjiawei  val ren = Wire(Bool())
73*1db30e61Slinjiawei  val (readBeatCnt, rLast) = {
74*1db30e61Slinjiawei    val c = Counter(256)
75*1db30e61Slinjiawei    val beatCnt = Counter(256)
76*1db30e61Slinjiawei    val len = HoldUnless(in.ar.bits.len, in.ar.fire())
77*1db30e61Slinjiawei    val burst = HoldUnless(in.ar.bits.burst, in.ar.fire())
78*1db30e61Slinjiawei    val wrapAddr = in.ar.bits.addr & (~(in.ar.bits.len << in.ar.bits.size)).asUInt()
79*1db30e61Slinjiawei    raddr := HoldUnless(wrapAddr, in.ar.fire())
80*1db30e61Slinjiawei    in.r.bits.last := (c.value === len)
81*1db30e61Slinjiawei    when(ren) {
82*1db30e61Slinjiawei      beatCnt.inc()
83*1db30e61Slinjiawei      when(burst === AXI4Parameters.BURST_WRAP && beatCnt.value === len) {
84*1db30e61Slinjiawei        beatCnt.value := 0.U
85*1db30e61Slinjiawei      }
86*1db30e61Slinjiawei    }
87*1db30e61Slinjiawei    when(in.r.fire()) {
88*1db30e61Slinjiawei      c.inc()
89*1db30e61Slinjiawei      when(in.r.bits.last) {
90*1db30e61Slinjiawei        c.value := 0.U
91*1db30e61Slinjiawei      }
92*1db30e61Slinjiawei    }
93*1db30e61Slinjiawei    when(in.ar.fire()) {
94*1db30e61Slinjiawei      beatCnt.value := (in.ar.bits.addr >> in.ar.bits.size).asUInt() & in.ar.bits.len
95*1db30e61Slinjiawei      when(in.ar.bits.len =/= 0.U && in.ar.bits.burst === AXI4Parameters.BURST_WRAP) {
96*1db30e61Slinjiawei        assert(in.ar.bits.len === 1.U || in.ar.bits.len === 3.U ||
97*1db30e61Slinjiawei          in.ar.bits.len === 7.U || in.ar.bits.len === 15.U)
98*1db30e61Slinjiawei      }
99*1db30e61Slinjiawei    }
100*1db30e61Slinjiawei    (beatCnt.value, in.r.bits.last)
101*1db30e61Slinjiawei  }
102*1db30e61Slinjiawei
103*1db30e61Slinjiawei  val r_busy = BoolStopWatch(in.ar.fire(), in.r.fire() && rLast, startHighPriority = true)
104*1db30e61Slinjiawei  in.ar.ready := in.r.ready || !r_busy
105*1db30e61Slinjiawei  in.r.bits.resp := AXI4Parameters.RESP_OKAY
106*1db30e61Slinjiawei  ren := RegNext(in.ar.fire()) || (in.r.fire() && !rLast)
107*1db30e61Slinjiawei  in.r.valid := BoolStopWatch(ren && (in.ar.fire() || r_busy), in.r.fire(), startHighPriority = true)
108*1db30e61Slinjiawei
109*1db30e61Slinjiawei
110*1db30e61Slinjiawei  val waddr = Wire(UInt())
111*1db30e61Slinjiawei  val (writeBeatCnt, wLast) = {
112*1db30e61Slinjiawei    val c = Counter(256)
113*1db30e61Slinjiawei    waddr := HoldUnless(in.aw.bits.addr, in.aw.fire())
114*1db30e61Slinjiawei    when(in.w.fire()) {
115*1db30e61Slinjiawei      c.inc()
116*1db30e61Slinjiawei      when(in.w.bits.last) {
117*1db30e61Slinjiawei        c.value := 0.U
118*1db30e61Slinjiawei      }
119*1db30e61Slinjiawei    }
120*1db30e61Slinjiawei    (c.value, in.w.bits.last)
121*1db30e61Slinjiawei  }
122*1db30e61Slinjiawei
123*1db30e61Slinjiawei  val w_busy = BoolStopWatch(in.aw.fire(), in.b.fire(), startHighPriority = true)
124*1db30e61Slinjiawei  in.aw.ready := !w_busy
125*1db30e61Slinjiawei  in.w.ready := in.aw.valid || (w_busy)
126*1db30e61Slinjiawei  in.b.bits.resp := AXI4Parameters.RESP_OKAY
127*1db30e61Slinjiawei  in.b.valid := BoolStopWatch(in.w.fire() && wLast, in.b.fire(), startHighPriority = true)
128*1db30e61Slinjiawei
129*1db30e61Slinjiawei  in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire())
130*1db30e61Slinjiawei  in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire())
131*1db30e61Slinjiawei  in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire())
132*1db30e61Slinjiawei  in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire())
133*1db30e61Slinjiawei}
134