11db30e61Slinjiaweipackage device 21db30e61Slinjiawei 31db30e61Slinjiaweiimport chisel3._ 41db30e61Slinjiaweiimport chisel3.util._ 51db30e61Slinjiaweiimport utils._ 61db30e61Slinjiaweiimport freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp, RegionType, TransferSizes} 71db30e61Slinjiaweiimport chipsalliance.rocketchip.config.Parameters 81db30e61Slinjiaweiimport freechips.rocketchip.amba.axi4.{AXI4Parameters, AXI4SlaveNode, AXI4SlaveParameters, AXI4SlavePortParameters} 9e2801f97Slinjiaweiimport xiangshan.HasXSLog 101db30e61Slinjiawei 111db30e61Slinjiaweiabstract class AXI4SlaveModule[T <: Data] 121db30e61Slinjiawei( 13a2e9bde6SAllen address: Seq[AddressSet], 141db30e61Slinjiawei executable: Boolean = true, 151db30e61Slinjiawei beatBytes: Int = 8, 161db30e61Slinjiawei burstLen: Int = 1, 171db30e61Slinjiawei val _extra: T = null 181db30e61Slinjiawei)(implicit p: Parameters) extends LazyModule { 191db30e61Slinjiawei 201db30e61Slinjiawei val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters( 211db30e61Slinjiawei Seq(AXI4SlaveParameters( 22a2e9bde6SAllen address, 231db30e61Slinjiawei regionType = RegionType.UNCACHED, 241db30e61Slinjiawei executable = executable, 251db30e61Slinjiawei supportsWrite = TransferSizes(1, beatBytes * burstLen), 261db30e61Slinjiawei supportsRead = TransferSizes(1, beatBytes * burstLen), 271db30e61Slinjiawei interleavedId = Some(0) 281db30e61Slinjiawei )), 291db30e61Slinjiawei beatBytes = beatBytes 301db30e61Slinjiawei ))) 311db30e61Slinjiawei 321db30e61Slinjiawei lazy val module = new AXI4SlaveModuleImp[T](this) 331db30e61Slinjiawei 341db30e61Slinjiawei} 351db30e61Slinjiawei 361db30e61Slinjiaweiclass AXI4SlaveModuleImp[T<:Data](outer: AXI4SlaveModule[T]) 37e2801f97Slinjiawei extends LazyModuleImp(outer) with HasXSLog 381db30e61Slinjiawei{ 391db30e61Slinjiawei val io = IO(new Bundle { 40956d83c0Slinjiawei val extra = if(outer._extra == null) None else Some(outer._extra.cloneType) 411db30e61Slinjiawei }) 421db30e61Slinjiawei 431db30e61Slinjiawei val (in, edge) = outer.node.in.head 44*55fc3133SAllen // do not let MMIO AXI signals optimized out 45*55fc3133SAllen chisel3.dontTouch(in) 46*55fc3133SAllen 471db30e61Slinjiawei 48e2801f97Slinjiawei// val timer = GTimer() 491db30e61Slinjiawei when(in.ar.fire()){ 50e2801f97Slinjiawei XSDebug(p"[ar] addr: ${Hexadecimal(in.ar.bits.addr)} " + 511db30e61Slinjiawei p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " + 521db30e61Slinjiawei p"id: ${in.ar.bits.id}\n" 531db30e61Slinjiawei ) 541db30e61Slinjiawei } 551db30e61Slinjiawei when(in.aw.fire()){ 56e2801f97Slinjiawei XSDebug(p"[aw] addr: ${Hexadecimal(in.aw.bits.addr)} " + 571db30e61Slinjiawei p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " + 581db30e61Slinjiawei p"id: ${in.aw.bits.id}\n" 591db30e61Slinjiawei ) 601db30e61Slinjiawei } 611db30e61Slinjiawei when(in.w.fire()){ 6224b11ca3Slinjiawei XSDebug(p"[w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last} data:${Hexadecimal(in.w.bits.data)}\n") 631db30e61Slinjiawei } 641db30e61Slinjiawei when(in.b.fire()){ 65e2801f97Slinjiawei XSDebug(p"[b] id: ${in.b.bits.id}\n") 661db30e61Slinjiawei } 671db30e61Slinjiawei when(in.r.fire()){ 6824b11ca3Slinjiawei XSDebug(p"[r] id: ${in.r.bits.id} data: ${Hexadecimal(in.r.bits.data)}\n") 691db30e61Slinjiawei } 701db30e61Slinjiawei 71efc6a777Slinjiawei when(in.aw.fire()){ 72efc6a777Slinjiawei assert(in.aw.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 73efc6a777Slinjiawei } 74efc6a777Slinjiawei when(in.ar.fire()){ 75efc6a777Slinjiawei assert(in.ar.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 76efc6a777Slinjiawei } 77075891a7Slinjiawei 7824b11ca3Slinjiawei private val s_idle :: s_rdata :: s_wdata :: s_wresp :: Nil = Enum(4) 79075891a7Slinjiawei 8024b11ca3Slinjiawei private val state = RegInit(s_idle) 81075891a7Slinjiawei 82075891a7Slinjiawei switch(state){ 83075891a7Slinjiawei is(s_idle){ 84075891a7Slinjiawei when(in.ar.fire()){ 85075891a7Slinjiawei state := s_rdata 86075891a7Slinjiawei } 87075891a7Slinjiawei when(in.aw.fire()){ 88075891a7Slinjiawei state := s_wdata 89075891a7Slinjiawei } 90075891a7Slinjiawei } 91075891a7Slinjiawei is(s_rdata){ 92075891a7Slinjiawei when(in.r.fire() && in.r.bits.last){ 93075891a7Slinjiawei state := s_idle 94075891a7Slinjiawei } 95075891a7Slinjiawei } 96075891a7Slinjiawei is(s_wdata){ 97075891a7Slinjiawei when(in.w.fire() && in.w.bits.last){ 98075891a7Slinjiawei state := s_wresp 99075891a7Slinjiawei } 100075891a7Slinjiawei } 101075891a7Slinjiawei is(s_wresp){ 102075891a7Slinjiawei when(in.b.fire()){ 103075891a7Slinjiawei state := s_idle 104075891a7Slinjiawei } 105075891a7Slinjiawei } 106075891a7Slinjiawei } 107075891a7Slinjiawei 108075891a7Slinjiawei 1091db30e61Slinjiawei val fullMask = MaskExpand(in.w.bits.strb) 1101db30e61Slinjiawei 1111db30e61Slinjiawei def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask) 1121db30e61Slinjiawei 1131db30e61Slinjiawei val raddr = Wire(UInt()) 1141db30e61Slinjiawei val (readBeatCnt, rLast) = { 1151db30e61Slinjiawei val c = Counter(256) 1161db30e61Slinjiawei val len = HoldUnless(in.ar.bits.len, in.ar.fire()) 117efc6a777Slinjiawei raddr := HoldUnless(in.ar.bits.addr, in.ar.fire()) 1181db30e61Slinjiawei in.r.bits.last := (c.value === len) 119efc6a777Slinjiawei 1201db30e61Slinjiawei when(in.r.fire()) { 1211db30e61Slinjiawei c.inc() 1221db30e61Slinjiawei when(in.r.bits.last) { 1231db30e61Slinjiawei c.value := 0.U 1241db30e61Slinjiawei } 1251db30e61Slinjiawei } 1261db30e61Slinjiawei when(in.ar.fire()) { 127efc6a777Slinjiawei assert( 128efc6a777Slinjiawei in.ar.bits.len === 0.U || 129efc6a777Slinjiawei in.ar.bits.len === 1.U || 130efc6a777Slinjiawei in.ar.bits.len === 3.U || 131efc6a777Slinjiawei in.ar.bits.len === 7.U || 132efc6a777Slinjiawei in.ar.bits.len === 15.U 133efc6a777Slinjiawei ) 1341db30e61Slinjiawei } 135efc6a777Slinjiawei (c.value, in.r.bits.last) 1361db30e61Slinjiawei } 1371db30e61Slinjiawei 138075891a7Slinjiawei in.ar.ready := state === s_idle 1391db30e61Slinjiawei in.r.bits.resp := AXI4Parameters.RESP_OKAY 140075891a7Slinjiawei in.r.valid := state === s_rdata 1411db30e61Slinjiawei 1421db30e61Slinjiawei 1431db30e61Slinjiawei val waddr = Wire(UInt()) 1441db30e61Slinjiawei val (writeBeatCnt, wLast) = { 1451db30e61Slinjiawei val c = Counter(256) 1461db30e61Slinjiawei waddr := HoldUnless(in.aw.bits.addr, in.aw.fire()) 1471db30e61Slinjiawei when(in.w.fire()) { 1481db30e61Slinjiawei c.inc() 1491db30e61Slinjiawei when(in.w.bits.last) { 1501db30e61Slinjiawei c.value := 0.U 1511db30e61Slinjiawei } 1521db30e61Slinjiawei } 1531db30e61Slinjiawei (c.value, in.w.bits.last) 1541db30e61Slinjiawei } 1551db30e61Slinjiawei 156075891a7Slinjiawei in.aw.ready := state === s_idle 157075891a7Slinjiawei in.w.ready := state === s_wdata 158075891a7Slinjiawei 1591db30e61Slinjiawei in.b.bits.resp := AXI4Parameters.RESP_OKAY 160075891a7Slinjiawei in.b.valid := state===s_wresp 1611db30e61Slinjiawei 1621db30e61Slinjiawei in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire()) 1631db30e61Slinjiawei in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire()) 1641db30e61Slinjiawei in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire()) 1651db30e61Slinjiawei in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire()) 1661db30e61Slinjiawei} 167