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} 9import xiangshan.HasXSLog 10 11abstract class AXI4SlaveModule[T <: Data] 12( 13 address: Seq[AddressSet], 14 executable: Boolean = true, 15 beatBytes: Int = 8, 16 burstLen: Int = 1, 17 val _extra: T = null 18)(implicit p: Parameters) extends LazyModule { 19 20 val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters( 21 Seq(AXI4SlaveParameters( 22 address, 23 regionType = RegionType.UNCACHED, 24 executable = executable, 25 supportsWrite = TransferSizes(1, beatBytes * burstLen), 26 supportsRead = TransferSizes(1, beatBytes * burstLen), 27 interleavedId = Some(0) 28 )), 29 beatBytes = beatBytes 30 ))) 31 32 lazy val module = new AXI4SlaveModuleImp[T](this) 33 34} 35 36class AXI4SlaveModuleImp[T<:Data](outer: AXI4SlaveModule[T]) 37 extends LazyModuleImp(outer) with HasXSLog 38{ 39 val io = IO(new Bundle { 40 val extra = if(outer._extra == null) None else Some(outer._extra.cloneType) 41 }) 42 43 val (in, edge) = outer.node.in.head 44 // do not let MMIO AXI signals optimized out 45 chisel3.dontTouch(in) 46 47 48// val timer = GTimer() 49 when(in.ar.fire()){ 50 XSDebug(p"[ar] addr: ${Hexadecimal(in.ar.bits.addr)} " + 51 p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " + 52 p"id: ${in.ar.bits.id}\n" 53 ) 54 } 55 when(in.aw.fire()){ 56 XSDebug(p"[aw] addr: ${Hexadecimal(in.aw.bits.addr)} " + 57 p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " + 58 p"id: ${in.aw.bits.id}\n" 59 ) 60 } 61 when(in.w.fire()){ 62 XSDebug(p"[w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last} data:${Hexadecimal(in.w.bits.data)}\n") 63 } 64 when(in.b.fire()){ 65 XSDebug(p"[b] id: ${in.b.bits.id}\n") 66 } 67 when(in.r.fire()){ 68 XSDebug(p"[r] id: ${in.r.bits.id} data: ${Hexadecimal(in.r.bits.data)}\n") 69 } 70 71 when(in.aw.fire()){ 72 assert(in.aw.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 73 } 74 when(in.ar.fire()){ 75 assert(in.ar.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 76 } 77 78 private val s_idle :: s_rdata :: s_wdata :: s_wresp :: Nil = Enum(4) 79 80 private val state = RegInit(s_idle) 81 82 switch(state){ 83 is(s_idle){ 84 when(in.ar.fire()){ 85 state := s_rdata 86 } 87 when(in.aw.fire()){ 88 state := s_wdata 89 } 90 } 91 is(s_rdata){ 92 when(in.r.fire() && in.r.bits.last){ 93 state := s_idle 94 } 95 } 96 is(s_wdata){ 97 when(in.w.fire() && in.w.bits.last){ 98 state := s_wresp 99 } 100 } 101 is(s_wresp){ 102 when(in.b.fire()){ 103 state := s_idle 104 } 105 } 106 } 107 108 109 val fullMask = MaskExpand(in.w.bits.strb) 110 111 def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask) 112 113 val raddr = Wire(UInt()) 114 val (readBeatCnt, rLast) = { 115 val c = Counter(256) 116 val len = HoldUnless(in.ar.bits.len, in.ar.fire()) 117 raddr := HoldUnless(in.ar.bits.addr, in.ar.fire()) 118 in.r.bits.last := (c.value === len) 119 120 when(in.r.fire()) { 121 c.inc() 122 when(in.r.bits.last) { 123 c.value := 0.U 124 } 125 } 126 when(in.ar.fire()) { 127 assert( 128 in.ar.bits.len === 0.U || 129 in.ar.bits.len === 1.U || 130 in.ar.bits.len === 3.U || 131 in.ar.bits.len === 7.U || 132 in.ar.bits.len === 15.U 133 ) 134 } 135 (c.value, in.r.bits.last) 136 } 137 138 in.ar.ready := state === s_idle 139 in.r.bits.resp := AXI4Parameters.RESP_OKAY 140 in.r.valid := state === s_rdata 141 142 143 val waddr = Wire(UInt()) 144 val (writeBeatCnt, wLast) = { 145 val c = Counter(256) 146 waddr := HoldUnless(in.aw.bits.addr, in.aw.fire()) 147 when(in.w.fire()) { 148 c.inc() 149 when(in.w.bits.last) { 150 c.value := 0.U 151 } 152 } 153 (c.value, in.w.bits.last) 154 } 155 156 in.aw.ready := state === s_idle 157 in.w.ready := state === s_wdata 158 159 in.b.bits.resp := AXI4Parameters.RESP_OKAY 160 in.b.valid := state===s_wresp 161 162 in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire()) 163 in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire()) 164 in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire()) 165 in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire()) 166} 167