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} 91db30e61Slinjiawei 101db30e61Slinjiaweiabstract class AXI4SlaveModule[T <: Data] 111db30e61Slinjiawei( 12a2e9bde6SAllen address: Seq[AddressSet], 131db30e61Slinjiawei executable: Boolean = true, 141db30e61Slinjiawei beatBytes: Int = 8, 151db30e61Slinjiawei burstLen: Int = 1, 161db30e61Slinjiawei val _extra: T = null 171db30e61Slinjiawei)(implicit p: Parameters) extends LazyModule { 181db30e61Slinjiawei 191db30e61Slinjiawei val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters( 201db30e61Slinjiawei Seq(AXI4SlaveParameters( 21a2e9bde6SAllen address, 221db30e61Slinjiawei regionType = RegionType.UNCACHED, 231db30e61Slinjiawei executable = executable, 241db30e61Slinjiawei supportsWrite = TransferSizes(1, beatBytes * burstLen), 251db30e61Slinjiawei supportsRead = TransferSizes(1, beatBytes * burstLen), 261db30e61Slinjiawei interleavedId = Some(0) 271db30e61Slinjiawei )), 281db30e61Slinjiawei beatBytes = beatBytes 291db30e61Slinjiawei ))) 301db30e61Slinjiawei 311db30e61Slinjiawei lazy val module = new AXI4SlaveModuleImp[T](this) 321db30e61Slinjiawei 331db30e61Slinjiawei} 341db30e61Slinjiawei 351db30e61Slinjiaweiclass AXI4SlaveModuleImp[T<:Data](outer: AXI4SlaveModule[T]) 36*5c5bd416Sljw extends LazyModuleImp(outer) 371db30e61Slinjiawei{ 381db30e61Slinjiawei val io = IO(new Bundle { 39956d83c0Slinjiawei val extra = if(outer._extra == null) None else Some(outer._extra.cloneType) 401db30e61Slinjiawei }) 411db30e61Slinjiawei 421db30e61Slinjiawei val (in, edge) = outer.node.in.head 4355fc3133SAllen // do not let MMIO AXI signals optimized out 4455fc3133SAllen chisel3.dontTouch(in) 4555fc3133SAllen 461db30e61Slinjiawei 47e2801f97Slinjiawei// val timer = GTimer() 481db30e61Slinjiawei when(in.ar.fire()){ 49e2801f97Slinjiawei XSDebug(p"[ar] addr: ${Hexadecimal(in.ar.bits.addr)} " + 501db30e61Slinjiawei p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " + 511db30e61Slinjiawei p"id: ${in.ar.bits.id}\n" 521db30e61Slinjiawei ) 531db30e61Slinjiawei } 541db30e61Slinjiawei when(in.aw.fire()){ 55e2801f97Slinjiawei XSDebug(p"[aw] addr: ${Hexadecimal(in.aw.bits.addr)} " + 561db30e61Slinjiawei p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " + 571db30e61Slinjiawei p"id: ${in.aw.bits.id}\n" 581db30e61Slinjiawei ) 591db30e61Slinjiawei } 601db30e61Slinjiawei when(in.w.fire()){ 6124b11ca3Slinjiawei XSDebug(p"[w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last} data:${Hexadecimal(in.w.bits.data)}\n") 621db30e61Slinjiawei } 631db30e61Slinjiawei when(in.b.fire()){ 64e2801f97Slinjiawei XSDebug(p"[b] id: ${in.b.bits.id}\n") 651db30e61Slinjiawei } 661db30e61Slinjiawei when(in.r.fire()){ 6724b11ca3Slinjiawei XSDebug(p"[r] id: ${in.r.bits.id} data: ${Hexadecimal(in.r.bits.data)}\n") 681db30e61Slinjiawei } 691db30e61Slinjiawei 70efc6a777Slinjiawei when(in.aw.fire()){ 71efc6a777Slinjiawei assert(in.aw.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 72efc6a777Slinjiawei } 73efc6a777Slinjiawei when(in.ar.fire()){ 74efc6a777Slinjiawei assert(in.ar.bits.burst === AXI4Parameters.BURST_INCR, "only support busrt ince!") 75efc6a777Slinjiawei } 76075891a7Slinjiawei 772195ebbdSYinan Xu val s_idle :: s_rdata :: s_wdata :: s_wresp :: Nil = Enum(4) 78075891a7Slinjiawei 792195ebbdSYinan Xu val state = RegInit(s_idle) 80075891a7Slinjiawei 81075891a7Slinjiawei switch(state){ 82075891a7Slinjiawei is(s_idle){ 83075891a7Slinjiawei when(in.ar.fire()){ 84075891a7Slinjiawei state := s_rdata 85075891a7Slinjiawei } 86075891a7Slinjiawei when(in.aw.fire()){ 87075891a7Slinjiawei state := s_wdata 88075891a7Slinjiawei } 89075891a7Slinjiawei } 90075891a7Slinjiawei is(s_rdata){ 91075891a7Slinjiawei when(in.r.fire() && in.r.bits.last){ 92075891a7Slinjiawei state := s_idle 93075891a7Slinjiawei } 94075891a7Slinjiawei } 95075891a7Slinjiawei is(s_wdata){ 96075891a7Slinjiawei when(in.w.fire() && in.w.bits.last){ 97075891a7Slinjiawei state := s_wresp 98075891a7Slinjiawei } 99075891a7Slinjiawei } 100075891a7Slinjiawei is(s_wresp){ 101075891a7Slinjiawei when(in.b.fire()){ 102075891a7Slinjiawei state := s_idle 103075891a7Slinjiawei } 104075891a7Slinjiawei } 105075891a7Slinjiawei } 106075891a7Slinjiawei 107075891a7Slinjiawei 1081db30e61Slinjiawei val fullMask = MaskExpand(in.w.bits.strb) 1091db30e61Slinjiawei 1101db30e61Slinjiawei def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask) 1111db30e61Slinjiawei 1121db30e61Slinjiawei val raddr = Wire(UInt()) 1131db30e61Slinjiawei val (readBeatCnt, rLast) = { 1141db30e61Slinjiawei val c = Counter(256) 1151db30e61Slinjiawei val len = HoldUnless(in.ar.bits.len, in.ar.fire()) 116efc6a777Slinjiawei raddr := HoldUnless(in.ar.bits.addr, in.ar.fire()) 1171db30e61Slinjiawei in.r.bits.last := (c.value === len) 118efc6a777Slinjiawei 1191db30e61Slinjiawei when(in.r.fire()) { 1201db30e61Slinjiawei c.inc() 1211db30e61Slinjiawei when(in.r.bits.last) { 1221db30e61Slinjiawei c.value := 0.U 1231db30e61Slinjiawei } 1241db30e61Slinjiawei } 1251db30e61Slinjiawei when(in.ar.fire()) { 126efc6a777Slinjiawei assert( 127efc6a777Slinjiawei in.ar.bits.len === 0.U || 128efc6a777Slinjiawei in.ar.bits.len === 1.U || 129efc6a777Slinjiawei in.ar.bits.len === 3.U || 130efc6a777Slinjiawei in.ar.bits.len === 7.U || 131efc6a777Slinjiawei in.ar.bits.len === 15.U 132efc6a777Slinjiawei ) 1331db30e61Slinjiawei } 134efc6a777Slinjiawei (c.value, in.r.bits.last) 1351db30e61Slinjiawei } 1361db30e61Slinjiawei 137075891a7Slinjiawei in.ar.ready := state === s_idle 1381db30e61Slinjiawei in.r.bits.resp := AXI4Parameters.RESP_OKAY 139075891a7Slinjiawei in.r.valid := state === s_rdata 1401db30e61Slinjiawei 1411db30e61Slinjiawei 1421db30e61Slinjiawei val waddr = Wire(UInt()) 1431db30e61Slinjiawei val (writeBeatCnt, wLast) = { 1441db30e61Slinjiawei val c = Counter(256) 1451db30e61Slinjiawei waddr := HoldUnless(in.aw.bits.addr, in.aw.fire()) 1461db30e61Slinjiawei when(in.w.fire()) { 1471db30e61Slinjiawei c.inc() 1481db30e61Slinjiawei when(in.w.bits.last) { 1491db30e61Slinjiawei c.value := 0.U 1501db30e61Slinjiawei } 1511db30e61Slinjiawei } 1521db30e61Slinjiawei (c.value, in.w.bits.last) 1531db30e61Slinjiawei } 1541db30e61Slinjiawei 1556c6d537cSAllen in.aw.ready := state === s_idle && !in.ar.valid 156075891a7Slinjiawei in.w.ready := state === s_wdata 157075891a7Slinjiawei 1581db30e61Slinjiawei in.b.bits.resp := AXI4Parameters.RESP_OKAY 159075891a7Slinjiawei in.b.valid := state===s_wresp 1601db30e61Slinjiawei 1611db30e61Slinjiawei in.b.bits.id := RegEnable(in.aw.bits.id, in.aw.fire()) 1621db30e61Slinjiawei in.b.bits.user := RegEnable(in.aw.bits.user, in.aw.fire()) 1631db30e61Slinjiawei in.r.bits.id := RegEnable(in.ar.bits.id, in.ar.fire()) 1641db30e61Slinjiawei in.r.bits.user := RegEnable(in.ar.bits.user, in.ar.fire()) 1651db30e61Slinjiawei} 166