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( 131db30e61Slinjiawei address: 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( 221db30e61Slinjiawei Seq(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 441db30e61Slinjiawei 45e2801f97Slinjiawei// val timer = GTimer() 461db30e61Slinjiawei when(in.ar.fire()){ 47e2801f97Slinjiawei XSDebug(p"[ar] addr: ${Hexadecimal(in.ar.bits.addr)} " + 481db30e61Slinjiawei p"arlen:${in.ar.bits.len} arsize:${in.ar.bits.size} " + 491db30e61Slinjiawei p"id: ${in.ar.bits.id}\n" 501db30e61Slinjiawei ) 511db30e61Slinjiawei } 521db30e61Slinjiawei when(in.aw.fire()){ 53e2801f97Slinjiawei XSDebug(p"[aw] addr: ${Hexadecimal(in.aw.bits.addr)} " + 541db30e61Slinjiawei p"awlen:${in.aw.bits.len} awsize:${in.aw.bits.size} " + 551db30e61Slinjiawei p"id: ${in.aw.bits.id}\n" 561db30e61Slinjiawei ) 571db30e61Slinjiawei } 581db30e61Slinjiawei when(in.w.fire()){ 59*24b11ca3Slinjiawei XSDebug(p"[w] wmask: ${Binary(in.w.bits.strb)} last:${in.w.bits.last} data:${Hexadecimal(in.w.bits.data)}\n") 601db30e61Slinjiawei } 611db30e61Slinjiawei when(in.b.fire()){ 62e2801f97Slinjiawei XSDebug(p"[b] id: ${in.b.bits.id}\n") 631db30e61Slinjiawei } 641db30e61Slinjiawei when(in.r.fire()){ 65*24b11ca3Slinjiawei XSDebug(p"[r] id: ${in.r.bits.id} data: ${Hexadecimal(in.r.bits.data)}\n") 661db30e61Slinjiawei } 671db30e61Slinjiawei 68075891a7Slinjiawei 69*24b11ca3Slinjiawei private val s_idle :: s_rdata :: s_wdata :: s_wresp :: Nil = Enum(4) 70075891a7Slinjiawei 71*24b11ca3Slinjiawei private val state = RegInit(s_idle) 72075891a7Slinjiawei 73075891a7Slinjiawei switch(state){ 74075891a7Slinjiawei is(s_idle){ 75075891a7Slinjiawei when(in.ar.fire()){ 76075891a7Slinjiawei state := s_rdata 77075891a7Slinjiawei } 78075891a7Slinjiawei when(in.aw.fire()){ 79075891a7Slinjiawei state := s_wdata 80075891a7Slinjiawei } 81075891a7Slinjiawei } 82075891a7Slinjiawei is(s_rdata){ 83075891a7Slinjiawei when(in.r.fire() && in.r.bits.last){ 84075891a7Slinjiawei state := s_idle 85075891a7Slinjiawei } 86075891a7Slinjiawei } 87075891a7Slinjiawei is(s_wdata){ 88075891a7Slinjiawei when(in.w.fire() && in.w.bits.last){ 89075891a7Slinjiawei state := s_wresp 90075891a7Slinjiawei } 91075891a7Slinjiawei } 92075891a7Slinjiawei is(s_wresp){ 93075891a7Slinjiawei when(in.b.fire()){ 94075891a7Slinjiawei state := s_idle 95075891a7Slinjiawei } 96075891a7Slinjiawei } 97075891a7Slinjiawei } 98075891a7Slinjiawei 99075891a7Slinjiawei 1001db30e61Slinjiawei val fullMask = MaskExpand(in.w.bits.strb) 1011db30e61Slinjiawei 1021db30e61Slinjiawei def genWdata(originData: UInt) = (originData & (~fullMask).asUInt()) | (in.w.bits.data & fullMask) 1031db30e61Slinjiawei 1041db30e61Slinjiawei val raddr = Wire(UInt()) 1051db30e61Slinjiawei val ren = Wire(Bool()) 1061db30e61Slinjiawei val (readBeatCnt, rLast) = { 1071db30e61Slinjiawei val c = Counter(256) 1081db30e61Slinjiawei val beatCnt = Counter(256) 1091db30e61Slinjiawei val len = HoldUnless(in.ar.bits.len, in.ar.fire()) 1101db30e61Slinjiawei val burst = HoldUnless(in.ar.bits.burst, in.ar.fire()) 1111db30e61Slinjiawei val wrapAddr = in.ar.bits.addr & (~(in.ar.bits.len << in.ar.bits.size)).asUInt() 1121db30e61Slinjiawei raddr := HoldUnless(wrapAddr, in.ar.fire()) 1131db30e61Slinjiawei in.r.bits.last := (c.value === len) 1141db30e61Slinjiawei when(ren) { 1151db30e61Slinjiawei beatCnt.inc() 1161db30e61Slinjiawei when(burst === AXI4Parameters.BURST_WRAP && beatCnt.value === len) { 1171db30e61Slinjiawei beatCnt.value := 0.U 1181db30e61Slinjiawei } 1191db30e61Slinjiawei } 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()) { 1271db30e61Slinjiawei beatCnt.value := (in.ar.bits.addr >> in.ar.bits.size).asUInt() & in.ar.bits.len 1281db30e61Slinjiawei when(in.ar.bits.len =/= 0.U && in.ar.bits.burst === AXI4Parameters.BURST_WRAP) { 1291db30e61Slinjiawei assert(in.ar.bits.len === 1.U || in.ar.bits.len === 3.U || 1301db30e61Slinjiawei in.ar.bits.len === 7.U || in.ar.bits.len === 15.U) 1311db30e61Slinjiawei } 1321db30e61Slinjiawei } 1331db30e61Slinjiawei (beatCnt.value, in.r.bits.last) 1341db30e61Slinjiawei } 1351db30e61Slinjiawei 1361db30e61Slinjiawei val r_busy = BoolStopWatch(in.ar.fire(), in.r.fire() && rLast, startHighPriority = true) 137075891a7Slinjiawei in.ar.ready := state === s_idle 1381db30e61Slinjiawei in.r.bits.resp := AXI4Parameters.RESP_OKAY 1391db30e61Slinjiawei ren := RegNext(in.ar.fire()) || (in.r.fire() && !rLast) 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