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: Seq[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 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 = if(outer._extra == null) None else Some(outer._extra.cloneType) 40 }) 41 42 val (in, edge) = outer.node.in.head 43 // do not let MMIO AXI signals optimized out 44 chisel3.dontTouch(in) 45 46 47// val timer = GTimer() 48 when(in.ar.fire()){ 49 XSDebug(p"[ar] addr: ${Hexadecimal(in.ar.bits.addr)} " + 50 p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " + 51 p"id: ${in.ar.bits.id}\n" 52 ) 53 } 54 when(in.aw.fire()){ 55 XSDebug(p"[aw] addr: ${Hexadecimal(in.aw.bits.addr)} " + 56 p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " + 57 p"id: ${in.aw.bits.id}\n" 58 ) 59 } 60 when(in.w.fire()){ 61 XSDebug(p"[w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last} data:${Hexadecimal(in.w.bits.data)}\n") 62 } 63 when(in.b.fire()){ 64 XSDebug(p"[b] id: ${in.b.bits.id}\n") 65 } 66 when(in.r.fire()){ 67 XSDebug(p"[r] id: ${in.r.bits.id} data: ${Hexadecimal(in.r.bits.data)}\n") 68 } 69 70 when(in.aw.fire()){ 71 assert(in.aw.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 72 } 73 when(in.ar.fire()){ 74 assert(in.ar.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 75 } 76 77 val s_idle :: s_rdata :: s_wdata :: s_wresp :: Nil = Enum(4) 78 79 val state = RegInit(s_idle) 80 81 switch(state){ 82 is(s_idle){ 83 when(in.ar.fire()){ 84 state := s_rdata 85 } 86 when(in.aw.fire()){ 87 state := s_wdata 88 } 89 } 90 is(s_rdata){ 91 when(in.r.fire() && in.r.bits.last){ 92 state := s_idle 93 } 94 } 95 is(s_wdata){ 96 when(in.w.fire() && in.w.bits.last){ 97 state := s_wresp 98 } 99 } 100 is(s_wresp){ 101 when(in.b.fire()){ 102 state := s_idle 103 } 104 } 105 } 106 107 108 val fullMask = MaskExpand(in.w.bits.strb) 109 110 def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask) 111 112 val raddr = Wire(UInt()) 113 val (readBeatCnt, rLast) = { 114 val c = Counter(256) 115 val len = HoldUnless(in.ar.bits.len, in.ar.fire()) 116 raddr := HoldUnless(in.ar.bits.addr, in.ar.fire()) 117 in.r.bits.last := (c.value === len) 118 119 when(in.r.fire()) { 120 c.inc() 121 when(in.r.bits.last) { 122 c.value := 0.U 123 } 124 } 125 when(in.ar.fire()) { 126 assert( 127 in.ar.bits.len === 0.U || 128 in.ar.bits.len === 1.U || 129 in.ar.bits.len === 3.U || 130 in.ar.bits.len === 7.U || 131 in.ar.bits.len === 15.U 132 ) 133 } 134 (c.value, in.r.bits.last) 135 } 136 137 in.ar.ready := state === s_idle 138 in.r.bits.resp := AXI4Parameters.RESP_OKAY 139 in.r.valid := state === s_rdata 140 141 142 val waddr = Wire(UInt()) 143 val (writeBeatCnt, wLast) = { 144 val c = Counter(256) 145 waddr := HoldUnless(in.aw.bits.addr, in.aw.fire()) 146 when(in.w.fire()) { 147 c.inc() 148 when(in.w.bits.last) { 149 c.value := 0.U 150 } 151 } 152 (c.value, in.w.bits.last) 153 } 154 155 in.aw.ready := state === s_idle && !in.ar.valid 156 in.w.ready := state === s_wdata 157 158 in.b.bits.resp := AXI4Parameters.RESP_OKAY 159 in.b.valid := state===s_wresp 160 161 in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire()) 162 in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire()) 163 in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire()) 164 in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire()) 165} 166