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