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