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