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 69 private val s_idle :: s_rdata :: s_wdata :: s_wresp :: Nil = Enum(4) 70 71 private val state = RegInit(s_idle) 72 73 switch(state){ 74 is(s_idle){ 75 when(in.ar.fire()){ 76 state := s_rdata 77 } 78 when(in.aw.fire()){ 79 state := s_wdata 80 } 81 } 82 is(s_rdata){ 83 when(in.r.fire() && in.r.bits.last){ 84 state := s_idle 85 } 86 } 87 is(s_wdata){ 88 when(in.w.fire() && in.w.bits.last){ 89 state := s_wresp 90 } 91 } 92 is(s_wresp){ 93 when(in.b.fire()){ 94 state := s_idle 95 } 96 } 97 } 98 99 100 val fullMask = MaskExpand(in.w.bits.strb) 101 102 def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask) 103 104 val raddr = Wire(UInt()) 105 val ren = Wire(Bool()) 106 val (readBeatCnt, rLast) = { 107 val c = Counter(256) 108 val beatCnt = Counter(256) 109 val len = HoldUnless(in.ar.bits.len, in.ar.fire()) 110 val burst = HoldUnless(in.ar.bits.burst, in.ar.fire()) 111 val wrapAddr = in.ar.bits.addr & (~(in.ar.bits.len << in.ar.bits.size)).asUInt() 112 raddr := HoldUnless(wrapAddr, in.ar.fire()) 113 in.r.bits.last := (c.value === len) 114 when(ren) { 115 beatCnt.inc() 116 when(burst === AXI4Parameters.BURST_WRAP && beatCnt.value === len) { 117 beatCnt.value := 0.U 118 } 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 beatCnt.value := (in.ar.bits.addr >> in.ar.bits.size).asUInt() & in.ar.bits.len 128 when(in.ar.bits.len =/= 0.U && in.ar.bits.burst === AXI4Parameters.BURST_WRAP) { 129 assert(in.ar.bits.len === 1.U || in.ar.bits.len === 3.U || 130 in.ar.bits.len === 7.U || in.ar.bits.len === 15.U) 131 } 132 } 133 (beatCnt.value, in.r.bits.last) 134 } 135 136 val r_busy = BoolStopWatch(in.ar.fire(), in.r.fire() && rLast, startHighPriority = true) 137 in.ar.ready := state === s_idle 138 in.r.bits.resp := AXI4Parameters.RESP_OKAY 139 ren := RegNext(in.ar.fire()) || (in.r.fire() && !rLast) 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