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